From 95e9b6fef4e6c594af0f76e87564acc049b0cba3 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 29 Jun 2026 14:01:12 +0800 Subject: [PATCH 01/37] =?UTF-8?q?feat(samples):=20=E6=B7=BB=E5=8A=A0PHP?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B=E4=BB=A3=E7=A0=81=E6=96=87=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增c1.php包含函数定义和调用示例 - 新增c2.php包含类静态方法和实例方法示例 - 新增c3.php包含require语句和系统函数调用示例 - 新增c4.php包含继承类方法重写和uname函数示例 --- samples/c1.php | 14 ++++++++++++++ samples/c2.php | 20 ++++++++++++++++++++ samples/c3.php | 6 ++++++ samples/c4.php | 34 ++++++++++++++++++++++++++++++++++ 4 files changed, 74 insertions(+) create mode 100644 samples/c1.php create mode 100644 samples/c2.php create mode 100644 samples/c3.php create mode 100644 samples/c4.php diff --git a/samples/c1.php b/samples/c1.php new file mode 100644 index 00000000..5e29ce44 --- /dev/null +++ b/samples/c1.php @@ -0,0 +1,14 @@ +func2('php'); +} diff --git a/samples/c3.php b/samples/c3.php new file mode 100644 index 00000000..897b6422 --- /dev/null +++ b/samples/c3.php @@ -0,0 +1,6 @@ +bar(); + } +} + +class Child extends Base +{ + function bar() + { + var_dump(__METHOD__); + } +} + +function my_uname_func() +{ + var_dump(php_uname()); +} + +function main() +{ + $obj1 = new Child(); + $obj1->run(); + + $obj2 = new Base(); + $obj2->run(); +} From 918a52d7fb2866570154f4cd2488b126e5a84442 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 29 Jun 2026 14:01:25 +0800 Subject: [PATCH 02/37] =?UTF-8?q?test(samples):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=96=B0=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B=E5=92=8C=E7=A4=BA?= =?UTF-8?q?=E4=BE=8B=E8=84=9A=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增 tests/aot/class/new-and-call.phpt 测试文件,验证 new 和 call 操作 - 添加 samples/script.php 示例文件,演示 PHP_OS 函数使用 - 实现了类实例化后直接调用方法的测试场景 - 创建 --- samples/script.php | 5 +++++ tests/aot/class/new-and-call.phpt | 20 ++++++++++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 samples/script.php create mode 100644 tests/aot/class/new-and-call.phpt diff --git a/samples/script.php b/samples/script.php new file mode 100644 index 00000000..fd125df1 --- /dev/null +++ b/samples/script.php @@ -0,0 +1,5 @@ +bar('world'); + echo "done\n"; +} + +?> +--EXPECT-- +string(12) "hello world!" +done \ No newline at end of file From a01548ae968f2d4ad26b8e2de262048975429751 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 29 Jun 2026 14:01:59 +0800 Subject: [PATCH 03/37] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E7=BB=A7?= =?UTF-8?q?=E6=89=BF=E6=A3=80=E6=9F=A5=E4=B8=AD=E7=9A=84=E5=8F=AF=E8=A7=81?= =?UTF-8?q?=E6=80=A7=E5=AE=BD=E5=8C=96=E5=92=8C=E5=8F=82=E6=95=B0=E5=8C=B9?= =?UTF-8?q?=E9=85=8D=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了PHP允许的方法可见性宽化(如protected到public),但禁止窄化 - 添加了子类可以添加可选尾随参数的支持 - 修复了必需参数数量比较逻辑,确保子类不能要求比父类更多的必需参数 - 添加了对缺少父类声明参数的检查 - 实现了额外子类参数必须为可选或可变参数的验证 - 添加了可见性等级比较函数来正确处理继承可见性检查 --- phpunit/src/InheritanceErrorTest.php | 24 +++++++++++++++- src/Php/Translator.php | 43 ++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 9 deletions(-) diff --git a/phpunit/src/InheritanceErrorTest.php b/phpunit/src/InheritanceErrorTest.php index 1139ab14..6453e860 100644 --- a/phpunit/src/InheritanceErrorTest.php +++ b/phpunit/src/InheritanceErrorTest.php @@ -21,6 +21,18 @@ class InheritanceErrorTest extends TestCase $this->fail('Expected TestError exception was not thrown'); } + private function assertCompiles(string $file): void + { + global $translator; + $compiler = CompilerTest::create(ROOT_PATH); + $translator = $compiler; + $testFile = __DIR__ . '/../code/' . $file; + $compiler->addFiles([$testFile]); + $compiler->prepareFile($testFile); + $compiler->convertFile($testFile); + $this->addToAssertionCount(1); + } + public function testParameterCountMismatch() { $this->exec('must be compatible', 'inheritance_error.php'); @@ -48,7 +60,17 @@ class InheritanceErrorTest extends TestCase public function testMethodVisibilityMismatch() { - $this->exec('must be compatible', 'inheritance_error_visibility.php'); + $this->exec('must be compatible', 'inheritance_error_visibility_narrow.php'); + } + + public function testMethodVisibilityWideningIsAllowed() + { + $this->assertCompiles('inheritance_error_visibility.php'); + } + + public function testChildMayAddOptionalTrailingParameter() + { + $this->assertCompiles('inheritance_optional_param_allowed.php'); } public function testPropertyTypeMismatch() diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 3577e509..12e701f6 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -2966,8 +2966,9 @@ CODE; "with `{$parentClass}::{$methodName}()`"); }; - // Compare visibility (public/protected/private) - if (($this->methodDef->flags & Modifiers::VISIBILITY_MASK) !== ($parentMethodDef->flags & Modifiers::VISIBILITY_MASK)) { + // PHP allows widening visibility in overrides (e.g. protected -> public), + // but forbids narrowing it. + if ($this->getVisibilityRank($this->methodDef->flags) < $this->getVisibilityRank($parentMethodDef->flags)) { $error('visibility mismatch'); } @@ -2976,19 +2977,23 @@ CODE; return; } - // Compare parameter count - if (count($childFuncDef->argInfoList) !== count($parentFuncDef->argInfoList)) { - $error('parameter count mismatch'); - } - // Compare return type if ($childFuncDef->returnType !== $parentFuncDef->returnType || $childFuncDef->returnClass !== $parentFuncDef->returnClass) { $error('return type mismatch'); } - // Compare each parameter + // Child methods may add optional trailing parameters, but they cannot + // require more arguments than the parent contract. + if ($childFuncDef->argCountRequired > $parentFuncDef->argCountRequired) { + $error('required parameter count mismatch'); + } + + // Compare each parent-declared parameter position. foreach ($parentFuncDef->argInfoList as $i => $parentArg) { + if (!isset($childFuncDef->argInfoList[$i])) { + $error("missing parameter #{$i}"); + } $childArg = $childFuncDef->argInfoList[$i]; if ($childArg->type !== $parentArg->type || $childArg->class !== $parentArg->class) { $error("parameter #{$i} type mismatch"); @@ -3000,6 +3005,28 @@ CODE; $error("parameter #{$i} variadic mismatch"); } } + + // Any extra child parameters must be optional or variadic. + for ($i = count($parentFuncDef->argInfoList); $i < count($childFuncDef->argInfoList); $i++) { + $childArg = $childFuncDef->argInfoList[$i]; + if (!$childArg->variadic && $childArg->defaultValue === null) { + $error("extra required parameter #{$i}"); + } + } + } + + private function getVisibilityRank(int $flags): int + { + if ($flags & Modifiers::PUBLIC) { + return 3; + } + if ($flags & Modifiers::PROTECTED) { + return 2; + } + if ($flags & Modifiers::PRIVATE) { + return 1; + } + return 3; } private function checkPropertyOverride(Node\Stmt\Class_|Node\Stmt\Trait_|Node\Stmt\Enum_ $classStmt): void From 04610c5897f751d0fe36176b6462dd9b2adc3763 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 29 Jun 2026 14:05:03 +0800 Subject: [PATCH 04/37] =?UTF-8?q?refactor(reflection):=20=E9=87=8D?= =?UTF-8?q?=E6=9E=84=E8=BF=94=E5=9B=9E=E7=B1=BB=E5=9E=8B=E6=8F=90=E5=8F=96?= =?UTF-8?q?=E9=80=BB=E8=BE=91=E4=BB=A5=E6=94=AF=E6=8C=81=E8=81=94=E5=90=88?= =?UTF-8?q?=E5=92=8C=E4=BA=A4=E9=9B=86=E7=B1=BB=E5=9E=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 提取公共方法 extractNamedReturnType 处理返回类型 - 移除对 ReflectionUnionType 和 ReflectionIntersectionType 的直接检查 - 简化函数和方法返回类型的获取逻辑 - 添加对联合类型返回值的测试用例 - 添加对交集类型返回值的测试用例 - 统一返回类型处理方式提高代码可维护性 --- phpunit/src/ReflectionTest.php | 46 ++++++++++++++++++++++++++++++++++ src/Php/Reflection.php | 21 ++++++++-------- 2 files changed, 57 insertions(+), 10 deletions(-) diff --git a/phpunit/src/ReflectionTest.php b/phpunit/src/ReflectionTest.php index 1158c2cf..effac68c 100644 --- a/phpunit/src/ReflectionTest.php +++ b/phpunit/src/ReflectionTest.php @@ -7,6 +7,25 @@ use PhpAot\Php\Reflection; class ReflectionTest extends TestCase { + public function testGetFunctionReturnTypeUnionReturnsNull(): void + { + eval('function php_aot_reflection_union_return(): int|string { return 1; }'); + $this->assertNull(Reflection::getFunctionReturnType('php_aot_reflection_union_return')); + } + + public function testGetFunctionReturnTypeIntersectionReturnsNull(): void + { + eval(' + interface PhpAotReflectionI1 {} + interface PhpAotReflectionI2 {} + final class PhpAotReflectionBoth implements PhpAotReflectionI1, PhpAotReflectionI2 {} + function php_aot_reflection_intersection_return(): PhpAotReflectionI1&PhpAotReflectionI2 { + return new PhpAotReflectionBoth(); + } + '); + $this->assertNull(Reflection::getFunctionReturnType('php_aot_reflection_intersection_return')); + } + public function testIsInternalClass(): void { // Standard PHP internal classes @@ -125,6 +144,33 @@ class ReflectionTest extends TestCase $this->assertEquals('string', $type); } + public function testGetMethodReturnTypeUnionReturnsNull(): void + { + eval(' + class PhpAotReflectionUnionMethodReturn { + public function value(): int|string { + return 1; + } + } + '); + $this->assertNull(Reflection::getMethodReturnType('PhpAotReflectionUnionMethodReturn', 'value')); + } + + public function testGetMethodReturnTypeIntersectionReturnsNull(): void + { + eval(' + interface PhpAotReflectionMethodI1 {} + interface PhpAotReflectionMethodI2 {} + final class PhpAotReflectionMethodBoth implements PhpAotReflectionMethodI1, PhpAotReflectionMethodI2 {} + class PhpAotReflectionIntersectionMethodReturn { + public function value(): PhpAotReflectionMethodI1&PhpAotReflectionMethodI2 { + return new PhpAotReflectionMethodBoth(); + } + } + '); + $this->assertNull(Reflection::getMethodReturnType('PhpAotReflectionIntersectionMethodReturn', 'value')); + } + public function testGetMethodReturnTypeNonexistent(): void { $type = Reflection::getMethodReturnType('NonExistent_' . uniqid(), 'test'); diff --git a/src/Php/Reflection.php b/src/Php/Reflection.php index 9dc89764..5c380d3f 100644 --- a/src/Php/Reflection.php +++ b/src/Php/Reflection.php @@ -93,15 +93,7 @@ class Reflection if (!$func) { return null; } - $returnType = $func->getReturnType(); - if (!$returnType) { - return null; - } - if ($returnType instanceof \ReflectionUnionType) { - return null; - } - - return $returnType->getName(); + return self::extractNamedReturnType($func->getReturnType()); } public static function getFunctionParameter(string $fn, int $index): ?\ReflectionParameter @@ -172,7 +164,7 @@ class Reflection return null; } $methodDef = $classRef->getMethod($method); - return $methodDef->getReturnType() ? $methodDef->getReturnType()->getName() : null; + return self::extractNamedReturnType($methodDef->getReturnType()); } public static function isAbstractClass(string $name): bool @@ -215,4 +207,13 @@ class Reflection $lastParam = end($params); return $lastParam->isVariadic() ? $lastParam : null; } + + private static function extractNamedReturnType(?\ReflectionType $returnType): ?string + { + if (!$returnType instanceof \ReflectionNamedType) { + return null; + } + + return $returnType->getName(); + } } From a0c9591e81f7dba2c06a10be88712fd6b997c2e2 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 29 Jun 2026 14:16:07 +0800 Subject: [PATCH 05/37] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E4=BA=A4=E9=9B=86=E7=B1=BB=E5=9E=8B=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在 CompilerBase 中添加 IntersectionType 的引入和处理逻辑 - 更新 upgradeToFullyQualifiedName 方法以处理交集类型 - 修改复杂类型处理逻辑,将交集类型统一按 mixed/var 处理并在运行时进行 typeCheck - 在 Preprocessor 中添加对交集类型的参数和返回值检查支持 - 扩展 TypeCheckGenerator 以支持交集类型的类型检查代码生成 - 添加交集类型参数和返回值的运行时检查测试用例 - 实现交集类型的字符串表示转换功能 - 添加 allOf 类型条件生成器以处理多个类型约束组合 --- phpunit/src/PreprocessorTest.php | 45 +++++ src/Php/CompilerBase.php | 11 +- src/Php/Generator/TypeCheckGenerator.php | 175 ++++++++++++------ src/Php/Preprocessor.php | 5 +- .../type_decl/intersection-param-check.phpt | 34 ++++ .../type_decl/intersection-return-check.phpt | 34 ++++ 6 files changed, 243 insertions(+), 61 deletions(-) create mode 100644 tests/aot/type_decl/intersection-param-check.phpt create mode 100644 tests/aot/type_decl/intersection-return-check.phpt diff --git a/phpunit/src/PreprocessorTest.php b/phpunit/src/PreprocessorTest.php index ff3ddb0d..2f743a98 100644 --- a/phpunit/src/PreprocessorTest.php +++ b/phpunit/src/PreprocessorTest.php @@ -6,6 +6,8 @@ use PHPUnit\Framework\TestCase; use PhpAot\Php\CompilerTest; use PhpAot\Php\ArgInfo; use PhpParser\Node; +use PhpParser\Node\Stmt\Function_; +use PhpParser\ParserFactory; class PreprocessorTest extends TestCase { @@ -57,6 +59,19 @@ class PreprocessorTest extends TestCase $prop->setValue($this->compiler, $value); } + private function parseFunctionNode(string $code): Function_ + { + $parser = (new ParserFactory())->createForHostVersion(); + $stmts = $parser->parse($code); + $this->assertNotNull($stmts); + foreach ($stmts as $stmt) { + if ($stmt instanceof Function_) { + return $stmt; + } + } + $this->fail('No function node found'); + } + // ======================================================================== // genArgumentDeclaration // ======================================================================== @@ -210,4 +225,34 @@ class PreprocessorTest extends TestCase // Empty array stays empty or nearly empty $this->assertIsArray($files); } + + public function testIntersectionParamDeclFallsBackToVarWithRuntimeCheck(): void + { + $fn = $this->parseFunctionNode('invokeMethod('parseFunctionDecl', $fn); + + $this->assertSame('php::Var', $functionDef->argInfoList[0]->type); + $this->assertNotEmpty($functionDef->argInfoList[0]->typeCheck); + $this->assertSame('A&B', $functionDef->argInfoList[0]->typeStr); + } + + public function testIntersectionReturnDeclFallsBackToVarWithRuntimeCheck(): void + { + $fn = $this->parseFunctionNode('invokeMethod('parseFunctionDecl', $fn); + + $this->assertSame('php::Var', $functionDef->returnType); + $this->assertNotEmpty($functionDef->returnTypeCheck); + $this->assertSame('A&B', $functionDef->returnTypeStr); + } + + public function testNullableReturnDeclFallsBackToVarWithRuntimeCheck(): void + { + $fn = $this->parseFunctionNode('invokeMethod('parseFunctionDecl', $fn); + + $this->assertSame('php::Var', $functionDef->returnType); + $this->assertNotEmpty($functionDef->returnTypeCheck); + $this->assertSame('?int', $functionDef->returnTypeStr); + } } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index f9ac543a..86494cc6 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -50,6 +50,7 @@ use PhpParser\Node\Expr; use PhpParser\Node\Expr\CallLike; use PhpParser\Node\Expr\Variable; use PhpParser\Node\FunctionLike; +use PhpParser\Node\IntersectionType; use PhpParser\Node\NullableType; use PhpParser\Node\Scalar\MagicConst; use PhpParser\Node\Stmt\Foreach_; @@ -957,6 +958,12 @@ class CompilerBase extends \PhpAot\Core\Translator } return $type; } + if ($type instanceof Node\IntersectionType) { + foreach ($type->types as $i => $subType) { + $type->types[$i] = $this->upgradeToFullyQualifiedName($subType); + } + return $type; + } if ($type instanceof Node\Name\FullyQualified) { return $type; } @@ -1095,8 +1102,8 @@ class CompilerBase extends \PhpAot\Core\Translator if ($type === null) { return self::TYPE_VAR; } - if ($type instanceof UnionType or $type instanceof NullableType) { - // 联合类型暂时不支持,使用 var 类型代替 + if ($type instanceof UnionType || $type instanceof NullableType || $type instanceof IntersectionType) { + // 复杂类型静态阶段统一按 mixed/var 处理,运行时再由 typeCheck 兜底。 return self::TYPE_VAR; } else { $typeName = $this->parseIdentifier($type); diff --git a/src/Php/Generator/TypeCheckGenerator.php b/src/Php/Generator/TypeCheckGenerator.php index ce7ac739..c8bb9d09 100644 --- a/src/Php/Generator/TypeCheckGenerator.php +++ b/src/Php/Generator/TypeCheckGenerator.php @@ -10,6 +10,7 @@ namespace PhpAot\Php\Generator; use PhpAot\Php\ArgInfo; use PhpParser\Node; +use PhpParser\Node\IntersectionType; use PhpParser\Node\NullableType; use PhpParser\Node\UnionType; use PhpParser\NodeAbstract; @@ -19,81 +20,123 @@ trait TypeCheckGenerator protected function buildTypeCheckFromNode(NodeAbstract $typeNode): array { $check = []; - $names = []; + $typeStr = $this->typeCheckNodeToString($typeNode); if ($typeNode instanceof NullableType) { - $subTypes = [$typeNode->type]; - $isNullable = true; + $check[] = ['kind' => 'isNull']; + $innerClause = $this->buildTypeCheckClause($typeNode->type); + if (!empty($innerClause)) { + $check[] = count($innerClause) === 1 ? $innerClause[0] : ['kind' => 'allOf', 'types' => $innerClause]; + } } elseif ($typeNode instanceof UnionType) { - $subTypes = $typeNode->types; - $isNullable = false; + foreach ($typeNode->types as $subType) { + $clause = $this->buildTypeCheckClause($subType); + if (empty($clause)) { + continue; + } + $check[] = count($clause) === 1 ? $clause[0] : ['kind' => 'allOf', 'types' => $clause]; + } + } elseif ($typeNode instanceof IntersectionType) { + $clause = $this->buildTypeCheckClause($typeNode); + if (!empty($clause)) { + $check[] = count($clause) === 1 ? $clause[0] : ['kind' => 'allOf', 'types' => $clause]; + } } else { return ['check' => [], 'typeStr' => '']; } - foreach ($subTypes as $subType) { - $name = $this->parseIdentifier($subType); - $nameLower = strtolower($name); - - if ($nameLower === 'void' or $nameLower === 'never') { - $this->fatalError($subType, "Type '{$nameLower}' cannot be part of a union type"); - } + if (empty($check)) { + return ['check' => [], 'typeStr' => $typeStr]; + } - if ($nameLower === 'mixed') { - // mixed accepts everything — don't add any check - $names[] = $name; - continue; - } + return ['check' => $check, 'typeStr' => $typeStr]; + } - $entry = match ($nameLower) { - 'int' => ['kind' => 'isInt'], - 'float', 'double' => ['kind' => 'isFloat'], - 'bool' => ['kind' => 'isBool'], - 'string' => ['kind' => 'isString'], - 'array' => ['kind' => 'isArray'], - 'object' => ['kind' => 'isObject'], - 'null' => ['kind' => 'isNull'], - 'true' => ['kind' => 'isTrue'], - 'false' => ['kind' => 'isFalse'], - 'resource' => ['kind' => 'isResource'], - 'callable' => ['kind' => 'callable'], - 'iterable' => ['kind' => 'iterable'], - default => null, - }; - - if ($entry !== null) { - $check[] = $entry; - } else { - // Class/interface type - if ($name === 'self') { - $class = $this->getFullClassName(); - } elseif ($name === 'parent') { - $class = $this->classDef->extends ?? ''; - } elseif ($name === 'static') { - $class = 'static'; - } else { - $class = $this->getNamespacedClassName($name); - } - if ($class) { - $check[] = ['kind' => 'instanceof', 'class' => $class]; + private function buildTypeCheckClause(NodeAbstract $typeNode): array + { + if ($typeNode instanceof IntersectionType) { + $clause = []; + foreach ($typeNode->types as $subType) { + foreach ($this->buildTypeCheckClause($subType) as $entry) { + $clause[] = $entry; } } - $names[] = $name; + return $clause; + } + + $name = $this->parseIdentifier($typeNode); + $nameLower = strtolower($name); + + if ($nameLower === 'void' || $nameLower === 'never') { + $this->fatalError($typeNode, "Type '{$nameLower}' cannot be part of a composite type"); + } + + if ($nameLower === 'mixed') { + return []; } - if ($isNullable) { - // NullableType: prepend null to both check array and typeStr - array_unshift($check, ['kind' => 'isNull']); - $typeStr = '?' . implode('|', $names); + $entry = match ($nameLower) { + 'int' => ['kind' => 'isInt'], + 'float', 'double' => ['kind' => 'isFloat'], + 'bool' => ['kind' => 'isBool'], + 'string' => ['kind' => 'isString'], + 'array' => ['kind' => 'isArray'], + 'object' => ['kind' => 'isObject'], + 'null' => ['kind' => 'isNull'], + 'true' => ['kind' => 'isTrue'], + 'false' => ['kind' => 'isFalse'], + 'resource' => ['kind' => 'isResource'], + 'callable' => ['kind' => 'callable'], + 'iterable' => ['kind' => 'iterable'], + default => null, + }; + + if ($entry !== null) { + return [$entry]; + } + + if ($name === 'self') { + $class = $this->getFullClassName(); + } elseif ($name === 'parent') { + $class = $this->classDef->extends ?? ''; + } elseif ($name === 'static') { + $class = 'static'; } else { - $typeStr = implode('|', $names); + $class = $this->getNamespacedClassName($name); } - if (empty($check)) { - return ['check' => [], 'typeStr' => $typeStr]; + return $class ? [['kind' => 'instanceof', 'class' => $class]] : []; + } + + private function typeCheckNodeToString(NodeAbstract $typeNode): string + { + if ($typeNode instanceof Node\Identifier) { + return $typeNode->name; + } + if ($typeNode instanceof Node\Name) { + return $typeNode->toString(); + } + if ($typeNode instanceof NullableType) { + return '?' . $this->typeCheckNodeToString($typeNode->type); + } + if ($typeNode instanceof UnionType) { + $parts = []; + foreach ($typeNode->types as $type) { + $parts[] = $this->typeCheckNodeToString($type); + } + sort($parts); + return implode('|', $parts); + } + if ($typeNode instanceof IntersectionType) { + $parts = []; + foreach ($typeNode->types as $type) { + $parts[] = $this->typeCheckNodeToString($type); + } + sort($parts); + return implode('&', $parts); } - return ['check' => $check, 'typeStr' => $typeStr]; + return $this->printer->prettyPrint([$typeNode]); } protected function genSingleTypeCondition(string $varName, array $entry): string @@ -112,6 +155,7 @@ trait TypeCheckGenerator 'isResource' => $v . '.isResource()', 'callable' => $v . '.isCallable()', 'iterable' => '(' . $v . '.isArray() || (' . $v . '.isObject() && php::instanceOf(' . $v . ', zend_ce_traversable)))', + 'allOf' => $this->genAllOfTypeCondition($varName, $entry['types']), 'instanceof' => $entry['class'] === 'static' ? '(' . $v . '.isObject() && php::instanceOf(' . $v . ', php_get_called_ce(this_)))' : '(' . $v . '.isObject() && php::instanceOf(' . $v . ', ' . $this->getClassEntryPtr($entry['class']) . '))', @@ -119,6 +163,23 @@ trait TypeCheckGenerator }; } + private function genAllOfTypeCondition(string $varName, array $types): string + { + $conditions = []; + foreach ($types as $type) { + $cond = $this->genSingleTypeCondition($varName, $type); + if ($cond !== '') { + $conditions[] = $cond; + } + } + + if (empty($conditions)) { + return ''; + } + + return '(' . implode(' && ', $conditions) . ')'; + } + protected function genUnionParamCheck(ArgInfo $argInfo, int $argIndex): string { if (empty($argInfo->typeCheck)) { diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 8120abae..c9bc6693 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -19,6 +19,7 @@ use PhpAot\Php\Entity\PropertyDef; use PhpAot\Php\Exception\SyntaxError; use PhpParser\Modifiers; use PhpParser\Node; +use PhpParser\Node\IntersectionType; use PhpParser\Node\NullableType; use PhpParser\Node\UnionType; use PhpParser\NodeAbstract; @@ -284,7 +285,7 @@ class Preprocessor extends CompilerBase if ($param->type === null || $param->type instanceof NullableType) { $argInfo->nullable = true; } - if ($param->type instanceof NullableType or $param->type instanceof UnionType) { + if ($param->type instanceof NullableType || $param->type instanceof UnionType || $param->type instanceof IntersectionType) { $typeInfo = $this->buildTypeCheckFromNode($param->type); if (!empty($typeInfo['check'])) { $argInfo->typeCheck = $typeInfo['check']; @@ -360,7 +361,7 @@ class Preprocessor extends CompilerBase $functionDef->stub = $this->stubFile; $functionDef->returnTypeUndeclared = $v->returnType === null; - if ($v->returnType instanceof NullableType or $v->returnType instanceof UnionType) { + if ($v->returnType instanceof NullableType || $v->returnType instanceof UnionType || $v->returnType instanceof IntersectionType) { $typeInfo = $this->buildTypeCheckFromNode($v->returnType); if (!empty($typeInfo['check'])) { $functionDef->returnTypeCheck = $typeInfo['check']; diff --git a/tests/aot/type_decl/intersection-param-check.phpt b/tests/aot/type_decl/intersection-param-check.phpt new file mode 100644 index 00000000..ad052f9f --- /dev/null +++ b/tests/aot/type_decl/intersection-param-check.phpt @@ -0,0 +1,34 @@ +--TEST-- +Intersection type: parameter runtime type checking +--FILE-- +getMessage(); + } + + foreach ($errors as $err) { + var_dump($err); + } +} +?> +--EXPECT-- +string(4) "Both" +string(71) "expect_both(): Argument #1 ($value) must be of type IA&IB, object given" diff --git a/tests/aot/type_decl/intersection-return-check.phpt b/tests/aot/type_decl/intersection-return-check.phpt new file mode 100644 index 00000000..dca68c9d --- /dev/null +++ b/tests/aot/type_decl/intersection-return-check.phpt @@ -0,0 +1,34 @@ +--TEST-- +Intersection type: return runtime type checking +--FILE-- +getMessage(); + } + + foreach ($errors as $err) { + var_dump($err); + } +} +?> +--EXPECT-- +string(4) "Both" +string(63) "return_both(): Return value must be of type IA&IB, object given" From 409c0959f476e1ede7b68884cc8ea3650d0befac Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 29 Jun 2026 14:41:16 +0800 Subject: [PATCH 06/37] =?UTF-8?q?feat(type-check):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=AF=B9=E8=81=94=E5=90=88=E7=B1=BB=E5=9E=8B=E5=92=8C=E4=BA=A4?= =?UTF-8?q?=E9=9B=86=E7=B1=BB=E5=9E=8B=E7=9A=84=E8=87=AA=E6=88=91=E7=88=B6?= =?UTF-8?q?=E9=9D=99=E6=80=81=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E6=94=AF?= =?UTF-8?q?=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现 self 类型作为联合类型成员的功能测试 - 实现 parent 类型作为联合类型成员的功能测试 - 添加 self 类型不能作为交集类型成员的错误检查 - 添加 parent 类型不能作为交集类型成员的错误检查 - 添加 static 类型不能作为交集类型成员的错误检查 - 重构类型检查可调用名称生成逻辑以支持类方法上下文 - 修复函数命名空间名称获取在类方法中的问题 --- phpunit/src/ClassTest.php | 39 ++++++++++++++++++++++++ src/Php/Generator/TypeCheckGenerator.php | 19 ++++++++++-- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/phpunit/src/ClassTest.php b/phpunit/src/ClassTest.php index b74146c2..9332bf01 100644 --- a/phpunit/src/ClassTest.php +++ b/phpunit/src/ClassTest.php @@ -26,4 +26,43 @@ class ClassTest extends \BaseTest { $this->exec('Cannot override private method `Base::doWork()`', 'override-private-method.php'); } + + public function testSelfCanBePartOfUnionType() + { + global $translator; + $compiler = \PhpAot\Php\CompilerTest::create(ROOT_PATH); + $translator = $compiler; + $testFile = __DIR__ . '/../code/union_type_self_allowed.php'; + $compiler->addFiles([$testFile]); + $compiler->prepareFile($testFile); + $compiler->convertFile($testFile); + $this->addToAssertionCount(1); + } + + public function testParentCanBePartOfUnionType() + { + global $translator; + $compiler = \PhpAot\Php\CompilerTest::create(ROOT_PATH); + $translator = $compiler; + $testFile = __DIR__ . '/../code/union_type_parent_allowed.php'; + $compiler->addFiles([$testFile]); + $compiler->prepareFile($testFile); + $compiler->convertFile($testFile); + $this->addToAssertionCount(1); + } + + public function testSelfCannotBePartOfIntersectionType() + { + $this->exec("Type 'self' cannot be part of an intersection type", 'intersection_type_self_not_allowed.php'); + } + + public function testParentCannotBePartOfIntersectionType() + { + $this->exec("Type 'parent' cannot be part of an intersection type", 'intersection_type_parent_not_allowed.php'); + } + + public function testStaticCannotBePartOfIntersectionType() + { + $this->exec("Type 'static' cannot be part of an intersection type", 'intersection_type_static_not_allowed.php'); + } } diff --git a/src/Php/Generator/TypeCheckGenerator.php b/src/Php/Generator/TypeCheckGenerator.php index c8bb9d09..eb706d49 100644 --- a/src/Php/Generator/TypeCheckGenerator.php +++ b/src/Php/Generator/TypeCheckGenerator.php @@ -37,6 +37,12 @@ trait TypeCheckGenerator $check[] = count($clause) === 1 ? $clause[0] : ['kind' => 'allOf', 'types' => $clause]; } } elseif ($typeNode instanceof IntersectionType) { + foreach ($typeNode->types as $subType) { + $nameLower = strtolower($this->parseIdentifier($subType)); + if ($nameLower === 'self' || $nameLower === 'parent' || $nameLower === 'static') { + $this->fatalError($subType, "Type '{$nameLower}' cannot be part of an intersection type"); + } + } $clause = $this->buildTypeCheckClause($typeNode); if (!empty($clause)) { $check[] = count($clause) === 1 ? $clause[0] : ['kind' => 'allOf', 'types' => $clause]; @@ -180,6 +186,15 @@ trait TypeCheckGenerator return '(' . implode(' && ', $conditions) . ')'; } + protected function getTypeCheckCallableName(): string + { + if ($this->classDef) { + return $this->classDef->getNamespacedName(false) . '::' . $this->functionDef->name; + } + + return $this->functionDef->getNamespacedName(); + } + protected function genUnionParamCheck(ArgInfo $argInfo, int $argIndex): string { if (empty($argInfo->typeCheck)) { @@ -251,7 +266,7 @@ trait TypeCheckGenerator protected function genUnionParamTypeErrorExpr(ArgInfo $argInfo, string $valueExpr, string $argNoExpr): string { - $fnName = $this->functionDef->getNamespacedName(); + $fnName = $this->getTypeCheckCallableName(); return 'php::concat({' . 'php::Str(' . $this->genCharPtr($fnName . '(): Argument #', true) . '), ' . 'php::toString(' . $argNoExpr . '), ' @@ -282,7 +297,7 @@ trait TypeCheckGenerator } $orExpr = implode(' || ', $conditions); - $fnName = $this->functionDef->getNamespacedName(); + $fnName = $this->getTypeCheckCallableName(); $typeStr = $this->functionDef->returnTypeStr; $msgExpr = 'php::concat(php::concat(php::Str(' . $this->genCharPtr($fnName, true) . ' "(): Return value must be of type " ' From 4632a8bba4d2117a51d4eb82fc2c6b8f4e2d73e4 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 29 Jun 2026 14:55:13 +0800 Subject: [PATCH 07/37] =?UTF-8?q?feat(compiler):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E9=A1=B9=E7=9B=AE=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E8=A7=A3?= =?UTF-8?q?=E6=9E=90=E5=92=8C=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了 project.yml 配置文件解析支持 include-paths、defines、lto 等选项 - 添加了命令行参数与配置文件选项的合并逻辑 - 增强了类型检查错误消息中的可调用名称显示 - 添加了多个测试用例验证配置文件解析和类型检查行为 - 实现了 PHP 代码中父类方法重写和联合类型的功能测试 --- .../code/class-method-override-namespace.php | 32 +++++++++ .../inheritance_error_visibility_narrow.php | 12 ++++ .../inheritance_optional_param_allowed.php | 12 ++++ .../intersection_type_parent_not_allowed.php | 16 +++++ .../intersection_type_self_not_allowed.php | 12 ++++ .../intersection_type_static_not_allowed.php | 15 ++++ phpunit/code/union_type_parent_allowed.php | 12 ++++ phpunit/code/union_type_self_allowed.php | 8 +++ phpunit/src/CompilerBaseApiTest.php | 71 +++++++++++++++++++ phpunit/src/TypeCheckGeneratorTest.php | 70 ++++++++++++++++++ src/Php/CompilerBase.php | 2 +- src/Php/Translator.php | 63 ++++++++++++++-- 12 files changed, 320 insertions(+), 5 deletions(-) create mode 100644 phpunit/code/class-method-override-namespace.php create mode 100644 phpunit/code/inheritance_error_visibility_narrow.php create mode 100644 phpunit/code/inheritance_optional_param_allowed.php create mode 100644 phpunit/code/intersection_type_parent_not_allowed.php create mode 100644 phpunit/code/intersection_type_self_not_allowed.php create mode 100644 phpunit/code/intersection_type_static_not_allowed.php create mode 100644 phpunit/code/union_type_parent_allowed.php create mode 100644 phpunit/code/union_type_self_allowed.php create mode 100644 phpunit/src/TypeCheckGeneratorTest.php diff --git a/phpunit/code/class-method-override-namespace.php b/phpunit/code/class-method-override-namespace.php new file mode 100644 index 00000000..4b70736e --- /dev/null +++ b/phpunit/code/class-method-override-namespace.php @@ -0,0 +1,32 @@ +bar(); + } + + public function bar(): void + { + echo "Parent\n"; + } + } +} + +namespace { + function main(): void + { + $o = new Demo\Dispatch\ChildOverrideNs(); + $o->run(); + } +} diff --git a/phpunit/code/inheritance_error_visibility_narrow.php b/phpunit/code/inheritance_error_visibility_narrow.php new file mode 100644 index 00000000..449a1a71 --- /dev/null +++ b/phpunit/code/inheritance_error_visibility_narrow.php @@ -0,0 +1,12 @@ +originalArgv = $argv ?? []; $this->testDir = sys_get_temp_dir() . '/compiler_api_test_' . uniqid(); mkdir($this->testDir, 0777, true); $this->compiler = CompilerTest::create($this->testDir); @@ -24,6 +27,8 @@ class CompilerBaseApiTest extends TestCase protected function tearDown(): void { parent::tearDown(); + global $argv; + $argv = $this->originalArgv; // Recursively remove the test directory (compiler creates build/ subdir) $this->removeDirectory($this->testDir); } @@ -62,6 +67,17 @@ class CompilerBaseApiTest extends TestCase return $m->invoke($this->compiler, ...$args); } + private function createProjectFile(string $yaml): string + { + $sourceFile = $this->testDir . '/main.php'; + file_put_contents($sourceFile, "testDir . '/project.yml'; + file_put_contents($projectFile, $yaml); + + return $projectFile; + } + // ======================================================================== // getTypeFromZendType // ======================================================================== @@ -145,6 +161,61 @@ class CompilerBaseApiTest extends TestCase $this->assertEquals($buildDir . '/include', $includeDir); } + public function testParseProjectYamlLoadsDocumentedCompilerOptions(): void + { + $projectFile = $this->createProjectFile(<<<'YAML' +sources: + - main.php +include-paths: + - /opt/mylib/include + - ../shared/headers +defines: + - ENABLE_LOGGING=1 + - DEBUG_LEVEL=3 +lto: true +link-libs: + - curl + - ssl +link-paths: + - /usr/local/lib + - /opt/custom/lib +YAML); + + $this->invokeMethod('parseProjectYaml', $projectFile); + + $this->assertSame(['/opt/mylib/include', '../shared/headers'], $this->compiler->getUserIncludePaths()); + $this->assertSame(['ENABLE_LOGGING=1', 'DEBUG_LEVEL=3'], $this->compiler->getUserDefines()); + $this->assertTrue($this->compiler->isLtoEnabled()); + $this->assertSame(['curl', 'ssl'], $this->compiler->getLinkLibs()); + $this->assertSame(['/usr/local/lib', '/opt/custom/lib'], $this->compiler->getLinkPaths()); + } + + public function testApplyCommandLineArgumentsDoesNotClearYamlRepeatableOptionsWhenCliAbsent(): void + { + $projectFile = $this->createProjectFile(<<<'YAML' +sources: + - main.php +include-paths: + - /yaml/include +defines: + - YAML_DEFINE=1 +lto: true +link-libs: + - yamlssl +link-paths: + - /yaml/lib +YAML); + + $this->invokeMethod('parseProjectYaml', $projectFile); + $this->invokeMethod('applyCommandLineArguments'); + + $this->assertSame(['/yaml/include'], $this->compiler->getUserIncludePaths()); + $this->assertSame(['YAML_DEFINE=1'], $this->compiler->getUserDefines()); + $this->assertTrue($this->compiler->isLtoEnabled()); + $this->assertSame(['yamlssl'], $this->compiler->getLinkLibs()); + $this->assertSame(['/yaml/lib'], $this->compiler->getLinkPaths()); + } + // ======================================================================== // isWindows / isLinux / isMacos // ======================================================================== diff --git a/phpunit/src/TypeCheckGeneratorTest.php b/phpunit/src/TypeCheckGeneratorTest.php new file mode 100644 index 00000000..6934bf57 --- /dev/null +++ b/phpunit/src/TypeCheckGeneratorTest.php @@ -0,0 +1,70 @@ +setAccessible(true); + $ref->setValue($object, $value); + } + + private function invokeMethod(object $object, string $method, array $args = []): mixed + { + $ref = new ReflectionMethod($object, $method); + $ref->setAccessible(true); + return $ref->invokeArgs($object, $args); + } + + public function testMethodTypeCheckErrorUsesClassQualifiedCallableName(): void + { + $compiler = CompilerTest::create(ROOT_PATH); + $classDef = new ClassDef('Demo', 0, 'Foo\\Bar'); + $functionDef = new FunctionDef('run', 'php::Var', 'Foo\\Bar'); + $argInfo = new ArgInfo(); + $argInfo->name = 'value'; + $argInfo->typeStr = 'int|string'; + + $functionDef->returnTypeCheck = [['kind' => 'isInt'], ['kind' => 'isString']]; + $functionDef->returnTypeStr = 'int|string'; + + $this->setProtectedProperty($compiler, 'classDef', $classDef); + $this->setProtectedProperty($compiler, 'functionDef', $functionDef); + + $callableName = $this->invokeMethod($compiler, 'getTypeCheckCallableName'); + $paramExpr = $this->invokeMethod($compiler, 'genUnionParamTypeErrorExpr', [$argInfo, 'value', '1']); + $returnCode = $this->invokeMethod($compiler, 'genUnionReturnCheck', ['retval']); + + $this->assertSame('Foo\\Bar\\Demo::run', $callableName); + $this->assertStringContainsString('Foo\\\\Bar\\\\Demo::run(): Argument #', $paramExpr); + $this->assertStringContainsString('Foo\\\\Bar\\\\Demo::run', $returnCode); + } + + public function testFunctionTypeCheckErrorUsesFunctionQualifiedCallableName(): void + { + $compiler = CompilerTest::create(ROOT_PATH); + $functionDef = new FunctionDef('run', 'php::Var', 'Foo\\Bar'); + $argInfo = new ArgInfo(); + $argInfo->name = 'value'; + $argInfo->typeStr = 'int|string'; + + $functionDef->returnTypeCheck = [['kind' => 'isInt'], ['kind' => 'isString']]; + $functionDef->returnTypeStr = 'int|string'; + + $this->setProtectedProperty($compiler, 'classDef', null); + $this->setProtectedProperty($compiler, 'functionDef', $functionDef); + + $callableName = $this->invokeMethod($compiler, 'getTypeCheckCallableName'); + $paramExpr = $this->invokeMethod($compiler, 'genUnionParamTypeErrorExpr', [$argInfo, 'value', '1']); + $returnCode = $this->invokeMethod($compiler, 'genUnionReturnCheck', ['retval']); + + $this->assertSame('Foo\\Bar\\run', $callableName); + $this->assertStringContainsString('Foo\\\\Bar\\\\run(): Argument #', $paramExpr); + $this->assertStringContainsString('Foo\\\\Bar\\\\run', $returnCode); + } +} diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 86494cc6..36ca49de 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -3647,7 +3647,7 @@ class CompilerBase extends \PhpAot\Core\Translator return '-' . $code; } - protected function parseUnaryPlus(Expr\UnaryPlus $expr) + protected function parseUnaryPlus(Expr\UnaryPlus $expr): string { return $this->parseExpr($expr->expr); } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 12e701f6..7f3dae2b 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -339,9 +339,13 @@ class Translator extends Preprocessor } // 用户自定义 C++ include 路径(直接从 argv 解析以支持多值) - $this->userIncludePaths = $this->parseRepeatableArgv(['-I', '--include-path']); + if ($this->hasRepeatableArgvFlag(['-I', '--include-path'])) { + $this->userIncludePaths = $this->parseRepeatableArgv(['-I', '--include-path']); + } // 用户自定义预处理器宏(直接从 argv 解析以支持多值) - $this->userDefines = $this->parseRepeatableArgv(['-D', '--define']); + if ($this->hasRepeatableArgvFlag(['-D', '--define'])) { + $this->userDefines = $this->parseRepeatableArgv(['-D', '--define']); + } // 链接时优化 if ($this->climate->arguments->defined('lto')) { @@ -359,9 +363,13 @@ class Translator extends Preprocessor } // 用户自定义链接库(直接从 argv 解析以支持多值) - $this->linkLibs = $this->parseRepeatableArgv(['-l', '--link-lib']); + if ($this->hasRepeatableArgvFlag(['-l', '--link-lib'])) { + $this->linkLibs = $this->parseRepeatableArgv(['-l', '--link-lib']); + } // 用户自定义库搜索路径(直接从 argv 解析以支持多值) - $this->linkPaths = $this->parseRepeatableArgv(['-L', '--link-path']); + if ($this->hasRepeatableArgvFlag(['-L', '--link-path'])) { + $this->linkPaths = $this->parseRepeatableArgv(['-L', '--link-path']); + } } /** @@ -397,6 +405,32 @@ class Translator extends Preprocessor return $values; } + protected function hasRepeatableArgvFlag(array $flags): bool + { + global $argv; + + for ($i = 1; $i < count($argv); $i++) { + $arg = $argv[$i]; + if (in_array($arg, $flags, true)) { + return true; + } + + foreach ($flags as $flag) { + if (str_starts_with($arg, $flag . '=')) { + return true; + } + if (strlen($flag) === 2 && $flag[0] === '-') { + $short = substr($flag, 1); + if (preg_match('/^-' . preg_quote($short, '/') . '(.+)$/', $arg)) { + return true; + } + } + } + } + + return false; + } + /** * 处理 --flag=value 格式的长标志 */ @@ -1967,6 +2001,27 @@ CODE; } } + // 读取 include-paths + $includePaths = $cfg['include-paths'] ?? null; + if (!empty($includePaths) && is_array($includePaths)) { + foreach ($includePaths as $includePath) { + $this->userIncludePaths[] = (string) $includePath; + } + } + + // 读取 defines + $defines = $cfg['defines'] ?? null; + if (!empty($defines) && is_array($defines)) { + foreach ($defines as $define) { + $this->userDefines[] = (string) $define; + } + } + + // 读取 lto + if (!empty($cfg['lto'])) { + $this->enableLto = true; + } + // 读取 link-libs $linkLibs = $cfg['link-libs'] ?? null; if (!empty($linkLibs) && is_array($linkLibs)) { From 47d11655efed3e807f6d0796bf06a3b662514643 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Mon, 29 Jun 2026 18:40:49 +0800 Subject: [PATCH 08/37] =?UTF-8?q?fix(backend):=20=E4=BF=AE=E5=A4=8D?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E9=80=89=E9=A1=B9=E4=B8=AD=E7=9A=84=E5=AE=89?= =?UTF-8?q?=E5=85=A8=E5=AE=9A=E4=B9=89=E8=BD=AC=E4=B9=89=E5=92=8C=E8=B7=AF?= =?UTF-8?q?=E5=BE=84=E5=A4=84=E7=90=86=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 为MSVC和GCC编译器添加unsafe defines的安全转义测试 - 实现formatDefineFlag方法统一处理宏定义转义逻辑 - 添加临时目录管理功能用于测试清理 - 重构共享编译选项构建逻辑到buildSharedCompileFlags方法 - 修复response file参数转义问题解决路径空格问题 - 更新clang-format命令执行时的路径转义 - 改进项目配置文件解析支持多种配置选项 - 添加对YAML配置文件自定义名称和相对路径的支持 - 实现代码格式化功能的可用性检查机制 - 修复默认formatCode选项设置为false的问题 --- phpunit/src/Backend/BackendOptionsTest.php | 30 ++++ phpunit/src/Backend/BackendTest.php | 105 ++++++++++++ phpunit/src/CompilerBaseApiTest.php | 122 +++++++++++++- src/Php/Backend/CompilerBackend.php | 11 +- src/Php/Backend/GccLikeBackend.php | 154 ++++++++---------- src/Php/Backend/Msvc.php | 178 +++++++++------------ src/Php/CompilerBase.php | 2 +- src/Php/Translator.php | 128 ++++++++++++--- 8 files changed, 509 insertions(+), 221 deletions(-) diff --git a/phpunit/src/Backend/BackendOptionsTest.php b/phpunit/src/Backend/BackendOptionsTest.php index e30fff17..91f0eac0 100644 --- a/phpunit/src/Backend/BackendOptionsTest.php +++ b/phpunit/src/Backend/BackendOptionsTest.php @@ -121,6 +121,21 @@ class BackendOptionsTest extends TestCase $this->assertStringContainsString('/DPPROF_ON=1', $options); } + public function testMsvcCompileOptionsEscapesUnsafeDefines(): void + { + $platform = new Windows(); + $compiler = new Msvc($platform); + + $options = $compiler->buildCompileOptions([ + 'enable_profiler' => true, + 'prof_output' => 'profile output.log', + 'user_defines' => ['APP_NAME="hello world"'], + ]); + + $this->assertStringContainsString('/D' . escapeshellarg('APP_NAME="hello world"'), $options); + $this->assertStringContainsString('/D' . escapeshellarg('PROF_OUTPUT_FILE="profile output.log"'), $options); + } + /** * 测试 MSVC 编译选项 - 自定义标志 */ @@ -276,6 +291,21 @@ class BackendOptionsTest extends TestCase $this->assertStringContainsString('-fPIC', $options); } + public function testGccCompileOptionsEscapesUnsafeDefines(): void + { + $platform = new Linux(); + $compiler = new Gcc($platform); + + $options = $compiler->buildCompileOptions([ + 'enable_profiler' => true, + 'prof_output' => 'profile output.log', + 'user_defines' => ['APP_NAME="hello world"'], + ]); + + $this->assertStringContainsString('-D' . escapeshellarg('APP_NAME="hello world"'), $options); + $this->assertStringContainsString('-D' . escapeshellarg('PROF_OUTPUT_FILE="profile output.log"'), $options); + } + /** * 测试 GCC 链接选项 - 基本配置 */ diff --git a/phpunit/src/Backend/BackendTest.php b/phpunit/src/Backend/BackendTest.php index e35f7bdf..9316f0e5 100644 --- a/phpunit/src/Backend/BackendTest.php +++ b/phpunit/src/Backend/BackendTest.php @@ -13,6 +13,39 @@ use PhpAot\Php\Backend\CompilerFactory; class BackendTest extends TestCase { + private array $temporaryDirectories = []; + + protected function tearDown(): void + { + parent::tearDown(); + foreach ($this->temporaryDirectories as $dir) { + $this->removeDirectory($dir); + } + $this->temporaryDirectories = []; + } + + private function createTemporaryDirectory(string $prefix): string + { + $dir = sys_get_temp_dir() . '/' . $prefix . '_' . uniqid(); + mkdir($dir, 0777, true); + $this->temporaryDirectories[] = $dir; + return $dir; + } + + private function removeDirectory(string $dir): void + { + if (!is_dir($dir)) { + return; + } + + $files = array_diff(scandir($dir), ['.', '..']); + foreach ($files as $file) { + $path = $dir . DIRECTORY_SEPARATOR . $file; + is_dir($path) ? $this->removeDirectory($path) : unlink($path); + } + rmdir($dir); + } + /** * 测试 MSVC 编译器基本信息 */ @@ -103,6 +136,31 @@ class BackendTest extends TestCase $this->assertStringContainsString('/nologo', $cmd); } + public function testMsvcBuildCCompileCommandKeepsSharedCompilerOptions(): void + { + $platform = new Windows([], true); + $compiler = new Msvc($platform); + + $cmd = $compiler->buildCCompileCommand('misc.c', 'misc.obj', [ + 'sanitize' => 'address', + 'enable_profiler' => true, + 'prof_output' => 'app.prof', + 'user_defines' => ['FEATURE_X=1'], + 'lto' => true, + 'is_zts' => true, + ]); + + $this->assertStringContainsString('/TC', $cmd); + $this->assertStringContainsString('/fsanitize=address', $cmd); + $this->assertStringContainsString('/DPPROF_ON=1', $cmd); + $this->assertStringContainsString('/DPROF_OUTPUT_FILE=', $cmd); + $this->assertStringContainsString('/DFEATURE_X=1', $cmd); + $this->assertStringContainsString('/GL', $cmd); + $this->assertStringContainsString('/DZTS', $cmd); + $this->assertStringNotContainsString('/EHsc', $cmd); + $this->assertStringNotContainsString('/std:', $cmd); + } + /** * 测试 MSVC 完整链接命令 */ @@ -250,6 +308,32 @@ class BackendTest extends TestCase $this->assertStringContainsString('-fno-rtti', $cmd); } + public function testGccBuildCCompileCommandKeepsSharedCompilerOptions(): void + { + $platform = new Linux(); + $compiler = new Gcc($platform); + + $cmd = $compiler->buildCCompileCommand('misc.c', 'misc.o', [ + 'sanitize' => 'address', + 'enable_profiler' => true, + 'prof_output' => 'app.prof', + 'user_defines' => ['FEATURE_X=1'], + 'lto' => true, + 'march' => 'native', + 'target_platform' => 'aarch64-linux-gnu', + 'build_mode' => 'ext', + ]); + + $this->assertStringContainsString('-fsanitize=address', $cmd); + $this->assertStringContainsString('-DPPROF_ON=1', $cmd); + $this->assertStringContainsString('-DPROF_OUTPUT_FILE=', $cmd); + $this->assertStringContainsString('-DFEATURE_X=1', $cmd); + $this->assertStringContainsString('-flto', $cmd); + $this->assertStringContainsString('-march=native', $cmd); + $this->assertStringContainsString('--target=aarch64-linux-gnu', $cmd); + $this->assertStringContainsString('-fPIC', $cmd); + } + public function testGccBuildLinkCommandIncludesPlatformPathsOptionsAndLibraries(): void { $platform = new Linux(); @@ -270,6 +354,27 @@ class BackendTest extends TestCase $this->assertStringContainsString('-lphp', $cmd); } + public function testResponseFileArgumentIsEscapedForPathsWithSpaces(): void + { + $platform = new Linux(); + $compiler = new Gcc($platform, 'g++'); + $dir = $this->createTemporaryDirectory('backend link path'); + $target = $dir . '/my app'; + $rspFile = $target . '.rsp'; + $objectWithSpace = $dir . '/object one.o'; + $objectWithoutSpace = $dir . '/object_two.o'; + + $cmd = $compiler->buildLinkCommand([$objectWithSpace, $objectWithoutSpace], $target); + + $this->assertStringContainsString(escapeshellarg('@' . $rspFile), $cmd); + $this->assertStringContainsString('-o ' . escapeshellarg($target), $cmd); + $this->assertFileExists($rspFile); + + $lines = file($rspFile, FILE_IGNORE_NEW_LINES); + $this->assertSame('"' . $objectWithSpace . '"', $lines[0]); + $this->assertSame('"' . $objectWithoutSpace . '"', $lines[1]); + } + /** * 测试 GCC 完整编译选项 */ diff --git a/phpunit/src/CompilerBaseApiTest.php b/phpunit/src/CompilerBaseApiTest.php index a732b4f4..e7df6af8 100644 --- a/phpunit/src/CompilerBaseApiTest.php +++ b/phpunit/src/CompilerBaseApiTest.php @@ -12,12 +12,14 @@ class CompilerBaseApiTest extends TestCase private CompilerTest $compiler; private \ReflectionClass $ref; private array $originalArgv; + private string|false $originalPath; protected function setUp(): void { parent::setUp(); global $argv; $this->originalArgv = $argv ?? []; + $this->originalPath = getenv('PATH'); $this->testDir = sys_get_temp_dir() . '/compiler_api_test_' . uniqid(); mkdir($this->testDir, 0777, true); $this->compiler = CompilerTest::create($this->testDir); @@ -29,6 +31,11 @@ class CompilerBaseApiTest extends TestCase parent::tearDown(); global $argv; $argv = $this->originalArgv; + if ($this->originalPath === false) { + putenv('PATH'); + } else { + putenv('PATH=' . $this->originalPath); + } // Recursively remove the test directory (compiler creates build/ subdir) $this->removeDirectory($this->testDir); } @@ -67,17 +74,29 @@ class CompilerBaseApiTest extends TestCase return $m->invoke($this->compiler, ...$args); } - private function createProjectFile(string $yaml): string + private function createProjectFile(string $yaml, string $filename = 'project.yml', string $baseDir = ''): string { - $sourceFile = $this->testDir . '/main.php'; + $projectDir = $baseDir === '' ? $this->testDir : $this->testDir . '/' . trim($baseDir, '/'); + if (!is_dir($projectDir)) { + mkdir($projectDir, 0777, true); + } + + $sourceFile = $projectDir . '/main.php'; file_put_contents($sourceFile, "testDir . '/project.yml'; + $projectFile = $projectDir . '/' . $filename; file_put_contents($projectFile, $yaml); return $projectFile; } + private function createFakeClangFormat(string $binDir, string $logFile): void + { + mkdir($binDir, 0777, true); + file_put_contents($binDir . '/clang-format', "#!/bin/sh\nif [ \"$1\" = \"--version\" ]; then\n echo 'clang-format version test'\n exit 0\nfi\npwd > " . escapeshellarg($logFile) . "\nprintf '%s\\n' \"$@\" >> " . escapeshellarg($logFile) . "\n"); + chmod($binDir . '/clang-format', 0755); + } + // ======================================================================== // getTypeFromZendType // ======================================================================== @@ -154,6 +173,11 @@ class CompilerBaseApiTest extends TestCase $this->assertStringStartsWith($this->testDir, $buildDir); } + public function testFormatCodeDisabledByDefault(): void + { + $this->assertFalse($this->getPropertyValue('formatCode')); + } + public function testGetIncludeDir(): void { $includeDir = $this->compiler->getIncludeDir(); @@ -163,9 +187,24 @@ class CompilerBaseApiTest extends TestCase public function testParseProjectYamlLoadsDocumentedCompilerOptions(): void { + $binDir = $this->testDir . '/bin'; + $formatLog = $this->testDir . '/format.log'; + $this->createFakeClangFormat($binDir, $formatLog); + putenv('PATH=' . $binDir . ':' . ($this->originalPath ?: '')); + $projectFile = $this->createProjectFile(<<<'YAML' sources: - main.php +optimize: 2 +job: 8 +debug: true +profile: true +no-progress: true +no-console: true +no-literal-strings: true +sanitize: address +target-platform: aarch64-linux-gnu +build-dir: /tmp/project-build include-paths: - /opt/mylib/include - ../shared/headers @@ -173,6 +212,7 @@ defines: - ENABLE_LOGGING=1 - DEBUG_LEVEL=3 lto: true +format: true link-libs: - curl - ssl @@ -183,11 +223,56 @@ YAML); $this->invokeMethod('parseProjectYaml', $projectFile); + $this->assertSame(2, $this->getPropertyValue('optimizeLevel')); + $this->assertSame(8, $this->getPropertyValue('maxJob')); + $this->assertTrue($this->getPropertyValue('debug')); + $this->assertTrue($this->getPropertyValue('enableProfiler')); + $this->assertTrue($this->getPropertyValue('noProgress')); + $this->assertTrue($this->getPropertyValue('noConsole')); + $this->assertTrue($this->getPropertyValue('noLiteralStrings')); + $this->assertSame('address', $this->getPropertyValue('sanitize')); + $this->assertSame('aarch64-linux-gnu', $this->getPropertyValue('targetPlatform')); $this->assertSame(['/opt/mylib/include', '../shared/headers'], $this->compiler->getUserIncludePaths()); $this->assertSame(['ENABLE_LOGGING=1', 'DEBUG_LEVEL=3'], $this->compiler->getUserDefines()); $this->assertTrue($this->compiler->isLtoEnabled()); $this->assertSame(['curl', 'ssl'], $this->compiler->getLinkLibs()); $this->assertSame(['/usr/local/lib', '/opt/custom/lib'], $this->compiler->getLinkPaths()); + $this->assertSame('/tmp/project-build', $this->compiler->getBuildDir()); + $this->assertTrue($this->getPropertyValue('formatCode')); + } + + public function testParseProjectYamlSupportsCustomFilenameAndRelativeBuildDir(): void + { + $projectFile = $this->createProjectFile(<<<'YAML' +sources: + - main.php +build-dir: build/output +YAML, 'myproject.yml', 'nested/config'); + + $this->invokeMethod('parseProjectYaml', $projectFile); + + $this->assertSame( + realpath($this->testDir . '/nested/config/build/output'), + $this->compiler->getBuildDir() + ); + } + + public function testParseProjectYamlSupportsCliStyleModeAndOutputAliases(): void + { + $projectFile = $this->createProjectFile(<<<'YAML' +sources: + - main.php +mode: ext +output: out/custom-ext +dry: true +YAML, 'custom-name.yml', 'yaml-alias'); + + $this->invokeMethod('parseProjectYaml', $projectFile); + + $this->assertSame(CompilerBase::BUILD_MODE_EXT, $this->getPropertyValue('buildMode')); + $this->assertTrue($this->getPropertyValue('dryRun')); + $this->assertSame('custom_ext', $this->getPropertyValue('targetName')); + $this->assertSame('out', $this->getPropertyValue('outputDir')); } public function testApplyCommandLineArgumentsDoesNotClearYamlRepeatableOptionsWhenCliAbsent(): void @@ -216,6 +301,37 @@ YAML); $this->assertSame(['/yaml/lib'], $this->compiler->getLinkPaths()); } + public function testFormatCppCodeEscapesPathsWithSpaces(): void + { + $spaceDir = sys_get_temp_dir() . '/compiler api format ' . uniqid(); + mkdir($spaceDir, 0777, true); + $binDir = $spaceDir . '/bin'; + $logFile = $spaceDir . '/format.log'; + $sourceFile = $spaceDir . '/hello world.cc'; + + file_put_contents($sourceFile, "int main() { return 0; }\n"); + $this->createFakeClangFormat($binDir, $logFile); + putenv('PATH=' . $binDir . ':' . ($this->originalPath ?: '')); + + $compiler = CompilerTest::create($spaceDir); + $ref = new \ReflectionClass($compiler); + $formatProp = $ref->getProperty('formatCode'); + $formatProp->setAccessible(true); + $formatProp->setValue($compiler, true); + + $method = $ref->getMethod('formatCppCode'); + $method->setAccessible(true); + $method->invoke($compiler, $sourceFile); + + $this->assertFileExists($logFile); + $lines = file($logFile, FILE_IGNORE_NEW_LINES); + $this->assertSame($spaceDir, $lines[0]); + $this->assertSame('-i', $lines[1]); + $this->assertSame($sourceFile, $lines[2]); + + $this->removeDirectory($spaceDir); + } + // ======================================================================== // isWindows / isLinux / isMacos // ======================================================================== diff --git a/src/Php/Backend/CompilerBackend.php b/src/Php/Backend/CompilerBackend.php index 23bcb466..a206749c 100644 --- a/src/Php/Backend/CompilerBackend.php +++ b/src/Php/Backend/CompilerBackend.php @@ -158,6 +158,15 @@ abstract class CompilerBackend return $this->platform->getLibraryFlags($libraries); } + protected function formatDefineFlag(string $define, string $prefix): string + { + if (preg_match('/^[A-Za-z_][A-Za-z0-9_]*(=(?:[A-Za-z0-9_.,:+\/@%-]+))?$/', $define) === 1) { + return $prefix . $define; + } + + return $prefix . escapeshellarg($define); + } + /** * 将目标文件列表写入 Response File,避免命令行参数过长超出 OS 限制(Windows 8191 字符) * @@ -178,7 +187,7 @@ abstract class CompilerBackend $lines[] = $file; } file_put_contents($rspFile, implode("\n", $lines)); - return '@' . $rspFile; + return escapeshellarg('@' . $rspFile); } /** diff --git a/src/Php/Backend/GccLikeBackend.php b/src/Php/Backend/GccLikeBackend.php index c31cf242..790d7e74 100644 --- a/src/Php/Backend/GccLikeBackend.php +++ b/src/Php/Backend/GccLikeBackend.php @@ -59,6 +59,63 @@ abstract class GccLikeBackend extends CompilerBackend return ''; } + /** 构建 GCC/Clang 共享编译选项,C 和 C++ 编译路径都复用这里 */ + protected function buildSharedCompileFlags(array $config, bool $includeCppStd = false): string + { + $cmd = ''; + + if (!empty($config['sanitize'])) { + $cmd .= ' ' . $this->formatSanitizerFlag($config['sanitize']); + } + + if (!empty($config['debug'])) { + $cmd .= ' -O0 -g'; + } else { + $optimizeLevel = $config['optimize'] ?? 2; + $cmd .= ' -O' . $optimizeLevel; + } + + $cmd .= ' -Wall'; + + if ($includeCppStd && !empty($config['cpp_std'])) { + $cmd .= ' -std=' . $config['cpp_std']; + } + + if (!empty($config['march'])) { + $cmd .= ' -march=' . $config['march']; + } + + if (!empty($config['target_platform'])) { + $cmd .= ' --target=' . $config['target_platform']; + } + + $cmd .= $this->getPICFlag($config); + + if (!empty($config['enable_profiler'])) { + $cmd .= ' ' . $this->formatDefineFlag('PPROF_ON=1', '-D'); + if (!empty($config['prof_output'])) { + $profOutput = addcslashes($config['prof_output'], "\\\""); + $cmd .= ' ' . $this->formatDefineFlag('PROF_OUTPUT_FILE="' . $profOutput . '"', '-D'); + } + } + + if ($includeCppStd && !empty($config['cxxflags'])) { + $cmd .= ' ' . $config['cxxflags']; + } + + if (!empty($config['user_defines'])) { + foreach ($config['user_defines'] as $define) { + $cmd .= ' ' . $this->formatDefineFlag($define, '-D'); + } + } + + if (!empty($config['lto'])) { + $cmd .= ' -flto'; + } + + return $cmd; + } + /** 获取平台特定的链接选项 */ protected function getPlatformLinkFlags(array $config): string { @@ -116,7 +173,7 @@ abstract class GccLikeBackend extends CompilerBackend } foreach ($defines as $define) { - $cmd .= ' -D' . $define; + $cmd .= ' ' . $this->formatDefineFlag($define, '-D'); } if (!empty($flags)) { @@ -181,15 +238,7 @@ abstract class GccLikeBackend extends CompilerBackend if (!empty($options['include_paths'])) { $cmd .= ' ' . $this->formatIncludePaths($options['include_paths']); } - - $optimizeLevel = $options['optimize'] ?? 0; - if (!empty($options['debug'])) { - $cmd .= ' -O0 -g'; - } else { - $cmd .= ' -O' . $optimizeLevel; - } - - $cmd .= ' -Wall'; + $cmd .= $this->buildSharedCompileFlags($options, false); return $cmd; } @@ -239,58 +288,8 @@ abstract class GccLikeBackend extends CompilerBackend public function buildCompileOptions(array $config = []): string { - $cmd = ''; - - $cmd .= $this->getCompilerPrefixFlags(); - - if (!empty($config['sanitize'])) { - $cmd .= ' ' . $this->formatSanitizerFlag($config['sanitize']); - } - - if (!empty($config['debug'])) { - $cmd .= ' -O0 -g'; - } else { - $optimizeLevel = $config['optimize'] ?? 2; - $cmd .= ' -O' . $optimizeLevel; - } - - $cmd .= ' -Wall'; - - if (!empty($config['cpp_std'])) { - $cmd .= ' -std=' . $config['cpp_std']; - } - - if (!empty($config['march'])) { - $cmd .= ' -march=' . $config['march']; - } - - if (!empty($config['target_platform'])) { - $cmd .= ' --target=' . $config['target_platform']; - } - - $cmd .= $this->getPICFlag($config); - - if (!empty($config['enable_profiler'])) { - $cmd .= ' -DPPROF_ON=1'; - if (!empty($config['prof_output'])) { - $cmd .= ' -DPROF_OUTPUT_FILE=\'"' . $config['prof_output'] . '"\''; - } - } - - if (!empty($config['cxxflags'])) { - $cmd .= ' ' . $config['cxxflags']; - } - - if (!empty($config['user_defines'])) { - foreach ($config['user_defines'] as $define) { - $cmd .= ' -D' . $define; - } - } - - if (!empty($config['lto'])) { - $cmd .= ' -flto'; - } - + $cmd = $this->getCompilerPrefixFlags(); + $cmd .= $this->buildSharedCompileFlags($config, true); return $cmd; } @@ -317,35 +316,8 @@ abstract class GccLikeBackend extends CompilerBackend public function buildFullCompileOptions(array $options = []): string { - $cmd = ''; - - $cmd .= $this->getCompilerPrefixFlags(); - - if (!empty($options['debug'])) { - $cmd .= ' -O0 -g'; - } else { - $optimizeLevel = $options['optimize'] ?? 2; - $cmd .= ' -O' . $optimizeLevel; - } - - $cmd .= ' -Wall'; - - if (!empty($options['cpp_std'])) { - $cmd .= ' -std=' . $options['cpp_std']; - } - - if (!empty($options['march'])) { - $cmd .= ' -march=' . $options['march']; - } - - if (!empty($options['sanitize'])) { - $cmd .= ' ' . $this->formatSanitizerFlag($options['sanitize']); - } - - if (!empty($options['pic'])) { - $cmd .= ' -fPIC'; - } - + $cmd = $this->getCompilerPrefixFlags(); + $cmd .= $this->buildSharedCompileFlags($options, true); return $cmd; } diff --git a/src/Php/Backend/Msvc.php b/src/Php/Backend/Msvc.php index 817632a5..9256d68e 100644 --- a/src/Php/Backend/Msvc.php +++ b/src/Php/Backend/Msvc.php @@ -34,6 +34,75 @@ class Msvc extends CompilerBackend return $this->linkerCommand; } + private function buildCommonCompileFlags(array $config, bool $includeCppOptions = true): string + { + $cmd = ''; + + $cmd .= ' /DZEND_WIN32 /DPHP_WIN32 /DZEND_DEBUG=0'; + + if (!empty($config['is_zts'])) { + $cmd .= ' /DZTS'; + } + + if (!empty($config['sanitize'])) { + if ($config['sanitize'] === 'address' || $config['sanitize'] === 'addr') { + $cmd .= ' /fsanitize=address'; + } + } + + if (!empty($config['debug'])) { + $cmd .= ' /Od /Zi'; + } else { + $optimizeLevel = $config['optimize'] ?? 2; + $optMap = [0 => '/Od', 1 => '/O1', 2 => '/O2', 3 => '/Ox']; + $cmd .= ' ' . ($optMap[$optimizeLevel] ?? '/O2'); + } + + $cmd .= ' /W3'; + + if (!empty($config['suppressed_warnings'])) { + foreach ($config['suppressed_warnings'] as $code => $description) { + $code = is_int($code) && $code < 100 ? $description : $code; + $cmd .= " /wd{$code}"; + } + } + + if (!empty($config['enable_profiler'])) { + $cmd .= ' ' . $this->formatDefineFlag('PPROF_ON=1', '/D'); + if (!empty($config['prof_output'])) { + $profOutput = addcslashes($config['prof_output'], "\\\""); + $cmd .= ' ' . $this->formatDefineFlag('PROF_OUTPUT_FILE="' . $profOutput . '"', '/D'); + } + } + + if (!empty($config['user_defines'])) { + foreach ($config['user_defines'] as $define) { + $cmd .= ' ' . $this->formatDefineFlag($define, '/D'); + } + } + + if (!empty($config['lto'])) { + $cmd .= ' /GL'; + } + + if ($includeCppOptions) { + $cmd .= ' /EHsc'; + if (!empty($config['cpp_std'])) { + $cmd .= ' /std:' . $config['cpp_std']; + } + + $cmd .= ' /MD'; + + if (!empty($config['cxxflags'])) { + $cmd .= ' ' . $config['cxxflags']; + } + } + + $cmd .= ' /nologo'; + + return $cmd; + } + public function compileFile( string $sourceFile, string $outputFile, @@ -52,7 +121,7 @@ class Msvc extends CompilerBackend // 添加宏定义 foreach ($defines as $define) { - $cmd .= ' /D' . $define; + $cmd .= ' ' . $this->formatDefineFlag($define, '/D'); } // 添加额外标志 @@ -129,29 +198,7 @@ class Msvc extends CompilerBackend } // 平台宏定义 - $cmd .= ' /DZEND_WIN32 /DPHP_WIN32 /DZEND_DEBUG=0'; - - // ZTS 支持 - if ($this->platform instanceof Windows && $this->platform->isZts()) { - $cmd .= ' /DZTS'; - } - - // 优化级别(C 文件通常使用较低的优化) - $optimizeLevel = $options['optimize'] ?? 0; - $optMap = [0 => '/Od', 1 => '/O1', 2 => '/O2', 3 => '/Ox']; - $cmd .= ' ' . ($optMap[$optimizeLevel] ?? '/O2'); - - // 警告级别 - $cmd .= ' /W3'; - - // 禁用常见警告 - $suppressedWarnings = $options['suppressed_warnings'] ?? ['4244', '4146']; - foreach ($suppressedWarnings as $code) { - $cmd .= " /wd{$code}"; - } - - // nologo - $cmd .= ' /nologo'; + $cmd .= $this->buildCommonCompileFlags($options, false); // 注意:C 文件不使用 /EHsc, /std:c++17, /MD 等 C++ 特定选项 @@ -220,7 +267,7 @@ class Msvc extends CompilerBackend // 宏定义 foreach ($defines as $define) { - $cmd .= ' /D' . $define; + $cmd .= ' ' . $this->formatDefineFlag($define, '/D'); } // 编译选项 @@ -322,86 +369,7 @@ class Msvc extends CompilerBackend */ public function buildCompileOptions(array $config = []): string { - $cmd = ''; - - // 平台宏定义 - $cmd .= ' /DZEND_WIN32 /DPHP_WIN32 /DZEND_DEBUG=0'; - - // ZTS - if (!empty($config['is_zts'])) { - $cmd .= ' /DZTS'; - } - - // Sanitizer - if (!empty($config['sanitize'])) { - if ($config['sanitize'] === 'address' || $config['sanitize'] === 'addr') { - $cmd .= ' /fsanitize=address'; - } - } - - // 优化和调试 - if (!empty($config['debug'])) { - $cmd .= ' /Od /Zi'; - } else { - $optimizeLevel = $config['optimize'] ?? 2; - $optMap = [0 => '/Od', 1 => '/O1', 2 => '/O2', 3 => '/Ox']; - $cmd .= ' ' . ($optMap[$optimizeLevel] ?? '/O2'); - } - - // 警告 - $cmd .= ' /W3'; - - // 禁用常见警告(只使用键,即警告代码) - if (!empty($config['suppressed_warnings'])) { - foreach ($config['suppressed_warnings'] as $code => $description) { - $code = is_int($code) && $code < 100 ? $description : $code; - $cmd .= " /wd{$code}"; - } - } - - // C++ 选项 - $cmd .= ' /EHsc'; - if (!empty($config['cpp_std'])) { - $cmd .= ' /std:' . $config['cpp_std']; - } - - // 扩展模块选项 - if (!empty($config['build_mode']) && $config['build_mode'] === 'ext') { - // MSVC 不需要 -fPIC,默认就是位置无关代码 - } - - // CRT - $cmd .= ' /MD'; - - // nologo - $cmd .= ' /nologo'; - - // 性能分析宏 - if (!empty($config['enable_profiler'])) { - $cmd .= ' /DPPROF_ON=1'; - if (!empty($config['prof_output'])) { - $cmd .= ' /DPROF_OUTPUT_FILE=\'"' . $config['prof_output'] . '"\''; - } - } - - // 用户自定义编译标志 - if (!empty($config['cxxflags'])) { - $cmd .= ' ' . $config['cxxflags']; - } - - // 用户自定义预处理器宏 - if (!empty($config['user_defines'])) { - foreach ($config['user_defines'] as $define) { - $cmd .= ' /D' . $define; - } - } - - // LTO(全程序优化 /GL + 链接时代码生成 /LTCG) - if (!empty($config['lto'])) { - $cmd .= ' /GL'; - } - - return $cmd; + return $this->buildCommonCompileFlags($config, true); } /** diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 36ca49de..cda52ff0 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -251,7 +251,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected array $linkPaths = []; // --link-path / -L: user-specified library search paths protected int $floatPrecision = 17; protected bool $debug = false; - protected bool $formatCode = true; // --format: enable clang-format (disabled by default) + protected bool $formatCode = false; // --format: enable clang-format (disabled by default) protected bool $printBacktraceOnError = true; protected bool $noLiteralStrings = false; protected bool $noConsole = false; // Windows: hide console window diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 7f3dae2b..98bc550a 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -206,11 +206,11 @@ class Translator extends Preprocessor $cmd = $argv[0]; $climate->bold('USAGE:'); - $climate->tab()->out($cmd . ' [options]'); + $climate->tab()->out($cmd . ' [options]'); $climate->br(); $climate->bold('ARGUMENTS:'); - $climate->tab()->out(' Input PHP file/directory/project.yml to compile'); + $climate->tab()->out(' Input PHP file/directory/YAML config to compile'); $climate->br(); $climate->bold('EXAMPLES:'); @@ -354,12 +354,7 @@ class Translator extends Preprocessor // clang-format 代码格式化(默认关闭,需显式 --format 开启) if ($this->climate->arguments->defined('format')) { - $clangFormatVersion = shell_exec('clang-format --version'); - if (!empty($clangFormatVersion)) { - $this->formatCode = true; - } else { - $this->climate->warning('--format requested but clang-format not found, skipping formatting'); - } + $this->enableCodeFormattingIfAvailable('--format'); } // 用户自定义链接库(直接从 argv 解析以支持多值) @@ -450,13 +445,24 @@ class Translator extends Preprocessor $this->climate->bold()->out(self::APP_NAME . ' v' . self::VERSION); } + private function enableCodeFormattingIfAvailable(string $source): void + { + $clangFormatVersion = shell_exec('clang-format --version'); + if (!empty($clangFormatVersion)) { + $this->formatCode = true; + return; + } + + $this->climate->warning($source . ' requested but clang-format not found, skipping formatting'); + } + protected function formatCppCode(string $file): void { if (!$this->formatCode) { return; } - $cmd = 'cd ' . $this->rootPath . ' && clang-format -i ' . $file; + $cmd = 'cd ' . escapeshellarg($this->rootPath) . ' && clang-format -i ' . escapeshellarg($file); $this->climate->info('format: ' . $this->getRelativePath($file)); $this->climate->comment($cmd); shell_exec($cmd); @@ -1513,7 +1519,14 @@ CODE; 'include_paths' => $this->getIncludePaths(), 'optimize' => 0, 'debug' => $this->debug, + 'sanitize' => $this->sanitize, 'is_zts' => $this->isPhpZts, + 'enable_profiler' => $this->enableProfiler, + 'prof_output' => $this->targetName . '.prof', + 'user_defines' => $this->userDefines, + 'lto' => $this->enableLto, + 'march' => $this->march, + 'target_platform' => $this->targetPlatform, 'suppressed_warnings' => ['4244', '4146'], ]; } @@ -1927,17 +1940,33 @@ CODE; } protected function getAbsolutePath(string $path, string $projectDir): string + { + $absPath = $this->resolvePath($path, $projectDir, 'Source path'); + return realpath($absPath); + } + + protected function resolvePath(string $path, string $baseDir, string $label = 'Path'): string { $path = trim($path); if ($path === '') { - $this->error('Source path must not be empty'); + $this->error($label . ' must not be empty'); } - if ($path[0] !== '/') { - $absPath = $projectDir . '/' . $path; - } else { - $absPath = $path; + + if ($this->isAbsolutePath($path)) { + return $path; } - return realpath($absPath); + + return $baseDir . '/' . $path; + } + + protected function isAbsolutePath(string $path): bool + { + return $path !== '' + && ( + $path[0] === '/' + || $path[0] === '\\' + || preg_match('/^[A-Za-z]:[\\\\\\/]/', $path) === 1 + ); } protected function parseProjectYaml(string $path): array @@ -1969,6 +1998,43 @@ CODE; $list = $this->getFilesFromDir($projectDir); } + if (array_key_exists('optimize', $cfg)) { + $this->optimizeLevel = (int) $cfg['optimize']; + } + + if (array_key_exists('job', $cfg)) { + $this->maxJob = (int) $cfg['job']; + } + + if (!empty($cfg['debug'])) { + $this->debug = true; + } + + if (!empty($cfg['no-literal-strings'])) { + $this->noLiteralStrings = true; + } + + if (!empty($cfg['profile'])) { + if (!$this->isLinux()) { + $this->climate->error('`profile` in YAML is only supported on Linux (requires gperftools)'); + exit(1); + } + $this->enableProfiler = true; + } + + if (!empty($cfg['no-progress'])) { + $this->noProgress = true; + } + + if (!empty($cfg['no-console'])) { + $this->noConsole = true; + } + + $sanitize = $cfg['sanitize'] ?? null; + if (!empty($sanitize)) { + $this->sanitize = (string) $sanitize; + } + // 读取 cxx-flags $cxxFlags = $cfg['cxx-flags'] ?? null; if (!empty($cxxFlags)) { @@ -1991,6 +2057,22 @@ CODE; $this->march = $march; } + // 读取 target-platform + $targetPlatform = $cfg['target-platform'] ?? null; + if (!empty($targetPlatform)) { + $this->targetPlatform = (string) $targetPlatform; + } + + // 读取 build-dir + $buildDir = $cfg['build-dir'] ?? null; + if (!empty($buildDir)) { + $this->setBuildDir($this->resolvePath((string) $buildDir, $projectDir, 'Build path')); + } + + if (!empty($cfg['dry'])) { + $this->dryRun = true; + } + // 读取 ld-flags $ldflags = $cfg['ld-flags'] ?? null; if (!empty($ldflags)) { @@ -2022,6 +2104,11 @@ CODE; $this->enableLto = true; } + // 读取 format + if (!empty($cfg['format'])) { + $this->enableCodeFormattingIfAvailable('YAML format'); + } + // 读取 link-libs $linkLibs = $cfg['link-libs'] ?? null; if (!empty($linkLibs) && is_array($linkLibs)) { @@ -2038,9 +2125,10 @@ CODE; } } - // 读取 name - if (!empty($cfg['name'])) { - $this->setTargetName($cfg['name']); + // 读取 output/name + $output = $cfg['output'] ?? $cfg['name'] ?? null; + if (!empty($output)) { + $this->setTargetName((string) $output); } // 读取 cpp-compiler @@ -2049,8 +2137,8 @@ CODE; $this->setCppCompiler($cppCompiler); } - // 读取 type/build-mode(支持中横线和下划线) - $buildMode = $cfg['build-mode'] ?? $cfg['type'] ?? null; + // 读取 mode/type/build-mode(支持 CLI/YAML 两套命名) + $buildMode = $cfg['mode'] ?? $cfg['build-mode'] ?? $cfg['type'] ?? null; if (!empty($buildMode)) { // 映射常见的类型名称到内部 buildMode $modeMap = [ From c8372fce04522550c3c5ed4f5dc0e5ea17e4ecfe Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 09:07:42 +0800 Subject: [PATCH 09/37] =?UTF-8?q?refactor(php):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E7=BC=96=E8=AF=91=E5=91=BD=E4=BB=A4=E9=80=89=E9=A1=B9=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 getCompileCommandOptions 方法重命名为 getCommonCompileCommandOptions - 提取公共编译选项到独立方法中避免重复代码 - 优化 C 编译和原生编译选项获取逻辑 - 改进链接命令中的库路径和库列表处理方式 - 更新测试用例以验证编译选项配置的正确性 - 在测试中添加对转义参数的支持验证 --- phpunit/src/Backend/BackendTest.php | 4 +- phpunit/src/CompilerBaseApiTest.php | 69 +++++++++++++++++++++++++++ src/Php/Translator.php | 72 +++++++++++------------------ 3 files changed, 99 insertions(+), 46 deletions(-) diff --git a/phpunit/src/Backend/BackendTest.php b/phpunit/src/Backend/BackendTest.php index 9316f0e5..8427c6c4 100644 --- a/phpunit/src/Backend/BackendTest.php +++ b/phpunit/src/Backend/BackendTest.php @@ -153,7 +153,7 @@ class BackendTest extends TestCase $this->assertStringContainsString('/TC', $cmd); $this->assertStringContainsString('/fsanitize=address', $cmd); $this->assertStringContainsString('/DPPROF_ON=1', $cmd); - $this->assertStringContainsString('/DPROF_OUTPUT_FILE=', $cmd); + $this->assertStringContainsString('/D' . escapeshellarg('PROF_OUTPUT_FILE="app.prof"'), $cmd); $this->assertStringContainsString('/DFEATURE_X=1', $cmd); $this->assertStringContainsString('/GL', $cmd); $this->assertStringContainsString('/DZTS', $cmd); @@ -326,7 +326,7 @@ class BackendTest extends TestCase $this->assertStringContainsString('-fsanitize=address', $cmd); $this->assertStringContainsString('-DPPROF_ON=1', $cmd); - $this->assertStringContainsString('-DPROF_OUTPUT_FILE=', $cmd); + $this->assertStringContainsString('-D' . escapeshellarg('PROF_OUTPUT_FILE="app.prof"'), $cmd); $this->assertStringContainsString('-DFEATURE_X=1', $cmd); $this->assertStringContainsString('-flto', $cmd); $this->assertStringContainsString('-march=native', $cmd); diff --git a/phpunit/src/CompilerBaseApiTest.php b/phpunit/src/CompilerBaseApiTest.php index e7df6af8..080d0078 100644 --- a/phpunit/src/CompilerBaseApiTest.php +++ b/phpunit/src/CompilerBaseApiTest.php @@ -301,6 +301,75 @@ YAML); $this->assertSame(['/yaml/lib'], $this->compiler->getLinkPaths()); } + public function testCCompileCommandOptionsKeepCommonUserConfiguration(): void + { + $this->setPropertyValue('userIncludePaths', ['/user/include']); + $this->setPropertyValue('userDefines', ['FEATURE_X=1']); + $this->setPropertyValue('buildMode', CompilerBase::BUILD_MODE_EXT); + $this->setPropertyValue('enableProfiler', true); + $this->setPropertyValue('enableLto', true); + $this->setPropertyValue('sanitize', 'address'); + $this->setPropertyValue('targetPlatform', 'aarch64-linux-gnu'); + $this->setPropertyValue('march', 'native'); + + $options = $this->invokeMethod('getCCompileCommandOptions'); + + $this->assertContains('/user/include', $options['include_paths']); + $this->assertSame(['FEATURE_X=1'], $options['user_defines']); + $this->assertSame(CompilerBase::BUILD_MODE_EXT, $options['build_mode']); + $this->assertTrue($options['enable_profiler']); + $this->assertTrue($options['lto']); + $this->assertSame('address', $options['sanitize']); + $this->assertSame('aarch64-linux-gnu', $options['target_platform']); + $this->assertSame('native', $options['march']); + } + + public function testNativeCompileCommandOptionsKeepCommonUserConfiguration(): void + { + $this->setPropertyValue('userIncludePaths', ['/native/include']); + $this->setPropertyValue('userDefines', ['NATIVE_FEATURE=1']); + $this->setPropertyValue('buildMode', CompilerBase::BUILD_MODE_EXT); + $this->setPropertyValue('enableProfiler', true); + $this->setPropertyValue('enableLto', true); + + $options = $this->invokeMethod('getNativeCompileCommandOptions', 'objective-c'); + + $this->assertContains('/native/include', $options['include_paths']); + $this->assertSame(['NATIVE_FEATURE=1'], $options['user_defines']); + $this->assertSame(CompilerBase::BUILD_MODE_EXT, $options['build_mode']); + $this->assertTrue($options['enable_profiler']); + $this->assertTrue($options['lto']); + $this->assertArrayNotHasKey('cpp_std', $options); + $this->assertArrayNotHasKey('cxxflags', $options); + } + + public function testObjectiveCppCompileCommandOptionsKeepCppOptions(): void + { + $this->setPropertyValue('cxxStd', 'c++20'); + $this->setPropertyValue('cxxFlags', '-fobjc-arc'); + + $options = $this->invokeMethod('getNativeCompileCommandOptions', 'objective-c++'); + + $this->assertSame('c++20', $options['cpp_std']); + $this->assertSame('-fobjc-arc', $options['cxxflags']); + } + + public function testLinkCommandOptionsPassUserLibrariesThroughBackendFields(): void + { + $this->setPropertyValue('linkLibs', ['curl', 'ssl']); + $this->setPropertyValue('linkPaths', ['/user/lib']); + $this->setPropertyValue('enableProfiler', true); + $this->setPropertyValue('ldflags', '-Wl,--as-needed'); + + $options = $this->invokeMethod('getLinkCommandOptions'); + + $this->assertContains('/user/lib', $options['library_paths']); + $this->assertContains('profiler', $options['libraries']); + $this->assertContains('curl', $options['libraries']); + $this->assertContains('ssl', $options['libraries']); + $this->assertSame('-Wl,--as-needed', $options['ldflags']); + } + public function testFormatCppCodeEscapesPathsWithSpaces(): void { $spaceDir = sys_get_temp_dir() . '/compiler api format ' . uniqid(); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 98bc550a..877a8031 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -1486,7 +1486,7 @@ CODE; } } - protected function getCompileCommandOptions(): array + protected function getCommonCompileCommandOptions(): array { // 包含路径:系统路径 + 用户自定义路径 $includePaths = $this->getIncludePaths(); @@ -1499,36 +1499,31 @@ CODE; 'optimize' => $this->optimizeLevel, 'debug' => $this->debug, 'sanitize' => $this->sanitize, - 'cpp_std' => $this->cxxStd, 'march' => $this->march, 'target_platform' => $this->targetPlatform, 'is_zts' => $this->isPhpZts, 'build_mode' => $this->buildMode, 'enable_profiler' => $this->enableProfiler, 'prof_output' => $this->targetName . '.prof', - 'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [], - 'cxxflags' => $this->cxxFlags, 'user_defines' => $this->userDefines, 'lto' => $this->enableLto, ]; } + protected function getCompileCommandOptions(): array + { + $options = $this->getCommonCompileCommandOptions(); + $options['cpp_std'] = $this->cxxStd; + $options['cxxflags'] = $this->cxxFlags; + $options['suppressed_warnings'] = Constants::MSVC_SUPPRESSED_WARNINGS ?? []; + return $options; + } + protected function getCCompileCommandOptions(): array { - return [ - 'include_paths' => $this->getIncludePaths(), - 'optimize' => 0, - 'debug' => $this->debug, - 'sanitize' => $this->sanitize, - 'is_zts' => $this->isPhpZts, - 'enable_profiler' => $this->enableProfiler, - 'prof_output' => $this->targetName . '.prof', - 'user_defines' => $this->userDefines, - 'lto' => $this->enableLto, - 'march' => $this->march, - 'target_platform' => $this->targetPlatform, - 'suppressed_warnings' => ['4244', '4146'], - ]; + $options = $this->getCommonCompileCommandOptions(); + $options['suppressed_warnings'] = ['4244', '4146']; + return $options; } /** @@ -1538,41 +1533,30 @@ CODE; */ protected function getNativeCompileCommandOptions(string $language = ''): array { - return [ - 'include_paths' => $this->getIncludePaths(), - 'optimize' => $this->optimizeLevel, - 'debug' => $this->debug, - 'sanitize' => $this->sanitize, - 'is_zts' => $this->isPhpZts, - 'build_mode' => $this->buildMode, - 'enable_profiler' => $this->enableProfiler, - 'suppressed_warnings' => Constants::MSVC_SUPPRESSED_WARNINGS ?? [], - 'march' => $this->march, - 'target_platform' => $this->targetPlatform, - ]; + $options = $this->getCommonCompileCommandOptions(); + $options['suppressed_warnings'] = Constants::MSVC_SUPPRESSED_WARNINGS ?? []; + + if ($language === 'objective-c++') { + $options['cpp_std'] = $this->cxxStd; + $options['cxxflags'] = $this->cxxFlags; + } + + return $options; } protected function getLinkCommandOptions(): array { $ldflags = $this->ldflags; - + $libraryPaths = array_merge($this->getLibraryPaths(), $this->linkPaths); + $libraries = $this->getLibraries(); if ($this->enableProfiler) { - $ldflags .= ' -lprofiler'; - } - - // 用户通过 --link-lib / -l 指定的链接库 - foreach ($this->linkLibs as $lib) { - $ldflags .= ' -l' . $lib; - } - - // 用户通过 --link-path / -L 指定的库搜索路径 - foreach ($this->linkPaths as $path) { - $ldflags .= ' -L' . escapeshellarg($path); + $libraries[] = 'profiler'; } + $libraries = array_merge($libraries, $this->linkLibs); $options = [ - 'library_paths' => $this->getLibraryPaths(), - 'libraries' => $this->getLibraries(), + 'library_paths' => $libraryPaths, + 'libraries' => $libraries, 'ldflags' => $ldflags, 'debug' => $this->debug, 'no_console' => $this->noConsole, From 5bbb50b031421d368dd8aea7a1ba77ddaf374fa9 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 09:09:53 +0800 Subject: [PATCH 10/37] =?UTF-8?q?refactor(php):=20=E4=BC=98=E5=8C=96?= =?UTF-8?q?=E8=B7=AF=E5=BE=84=E5=89=8D=E7=BC=80=E7=A7=BB=E9=99=A4=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BB=A5=E6=94=AF=E6=8C=81=E8=B7=AF=E5=BE=84=E6=AE=B5?= =?UTF-8?q?=E5=8C=B9=E9=85=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 PlatformBase.php 中的 removeCommonPrefix 方法 - 使用 rtrim 移除路径分隔符后缀 - 将路径拆分为段进行比较而非逐字符比较 - 使用 implode 重新组合剩余路径段 - 添加新测试用例验证路径段匹配功能 - 修复相邻目录按字符前缀截断的问题 --- phpunit/src/Platform/PlatformTest.php | 9 +++++++++ phpunit/src/PreprocessorTest.php | 9 +++++++++ src/Php/Platform/PlatformBase.php | 10 +++++++--- 3 files changed, 25 insertions(+), 3 deletions(-) diff --git a/phpunit/src/Platform/PlatformTest.php b/phpunit/src/Platform/PlatformTest.php index 35e0ec27..589ad117 100644 --- a/phpunit/src/Platform/PlatformTest.php +++ b/phpunit/src/Platform/PlatformTest.php @@ -110,6 +110,15 @@ class PlatformTest extends TestCase $this->assertSame('src/app.php', $linux->removeCommonPrefix('/project', '/project/src/app.php')); } + public function testPlatformPathPrefixRemovalUsesPathSegments(): void + { + $windows = new Windows(); + $linux = new Linux(); + + $this->assertSame('project2\src\app.php', $windows->removeCommonPrefix('C:\project', 'C:/project2/src/app.php')); + $this->assertSame('project2/src/app.php', $linux->removeCommonPrefix('/tmp/project', '/tmp/project2/src/app.php')); + } + /** * 测试 Windows 子系统选项 */ diff --git a/phpunit/src/PreprocessorTest.php b/phpunit/src/PreprocessorTest.php index 2f743a98..3e1f1bc2 100644 --- a/phpunit/src/PreprocessorTest.php +++ b/phpunit/src/PreprocessorTest.php @@ -135,6 +135,15 @@ class PreprocessorTest extends TestCase $this->assertStringStartsWith($this->compiler->getBuildDir(), $result); } + public function testGetCppFileDoesNotTrimSiblingDirectoryByCharacterPrefix(): void + { + $this->setProperty('buildDir', '/tmp/project/build'); + + $result = $this->compiler->getCppFile('/tmp/project2/src/app.php'); + + $this->assertSame('/tmp/project/build/project2/src/app.cc', $result); + } + public function testGetCppFileDotPhpReplaced(): void { $phpFile = '/tmp/test_file.php'; diff --git a/src/Php/Platform/PlatformBase.php b/src/Php/Platform/PlatformBase.php index 272ca47d..fc4e2da6 100644 --- a/src/Php/Platform/PlatformBase.php +++ b/src/Php/Platform/PlatformBase.php @@ -154,18 +154,22 @@ abstract class PlatformBase $long = str_replace('/', '\\', $long); } - $len = min(strlen($short), strlen($long)); + $short = rtrim($short, $separator); + $long = rtrim($long, $separator); + $shortParts = explode($separator, $short); + $longParts = explode($separator, $long); $prefixLen = 0; + $len = min(count($shortParts), count($longParts)); for ($i = 0; $i < $len; $i++) { - if ($short[$i] === $long[$i]) { + if ($shortParts[$i] === $longParts[$i]) { $prefixLen++; } else { break; } } - return ltrim(substr($long, $prefixLen), $separator); + return implode($separator, array_slice($longParts, $prefixLen)); } /** From 1ad6b54a495cf37c9741926b3b47334d88b5fe60 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 09:20:58 +0800 Subject: [PATCH 11/37] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E9=85=8D=E7=BD=AE=E4=B8=AD=E7=9A=84=E8=B7=AF=E5=BE=84?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=92=8C=E6=96=87=E4=BB=B6=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复 YAML 配置中 include-paths、link-paths 和 output 的相对路径解析 - 实现忽略文件过滤功能,过滤被 ignore 规则匹配的源文件 - 修复命令行参数 output 对目标名称设置的影响 - 添加单元测试验证相对路径选项相对于 YAML 目录的解析 - 添加测试验证 CLI 参数覆盖 YAML 配置的行为 - 添加测试验证 YAML 配置中忽略文件的过滤逻辑 --- phpunit/src/CompilerBaseApiTest.php | 78 ++++++++++++++++++++++++++++- src/Php/Translator.php | 56 +++++++++++++-------- 2 files changed, 110 insertions(+), 24 deletions(-) diff --git a/phpunit/src/CompilerBaseApiTest.php b/phpunit/src/CompilerBaseApiTest.php index 080d0078..ddcaa871 100644 --- a/phpunit/src/CompilerBaseApiTest.php +++ b/phpunit/src/CompilerBaseApiTest.php @@ -232,7 +232,7 @@ YAML); $this->assertTrue($this->getPropertyValue('noLiteralStrings')); $this->assertSame('address', $this->getPropertyValue('sanitize')); $this->assertSame('aarch64-linux-gnu', $this->getPropertyValue('targetPlatform')); - $this->assertSame(['/opt/mylib/include', '../shared/headers'], $this->compiler->getUserIncludePaths()); + $this->assertSame(['/opt/mylib/include', dirname($projectFile) . '/../shared/headers'], $this->compiler->getUserIncludePaths()); $this->assertSame(['ENABLE_LOGGING=1', 'DEBUG_LEVEL=3'], $this->compiler->getUserDefines()); $this->assertTrue($this->compiler->isLtoEnabled()); $this->assertSame(['curl', 'ssl'], $this->compiler->getLinkLibs()); @@ -272,7 +272,58 @@ YAML, 'custom-name.yml', 'yaml-alias'); $this->assertSame(CompilerBase::BUILD_MODE_EXT, $this->getPropertyValue('buildMode')); $this->assertTrue($this->getPropertyValue('dryRun')); $this->assertSame('custom_ext', $this->getPropertyValue('targetName')); - $this->assertSame('out', $this->getPropertyValue('outputDir')); + $this->assertSame(dirname($projectFile) . '/out', $this->getPropertyValue('outputDir')); + } + + public function testParseProjectYamlResolvesRelativePathOptionsAgainstYamlDirectory(): void + { + $projectFile = $this->createProjectFile(<<<'YAML' +sources: + - main.php +include-paths: + - includes +link-paths: + - libs +output: bin/my-app +YAML, 'myproject.yml', 'nested/config'); + + $this->invokeMethod('parseProjectYaml', $projectFile); + + $projectDir = dirname($projectFile); + $this->assertSame([$projectDir . '/includes'], $this->compiler->getUserIncludePaths()); + $this->assertSame([$projectDir . '/libs'], $this->compiler->getLinkPaths()); + $this->assertSame($projectDir . '/bin', $this->getPropertyValue('outputDir')); + $this->assertSame('my_app', $this->getPropertyValue('targetName')); + } + + public function testCliOutputOverridesYamlOutputOnlyWhenCommandLineArgumentsAreApplied(): void + { + global $argv; + $argv = ['compiler.php', '--output', 'cli/out-file']; + $compiler = CompilerTest::create($this->testDir); + $ref = new \ReflectionClass($compiler); + $parseMethod = $ref->getMethod('parseProjectYaml'); + $parseMethod->setAccessible(true); + $applyMethod = $ref->getMethod('applyCommandLineArguments'); + $applyMethod->setAccessible(true); + $targetProp = $ref->getProperty('targetName'); + $targetProp->setAccessible(true); + $outputProp = $ref->getProperty('outputDir'); + $outputProp->setAccessible(true); + + $projectFile = $this->createProjectFile(<<<'YAML' +sources: + - main.php +output: yaml/out-file +YAML, 'myproject.yml', 'cli-output'); + + $parseMethod->invoke($compiler, $projectFile); + $this->assertSame(dirname($projectFile) . '/yaml', $outputProp->getValue($compiler)); + $this->assertSame('out_file', $targetProp->getValue($compiler)); + + $applyMethod->invoke($compiler); + $this->assertSame('cli', $outputProp->getValue($compiler)); + $this->assertSame('out_file', $targetProp->getValue($compiler)); } public function testApplyCommandLineArgumentsDoesNotClearYamlRepeatableOptionsWhenCliAbsent(): void @@ -301,6 +352,29 @@ YAML); $this->assertSame(['/yaml/lib'], $this->compiler->getLinkPaths()); } + public function testParseProjectYamlFiltersIgnoredFilesFromReturnedSources(): void + { + $projectFile = $this->createProjectFile(<<<'YAML' +sources: + - . +ignore: + - ignored.php + - skipped +YAML); + $projectDir = dirname($projectFile); + mkdir($projectDir . '/skipped', 0777, true); + file_put_contents($projectDir . '/ignored.php', "invokeMethod('parseProjectYaml', $projectFile); + + $this->assertContains(realpath($projectDir . '/main.php'), $files); + $this->assertContains(realpath($projectDir . '/kept.php'), $files); + $this->assertNotContains(realpath($projectDir . '/ignored.php'), $files); + $this->assertNotContains(realpath($projectDir . '/skipped/nested.php'), $files); + } + public function testCCompileCommandOptionsKeepCommonUserConfiguration(): void { $this->setPropertyValue('userIncludePaths', ['/user/include']); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 877a8031..dc5401cc 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -325,6 +325,11 @@ class Translator extends Preprocessor $this->targetPlatform = $this->climate->arguments->get('target-platform'); } + // 输出文件名/路径 + if ($this->climate->arguments->defined('output')) { + $this->setTargetName($this->climate->arguments->get('output')); + } + // 构建目录 if ($this->climate->arguments->defined('build-dir')) { $buildDir = $this->climate->arguments->get('build-dir'); @@ -546,9 +551,6 @@ class Translator extends Preprocessor public function setTargetName(string $name): void { - if ($this->climate->arguments->defined('output')) { - $name = $this->climate->arguments->get('output'); - } // 如果指定了路径(包含目录分隔符),提取目录和文件名 if (str_contains($name, '/') || str_contains($name, '\\')) { $this->outputDir = dirname($name); @@ -609,7 +611,7 @@ class Translator extends Preprocessor // 在所有配置加载完成后,应用命令行参数(确保优先级最高) $this->applyCommandLineArguments(); - return $list; + return $this->filterIgnoredFiles($list); } public function prepare(string $path): array @@ -627,20 +629,7 @@ class Translator extends Preprocessor } $files = $this->getFiles($path); - // 应用 ignorePaths 过滤 - if (!empty($this->ignorePaths)) { - $files = array_filter($files, function ($file) { - foreach ($this->ignorePaths as $ignorePath) { - if ($file === $ignorePath) { - return false; - } - if (is_dir($ignorePath) && str_starts_with($file, $ignorePath . DIRECTORY_SEPARATOR)) { - return false; - } - } - return true; - }); - } + $files = $this->filterIgnoredFiles($files); // 分析 PHP 文件,预处理 foreach ($files as $k => $file) { if (FileScanner::isPhpFile($file)) { @@ -659,6 +648,29 @@ class Translator extends Preprocessor return $files; } + protected function shouldIgnoreFile(string $file): bool + { + foreach ($this->ignorePaths as $ignorePath) { + if ($file === $ignorePath) { + return true; + } + if (is_dir($ignorePath) && str_starts_with($file, rtrim($ignorePath, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR)) { + return true; + } + } + + return false; + } + + protected function filterIgnoredFiles(array $files): array + { + if (empty($this->ignorePaths)) { + return $files; + } + + return array_values(array_filter($files, fn(string $file): bool => !$this->shouldIgnoreFile($file))); + } + public function convert(array $files): array { $sourceFiles = []; @@ -2071,7 +2083,7 @@ CODE; $includePaths = $cfg['include-paths'] ?? null; if (!empty($includePaths) && is_array($includePaths)) { foreach ($includePaths as $includePath) { - $this->userIncludePaths[] = (string) $includePath; + $this->userIncludePaths[] = $this->resolvePath((string) $includePath, $projectDir, 'Include path'); } } @@ -2105,14 +2117,14 @@ CODE; $linkPaths = $cfg['link-paths'] ?? null; if (!empty($linkPaths) && is_array($linkPaths)) { foreach ($linkPaths as $linkPath) { - $this->linkPaths[] = (string)$linkPath; + $this->linkPaths[] = $this->resolvePath((string) $linkPath, $projectDir, 'Link path'); } } // 读取 output/name $output = $cfg['output'] ?? $cfg['name'] ?? null; if (!empty($output)) { - $this->setTargetName((string) $output); + $this->setTargetName($this->resolvePath((string) $output, $projectDir, 'Output path')); } // 读取 cpp-compiler @@ -2175,7 +2187,7 @@ CODE; $this->resourceConfig['_projectDir'] = $projectDir; } - return $list; + return $this->filterIgnoredFiles($list); } protected function getInternalCeInfo(string $ce): array From 3ca0d64a6a6c11380dd245ee31fa8bce70b0784a Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 09:57:00 +0800 Subject: [PATCH 12/37] =?UTF-8?q?feat(preprocessor):=20=E5=A2=9E=E5=BC=BAP?= =?UTF-8?q?HP=E9=A2=84=E5=A4=84=E7=90=86=E5=99=A8=E5=8A=9F=E8=83=BD?= =?UTF-8?q?=E6=94=AF=E6=8C=81=E6=8E=A5=E5=8F=A3=E6=88=90=E5=91=98=E5=92=8C?= =?UTF-8?q?=E5=B8=B8=E9=87=8F=E8=A7=A3=E6=9E=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现接口方法、常量和继承列表的解析与存储 - 添加对抽象方法签名的完整解析支持 - 增加命名空间常量的解析和类型推断功能 - 实现接口实现验证和方法签名匹配检查 - 支持多重接口继承关系的解析处理 - 添加重复定义(类、接口、常量、方法)的检测机制 - 实现trait别名和修饰符的正确解析 - 增强依赖排序算法支持接口和trait依赖关系 - 完善方法重写签名验证逻辑 - 添加接口方法由trait提供的情况处理 --- phpunit/code/compiler_api/hello_world.cc | 1 + phpunit/code/compiler_api/ignored.php | 2 + phpunit/code/compiler_api/kept.php | 2 + phpunit/code/compiler_api/main.php | 2 + phpunit/code/compiler_api/skipped_nested.php | 2 + phpunit/code/interface_method_from_trait.php | 20 +++ phpunit/code/interface_method_missing.php | 11 ++ .../interface_method_signature_mismatch.php | 15 ++ .../abstract_method_signature.php | 4 + phpunit/code/preprocessor/class_constants.php | 4 + .../preprocessor/deps_class_implements.php | 2 + .../preprocessor/deps_class_uses_trait.php | 4 + phpunit/code/preprocessor/deps_interface.php | 2 + phpunit/code/preprocessor/deps_trait.php | 2 + .../duplicate_abstract_method.php | 5 + .../preprocessor/duplicate_class_constant.php | 5 + .../duplicate_namespaced_class_interface.php | 4 + .../code/preprocessor/interface_members.php | 7 + .../code/preprocessor/namespaced_const.php | 3 + .../preprocessor/trait_alias_modifier.php | 10 ++ phpunit/src/CompilerBaseApiTest.php | 15 +- phpunit/src/Entity/InterfaceDefTest.php | 19 +++ phpunit/src/InheritanceErrorTest.php | 15 ++ phpunit/src/PreprocessorTest.php | 136 ++++++++++++++++++ src/Php/CompilerBase.php | 26 +++- src/Php/Entity/ClassDef.php | 14 +- src/Php/Entity/InterfaceDef.php | 30 ++++ src/Php/Preprocessor.php | 104 ++++++++++++-- src/Php/Translator.php | 84 +++++++++-- .../{ns-const.phpt => ns-const-01.phpt} | 0 tests/aot/namespace/ns-const-02.phpt | 28 ++++ tests/aot/namespace/ns-const-03.phpt | 24 ++++ 32 files changed, 566 insertions(+), 36 deletions(-) create mode 100644 phpunit/code/compiler_api/hello_world.cc create mode 100644 phpunit/code/compiler_api/ignored.php create mode 100644 phpunit/code/compiler_api/kept.php create mode 100644 phpunit/code/compiler_api/main.php create mode 100644 phpunit/code/compiler_api/skipped_nested.php create mode 100644 phpunit/code/interface_method_from_trait.php create mode 100644 phpunit/code/interface_method_missing.php create mode 100644 phpunit/code/interface_method_signature_mismatch.php create mode 100644 phpunit/code/preprocessor/abstract_method_signature.php create mode 100644 phpunit/code/preprocessor/class_constants.php create mode 100644 phpunit/code/preprocessor/deps_class_implements.php create mode 100644 phpunit/code/preprocessor/deps_class_uses_trait.php create mode 100644 phpunit/code/preprocessor/deps_interface.php create mode 100644 phpunit/code/preprocessor/deps_trait.php create mode 100644 phpunit/code/preprocessor/duplicate_abstract_method.php create mode 100644 phpunit/code/preprocessor/duplicate_class_constant.php create mode 100644 phpunit/code/preprocessor/duplicate_namespaced_class_interface.php create mode 100644 phpunit/code/preprocessor/interface_members.php create mode 100644 phpunit/code/preprocessor/namespaced_const.php create mode 100644 phpunit/code/preprocessor/trait_alias_modifier.php rename tests/aot/namespace/{ns-const.phpt => ns-const-01.phpt} (100%) create mode 100644 tests/aot/namespace/ns-const-02.phpt create mode 100644 tests/aot/namespace/ns-const-03.phpt diff --git a/phpunit/code/compiler_api/hello_world.cc b/phpunit/code/compiler_api/hello_world.cc new file mode 100644 index 00000000..76e81970 --- /dev/null +++ b/phpunit/code/compiler_api/hello_world.cc @@ -0,0 +1 @@ +int main() { return 0; } diff --git a/phpunit/code/compiler_api/ignored.php b/phpunit/code/compiler_api/ignored.php new file mode 100644 index 00000000..f95a9e1b --- /dev/null +++ b/phpunit/code/compiler_api/ignored.php @@ -0,0 +1,2 @@ +invoke($this->compiler, ...$args); } + private function fixturePath(string $file): string + { + return __DIR__ . '/../code/compiler_api/' . $file; + } + private function createProjectFile(string $yaml, string $filename = 'project.yml', string $baseDir = ''): string { $projectDir = $baseDir === '' ? $this->testDir : $this->testDir . '/' . trim($baseDir, '/'); @@ -82,7 +87,7 @@ class CompilerBaseApiTest extends TestCase } $sourceFile = $projectDir . '/main.php'; - file_put_contents($sourceFile, "fixturePath('main.php'), $sourceFile); $projectFile = $projectDir . '/' . $filename; file_put_contents($projectFile, $yaml); @@ -363,9 +368,9 @@ ignore: YAML); $projectDir = dirname($projectFile); mkdir($projectDir . '/skipped', 0777, true); - file_put_contents($projectDir . '/ignored.php', "fixturePath('ignored.php'), $projectDir . '/ignored.php'); + copy($this->fixturePath('skipped_nested.php'), $projectDir . '/skipped/nested.php'); + copy($this->fixturePath('kept.php'), $projectDir . '/kept.php'); $files = $this->invokeMethod('parseProjectYaml', $projectFile); @@ -452,7 +457,7 @@ YAML); $logFile = $spaceDir . '/format.log'; $sourceFile = $spaceDir . '/hello world.cc'; - file_put_contents($sourceFile, "int main() { return 0; }\n"); + copy($this->fixturePath('hello_world.cc'), $sourceFile); $this->createFakeClangFormat($binDir, $logFile); putenv('PATH=' . $binDir . ':' . ($this->originalPath ?: '')); diff --git a/phpunit/src/Entity/InterfaceDefTest.php b/phpunit/src/Entity/InterfaceDefTest.php index 645847ff..b769aacc 100644 --- a/phpunit/src/Entity/InterfaceDefTest.php +++ b/phpunit/src/Entity/InterfaceDefTest.php @@ -4,6 +4,7 @@ namespace PhpAot\Tests\Entity; use PHPUnit\Framework\TestCase; use PhpAot\Php\Entity\InterfaceDef; +use PhpAot\Php\Entity\MethodDef; class InterfaceDefTest extends TestCase { @@ -39,4 +40,22 @@ class InterfaceDefTest extends TestCase $this->assertEquals('Parent', $iface->extends); } + + public function testTracksMethodsCaseInsensitively(): void + { + $iface = new InterfaceDef('Runnable'); + $iface->addMethod(new MethodDef(0, 'run')); + + $this->assertTrue($iface->hasMethod('run')); + $this->assertTrue($iface->hasMethod('RUN')); + $this->assertArrayHasKey('run', $iface->methods); + } + + public function testTracksMultipleParentInterfaces(): void + { + $iface = new InterfaceDef('Child'); + $iface->extendsList = ['ParentA', 'ParentB']; + + $this->assertSame(['ParentA', 'ParentB'], $iface->extendsList); + } } diff --git a/phpunit/src/InheritanceErrorTest.php b/phpunit/src/InheritanceErrorTest.php index 6453e860..b1f0e0cd 100644 --- a/phpunit/src/InheritanceErrorTest.php +++ b/phpunit/src/InheritanceErrorTest.php @@ -97,4 +97,19 @@ class InheritanceErrorTest extends TestCase { $this->exec('must be compatible', 'inheritance_error_prop_readonly.php'); } + + public function testInterfaceMethodMissing() + { + $this->exec('must implement method', 'interface_method_missing.php'); + } + + public function testInterfaceMethodSignatureMismatch() + { + $this->exec('must be compatible', 'interface_method_signature_mismatch.php'); + } + + public function testInterfaceMethodProvidedByTrait() + { + $this->assertCompiles('interface_method_from_trait.php'); + } } diff --git a/phpunit/src/PreprocessorTest.php b/phpunit/src/PreprocessorTest.php index 3e1f1bc2..19277715 100644 --- a/phpunit/src/PreprocessorTest.php +++ b/phpunit/src/PreprocessorTest.php @@ -5,8 +5,10 @@ namespace PhpAot\Tests; use PHPUnit\Framework\TestCase; use PhpAot\Php\CompilerTest; use PhpAot\Php\ArgInfo; +use PhpAot\Php\Exception\TestError; use PhpParser\Node; use PhpParser\Node\Stmt\Function_; +use PhpParser\Modifiers; use PhpParser\ParserFactory; class PreprocessorTest extends TestCase @@ -59,6 +61,13 @@ class PreprocessorTest extends TestCase $prop->setValue($this->compiler, $value); } + private function getProperty(string $name): mixed + { + $prop = $this->ref->getProperty($name); + $prop->setAccessible(true); + return $prop->getValue($this->compiler); + } + private function parseFunctionNode(string $code): Function_ { $parser = (new ParserFactory())->createForHostVersion(); @@ -235,6 +244,133 @@ class PreprocessorTest extends TestCase $this->assertIsArray($files); } + public function testPrepareFileParsesInterfaceMembersAndTypeChecks(): void + { + $file = __DIR__ . '/../code/preprocessor/interface_members.php'; + + $this->compiler->prepareFile($file); + + $interfaces = $this->getProperty('interfaces'); + $this->assertArrayHasKey('demo', $interfaces); + + $iface = $interfaces['demo']; + $this->assertSame(['ParentA', 'ParentB'], $iface->extendsList); + $this->assertSame('ParentA', $iface->extends); + $this->assertArrayHasKey('VERSION', $iface->constants); + $this->assertTrue($iface->hasMethod('run')); + + $functionDef = $iface->methods['run']->functionDef; + $this->assertTrue($functionDef->method); + $this->assertSame('php::Int', $functionDef->argInfoList[0]->type); + $this->assertNull($functionDef->argInfoList[0]->typeCheck); + $this->assertSame('php::Var', $functionDef->argInfoList[1]->type); + $this->assertNotEmpty($functionDef->argInfoList[1]->typeCheck); + $this->assertSame('php::Var', $functionDef->returnType); + $this->assertNotEmpty($functionDef->returnTypeCheck); + } + + public function testPrepareFileRejectsNamespacedDuplicateClassAndInterface(): void + { + $this->expectException(TestError::class); + $this->expectExceptionMessage('Duplicate class `App\\Demo`'); + + $file = __DIR__ . '/../code/preprocessor/duplicate_namespaced_class_interface.php'; + $this->compiler->prepareFile($file); + } + + public function testPrepareFileParsesNamespacedConstants(): void + { + $file = __DIR__ . '/../code/preprocessor/namespaced_const.php'; + + $this->compiler->prepareFile($file); + + $constants = $this->getProperty('constants'); + $this->assertArrayHasKey('_const_var_App__VERSION', $constants); + $this->assertSame('App\\VERSION', $constants['_const_var_App__VERSION']->name); + } + + public function testSortFilesUsesImplementsAndTraitDependencies(): void + { + $classFile = realpath(__DIR__ . '/../code/preprocessor/deps_class_implements.php'); + $interfaceFile = realpath(__DIR__ . '/../code/preprocessor/deps_interface.php'); + $traitUserFile = realpath(__DIR__ . '/../code/preprocessor/deps_class_uses_trait.php'); + $traitFile = realpath(__DIR__ . '/../code/preprocessor/deps_trait.php'); + + $this->compiler->prepareFile($classFile); + $this->compiler->prepareFile($interfaceFile); + $this->compiler->prepareFile($traitUserFile); + $this->compiler->prepareFile($traitFile); + + $files = [$classFile, $interfaceFile, $traitUserFile, $traitFile]; + $this->compiler->sortFiles($files); + + $this->assertLessThan(array_search($classFile, $files, true), array_search($interfaceFile, $files, true)); + $this->assertLessThan(array_search($traitUserFile, $files, true), array_search($traitFile, $files, true)); + } + + public function testPrepareFileParsesTraitAliasModifierWithoutNewName(): void + { + $file = __DIR__ . '/../code/preprocessor/trait_alias_modifier.php'; + + $this->compiler->prepareFile($file); + + $classes = $this->getProperty('classes'); + $this->assertArrayHasKey('aliasmodifieruser', $classes); + $aliases = $classes['aliasmodifieruser']->traitAliases; + $this->assertArrayHasKey('aliasmodifiertrait::hello', $aliases); + $this->assertSame('hello', $aliases['aliasmodifiertrait::hello']['newName']); + $this->assertSame(Modifiers::PRIVATE, $aliases['aliasmodifiertrait::hello']['newModifier']); + } + + public function testPrepareFileInfersEachClassConstantTypeIndependently(): void + { + $file = __DIR__ . '/../code/preprocessor/class_constants.php'; + + $this->compiler->prepareFile($file); + + $classes = $this->getProperty('classes'); + $this->assertArrayHasKey('preprocessorclassconstants', $classes); + $constants = $classes['preprocessorclassconstants']->constants; + $this->assertSame('php::Str', $constants['TEXT']->type); + $this->assertSame('php::Array', $constants['ITEMS']->type); + } + + public function testPrepareFileRejectsDuplicateClassConstants(): void + { + $this->expectException(TestError::class); + $this->expectExceptionMessage('Duplicate constant `VALUE`'); + + $file = __DIR__ . '/../code/preprocessor/duplicate_class_constant.php'; + $this->compiler->prepareFile($file); + } + + public function testPrepareFileParsesAbstractMethodSignatures(): void + { + $file = __DIR__ . '/../code/preprocessor/abstract_method_signature.php'; + + $this->compiler->prepareFile($file); + + $classes = $this->getProperty('classes'); + $this->assertArrayHasKey('preprocessorabstractsignature', $classes); + $methodDef = $classes['preprocessorabstractsignature']->abstractMethodDefs['load']; + $functionDef = $methodDef->functionDef; + $this->assertTrue($functionDef->method); + $this->assertSame('php::Int', $functionDef->argInfoList[0]->type); + $this->assertSame('php::Var', $functionDef->argInfoList[1]->type); + $this->assertNotEmpty($functionDef->argInfoList[1]->typeCheck); + $this->assertSame('php::Object', $functionDef->returnType); + $this->assertSame('PreprocessorAbstractSignature', $functionDef->returnClass); + } + + public function testPrepareFileRejectsDuplicateAbstractMethods(): void + { + $this->expectException(TestError::class); + $this->expectExceptionMessage('Duplicate method `load`'); + + $file = __DIR__ . '/../code/preprocessor/duplicate_abstract_method.php'; + $this->compiler->prepareFile($file); + } + public function testIntersectionParamDeclFallsBackToVarWithRuntimeCheck(): void { $fn = $this->parseFunctionNode('getNamespacedClassName($implement); + $interfaceName = $this->getNamespacedClassName($this->parseIdentifier($implement)); + $list[] = $interfaceName; + if (!$this->isInternalInterface($interfaceName)) { + $this->symbolCallInFile[$this->file][] = strtolower($interfaceName); + } } return $list; } @@ -1822,6 +1826,11 @@ class CompilerBase extends \PhpAot\Core\Translator return array_key_exists($this->escapeClass($name), $this->interfaces); } + protected function getInterface(string $name): InterfaceDef + { + return $this->interfaces[$this->escapeClass($name)]; + } + protected function checkFunction(string $name): void { // 在预处理阶段检测到函数声明,但是未定义,说明在当前文件,但是顺序错误 @@ -3578,7 +3587,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isNameExpr($expr->name) and $this->hasConstant($name)) { return $this->getConstant($name); } - if ($this->namespace and $this->isNameExpr($expr->name) and !str_contains($name, '\\')) { + if ($this->namespace and $this->isNameExpr($expr->name) and !$expr->name instanceof Node\Name\FullyQualified) { $nsName = $this->namespace . '\\' . $name; if ($this->hasConstant($nsName)) { return $this->getConstant($nsName); @@ -3725,12 +3734,19 @@ class CompilerBase extends \PhpAot\Core\Translator } // Check transitive interface inheritance (e.g., Iterator extends Traversable) foreach ($classDef->implements as $iface) { - $check = $iface; - while ($check && $this->hasInterface($check)) { + $stack = [$iface]; + while ($stack) { + $check = array_pop($stack); if (strcasecmp($check, $expected) === 0) { return true; } - $check = $this->getInterface($check)->extends; + if (!$this->hasInterface($check)) { + continue; + } + $interfaceDef = $this->getInterface($check); + foreach ($interfaceDef->extendsList ?: ($interfaceDef->extends ? [$interfaceDef->extends] : []) as $parentIface) { + $stack[] = $parentIface; + } } if (is_subclass_of($iface, $expected)) { return true; diff --git a/src/Php/Entity/ClassDef.php b/src/Php/Entity/ClassDef.php index 96a13f5b..0e23e0ee 100644 --- a/src/Php/Entity/ClassDef.php +++ b/src/Php/Entity/ClassDef.php @@ -48,6 +48,12 @@ class ClassDef extends ClassLikeDef * @var array */ public array $abstractMethods = []; + + /** + * Abstract method name (lowercase) => method definition + * @var array + */ + public array $abstractMethodDefs = []; public ?Trait_ $trait = null; /** @@ -79,9 +85,13 @@ class ClassDef extends ClassLikeDef $this->methods[strtolower($method->name)] = $method; } - public function addAbstractMethod(string $name, int $flags): void + public function addAbstractMethod(string $name, int $flags, ?MethodDef $methodDef = null): void { - $this->abstractMethods[strtolower($name)] = $flags; + $lower = strtolower($name); + $this->abstractMethods[$lower] = $flags; + if ($methodDef !== null) { + $this->abstractMethodDefs[$lower] = $methodDef; + } } public function hasMethod(string $method): bool diff --git a/src/Php/Entity/InterfaceDef.php b/src/Php/Entity/InterfaceDef.php index 019b4e9f..a5fef3f2 100644 --- a/src/Php/Entity/InterfaceDef.php +++ b/src/Php/Entity/InterfaceDef.php @@ -10,8 +10,38 @@ namespace PhpAot\Php\Entity; class InterfaceDef extends ClassLikeDef { + /** + * @var array + */ + public array $methods = []; + + /** + * @var array + */ + public array $constants = []; + + /** + * @var string[] + */ + public array $extendsList = []; + public function __construct(string $name, string $namespace = '') { parent::__construct($name, $namespace); } + + public function addMethod(MethodDef $method): void + { + $this->methods[strtolower($method->name)] = $method; + } + + public function hasMethod(string $method): bool + { + return isset($this->methods[strtolower($method)]); + } + + public function hasConstant(string $name): bool + { + return isset($this->constants[$name]); + } } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index c9bc6693..d2054afb 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -212,6 +212,7 @@ class Preprocessor extends CompilerBase $this->parseGroupUse($v2); break; case 'Stmt_Const': + $this->parseConstDef($v2); break; case 'Stmt_Interface': $this->parseInterface($v2); @@ -554,13 +555,10 @@ class Preprocessor extends CompilerBase $flags = $this->parseModifiers($v->flags); $class = ''; - if ($v->type) { - $type = $this->parseTypeDecl($v->type, self::DECL_TYPE_OF_CONST, $class); - } else { - $type = null; - } + $declaredType = $v->type ? $this->parseTypeDecl($v->type, self::DECL_TYPE_OF_CONST, $class) : null; foreach ($v->consts as $const) { + $type = $declaredType; if ($type === null) { $type = match ($const->value->getType()) { 'Expr_Array' => self::TYPE_ARRAY, @@ -569,6 +567,9 @@ class Preprocessor extends CompilerBase }; } $constName = $this->parseIdentifier($const->name); + if ($this->classDef->hasConstant($constName)) { + $this->fatalError($v, "Duplicate constant `{$constName}`"); + } $constValue = $this->parseIdentifier($const->value); $constInfo = new ConstantDef($constName, $flags, $type, $constValue); @@ -654,9 +655,16 @@ class Preprocessor extends CompilerBase $this->checkRequiredArgNum($name, $this->methodDef, $v); $this->classDef->addMethod($this->methodDef); } else { + if ($this->classDef->hasMethod($name) || $this->classDef->hasAbstractMethod($name)) { + $this->fatalError($v, "Duplicate method `{$this->method}`"); + } if (!$class instanceof Node\Stmt\Trait_ && isset($class->flags) && !($class->flags & Modifiers::ABSTRACT)) { $this->fatalError($v, "Non-abstract class {$this->class} contains abstract method {$v->name}"); } + $this->methodDef = new MethodDef($flags, $name); + $this->methodDef->functionDef = $this->parseFunctionDecl($v); + $this->methodDef->functionDef->method = true; + $this->checkRequiredArgNum($name, $this->methodDef, $v); if ($this->method === '__construct') { foreach ($v->params as $param) { if ($param->isPromoted()) { @@ -664,7 +672,7 @@ class Preprocessor extends CompilerBase } } } - $this->classDef->addAbstractMethod($name, $flags); + $this->classDef->addAbstractMethod($name, $flags, $this->methodDef); } $fullClassName = $this->getFullClassName(); @@ -716,12 +724,81 @@ class Preprocessor extends CompilerBase protected function parseInterface(Node\Stmt\Interface_ $v): void { + $this->resetClass(); + $this->resetMethod(); + $this->resetFunction(); $name = $this->parseIdentifier($v->name); $this->interface = $name; $this->interfaceDef = new InterfaceDef($name, $this->namespace); - $interfaceName = $this->interfaceDef->getNamespacedName(); + $interfaceName = $this->interfaceDef->getNamespacedName(false); + $interfaceNameLower = strtolower($interfaceName); + + foreach ($v->extends as $parent) { + $parentName = $this->getNamespacedClassName($this->parseIdentifier($parent)); + $this->interfaceDef->extendsList[] = $parentName; + if ($this->interfaceDef->extends === '') { + $this->interfaceDef->extends = $parentName; + } + if (!$this->isInternalInterface($parentName)) { + $this->symbolCallInFile[$this->file][] = strtolower($parentName); + } + } + + if (isset($this->symbolDeclInFile[$interfaceNameLower])) { + $this->fatalError($v, "Duplicate interface `{$interfaceName}`"); + } + + $this->symbolDeclInFile[$interfaceNameLower] = $this->file; $this->interfaces[$this->escapeClass($interfaceName)] = $this->interfaceDef; $this->interfacesDefineInFile[$interfaceName] = $this->interfaceDef; + + foreach ($v->stmts as $stmt) { + if ($stmt instanceof Node\Stmt\ClassConst) { + foreach ($stmt->consts as $const) { + $constName = $this->parseIdentifier($const->name); + if ($this->interfaceDef->hasConstant($constName)) { + $this->fatalError($stmt, "Duplicate constant `{$constName}`"); + } + $class = ''; + $type = $stmt->type + ? $this->parseTypeDecl($stmt->type, self::DECL_TYPE_OF_CONST, $class) + : match ($const->value->getType()) { + 'Expr_Array' => self::TYPE_ARRAY, + 'Scalar_String' => self::TYPE_STR, + default => self::TYPE_VAR, + }; + $constInfo = new ConstantDef($constName, $this->parseModifiers($stmt->flags), $type, $this->parseIdentifier($const->value)); + $constInfo->class = $class; + $constInfo->valueExpr = $const->value; + $this->interfaceDef->constants[$constName] = $constInfo; + } + continue; + } + + if ($stmt instanceof Node\Stmt\ClassMethod) { + $methodName = $this->getMethodName($stmt); + if ($this->interfaceDef->hasMethod($methodName)) { + $this->fatalError($stmt, "Duplicate method `{$methodName}`"); + } + $this->method = $methodName; + $methodDef = new MethodDef($this->parseModifiers($stmt->flags), $methodName); + $methodDef->functionDef = $this->parseFunctionDecl($stmt); + $methodDef->functionDef->method = true; + $this->interfaceDef->addMethod($methodDef); + $this->resetMethod(); + $this->resetFunction(); + continue; + } + + if (!$stmt instanceof Node\Stmt\Nop) { + $this->fatalError($stmt, 'Unsupported interface statement: ' . $stmt->getType()); + } + } + + $this->resetMethod(); + $this->resetFunction(); + $this->interface = ''; + $this->interfaceDef = null; } protected function parseTraitUseOptions(Node\Stmt\TraitUse $traitUse, array &$aliases, array &$ignored): void @@ -739,7 +816,7 @@ class Preprocessor extends CompilerBase $traits[] = $adaptation->trait; } foreach ($traits as $trait) { - $traitName = $this->getNamespacedClassName($trait); + $traitName = $this->getNamespacedClassName($this->parseIdentifier($trait)); $methodName = $adaptation->method->toString(); /* * 例如: @@ -747,7 +824,7 @@ class Preprocessor extends CompilerBase * 这表示 TraitA::method() 会被重命名为 TraitA::newMethod() */ $aliases[$this->getFullMethodName($traitName, $methodName)] = [ - 'newName' => $adaptation->newName->toString(), + 'newName' => $adaptation->newName ? $adaptation->newName->toString() : $methodName, 'newModifier' => $adaptation->newModifier ?: 0, ]; } @@ -763,7 +840,8 @@ class Preprocessor extends CompilerBase * 这表示 TraitB::method() 将会被忽略,真正执行的是 TraitA::method() */ foreach ($adaptation->insteadof as $trait2) { - $ignored[$this->getFullMethodName($trait2, $methodName)] = true; + $traitName = $this->getNamespacedClassName($this->parseIdentifier($trait2)); + $ignored[$this->getFullMethodName($traitName, $methodName)] = true; } } } @@ -776,6 +854,12 @@ class Preprocessor extends CompilerBase if ($v->adaptations) { $this->parseTraitUseOptions($v, $aliases, $ignored); } + foreach ($v->traits as $trait) { + $traitName = $this->getNamespacedClassName($this->parseIdentifier($trait)); + if (!$this->isInternalClass($traitName)) { + $this->symbolCallInFile[$this->file][] = strtolower($traitName); + } + } $this->classDef->traitAliases = array_merge($this->classDef->traitAliases, $aliases); $this->classDef->traitIgnored = array_merge($this->classDef->traitIgnored, $ignored); } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index dc5401cc..0a976bc7 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -1864,14 +1864,17 @@ CODE; protected function getRegisterClassFunctionCeList(ClassDef|InterfaceDef $classDef): array { $list = []; + if ($classDef instanceof InterfaceDef) { + foreach ($classDef->extendsList ?: ($classDef->extends ? [$classDef->extends] : []) as $parentInterface) { + $list[] = self::PREFIX . 'class_entry_' . $this->escapeCeName($parentInterface); + } + return $list; + } + $parentCe = $this->getParentClassCe($classDef); if ($parentCe !== '') { $list = [$parentCe]; } - // interface 没有 implements - if ($classDef instanceof InterfaceDef) { - return $list; - } $implements = $this->getImplementCe($classDef); return array_merge($list, $implements); @@ -2290,14 +2293,13 @@ CODE; $sorter = new StringSort(); foreach ($this->interfaces as $interfaceDef) { - $parent = $interfaceDef->extends; $ce = $this->getClassCe($interfaceDef); $deps = []; - if ($parent) { + foreach ($interfaceDef->extendsList ?: ($interfaceDef->extends ? [$interfaceDef->extends] : []) as $parent) { + $tmpCe = self::PREFIX . 'class_entry_' . $this->escapeCeName($parent); // 不存在的接口,说明可能是内置接口 - $tmpCe = $this->getParentClassCe($interfaceDef); - if (!isset($this->interfaces[$parent])) { + if (!$this->hasInterface($parent)) { $sorter->add($tmpCe); } $deps[] = $tmpCe; @@ -2735,6 +2737,9 @@ CODE; break; } } + if (!$class instanceof Node\Stmt\Trait_) { + $this->checkInterfaceImplementations($class); + } $code = $this->genNativeMethod($methodCodes); $oriCtx = $this->context; @@ -3084,17 +3089,16 @@ CODE; 'Cannot override private method `' . $extends . '::' . $name . '()`'); } - $parentFuncDef = $methodDef->functionDef; - $this->validateMethodOverrideSignature($v, $name, $childFuncDef, $methodDef, $extends); + $this->validateMethodOverrideSignature($v, $name, $this->methodDef, $methodDef, $extends); break; } } } private function validateMethodOverrideSignature( - Node\Stmt\ClassMethod $v, + NodeAbstract $v, string $methodName, - FunctionDef $childFuncDef, + MethodDef $childMethodDef, MethodDef $parentMethodDef, string $parentClass ): void { @@ -3107,12 +3111,13 @@ CODE; // PHP allows widening visibility in overrides (e.g. protected -> public), // but forbids narrowing it. - if ($this->getVisibilityRank($this->methodDef->flags) < $this->getVisibilityRank($parentMethodDef->flags)) { + if ($this->getVisibilityRank($childMethodDef->flags) < $this->getVisibilityRank($parentMethodDef->flags)) { $error('visibility mismatch'); } + $childFuncDef = $childMethodDef->functionDef; $parentFuncDef = $parentMethodDef->functionDef; - if (!$parentFuncDef) { + if (!$childFuncDef || !$parentFuncDef) { return; } @@ -3154,6 +3159,57 @@ CODE; } } + private function checkInterfaceImplementations(Node\Stmt\Class_|Node\Stmt\Enum_ $classStmt): void + { + $classDef = $this->classDef; + foreach ($classDef->implements as $interfaceName) { + $this->checkInterfaceImplementation($classStmt, $classDef, $interfaceName); + } + } + + private function checkInterfaceImplementation(NodeAbstract $node, ClassDef $classDef, string $interfaceName): void + { + if ($this->isInternalInterface($interfaceName)) { + return; + } + if (!$this->hasInterface($interfaceName)) { + return; + } + + $interfaceDef = $this->getInterface($interfaceName); + foreach ($interfaceDef->methods as $methodName => $interfaceMethodDef) { + $childMethodDef = $this->findClassMethodDef($classDef, $methodName); + if ($childMethodDef === null) { + $this->fatalError($node, "Class `{$classDef->getNamespacedName(false)}` must implement method `{$interfaceName}::{$interfaceMethodDef->name}()`"); + } + $this->validateMethodOverrideSignature( + $node, + $interfaceMethodDef->name, + $childMethodDef, + $interfaceMethodDef, + $interfaceName + ); + } + + foreach ($interfaceDef->extendsList ?: ($interfaceDef->extends ? [$interfaceDef->extends] : []) as $parentInterface) { + $this->checkInterfaceImplementation($node, $classDef, $parentInterface); + } + } + + private function findClassMethodDef(ClassDef $classDef, string $methodName): ?MethodDef + { + $current = $classDef; + while (true) { + if ($current->hasMethod($methodName)) { + return $current->getMethod($methodName); + } + if (!$current->extends || !$this->hasClass($current->extends)) { + return null; + } + $current = $this->getClass($current->extends); + } + } + private function getVisibilityRank(int $flags): int { if ($flags & Modifiers::PUBLIC) { diff --git a/tests/aot/namespace/ns-const.phpt b/tests/aot/namespace/ns-const-01.phpt similarity index 100% rename from tests/aot/namespace/ns-const.phpt rename to tests/aot/namespace/ns-const-01.phpt diff --git a/tests/aot/namespace/ns-const-02.phpt b/tests/aot/namespace/ns-const-02.phpt new file mode 100644 index 00000000..247e0dda --- /dev/null +++ b/tests/aot/namespace/ns-const-02.phpt @@ -0,0 +1,28 @@ +--TEST-- +preprocessor registers namespace constants +--FILE-- + +--EXPECT-- +string(12) "ns-const:123" +string(8) "ns-const" +int(123) diff --git a/tests/aot/namespace/ns-const-03.phpt b/tests/aot/namespace/ns-const-03.phpt new file mode 100644 index 00000000..9d3b6c7d --- /dev/null +++ b/tests/aot/namespace/ns-const-03.phpt @@ -0,0 +1,24 @@ +--TEST-- +namespace relative qualified constants +--FILE-- + +--EXPECT-- +int(77) +int(77) From c4a81466619565eb1f611b9b7aad6c7206e6533a Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 10:15:58 +0800 Subject: [PATCH 13/37] =?UTF-8?q?refactor(php):=20=E9=87=8D=E6=9E=84PHP?= =?UTF-8?q?=E7=B1=BB=E5=AE=9A=E4=B9=89=E5=92=8C=E6=8E=A5=E5=8F=A3=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0=E6=A3=80=E6=9F=A5=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加抽象方法签名兼容性检查功能 - 实现接口常量初始化表达式解析支持 - 优化类和接口常量处理流程 - 增强继承关系中抽象方法实现验证 - 改进接口实现方法查找逻辑 - 添加抽象类可延迟实现接口方法的支持 - 修复方法重写签名验证问题 - 重构常量解析为统一方法处理 - 更新类型检查生成器去除排序逻辑 - 扩展测试用例覆盖各种继承场景 --- .../abstract_method_signature_mismatch.php | 15 ++++ .../code/abstract_parent_method_missing.php | 11 +++ .../code/interface_abstract_class_missing.php | 19 +++++ .../interface_abstract_method_mismatch.php | 12 +++ .../interface_abstract_method_signature.php | 20 +++++ .../interface_abstract_parent_missing.php | 15 ++++ phpunit/code/interface_array_constant.php | 7 ++ phpunit/src/InheritanceErrorTest.php | 44 +++++++++++ phpunit/src/PreprocessorTest.php | 14 ++++ src/Php/Entity/ClassDef.php | 5 ++ src/Php/Generator/TypeCheckGenerator.php | 2 - src/Php/Preprocessor.php | 36 +++++---- src/Php/Translator.php | 77 +++++++++++++++++-- 13 files changed, 252 insertions(+), 25 deletions(-) create mode 100644 phpunit/code/abstract_method_signature_mismatch.php create mode 100644 phpunit/code/abstract_parent_method_missing.php create mode 100644 phpunit/code/interface_abstract_class_missing.php create mode 100644 phpunit/code/interface_abstract_method_mismatch.php create mode 100644 phpunit/code/interface_abstract_method_signature.php create mode 100644 phpunit/code/interface_abstract_parent_missing.php create mode 100644 phpunit/code/interface_array_constant.php diff --git a/phpunit/code/abstract_method_signature_mismatch.php b/phpunit/code/abstract_method_signature_mismatch.php new file mode 100644 index 00000000..c23c370e --- /dev/null +++ b/phpunit/code/abstract_method_signature_mismatch.php @@ -0,0 +1,15 @@ +assertCompiles('interface_method_from_trait.php'); } + + public function testAbstractClassMayDeferInterfaceMethodImplementation() + { + $this->assertCompiles('interface_abstract_class_missing.php'); + } + + public function testAbstractMethodMayImplementInterfaceContract() + { + $this->assertCompiles('interface_abstract_method_signature.php'); + } + + public function testAbstractInterfaceMethodSignatureMismatch() + { + $this->exec('must be compatible', 'interface_abstract_method_mismatch.php'); + } + + public function testInterfaceArrayConstantInitializesRuntimeValue() + { + global $translator; + $compiler = CompilerTest::create(ROOT_PATH); + $translator = $compiler; + $testFile = __DIR__ . '/../code/interface_array_constant.php'; + $compiler->addFiles([$testFile]); + $compiler->prepareFile($testFile); + $compiler->convertFile($testFile); + $extensionFile = $compiler->genExtension(); + + $this->assertStringContainsString('php::updateConstant("InterfaceArrayConstant", "ITEMS"', file_get_contents($extensionFile)); + } + + public function testConcreteClassMustImplementInheritedAbstractMethod() + { + $this->exec('must implement abstract method', 'abstract_parent_method_missing.php'); + } + + public function testConcreteClassMustImplementInheritedInterfaceMethod() + { + $this->exec('must implement method', 'interface_abstract_parent_missing.php'); + } + + public function testAbstractMethodSignatureMismatch() + { + $this->exec('must be compatible', 'abstract_method_signature_mismatch.php'); + } } diff --git a/phpunit/src/PreprocessorTest.php b/phpunit/src/PreprocessorTest.php index 19277715..a8162fdc 100644 --- a/phpunit/src/PreprocessorTest.php +++ b/phpunit/src/PreprocessorTest.php @@ -269,6 +269,20 @@ class PreprocessorTest extends TestCase $this->assertNotEmpty($functionDef->returnTypeCheck); } + public function testPrepareFileParsesInterfaceArrayConstantInitExpr(): void + { + $file = __DIR__ . '/../code/interface_array_constant.php'; + + $this->compiler->prepareFile($file); + + $interfaces = $this->getProperty('interfaces'); + $this->assertArrayHasKey('interfacearrayconstant', $interfaces); + $constant = $interfaces['interfacearrayconstant']->constants['ITEMS']; + + $this->assertSame('php::Array', $constant->type); + $this->assertStringContainsString('php::Array', $constant->value); + } + public function testPrepareFileRejectsNamespacedDuplicateClassAndInterface(): void { $this->expectException(TestError::class); diff --git a/src/Php/Entity/ClassDef.php b/src/Php/Entity/ClassDef.php index 0e23e0ee..3282b27a 100644 --- a/src/Php/Entity/ClassDef.php +++ b/src/Php/Entity/ClassDef.php @@ -136,6 +136,11 @@ class ClassDef extends ClassLikeDef return $this->methods[strtolower($method)]; } + public function getAbstractMethod($method): MethodDef + { + return $this->abstractMethodDefs[strtolower($method)]; + } + public function getConstant($name): ConstantDef { return $this->constants[$name]; diff --git a/src/Php/Generator/TypeCheckGenerator.php b/src/Php/Generator/TypeCheckGenerator.php index eb706d49..242b44c0 100644 --- a/src/Php/Generator/TypeCheckGenerator.php +++ b/src/Php/Generator/TypeCheckGenerator.php @@ -130,7 +130,6 @@ trait TypeCheckGenerator foreach ($typeNode->types as $type) { $parts[] = $this->typeCheckNodeToString($type); } - sort($parts); return implode('|', $parts); } if ($typeNode instanceof IntersectionType) { @@ -138,7 +137,6 @@ trait TypeCheckGenerator foreach ($typeNode->types as $type) { $parts[] = $this->typeCheckNodeToString($type); } - sort($parts); return implode('&', $parts); } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index d2054afb..9d156b6e 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -570,22 +570,30 @@ class Preprocessor extends CompilerBase if ($this->classDef->hasConstant($constName)) { $this->fatalError($v, "Duplicate constant `{$constName}`"); } - $constValue = $this->parseIdentifier($const->value); + $constInfo = $this->parseClassLikeConstant($const, $flags, $type, $class); + $constInfo->class = $class; + $this->classDef->constants[$constInfo->name] = $constInfo; + } + } - $constInfo = new ConstantDef($constName, $flags, $type, $constValue); - $constInfo->valueExpr = $const->value; + private function parseClassLikeConstant(Node\Const_ $const, int $flags, string $type, string $class = ''): ConstantDef + { + $constName = $this->parseIdentifier($const->name); + $constValue = $this->parseIdentifier($const->value); - if ($this->context->beforeStmtLines) { - $arrayExpr = ''; - if ($this->context->localVars) { - $arrayExpr .= $this->genScopeVarDecl(); - } - $arrayExpr .= $this->parseBeforeStmtLines(); - $constInfo->arrayExpr = $arrayExpr; + $constInfo = new ConstantDef($constName, $flags, $type, $constValue); + $constInfo->valueExpr = $const->value; + + if ($this->context->beforeStmtLines) { + $arrayExpr = ''; + if ($this->context->localVars) { + $arrayExpr .= $this->genScopeVarDecl(); } - $constInfo->class = $class; - $this->classDef->constants[$constInfo->name] = $constInfo; + $arrayExpr .= $this->parseBeforeStmtLines(); + $constInfo->arrayExpr = $arrayExpr; } + $constInfo->class = $class; + return $constInfo; } /** @@ -767,9 +775,7 @@ class Preprocessor extends CompilerBase 'Scalar_String' => self::TYPE_STR, default => self::TYPE_VAR, }; - $constInfo = new ConstantDef($constName, $this->parseModifiers($stmt->flags), $type, $this->parseIdentifier($const->value)); - $constInfo->class = $class; - $constInfo->valueExpr = $const->value; + $constInfo = $this->parseClassLikeConstant($const, $this->parseModifiers($stmt->flags), $type, $class); $this->interfaceDef->constants[$constName] = $constInfo; } continue; diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 0a976bc7..8ee92cb6 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -752,7 +752,7 @@ class Translator extends Preprocessor $propCount = max(1, count($this->propMap)); $lines[] = 'extern THREAD_LOCAL uint32_t ' . self::PREFIX . self::PROP_MAP . '[' . $propCount . '];' . PHP_EOL; - foreach ($this->classes as $classDef) { + foreach ($this->getClassLikesWithConstants() as $classDef) { foreach ($classDef->constants as $constant) { if ($constant->type === self::TYPE_ARRAY) { $constName = self::PREFIX . $this->getNativeName($constant->name, $classDef->namespace, $classDef->name); @@ -861,8 +861,8 @@ CODE; } $code .= "// class \n"; - foreach ($this->classes as $classDef) { - if ($classDef->requireCtor) { + foreach ($this->getClassLikesWithConstants() as $classDef) { + if ($classDef instanceof ClassDef && $classDef->requireCtor) { $code .= 'static zend_object* (*create_object_' . $classDef->getNamespacedName() . ")(zend_class_entry *class_type);\n"; } foreach ($classDef->constants as $constant) { @@ -964,7 +964,7 @@ CODE; } $code .= '// class array constants' . PHP_EOL; - foreach ($this->classes as $classDef) { + foreach ($this->getClassLikesWithConstants() as $classDef) { foreach ($classDef->constants as $constant) { if ($constant->type === self::TYPE_ARRAY) { $constName = self::PREFIX . $this->getNativeName($constant->name, $classDef->namespace, $classDef->name); @@ -1885,6 +1885,14 @@ CODE; return self::PREFIX . 'class_entry_' . $this->escapeCeName($classDef->getNamespacedName()); } + /** + * @return array + */ + private function getClassLikesWithConstants(): array + { + return array_merge($this->classes, $this->interfaces); + } + protected function getFilesFromDir(string $path): array { $scanner = new FileScanner($path); @@ -1895,7 +1903,7 @@ CODE; protected function genClassArrayConstants(): string { $code = ''; - foreach ($this->classes as $classDef) { + foreach ($this->getClassLikesWithConstants() as $classDef) { foreach ($classDef->constants as $constant) { if ($constant->type === self::TYPE_ARRAY) { $constName = self::PREFIX . $this->getNativeName($constant->name, $classDef->namespace, $classDef->name); @@ -2739,6 +2747,7 @@ CODE; } if (!$class instanceof Node\Stmt\Trait_) { $this->checkInterfaceImplementations($class); + $this->checkInheritedAbstractMethodsAreImplemented($class); } $code = $this->genNativeMethod($methodCodes); @@ -3092,6 +3101,10 @@ CODE; $this->validateMethodOverrideSignature($v, $name, $this->methodDef, $methodDef, $extends); break; } + if ($classDef->hasAbstractMethod($name) && isset($classDef->abstractMethodDefs[strtolower($name)])) { + $this->validateMethodOverrideSignature($v, $name, $this->methodDef, $classDef->getAbstractMethod($name), $extends); + break; + } } } @@ -3162,11 +3175,31 @@ CODE; private function checkInterfaceImplementations(Node\Stmt\Class_|Node\Stmt\Enum_ $classStmt): void { $classDef = $this->classDef; - foreach ($classDef->implements as $interfaceName) { + foreach ($this->getImplementedInterfacesForClass($classDef) as $interfaceName) { $this->checkInterfaceImplementation($classStmt, $classDef, $interfaceName); } } + /** + * @return array + */ + private function getImplementedInterfacesForClass(ClassDef $classDef): array + { + $interfaces = []; + $current = $classDef; + while (true) { + foreach ($current->implements as $interfaceName) { + $interfaces[$interfaceName] = $interfaceName; + } + if (!$current->extends || !$this->hasClass($current->extends)) { + break; + } + $current = $this->getClass($current->extends); + } + + return array_values($interfaces); + } + private function checkInterfaceImplementation(NodeAbstract $node, ClassDef $classDef, string $interfaceName): void { if ($this->isInternalInterface($interfaceName)) { @@ -3178,8 +3211,11 @@ CODE; $interfaceDef = $this->getInterface($interfaceName); foreach ($interfaceDef->methods as $methodName => $interfaceMethodDef) { - $childMethodDef = $this->findClassMethodDef($classDef, $methodName); + $childMethodDef = $this->findClassMethodDef($classDef, $methodName, $classDef->isAbstract()); if ($childMethodDef === null) { + if ($classDef->isAbstract()) { + continue; + } $this->fatalError($node, "Class `{$classDef->getNamespacedName(false)}` must implement method `{$interfaceName}::{$interfaceMethodDef->name}()`"); } $this->validateMethodOverrideSignature( @@ -3196,13 +3232,16 @@ CODE; } } - private function findClassMethodDef(ClassDef $classDef, string $methodName): ?MethodDef + private function findClassMethodDef(ClassDef $classDef, string $methodName, bool $includeAbstract = true): ?MethodDef { $current = $classDef; while (true) { if ($current->hasMethod($methodName)) { return $current->getMethod($methodName); } + if ($includeAbstract && $current->hasAbstractMethod($methodName) && isset($current->abstractMethodDefs[strtolower($methodName)])) { + return $current->getAbstractMethod($methodName); + } if (!$current->extends || !$this->hasClass($current->extends)) { return null; } @@ -3210,6 +3249,28 @@ CODE; } } + private function checkInheritedAbstractMethodsAreImplemented(NodeAbstract $node): void + { + $classDef = $this->classDef; + if ($classDef->isAbstract()) { + return; + } + + $current = $classDef; + while ($current->extends && $this->hasClass($current->extends)) { + $parent = $this->getClass($current->extends); + foreach ($parent->abstractMethodDefs as $methodName => $abstractMethodDef) { + if ($this->findClassMethodDef($classDef, $methodName, false) === null) { + $this->fatalError( + $node, + "Class `{$classDef->getNamespacedName(false)}` must implement abstract method `{$parent->getNamespacedName(false)}::{$abstractMethodDef->name}()`" + ); + } + } + $current = $parent; + } + } + private function getVisibilityRank(int $flags): int { if ($flags & Modifiers::PUBLIC) { From 42ee6e3aa60780c8a38a50e748be1656577f74f6 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 10:24:30 +0800 Subject: [PATCH 14/37] =?UTF-8?q?feat(php):=20=E6=94=AF=E6=8C=81=E6=8E=A5?= =?UTF-8?q?=E5=8F=A3=E5=B8=B8=E9=87=8F=E7=BB=A7=E6=89=BF=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了类通过继承链查找接口常量的功能 - 添加了接口及其父接口常量的递归收集机制 - 在编译器中增加了对实现接口的类处理数组常量的支持 - 更新了常量访问检查逻辑以支持接口常量继承 - 添加了单元测试验证接口数组常量向实现类的传播 - 创建了AOT测试用例覆盖接口数组常量继承场景 - 重构了接口实现检查相关代码结构 --- .../interface_array_constant_implements.php | 14 +++++ phpunit/src/InheritanceErrorTest.php | 15 +++++ src/Php/CompilerBase.php | 62 ++++++++++++++++++- src/Php/Translator.php | 53 +++++++++------- .../aot/const/interface-array-const-001.phpt | 60 ++++++++++++++++++ 5 files changed, 180 insertions(+), 24 deletions(-) create mode 100644 phpunit/code/interface_array_constant_implements.php create mode 100644 tests/aot/const/interface-array-const-001.phpt diff --git a/phpunit/code/interface_array_constant_implements.php b/phpunit/code/interface_array_constant_implements.php new file mode 100644 index 00000000..2cb28fba --- /dev/null +++ b/phpunit/code/interface_array_constant_implements.php @@ -0,0 +1,14 @@ +assertStringContainsString('php::updateConstant("InterfaceArrayConstant", "ITEMS"', file_get_contents($extensionFile)); } + public function testInterfaceArrayConstantPropagatesToImplementingClass() + { + global $translator; + $compiler = CompilerTest::create(ROOT_PATH); + $translator = $compiler; + $testFile = __DIR__ . '/../code/interface_array_constant_implements.php'; + $compiler->addFiles([$testFile]); + $compiler->prepareFile($testFile); + $cppFile = $compiler->convertFile($testFile); + $extensionFile = $compiler->genExtension(); + + $this->assertStringContainsString('php_interfacearrayconstantcontract__items', file_get_contents($cppFile)); + $this->assertStringContainsString('php::updateConstant("InterfaceArrayConstantImpl", "ITEMS"', file_get_contents($extensionFile)); + } + public function testConcreteClassMustImplementInheritedAbstractMethod() { $this->exec('must implement abstract method', 'abstract_parent_method_missing.php'); diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 1921cf09..4c928170 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1979,15 +1979,16 @@ class CompilerBase extends \PhpAot\Core\Translator } $classDef = $this->getClass($class); + $originClassDef = $classDef; $constDef = null; // 递归查找,若子类中未定义方法,则尝试查找父类是否存在此方法 while (true) { if (!$classDef->hasConstant($const)) { if (!$classDef->extends) { - return false; + break; } if (!$this->hasClass($classDef->extends)) { - return false; + break; } $classDef = $this->getClass($classDef->extends); } else { @@ -1995,7 +1996,24 @@ class CompilerBase extends \PhpAot\Core\Translator break; } } - if (!$this->checkAccessible($classDef, $constDef->flags)) { + if ($constDef === null) { + foreach ($this->getClassImplementedInterfaces($originClassDef) as $interfaceName) { + if (!$this->hasInterface($interfaceName)) { + continue; + } + $interfaceDef = $this->getInterface($interfaceName); + if (!$interfaceDef->hasConstant($const)) { + continue; + } + $classDef = $interfaceDef; + $constDef = $interfaceDef->constants[$const]; + break; + } + } + if ($constDef === null) { + return false; + } + if ($classDef instanceof ClassDef && !$this->checkAccessible($classDef, $constDef->flags)) { $this->fatalError($expr, 'Constant `' . $classDef->getNamespacedName() . '::' . $const . '` is not accessible'); } if ($constDef->type === self::TYPE_ARRAY) { @@ -2006,6 +2024,44 @@ class CompilerBase extends \PhpAot\Core\Translator } } + /** + * @return array + */ + protected function getClassImplementedInterfaces(ClassDef $classDef): array + { + $interfaces = []; + $current = $classDef; + while (true) { + foreach ($current->implements as $interfaceName) { + $this->collectInterfaceAndParents($interfaceName, $interfaces); + } + if (!$current->extends || !$this->hasClass($current->extends)) { + break; + } + $current = $this->getClass($current->extends); + } + + return array_values($interfaces); + } + + /** + * @param array $interfaces + */ + private function collectInterfaceAndParents(string $interfaceName, array &$interfaces): void + { + if (isset($interfaces[$interfaceName])) { + return; + } + $interfaces[$interfaceName] = $interfaceName; + if (!$this->hasInterface($interfaceName)) { + return; + } + $interfaceDef = $this->getInterface($interfaceName); + foreach ($interfaceDef->extendsList ?: ($interfaceDef->extends ? [$interfaceDef->extends] : []) as $parentInterface) { + $this->collectInterfaceAndParents($parentInterface, $interfaces); + } + } + protected function resetReturnType(Node\Stmt\Return_ $node, string $type): void { $oriType = $this->functionDef->returnType; diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 8ee92cb6..06ba9390 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -999,6 +999,21 @@ CODE; } $parentName = $this->escapeClass($parentDef->extends); } + + foreach ($this->getClassImplementedInterfaces($classDef) as $interfaceName) { + if (!$this->hasInterface($interfaceName)) { + continue; + } + $interfaceDef = $this->getInterface($interfaceName); + foreach ($interfaceDef->constants as $constant) { + if ($constant->type === self::TYPE_ARRAY && !isset($ownConstNames[$constant->name])) { + $ownConstNames[$constant->name] = true; + $classNameStr = $this->genCharPtr($classDef->getNamespacedName(false), true); + $classConstStr = $this->genCharPtr($constant->name); + $code .= "php::updateConstant($classNameStr, $classConstStr, php::null);\n"; + } + } + } } // 扩展模式,需要在 RSHUTDOWN 阶段中清理函数、类、属性表 @@ -1941,6 +1956,22 @@ CODE; } $parentName = $this->escapeClass($parentDef->extends); } + + foreach ($this->getClassImplementedInterfaces($classDef) as $interfaceName) { + if (!$this->hasInterface($interfaceName)) { + continue; + } + $interfaceDef = $this->getInterface($interfaceName); + foreach ($interfaceDef->constants as $constant) { + if ($constant->type === self::TYPE_ARRAY && !isset($ownConstNames[$constant->name])) { + $ownConstNames[$constant->name] = true; + $constName = self::PREFIX . $this->getNativeName($constant->name, $interfaceDef->namespace, $interfaceDef->name); + $classNameStr = $this->genCharPtr($classDef->getNamespacedName(false), true); + $classConstStr = $this->genCharPtr($constant->name); + $code .= "php::updateConstant($classNameStr, $classConstStr, {$constName});\n"; + } + } + } } return $code; @@ -3175,31 +3206,11 @@ CODE; private function checkInterfaceImplementations(Node\Stmt\Class_|Node\Stmt\Enum_ $classStmt): void { $classDef = $this->classDef; - foreach ($this->getImplementedInterfacesForClass($classDef) as $interfaceName) { + foreach ($this->getClassImplementedInterfaces($classDef) as $interfaceName) { $this->checkInterfaceImplementation($classStmt, $classDef, $interfaceName); } } - /** - * @return array - */ - private function getImplementedInterfacesForClass(ClassDef $classDef): array - { - $interfaces = []; - $current = $classDef; - while (true) { - foreach ($current->implements as $interfaceName) { - $interfaces[$interfaceName] = $interfaceName; - } - if (!$current->extends || !$this->hasClass($current->extends)) { - break; - } - $current = $this->getClass($current->extends); - } - - return array_values($interfaces); - } - private function checkInterfaceImplementation(NodeAbstract $node, ClassDef $classDef, string $interfaceName): void { if ($this->isInternalInterface($interfaceName)) { diff --git a/tests/aot/const/interface-array-const-001.phpt b/tests/aot/const/interface-array-const-001.phpt new file mode 100644 index 00000000..d5b7ec08 --- /dev/null +++ b/tests/aot/const/interface-array-const-001.phpt @@ -0,0 +1,60 @@ +--TEST-- +interface array constant inherited by implementing class +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + string(3) "php" + [1]=> + string(3) "aot" +} +string(3) "aot" +array(2) { + [0]=> + string(3) "php" + [1]=> + string(3) "aot" +} +array(2) { + [0]=> + string(3) "php" + [1]=> + string(3) "aot" +} From 72b80276ba20c5c26bf48a48d48094ff687a6e5c Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 10:29:31 +0800 Subject: [PATCH 15/37] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8Dtrait?= =?UTF-8?q?=E6=88=90=E5=91=98=E5=86=B2=E7=AA=81=E6=A3=80=E6=B5=8B=E9=80=BB?= =?UTF-8?q?=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修复trait常量冲突检查,只在不兼容时抛出错误 - 修复trait属性冲突检查,只在不兼容时抛出错误 - 添加类型节点转字符串的辅助方法 - 实现兼容性检查方法验证trait常量和属性是否一致 - 更新测试用例验证trait成员兼容性和冲突场景 --- phpunit/code/trait_constant_conflict.php | 14 +++++ phpunit/code/trait_member_compatible.php | 16 ++++++ phpunit/code/trait_property_conflict.php | 14 +++++ phpunit/src/InheritanceErrorTest.php | 15 +++++ src/Php/Translator.php | 70 ++++++++++++++++++++++-- 5 files changed, 123 insertions(+), 6 deletions(-) create mode 100644 phpunit/code/trait_constant_conflict.php create mode 100644 phpunit/code/trait_member_compatible.php create mode 100644 phpunit/code/trait_property_conflict.php diff --git a/phpunit/code/trait_constant_conflict.php b/phpunit/code/trait_constant_conflict.php new file mode 100644 index 00000000..2762737e --- /dev/null +++ b/phpunit/code/trait_constant_conflict.php @@ -0,0 +1,14 @@ +exec('must implement method', 'interface_abstract_parent_missing.php'); } + public function testCompatibleTraitMemberDuplicatesCompile() + { + $this->assertCompiles('trait_member_compatible.php'); + } + + public function testTraitConstantConflict() + { + $this->exec('constant `VALUE` conflicts', 'trait_constant_conflict.php'); + } + + public function testTraitPropertyConflict() + { + $this->exec('property `count` conflicts', 'trait_property_conflict.php'); + } + public function testAbstractMethodSignatureMismatch() { $this->exec('must be compatible', 'abstract_method_signature_mismatch.php'); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 06ba9390..3ca1c567 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -2585,24 +2585,54 @@ CODE; foreach ($traitStmt->consts as $k2 => $const) { $constName = strtolower($const->name->toString()); if (isset($constants[$constName])) { - unset($traitStmts[$k1][$k2]); + unset($traitStmt->consts[$k2]); + if (!$traitStmt->consts) { + unset($traitStmts[$k1]); + } + continue; } if (isset($traitConstants[$constName])) { - $this->fatalError($classStmt, "Trait `{$traitFullName}` constant `{$constName}` already exists"); + [$existingConstStmt, $existingConst] = $traitConstants[$constName]; + if ($existingConstStmt->flags !== $traitStmt->flags || + $this->typeNodeToStringOrNull($existingConstStmt->type) !== $this->typeNodeToStringOrNull($traitStmt->type) || + $this->printer->prettyPrintExpr($existingConst->value) !== $this->printer->prettyPrintExpr($const->value)) { + $this->fatalError($classStmt, "Trait `{$traitFullName}` constant `{$constName}` already exists"); + } + unset($traitStmt->consts[$k2]); + if (!$traitStmt->consts) { + unset($traitStmts[$k1]); + } + continue; } - $traitConstants[$constName] = $const; + $traitConstants[$constName] = [$traitStmt, $const]; } } if ($traitStmt instanceof Node\Stmt\Property) { foreach ($traitStmt->props as $k2 => $prop) { $propName = strtolower($prop->name->toString()); if (isset($properties[$propName])) { - unset($traitStmts[$k1][$k2]); + unset($traitStmt->props[$k2]); + if (!$traitStmt->props) { + unset($traitStmts[$k1]); + } + continue; } if (isset($traitProperties[$propName])) { - $this->fatalError($classStmt, "Trait `{$traitFullName}` property `{$propName}` already exists"); + [$existingPropStmt, $existingProp] = $traitProperties[$propName]; + $existingDefault = $existingProp->default ? $this->printer->prettyPrintExpr($existingProp->default) : null; + $propDefault = $prop->default ? $this->printer->prettyPrintExpr($prop->default) : null; + if ($existingPropStmt->flags !== $traitStmt->flags || + $this->typeNodeToStringOrNull($existingPropStmt->type) !== $this->typeNodeToStringOrNull($traitStmt->type) || + $existingDefault !== $propDefault) { + $this->fatalError($classStmt, "Trait `{$traitFullName}` property `{$propName}` already exists"); + } + unset($traitStmt->props[$k2]); + if (!$traitStmt->props) { + unset($traitStmts[$k1]); + } + continue; } - $traitProperties[$propName] = $prop; + $traitProperties[$propName] = [$traitStmt, $prop]; } } } @@ -2717,6 +2747,11 @@ CODE; return $this->printer->prettyPrint([$typeNode]); } + private function typeNodeToStringOrNull(?NodeAbstract $typeNode): ?string + { + return $typeNode ? $this->typeNodeToString($typeNode) : null; + } + protected function parseClass(Node\Stmt\Class_|Node\Stmt\Trait_|Node\Stmt\Enum_ $class): string { $this->class = $this->parseIdentifier($class->name); @@ -3389,12 +3424,18 @@ CODE; // 将 Trait 中定义的 常量、静态常量、属性、方法、静态属性复制到当前类中 foreach ($traitDef->constants as $const) { if ($classDef->hasConstant($const->name)) { + if (!$this->isCompatibleTraitConstant($classDef->getConstant($const->name), $const)) { + $this->fatalError($v, "Trait `{$traitFullName}` constant `{$const->name}` conflicts with class `{$classDef->getNamespacedName(false)}`"); + } continue; } $classDef->constants[$const->name] = $const; } foreach ($traitDef->properties as $prop) { if ($classDef->hasProperty($prop->name)) { + if (!$this->isCompatibleTraitProperty($classDef->getProperty($prop->name), $prop)) { + $this->fatalError($v, "Trait `{$traitFullName}` property `{$prop->name}` conflicts with class `{$classDef->getNamespacedName(false)}`"); + } continue; } $classDef->properties[$prop->name] = $prop; @@ -3454,6 +3495,23 @@ CODE; } } + private function isCompatibleTraitConstant(ConstantDef $existing, ConstantDef $incoming): bool + { + return $existing->flags === $incoming->flags && + $existing->type === $incoming->type && + $existing->class === $incoming->class && + $existing->value === $incoming->value; + } + + private function isCompatibleTraitProperty(PropertyDef $existing, PropertyDef $incoming): bool + { + return $existing->flags === $incoming->flags && + $existing->type === $incoming->type && + $existing->class === $incoming->class && + $existing->nullable === $incoming->nullable && + $existing->default === $incoming->default; + } + protected function parseForeachObject(Foreach_ $node): string { $obj = $this->parseIdentifier($node->expr); From 09be0226cb37ee66e85e4dbb24888f8a44261253 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 10:47:14 +0800 Subject: [PATCH 16/37] =?UTF-8?q?feat(trait):=20=E6=94=AF=E6=8C=81trait?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E5=A4=9A=E5=88=AB=E5=90=8D=E5=92=8Cinsteadof?= =?UTF-8?q?=E8=AF=AD=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现trait方法可以有多个别名的功能 - 支持insteadof语法在trait列表中的顺序无关性 - 保持trait别名的原始方法功能 - 添加对继承中静态方法不匹配的检查 - 更新trait别名数据结构以支持别名列表 - 重构trait方法包装器为独立函数 - 修复trait方法别名处理逻辑错误 --- phpunit/code/inheritance_error_static.php | 15 ++ .../code/interface_method_static_mismatch.php | 13 ++ phpunit/src/InheritanceErrorTest.php | 10 ++ phpunit/src/PreprocessorTest.php | 4 +- src/Php/Entity/ClassDef.php | 4 +- src/Php/Preprocessor.php | 8 +- src/Php/Translator.php | 158 ++++++++++++------ tests/aot/trait/015.phpt | 29 ++++ tests/aot/trait/016.phpt | 38 +++++ tests/aot/trait/017.phpt | 32 ++++ 10 files changed, 257 insertions(+), 54 deletions(-) create mode 100644 phpunit/code/inheritance_error_static.php create mode 100644 phpunit/code/interface_method_static_mismatch.php create mode 100644 tests/aot/trait/015.phpt create mode 100644 tests/aot/trait/016.phpt create mode 100644 tests/aot/trait/017.phpt diff --git a/phpunit/code/inheritance_error_static.php b/phpunit/code/inheritance_error_static.php new file mode 100644 index 00000000..655844c8 --- /dev/null +++ b/phpunit/code/inheritance_error_static.php @@ -0,0 +1,15 @@ +assertCompiles('inheritance_error_visibility.php'); } + public function testMethodStaticMismatch() + { + $this->exec('must be compatible', 'inheritance_error_static.php'); + } + + public function testInterfaceMethodStaticMismatch() + { + $this->exec('must be compatible', 'interface_method_static_mismatch.php'); + } + public function testChildMayAddOptionalTrailingParameter() { $this->assertCompiles('inheritance_optional_param_allowed.php'); diff --git a/phpunit/src/PreprocessorTest.php b/phpunit/src/PreprocessorTest.php index a8162fdc..39888c4d 100644 --- a/phpunit/src/PreprocessorTest.php +++ b/phpunit/src/PreprocessorTest.php @@ -332,8 +332,8 @@ class PreprocessorTest extends TestCase $this->assertArrayHasKey('aliasmodifieruser', $classes); $aliases = $classes['aliasmodifieruser']->traitAliases; $this->assertArrayHasKey('aliasmodifiertrait::hello', $aliases); - $this->assertSame('hello', $aliases['aliasmodifiertrait::hello']['newName']); - $this->assertSame(Modifiers::PRIVATE, $aliases['aliasmodifiertrait::hello']['newModifier']); + $this->assertSame('hello', $aliases['aliasmodifiertrait::hello'][0]['newName']); + $this->assertSame(Modifiers::PRIVATE, $aliases['aliasmodifiertrait::hello'][0]['newModifier']); } public function testPrepareFileInfersEachClassConstantTypeIndependently(): void diff --git a/src/Php/Entity/ClassDef.php b/src/Php/Entity/ClassDef.php index 3282b27a..ae3703c5 100644 --- a/src/Php/Entity/ClassDef.php +++ b/src/Php/Entity/ClassDef.php @@ -57,8 +57,8 @@ class ClassDef extends ClassLikeDef public ?Trait_ $trait = null; /** - * FullMethodName -> NewMethodName - * @var array + * FullMethodName -> alias list + * @var array> */ public array $traitAliases = []; diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 9d156b6e..feff1478 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -829,7 +829,7 @@ class Preprocessor extends CompilerBase * use TraitA { TraitA::method as newMethod} * 这表示 TraitA::method() 会被重命名为 TraitA::newMethod() */ - $aliases[$this->getFullMethodName($traitName, $methodName)] = [ + $aliases[$this->getFullMethodName($traitName, $methodName)][] = [ 'newName' => $adaptation->newName ? $adaptation->newName->toString() : $methodName, 'newModifier' => $adaptation->newModifier ?: 0, ]; @@ -866,7 +866,11 @@ class Preprocessor extends CompilerBase $this->symbolCallInFile[$this->file][] = strtolower($traitName); } } - $this->classDef->traitAliases = array_merge($this->classDef->traitAliases, $aliases); + foreach ($aliases as $fullMethodName => $aliasList) { + foreach ($aliasList as $alias) { + $this->classDef->traitAliases[$fullMethodName][] = $alias; + } + } $this->classDef->traitIgnored = array_merge($this->classDef->traitIgnored, $ignored); } } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 3ca1c567..7a69a90e 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -2528,9 +2528,31 @@ CODE; $traitAst = clone $traitDef->trait; $traitStmts = $traitAst->stmts; + $aliasStmts = []; foreach ($traitStmts as $k1 => $traitStmt) { if ($traitStmt instanceof Node\Stmt\ClassMethod) { $methodName = strtolower($traitStmt->name->toString()); + $fullMethodName = $this->getFullMethodName($traitFullName, $methodName); + foreach ($classDef->traitAliases[$fullMethodName] ?? [] as $alias) { + $aliasName = strtolower($alias['newName']); + if ($aliasName === $methodName) { + if ($alias['newModifier']) { + $traitStmt->flags = $alias['newModifier']; + } + } elseif (!isset($methods[$aliasName]) && !isset($traitMethods[$aliasName])) { + $aliasStmt = clone $traitStmt; + $aliasStmt->name = new Node\Identifier($alias['newName']); + if ($alias['newModifier']) { + $aliasStmt->flags = $alias['newModifier']; + } + $aliasStmts[] = $aliasStmt; + $traitMethods[$aliasName] = [$traitFullName, $aliasStmt]; + } + } + if (isset($classDef->traitIgnored[$fullMethodName])) { + unset($traitStmts[$k1]); + continue; + } if (isset($traitMethods[$methodName])) { [$existingTraitName, $existingStmt] = $traitMethods[$methodName]; $newAbstract = $traitStmt->isAbstract(); @@ -2563,19 +2585,6 @@ CODE; // Both concrete — error $this->fatalError($classStmt, "Trait `{$traitFullName}` method `{$methodName}` already exists"); } - $fullMethodName = $this->getFullMethodName($traitFullName, $methodName); - if (isset($classDef->traitAliases[$fullMethodName])) { - $alias = $classDef->traitAliases[$fullMethodName]; - $methodName = $alias['newName']; - $traitStmt->name = new Node\Identifier($methodName); - if ($alias['newModifier']) { - $traitStmt->flags = $alias['newModifier']; - } - } - if (isset($classDef->traitIgnored[$fullMethodName])) { - unset($traitStmts[$k1]); - continue; - } if (isset($methods[$methodName])) { unset($traitStmts[$k1]); } @@ -2637,7 +2646,7 @@ CODE; } } - $stmt->stmts = array_merge($stmt->stmts, $traitStmts); + $stmt->stmts = array_merge($stmt->stmts, $traitStmts, $aliasStmts); } } } @@ -3194,6 +3203,10 @@ CODE; $error('visibility mismatch'); } + if (($childMethodDef->flags & Modifiers::STATIC) !== ($parentMethodDef->flags & Modifiers::STATIC)) { + $error('static mismatch'); + } + $childFuncDef = $childMethodDef->functionDef; $parentFuncDef = $parentMethodDef->functionDef; if (!$childFuncDef || !$parentFuncDef) { @@ -3443,56 +3456,105 @@ CODE; foreach ($traitDef->methods as $methodDef) { $classMethodName = $traitMethodName = $methodDef->name; $fullMethodName = $this->getFullMethodName($traitFullName, $traitMethodName); - // Trait 设置了别名 - if (isset($classDef->traitAliases[$fullMethodName])) { - $alias = $classDef->traitAliases[$fullMethodName]; - $methodDef = clone $methodDef; - $classMethodName = $methodDef->name = $alias['newName']; + $originalMethodDef = $methodDef; + $aliasMethodDefs = []; + foreach ($classDef->traitAliases[$fullMethodName] ?? [] as $alias) { + if (strtolower($alias['newName']) === strtolower($traitMethodName)) { + if ($alias['newModifier']) { + if ($originalMethodDef === $methodDef) { + $originalMethodDef = clone $methodDef; + } + $originalMethodDef->flags = $this->parseModifiers($alias['newModifier']); + } + continue; + } + $aliasMethodDef = clone $methodDef; + $classMethodName = $aliasMethodDef->name = $alias['newName']; if ($alias['newModifier']) { - $methodDef->flags = $this->parseModifiers($alias['newModifier']); + $aliasMethodDef->flags = $this->parseModifiers($alias['newModifier']); } + $aliasMethodDefs[strtolower($classMethodName)] = [$classMethodName, $aliasMethodDef]; } // 设置了 insteadof 选项,此 Trait 的方法将不会被使用 if (isset($classDef->traitIgnored[$fullMethodName])) { + foreach ($aliasMethodDefs as [$aliasMethodName, $aliasMethodDef]) { + if ($classDef->hasMethod($aliasMethodName)) { + continue; + } + $methodCodes[$aliasMethodName] = $this->addTraitMethodWrapper( + $classDef, + $traitDef, + $aliasMethodDef, + $traitMethodName, + $aliasMethodName + ); + } continue; } // 类中已经有同名方法,则不使用 Trait 中的方法 - if ($classDef->hasMethod($classMethodName)) { - continue; - } - - $classDef->addMethod($methodDef); - $traitMethodNativeName = $this->getNativeName($traitMethodName, $traitDef->namespace, $traitDef->name); - $classMethodNativeName = $this->getNativeName($classMethodName, $classDef->namespace, $classDef->name); - $argList = ['this_']; - foreach ($methodDef->functionDef->argInfoList as $argInfo) { - $argList[] = $argInfo->name; + if (!$classDef->hasMethod($traitMethodName)) { + $methodCodes[$traitMethodName] = $this->addTraitMethodWrapper( + $classDef, + $traitDef, + $originalMethodDef, + $traitMethodName, + $traitMethodName + ); } - $argv = implode(', ', $argList); - $code = $methodDef->getReturnType() . ' ' . self::PREFIX . $classMethodNativeName . '('; - if ($this->class) { - $code .= self::TYPE_OBJECT . ' &this_'; - if ($methodDef->functionDef->params) { - $code .= ', '; + foreach ($aliasMethodDefs as [$aliasMethodName, $aliasMethodDef]) { + if ($classDef->hasMethod($aliasMethodName)) { + continue; } + $methodCodes[$aliasMethodName] = $this->addTraitMethodWrapper( + $classDef, + $traitDef, + $aliasMethodDef, + $traitMethodName, + $aliasMethodName + ); } + } + } + } - $this->addFunction($classMethodNativeName, $methodDef->functionDef); + private function addTraitMethodWrapper( + ClassDef $classDef, + ClassDef $traitDef, + MethodDef $methodDef, + string $traitMethodName, + string $classMethodName + ): string { + $classDef->addMethod($methodDef); + $traitMethodNativeName = $this->getNativeName($traitMethodName, $traitDef->namespace, $traitDef->name); + $classMethodNativeName = $this->getNativeName($classMethodName, $classDef->namespace, $classDef->name); + $argList = ['this_']; + foreach ($methodDef->functionDef->argInfoList as $argInfo) { + $argList[] = $argInfo->name; + } + $argv = implode(', ', $argList); - $code .= $methodDef->functionDef->params . ')'; - $code .= '{' . PHP_EOL; - $this->indentLevel++; - $methodCall = self::PREFIX . $traitMethodNativeName . '(' . $argv . ')'; - if ($methodDef->getReturnType() !== self::TYPE_VOID) { - $methodCall = 'return ' . $methodCall; - } - $code .= $this->getIndent() . $methodCall . ';' . PHP_EOL; - $this->indentLevel--; - $code .= $this->getIndent() . '}' . PHP_EOL; - $methodCodes[$classMethodName] = $code; + $code = $methodDef->getReturnType() . ' ' . self::PREFIX . $classMethodNativeName . '('; + if ($this->class) { + $code .= self::TYPE_OBJECT . ' &this_'; + if ($methodDef->functionDef->params) { + $code .= ', '; } } + + $this->addFunction($classMethodNativeName, $methodDef->functionDef); + + $code .= $methodDef->functionDef->params . ')'; + $code .= '{' . PHP_EOL; + $this->indentLevel++; + $methodCall = self::PREFIX . $traitMethodNativeName . '(' . $argv . ')'; + if ($methodDef->getReturnType() !== self::TYPE_VOID) { + $methodCall = 'return ' . $methodCall; + } + $code .= $this->getIndent() . $methodCall . ';' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + return $code; } private function isCompatibleTraitConstant(ConstantDef $existing, ConstantDef $incoming): bool diff --git a/tests/aot/trait/015.phpt b/tests/aot/trait/015.phpt new file mode 100644 index 00000000..d0475d0d --- /dev/null +++ b/tests/aot/trait/015.phpt @@ -0,0 +1,29 @@ +--TEST-- +Trait alias keeps original method +--FILE-- +hello(); + $user->hi(); +} +?> +--EXPECT-- +hello +hello diff --git a/tests/aot/trait/016.phpt b/tests/aot/trait/016.phpt new file mode 100644 index 00000000..303afdb3 --- /dev/null +++ b/tests/aot/trait/016.phpt @@ -0,0 +1,38 @@ +--TEST-- +Trait insteadof works regardless of trait list order +--FILE-- +hello(); + $user->helloA(); +} +?> +--EXPECT-- +B +A diff --git a/tests/aot/trait/017.phpt b/tests/aot/trait/017.phpt new file mode 100644 index 00000000..65f370ca --- /dev/null +++ b/tests/aot/trait/017.phpt @@ -0,0 +1,32 @@ +--TEST-- +Trait method can have multiple aliases +--FILE-- +hello(); + $user->hi(); + $user->hey(); +} +?> +--EXPECT-- +hello +hello +hello From 252b112405e5619d7a049303a34ec5f7140d91b6 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 10:51:33 +0800 Subject: [PATCH 17/37] =?UTF-8?q?feat(php):=20=E5=AE=9E=E7=8E=B0=E7=BB=A7?= =?UTF-8?q?=E6=89=BF=E4=B8=AD=E6=96=B9=E6=B3=95=E9=87=8D=E5=86=99=E7=9A=84?= =?UTF-8?q?=E7=B1=BB=E5=9E=8B=E5=85=BC=E5=AE=B9=E6=80=A7=E6=A3=80=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加对final方法重写错误的检测和报告 - 实现返回类型的协变性检查,允许子类返回更具体的类型 - 实现参数类型的逆变性检查,允许子类参数接受更通用的类型 - 添加从无返回类型到有返回类型的合法转换支持 - 增强方法重写签名验证逻辑以支持PHP类型系统规则 - 添加新的测试用例覆盖各种继承错误场景 --- .../code/inheritance_error_final_method.php | 15 ++++ ...nheritance_error_param_covariant_class.php | 23 ++++++ ...tance_error_return_contravariant_class.php | 25 +++++++ ...nce_parameter_type_contravariant_class.php | 23 ++++++ ...nheritance_return_type_covariant_class.php | 25 +++++++ ...itance_return_type_covariant_from_none.php | 17 +++++ phpunit/src/InheritanceErrorTest.php | 30 ++++++++ src/Php/Translator.php | 73 +++++++++++++++++-- 8 files changed, 226 insertions(+), 5 deletions(-) create mode 100644 phpunit/code/inheritance_error_final_method.php create mode 100644 phpunit/code/inheritance_error_param_covariant_class.php create mode 100644 phpunit/code/inheritance_error_return_contravariant_class.php create mode 100644 phpunit/code/inheritance_parameter_type_contravariant_class.php create mode 100644 phpunit/code/inheritance_return_type_covariant_class.php create mode 100644 phpunit/code/inheritance_return_type_covariant_from_none.php diff --git a/phpunit/code/inheritance_error_final_method.php b/phpunit/code/inheritance_error_final_method.php new file mode 100644 index 00000000..b2f62163 --- /dev/null +++ b/phpunit/code/inheritance_error_final_method.php @@ -0,0 +1,15 @@ +exec('must be compatible', 'inheritance_error_return.php'); } + public function testReturnTypeCannotBeContravariant() + { + $this->exec('must be compatible', 'inheritance_error_return_contravariant_class.php'); + } + + public function testParameterTypeCannotBeCovariant() + { + $this->exec('must be compatible', 'inheritance_error_param_covariant_class.php'); + } + public function testByRefMismatch() { $this->exec('must be compatible', 'inheritance_error_byref.php'); @@ -73,6 +83,11 @@ class InheritanceErrorTest extends TestCase $this->exec('must be compatible', 'inheritance_error_static.php'); } + public function testCannotOverrideFinalMethod() + { + $this->exec('Cannot override final method', 'inheritance_error_final_method.php'); + } + public function testInterfaceMethodStaticMismatch() { $this->exec('must be compatible', 'interface_method_static_mismatch.php'); @@ -83,6 +98,21 @@ class InheritanceErrorTest extends TestCase $this->assertCompiles('inheritance_optional_param_allowed.php'); } + public function testChildMayDeclareReturnTypeWhenParentHasNone() + { + $this->assertCompiles('inheritance_return_type_covariant_from_none.php'); + } + + public function testChildReturnTypeMayBeCovariant() + { + $this->assertCompiles('inheritance_return_type_covariant_class.php'); + } + + public function testChildParameterTypeMayBeContravariant() + { + $this->assertCompiles('inheritance_parameter_type_contravariant_class.php'); + } + public function testPropertyTypeMismatch() { $this->exec('must be compatible', 'inheritance_error_prop_type.php'); diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 7a69a90e..cfe04d6c 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -3159,9 +3159,13 @@ CODE; } // 父类是内置类 if ($classDef->inheritedFromInternalClass) { - if (Reflection::getClassMethodModifiers($extends, $name) & \ReflectionMethod::IS_PRIVATE) { + $modifiers = Reflection::getClassMethodModifiers($extends, $name); + if ($modifiers & \ReflectionMethod::IS_PRIVATE) { goto _error; } + if ($modifiers & \ReflectionMethod::IS_FINAL) { + goto _final_error; + } break; } $classDef = $this->getClass($extends); @@ -3173,6 +3177,12 @@ CODE; 'Cannot override private method `' . $extends . '::' . $name . '()`'); } + if ($methodDef->flags & Modifiers::FINAL) { + _final_error: + $this->fatalError($v, + 'Cannot override final method `' . + $extends . '::' . $name . '()`'); + } $this->validateMethodOverrideSignature($v, $name, $this->methodDef, $methodDef, $extends); break; } @@ -3213,9 +3223,7 @@ CODE; return; } - // Compare return type - if ($childFuncDef->returnType !== $parentFuncDef->returnType || - $childFuncDef->returnClass !== $parentFuncDef->returnClass) { + if (!$this->isReturnTypeOverrideCompatible($childFuncDef, $parentFuncDef)) { $error('return type mismatch'); } @@ -3231,7 +3239,7 @@ CODE; $error("missing parameter #{$i}"); } $childArg = $childFuncDef->argInfoList[$i]; - if ($childArg->type !== $parentArg->type || $childArg->class !== $parentArg->class) { + if (!$this->isParameterTypeOverrideCompatible($childArg, $parentArg)) { $error("parameter #{$i} type mismatch"); } if ($childArg->byRef !== $parentArg->byRef) { @@ -3251,6 +3259,61 @@ CODE; } } + private function isReturnTypeOverrideCompatible(FunctionDef $childFuncDef, FunctionDef $parentFuncDef): bool + { + if ($parentFuncDef->returnTypeUndeclared) { + return true; + } + if ($childFuncDef->returnTypeUndeclared) { + return false; + } + if ($parentFuncDef->returnTypeCheck || $childFuncDef->returnTypeCheck) { + return $parentFuncDef->returnTypeStr === $childFuncDef->returnTypeStr; + } + if ($parentFuncDef->returnType === self::TYPE_VAR) { + return true; + } + if ($childFuncDef->returnType !== $parentFuncDef->returnType) { + return false; + } + if ($parentFuncDef->returnType !== self::TYPE_OBJECT) { + return true; + } + if ($childFuncDef->returnClass === $parentFuncDef->returnClass) { + return true; + } + if (!$childFuncDef->returnClass || !$parentFuncDef->returnClass) { + return false; + } + return $this->isInheritedFrom($childFuncDef->returnClass, $parentFuncDef->returnClass); + } + + private function isParameterTypeOverrideCompatible(ArgInfo $childArg, ArgInfo $parentArg): bool + { + if ($parentArg->typeCheck || $childArg->typeCheck) { + return $parentArg->typeStr === $childArg->typeStr; + } + if ($childArg->undeclared || $childArg->type === self::TYPE_VAR) { + return true; + } + if ($parentArg->undeclared || $parentArg->type === self::TYPE_VAR) { + return false; + } + if ($childArg->type !== $parentArg->type) { + return false; + } + if ($parentArg->type !== self::TYPE_OBJECT) { + return true; + } + if ($childArg->class === $parentArg->class) { + return true; + } + if (!$childArg->class || !$parentArg->class) { + return false; + } + return $this->isInheritedFrom($parentArg->class, $childArg->class); + } + private function checkInterfaceImplementations(Node\Stmt\Class_|Node\Stmt\Enum_ $classStmt): void { $classDef = $this->classDef; From 8231208eaf48240c38ab9816d9a023750524635f Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 11:27:05 +0800 Subject: [PATCH 18/37] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8D=E7=BB=A7?= =?UTF-8?q?=E6=89=BF=E8=AE=BF=E9=97=AE=E6=8E=A7=E5=88=B6=E5=92=8C=E6=89=A9?= =?UTF-8?q?=E5=B1=95=E6=B8=85=E7=90=86=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 修改 canAccessProtectedProperty 替代 isInheritedFrom 处理保护属性访问 - 更新扩展模式下的映射表清理逻辑,使用 C++ 样式初始化替代 PHP 数组赋值 - 修复继承检查中私有成员重声明的处理,跳过私有父类属性/常量的兼容性检查 - 优化可见性检查逻辑,支持可见性放宽但阻止私有成员重声明 - 添加对父类可访问子类保护方法和常量的支持测试 - 新增属性和常量可见性放宽及私有成员重声明的测试用例 - 添加扩展清理映射表的运行时测试验证 --- .../compiler_api/extension_clean_maps.php | 6 ++++ .../inheritance_const_visibility_widen.php | 11 +++++++ .../inheritance_private_const_redeclare.php | 11 +++++++ .../inheritance_private_prop_redeclare.php | 11 +++++++ .../inheritance_prop_visibility_widen.php | 11 +++++++ ...heritance_protected_child_const_access.php | 14 +++++++++ ...eritance_protected_child_method_access.php | 16 ++++++++++ phpunit/src/CompilerBaseApiTest.php | 26 ++++++++++++++++ phpunit/src/InheritanceErrorTest.php | 30 +++++++++++++++++++ src/Php/CompilerBase.php | 5 +++- src/Php/Translator.php | 19 ++++++++---- 11 files changed, 153 insertions(+), 7 deletions(-) create mode 100644 phpunit/code/compiler_api/extension_clean_maps.php create mode 100644 phpunit/code/inheritance_const_visibility_widen.php create mode 100644 phpunit/code/inheritance_private_const_redeclare.php create mode 100644 phpunit/code/inheritance_private_prop_redeclare.php create mode 100644 phpunit/code/inheritance_prop_visibility_widen.php create mode 100644 phpunit/code/inheritance_protected_child_const_access.php create mode 100644 phpunit/code/inheritance_protected_child_method_access.php diff --git a/phpunit/code/compiler_api/extension_clean_maps.php b/phpunit/code/compiler_api/extension_clean_maps.php new file mode 100644 index 00000000..74dd0adb --- /dev/null +++ b/phpunit/code/compiler_api/extension_clean_maps.php @@ -0,0 +1,6 @@ +assertArrayNotHasKey('cxxflags', $options); } + public function testExtensionCleanClearsRuntimeMapsWithValidCpp(): void + { + global $translator; + $compiler = CompilerTest::create(ROOT_PATH); + $translator = $compiler; + $ref = new \ReflectionClass($compiler); + $buildMode = $ref->getProperty('buildMode'); + $buildMode->setAccessible(true); + $buildMode->setValue($compiler, CompilerBase::BUILD_MODE_EXT); + + $testFile = ROOT_PATH . '/phpunit/code/compiler_api/extension_clean_maps.php'; + $compiler->addFiles([$testFile]); + $compiler->prepareFile($testFile); + $compiler->convertFile($testFile); + $extensionFile = $compiler->genExtension(); + $code = file_get_contents($extensionFile); + + $this->assertStringContainsString('#include ', $code); + $this->assertStringContainsString('std::memset(php_func_map, 0, sizeof(php_func_map));', $code); + $this->assertStringContainsString('std::memset(php_class_map, 0, sizeof(php_class_map));', $code); + $this->assertStringContainsString('std::memset(php_property_map, 0, sizeof(php_property_map));', $code); + $this->assertStringNotContainsString('func_map = {}', $code); + $this->assertStringNotContainsString('class_map = {}', $code); + $this->assertStringNotContainsString('property_map = {}', $code); + } + public function testObjectiveCppCompileCommandOptionsKeepCppOptions(): void { $this->setPropertyValue('cxxStd', 'c++20'); diff --git a/phpunit/src/InheritanceErrorTest.php b/phpunit/src/InheritanceErrorTest.php index ab54eac6..dcc38a33 100644 --- a/phpunit/src/InheritanceErrorTest.php +++ b/phpunit/src/InheritanceErrorTest.php @@ -78,6 +78,16 @@ class InheritanceErrorTest extends TestCase $this->assertCompiles('inheritance_error_visibility.php'); } + public function testParentScopeMayAccessChildProtectedMethod() + { + $this->assertCompiles('inheritance_protected_child_method_access.php'); + } + + public function testParentScopeMayAccessChildProtectedConstant() + { + $this->assertCompiles('inheritance_protected_child_const_access.php'); + } + public function testMethodStaticMismatch() { $this->exec('must be compatible', 'inheritance_error_static.php'); @@ -123,6 +133,16 @@ class InheritanceErrorTest extends TestCase $this->exec('must be compatible', 'inheritance_error_prop_visibility.php'); } + public function testPropertyVisibilityMayBeWidened() + { + $this->assertCompiles('inheritance_prop_visibility_widen.php'); + } + + public function testPrivateParentPropertyMayBeRedeclared() + { + $this->assertCompiles('inheritance_private_prop_redeclare.php'); + } + public function testConstantTypeMismatch() { $this->exec('must be compatible', 'inheritance_error_const_type.php'); @@ -133,6 +153,16 @@ class InheritanceErrorTest extends TestCase $this->exec('must be compatible', 'inheritance_error_const_visibility.php'); } + public function testConstantVisibilityMayBeWidened() + { + $this->assertCompiles('inheritance_const_visibility_widen.php'); + } + + public function testPrivateParentConstantMayBeRedeclared() + { + $this->assertCompiles('inheritance_private_const_redeclare.php'); + } + public function testPropertyReadonlyMismatch() { $this->exec('must be compatible', 'inheritance_error_prop_readonly.php'); diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 4c928170..73608a11 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -5483,7 +5483,10 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$this->classDef) { return false; } - return $this->isInheritedFrom($this->classDef->getNamespacedName(false), $classDef->getNamespacedName(false)); + return $this->canAccessProtectedProperty( + $this->classDef->getNamespacedName(false), + $classDef->getNamespacedName(false) + ); } // 类外部调用,只允许调用 public 方法 return true; diff --git a/src/Php/Translator.php b/src/Php/Translator.php index cfe04d6c..70ab0473 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -778,7 +778,8 @@ class Translator extends Preprocessor $this->genClassCeList(); $this->indentLevel++; - $code = $this->genIncludeHeaderFiles(); + $code = '#include ' . PHP_EOL; + $code .= $this->genIncludeHeaderFiles(); if ($this->isBuildModeBin()) { $cliHeaders = [ @@ -1018,9 +1019,9 @@ CODE; // 扩展模式,需要在 RSHUTDOWN 阶段中清理函数、类、属性表 if ($this->isBuildModeExt()) { - $code .= self::FUNC_MAP." = {}\n"; - $code .= self::CLASS_MAP." = {}\n"; - $code .= self::PROP_MAP." = {}\n"; + $code .= 'std::memset(' . self::PREFIX . self::FUNC_MAP . ', 0, sizeof(' . self::PREFIX . self::FUNC_MAP . '));' . PHP_EOL; + $code .= 'std::memset(' . self::PREFIX . self::CLASS_MAP . ', 0, sizeof(' . self::PREFIX . self::CLASS_MAP . '));' . PHP_EOL; + $code .= 'std::memset(' . self::PREFIX . self::PROP_MAP . ', 0, sizeof(' . self::PREFIX . self::PROP_MAP . '));' . PHP_EOL; } $code .= '}' . PHP_EOL . PHP_EOL; @@ -3421,12 +3422,15 @@ CODE; foreach ($this->classDef->properties as $name => $childProp) { if ($chainNode->hasProperty($name)) { $parentProp = $chainNode->getProperty($name); + if ($parentProp->flags & Modifiers::PRIVATE) { + continue; + } if ($childProp->type !== $parentProp->type || $childProp->class !== $parentProp->class) { $this->fatalError($classStmt, "Declaration of `{$className}::\${$name}` must be compatible " . "with `{$parentClass}::\${$name}`"); } - if (($childProp->flags & Modifiers::VISIBILITY_MASK) !== ($parentProp->flags & Modifiers::VISIBILITY_MASK)) { + if ($this->getVisibilityRank($childProp->flags) < $this->getVisibilityRank($parentProp->flags)) { $this->fatalError($classStmt, "Declaration of `{$className}::\${$name}` must be compatible " . "with `{$parentClass}::\${$name}`"); @@ -3455,12 +3459,15 @@ CODE; foreach ($this->classDef->constants as $name => $childConst) { if ($chainNode->hasConstant($name)) { $parentConst = $chainNode->getConstant($name); + if ($parentConst->flags & Modifiers::PRIVATE) { + continue; + } if ($childConst->type !== $parentConst->type || $childConst->class !== $parentConst->class) { $this->fatalError($classStmt, "Declaration of `{$className}::{$name}` must be compatible " . "with `{$parentClass}::{$name}`"); } - if (($childConst->flags & Modifiers::VISIBILITY_MASK) !== ($parentConst->flags & Modifiers::VISIBILITY_MASK)) { + if ($this->getVisibilityRank($childConst->flags) < $this->getVisibilityRank($parentConst->flags)) { $this->fatalError($classStmt, "Declaration of `{$className}::{$name}` must be compatible " . "with `{$parentClass}::{$name}`"); From 0c9a4495367ed1a31ca72c4b2b7bf52675dcb467 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 11:27:23 +0800 Subject: [PATCH 19/37] =?UTF-8?q?test(array):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=95=B0=E7=BB=84=E5=87=BD=E6=95=B0=E6=B5=8B=E8=AF=95=E7=94=A8?= =?UTF-8?q?=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/std/array/009.phpt | 408 +++++ tests/std/array/array_all_basic.phpt | 59 + tests/std/array/array_any_basic.phpt | 51 + tests/std/array/array_change_key_case.phpt | 811 ++++++++++ .../array_change_key_case_variation.phpt | 50 + .../array_change_key_case_variation3.phpt | 167 ++ .../array_change_key_case_variation4.phpt | 132 ++ .../array_change_key_case_variation5.phpt | 40 + .../array_change_key_case_variation6.phpt | 66 + .../array_change_key_case_variation7.phpt | 57 + .../array_change_key_case_variation8.phpt | 124 ++ tests/std/array/array_chunk2.phpt | 154 ++ tests/std/array/array_chunk_basic1.phpt | 132 ++ tests/std/array/array_chunk_basic2.phpt | 216 +++ tests/std/array/array_chunk_variation10.phpt | 154 ++ tests/std/array/array_chunk_variation11.phpt | 88 + tests/std/array/array_chunk_variation12.phpt | 154 ++ tests/std/array/array_chunk_variation13.phpt | 87 + tests/std/array/array_chunk_variation14.phpt | 154 ++ tests/std/array/array_chunk_variation15.phpt | 154 ++ tests/std/array/array_chunk_variation16.phpt | 233 +++ tests/std/array/array_chunk_variation17.phpt | 233 +++ tests/std/array/array_chunk_variation18.phpt | 333 ++++ tests/std/array/array_chunk_variation19.phpt | 1013 ++++++++++++ tests/std/array/array_chunk_variation20.phpt | 1194 ++++++++++++++ tests/std/array/array_chunk_variation21.phpt | 41 + tests/std/array/array_chunk_variation22.phpt | 87 + tests/std/array/array_chunk_variation23.phpt | 436 +++++ tests/std/array/array_chunk_variation24.phpt | 41 + tests/std/array/array_chunk_variation25.phpt | 436 +++++ tests/std/array/array_chunk_variation26.phpt | 41 + tests/std/array/array_chunk_variation27.phpt | 41 + tests/std/array/array_chunk_variation28.phpt | 41 + tests/std/array/array_chunk_variation29.phpt | 87 + tests/std/array/array_chunk_variation30.phpt | 154 ++ tests/std/array/array_chunk_variation31.phpt | 41 + tests/std/array/array_chunk_variation32.phpt | 41 + tests/std/array/array_chunk_variation4.phpt | 114 ++ tests/std/array/array_chunk_variation5.phpt | 140 ++ tests/std/array/array_chunk_variation6.phpt | 129 ++ tests/std/array/array_chunk_variation7.phpt | 85 + tests/std/array/array_chunk_variation8.phpt | 41 + tests/std/array/array_chunk_variation9.phpt | 87 + tests/std/array/array_column_basic.phpt | 259 +++ .../array_column_numeric_string_key.phpt | 23 + tests/std/array/array_column_object_cast.phpt | 38 + .../array_column_property_visibility.phpt | 31 + ...rray_column_scalar_index_strict_types.phpt | 66 + .../array_column_scalar_index_weak_types.phpt | 83 + tests/std/array/array_column_variant.phpt | 86 + .../array/array_column_variant_objects.phpt | 142 ++ tests/std/array/array_combine.phpt | 155 ++ tests/std/array/array_combine_basic.phpt | 46 + tests/std/array/array_combine_error2.phpt | 48 + tests/std/array/array_combine_variation3.phpt | 275 ++++ tests/std/array/array_combine_variation4.phpt | 150 ++ tests/std/array/array_combine_variation5.phpt | 172 ++ tests/std/array/array_combine_variation6.phpt | 47 + tests/std/array/array_count_values.phpt | 94 ++ tests/std/array/array_count_values2.phpt | 43 + .../array/array_count_values_variation.phpt | 41 + tests/std/array/array_diff_1.phpt | 19 + tests/std/array/array_diff_assoc.phpt | 46 + tests/std/array/array_diff_assoc_basic.phpt | 84 + .../array/array_diff_assoc_variation1.phpt | 179 +++ .../array/array_diff_assoc_variation10.phpt | 43 + .../array/array_diff_assoc_variation2.phpt | 179 +++ .../array/array_diff_assoc_variation3.phpt | 165 ++ .../array/array_diff_assoc_variation4.phpt | 156 ++ .../array/array_diff_assoc_variation5.phpt | 141 ++ .../array/array_diff_assoc_variation6.phpt | 192 +++ .../array/array_diff_assoc_variation7.phpt | 97 ++ .../array/array_diff_assoc_variation8.phpt | 42 + .../array/array_diff_assoc_variation9.phpt | 134 ++ tests/std/array/array_diff_basic.phpt | 110 ++ tests/std/array/array_diff_key.phpt | 286 ++++ tests/std/array/array_diff_key2.phpt | 44 + tests/std/array/array_diff_key_basic.phpt | 18 + .../std/array/array_diff_key_variation1.phpt | 196 +++ .../std/array/array_diff_key_variation2.phpt | 196 +++ .../std/array/array_diff_key_variation4.phpt | 54 + .../std/array/array_diff_key_variation6.phpt | 30 + .../std/array/array_diff_key_variation7.phpt | 57 + .../std/array/array_diff_key_variation8.phpt | 47 + tests/std/array/array_diff_single_array.phpt | 50 + tests/std/array/array_diff_uassoc_basic.phpt | 32 + tests/std/array/array_diff_uassoc_error.phpt | 50 + .../array/array_diff_uassoc_variation1.phpt | 174 ++ .../array/array_diff_uassoc_variation11.phpt | 38 + .../array/array_diff_uassoc_variation12.phpt | 57 + .../array/array_diff_uassoc_variation13.phpt | 65 + .../array/array_diff_uassoc_variation2.phpt | 174 ++ .../array/array_diff_uassoc_variation5.phpt | 30 + .../array/array_diff_uassoc_variation6.phpt | 48 + .../array/array_diff_uassoc_variation7.phpt | 38 + .../array/array_diff_uassoc_variation8.phpt | 52 + .../array/array_diff_uassoc_variation9.phpt | 54 + tests/std/array/array_diff_ukey_basic.phpt | 31 + .../std/array/array_diff_ukey_variation1.phpt | 203 +++ .../array/array_diff_ukey_variation10.phpt | 29 + .../std/array/array_diff_ukey_variation2.phpt | 204 +++ .../std/array/array_diff_ukey_variation5.phpt | 47 + .../std/array/array_diff_ukey_variation6.phpt | 53 + .../std/array/array_diff_ukey_variation8.phpt | 34 + .../std/array/array_diff_ukey_variation9.phpt | 57 + tests/std/array/array_diff_variation1.phpt | 153 ++ tests/std/array/array_diff_variation10.phpt | 38 + tests/std/array/array_diff_variation2.phpt | 153 ++ tests/std/array/array_diff_variation3.phpt | 189 +++ tests/std/array/array_diff_variation4.phpt | 183 +++ tests/std/array/array_diff_variation5.phpt | 113 ++ tests/std/array/array_diff_variation6.phpt | 40 + tests/std/array/array_diff_variation7.phpt | 92 ++ tests/std/array/array_diff_variation8.phpt | 198 +++ tests/std/array/array_diff_variation9.phpt | 118 ++ tests/std/array/array_fill.phpt | 345 ++++ tests/std/array/array_fill_basic.phpt | 91 ++ tests/std/array/array_fill_error.phpt | 21 + tests/std/array/array_fill_error2.phpt | 20 + tests/std/array/array_fill_keys.phpt | 40 + .../std/array/array_fill_keys_variation1.phpt | 73 + .../std/array/array_fill_keys_variation2.phpt | 72 + .../std/array/array_fill_keys_variation3.phpt | 28 + .../std/array/array_fill_keys_variation4.phpt | 82 + tests/std/array/array_fill_object.phpt | 403 +++++ tests/std/array/array_fill_variation3.phpt | 102 ++ tests/std/array/array_fill_variation4.phpt | 163 ++ tests/std/array/array_fill_variation5.phpt | 289 ++++ tests/std/array/array_fill_variation6.phpt | 21 + tests/std/array/array_filter.phpt | 77 + tests/std/array/array_filter_basic.phpt | 55 + tests/std/array/array_filter_object.phpt | 151 ++ tests/std/array/array_filter_variation10.phpt | 79 + tests/std/array/array_filter_variation3.phpt | 216 +++ tests/std/array/array_filter_variation4.phpt | 99 ++ tests/std/array/array_filter_variation5.phpt | 109 ++ tests/std/array/array_filter_variation6.phpt | 90 ++ tests/std/array/array_filter_variation7.phpt | 62 + tests/std/array/array_filter_variation8.phpt | 151 ++ tests/std/array/array_filter_variation9.phpt | 67 + tests/std/array/array_find_basic.phpt | 51 + tests/std/array/array_find_key_basic.phpt | 51 + tests/std/array/array_find_types.phpt | 210 +++ tests/std/array/array_flip.phpt | 37 + tests/std/array/array_flip_basic.phpt | 66 + tests/std/array/array_flip_variation2.phpt | 99 ++ tests/std/array/array_flip_variation3.phpt | 120 ++ tests/std/array/array_flip_variation4.phpt | 88 + tests/std/array/array_flip_variation5.phpt | 79 + tests/std/array/array_intersect_1.phpt | 370 +++++ .../array/array_intersect_assoc_basic.phpt | 63 + .../array_intersect_assoc_variation1.phpt | 183 +++ .../array_intersect_assoc_variation10.phpt | 48 + .../array_intersect_assoc_variation2.phpt | 182 +++ .../array_intersect_assoc_variation3.phpt | 237 +++ .../array_intersect_assoc_variation4.phpt | 248 +++ .../array_intersect_assoc_variation5.phpt | 139 ++ .../array_intersect_assoc_variation6.phpt | 139 ++ .../array_intersect_assoc_variation7.phpt | 191 +++ .../array_intersect_assoc_variation8.phpt | 191 +++ .../array_intersect_assoc_variation9.phpt | 146 ++ tests/std/array/array_intersect_basic.phpt | 75 + tests/std/array/array_intersect_key.phpt | 228 +++ .../std/array/array_intersect_key_basic.phpt | 18 + .../array/array_intersect_key_variation1.phpt | 199 +++ .../array/array_intersect_key_variation2.phpt | 199 +++ .../array/array_intersect_key_variation4.phpt | 53 + .../array/array_intersect_key_variation6.phpt | 31 + .../array/array_intersect_key_variation7.phpt | 61 + .../array/array_intersect_key_variation8.phpt | 57 + .../array/array_intersect_uassoc_basic.phpt | 28 + .../array_intersect_uassoc_variation1.phpt | 207 +++ .../array_intersect_uassoc_variation10.phpt | 48 + .../array_intersect_uassoc_variation2.phpt | 207 +++ .../array_intersect_uassoc_variation5.phpt | 49 + .../array_intersect_uassoc_variation6.phpt | 38 + .../array_intersect_uassoc_variation7.phpt | 45 + .../array_intersect_uassoc_variation8.phpt | 49 + .../std/array/array_intersect_ukey_basic.phpt | 31 + .../array_intersect_ukey_variation1.phpt | 205 +++ .../array_intersect_ukey_variation2.phpt | 205 +++ .../array_intersect_ukey_variation5.phpt | 55 + .../array_intersect_ukey_variation6.phpt | 44 + .../array_intersect_ukey_variation7.phpt | 55 + .../array_intersect_ukey_variation8.phpt | 29 + .../array_intersect_ukey_variation9.phpt | 53 + .../std/array/array_intersect_variation1.phpt | 182 +++ .../array/array_intersect_variation10.phpt | 48 + .../std/array/array_intersect_variation2.phpt | 182 +++ .../std/array/array_intersect_variation3.phpt | 340 ++++ .../std/array/array_intersect_variation4.phpt | 347 ++++ .../std/array/array_intersect_variation5.phpt | 159 ++ .../std/array/array_intersect_variation6.phpt | 159 ++ .../std/array/array_intersect_variation7.phpt | 196 +++ .../std/array/array_intersect_variation8.phpt | 204 +++ .../std/array/array_intersect_variation9.phpt | 238 +++ tests/std/array/array_key_exists.phpt | 197 +++ tests/std/array/array_key_exists_basic.phpt | 23 + .../array/array_key_exists_variation1.phpt | 154 ++ .../array/array_key_exists_variation3.phpt | 59 + .../array/array_key_exists_variation4.phpt | 24 + .../array/array_key_exists_variation5.phpt | 32 + .../array/array_key_exists_variation6.phpt | 94 ++ .../array/array_key_exists_variation7.phpt | 29 + .../array/array_key_exists_variation8.phpt | 391 +++++ tests/std/array/array_key_first.phpt | 296 ++++ .../std/array/array_key_first_variation.phpt | 36 + tests/std/array/array_key_last.phpt | 296 ++++ tests/std/array/array_key_last_variation.phpt | 36 + tests/std/array/array_keys_basic.phpt | 27 + tests/std/array/array_keys_on_GLOBALS.phpt | 17 + tests/std/array/array_keys_variation_001.phpt | 149 ++ tests/std/array/array_keys_variation_002.phpt | 24 + tests/std/array/array_keys_variation_003.phpt | 114 ++ tests/std/array/array_keys_variation_004.phpt | 73 + tests/std/array/array_keys_variation_005.phpt | 45 + tests/std/array/array_map_001.phpt | 24 + tests/std/array/array_map_basic.phpt | 62 + tests/std/array/array_map_error.phpt | 58 + tests/std/array/array_map_object1.phpt | 195 +++ tests/std/array/array_map_object2.phpt | 46 + tests/std/array/array_map_object3.phpt | 90 ++ tests/std/array/array_map_variation1.phpt | 55 + tests/std/array/array_map_variation10.phpt | 89 ++ tests/std/array/array_map_variation11.phpt | 46 + tests/std/array/array_map_variation12.phpt | 48 + tests/std/array/array_map_variation13.phpt | 97 ++ tests/std/array/array_map_variation14.phpt | 129 ++ tests/std/array/array_map_variation15.phpt | 27 + tests/std/array/array_map_variation16.phpt | 38 + tests/std/array/array_map_variation17.phpt | 133 ++ tests/std/array/array_map_variation19.phpt | 35 + tests/std/array/array_map_variation2.phpt | 134 ++ tests/std/array/array_map_variation3.phpt | 234 +++ tests/std/array/array_map_variation4.phpt | 147 ++ tests/std/array/array_map_variation5.phpt | 169 ++ tests/std/array/array_map_variation6.phpt | 60 + tests/std/array/array_map_variation7.phpt | 101 ++ tests/std/array/array_map_variation8.phpt | 65 + tests/std/array/array_map_variation9.phpt | 50 + tests/std/array/array_merge.phpt | 914 +++++++++++ tests/std/array/array_merge_basic.phpt | 52 + .../array/array_merge_recursive_basic1.phpt | 99 ++ .../array/array_merge_recursive_basic2.phpt | 89 ++ .../array_merge_recursive_variation1.phpt | 205 +++ .../array_merge_recursive_variation10.phpt | 169 ++ .../array_merge_recursive_variation2.phpt | 148 ++ .../array_merge_recursive_variation3.phpt | 758 +++++++++ .../array_merge_recursive_variation4.phpt | 330 ++++ .../array_merge_recursive_variation5.phpt | 392 +++++ .../array_merge_recursive_variation6.phpt | 108 ++ .../array_merge_recursive_variation7.phpt | 79 + .../array_merge_recursive_variation8.phpt | 68 + .../array_merge_recursive_variation9.phpt | 112 ++ .../array_merge_replace_recursive_refs.phpt | 38 + tests/std/array/array_merge_variation1.phpt | 102 ++ tests/std/array/array_merge_variation10.phpt | 64 + tests/std/array/array_merge_variation2.phpt | 179 +++ tests/std/array/array_merge_variation3.phpt | 336 ++++ tests/std/array/array_merge_variation4.phpt | 308 ++++ tests/std/array/array_merge_variation5.phpt | 57 + tests/std/array/array_merge_variation6.phpt | 47 + tests/std/array/array_merge_variation7.phpt | 61 + tests/std/array/array_merge_variation8.phpt | 68 + tests/std/array/array_merge_variation9.phpt | 95 ++ tests/std/array/array_multisort_basic1.phpt | 53 + tests/std/array/array_multisort_basic2.phpt | 38 + tests/std/array/array_multisort_case.phpt | 67 + tests/std/array/array_multisort_error.phpt | 32 + tests/std/array/array_multisort_incase.phpt | 67 + tests/std/array/array_multisort_natural.phpt | 55 + .../array/array_multisort_natural_case.phpt | 67 + .../array/array_multisort_natural_incase.phpt | 67 + .../std/array/array_multisort_stability.phpt | 15 + .../std/array/array_multisort_variation1.phpt | 167 ++ .../array/array_multisort_variation10.phpt | 14 + .../array/array_multisort_variation11.phpt | 14 + .../std/array/array_multisort_variation2.phpt | 186 +++ .../std/array/array_multisort_variation3.phpt | 168 ++ .../std/array/array_multisort_variation4.phpt | 52 + .../std/array/array_multisort_variation5.phpt | 47 + .../std/array/array_multisort_variation6.phpt | 47 + .../std/array/array_multisort_variation7.phpt | 55 + .../std/array/array_multisort_variation8.phpt | 58 + .../std/array/array_multisort_variation9.phpt | 63 + tests/std/array/array_next_error1.phpt | 18 + tests/std/array/array_next_error2.phpt | 20 + tests/std/array/array_pad.phpt | 80 + .../array/array_pad_too_large_padding.phpt | 21 + tests/std/array/array_pad_variation3.phpt | 864 ++++++++++ tests/std/array/array_pad_variation4.phpt | 55 + tests/std/array/array_pad_variation5.phpt | 135 ++ tests/std/array/array_pad_variation6.phpt | 665 ++++++++ tests/std/array/array_pad_variation7.phpt | 122 ++ tests/std/array/array_pop.phpt | 277 ++++ tests/std/array/array_pop_variation.phpt | 55 + .../std/array/array_product_empty_array.phpt | 17 + ...ray_product_objects_operation_no_cast.phpt | 28 + tests/std/array/array_product_variation1.phpt | 56 + tests/std/array/array_product_variation2.phpt | 14 + tests/std/array/array_product_variation3.phpt | 40 + tests/std/array/array_product_variation4.phpt | 21 + tests/std/array/array_product_variation5.phpt | 24 + tests/std/array/array_product_variation6.phpt | 22 + tests/std/array/array_push.phpt | 320 ++++ tests/std/array/array_push_basic.phpt | 57 + tests/std/array/array_push_empty.phpt | 25 + tests/std/array/array_push_error2.phpt | 27 + tests/std/array/array_push_variation2.phpt | 171 ++ tests/std/array/array_push_variation3.phpt | 65 + tests/std/array/array_push_variation5.phpt | 30 + tests/std/array/array_push_variation6.phpt | 138 ++ tests/std/array/array_rand.phpt | 59 + tests/std/array/array_rand_basic1.phpt | 47 + tests/std/array/array_rand_basic2.phpt | 52 + tests/std/array/array_rand_variation3.phpt | 144 ++ tests/std/array/array_rand_variation4.phpt | 163 ++ tests/std/array/array_rand_variation5.phpt | 76 + tests/std/array/array_rand_variation6.phpt | 98 ++ tests/std/array/array_reduce.phpt | 90 ++ .../std/array/array_reduce_return_by_ref.phpt | 11 + tests/std/array/array_reduce_variation1.phpt | 37 + tests/std/array/array_reduce_variation3.phpt | 33 + tests/std/array/array_replace.phpt | 114 ++ .../array_replace_merge_recursive_ref.phpt | 31 + tests/std/array/array_reverse_basic1.phpt | 67 + tests/std/array/array_reverse_basic2.phpt | 55 + tests/std/array/array_reverse_variation3.phpt | 605 +++++++ tests/std/array/array_reverse_variation4.phpt | 317 ++++ tests/std/array/array_reverse_variation5.phpt | 389 +++++ tests/std/array/array_reverse_variation6.phpt | 204 +++ tests/std/array/array_search.phpt | 29 + tests/std/array/array_search1.phpt | 28 + tests/std/array/array_search_variation1.phpt | 635 ++++++++ tests/std/array/array_search_variation2.phpt | 98 ++ tests/std/array/array_search_variation3.phpt | 55 + tests/std/array/array_search_variation4.phpt | 68 + tests/std/array/array_shift_basic.phpt | 49 + tests/std/array/array_shift_variation2.phpt | 165 ++ tests/std/array/array_shift_variation3.phpt | 160 ++ tests/std/array/array_shift_variation4.phpt | 104 ++ tests/std/array/array_shift_variation5.phpt | 42 + tests/std/array/array_shift_variation6.phpt | 80 + tests/std/array/array_shift_variation7.phpt | 29 + tests/std/array/array_shift_variation8.phpt | 50 + tests/std/array/array_shuffle_basic.phpt | 98 ++ tests/std/array/array_slice.phpt | 1419 +++++++++++++++++ tests/std/array/array_slice_basic.phpt | 45 + tests/std/array/array_slice_variation1.phpt | 66 + tests/std/array/array_slice_variation10.phpt | 38 + tests/std/array/array_slice_variation11.phpt | 99 ++ tests/std/array/array_slice_variation5.phpt | 185 +++ tests/std/array/array_slice_variation6.phpt | 144 ++ tests/std/array/array_slice_variation7.phpt | 251 +++ tests/std/array/array_slice_variation8.phpt | 50 + tests/std/array/array_slice_variation9.phpt | 46 + tests/std/array/array_splice_basic.phpt | 135 ++ tests/std/array/array_splice_variation1.phpt | 113 ++ tests/std/array/array_splice_variation3.phpt | 844 ++++++++++ tests/std/array/array_splice_variation4.phpt | 66 + tests/std/array/array_sum.phpt | 30 + tests/std/array/array_sum_basic.phpt | 32 + tests/std/array/array_sum_empty_array.phpt | 17 + .../array_sum_objects_operation_no_cast.phpt | 26 + ...ray_sum_objects_operation_no_cast_FFI.phpt | 29 + tests/std/array/array_sum_on_reference.phpt | 15 + tests/std/array/array_sum_variation2.phpt | 44 + tests/std/array/array_sum_variation3.phpt | 49 + tests/std/array/array_sum_variation4.phpt | 29 + tests/std/array/array_sum_variation5.phpt | 32 + tests/std/array/array_sum_variation6.phpt | 28 + tests/std/array/array_sum_variation7.phpt | 110 ++ tests/std/array/array_sum_variation8.phpt | 24 + tests/std/array/array_sum_variation9.phpt | 22 + tests/std/array/array_udiff_assoc_basic.phpt | 48 + .../array/array_udiff_assoc_variation.phpt | 29 + .../array/array_udiff_assoc_variation1.phpt | 161 ++ .../array/array_udiff_assoc_variation2.phpt | 161 ++ .../array/array_udiff_assoc_variation5.phpt | 56 + tests/std/array/array_udiff_basic.phpt | 43 + tests/std/array/array_udiff_uassoc_basic.phpt | 55 + .../array/array_udiff_uassoc_variation1.phpt | 160 ++ .../array/array_udiff_uassoc_variation2.phpt | 162 ++ .../array/array_udiff_uassoc_variation6.phpt | 56 + tests/std/array/array_udiff_variation1.phpt | 161 ++ tests/std/array/array_udiff_variation2.phpt | 161 ++ tests/std/array/array_udiff_variation5.phpt | 53 + .../array/array_uintersect_assoc_basic.phpt | 43 + .../array/array_uintersect_assoc_basic2.phpt | 29 + .../array_uintersect_assoc_variation1.phpt | 161 ++ .../array_uintersect_assoc_variation2.phpt | 161 ++ .../array_uintersect_assoc_variation5.phpt | 51 + tests/std/array/array_uintersect_basic.phpt | 48 + .../array/array_uintersect_uassoc_basic.phpt | 50 + .../array_uintersect_uassoc_variation1.phpt | 162 ++ .../array_uintersect_uassoc_variation2.phpt | 162 ++ .../array_uintersect_uassoc_variation6.phpt | 50 + .../array/array_uintersect_variation1.phpt | 161 ++ .../array/array_uintersect_variation2.phpt | 161 ++ .../array/array_uintersect_variation5.phpt | 51 + tests/std/array/array_unique_basic.phpt | 43 + tests/std/array/array_unique_variation2.phpt | 229 +++ tests/std/array/array_unique_variation3.phpt | 109 ++ tests/std/array/array_unique_variation4.phpt | 106 ++ tests/std/array/array_unique_variation5.phpt | 28 + tests/std/array/array_unique_variation6.phpt | 41 + tests/std/array/array_unique_variation7.phpt | 28 + tests/std/array/array_unique_variation8.phpt | 47 + tests/std/array/array_unique_variation9.phpt | 109 ++ tests/std/array/array_unshift.phpt | 31 + tests/std/array/array_unshift_basic1.phpt | 58 + tests/std/array/array_unshift_basic2.phpt | 66 + tests/std/array/array_unshift_empty.phpt | 25 + tests/std/array/array_unshift_object.phpt | 273 ++++ tests/std/array/array_unshift_variation2.phpt | 1048 ++++++++++++ tests/std/array/array_unshift_variation3.phpt | 568 +++++++ tests/std/array/array_unshift_variation4.phpt | 316 ++++ tests/std/array/array_unshift_variation5.phpt | 383 +++++ tests/std/array/array_unshift_variation6.phpt | 191 +++ tests/std/array/array_unshift_variation7.phpt | 211 +++ tests/std/array/array_unshift_variation8.phpt | 209 +++ tests/std/array/array_unshift_variation9.phpt | 304 ++++ tests/std/array/array_user_key_compare.phpt | 27 + tests/std/array/array_values.phpt | 233 +++ tests/std/array/array_values_basic.phpt | 34 + tests/std/array/array_values_variation.phpt | 76 + tests/std/array/array_values_variation2.phpt | 173 ++ tests/std/array/array_values_variation3.phpt | 169 ++ tests/std/array/array_values_variation4.phpt | 93 ++ tests/std/array/array_values_variation5.phpt | 40 + tests/std/array/array_values_variation6.phpt | 50 + tests/std/array/array_values_variation7.phpt | 49 + .../array/array_values_variation_64bit.phpt | 74 + tests/std/array/array_walk.phpt | 38 + tests/std/array/array_walk_basic1.phpt | 75 + tests/std/array/array_walk_basic2.phpt | 91 ++ tests/std/array/array_walk_closure.phpt | 247 +++ tests/std/array/array_walk_error2.phpt | 64 + tests/std/array/array_walk_object1.phpt | 56 + tests/std/array/array_walk_object2.phpt | 94 ++ tests/std/array/array_walk_objects.phpt | 46 + tests/std/array/array_walk_rec_objects.phpt | 46 + tests/std/array/array_walk_recursive.phpt | 29 + tests/std/array/array_walk_recursive1.phpt | 44 + .../array/array_walk_recursive_basic1.phpt | 75 + .../array/array_walk_recursive_basic2.phpt | 91 ++ .../array/array_walk_recursive_error2.phpt | 64 + .../array/array_walk_recursive_object1.phpt | 55 + .../array/array_walk_recursive_object2.phpt | 96 ++ .../array_walk_recursive_variation3.phpt | 116 ++ .../array_walk_recursive_variation4.phpt | 67 + .../array_walk_recursive_variation5.phpt | 59 + .../array_walk_recursive_variation6.phpt | 127 ++ .../array_walk_recursive_variation7.phpt | 81 + .../array_walk_recursive_variation8.phpt | 39 + .../array_walk_recursive_variation9.phpt | 101 ++ tests/std/array/array_walk_variation3.phpt | 116 ++ tests/std/array/array_walk_variation4.phpt | 78 + tests/std/array/array_walk_variation5.phpt | 59 + tests/std/array/array_walk_variation6.phpt | 123 ++ tests/std/array/array_walk_variation7.phpt | 81 + tests/std/array/array_walk_variation8.phpt | 39 + tests/std/array/array_walk_variation9.phpt | 101 ++ tests/std/array/arsort_basic.phpt | 239 +++ tests/std/array/arsort_object1.phpt | 220 +++ tests/std/array/arsort_object2.phpt | 232 +++ tests/std/array/arsort_variation10.phpt | 108 ++ tests/std/array/arsort_variation11.phpt | 155 ++ tests/std/array/arsort_variation3.phpt | 320 ++++ tests/std/array/arsort_variation4.phpt | 78 + tests/std/array/arsort_variation5.phpt | 236 +++ tests/std/array/arsort_variation6.phpt | 108 ++ tests/std/array/arsort_variation7.phpt | 92 ++ tests/std/array/arsort_variation8.phpt | 174 ++ tests/std/array/arsort_variation9.phpt | 252 +++ tests/std/array/asort_basic.phpt | 239 +++ tests/std/array/asort_object1.phpt | 220 +++ tests/std/array/asort_object2.phpt | 232 +++ tests/std/array/asort_stability.phpt | 12 + tests/std/array/asort_variation10.phpt | 108 ++ tests/std/array/asort_variation11.phpt | 155 ++ tests/std/array/asort_variation3.phpt | 320 ++++ tests/std/array/asort_variation4.phpt | 78 + tests/std/array/asort_variation5.phpt | 236 +++ tests/std/array/asort_variation6.phpt | 108 ++ tests/std/array/asort_variation7.phpt | 92 ++ tests/std/array/asort_variation8.phpt | 174 ++ tests/std/array/asort_variation9.phpt | 252 +++ tests/std/array/bug12776.phpt | 31 + tests/std/array/bug14580.phpt | 11 + tests/std/array/bug20381.phpt | 79 + tests/std/array/bug20865.phpt | 13 + tests/std/array/bug21918.phpt | 53 + tests/std/array/bug21998.phpt | 24 + tests/std/array/bug22088.phpt | 33 + tests/std/array/bug22463.phpt | 20 + tests/std/array/bug23581.phpt | 43 + tests/std/array/bug23788.phpt | 26 + tests/std/array/bug24198.phpt | 25 + tests/std/array/bug24766.phpt | 45 + tests/std/array/bug24897.phpt | 21 + tests/std/array/bug24980.phpt | 52 + tests/std/array/bug25359.phpt | 31 + tests/std/array/bug25708.phpt | 230 +++ tests/std/array/bug25758.phpt | 14 + tests/std/array/bug26458.phpt | 20 + tests/std/array/bug28739.phpt | 71 + tests/std/array/bug28974.phpt | 89 ++ tests/std/array/bug29253.phpt | 22 + tests/std/array/bug29493.phpt | 108 ++ tests/std/array/bug30074.phpt | 20 + tests/std/array/bug30266.phpt | 32 + tests/std/array/bug30833.phpt | 35 + tests/std/array/bug31158.phpt | 27 + tests/std/array/bug31213.phpt | 56 + tests/std/array/bug33382.phpt | 27 + tests/std/array/bug33989.phpt | 15 + tests/std/array/bug34066.phpt | 574 +++++++ tests/std/array/bug34066_1.phpt | 501 ++++++ tests/std/array/bug34227.phpt | 85 + tests/std/array/bug34982.phpt | 39 + tests/std/array/bug35014.phpt | 28 + tests/std/array/bug35014_64bit.phpt | 30 + tests/std/array/bug35022.phpt | 27 + tests/std/array/bug35821.phpt | 32 + tests/std/array/bug36975.phpt | 62 + tests/std/array/bug38464.phpt | 20 + tests/std/array/bug39576.phpt | 53 + tests/std/array/bug40191.phpt | 21 + tests/std/array/bug40709.phpt | 29 + tests/std/array/bug41686.phpt | 56 + tests/std/array/bug42177.phpt | 40 + tests/std/array/bug42233.phpt | 38 + tests/std/array/bug42838.phpt | 23 + tests/std/array/bug42850.phpt | 64 + tests/std/array/bug43495.phpt | 24 + tests/std/array/bug43505.phpt | 40 + tests/std/array/bug43541.phpt | 22 + tests/std/array/bug44181.phpt | 23 + tests/std/array/bug44182.phpt | 23 + tests/std/array/bug44929.phpt | 35 + tests/std/array/bug45312.phpt | 52 + tests/std/array/bug46873.phpt | 17 + tests/std/array/bug48224.phpt | 15 + tests/std/array/bug48854.phpt | 43 + tests/std/array/bug50006.phpt | 30 + tests/std/array/bug50006_1.phpt | 30 + tests/std/array/bug50006_2.phpt | 30 + tests/std/array/bug51552.phpt | 26 + tests/std/array/bug52534.phpt | 14 + tests/std/array/bug52719.phpt | 23 + tests/std/array/bug61058.phpt | 15 + tests/std/array/bug61730.phpt | 37 + tests/std/array/bug61967.phpt | 30 + tests/std/array/bug62607.phpt | 17 + tests/std/array/bug65251.phpt | 24 + tests/std/array/bug65304.phpt | 10 + tests/std/array/bug67693.phpt | 25 + tests/std/array/bug68553.phpt | 85 + tests/std/array/bug69068.phpt | 28 + tests/std/array/bug69068_2.phpt | 39 + tests/std/array/bug69166.phpt | 17 + tests/std/array/bug69198.phpt | 19 + tests/std/array/bug69299.phpt | 18 + tests/std/array/bug69371.phpt | 23 + tests/std/array/bug69413.phpt | 18 + tests/std/array/bug69674.phpt | 8 + tests/std/array/bug69723.phpt | 32 + tests/std/array/bug70250.phpt | 26 + tests/std/array/bug70668.phpt | 63 + tests/std/array/bug70713.phpt | 29 + tests/std/array/bug70808.phpt | 23 + tests/std/array/bug70910.phpt | 19 + tests/std/array/bug71220.phpt | 13 + tests/std/array/bug71334.phpt | 31 + tests/std/array/bug71603.phpt | 15 + tests/std/array/bug71660.phpt | 18 + tests/std/array/bug71837.phpt | 27 + tests/std/array/bug72031.phpt | 39 + tests/std/array/bug72116.phpt | 17 + tests/std/array/bug72369.phpt | 18 + tests/std/array/bug72622.phpt | 37 + tests/std/array/bug74345.phpt | 49 + tests/std/array/bug74361.phpt | 11 + tests/std/array/bug74361_2.phpt | 24 + tests/std/array/bug75433.phpt | 18 + tests/std/array/bug75653.phpt | 20 + tests/std/array/bug76505.phpt | 33 + tests/std/array/bug76713.phpt | 35 + tests/std/array/bug76778.phpt | 20 + tests/std/array/bug77135.phpt | 91 ++ tests/std/array/bug77395.phpt | 27 + tests/std/array/bug77669.phpt | 39 + tests/std/array/bug77793.phpt | 23 + tests/std/array/bug77931.phpt | 26 + tests/std/array/bug78759.phpt | 20 + tests/std/array/bug79839.phpt | 33 + tests/std/array/bug79868.phpt | 15 + tests/std/array/bug79930.phpt | 33 + tests/std/array/compact.phpt | 42 + tests/std/array/compact_basic.phpt | 78 + tests/std/array/compact_no_this.phpt | 27 + tests/std/array/compact_order.phpt | 25 + tests/std/array/compact_this.phpt | 46 + tests/std/array/compact_variation1.phpt | 46 + tests/std/array/compact_variation2.phpt | 42 + tests/std/array/compare_function.inc | 13 + tests/std/array/count_basic.phpt | 40 + tests/std/array/count_invalid.phpt | 56 + tests/std/array/count_invalid_mode.phpt | 34 + tests/std/array/count_recursive.phpt | 131 ++ tests/std/array/count_symbol_table.phpt | 25 + tests/std/array/count_variation3.phpt | 34 + tests/std/array/current_basic.phpt | 25 + tests/std/array/current_variation2.phpt | 112 ++ tests/std/array/current_variation3.phpt | 34 + tests/std/array/current_variation4.phpt | 63 + tests/std/array/current_variation5.phpt | 43 + tests/std/array/current_variation6.phpt | 20 + tests/std/array/data.inc | 13 + tests/std/array/end.phpt | 177 ++ tests/std/array/end_64bit.phpt | 173 ++ tests/std/array/end_basic.phpt | 39 + tests/std/array/end_variation2.phpt | 36 + tests/std/array/end_variation3.phpt | 34 + tests/std/array/extract_error.phpt | 41 + tests/std/array/extract_error_variation1.phpt | 19 + tests/std/array/extract_safety.phpt | 28 + tests/std/array/extract_typed_ref.phpt | 31 + tests/std/array/extract_variation1.phpt | 31 + tests/std/array/extract_variation10.phpt | 18 + tests/std/array/extract_variation11.phpt | 18 + tests/std/array/extract_variation2.phpt | 74 + tests/std/array/extract_variation3.phpt | 74 + tests/std/array/extract_variation4.phpt | 74 + tests/std/array/extract_variation5.phpt | 62 + tests/std/array/extract_variation6.phpt | 33 + tests/std/array/extract_variation7.phpt | 28 + tests/std/array/extract_variation8.phpt | 30 + tests/std/array/extract_variation9.phpt | 26 + tests/std/array/gh14140.phpt | 24 + tests/std/array/gh14775.phpt | 17 + tests/std/array/gh15982.phpt | 11 + tests/std/array/gh16053.phpt | 29 + .../array_splice_normal_destructor.phpt | 22 + .../array_splice_uaf_add_elements.phpt | 24 + .../array_splice_uaf_array_deallocated.phpt | 24 + ...array_splice_uaf_complex_modification.phpt | 27 + ...array_splice_uaf_multiple_destructors.phpt | 35 + .../array_splice_uaf_original_case.phpt | 31 + .../array_splice_uaf_packed_to_hash.phpt | 25 + .../array_splice_with_replacement.phpt | 25 + tests/std/array/gh16905.phpt | 89 ++ tests/std/array/gh16957.phpt | 43 + tests/std/array/gh17447.phpt | 12 + tests/std/array/gh17977.phpt | 18 + tests/std/array/gh18480.phpt | 45 + tests/std/array/gh19300_1.phpt | 42 + tests/std/array/gh19300_2.phpt | 39 + tests/std/array/gh19926.phpt | 25 + tests/std/array/gh19926_pointer.phpt | 19 + tests/std/array/gh20043.phpt | 12 + tests/std/array/gh9244.phpt | 11 + tests/std/array/gh9296.phpt | 17 + tests/std/array/in_array_variation1.phpt | 635 ++++++++ tests/std/array/in_array_variation2.phpt | 95 ++ tests/std/array/in_array_variation3.phpt | 56 + tests/std/array/in_array_variation4.phpt | 70 + tests/std/array/in_array_with_ref.phpt | 14 + tests/std/array/key_basic.phpt | 40 + tests/std/array/key_exists_basic.phpt | 16 + tests/std/array/key_exists_variation1.phpt | 16 + tests/std/array/key_exists_variation2.phpt | 64 + tests/std/array/key_variation2.phpt | 132 ++ tests/std/array/key_variation3.phpt | 36 + tests/std/array/key_variation4.phpt | 56 + tests/std/array/krsort_basic.phpt | 240 +++ tests/std/array/krsort_object.phpt | 220 +++ tests/std/array/krsort_variation10.phpt | 93 ++ tests/std/array/krsort_variation11.phpt | 77 + tests/std/array/krsort_variation3.phpt | 204 +++ tests/std/array/krsort_variation4.phpt | 109 ++ tests/std/array/krsort_variation5.phpt | 227 +++ tests/std/array/krsort_variation6.phpt | 109 ++ tests/std/array/krsort_variation7.phpt | 172 ++ tests/std/array/krsort_variation8.phpt | 156 ++ tests/std/array/krsort_variation9.phpt | 252 +++ tests/std/array/ksort_basic.phpt | 238 +++ tests/std/array/ksort_object.phpt | 220 +++ tests/std/array/ksort_variation10.phpt | 108 ++ tests/std/array/ksort_variation11.phpt | 93 ++ tests/std/array/ksort_variation3.phpt | 204 +++ tests/std/array/ksort_variation4.phpt | 77 + tests/std/array/ksort_variation5.phpt | 227 +++ tests/std/array/ksort_variation6.phpt | 109 ++ tests/std/array/ksort_variation7.phpt | 172 ++ tests/std/array/ksort_variation8.phpt | 155 ++ tests/std/array/ksort_variation9.phpt | 251 +++ tests/std/array/locale_sort.phpt | 60 + tests/std/array/max.phpt | 45 + tests/std/array/max_basic.phpt | 40 + tests/std/array/max_basiclong_64bit.phpt | 33 + .../std/array/max_int_float_optimisation.phpt | 61 + tests/std/array/max_variation1.phpt | 35 + tests/std/array/max_variation2.phpt | 53 + tests/std/array/min.phpt | 45 + tests/std/array/min_basic.phpt | 35 + tests/std/array/min_basiclong_64bit.phpt | 33 + .../std/array/min_int_float_optimisation.phpt | 61 + tests/std/array/min_variation1.phpt | 35 + tests/std/array/min_variation2.phpt | 48 + tests/std/array/natcasesort_basic.phpt | 52 + tests/std/array/natcasesort_object1.phpt | 81 + tests/std/array/natcasesort_object2.phpt | 83 + tests/std/array/natcasesort_variation10.phpt | 46 + tests/std/array/natcasesort_variation11.phpt | 199 +++ tests/std/array/natcasesort_variation2.phpt | 185 +++ tests/std/array/natcasesort_variation3.phpt | 129 ++ tests/std/array/natcasesort_variation4.phpt | 81 + tests/std/array/natcasesort_variation5.phpt | 44 + tests/std/array/natcasesort_variation6.phpt | 53 + tests/std/array/natcasesort_variation7.phpt | 47 + tests/std/array/natcasesort_variation8.phpt | 41 + tests/std/array/natcasesort_variation9.phpt | 104 ++ tests/std/array/natsort_basic.phpt | 33 + tests/std/array/negative_index.phpt | 31 + .../std/array/negative_index_empty_array.phpt | 18 + tests/std/array/next_basic.phpt | 28 + tests/std/array/next_variation2.phpt | 38 + tests/std/array/packed_001.phpt | 85 + tests/std/array/prev_basic.phpt | 46 + tests/std/array/prev_error2.phpt | 26 + tests/std/array/prev_error3.phpt | 18 + tests/std/array/prev_variation2.phpt | 42 + tests/std/array/range/bug21182.phpt | 12 + tests/std/array/range/bug24220.phpt | 91 ++ tests/std/array/range/bug32021.phpt | 18 + tests/std/array/range/bug41121.phpt | 128 ++ tests/std/array/range/bug54459.phpt | 219 +++ tests/std/array/range/gh13094.phpt | 29 + tests/std/array/range/range_bug70239_0.phpt | 12 + tests/std/array/range/range_bug70239_1.phpt | 12 + tests/std/array/range/range_bug70239_2.phpt | 12 + tests/std/array/range/range_bug70239_3.phpt | 12 + tests/std/array/range/range_bug71132.phpt | 10 + tests/std/array/range/range_bug71197.phpt | 8 + tests/std/array/range/range_bug72017.phpt | 17 + .../range/range_inputs_float_NAN_values.phpt | 69 + .../array/range/range_inputs_float_basic.phpt | 149 ++ ...ge_inputs_float_small_step_exhaustion.phpt | 18 + .../array/range/range_inputs_int_basic.phpt | 189 +++ .../range_inputs_int_with_float_step.phpt | 17 + .../range/range_inputs_null_variations.phpt | 98 ++ .../range/range_inputs_numeric_basic.phpt | 74 + .../range/range_inputs_string_basic.phpt | 153 ++ .../range/range_inputs_string_digits.phpt | 97 ++ ...range_inputs_string_digits_float_step.phpt | 34 + .../range/range_inputs_string_invalid.phpt | 85 + .../range/range_inputs_string_numeric.phpt | 189 +++ .../range/range_inputs_string_variations.phpt | 148 ++ ...range_negative_step_decreasing_ranges.phpt | 33 + tests/std/array/range/range_step_errors.phpt | 134 ++ tests/std/array/range/range_variation1.phpt | 60 + .../array/range/range_variation1_64bit.phpt | 60 + tests/std/array/rcn_in_place.phpt | 57 + tests/std/array/reset_basic.phpt | 38 + tests/std/array/reset_variation2.phpt | 27 + tests/std/array/reset_variation3.phpt | 49 + tests/std/array/rsort_basic.phpt | 235 +++ tests/std/array/rsort_object1.phpt | 218 +++ tests/std/array/rsort_object2.phpt | 230 +++ tests/std/array/rsort_variation10.phpt | 102 ++ tests/std/array/rsort_variation11.phpt | 187 +++ tests/std/array/rsort_variation3.phpt | 319 ++++ tests/std/array/rsort_variation4.phpt | 62 + tests/std/array/rsort_variation5.phpt | 215 +++ tests/std/array/rsort_variation6.phpt | 114 ++ tests/std/array/rsort_variation7.phpt | 90 ++ tests/std/array/rsort_variation8.phpt | 174 ++ tests/std/array/rsort_variation9.phpt | 254 +++ tests/std/array/shuffle_basic1.phpt | 144 ++ tests/std/array/shuffle_basic2.phpt | 83 + tests/std/array/shuffle_variation2.phpt | 206 +++ tests/std/array/shuffle_variation3.phpt | 227 +++ tests/std/array/shuffle_variation4.phpt | 225 +++ tests/std/array/shuffle_variation5.phpt | 114 ++ tests/std/array/sizeof_basic2.phpt | 92 ++ tests/std/array/sizeof_object1.phpt | 39 + tests/std/array/sizeof_object2.phpt | 112 ++ tests/std/array/sizeof_variation2.phpt | 156 ++ tests/std/array/sizeof_variation3.phpt | 32 + tests/std/array/sort_basic.phpt | 240 +++ tests/std/array/sort_object1.phpt | 218 +++ tests/std/array/sort_object2.phpt | 230 +++ tests/std/array/sort_variation10.phpt | 106 ++ tests/std/array/sort_variation11.phpt | 185 +++ tests/std/array/sort_variation3.phpt | 322 ++++ tests/std/array/sort_variation4.phpt | 78 + tests/std/array/sort_variation5.phpt | 227 +++ tests/std/array/sort_variation6.phpt | 117 ++ tests/std/array/sort_variation7.phpt | 92 ++ tests/std/array/sort_variation8.phpt | 172 ++ tests/std/array/sort_variation9.phpt | 253 +++ tests/std/array/uasort_basic1.phpt | 106 ++ tests/std/array/uasort_basic2.phpt | 92 ++ tests/std/array/uasort_object1.phpt | 140 ++ tests/std/array/uasort_object2.phpt | 175 ++ tests/std/array/uasort_variation10.phpt | 68 + tests/std/array/uasort_variation11.phpt | 72 + tests/std/array/uasort_variation3.phpt | 127 ++ tests/std/array/uasort_variation4.phpt | 140 ++ tests/std/array/uasort_variation5.phpt | 135 ++ tests/std/array/uasort_variation6.phpt | 92 ++ tests/std/array/uasort_variation7.phpt | 86 + tests/std/array/uasort_variation8.phpt | 57 + tests/std/array/uksort_basic.phpt | 29 + tests/std/array/unexpected_array_mod_bug.phpt | 31 + .../unexpected_array_mod_bug_variation1.phpt | 33 + tests/std/array/usort_basic.phpt | 104 ++ tests/std/array/usort_object1.phpt | 123 ++ tests/std/array/usort_object2.phpt | 139 ++ tests/std/array/usort_stability.phpt | 15 + tests/std/array/usort_variation10.phpt | 66 + tests/std/array/usort_variation11.phpt | 87 + tests/std/array/usort_variation3.phpt | 100 ++ tests/std/array/usort_variation4.phpt | 132 ++ tests/std/array/usort_variation5.phpt | 116 ++ tests/std/array/usort_variation6.phpt | 116 ++ tests/std/array/usort_variation7.phpt | 85 + tests/std/array/usort_variation8.phpt | 60 + tests/std/array/usort_variation9.phpt | 51 + tests/std/array/var_export.phpt | 13 + tests/std/array/var_export2.phpt | 13 + tests/std/array/var_export3.phpt | 25 + 834 files changed, 87929 insertions(+) create mode 100644 tests/std/array/009.phpt create mode 100644 tests/std/array/array_all_basic.phpt create mode 100644 tests/std/array/array_any_basic.phpt create mode 100644 tests/std/array/array_change_key_case.phpt create mode 100644 tests/std/array/array_change_key_case_variation.phpt create mode 100644 tests/std/array/array_change_key_case_variation3.phpt create mode 100644 tests/std/array/array_change_key_case_variation4.phpt create mode 100644 tests/std/array/array_change_key_case_variation5.phpt create mode 100644 tests/std/array/array_change_key_case_variation6.phpt create mode 100644 tests/std/array/array_change_key_case_variation7.phpt create mode 100644 tests/std/array/array_change_key_case_variation8.phpt create mode 100644 tests/std/array/array_chunk2.phpt create mode 100644 tests/std/array/array_chunk_basic1.phpt create mode 100644 tests/std/array/array_chunk_basic2.phpt create mode 100644 tests/std/array/array_chunk_variation10.phpt create mode 100644 tests/std/array/array_chunk_variation11.phpt create mode 100644 tests/std/array/array_chunk_variation12.phpt create mode 100644 tests/std/array/array_chunk_variation13.phpt create mode 100644 tests/std/array/array_chunk_variation14.phpt create mode 100644 tests/std/array/array_chunk_variation15.phpt create mode 100644 tests/std/array/array_chunk_variation16.phpt create mode 100644 tests/std/array/array_chunk_variation17.phpt create mode 100644 tests/std/array/array_chunk_variation18.phpt create mode 100644 tests/std/array/array_chunk_variation19.phpt create mode 100644 tests/std/array/array_chunk_variation20.phpt create mode 100644 tests/std/array/array_chunk_variation21.phpt create mode 100644 tests/std/array/array_chunk_variation22.phpt create mode 100644 tests/std/array/array_chunk_variation23.phpt create mode 100644 tests/std/array/array_chunk_variation24.phpt create mode 100644 tests/std/array/array_chunk_variation25.phpt create mode 100644 tests/std/array/array_chunk_variation26.phpt create mode 100644 tests/std/array/array_chunk_variation27.phpt create mode 100644 tests/std/array/array_chunk_variation28.phpt create mode 100644 tests/std/array/array_chunk_variation29.phpt create mode 100644 tests/std/array/array_chunk_variation30.phpt create mode 100644 tests/std/array/array_chunk_variation31.phpt create mode 100644 tests/std/array/array_chunk_variation32.phpt create mode 100644 tests/std/array/array_chunk_variation4.phpt create mode 100644 tests/std/array/array_chunk_variation5.phpt create mode 100644 tests/std/array/array_chunk_variation6.phpt create mode 100644 tests/std/array/array_chunk_variation7.phpt create mode 100644 tests/std/array/array_chunk_variation8.phpt create mode 100644 tests/std/array/array_chunk_variation9.phpt create mode 100644 tests/std/array/array_column_basic.phpt create mode 100644 tests/std/array/array_column_numeric_string_key.phpt create mode 100644 tests/std/array/array_column_object_cast.phpt create mode 100644 tests/std/array/array_column_property_visibility.phpt create mode 100644 tests/std/array/array_column_scalar_index_strict_types.phpt create mode 100644 tests/std/array/array_column_scalar_index_weak_types.phpt create mode 100644 tests/std/array/array_column_variant.phpt create mode 100644 tests/std/array/array_column_variant_objects.phpt create mode 100644 tests/std/array/array_combine.phpt create mode 100644 tests/std/array/array_combine_basic.phpt create mode 100644 tests/std/array/array_combine_error2.phpt create mode 100644 tests/std/array/array_combine_variation3.phpt create mode 100644 tests/std/array/array_combine_variation4.phpt create mode 100644 tests/std/array/array_combine_variation5.phpt create mode 100644 tests/std/array/array_combine_variation6.phpt create mode 100644 tests/std/array/array_count_values.phpt create mode 100644 tests/std/array/array_count_values2.phpt create mode 100644 tests/std/array/array_count_values_variation.phpt create mode 100644 tests/std/array/array_diff_1.phpt create mode 100644 tests/std/array/array_diff_assoc.phpt create mode 100644 tests/std/array/array_diff_assoc_basic.phpt create mode 100644 tests/std/array/array_diff_assoc_variation1.phpt create mode 100644 tests/std/array/array_diff_assoc_variation10.phpt create mode 100644 tests/std/array/array_diff_assoc_variation2.phpt create mode 100644 tests/std/array/array_diff_assoc_variation3.phpt create mode 100644 tests/std/array/array_diff_assoc_variation4.phpt create mode 100644 tests/std/array/array_diff_assoc_variation5.phpt create mode 100644 tests/std/array/array_diff_assoc_variation6.phpt create mode 100644 tests/std/array/array_diff_assoc_variation7.phpt create mode 100644 tests/std/array/array_diff_assoc_variation8.phpt create mode 100644 tests/std/array/array_diff_assoc_variation9.phpt create mode 100644 tests/std/array/array_diff_basic.phpt create mode 100644 tests/std/array/array_diff_key.phpt create mode 100644 tests/std/array/array_diff_key2.phpt create mode 100644 tests/std/array/array_diff_key_basic.phpt create mode 100644 tests/std/array/array_diff_key_variation1.phpt create mode 100644 tests/std/array/array_diff_key_variation2.phpt create mode 100644 tests/std/array/array_diff_key_variation4.phpt create mode 100644 tests/std/array/array_diff_key_variation6.phpt create mode 100644 tests/std/array/array_diff_key_variation7.phpt create mode 100644 tests/std/array/array_diff_key_variation8.phpt create mode 100644 tests/std/array/array_diff_single_array.phpt create mode 100644 tests/std/array/array_diff_uassoc_basic.phpt create mode 100644 tests/std/array/array_diff_uassoc_error.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation1.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation11.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation12.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation13.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation2.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation5.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation6.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation7.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation8.phpt create mode 100644 tests/std/array/array_diff_uassoc_variation9.phpt create mode 100644 tests/std/array/array_diff_ukey_basic.phpt create mode 100644 tests/std/array/array_diff_ukey_variation1.phpt create mode 100644 tests/std/array/array_diff_ukey_variation10.phpt create mode 100644 tests/std/array/array_diff_ukey_variation2.phpt create mode 100644 tests/std/array/array_diff_ukey_variation5.phpt create mode 100644 tests/std/array/array_diff_ukey_variation6.phpt create mode 100644 tests/std/array/array_diff_ukey_variation8.phpt create mode 100644 tests/std/array/array_diff_ukey_variation9.phpt create mode 100644 tests/std/array/array_diff_variation1.phpt create mode 100644 tests/std/array/array_diff_variation10.phpt create mode 100644 tests/std/array/array_diff_variation2.phpt create mode 100644 tests/std/array/array_diff_variation3.phpt create mode 100644 tests/std/array/array_diff_variation4.phpt create mode 100644 tests/std/array/array_diff_variation5.phpt create mode 100644 tests/std/array/array_diff_variation6.phpt create mode 100644 tests/std/array/array_diff_variation7.phpt create mode 100644 tests/std/array/array_diff_variation8.phpt create mode 100644 tests/std/array/array_diff_variation9.phpt create mode 100644 tests/std/array/array_fill.phpt create mode 100644 tests/std/array/array_fill_basic.phpt create mode 100644 tests/std/array/array_fill_error.phpt create mode 100644 tests/std/array/array_fill_error2.phpt create mode 100644 tests/std/array/array_fill_keys.phpt create mode 100644 tests/std/array/array_fill_keys_variation1.phpt create mode 100644 tests/std/array/array_fill_keys_variation2.phpt create mode 100644 tests/std/array/array_fill_keys_variation3.phpt create mode 100644 tests/std/array/array_fill_keys_variation4.phpt create mode 100644 tests/std/array/array_fill_object.phpt create mode 100644 tests/std/array/array_fill_variation3.phpt create mode 100644 tests/std/array/array_fill_variation4.phpt create mode 100644 tests/std/array/array_fill_variation5.phpt create mode 100644 tests/std/array/array_fill_variation6.phpt create mode 100644 tests/std/array/array_filter.phpt create mode 100644 tests/std/array/array_filter_basic.phpt create mode 100644 tests/std/array/array_filter_object.phpt create mode 100644 tests/std/array/array_filter_variation10.phpt create mode 100644 tests/std/array/array_filter_variation3.phpt create mode 100644 tests/std/array/array_filter_variation4.phpt create mode 100644 tests/std/array/array_filter_variation5.phpt create mode 100644 tests/std/array/array_filter_variation6.phpt create mode 100644 tests/std/array/array_filter_variation7.phpt create mode 100644 tests/std/array/array_filter_variation8.phpt create mode 100644 tests/std/array/array_filter_variation9.phpt create mode 100644 tests/std/array/array_find_basic.phpt create mode 100644 tests/std/array/array_find_key_basic.phpt create mode 100644 tests/std/array/array_find_types.phpt create mode 100644 tests/std/array/array_flip.phpt create mode 100644 tests/std/array/array_flip_basic.phpt create mode 100644 tests/std/array/array_flip_variation2.phpt create mode 100644 tests/std/array/array_flip_variation3.phpt create mode 100644 tests/std/array/array_flip_variation4.phpt create mode 100644 tests/std/array/array_flip_variation5.phpt create mode 100644 tests/std/array/array_intersect_1.phpt create mode 100644 tests/std/array/array_intersect_assoc_basic.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation1.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation10.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation2.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation3.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation4.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation5.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation6.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation7.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation8.phpt create mode 100644 tests/std/array/array_intersect_assoc_variation9.phpt create mode 100644 tests/std/array/array_intersect_basic.phpt create mode 100644 tests/std/array/array_intersect_key.phpt create mode 100644 tests/std/array/array_intersect_key_basic.phpt create mode 100644 tests/std/array/array_intersect_key_variation1.phpt create mode 100644 tests/std/array/array_intersect_key_variation2.phpt create mode 100644 tests/std/array/array_intersect_key_variation4.phpt create mode 100644 tests/std/array/array_intersect_key_variation6.phpt create mode 100644 tests/std/array/array_intersect_key_variation7.phpt create mode 100644 tests/std/array/array_intersect_key_variation8.phpt create mode 100644 tests/std/array/array_intersect_uassoc_basic.phpt create mode 100644 tests/std/array/array_intersect_uassoc_variation1.phpt create mode 100644 tests/std/array/array_intersect_uassoc_variation10.phpt create mode 100644 tests/std/array/array_intersect_uassoc_variation2.phpt create mode 100644 tests/std/array/array_intersect_uassoc_variation5.phpt create mode 100644 tests/std/array/array_intersect_uassoc_variation6.phpt create mode 100644 tests/std/array/array_intersect_uassoc_variation7.phpt create mode 100644 tests/std/array/array_intersect_uassoc_variation8.phpt create mode 100644 tests/std/array/array_intersect_ukey_basic.phpt create mode 100644 tests/std/array/array_intersect_ukey_variation1.phpt create mode 100644 tests/std/array/array_intersect_ukey_variation2.phpt create mode 100644 tests/std/array/array_intersect_ukey_variation5.phpt create mode 100644 tests/std/array/array_intersect_ukey_variation6.phpt create mode 100644 tests/std/array/array_intersect_ukey_variation7.phpt create mode 100644 tests/std/array/array_intersect_ukey_variation8.phpt create mode 100644 tests/std/array/array_intersect_ukey_variation9.phpt create mode 100644 tests/std/array/array_intersect_variation1.phpt create mode 100644 tests/std/array/array_intersect_variation10.phpt create mode 100644 tests/std/array/array_intersect_variation2.phpt create mode 100644 tests/std/array/array_intersect_variation3.phpt create mode 100644 tests/std/array/array_intersect_variation4.phpt create mode 100644 tests/std/array/array_intersect_variation5.phpt create mode 100644 tests/std/array/array_intersect_variation6.phpt create mode 100644 tests/std/array/array_intersect_variation7.phpt create mode 100644 tests/std/array/array_intersect_variation8.phpt create mode 100644 tests/std/array/array_intersect_variation9.phpt create mode 100644 tests/std/array/array_key_exists.phpt create mode 100644 tests/std/array/array_key_exists_basic.phpt create mode 100644 tests/std/array/array_key_exists_variation1.phpt create mode 100644 tests/std/array/array_key_exists_variation3.phpt create mode 100644 tests/std/array/array_key_exists_variation4.phpt create mode 100644 tests/std/array/array_key_exists_variation5.phpt create mode 100644 tests/std/array/array_key_exists_variation6.phpt create mode 100644 tests/std/array/array_key_exists_variation7.phpt create mode 100644 tests/std/array/array_key_exists_variation8.phpt create mode 100644 tests/std/array/array_key_first.phpt create mode 100644 tests/std/array/array_key_first_variation.phpt create mode 100644 tests/std/array/array_key_last.phpt create mode 100644 tests/std/array/array_key_last_variation.phpt create mode 100644 tests/std/array/array_keys_basic.phpt create mode 100644 tests/std/array/array_keys_on_GLOBALS.phpt create mode 100644 tests/std/array/array_keys_variation_001.phpt create mode 100644 tests/std/array/array_keys_variation_002.phpt create mode 100644 tests/std/array/array_keys_variation_003.phpt create mode 100644 tests/std/array/array_keys_variation_004.phpt create mode 100644 tests/std/array/array_keys_variation_005.phpt create mode 100644 tests/std/array/array_map_001.phpt create mode 100644 tests/std/array/array_map_basic.phpt create mode 100644 tests/std/array/array_map_error.phpt create mode 100644 tests/std/array/array_map_object1.phpt create mode 100644 tests/std/array/array_map_object2.phpt create mode 100644 tests/std/array/array_map_object3.phpt create mode 100644 tests/std/array/array_map_variation1.phpt create mode 100644 tests/std/array/array_map_variation10.phpt create mode 100644 tests/std/array/array_map_variation11.phpt create mode 100644 tests/std/array/array_map_variation12.phpt create mode 100644 tests/std/array/array_map_variation13.phpt create mode 100644 tests/std/array/array_map_variation14.phpt create mode 100644 tests/std/array/array_map_variation15.phpt create mode 100644 tests/std/array/array_map_variation16.phpt create mode 100644 tests/std/array/array_map_variation17.phpt create mode 100644 tests/std/array/array_map_variation19.phpt create mode 100644 tests/std/array/array_map_variation2.phpt create mode 100644 tests/std/array/array_map_variation3.phpt create mode 100644 tests/std/array/array_map_variation4.phpt create mode 100644 tests/std/array/array_map_variation5.phpt create mode 100644 tests/std/array/array_map_variation6.phpt create mode 100644 tests/std/array/array_map_variation7.phpt create mode 100644 tests/std/array/array_map_variation8.phpt create mode 100644 tests/std/array/array_map_variation9.phpt create mode 100644 tests/std/array/array_merge.phpt create mode 100644 tests/std/array/array_merge_basic.phpt create mode 100644 tests/std/array/array_merge_recursive_basic1.phpt create mode 100644 tests/std/array/array_merge_recursive_basic2.phpt create mode 100644 tests/std/array/array_merge_recursive_variation1.phpt create mode 100644 tests/std/array/array_merge_recursive_variation10.phpt create mode 100644 tests/std/array/array_merge_recursive_variation2.phpt create mode 100644 tests/std/array/array_merge_recursive_variation3.phpt create mode 100644 tests/std/array/array_merge_recursive_variation4.phpt create mode 100644 tests/std/array/array_merge_recursive_variation5.phpt create mode 100644 tests/std/array/array_merge_recursive_variation6.phpt create mode 100644 tests/std/array/array_merge_recursive_variation7.phpt create mode 100644 tests/std/array/array_merge_recursive_variation8.phpt create mode 100644 tests/std/array/array_merge_recursive_variation9.phpt create mode 100644 tests/std/array/array_merge_replace_recursive_refs.phpt create mode 100644 tests/std/array/array_merge_variation1.phpt create mode 100644 tests/std/array/array_merge_variation10.phpt create mode 100644 tests/std/array/array_merge_variation2.phpt create mode 100644 tests/std/array/array_merge_variation3.phpt create mode 100644 tests/std/array/array_merge_variation4.phpt create mode 100644 tests/std/array/array_merge_variation5.phpt create mode 100644 tests/std/array/array_merge_variation6.phpt create mode 100644 tests/std/array/array_merge_variation7.phpt create mode 100644 tests/std/array/array_merge_variation8.phpt create mode 100644 tests/std/array/array_merge_variation9.phpt create mode 100644 tests/std/array/array_multisort_basic1.phpt create mode 100644 tests/std/array/array_multisort_basic2.phpt create mode 100644 tests/std/array/array_multisort_case.phpt create mode 100644 tests/std/array/array_multisort_error.phpt create mode 100644 tests/std/array/array_multisort_incase.phpt create mode 100644 tests/std/array/array_multisort_natural.phpt create mode 100644 tests/std/array/array_multisort_natural_case.phpt create mode 100644 tests/std/array/array_multisort_natural_incase.phpt create mode 100644 tests/std/array/array_multisort_stability.phpt create mode 100644 tests/std/array/array_multisort_variation1.phpt create mode 100644 tests/std/array/array_multisort_variation10.phpt create mode 100644 tests/std/array/array_multisort_variation11.phpt create mode 100644 tests/std/array/array_multisort_variation2.phpt create mode 100644 tests/std/array/array_multisort_variation3.phpt create mode 100644 tests/std/array/array_multisort_variation4.phpt create mode 100644 tests/std/array/array_multisort_variation5.phpt create mode 100644 tests/std/array/array_multisort_variation6.phpt create mode 100644 tests/std/array/array_multisort_variation7.phpt create mode 100644 tests/std/array/array_multisort_variation8.phpt create mode 100644 tests/std/array/array_multisort_variation9.phpt create mode 100644 tests/std/array/array_next_error1.phpt create mode 100644 tests/std/array/array_next_error2.phpt create mode 100644 tests/std/array/array_pad.phpt create mode 100644 tests/std/array/array_pad_too_large_padding.phpt create mode 100644 tests/std/array/array_pad_variation3.phpt create mode 100644 tests/std/array/array_pad_variation4.phpt create mode 100644 tests/std/array/array_pad_variation5.phpt create mode 100644 tests/std/array/array_pad_variation6.phpt create mode 100644 tests/std/array/array_pad_variation7.phpt create mode 100644 tests/std/array/array_pop.phpt create mode 100644 tests/std/array/array_pop_variation.phpt create mode 100644 tests/std/array/array_product_empty_array.phpt create mode 100644 tests/std/array/array_product_objects_operation_no_cast.phpt create mode 100644 tests/std/array/array_product_variation1.phpt create mode 100644 tests/std/array/array_product_variation2.phpt create mode 100644 tests/std/array/array_product_variation3.phpt create mode 100644 tests/std/array/array_product_variation4.phpt create mode 100644 tests/std/array/array_product_variation5.phpt create mode 100644 tests/std/array/array_product_variation6.phpt create mode 100644 tests/std/array/array_push.phpt create mode 100644 tests/std/array/array_push_basic.phpt create mode 100644 tests/std/array/array_push_empty.phpt create mode 100644 tests/std/array/array_push_error2.phpt create mode 100644 tests/std/array/array_push_variation2.phpt create mode 100644 tests/std/array/array_push_variation3.phpt create mode 100644 tests/std/array/array_push_variation5.phpt create mode 100644 tests/std/array/array_push_variation6.phpt create mode 100644 tests/std/array/array_rand.phpt create mode 100644 tests/std/array/array_rand_basic1.phpt create mode 100644 tests/std/array/array_rand_basic2.phpt create mode 100644 tests/std/array/array_rand_variation3.phpt create mode 100644 tests/std/array/array_rand_variation4.phpt create mode 100644 tests/std/array/array_rand_variation5.phpt create mode 100644 tests/std/array/array_rand_variation6.phpt create mode 100644 tests/std/array/array_reduce.phpt create mode 100644 tests/std/array/array_reduce_return_by_ref.phpt create mode 100644 tests/std/array/array_reduce_variation1.phpt create mode 100644 tests/std/array/array_reduce_variation3.phpt create mode 100644 tests/std/array/array_replace.phpt create mode 100644 tests/std/array/array_replace_merge_recursive_ref.phpt create mode 100644 tests/std/array/array_reverse_basic1.phpt create mode 100644 tests/std/array/array_reverse_basic2.phpt create mode 100644 tests/std/array/array_reverse_variation3.phpt create mode 100644 tests/std/array/array_reverse_variation4.phpt create mode 100644 tests/std/array/array_reverse_variation5.phpt create mode 100644 tests/std/array/array_reverse_variation6.phpt create mode 100644 tests/std/array/array_search.phpt create mode 100644 tests/std/array/array_search1.phpt create mode 100644 tests/std/array/array_search_variation1.phpt create mode 100644 tests/std/array/array_search_variation2.phpt create mode 100644 tests/std/array/array_search_variation3.phpt create mode 100644 tests/std/array/array_search_variation4.phpt create mode 100644 tests/std/array/array_shift_basic.phpt create mode 100644 tests/std/array/array_shift_variation2.phpt create mode 100644 tests/std/array/array_shift_variation3.phpt create mode 100644 tests/std/array/array_shift_variation4.phpt create mode 100644 tests/std/array/array_shift_variation5.phpt create mode 100644 tests/std/array/array_shift_variation6.phpt create mode 100644 tests/std/array/array_shift_variation7.phpt create mode 100644 tests/std/array/array_shift_variation8.phpt create mode 100644 tests/std/array/array_shuffle_basic.phpt create mode 100644 tests/std/array/array_slice.phpt create mode 100644 tests/std/array/array_slice_basic.phpt create mode 100644 tests/std/array/array_slice_variation1.phpt create mode 100644 tests/std/array/array_slice_variation10.phpt create mode 100644 tests/std/array/array_slice_variation11.phpt create mode 100644 tests/std/array/array_slice_variation5.phpt create mode 100644 tests/std/array/array_slice_variation6.phpt create mode 100644 tests/std/array/array_slice_variation7.phpt create mode 100644 tests/std/array/array_slice_variation8.phpt create mode 100644 tests/std/array/array_slice_variation9.phpt create mode 100644 tests/std/array/array_splice_basic.phpt create mode 100644 tests/std/array/array_splice_variation1.phpt create mode 100644 tests/std/array/array_splice_variation3.phpt create mode 100644 tests/std/array/array_splice_variation4.phpt create mode 100644 tests/std/array/array_sum.phpt create mode 100644 tests/std/array/array_sum_basic.phpt create mode 100644 tests/std/array/array_sum_empty_array.phpt create mode 100644 tests/std/array/array_sum_objects_operation_no_cast.phpt create mode 100644 tests/std/array/array_sum_objects_operation_no_cast_FFI.phpt create mode 100644 tests/std/array/array_sum_on_reference.phpt create mode 100644 tests/std/array/array_sum_variation2.phpt create mode 100644 tests/std/array/array_sum_variation3.phpt create mode 100644 tests/std/array/array_sum_variation4.phpt create mode 100644 tests/std/array/array_sum_variation5.phpt create mode 100644 tests/std/array/array_sum_variation6.phpt create mode 100644 tests/std/array/array_sum_variation7.phpt create mode 100644 tests/std/array/array_sum_variation8.phpt create mode 100644 tests/std/array/array_sum_variation9.phpt create mode 100644 tests/std/array/array_udiff_assoc_basic.phpt create mode 100644 tests/std/array/array_udiff_assoc_variation.phpt create mode 100644 tests/std/array/array_udiff_assoc_variation1.phpt create mode 100644 tests/std/array/array_udiff_assoc_variation2.phpt create mode 100644 tests/std/array/array_udiff_assoc_variation5.phpt create mode 100644 tests/std/array/array_udiff_basic.phpt create mode 100644 tests/std/array/array_udiff_uassoc_basic.phpt create mode 100644 tests/std/array/array_udiff_uassoc_variation1.phpt create mode 100644 tests/std/array/array_udiff_uassoc_variation2.phpt create mode 100644 tests/std/array/array_udiff_uassoc_variation6.phpt create mode 100644 tests/std/array/array_udiff_variation1.phpt create mode 100644 tests/std/array/array_udiff_variation2.phpt create mode 100644 tests/std/array/array_udiff_variation5.phpt create mode 100644 tests/std/array/array_uintersect_assoc_basic.phpt create mode 100644 tests/std/array/array_uintersect_assoc_basic2.phpt create mode 100644 tests/std/array/array_uintersect_assoc_variation1.phpt create mode 100644 tests/std/array/array_uintersect_assoc_variation2.phpt create mode 100644 tests/std/array/array_uintersect_assoc_variation5.phpt create mode 100644 tests/std/array/array_uintersect_basic.phpt create mode 100644 tests/std/array/array_uintersect_uassoc_basic.phpt create mode 100644 tests/std/array/array_uintersect_uassoc_variation1.phpt create mode 100644 tests/std/array/array_uintersect_uassoc_variation2.phpt create mode 100644 tests/std/array/array_uintersect_uassoc_variation6.phpt create mode 100644 tests/std/array/array_uintersect_variation1.phpt create mode 100644 tests/std/array/array_uintersect_variation2.phpt create mode 100644 tests/std/array/array_uintersect_variation5.phpt create mode 100644 tests/std/array/array_unique_basic.phpt create mode 100644 tests/std/array/array_unique_variation2.phpt create mode 100644 tests/std/array/array_unique_variation3.phpt create mode 100644 tests/std/array/array_unique_variation4.phpt create mode 100644 tests/std/array/array_unique_variation5.phpt create mode 100644 tests/std/array/array_unique_variation6.phpt create mode 100644 tests/std/array/array_unique_variation7.phpt create mode 100644 tests/std/array/array_unique_variation8.phpt create mode 100644 tests/std/array/array_unique_variation9.phpt create mode 100644 tests/std/array/array_unshift.phpt create mode 100644 tests/std/array/array_unshift_basic1.phpt create mode 100644 tests/std/array/array_unshift_basic2.phpt create mode 100644 tests/std/array/array_unshift_empty.phpt create mode 100644 tests/std/array/array_unshift_object.phpt create mode 100644 tests/std/array/array_unshift_variation2.phpt create mode 100644 tests/std/array/array_unshift_variation3.phpt create mode 100644 tests/std/array/array_unshift_variation4.phpt create mode 100644 tests/std/array/array_unshift_variation5.phpt create mode 100644 tests/std/array/array_unshift_variation6.phpt create mode 100644 tests/std/array/array_unshift_variation7.phpt create mode 100644 tests/std/array/array_unshift_variation8.phpt create mode 100644 tests/std/array/array_unshift_variation9.phpt create mode 100644 tests/std/array/array_user_key_compare.phpt create mode 100644 tests/std/array/array_values.phpt create mode 100644 tests/std/array/array_values_basic.phpt create mode 100644 tests/std/array/array_values_variation.phpt create mode 100644 tests/std/array/array_values_variation2.phpt create mode 100644 tests/std/array/array_values_variation3.phpt create mode 100644 tests/std/array/array_values_variation4.phpt create mode 100644 tests/std/array/array_values_variation5.phpt create mode 100644 tests/std/array/array_values_variation6.phpt create mode 100644 tests/std/array/array_values_variation7.phpt create mode 100644 tests/std/array/array_values_variation_64bit.phpt create mode 100644 tests/std/array/array_walk.phpt create mode 100644 tests/std/array/array_walk_basic1.phpt create mode 100644 tests/std/array/array_walk_basic2.phpt create mode 100644 tests/std/array/array_walk_closure.phpt create mode 100644 tests/std/array/array_walk_error2.phpt create mode 100644 tests/std/array/array_walk_object1.phpt create mode 100644 tests/std/array/array_walk_object2.phpt create mode 100644 tests/std/array/array_walk_objects.phpt create mode 100644 tests/std/array/array_walk_rec_objects.phpt create mode 100644 tests/std/array/array_walk_recursive.phpt create mode 100644 tests/std/array/array_walk_recursive1.phpt create mode 100644 tests/std/array/array_walk_recursive_basic1.phpt create mode 100644 tests/std/array/array_walk_recursive_basic2.phpt create mode 100644 tests/std/array/array_walk_recursive_error2.phpt create mode 100644 tests/std/array/array_walk_recursive_object1.phpt create mode 100644 tests/std/array/array_walk_recursive_object2.phpt create mode 100644 tests/std/array/array_walk_recursive_variation3.phpt create mode 100644 tests/std/array/array_walk_recursive_variation4.phpt create mode 100644 tests/std/array/array_walk_recursive_variation5.phpt create mode 100644 tests/std/array/array_walk_recursive_variation6.phpt create mode 100644 tests/std/array/array_walk_recursive_variation7.phpt create mode 100644 tests/std/array/array_walk_recursive_variation8.phpt create mode 100644 tests/std/array/array_walk_recursive_variation9.phpt create mode 100644 tests/std/array/array_walk_variation3.phpt create mode 100644 tests/std/array/array_walk_variation4.phpt create mode 100644 tests/std/array/array_walk_variation5.phpt create mode 100644 tests/std/array/array_walk_variation6.phpt create mode 100644 tests/std/array/array_walk_variation7.phpt create mode 100644 tests/std/array/array_walk_variation8.phpt create mode 100644 tests/std/array/array_walk_variation9.phpt create mode 100644 tests/std/array/arsort_basic.phpt create mode 100644 tests/std/array/arsort_object1.phpt create mode 100644 tests/std/array/arsort_object2.phpt create mode 100644 tests/std/array/arsort_variation10.phpt create mode 100644 tests/std/array/arsort_variation11.phpt create mode 100644 tests/std/array/arsort_variation3.phpt create mode 100644 tests/std/array/arsort_variation4.phpt create mode 100644 tests/std/array/arsort_variation5.phpt create mode 100644 tests/std/array/arsort_variation6.phpt create mode 100644 tests/std/array/arsort_variation7.phpt create mode 100644 tests/std/array/arsort_variation8.phpt create mode 100644 tests/std/array/arsort_variation9.phpt create mode 100644 tests/std/array/asort_basic.phpt create mode 100644 tests/std/array/asort_object1.phpt create mode 100644 tests/std/array/asort_object2.phpt create mode 100644 tests/std/array/asort_stability.phpt create mode 100644 tests/std/array/asort_variation10.phpt create mode 100644 tests/std/array/asort_variation11.phpt create mode 100644 tests/std/array/asort_variation3.phpt create mode 100644 tests/std/array/asort_variation4.phpt create mode 100644 tests/std/array/asort_variation5.phpt create mode 100644 tests/std/array/asort_variation6.phpt create mode 100644 tests/std/array/asort_variation7.phpt create mode 100644 tests/std/array/asort_variation8.phpt create mode 100644 tests/std/array/asort_variation9.phpt create mode 100644 tests/std/array/bug12776.phpt create mode 100644 tests/std/array/bug14580.phpt create mode 100644 tests/std/array/bug20381.phpt create mode 100644 tests/std/array/bug20865.phpt create mode 100644 tests/std/array/bug21918.phpt create mode 100644 tests/std/array/bug21998.phpt create mode 100644 tests/std/array/bug22088.phpt create mode 100644 tests/std/array/bug22463.phpt create mode 100644 tests/std/array/bug23581.phpt create mode 100644 tests/std/array/bug23788.phpt create mode 100644 tests/std/array/bug24198.phpt create mode 100644 tests/std/array/bug24766.phpt create mode 100644 tests/std/array/bug24897.phpt create mode 100644 tests/std/array/bug24980.phpt create mode 100644 tests/std/array/bug25359.phpt create mode 100644 tests/std/array/bug25708.phpt create mode 100644 tests/std/array/bug25758.phpt create mode 100644 tests/std/array/bug26458.phpt create mode 100644 tests/std/array/bug28739.phpt create mode 100644 tests/std/array/bug28974.phpt create mode 100644 tests/std/array/bug29253.phpt create mode 100644 tests/std/array/bug29493.phpt create mode 100644 tests/std/array/bug30074.phpt create mode 100644 tests/std/array/bug30266.phpt create mode 100644 tests/std/array/bug30833.phpt create mode 100644 tests/std/array/bug31158.phpt create mode 100644 tests/std/array/bug31213.phpt create mode 100644 tests/std/array/bug33382.phpt create mode 100644 tests/std/array/bug33989.phpt create mode 100644 tests/std/array/bug34066.phpt create mode 100644 tests/std/array/bug34066_1.phpt create mode 100644 tests/std/array/bug34227.phpt create mode 100644 tests/std/array/bug34982.phpt create mode 100644 tests/std/array/bug35014.phpt create mode 100644 tests/std/array/bug35014_64bit.phpt create mode 100644 tests/std/array/bug35022.phpt create mode 100644 tests/std/array/bug35821.phpt create mode 100644 tests/std/array/bug36975.phpt create mode 100644 tests/std/array/bug38464.phpt create mode 100644 tests/std/array/bug39576.phpt create mode 100644 tests/std/array/bug40191.phpt create mode 100644 tests/std/array/bug40709.phpt create mode 100644 tests/std/array/bug41686.phpt create mode 100644 tests/std/array/bug42177.phpt create mode 100644 tests/std/array/bug42233.phpt create mode 100644 tests/std/array/bug42838.phpt create mode 100644 tests/std/array/bug42850.phpt create mode 100644 tests/std/array/bug43495.phpt create mode 100644 tests/std/array/bug43505.phpt create mode 100644 tests/std/array/bug43541.phpt create mode 100644 tests/std/array/bug44181.phpt create mode 100644 tests/std/array/bug44182.phpt create mode 100644 tests/std/array/bug44929.phpt create mode 100644 tests/std/array/bug45312.phpt create mode 100644 tests/std/array/bug46873.phpt create mode 100644 tests/std/array/bug48224.phpt create mode 100644 tests/std/array/bug48854.phpt create mode 100644 tests/std/array/bug50006.phpt create mode 100644 tests/std/array/bug50006_1.phpt create mode 100644 tests/std/array/bug50006_2.phpt create mode 100644 tests/std/array/bug51552.phpt create mode 100644 tests/std/array/bug52534.phpt create mode 100644 tests/std/array/bug52719.phpt create mode 100644 tests/std/array/bug61058.phpt create mode 100644 tests/std/array/bug61730.phpt create mode 100644 tests/std/array/bug61967.phpt create mode 100644 tests/std/array/bug62607.phpt create mode 100644 tests/std/array/bug65251.phpt create mode 100644 tests/std/array/bug65304.phpt create mode 100644 tests/std/array/bug67693.phpt create mode 100644 tests/std/array/bug68553.phpt create mode 100644 tests/std/array/bug69068.phpt create mode 100644 tests/std/array/bug69068_2.phpt create mode 100644 tests/std/array/bug69166.phpt create mode 100644 tests/std/array/bug69198.phpt create mode 100644 tests/std/array/bug69299.phpt create mode 100644 tests/std/array/bug69371.phpt create mode 100644 tests/std/array/bug69413.phpt create mode 100644 tests/std/array/bug69674.phpt create mode 100644 tests/std/array/bug69723.phpt create mode 100644 tests/std/array/bug70250.phpt create mode 100644 tests/std/array/bug70668.phpt create mode 100644 tests/std/array/bug70713.phpt create mode 100644 tests/std/array/bug70808.phpt create mode 100644 tests/std/array/bug70910.phpt create mode 100644 tests/std/array/bug71220.phpt create mode 100644 tests/std/array/bug71334.phpt create mode 100644 tests/std/array/bug71603.phpt create mode 100644 tests/std/array/bug71660.phpt create mode 100644 tests/std/array/bug71837.phpt create mode 100644 tests/std/array/bug72031.phpt create mode 100644 tests/std/array/bug72116.phpt create mode 100644 tests/std/array/bug72369.phpt create mode 100644 tests/std/array/bug72622.phpt create mode 100644 tests/std/array/bug74345.phpt create mode 100644 tests/std/array/bug74361.phpt create mode 100644 tests/std/array/bug74361_2.phpt create mode 100644 tests/std/array/bug75433.phpt create mode 100644 tests/std/array/bug75653.phpt create mode 100644 tests/std/array/bug76505.phpt create mode 100644 tests/std/array/bug76713.phpt create mode 100644 tests/std/array/bug76778.phpt create mode 100644 tests/std/array/bug77135.phpt create mode 100644 tests/std/array/bug77395.phpt create mode 100644 tests/std/array/bug77669.phpt create mode 100644 tests/std/array/bug77793.phpt create mode 100644 tests/std/array/bug77931.phpt create mode 100644 tests/std/array/bug78759.phpt create mode 100644 tests/std/array/bug79839.phpt create mode 100644 tests/std/array/bug79868.phpt create mode 100644 tests/std/array/bug79930.phpt create mode 100644 tests/std/array/compact.phpt create mode 100644 tests/std/array/compact_basic.phpt create mode 100644 tests/std/array/compact_no_this.phpt create mode 100644 tests/std/array/compact_order.phpt create mode 100644 tests/std/array/compact_this.phpt create mode 100644 tests/std/array/compact_variation1.phpt create mode 100644 tests/std/array/compact_variation2.phpt create mode 100644 tests/std/array/compare_function.inc create mode 100644 tests/std/array/count_basic.phpt create mode 100644 tests/std/array/count_invalid.phpt create mode 100644 tests/std/array/count_invalid_mode.phpt create mode 100644 tests/std/array/count_recursive.phpt create mode 100644 tests/std/array/count_symbol_table.phpt create mode 100644 tests/std/array/count_variation3.phpt create mode 100644 tests/std/array/current_basic.phpt create mode 100644 tests/std/array/current_variation2.phpt create mode 100644 tests/std/array/current_variation3.phpt create mode 100644 tests/std/array/current_variation4.phpt create mode 100644 tests/std/array/current_variation5.phpt create mode 100644 tests/std/array/current_variation6.phpt create mode 100644 tests/std/array/data.inc create mode 100644 tests/std/array/end.phpt create mode 100644 tests/std/array/end_64bit.phpt create mode 100644 tests/std/array/end_basic.phpt create mode 100644 tests/std/array/end_variation2.phpt create mode 100644 tests/std/array/end_variation3.phpt create mode 100644 tests/std/array/extract_error.phpt create mode 100644 tests/std/array/extract_error_variation1.phpt create mode 100644 tests/std/array/extract_safety.phpt create mode 100644 tests/std/array/extract_typed_ref.phpt create mode 100644 tests/std/array/extract_variation1.phpt create mode 100644 tests/std/array/extract_variation10.phpt create mode 100644 tests/std/array/extract_variation11.phpt create mode 100644 tests/std/array/extract_variation2.phpt create mode 100644 tests/std/array/extract_variation3.phpt create mode 100644 tests/std/array/extract_variation4.phpt create mode 100644 tests/std/array/extract_variation5.phpt create mode 100644 tests/std/array/extract_variation6.phpt create mode 100644 tests/std/array/extract_variation7.phpt create mode 100644 tests/std/array/extract_variation8.phpt create mode 100644 tests/std/array/extract_variation9.phpt create mode 100644 tests/std/array/gh14140.phpt create mode 100644 tests/std/array/gh14775.phpt create mode 100644 tests/std/array/gh15982.phpt create mode 100644 tests/std/array/gh16053.phpt create mode 100644 tests/std/array/gh16649/array_splice_normal_destructor.phpt create mode 100644 tests/std/array/gh16649/array_splice_uaf_add_elements.phpt create mode 100644 tests/std/array/gh16649/array_splice_uaf_array_deallocated.phpt create mode 100644 tests/std/array/gh16649/array_splice_uaf_complex_modification.phpt create mode 100644 tests/std/array/gh16649/array_splice_uaf_multiple_destructors.phpt create mode 100644 tests/std/array/gh16649/array_splice_uaf_original_case.phpt create mode 100644 tests/std/array/gh16649/array_splice_uaf_packed_to_hash.phpt create mode 100644 tests/std/array/gh16649/array_splice_with_replacement.phpt create mode 100644 tests/std/array/gh16905.phpt create mode 100644 tests/std/array/gh16957.phpt create mode 100644 tests/std/array/gh17447.phpt create mode 100644 tests/std/array/gh17977.phpt create mode 100644 tests/std/array/gh18480.phpt create mode 100644 tests/std/array/gh19300_1.phpt create mode 100644 tests/std/array/gh19300_2.phpt create mode 100644 tests/std/array/gh19926.phpt create mode 100644 tests/std/array/gh19926_pointer.phpt create mode 100644 tests/std/array/gh20043.phpt create mode 100644 tests/std/array/gh9244.phpt create mode 100644 tests/std/array/gh9296.phpt create mode 100644 tests/std/array/in_array_variation1.phpt create mode 100644 tests/std/array/in_array_variation2.phpt create mode 100644 tests/std/array/in_array_variation3.phpt create mode 100644 tests/std/array/in_array_variation4.phpt create mode 100644 tests/std/array/in_array_with_ref.phpt create mode 100644 tests/std/array/key_basic.phpt create mode 100644 tests/std/array/key_exists_basic.phpt create mode 100644 tests/std/array/key_exists_variation1.phpt create mode 100644 tests/std/array/key_exists_variation2.phpt create mode 100644 tests/std/array/key_variation2.phpt create mode 100644 tests/std/array/key_variation3.phpt create mode 100644 tests/std/array/key_variation4.phpt create mode 100644 tests/std/array/krsort_basic.phpt create mode 100644 tests/std/array/krsort_object.phpt create mode 100644 tests/std/array/krsort_variation10.phpt create mode 100644 tests/std/array/krsort_variation11.phpt create mode 100644 tests/std/array/krsort_variation3.phpt create mode 100644 tests/std/array/krsort_variation4.phpt create mode 100644 tests/std/array/krsort_variation5.phpt create mode 100644 tests/std/array/krsort_variation6.phpt create mode 100644 tests/std/array/krsort_variation7.phpt create mode 100644 tests/std/array/krsort_variation8.phpt create mode 100644 tests/std/array/krsort_variation9.phpt create mode 100644 tests/std/array/ksort_basic.phpt create mode 100644 tests/std/array/ksort_object.phpt create mode 100644 tests/std/array/ksort_variation10.phpt create mode 100644 tests/std/array/ksort_variation11.phpt create mode 100644 tests/std/array/ksort_variation3.phpt create mode 100644 tests/std/array/ksort_variation4.phpt create mode 100644 tests/std/array/ksort_variation5.phpt create mode 100644 tests/std/array/ksort_variation6.phpt create mode 100644 tests/std/array/ksort_variation7.phpt create mode 100644 tests/std/array/ksort_variation8.phpt create mode 100644 tests/std/array/ksort_variation9.phpt create mode 100644 tests/std/array/locale_sort.phpt create mode 100644 tests/std/array/max.phpt create mode 100644 tests/std/array/max_basic.phpt create mode 100644 tests/std/array/max_basiclong_64bit.phpt create mode 100644 tests/std/array/max_int_float_optimisation.phpt create mode 100644 tests/std/array/max_variation1.phpt create mode 100644 tests/std/array/max_variation2.phpt create mode 100644 tests/std/array/min.phpt create mode 100644 tests/std/array/min_basic.phpt create mode 100644 tests/std/array/min_basiclong_64bit.phpt create mode 100644 tests/std/array/min_int_float_optimisation.phpt create mode 100644 tests/std/array/min_variation1.phpt create mode 100644 tests/std/array/min_variation2.phpt create mode 100644 tests/std/array/natcasesort_basic.phpt create mode 100644 tests/std/array/natcasesort_object1.phpt create mode 100644 tests/std/array/natcasesort_object2.phpt create mode 100644 tests/std/array/natcasesort_variation10.phpt create mode 100644 tests/std/array/natcasesort_variation11.phpt create mode 100644 tests/std/array/natcasesort_variation2.phpt create mode 100644 tests/std/array/natcasesort_variation3.phpt create mode 100644 tests/std/array/natcasesort_variation4.phpt create mode 100644 tests/std/array/natcasesort_variation5.phpt create mode 100644 tests/std/array/natcasesort_variation6.phpt create mode 100644 tests/std/array/natcasesort_variation7.phpt create mode 100644 tests/std/array/natcasesort_variation8.phpt create mode 100644 tests/std/array/natcasesort_variation9.phpt create mode 100644 tests/std/array/natsort_basic.phpt create mode 100644 tests/std/array/negative_index.phpt create mode 100644 tests/std/array/negative_index_empty_array.phpt create mode 100644 tests/std/array/next_basic.phpt create mode 100644 tests/std/array/next_variation2.phpt create mode 100644 tests/std/array/packed_001.phpt create mode 100644 tests/std/array/prev_basic.phpt create mode 100644 tests/std/array/prev_error2.phpt create mode 100644 tests/std/array/prev_error3.phpt create mode 100644 tests/std/array/prev_variation2.phpt create mode 100644 tests/std/array/range/bug21182.phpt create mode 100644 tests/std/array/range/bug24220.phpt create mode 100644 tests/std/array/range/bug32021.phpt create mode 100644 tests/std/array/range/bug41121.phpt create mode 100644 tests/std/array/range/bug54459.phpt create mode 100644 tests/std/array/range/gh13094.phpt create mode 100644 tests/std/array/range/range_bug70239_0.phpt create mode 100644 tests/std/array/range/range_bug70239_1.phpt create mode 100644 tests/std/array/range/range_bug70239_2.phpt create mode 100644 tests/std/array/range/range_bug70239_3.phpt create mode 100644 tests/std/array/range/range_bug71132.phpt create mode 100644 tests/std/array/range/range_bug71197.phpt create mode 100644 tests/std/array/range/range_bug72017.phpt create mode 100644 tests/std/array/range/range_inputs_float_NAN_values.phpt create mode 100644 tests/std/array/range/range_inputs_float_basic.phpt create mode 100644 tests/std/array/range/range_inputs_float_small_step_exhaustion.phpt create mode 100644 tests/std/array/range/range_inputs_int_basic.phpt create mode 100644 tests/std/array/range/range_inputs_int_with_float_step.phpt create mode 100644 tests/std/array/range/range_inputs_null_variations.phpt create mode 100644 tests/std/array/range/range_inputs_numeric_basic.phpt create mode 100644 tests/std/array/range/range_inputs_string_basic.phpt create mode 100644 tests/std/array/range/range_inputs_string_digits.phpt create mode 100644 tests/std/array/range/range_inputs_string_digits_float_step.phpt create mode 100644 tests/std/array/range/range_inputs_string_invalid.phpt create mode 100644 tests/std/array/range/range_inputs_string_numeric.phpt create mode 100644 tests/std/array/range/range_inputs_string_variations.phpt create mode 100644 tests/std/array/range/range_negative_step_decreasing_ranges.phpt create mode 100644 tests/std/array/range/range_step_errors.phpt create mode 100644 tests/std/array/range/range_variation1.phpt create mode 100644 tests/std/array/range/range_variation1_64bit.phpt create mode 100644 tests/std/array/rcn_in_place.phpt create mode 100644 tests/std/array/reset_basic.phpt create mode 100644 tests/std/array/reset_variation2.phpt create mode 100644 tests/std/array/reset_variation3.phpt create mode 100644 tests/std/array/rsort_basic.phpt create mode 100644 tests/std/array/rsort_object1.phpt create mode 100644 tests/std/array/rsort_object2.phpt create mode 100644 tests/std/array/rsort_variation10.phpt create mode 100644 tests/std/array/rsort_variation11.phpt create mode 100644 tests/std/array/rsort_variation3.phpt create mode 100644 tests/std/array/rsort_variation4.phpt create mode 100644 tests/std/array/rsort_variation5.phpt create mode 100644 tests/std/array/rsort_variation6.phpt create mode 100644 tests/std/array/rsort_variation7.phpt create mode 100644 tests/std/array/rsort_variation8.phpt create mode 100644 tests/std/array/rsort_variation9.phpt create mode 100644 tests/std/array/shuffle_basic1.phpt create mode 100644 tests/std/array/shuffle_basic2.phpt create mode 100644 tests/std/array/shuffle_variation2.phpt create mode 100644 tests/std/array/shuffle_variation3.phpt create mode 100644 tests/std/array/shuffle_variation4.phpt create mode 100644 tests/std/array/shuffle_variation5.phpt create mode 100644 tests/std/array/sizeof_basic2.phpt create mode 100644 tests/std/array/sizeof_object1.phpt create mode 100644 tests/std/array/sizeof_object2.phpt create mode 100644 tests/std/array/sizeof_variation2.phpt create mode 100644 tests/std/array/sizeof_variation3.phpt create mode 100644 tests/std/array/sort_basic.phpt create mode 100644 tests/std/array/sort_object1.phpt create mode 100644 tests/std/array/sort_object2.phpt create mode 100644 tests/std/array/sort_variation10.phpt create mode 100644 tests/std/array/sort_variation11.phpt create mode 100644 tests/std/array/sort_variation3.phpt create mode 100644 tests/std/array/sort_variation4.phpt create mode 100644 tests/std/array/sort_variation5.phpt create mode 100644 tests/std/array/sort_variation6.phpt create mode 100644 tests/std/array/sort_variation7.phpt create mode 100644 tests/std/array/sort_variation8.phpt create mode 100644 tests/std/array/sort_variation9.phpt create mode 100644 tests/std/array/uasort_basic1.phpt create mode 100644 tests/std/array/uasort_basic2.phpt create mode 100644 tests/std/array/uasort_object1.phpt create mode 100644 tests/std/array/uasort_object2.phpt create mode 100644 tests/std/array/uasort_variation10.phpt create mode 100644 tests/std/array/uasort_variation11.phpt create mode 100644 tests/std/array/uasort_variation3.phpt create mode 100644 tests/std/array/uasort_variation4.phpt create mode 100644 tests/std/array/uasort_variation5.phpt create mode 100644 tests/std/array/uasort_variation6.phpt create mode 100644 tests/std/array/uasort_variation7.phpt create mode 100644 tests/std/array/uasort_variation8.phpt create mode 100644 tests/std/array/uksort_basic.phpt create mode 100644 tests/std/array/unexpected_array_mod_bug.phpt create mode 100644 tests/std/array/unexpected_array_mod_bug_variation1.phpt create mode 100644 tests/std/array/usort_basic.phpt create mode 100644 tests/std/array/usort_object1.phpt create mode 100644 tests/std/array/usort_object2.phpt create mode 100644 tests/std/array/usort_stability.phpt create mode 100644 tests/std/array/usort_variation10.phpt create mode 100644 tests/std/array/usort_variation11.phpt create mode 100644 tests/std/array/usort_variation3.phpt create mode 100644 tests/std/array/usort_variation4.phpt create mode 100644 tests/std/array/usort_variation5.phpt create mode 100644 tests/std/array/usort_variation6.phpt create mode 100644 tests/std/array/usort_variation7.phpt create mode 100644 tests/std/array/usort_variation8.phpt create mode 100644 tests/std/array/usort_variation9.phpt create mode 100644 tests/std/array/var_export.phpt create mode 100644 tests/std/array/var_export2.phpt create mode 100644 tests/std/array/var_export3.phpt diff --git a/tests/std/array/009.phpt b/tests/std/array/009.phpt new file mode 100644 index 00000000..f4aab2fa --- /dev/null +++ b/tests/std/array/009.phpt @@ -0,0 +1,408 @@ +--TEST-- +Test key(), current(), next() & reset() functions +--FILE-- + "apple", "b" => "book", "c" => "cook"), // associative array + array('d' => 'drink', 'p' => 'port', 's' => 'set'), // another associative array + array(1 => 'One', 2 => 'two', 3 => "three") // associative array with key as integers +); + +$varient_arrays = array ( + array(), // empty array + array(""), // array with null string + array(NULL),// array with NULL + array(null),// array with null + array(NULL, true, null, "", 1), // mixed array + array(-1 => "test", -2 => "rest", 2 => "two", + "" => "string", 0 => "zero", "" => "" ) // mixed array +); + +echo "*** Testing basic operations ***\n"; +$loop_count = 1; +foreach ($basic_arrays as $sub_array ) { + echo "-- Iteration $loop_count --\n"; + $loop_count++; + $c = count ($sub_array); + $c++; // increment by one to create the situation of accessing beyond array size + while ( $c ) { + var_dump( current($sub_array)); // current element + var_dump( key($sub_array) ); // key of the current element + var_dump( next($sub_array) ); // move to next element + $c --; + } + var_dump( reset($sub_array) ); // reset the internal pointer to first element + var_dump( key($sub_array) ); // access the array after reset + var_dump( $sub_array ); // dump the array to see that its intact + + echo "\n"; +} + +echo "\n*** Testing possible variations ***\n"; +$loop_count = 1; +foreach ($varient_arrays as $sub_array ) { + echo "-- Iteration $loop_count --\n"; + $loop_count++; + $c = count ($sub_array); + $c++; // increment by one to create the situation of accessing beyond array size + while ( $c ) { + var_dump( current($sub_array)); // current element + var_dump( key($sub_array) ); // key of the current element + var_dump( next($sub_array) ); // move to next element + $c --; + } + var_dump( reset($sub_array) ); // reset the internal pointer to first element + var_dump( key($sub_array) ); // access the array after reset + var_dump( $sub_array ); // dump the array to see that its intact + echo "\n"; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing basic operations *** +-- Iteration 1 -- +int(0) +int(0) +bool(false) +bool(false) +NULL +bool(false) +int(0) +int(0) +array(1) { + [0]=> + int(0) +} + +-- Iteration 2 -- +int(1) +int(0) +bool(false) +bool(false) +NULL +bool(false) +int(1) +int(0) +array(1) { + [0]=> + int(1) +} + +-- Iteration 3 -- +int(1) +int(0) +int(2) +int(2) +int(1) +int(3) +int(3) +int(2) +int(-1) +int(-1) +int(3) +int(-2) +int(-2) +int(4) +int(-3) +int(-3) +int(5) +bool(false) +bool(false) +NULL +bool(false) +int(1) +int(0) +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(-1) + [4]=> + int(-2) + [5]=> + int(-3) +} + +-- Iteration 4 -- +float(1.1) +int(0) +float(2.2) +float(2.2) +int(1) +float(3.3) +float(3.3) +int(2) +float(-1.1) +float(-1.1) +int(3) +float(-2.2) +float(-2.2) +int(4) +float(-3.3) +float(-3.3) +int(5) +bool(false) +bool(false) +NULL +bool(false) +float(1.1) +int(0) +array(6) { + [0]=> + float(1.1) + [1]=> + float(2.2) + [2]=> + float(3.3) + [3]=> + float(-1.1) + [4]=> + float(-2.2) + [5]=> + float(-3.3) +} + +-- Iteration 5 -- +string(1) "a" +int(0) +string(1) "b" +string(1) "b" +int(1) +string(1) "c" +string(1) "c" +int(2) +string(2) "ab" +string(2) "ab" +int(3) +string(2) "ac" +string(2) "ac" +int(4) +string(2) "ad" +string(2) "ad" +int(5) +bool(false) +bool(false) +NULL +bool(false) +string(1) "a" +int(0) +array(6) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(2) "ab" + [4]=> + string(2) "ac" + [5]=> + string(2) "ad" +} + +-- Iteration 6 -- +string(5) "apple" +string(1) "a" +string(4) "book" +string(4) "book" +string(1) "b" +string(4) "cook" +string(4) "cook" +string(1) "c" +bool(false) +bool(false) +NULL +bool(false) +string(5) "apple" +string(1) "a" +array(3) { + ["a"]=> + string(5) "apple" + ["b"]=> + string(4) "book" + ["c"]=> + string(4) "cook" +} + +-- Iteration 7 -- +string(5) "drink" +string(1) "d" +string(4) "port" +string(4) "port" +string(1) "p" +string(3) "set" +string(3) "set" +string(1) "s" +bool(false) +bool(false) +NULL +bool(false) +string(5) "drink" +string(1) "d" +array(3) { + ["d"]=> + string(5) "drink" + ["p"]=> + string(4) "port" + ["s"]=> + string(3) "set" +} + +-- Iteration 8 -- +string(3) "One" +int(1) +string(3) "two" +string(3) "two" +int(2) +string(5) "three" +string(5) "three" +int(3) +bool(false) +bool(false) +NULL +bool(false) +string(3) "One" +int(1) +array(3) { + [1]=> + string(3) "One" + [2]=> + string(3) "two" + [3]=> + string(5) "three" +} + + +*** Testing possible variations *** +-- Iteration 1 -- +bool(false) +NULL +bool(false) +bool(false) +NULL +array(0) { +} + +-- Iteration 2 -- +string(0) "" +int(0) +bool(false) +bool(false) +NULL +bool(false) +string(0) "" +int(0) +array(1) { + [0]=> + string(0) "" +} + +-- Iteration 3 -- +NULL +int(0) +bool(false) +bool(false) +NULL +bool(false) +NULL +int(0) +array(1) { + [0]=> + NULL +} + +-- Iteration 4 -- +NULL +int(0) +bool(false) +bool(false) +NULL +bool(false) +NULL +int(0) +array(1) { + [0]=> + NULL +} + +-- Iteration 5 -- +NULL +int(0) +bool(true) +bool(true) +int(1) +NULL +NULL +int(2) +string(0) "" +string(0) "" +int(3) +int(1) +int(1) +int(4) +bool(false) +bool(false) +NULL +bool(false) +NULL +int(0) +array(5) { + [0]=> + NULL + [1]=> + bool(true) + [2]=> + NULL + [3]=> + string(0) "" + [4]=> + int(1) +} + +-- Iteration 6 -- +string(4) "test" +int(-1) +string(4) "rest" +string(4) "rest" +int(-2) +string(3) "two" +string(3) "two" +int(2) +string(0) "" +string(0) "" +string(0) "" +string(4) "zero" +string(4) "zero" +int(0) +bool(false) +bool(false) +NULL +bool(false) +string(4) "test" +int(-1) +array(5) { + [-1]=> + string(4) "test" + [-2]=> + string(4) "rest" + [2]=> + string(3) "two" + [""]=> + string(0) "" + [0]=> + string(4) "zero" +} + +Done diff --git a/tests/std/array/array_all_basic.phpt b/tests/std/array/array_all_basic.phpt new file mode 100644 index 00000000..37a33069 --- /dev/null +++ b/tests/std/array/array_all_basic.phpt @@ -0,0 +1,59 @@ +--TEST-- +Test array_all() function : basic functionality +--SKIPIF-- +--FILE-- + 1, + "b" => 2, + "c" => 3, + "d" => 4, + "e" => 5, +]; + +$array2 = [ + 1, 2, 3, 4, 5 +]; + +var_dump(array_all($array1, fn($value, $key) => $value > 0)); +var_dump(array_all($array2, fn($value, $key) => $value > 0)); +var_dump(array_all($array2, fn($value, $key) => $value > 1)); +var_dump(array_all([], fn($value, $key) => true)); + +var_dump(array_all($array1, 'even')); + +var_dump(array_all($array1, 'return_nothing')); + +var_dump(array_all($array1, [ + 'SmallerTenClass', + 'smallerTen' +])); + +var_dump(array_all($array1, "SmallerTenClass::smallerTen")); +} +?> +--EXPECT-- +bool(true) +bool(true) +bool(false) +bool(true) +bool(false) +bool(false) +bool(true) +bool(true) diff --git a/tests/std/array/array_any_basic.phpt b/tests/std/array/array_any_basic.phpt new file mode 100644 index 00000000..47606623 --- /dev/null +++ b/tests/std/array/array_any_basic.phpt @@ -0,0 +1,51 @@ +--TEST-- +Test array_any() function : basic functionality +--SKIPIF-- + + +--FILE-- + 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5]; + $array2 = [1, 2, 3, 4, 5]; + var_dump(array_any($array1, fn($value, $key) => $value > 3)); + var_dump(array_any($array2, fn($value, $key) => $value > 3)); + var_dump(array_any($array2, fn($value, $key) => $value > 5)); + var_dump(array_any([], fn($value, $key) => true)); + var_dump(array_any($array1, fn($value, $key) => $key === "c")); + var_dump(array_any($array1, fn($value, $key) => false)); + var_dump(array_any($array1, 'even')); + var_dump(array_any($array1, 'return_nothing')); + var_dump(array_any($array1, ['EvenClass', 'even'])); + var_dump(array_any($array1, "EvenClass::even")); +} +?> +--EXPECT-- +bool(true) +bool(true) +bool(false) +bool(false) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +bool(true) diff --git a/tests/std/array/array_change_key_case.phpt b/tests/std/array/array_change_key_case.phpt new file mode 100644 index 00000000..92c45640 --- /dev/null +++ b/tests/std/array/array_change_key_case.phpt @@ -0,0 +1,811 @@ +--TEST-- +Test array_change_key_case() function +--FILE-- + 1), + array ("a" => 1), + array ("Z" => 1), + array ("one" => 1), + array ("ONE" => 1), + array ("OnE" => 1), + array ("oNe" => 1), + array ("one" => 1, "two" => 2), + array ("ONE" => 1, "two" => 2), + array ("OnE" => 1, "two" => 2), + array ("oNe" => 1, "two" => 2), + array ("one" => 1, "TWO" => 2), + array ("ONE" => 1, "TWO" => 2), + array ("OnE" => 1, "TWO" => 2), + array ("oNe" => 1, "TWO" => 2), + array ("one" => 1, "TwO" => 2), + array ("ONE" => 1, "TwO" => 2), + array ("OnE" => 1, "TwO" => 2), + array ("oNe" => 1, "TwO" => 2), + array ("one" => 1, "tWo" => 2), + array ("ONE" => 1, "tWo" => 2), + array ("OnE" => 1, "tWo" => 2), + array ("oNe" => 1, "tWo" => 2), + array ("one" => 1, 2), + array ("ONE" => 1, 2), + array ("OnE" => 1, 2), + array ("oNe" => 1, 2), + array ("ONE" => 1, "TWO" => 2, "THREE" => 3, "FOUR" => "four"), + array ("one" => 1, "two" => 2, "three" => 3, "four" => "FOUR"), + array ("ONE" => 1, "TWO" => 2, "three" => 3, "four" => "FOUR"), + array ("one" => 1, "two" => 2, "THREE" => 3, "FOUR" => "four") +); + +echo "*** Testing basic operations ***\n"; +$loop_counter = 1; +foreach ($arrays as $item) { + echo "** Iteration $loop_counter **\n"; $loop_counter++; + var_dump(array_change_key_case($item)); + var_dump(array_change_key_case($item, CASE_UPPER)); + var_dump(array_change_key_case($item, CASE_LOWER)); + echo "\n"; +} + +echo "end\n"; +?> +--EXPECT-- +*** Testing basic operations *** +** Iteration 1 ** +array(0) { +} +array(0) { +} +array(0) { +} + +** Iteration 2 ** +array(1) { + [0]=> + int(0) +} +array(1) { + [0]=> + int(0) +} +array(1) { + [0]=> + int(0) +} + +** Iteration 3 ** +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(1) +} + +** Iteration 4 ** +array(1) { + [0]=> + int(-1) +} +array(1) { + [0]=> + int(-1) +} +array(1) { + [0]=> + int(-1) +} + +** Iteration 5 ** +array(5) { + [0]=> + int(0) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} +array(5) { + [0]=> + int(0) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} +array(5) { + [0]=> + int(0) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} + +** Iteration 6 ** +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) +} + +** Iteration 7 ** +array(1) { + [""]=> + int(1) +} +array(1) { + [""]=> + int(1) +} +array(1) { + [""]=> + int(1) +} + +** Iteration 8 ** +array(1) { + ["a"]=> + int(1) +} +array(1) { + ["A"]=> + int(1) +} +array(1) { + ["a"]=> + int(1) +} + +** Iteration 9 ** +array(1) { + ["z"]=> + int(1) +} +array(1) { + ["Z"]=> + int(1) +} +array(1) { + ["z"]=> + int(1) +} + +** Iteration 10 ** +array(1) { + ["one"]=> + int(1) +} +array(1) { + ["ONE"]=> + int(1) +} +array(1) { + ["one"]=> + int(1) +} + +** Iteration 11 ** +array(1) { + ["one"]=> + int(1) +} +array(1) { + ["ONE"]=> + int(1) +} +array(1) { + ["one"]=> + int(1) +} + +** Iteration 12 ** +array(1) { + ["one"]=> + int(1) +} +array(1) { + ["ONE"]=> + int(1) +} +array(1) { + ["one"]=> + int(1) +} + +** Iteration 13 ** +array(1) { + ["one"]=> + int(1) +} +array(1) { + ["ONE"]=> + int(1) +} +array(1) { + ["one"]=> + int(1) +} + +** Iteration 14 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 15 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 16 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 17 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 18 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 19 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 20 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 21 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 22 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 23 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 24 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 25 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 26 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 27 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 28 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 29 ** +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} + +** Iteration 30 ** +array(2) { + ["one"]=> + int(1) + [0]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + [0]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + [0]=> + int(2) +} + +** Iteration 31 ** +array(2) { + ["one"]=> + int(1) + [0]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + [0]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + [0]=> + int(2) +} + +** Iteration 32 ** +array(2) { + ["one"]=> + int(1) + [0]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + [0]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + [0]=> + int(2) +} + +** Iteration 33 ** +array(2) { + ["one"]=> + int(1) + [0]=> + int(2) +} +array(2) { + ["ONE"]=> + int(1) + [0]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + [0]=> + int(2) +} + +** Iteration 34 ** +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + ["four"]=> + string(4) "four" +} +array(4) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) + ["THREE"]=> + int(3) + ["FOUR"]=> + string(4) "four" +} +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + ["four"]=> + string(4) "four" +} + +** Iteration 35 ** +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + ["four"]=> + string(4) "FOUR" +} +array(4) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) + ["THREE"]=> + int(3) + ["FOUR"]=> + string(4) "FOUR" +} +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + ["four"]=> + string(4) "FOUR" +} + +** Iteration 36 ** +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + ["four"]=> + string(4) "FOUR" +} +array(4) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) + ["THREE"]=> + int(3) + ["FOUR"]=> + string(4) "FOUR" +} +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + ["four"]=> + string(4) "FOUR" +} + +** Iteration 37 ** +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + ["four"]=> + string(4) "four" +} +array(4) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) + ["THREE"]=> + int(3) + ["FOUR"]=> + string(4) "four" +} +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + ["four"]=> + string(4) "four" +} + +end diff --git a/tests/std/array/array_change_key_case_variation.phpt b/tests/std/array/array_change_key_case_variation.phpt new file mode 100644 index 00000000..c221a3f3 --- /dev/null +++ b/tests/std/array/array_change_key_case_variation.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test array_change_key_case() function - 2 +--FILE-- + 1, "two" => 2, "THREE" => 3, "FOUR" => "four"); + +/* use 'case' argument other than CASE_LOWER & CASE_UPPER */ +try { + var_dump(array_change_key_case($item, "CASE_UPPER")); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +var_dump(array_change_key_case($item, 5)); + +/* when keys are different in terms of only case */ +/* should return one value key pair with key being in lowercase */ +var_dump( array_change_key_case( array("ONE" => 1, "one" => 3, "One" => 4) ) ); + +/* should return one value key pair with key being in uppercase */ +var_dump( array_change_key_case( array("ONE" => 1, "one" => 2, "One" => 3), CASE_UPPER ) ); +var_dump( array_change_key_case( array("ONE" => 1, "one" => 1, "One" => 2), 5 ) ); + +echo "end\n"; +?> +--EXPECT-- +array_change_key_case(): Argument #2 ($case) must be of type int, string given +array(4) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) + ["THREE"]=> + int(3) + ["FOUR"]=> + string(4) "four" +} +array(1) { + ["one"]=> + int(4) +} +array(1) { + ["ONE"]=> + int(3) +} +array(1) { + ["ONE"]=> + int(2) +} +end diff --git a/tests/std/array/array_change_key_case_variation3.phpt b/tests/std/array/array_change_key_case_variation3.phpt new file mode 100644 index 00000000..8edec6ef --- /dev/null +++ b/tests/std/array/array_change_key_case_variation3.phpt @@ -0,0 +1,167 @@ +--TEST-- +Test array_change_key_case() function : usage variations - different data types as keys +--SKIPIF-- + + +--FILE-- + array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative', + ), + + // null data +/*3*/ 'null uppercase' => array( + NULL => 'null 1', + ), + 'null lowercase' => array( + null => 'null 2', + ), + + // boolean data +/*4*/ 'bool lowercase' => array( + true => 'lowert', + false => 'lowerf', + ), + 'bool uppercase' => array( + TRUE => 'uppert', + FALSE => 'upperf', + ), + + // empty data +/*5*/ 'empty double quotes' => array( + "" => 'emptyd', + ), + 'empty single quotes' => array( + '' => 'emptys', + ), + + // string data +/*6*/ 'string' => array( + "stringd" => 'stringd', + 'strings' => 'strings', + $heredoc => 'stringh', + ), + + // undefined data +/*8*/ 'undefined' => array( + @$undefined_var => 'undefined', + ), + + // unset data +/*9*/ 'unset' => array( + @$unset_var => 'unset', + ), +); + +// loop through each sub-array of $inputs to check the behavior of array_change_key_case() +$iterator = 1; +foreach($inputs as $key => $input) { + echo "\n-- Iteration $iterator : $key data --\n"; + var_dump( array_change_key_case($input, CASE_UPPER) ); + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_change_key_case() : usage variations *** + +-- Iteration 1 : int data -- +array(4) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [12345]=> + string(8) "positive" + [-2345]=> + string(8) "negative" +} + +-- Iteration 2 : null uppercase data -- +array(1) { + [""]=> + string(6) "null 1" +} + +-- Iteration 3 : null lowercase data -- +array(1) { + [""]=> + string(6) "null 2" +} + +-- Iteration 4 : bool lowercase data -- +array(2) { + [1]=> + string(6) "lowert" + [0]=> + string(6) "lowerf" +} + +-- Iteration 5 : bool uppercase data -- +array(2) { + [1]=> + string(6) "uppert" + [0]=> + string(6) "upperf" +} + +-- Iteration 6 : empty double quotes data -- +array(1) { + [""]=> + string(6) "emptyd" +} + +-- Iteration 7 : empty single quotes data -- +array(1) { + [""]=> + string(6) "emptys" +} + +-- Iteration 8 : string data -- +array(3) { + ["STRINGD"]=> + string(7) "stringd" + ["STRINGS"]=> + string(7) "strings" + ["HELLO WORLD"]=> + string(7) "stringh" +} + +-- Iteration 9 : undefined data -- +array(1) { + [""]=> + string(9) "undefined" +} + +-- Iteration 10 : unset data -- +array(1) { + [""]=> + string(5) "unset" +} +Done diff --git a/tests/std/array/array_change_key_case_variation4.phpt b/tests/std/array/array_change_key_case_variation4.phpt new file mode 100644 index 00000000..82d21145 --- /dev/null +++ b/tests/std/array/array_change_key_case_variation4.phpt @@ -0,0 +1,132 @@ +--TEST-- +Test array_change_key_case() function : usage variations - different int values for $case +--FILE-- + 'un', 'TWO' => 'deux', 'three' => 'trois'); +for ($i = -5; $i <=5; $i += 1){ + echo "\n-- \$sort argument is $i --\n"; + $temp = $input; + var_dump(array_change_key_case($temp, $i)); +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_change_key_case() : usage variations *** + +-- $sort argument is -5 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} + +-- $sort argument is -4 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} + +-- $sort argument is -3 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} + +-- $sort argument is -2 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} + +-- $sort argument is -1 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} + +-- $sort argument is 0 -- +array(3) { + ["one"]=> + string(2) "un" + ["two"]=> + string(4) "deux" + ["three"]=> + string(5) "trois" +} + +-- $sort argument is 1 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} + +-- $sort argument is 2 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} + +-- $sort argument is 3 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} + +-- $sort argument is 4 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} + +-- $sort argument is 5 -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} +Done diff --git a/tests/std/array/array_change_key_case_variation5.phpt b/tests/std/array/array_change_key_case_variation5.phpt new file mode 100644 index 00000000..7fe48e87 --- /dev/null +++ b/tests/std/array/array_change_key_case_variation5.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test array_change_key_case() function : usage variations - position of internal pointer +--FILE-- + 'un', 'two' => 'deux', 'three' => 'trois'); + +echo "\n-- Call array_change_key_case() --\n"; +var_dump($result = array_change_key_case($input, CASE_UPPER)); + +echo "-- Position of Internal Pointer in Result: --\n"; +echo key($result) . " => " . current($result) . "\n"; +echo "\n-- Position of Internal Pointer in Original Array: --\n"; +echo key($input) . " => " . current ($input) . "\n"; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_change_key_case() : usage variations *** + +-- Call array_change_key_case() -- +array(3) { + ["ONE"]=> + string(2) "un" + ["TWO"]=> + string(4) "deux" + ["THREE"]=> + string(5) "trois" +} +-- Position of Internal Pointer in Result: -- +ONE => un + +-- Position of Internal Pointer in Original Array: -- +one => un +Done diff --git a/tests/std/array/array_change_key_case_variation6.phpt b/tests/std/array/array_change_key_case_variation6.phpt new file mode 100644 index 00000000..1357650e --- /dev/null +++ b/tests/std/array/array_change_key_case_variation6.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test array_change_key_case() function : usage variations - multidimensional arrays +--FILE-- + array('one' => 1, 'two' => 2, 'three' => 3), + 'French' => array('un' => 1, 'deux' => 2, 'trois' => 3), + 'German' => array('eins' => 1, 'zwei' => 2, 'drei' => 3)); + +echo "\n-- Pass a two-dimensional array as \$input argument --\n"; +var_dump(array_change_key_case($input, CASE_UPPER)); + +echo "\n-- Pass a sub-array as \$input argument --\n"; +var_dump(array_change_key_case($input['English'], CASE_UPPER)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_change_key_case() : usage variations *** + +-- Pass a two-dimensional array as $input argument -- +array(3) { + ["ENGLISH"]=> + array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + } + ["FRENCH"]=> + array(3) { + ["un"]=> + int(1) + ["deux"]=> + int(2) + ["trois"]=> + int(3) + } + ["GERMAN"]=> + array(3) { + ["eins"]=> + int(1) + ["zwei"]=> + int(2) + ["drei"]=> + int(3) + } +} + +-- Pass a sub-array as $input argument -- +array(3) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) + ["THREE"]=> + int(3) +} +Done diff --git a/tests/std/array/array_change_key_case_variation7.phpt b/tests/std/array/array_change_key_case_variation7.phpt new file mode 100644 index 00000000..44fd6adb --- /dev/null +++ b/tests/std/array/array_change_key_case_variation7.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test array_change_key_case() function : usage variations - referenced variables +--FILE-- + 1, 'two' => 2, 'ABC' => 'xyz'); + +echo "\n-- \$input argument is a reference to array --\n"; +$new_input = &$input; +echo "Result:\n"; +var_dump(array_change_key_case($new_input, CASE_UPPER)); +echo "Original:\n"; +var_dump($input); +echo "Referenced:\n"; +var_dump($new_input); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_change_key_case() : usage variations *** + +-- $input argument is a reference to array -- +Result: +array(3) { + ["ONE"]=> + int(1) + ["TWO"]=> + int(2) + ["ABC"]=> + string(3) "xyz" +} +Original: +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["ABC"]=> + string(3) "xyz" +} +Referenced: +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["ABC"]=> + string(3) "xyz" +} +Done diff --git a/tests/std/array/array_change_key_case_variation8.phpt b/tests/std/array/array_change_key_case_variation8.phpt new file mode 100644 index 00000000..bb81d939 --- /dev/null +++ b/tests/std/array/array_change_key_case_variation8.phpt @@ -0,0 +1,124 @@ +--TEST-- +Test array_change_key_case() function : usage variations - Different strings as keys +--SKIPIF-- + +--FILE-- + 1, NULL => 2, "\a" => 3, "\cx" => 4, "\e" => 5, "\f" => 6, "\n" => 7, "\t" => 8, "\xhh" => 9, "\ddd" => 10, "\v" => 11), + + // array contains combination of capital/small letters + array("lemoN" => 1, "Orange" => 2, "banana" => 3, "apple" => 4, "Test" => 5, "TTTT" => 6, "ttt" => 7, "ww" => 8, "x" => 9, "X" => 10, "oraNGe" => 11, "BANANA" => 12) +); + +foreach($inputs as $input) { + echo "\n-- \$case = default --\n"; + var_dump(array_change_key_case($input)); + echo "-- \$case = upper --\n"; + var_dump(array_change_key_case($input, CASE_UPPER)); +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_change_key_case() : usage variations *** + +-- $case = default -- +array(10) { + [""]=> + int(2) + ["\a"]=> + int(3) + ["\cx"]=> + int(4) + [""]=> + int(5) + [" "]=> + int(6) + [" +"]=> + int(7) + [" "]=> + int(8) + ["\xhh"]=> + int(9) + ["\ddd"]=> + int(10) + [" "]=> + int(11) +} +-- $case = upper -- +array(10) { + [""]=> + int(2) + ["\A"]=> + int(3) + ["\CX"]=> + int(4) + [""]=> + int(5) + [" "]=> + int(6) + [" +"]=> + int(7) + [" "]=> + int(8) + ["\XHH"]=> + int(9) + ["\DDD"]=> + int(10) + [" "]=> + int(11) +} + +-- $case = default -- +array(9) { + ["lemon"]=> + int(1) + ["orange"]=> + int(11) + ["banana"]=> + int(12) + ["apple"]=> + int(4) + ["test"]=> + int(5) + ["tttt"]=> + int(6) + ["ttt"]=> + int(7) + ["ww"]=> + int(8) + ["x"]=> + int(10) +} +-- $case = upper -- +array(9) { + ["LEMON"]=> + int(1) + ["ORANGE"]=> + int(11) + ["BANANA"]=> + int(12) + ["APPLE"]=> + int(4) + ["TEST"]=> + int(5) + ["TTTT"]=> + int(6) + ["TTT"]=> + int(7) + ["WW"]=> + int(8) + ["X"]=> + int(10) +} +Done diff --git a/tests/std/array/array_chunk2.phpt b/tests/std/array/array_chunk2.phpt new file mode 100644 index 00000000..c83f051a --- /dev/null +++ b/tests/std/array/array_chunk2.phpt @@ -0,0 +1,154 @@ +--TEST-- +basic array_chunk test +--FILE-- +getMessage() . "\n"; +} + +try { + var_dump(array_chunk($input_array, 0, true)); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +var_dump(array_chunk($input_array, 1)); +var_dump(array_chunk($input_array, 1, true)); +var_dump(array_chunk($input_array, 2)); +var_dump(array_chunk($input_array, 2, true)); +var_dump(array_chunk($input_array, 10)); +var_dump(array_chunk($input_array, 10, true)); +?> +--EXPECT-- +array_chunk(): Argument #2 ($length) must be greater than 0 +array_chunk(): Argument #2 ($length) must be greater than 0 +array(5) { + [0]=> + array(1) { + [0]=> + string(1) "a" + } + [1]=> + array(1) { + [0]=> + string(1) "b" + } + [2]=> + array(1) { + [0]=> + string(1) "c" + } + [3]=> + array(1) { + [0]=> + string(1) "d" + } + [4]=> + array(1) { + [0]=> + string(1) "e" + } +} +array(5) { + [0]=> + array(1) { + [0]=> + string(1) "a" + } + [1]=> + array(1) { + [1]=> + string(1) "b" + } + [2]=> + array(1) { + [2]=> + string(1) "c" + } + [3]=> + array(1) { + [3]=> + string(1) "d" + } + [4]=> + array(1) { + [4]=> + string(1) "e" + } +} +array(3) { + [0]=> + array(2) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + } + [1]=> + array(2) { + [0]=> + string(1) "c" + [1]=> + string(1) "d" + } + [2]=> + array(1) { + [0]=> + string(1) "e" + } +} +array(3) { + [0]=> + array(2) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + } + [1]=> + array(2) { + [2]=> + string(1) "c" + [3]=> + string(1) "d" + } + [2]=> + array(1) { + [4]=> + string(1) "e" + } +} +array(1) { + [0]=> + array(5) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "d" + [4]=> + string(1) "e" + } +} +array(1) { + [0]=> + array(5) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "d" + [4]=> + string(1) "e" + } +} diff --git a/tests/std/array/array_chunk_basic1.phpt b/tests/std/array/array_chunk_basic1.phpt new file mode 100644 index 00000000..e03749ec --- /dev/null +++ b/tests/std/array/array_chunk_basic1.phpt @@ -0,0 +1,132 @@ +--TEST-- +Test array_chunk() function : basic functionality - default 'preserve_keys' +--FILE-- + 1, "key2" => 2, "key3" => 3), + + // associative arrays - key as numeric + array(1 => 'one', 2 => "two", 3 => "three"), + + // array containing elements with/without keys + array(1 => 'one','two', 3 => 'three', 4, "five" => 5) + +); + +$count = 1; +// loop through each element of the array for input +foreach ($input_arrays as $input_array){ + echo "\n-- Iteration $count --\n"; + var_dump( array_chunk($input_array, $size) ); + $count++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_chunk() : basic functionality *** + +-- Iteration 1 -- +array(3) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } + [2]=> + array(1) { + [0]=> + int(5) + } +} + +-- Iteration 2 -- +array(2) { + [0]=> + array(2) { + [0]=> + string(6) "value1" + [1]=> + string(6) "value2" + } + [1]=> + array(1) { + [0]=> + string(6) "value3" + } +} + +-- Iteration 3 -- +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} + +-- Iteration 4 -- +array(2) { + [0]=> + array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + } + [1]=> + array(1) { + [0]=> + string(5) "three" + } +} + +-- Iteration 5 -- +array(3) { + [0]=> + array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + } + [1]=> + array(2) { + [0]=> + string(5) "three" + [1]=> + int(4) + } + [2]=> + array(1) { + [0]=> + int(5) + } +} +Done diff --git a/tests/std/array/array_chunk_basic2.phpt b/tests/std/array/array_chunk_basic2.phpt new file mode 100644 index 00000000..472df0fe --- /dev/null +++ b/tests/std/array/array_chunk_basic2.phpt @@ -0,0 +1,216 @@ +--TEST-- +Test array_chunk() function : basic functionality - 'preserve_keys' as true/false +--FILE-- + 1, "key2" => 2, "key3" => 3), + + // associative arrays - key as numeric + array(1 => 'one', 2 => "two", 3 => "three"), + + // array containing elements with/without keys + array(1 => 'one','two', 3 => 'three', 4, "five" => 5) +); + +$count = 1; +// loop through each element of the array for input +foreach ($input_arrays as $input_array){ + echo "\n-- Iteration $count --\n"; + var_dump( array_chunk($input_array, $size, true) ); + var_dump( array_chunk($input_array, $size, false) ); + $count++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_chunk() : basic functionality *** + +-- Iteration 1 -- +array(3) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [2]=> + int(3) + [3]=> + int(4) + } + [2]=> + array(1) { + [4]=> + int(5) + } +} +array(3) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } + [2]=> + array(1) { + [0]=> + int(5) + } +} + +-- Iteration 2 -- +array(2) { + [0]=> + array(2) { + [0]=> + string(6) "value1" + [1]=> + string(6) "value2" + } + [1]=> + array(1) { + [2]=> + string(6) "value3" + } +} +array(2) { + [0]=> + array(2) { + [0]=> + string(6) "value1" + [1]=> + string(6) "value2" + } + [1]=> + array(1) { + [0]=> + string(6) "value3" + } +} + +-- Iteration 3 -- +array(2) { + [0]=> + array(2) { + ["key1"]=> + int(1) + ["key2"]=> + int(2) + } + [1]=> + array(1) { + ["key3"]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} + +-- Iteration 4 -- +array(2) { + [0]=> + array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + } + [1]=> + array(1) { + [3]=> + string(5) "three" + } +} +array(2) { + [0]=> + array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + } + [1]=> + array(1) { + [0]=> + string(5) "three" + } +} + +-- Iteration 5 -- +array(3) { + [0]=> + array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + } + [1]=> + array(2) { + [3]=> + string(5) "three" + [4]=> + int(4) + } + [2]=> + array(1) { + ["five"]=> + int(5) + } +} +array(3) { + [0]=> + array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + } + [1]=> + array(2) { + [0]=> + string(5) "three" + [1]=> + int(4) + } + [2]=> + array(1) { + [0]=> + int(5) + } +} +Done diff --git a/tests/std/array/array_chunk_variation10.phpt b/tests/std/array/array_chunk_variation10.phpt new file mode 100644 index 00000000..326d7de9 --- /dev/null +++ b/tests/std/array/array_chunk_variation10.phpt @@ -0,0 +1,154 @@ +--TEST-- +array_chunk() - variation 10 +--FILE-- + 1, 2 => 2, 3 => 3); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(3) { + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) +} +[1] +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [1]=> + int(1) + } + [1]=> + array(1) { + [2]=> + int(2) + } + [2]=> + array(1) { + [3]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} + +[2] +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(1) { + [3]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} + +[3] +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} diff --git a/tests/std/array/array_chunk_variation11.phpt b/tests/std/array/array_chunk_variation11.phpt new file mode 100644 index 00000000..e3ce4453 --- /dev/null +++ b/tests/std/array/array_chunk_variation11.phpt @@ -0,0 +1,88 @@ +--TEST-- +array_chunk() - variation 11 +--FILE-- + 0, 3 => 2); + +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(2) { + [0]=> + int(0) + [3]=> + int(2) +} +[1] +array(2) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [3]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} + +[2] +array(1) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + [0]=> + int(0) + [3]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(2) + } +} diff --git a/tests/std/array/array_chunk_variation12.phpt b/tests/std/array/array_chunk_variation12.phpt new file mode 100644 index 00000000..3b0cb79b --- /dev/null +++ b/tests/std/array/array_chunk_variation12.phpt @@ -0,0 +1,154 @@ +--TEST-- +array_chunk() - variation 12 +--FILE-- + 1, 5 => 2, 8 => 3); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(3) { + [1]=> + int(1) + [5]=> + int(2) + [8]=> + int(3) +} +[1] +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [1]=> + int(1) + } + [1]=> + array(1) { + [5]=> + int(2) + } + [2]=> + array(1) { + [8]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} + +[2] +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [1]=> + int(1) + [5]=> + int(2) + } + [1]=> + array(1) { + [8]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} + +[3] +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [1]=> + int(1) + [5]=> + int(2) + [8]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} diff --git a/tests/std/array/array_chunk_variation13.phpt b/tests/std/array/array_chunk_variation13.phpt new file mode 100644 index 00000000..f62d309c --- /dev/null +++ b/tests/std/array/array_chunk_variation13.phpt @@ -0,0 +1,87 @@ +--TEST-- +array_chunk() - variation 13 +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +[1] +array(2) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [1]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} + +[2] +array(1) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} diff --git a/tests/std/array/array_chunk_variation14.phpt b/tests/std/array/array_chunk_variation14.phpt new file mode 100644 index 00000000..64746bf6 --- /dev/null +++ b/tests/std/array/array_chunk_variation14.phpt @@ -0,0 +1,154 @@ +--TEST-- +array_chunk() - variation 14 +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) +} +[1] +array(3) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [1]=> + int(1) + } + [2]=> + array(1) { + [2]=> + int(2) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } +} + +[2] +array(2) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(1) { + [2]=> + int(2) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} + +[3] +array(1) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } +} diff --git a/tests/std/array/array_chunk_variation15.phpt b/tests/std/array/array_chunk_variation15.phpt new file mode 100644 index 00000000..294dd9f8 --- /dev/null +++ b/tests/std/array/array_chunk_variation15.phpt @@ -0,0 +1,154 @@ +--TEST-- +array_chunk() - variation 15 +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +[1] +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [1]=> + int(2) + } + [2]=> + array(1) { + [2]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} + +[2] +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [2]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} + +[3] +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} diff --git a/tests/std/array/array_chunk_variation16.phpt b/tests/std/array/array_chunk_variation16.phpt new file mode 100644 index 00000000..b7159cba --- /dev/null +++ b/tests/std/array/array_chunk_variation16.phpt @@ -0,0 +1,233 @@ +--TEST-- +array_chunk() - variation 16 +--FILE-- + +--EXPECT-- +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) +} +[1] +array(4) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } + [3]=> + array(1) { + [0]=> + int(3) + } +} +array(4) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [1]=> + int(1) + } + [2]=> + array(1) { + [2]=> + int(2) + } + [3]=> + array(1) { + [3]=> + int(3) + } +} +array(4) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } + [3]=> + array(1) { + [0]=> + int(3) + } +} + +[2] +array(2) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(2) { + [0]=> + int(2) + [1]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(2) { + [2]=> + int(2) + [3]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(2) { + [0]=> + int(2) + [1]=> + int(3) + } +} + +[3] +array(2) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} +array(2) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(1) { + [3]=> + int(3) + } +} +array(2) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} + +[4] +array(1) { + [0]=> + array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } +} +array(1) { + [0]=> + array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } +} +array(1) { + [0]=> + array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } +} diff --git a/tests/std/array/array_chunk_variation17.phpt b/tests/std/array/array_chunk_variation17.phpt new file mode 100644 index 00000000..07826d06 --- /dev/null +++ b/tests/std/array/array_chunk_variation17.phpt @@ -0,0 +1,233 @@ +--TEST-- +array_chunk() - variation 17 +--FILE-- + +--EXPECT-- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) +} +[1] +array(4) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } + [3]=> + array(1) { + [0]=> + int(4) + } +} +array(4) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [1]=> + int(2) + } + [2]=> + array(1) { + [2]=> + int(3) + } + [3]=> + array(1) { + [3]=> + int(4) + } +} +array(4) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } + [3]=> + array(1) { + [0]=> + int(4) + } +} + +[2] +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [2]=> + int(3) + [3]=> + int(4) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } +} + +[3] +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(1) { + [0]=> + int(4) + } +} +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(1) { + [3]=> + int(4) + } +} +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(1) { + [0]=> + int(4) + } +} + +[4] +array(1) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } +} +array(1) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } +} +array(1) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } +} diff --git a/tests/std/array/array_chunk_variation18.phpt b/tests/std/array/array_chunk_variation18.phpt new file mode 100644 index 00000000..1fa9ca6e --- /dev/null +++ b/tests/std/array/array_chunk_variation18.phpt @@ -0,0 +1,333 @@ +--TEST-- +array_chunk() - variation 18 +--FILE-- + +--EXPECT-- +array(5) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) +} +[1] +array(5) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } + [3]=> + array(1) { + [0]=> + int(3) + } + [4]=> + array(1) { + [0]=> + int(4) + } +} +array(5) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [1]=> + int(1) + } + [2]=> + array(1) { + [2]=> + int(2) + } + [3]=> + array(1) { + [3]=> + int(3) + } + [4]=> + array(1) { + [4]=> + int(4) + } +} +array(5) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } + [3]=> + array(1) { + [0]=> + int(3) + } + [4]=> + array(1) { + [0]=> + int(4) + } +} + +[2] +array(3) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(2) { + [0]=> + int(2) + [1]=> + int(3) + } + [2]=> + array(1) { + [0]=> + int(4) + } +} +array(3) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(2) { + [2]=> + int(2) + [3]=> + int(3) + } + [2]=> + array(1) { + [4]=> + int(4) + } +} +array(3) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(2) { + [0]=> + int(2) + [1]=> + int(3) + } + [2]=> + array(1) { + [0]=> + int(4) + } +} + +[3] +array(2) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } +} +array(2) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(2) { + [3]=> + int(3) + [4]=> + int(4) + } +} +array(2) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } +} + +[4] +array(2) { + [0]=> + array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } + [1]=> + array(1) { + [0]=> + int(4) + } +} +array(2) { + [0]=> + array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } + [1]=> + array(1) { + [4]=> + int(4) + } +} +array(2) { + [0]=> + array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } + [1]=> + array(1) { + [0]=> + int(4) + } +} + +[5] +array(1) { + [0]=> + array(5) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + } +} +array(1) { + [0]=> + array(5) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + } +} +array(1) { + [0]=> + array(5) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + } +} diff --git a/tests/std/array/array_chunk_variation19.phpt b/tests/std/array/array_chunk_variation19.phpt new file mode 100644 index 00000000..2591db89 --- /dev/null +++ b/tests/std/array/array_chunk_variation19.phpt @@ -0,0 +1,1013 @@ +--TEST-- +array_chunk() - variation 19 +--FILE-- + +--EXPECT-- +array(10) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) +} +[1] +array(10) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } + [3]=> + array(1) { + [0]=> + int(4) + } + [4]=> + array(1) { + [0]=> + int(5) + } + [5]=> + array(1) { + [0]=> + int(6) + } + [6]=> + array(1) { + [0]=> + int(7) + } + [7]=> + array(1) { + [0]=> + int(8) + } + [8]=> + array(1) { + [0]=> + int(9) + } + [9]=> + array(1) { + [0]=> + int(10) + } +} +array(10) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [1]=> + int(2) + } + [2]=> + array(1) { + [2]=> + int(3) + } + [3]=> + array(1) { + [3]=> + int(4) + } + [4]=> + array(1) { + [4]=> + int(5) + } + [5]=> + array(1) { + [5]=> + int(6) + } + [6]=> + array(1) { + [6]=> + int(7) + } + [7]=> + array(1) { + [7]=> + int(8) + } + [8]=> + array(1) { + [8]=> + int(9) + } + [9]=> + array(1) { + [9]=> + int(10) + } +} +array(10) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } + [3]=> + array(1) { + [0]=> + int(4) + } + [4]=> + array(1) { + [0]=> + int(5) + } + [5]=> + array(1) { + [0]=> + int(6) + } + [6]=> + array(1) { + [0]=> + int(7) + } + [7]=> + array(1) { + [0]=> + int(8) + } + [8]=> + array(1) { + [0]=> + int(9) + } + [9]=> + array(1) { + [0]=> + int(10) + } +} + +[2] +array(5) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } + [2]=> + array(2) { + [0]=> + int(5) + [1]=> + int(6) + } + [3]=> + array(2) { + [0]=> + int(7) + [1]=> + int(8) + } + [4]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} +array(5) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [2]=> + int(3) + [3]=> + int(4) + } + [2]=> + array(2) { + [4]=> + int(5) + [5]=> + int(6) + } + [3]=> + array(2) { + [6]=> + int(7) + [7]=> + int(8) + } + [4]=> + array(2) { + [8]=> + int(9) + [9]=> + int(10) + } +} +array(5) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } + [2]=> + array(2) { + [0]=> + int(5) + [1]=> + int(6) + } + [3]=> + array(2) { + [0]=> + int(7) + [1]=> + int(8) + } + [4]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} + +[3] +array(4) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } + [3]=> + array(1) { + [0]=> + int(10) + } +} +array(4) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } + [2]=> + array(3) { + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + } + [3]=> + array(1) { + [9]=> + int(10) + } +} +array(4) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } + [2]=> + array(3) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + } + [3]=> + array(1) { + [0]=> + int(10) + } +} + +[4] +array(3) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + [1]=> + array(4) { + [0]=> + int(5) + [1]=> + int(6) + [2]=> + int(7) + [3]=> + int(8) + } + [2]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} +array(3) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + [1]=> + array(4) { + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + } + [2]=> + array(2) { + [8]=> + int(9) + [9]=> + int(10) + } +} +array(3) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + [1]=> + array(4) { + [0]=> + int(5) + [1]=> + int(6) + [2]=> + int(7) + [3]=> + int(8) + } + [2]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} + +[5] +array(2) { + [0]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [1]=> + array(5) { + [0]=> + int(6) + [1]=> + int(7) + [2]=> + int(8) + [3]=> + int(9) + [4]=> + int(10) + } +} +array(2) { + [0]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [1]=> + array(5) { + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) + } +} +array(2) { + [0]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [1]=> + array(5) { + [0]=> + int(6) + [1]=> + int(7) + [2]=> + int(8) + [3]=> + int(9) + [4]=> + int(10) + } +} + +[6] +array(2) { + [0]=> + array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } + [1]=> + array(4) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + [3]=> + int(10) + } +} +array(2) { + [0]=> + array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } + [1]=> + array(4) { + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) + } +} +array(2) { + [0]=> + array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } + [1]=> + array(4) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + [3]=> + int(10) + } +} + +[7] +array(2) { + [0]=> + array(7) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + } + [1]=> + array(3) { + [0]=> + int(8) + [1]=> + int(9) + [2]=> + int(10) + } +} +array(2) { + [0]=> + array(7) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + } + [1]=> + array(3) { + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) + } +} +array(2) { + [0]=> + array(7) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + } + [1]=> + array(3) { + [0]=> + int(8) + [1]=> + int(9) + [2]=> + int(10) + } +} + +[8] +array(2) { + [0]=> + array(8) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + } + [1]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} +array(2) { + [0]=> + array(8) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + } + [1]=> + array(2) { + [8]=> + int(9) + [9]=> + int(10) + } +} +array(2) { + [0]=> + array(8) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + } + [1]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} + +[9] +array(2) { + [0]=> + array(9) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + } + [1]=> + array(1) { + [0]=> + int(10) + } +} +array(2) { + [0]=> + array(9) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + } + [1]=> + array(1) { + [9]=> + int(10) + } +} +array(2) { + [0]=> + array(9) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + } + [1]=> + array(1) { + [0]=> + int(10) + } +} + +[10] +array(1) { + [0]=> + array(10) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) + } +} +array(1) { + [0]=> + array(10) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) + } +} +array(1) { + [0]=> + array(10) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) + } +} diff --git a/tests/std/array/array_chunk_variation20.phpt b/tests/std/array/array_chunk_variation20.phpt new file mode 100644 index 00000000..ec2e45b1 --- /dev/null +++ b/tests/std/array/array_chunk_variation20.phpt @@ -0,0 +1,1194 @@ +--TEST-- +array_chunk() - variation 20 +--FILE-- + +--EXPECT-- +array(11) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + [10]=> + int(10) +} +[1] +array(11) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } + [3]=> + array(1) { + [0]=> + int(3) + } + [4]=> + array(1) { + [0]=> + int(4) + } + [5]=> + array(1) { + [0]=> + int(5) + } + [6]=> + array(1) { + [0]=> + int(6) + } + [7]=> + array(1) { + [0]=> + int(7) + } + [8]=> + array(1) { + [0]=> + int(8) + } + [9]=> + array(1) { + [0]=> + int(9) + } + [10]=> + array(1) { + [0]=> + int(10) + } +} +array(11) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [1]=> + int(1) + } + [2]=> + array(1) { + [2]=> + int(2) + } + [3]=> + array(1) { + [3]=> + int(3) + } + [4]=> + array(1) { + [4]=> + int(4) + } + [5]=> + array(1) { + [5]=> + int(5) + } + [6]=> + array(1) { + [6]=> + int(6) + } + [7]=> + array(1) { + [7]=> + int(7) + } + [8]=> + array(1) { + [8]=> + int(8) + } + [9]=> + array(1) { + [9]=> + int(9) + } + [10]=> + array(1) { + [10]=> + int(10) + } +} +array(11) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + array(1) { + [0]=> + int(2) + } + [3]=> + array(1) { + [0]=> + int(3) + } + [4]=> + array(1) { + [0]=> + int(4) + } + [5]=> + array(1) { + [0]=> + int(5) + } + [6]=> + array(1) { + [0]=> + int(6) + } + [7]=> + array(1) { + [0]=> + int(7) + } + [8]=> + array(1) { + [0]=> + int(8) + } + [9]=> + array(1) { + [0]=> + int(9) + } + [10]=> + array(1) { + [0]=> + int(10) + } +} + +[2] +array(6) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(2) { + [0]=> + int(2) + [1]=> + int(3) + } + [2]=> + array(2) { + [0]=> + int(4) + [1]=> + int(5) + } + [3]=> + array(2) { + [0]=> + int(6) + [1]=> + int(7) + } + [4]=> + array(2) { + [0]=> + int(8) + [1]=> + int(9) + } + [5]=> + array(1) { + [0]=> + int(10) + } +} +array(6) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(2) { + [2]=> + int(2) + [3]=> + int(3) + } + [2]=> + array(2) { + [4]=> + int(4) + [5]=> + int(5) + } + [3]=> + array(2) { + [6]=> + int(6) + [7]=> + int(7) + } + [4]=> + array(2) { + [8]=> + int(8) + [9]=> + int(9) + } + [5]=> + array(1) { + [10]=> + int(10) + } +} +array(6) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(1) + } + [1]=> + array(2) { + [0]=> + int(2) + [1]=> + int(3) + } + [2]=> + array(2) { + [0]=> + int(4) + [1]=> + int(5) + } + [3]=> + array(2) { + [0]=> + int(6) + [1]=> + int(7) + } + [4]=> + array(2) { + [0]=> + int(8) + [1]=> + int(9) + } + [5]=> + array(1) { + [0]=> + int(10) + } +} + +[3] +array(4) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(3) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) + } + [2]=> + array(3) { + [0]=> + int(6) + [1]=> + int(7) + [2]=> + int(8) + } + [3]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} +array(4) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(3) { + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + } + [2]=> + array(3) { + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + } + [3]=> + array(2) { + [9]=> + int(9) + [10]=> + int(10) + } +} +array(4) { + [0]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + [1]=> + array(3) { + [0]=> + int(3) + [1]=> + int(4) + [2]=> + int(5) + } + [2]=> + array(3) { + [0]=> + int(6) + [1]=> + int(7) + [2]=> + int(8) + } + [3]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} + +[4] +array(3) { + [0]=> + array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } + [1]=> + array(4) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + [3]=> + int(7) + } + [2]=> + array(3) { + [0]=> + int(8) + [1]=> + int(9) + [2]=> + int(10) + } +} +array(3) { + [0]=> + array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } + [1]=> + array(4) { + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + } + [2]=> + array(3) { + [8]=> + int(8) + [9]=> + int(9) + [10]=> + int(10) + } +} +array(3) { + [0]=> + array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + } + [1]=> + array(4) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + [3]=> + int(7) + } + [2]=> + array(3) { + [0]=> + int(8) + [1]=> + int(9) + [2]=> + int(10) + } +} + +[5] +array(3) { + [0]=> + array(5) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + } + [1]=> + array(5) { + [0]=> + int(5) + [1]=> + int(6) + [2]=> + int(7) + [3]=> + int(8) + [4]=> + int(9) + } + [2]=> + array(1) { + [0]=> + int(10) + } +} +array(3) { + [0]=> + array(5) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + } + [1]=> + array(5) { + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + } + [2]=> + array(1) { + [10]=> + int(10) + } +} +array(3) { + [0]=> + array(5) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + } + [1]=> + array(5) { + [0]=> + int(5) + [1]=> + int(6) + [2]=> + int(7) + [3]=> + int(8) + [4]=> + int(9) + } + [2]=> + array(1) { + [0]=> + int(10) + } +} + +[6] +array(2) { + [0]=> + array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + } + [1]=> + array(5) { + [0]=> + int(6) + [1]=> + int(7) + [2]=> + int(8) + [3]=> + int(9) + [4]=> + int(10) + } +} +array(2) { + [0]=> + array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + } + [1]=> + array(5) { + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + [10]=> + int(10) + } +} +array(2) { + [0]=> + array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + } + [1]=> + array(5) { + [0]=> + int(6) + [1]=> + int(7) + [2]=> + int(8) + [3]=> + int(9) + [4]=> + int(10) + } +} + +[7] +array(2) { + [0]=> + array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + } + [1]=> + array(4) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + [3]=> + int(10) + } +} +array(2) { + [0]=> + array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + } + [1]=> + array(4) { + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + [10]=> + int(10) + } +} +array(2) { + [0]=> + array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + } + [1]=> + array(4) { + [0]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) + [3]=> + int(10) + } +} + +[8] +array(2) { + [0]=> + array(8) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + } + [1]=> + array(3) { + [0]=> + int(8) + [1]=> + int(9) + [2]=> + int(10) + } +} +array(2) { + [0]=> + array(8) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + } + [1]=> + array(3) { + [8]=> + int(8) + [9]=> + int(9) + [10]=> + int(10) + } +} +array(2) { + [0]=> + array(8) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + } + [1]=> + array(3) { + [0]=> + int(8) + [1]=> + int(9) + [2]=> + int(10) + } +} + +[9] +array(2) { + [0]=> + array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + } + [1]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} +array(2) { + [0]=> + array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + } + [1]=> + array(2) { + [9]=> + int(9) + [10]=> + int(10) + } +} +array(2) { + [0]=> + array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + } + [1]=> + array(2) { + [0]=> + int(9) + [1]=> + int(10) + } +} + +[10] +array(2) { + [0]=> + array(10) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + } + [1]=> + array(1) { + [0]=> + int(10) + } +} +array(2) { + [0]=> + array(10) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + } + [1]=> + array(1) { + [10]=> + int(10) + } +} +array(2) { + [0]=> + array(10) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + } + [1]=> + array(1) { + [0]=> + int(10) + } +} + +[11] +array(1) { + [0]=> + array(11) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + [10]=> + int(10) + } +} +array(1) { + [0]=> + array(11) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + [10]=> + int(10) + } +} +array(1) { + [0]=> + array(11) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) + [7]=> + int(7) + [8]=> + int(8) + [9]=> + int(9) + [10]=> + int(10) + } +} diff --git a/tests/std/array/array_chunk_variation21.phpt b/tests/std/array/array_chunk_variation21.phpt new file mode 100644 index 00000000..ce672a92 --- /dev/null +++ b/tests/std/array/array_chunk_variation21.phpt @@ -0,0 +1,41 @@ +--TEST-- +array_chunk() - variation 21 +--FILE-- + 1); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(1) { + ["a"]=> + int(1) +} +[1] +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} +array(1) { + [0]=> + array(1) { + ["a"]=> + int(1) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} diff --git a/tests/std/array/array_chunk_variation22.phpt b/tests/std/array/array_chunk_variation22.phpt new file mode 100644 index 00000000..d67269f4 --- /dev/null +++ b/tests/std/array/array_chunk_variation22.phpt @@ -0,0 +1,87 @@ +--TEST-- +array_chunk() - variation 22 +--FILE-- + 1, "c" => 2); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(2) { + ["b"]=> + int(1) + ["c"]=> + int(2) +} +[1] +array(2) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + ["b"]=> + int(1) + } + [1]=> + array(1) { + ["c"]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} + +[2] +array(1) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + ["b"]=> + int(1) + ["c"]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} diff --git a/tests/std/array/array_chunk_variation23.phpt b/tests/std/array/array_chunk_variation23.phpt new file mode 100644 index 00000000..99138eae --- /dev/null +++ b/tests/std/array/array_chunk_variation23.phpt @@ -0,0 +1,436 @@ +--TEST-- +array_chunk() - variation 23 +--FILE-- + 1, "q" => 2, "r" => 3, "s" => 4, "u" => 5, "v" => 6); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(6) { + ["p"]=> + int(1) + ["q"]=> + int(2) + ["r"]=> + int(3) + ["s"]=> + int(4) + ["u"]=> + int(5) + ["v"]=> + int(6) +} +[1] +array(6) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } + [3]=> + array(1) { + [0]=> + int(4) + } + [4]=> + array(1) { + [0]=> + int(5) + } + [5]=> + array(1) { + [0]=> + int(6) + } +} +array(6) { + [0]=> + array(1) { + ["p"]=> + int(1) + } + [1]=> + array(1) { + ["q"]=> + int(2) + } + [2]=> + array(1) { + ["r"]=> + int(3) + } + [3]=> + array(1) { + ["s"]=> + int(4) + } + [4]=> + array(1) { + ["u"]=> + int(5) + } + [5]=> + array(1) { + ["v"]=> + int(6) + } +} +array(6) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } + [3]=> + array(1) { + [0]=> + int(4) + } + [4]=> + array(1) { + [0]=> + int(5) + } + [5]=> + array(1) { + [0]=> + int(6) + } +} + +[2] +array(3) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } + [2]=> + array(2) { + [0]=> + int(5) + [1]=> + int(6) + } +} +array(3) { + [0]=> + array(2) { + ["p"]=> + int(1) + ["q"]=> + int(2) + } + [1]=> + array(2) { + ["r"]=> + int(3) + ["s"]=> + int(4) + } + [2]=> + array(2) { + ["u"]=> + int(5) + ["v"]=> + int(6) + } +} +array(3) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(4) + } + [2]=> + array(2) { + [0]=> + int(5) + [1]=> + int(6) + } +} + +[3] +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} +array(2) { + [0]=> + array(3) { + ["p"]=> + int(1) + ["q"]=> + int(2) + ["r"]=> + int(3) + } + [1]=> + array(3) { + ["s"]=> + int(4) + ["u"]=> + int(5) + ["v"]=> + int(6) + } +} +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) + } +} + +[4] +array(2) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + [1]=> + array(2) { + [0]=> + int(5) + [1]=> + int(6) + } +} +array(2) { + [0]=> + array(4) { + ["p"]=> + int(1) + ["q"]=> + int(2) + ["r"]=> + int(3) + ["s"]=> + int(4) + } + [1]=> + array(2) { + ["u"]=> + int(5) + ["v"]=> + int(6) + } +} +array(2) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + [1]=> + array(2) { + [0]=> + int(5) + [1]=> + int(6) + } +} + +[5] +array(2) { + [0]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [1]=> + array(1) { + [0]=> + int(6) + } +} +array(2) { + [0]=> + array(5) { + ["p"]=> + int(1) + ["q"]=> + int(2) + ["r"]=> + int(3) + ["s"]=> + int(4) + ["u"]=> + int(5) + } + [1]=> + array(1) { + ["v"]=> + int(6) + } +} +array(2) { + [0]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [1]=> + array(1) { + [0]=> + int(6) + } +} + +[6] +array(1) { + [0]=> + array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } +} +array(1) { + [0]=> + array(6) { + ["p"]=> + int(1) + ["q"]=> + int(2) + ["r"]=> + int(3) + ["s"]=> + int(4) + ["u"]=> + int(5) + ["v"]=> + int(6) + } +} +array(1) { + [0]=> + array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } +} diff --git a/tests/std/array/array_chunk_variation24.phpt b/tests/std/array/array_chunk_variation24.phpt new file mode 100644 index 00000000..c96d59d8 --- /dev/null +++ b/tests/std/array/array_chunk_variation24.phpt @@ -0,0 +1,41 @@ +--TEST-- +array_chunk() - variation 24 +--FILE-- + "A"); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(1) { + ["a"]=> + string(1) "A" +} +[1] +array(1) { + [0]=> + array(1) { + [0]=> + string(1) "A" + } +} +array(1) { + [0]=> + array(1) { + ["a"]=> + string(1) "A" + } +} +array(1) { + [0]=> + array(1) { + [0]=> + string(1) "A" + } +} diff --git a/tests/std/array/array_chunk_variation25.phpt b/tests/std/array/array_chunk_variation25.phpt new file mode 100644 index 00000000..978588e0 --- /dev/null +++ b/tests/std/array/array_chunk_variation25.phpt @@ -0,0 +1,436 @@ +--TEST-- +array_chunk() - variation 25 +--FILE-- + "A", "q" => "B", "r" => "C", "s" => "D", "u" => "E", "v" => "F"); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(6) { + ["p"]=> + string(1) "A" + ["q"]=> + string(1) "B" + ["r"]=> + string(1) "C" + ["s"]=> + string(1) "D" + ["u"]=> + string(1) "E" + ["v"]=> + string(1) "F" +} +[1] +array(6) { + [0]=> + array(1) { + [0]=> + string(1) "A" + } + [1]=> + array(1) { + [0]=> + string(1) "B" + } + [2]=> + array(1) { + [0]=> + string(1) "C" + } + [3]=> + array(1) { + [0]=> + string(1) "D" + } + [4]=> + array(1) { + [0]=> + string(1) "E" + } + [5]=> + array(1) { + [0]=> + string(1) "F" + } +} +array(6) { + [0]=> + array(1) { + ["p"]=> + string(1) "A" + } + [1]=> + array(1) { + ["q"]=> + string(1) "B" + } + [2]=> + array(1) { + ["r"]=> + string(1) "C" + } + [3]=> + array(1) { + ["s"]=> + string(1) "D" + } + [4]=> + array(1) { + ["u"]=> + string(1) "E" + } + [5]=> + array(1) { + ["v"]=> + string(1) "F" + } +} +array(6) { + [0]=> + array(1) { + [0]=> + string(1) "A" + } + [1]=> + array(1) { + [0]=> + string(1) "B" + } + [2]=> + array(1) { + [0]=> + string(1) "C" + } + [3]=> + array(1) { + [0]=> + string(1) "D" + } + [4]=> + array(1) { + [0]=> + string(1) "E" + } + [5]=> + array(1) { + [0]=> + string(1) "F" + } +} + +[2] +array(3) { + [0]=> + array(2) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + } + [1]=> + array(2) { + [0]=> + string(1) "C" + [1]=> + string(1) "D" + } + [2]=> + array(2) { + [0]=> + string(1) "E" + [1]=> + string(1) "F" + } +} +array(3) { + [0]=> + array(2) { + ["p"]=> + string(1) "A" + ["q"]=> + string(1) "B" + } + [1]=> + array(2) { + ["r"]=> + string(1) "C" + ["s"]=> + string(1) "D" + } + [2]=> + array(2) { + ["u"]=> + string(1) "E" + ["v"]=> + string(1) "F" + } +} +array(3) { + [0]=> + array(2) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + } + [1]=> + array(2) { + [0]=> + string(1) "C" + [1]=> + string(1) "D" + } + [2]=> + array(2) { + [0]=> + string(1) "E" + [1]=> + string(1) "F" + } +} + +[3] +array(2) { + [0]=> + array(3) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + } + [1]=> + array(3) { + [0]=> + string(1) "D" + [1]=> + string(1) "E" + [2]=> + string(1) "F" + } +} +array(2) { + [0]=> + array(3) { + ["p"]=> + string(1) "A" + ["q"]=> + string(1) "B" + ["r"]=> + string(1) "C" + } + [1]=> + array(3) { + ["s"]=> + string(1) "D" + ["u"]=> + string(1) "E" + ["v"]=> + string(1) "F" + } +} +array(2) { + [0]=> + array(3) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + } + [1]=> + array(3) { + [0]=> + string(1) "D" + [1]=> + string(1) "E" + [2]=> + string(1) "F" + } +} + +[4] +array(2) { + [0]=> + array(4) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + string(1) "D" + } + [1]=> + array(2) { + [0]=> + string(1) "E" + [1]=> + string(1) "F" + } +} +array(2) { + [0]=> + array(4) { + ["p"]=> + string(1) "A" + ["q"]=> + string(1) "B" + ["r"]=> + string(1) "C" + ["s"]=> + string(1) "D" + } + [1]=> + array(2) { + ["u"]=> + string(1) "E" + ["v"]=> + string(1) "F" + } +} +array(2) { + [0]=> + array(4) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + string(1) "D" + } + [1]=> + array(2) { + [0]=> + string(1) "E" + [1]=> + string(1) "F" + } +} + +[5] +array(2) { + [0]=> + array(5) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + string(1) "D" + [4]=> + string(1) "E" + } + [1]=> + array(1) { + [0]=> + string(1) "F" + } +} +array(2) { + [0]=> + array(5) { + ["p"]=> + string(1) "A" + ["q"]=> + string(1) "B" + ["r"]=> + string(1) "C" + ["s"]=> + string(1) "D" + ["u"]=> + string(1) "E" + } + [1]=> + array(1) { + ["v"]=> + string(1) "F" + } +} +array(2) { + [0]=> + array(5) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + string(1) "D" + [4]=> + string(1) "E" + } + [1]=> + array(1) { + [0]=> + string(1) "F" + } +} + +[6] +array(1) { + [0]=> + array(6) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + string(1) "D" + [4]=> + string(1) "E" + [5]=> + string(1) "F" + } +} +array(1) { + [0]=> + array(6) { + ["p"]=> + string(1) "A" + ["q"]=> + string(1) "B" + ["r"]=> + string(1) "C" + ["s"]=> + string(1) "D" + ["u"]=> + string(1) "E" + ["v"]=> + string(1) "F" + } +} +array(1) { + [0]=> + array(6) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + string(1) "D" + [4]=> + string(1) "E" + [5]=> + string(1) "F" + } +} diff --git a/tests/std/array/array_chunk_variation26.phpt b/tests/std/array/array_chunk_variation26.phpt new file mode 100644 index 00000000..7b46215f --- /dev/null +++ b/tests/std/array/array_chunk_variation26.phpt @@ -0,0 +1,41 @@ +--TEST-- +array_chunk() - variation 26 +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + int(0) +} +[1] +array(1) { + [0]=> + array(1) { + [0]=> + int(0) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(0) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(0) + } +} diff --git a/tests/std/array/array_chunk_variation27.phpt b/tests/std/array/array_chunk_variation27.phpt new file mode 100644 index 00000000..a91a8b91 --- /dev/null +++ b/tests/std/array/array_chunk_variation27.phpt @@ -0,0 +1,41 @@ +--TEST-- +array_chunk() - variation 27 +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + int(1) +} +[1] +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} diff --git a/tests/std/array/array_chunk_variation28.phpt b/tests/std/array/array_chunk_variation28.phpt new file mode 100644 index 00000000..707b0cde --- /dev/null +++ b/tests/std/array/array_chunk_variation28.phpt @@ -0,0 +1,41 @@ +--TEST-- +array_chunk() - variation 28 +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + int(-1) +} +[1] +array(1) { + [0]=> + array(1) { + [0]=> + int(-1) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(-1) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(-1) + } +} diff --git a/tests/std/array/array_chunk_variation29.phpt b/tests/std/array/array_chunk_variation29.phpt new file mode 100644 index 00000000..07187135 --- /dev/null +++ b/tests/std/array/array_chunk_variation29.phpt @@ -0,0 +1,87 @@ +--TEST-- +array_chunk() - variation 29 +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + int(0) + [1]=> + int(2) +} +[1] +array(2) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [1]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} + +[2] +array(1) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(2) + } +} diff --git a/tests/std/array/array_chunk_variation30.phpt b/tests/std/array/array_chunk_variation30.phpt new file mode 100644 index 00000000..5400b595 --- /dev/null +++ b/tests/std/array/array_chunk_variation30.phpt @@ -0,0 +1,154 @@ +--TEST-- +array_chunk() - variation 30 +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +[1] +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [1]=> + int(2) + } + [2]=> + array(1) { + [2]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} + +[2] +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [2]=> + int(3) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(3) + } +} + +[3] +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} diff --git a/tests/std/array/array_chunk_variation31.phpt b/tests/std/array/array_chunk_variation31.phpt new file mode 100644 index 00000000..ffdfa2bc --- /dev/null +++ b/tests/std/array/array_chunk_variation31.phpt @@ -0,0 +1,41 @@ +--TEST-- +array_chunk() - variation 31 +--FILE-- + 0); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(1) { + [1]=> + int(0) +} +[1] +array(1) { + [0]=> + array(1) { + [0]=> + int(0) + } +} +array(1) { + [0]=> + array(1) { + [1]=> + int(0) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(0) + } +} diff --git a/tests/std/array/array_chunk_variation32.phpt b/tests/std/array/array_chunk_variation32.phpt new file mode 100644 index 00000000..b0a01f20 --- /dev/null +++ b/tests/std/array/array_chunk_variation32.phpt @@ -0,0 +1,41 @@ +--TEST-- +array_chunk() - variation 32 +--FILE-- + 1); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(1) { + [2]=> + int(1) +} +[1] +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} +array(1) { + [0]=> + array(1) { + [2]=> + int(1) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} diff --git a/tests/std/array/array_chunk_variation4.phpt b/tests/std/array/array_chunk_variation4.phpt new file mode 100644 index 00000000..265fc390 --- /dev/null +++ b/tests/std/array/array_chunk_variation4.phpt @@ -0,0 +1,114 @@ +--TEST-- +Test array_chunk() function : usage variations - array with diff. sub arrays +--FILE-- + array(), + "array2" => array(1, 2, 3), + "array3" => array(1) +); + +echo "\n-- Testing array_chunk() by supplying an array containing different sub arrays & 'preserve_key' as default --\n"; +var_dump( array_chunk($input_array, $size) ); + +echo "\n-- Testing array_chunk() by supplying an array containing different sub arrays & 'preserve_key' = true --\n"; +var_dump( array_chunk($input_array, $size, true) ); + +echo "\n-- Testing array_chunk() by supplying an array containing different sub arrays & 'preserve_key' = false --\n"; +var_dump( array_chunk($input_array, $size, false) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_chunk() : usage variations *** + +-- Testing array_chunk() by supplying an array containing different sub arrays & 'preserve_key' as default -- +array(2) { + [0]=> + array(2) { + [0]=> + array(0) { + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + } + [1]=> + array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } + } +} + +-- Testing array_chunk() by supplying an array containing different sub arrays & 'preserve_key' = true -- +array(2) { + [0]=> + array(2) { + ["array1"]=> + array(0) { + } + ["array2"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + } + [1]=> + array(1) { + ["array3"]=> + array(1) { + [0]=> + int(1) + } + } +} + +-- Testing array_chunk() by supplying an array containing different sub arrays & 'preserve_key' = false -- +array(2) { + [0]=> + array(2) { + [0]=> + array(0) { + } + [1]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + } + [1]=> + array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } + } +} +Done diff --git a/tests/std/array/array_chunk_variation5.phpt b/tests/std/array/array_chunk_variation5.phpt new file mode 100644 index 00000000..dfae4897 --- /dev/null +++ b/tests/std/array/array_chunk_variation5.phpt @@ -0,0 +1,140 @@ +--TEST-- +Test array_chunk() function : usage variations - different 'size' values +--FILE-- +getMessage() . "\n"; + } + try { + var_dump( array_chunk($input_array, $size, true) ); + } catch (\ValueError $e) { + echo $e->getMessage() . "\n"; + } + try { + var_dump( array_chunk($input_array, $size, false) ); + } catch (\ValueError $e) { + echo $e->getMessage() . "\n"; + } +} +?> +--EXPECT-- +*** Testing array_chunk() : usage variations *** + +-- Testing array_chunk() when size = -1 -- +array_chunk(): Argument #2 ($length) must be greater than 0 +array_chunk(): Argument #2 ($length) must be greater than 0 +array_chunk(): Argument #2 ($length) must be greater than 0 + +-- Testing array_chunk() when size = 4 -- +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} + +-- Testing array_chunk() when size = 0 -- +array_chunk(): Argument #2 ($length) must be greater than 0 +array_chunk(): Argument #2 ($length) must be greater than 0 +array_chunk(): Argument #2 ($length) must be greater than 0 + +-- Testing array_chunk() when size = 1 -- +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [1]=> + int(2) + } + [2]=> + array(1) { + [2]=> + int(3) + } +} +array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(3) + } +} diff --git a/tests/std/array/array_chunk_variation6.phpt b/tests/std/array/array_chunk_variation6.phpt new file mode 100644 index 00000000..c9c34e51 --- /dev/null +++ b/tests/std/array/array_chunk_variation6.phpt @@ -0,0 +1,129 @@ +--TEST-- +Test array_chunk() function : usage variations - different arrays +--FILE-- + array(), + + // array with one element + "array2" => array(1), + + // associative array with duplicate keys + "array3" => array("a" => 1, "b" => 2, "c" => 3, "a" => 4, "d" => 5) + +); + +$size = 2; +$count = 1; + +echo "\n-- Testing array_chunk() by supplying various arrays --\n"; + +// loop through the array for 'array' argument +foreach ($input_arrays as $input_array){ + echo "\n-- Iteration $count --\n"; + var_dump( array_chunk($input_array, $size) ); + var_dump( array_chunk($input_array, $size, true) ); + var_dump( array_chunk($input_array, $size, false) ); + $count++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_chunk() : usage variations *** + +-- Testing array_chunk() by supplying various arrays -- + +-- Iteration 1 -- +array(0) { +} +array(0) { +} +array(0) { +} + +-- Iteration 2 -- +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(1) + } +} + +-- Iteration 3 -- +array(2) { + [0]=> + array(2) { + [0]=> + int(4) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(5) + } +} +array(2) { + [0]=> + array(2) { + ["a"]=> + int(4) + ["b"]=> + int(2) + } + [1]=> + array(2) { + ["c"]=> + int(3) + ["d"]=> + int(5) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + int(4) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(3) + [1]=> + int(5) + } +} +Done diff --git a/tests/std/array/array_chunk_variation7.phpt b/tests/std/array/array_chunk_variation7.phpt new file mode 100644 index 00000000..8deb9a32 --- /dev/null +++ b/tests/std/array/array_chunk_variation7.phpt @@ -0,0 +1,85 @@ +--TEST-- +Test array_chunk() function : usage variations - references +--SKIPIF-- + +--FILE-- + &$numbers[0], + "two" => &$numbers[1], + "three" => &$numbers[2], + "four" => &$numbers[3] +); + +var_dump( array_chunk($input_array, $size) ); +var_dump( array_chunk($input_array, $size, true) ); +var_dump( array_chunk($input_array, $size, false) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_chunk() : usage variations *** + +-- Testing array_chunk(), input array containing references +array(2) { + [0]=> + array(2) { + [0]=> + &int(1) + [1]=> + &int(2) + } + [1]=> + array(2) { + [0]=> + &int(3) + [1]=> + &int(4) + } +} +array(2) { + [0]=> + array(2) { + ["one"]=> + &int(1) + ["two"]=> + &int(2) + } + [1]=> + array(2) { + ["three"]=> + &int(3) + ["four"]=> + &int(4) + } +} +array(2) { + [0]=> + array(2) { + [0]=> + &int(1) + [1]=> + &int(2) + } + [1]=> + array(2) { + [0]=> + &int(3) + [1]=> + &int(4) + } +} +Done diff --git a/tests/std/array/array_chunk_variation8.phpt b/tests/std/array/array_chunk_variation8.phpt new file mode 100644 index 00000000..2d8fa07c --- /dev/null +++ b/tests/std/array/array_chunk_variation8.phpt @@ -0,0 +1,41 @@ +--TEST-- +array_chunk() - variation 8 +--FILE-- + -1); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(1) { + [3]=> + int(-1) +} +[1] +array(1) { + [0]=> + array(1) { + [0]=> + int(-1) + } +} +array(1) { + [0]=> + array(1) { + [3]=> + int(-1) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(-1) + } +} diff --git a/tests/std/array/array_chunk_variation9.phpt b/tests/std/array/array_chunk_variation9.phpt new file mode 100644 index 00000000..2be7b81e --- /dev/null +++ b/tests/std/array/array_chunk_variation9.phpt @@ -0,0 +1,87 @@ +--TEST-- +array_chunk() - variation 9 +--FILE-- + 0, 2 => 2); +var_dump ($array); +for ($i = 1; $i < (sizeof($array) + 1); $i++) { + echo "[$i]\n"; + var_dump (array_chunk ($array, $i)); + var_dump (array_chunk ($array, $i, TRUE)); + var_dump (array_chunk ($array, $i, FALSE)); + echo "\n"; +} +?> +--EXPECT-- +array(2) { + [1]=> + int(0) + [2]=> + int(2) +} +[1] +array(2) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + [1]=> + int(0) + } + [1]=> + array(1) { + [2]=> + int(2) + } +} +array(2) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} + +[2] +array(1) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + [1]=> + int(0) + [2]=> + int(2) + } +} +array(1) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(2) + } +} diff --git a/tests/std/array/array_column_basic.phpt b/tests/std/array/array_column_basic.phpt new file mode 100644 index 00000000..a7d0ec70 --- /dev/null +++ b/tests/std/array/array_column_basic.phpt @@ -0,0 +1,259 @@ +--TEST-- +Test array_column() function: basic functionality +--SKIPIF-- + +--FILE-- + 1, 'first_name' => 'John', 'last_name' => 'Doe'), array('id' => 2, 'first_name' => 'Sally', 'last_name' => 'Smith'), array('id' => 3, 'first_name' => 'Jane', 'last_name' => 'Jones')); + echo "-- first_name column from recordset --\n"; + var_dump(array_column($records, 'first_name')); + echo "-- id column from recordset --\n"; + var_dump(array_column($records, 'id')); + echo "-- last_name column from recordset, keyed by value from id column --\n"; + var_dump(array_column($records, 'last_name', 'id')); + echo "-- last_name column from recordset, keyed by value from first_name column --\n"; + var_dump(array_column($records, 'last_name', 'first_name')); + echo "\n*** Testing multiple data types ***\n"; + $fh = fopen(__FILE__, 'r', true); + $values = array(array('id' => 1, 'value' => new stdClass()), array('id' => 2, 'value' => 34.2345), array('id' => 3, 'value' => true), array('id' => 4, 'value' => false), array('id' => 5, 'value' => null), array('id' => 6, 'value' => 1234), array('id' => 7, 'value' => 'Foo'), array('id' => 8, 'value' => $fh)); + var_dump(array_column($values, 'value')); + var_dump(array_column($values, 'value', 'id')); + echo "\n*** Testing numeric column keys ***\n"; + $numericCols = array(array('aaa', '111'), array('bbb', '222'), array('ccc', '333', -1 => 'ddd')); + var_dump(array_column($numericCols, 1)); + var_dump(array_column($numericCols, 1, 0)); + var_dump(array_column($numericCols, 1, 0.123)); + var_dump(array_column($numericCols, 1, -1)); + echo "\n*** Testing failure to find specified column ***\n"; + var_dump(array_column($numericCols, 2)); + var_dump(array_column($numericCols, 'foo')); + var_dump(array_column($numericCols, 0, 'foo')); + var_dump(array_column($numericCols, 3.14)); + echo "\n*** Testing single dimensional array ***\n"; + $singleDimension = array('foo', 'bar', 'baz'); + var_dump(array_column($singleDimension, 1)); + echo "\n*** Testing columns not present in all rows ***\n"; + $mismatchedColumns = array(array('a' => 'foo', 'b' => 'bar', 'e' => 'bbb'), array('a' => 'baz', 'c' => 'qux', 'd' => 'aaa'), array('a' => 'eee', 'b' => 'fff', 'e' => 'ggg')); + var_dump(array_column($mismatchedColumns, 'c')); + var_dump(array_column($mismatchedColumns, 'c', 'a')); + var_dump(array_column($mismatchedColumns, 'a', 'd')); + var_dump(array_column($mismatchedColumns, 'a', 'e')); + var_dump(array_column($mismatchedColumns, 'b')); + var_dump(array_column($mismatchedColumns, 'b', 'a')); + echo "\n*** Testing use of object converted to string ***\n"; + $f = new Foo(); + $b = new Bar(); + var_dump(array_column($records, $f)); + var_dump(array_column($records, $f, $b)); + echo "Done\n"; +} +?> +--EXPECTF-- +*** Testing array_column() : basic functionality *** +-- first_name column from recordset -- +array(3) { + [0]=> + string(4) "John" + [1]=> + string(5) "Sally" + [2]=> + string(4) "Jane" +} +-- id column from recordset -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +-- last_name column from recordset, keyed by value from id column -- +array(3) { + [1]=> + string(3) "Doe" + [2]=> + string(5) "Smith" + [3]=> + string(5) "Jones" +} +-- last_name column from recordset, keyed by value from first_name column -- +array(3) { + ["John"]=> + string(3) "Doe" + ["Sally"]=> + string(5) "Smith" + ["Jane"]=> + string(5) "Jones" +} + +*** Testing multiple data types *** +array(8) { + [0]=> + object(stdClass)#%d (0) { + } + [1]=> + float(34.2345) + [2]=> + bool(true) + [3]=> + bool(false) + [4]=> + NULL + [5]=> + int(1234) + [6]=> + string(3) "Foo" + [7]=> + resource(%d) of type (stream) +} +array(8) { + [1]=> + object(stdClass)#%d (0) { + } + [2]=> + float(34.2345) + [3]=> + bool(true) + [4]=> + bool(false) + [5]=> + NULL + [6]=> + int(1234) + [7]=> + string(3) "Foo" + [8]=> + resource(%d) of type (stream) +} + +*** Testing numeric column keys *** +array(3) { + [0]=> + string(3) "111" + [1]=> + string(3) "222" + [2]=> + string(3) "333" +} +array(3) { + ["aaa"]=> + string(3) "111" + ["bbb"]=> + string(3) "222" + ["ccc"]=> + string(3) "333" +} + +Deprecated: Implicit conversion from float 0.123 to int loses precision in %s on line %d +array(3) { + ["aaa"]=> + string(3) "111" + ["bbb"]=> + string(3) "222" + ["ccc"]=> + string(3) "333" +} +array(3) { + [0]=> + string(3) "111" + [1]=> + string(3) "222" + ["ddd"]=> + string(3) "333" +} + +*** Testing failure to find specified column *** +array(0) { +} +array(0) { +} +array(3) { + [0]=> + string(3) "aaa" + [1]=> + string(3) "bbb" + [2]=> + string(3) "ccc" +} + +Deprecated: Implicit conversion from float 3.14 to int loses precision in %s on line %d +array(0) { +} + +*** Testing single dimensional array *** +array(0) { +} + +*** Testing columns not present in all rows *** +array(1) { + [0]=> + string(3) "qux" +} +array(1) { + ["baz"]=> + string(3) "qux" +} +array(3) { + [0]=> + string(3) "foo" + ["aaa"]=> + string(3) "baz" + [1]=> + string(3) "eee" +} +array(3) { + ["bbb"]=> + string(3) "foo" + [0]=> + string(3) "baz" + ["ggg"]=> + string(3) "eee" +} +array(2) { + [0]=> + string(3) "bar" + [1]=> + string(3) "fff" +} +array(2) { + ["foo"]=> + string(3) "bar" + ["eee"]=> + string(3) "fff" +} + +*** Testing use of object converted to string *** +array(3) { + [0]=> + string(3) "Doe" + [1]=> + string(5) "Smith" + [2]=> + string(5) "Jones" +} +array(3) { + ["John"]=> + string(3) "Doe" + ["Sally"]=> + string(5) "Smith" + ["Jane"]=> + string(5) "Jones" +} +Done diff --git a/tests/std/array/array_column_numeric_string_key.phpt b/tests/std/array/array_column_numeric_string_key.phpt new file mode 100644 index 00000000..aed3c35e --- /dev/null +++ b/tests/std/array/array_column_numeric_string_key.phpt @@ -0,0 +1,23 @@ +--TEST-- +array_column() treats numeric string keys as usual +--FILE-- + 'a'], [42 => 'b']]; +var_dump(array_column($array, 42)); +var_dump(array_column($array, "42")); + +?> +--EXPECT-- +array(2) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" +} +array(2) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" +} diff --git a/tests/std/array/array_column_object_cast.phpt b/tests/std/array/array_column_object_cast.phpt new file mode 100644 index 00000000..eee58528 --- /dev/null +++ b/tests/std/array/array_column_object_cast.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test array_column() function: basic functionality +--FILE-- + 2135, 'first_name' => 'John', 'last_name' => 'XXX'), array('id' => 3245, 'first_name' => 'Sally', 'last_name' => 'Smith')); + $firstNames = array_column($records, $column_key, $index_key); + print_r($firstNames); + var_dump($column_key); + var_dump($index_key); +} +?> +--EXPECT-- +Array +( + [2135] => John + [3245] => Sally +) +object(ColumnKeyClass)#1 (0) { +} +object(IndexKeyClass)#2 (0) { +} diff --git a/tests/std/array/array_column_property_visibility.phpt b/tests/std/array/array_column_property_visibility.phpt new file mode 100644 index 00000000..3595596c --- /dev/null +++ b/tests/std/array/array_column_property_visibility.phpt @@ -0,0 +1,31 @@ +--TEST-- +array_column() respects property visibility +--FILE-- +prop = $value; + } + public function __isset($name): bool + { + return true; + } + public function __get($name) + { + return "__get({$this->prop})"; + } +} +function main() +{ + $arr = [new Test("foobar")]; + var_dump(array_column($arr, "prop")); +} +?> +--EXPECT-- +array(1) { + [0]=> + string(13) "__get(foobar)" +} diff --git a/tests/std/array/array_column_scalar_index_strict_types.phpt b/tests/std/array/array_column_scalar_index_strict_types.phpt new file mode 100644 index 00000000..fbb4a641 --- /dev/null +++ b/tests/std/array/array_column_scalar_index_strict_types.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test array_column(): Index argument with various types in strict type mode +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; + } + try { + var_dump(array_column([['php7', 'foo'], ['php8', 'bar']], true)); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + + echo "\n-- Testing array_column() column key parameter should be a string or integer (testing array) --\n"; + try { + var_dump(array_column([['php7', 'foo'], ['php8', 'bar']], array())); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + + echo "\n-- Testing array_column() index key parameter should be a string or an integer (testing bool) --\n"; + try { + var_dump(array_column([['php' => 7, 'foo'], ['php' => 8, 'bar']], 'php', false)); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + try { + var_dump(array_column([['php' => 7, 'foo'], ['php' => 8, 'bar']], 'php', true)); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + + echo "\n-- Testing array_column() index key parameter should be a string or integer (testing array) --\n"; + try { + var_dump(array_column([['php' => 7, 'foo'], ['php' => 8, 'bar']], 'php', array())); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + + echo "DONE\n"; +} +?> +--EXPECT-- +-- Testing array_column() column key parameter should be a string or an integer (testing bool) -- +array_column(): Argument #2 ($column_key) must be of type string|int|null, false given +array_column(): Argument #2 ($column_key) must be of type string|int|null, true given + +-- Testing array_column() column key parameter should be a string or integer (testing array) -- +array_column(): Argument #2 ($column_key) must be of type string|int|null, array given + +-- Testing array_column() index key parameter should be a string or an integer (testing bool) -- +array_column(): Argument #3 ($index_key) must be of type string|int|null, false given +array_column(): Argument #3 ($index_key) must be of type string|int|null, true given + +-- Testing array_column() index key parameter should be a string or integer (testing array) -- +array_column(): Argument #3 ($index_key) must be of type string|int|null, array given + +DONE diff --git a/tests/std/array/array_column_scalar_index_weak_types.phpt b/tests/std/array/array_column_scalar_index_weak_types.phpt new file mode 100644 index 00000000..4cba6919 --- /dev/null +++ b/tests/std/array/array_column_scalar_index_weak_types.phpt @@ -0,0 +1,83 @@ +--TEST-- +Test array_column(): Index argument with various types in weak type mode +--SKIPIF-- +--FILE-- +getMessage() . "\n"; + } + try { + var_dump(array_column([['php7', 'foo'], ['php8', 'bar']], true)); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + + echo "\n-- Testing array_column() column key parameter should be a string or integer (testing array) --\n"; + try { + var_dump(array_column([['php7', 'foo'], ['php8', 'bar']], array())); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + + echo "\n-- Testing array_column() index key parameter should be a string or an integer (testing bool) --\n"; + try { + var_dump(array_column([['php' => 7, 'foo'], ['php' => 8, 'bar']], 'php', false)); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + try { + var_dump(array_column([['php' => 7, 'foo'], ['php' => 8, 'bar']], 'php', true)); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + + echo "\n-- Testing array_column() index key parameter should be a string or integer (testing array) --\n"; + try { + var_dump(array_column([['php' => 7, 'foo'], ['php' => 8, 'bar']], 'php', array())); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } + + echo "DONE\n"; +} +?> +--EXPECT-- +-- Testing array_column() column key parameter should be a string or an integer (testing bool) -- +array(2) { + [0]=> + string(4) "php7" + [1]=> + string(4) "php8" +} +array(2) { + [0]=> + string(3) "foo" + [1]=> + string(3) "bar" +} + +-- Testing array_column() column key parameter should be a string or integer (testing array) -- +array_column(): Argument #2 ($column_key) must be of type string|int|null, array given + +-- Testing array_column() index key parameter should be a string or an integer (testing bool) -- +array(2) { + ["foo"]=> + int(7) + ["bar"]=> + int(8) +} +array(2) { + [0]=> + int(7) + [1]=> + int(8) +} + +-- Testing array_column() index key parameter should be a string or integer (testing array) -- +array_column(): Argument #3 ($index_key) must be of type string|int|null, array given +DONE \ No newline at end of file diff --git a/tests/std/array/array_column_variant.phpt b/tests/std/array/array_column_variant.phpt new file mode 100644 index 00000000..9673ff17 --- /dev/null +++ b/tests/std/array/array_column_variant.phpt @@ -0,0 +1,86 @@ +--TEST-- +Test array_column() function: variant functionality +--FILE-- + array('id' => '3', 'title' => 'Foo', 'date' => '2013-03-25'), + 457 => array('id' => '5', 'title' => 'Bar', 'date' => '2012-05-20'), +); + +echo "-- pass null as second parameter to get back all columns indexed by third parameter --\n"; +var_dump(array_column($rows, null, 'id')); + +echo "-- pass null as second parameter and bogus third param to get back zero-indexed array of all columns --\n"; +var_dump(array_column($rows, null, 'foo')); + +echo "-- pass null as second parameter and no third param to get back array_values(input) --\n"; +var_dump(array_column($rows, null)); + +echo "Done\n"; +?> +--EXPECT-- +-- pass null as second parameter to get back all columns indexed by third parameter -- +array(2) { + [3]=> + array(3) { + ["id"]=> + string(1) "3" + ["title"]=> + string(3) "Foo" + ["date"]=> + string(10) "2013-03-25" + } + [5]=> + array(3) { + ["id"]=> + string(1) "5" + ["title"]=> + string(3) "Bar" + ["date"]=> + string(10) "2012-05-20" + } +} +-- pass null as second parameter and bogus third param to get back zero-indexed array of all columns -- +array(2) { + [0]=> + array(3) { + ["id"]=> + string(1) "3" + ["title"]=> + string(3) "Foo" + ["date"]=> + string(10) "2013-03-25" + } + [1]=> + array(3) { + ["id"]=> + string(1) "5" + ["title"]=> + string(3) "Bar" + ["date"]=> + string(10) "2012-05-20" + } +} +-- pass null as second parameter and no third param to get back array_values(input) -- +array(2) { + [0]=> + array(3) { + ["id"]=> + string(1) "3" + ["title"]=> + string(3) "Foo" + ["date"]=> + string(10) "2013-03-25" + } + [1]=> + array(3) { + ["id"]=> + string(1) "5" + ["title"]=> + string(3) "Bar" + ["date"]=> + string(10) "2012-05-20" + } +} +Done diff --git a/tests/std/array/array_column_variant_objects.phpt b/tests/std/array/array_column_variant_objects.phpt new file mode 100644 index 00000000..79174490 --- /dev/null +++ b/tests/std/array/array_column_variant_objects.phpt @@ -0,0 +1,142 @@ +--TEST-- +Test array_column() function: testing with objects +--FILE-- +id = $id; + $this->first_name = $first_name; + $this->last_name = $last_name; + } +} +function newUser($id, $first_name, $last_name) +{ + $o = new stdClass(); + $o->{0} = $id; + $o->{1} = $first_name; + $o->{2} = $last_name; + return $o; +} +class Something +{ + public function __isset($name): bool + { + return $name == 'first_name'; + } + public function __get($name) + { + return new User(4, 'Jack', 'Sparrow'); + } +} +function main() +{ + $records = array(newUser(1, 'John', 'Doe'), newUser(2, 'Sally', 'Smith'), newUser(3, 'Jane', 'Jones'), new User(1, 'John', 'Doe'), new User(2, 'Sally', 'Smith'), new User(3, 'Jane', 'Jones'), new Something()); + echo "*** Testing array_column() : object property fetching (numeric property names) ***\n"; + echo "-- first_name column from recordset --\n"; + var_dump(array_column($records, 1)); + echo "-- id column from recordset --\n"; + var_dump(array_column($records, 0)); + echo "-- last_name column from recordset, keyed by value from id column --\n"; + var_dump(array_column($records, 2, 0)); + echo "-- last_name column from recordset, keyed by value from first_name column --\n"; + var_dump(array_column($records, 2, 1)); + echo "*** Testing array_column() : object property fetching (string property names) ***\n"; + echo "-- first_name column from recordset --\n"; + var_dump(array_column($records, 'first_name')); + echo "-- id column from recordset --\n"; + var_dump(array_column($records, 'id')); + echo "-- last_name column from recordset, keyed by value from id column --\n"; + var_dump(array_column($records, 'last_name', 'id')); + echo "-- last_name column from recordset, keyed by value from first_name column --\n"; + var_dump(array_column($records, 'last_name', 'first_name')); + echo "Done\n"; +} +?> +--EXPECT-- +*** Testing array_column() : object property fetching (numeric property names) *** +-- first_name column from recordset -- +array(3) { + [0]=> + string(4) "John" + [1]=> + string(5) "Sally" + [2]=> + string(4) "Jane" +} +-- id column from recordset -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +-- last_name column from recordset, keyed by value from id column -- +array(3) { + [1]=> + string(3) "Doe" + [2]=> + string(5) "Smith" + [3]=> + string(5) "Jones" +} +-- last_name column from recordset, keyed by value from first_name column -- +array(3) { + ["John"]=> + string(3) "Doe" + ["Sally"]=> + string(5) "Smith" + ["Jane"]=> + string(5) "Jones" +} +*** Testing array_column() : object property fetching (string property names) *** +-- first_name column from recordset -- +array(4) { + [0]=> + string(4) "John" + [1]=> + string(5) "Sally" + [2]=> + string(4) "Jane" + [3]=> + object(User)#8 (3) { + ["id"]=> + int(4) + ["first_name"]=> + string(4) "Jack" + ["last_name"]=> + string(7) "Sparrow" + } +} +-- id column from recordset -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +-- last_name column from recordset, keyed by value from id column -- +array(3) { + [1]=> + string(3) "Doe" + [2]=> + string(5) "Smith" + [3]=> + string(5) "Jones" +} +-- last_name column from recordset, keyed by value from first_name column -- +array(3) { + ["John"]=> + string(3) "Doe" + ["Sally"]=> + string(5) "Smith" + ["Jane"]=> + string(5) "Jones" +} +Done diff --git a/tests/std/array/array_combine.phpt b/tests/std/array/array_combine.phpt new file mode 100644 index 00000000..d6ec31b0 --- /dev/null +++ b/tests/std/array/array_combine.phpt @@ -0,0 +1,155 @@ +--TEST-- +basic array_combine test +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(3) { + ["green"]=> + string(5) "green" + ["red"]=> + string(3) "red" + ["yellow"]=> + string(6) "yellow" +} +array(3) { + ["green"]=> + string(1) "1" + ["red"]=> + string(1) "2" + ["yellow"]=> + string(1) "3" +} +array(3) { + ["green"]=> + int(0) + ["red"]=> + int(1) + ["yellow"]=> + int(2) +} +array(3) { + ["green"]=> + bool(true) + ["red"]=> + bool(false) + ["yellow"]=> + NULL +} +array(3) { + [1]=> + string(5) "green" + [2]=> + string(3) "red" + [3]=> + string(6) "yellow" +} +array(3) { + [1]=> + string(1) "1" + [2]=> + string(1) "2" + [3]=> + string(1) "3" +} +array(3) { + [1]=> + int(0) + [2]=> + int(1) + [3]=> + int(2) +} +array(3) { + [1]=> + bool(true) + [2]=> + bool(false) + [3]=> + NULL +} +array(3) { + [0]=> + string(5) "green" + [1]=> + string(3) "red" + [2]=> + string(6) "yellow" +} +array(3) { + [0]=> + string(1) "1" + [1]=> + string(1) "2" + [2]=> + string(1) "3" +} +array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) +} +array(3) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + NULL +} +array(2) { + [1]=> + string(5) "green" + [""]=> + string(6) "yellow" +} +array(2) { + [1]=> + string(1) "1" + [""]=> + string(1) "3" +} +array(2) { + [1]=> + int(0) + [""]=> + int(2) +} +array(2) { + [1]=> + bool(true) + [""]=> + NULL +} diff --git a/tests/std/array/array_combine_basic.phpt b/tests/std/array/array_combine_basic.phpt new file mode 100644 index 00000000..ccf1bbf4 --- /dev/null +++ b/tests/std/array/array_combine_basic.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test array_combine() function : basic functionality +--FILE-- + "a", 2 => 'b'); +$values_array = array(3 => 'c', 4 => "d"); +var_dump( array_combine($keys_array, $values_array) ); + +// mixed array for $keys and $values arguments +$keys_array = array(1, 2 => "b"); +$values_array = array(3 => 'c', 4); +var_dump( array_combine($keys_array, $values_array) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_combine() : basic functionality *** +array(2) { + [1]=> + int(3) + [2]=> + int(4) +} +array(2) { + ["a"]=> + string(1) "c" + ["b"]=> + string(1) "d" +} +array(2) { + [1]=> + string(1) "c" + ["b"]=> + int(4) +} +Done diff --git a/tests/std/array/array_combine_error2.phpt b/tests/std/array/array_combine_error2.phpt new file mode 100644 index 00000000..8d3440ea --- /dev/null +++ b/tests/std/array/array_combine_error2.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test array_combine() function : error conditions - empty array +--FILE-- +getMessage(); +} + +// Testing array_combine by passing empty array to $values +echo "\n-- Testing array_combine() function with empty array for \$values argument --\n"; +try { + var_dump( array_combine(array(1, 2), array()) ); +} catch (\ValueError $e) { + echo $e->getMessage(); +} + +// Testing array_combine with arrays having unequal number of elements +echo "\n-- Testing array_combine() function by passing array with unequal number of elements --\n"; +try { + var_dump( array_combine(array(1, 2), array(1, 2, 3)) ); +} catch (\ValueError $e) { + echo $e->getMessage(); +} + +?> +--EXPECT-- +*** Testing array_combine() : error conditions specific to array_combine() *** + +-- Testing array_combine() function with empty arrays -- +array(0) { +} + +-- Testing array_combine() function with empty array for $keys argument -- +array_combine(): Argument #1 ($keys) and argument #2 ($values) must have the same number of elements +-- Testing array_combine() function with empty array for $values argument -- +array_combine(): Argument #1 ($keys) and argument #2 ($values) must have the same number of elements +-- Testing array_combine() function by passing array with unequal number of elements -- +array_combine(): Argument #1 ($keys) and argument #2 ($values) must have the same number of elements diff --git a/tests/std/array/array_combine_variation3.phpt b/tests/std/array/array_combine_variation3.phpt new file mode 100644 index 00000000..a04c67e7 --- /dev/null +++ b/tests/std/array/array_combine_variation3.phpt @@ -0,0 +1,275 @@ +--TEST-- +Test array_combine() function : usage variations - different arrays(Bug#43424) +--SKIPIF-- + +--FILE-- +22 +'single quoted string' +"double quoted string" +2222 != 1111.\t 0000 = 0000\n +EOT; + +// arrays passed to $keys argument +$arrays = array ( +/*1*/ array(1, 2), // with default keys and numeric values + array(1.1, 2.2), // with default keys & float values + array(false,true), // with default keys and boolean values + array(), // empty array +/*5*/ array(NULL), // with NULL + array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // with double quoted strings + array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // with single quoted strings + array("h1" => $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $numeric_string), // with heredocs + + // associative arrays +/*9*/ array(1 => "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values + array("one" => 1, "two" => 2, "three" => 3 ), // string keys & numeric values + array( 1 => 10, 2 => 20, 4 => 40, 3 => 30), // explicit numeric keys and numeric values + array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value + array("one" => 1, 2 => "two", 4 => "four"), //mixed + + // associative array, containing null/empty/boolean values as key/value +/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + + // array with repetitive keys +/*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) +); + +// loop through each sub-array within $arrays to check the behavior of array_combine() +// same arrays are passed to both $keys and $values +$iterator = 1; +foreach($arrays as $array) { + echo "-- Iteration $iterator --\n"; + var_dump( array_combine($array, $array) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_combine() : Passing different types of arrays to both $keys and $values argument *** +-- Iteration 1 -- +array(2) { + [1]=> + int(1) + [2]=> + int(2) +} +-- Iteration 2 -- +array(2) { + ["1.1"]=> + float(1.1) + ["2.2"]=> + float(2.2) +} +-- Iteration 3 -- +array(2) { + [""]=> + bool(false) + [1]=> + bool(true) +} +-- Iteration 4 -- +array(0) { +} +-- Iteration 5 -- +array(1) { + [""]=> + NULL +} +-- Iteration 6 -- +array(6) { + ["a "]=> + string(3) "a " + ["aaaa "]=> + string(5) "aaaa " + ["b"]=> + string(1) "b" + ["b bbb"]=> + string(5) "b bbb" + ["c"]=> + string(1) "c" + ["\[\]\!\@\#$\%\^\&\*\(\)\{\}"]=> + string(27) "\[\]\!\@\#$\%\^\&\*\(\)\{\}" +} +-- Iteration 7 -- +array(6) { + ["a\v\f"]=> + string(5) "a\v\f" + ["aaaa\r"]=> + string(6) "aaaa\r" + ["b"]=> + string(1) "b" + ["b\tbbb"]=> + string(6) "b\tbbb" + ["c"]=> + string(1) "c" + ["\[\]\!\@\#\$\%\^\&\*\(\)\{\}"]=> + string(28) "\[\]\!\@\#\$\%\^\&\*\(\)\{\}" +} +-- Iteration 8 -- +array(4) { + [" +"]=> + string(1) " +" + ["hello world +The quick brown fox jumped over; +the lazy dog +This is a double quoted string"]=> + string(88) "hello world +The quick brown fox jumped over; +the lazy dog +This is a double quoted string" + ["hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" + ["11 < 12. 123 >22 +'single quoted string' +"double quoted string" +2222 != 1111. 0000 = 0000 +"]=> + string(90) "11 < 12. 123 >22 +'single quoted string' +"double quoted string" +2222 != 1111. 0000 = 0000 +" +} +-- Iteration 9 -- +array(3) { + ["one"]=> + string(3) "one" + ["two"]=> + string(3) "two" + ["three"]=> + string(5) "three" +} +-- Iteration 10 -- +array(3) { + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) +} +-- Iteration 11 -- +array(4) { + [10]=> + int(10) + [20]=> + int(20) + [40]=> + int(40) + [30]=> + int(30) +} +-- Iteration 12 -- +array(3) { + ["ten"]=> + string(3) "ten" + ["twenty"]=> + string(6) "twenty" + ["thirty"]=> + string(6) "thirty" +} +-- Iteration 13 -- +array(3) { + [1]=> + int(1) + ["two"]=> + string(3) "two" + ["four"]=> + string(4) "four" +} +-- Iteration 14 -- +array(2) { + ["null"]=> + string(4) "null" + [""]=> + NULL +} +-- Iteration 15 -- +array(4) { + ["true"]=> + string(4) "true" + ["false"]=> + string(5) "false" + [""]=> + bool(false) + [1]=> + bool(true) +} +-- Iteration 16 -- +array(2) { + ["emptys"]=> + string(6) "emptys" + [""]=> + string(0) "" +} +-- Iteration 17 -- +array(2) { + [""]=> + bool(false) + [1]=> + bool(true) +} +-- Iteration 18 -- +array(3) { + [4]=> + int(4) + [5]=> + int(5) + [6]=> + int(6) +} +-- Iteration 19 -- +array(3) { + [10]=> + int(10) + [20]=> + int(20) + [3]=> + int(3) +} +Done diff --git a/tests/std/array/array_combine_variation4.phpt b/tests/std/array/array_combine_variation4.phpt new file mode 100644 index 00000000..c8fca16a --- /dev/null +++ b/tests/std/array/array_combine_variation4.phpt @@ -0,0 +1,150 @@ +--TEST-- +Test array_combine() function : usage variations - associative array with different keys(Bug#43424) +--SKIPIF-- + +--FILE-- + "0"), + array(1 => "1"), + array(1 => "1", 2 => "2", 3 => "3", 4 => "4"), + // arrays with string keys + /*7*/ + array('\tHello' => 111, 're\td' => "color", '\v\fworld' => 2.2, 'pen\n' => 33), + array("\tHello" => 111, "re\td" => "color", "\v\fworld" => 2.2, "pen\n" => 33), + array("hello", $heredoc => "string"), + // heredoc + // array with object, unset variable and resource variable + /*10*/ + array(@$unset_var => "hello", $fp => 'resource'), + // array with mixed keys + /*11*/ + array('hello' => 1, "fruit" => 2.2, $fp => 'resource', 133 => "int", @$unset_var => "unset", $heredoc => "heredoc"), + ); + // array to be passsed to $arr2 argument + $arr2 = array(0 => 0, 2 => "float", 4 => "f3", 33333333 => "f4", "\tHello" => 111, 2.2, 'color', "Hello world" => "string", "pen\n" => 33, 133 => "int"); + // loop through each sub-array within $arrays to check the behavior of array_combine() + // same arrays are passed to both $keys and $values + $iterator = 1; + foreach ($arrays as $array) { + echo "-- Iteration {$iterator} --\n"; + var_dump(array_combine($array, $array)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_combine() : assoc array with diff keys to both $keys and $values argument *** + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d +-- Iteration 1 -- +array(0) { +} +-- Iteration 2 -- +array(1) { + [0]=> + string(1) "0" +} +-- Iteration 3 -- +array(1) { + [1]=> + string(1) "1" +} +-- Iteration 4 -- +array(4) { + [1]=> + string(1) "1" + [2]=> + string(1) "2" + [3]=> + string(1) "3" + [4]=> + string(1) "4" +} +-- Iteration 5 -- +array(4) { + [111]=> + int(111) + ["color"]=> + string(5) "color" + ["2.2"]=> + float(2.2) + [33]=> + int(33) +} +-- Iteration 6 -- +array(4) { + [111]=> + int(111) + ["color"]=> + string(5) "color" + ["2.2"]=> + float(2.2) + [33]=> + int(33) +} +-- Iteration 7 -- +array(2) { + ["hello"]=> + string(5) "hello" + ["string"]=> + string(6) "string" +} +-- Iteration 8 -- +array(2) { + ["hello"]=> + string(5) "hello" + ["resource"]=> + string(8) "resource" +} +-- Iteration 9 -- +array(6) { + [1]=> + int(1) + ["2.2"]=> + float(2.2) + ["resource"]=> + string(8) "resource" + ["int"]=> + string(3) "int" + ["unset"]=> + string(5) "unset" + ["heredoc"]=> + string(7) "heredoc" +} +Done diff --git a/tests/std/array/array_combine_variation5.phpt b/tests/std/array/array_combine_variation5.phpt new file mode 100644 index 00000000..2d80ac57 --- /dev/null +++ b/tests/std/array/array_combine_variation5.phpt @@ -0,0 +1,172 @@ +--TEST-- +Test array_combine() function : usage variations - associative array with different values(Bug#43424) +--SKIPIF-- + +--FILE-- + 0), + array("1" => 1), + array("one" => 1, 'two' => 2, "three" => 3, 4 => 4), + // arrays with float values + /*5*/ + array("float" => 2.3333), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => 33333333.333), + // arrays with string values + /*7*/ + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "pen\n"), + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => 'pen\n'), + array(1 => "hello", "heredoc" => $heredoc), + // array with object, unset variable and resource variable + /*10*/ + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp), + // array with mixed values + /*11*/ + array(1 => 'hello', 2 => new classA(), 222 => "fruit", 'resource' => $fp, "int" => 133, "float" => 444.432, "unset" => @$unset_var, "heredoc" => $heredoc), + ); + // loop through each sub-array within $arrays to check the behavior of array_combine() + $iterator = 1; + foreach ($arrays as $array) { + echo "-- Iteration {$iterator} --\n"; + var_dump(array_combine($array, $array)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_combine() : assoc array with diff values to both $keys and $values argument *** +-- Iteration 1 -- +array(0) { +} +-- Iteration 2 -- +array(1) { + [0]=> + int(0) +} +-- Iteration 3 -- +array(1) { + [1]=> + int(1) +} +-- Iteration 4 -- +array(4) { + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) +} +-- Iteration 5 -- +array(1) { + ["2.3333"]=> + float(2.3333) +} +-- Iteration 6 -- +array(4) { + ["1.2"]=> + float(1.2) + ["3.33"]=> + float(3.33) + ["4.8999992284"]=> + float(4.89999922839999) + ["33333333.333"]=> + float(33333333.333) +} +-- Iteration 7 -- +array(4) { + [" Hello"]=> + string(6) " Hello" + ["col or"]=> + string(6) "col or" + [" world"]=> + string(7) " world" + ["pen +"]=> + string(4) "pen +" +} +-- Iteration 8 -- +array(4) { + ["\tHello"]=> + string(7) "\tHello" + ["col\tor"]=> + string(7) "col\tor" + ["\v\fworld"]=> + string(9) "\v\fworld" + ["pen\n"]=> + string(5) "pen\n" +} +-- Iteration 9 -- +array(2) { + ["hello"]=> + string(5) "hello" + ["Hello world"]=> + string(11) "Hello world" +} +-- Iteration 10 -- +array(3) { + ["Class A object"]=> + object(classA)#%d (0) { + } + [""]=> + NULL + ["Resource id #%d"]=> + resource(%d) of type (stream) +} +-- Iteration 11 -- +array(8) { + ["hello"]=> + string(5) "hello" + ["Class A object"]=> + object(classA)#%d (0) { + } + ["fruit"]=> + string(5) "fruit" + ["Resource id #%d"]=> + resource(%d) of type (stream) + [133]=> + int(133) + ["444.432"]=> + float(444.432) + [""]=> + NULL + ["Hello world"]=> + string(11) "Hello world" +} +Done diff --git a/tests/std/array/array_combine_variation6.phpt b/tests/std/array/array_combine_variation6.phpt new file mode 100644 index 00000000..b9985a0a --- /dev/null +++ b/tests/std/array/array_combine_variation6.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test array_combine() function : usage variations - binary safe checking +--FILE-- + +--EXPECT-- +*** Testing array_combine() : binary safe checking *** +array(2) { + ["hello"]=> + string(5) "hello" + ["world"]=> + string(5) "world" +} +array(2) { + ["hello"]=> + string(5) "hello" + ["world"]=> + string(5) "world" +} +array(2) { + ["hello"]=> + string(5) "hello" + ["world"]=> + string(5) "world" +} +Done diff --git a/tests/std/array/array_count_values.phpt b/tests/std/array/array_count_values.phpt new file mode 100644 index 00000000..eb515124 --- /dev/null +++ b/tests/std/array/array_count_values.phpt @@ -0,0 +1,94 @@ +--TEST-- +array_count_values() +--FILE-- + +--EXPECT-- +array(0) { +} + +array(1) { + [0]=> + int(1) +} + +array(1) { + [1]=> + int(1) +} + +array(1) { + [-1]=> + int(1) +} + +array(1) { + [0]=> + int(2) +} + +array(2) { + [0]=> + int(1) + [1]=> + int(1) +} + +array(1) { + [1]=> + int(2) +} + +array(3) { + [1]=> + int(2) + ["hello"]=> + int(2) + ["world"]=> + int(1) +} + +array(2) { + ["hello"]=> + int(2) + ["world"]=> + int(1) +} + +array(3) { + [""]=> + int(2) + ["world"]=> + int(3) + ["hello"]=> + int(4) +} + +array(1) { + [0]=> + int(1) +} + +array(1) { + [1]=> + int(1) +} diff --git a/tests/std/array/array_count_values2.phpt b/tests/std/array/array_count_values2.phpt new file mode 100644 index 00000000..1b7d8442 --- /dev/null +++ b/tests/std/array/array_count_values2.phpt @@ -0,0 +1,43 @@ +--TEST-- +basic array_count_values test +--FILE-- + +--EXPECTF-- +Warning:%S Can only count string and integer values, entry skipped in %s on line %d + +Warning:%S Can only count string and integer values, entry skipped in %s on line %d + +Warning:%S Can only count string and integer values, entry skipped in %s on line %d +array(8) { + [1]=> + int(2) + ["hello"]=> + int(2) + ["world"]=> + int(1) + [""]=> + int(1) + ["rabbit"]=> + int(1) + ["foo"]=> + int(1) + ["Foo"]=> + int(1) + [0]=> + int(1) +} diff --git a/tests/std/array/array_count_values_variation.phpt b/tests/std/array/array_count_values_variation.phpt new file mode 100644 index 00000000..9d895a33 --- /dev/null +++ b/tests/std/array/array_count_values_variation.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test array_count_values() function : Test all normal parameter variations +--FILE-- + "bobv", "val", 6 => "val6", $fp, $ob); + var_dump(@array_count_values($arrays)); + echo "\n"; + echo "Done"; +} +?> +--CLEAN-- + +--EXPECT-- +*** Testing array_count_values() : parameter variations *** +array(3) { + ["bobv"]=> + int(1) + ["val"]=> + int(1) + ["val6"]=> + int(1) +} + +Done diff --git a/tests/std/array/array_diff_1.phpt b/tests/std/array/array_diff_1.phpt new file mode 100644 index 00000000..7b58077e --- /dev/null +++ b/tests/std/array/array_diff_1.phpt @@ -0,0 +1,19 @@ +--TEST-- +Test array_diff when non-array is passed +--FILE-- +getMessage(), "\n"; +} +//-=-=-=-=-=- +echo "OK!"; +?> +--EXPECT-- +array_diff(): Argument #2 must be of type array, int given +OK! diff --git a/tests/std/array/array_diff_assoc.phpt b/tests/std/array/array_diff_assoc.phpt new file mode 100644 index 00000000..ef659f50 --- /dev/null +++ b/tests/std/array/array_diff_assoc.phpt @@ -0,0 +1,46 @@ +--TEST-- +basic array_diff_assoc test +--FILE-- + "green", "b" => "brown", "c" => "blue", "red", ""); +$array2 = array("a" => "green", "yellow", "red", TRUE); +$array3 = array("red", "a"=>"brown", ""); +$result[] = array_diff_assoc($array1, $array2); +$result[] = array_diff_assoc($array1, $array3); +$result[] = array_diff_assoc($array2, $array3); +$result[] = array_diff_assoc($array1, $array2, $array3); +print_r($result); +?> +--EXPECT-- +Array +( + [0] => Array + ( + [b] => brown + [c] => blue + [0] => red + [1] => + ) + + [1] => Array + ( + [a] => green + [b] => brown + [c] => blue + ) + + [2] => Array + ( + [a] => green + [0] => yellow + [1] => red + [2] => 1 + ) + + [3] => Array + ( + [b] => brown + [c] => blue + ) + +) diff --git a/tests/std/array/array_diff_assoc_basic.phpt b/tests/std/array/array_diff_assoc_basic.phpt new file mode 100644 index 00000000..3a9ec872 --- /dev/null +++ b/tests/std/array/array_diff_assoc_basic.phpt @@ -0,0 +1,84 @@ +--TEST-- +Test array_diff_assoc() function : basic functionality +--FILE-- + 'one', 2=> 'two', 3 => 4); +$array_string_key = array('one' => 1, 'two' => '2', '3' => 'three'); + + + +echo "-- Compare Default keys to numeric keys --\n"; +var_dump(array_diff_assoc($array_default_key, $array_numeric_key)); +var_dump(array_diff_assoc($array_numeric_key, $array_default_key)); + + +echo "\n-- Compare Default keys to string keys --\n"; +var_dump(array_diff_assoc($array_default_key, $array_numeric_key)); +var_dump(array_diff_assoc($array_numeric_key, $array_default_key)); + + +echo "\n-- Compare numeric keys to string keys --\n"; +var_dump(array_diff_assoc($array_numeric_key, $array_string_key)); +var_dump(array_diff_assoc($array_string_key, $array_numeric_key)); + + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff_assoc() : basic functionality *** +-- Compare Default keys to numeric keys -- +array(3) { + [0]=> + string(3) "one" + [1]=> + int(2) + [2]=> + string(5) "three" +} +array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} + +-- Compare Default keys to string keys -- +array(3) { + [0]=> + string(3) "one" + [1]=> + int(2) + [2]=> + string(5) "three" +} +array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} + +-- Compare numeric keys to string keys -- +array(3) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + int(4) +} +array(3) { + ["one"]=> + int(1) + ["two"]=> + string(1) "2" + [3]=> + string(5) "three" +} +Done diff --git a/tests/std/array/array_diff_assoc_variation1.phpt b/tests/std/array/array_diff_assoc_variation1.phpt new file mode 100644 index 00000000..82618d0f --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation1.phpt @@ -0,0 +1,179 @@ +--TEST-- +Test array_diff_assoc() function : usage variations - unexpected values for 'array1' argument +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; + } + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_diff_assoc() : usage variations *** + +-- Iteration 1 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, int given + +-- Iteration 2 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, int given + +-- Iteration 3 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, int given + +-- Iteration 4 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, int given + +-- Iteration 5 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 6 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 7 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 8 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 9 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 10 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, null given + +-- Iteration 11 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, null given + +-- Iteration 12 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, true given + +-- Iteration 13 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, false given + +-- Iteration 14 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, true given + +-- Iteration 15 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, false given + +-- Iteration 16 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 17 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 18 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 19 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 20 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 21 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 22 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 23 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, classA given + +-- Iteration 24 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, null given + +-- Iteration 25 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, null given + +-- Iteration 26 -- +array_diff_assoc(): Argument #1 ($array) must be of type array, resource given +Done diff --git a/tests/std/array/array_diff_assoc_variation10.phpt b/tests/std/array/array_diff_assoc_variation10.phpt new file mode 100644 index 00000000..edaaec73 --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation10.phpt @@ -0,0 +1,43 @@ +--TEST-- +Test array_diff_assoc() function : usage variations - binary safe check +--FILE-- + "hello", + "str2" => "world"); + +$array2 = array( b"1" => 'hello', + b"world", + "hello", + 'test'); + +var_dump(array_diff_assoc($array1, $array2)); +var_dump(array_diff_assoc($array2, $array1)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff_assoc() : usage variations *** +array(3) { + [0]=> + string(1) "1" + ["str1"]=> + string(5) "hello" + ["str2"]=> + string(5) "world" +} +array(2) { + [3]=> + string(5) "hello" + [4]=> + string(4) "test" +} +Done diff --git a/tests/std/array/array_diff_assoc_variation2.phpt b/tests/std/array/array_diff_assoc_variation2.phpt new file mode 100644 index 00000000..ff1c0ff8 --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation2.phpt @@ -0,0 +1,179 @@ +--TEST-- +Test array_diff_assoc() function : usage variations - unexpected values for 'array1' argument +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; + } + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_diff_assoc() : usage variations *** + +-- Iteration 1 -- +array_diff_assoc(): Argument #2 must be of type array, int given + +-- Iteration 2 -- +array_diff_assoc(): Argument #2 must be of type array, int given + +-- Iteration 3 -- +array_diff_assoc(): Argument #2 must be of type array, int given + +-- Iteration 4 -- +array_diff_assoc(): Argument #2 must be of type array, int given + +-- Iteration 5 -- +array_diff_assoc(): Argument #2 must be of type array, float given + +-- Iteration 6 -- +array_diff_assoc(): Argument #2 must be of type array, float given + +-- Iteration 7 -- +array_diff_assoc(): Argument #2 must be of type array, float given + +-- Iteration 8 -- +array_diff_assoc(): Argument #2 must be of type array, float given + +-- Iteration 9 -- +array_diff_assoc(): Argument #2 must be of type array, float given + +-- Iteration 10 -- +array_diff_assoc(): Argument #2 must be of type array, null given + +-- Iteration 11 -- +array_diff_assoc(): Argument #2 must be of type array, null given + +-- Iteration 12 -- +array_diff_assoc(): Argument #2 must be of type array, true given + +-- Iteration 13 -- +array_diff_assoc(): Argument #2 must be of type array, false given + +-- Iteration 14 -- +array_diff_assoc(): Argument #2 must be of type array, true given + +-- Iteration 15 -- +array_diff_assoc(): Argument #2 must be of type array, false given + +-- Iteration 16 -- +array_diff_assoc(): Argument #2 must be of type array, string given + +-- Iteration 17 -- +array_diff_assoc(): Argument #2 must be of type array, string given + +-- Iteration 18 -- +array_diff_assoc(): Argument #2 must be of type array, string given + +-- Iteration 19 -- +array_diff_assoc(): Argument #2 must be of type array, string given + +-- Iteration 20 -- +array_diff_assoc(): Argument #2 must be of type array, string given + +-- Iteration 21 -- +array_diff_assoc(): Argument #2 must be of type array, string given + +-- Iteration 22 -- +array_diff_assoc(): Argument #2 must be of type array, string given + +-- Iteration 23 -- +array_diff_assoc(): Argument #2 must be of type array, classA given + +-- Iteration 24 -- +array_diff_assoc(): Argument #2 must be of type array, null given + +-- Iteration 25 -- +array_diff_assoc(): Argument #2 must be of type array, null given + +-- Iteration 26 -- +array_diff_assoc(): Argument #2 must be of type array, resource given +Done diff --git a/tests/std/array/array_diff_assoc_variation3.phpt b/tests/std/array/array_diff_assoc_variation3.phpt new file mode 100644 index 00000000..3826a907 --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation3.phpt @@ -0,0 +1,165 @@ +--TEST-- +Test array_diff_assoc() function : variation - array containing different data types +--SKIPIF-- + + +--FILE-- + array(0, 1, 12345, -2345), + // float data + /*2*/ + 'float' => array(10.5, -10.5, 123456789000.0, 1.23456789E-9, 0.5), + // null data + /*3*/ + 'null' => array(NULL, null), + // boolean data + /*4*/ + 'bool' => array(true, false, TRUE, FALSE), + // empty data + /*5*/ + 'empty' => array("", ''), + // string data + /*6*/ + 'string' => array("string", 'string', $heredoc), + // binary data + /*7*/ + 'binary' => array("binary", (string) "binary"), + // object data + /*8*/ + 'object' => array(new classA()), + // undefined data + /*9*/ + 'undefined' => array(@$undefined_var), + // unset data + /*10*/ + 'unset' => array(@$unset_var), + ); + // loop through each element of $inputs to check the behavior of array_diff_assoc + $iterator = 1; + foreach ($inputs as $key => $input) { + echo "\n-- Iteration {$iterator} --\n"; + var_dump(array_diff_assoc($input, $array)); + $iterator++; + } + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_diff_assoc() : usage variations *** + +-- Iteration 1 -- +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(12345) + [3]=> + int(-2345) +} + +-- Iteration 2 -- +array(5) { + [0]=> + float(10.5) + [1]=> + float(-10.5) + [2]=> + float(123456789000) + [3]=> + float(1.23456789E-9) + [4]=> + float(0.5) +} + +-- Iteration 3 -- +array(2) { + [0]=> + NULL + [1]=> + NULL +} + +-- Iteration 4 -- +array(3) { + [1]=> + bool(false) + [2]=> + bool(true) + [3]=> + bool(false) +} + +-- Iteration 5 -- +array(2) { + [0]=> + string(0) "" + [1]=> + string(0) "" +} + +-- Iteration 6 -- +array(3) { + [0]=> + string(6) "string" + [1]=> + string(6) "string" + [2]=> + string(11) "hello world" +} + +-- Iteration 7 -- +array(2) { + [0]=> + string(6) "binary" + [1]=> + string(6) "binary" +} + +-- Iteration 8 -- +array(1) { + [0]=> + object(classA)#%d (0) { + } +} + +-- Iteration 9 -- +array(1) { + [0]=> + NULL +} + +-- Iteration 10 -- +array(1) { + [0]=> + NULL +} +Done diff --git a/tests/std/array/array_diff_assoc_variation4.phpt b/tests/std/array/array_diff_assoc_variation4.phpt new file mode 100644 index 00000000..f18143fe --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation4.phpt @@ -0,0 +1,156 @@ +--TEST-- +Test array_diff_assoc() function : usage variations - arrays with different data types as keys +--SKIPIF-- + + +--FILE-- + array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative'), + + // null data +/*3*/ +'null' => array( + NULL => 'null 1', + null => 'null 2'), + + // boolean data +/*4*/ +'bool' => array( + true => 'boolt', + false => 'boolf', + TRUE => 'boolT', + FALSE => 'boolF'), + + // empty data +/*5*/ +'empty' => array( + "" => 'emptyd', + '' => 'emptys'), + + // string data +/*6*/ +'string' => array( + "string" => 'stringd', + 'string' => 'strings', + $heredoc => 'stringh'), + + // binary data +/*7*/ +'binary' => array( + b"binary1" => 'binary 1', + (binary)"binary2" => 'binary 2'), + + // undefined data +/*8*/ +'undefined' => array( + @$undefined_var => 'undefined'), + + // unset data +/*9*/ +'unset' => array( + @$unset_var => 'unset'), + +); + +// loop through each element of $inputs to check the behavior of array_diff_assoc +$iterator = 1; +foreach($inputs as $key => $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( array_diff_assoc($input, $array)); + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff_assoc() : usage variations *** + +-- Iteration 1 -- +array(4) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [12345]=> + string(8) "positive" + [-2345]=> + string(8) "negative" +} + +-- Iteration 2 -- +array(1) { + [""]=> + string(6) "null 2" +} + +-- Iteration 3 -- +array(2) { + [1]=> + string(5) "boolT" + [0]=> + string(5) "boolF" +} + +-- Iteration 4 -- +array(1) { + [""]=> + string(6) "emptys" +} + +-- Iteration 5 -- +array(2) { + ["string"]=> + string(7) "strings" + ["hello world"]=> + string(7) "stringh" +} + +-- Iteration 6 -- +array(2) { + ["binary1"]=> + string(8) "binary 1" + ["binary2"]=> + string(8) "binary 2" +} + +-- Iteration 7 -- +array(1) { + [""]=> + string(9) "undefined" +} + +-- Iteration 8 -- +array(1) { + [""]=> + string(5) "unset" +} +Done diff --git a/tests/std/array/array_diff_assoc_variation5.phpt b/tests/std/array/array_diff_assoc_variation5.phpt new file mode 100644 index 00000000..09af9cb4 --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation5.phpt @@ -0,0 +1,141 @@ +--TEST-- +Test array_diff_assoc() function : usage variations - compare integers, floats and strings +--FILE-- + 1.00, 1 => 2.00, 2 => 3.00, 'b'); +$arr_string = array('1', '2', '3', 'c'); +$arr_string_float = array('0' => '1.00', '1.00' => '2.00', '2.00' => '3.00', 'd'); + +echo "-- Result of comparing integers and floating point numbers: --\n"; +var_dump(array_diff_assoc($arr_default_int, $arr_float)); +var_dump(array_diff_assoc($arr_float, $arr_default_int)); + +echo "-- Result of comparing integers and strings containing an integers : --\n"; +var_dump(array_diff_assoc($arr_default_int, $arr_string)); +var_dump(array_diff_assoc($arr_string, $arr_default_int)); + +echo "-- Result of comparing integers and strings containing floating points : --\n"; +var_dump(array_diff_assoc($arr_default_int, $arr_string_float)); +var_dump(array_diff_assoc($arr_string_float, $arr_default_int)); + +echo "-- Result of comparing floating points and strings containing integers : --\n"; +var_dump(array_diff_assoc($arr_float, $arr_string)); +var_dump(array_diff_assoc($arr_string, $arr_float)); + +echo "-- Result of comparing floating points and strings containing floating point: --\n"; +var_dump(array_diff_assoc($arr_float, $arr_string_float)); +var_dump(array_diff_assoc($arr_string_float, $arr_float)); + +echo "-- Result of comparing strings containing integers and strings containing floating points : --\n"; +var_dump(array_diff_assoc($arr_string, $arr_string_float)); +var_dump(array_diff_assoc($arr_string_float, $arr_string)); + +echo "-- Result of comparing more than two arrays: --\n"; +var_dump(array_diff_assoc($arr_default_int, $arr_float, $arr_string, $arr_string_float)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff_assoc() : usage variations *** +-- Result of comparing integers and floating point numbers: -- +array(1) { + [3]=> + string(1) "a" +} +array(1) { + [3]=> + string(1) "b" +} +-- Result of comparing integers and strings containing an integers : -- +array(1) { + [3]=> + string(1) "a" +} +array(1) { + [3]=> + string(1) "c" +} +-- Result of comparing integers and strings containing floating points : -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + string(1) "a" +} +array(4) { + [0]=> + string(4) "1.00" + ["1.00"]=> + string(4) "2.00" + ["2.00"]=> + string(4) "3.00" + [1]=> + string(1) "d" +} +-- Result of comparing floating points and strings containing integers : -- +array(1) { + [3]=> + string(1) "b" +} +array(1) { + [3]=> + string(1) "c" +} +-- Result of comparing floating points and strings containing floating point: -- +array(4) { + [0]=> + float(1) + [1]=> + float(2) + [2]=> + float(3) + [3]=> + string(1) "b" +} +array(4) { + [0]=> + string(4) "1.00" + ["1.00"]=> + string(4) "2.00" + ["2.00"]=> + string(4) "3.00" + [1]=> + string(1) "d" +} +-- Result of comparing strings containing integers and strings containing floating points : -- +array(4) { + [0]=> + string(1) "1" + [1]=> + string(1) "2" + [2]=> + string(1) "3" + [3]=> + string(1) "c" +} +array(4) { + [0]=> + string(4) "1.00" + ["1.00"]=> + string(4) "2.00" + ["2.00"]=> + string(4) "3.00" + [1]=> + string(1) "d" +} +-- Result of comparing more than two arrays: -- +array(1) { + [3]=> + string(1) "a" +} +Done diff --git a/tests/std/array/array_diff_assoc_variation6.phpt b/tests/std/array/array_diff_assoc_variation6.phpt new file mode 100644 index 00000000..bee55152 --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation6.phpt @@ -0,0 +1,192 @@ +--TEST-- +Test array_diff_assoc() function : usage variations - strict string comparison check +--SKIPIF-- + +--FILE-- + 1, + 'two' => 2.00000000000001); + +$inputs = array ( + +//default keys => string values +/*1*/ array('2.00000000000001', '1', 'zero', 'a'), + +//numeric keys => string values +/*2*/ array(2 => '2.00000000000001', + 1 => '1', + 0 => 'zero', + 3 => 'a'), + +//string keys => string values +/*3*/ array('2' => '2.00000000000001', + '1' => '1', + '0' => 'zero', + '3' => 'a') , + +//default keys => numeric values +/*4*/ array(2, 1, 0), + +//numeric keys => numeric values +/*5*/ array(2 => 2, + 1 => 1, + 0 => 0), + +//string keys => numeric values +/*6*/ array('two' => 2, + '1' => 1, + '0' => 0), + +//default keys => float values +/*7*/ array(2.00000000000001, 1.00, 0.01E-9), + +//numeric keys => float values +/*8*/ array(2 => 2.00000000000001, + 1 => 1.00, + 0 => 0.01E-9), + +//string keys => float values +/*9*/ array ('two' => 2.00000000000001, + '1' => 1.00, + '0' =>0.01E-9) +); + +// loop through each element of $inputs to check the behavior of array_diff_assoc +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump(array_diff_assoc($array, $input)); + var_dump(array_diff_assoc($input, $array)); + $iterator++; +}; +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff_assoc() : usage variations *** + +-- Iteration 1 -- +array(2) { + [0]=> + string(4) "zero" + ["two"]=> + float(2.00000000000001) +} +array(3) { + [0]=> + string(16) "2.00000000000001" + [2]=> + string(4) "zero" + [3]=> + string(1) "a" +} + +-- Iteration 2 -- +array(1) { + ["two"]=> + float(2.00000000000001) +} +array(2) { + [2]=> + string(16) "2.00000000000001" + [3]=> + string(1) "a" +} + +-- Iteration 3 -- +array(1) { + ["two"]=> + float(2.00000000000001) +} +array(2) { + [2]=> + string(16) "2.00000000000001" + [3]=> + string(1) "a" +} + +-- Iteration 4 -- +array(2) { + [0]=> + string(4) "zero" + ["two"]=> + float(2.00000000000001) +} +array(2) { + [0]=> + int(2) + [2]=> + int(0) +} + +-- Iteration 5 -- +array(2) { + [0]=> + string(4) "zero" + ["two"]=> + float(2.00000000000001) +} +array(2) { + [2]=> + int(2) + [0]=> + int(0) +} + +-- Iteration 6 -- +array(1) { + [0]=> + string(4) "zero" +} +array(1) { + [0]=> + int(0) +} + +-- Iteration 7 -- +array(2) { + [0]=> + string(4) "zero" + ["two"]=> + float(2.00000000000001) +} +array(2) { + [0]=> + float(2.00000000000001) + [2]=> + float(1.0E-11) +} + +-- Iteration 8 -- +array(2) { + [0]=> + string(4) "zero" + ["two"]=> + float(2.00000000000001) +} +array(2) { + [2]=> + float(2.00000000000001) + [0]=> + float(1.0E-11) +} + +-- Iteration 9 -- +array(1) { + [0]=> + string(4) "zero" +} +array(1) { + [0]=> + float(1.0E-11) +} +Done diff --git a/tests/std/array/array_diff_assoc_variation7.phpt b/tests/std/array/array_diff_assoc_variation7.phpt new file mode 100644 index 00000000..ee791247 --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation7.phpt @@ -0,0 +1,97 @@ +--TEST-- +Test array_diff_assoc() function : usage variations - arrays containing referenced variables +--SKIPIF-- + + +--FILE-- + 1, 'b' => 2, 'c' => 3, &$a); + +echo "-- Results when \$a = $a: --\n"; +var_dump(array_diff_assoc($arr1, $arr2)); +var_dump(array_diff_assoc($arr2, $arr1)); + +$a = 4; + +echo "-- Results when \$a has been changed to $a: --\n"; +var_dump(array_diff_assoc($arr1, $arr2)); +var_dump(array_diff_assoc($arr2, $arr1)); + +$arr2 = &$arr1; + +echo "-- Results when \$arr2 is referenced to \$arr1 --\n"; +var_dump(array_diff_assoc($arr1, $arr2)); +var_dump(array_diff_assoc($arr2, $arr1)); + +$arr1 = array('zero' => 'x', 'one' => 'y', 'two' => 'z'); + +echo "-- Results when \$arr1 is changed --\n"; +var_dump(array_diff_assoc($arr1, $arr2)); +var_dump(array_diff_assoc($arr2, $arr1)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff_assoc() : usage variations *** +-- Results when $a = a: -- +array(3) { + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "a" +} +array(3) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + int(3) +} +-- Results when $a has been changed to 4: -- +array(4) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "a" +} +array(4) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + int(3) + [0]=> + &int(4) +} +-- Results when $arr2 is referenced to $arr1 -- +array(0) { +} +array(0) { +} +-- Results when $arr1 is changed -- +array(0) { +} +array(0) { +} +Done diff --git a/tests/std/array/array_diff_assoc_variation8.phpt b/tests/std/array/array_diff_assoc_variation8.phpt new file mode 100644 index 00000000..0ca368f9 --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation8.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test array_diff_assoc() function : usage variations - array containing duplicate keys and values +--FILE-- + 'd', 'b'); //duplicate key (0), duplicate value (b) +$array_assoc = array ('2' => 'c', //same key=>value pair, different order + '1' => 'b', + '0' => 'a', + 'b' => '3', //key and value from array_index swapped + 'c' => 2); //same as above, using integer + +var_dump(array_diff_assoc($array_index, $array_assoc)); +var_dump(array_diff_assoc($array_assoc, $array_index)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff_assoc() : variation *** +array(2) { + [0]=> + string(1) "d" + [3]=> + string(1) "b" +} +array(3) { + [0]=> + string(1) "a" + ["b"]=> + string(1) "3" + ["c"]=> + int(2) +} +Done diff --git a/tests/std/array/array_diff_assoc_variation9.phpt b/tests/std/array/array_diff_assoc_variation9.phpt new file mode 100644 index 00000000..e6d8ce06 --- /dev/null +++ b/tests/std/array/array_diff_assoc_variation9.phpt @@ -0,0 +1,134 @@ +--TEST-- +Test array_diff_assoc() function : usage variations - compare multidimensional arrays +--FILE-- + array (1, 2, 3), + 'sub_array2' => array ('a', 'b', 'c')); +$array2 = array('sub_arraya' => array (1, 3, 5), + 'sub_arrayb' => array ('a', 'z', 'y')); + +echo "-- Compare two 2-D arrays --\n"; +var_dump(array_diff_assoc($array1, $array2)); +var_dump(array_diff_assoc($array2, $array1)); + +echo "\n-- Compare subarrays from two 2-D arrays --\n"; +var_dump(array_diff_assoc($array1['sub_array1'], $array2['sub_arraya'])); +var_dump(array_diff_assoc($array2['sub_arraya'], $array1['sub_array1'])); +var_dump(array_diff_assoc($array1['sub_array2'], $array2['sub_arrayb'])); +var_dump(array_diff_assoc($array2['sub_arrayb'], $array1['sub_array1'])); + +echo "\n-- Compare a subarray from one 2-D array and one 2-D array --\n"; +var_dump(array_diff_assoc($array1['sub_array1'], $array2)); +var_dump(array_diff_assoc($array1, $array2['sub_arraya'])); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff_assoc() : usage variations *** +-- Compare two 2-D arrays -- +array(2) { + ["sub_array1"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + ["sub_array2"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +array(2) { + ["sub_arraya"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(3) + [2]=> + int(5) + } + ["sub_arrayb"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "z" + [2]=> + string(1) "y" + } +} + +-- Compare subarrays from two 2-D arrays -- +array(2) { + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + [1]=> + int(3) + [2]=> + int(5) +} +array(2) { + [1]=> + string(1) "b" + [2]=> + string(1) "c" +} +array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "z" + [2]=> + string(1) "y" +} + +-- Compare a subarray from one 2-D array and one 2-D array -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + ["sub_array1"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + ["sub_array2"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +Done diff --git a/tests/std/array/array_diff_basic.phpt b/tests/std/array/array_diff_basic.phpt new file mode 100644 index 00000000..aa9f1cbf --- /dev/null +++ b/tests/std/array/array_diff_basic.phpt @@ -0,0 +1,110 @@ +--TEST-- +Test array_diff() function : basic functionality +--FILE-- + 1, 'two' => 2, 'three' => 3, 'four' => 4); +$array_assoc_int2 = array ('three' => 3, 'four' => 4, 'five' => 5, 'six' => 6); + +echo "-- Test associative array with strings as keys and integers as elements --\n"; +var_dump(array_diff($array_assoc_int1, $array_assoc_int2)); +var_dump(array_diff($array_assoc_int2, $array_assoc_int1)); + +//Test associative array with strings as keys and elements +$array_assoc_str1 = array ('one' => 'un', 'two' => 'deux', 'three' => 'trois', 'four' => 'quatre'); +$array_assoc_str2 = array ('three' => 'trois', 'four' => 'quatre', 'five' => 'cinq', 'six' => 'six'); + +echo "-- Test associative array with strings as keys and integers as elements --\n"; +var_dump(array_diff($array_assoc_str1, $array_assoc_str2)); +var_dump(array_diff($array_assoc_str2, $array_assoc_str1)); + +echo "-- Test array_diff with more than 2 arguments --\n"; +var_dump(array_diff($array_int1, $array_int2, $array_string1, $array_string2)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff() : basic functionality *** +-- Test indexed array with integers as elements -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +array(2) { + [2]=> + int(5) + [3]=> + int(6) +} +-- Test indexed array with strings as elements -- +array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" +} +array(2) { + [2]=> + string(4) "five" + [3]=> + string(3) "six" +} +-- Test associative array with strings as keys and integers as elements -- +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["five"]=> + int(5) + ["six"]=> + int(6) +} +-- Test associative array with strings as keys and integers as elements -- +array(2) { + ["one"]=> + string(2) "un" + ["two"]=> + string(4) "deux" +} +array(2) { + ["five"]=> + string(4) "cinq" + ["six"]=> + string(3) "six" +} +-- Test array_diff with more than 2 arguments -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +Done diff --git a/tests/std/array/array_diff_key.phpt b/tests/std/array/array_diff_key.phpt new file mode 100644 index 00000000..bb3db1a1 --- /dev/null +++ b/tests/std/array/array_diff_key.phpt @@ -0,0 +1,286 @@ +--TEST-- +Test of the array_diff_key() and array_diff_ukey() +--FILE-- + $b ? 1 : -1; +} +function main() +{ + $a = array(1, 6, 2, -20, 15, 1200, -2500); + $b = array(0, 7, 2, -20, 11, 1100, -2500); + $c = array(0, 6, 2, -20, 19, 1000, -2500); + $d = array(3, 8, -2, -20, 14, 900, -2600); + $a_f = array_flip($a); + $b_f = array_flip($b); + $c_f = array_flip($c); + $d_f = array_flip($d); + $i = 1; + /* give nicer values */ + foreach ($a_f as $k => &$a_f_el) { + $a_f_el = $k * 2; + } + foreach ($b_f as $k => &$b_f_el) { + $b_f_el = $k * 2; + } + foreach ($c_f as $k => &$c_f_el) { + $c_f_el = $k * 2; + } + foreach ($d_f as $k => &$d_f_el) { + $d_f_el = $k * 2; + } + echo "------ Test {$i} --------\n"; + $i++; + // 1 + var_dump(array_diff_key($a_f, $b_f)); + // keys -> 1, 6, 15, 1200 + var_dump(array_diff_ukey($a_f, $b_f, "comp_func")); + // 1, 6, 15, 1200 + echo "------ Test {$i} --------\n"; + $i++; + // 2 + var_dump(array_diff_key($a_f, $c_f)); + // keys -> 1, 15, 1200 + var_dump(array_diff_ukey($a_f, $c_f, "comp_func")); + // 1, 15, 1200 + echo "------ Test {$i} --------\n"; + $i++; + // 3 + var_dump(array_diff_key($a_f, $d_f)); + // 1, 6, 2, 15, 1200, -2500 + var_dump(array_diff_ukey($a_f, $d_f, "comp_func")); + // 1, 6, 2, 15, 1200, -2500 + echo "------ Test {$i} --------\n"; + $i++; + // 4 + var_dump(array_diff_key($a_f, $b_f, $c_f)); + // 1, 15, 1200 + var_dump(array_diff_ukey($a_f, $b_f, $c_f, "comp_func")); + // 1, 15, 1200 + echo "------ Test {$i} --------\n"; + $i++; + // 5 + var_dump(array_diff_key($a_f, $b_f, $d_f)); + // 1, 6, 15, 1200 + var_dump(array_diff_ukey($a_f, $b_f, $d_f, "comp_func")); + // 1, 6, 15, 1200 + echo "------ Test {$i} --------\n"; + $i++; + // 6 + var_dump(array_diff_key($a_f, $b_f, $c_f, $d_f)); + // 1, 15, 1200 + var_dump(array_diff_ukey($a_f, $b_f, $c_f, $d_f, "comp_func")); + //1, 15, 1200 + echo "------ Test {$i} --------\n"; + $i++; + // 7 + var_dump(array_diff_key($b_f, $c_f)); + // 7, 11, 1100 + var_dump(array_diff_ukey($b_f, $c_f, "comp_func")); + //7, 11, 1100 + echo "------ Test {$i} --------\n"; + $i++; + // 8 + var_dump(array_diff_key($b_f, $d_f)); + //0, 7, 2, 11, 1100, -2500 + var_dump(array_diff_ukey($b_f, $d_f, "comp_func")); + //0, 7, 2, 11, 1100, -2500 + echo "------ Test {$i} --------\n"; + $i++; + // 9 + var_dump(array_diff_key($b_f, $c_f, $d_f)); + // 7, 11, 1100 + var_dump(array_diff_ukey($b_f, $c_f, $d_f, "comp_func")); +} +?> +--EXPECT-- +------ Test 1 -------- +array(4) { + [1]=> + int(2) + [6]=> + int(12) + [15]=> + int(30) + [1200]=> + int(2400) +} +array(4) { + [1]=> + int(2) + [6]=> + int(12) + [15]=> + int(30) + [1200]=> + int(2400) +} +------ Test 2 -------- +array(3) { + [1]=> + int(2) + [15]=> + int(30) + [1200]=> + int(2400) +} +array(3) { + [1]=> + int(2) + [15]=> + int(30) + [1200]=> + int(2400) +} +------ Test 3 -------- +array(6) { + [1]=> + int(2) + [6]=> + int(12) + [2]=> + int(4) + [15]=> + int(30) + [1200]=> + int(2400) + [-2500]=> + &int(-5000) +} +array(6) { + [1]=> + int(2) + [6]=> + int(12) + [2]=> + int(4) + [15]=> + int(30) + [1200]=> + int(2400) + [-2500]=> + &int(-5000) +} +------ Test 4 -------- +array(3) { + [1]=> + int(2) + [15]=> + int(30) + [1200]=> + int(2400) +} +array(3) { + [1]=> + int(2) + [15]=> + int(30) + [1200]=> + int(2400) +} +------ Test 5 -------- +array(4) { + [1]=> + int(2) + [6]=> + int(12) + [15]=> + int(30) + [1200]=> + int(2400) +} +array(4) { + [1]=> + int(2) + [6]=> + int(12) + [15]=> + int(30) + [1200]=> + int(2400) +} +------ Test 6 -------- +array(3) { + [1]=> + int(2) + [15]=> + int(30) + [1200]=> + int(2400) +} +array(3) { + [1]=> + int(2) + [15]=> + int(30) + [1200]=> + int(2400) +} +------ Test 7 -------- +array(3) { + [7]=> + int(14) + [11]=> + int(22) + [1100]=> + int(2200) +} +array(3) { + [7]=> + int(14) + [11]=> + int(22) + [1100]=> + int(2200) +} +------ Test 8 -------- +array(6) { + [0]=> + int(0) + [7]=> + int(14) + [2]=> + int(4) + [11]=> + int(22) + [1100]=> + int(2200) + [-2500]=> + &int(-5000) +} +array(6) { + [0]=> + int(0) + [7]=> + int(14) + [2]=> + int(4) + [11]=> + int(22) + [1100]=> + int(2200) + [-2500]=> + &int(-5000) +} +------ Test 9 -------- +array(3) { + [7]=> + int(14) + [11]=> + int(22) + [1100]=> + int(2200) +} +array(3) { + [7]=> + int(14) + [11]=> + int(22) + [1100]=> + int(2200) +} diff --git a/tests/std/array/array_diff_key2.phpt b/tests/std/array/array_diff_key2.phpt new file mode 100644 index 00000000..b7ef7f31 --- /dev/null +++ b/tests/std/array/array_diff_key2.phpt @@ -0,0 +1,44 @@ +--TEST-- +basic array_diff_key test +--FILE-- + "green", "b" => "brown", "c" => "blue", "red", ""); +$array2 = array("a" => "green", "yellow", "red", TRUE); +$array3 = array("red", "a"=>"brown", ""); +$result[] = array_diff_key($array1, $array2); +$result[] = array_diff_key($array1, $array3); +$result[] = array_diff_key($array2, $array3); +$result[] = array_diff_key($array1, $array2, $array3); + +var_dump($result); + +?> +--EXPECT-- +array(4) { + [0]=> + array(2) { + ["b"]=> + string(5) "brown" + ["c"]=> + string(4) "blue" + } + [1]=> + array(2) { + ["b"]=> + string(5) "brown" + ["c"]=> + string(4) "blue" + } + [2]=> + array(1) { + [2]=> + bool(true) + } + [3]=> + array(2) { + ["b"]=> + string(5) "brown" + ["c"]=> + string(4) "blue" + } +} diff --git a/tests/std/array/array_diff_key_basic.phpt b/tests/std/array/array_diff_key_basic.phpt new file mode 100644 index 00000000..1ce70c6a --- /dev/null +++ b/tests/std/array/array_diff_key_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test array_diff_key() : basic functionality +--FILE-- + 1, 'red' => 2, 'green' => 3, 'purple' => 4); +$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); +var_dump(array_diff_key($array1, $array2)); +?> +--EXPECT-- +array(2) { + ["red"]=> + int(2) + ["purple"]=> + int(4) +} diff --git a/tests/std/array/array_diff_key_variation1.phpt b/tests/std/array/array_diff_key_variation1.phpt new file mode 100644 index 00000000..b9d38dde --- /dev/null +++ b/tests/std/array/array_diff_key_variation1.phpt @@ -0,0 +1,196 @@ +--TEST-- +Test array_diff_key() function : usage variation - Passing unexpected values to first argument +--SKIPIF-- + + +--FILE-- + 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + $array3 = array(1, 2, 3, 4, 5); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -12345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource' => $fp, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_diff_key($value, $array2)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_diff_key($value, $array2, $array3)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_diff_key() : usage variation *** + +--int 0-- +array_diff_key(): Argument #1 ($array) must be of type array, int given +array_diff_key(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_diff_key(): Argument #1 ($array) must be of type array, int given +array_diff_key(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_diff_key(): Argument #1 ($array) must be of type array, int given +array_diff_key(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_diff_key(): Argument #1 ($array) must be of type array, int given +array_diff_key(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_diff_key(): Argument #1 ($array) must be of type array, float given +array_diff_key(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_diff_key(): Argument #1 ($array) must be of type array, float given +array_diff_key(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_diff_key(): Argument #1 ($array) must be of type array, float given +array_diff_key(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_diff_key(): Argument #1 ($array) must be of type array, float given +array_diff_key(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_diff_key(): Argument #1 ($array) must be of type array, float given +array_diff_key(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_diff_key(): Argument #1 ($array) must be of type array, null given +array_diff_key(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_diff_key(): Argument #1 ($array) must be of type array, null given +array_diff_key(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_diff_key(): Argument #1 ($array) must be of type array, true given +array_diff_key(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_diff_key(): Argument #1 ($array) must be of type array, false given +array_diff_key(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_diff_key(): Argument #1 ($array) must be of type array, true given +array_diff_key(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_diff_key(): Argument #1 ($array) must be of type array, false given +array_diff_key(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_diff_key(): Argument #1 ($array) must be of type array, string given +array_diff_key(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_diff_key(): Argument #1 ($array) must be of type array, string given +array_diff_key(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_diff_key(): Argument #1 ($array) must be of type array, string given +array_diff_key(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_diff_key(): Argument #1 ($array) must be of type array, string given +array_diff_key(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_diff_key(): Argument #1 ($array) must be of type array, string given +array_diff_key(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_diff_key(): Argument #1 ($array) must be of type array, string given +array_diff_key(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_diff_key(): Argument #1 ($array) must be of type array, classWithToString given +array_diff_key(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_diff_key(): Argument #1 ($array) must be of type array, classWithoutToString given +array_diff_key(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_diff_key(): Argument #1 ($array) must be of type array, null given +array_diff_key(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_diff_key(): Argument #1 ($array) must be of type array, null given +array_diff_key(): Argument #1 ($array) must be of type array, null given + +--resource-- +array_diff_key(): Argument #1 ($array) must be of type array, resource given +array_diff_key(): Argument #1 ($array) must be of type array, resource given diff --git a/tests/std/array/array_diff_key_variation2.phpt b/tests/std/array/array_diff_key_variation2.phpt new file mode 100644 index 00000000..f18661a4 --- /dev/null +++ b/tests/std/array/array_diff_key_variation2.phpt @@ -0,0 +1,196 @@ +--TEST-- +Test array_diff_key() function : usage variation - Passing unexpected values to second argument +--SKIPIF-- + + +--FILE-- + 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + $array3 = array(1, 2, 3, 4, 5); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -12345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource' => $fp, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_diff_key($array1, $value)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_diff_key($array1, $value, $array3)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_diff_key() : usage variation *** + +--int 0-- +array_diff_key(): Argument #2 must be of type array, int given +array_diff_key(): Argument #2 must be of type array, int given + +--int 1-- +array_diff_key(): Argument #2 must be of type array, int given +array_diff_key(): Argument #2 must be of type array, int given + +--int 12345-- +array_diff_key(): Argument #2 must be of type array, int given +array_diff_key(): Argument #2 must be of type array, int given + +--int -12345-- +array_diff_key(): Argument #2 must be of type array, int given +array_diff_key(): Argument #2 must be of type array, int given + +--float 10.5-- +array_diff_key(): Argument #2 must be of type array, float given +array_diff_key(): Argument #2 must be of type array, float given + +--float -10.5-- +array_diff_key(): Argument #2 must be of type array, float given +array_diff_key(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_diff_key(): Argument #2 must be of type array, float given +array_diff_key(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_diff_key(): Argument #2 must be of type array, float given +array_diff_key(): Argument #2 must be of type array, float given + +--float .5-- +array_diff_key(): Argument #2 must be of type array, float given +array_diff_key(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_diff_key(): Argument #2 must be of type array, null given +array_diff_key(): Argument #2 must be of type array, null given + +--lowercase null-- +array_diff_key(): Argument #2 must be of type array, null given +array_diff_key(): Argument #2 must be of type array, null given + +--lowercase true-- +array_diff_key(): Argument #2 must be of type array, true given +array_diff_key(): Argument #2 must be of type array, true given + +--lowercase false-- +array_diff_key(): Argument #2 must be of type array, false given +array_diff_key(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_diff_key(): Argument #2 must be of type array, true given +array_diff_key(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_diff_key(): Argument #2 must be of type array, false given +array_diff_key(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_diff_key(): Argument #2 must be of type array, string given +array_diff_key(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_diff_key(): Argument #2 must be of type array, string given +array_diff_key(): Argument #2 must be of type array, string given + +--string DQ-- +array_diff_key(): Argument #2 must be of type array, string given +array_diff_key(): Argument #2 must be of type array, string given + +--string SQ-- +array_diff_key(): Argument #2 must be of type array, string given +array_diff_key(): Argument #2 must be of type array, string given + +--mixed case string-- +array_diff_key(): Argument #2 must be of type array, string given +array_diff_key(): Argument #2 must be of type array, string given + +--heredoc-- +array_diff_key(): Argument #2 must be of type array, string given +array_diff_key(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_diff_key(): Argument #2 must be of type array, classWithToString given +array_diff_key(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_diff_key(): Argument #2 must be of type array, classWithoutToString given +array_diff_key(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_diff_key(): Argument #2 must be of type array, null given +array_diff_key(): Argument #2 must be of type array, null given + +--unset var-- +array_diff_key(): Argument #2 must be of type array, null given +array_diff_key(): Argument #2 must be of type array, null given + +--resource-- +array_diff_key(): Argument #2 must be of type array, resource given +array_diff_key(): Argument #2 must be of type array, resource given diff --git a/tests/std/array/array_diff_key_variation4.phpt b/tests/std/array/array_diff_key_variation4.phpt new file mode 100644 index 00000000..eb358af0 --- /dev/null +++ b/tests/std/array/array_diff_key_variation4.phpt @@ -0,0 +1,54 @@ +--TEST-- +Test array_diff_key() function : usage variation - Passing integer indexed array +--FILE-- + '-07', 0xA => '0xA'); + +$input_arrays = array( + 'decimal indexed' => array(10 => '10', '-17' => '-17'), + 'octal indexed' => array(-011 => '-011', 012 => '012'), + 'hexa indexed' => array(0x12 => '0x12', -0x7 => '-0x7', ), +); + +// loop through each element of the array for arr1 +foreach($input_arrays as $key =>$value) { + echo "\n--$key--\n"; + var_dump( array_diff_key($input_array, $value) ); + var_dump( array_diff_key($value, $input_array) ); +} +?> +--EXPECT-- +*** Testing array_diff_key() : usage variation *** + +--decimal indexed-- +array(1) { + [-7]=> + string(3) "-07" +} +array(1) { + [-17]=> + string(3) "-17" +} + +--octal indexed-- +array(1) { + [-7]=> + string(3) "-07" +} +array(1) { + [-9]=> + string(4) "-011" +} + +--hexa indexed-- +array(1) { + [10]=> + string(3) "0xA" +} +array(1) { + [18]=> + string(4) "0x12" +} diff --git a/tests/std/array/array_diff_key_variation6.phpt b/tests/std/array/array_diff_key_variation6.phpt new file mode 100644 index 00000000..b3b19db8 --- /dev/null +++ b/tests/std/array/array_diff_key_variation6.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test array_diff_key() function : usage variation - Passing boolean indexed array +--SKIPIF-- +--FILE-- + '0', 1 => '1', -10 => '-10', 'true' => 1, 'false' => 0); +$boolean_indx_array = array(true => 'boolt', false => 'boolf', TRUE => 'boolT', FALSE => 'boolF'); + +echo "\n-- Testing array_diff_key() function with boolean indexed array --\n"; +// loop through each element of the array for arr1 +var_dump( array_diff_key($input_array, $boolean_indx_array) ); +var_dump( array_diff_key($boolean_indx_array, $input_array) ); +?> +--EXPECT-- +*** Testing array_diff_key() : usage variation *** + +-- Testing array_diff_key() function with boolean indexed array -- +array(3) { + [-10]=> + string(3) "-10" + ["true"]=> + int(1) + ["false"]=> + int(0) +} +array(0) { +} diff --git a/tests/std/array/array_diff_key_variation7.phpt b/tests/std/array/array_diff_key_variation7.phpt new file mode 100644 index 00000000..f8821cb9 --- /dev/null +++ b/tests/std/array/array_diff_key_variation7.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test array_diff_key() function : usage variation - Passing null,unset and undefined variable indexed array +--SKIPIF-- + + +--FILE-- + '10', "" => 'empty'); + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +$input_arrays = array( + 'null indexed' => array(NULL => 'null 1', null => 'null 2'), + 'undefined indexed' => array(@$undefined_var => 'undefined'), + 'unset indexed' => array(@$unset_var => 'unset'), +); + +foreach($input_arrays as $key =>$value) { + echo "\n--$key--\n"; + // loop through each element of the array for arr1 + var_dump( array_diff_key($input_array, $value) ); + var_dump( array_diff_key($value, $input_array) ); +} +?> +--EXPECT-- +*** Testing array_diff_key() : usage variation *** + +--null indexed-- +array(1) { + [10]=> + string(2) "10" +} +array(0) { +} + +--undefined indexed-- +array(1) { + [10]=> + string(2) "10" +} +array(0) { +} + +--unset indexed-- +array(1) { + [10]=> + string(2) "10" +} +array(0) { +} diff --git a/tests/std/array/array_diff_key_variation8.phpt b/tests/std/array/array_diff_key_variation8.phpt new file mode 100644 index 00000000..dc54a976 --- /dev/null +++ b/tests/std/array/array_diff_key_variation8.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test array_diff_key() function : usage variation - Passing multi-dimensional array +--FILE-- + array('blue' => 1, 'red' => 2), + + 'second' => array('yellow' => 7), + + 'third' => array(0 => 'zero'), +); + +$array2 = array ( + + 'first' => array('blue' => 1, 'red' => 2,), + + 'second' => array('cyan' => 8), + + 'fourth' => array(2 => 'two'), +); + +echo "\n-- Testing array_diff_key() function with multi dimensional array --\n"; +var_dump( array_diff_key($array1, $array2) ); +var_dump( array_diff_key($array2, $array1) ); +?> +--EXPECT-- +*** Testing array_diff_key() : usage variation *** + +-- Testing array_diff_key() function with multi dimensional array -- +array(1) { + ["third"]=> + array(1) { + [0]=> + string(4) "zero" + } +} +array(1) { + ["fourth"]=> + array(1) { + [2]=> + string(3) "two" + } +} diff --git a/tests/std/array/array_diff_single_array.phpt b/tests/std/array/array_diff_single_array.phpt new file mode 100644 index 00000000..83355b08 --- /dev/null +++ b/tests/std/array/array_diff_single_array.phpt @@ -0,0 +1,50 @@ +--TEST-- +array_diff() with single array argument +--FILE-- + 42]; +$cmp = function($a, $b) { return $a <=> $b; }; +var_dump(array_diff($array)); +var_dump(array_diff_key($array)); +var_dump(array_diff_ukey($array, $cmp)); +var_dump(array_diff_assoc($array)); +var_dump(array_diff_uassoc($array, $cmp)); +var_dump(array_udiff($array, $cmp)); +var_dump(array_udiff_assoc($array, $cmp)); +var_dump(array_udiff_uassoc($array, $cmp, $cmp)); + +?> +--EXPECT-- +array(1) { + ["a"]=> + int(42) +} +array(1) { + ["a"]=> + int(42) +} +array(1) { + ["a"]=> + int(42) +} +array(1) { + ["a"]=> + int(42) +} +array(1) { + ["a"]=> + int(42) +} +array(1) { + ["a"]=> + int(42) +} +array(1) { + ["a"]=> + int(42) +} +array(1) { + ["a"]=> + int(42) +} diff --git a/tests/std/array/array_diff_uassoc_basic.phpt b/tests/std/array/array_diff_uassoc_basic.phpt new file mode 100644 index 00000000..3a9296e5 --- /dev/null +++ b/tests/std/array/array_diff_uassoc_basic.phpt @@ -0,0 +1,32 @@ +--TEST-- +array_diff_uassoc(): Basic test +--FILE-- + $b ? 1 : -1; +} +function main() +{ + $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red"); + $array2 = array("a" => "green", "yellow", "red"); + $result = array_diff_uassoc($array1, $array2, "key_compare_func"); + var_dump($result); +} +?> +--EXPECT-- +array(3) { + ["b"]=> + string(5) "brown" + ["c"]=> + string(4) "blue" + [0]=> + string(3) "red" +} diff --git a/tests/std/array/array_diff_uassoc_error.phpt b/tests/std/array/array_diff_uassoc_error.phpt new file mode 100644 index 00000000..8f166d50 --- /dev/null +++ b/tests/std/array/array_diff_uassoc_error.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test array_diff_uassoc() function : error conditions +--FILE-- + $b ? 1 : -1; +} +function main() +{ + echo "*** Testing array_diff_uassoc() : error conditions ***\n"; + //Initialize array + $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red"); + $array2 = array("a" => "green", "yellow", "red"); + $array3 = array("a" => "green", "red"); + $array4 = array(); + $extra_arg = array(1, 2, 3, 4); + //Test array_diff_uassoc with one more than the expected number of arguments + echo "\n-- Testing array_diff_uassoc() function with more than expected no. of arguments --\n"; + try { + var_dump(array_diff_uassoc($array1, $array2, "key_compare_func", $extra_arg)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_diff_uassoc($array1, $array2, $array3, $array4, "key_compare_func", $extra_arg)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + // Testing array_diff_uassoc with one less than the expected number of arguments + echo "\n-- Testing array_diff_uassoc() function with less than expected no. of arguments --\n"; + try { + var_dump(array_diff_uassoc($array1, $array2)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } +} +?> +--EXPECT-- +*** Testing array_diff_uassoc() : error conditions *** + +-- Testing array_diff_uassoc() function with more than expected no. of arguments -- +array_diff_uassoc(): Argument #4 must be a valid callback, array callback must have exactly two members +array_diff_uassoc(): Argument #6 must be a valid callback, array callback must have exactly two members + +-- Testing array_diff_uassoc() function with less than expected no. of arguments -- +array_diff_uassoc(): Argument #2 must be a valid callback, array callback must have exactly two members diff --git a/tests/std/array/array_diff_uassoc_variation1.phpt b/tests/std/array/array_diff_uassoc_variation1.phpt new file mode 100644 index 00000000..c7a737f6 --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation1.phpt @@ -0,0 +1,174 @@ +--TEST-- +Test array_diff_uassoc() function : usage variation - Passing unexpected values to first argument +--SKIPIF-- + + +--FILE-- + $b ? 1 : -1; +} +// define some classes +class classWithToString +{ + public function __toString(): string { + return "Class A object"; + } +} +class classWithoutToString +{ +} +function main() +{ + echo "*** Testing array_diff_uassoc() : usage variation ***\n"; + //Initialize variables + $array2 = array("a" => "green", "yellow", "red"); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource' => $fp, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_diff_uassoc($value, $array2, "key_compare_func")); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +--int 0-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, null given + +--resource-- +array_diff_uassoc(): Argument #1 ($array) must be of type array, resource given diff --git a/tests/std/array/array_diff_uassoc_variation11.phpt b/tests/std/array/array_diff_uassoc_variation11.phpt new file mode 100644 index 00000000..ac9544b1 --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation11.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test array_diff_uassoc() function : usage variation - Passing boolean indexed array +--SKIPIF-- +--FILE-- + '0', 1 => '1', -10 => '-10', 'true' => 1, 'false' => 0); +$boolean_indx_array = array(true => 'boolt', false => 'boolf', TRUE => 'boolT', FALSE => 'boolF'); + +echo "\n-- Testing array_diff_key() function with float indexed array --\n"; +var_dump( array_diff_uassoc($input_array, $boolean_indx_array, "strcasecmp") ); +var_dump( array_diff_uassoc($boolean_indx_array, $input_array, "strcasecmp") ); + +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +-- Testing array_diff_key() function with float indexed array -- +array(5) { + [0]=> + string(1) "0" + [1]=> + string(1) "1" + [-10]=> + string(3) "-10" + ["true"]=> + int(1) + ["false"]=> + int(0) +} +array(2) { + [1]=> + string(5) "boolT" + [0]=> + string(5) "boolF" +} diff --git a/tests/std/array/array_diff_uassoc_variation12.phpt b/tests/std/array/array_diff_uassoc_variation12.phpt new file mode 100644 index 00000000..4ab1cf0e --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation12.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test array_diff_uassoc() function : usage variation - Passing null,unset and undefined variable indexed array +--SKIPIF-- + + +--FILE-- + '10', "" => ''); + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +$input_arrays = array( + 'null indexed' => array(NULL => NULL, null => null), + 'undefined indexed' => array(@$undefined_var => @$undefined_var), + 'unset indexed' => array(@$unset_var => @$unset_var), +); + +foreach($input_arrays as $key =>$value) { + echo "\n--$key--\n"; + var_dump( array_diff_uassoc($input_array, $value, "strcasecmp") ); + var_dump( array_diff_uassoc($value, $input_array, "strcasecmp") ); +} + +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +--null indexed-- +array(1) { + [10]=> + string(2) "10" +} +array(0) { +} + +--undefined indexed-- +array(1) { + [10]=> + string(2) "10" +} +array(0) { +} + +--unset indexed-- +array(1) { + [10]=> + string(2) "10" +} +array(0) { +} diff --git a/tests/std/array/array_diff_uassoc_variation13.phpt b/tests/std/array/array_diff_uassoc_variation13.phpt new file mode 100644 index 00000000..7ff8e49b --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation13.phpt @@ -0,0 +1,65 @@ +--TEST-- +Test array_diff_uassoc() function : usage variations - arrays containing referenced variables +--SKIPIF-- + + +--FILE-- + 1, &$ref_var); + +echo "\n-- Testing array_diff_uassoc() function with referenced variable \$ref_var has value '$ref_var' --\n"; +var_dump( array_diff_uassoc($array1, $array2, "strcasecmp") ); +var_dump( array_diff_uassoc($array2, $array1, "strcasecmp") ); + +// re-assign reference variable to different value +$ref_var = 10.00; +echo "\n-- Testing array_diff_uassoc() function with referenced variable \$ref_var value changed to $ref_var --\n"; +var_dump( array_diff_uassoc($array1, $array2, "strcasecmp") ); +var_dump( array_diff_uassoc($array2, $array1, "strcasecmp") ); + +//When array are refenced +$array2 = &$array1; +echo "\n-- Testing array_diff_uassoc() function when \$array2 is referenced to \$array1 --\n"; +var_dump( array_diff_uassoc($array1, $array2, "strcasecmp") ); +var_dump( array_diff_uassoc($array2, $array1, "strcasecmp") ); + +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +-- Testing array_diff_uassoc() function with referenced variable $ref_var has value 'a' -- +array(1) { + [1]=> + string(1) "a" +} +array(1) { + ["a"]=> + int(1) +} + +-- Testing array_diff_uassoc() function with referenced variable $ref_var value changed to 10 -- +array(2) { + [0]=> + string(1) "a" + [1]=> + string(1) "a" +} +array(2) { + ["a"]=> + int(1) + [0]=> + &float(10) +} + +-- Testing array_diff_uassoc() function when $array2 is referenced to $array1 -- +array(0) { +} +array(0) { +} diff --git a/tests/std/array/array_diff_uassoc_variation2.phpt b/tests/std/array/array_diff_uassoc_variation2.phpt new file mode 100644 index 00000000..9f85ed89 --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation2.phpt @@ -0,0 +1,174 @@ +--TEST-- +Test array_diff_uassoc() function : usage variation -Passing unexpected values to second argument +--SKIPIF-- + + +--FILE-- + $b ? 1 : -1; +} +// define some classes +class classWithToString +{ + public function __toString(): string { + return "Class A object"; + } +} +class classWithoutToString +{ +} +function main() +{ + echo "*** Testing array_diff_uassoc() : usage variation ***\n"; + //Initialize variables + $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red"); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource' => $fp, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_diff_uassoc($array1, $value, "key_compare_func")); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +--int 0-- +array_diff_uassoc(): Argument #2 must be of type array, int given + +--int 1-- +array_diff_uassoc(): Argument #2 must be of type array, int given + +--int 12345-- +array_diff_uassoc(): Argument #2 must be of type array, int given + +--int -12345-- +array_diff_uassoc(): Argument #2 must be of type array, int given + +--float 10.5-- +array_diff_uassoc(): Argument #2 must be of type array, float given + +--float -10.5-- +array_diff_uassoc(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_diff_uassoc(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_diff_uassoc(): Argument #2 must be of type array, float given + +--float .5-- +array_diff_uassoc(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_diff_uassoc(): Argument #2 must be of type array, null given + +--lowercase null-- +array_diff_uassoc(): Argument #2 must be of type array, null given + +--lowercase true-- +array_diff_uassoc(): Argument #2 must be of type array, true given + +--lowercase false-- +array_diff_uassoc(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_diff_uassoc(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_diff_uassoc(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_diff_uassoc(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_diff_uassoc(): Argument #2 must be of type array, string given + +--string DQ-- +array_diff_uassoc(): Argument #2 must be of type array, string given + +--string SQ-- +array_diff_uassoc(): Argument #2 must be of type array, string given + +--mixed case string-- +array_diff_uassoc(): Argument #2 must be of type array, string given + +--heredoc-- +array_diff_uassoc(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_diff_uassoc(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_diff_uassoc(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_diff_uassoc(): Argument #2 must be of type array, null given + +--unset var-- +array_diff_uassoc(): Argument #2 must be of type array, null given + +--resource-- +array_diff_uassoc(): Argument #2 must be of type array, resource given diff --git a/tests/std/array/array_diff_uassoc_variation5.phpt b/tests/std/array/array_diff_uassoc_variation5.phpt new file mode 100644 index 00000000..384c9774 --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation5.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test array_diff_uassoc() function : usage variation - Comparing integers and floating point numbers +--FILE-- + $key2 ? 1 : -1; +} +function main() +{ + echo "*** Testing array_diff_uassoc() : usage variation ***\n"; + //Initialize variables + $arr_default_int = array(1, 2, 3, 4); + $arr_float = array(0 => 1.0, 1 => 2.0, 2 => 3.0, 3 => 4.0); + echo "\n-- Result of comparing integers and floating point numbers --\n"; + var_dump(array_diff_uassoc($arr_default_int, $arr_float, "key_compare_func")); + var_dump(array_diff_uassoc($arr_float, $arr_default_int, "key_compare_func")); +} +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +-- Result of comparing integers and floating point numbers -- +array(0) { +} +array(0) { +} diff --git a/tests/std/array/array_diff_uassoc_variation6.phpt b/tests/std/array/array_diff_uassoc_variation6.phpt new file mode 100644 index 00000000..56c65590 --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation6.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test array_diff_uassoc() function : usage variation - Comparing floating points with strings having integers and float +--FILE-- + $key2 ? 1 : -1; +} +function main() +{ + echo "*** Testing array_diff_uassoc() : usage variation ***\n"; + //Initialize variables + $arr_float = array(0 => 1.0, 1 => 2.0); + $arr_string_int = array('1', '2'); + $arr_string_float = array('0' => '1.00', '1.00' => '2.00'); + echo "\n-- Result of comparing floating points and strings containing integers --\n"; + var_dump(array_diff_uassoc($arr_float, $arr_string_int, "key_compare_func")); + var_dump(array_diff_uassoc($arr_string_int, $arr_float, "key_compare_func")); + echo "\n-- Result of comparing floating points and strings containing floating point --\n"; + var_dump(array_diff_uassoc($arr_float, $arr_string_float, "key_compare_func")); + var_dump(array_diff_uassoc($arr_string_float, $arr_float, "key_compare_func")); +} +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +-- Result of comparing floating points and strings containing integers -- +array(0) { +} +array(0) { +} + +-- Result of comparing floating points and strings containing floating point -- +array(2) { + [0]=> + float(1) + [1]=> + float(2) +} +array(2) { + [0]=> + string(4) "1.00" + ["1.00"]=> + string(4) "2.00" +} diff --git a/tests/std/array/array_diff_uassoc_variation7.phpt b/tests/std/array/array_diff_uassoc_variation7.phpt new file mode 100644 index 00000000..63bdbdcb --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation7.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test array_diff_uassoc() function : usage variation - Comparing strings containing integers and float +--FILE-- + $key2 ? 1 : -1; +} +function main() +{ + echo "*** Testing array_diff_uassoc() : usage variation ***\n"; + //Initialize variables + $arr_string_int = array('1', '2'); + $arr_string_float = array('0' => '1.00', '1.00' => '2.00'); + echo "\n-- Result of comparing strings containing integers and strings containing floating points --\n"; + var_dump(array_diff_uassoc($arr_string_int, $arr_string_float, "key_compare_func")); + var_dump(array_diff_uassoc($arr_string_float, $arr_string_int, "key_compare_func")); +} +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +-- Result of comparing strings containing integers and strings containing floating points -- +array(2) { + [0]=> + string(1) "1" + [1]=> + string(1) "2" +} +array(2) { + [0]=> + string(4) "1.00" + ["1.00"]=> + string(4) "2.00" +} diff --git a/tests/std/array/array_diff_uassoc_variation8.phpt b/tests/std/array/array_diff_uassoc_variation8.phpt new file mode 100644 index 00000000..1746f112 --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation8.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test array_diff_uassoc() function : usage variation - Comparing integers with strings containing integers and float +--FILE-- + $key2 ? 1 : -1; +} +function main() +{ + echo "*** Testing array_diff_uassoc() : usage variation ***\n"; + //Initialize variables + $arr_default_int = array(1, 2, 3); + $arr_string_int = array('1', '2'); + $arr_string_float = array('0' => '1.00', '1.00' => '2.00'); + echo "\n-- Result of comparing integers and strings containing an integers --\n"; + var_dump(array_diff_uassoc($arr_default_int, $arr_string_int, "key_compare_func")); + var_dump(array_diff_uassoc($arr_string_int, $arr_default_int, "key_compare_func")); + echo "\n-- Result of comparing integers and strings containing floating points --\n"; + var_dump(array_diff_uassoc($arr_default_int, $arr_string_float, "key_compare_func")); + var_dump(array_diff_uassoc($arr_string_float, $arr_default_int, "key_compare_func")); +} +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +-- Result of comparing integers and strings containing an integers -- +array(1) { + [2]=> + int(3) +} +array(0) { +} + +-- Result of comparing integers and strings containing floating points -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + [0]=> + string(4) "1.00" + ["1.00"]=> + string(4) "2.00" +} diff --git a/tests/std/array/array_diff_uassoc_variation9.phpt b/tests/std/array/array_diff_uassoc_variation9.phpt new file mode 100644 index 00000000..a8033ba3 --- /dev/null +++ b/tests/std/array/array_diff_uassoc_variation9.phpt @@ -0,0 +1,54 @@ +--TEST-- +Test array_diff_uassoc() function : usage variation - Passing integer indexed array +--FILE-- + 10, 12 => 12); + +$input_arrays = array( + 'decimal indexed' => array(10 => 10, -17 => -17), + 'octal indexed' => array( 012 => 10, -011 => -011,), + 'hexa indexed' => array(0xA => 10, -0x7 => -0x7 ), +); + +foreach($input_arrays as $key =>$value) { + echo "\n--$key--\n"; + var_dump( array_diff_uassoc($input_array, $value, "strcasecmp") ); + var_dump( array_diff_uassoc($value, $input_array, "strcasecmp") ); +} + +?> +--EXPECT-- +*** Testing array_diff_uassoc() : usage variation *** + +--decimal indexed-- +array(1) { + [12]=> + int(12) +} +array(1) { + [-17]=> + int(-17) +} + +--octal indexed-- +array(1) { + [12]=> + int(12) +} +array(1) { + [-9]=> + int(-9) +} + +--hexa indexed-- +array(1) { + [12]=> + int(12) +} +array(1) { + [-7]=> + int(-7) +} diff --git a/tests/std/array/array_diff_ukey_basic.phpt b/tests/std/array/array_diff_ukey_basic.phpt new file mode 100644 index 00000000..3a925120 --- /dev/null +++ b/tests/std/array/array_diff_ukey_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +array_diff_ukey() : Basic test. +--FILE-- + $key2) { + return 1; + } else { + return -1; + } +} +function main() +{ + $array1 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4); + $array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + var_dump(array_diff_ukey($array1, $array2, 'key_compare_func')); +} +?> +--EXPECT-- +array(2) { + ["red"]=> + int(2) + ["purple"]=> + int(4) +} diff --git a/tests/std/array/array_diff_ukey_variation1.phpt b/tests/std/array/array_diff_ukey_variation1.phpt new file mode 100644 index 00000000..1ac2b870 --- /dev/null +++ b/tests/std/array/array_diff_ukey_variation1.phpt @@ -0,0 +1,203 @@ +--TEST-- +Test array_diff_ukey() function : usage variation - Passing unexpected values to first argument +--SKIPIF-- + + +--FILE-- + $key2 ? 1 : -1; +} +// define some classes +class classWithToString +{ + public function __toString(): string { + return "Class A object"; + } +} +class classWithoutToString +{ +} +function main() +{ + echo "*** Testing array_diff_ukey() : usage variation ***\n"; + // Initialise function arguments not being substituted (if any) + $array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + $array3 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource' => $fp, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_diff_ukey($value, $array2, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_diff_ukey($value, $array2, $array3, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_diff_ukey() : usage variation *** + +--int 0-- +array_diff_ukey(): Argument #1 ($array) must be of type array, int given +array_diff_ukey(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_diff_ukey(): Argument #1 ($array) must be of type array, int given +array_diff_ukey(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_diff_ukey(): Argument #1 ($array) must be of type array, int given +array_diff_ukey(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_diff_ukey(): Argument #1 ($array) must be of type array, int given +array_diff_ukey(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_diff_ukey(): Argument #1 ($array) must be of type array, float given +array_diff_ukey(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_diff_ukey(): Argument #1 ($array) must be of type array, float given +array_diff_ukey(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_diff_ukey(): Argument #1 ($array) must be of type array, float given +array_diff_ukey(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_diff_ukey(): Argument #1 ($array) must be of type array, float given +array_diff_ukey(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_diff_ukey(): Argument #1 ($array) must be of type array, float given +array_diff_ukey(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_diff_ukey(): Argument #1 ($array) must be of type array, null given +array_diff_ukey(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_diff_ukey(): Argument #1 ($array) must be of type array, null given +array_diff_ukey(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_diff_ukey(): Argument #1 ($array) must be of type array, true given +array_diff_ukey(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_diff_ukey(): Argument #1 ($array) must be of type array, false given +array_diff_ukey(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_diff_ukey(): Argument #1 ($array) must be of type array, true given +array_diff_ukey(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_diff_ukey(): Argument #1 ($array) must be of type array, false given +array_diff_ukey(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_diff_ukey(): Argument #1 ($array) must be of type array, string given +array_diff_ukey(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_diff_ukey(): Argument #1 ($array) must be of type array, string given +array_diff_ukey(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_diff_ukey(): Argument #1 ($array) must be of type array, string given +array_diff_ukey(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_diff_ukey(): Argument #1 ($array) must be of type array, string given +array_diff_ukey(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_diff_ukey(): Argument #1 ($array) must be of type array, string given +array_diff_ukey(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_diff_ukey(): Argument #1 ($array) must be of type array, string given +array_diff_ukey(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_diff_ukey(): Argument #1 ($array) must be of type array, classWithToString given +array_diff_ukey(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_diff_ukey(): Argument #1 ($array) must be of type array, classWithoutToString given +array_diff_ukey(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_diff_ukey(): Argument #1 ($array) must be of type array, null given +array_diff_ukey(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_diff_ukey(): Argument #1 ($array) must be of type array, null given +array_diff_ukey(): Argument #1 ($array) must be of type array, null given + +--resource-- +array_diff_ukey(): Argument #1 ($array) must be of type array, resource given +array_diff_ukey(): Argument #1 ($array) must be of type array, resource given diff --git a/tests/std/array/array_diff_ukey_variation10.phpt b/tests/std/array/array_diff_ukey_variation10.phpt new file mode 100644 index 00000000..b8dfb738 --- /dev/null +++ b/tests/std/array/array_diff_ukey_variation10.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_diff_ukey() function : usage variation - Passing non-existing function name to callback +--FILE-- + "green", "b" => "brown", "c" => "blue", "red"); +$array2 = array("a" => "green", "yellow", "red"); + +//function name within double quotes +try { + var_dump( array_diff_ukey($array1, $array1, "unknown_function") ); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +//function name within single quotes +try { + var_dump( array_diff_ukey($array1, $array1, 'unknown_function') ); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +*** Testing array_diff_ukey() : usage variation *** +array_diff_ukey(): Argument #3 must be a valid callback, function "unknown_function" not found or invalid function name +array_diff_ukey(): Argument #3 must be a valid callback, function "unknown_function" not found or invalid function name diff --git a/tests/std/array/array_diff_ukey_variation2.phpt b/tests/std/array/array_diff_ukey_variation2.phpt new file mode 100644 index 00000000..0955b566 --- /dev/null +++ b/tests/std/array/array_diff_ukey_variation2.phpt @@ -0,0 +1,204 @@ +--TEST-- +Test array_diff_ukey() function : usage variation - Passing unexpected values to second argument +--SKIPIF-- + + +--FILE-- + $key2 ? 1 : -1; +} +// define some classes +class classWithToString +{ + public function __toString(): string { + return "Class A object"; + } +} +class classWithoutToString +{ +} +function main() +{ + echo "*** Testing array_diff_ukey() : usage variation ***\n"; + // Initialize function arguments not being substituted (if any) + $array1 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + $array3 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource' => $fp, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_diff_ukey($array1, $value, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_diff_ukey($array1, $value, $array3, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_diff_ukey() : usage variation *** + +--int 0-- +array_diff_ukey(): Argument #2 must be of type array, int given +array_diff_ukey(): Argument #2 must be of type array, int given + +--int 1-- +array_diff_ukey(): Argument #2 must be of type array, int given +array_diff_ukey(): Argument #2 must be of type array, int given + +--int 12345-- +array_diff_ukey(): Argument #2 must be of type array, int given +array_diff_ukey(): Argument #2 must be of type array, int given + +--int -12345-- +array_diff_ukey(): Argument #2 must be of type array, int given +array_diff_ukey(): Argument #2 must be of type array, int given + +--float 10.5-- +array_diff_ukey(): Argument #2 must be of type array, float given +array_diff_ukey(): Argument #2 must be of type array, float given + +--float -10.5-- +array_diff_ukey(): Argument #2 must be of type array, float given +array_diff_ukey(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_diff_ukey(): Argument #2 must be of type array, float given +array_diff_ukey(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_diff_ukey(): Argument #2 must be of type array, float given +array_diff_ukey(): Argument #2 must be of type array, float given + +--float .5-- +array_diff_ukey(): Argument #2 must be of type array, float given +array_diff_ukey(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_diff_ukey(): Argument #2 must be of type array, null given +array_diff_ukey(): Argument #2 must be of type array, null given + +--lowercase null-- +array_diff_ukey(): Argument #2 must be of type array, null given +array_diff_ukey(): Argument #2 must be of type array, null given + +--lowercase true-- +array_diff_ukey(): Argument #2 must be of type array, true given +array_diff_ukey(): Argument #2 must be of type array, true given + +--lowercase false-- +array_diff_ukey(): Argument #2 must be of type array, false given +array_diff_ukey(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_diff_ukey(): Argument #2 must be of type array, true given +array_diff_ukey(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_diff_ukey(): Argument #2 must be of type array, false given +array_diff_ukey(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_diff_ukey(): Argument #2 must be of type array, string given +array_diff_ukey(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_diff_ukey(): Argument #2 must be of type array, string given +array_diff_ukey(): Argument #2 must be of type array, string given + +--string DQ-- +array_diff_ukey(): Argument #2 must be of type array, string given +array_diff_ukey(): Argument #2 must be of type array, string given + +--string SQ-- +array_diff_ukey(): Argument #2 must be of type array, string given +array_diff_ukey(): Argument #2 must be of type array, string given + +--mixed case string-- +array_diff_ukey(): Argument #2 must be of type array, string given +array_diff_ukey(): Argument #2 must be of type array, string given + +--heredoc-- +array_diff_ukey(): Argument #2 must be of type array, string given +array_diff_ukey(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_diff_ukey(): Argument #2 must be of type array, classWithToString given +array_diff_ukey(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_diff_ukey(): Argument #2 must be of type array, classWithoutToString given +array_diff_ukey(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_diff_ukey(): Argument #2 must be of type array, null given +array_diff_ukey(): Argument #2 must be of type array, null given + +--unset var-- +array_diff_ukey(): Argument #2 must be of type array, null given +array_diff_ukey(): Argument #2 must be of type array, null given + +--resource-- +array_diff_ukey(): Argument #2 must be of type array, resource given +array_diff_ukey(): Argument #2 must be of type array, resource given diff --git a/tests/std/array/array_diff_ukey_variation5.phpt b/tests/std/array/array_diff_ukey_variation5.phpt new file mode 100644 index 00000000..c41147d8 --- /dev/null +++ b/tests/std/array/array_diff_ukey_variation5.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test array_diff_ukey() function : usage variation - Passing multi-dimensional array +--FILE-- + array('blue' => 1, 'red' => 2), + + 'second' => array('yellow' => 7), + + 'third' => array(0 => 'zero'), +); + +$array2 = array ( + + 'first' => array('blue' => 1, 'red' => 2,), + + 'second' => array('cyan' => 8), + + 'fourth' => array(2 => 'two'), +); + +echo "\n-- Testing array_diff_ukey() function with multi dimensional array --\n"; +var_dump( array_diff_ukey($array1, $array2, 'strcasecmp') ); +var_dump( array_diff_ukey($array2, $array1, 'strcasecmp') ); +?> +--EXPECT-- +*** Testing array_diff_ukey() : usage variation *** + +-- Testing array_diff_ukey() function with multi dimensional array -- +array(1) { + ["third"]=> + array(1) { + [0]=> + string(4) "zero" + } +} +array(1) { + ["fourth"]=> + array(1) { + [2]=> + string(3) "two" + } +} diff --git a/tests/std/array/array_diff_ukey_variation6.phpt b/tests/std/array/array_diff_ukey_variation6.phpt new file mode 100644 index 00000000..fdc6dd65 --- /dev/null +++ b/tests/std/array/array_diff_ukey_variation6.phpt @@ -0,0 +1,53 @@ +--TEST-- +Test array_diff_ukey() function : usage variation - Passing integer indexed array +--FILE-- + '-07', 0xa => '0xA'); + $input_arrays = array('decimal indexed' => array(10 => '10', '-17' => '-17'), 'octal indexed' => array(-011 => '-011', 012 => '012'), 'hexa indexed' => array(0x12 => '0x12', -0x7 => '-0x7')); + foreach ($input_arrays as $key => $value) { + echo "\n--{$key}--\n"; + var_dump(array_diff_ukey($value, $input_array, 'key_compare_func')); + var_dump(array_diff_ukey($input_array, $value, 'key_compare_func')); + } +} +?> +--EXPECT-- +*** Testing array_diff_ukey() : usage variation *** + +--decimal indexed-- +array(1) { + [-17]=> + string(3) "-17" +} +array(1) { + [-7]=> + string(3) "-07" +} + +--octal indexed-- +array(1) { + [-9]=> + string(4) "-011" +} +array(1) { + [-7]=> + string(3) "-07" +} + +--hexa indexed-- +array(1) { + [18]=> + string(4) "0x12" +} +array(1) { + [10]=> + string(3) "0xA" +} diff --git a/tests/std/array/array_diff_ukey_variation8.phpt b/tests/std/array/array_diff_ukey_variation8.phpt new file mode 100644 index 00000000..24298a66 --- /dev/null +++ b/tests/std/array/array_diff_ukey_variation8.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test array_diff_ukey() function : usage variation - Passing boolean indexed array +--SKIPIF-- +--FILE-- + '0', 1 => '1', -10 => '-10', 'true' => 1, 'false' => 0); + $boolean_indx_array = array(true => 'boolt', false => 'boolf', TRUE => 'boolT', FALSE => 'boolF'); + echo "\n-- Testing array_diff_ukey() function with boolean indexed array --\n"; + var_dump(array_diff_ukey($boolean_indx_array, $input_array, 'key_compare_func')); + var_dump(array_diff_ukey($input_array, $boolean_indx_array, 'key_compare_func')); +} +?> +--EXPECT-- +*** Testing array_diff_ukey() : usage variation *** + +-- Testing array_diff_ukey() function with boolean indexed array -- +array(0) { +} +array(3) { + [-10]=> + string(3) "-10" + ["true"]=> + int(1) + ["false"]=> + int(0) +} diff --git a/tests/std/array/array_diff_ukey_variation9.phpt b/tests/std/array/array_diff_ukey_variation9.phpt new file mode 100644 index 00000000..f2ca3a66 --- /dev/null +++ b/tests/std/array/array_diff_ukey_variation9.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test array_diff_ukey() function : usage variation - Passing null,unset and undefined variable indexed array +--SKIPIF-- + + +--FILE-- + '10', "" => 'empty'); + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +$input_arrays = array( + 'null indexed' => array(NULL => 'null 1', null => 'null 2'), + 'undefined indexed' => array(@$undefined_var => 'undefined'), + 'unset indexed' => array(@$unset_var => 'unset'), +); + +foreach($input_arrays as $key =>$value) { + echo "\n--$key--\n"; + var_dump( array_diff_ukey($value, $input_array, 'strcasecmp') ); + var_dump( array_diff_ukey($input_array, $value, 'strcasecmp') ); +} + +?> +--EXPECT-- +*** Testing array_diff_ukey() : usage variation *** + +--null indexed-- +array(0) { +} +array(1) { + [10]=> + string(2) "10" +} + +--undefined indexed-- +array(0) { +} +array(1) { + [10]=> + string(2) "10" +} + +--unset indexed-- +array(0) { +} +array(1) { + [10]=> + string(2) "10" +} diff --git a/tests/std/array/array_diff_variation1.phpt b/tests/std/array/array_diff_variation1.phpt new file mode 100644 index 00000000..e9cbad88 --- /dev/null +++ b/tests/std/array/array_diff_variation1.phpt @@ -0,0 +1,153 @@ +--TEST-- +Test array_diff() function : usage variations - unexpected values for 'array1' argument +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; + } + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_diff() : usage variations *** + +-- Iteration 1 --array_diff(): Argument #1 ($array) must be of type array, int given + +-- Iteration 2 --array_diff(): Argument #1 ($array) must be of type array, int given + +-- Iteration 3 --array_diff(): Argument #1 ($array) must be of type array, int given + +-- Iteration 4 --array_diff(): Argument #1 ($array) must be of type array, int given + +-- Iteration 5 --array_diff(): Argument #1 ($array) must be of type array, float given + +-- Iteration 6 --array_diff(): Argument #1 ($array) must be of type array, float given + +-- Iteration 7 --array_diff(): Argument #1 ($array) must be of type array, float given + +-- Iteration 8 --array_diff(): Argument #1 ($array) must be of type array, float given + +-- Iteration 9 --array_diff(): Argument #1 ($array) must be of type array, float given + +-- Iteration 10 --array_diff(): Argument #1 ($array) must be of type array, null given + +-- Iteration 11 --array_diff(): Argument #1 ($array) must be of type array, null given + +-- Iteration 12 --array_diff(): Argument #1 ($array) must be of type array, true given + +-- Iteration 13 --array_diff(): Argument #1 ($array) must be of type array, false given + +-- Iteration 14 --array_diff(): Argument #1 ($array) must be of type array, true given + +-- Iteration 15 --array_diff(): Argument #1 ($array) must be of type array, false given + +-- Iteration 16 --array_diff(): Argument #1 ($array) must be of type array, string given + +-- Iteration 17 --array_diff(): Argument #1 ($array) must be of type array, string given + +-- Iteration 18 --array_diff(): Argument #1 ($array) must be of type array, string given + +-- Iteration 19 --array_diff(): Argument #1 ($array) must be of type array, string given + +-- Iteration 20 --array_diff(): Argument #1 ($array) must be of type array, string given + +-- Iteration 21 --array_diff(): Argument #1 ($array) must be of type array, string given + +-- Iteration 22 --array_diff(): Argument #1 ($array) must be of type array, string given + +-- Iteration 23 --array_diff(): Argument #1 ($array) must be of type array, classA given + +-- Iteration 24 --array_diff(): Argument #1 ($array) must be of type array, null given + +-- Iteration 25 --array_diff(): Argument #1 ($array) must be of type array, null given + +-- Iteration 26 --array_diff(): Argument #1 ($array) must be of type array, resource given +Done diff --git a/tests/std/array/array_diff_variation10.phpt b/tests/std/array/array_diff_variation10.phpt new file mode 100644 index 00000000..01e849f2 --- /dev/null +++ b/tests/std/array/array_diff_variation10.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test array_diff() function : usage variations - binary safe checking +--FILE-- + "hello", + "str2" => "world"); + +$array2 = array( b"1" => 'hello', + b"world", + "hello", + 'test'); + +var_dump(array_diff($array1, $array2)); +var_dump(array_diff($array2, $array1)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff() : usage variations *** +array(1) { + [0]=> + string(1) "1" +} +array(1) { + [4]=> + string(4) "test" +} +Done diff --git a/tests/std/array/array_diff_variation2.phpt b/tests/std/array/array_diff_variation2.phpt new file mode 100644 index 00000000..bdc41144 --- /dev/null +++ b/tests/std/array/array_diff_variation2.phpt @@ -0,0 +1,153 @@ +--TEST-- +Test array_diff() function : usage variations - unexpected values for 'array2' argument +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; + } + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_diff() : usage variations *** + +-- Iteration 1 --array_diff(): Argument #2 must be of type array, int given + +-- Iteration 2 --array_diff(): Argument #2 must be of type array, int given + +-- Iteration 3 --array_diff(): Argument #2 must be of type array, int given + +-- Iteration 4 --array_diff(): Argument #2 must be of type array, int given + +-- Iteration 5 --array_diff(): Argument #2 must be of type array, float given + +-- Iteration 6 --array_diff(): Argument #2 must be of type array, float given + +-- Iteration 7 --array_diff(): Argument #2 must be of type array, float given + +-- Iteration 8 --array_diff(): Argument #2 must be of type array, float given + +-- Iteration 9 --array_diff(): Argument #2 must be of type array, float given + +-- Iteration 10 --array_diff(): Argument #2 must be of type array, null given + +-- Iteration 11 --array_diff(): Argument #2 must be of type array, null given + +-- Iteration 12 --array_diff(): Argument #2 must be of type array, true given + +-- Iteration 13 --array_diff(): Argument #2 must be of type array, false given + +-- Iteration 14 --array_diff(): Argument #2 must be of type array, true given + +-- Iteration 15 --array_diff(): Argument #2 must be of type array, false given + +-- Iteration 16 --array_diff(): Argument #2 must be of type array, string given + +-- Iteration 17 --array_diff(): Argument #2 must be of type array, string given + +-- Iteration 18 --array_diff(): Argument #2 must be of type array, string given + +-- Iteration 19 --array_diff(): Argument #2 must be of type array, string given + +-- Iteration 20 --array_diff(): Argument #2 must be of type array, string given + +-- Iteration 21 --array_diff(): Argument #2 must be of type array, string given + +-- Iteration 22 --array_diff(): Argument #2 must be of type array, string given + +-- Iteration 23 --array_diff(): Argument #2 must be of type array, classA given + +-- Iteration 24 --array_diff(): Argument #2 must be of type array, null given + +-- Iteration 25 --array_diff(): Argument #2 must be of type array, null given + +-- Iteration 26 --array_diff(): Argument #2 must be of type array, resource given +Done diff --git a/tests/std/array/array_diff_variation3.phpt b/tests/std/array/array_diff_variation3.phpt new file mode 100644 index 00000000..557b9166 --- /dev/null +++ b/tests/std/array/array_diff_variation3.phpt @@ -0,0 +1,189 @@ +--TEST-- +Test array_diff() function : usage variations - array with different data types as values +--SKIPIF-- + + +--FILE-- + array(), + +/*2*/ +"int" => array( + // int data + 0, + 1, + 12345, + -2345), + +/*3*/ +"float" => array( + // float data + 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5), + +/*4*/ +"null" => array( + // null data + NULL, + null), + +/*5*/ +"boolean" => array( + // boolean data + true, + false, + TRUE, + FALSE), + +/*6*/ +"empty" => array( + // empty data + "", + ''), + +/*7*/ +"string" => array( + // string data + "string", + 'string', + $heredoc), + +/*8*/ +"binary" => array( + // binary data + b"binary", + (binary)"binary"), + +/*9*/ +"undefined" => array( + // undefined data + @$undefined_var), + +/*10*/ +"unset" => array( + // unset data + @$unset_var) +); + +// loop through each element of the array for arr1 +$iterator = 1; +foreach($values as $value) { + echo "\n Iteration: $iterator \n"; + var_dump( array_diff($value, $array) ); + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff() : usage variations *** + + Iteration: 1 +array(0) { +} + + Iteration: 2 +array(3) { + [0]=> + int(0) + [2]=> + int(12345) + [3]=> + int(-2345) +} + + Iteration: 3 +array(5) { + [0]=> + float(10.5) + [1]=> + float(-10.5) + [2]=> + float(123456789000) + [3]=> + float(1.23456789E-9) + [4]=> + float(0.5) +} + + Iteration: 4 +array(2) { + [0]=> + NULL + [1]=> + NULL +} + + Iteration: 5 +array(2) { + [1]=> + bool(false) + [3]=> + bool(false) +} + + Iteration: 6 +array(2) { + [0]=> + string(0) "" + [1]=> + string(0) "" +} + + Iteration: 7 +array(3) { + [0]=> + string(6) "string" + [1]=> + string(6) "string" + [2]=> + string(17) "This is a heredoc" +} + + Iteration: 8 +array(2) { + [0]=> + string(6) "binary" + [1]=> + string(6) "binary" +} + + Iteration: 9 +array(1) { + [0]=> + NULL +} + + Iteration: 10 +array(1) { + [0]=> + NULL +} +Done diff --git a/tests/std/array/array_diff_variation4.phpt b/tests/std/array/array_diff_variation4.phpt new file mode 100644 index 00000000..3ba95d96 --- /dev/null +++ b/tests/std/array/array_diff_variation4.phpt @@ -0,0 +1,183 @@ +--TEST-- +Test array_diff() function : usage variations - array with different data types as values +--SKIPIF-- + + +--FILE-- + array(), + +/*2*/ +"int" => array( + // int data + 0, + 1, + 12345, + -2345), + +/*3*/ +"float" => array( + // float data + 10.5, + -10.5, + 12.3456789000e10, + 12.3456789000E-10, + .5), + +/*4*/ +"null" => array( + // null data + NULL, + null), + +/*5*/ +"boolean" => array( + // boolean data + true, + false, + TRUE, + FALSE), + +/*6*/ +"empty" => array( + // empty data + "", + ''), + +/*7*/ +"string" => array( + // string data + "string", + 'string', + $heredoc), + +/*8*/ +"binary" => array( + // binary data + b"binary", + (binary)"binary"), + +/*9*/ +"undefined" => array( + // undefined data + @$undefined_var), + +/*10*/ +"unset" => array( + // unset data + @$unset_var) +); + +// loop through each element of the array for $arr2 +$iterator = 1; +foreach($values as $value) { + echo "\n Iteration: $iterator \n"; + var_dump( array_diff($array, $value) ); + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff() : usage variations *** + + Iteration: 1 +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + + Iteration: 2 +array(1) { + [1]=> + int(2) +} + + Iteration: 3 +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + + Iteration: 4 +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + + Iteration: 5 +array(1) { + [1]=> + int(2) +} + + Iteration: 6 +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + + Iteration: 7 +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + + Iteration: 8 +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + + Iteration: 9 +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + + Iteration: 10 +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +Done diff --git a/tests/std/array/array_diff_variation5.phpt b/tests/std/array/array_diff_variation5.phpt new file mode 100644 index 00000000..9c9369de --- /dev/null +++ b/tests/std/array/array_diff_variation5.phpt @@ -0,0 +1,113 @@ +--TEST-- +Test array_diff() function : usage variations - comparing integers, float +and string array values +--FILE-- + +--EXPECT-- +*** Testing array_diff() : usage variations *** +-- Compare integers and floats: -- +array(0) { +} +array(0) { +} +-- Compare integers and strings containing an integers: -- +array(0) { +} +array(0) { +} +-- Compare integers and strings containing floats: -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(3) { + [0]=> + string(4) "1.00" + [1]=> + string(4) "2.00" + [2]=> + string(4) "3.00" +} +-- Compare floats and strings containing integers: -- +array(0) { +} +array(0) { +} +-- Compare floats and strings containing floats: -- +array(3) { + [0]=> + float(1) + [1]=> + float(2) + [2]=> + float(3) +} +array(3) { + [0]=> + string(4) "1.00" + [1]=> + string(4) "2.00" + [2]=> + string(4) "3.00" +} +-- Compare strings containing integers and strings containing floats: -- +array(3) { + [0]=> + string(1) "1" + [1]=> + string(1) "2" + [2]=> + string(1) "3" +} +array(3) { + [0]=> + string(4) "1.00" + [1]=> + string(4) "2.00" + [2]=> + string(4) "3.00" +} +Done diff --git a/tests/std/array/array_diff_variation6.phpt b/tests/std/array/array_diff_variation6.phpt new file mode 100644 index 00000000..15cedc6c --- /dev/null +++ b/tests/std/array/array_diff_variation6.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test array_diff() function : usage variations - array containing duplicate keys and values +--FILE-- + 'd', 'b'); //duplicate key (0), duplicate value (b) +$array_assoc = array ('2' => 'c', //same key=>value pair, different order + '1' => 'b', + '0' => 'a', + 'b' => '3', //key and value from array_index swapped + 'c' => 2); //same as above, using integer + +var_dump(array_diff($array_index, $array_assoc)); +var_dump(array_diff($array_assoc, $array_index)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_diff() : usage variations *** +array(1) { + [0]=> + string(1) "d" +} +array(3) { + [0]=> + string(1) "a" + ["b"]=> + string(1) "3" + ["c"]=> + int(2) +} +Done diff --git a/tests/std/array/array_diff_variation7.phpt b/tests/std/array/array_diff_variation7.phpt new file mode 100644 index 00000000..75374f1c --- /dev/null +++ b/tests/std/array/array_diff_variation7.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test array_diff() function : usage variations - arrays containing referenced variables +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +*** Testing array_diff() : usage variations *** +-- Basic Comparison -- +array(3) { + [0]=> + string(2) "&a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +-- $a changed -- +array(3) { + [0]=> + string(2) "&a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +-- Arrays referenced to each other -- +array(0) { +} +array(0) { +} +-- $arr1 changed -- +array(0) { +} +array(0) { +} +Done diff --git a/tests/std/array/array_diff_variation8.phpt b/tests/std/array/array_diff_variation8.phpt new file mode 100644 index 00000000..0035f580 --- /dev/null +++ b/tests/std/array/array_diff_variation8.phpt @@ -0,0 +1,198 @@ +--TEST-- +Test array_diff() function : usage variations - associative arrays containing different data types +--SKIPIF-- + +--FILE-- + '1', 'b' => '2', 'c' => '3'); + // get an unset variable + $unset_var = 10; + unset($unset_var); + // get a resource variable + $fp = fopen(__FILE__, "r"); + // get a heredoc string + $heredoc = << 0, '1' => 0), + array("one" => 1, 'two' => 2, "three" => 1, 4 => 1), + // arrays with float values + /*3*/ + array("float1" => 2.3333, "float2" => 2.3333), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => 1.2), + // arrays with string values + /*5*/ + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "\tHello"), + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => '\tHello'), + array(1 => "hello", "heredoc" => $heredoc, $heredoc), + // array with object, unset variable and resource variable + /*8*/ + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp, new classA(), $fp), + ); + // loop through each sub-array of $inputs to check the behavior of array_unique() + $iterator = 1; + foreach ($inputs as $input) { + echo "-- Iteration {$iterator} --\n"; + var_dump(array_diff($array, $input)); + var_dump(array_diff($input, $array)); + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_diff() : usage variations *** +-- Iteration 1 -- +array(3) { + ["a"]=> + string(1) "1" + ["b"]=> + string(1) "2" + ["c"]=> + string(1) "3" +} +array(2) { + [0]=> + int(0) + [1]=> + int(0) +} +-- Iteration 2 -- +array(1) { + ["c"]=> + string(1) "3" +} +array(0) { +} +-- Iteration 3 -- +array(3) { + ["a"]=> + string(1) "1" + ["b"]=> + string(1) "2" + ["c"]=> + string(1) "3" +} +array(2) { + ["float1"]=> + float(2.3333) + ["float2"]=> + float(2.3333) +} +-- Iteration 4 -- +array(3) { + ["a"]=> + string(1) "1" + ["b"]=> + string(1) "2" + ["c"]=> + string(1) "3" +} +array(4) { + ["f1"]=> + float(1.2) + ["f2"]=> + float(3.33) + [3]=> + float(4.89999922839999) + ["f4"]=> + float(1.2) +} +-- Iteration 5 -- +array(3) { + ["a"]=> + string(1) "1" + ["b"]=> + string(1) "2" + ["c"]=> + string(1) "3" +} +array(4) { + [111]=> + string(6) " Hello" + ["red"]=> + string(6) "col or" + [2]=> + string(7) " world" + [3]=> + string(6) " Hello" +} +-- Iteration 6 -- +array(3) { + ["a"]=> + string(1) "1" + ["b"]=> + string(1) "2" + ["c"]=> + string(1) "3" +} +array(4) { + [111]=> + string(7) "\tHello" + ["red"]=> + string(7) "col\tor" + [2]=> + string(9) "\v\fworld" + [3]=> + string(7) "\tHello" +} +-- Iteration 7 -- +array(3) { + ["a"]=> + string(1) "1" + ["b"]=> + string(1) "2" + ["c"]=> + string(1) "3" +} +array(3) { + [1]=> + string(5) "hello" + ["heredoc"]=> + string(11) "Hello world" + [2]=> + string(11) "Hello world" +} +-- Iteration 8 -- +array(3) { + ["a"]=> + string(1) "1" + ["b"]=> + string(1) "2" + ["c"]=> + string(1) "3" +} +array(5) { + [11]=> + object(classA)#%d (0) { + } + ["unset"]=> + NULL + ["resource"]=> + resource(%d) of type (stream) + [12]=> + object(classA)#%d (0) { + } + [13]=> + resource(%d) of type (stream) +} +Done diff --git a/tests/std/array/array_diff_variation9.phpt b/tests/std/array/array_diff_variation9.phpt new file mode 100644 index 00000000..3a956e99 --- /dev/null +++ b/tests/std/array/array_diff_variation9.phpt @@ -0,0 +1,118 @@ +--TEST-- +Test array_diff() function : usage variations - multidimensional arrays +--FILE-- + array (1, 2, 3), + 'sub_array2' => array ('a', 'b', 'c')); +$array2 = array('sub_arraya' => array (1, 3, 5), + 'sub_arrayb' => array ('a', 'z', 'y')); + +echo "-- Compare two 2-D arrays --\n"; +var_dump(array_diff($array1, $array2)); +var_dump(array_diff($array2, $array1)); + +echo "\n-- Compare subarrays from two 2-D arrays --\n"; +var_dump(array_diff($array1['sub_array1'], $array2['sub_arraya'])); +var_dump(array_diff($array2['sub_arraya'], $array1['sub_array1'])); + +var_dump(array_diff($array1['sub_array2'], $array2['sub_arrayb'])); +var_dump(array_diff($array2['sub_arrayb'], $array1['sub_array1'])); + +echo "\n-- Compare a subarray from one 2-D array and one 2-D array --\n"; +var_dump(array_diff($array1['sub_array1'], $array2)); +var_dump(array_diff($array1, $array2['sub_arraya'])); + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_diff() : usage variations *** +-- Compare two 2-D arrays -- + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d +array(0) { +} + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d +array(0) { +} + +-- Compare subarrays from two 2-D arrays -- +array(1) { + [1]=> + int(2) +} +array(1) { + [2]=> + int(5) +} +array(2) { + [1]=> + string(1) "b" + [2]=> + string(1) "c" +} +array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "z" + [2]=> + string(1) "y" +} + +-- Compare a subarray from one 2-D array and one 2-D array -- + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d +array(2) { + ["sub_array1"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + ["sub_array2"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +Done diff --git a/tests/std/array/array_fill.phpt b/tests/std/array/array_fill.phpt new file mode 100644 index 00000000..cfc2126d --- /dev/null +++ b/tests/std/array/array_fill.phpt @@ -0,0 +1,345 @@ +--TEST-- +basic array_fill test +--FILE-- + +--EXPECT-- +=========================== +bool(true) +start: 0 num: 0 value: array(0) { +} +=========================== +bool(false) +start: 0 num: 0 value: array(0) { +} +=========================== +NULL +start: 0 num: 0 value: array(0) { +} +=========================== +string(1) "d" +start: 0 num: 0 value: array(0) { +} +=========================== +string(1) "e" +start: 0 num: 0 value: array(0) { +} +=========================== +string(1) "f" +start: 0 num: 0 value: array(0) { +} +=========================== +bool(true) +start: 0 num: 1 value: array(1) { + [0]=> + bool(true) +} +=========================== +bool(false) +start: 0 num: 1 value: array(1) { + [0]=> + bool(false) +} +=========================== +NULL +start: 0 num: 1 value: array(1) { + [0]=> + NULL +} +=========================== +string(1) "d" +start: 0 num: 1 value: array(1) { + [0]=> + string(1) "d" +} +=========================== +string(1) "e" +start: 0 num: 1 value: array(1) { + [0]=> + string(1) "e" +} +=========================== +string(1) "f" +start: 0 num: 1 value: array(1) { + [0]=> + string(1) "f" +} +=========================== +bool(true) +start: 0 num: 2 value: array(2) { + [0]=> + bool(true) + [1]=> + bool(true) +} +=========================== +bool(false) +start: 0 num: 2 value: array(2) { + [0]=> + bool(false) + [1]=> + bool(false) +} +=========================== +NULL +start: 0 num: 2 value: array(2) { + [0]=> + NULL + [1]=> + NULL +} +=========================== +string(1) "d" +start: 0 num: 2 value: array(2) { + [0]=> + string(1) "d" + [1]=> + string(1) "d" +} +=========================== +string(1) "e" +start: 0 num: 2 value: array(2) { + [0]=> + string(1) "e" + [1]=> + string(1) "e" +} +=========================== +string(1) "f" +start: 0 num: 2 value: array(2) { + [0]=> + string(1) "f" + [1]=> + string(1) "f" +} +=========================== +bool(true) +start: 1 num: 0 value: array(0) { +} +=========================== +bool(false) +start: 1 num: 0 value: array(0) { +} +=========================== +NULL +start: 1 num: 0 value: array(0) { +} +=========================== +string(1) "d" +start: 1 num: 0 value: array(0) { +} +=========================== +string(1) "e" +start: 1 num: 0 value: array(0) { +} +=========================== +string(1) "f" +start: 1 num: 0 value: array(0) { +} +=========================== +bool(true) +start: 1 num: 1 value: array(1) { + [1]=> + bool(true) +} +=========================== +bool(false) +start: 1 num: 1 value: array(1) { + [1]=> + bool(false) +} +=========================== +NULL +start: 1 num: 1 value: array(1) { + [1]=> + NULL +} +=========================== +string(1) "d" +start: 1 num: 1 value: array(1) { + [1]=> + string(1) "d" +} +=========================== +string(1) "e" +start: 1 num: 1 value: array(1) { + [1]=> + string(1) "e" +} +=========================== +string(1) "f" +start: 1 num: 1 value: array(1) { + [1]=> + string(1) "f" +} +=========================== +bool(true) +start: 1 num: 2 value: array(2) { + [1]=> + bool(true) + [2]=> + bool(true) +} +=========================== +bool(false) +start: 1 num: 2 value: array(2) { + [1]=> + bool(false) + [2]=> + bool(false) +} +=========================== +NULL +start: 1 num: 2 value: array(2) { + [1]=> + NULL + [2]=> + NULL +} +=========================== +string(1) "d" +start: 1 num: 2 value: array(2) { + [1]=> + string(1) "d" + [2]=> + string(1) "d" +} +=========================== +string(1) "e" +start: 1 num: 2 value: array(2) { + [1]=> + string(1) "e" + [2]=> + string(1) "e" +} +=========================== +string(1) "f" +start: 1 num: 2 value: array(2) { + [1]=> + string(1) "f" + [2]=> + string(1) "f" +} +=========================== +bool(true) +start: 2 num: 0 value: array(0) { +} +=========================== +bool(false) +start: 2 num: 0 value: array(0) { +} +=========================== +NULL +start: 2 num: 0 value: array(0) { +} +=========================== +string(1) "d" +start: 2 num: 0 value: array(0) { +} +=========================== +string(1) "e" +start: 2 num: 0 value: array(0) { +} +=========================== +string(1) "f" +start: 2 num: 0 value: array(0) { +} +=========================== +bool(true) +start: 2 num: 1 value: array(1) { + [2]=> + bool(true) +} +=========================== +bool(false) +start: 2 num: 1 value: array(1) { + [2]=> + bool(false) +} +=========================== +NULL +start: 2 num: 1 value: array(1) { + [2]=> + NULL +} +=========================== +string(1) "d" +start: 2 num: 1 value: array(1) { + [2]=> + string(1) "d" +} +=========================== +string(1) "e" +start: 2 num: 1 value: array(1) { + [2]=> + string(1) "e" +} +=========================== +string(1) "f" +start: 2 num: 1 value: array(1) { + [2]=> + string(1) "f" +} +=========================== +bool(true) +start: 2 num: 2 value: array(2) { + [2]=> + bool(true) + [3]=> + bool(true) +} +=========================== +bool(false) +start: 2 num: 2 value: array(2) { + [2]=> + bool(false) + [3]=> + bool(false) +} +=========================== +NULL +start: 2 num: 2 value: array(2) { + [2]=> + NULL + [3]=> + NULL +} +=========================== +string(1) "d" +start: 2 num: 2 value: array(2) { + [2]=> + string(1) "d" + [3]=> + string(1) "d" +} +=========================== +string(1) "e" +start: 2 num: 2 value: array(2) { + [2]=> + string(1) "e" + [3]=> + string(1) "e" +} +=========================== +string(1) "f" +start: 2 num: 2 value: array(2) { + [2]=> + string(1) "f" + [3]=> + string(1) "f" +} diff --git a/tests/std/array/array_fill_basic.phpt b/tests/std/array/array_fill_basic.phpt new file mode 100644 index 00000000..a613f5a2 --- /dev/null +++ b/tests/std/array/array_fill_basic.phpt @@ -0,0 +1,91 @@ +--TEST-- +Test array_fill() function : basic functionality +--FILE-- + +--EXPECT-- +*** Testing array_fill() : basic functionality *** +-- Iteration 1 -- +array(2) { + [0]=> + NULL + [1]=> + NULL +} +-- Iteration 2 -- +array(2) { + [0]=> + int(0) + [1]=> + int(0) +} +-- Iteration 3 -- +array(2) { + [0]=> + int(1) + [1]=> + int(1) +} +-- Iteration 4 -- +array(2) { + [0]=> + float(1.5) + [1]=> + float(1.5) +} +-- Iteration 5 -- +array(2) { + [0]=> + string(2) "hi" + [1]=> + string(2) "hi" +} +-- Iteration 6 -- +array(2) { + [0]=> + string(2) "hi" + [1]=> + string(2) "hi" +} +-- Iteration 7 -- +array(2) { + [0]=> + string(5) "Hello" + [1]=> + string(5) "Hello" +} +Done diff --git a/tests/std/array/array_fill_error.phpt b/tests/std/array/array_fill_error.phpt new file mode 100644 index 00000000..9b04f755 --- /dev/null +++ b/tests/std/array/array_fill_error.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test array_fill() function : error conditions +--FILE-- +getMessage() . "\n"; +} + +?> +--EXPECT-- +*** Testing array_fill() : error conditions *** +array_fill(): Argument #2 ($count) must be greater than or equal to 0 diff --git a/tests/std/array/array_fill_error2.phpt b/tests/std/array/array_fill_error2.phpt new file mode 100644 index 00000000..054a52aa --- /dev/null +++ b/tests/std/array/array_fill_error2.phpt @@ -0,0 +1,20 @@ +--TEST-- +Test array_fill() function : error conditions - count is too large +--SKIPIF-- +--FILE-- +getMessage() . "\n"; +} + +// calling array_fill() with 'count' equals to INT_MAX +$array = array_fill(0, $intMax, 1); + +?> +--EXPECTF-- +%SFatal error: Possible integer overflow in memory allocation (%d * %d + %d) in %s diff --git a/tests/std/array/array_fill_keys.phpt b/tests/std/array/array_fill_keys.phpt new file mode 100644 index 00000000..eebfd0aa --- /dev/null +++ b/tests/std/array/array_fill_keys.phpt @@ -0,0 +1,40 @@ +--TEST-- +basic array_fill_keys test +--INI-- +precision=14 +--FILE-- + +--EXPECT-- +array(0) { +} +array(2) { + ["foo"]=> + NULL + ["bar"]=> + NULL +} +array(4) { + [5]=> + int(123) + ["foo"]=> + int(123) + [10]=> + int(123) + ["1.23"]=> + int(123) +} +array(4) { + ["test"]=> + string(0) "" + [1]=> + string(0) "" + [10]=> + string(0) "" + [100]=> + string(0) "" +} diff --git a/tests/std/array/array_fill_keys_variation1.phpt b/tests/std/array/array_fill_keys_variation1.phpt new file mode 100644 index 00000000..2f210823 --- /dev/null +++ b/tests/std/array/array_fill_keys_variation1.phpt @@ -0,0 +1,73 @@ +--TEST-- +Test array_fill_keys() function : variation of parameter +--SKIPIF-- + +--FILE-- + 2, "strk1" => "strv1", 4, $simpleStr); + var_dump(array_fill_keys($keyedArray, $simpleStr)); + echo "\n-- Testing array_fill_keys() function with mixed array --\n"; + $mixedArray = array($fp, $obj, $simpleStr, $emptyArr, 2, $bool, $float); + var_dump(array_fill_keys($mixedArray, $simpleStr)); + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_fill_keys() : parameter variations *** + +-- Testing array_fill_keys() function with empty arguments -- +array(0) { +} + +-- Testing array_fill_keys() function with keyed array -- +array(4) { + [2]=> + string(6) "simple" + ["strv1"]=> + string(6) "simple" + [4]=> + string(6) "simple" + ["simple"]=> + string(6) "simple" +} + +-- Testing array_fill_keys() function with mixed array -- + +Warning: Array to string conversion in %s on line %d +array(7) { + ["Resource id #%d"]=> + string(6) "simple" + ["Class A object"]=> + string(6) "simple" + ["simple"]=> + string(6) "simple" + ["Array"]=> + string(6) "simple" + [2]=> + string(6) "simple" + [""]=> + string(6) "simple" + ["2.4"]=> + string(6) "simple" +} +Done diff --git a/tests/std/array/array_fill_keys_variation2.phpt b/tests/std/array/array_fill_keys_variation2.phpt new file mode 100644 index 00000000..15d0bfbf --- /dev/null +++ b/tests/std/array/array_fill_keys_variation2.phpt @@ -0,0 +1,72 @@ +--TEST-- +Test array_fill_keys() function : variation of parameter +--FILE-- + +--EXPECT-- +*** Testing array_fill_keys() : parameter variations *** + +-- Testing array_fill_keys() function with reference value -- +array(2) { + ["one"]=> + string(6) "simple" + ["two"]=> + string(6) "simple" +} + +-- Testing array_fill_keys() function with reference keys -- +array(2) { + ["one"]=> + string(6) "simple" + ["simple"]=> + string(6) "simple" +} +array(2) { + ["one"]=> + string(6) "simple" + ["simple"]=> + string(6) "simple" +} + +-- Testing array_fill_keys() function with reference array input -- +array(2) { + ["one"]=> + string(3) "bob" + ["two"]=> + string(3) "bob" +} +Done diff --git a/tests/std/array/array_fill_keys_variation3.phpt b/tests/std/array/array_fill_keys_variation3.phpt new file mode 100644 index 00000000..a800965a --- /dev/null +++ b/tests/std/array/array_fill_keys_variation3.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test array_fill_keys() function : variation of parameter +--FILE-- + +--EXPECTF-- +*** Testing array_fill_keys() : parameter variations *** + +-- Testing array_fill_keys() function with unusual second arguments -- +array(2) { + ["one"]=> + resource(%d) of type (stream) + ["two"]=> + resource(%d) of type (stream) +} +Done diff --git a/tests/std/array/array_fill_keys_variation4.phpt b/tests/std/array/array_fill_keys_variation4.phpt new file mode 100644 index 00000000..995a30c2 --- /dev/null +++ b/tests/std/array/array_fill_keys_variation4.phpt @@ -0,0 +1,82 @@ +--TEST-- +Test array_fill_keys() function : variation of parameter +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing array_fill_keys() : parameter variations *** + +-- Testing array_fill_keys() function with float -- +array(1) { + ["one"]=> + float(2.4) +} + +-- Testing array_fill_keys() function with null -- +array(1) { + ["one"]=> + NULL +} + +-- Testing array_fill_keys() function with object -- +array(1) { + ["one"]=> + object(classA)#%d (0) { + } +} + +-- Testing array_fill_keys() function with boolean -- +array(1) { + ["one"]=> + bool(false) +} + +-- Testing array_fill_keys() function with resource -- +array(1) { + ["one"]=> + resource(%d) of type (stream) +} + +-- Testing array_fill_keys() function with unset var -- + +Warning: Undefined variable $unset_var in %s on line %d +array(1) { + ["one"]=> + NULL +} +Done diff --git a/tests/std/array/array_fill_object.phpt b/tests/std/array/array_fill_object.phpt new file mode 100644 index 00000000..474c17f7 --- /dev/null +++ b/tests/std/array/array_fill_object.phpt @@ -0,0 +1,403 @@ +--TEST-- +Test array_fill() function : usage variations - various object values for 'val' argument +--SKIPIF-- + +--FILE-- +member1 = $value1; + $this->var2 = $value2; + } +} +// child class which inherits parent class test1 +class Child_test1 extends Test1 +{ + public $member2; + function __construct($value1, $value2, $value3) + { + parent::__construct($value1, $value2); + $this->member2 = $value3; + } +} +//class with private member, static member, constant and constructor to initialize the private member +class Test2 +{ + const test2_constant = "test2"; + public static $test2_static = 0; + private $member1; + var $var1 = 30; + var $var2; + function __construct($value1, $value2) + { + $this->member1 = $value1; + $this->var2 = $value2; + } +} +// child class which inherits parent class test2 +class Child_test2 extends Test2 +{ + private $member1; + function __construct($value1, $value2, $value3) + { + parent::__construct($value1, $value2); + $this->member1 = $value3; + } +} +// class with protected member, static member, constant and consturctor to initialize the protected member +class Test3 +{ + const test3_constant = "test3"; + public static $test3_static = 0; + protected $member1; + var $var1 = 30; + var $var2; + function __construct($value1, $value2) + { + $this->member1 = $value1; + $this->var2 = $value2; + } +} +// child class which inherits parent class test3 +class Child_test3 extends Test3 +{ + protected $member1; + function __construct($value1, $value2, $value3) + { + parent::__construct($value1, $value2); + $this->member1 = $value3; + } +} +// class with public, private, protected members, static, constant members and constructor to initialize all the members +class Test4 +{ + const test4_constant = "test4"; + public static $test4_static = 0; + public $member1; + private $member2; + protected $member3; + function __construct($value1, $value2, $value3) + { + $this->member1 = $value1; + $this->member2 = $value2; + $this->member3 = $value3; + } +} +// child class which inherits parent class test4 +class Child_test4 extends Test4 +{ + var $var1; + function __construct($value1, $value2, $value3, $value4) + { + parent::__construct($value1, $value2, $value3); + $this->var1 = $value4; + } +} +// abstract class with public, private, protected members +abstract class AbstractClass +{ + public $member1; + private $member2; + protected $member3; + var $var1 = 30; + abstract protected function display(); +} +// implement abstract 'AbstractClass' class +class ConcreteClass1 extends AbstractClass +{ + protected function display() + { + echo "class name is ConcreteClass1 \n"; + } +} +// declarationn of the interface 'iTemplate' +interface iTemplate +{ + public function display(); +} +// implement the interface 'iTemplate' +class Template1 implements iTemplate +{ + public function display() + { + echo "class name is Template1\n"; + } +} +function main() +{ + /* + * testing array_fill() by passing various object values for 'val' argument + */ + echo "*** Testing array_fill() : usage variations ***\n"; + // Initialise function arguments not being substituted + $start_key = 0; + $num = 2; + //array of object values for 'val' argument + $objects = array( + /* 1 */ + new Test(), + new Test1(100, 101), + new Child_test1(100, 101, 102), + new Test2(100, 101), + /* 5 */ + new Child_test2(100, 101, 102), + new Test3(100, 101), + new Child_test3(100, 101, 102), + new Test4(100, 101, 102), + new Child_test4(100, 101, 102, 103), + new ConcreteClass1(), + /* 11 */ + new Template1(), + ); + // loop through each element of the array for 'val' argument + // check the working of array_fill() + echo "--- Testing array_fill() with different object values for 'val' argument ---\n"; + $counter = 1; + for ($index = 0; $index < count($objects); $index++) { + echo "-- Iteration {$counter} --\n"; + $val = $objects[$index]; + var_dump(array_fill($start_key, $num, $val)); + $counter++; + } + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_fill() : usage variations *** +--- Testing array_fill() with different object values for 'val' argument --- +-- Iteration 1 -- +array(2) { + [0]=> + object(Test)#%d (0) { + } + [1]=> + object(Test)#%d (0) { + } +} +-- Iteration 2 -- +array(2) { + [0]=> + object(Test1)#%d (3) { + ["member1"]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } + [1]=> + object(Test1)#%d (3) { + ["member1"]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } +} +-- Iteration 3 -- +array(2) { + [0]=> + object(Child_test1)#%d (4) { + ["member1"]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + ["member2"]=> + int(102) + } + [1]=> + object(Child_test1)#%d (4) { + ["member1"]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + ["member2"]=> + int(102) + } +} +-- Iteration 4 -- +array(2) { + [0]=> + object(Test2)#%d (3) { + ["member1":"Test2":private]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } + [1]=> + object(Test2)#%d (3) { + ["member1":"Test2":private]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } +} +-- Iteration 5 -- +array(2) { + [0]=> + object(Child_test2)#%d (4) { + ["member1":"Test2":private]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + ["member1":"Child_test2":private]=> + int(102) + } + [1]=> + object(Child_test2)#%d (4) { + ["member1":"Test2":private]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + ["member1":"Child_test2":private]=> + int(102) + } +} +-- Iteration 6 -- +array(2) { + [0]=> + object(Test3)#%d (3) { + ["member1":protected]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } + [1]=> + object(Test3)#%d (3) { + ["member1":protected]=> + int(100) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } +} +-- Iteration 7 -- +array(2) { + [0]=> + object(Child_test3)#%d (3) { + ["member1":protected]=> + int(102) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } + [1]=> + object(Child_test3)#%d (3) { + ["member1":protected]=> + int(102) + ["var1"]=> + int(30) + ["var2"]=> + int(101) + } +} +-- Iteration 8 -- +array(2) { + [0]=> + object(Test4)#%d (3) { + ["member1"]=> + int(100) + ["member2":"Test4":private]=> + int(101) + ["member3":protected]=> + int(102) + } + [1]=> + object(Test4)#%d (3) { + ["member1"]=> + int(100) + ["member2":"Test4":private]=> + int(101) + ["member3":protected]=> + int(102) + } +} +-- Iteration 9 -- +array(2) { + [0]=> + object(Child_test4)#%d (4) { + ["member1"]=> + int(100) + ["member2":"Test4":private]=> + int(101) + ["member3":protected]=> + int(102) + ["var1"]=> + int(103) + } + [1]=> + object(Child_test4)#%d (4) { + ["member1"]=> + int(100) + ["member2":"Test4":private]=> + int(101) + ["member3":protected]=> + int(102) + ["var1"]=> + int(103) + } +} +-- Iteration 10 -- +array(2) { + [0]=> + object(ConcreteClass1)#%d (4) { + ["member1"]=> + NULL + ["member2":"AbstractClass":private]=> + NULL + ["member3":protected]=> + NULL + ["var1"]=> + int(30) + } + [1]=> + object(ConcreteClass1)#%d (4) { + ["member1"]=> + NULL + ["member2":"AbstractClass":private]=> + NULL + ["member3":protected]=> + NULL + ["var1"]=> + int(30) + } +} +-- Iteration 11 -- +array(2) { + [0]=> + object(Template1)#%d (0) { + } + [1]=> + object(Template1)#%d (0) { + } +} +Done diff --git a/tests/std/array/array_fill_variation3.phpt b/tests/std/array/array_fill_variation3.phpt new file mode 100644 index 00000000..7963ea12 --- /dev/null +++ b/tests/std/array/array_fill_variation3.phpt @@ -0,0 +1,102 @@ +--TEST-- +Test array_fill() function : usage variations - unexpected values for 'val' argument +--SKIPIF-- + + +--FILE-- + +--EXPECTF-- +*** Testing array_fill() : usage variations *** +--- Testing array_fill() with different values for 'val' argument --- +-- Iteration 1 -- +array(2) { + [0]=> + string(0) "" + [1]=> + string(0) "" +} +-- Iteration 2 -- +array(2) { + [0]=> + string(0) "" + [1]=> + string(0) "" +} +-- Iteration 3 -- +array(2) { + [0]=> + object(test)#%d (1) { + ["t"]=> + int(10) + } + [1]=> + object(test)#%d (1) { + ["t"]=> + int(10) + } +} +-- Iteration 4 -- +array(2) { + [0]=> + NULL + [1]=> + NULL +} +-- Iteration 5 -- +array(2) { + [0]=> + NULL + [1]=> + NULL +} +Done diff --git a/tests/std/array/array_fill_variation4.phpt b/tests/std/array/array_fill_variation4.phpt new file mode 100644 index 00000000..79df201e --- /dev/null +++ b/tests/std/array/array_fill_variation4.phpt @@ -0,0 +1,163 @@ +--TEST-- +Test array_fill() function : usage variations - using return value of array_fill for 'val' argument +--FILE-- + +--EXPECT-- +*** Testing array_fill() : variation *** +*** Filling 2 dimensional array with all basic valid values *** +-- Iteration 1 -- +array(2) { + [0]=> + array(2) { + [0]=> + NULL + [1]=> + NULL + } + [1]=> + array(2) { + [0]=> + NULL + [1]=> + NULL + } +} +-- Iteration 2 -- +array(2) { + [0]=> + array(2) { + [0]=> + int(0) + [1]=> + int(0) + } + [1]=> + array(2) { + [0]=> + int(0) + [1]=> + int(0) + } +} +-- Iteration 3 -- +array(2) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(1) + } + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(1) + } +} +-- Iteration 4 -- +array(2) { + [0]=> + array(2) { + [0]=> + float(1) + [1]=> + float(1) + } + [1]=> + array(2) { + [0]=> + float(1) + [1]=> + float(1) + } +} +-- Iteration 5 -- +array(2) { + [0]=> + array(2) { + [0]=> + string(2) "hi" + [1]=> + string(2) "hi" + } + [1]=> + array(2) { + [0]=> + string(2) "hi" + [1]=> + string(2) "hi" + } +} +-- Iteration 6 -- +array(2) { + [0]=> + array(2) { + [0]=> + string(2) "hi" + [1]=> + string(2) "hi" + } + [1]=> + array(2) { + [0]=> + string(2) "hi" + [1]=> + string(2) "hi" + } +} +-- Iteration 7 -- +array(2) { + [0]=> + array(2) { + [0]=> + string(5) "Hello" + [1]=> + string(5) "Hello" + } + [1]=> + array(2) { + [0]=> + string(5) "Hello" + [1]=> + string(5) "Hello" + } +} +Done diff --git a/tests/std/array/array_fill_variation5.phpt b/tests/std/array/array_fill_variation5.phpt new file mode 100644 index 00000000..43dd5fd3 --- /dev/null +++ b/tests/std/array/array_fill_variation5.phpt @@ -0,0 +1,289 @@ +--TEST-- +Test array_fill() function : usage variations - different types of array values for 'val' argument +--SKIPIF-- + +--FILE-- + "Hi" , 2 => "Hello"), + array("Saffron" , "White" , "Green"), + /* 5 */ array('color' => 'red' , 'item' => 'pen'), + array( 'color' => 'red' , 2 => 'green ' ), + array("colour" => "red" , "item" => "pen"), + array( TRUE => "red" , FALSE => "green" ), + array( true => "red" , FALSE => "green" ), + /* 10 */ array( 1 => "Hi" , "color" => "red" , 'item' => 'pen'), + array( NULL => "Hi", '1' => "Hello" , "1" => "Green"), + array( ""=>1, "color" => "green"), + /* 13 */ array('Saffron' , 'White' , 'Green') +); + +// loop through each element of the values array for 'val' argument +// check the working of array_fill() +echo "--- Testing array_fill() with different types of array values for 'val' argument ---\n"; +$counter = 1; +for($i = 0; $i < count($values); $i++) +{ + echo "-- Iteration $counter --\n"; + $val = $values[$i]; + + var_dump( array_fill($start_key , $num , $val) ); + + $counter++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_fill() : usage variations *** +--- Testing array_fill() with different types of array values for 'val' argument --- +-- Iteration 1 -- +array(2) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } +} +-- Iteration 2 -- +array(2) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + [1]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } +} +-- Iteration 3 -- +array(2) { + [0]=> + array(2) { + [1]=> + string(2) "Hi" + [2]=> + string(5) "Hello" + } + [1]=> + array(2) { + [1]=> + string(2) "Hi" + [2]=> + string(5) "Hello" + } +} +-- Iteration 4 -- +array(2) { + [0]=> + array(3) { + [0]=> + string(7) "Saffron" + [1]=> + string(5) "White" + [2]=> + string(5) "Green" + } + [1]=> + array(3) { + [0]=> + string(7) "Saffron" + [1]=> + string(5) "White" + [2]=> + string(5) "Green" + } +} +-- Iteration 5 -- +array(2) { + [0]=> + array(2) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } + [1]=> + array(2) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } +} +-- Iteration 6 -- +array(2) { + [0]=> + array(2) { + ["color"]=> + string(3) "red" + [2]=> + string(6) "green " + } + [1]=> + array(2) { + ["color"]=> + string(3) "red" + [2]=> + string(6) "green " + } +} +-- Iteration 7 -- +array(2) { + [0]=> + array(2) { + ["colour"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } + [1]=> + array(2) { + ["colour"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } +} +-- Iteration 8 -- +array(2) { + [0]=> + array(2) { + [1]=> + string(3) "red" + [0]=> + string(5) "green" + } + [1]=> + array(2) { + [1]=> + string(3) "red" + [0]=> + string(5) "green" + } +} +-- Iteration 9 -- +array(2) { + [0]=> + array(2) { + [1]=> + string(3) "red" + [0]=> + string(5) "green" + } + [1]=> + array(2) { + [1]=> + string(3) "red" + [0]=> + string(5) "green" + } +} +-- Iteration 10 -- +array(2) { + [0]=> + array(3) { + [1]=> + string(2) "Hi" + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } + [1]=> + array(3) { + [1]=> + string(2) "Hi" + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } +} +-- Iteration 11 -- +array(2) { + [0]=> + array(2) { + [""]=> + string(2) "Hi" + [1]=> + string(5) "Green" + } + [1]=> + array(2) { + [""]=> + string(2) "Hi" + [1]=> + string(5) "Green" + } +} +-- Iteration 12 -- +array(2) { + [0]=> + array(2) { + [""]=> + int(1) + ["color"]=> + string(5) "green" + } + [1]=> + array(2) { + [""]=> + int(1) + ["color"]=> + string(5) "green" + } +} +-- Iteration 13 -- +array(2) { + [0]=> + array(3) { + [0]=> + string(7) "Saffron" + [1]=> + string(5) "White" + [2]=> + string(5) "Green" + } + [1]=> + array(3) { + [0]=> + string(7) "Saffron" + [1]=> + string(5) "White" + [2]=> + string(5) "Green" + } +} +Done diff --git a/tests/std/array/array_fill_variation6.phpt b/tests/std/array/array_fill_variation6.phpt new file mode 100644 index 00000000..c9ca2616 --- /dev/null +++ b/tests/std/array/array_fill_variation6.phpt @@ -0,0 +1,21 @@ +--TEST-- +array_fill(): last element +--SKIPIF-- + +--FILE-- +getMessage(), PHP_EOL; +} +?> +--EXPECT-- +int(1) +bool(true) +Cannot add element to the array as the next element is already occupied diff --git a/tests/std/array/array_filter.phpt b/tests/std/array/array_filter.phpt new file mode 100644 index 00000000..6b7f45ad --- /dev/null +++ b/tests/std/array/array_filter.phpt @@ -0,0 +1,77 @@ +--TEST-- +basic array_filter test +--FILE-- + 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5); + $array2 = array(6, 7, 8, 9, 10, 11, 12, 0); + $array3 = array(TRUE, FALSE, NULL); + echo "Odd :\n"; + var_dump(array_filter($array1, "odd")); + var_dump(array_filter($array2, "odd")); + var_dump(array_filter($array3, "odd")); + echo "Even:\n"; + var_dump(array_filter($array1, "even")); + var_dump(array_filter($array2, "even")); + var_dump(array_filter($array3, "even")); + var_dump(array_filter(array())); +} +?> +--EXPECT-- +Odd : +array(3) { + ["a"]=> + int(1) + ["c"]=> + int(3) + ["e"]=> + int(5) +} +array(3) { + [1]=> + int(7) + [3]=> + int(9) + [5]=> + int(11) +} +array(1) { + [0]=> + bool(true) +} +Even: +array(2) { + ["b"]=> + int(2) + ["d"]=> + int(4) +} +array(5) { + [0]=> + int(6) + [2]=> + int(8) + [4]=> + int(10) + [6]=> + int(12) + [7]=> + int(0) +} +array(2) { + [1]=> + bool(false) + [2]=> + NULL +} +array(0) { +} diff --git a/tests/std/array/array_filter_basic.phpt b/tests/std/array/array_filter_basic.phpt new file mode 100644 index 00000000..f13af677 --- /dev/null +++ b/tests/std/array/array_filter_basic.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_filter() function : basic functionality +--FILE-- + +--EXPECT-- +*** Testing array_filter() : basic functionality *** +array(2) { + [1]=> + int(2) + [3]=> + int(0) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [4]=> + int(-1) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [4]=> + int(-1) +} +Done diff --git a/tests/std/array/array_filter_object.phpt b/tests/std/array/array_filter_object.phpt new file mode 100644 index 00000000..3b0c4776 --- /dev/null +++ b/tests/std/array/array_filter_object.phpt @@ -0,0 +1,151 @@ +--TEST-- +Test array_filter() function : object functionality +--FILE-- +var1; + } +} + +// class without members +class EmptyClass +{ +} + +// abstract class +abstract class AbstractClass +{ + protected $var2 = 5; + abstract function emptyMethod(); +} + +// class deriving above abstract class +class ChildClass extends AbstractClass +{ + private $var3; + public function emptyMethod() { + echo "defined in child"; + } +} + +// class with final method +class FinalClass +{ + private $var4; + final function finalMethod() { + echo 'This cannot be overloaded'; + } +} + +// class with static members +class StaticClass +{ + static $var5 = 5; + public static function staticMethod() { + echo 'this is static method'; + } +} + +function always_true($input) +{ + return true; +} + +// Callback function which returns always false +function always_false($input) +{ + return false; +} + +function main() { +echo "*** Testing array_filter() : object functionality ***\n"; + +// 'input' array containing objects as elements +$input = array( + new SimpleClass(), + new EmptyClass(), + new ChildClass(), + new FinalClass(), + new StaticClass() +); + + +// with default callback +var_dump( array_filter($input) ); + +// with always_true callback function +var_dump( array_filter($input, "always_true") ); + +// with always_false callback function +var_dump( array_filter($input, "always_false") ); + +echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_filter() : object functionality *** +array(5) { + [0]=> + object(SimpleClass)#%d (1) { + ["var1"]=> + int(10) + } + [1]=> + object(EmptyClass)#%d (0) { + } + [2]=> + object(ChildClass)#%d (2) { + ["var2":protected]=> + int(5) + ["var3":"ChildClass":private]=> + NULL + } + [3]=> + object(FinalClass)#%d (1) { + ["var4":"FinalClass":private]=> + NULL + } + [4]=> + object(StaticClass)#%d (0) { + } +} +array(5) { + [0]=> + object(SimpleClass)#%d (1) { + ["var1"]=> + int(10) + } + [1]=> + object(EmptyClass)#%d (0) { + } + [2]=> + object(ChildClass)#%d (2) { + ["var2":protected]=> + int(5) + ["var3":"ChildClass":private]=> + NULL + } + [3]=> + object(FinalClass)#%d (1) { + ["var4":"FinalClass":private]=> + NULL + } + [4]=> + object(StaticClass)#%d (0) { + } +} +array(0) { +} +Done diff --git a/tests/std/array/array_filter_variation10.phpt b/tests/std/array/array_filter_variation10.phpt new file mode 100644 index 00000000..4688efab --- /dev/null +++ b/tests/std/array/array_filter_variation10.phpt @@ -0,0 +1,79 @@ +--TEST-- +Test array_filter() function : usage variations - using the array keys inside 'callback' +--SKIPIF-- + +--FILE-- + 4; +} + +function main() { +echo "*** Testing array_filter() : usage variations - using array keys in 'callback' ***\n"; + +$input = array(0, 1, -1, 10, 100, 1000, 'Hello', null); + +var_dump( array_filter($input, 'dump', true) ); + +echo "*** Testing array_filter() : usage variations - 'callback' filters based on key value ***\n"; + +var_dump( array_filter($input, 'dump2', true) ); + +echo "*** Testing array_filter() with various use types ***\n"; + +$mixed = array(1 => 'a', 2 => 'b', 'a' => 1, 'b' => 2); + +var_dump(array_filter($mixed, 'is_numeric', ARRAY_FILTER_USE_KEY)); + +var_dump(array_filter($mixed, 'is_numeric', 0)); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing array_filter() : usage variations - using array keys in 'callback' *** +0 = 0 +1 = 1 +2 = -1 +3 = 10 +4 = 100 +5 = 1000 +6 = Hello +7 = +array(0) { +} +*** Testing array_filter() : usage variations - 'callback' filters based on key value *** +array(3) { + [5]=> + int(1000) + [6]=> + string(5) "Hello" + [7]=> + NULL +} +*** Testing array_filter() with various use types *** +array(2) { + [1]=> + string(1) "a" + [2]=> + string(1) "b" +} +array(2) { + ["a"]=> + int(1) + ["b"]=> + int(2) +} +Done diff --git a/tests/std/array/array_filter_variation3.phpt b/tests/std/array/array_filter_variation3.phpt new file mode 100644 index 00000000..fd4b90b9 --- /dev/null +++ b/tests/std/array/array_filter_variation3.phpt @@ -0,0 +1,216 @@ +--TEST-- +Test array_filter() function : usage variations - Different types of array for 'input' argument +--SKIPIF-- + +--FILE-- + 'one', 'zero' => 0, -2 => "value"), //associative array + array("one" => 1, null => 'null', 5 => "float", true => 1, "" => 'empty'), // associative array with different keys + array(1 => 'one', 2, "key" => 'value') // combinition of associative and non-associative array + +); + +// loop through each element of 'input' with default callback +for($count = 0; $count < count($input_values); $count++) +{ + echo "-- Iteration ".($count + 1). " --\n"; + var_dump( array_filter($input_values[$count]) ); + var_dump( array_filter($input_values[$count], 'always_true') ); + var_dump( array_filter($input_values[$count], 'always_false') ); +} + +echo "Done"; +} +?> +--EXPECT-- +*** Testing array_filter() : usage variations - different types of array for 'input' argument*** +-- Iteration 1 -- +array(5) { + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(-1) + [4]=> + int(28) + [5]=> + int(74) +} +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(-1) + [4]=> + int(28) + [5]=> + int(74) +} +array(0) { +} +-- Iteration 2 -- +array(3) { + [1]=> + float(1.2) + [2]=> + float(1200) + [3]=> + float(0.0012) +} +array(4) { + [0]=> + float(0) + [1]=> + float(1.2) + [2]=> + float(1200) + [3]=> + float(0.0012) +} +array(0) { +} +-- Iteration 3 -- +array(3) { + [0]=> + string(6) "value1" + [1]=> + string(6) "value2" + [3]=> + string(1) " " +} +array(5) { + [0]=> + string(6) "value1" + [1]=> + string(6) "value2" + [2]=> + string(0) "" + [3]=> + string(1) " " + [4]=> + string(0) "" +} +array(0) { +} +-- Iteration 4 -- +array(2) { + [0]=> + bool(true) + [2]=> + bool(true) +} +array(4) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + bool(true) + [3]=> + bool(false) +} +array(0) { +} +-- Iteration 5 -- +array(0) { +} +array(2) { + [0]=> + NULL + [1]=> + NULL +} +array(0) { +} +-- Iteration 6 -- +array(2) { + [1]=> + string(3) "one" + [-2]=> + string(5) "value" +} +array(3) { + [1]=> + string(3) "one" + ["zero"]=> + int(0) + [-2]=> + string(5) "value" +} +array(0) { +} +-- Iteration 7 -- +array(4) { + ["one"]=> + int(1) + [""]=> + string(5) "empty" + [5]=> + string(5) "float" + [1]=> + int(1) +} +array(4) { + ["one"]=> + int(1) + [""]=> + string(5) "empty" + [5]=> + string(5) "float" + [1]=> + int(1) +} +array(0) { +} +-- Iteration 8 -- +array(3) { + [1]=> + string(3) "one" + [2]=> + int(2) + ["key"]=> + string(5) "value" +} +array(3) { + [1]=> + string(3) "one" + [2]=> + int(2) + ["key"]=> + string(5) "value" +} +array(0) { +} +Done diff --git a/tests/std/array/array_filter_variation4.phpt b/tests/std/array/array_filter_variation4.phpt new file mode 100644 index 00000000..6db83574 --- /dev/null +++ b/tests/std/array/array_filter_variation4.phpt @@ -0,0 +1,99 @@ +--TEST-- +Test array_filter() function : usage variations - Different types of 'callback' function +--FILE-- + 0 ) { + return true; + } + else { + return false; + } +} + +function main() { +echo "*** Testing array_filter() : usage variation - different 'callback' functions***\n"; + +// Initialize variables +$input = array(0, -1, 2, 3.4E-3, 'hello', "value", "key" => 4, 'null' => NULL); + +echo "-- Callback function without parameter and with return --\n"; +var_dump( array_filter($input, "callback1") ); + +echo "-- Callback function with parameter and without return --\n"; +var_dump( array_filter($input, "callback2") ); + +echo "-- Callback function without parameter and return --\n"; +var_dump( array_filter($input, "callback3") ); + +echo "-- Callback function with parameter and return --\n"; +var_dump( array_filter($input, "callback4") ); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing array_filter() : usage variation - different 'callback' functions*** +-- Callback function without parameter and with return -- +array(8) { + [0]=> + int(0) + [1]=> + int(-1) + [2]=> + int(2) + [3]=> + float(0.0034) + [4]=> + string(5) "hello" + [5]=> + string(5) "value" + ["key"]=> + int(4) + ["null"]=> + NULL +} +-- Callback function with parameter and without return -- +array(0) { +} +-- Callback function without parameter and return -- +array(0) { +} +-- Callback function with parameter and return -- +array(5) { + [2]=> + int(2) + [3]=> + float(0.0034) + [4]=> + string(5) "hello" + [5]=> + string(5) "value" + ["key"]=> + int(4) +} +Done diff --git a/tests/std/array/array_filter_variation5.phpt b/tests/std/array/array_filter_variation5.phpt new file mode 100644 index 00000000..d5dd6f91 --- /dev/null +++ b/tests/std/array/array_filter_variation5.phpt @@ -0,0 +1,109 @@ +--TEST-- +Test array_filter() function : usage variations - 'input' argument with different false entries +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_filter() : usage variations - different false elements in 'input' *** +array(0) { +} +array(16) { + [0]=> + bool(false) + [1]=> + bool(false) + [2]=> + string(0) "" + [3]=> + string(0) "" + [4]=> + int(0) + [5]=> + float(0) + [6]=> + NULL + [7]=> + NULL + [8]=> + string(1) "0" + [9]=> + string(1) "0" + [10]=> + array(0) { + } + [11]=> + bool(false) + [12]=> + bool(false) + [13]=> + string(0) "" + [14]=> + NULL + [15]=> + NULL +} +array(0) { +} +Done diff --git a/tests/std/array/array_filter_variation6.phpt b/tests/std/array/array_filter_variation6.phpt new file mode 100644 index 00000000..adc1d4ff --- /dev/null +++ b/tests/std/array/array_filter_variation6.phpt @@ -0,0 +1,90 @@ +--TEST-- +Test array_filter() function : usage variations - 'input' array containing references +--SKIPIF-- + +--FILE-- + 5) { + return true; + } + else { + return false; + } +} + +function main() { +echo "*** Testing array_filter() : usage variations - 'input' containing references ***\n"; + +// initializing variables +$value1 = array(1, 2, 8); +$value2 = array(5, 6, 4); +$input = array(&$value1, 10, &$value2, 'value'); + +// with 'callback' argument +var_dump( array_filter($input, 'callback') ); + +// with default 'callback' argument +var_dump( array_filter($input) ); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing array_filter() : usage variations - 'input' containing references *** +array(4) { + [0]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(8) + } + [1]=> + int(10) + [2]=> + &array(3) { + [0]=> + int(5) + [1]=> + int(6) + [2]=> + int(4) + } + [3]=> + string(5) "value" +} +array(4) { + [0]=> + &array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(8) + } + [1]=> + int(10) + [2]=> + &array(3) { + [0]=> + int(5) + [1]=> + int(6) + [2]=> + int(4) + } + [3]=> + string(5) "value" +} +Done diff --git a/tests/std/array/array_filter_variation7.phpt b/tests/std/array/array_filter_variation7.phpt new file mode 100644 index 00000000..cea5e7ae --- /dev/null +++ b/tests/std/array/array_filter_variation7.phpt @@ -0,0 +1,62 @@ +--TEST-- +Test array_filter() function : usage variations - anonymous callback functions +--FILE-- + 1); }) ); + +// anonymous callback function with null argument +echo "Anonymous callback function with null argument\n"; +var_dump( array_filter($input, function() { return true; }) ); + +// anonymous callback function with argument and null statement +echo "Anonymous callback function with regular argument and null statement\n"; +var_dump( array_filter($input, function($input) { }) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_filter() : usage variations - Anonymous callback functions *** +Anonymous callback function with regular parameter and statement +array(4) { + [3]=> + int(10) + [4]=> + int(100) + [5]=> + int(1000) + [6]=> + string(5) "Hello" +} +Anonymous callback function with null argument +array(8) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(-1) + [3]=> + int(10) + [4]=> + int(100) + [5]=> + int(1000) + [6]=> + string(5) "Hello" + [7]=> + NULL +} +Anonymous callback function with regular argument and null statement +array(0) { +} +Done diff --git a/tests/std/array/array_filter_variation8.phpt b/tests/std/array/array_filter_variation8.phpt new file mode 100644 index 00000000..79978898 --- /dev/null +++ b/tests/std/array/array_filter_variation8.phpt @@ -0,0 +1,151 @@ +--TEST-- +Test array_filter() function : usage variations - Callback function with different return values +--FILE-- + +--EXPECT-- +*** Testing array_filter() : usage variations - callback function with different return values*** +callback function with int return value +array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(-1) + [3]=> + int(10) + [4]=> + int(100) + [5]=> + int(1000) + [6]=> + string(5) "Hello" + [7]=> + NULL + [8]=> + bool(true) +} +callback function with float return value +array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(-1) + [3]=> + int(10) + [4]=> + int(100) + [5]=> + int(1000) + [6]=> + string(5) "Hello" + [7]=> + NULL + [8]=> + bool(true) +} +callback function with string return value +array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(-1) + [3]=> + int(10) + [4]=> + int(100) + [5]=> + int(1000) + [6]=> + string(5) "Hello" + [7]=> + NULL + [8]=> + bool(true) +} +callback function with null return value +array(0) { +} +callback function with array as return value +array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(-1) + [3]=> + int(10) + [4]=> + int(100) + [5]=> + int(1000) + [6]=> + string(5) "Hello" + [7]=> + NULL + [8]=> + bool(true) +} +Done diff --git a/tests/std/array/array_filter_variation9.phpt b/tests/std/array/array_filter_variation9.phpt new file mode 100644 index 00000000..e0000612 --- /dev/null +++ b/tests/std/array/array_filter_variation9.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test array_filter() function : usage variations - built-in functions as 'callback' argument +--FILE-- +getMessage(), "\n"; +} + +// using language construct 'isset' as 'callback' +try { + var_dump( array_filter($input, 'isset') ); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_filter() : usage variations - built-in functions as 'callback' argument *** +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(-1) + [3]=> + int(10) + [4]=> + int(100) + [5]=> + int(1000) +} +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(-1) + [3]=> + int(10) + [4]=> + int(100) + [5]=> + int(1000) +} +array_filter(): Argument #2 ($callback) must be a valid callback or null, function "echo" not found or invalid function name +array_filter(): Argument #2 ($callback) must be a valid callback or null, function "isset" not found or invalid function name +Done diff --git a/tests/std/array/array_find_basic.phpt b/tests/std/array/array_find_basic.phpt new file mode 100644 index 00000000..b98debee --- /dev/null +++ b/tests/std/array/array_find_basic.phpt @@ -0,0 +1,51 @@ +--TEST-- +Test array_find() function : basic functionality +--SKIPIF-- + + +--FILE-- + 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5]; + $array2 = [1, 2, 3, 4, 5]; + var_dump(array_find($array1, fn($value, $key) => $value > 3)); + var_dump(array_find($array2, fn($value, $key) => $value > 3)); + var_dump(array_find($array2, fn($value, $key) => $value > 5)); + var_dump(array_find([], fn($value, $key) => true)); + var_dump(array_find($array1, fn($value, $key) => $key === "c")); + var_dump(array_find($array1, fn($value, $key) => false)); + var_dump(array_find($array1, 'even')); + var_dump(array_find($array1, 'return_nothing')); + var_dump(array_find($array1, ['EvenClass', 'even'])); + var_dump(array_find($array1, "EvenClass::even")); +} +?> +--EXPECT-- +int(4) +int(4) +NULL +NULL +int(3) +NULL +int(2) +NULL +int(2) +int(2) diff --git a/tests/std/array/array_find_key_basic.phpt b/tests/std/array/array_find_key_basic.phpt new file mode 100644 index 00000000..6b972237 --- /dev/null +++ b/tests/std/array/array_find_key_basic.phpt @@ -0,0 +1,51 @@ +--TEST-- +Test array_find_key() function : basic functionality +--SKIPIF-- + + +--FILE-- + 1, "b" => 2, "c" => 3, "d" => 4, "e" => 5]; + $array2 = [1, 2, 3, 4, 5]; + var_dump(array_find_key($array1, fn($value, $key) => $value > 3)); + var_dump(array_find_key($array2, fn($value, $key) => $value > 3)); + var_dump(array_find_key($array2, fn($value, $key) => $value > 5)); + var_dump(array_find_key([], fn($value, $key) => true)); + var_dump(array_find_key($array1, fn($value, $key) => $key === "c")); + var_dump(array_find_key($array1, fn($value, $key) => false)); + var_dump(array_find_key($array1, 'even')); + var_dump(array_find_key($array1, 'return_nothing')); + var_dump(array_find_key($array1, ['EvenClass', 'even'])); + var_dump(array_find_key($array1, "EvenClass::even")); +} +?> +--EXPECT-- +string(1) "d" +int(3) +NULL +NULL +string(1) "c" +NULL +string(1) "b" +NULL +string(1) "b" +string(1) "b" diff --git a/tests/std/array/array_find_types.phpt b/tests/std/array/array_find_types.phpt new file mode 100644 index 00000000..9c6e5e96 --- /dev/null +++ b/tests/std/array/array_find_types.phpt @@ -0,0 +1,210 @@ +--TEST-- +basic array_find test +--SKIPIF-- + + +--FILE-- +a = "1"; + +$array = [ + ...[0, 1, 2, -1, 034, 0X4A], + ...[0.0, 1.2, 1.2e3, 1.2e-3], + ...['value1', "value2", '', " ", ""], + ...[true, false, TRUE, FALSE], + ...[null, NULL], + ...[1 => 'one', 'zero' => 0, -2 => "value"], + ...["one" => 1, 5 => "float", true => 1, "" => 'empty'], + ...[1 => 'one', 2, "key" => 'value'], + ...[new stdClass(), $stdClass, (object)['b' => 2]], + ...[[], [1, 2, 3], [-1 => 1, -2 => 2]], + ...[@$undefined_var] +]; + +echo "*** Dumping each key value pair. ***". PHP_EOL; +var_dump(array_find($array, function ($value, $key) { + var_dump($key, $value); + + return false; +})); + +echo "*** Dumping only first key value pair. ***". PHP_EOL; +var_dump(array_find($array, function ($value, $key) { + var_dump($key, $value); + + return true; +})); + +echo "*** Returning each value. ***". PHP_EOL; +foreach (array_keys($array) as $key) { + var_dump(array_find($array, function ($value, $arrayKey) use ($key) { + return $arrayKey === $key; + })); +} +?> +--EXPECT-- +*** Dumping each key value pair. *** +int(0) +int(0) +int(1) +int(1) +int(2) +int(2) +int(3) +int(-1) +int(4) +int(28) +int(5) +int(74) +int(6) +float(0) +int(7) +float(1.2) +int(8) +float(1200) +int(9) +float(0.0012) +int(10) +string(6) "value1" +int(11) +string(6) "value2" +int(12) +string(0) "" +int(13) +string(1) " " +int(14) +string(0) "" +int(15) +bool(true) +int(16) +bool(false) +int(17) +bool(true) +int(18) +bool(false) +int(19) +NULL +int(20) +NULL +int(21) +string(3) "one" +string(4) "zero" +int(0) +int(22) +string(5) "value" +string(3) "one" +int(1) +int(23) +string(5) "float" +int(24) +int(1) +string(0) "" +string(5) "empty" +int(25) +string(3) "one" +int(26) +int(2) +string(3) "key" +string(5) "value" +int(27) +object(stdClass)#2 (0) { +} +int(28) +object(stdClass)#1 (1) { + ["a"]=> + string(1) "1" +} +int(29) +object(stdClass)#3 (1) { + ["b"]=> + int(2) +} +int(30) +array(0) { +} +int(31) +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +int(32) +array(2) { + [-1]=> + int(1) + [-2]=> + int(2) +} +int(33) +NULL +NULL +*** Dumping only first key value pair. *** +int(0) +int(0) +int(0) +*** Returning each value. *** +int(0) +int(1) +int(2) +int(-1) +int(28) +int(74) +float(0) +float(1.2) +float(1200) +float(0.0012) +string(6) "value1" +string(6) "value2" +string(0) "" +string(1) " " +string(0) "" +bool(true) +bool(false) +bool(true) +bool(false) +NULL +NULL +string(3) "one" +int(0) +string(5) "value" +int(1) +string(5) "float" +int(1) +string(5) "empty" +string(3) "one" +int(2) +string(5) "value" +object(stdClass)#2 (0) { +} +object(stdClass)#1 (1) { + ["a"]=> + string(1) "1" +} +object(stdClass)#3 (1) { + ["b"]=> + int(2) +} +array(0) { +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + [-1]=> + int(1) + [-2]=> + int(2) +} +NULL diff --git a/tests/std/array/array_flip.phpt b/tests/std/array/array_flip.phpt new file mode 100644 index 00000000..b16063a4 --- /dev/null +++ b/tests/std/array/array_flip.phpt @@ -0,0 +1,37 @@ +--TEST-- +basic array_flip test +--FILE-- + 1, + "b" => 1, + "c" => 2, + "z" => 0, + "d" => TRUE, + "E" => FALSE, + "F" => NULL, + 0 => "G", + 1 => "h", + 2 => "i"); +$trans = array_flip($trans); +var_dump($trans); +?> +--EXPECTF-- +Warning:%S Can only flip string and integer values, entry skipped in %s on line %d + +Warning:%S Can only flip string and integer values, entry skipped in %s on line %d + +Warning:%S Can only flip string and integer values, entry skipped in %s on line %d +array(6) { + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [0]=> + string(1) "z" + ["G"]=> + int(0) + ["h"]=> + int(1) + ["i"]=> + int(2) +} diff --git a/tests/std/array/array_flip_basic.phpt b/tests/std/array/array_flip_basic.phpt new file mode 100644 index 00000000..3edcd3b5 --- /dev/null +++ b/tests/std/array/array_flip_basic.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test array_flip() function : basic functionality +--FILE-- + 1, "key2" => 2); +var_dump( array_flip($input) ); + +// associative arrays - key as numeric +$input = array(1 => 'one', 2 => "two"); +var_dump( array_flip($input) ); + +// combination of associative and non-associative array +$input = array(1 => 'one','two', 3 => 'three', 4, "five" => 5); +var_dump( array_flip($input) ); +echo "Done"; +?> +--EXPECT-- +*** Testing array_flip() : basic functionality *** +array(2) { + [1]=> + int(0) + [2]=> + int(1) +} +array(2) { + ["value1"]=> + int(0) + ["value2"]=> + int(1) +} +array(2) { + [1]=> + string(4) "key1" + [2]=> + string(4) "key2" +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(5) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + [4]=> + int(4) + [5]=> + string(4) "five" +} +Done diff --git a/tests/std/array/array_flip_variation2.phpt b/tests/std/array/array_flip_variation2.phpt new file mode 100644 index 00000000..f147fa9d --- /dev/null +++ b/tests/std/array/array_flip_variation2.phpt @@ -0,0 +1,99 @@ +--TEST-- +Test array_flip() function : usage variations - 'input' array with different keys +--SKIPIF-- + +--FILE-- + 'int_key', // expected: value will be replaced by 'bool_key3' + -2 => 'negative_key', + 012 => 'octal_key', + 0x34 => 'hex_key', + + // string keys + 'key' => 'string_key1', + "two" => 'string_key2', + '' => 'string_key3', + "" => 'string_key4', + " " => 'string_key5', + + // bool keys + true => 'bool_key1', + false => 'bool_key2', + TRUE => 'bool_key3', + FALSE => 'bool_key4', + + // null keys + null => 'null_key1', // expected: value will be replaced by 'null_key2' + NULL => 'null_key2', + + // binary key + "a".chr(0)."b" => 'binary_key1', + b"binary" => 'binary_key2', + + //heredoc keys + $empty_heredoc => 'empty_heredoc', + $simple_heredoc => 'simple_heredoc', + $multiline_heredoc => 'multiline_heredoc', +); + +var_dump( array_flip($input) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_flip() : different keys for 'input' array argument *** +array(13) { + ["bool_key4"]=> + int(0) + ["bool_key3"]=> + int(1) + ["negative_key"]=> + int(-2) + ["octal_key"]=> + int(10) + ["hex_key"]=> + int(52) + ["string_key1"]=> + string(3) "key" + ["string_key2"]=> + string(3) "two" + ["empty_heredoc"]=> + string(0) "" + ["string_key5"]=> + string(1) " " + ["binary_key1"]=> + string(3) "a%0b" + ["binary_key2"]=> + string(6) "binary" + ["simple_heredoc"]=> + string(6) "simple" + ["multiline_heredoc"]=> + string(6%d) "multiline heredoc with 123 and +speci@! ch@r$...checking +and also" +} +Done diff --git a/tests/std/array/array_flip_variation3.phpt b/tests/std/array/array_flip_variation3.phpt new file mode 100644 index 00000000..32d7452d --- /dev/null +++ b/tests/std/array/array_flip_variation3.phpt @@ -0,0 +1,120 @@ +--TEST-- +Test array_flip() function : usage variations - 'input' argument with different valid values +--FILE-- + 1, + 'negative_value' => -2, + 'zero_value' => 0, + 'octal_value' => 012, + 'hex_value' => 0x23, + + // single quoted string value + 'empty_value1' => '', + 'space_value1' => ' ', + 'char_value1' => 'a', + 'string_value1' => 'string1', + 'numeric_value1' => '123', + 'special_char_value1' => '!@#$%', + 'whitespace1_value1' => '\t', + 'whitespace2_value1' => '\n', + 'null_char_value1' => '\0', + + // double quoted string value + 'empty_value2' => "", + 'space_value2' => " ", + 'char_value2' => "b", + 'string_value2' => "string2", + 'numeric_value2' => "456", + 'special_char_value2' => "^&*", + 'whitespace1_value2' => "\t", + 'whitespace2_value2' => "\n", + 'null_char_value2' => "\0", + 'binary_value' => "a".chr(0)."b", + + // heredoc string value + 'empty_heredoc' => $empty_heredoc, + 'simple_heredoc' => $simple_heredoc, + 'multiline_heredoc' => $multiline_heredoc, +); + +var_dump( array_flip($input) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_flip() : different valid values in 'input' array argument *** +array(24) { + [1]=> + string(9) "int_value" + [-2]=> + string(14) "negative_value" + [0]=> + string(10) "zero_value" + [10]=> + string(11) "octal_value" + [35]=> + string(9) "hex_value" + [""]=> + string(13) "empty_heredoc" + [" "]=> + string(12) "space_value2" + ["a"]=> + string(11) "char_value1" + ["string1"]=> + string(13) "string_value1" + [123]=> + string(14) "numeric_value1" + ["!@#$%"]=> + string(19) "special_char_value1" + ["\t"]=> + string(18) "whitespace1_value1" + ["\n"]=> + string(18) "whitespace2_value1" + ["\0"]=> + string(16) "null_char_value1" + ["b"]=> + string(11) "char_value2" + ["string2"]=> + string(13) "string_value2" + [456]=> + string(14) "numeric_value2" + ["^&*"]=> + string(19) "special_char_value2" + [" "]=> + string(18) "whitespace1_value2" + [" +"]=> + string(18) "whitespace2_value2" + ["%0"]=> + string(16) "null_char_value2" + ["a%0b"]=> + string(12) "binary_value" + ["simple"]=> + string(14) "simple_heredoc" + ["multiline heredoc with 123 and +speci@! ch@r$..checking +with also"]=> + string(17) "multiline_heredoc" +} +Done diff --git a/tests/std/array/array_flip_variation4.phpt b/tests/std/array/array_flip_variation4.phpt new file mode 100644 index 00000000..60d51ef0 --- /dev/null +++ b/tests/std/array/array_flip_variation4.phpt @@ -0,0 +1,88 @@ +--TEST-- +Test array_flip() function : usage variations - 'input' argument with different invalid values for keys +--SKIPIF-- +--FILE-- + 1.2, + 'float_value2' => 0.5, + 'flaot_value3' => 3.4E3, + 'flaot_value4' => 5.6E-6, + + // bool values + 'bool_value1' => true, + 'bool_value2' => false, + 'bool_value3' => TRUE, + 'bool_value4' => FALSE, + + // null values + 'null_value1' => null, + + // array value + 'array_value' => array(1), + + // object value + 'obj_value' => $obj, + + // resource value + 'resource_value' => $fp, +); + +var_dump( array_flip($input) ); + +// closing resource +fclose($fp); + +echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_flip() : different invalid values in 'input' array argument *** + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s + +Warning:%S Can only flip string and integer values, entry skipped in %s +array(0) { +} +Done diff --git a/tests/std/array/array_flip_variation5.phpt b/tests/std/array/array_flip_variation5.phpt new file mode 100644 index 00000000..6e75648f --- /dev/null +++ b/tests/std/array/array_flip_variation5.phpt @@ -0,0 +1,79 @@ +--TEST-- +Test array_flip() function : usage variations - 'input' argument with repeatitive keys and values +--SKIPIF-- + +--FILE-- + 'value', 2 => 'VALUE', 1 => "VaLuE", 3 => 4, 3 => 5); +var_dump( array_flip($input) ); + +// array with string key repeatition +$input = array("key" => 1, "two" => 'TWO', 'three' => 3, 'key' => "FOUR"); +var_dump( array_flip($input) ); + +// array with bool key repeatition +$input = array(true => 1, false => 0, TRUE => -1); +var_dump( array_flip($input) ); + +// array with null key repeatition +$input = array(null => "Hello", NULL => 0); +var_dump( array_flip($input) ); + +// array with numeric value repeatition +$input = array('one' => 1, 'two' => 2, 3 => 1, "index" => 1); +var_dump( array_flip($input) ); + +//array with string value repeatition +$input = array('key1' => "value1", "key2" => '2', 'key3' => 'value1'); +var_dump( array_flip($input) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_flip() : 'input' array with repeatitive keys/values *** +array(3) { + ["VaLuE"]=> + int(1) + ["VALUE"]=> + int(2) + [5]=> + int(3) +} +array(3) { + ["FOUR"]=> + string(3) "key" + ["TWO"]=> + string(3) "two" + [3]=> + string(5) "three" +} +array(2) { + [-1]=> + int(1) + [0]=> + int(0) +} +array(1) { + [0]=> + string(0) "" +} +array(2) { + [1]=> + string(5) "index" + [2]=> + string(3) "two" +} +array(2) { + ["value1"]=> + string(4) "key3" + [2]=> + string(4) "key2" +} +Done diff --git a/tests/std/array/array_intersect_1.phpt b/tests/std/array/array_intersect_1.phpt new file mode 100644 index 00000000..72a9fa56 --- /dev/null +++ b/tests/std/array/array_intersect_1.phpt @@ -0,0 +1,370 @@ +--TEST-- +Test of the *intersect* bunch of functions (both assoc and non-assoc) +--FILE-- +priv_member = $val; + $this->public_member = $val; + } + static function comp_func_cr($a, $b) + { + if ($a->priv_member === $b->priv_member) { + return 0; + } + return $a->priv_member > $b->priv_member ? 1 : -1; + } +} +function comp_func($a, $b) +{ + if ($a === $b) { + return 0; + } + return $a > $b ? 1 : -1; +} +function comp_func_cr($a, $b) +{ + if ($a->public_member === $b->public_member) { + return 0; + } + return $a->public_member > $b->public_member ? 1 : -1; +} +function main() +{ + error_reporting(E_ALL); + $a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1 => new cr(4), 2 => new cr(-15)); + $b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1 => new cr(4), 2 => new cr(-15)); + /* array_uintersect() */ + echo "begin ------------ array_uintersect() ---------------------------\n"; + echo '$a=' . var_export($a, TRUE) . ";\n"; + echo '$b=' . var_export($b, TRUE) . ";\n"; + echo 'var_dump(array_uintersect($a, $b, "comp_func_cr"));' . "\n"; + var_dump(array_uintersect($a, $b, "comp_func_cr")); + echo "end ------------ array_uintersect() ---------------------------\n"; + /* array_uintersect_assoc() */ + echo "begin ------------ array_uintersect_assoc() ---------------------\n"; + echo '$a=' . var_export($a, TRUE) . ";\n"; + echo '$b=' . var_export($b, TRUE) . ";\n"; + echo 'var_dump(array_uintersect_assoc($a, $b, "comp_func_cr"));' . "\n"; + var_dump(array_uintersect_assoc($a, $b, "comp_func_cr")); + echo "end ------------ array_uintersect_assoc() ---------------------\n"; + /* array_uintersect_uassoc() - with ordinary function */ + echo "begin ------------ array_uintersect_uassoc() with ordinary func -\n"; + echo '$a=' . var_export($a, TRUE) . ";\n"; + echo '$b=' . var_export($b, TRUE) . ";\n"; + echo 'var_dump(array_uintersect_uassoc($a, $b, "comp_func_cr", "comp_func"));' . "\n"; + var_dump(array_uintersect_uassoc($a, $b, "comp_func_cr", "comp_func")); + echo "end ------------ array_uintersect_uassoc() with ordinary func -\n"; + /* array_uintersect_uassoc() - by method call */ + echo "begin ------------ array_uintersect_uassoc() with method --------\n"; + echo '$a=' . var_export($a, TRUE) . ";\n"; + echo '$b=' . var_export($b, TRUE) . ";\n"; + echo 'var_dump(array_uintersect_uassoc($a, $b, array("cr", "comp_func_cr"), "comp_func"));' . "\n"; + var_dump(array_uintersect_uassoc($a, $b, array("cr", "comp_func_cr"), "comp_func")); + echo "end ------------ array_uintersect_uassoc() with method --------\n"; +} +?> +--EXPECTF-- +begin ------------ array_uintersect() --------------------------- +$a=array ( + '0.1' => + \cr::__set_state(array( + 'priv_member' => 9, + 'public_member' => 9, + )), + '0.5' => + \cr::__set_state(array( + 'priv_member' => 12, + 'public_member' => 12, + )), + 0 => + \cr::__set_state(array( + 'priv_member' => 23, + 'public_member' => 23, + )), + 1 => + \cr::__set_state(array( + 'priv_member' => 4, + 'public_member' => 4, + )), + 2 => + \cr::__set_state(array( + 'priv_member' => -15, + 'public_member' => -15, + )), +); +$b=array ( + '0.2' => + \cr::__set_state(array( + 'priv_member' => 9, + 'public_member' => 9, + )), + '0.5' => + \cr::__set_state(array( + 'priv_member' => 22, + 'public_member' => 22, + )), + 0 => + \cr::__set_state(array( + 'priv_member' => 3, + 'public_member' => 3, + )), + 1 => + \cr::__set_state(array( + 'priv_member' => 4, + 'public_member' => 4, + )), + 2 => + \cr::__set_state(array( + 'priv_member' => -15, + 'public_member' => -15, + )), +); +var_dump(array_uintersect($a, $b, "comp_func_cr")); +array(3) { + ["0.1"]=> + object(cr)#%d (2) { + ["priv_member":"cr":private]=> + int(9) + ["public_member"]=> + int(9) + } + [1]=> + object(cr)#%d (2) { + ["priv_member":"cr":private]=> + int(4) + ["public_member"]=> + int(4) + } + [2]=> + object(cr)#%d (2) { + ["priv_member":"cr":private]=> + int(-15) + ["public_member"]=> + int(-15) + } +} +end ------------ array_uintersect() --------------------------- +begin ------------ array_uintersect_assoc() --------------------- +$a=array ( + '0.1' => + \cr::__set_state(array( + 'priv_member' => 9, + 'public_member' => 9, + )), + '0.5' => + \cr::__set_state(array( + 'priv_member' => 12, + 'public_member' => 12, + )), + 0 => + \cr::__set_state(array( + 'priv_member' => 23, + 'public_member' => 23, + )), + 1 => + \cr::__set_state(array( + 'priv_member' => 4, + 'public_member' => 4, + )), + 2 => + \cr::__set_state(array( + 'priv_member' => -15, + 'public_member' => -15, + )), +); +$b=array ( + '0.2' => + \cr::__set_state(array( + 'priv_member' => 9, + 'public_member' => 9, + )), + '0.5' => + \cr::__set_state(array( + 'priv_member' => 22, + 'public_member' => 22, + )), + 0 => + \cr::__set_state(array( + 'priv_member' => 3, + 'public_member' => 3, + )), + 1 => + \cr::__set_state(array( + 'priv_member' => 4, + 'public_member' => 4, + )), + 2 => + \cr::__set_state(array( + 'priv_member' => -15, + 'public_member' => -15, + )), +); +var_dump(array_uintersect_assoc($a, $b, "comp_func_cr")); +array(2) { + [1]=> + object(cr)#%d (2) { + ["priv_member":"cr":private]=> + int(4) + ["public_member"]=> + int(4) + } + [2]=> + object(cr)#%d (2) { + ["priv_member":"cr":private]=> + int(-15) + ["public_member"]=> + int(-15) + } +} +end ------------ array_uintersect_assoc() --------------------- +begin ------------ array_uintersect_uassoc() with ordinary func - +$a=array ( + '0.1' => + \cr::__set_state(array( + 'priv_member' => 9, + 'public_member' => 9, + )), + '0.5' => + \cr::__set_state(array( + 'priv_member' => 12, + 'public_member' => 12, + )), + 0 => + \cr::__set_state(array( + 'priv_member' => 23, + 'public_member' => 23, + )), + 1 => + \cr::__set_state(array( + 'priv_member' => 4, + 'public_member' => 4, + )), + 2 => + \cr::__set_state(array( + 'priv_member' => -15, + 'public_member' => -15, + )), +); +$b=array ( + '0.2' => + \cr::__set_state(array( + 'priv_member' => 9, + 'public_member' => 9, + )), + '0.5' => + \cr::__set_state(array( + 'priv_member' => 22, + 'public_member' => 22, + )), + 0 => + \cr::__set_state(array( + 'priv_member' => 3, + 'public_member' => 3, + )), + 1 => + \cr::__set_state(array( + 'priv_member' => 4, + 'public_member' => 4, + )), + 2 => + \cr::__set_state(array( + 'priv_member' => -15, + 'public_member' => -15, + )), +); +var_dump(array_uintersect_uassoc($a, $b, "comp_func_cr", "comp_func")); +array(2) { + [1]=> + object(cr)#%d (2) { + ["priv_member":"cr":private]=> + int(4) + ["public_member"]=> + int(4) + } + [2]=> + object(cr)#%d (2) { + ["priv_member":"cr":private]=> + int(-15) + ["public_member"]=> + int(-15) + } +} +end ------------ array_uintersect_uassoc() with ordinary func - +begin ------------ array_uintersect_uassoc() with method -------- +$a=array ( + '0.1' => + \cr::__set_state(array( + 'priv_member' => 9, + 'public_member' => 9, + )), + '0.5' => + \cr::__set_state(array( + 'priv_member' => 12, + 'public_member' => 12, + )), + 0 => + \cr::__set_state(array( + 'priv_member' => 23, + 'public_member' => 23, + )), + 1 => + \cr::__set_state(array( + 'priv_member' => 4, + 'public_member' => 4, + )), + 2 => + \cr::__set_state(array( + 'priv_member' => -15, + 'public_member' => -15, + )), +); +$b=array ( + '0.2' => + \cr::__set_state(array( + 'priv_member' => 9, + 'public_member' => 9, + )), + '0.5' => + \cr::__set_state(array( + 'priv_member' => 22, + 'public_member' => 22, + )), + 0 => + \cr::__set_state(array( + 'priv_member' => 3, + 'public_member' => 3, + )), + 1 => + \cr::__set_state(array( + 'priv_member' => 4, + 'public_member' => 4, + )), + 2 => + \cr::__set_state(array( + 'priv_member' => -15, + 'public_member' => -15, + )), +); +var_dump(array_uintersect_uassoc($a, $b, array("cr", "comp_func_cr"), "comp_func")); +array(2) { + [1]=> + object(cr)#%d (2) { + ["priv_member":"cr":private]=> + int(4) + ["public_member"]=> + int(4) + } + [2]=> + object(cr)#%d (2) { + ["priv_member":"cr":private]=> + int(-15) + ["public_member"]=> + int(-15) + } +} +end ------------ array_uintersect_uassoc() with method -------- diff --git a/tests/std/array/array_intersect_assoc_basic.phpt b/tests/std/array/array_intersect_assoc_basic.phpt new file mode 100644 index 00000000..d20cef75 --- /dev/null +++ b/tests/std/array/array_intersect_assoc_basic.phpt @@ -0,0 +1,63 @@ +--TEST-- +Test array_intersect_assoc() function : basic functionality +--FILE-- + 1, "two" => 2); + +// default key array for both $arr1 and $arr2 argument +var_dump( array_intersect_assoc($arr_default_keys, $arr_default_keys) ); + +// default key array for $arr1 and associative array for $arr2 argument +var_dump( array_intersect_assoc($arr_default_keys, $arr_associative) ); + +// associative array for $arr1 and default key array for $arr2 +var_dump( array_intersect_assoc($arr_associative, $arr_default_keys) ); + +// associative array for both $arr1 and $arr2 argument +var_dump( array_intersect_assoc($arr_associative, $arr_associative) ); + +// more arrays to be intersected +$arr3 = array(2, 3, 4); +var_dump( array_intersect_assoc($arr_default_keys, $arr_associative, $arr3) ); +var_dump( array_intersect_assoc($arr_associative, $arr_default_keys, $arr3, $arr_associative) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect_assoc() : basic functionality *** +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(5) "hello" + [3]=> + string(5) "world" +} +array(0) { +} +array(0) { +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(0) { +} +array(0) { +} +Done diff --git a/tests/std/array/array_intersect_assoc_variation1.phpt b/tests/std/array/array_intersect_assoc_variation1.phpt new file mode 100644 index 00000000..245b9792 --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation1.phpt @@ -0,0 +1,183 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - unexpected values for 'array1' argument(Bug#43196) +--SKIPIF-- + + +--FILE-- + 1, "two" => 2); + // get an unset variable + $unset_var = null; + // already null + $undefined_var = null; + // heredoc string + $heredoc = <<getMessage(), "\n"; + } + // Calling array_intersect_assoc() with more arguments + try { + var_dump(array_intersect_assoc($unexpected_value, $array2, $arr3)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_intersect_assoc() : Passing non-array values to $array1 argument *** + +-- Iteration 1 --array_intersect_assoc(): Argument #1 ($array) must be of type array, int given +array_intersect_assoc(): Argument #1 ($array) must be of type array, int given + +-- Iteration 2 --array_intersect_assoc(): Argument #1 ($array) must be of type array, int given +array_intersect_assoc(): Argument #1 ($array) must be of type array, int given + +-- Iteration 3 --array_intersect_assoc(): Argument #1 ($array) must be of type array, int given +array_intersect_assoc(): Argument #1 ($array) must be of type array, int given + +-- Iteration 4 --array_intersect_assoc(): Argument #1 ($array) must be of type array, int given +array_intersect_assoc(): Argument #1 ($array) must be of type array, int given + +-- Iteration 5 --array_intersect_assoc(): Argument #1 ($array) must be of type array, float given +array_intersect_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 6 --array_intersect_assoc(): Argument #1 ($array) must be of type array, float given +array_intersect_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 7 --array_intersect_assoc(): Argument #1 ($array) must be of type array, float given +array_intersect_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 8 --array_intersect_assoc(): Argument #1 ($array) must be of type array, float given +array_intersect_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 9 --array_intersect_assoc(): Argument #1 ($array) must be of type array, float given +array_intersect_assoc(): Argument #1 ($array) must be of type array, float given + +-- Iteration 10 --array_intersect_assoc(): Argument #1 ($array) must be of type array, null given +array_intersect_assoc(): Argument #1 ($array) must be of type array, null given + +-- Iteration 11 --array_intersect_assoc(): Argument #1 ($array) must be of type array, null given +array_intersect_assoc(): Argument #1 ($array) must be of type array, null given + +-- Iteration 12 --array_intersect_assoc(): Argument #1 ($array) must be of type array, true given +array_intersect_assoc(): Argument #1 ($array) must be of type array, true given + +-- Iteration 13 --array_intersect_assoc(): Argument #1 ($array) must be of type array, false given +array_intersect_assoc(): Argument #1 ($array) must be of type array, false given + +-- Iteration 14 --array_intersect_assoc(): Argument #1 ($array) must be of type array, true given +array_intersect_assoc(): Argument #1 ($array) must be of type array, true given + +-- Iteration 15 --array_intersect_assoc(): Argument #1 ($array) must be of type array, false given +array_intersect_assoc(): Argument #1 ($array) must be of type array, false given + +-- Iteration 16 --array_intersect_assoc(): Argument #1 ($array) must be of type array, string given +array_intersect_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 17 --array_intersect_assoc(): Argument #1 ($array) must be of type array, string given +array_intersect_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 18 --array_intersect_assoc(): Argument #1 ($array) must be of type array, string given +array_intersect_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 19 --array_intersect_assoc(): Argument #1 ($array) must be of type array, string given +array_intersect_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 20 --array_intersect_assoc(): Argument #1 ($array) must be of type array, string given +array_intersect_assoc(): Argument #1 ($array) must be of type array, string given + +-- Iteration 21 --array_intersect_assoc(): Argument #1 ($array) must be of type array, classA given +array_intersect_assoc(): Argument #1 ($array) must be of type array, classA given + +-- Iteration 22 --array_intersect_assoc(): Argument #1 ($array) must be of type array, null given +array_intersect_assoc(): Argument #1 ($array) must be of type array, null given + +-- Iteration 23 --array_intersect_assoc(): Argument #1 ($array) must be of type array, null given +array_intersect_assoc(): Argument #1 ($array) must be of type array, null given + +-- Iteration 24 --array_intersect_assoc(): Argument #1 ($array) must be of type array, resource given +array_intersect_assoc(): Argument #1 ($array) must be of type array, resource given +Done diff --git a/tests/std/array/array_intersect_assoc_variation10.phpt b/tests/std/array/array_intersect_assoc_variation10.phpt new file mode 100644 index 00000000..8e5c1adc --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation10.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - binary safe checking +--FILE-- + +--EXPECT-- +*** Testing array_intersect_assoc() : binary safe checking *** +array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" +} +array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" +} +array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" +} +Done diff --git a/tests/std/array/array_intersect_assoc_variation2.phpt b/tests/std/array/array_intersect_assoc_variation2.phpt new file mode 100644 index 00000000..73645489 --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation2.phpt @@ -0,0 +1,182 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - unexpected values for 'array2' argument(Bug#43196) +--SKIPIF-- + + +--FILE-- + 1, "two" => 2); + // get an unset variable + $unset_var = 10; + unset($unset_var); + // heredoc string + $heredoc = <<getMessage(), "\n"; + } + // Calling array_intersect_assoc() with more arguments + try { + var_dump(array_intersect_assoc($array1, $unexpected_value, $arr3)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_intersect_assoc() : Passing non-array values to $array2 argument *** + +-- Iteration 1 --array_intersect_assoc(): Argument #2 must be of type array, int given +array_intersect_assoc(): Argument #2 must be of type array, int given + +-- Iteration 2 --array_intersect_assoc(): Argument #2 must be of type array, int given +array_intersect_assoc(): Argument #2 must be of type array, int given + +-- Iteration 3 --array_intersect_assoc(): Argument #2 must be of type array, int given +array_intersect_assoc(): Argument #2 must be of type array, int given + +-- Iteration 4 --array_intersect_assoc(): Argument #2 must be of type array, int given +array_intersect_assoc(): Argument #2 must be of type array, int given + +-- Iteration 5 --array_intersect_assoc(): Argument #2 must be of type array, float given +array_intersect_assoc(): Argument #2 must be of type array, float given + +-- Iteration 6 --array_intersect_assoc(): Argument #2 must be of type array, float given +array_intersect_assoc(): Argument #2 must be of type array, float given + +-- Iteration 7 --array_intersect_assoc(): Argument #2 must be of type array, float given +array_intersect_assoc(): Argument #2 must be of type array, float given + +-- Iteration 8 --array_intersect_assoc(): Argument #2 must be of type array, float given +array_intersect_assoc(): Argument #2 must be of type array, float given + +-- Iteration 9 --array_intersect_assoc(): Argument #2 must be of type array, float given +array_intersect_assoc(): Argument #2 must be of type array, float given + +-- Iteration 10 --array_intersect_assoc(): Argument #2 must be of type array, null given +array_intersect_assoc(): Argument #2 must be of type array, null given + +-- Iteration 11 --array_intersect_assoc(): Argument #2 must be of type array, null given +array_intersect_assoc(): Argument #2 must be of type array, null given + +-- Iteration 12 --array_intersect_assoc(): Argument #2 must be of type array, true given +array_intersect_assoc(): Argument #2 must be of type array, true given + +-- Iteration 13 --array_intersect_assoc(): Argument #2 must be of type array, false given +array_intersect_assoc(): Argument #2 must be of type array, false given + +-- Iteration 14 --array_intersect_assoc(): Argument #2 must be of type array, true given +array_intersect_assoc(): Argument #2 must be of type array, true given + +-- Iteration 15 --array_intersect_assoc(): Argument #2 must be of type array, false given +array_intersect_assoc(): Argument #2 must be of type array, false given + +-- Iteration 16 --array_intersect_assoc(): Argument #2 must be of type array, string given +array_intersect_assoc(): Argument #2 must be of type array, string given + +-- Iteration 17 --array_intersect_assoc(): Argument #2 must be of type array, string given +array_intersect_assoc(): Argument #2 must be of type array, string given + +-- Iteration 18 --array_intersect_assoc(): Argument #2 must be of type array, string given +array_intersect_assoc(): Argument #2 must be of type array, string given + +-- Iteration 19 --array_intersect_assoc(): Argument #2 must be of type array, string given +array_intersect_assoc(): Argument #2 must be of type array, string given + +-- Iteration 20 --array_intersect_assoc(): Argument #2 must be of type array, string given +array_intersect_assoc(): Argument #2 must be of type array, string given + +-- Iteration 21 --array_intersect_assoc(): Argument #2 must be of type array, classA given +array_intersect_assoc(): Argument #2 must be of type array, classA given + +-- Iteration 22 --array_intersect_assoc(): Argument #2 must be of type array, null given +array_intersect_assoc(): Argument #2 must be of type array, null given + +-- Iteration 23 --array_intersect_assoc(): Argument #2 must be of type array, null given +array_intersect_assoc(): Argument #2 must be of type array, null given + +-- Iteration 24 --array_intersect_assoc(): Argument #2 must be of type array, resource given +array_intersect_assoc(): Argument #2 must be of type array, resource given +Done diff --git a/tests/std/array/array_intersect_assoc_variation3.phpt b/tests/std/array/array_intersect_assoc_variation3.phpt new file mode 100644 index 00000000..bb439a05 --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation3.phpt @@ -0,0 +1,237 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - different arrays for 'arr1' argument +--FILE-- +22 +'single quoted string' +"double quoted string" +2222 != 1111.\t 0000 = 0000\n +EOT; + +// arrays to be passed to $arr1 argument +$arrays = array ( +/*1*/ array(1, 2), // with default keys and numeric values + array(1.1, 2.2), // with default keys & float values + array(false,true), // with default keys and boolean values + array(), // empty array +/*5*/ array(NULL), // with NULL + array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // with double quoted strings + array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // with single quoted strings + array("h1" => $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $numeric_string), // with heredocs + + // associative arrays +/*9*/ array(1 => "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values + array("one" => 1, "two" => 2, "three" => 3 ), // string keys & numeric values + array( 1 => 10, 2 => 20, 4 => 40, 3 => 30), // explicit numeric keys and numeric values + array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value + array("one" => 1, 2 => "two", 4 => "four"), //mixed + + // associative array, containing null/empty/boolean values as key/value +/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + + // array with repetitive keys +/*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) +); + + +// array to be passsed to $arr2 argument +$arr2 = array ( + 1, 1.1, 2.2, "hello", "one", NULL, 2, + 'world', true,5 => false, 1 => 'aaaa\r', "aaaa\r", + 'h3' => $diff_whitespaces, $numeric_string, + "one" => "ten", 4 => "four", "two" => 2, + '', null => "null", '' => 'emptys', "emptyd" => "", +); + +// loop through each sub-array within $arrays to check the behavior of array_intersect_assoc() +$iterator = 1; +foreach($arrays as $arr1) { + echo "-- Iteration $iterator --\n"; + + // Calling array_intersect_assoc() with default arguments + var_dump( array_intersect_assoc($arr1, $arr2) ); + + // Calling array_intersect_assoc() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump( array_intersect_assoc($arr1, $arr2, $arr1) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect_assoc() : Passing different types of arrays to $arr1 argument *** +-- Iteration 1 -- +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(1) +} +-- Iteration 2 -- +array(0) { +} +array(0) { +} +-- Iteration 3 -- +array(0) { +} +array(0) { +} +-- Iteration 4 -- +array(0) { +} +array(0) { +} +-- Iteration 5 -- +array(0) { +} +array(0) { +} +-- Iteration 6 -- +array(0) { +} +array(0) { +} +-- Iteration 7 -- +array(1) { + [1]=> + string(6) "aaaa\r" +} +array(1) { + [1]=> + string(6) "aaaa\r" +} +-- Iteration 8 -- +array(1) { + ["h3"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" +} +array(1) { + ["h3"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" +} +-- Iteration 9 -- +array(0) { +} +array(0) { +} +-- Iteration 10 -- +array(1) { + ["two"]=> + int(2) +} +array(1) { + ["two"]=> + int(2) +} +-- Iteration 11 -- +array(0) { +} +array(0) { +} +-- Iteration 12 -- +array(1) { + ["one"]=> + string(3) "ten" +} +array(1) { + ["one"]=> + string(3) "ten" +} +-- Iteration 13 -- +array(1) { + [4]=> + string(4) "four" +} +array(1) { + [4]=> + string(4) "four" +} +-- Iteration 14 -- +array(0) { +} +array(0) { +} +-- Iteration 15 -- +array(0) { +} +array(0) { +} +-- Iteration 16 -- +array(2) { + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" +} +array(2) { + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" +} +-- Iteration 17 -- +array(1) { + [5]=> + bool(false) +} +array(1) { + [5]=> + bool(false) +} +-- Iteration 18 -- +array(0) { +} +array(0) { +} +-- Iteration 19 -- +array(0) { +} +array(0) { +} +Done diff --git a/tests/std/array/array_intersect_assoc_variation4.phpt b/tests/std/array/array_intersect_assoc_variation4.phpt new file mode 100644 index 00000000..859b7280 --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation4.phpt @@ -0,0 +1,248 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - different arrays for 'arr2' argument +--FILE-- +22 +'single quoted string' +"double quoted string" +2222 != 1111.\t 0000 = 0000\n +EOT; + +// array to be passsed to $arr1 argument +$arr1 = array ( + 1, 1.1, 1.3, 1 => true, "hello", "one", NULL, 2, + 'world', true, false, 3 => "b\tbbb", "aaaa\r", + $numeric_string, "h3" => $diff_whitespaces, "true" => true, + "one" => "ten", 4 => "four", "two" => 2, 6 => "six", + '', null => "null", '' => 'emptys' +); + +// arrays to be passed to $arr2 argument +$arrays = array ( +/*1*/ array(1, 2), // array with default keys and numeric values + array(1.1, 1.2, 1.3), // array with default keys & float values + array(false,true), // array with default keys and boolean values + array(), // empty array +/*5*/ array(NULL), // array with NULL + array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // array with double quoted strings + array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // array with single quoted strings + array($blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $numeric_string), // array with heredocs + + // associative arrays +/*9*/ array(1 => "one", 2 => "two", 6 => "six"), // explicit numeric keys, string values + array("one" => 1, "two" => 2, "three" => 3 ), // string keys & numeric values + array( 1 => 10, 2 => 20, 4 => 40, 3 => 30), // explicit numeric keys and numeric values + array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value + array("one" => 1, 2 => "two", 4 => "four"), //mixed + + // associative array, containing null/empty/boolean values as key/value +/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + + // array with repetitive keys +/*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) +); + +// loop through each sub-array within $arrays to check the behavior of array_intersect_assoc() +$iterator = 1; +foreach($arrays as $arr2) { + echo "-- Iteration $iterator --\n"; + + // Calling array_intersect_assoc() with default arguments + var_dump( array_intersect_assoc($arr1, $arr2) ); + + // Calling array_intersect_assoc() with more arguments + // additional argument passed is the same as $arr1 argument + var_dump( array_intersect_assoc($arr1, $arr2, $arr1) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect_assoc() : Passing different types of arrays to $arr2 argument *** +-- Iteration 1 -- +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(1) +} +-- Iteration 2 -- +array(1) { + [2]=> + float(1.3) +} +array(1) { + [2]=> + float(1.3) +} +-- Iteration 3 -- +array(1) { + [1]=> + bool(true) +} +array(1) { + [1]=> + bool(true) +} +-- Iteration 4 -- +array(0) { +} +array(0) { +} +-- Iteration 5 -- +array(0) { +} +array(0) { +} +-- Iteration 6 -- +array(1) { + [3]=> + string(5) "b bbb" +} +array(1) { + [3]=> + string(5) "b bbb" +} +-- Iteration 7 -- +array(0) { +} +array(0) { +} +-- Iteration 8 -- +array(1) { + ["h3"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" +} +array(1) { + ["h3"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" +} +-- Iteration 9 -- +array(1) { + [6]=> + string(3) "six" +} +array(1) { + [6]=> + string(3) "six" +} +-- Iteration 10 -- +array(1) { + ["two"]=> + int(2) +} +array(1) { + ["two"]=> + int(2) +} +-- Iteration 11 -- +array(0) { +} +array(0) { +} +-- Iteration 12 -- +array(1) { + ["one"]=> + string(3) "ten" +} +array(1) { + ["one"]=> + string(3) "ten" +} +-- Iteration 13 -- +array(1) { + [4]=> + string(4) "four" +} +array(1) { + [4]=> + string(4) "four" +} +-- Iteration 14 -- +array(0) { +} +array(0) { +} +-- Iteration 15 -- +array(1) { + ["true"]=> + bool(true) +} +array(1) { + ["true"]=> + bool(true) +} +-- Iteration 16 -- +array(1) { + [""]=> + string(6) "emptys" +} +array(1) { + [""]=> + string(6) "emptys" +} +-- Iteration 17 -- +array(1) { + [5]=> + NULL +} +array(1) { + [5]=> + NULL +} +-- Iteration 18 -- +array(0) { +} +array(0) { +} +-- Iteration 19 -- +array(0) { +} +array(0) { +} +Done diff --git a/tests/std/array/array_intersect_assoc_variation5.phpt b/tests/std/array/array_intersect_assoc_variation5.phpt new file mode 100644 index 00000000..65ce1dae --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation5.phpt @@ -0,0 +1,139 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - assoc array with diff keys for 'arr1' argument +--FILE-- + "0"), + array(1 => "1"), + array(1 => "1", 2 => "2", 3 => "3", 4 => "4"), + + // arrays with string keys +/*7*/ array('\tHello' => 111, 're\td' => "color", + '\v\fworld' => 2.2, 'pen\n' => 33), + array("\tHello" => 111, "re\td" => "color", + "\v\fworld" => 2.2, "pen\n" => 33), + array("hello", $heredoc => "string"), // heredoc + + // array with object, unset variable and resource variable +/*10*/ array(@$unset_var => "hello"), + + // array with mixed keys +/*11*/ array('hello' => 1, "fruit" => 2.2, + 133 => "int", + @$unset_var => "unset", $heredoc => "heredoc") +); + +// array to be passed to $arr2 argument +$arr2 = array(0 => 0, 2 => "float", 4 => "f3", 33333333 => "f4", + "\tHello" => 111, 2.2, 'color', "Hello world" => "string", + "pen\n" => 33, 133 => "int"); + +// loop through each sub-array within $arrays to check the behavior of array_intersect_assoc() +$iterator = 1; +foreach($arrays as $arr1) { + echo "-- Iteration $iterator --\n"; + + // Calling array_intersect_assoc() with default arguments + var_dump( array_intersect_assoc($arr1, $arr2) ); + + // Calling array_intersect_assoc() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump( array_intersect_assoc($arr1, $arr2, $arr1) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect_assoc() : assoc array with diff keys to $arr1 argument *** +-- Iteration 1 -- +array(0) { +} +array(0) { +} +-- Iteration 2 -- +array(1) { + [0]=> + string(1) "0" +} +array(1) { + [0]=> + string(1) "0" +} +-- Iteration 3 -- +array(0) { +} +array(0) { +} +-- Iteration 4 -- +array(0) { +} +array(0) { +} +-- Iteration 5 -- +array(0) { +} +array(0) { +} +-- Iteration 6 -- +array(2) { + [" Hello"]=> + int(111) + ["pen +"]=> + int(33) +} +array(2) { + [" Hello"]=> + int(111) + ["pen +"]=> + int(33) +} +-- Iteration 7 -- +array(1) { + ["Hello world"]=> + string(6) "string" +} +array(1) { + ["Hello world"]=> + string(6) "string" +} +-- Iteration 8 -- +array(0) { +} +array(0) { +} +-- Iteration 9 -- +array(1) { + [133]=> + string(3) "int" +} +array(1) { + [133]=> + string(3) "int" +} +Done diff --git a/tests/std/array/array_intersect_assoc_variation6.phpt b/tests/std/array/array_intersect_assoc_variation6.phpt new file mode 100644 index 00000000..f446c687 --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation6.phpt @@ -0,0 +1,139 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - assoc array with diff keys for 'arr2' argument +--FILE-- + "0"), + array(1 => "1"), + array(1 => "1", 2 => "2", 3 => "3", 4 => "4"), + + // arrays with string keys +/*7*/ array('\tHello' => 111, 're\td' => "color", + '\v\fworld' => 2.2, 'pen\n' => 33), + array("\tHello" => 111, "re\td" => "color", + "\v\fworld" => 2.2, "pen\n" => 33), + array("hello", $heredoc => "string"), // heredoc + + // array with unset variable +/*10*/ array( @$unset_var => "hello"), + + // array with mixed keys +/*11*/ array('hello' => 1, "fruit" => 2.2, + 133 => "int", + @$unset_var => "unset", $heredoc => "heredoc") +); + +// array to be passed to $arr1 argument +$arr1 = array(0 => 0, 2 => "float", 4 => "f3", 33333333 => "f4", + "\tHello" => 111, 2.2, 'color', "Hello world" => "string", + "pen\n" => 33, 133 => "int"); + +// loop through each sub-array within $arrays to check the behavior of array_intersect_assoc() +$iterator = 1; +foreach($arrays as $arr2) { + echo "-- Iteration $iterator --\n"; + + // Calling array_intersect_assoc() with default arguments + var_dump( array_intersect_assoc($arr1, $arr2) ); + + // Calling array_intersect_assoc() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump( array_intersect_assoc($arr1, $arr2, $arr1) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect_assoc() : assoc array with diff keys to $arr2 argument *** +-- Iteration 1 -- +array(0) { +} +array(0) { +} +-- Iteration 2 -- +array(1) { + [0]=> + int(0) +} +array(1) { + [0]=> + int(0) +} +-- Iteration 3 -- +array(0) { +} +array(0) { +} +-- Iteration 4 -- +array(0) { +} +array(0) { +} +-- Iteration 5 -- +array(0) { +} +array(0) { +} +-- Iteration 6 -- +array(2) { + [" Hello"]=> + int(111) + ["pen +"]=> + int(33) +} +array(2) { + [" Hello"]=> + int(111) + ["pen +"]=> + int(33) +} +-- Iteration 7 -- +array(1) { + ["Hello world"]=> + string(6) "string" +} +array(1) { + ["Hello world"]=> + string(6) "string" +} +-- Iteration 8 -- +array(0) { +} +array(0) { +} +-- Iteration 9 -- +array(1) { + [133]=> + string(3) "int" +} +array(1) { + [133]=> + string(3) "int" +} +Done diff --git a/tests/std/array/array_intersect_assoc_variation7.phpt b/tests/std/array/array_intersect_assoc_variation7.phpt new file mode 100644 index 00000000..a1171fb9 --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation7.phpt @@ -0,0 +1,191 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - assoc array with diff values for 'arr1' argument +--FILE-- + 0), + array("1" => 1), + array("one" => 1, 'two' => 2, "three" => 3, 4 => 4), + // arrays with float values + /*5*/ + array("float" => 2.3333), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => 33333333.333), + // arrays with string values + /*7*/ + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "pen\n"), + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => 'pen\n'), + array(1 => "hello", "heredoc" => $heredoc), + // array with object, unset variable and resource variable + /*10*/ + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp), + // array with mixed values + /*11*/ + array(1 => 'hello', 2 => new classA(), 222 => "fruit", 'resource' => $fp, "int" => 133, "float" => 444.432, "unset" => @$unset_var, "heredoc" => $heredoc), + ); + // array to be passsed to $arr2 argument + $arr2 = array(0 => "0", 1, "two" => 2, "float" => 2.3333, "f1" => 1.2, "f4" => 33333333.333, 111 => "\tHello", 3 => 'pen\n', '\v\fworld', "heredoc" => "Hello world", 11 => new classA(), "resource" => $fp, "int" => 133, 222 => "fruit"); + // loop through each sub-array within $arrays to check the behavior of array_intersect_assoc() + $iterator = 1; + foreach ($arrays as $arr1) { + echo "-- Iteration {$iterator} --\n"; + // Calling array_intersect_assoc() with default arguments + var_dump(array_intersect_assoc($arr1, $arr2)); + // Calling array_intersect_assoc() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump(array_intersect_assoc($arr1, $arr2, $arr1)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_intersect_assoc() : assoc array with diff values to $arr1 argument *** +-- Iteration 1 -- +array(0) { +} +array(0) { +} +-- Iteration 2 -- +array(1) { + [0]=> + int(0) +} +array(1) { + [0]=> + int(0) +} +-- Iteration 3 -- +array(1) { + [1]=> + int(1) +} +array(1) { + [1]=> + int(1) +} +-- Iteration 4 -- +array(1) { + ["two"]=> + int(2) +} +array(1) { + ["two"]=> + int(2) +} +-- Iteration 5 -- +array(1) { + ["float"]=> + float(2.3333) +} +array(1) { + ["float"]=> + float(2.3333) +} +-- Iteration 6 -- +array(2) { + ["f1"]=> + float(1.2) + ["f4"]=> + float(33333333.333) +} +array(2) { + ["f1"]=> + float(1.2) + ["f4"]=> + float(33333333.333) +} +-- Iteration 7 -- +array(1) { + [111]=> + string(6) " Hello" +} +array(1) { + [111]=> + string(6) " Hello" +} +-- Iteration 8 -- +array(1) { + [3]=> + string(5) "pen\n" +} +array(1) { + [3]=> + string(5) "pen\n" +} +-- Iteration 9 -- +array(1) { + ["heredoc"]=> + string(11) "Hello world" +} +array(1) { + ["heredoc"]=> + string(11) "Hello world" +} +-- Iteration 10 -- +array(2) { + [11]=> + object(classA)#%d (0) { + } + ["resource"]=> + resource(%d) of type (stream) +} +array(2) { + [11]=> + object(classA)#%d (0) { + } + ["resource"]=> + resource(%d) of type (stream) +} +-- Iteration 11 -- +array(4) { + [222]=> + string(5) "fruit" + ["resource"]=> + resource(%d) of type (stream) + ["int"]=> + int(133) + ["heredoc"]=> + string(11) "Hello world" +} +array(4) { + [222]=> + string(5) "fruit" + ["resource"]=> + resource(%d) of type (stream) + ["int"]=> + int(133) + ["heredoc"]=> + string(11) "Hello world" +} +Done diff --git a/tests/std/array/array_intersect_assoc_variation8.phpt b/tests/std/array/array_intersect_assoc_variation8.phpt new file mode 100644 index 00000000..4d252349 --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation8.phpt @@ -0,0 +1,191 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - assoc array with diff values for 'arr2' argument +--FILE-- + 0), + array("1" => 1), + array("one" => 1, 'two' => 2, "three" => 3, 4 => 4), + // arrays with float values + /*5*/ + array("float" => 2.3333), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => 33333333.333), + // arrays with string values + /*7*/ + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "pen\n"), + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => 'pen\n'), + array(1 => "hello", "heredoc" => $heredoc), + // array with object, unset variable and resource variable + /*10*/ + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp), + // array with mixed values + /*11*/ + array(1 => 'hello', 2 => new classA(), 222 => "fruit", 'resource' => $fp, "int" => 133, "float" => 444.432, "unset" => @$unset_var, "heredoc" => $heredoc), + ); + // array to be passsed to $arr1 argument + $arr1 = array(0 => "0", 1, "two" => 2, "float" => 2.3333, "f1" => 1.2, "f4" => 33333333.333, 111 => "\tHello", 3 => 'pen\n', '\v\fworld', "heredoc" => "Hello world", 11 => new classA(), "resource" => $fp, "int" => 133, 222 => "fruit"); + // loop through each sub-array within $arrays to check the behavior of array_intersect_assoc() + $iterator = 1; + foreach ($arrays as $arr2) { + echo "-- Iteration {$iterator} --\n"; + // Calling array_intersect_assoc() with default arguments + var_dump(array_intersect_assoc($arr1, $arr2)); + // Calling array_intersect_assoc() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump(array_intersect_assoc($arr1, $arr2, $arr1)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_intersect_assoc() : assoc array with diff values to $arr2 argument *** +-- Iteration 1 -- +array(0) { +} +array(0) { +} +-- Iteration 2 -- +array(1) { + [0]=> + string(1) "0" +} +array(1) { + [0]=> + string(1) "0" +} +-- Iteration 3 -- +array(1) { + [1]=> + int(1) +} +array(1) { + [1]=> + int(1) +} +-- Iteration 4 -- +array(1) { + ["two"]=> + int(2) +} +array(1) { + ["two"]=> + int(2) +} +-- Iteration 5 -- +array(1) { + ["float"]=> + float(2.3333) +} +array(1) { + ["float"]=> + float(2.3333) +} +-- Iteration 6 -- +array(2) { + ["f1"]=> + float(1.2) + ["f4"]=> + float(33333333.333) +} +array(2) { + ["f1"]=> + float(1.2) + ["f4"]=> + float(33333333.333) +} +-- Iteration 7 -- +array(1) { + [111]=> + string(6) " Hello" +} +array(1) { + [111]=> + string(6) " Hello" +} +-- Iteration 8 -- +array(1) { + [3]=> + string(5) "pen\n" +} +array(1) { + [3]=> + string(5) "pen\n" +} +-- Iteration 9 -- +array(1) { + ["heredoc"]=> + string(11) "Hello world" +} +array(1) { + ["heredoc"]=> + string(11) "Hello world" +} +-- Iteration 10 -- +array(2) { + [11]=> + object(classA)#%d (0) { + } + ["resource"]=> + resource(%d) of type (stream) +} +array(2) { + [11]=> + object(classA)#%d (0) { + } + ["resource"]=> + resource(%d) of type (stream) +} +-- Iteration 11 -- +array(4) { + ["heredoc"]=> + string(11) "Hello world" + ["resource"]=> + resource(%d) of type (stream) + ["int"]=> + int(133) + [222]=> + string(5) "fruit" +} +array(4) { + ["heredoc"]=> + string(11) "Hello world" + ["resource"]=> + resource(%d) of type (stream) + ["int"]=> + int(133) + [222]=> + string(5) "fruit" +} +Done diff --git a/tests/std/array/array_intersect_assoc_variation9.phpt b/tests/std/array/array_intersect_assoc_variation9.phpt new file mode 100644 index 00000000..86d0e8e7 --- /dev/null +++ b/tests/std/array/array_intersect_assoc_variation9.phpt @@ -0,0 +1,146 @@ +--TEST-- +Test array_intersect_assoc() function : usage variations - two dimensional arrays for $arr1 and $arr2 arguments +--FILE-- + "one", 2 => "two", 3 => "three"), + array("ten" => 10, "twenty" => 20.00, "thirty" => 30) +); + +$arr2 = array ( + array(1, 2, 3, 4), + array(1 => "one", 2 => "two", 3 => "three") +); + +/* Passing the entire array as argument to $arr1 and $arr2 */ +// Calling array_intersect_assoc() with default arguments +echo "-- Passing the entire 2-D array to \$arr1 and \$arr2 --\n"; +echo "- With default arguments -\n"; +var_dump( array_intersect_assoc($arr1, $arr2) ); + +// Calling array_intersect_assoc() with more arguments +// additional argument passed is the same as $arr1 +echo "- With more arguments -\n"; +var_dump( array_intersect_assoc($arr1, $arr2, $arr1) ); + +/* Passing the sub-array as argument to $arr1 and $arr2 */ +// Calling array_intersect_assoc() with default arguments +echo "-- Passing the sub-array to \$arr1 and \$arr2 --\n"; +echo "- With default arguments -\n"; +var_dump( array_intersect_assoc($arr1[0], $arr2[0]) ); + +// Calling array_intersect_assoc() with more arguments +// additional argument passed is the same as $arr1 +echo "- With more arguments -\n"; +var_dump( array_intersect_assoc($arr1[0], $arr2[0], $arr1[0]) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_intersect_assoc() : passing two dimensional array to both $arr1 and $arr2 arguments *** +-- Passing the entire 2-D array to $arr1 and $arr2 -- +- With default arguments - + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d +array(2) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(5) "hello" + [3]=> + string(5) "world" + } + [1]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } +} +- With more arguments - + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d +array(2) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(5) "hello" + [3]=> + string(5) "world" + } + [1]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } +} +-- Passing the sub-array to $arr1 and $arr2 -- +- With default arguments - +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +- With more arguments - +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +Done diff --git a/tests/std/array/array_intersect_basic.phpt b/tests/std/array/array_intersect_basic.phpt new file mode 100644 index 00000000..86ef64e1 --- /dev/null +++ b/tests/std/array/array_intersect_basic.phpt @@ -0,0 +1,75 @@ +--TEST-- +Test array_intersect() function : basic functionality +--FILE-- + 1, "two" => 2); + +// default key array for both $arr1 and $arr2 argument +var_dump( array_intersect($arr_default_keys, $arr_default_keys) ); + +// default key array for $arr1 and associative array for $arr2 argument +var_dump( array_intersect($arr_default_keys, $arr_associative) ); + +// associative array for $arr1 and default key array for $arr2 +var_dump( array_intersect($arr_associative, $arr_default_keys) ); + +// associative array for both $arr1 and $arr2 argument +var_dump( array_intersect($arr_associative, $arr_associative) ); + +// more arrays to be intersected +$arr3 = array(2, 3, 4); +var_dump( array_intersect($arr_default_keys, $arr_associative, $arr3) ); +var_dump( array_intersect($arr_associative, $arr_default_keys, $arr3, $arr_associative) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect() : basic functionality *** +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(5) "hello" + [3]=> + string(5) "world" +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(1) { + [1]=> + int(2) +} +array(1) { + ["two"]=> + int(2) +} +Done diff --git a/tests/std/array/array_intersect_key.phpt b/tests/std/array/array_intersect_key.phpt new file mode 100644 index 00000000..a8b55156 --- /dev/null +++ b/tests/std/array/array_intersect_key.phpt @@ -0,0 +1,228 @@ +--TEST-- +Test of the array_intersect_key() and array_intersect_ukey() +--FILE-- + $b ? 1 : -1; +} +function main() +{ + $a = array(1, 6, 2, -20, 15, 1200, -2500); + $b = array(0, 7, 2, -20, 11, 1100, -2500); + $c = array(0, 6, 2, -20, 19, 1000, -2500); + $d = array(3, 8, -2, -20, 14, 900, -2600); + $a_f = array_flip($a); + $b_f = array_flip($b); + $c_f = array_flip($c); + $d_f = array_flip($d); + /* give nicer values */ + foreach ($a_f as $k => &$a_f_el) { + $a_f_el = $k * 2; + } + foreach ($b_f as $k => &$b_f_el) { + $b_f_el = $k * 2; + } + foreach ($c_f as $k => &$c_f_el) { + $c_f_el = $k * 2; + } + foreach ($d_f as $k => &$d_f_el) { + $d_f_el = $k * 2; + } + var_dump(array_intersect_key($a_f, $b_f)); + // keys -> 2, -20, -2500 + var_dump(array_intersect_ukey($a_f, $b_f, "comp_func")); + // 2, 20, -2500 + var_dump(array_intersect_key($a_f, $c_f)); + // keys -> 6, 2, -20, -2500 + var_dump(array_intersect_ukey($a_f, $c_f, "comp_func")); + // 6, 2, -20, -2500 + var_dump(array_intersect_key($a_f, $d_f)); + // -20 + var_dump(array_intersect_ukey($a_f, $d_f, "comp_func")); + // -20 + var_dump(array_intersect_key($a_f, $b_f, $c_f)); + // 2, -20, -2500 + var_dump(array_intersect_ukey($a_f, $b_f, $c_f, "comp_func")); + // 2, -20, -2500 + var_dump(array_intersect_key($a_f, $b_f, $d_f)); + // -20 + var_dump(array_intersect_ukey($a_f, $b_f, $d_f, "comp_func")); + // -20 + var_dump(array_intersect_key($a_f, $b_f, $c_f, $d_f)); + // -20 + var_dump(array_intersect_ukey($a_f, $b_f, $c_f, $d_f, "comp_func")); + //-20 + var_dump(array_intersect_key($b_f, $c_f)); + // 0, 2, -20, -2500 + var_dump(array_intersect_ukey($b_f, $c_f, "comp_func")); + //0, 2, -20, 2500 + var_dump(array_intersect_key($b_f, $d_f)); + // -20 + var_dump(array_intersect_ukey($b_f, $d_f, "comp_func")); + // -20 + var_dump(array_intersect_key($b_f, $c_f, $d_f)); + // -20 + var_dump(array_intersect_ukey($b_f, $c_f, $d_f, "comp_func")); + // -20 + echo "----- Now testing array_intersect() ------- \n"; + var_dump(array_intersect($a, $b_f)); + var_dump(array_uintersect($a, $b, "comp_func")); + var_dump(array_intersect($a, $b, $c)); + var_dump(array_uintersect($a, $b, $c, "comp_func")); + var_dump(array_intersect($a, $b, $c, $d)); + var_dump(array_uintersect($a, $b, $c, $d, "comp_func")); +} +?> +--EXPECT-- +array(3) { + [2]=> + int(4) + [-20]=> + int(-40) + [-2500]=> + &int(-5000) +} +array(3) { + [2]=> + int(4) + [-20]=> + int(-40) + [-2500]=> + &int(-5000) +} +array(4) { + [6]=> + int(12) + [2]=> + int(4) + [-20]=> + int(-40) + [-2500]=> + &int(-5000) +} +array(4) { + [6]=> + int(12) + [2]=> + int(4) + [-20]=> + int(-40) + [-2500]=> + &int(-5000) +} +array(1) { + [-20]=> + int(-40) +} +array(1) { + [-20]=> + int(-40) +} +array(3) { + [2]=> + int(4) + [-20]=> + int(-40) + [-2500]=> + &int(-5000) +} +array(3) { + [2]=> + int(4) + [-20]=> + int(-40) + [-2500]=> + &int(-5000) +} +array(1) { + [-20]=> + int(-40) +} +array(1) { + [-20]=> + int(-40) +} +array(1) { + [-20]=> + int(-40) +} +array(1) { + [-20]=> + int(-40) +} +array(4) { + [0]=> + int(0) + [2]=> + int(4) + [-20]=> + int(-40) + [-2500]=> + &int(-5000) +} +array(4) { + [0]=> + int(0) + [2]=> + int(4) + [-20]=> + int(-40) + [-2500]=> + &int(-5000) +} +array(1) { + [-20]=> + int(-40) +} +array(1) { + [-20]=> + int(-40) +} +array(1) { + [-20]=> + int(-40) +} +array(1) { + [-20]=> + int(-40) +} +----- Now testing array_intersect() ------- +array(0) { +} +array(3) { + [2]=> + int(2) + [3]=> + int(-20) + [6]=> + int(-2500) +} +array(3) { + [2]=> + int(2) + [3]=> + int(-20) + [6]=> + int(-2500) +} +array(3) { + [2]=> + int(2) + [3]=> + int(-20) + [6]=> + int(-2500) +} +array(1) { + [3]=> + int(-20) +} +array(1) { + [3]=> + int(-20) +} diff --git a/tests/std/array/array_intersect_key_basic.phpt b/tests/std/array/array_intersect_key_basic.phpt new file mode 100644 index 00000000..4c650441 --- /dev/null +++ b/tests/std/array/array_intersect_key_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +array_intersect_key(): Basic Test +--FILE-- + 1, 'red' => 2, 'green' => 3, 'purple' => 4); +$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); +var_dump(array_intersect_key($array1, $array2)); +?> +--EXPECT-- +array(2) { + ["blue"]=> + int(1) + ["green"]=> + int(3) +} diff --git a/tests/std/array/array_intersect_key_variation1.phpt b/tests/std/array/array_intersect_key_variation1.phpt new file mode 100644 index 00000000..8e28a3b6 --- /dev/null +++ b/tests/std/array/array_intersect_key_variation1.phpt @@ -0,0 +1,199 @@ +--TEST-- +Test array_intersect_key() function : usage variation - Passing unexpected values to first argument +--SKIPIF-- + + +--FILE-- + 1, 'red' => 2, 'green' => 3, 'purple' => 4); + $array3 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -12345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource var' => $fp, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_intersect_key($value, $array2)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_intersect_key($value, $array2, $array3)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_intersect_key() : usage variation *** + +--int 0-- +array_intersect_key(): Argument #1 ($array) must be of type array, int given +array_intersect_key(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_intersect_key(): Argument #1 ($array) must be of type array, int given +array_intersect_key(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_intersect_key(): Argument #1 ($array) must be of type array, int given +array_intersect_key(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_intersect_key(): Argument #1 ($array) must be of type array, int given +array_intersect_key(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_intersect_key(): Argument #1 ($array) must be of type array, float given +array_intersect_key(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_intersect_key(): Argument #1 ($array) must be of type array, float given +array_intersect_key(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_intersect_key(): Argument #1 ($array) must be of type array, float given +array_intersect_key(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_intersect_key(): Argument #1 ($array) must be of type array, float given +array_intersect_key(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_intersect_key(): Argument #1 ($array) must be of type array, float given +array_intersect_key(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_intersect_key(): Argument #1 ($array) must be of type array, null given +array_intersect_key(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_intersect_key(): Argument #1 ($array) must be of type array, null given +array_intersect_key(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_intersect_key(): Argument #1 ($array) must be of type array, true given +array_intersect_key(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_intersect_key(): Argument #1 ($array) must be of type array, false given +array_intersect_key(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_intersect_key(): Argument #1 ($array) must be of type array, true given +array_intersect_key(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_intersect_key(): Argument #1 ($array) must be of type array, false given +array_intersect_key(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_intersect_key(): Argument #1 ($array) must be of type array, string given +array_intersect_key(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_intersect_key(): Argument #1 ($array) must be of type array, string given +array_intersect_key(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_intersect_key(): Argument #1 ($array) must be of type array, string given +array_intersect_key(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_intersect_key(): Argument #1 ($array) must be of type array, string given +array_intersect_key(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_intersect_key(): Argument #1 ($array) must be of type array, string given +array_intersect_key(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_intersect_key(): Argument #1 ($array) must be of type array, string given +array_intersect_key(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_intersect_key(): Argument #1 ($array) must be of type array, classWithToString given +array_intersect_key(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_intersect_key(): Argument #1 ($array) must be of type array, classWithoutToString given +array_intersect_key(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_intersect_key(): Argument #1 ($array) must be of type array, null given +array_intersect_key(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_intersect_key(): Argument #1 ($array) must be of type array, null given +array_intersect_key(): Argument #1 ($array) must be of type array, null given + +--resource var-- +array_intersect_key(): Argument #1 ($array) must be of type array, resource given +array_intersect_key(): Argument #1 ($array) must be of type array, resource given diff --git a/tests/std/array/array_intersect_key_variation2.phpt b/tests/std/array/array_intersect_key_variation2.phpt new file mode 100644 index 00000000..fd3acf83 --- /dev/null +++ b/tests/std/array/array_intersect_key_variation2.phpt @@ -0,0 +1,199 @@ +--TEST-- +Test array_intersect_key() function : usage variation - Passing unexpected values to second argument +--SKIPIF-- + + +--FILE-- + 1, 'red' => 2, 'green' => 3, 'purple' => 4); + $array3 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -12345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource var' => $fp, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_intersect_key($array1, $value)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_intersect_key($array1, $value, $array3)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_intersect_key() : usage variation *** + +--int 0-- +array_intersect_key(): Argument #2 must be of type array, int given +array_intersect_key(): Argument #2 must be of type array, int given + +--int 1-- +array_intersect_key(): Argument #2 must be of type array, int given +array_intersect_key(): Argument #2 must be of type array, int given + +--int 12345-- +array_intersect_key(): Argument #2 must be of type array, int given +array_intersect_key(): Argument #2 must be of type array, int given + +--int -12345-- +array_intersect_key(): Argument #2 must be of type array, int given +array_intersect_key(): Argument #2 must be of type array, int given + +--float 10.5-- +array_intersect_key(): Argument #2 must be of type array, float given +array_intersect_key(): Argument #2 must be of type array, float given + +--float -10.5-- +array_intersect_key(): Argument #2 must be of type array, float given +array_intersect_key(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_intersect_key(): Argument #2 must be of type array, float given +array_intersect_key(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_intersect_key(): Argument #2 must be of type array, float given +array_intersect_key(): Argument #2 must be of type array, float given + +--float .5-- +array_intersect_key(): Argument #2 must be of type array, float given +array_intersect_key(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_intersect_key(): Argument #2 must be of type array, null given +array_intersect_key(): Argument #2 must be of type array, null given + +--lowercase null-- +array_intersect_key(): Argument #2 must be of type array, null given +array_intersect_key(): Argument #2 must be of type array, null given + +--lowercase true-- +array_intersect_key(): Argument #2 must be of type array, true given +array_intersect_key(): Argument #2 must be of type array, true given + +--lowercase false-- +array_intersect_key(): Argument #2 must be of type array, false given +array_intersect_key(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_intersect_key(): Argument #2 must be of type array, true given +array_intersect_key(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_intersect_key(): Argument #2 must be of type array, false given +array_intersect_key(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_intersect_key(): Argument #2 must be of type array, string given +array_intersect_key(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_intersect_key(): Argument #2 must be of type array, string given +array_intersect_key(): Argument #2 must be of type array, string given + +--string DQ-- +array_intersect_key(): Argument #2 must be of type array, string given +array_intersect_key(): Argument #2 must be of type array, string given + +--string SQ-- +array_intersect_key(): Argument #2 must be of type array, string given +array_intersect_key(): Argument #2 must be of type array, string given + +--mixed case string-- +array_intersect_key(): Argument #2 must be of type array, string given +array_intersect_key(): Argument #2 must be of type array, string given + +--heredoc-- +array_intersect_key(): Argument #2 must be of type array, string given +array_intersect_key(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_intersect_key(): Argument #2 must be of type array, classWithToString given +array_intersect_key(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_intersect_key(): Argument #2 must be of type array, classWithoutToString given +array_intersect_key(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_intersect_key(): Argument #2 must be of type array, null given +array_intersect_key(): Argument #2 must be of type array, null given + +--unset var-- +array_intersect_key(): Argument #2 must be of type array, null given +array_intersect_key(): Argument #2 must be of type array, null given + +--resource var-- +array_intersect_key(): Argument #2 must be of type array, resource given +array_intersect_key(): Argument #2 must be of type array, resource given diff --git a/tests/std/array/array_intersect_key_variation4.phpt b/tests/std/array/array_intersect_key_variation4.phpt new file mode 100644 index 00000000..50b2828f --- /dev/null +++ b/tests/std/array/array_intersect_key_variation4.phpt @@ -0,0 +1,53 @@ +--TEST-- +Test array_intersect_key() function : usage variation - Passing integer indexed array +--FILE-- + '0', -1 => '-1' , 02 => 'two', -07 => '-07', 0xA => '0xA', -0xC => '-0xc'); + +$input_arrays = array( + 'decimal indexed' => array(10 => '10', '-17' => '-17'), + 'octal indexed' => array(-011 => '-011', 012 => '012'), + 'hexa indexed' => array(0x12 => '0x12', -0x7 => '-0x7', ), +); + +foreach($input_arrays as $key =>$value) { + echo "\n--$key--\n"; + var_dump( array_intersect_key($input_array, $value) ); + var_dump( array_intersect_key($value,$input_array ) ); +} +?> +--EXPECT-- +*** Testing array_intersect_key() : usage variation *** + +--decimal indexed-- +array(1) { + [10]=> + string(3) "0xA" +} +array(1) { + [10]=> + string(2) "10" +} + +--octal indexed-- +array(1) { + [10]=> + string(3) "0xA" +} +array(1) { + [10]=> + string(3) "012" +} + +--hexa indexed-- +array(1) { + [-7]=> + string(3) "-07" +} +array(1) { + [-7]=> + string(4) "-0x7" +} diff --git a/tests/std/array/array_intersect_key_variation6.phpt b/tests/std/array/array_intersect_key_variation6.phpt new file mode 100644 index 00000000..b0113628 --- /dev/null +++ b/tests/std/array/array_intersect_key_variation6.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test array_intersect_key() function : usage variation - Passing boolean indexed array +--SKIPIF-- +--FILE-- + '0', 1 => '1' , -10 => '-10'); +$boolean_indx_array = array(true => 'boolt', false => 'boolf', TRUE => 'boolT', FALSE => 'boolF'); + +echo "\n-- Testing array_intersect_key() function with boolean indexed array --\n"; +var_dump( array_intersect_key($input_array, $boolean_indx_array) ); +var_dump( array_intersect_key($boolean_indx_array,$input_array ) ); +?> +--EXPECT-- +*** Testing array_intersect_key() : usage variation *** + +-- Testing array_intersect_key() function with boolean indexed array -- +array(2) { + [0]=> + string(1) "0" + [1]=> + string(1) "1" +} +array(2) { + [1]=> + string(5) "boolT" + [0]=> + string(5) "boolF" +} diff --git a/tests/std/array/array_intersect_key_variation7.phpt b/tests/std/array/array_intersect_key_variation7.phpt new file mode 100644 index 00000000..06126612 --- /dev/null +++ b/tests/std/array/array_intersect_key_variation7.phpt @@ -0,0 +1,61 @@ +--TEST-- +Test array_intersect_key() function : usage variation - Passing null,unset and undefeined variable indexed array +--SKIPIF-- + + +--FILE-- + '0', 1 => '1' , -10 => '-10' , null => 'null'); +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +$input_arrays = array( + 'null indexed' => array(NULL => 'null 1', null => 'null 2'), + 'undefined indexed' => array(@$undefined_var => 'undefined'), + 'unset indexed' => array(@$unset_var => 'unset'), +); + +foreach($input_arrays as $key =>$value) { + echo "\n--$key--\n"; + var_dump( array_intersect_key($input_array, $value) ); + var_dump( array_intersect_key($value,$input_array ) ); +} +?> +--EXPECT-- +*** Testing array_intersect_key() : usage variation *** + +--null indexed-- +array(1) { + [""]=> + string(4) "null" +} +array(1) { + [""]=> + string(6) "null 2" +} + +--undefined indexed-- +array(1) { + [""]=> + string(4) "null" +} +array(1) { + [""]=> + string(9) "undefined" +} + +--unset indexed-- +array(1) { + [""]=> + string(4) "null" +} +array(1) { + [""]=> + string(5) "unset" +} diff --git a/tests/std/array/array_intersect_key_variation8.phpt b/tests/std/array/array_intersect_key_variation8.phpt new file mode 100644 index 00000000..b16c324d --- /dev/null +++ b/tests/std/array/array_intersect_key_variation8.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test array_intersect_key() function : usage variation - Passing Multi dimensional array +--FILE-- + array('blue' => 1, 'red' => 2), + + 'second' => array('yellow' => 7), + + 'third' => array(0 =>'zero'), +); + +$array2 = array ( + + 'first' => array('blue' => 1, 'red' => 2,), + + 'second' => array('cyan' => 8), + + 'fourth' => array(2 => 'two'), +); +var_dump( array_intersect_key($array1, $array2) ); +var_dump( array_intersect_key($array2,$array1 ) ); +?> +--EXPECT-- +*** Testing array_intersect_key() : usage variation *** +array(2) { + ["first"]=> + array(2) { + ["blue"]=> + int(1) + ["red"]=> + int(2) + } + ["second"]=> + array(1) { + ["yellow"]=> + int(7) + } +} +array(2) { + ["first"]=> + array(2) { + ["blue"]=> + int(1) + ["red"]=> + int(2) + } + ["second"]=> + array(1) { + ["cyan"]=> + int(8) + } +} diff --git a/tests/std/array/array_intersect_uassoc_basic.phpt b/tests/std/array/array_intersect_uassoc_basic.phpt new file mode 100644 index 00000000..7721772d --- /dev/null +++ b/tests/std/array/array_intersect_uassoc_basic.phpt @@ -0,0 +1,28 @@ +--TEST-- +array_intersect_uassoc(): Basic test +--FILE-- + $b ? 1 : -1; +} +function main() +{ + $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red"); + $array2 = array("a" => "green", "yellow", "red"); + $result = array_intersect_uassoc($array1, $array2, "key_compare_func"); + var_dump($result); +} +?> +--EXPECT-- +array(1) { + ["a"]=> + string(5) "green" +} diff --git a/tests/std/array/array_intersect_uassoc_variation1.phpt b/tests/std/array/array_intersect_uassoc_variation1.phpt new file mode 100644 index 00000000..c5bbded7 --- /dev/null +++ b/tests/std/array/array_intersect_uassoc_variation1.phpt @@ -0,0 +1,207 @@ +--TEST-- +Test array_intersect_uassoc() function : usage variation - Passing unexpected values to first argument +--SKIPIF-- + + +--FILE-- + $b ? 1 : -1; +} +// define some classes +class classWithToString +{ + public function __toString(): string { + return "Class A object"; + } +} +class classWithoutToString +{ +} +function main() +{ + echo "*** Testing array_intersect_uassoc() : usage variation ***\n"; + // Initialise function arguments + $array2 = array("a" => "green", "yellow", "red"); + $array3 = array("a" => "green", "brown"); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -12345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource' => $fp, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_intersect_uassoc($value, $array2, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_intersect_uassoc($value, $array2, $array3, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_intersect_uassoc() : usage variation *** + +--int 0-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, int given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, int given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, int given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, int given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, null given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, null given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, true given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, false given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, true given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, false given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, classWithToString given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, classWithoutToString given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, null given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, null given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, null given + +--resource-- +array_intersect_uassoc(): Argument #1 ($array) must be of type array, resource given +array_intersect_uassoc(): Argument #1 ($array) must be of type array, resource given diff --git a/tests/std/array/array_intersect_uassoc_variation10.phpt b/tests/std/array/array_intersect_uassoc_variation10.phpt new file mode 100644 index 00000000..c18a90aa --- /dev/null +++ b/tests/std/array/array_intersect_uassoc_variation10.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test array_intersect_uassoc() function : usage variation - Passing class/object methods to callback +--FILE-- + "green", "c" => "blue", "red"); + $array2 = array("a" => "green", "yellow", "red"); + echo "\n-- Testing array_intersect_uassoc() function using class with static method as callback --\n"; + var_dump(array_intersect_uassoc($array1, $array2, array('MyClass', 'static_compare_func'))); + var_dump(array_intersect_uassoc($array1, $array2, 'MyClass::static_compare_func')); + echo "\n-- Testing array_intersect_uassoc() function using class with regular method as callback --\n"; + $obj = new MyClass(); + var_dump(array_intersect_uassoc($array1, $array2, array($obj, 'class_compare_func'))); +} +?> +--EXPECT-- +*** Testing array_intersect_uassoc() : usage variation *** + +-- Testing array_intersect_uassoc() function using class with static method as callback -- +array(1) { + ["a"]=> + string(5) "green" +} +array(1) { + ["a"]=> + string(5) "green" +} + +-- Testing array_intersect_uassoc() function using class with regular method as callback -- +array(1) { + ["a"]=> + string(5) "green" +} diff --git a/tests/std/array/array_intersect_uassoc_variation2.phpt b/tests/std/array/array_intersect_uassoc_variation2.phpt new file mode 100644 index 00000000..b775702f --- /dev/null +++ b/tests/std/array/array_intersect_uassoc_variation2.phpt @@ -0,0 +1,207 @@ +--TEST-- +Test array_intersect_uassoc() function : usage variation - Passing unexpected values to second argument +--SKIPIF-- + + +--FILE-- + $b ? 1 : -1; +} +// define some classes +class classWithToString +{ + public function __toString(): string { + return "Class A object"; + } +} +class classWithoutToString +{ +} +function main() +{ + echo "*** Testing array_intersect_uassoc() : usage variation ***\n"; + // Initialise function arguments + $array1 = array("a" => "green", "b" => "brown", "c" => "blue", "red"); + $array3 = array("a" => "green", "brown"); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -12345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource' => $fp, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_intersect_uassoc($array1, $value, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_intersect_uassoc($array1, $value, $array3, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_intersect_uassoc() : usage variation *** + +--int 0-- +array_intersect_uassoc(): Argument #2 must be of type array, int given +array_intersect_uassoc(): Argument #2 must be of type array, int given + +--int 1-- +array_intersect_uassoc(): Argument #2 must be of type array, int given +array_intersect_uassoc(): Argument #2 must be of type array, int given + +--int 12345-- +array_intersect_uassoc(): Argument #2 must be of type array, int given +array_intersect_uassoc(): Argument #2 must be of type array, int given + +--int -12345-- +array_intersect_uassoc(): Argument #2 must be of type array, int given +array_intersect_uassoc(): Argument #2 must be of type array, int given + +--float 10.5-- +array_intersect_uassoc(): Argument #2 must be of type array, float given +array_intersect_uassoc(): Argument #2 must be of type array, float given + +--float -10.5-- +array_intersect_uassoc(): Argument #2 must be of type array, float given +array_intersect_uassoc(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_intersect_uassoc(): Argument #2 must be of type array, float given +array_intersect_uassoc(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_intersect_uassoc(): Argument #2 must be of type array, float given +array_intersect_uassoc(): Argument #2 must be of type array, float given + +--float .5-- +array_intersect_uassoc(): Argument #2 must be of type array, float given +array_intersect_uassoc(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_intersect_uassoc(): Argument #2 must be of type array, null given +array_intersect_uassoc(): Argument #2 must be of type array, null given + +--lowercase null-- +array_intersect_uassoc(): Argument #2 must be of type array, null given +array_intersect_uassoc(): Argument #2 must be of type array, null given + +--lowercase true-- +array_intersect_uassoc(): Argument #2 must be of type array, true given +array_intersect_uassoc(): Argument #2 must be of type array, true given + +--lowercase false-- +array_intersect_uassoc(): Argument #2 must be of type array, false given +array_intersect_uassoc(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_intersect_uassoc(): Argument #2 must be of type array, true given +array_intersect_uassoc(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_intersect_uassoc(): Argument #2 must be of type array, false given +array_intersect_uassoc(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_intersect_uassoc(): Argument #2 must be of type array, string given +array_intersect_uassoc(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_intersect_uassoc(): Argument #2 must be of type array, string given +array_intersect_uassoc(): Argument #2 must be of type array, string given + +--string DQ-- +array_intersect_uassoc(): Argument #2 must be of type array, string given +array_intersect_uassoc(): Argument #2 must be of type array, string given + +--string SQ-- +array_intersect_uassoc(): Argument #2 must be of type array, string given +array_intersect_uassoc(): Argument #2 must be of type array, string given + +--mixed case string-- +array_intersect_uassoc(): Argument #2 must be of type array, string given +array_intersect_uassoc(): Argument #2 must be of type array, string given + +--heredoc-- +array_intersect_uassoc(): Argument #2 must be of type array, string given +array_intersect_uassoc(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_intersect_uassoc(): Argument #2 must be of type array, classWithToString given +array_intersect_uassoc(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_intersect_uassoc(): Argument #2 must be of type array, classWithoutToString given +array_intersect_uassoc(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_intersect_uassoc(): Argument #2 must be of type array, null given +array_intersect_uassoc(): Argument #2 must be of type array, null given + +--unset var-- +array_intersect_uassoc(): Argument #2 must be of type array, null given +array_intersect_uassoc(): Argument #2 must be of type array, null given + +--resource-- +array_intersect_uassoc(): Argument #2 must be of type array, resource given +array_intersect_uassoc(): Argument #2 must be of type array, resource given diff --git a/tests/std/array/array_intersect_uassoc_variation5.phpt b/tests/std/array/array_intersect_uassoc_variation5.phpt new file mode 100644 index 00000000..9ed4fd68 --- /dev/null +++ b/tests/std/array/array_intersect_uassoc_variation5.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test array_intersect_uassoc() function : usage variation - Intersection of integers with floats and strings. +--FILE-- + $b ? 1 : -1; +} +function main() +{ + echo "*** Testing array_intersect_uassoc() : usage variation ***\n"; + //Initialize variables + $arr_default_int = array(1, 2); + $arr_float = array(0 => 1.0, 1 => 2.0, 2 => 3.0); + $arr_string = array('1', '2', '3'); + $arr_string_float = array('1.00', '2.00'); + echo "\n-- Result of integers and floating point intersection --\n"; + var_dump(array_intersect_uassoc($arr_default_int, $arr_float, "key_compare_func")); + echo "\n-- Result of integers and strings containing integers intersection --\n"; + var_dump(array_intersect_uassoc($arr_default_int, $arr_string, "key_compare_func")); + echo "\n-- Result of integers and strings containing floating points intersection --\n"; + var_dump(array_intersect_uassoc($arr_default_int, $arr_string_float, "key_compare_func")); +} +?> +--EXPECT-- +*** Testing array_intersect_uassoc() : usage variation *** + +-- Result of integers and floating point intersection -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + +-- Result of integers and strings containing integers intersection -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + +-- Result of integers and strings containing floating points intersection -- +array(0) { +} diff --git a/tests/std/array/array_intersect_uassoc_variation6.phpt b/tests/std/array/array_intersect_uassoc_variation6.phpt new file mode 100644 index 00000000..77ef7bdc --- /dev/null +++ b/tests/std/array/array_intersect_uassoc_variation6.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test array_intersect_uassoc() function : usage variation - Intersection of floating points with strings. +--FILE-- + $b ? 1 : -1; +} +function main() +{ + echo "*** Testing array_intersect_uassoc() : usage variation ***\n"; + //Initialize variables + $arr_float = array(0 => 1.0, 1 => 2.0); + $arr_string = array('1', '2', '3'); + $arr_string_float = array('1.00', '2.00'); + echo "\n-- Result of floating points and strings containing integers intersection --\n"; + var_dump(array_intersect_uassoc($arr_float, $arr_string, "key_compare_func")); + echo "\n-- Result of floating points and strings containing floating point intersection --\n"; + var_dump(array_intersect_uassoc($arr_float, $arr_string_float, "key_compare_func")); +} +?> +--EXPECT-- +*** Testing array_intersect_uassoc() : usage variation *** + +-- Result of floating points and strings containing integers intersection -- +array(2) { + [0]=> + float(1) + [1]=> + float(2) +} + +-- Result of floating points and strings containing floating point intersection -- +array(0) { +} diff --git a/tests/std/array/array_intersect_uassoc_variation7.phpt b/tests/std/array/array_intersect_uassoc_variation7.phpt new file mode 100644 index 00000000..0fc689e2 --- /dev/null +++ b/tests/std/array/array_intersect_uassoc_variation7.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test array_intersect_uassoc() function : usage variation - Intersection of strings containing integers, float +--FILE-- + $b ? 1 : -1; +} +function main() +{ + echo "*** Testing array_intersect_uassoc() : usage variation ***\n"; + //Initialize variables + $arr1_string_int = array('1', '2'); + $arr2_string_int = array('1', '3'); + $arr1_string_float = array('1.00', '2.00'); + $arr2_string_float = array('1.00', '3.00'); + echo "\n-- Result of strings containing integers intersection --\n"; + var_dump(array_intersect_uassoc($arr1_string_int, $arr2_string_int, "key_compare_func")); + echo "\n-- Result of strings containing floating points intersection --\n"; + var_dump(array_intersect_uassoc($arr1_string_float, $arr2_string_float, "key_compare_func")); + echo "\n-- Result of strings containing integers and strings containing floating points intersection --\n"; + var_dump(array_intersect_uassoc($arr1_string_int, $arr2_string_float, "key_compare_func")); +} +?> +--EXPECT-- +*** Testing array_intersect_uassoc() : usage variation *** + +-- Result of strings containing integers intersection -- +array(1) { + [0]=> + string(1) "1" +} + +-- Result of strings containing floating points intersection -- +array(1) { + [0]=> + string(4) "1.00" +} + +-- Result of strings containing integers and strings containing floating points intersection -- +array(0) { +} diff --git a/tests/std/array/array_intersect_uassoc_variation8.phpt b/tests/std/array/array_intersect_uassoc_variation8.phpt new file mode 100644 index 00000000..fd94f4bc --- /dev/null +++ b/tests/std/array/array_intersect_uassoc_variation8.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test array_intersect_uassoc() function : usage variation - arrays containing referenced variables +--SKIPIF-- + + +--FILE-- + 1, &$ref_var); + +echo "\n-- Testing array_intersect_uassoc() function with referenced variable \$ref_var has value '$ref_var' --\n"; +var_dump( array_intersect_uassoc($array1, $array2, "strcasecmp") ); + +// re-assign reference variable to different value +$ref_var = 10; +echo "\n-- Testing array_intersect_uassoc() function with referenced variable \$ref_var value changed to $ref_var --\n"; +var_dump( array_intersect_uassoc($array1, $array2, "strcasecmp") ); + +//When array are referenced +$array2 = &$array1; +echo "\n-- Testing array_intersect_uassoc() function when \$array2 is referencd to \$array1 --\n"; +var_dump( array_intersect_uassoc($array1, $array2, "strcasecmp") ); +?> +--EXPECT-- +*** Testing array_intersect_uassoc() : usage variation *** + +-- Testing array_intersect_uassoc() function with referenced variable $ref_var has value 'a' -- +array(1) { + [0]=> + string(1) "a" +} + +-- Testing array_intersect_uassoc() function with referenced variable $ref_var value changed to 10 -- +array(0) { +} + +-- Testing array_intersect_uassoc() function when $array2 is referencd to $array1 -- +array(2) { + [0]=> + string(1) "a" + [1]=> + string(1) "a" +} diff --git a/tests/std/array/array_intersect_ukey_basic.phpt b/tests/std/array/array_intersect_ukey_basic.phpt new file mode 100644 index 00000000..e16f110f --- /dev/null +++ b/tests/std/array/array_intersect_ukey_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +array_intersect_ukey(): Basic test. +--FILE-- + $key2) { + return 1; + } else { + return -1; + } +} +function main() +{ + $array1 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4); + $array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + var_dump(array_intersect_ukey($array1, $array2, 'key_compare_func')); +} +?> +--EXPECT-- +array(2) { + ["blue"]=> + int(1) + ["green"]=> + int(3) +} diff --git a/tests/std/array/array_intersect_ukey_variation1.phpt b/tests/std/array/array_intersect_ukey_variation1.phpt new file mode 100644 index 00000000..28b89895 --- /dev/null +++ b/tests/std/array/array_intersect_ukey_variation1.phpt @@ -0,0 +1,205 @@ +--TEST-- +Test array_intersect_ukey() function : usage variation - Passing unexpected values to first argument +--SKIPIF-- + + +--FILE-- + $key2 ? 1 : -1; + } +} +// define some classes +class classWithToString +{ + public function __toString(): string { + return "Class A object"; + } +} +class classWithoutToString +{ +} +function main() +{ + echo "*** Testing array_intersect_ukey() : usage variation ***\n"; + //Initialise arguments + $array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + $array3 = array('green' => 5, 'cyan' => 8); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -12345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource var' => $fp, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_intersect_ukey($value, $array2, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_intersect_ukey($value, $array2, $array3, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_intersect_ukey() : usage variation *** + +--int 0-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, int given +array_intersect_ukey(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, int given +array_intersect_ukey(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, int given +array_intersect_ukey(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, int given +array_intersect_ukey(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given +array_intersect_ukey(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, null given +array_intersect_ukey(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, null given +array_intersect_ukey(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, true given +array_intersect_ukey(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, false given +array_intersect_ukey(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, true given +array_intersect_ukey(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, false given +array_intersect_ukey(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given +array_intersect_ukey(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, classWithToString given +array_intersect_ukey(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, classWithoutToString given +array_intersect_ukey(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, null given +array_intersect_ukey(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, null given +array_intersect_ukey(): Argument #1 ($array) must be of type array, null given + +--resource var-- +array_intersect_ukey(): Argument #1 ($array) must be of type array, resource given +array_intersect_ukey(): Argument #1 ($array) must be of type array, resource given diff --git a/tests/std/array/array_intersect_ukey_variation2.phpt b/tests/std/array/array_intersect_ukey_variation2.phpt new file mode 100644 index 00000000..43f411af --- /dev/null +++ b/tests/std/array/array_intersect_ukey_variation2.phpt @@ -0,0 +1,205 @@ +--TEST-- +Test array_intersect_ukey() function : usage variation - Passing unexpected values to second argument +--SKIPIF-- + + +--FILE-- + $key2 ? 1 : -1; + } +} +// define some classes +class classWithToString +{ + public function __toString(): string { + return "Class A object"; + } +} +class classWithoutToString +{ +} +function main() +{ + echo "*** Testing array_intersect_ukey() : usage variation ***\n"; + //Initialise arguments + $array1 = array('blue' => 1, 'red' => 2, 'green' => 3, 'purple' => 4); + $array3 = array('green' => 5, 'cyan' => 8); + //get an unset variable + $unset_var = 10; + unset($unset_var); + //resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -12345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + // resource data + 'resource var' => $fp, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_intersect_ukey($array1, $value, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + var_dump(array_intersect_ukey($array1, $value, $array3, 'key_compare_func')); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } + fclose($fp); +} +?> +--EXPECT-- +*** Testing array_intersect_ukey() : usage variation *** + +--int 0-- +array_intersect_ukey(): Argument #2 must be of type array, int given +array_intersect_ukey(): Argument #2 must be of type array, int given + +--int 1-- +array_intersect_ukey(): Argument #2 must be of type array, int given +array_intersect_ukey(): Argument #2 must be of type array, int given + +--int 12345-- +array_intersect_ukey(): Argument #2 must be of type array, int given +array_intersect_ukey(): Argument #2 must be of type array, int given + +--int -12345-- +array_intersect_ukey(): Argument #2 must be of type array, int given +array_intersect_ukey(): Argument #2 must be of type array, int given + +--float 10.5-- +array_intersect_ukey(): Argument #2 must be of type array, float given +array_intersect_ukey(): Argument #2 must be of type array, float given + +--float -10.5-- +array_intersect_ukey(): Argument #2 must be of type array, float given +array_intersect_ukey(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_intersect_ukey(): Argument #2 must be of type array, float given +array_intersect_ukey(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_intersect_ukey(): Argument #2 must be of type array, float given +array_intersect_ukey(): Argument #2 must be of type array, float given + +--float .5-- +array_intersect_ukey(): Argument #2 must be of type array, float given +array_intersect_ukey(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_intersect_ukey(): Argument #2 must be of type array, null given +array_intersect_ukey(): Argument #2 must be of type array, null given + +--lowercase null-- +array_intersect_ukey(): Argument #2 must be of type array, null given +array_intersect_ukey(): Argument #2 must be of type array, null given + +--lowercase true-- +array_intersect_ukey(): Argument #2 must be of type array, true given +array_intersect_ukey(): Argument #2 must be of type array, true given + +--lowercase false-- +array_intersect_ukey(): Argument #2 must be of type array, false given +array_intersect_ukey(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_intersect_ukey(): Argument #2 must be of type array, true given +array_intersect_ukey(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_intersect_ukey(): Argument #2 must be of type array, false given +array_intersect_ukey(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_intersect_ukey(): Argument #2 must be of type array, string given +array_intersect_ukey(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_intersect_ukey(): Argument #2 must be of type array, string given +array_intersect_ukey(): Argument #2 must be of type array, string given + +--string DQ-- +array_intersect_ukey(): Argument #2 must be of type array, string given +array_intersect_ukey(): Argument #2 must be of type array, string given + +--string SQ-- +array_intersect_ukey(): Argument #2 must be of type array, string given +array_intersect_ukey(): Argument #2 must be of type array, string given + +--mixed case string-- +array_intersect_ukey(): Argument #2 must be of type array, string given +array_intersect_ukey(): Argument #2 must be of type array, string given + +--heredoc-- +array_intersect_ukey(): Argument #2 must be of type array, string given +array_intersect_ukey(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_intersect_ukey(): Argument #2 must be of type array, classWithToString given +array_intersect_ukey(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_intersect_ukey(): Argument #2 must be of type array, classWithoutToString given +array_intersect_ukey(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_intersect_ukey(): Argument #2 must be of type array, null given +array_intersect_ukey(): Argument #2 must be of type array, null given + +--unset var-- +array_intersect_ukey(): Argument #2 must be of type array, null given +array_intersect_ukey(): Argument #2 must be of type array, null given + +--resource var-- +array_intersect_ukey(): Argument #2 must be of type array, resource given +array_intersect_ukey(): Argument #2 must be of type array, resource given diff --git a/tests/std/array/array_intersect_ukey_variation5.phpt b/tests/std/array/array_intersect_ukey_variation5.phpt new file mode 100644 index 00000000..b870b52b --- /dev/null +++ b/tests/std/array/array_intersect_ukey_variation5.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_intersect_ukey() function : usage variation - Intersection of integers with floats and strings. +--FILE-- + $key2 ? 1 : -1; + } +} +function main() +{ + echo "*** Testing array_intersect_ukey() : usage variation ***\n"; + //Initialize variables + $arr_default_int = array(1, 2); + $arr_float = array(0 => 1.0, 1 => 2.0, 2 => 3.0); + $arr_string = array('0' => '1', '1' => '2', '2' => '3'); + $arr_string_float = array('0.00' => '1.00', '1.00' => '2.00'); + echo "\n-- Result of integers and floating point intersection --\n"; + var_dump(array_intersect_ukey($arr_default_int, $arr_float, "key_compare_func")); + echo "\n-- Result of integers and strings containing integers intersection --\n"; + var_dump(array_intersect_ukey($arr_default_int, $arr_string, "key_compare_func")); + echo "\n-- Result of integers and strings containing floating points intersection --\n"; + var_dump(array_intersect_ukey($arr_default_int, $arr_string_float, "key_compare_func")); +} +?> +--EXPECT-- +*** Testing array_intersect_ukey() : usage variation *** + +-- Result of integers and floating point intersection -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + +-- Result of integers and strings containing integers intersection -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + +-- Result of integers and strings containing floating points intersection -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} diff --git a/tests/std/array/array_intersect_ukey_variation6.phpt b/tests/std/array/array_intersect_ukey_variation6.phpt new file mode 100644 index 00000000..b7da0c29 --- /dev/null +++ b/tests/std/array/array_intersect_ukey_variation6.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test array_intersect_ukey() function : usage variation - Intersection of floating points with strings. +--FILE-- + $key2 ? 1 : -1; + } +} +function main() +{ + echo "*** Testing array_intersect_ukey() : usage variation ***\n"; + //Initialize variables + $arr_float = array(0 => 1.0, 1 => 2.0); + $arr_string = array('0' => '1', '1' => '2', '2' => '3'); + $arr_string_float = array('0.00' => '1.00', '1.00' => '2.00'); + echo "\n-- Result of floating points and strings containing integers intersection --\n"; + var_dump(array_intersect_ukey($arr_float, $arr_string, 'key_compare_func')); + echo "\n-- Result of floating points and strings containing floating point intersection --\n"; + var_dump(array_intersect_ukey($arr_float, $arr_string_float, 'key_compare_func')); +} +?> +--EXPECT-- +*** Testing array_intersect_ukey() : usage variation *** + +-- Result of floating points and strings containing integers intersection -- +array(2) { + [0]=> + float(1) + [1]=> + float(2) +} + +-- Result of floating points and strings containing floating point intersection -- +array(2) { + [0]=> + float(1) + [1]=> + float(2) +} diff --git a/tests/std/array/array_intersect_ukey_variation7.phpt b/tests/std/array/array_intersect_ukey_variation7.phpt new file mode 100644 index 00000000..832053f5 --- /dev/null +++ b/tests/std/array/array_intersect_ukey_variation7.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_intersect_ukey() function : usage variation - Intersection of strings containing integer and float +--FILE-- + $key2 ? 1 : -1; + } +} +function main() +{ + echo "*** Testing array_intersect_ukey() : usage variation ***\n"; + //Initialize variables + $arr1_string_int = array('0' => '1', '1' => '2'); + $arr2_string_int = array('0' => '1', '1' => '3'); + $arr1_string_float = array('0.00' => '1.00', '1.00' => '2.00'); + $arr2_string_float = array('0.00' => '1.00', '1.00' => '3.00'); + echo "\n-- Result of strings containing integers intersection --\n"; + var_dump(array_intersect_ukey($arr1_string_int, $arr2_string_int, 'key_compare_func')); + echo "\n-- Result of strings containing floating points intersection --\n"; + var_dump(array_intersect_ukey($arr1_string_float, $arr2_string_float, 'key_compare_func')); + echo "\n-- Result of strings containing integers and strings containing floating points intersection --\n"; + var_dump(array_intersect_ukey($arr1_string_int, $arr2_string_float, 'key_compare_func')); +} +?> +--EXPECT-- +*** Testing array_intersect_ukey() : usage variation *** + +-- Result of strings containing integers intersection -- +array(2) { + [0]=> + string(1) "1" + [1]=> + string(1) "2" +} + +-- Result of strings containing floating points intersection -- +array(2) { + ["0.00"]=> + string(4) "1.00" + ["1.00"]=> + string(4) "2.00" +} + +-- Result of strings containing integers and strings containing floating points intersection -- +array(2) { + [0]=> + string(1) "1" + [1]=> + string(1) "2" +} diff --git a/tests/std/array/array_intersect_ukey_variation8.phpt b/tests/std/array/array_intersect_ukey_variation8.phpt new file mode 100644 index 00000000..71126a1e --- /dev/null +++ b/tests/std/array/array_intersect_ukey_variation8.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_intersect_ukey() function : usage variation - Passing non-existing function name to callback +--FILE-- + 1, 'red' => 2, 'green' => 3, 'purple' => 4); +$array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + +//function name within double quotes +try { + var_dump( array_intersect_ukey($array1, $array2, "unknown_function") ); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +//function name within single quotes +try { + var_dump( array_intersect_ukey($array1, $array2, 'unknown_function') ); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +*** Testing array_intersect_ukey() : usage variation *** +array_intersect_ukey(): Argument #3 must be a valid callback, function "unknown_function" not found or invalid function name +array_intersect_ukey(): Argument #3 must be a valid callback, function "unknown_function" not found or invalid function name diff --git a/tests/std/array/array_intersect_ukey_variation9.phpt b/tests/std/array/array_intersect_ukey_variation9.phpt new file mode 100644 index 00000000..1eb5d750 --- /dev/null +++ b/tests/std/array/array_intersect_ukey_variation9.phpt @@ -0,0 +1,53 @@ +--TEST-- +Test array_intersect_ukey() function : usage variation - Passing class/object methods to callback +--FILE-- + 1, 'red' => 2, 'green' => 3, 'purple' => 4); + $array2 = array('green' => 5, 'blue' => 6, 'yellow' => 7, 'cyan' => 8); + echo "\n-- Testing array_intersect_ukey() function using class with static method as callback --\n"; + var_dump(array_intersect_ukey($array1, $array2, array('MyClass', 'static_compare_func'))); + var_dump(array_intersect_ukey($array1, $array2, 'MyClass::static_compare_func')); + echo "\n-- Testing array_intersect_uassoc() function using class with regular method as callback --\n"; + $obj = new MyClass(); + var_dump(array_intersect_ukey($array1, $array2, array($obj, 'class_compare_func'))); +} +?> +--EXPECT-- +*** Testing array_intersect_ukey() : usage variation *** + +-- Testing array_intersect_ukey() function using class with static method as callback -- +array(2) { + ["blue"]=> + int(1) + ["green"]=> + int(3) +} +array(2) { + ["blue"]=> + int(1) + ["green"]=> + int(3) +} + +-- Testing array_intersect_uassoc() function using class with regular method as callback -- +array(2) { + ["blue"]=> + int(1) + ["green"]=> + int(3) +} diff --git a/tests/std/array/array_intersect_variation1.phpt b/tests/std/array/array_intersect_variation1.phpt new file mode 100644 index 00000000..22a31a3e --- /dev/null +++ b/tests/std/array/array_intersect_variation1.phpt @@ -0,0 +1,182 @@ +--TEST-- +Test array_intersect() function : usage variations - unexpected values for 'array1' argument +--SKIPIF-- + + +--FILE-- + 1, "two" => 2); + // get an unset variable + $unset_var = 10; + unset($unset_var); + // heredoc string + $heredoc = <<getMessage(), "\n"; + } + // Calling array_intersect() with more arguments + try { + var_dump(array_intersect($unexpected_value, $array2, $arr3)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_intersect() : Passing non-array values to $array1 argument *** + +-- Iterator 1 --array_intersect(): Argument #1 ($array) must be of type array, int given +array_intersect(): Argument #1 ($array) must be of type array, int given + +-- Iterator 2 --array_intersect(): Argument #1 ($array) must be of type array, int given +array_intersect(): Argument #1 ($array) must be of type array, int given + +-- Iterator 3 --array_intersect(): Argument #1 ($array) must be of type array, int given +array_intersect(): Argument #1 ($array) must be of type array, int given + +-- Iterator 4 --array_intersect(): Argument #1 ($array) must be of type array, int given +array_intersect(): Argument #1 ($array) must be of type array, int given + +-- Iterator 5 --array_intersect(): Argument #1 ($array) must be of type array, float given +array_intersect(): Argument #1 ($array) must be of type array, float given + +-- Iterator 6 --array_intersect(): Argument #1 ($array) must be of type array, float given +array_intersect(): Argument #1 ($array) must be of type array, float given + +-- Iterator 7 --array_intersect(): Argument #1 ($array) must be of type array, float given +array_intersect(): Argument #1 ($array) must be of type array, float given + +-- Iterator 8 --array_intersect(): Argument #1 ($array) must be of type array, float given +array_intersect(): Argument #1 ($array) must be of type array, float given + +-- Iterator 9 --array_intersect(): Argument #1 ($array) must be of type array, float given +array_intersect(): Argument #1 ($array) must be of type array, float given + +-- Iterator 10 --array_intersect(): Argument #1 ($array) must be of type array, null given +array_intersect(): Argument #1 ($array) must be of type array, null given + +-- Iterator 11 --array_intersect(): Argument #1 ($array) must be of type array, null given +array_intersect(): Argument #1 ($array) must be of type array, null given + +-- Iterator 12 --array_intersect(): Argument #1 ($array) must be of type array, true given +array_intersect(): Argument #1 ($array) must be of type array, true given + +-- Iterator 13 --array_intersect(): Argument #1 ($array) must be of type array, false given +array_intersect(): Argument #1 ($array) must be of type array, false given + +-- Iterator 14 --array_intersect(): Argument #1 ($array) must be of type array, true given +array_intersect(): Argument #1 ($array) must be of type array, true given + +-- Iterator 15 --array_intersect(): Argument #1 ($array) must be of type array, false given +array_intersect(): Argument #1 ($array) must be of type array, false given + +-- Iterator 16 --array_intersect(): Argument #1 ($array) must be of type array, string given +array_intersect(): Argument #1 ($array) must be of type array, string given + +-- Iterator 17 --array_intersect(): Argument #1 ($array) must be of type array, string given +array_intersect(): Argument #1 ($array) must be of type array, string given + +-- Iterator 18 --array_intersect(): Argument #1 ($array) must be of type array, string given +array_intersect(): Argument #1 ($array) must be of type array, string given + +-- Iterator 19 --array_intersect(): Argument #1 ($array) must be of type array, string given +array_intersect(): Argument #1 ($array) must be of type array, string given + +-- Iterator 20 --array_intersect(): Argument #1 ($array) must be of type array, string given +array_intersect(): Argument #1 ($array) must be of type array, string given + +-- Iterator 21 --array_intersect(): Argument #1 ($array) must be of type array, classA given +array_intersect(): Argument #1 ($array) must be of type array, classA given + +-- Iterator 22 --array_intersect(): Argument #1 ($array) must be of type array, null given +array_intersect(): Argument #1 ($array) must be of type array, null given + +-- Iterator 23 --array_intersect(): Argument #1 ($array) must be of type array, null given +array_intersect(): Argument #1 ($array) must be of type array, null given + +-- Iterator 24 --array_intersect(): Argument #1 ($array) must be of type array, resource given +array_intersect(): Argument #1 ($array) must be of type array, resource given +Done diff --git a/tests/std/array/array_intersect_variation10.phpt b/tests/std/array/array_intersect_variation10.phpt new file mode 100644 index 00000000..e8ade132 --- /dev/null +++ b/tests/std/array/array_intersect_variation10.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test array_intersect() function : usage variations - binary safe checking +--FILE-- + +--EXPECT-- +*** Testing array_intersect() : binary safe checking *** +array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" +} +array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" +} +array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" +} +Done diff --git a/tests/std/array/array_intersect_variation2.phpt b/tests/std/array/array_intersect_variation2.phpt new file mode 100644 index 00000000..613e6a28 --- /dev/null +++ b/tests/std/array/array_intersect_variation2.phpt @@ -0,0 +1,182 @@ +--TEST-- +Test array_intersect() function : usage variations - unexpected values for 'array2' argument +--SKIPIF-- + + +--FILE-- + 1, "two" => 2); + // get an unset variable + $unset_var = 10; + unset($unset_var); + // heredoc string + $heredoc = <<getMessage(), "\n"; + } + // Calling array_intersect() with more arguments + try { + var_dump(array_intersect($array1, $unexpected_value, $arr3)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_intersect() : Passing non-array values to $array2 argument *** + +-- Iterator 1 --array_intersect(): Argument #2 must be of type array, int given +array_intersect(): Argument #2 must be of type array, int given + +-- Iterator 2 --array_intersect(): Argument #2 must be of type array, int given +array_intersect(): Argument #2 must be of type array, int given + +-- Iterator 3 --array_intersect(): Argument #2 must be of type array, int given +array_intersect(): Argument #2 must be of type array, int given + +-- Iterator 4 --array_intersect(): Argument #2 must be of type array, int given +array_intersect(): Argument #2 must be of type array, int given + +-- Iterator 5 --array_intersect(): Argument #2 must be of type array, float given +array_intersect(): Argument #2 must be of type array, float given + +-- Iterator 6 --array_intersect(): Argument #2 must be of type array, float given +array_intersect(): Argument #2 must be of type array, float given + +-- Iterator 7 --array_intersect(): Argument #2 must be of type array, float given +array_intersect(): Argument #2 must be of type array, float given + +-- Iterator 8 --array_intersect(): Argument #2 must be of type array, float given +array_intersect(): Argument #2 must be of type array, float given + +-- Iterator 9 --array_intersect(): Argument #2 must be of type array, float given +array_intersect(): Argument #2 must be of type array, float given + +-- Iterator 10 --array_intersect(): Argument #2 must be of type array, null given +array_intersect(): Argument #2 must be of type array, null given + +-- Iterator 11 --array_intersect(): Argument #2 must be of type array, null given +array_intersect(): Argument #2 must be of type array, null given + +-- Iterator 12 --array_intersect(): Argument #2 must be of type array, true given +array_intersect(): Argument #2 must be of type array, true given + +-- Iterator 13 --array_intersect(): Argument #2 must be of type array, false given +array_intersect(): Argument #2 must be of type array, false given + +-- Iterator 14 --array_intersect(): Argument #2 must be of type array, true given +array_intersect(): Argument #2 must be of type array, true given + +-- Iterator 15 --array_intersect(): Argument #2 must be of type array, false given +array_intersect(): Argument #2 must be of type array, false given + +-- Iterator 16 --array_intersect(): Argument #2 must be of type array, string given +array_intersect(): Argument #2 must be of type array, string given + +-- Iterator 17 --array_intersect(): Argument #2 must be of type array, string given +array_intersect(): Argument #2 must be of type array, string given + +-- Iterator 18 --array_intersect(): Argument #2 must be of type array, string given +array_intersect(): Argument #2 must be of type array, string given + +-- Iterator 19 --array_intersect(): Argument #2 must be of type array, string given +array_intersect(): Argument #2 must be of type array, string given + +-- Iterator 20 --array_intersect(): Argument #2 must be of type array, string given +array_intersect(): Argument #2 must be of type array, string given + +-- Iterator 21 --array_intersect(): Argument #2 must be of type array, classA given +array_intersect(): Argument #2 must be of type array, classA given + +-- Iterator 22 --array_intersect(): Argument #2 must be of type array, null given +array_intersect(): Argument #2 must be of type array, null given + +-- Iterator 23 --array_intersect(): Argument #2 must be of type array, null given +array_intersect(): Argument #2 must be of type array, null given + +-- Iterator 24 --array_intersect(): Argument #2 must be of type array, resource given +array_intersect(): Argument #2 must be of type array, resource given +Done diff --git a/tests/std/array/array_intersect_variation3.phpt b/tests/std/array/array_intersect_variation3.phpt new file mode 100644 index 00000000..05fcf78d --- /dev/null +++ b/tests/std/array/array_intersect_variation3.phpt @@ -0,0 +1,340 @@ +--TEST-- +Test array_intersect() function : usage variations - different arrays for 'arr1' argument +--SKIPIF-- + +--FILE-- +22 +'single quoted string' +"double quoted string" +2222 != 1111.\t 0000 = 0000\n +EOT; + +// arrays to be passed to $arr1 argument +$arrays = array ( +/*1*/ array(1, 2), // array with default keys and numeric values + array(1.1, 2.2), // array with default keys & float values + array(false,true), // array with default keys and boolean values + array(), // empty array +/*5*/ array(NULL), // array with NULL + array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // array with double quoted strings + array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // array with single quoted strings + array($blank_line, $multiline_string, $diff_whitespaces, $numeric_string), // array with heredocs + + // associative arrays +/*9*/ array(1 => "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values + array("one" => 1, "two" => 2, "three" => 3 ), // string keys & numeric values + array( 1 => 10, 2 => 20, 4 => 40, 3 => 30), // explicit numeric keys and numeric values + array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value + array("one" => 1, 2 => "two", 4 => "four"), //mixed + + // associative array, containing null/empty/boolean values as key/value +/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + + // array with repetitive keys +/*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) +); + + +// array to be passsed to $arr2 argument +$arr2 = array ( + 1, 1.1, "hello", "one", NULL, 2, + 'world', true, false, false => 5, 'aaaa\r', "aaaa\r", + $numeric_string, $diff_whitespaces, + "one" => "ten", 4 => "four", "two" => 2, 2 => "two", + '', null => "null", '' => 'emptys' +); + +// loop through each sub-array within $arrays to check the behavior of array_intersect() +$iterator = 1; +foreach($arrays as $arr1) { + echo "-- Iterator $iterator --\n"; + + // Calling array_intersect() with default arguments + var_dump( array_intersect($arr1, $arr2) ); + + // Calling array_intersect() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump( array_intersect($arr1, $arr2, $arr1) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect() : Passing different types of arrays to $arr1 argument *** +-- Iterator 1 -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +-- Iterator 2 -- +array(1) { + [0]=> + float(1.1) +} +array(1) { + [0]=> + float(1.1) +} +-- Iterator 3 -- +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} +-- Iterator 4 -- +array(0) { +} +array(0) { +} +-- Iterator 5 -- +array(1) { + [0]=> + NULL +} +array(1) { + [0]=> + NULL +} +-- Iterator 6 -- +array(1) { + [1]=> + string(5) "aaaa " +} +array(1) { + [1]=> + string(5) "aaaa " +} +-- Iterator 7 -- +array(1) { + [1]=> + string(6) "aaaa\r" +} +array(1) { + [1]=> + string(6) "aaaa\r" +} +-- Iterator 8 -- +array(2) { + [2]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" + [3]=> + string(90) "11 < 12. 123 >22 +'single quoted string' +"double quoted string" +2222 != 1111. 0000 = 0000 +" +} +array(2) { + [2]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" + [3]=> + string(90) "11 < 12. 123 >22 +'single quoted string' +"double quoted string" +2222 != 1111. 0000 = 0000 +" +} +-- Iterator 9 -- +array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} +array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} +-- Iterator 10 -- +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +-- Iterator 11 -- +array(0) { +} +array(0) { +} +-- Iterator 12 -- +array(1) { + ["one"]=> + string(3) "ten" +} +array(1) { + ["one"]=> + string(3) "ten" +} +-- Iterator 13 -- +array(3) { + ["one"]=> + int(1) + [2]=> + string(3) "two" + [4]=> + string(4) "four" +} +array(3) { + ["one"]=> + int(1) + [2]=> + string(3) "two" + [4]=> + string(4) "four" +} +-- Iterator 14 -- +array(2) { + ["NULL"]=> + NULL + ["null"]=> + NULL +} +array(2) { + ["NULL"]=> + NULL + ["null"]=> + NULL +} +-- Iterator 15 -- +array(2) { + ["false"]=> + bool(false) + ["true"]=> + bool(true) +} +array(2) { + ["false"]=> + bool(false) + ["true"]=> + bool(true) +} +-- Iterator 16 -- +array(3) { + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" + ["emptys"]=> + string(0) "" +} +array(3) { + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" + ["emptys"]=> + string(0) "" +} +-- Iterator 17 -- +array(6) { + [1]=> + string(0) "" + [2]=> + string(0) "" + [3]=> + NULL + [4]=> + NULL + [5]=> + bool(false) + [6]=> + bool(true) +} +array(6) { + [1]=> + string(0) "" + [2]=> + string(0) "" + [3]=> + NULL + [4]=> + NULL + [5]=> + bool(false) + [6]=> + bool(true) +} +-- Iterator 18 -- +array(1) { + [0]=> + int(5) +} +array(1) { + [0]=> + int(5) +} +-- Iterator 19 -- +array(0) { +} +array(0) { +} +Done diff --git a/tests/std/array/array_intersect_variation4.phpt b/tests/std/array/array_intersect_variation4.phpt new file mode 100644 index 00000000..f2fb9df5 --- /dev/null +++ b/tests/std/array/array_intersect_variation4.phpt @@ -0,0 +1,347 @@ +--TEST-- +Test array_intersect() function : usage variations - different arrays for 'arr2' argument +--SKIPIF-- + +--FILE-- +22 +'single quoted string' +"double quoted string" +2222 != 1111.\t 0000 = 0000\n +EOT; + +// array to be passsed to $arr1 argument +$arr1 = array ( + 1, 1.1, "hello", "one", NULL, 2, + 'world', true, false, false => 5, 'aaaa\r', "aaaa\r", + $numeric_string, $diff_whitespaces, + "one" => "ten", 4 => "four", "two" => 2, 2 => "two", + '', null => "null", '' => 'emptys' +); + +// arrays to be passed to $arr2 argument +$arrays = array ( +/*1*/ array(1, 2), // array with default keys and numeric values + array(1.1, 2.2), // array with default keys & float values + array(false,true), // array with default keys and boolean values + array(), // empty array +/*5*/ array(NULL), // array with NULL + array("a\v\f","aaaa\r","b","b\tbbb","c","\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // array with double quoted strings + array('a\v\f','aaaa\r','b','b\tbbb','c','\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // array with single quoted strings + array($blank_line, $multiline_string, $diff_whitespaces, $numeric_string), // array with heredocs + + // associative arrays +/*9*/ array(1 => "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values + array("one" => 1, "two" => 2, "three" => 3 ), // string keys & numeric values + array( 1 => 10, 2 => 20, 4 => 40, 3 => 30), // explicit numeric keys and numeric values + array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value + array("one" => 1, 2 => "two", 4 => "four"), //mixed + + // associative array, containing null/empty/boolean values as key/value +/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + + // array with repetitive keys +/*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) +); + +// loop through each sub-array within $arrays to check the behavior of array_intersect() +$iterator = 1; +foreach($arrays as $arr2) { + echo "-- Iteration $iterator --\n"; + + // Calling array_intersect() with default arguments + var_dump( array_intersect($arr1, $arr2) ); + + // Calling array_intersect() with more arguments + // additional argument passed is the same as $arr1 argument + var_dump( array_intersect($arr1, $arr2, $arr1) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect() : Passing different types of arrays to $arr2 argument *** +-- Iteration 1 -- +array(3) { + [5]=> + int(2) + [7]=> + bool(true) + ["two"]=> + int(2) +} +array(3) { + [5]=> + int(2) + [7]=> + bool(true) + ["two"]=> + int(2) +} +-- Iteration 2 -- +array(1) { + [1]=> + float(1.1) +} +array(1) { + [1]=> + float(1.1) +} +-- Iteration 3 -- +array(3) { + [7]=> + bool(true) + [8]=> + bool(false) + [13]=> + string(0) "" +} +array(3) { + [7]=> + bool(true) + [8]=> + bool(false) + [13]=> + string(0) "" +} +-- Iteration 4 -- +array(0) { +} +array(0) { +} +-- Iteration 5 -- +array(2) { + [8]=> + bool(false) + [13]=> + string(0) "" +} +array(2) { + [8]=> + bool(false) + [13]=> + string(0) "" +} +-- Iteration 6 -- +array(1) { + [10]=> + string(5) "aaaa " +} +array(1) { + [10]=> + string(5) "aaaa " +} +-- Iteration 7 -- +array(1) { + [9]=> + string(6) "aaaa\r" +} +array(1) { + [9]=> + string(6) "aaaa\r" +} +-- Iteration 8 -- +array(2) { + [11]=> + string(90) "11 < 12. 123 >22 +'single quoted string' +"double quoted string" +2222 != 1111. 0000 = 0000 +" + [12]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" +} +array(2) { + [11]=> + string(90) "11 < 12. 123 >22 +'single quoted string' +"double quoted string" +2222 != 1111. 0000 = 0000 +" + [12]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" +} +-- Iteration 9 -- +array(2) { + [2]=> + string(3) "two" + [3]=> + string(3) "one" +} +array(2) { + [2]=> + string(3) "two" + [3]=> + string(3) "one" +} +-- Iteration 10 -- +array(3) { + [5]=> + int(2) + [7]=> + bool(true) + ["two"]=> + int(2) +} +array(3) { + [5]=> + int(2) + [7]=> + bool(true) + ["two"]=> + int(2) +} +-- Iteration 11 -- +array(0) { +} +array(0) { +} +-- Iteration 12 -- +array(1) { + ["one"]=> + string(3) "ten" +} +array(1) { + ["one"]=> + string(3) "ten" +} +-- Iteration 13 -- +array(3) { + [2]=> + string(3) "two" + [4]=> + string(4) "four" + [7]=> + bool(true) +} +array(3) { + [2]=> + string(3) "two" + [4]=> + string(4) "four" + [7]=> + bool(true) +} +-- Iteration 14 -- +array(2) { + [8]=> + bool(false) + [13]=> + string(0) "" +} +array(2) { + [8]=> + bool(false) + [13]=> + string(0) "" +} +-- Iteration 15 -- +array(3) { + [7]=> + bool(true) + [8]=> + bool(false) + [13]=> + string(0) "" +} +array(3) { + [7]=> + bool(true) + [8]=> + bool(false) + [13]=> + string(0) "" +} +-- Iteration 16 -- +array(3) { + [8]=> + bool(false) + [13]=> + string(0) "" + [""]=> + string(6) "emptys" +} +array(3) { + [8]=> + bool(false) + [13]=> + string(0) "" + [""]=> + string(6) "emptys" +} +-- Iteration 17 -- +array(3) { + [7]=> + bool(true) + [8]=> + bool(false) + [13]=> + string(0) "" +} +array(3) { + [7]=> + bool(true) + [8]=> + bool(false) + [13]=> + string(0) "" +} +-- Iteration 18 -- +array(1) { + [0]=> + int(5) +} +array(1) { + [0]=> + int(5) +} +-- Iteration 19 -- +array(0) { +} +array(0) { +} +Done diff --git a/tests/std/array/array_intersect_variation5.phpt b/tests/std/array/array_intersect_variation5.phpt new file mode 100644 index 00000000..12edea88 --- /dev/null +++ b/tests/std/array/array_intersect_variation5.phpt @@ -0,0 +1,159 @@ +--TEST-- +Test array_intersect() function : usage variations - assoc array with diff keys for 'arr1' argument +--FILE-- + "0"), + array(1 => "1"), + array(1 => "1", 2 => "2", 3 => "3", 4 => "4"), + + // arrays with string keys +/*7*/ array('\tHello' => 111, 're\td' => "color", + '\v\fworld' => 2.2, 'pen\n' => 33), + array("\tHello" => 111, "re\td" => "color", + "\v\fworld" => 2.2, "pen\n" => 33), + array("hello", $heredoc => "string"), // heredoc + + // array with unset variable +/*10*/ array( @$unset_var => "hello"), + + // array with mixed keys +/*11*/ array('hello' => 1, "fruit" => 2.2, + 133 => "int", + @$unset_var => "unset", $heredoc => "heredoc") +); + +// array to be passed to $arr2 argument +$arr2 = array(1, "float", "f4", "hello", 2.2, 'color', "string", "pen\n", 11); + +// loop through each sub-array within $arrays to check the behavior of array_intersect() +$iterator = 1; +foreach($arrays as $arr1) { + echo "-- Iterator $iterator --\n"; + + // Calling array_intersect() with default arguments + var_dump( array_intersect($arr1, $arr2) ); + + // Calling array_intersect() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump( array_intersect($arr1, $arr2, $arr1) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect() : assoc array with diff keys to $arr1 argument *** +-- Iterator 1 -- +array(0) { +} +array(0) { +} +-- Iterator 2 -- +array(0) { +} +array(0) { +} +-- Iterator 3 -- +array(1) { + [1]=> + string(1) "1" +} +array(1) { + [1]=> + string(1) "1" +} +-- Iterator 4 -- +array(1) { + [1]=> + string(1) "1" +} +array(1) { + [1]=> + string(1) "1" +} +-- Iterator 5 -- +array(2) { + ["re\td"]=> + string(5) "color" + ["\v\fworld"]=> + float(2.2) +} +array(2) { + ["re\td"]=> + string(5) "color" + ["\v\fworld"]=> + float(2.2) +} +-- Iterator 6 -- +array(2) { + ["re d"]=> + string(5) "color" + [" world"]=> + float(2.2) +} +array(2) { + ["re d"]=> + string(5) "color" + [" world"]=> + float(2.2) +} +-- Iterator 7 -- +array(2) { + [0]=> + string(5) "hello" + ["Hello world"]=> + string(6) "string" +} +array(2) { + [0]=> + string(5) "hello" + ["Hello world"]=> + string(6) "string" +} +-- Iterator 8 -- +array(1) { + [""]=> + string(5) "hello" +} +array(1) { + [""]=> + string(5) "hello" +} +-- Iterator 9 -- +array(2) { + ["hello"]=> + int(1) + ["fruit"]=> + float(2.2) +} +array(2) { + ["hello"]=> + int(1) + ["fruit"]=> + float(2.2) +} +Done diff --git a/tests/std/array/array_intersect_variation6.phpt b/tests/std/array/array_intersect_variation6.phpt new file mode 100644 index 00000000..93ff4271 --- /dev/null +++ b/tests/std/array/array_intersect_variation6.phpt @@ -0,0 +1,159 @@ +--TEST-- +Test array_intersect() function : usage variations - assoc array with diff keys for 'arr2' argument +--FILE-- + "0"), + array(1 => "1"), + array(1 => "1", 2 => "2", 3 => "3", 4 => "4"), + + // arrays with string keys +/*7*/ array('\tHello' => 111, 're\td' => "color", + '\v\fworld' => 2.2, 'pen\n' => 33), + array("\tHello" => 111, "re\td" => "color", + "\v\fworld" => 2.2, "pen\n" => 33), + array("hello", $heredoc => "string"), // heredoc + + // array with unset variable +/*10*/ array( @$unset_var => "hello"), + + // array with mixed keys +/*11*/ array('hello' => 1, "fruit" => 2.2, + 133 => "int", + @$unset_var => "unset", $heredoc => "heredoc") +); + +// array to be passed to $arr1 argument +$arr1 = array(1, "float", "f4", "hello", 2.2, 'color', "string", "pen\n", 11); + +// loop through each sub-array within $arrays to check the behavior of array_intersect() +$iterator = 1; +foreach($arrays as $arr2) { + echo "-- Iterator $iterator --\n"; + + // Calling array_intersect() with default arguments + var_dump( array_intersect($arr1, $arr2) ); + + // Calling array_intersect() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump( array_intersect($arr1, $arr2, $arr1) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_intersect() : assoc array with diff keys to $arr2 argument *** +-- Iterator 1 -- +array(0) { +} +array(0) { +} +-- Iterator 2 -- +array(0) { +} +array(0) { +} +-- Iterator 3 -- +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(1) +} +-- Iterator 4 -- +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(1) +} +-- Iterator 5 -- +array(2) { + [4]=> + float(2.2) + [5]=> + string(5) "color" +} +array(2) { + [4]=> + float(2.2) + [5]=> + string(5) "color" +} +-- Iterator 6 -- +array(2) { + [4]=> + float(2.2) + [5]=> + string(5) "color" +} +array(2) { + [4]=> + float(2.2) + [5]=> + string(5) "color" +} +-- Iterator 7 -- +array(2) { + [3]=> + string(5) "hello" + [6]=> + string(6) "string" +} +array(2) { + [3]=> + string(5) "hello" + [6]=> + string(6) "string" +} +-- Iterator 8 -- +array(1) { + [3]=> + string(5) "hello" +} +array(1) { + [3]=> + string(5) "hello" +} +-- Iterator 9 -- +array(2) { + [0]=> + int(1) + [4]=> + float(2.2) +} +array(2) { + [0]=> + int(1) + [4]=> + float(2.2) +} +Done diff --git a/tests/std/array/array_intersect_variation7.phpt b/tests/std/array/array_intersect_variation7.phpt new file mode 100644 index 00000000..8282af87 --- /dev/null +++ b/tests/std/array/array_intersect_variation7.phpt @@ -0,0 +1,196 @@ +--TEST-- +Test array_intersect() function : usage variations - assoc array with diff values for 'arr1' argument +--SKIPIF-- + +--FILE-- + 0), + array("1" => 1), + array("one" => 1, 'two' => 2, "three" => 3, 4 => 4), + // arrays with float values + /*5*/ + array("float" => 2.3333), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => 33333333.333333), + // arrays with string values + /*7*/ + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "pen\n"), + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => 'pen\n'), + array(1 => "hello", "heredoc" => $heredoc), + // array with object, unset variable and resource variable + /*10*/ + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp), + // array with mixed values + /*11*/ + array(1 => 'hello', 2 => new classA(), 222 => "fruit", 'resource' => $fp, "int" => 133, "float" => 444.432, "unset" => @$unset_var, "heredoc" => $heredoc), + ); + // array to be passsed to $arr2 argument + $arr2 = array(1, 2, 1.2, 2.3333, "col\tor", '\v\fworld', $fp, "Hello world", $heredoc, new classA(), 444.432, "fruit"); + // loop through each sub-array within $arrays to check the behavior of array_intersect() + $iterator = 1; + foreach ($arrays as $arr1) { + echo "-- Iterator {$iterator} --\n"; + // Calling array_intersect() with default arguments + var_dump(array_intersect($arr1, $arr2)); + // Calling array_intersect() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump(array_intersect($arr1, $arr2, $arr1)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_intersect() : assoc array with diff values to $arr1 argument *** +-- Iterator 1 -- +array(0) { +} +array(0) { +} +-- Iterator 2 -- +array(0) { +} +array(0) { +} +-- Iterator 3 -- +array(1) { + [1]=> + int(1) +} +array(1) { + [1]=> + int(1) +} +-- Iterator 4 -- +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +-- Iterator 5 -- +array(1) { + ["float"]=> + float(2.3333) +} +array(1) { + ["float"]=> + float(2.3333) +} +-- Iterator 6 -- +array(1) { + ["f1"]=> + float(1.2) +} +array(1) { + ["f1"]=> + float(1.2) +} +-- Iterator 7 -- +array(1) { + ["red"]=> + string(6) "col or" +} +array(1) { + ["red"]=> + string(6) "col or" +} +-- Iterator 8 -- +array(1) { + [2]=> + string(9) "\v\fworld" +} +array(1) { + [2]=> + string(9) "\v\fworld" +} +-- Iterator 9 -- +array(1) { + ["heredoc"]=> + string(11) "Hello world" +} +array(1) { + ["heredoc"]=> + string(11) "Hello world" +} +-- Iterator 10 -- +array(2) { + [11]=> + object(classA)#%d (0) { + } + ["resource"]=> + resource(%d) of type (stream) +} +array(2) { + [11]=> + object(classA)#%d (0) { + } + ["resource"]=> + resource(%d) of type (stream) +} +-- Iterator 11 -- +array(5) { + [2]=> + object(classA)#%d (0) { + } + [222]=> + string(5) "fruit" + ["resource"]=> + resource(%d) of type (stream) + ["float"]=> + float(444.432) + ["heredoc"]=> + string(11) "Hello world" +} +array(5) { + [2]=> + object(classA)#%d (0) { + } + [222]=> + string(5) "fruit" + ["resource"]=> + resource(%d) of type (stream) + ["float"]=> + float(444.432) + ["heredoc"]=> + string(11) "Hello world" +} +Done diff --git a/tests/std/array/array_intersect_variation8.phpt b/tests/std/array/array_intersect_variation8.phpt new file mode 100644 index 00000000..706480b1 --- /dev/null +++ b/tests/std/array/array_intersect_variation8.phpt @@ -0,0 +1,204 @@ +--TEST-- +Test array_intersect() function : usage variations - assoc array with diff values for 'arr2' argument +--SKIPIF-- + +--FILE-- + 0), + array("1" => 1), + array("one" => 1, 'two' => 2, "three" => 3, 4 => 4), + // arrays with float values + /*5*/ + array("float" => 2.3333), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => 33333333.333333), + // arrays with string values + /*7*/ + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "pen\n"), + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => 'pen\n'), + array(1 => "hello", "heredoc" => $heredoc), + // array with object, unset variable and resource variable + /*10*/ + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp), + // array with mixed values + /*11*/ + array(1 => 'hello', 2 => new classA(), 222 => "fruit", 'resource' => $fp, "int" => 133, "float" => 444.432, "unset" => @$unset_var, "heredoc" => $heredoc), + ); + // array to be passsed to $arr1 argument + $arr1 = array(1, 2, 1.2, 2.3333, "col\tor", '\v\fworld', $fp, "Hello world", $heredoc, new classA(), 444.432, "fruit"); + // loop through each sub-array within $arrays to check the behavior of array_intersect() + $iterator = 1; + foreach ($arrays as $arr2) { + echo "-- Iterator {$iterator} --\n"; + // Calling array_intersect() with default arguments + var_dump(array_intersect($arr1, $arr2)); + // Calling array_intersect() with more arguments. + // additional argument passed is the same as $arr1 argument + var_dump(array_intersect($arr1, $arr2, $arr1)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_intersect() : assoc array with diff values to $arr2 argument *** +-- Iterator 1 -- +array(0) { +} +array(0) { +} +-- Iterator 2 -- +array(0) { +} +array(0) { +} +-- Iterator 3 -- +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(1) +} +-- Iterator 4 -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +-- Iterator 5 -- +array(1) { + [3]=> + float(2.3333) +} +array(1) { + [3]=> + float(2.3333) +} +-- Iterator 6 -- +array(1) { + [2]=> + float(1.2) +} +array(1) { + [2]=> + float(1.2) +} +-- Iterator 7 -- +array(1) { + [4]=> + string(6) "col or" +} +array(1) { + [4]=> + string(6) "col or" +} +-- Iterator 8 -- +array(1) { + [5]=> + string(9) "\v\fworld" +} +array(1) { + [5]=> + string(9) "\v\fworld" +} +-- Iterator 9 -- +array(2) { + [7]=> + string(11) "Hello world" + [8]=> + string(11) "Hello world" +} +array(2) { + [7]=> + string(11) "Hello world" + [8]=> + string(11) "Hello world" +} +-- Iterator 10 -- +array(2) { + [6]=> + resource(%d) of type (stream) + [9]=> + object(classA)#%d (0) { + } +} +array(2) { + [6]=> + resource(%d) of type (stream) + [9]=> + object(classA)#%d (0) { + } +} +-- Iterator 11 -- +array(6) { + [6]=> + resource(%d) of type (stream) + [7]=> + string(11) "Hello world" + [8]=> + string(11) "Hello world" + [9]=> + object(classA)#%d (0) { + } + [10]=> + float(444.432) + [11]=> + string(5) "fruit" +} +array(6) { + [6]=> + resource(%d) of type (stream) + [7]=> + string(11) "Hello world" + [8]=> + string(11) "Hello world" + [9]=> + object(classA)#%d (0) { + } + [10]=> + float(444.432) + [11]=> + string(5) "fruit" +} +Done diff --git a/tests/std/array/array_intersect_variation9.phpt b/tests/std/array/array_intersect_variation9.phpt new file mode 100644 index 00000000..c73b0f3d --- /dev/null +++ b/tests/std/array/array_intersect_variation9.phpt @@ -0,0 +1,238 @@ +--TEST-- +Test array_intersect() function : usage variations - two dimensional arrays for $arr1 and $arr2 arguments(Bug#43109) +--FILE-- + "one", 2 => "two", 3 => "three"), + array("ten" => 10, "twenty" => 20.00, "thirty" => 30) +); + +$arr2 = array ( + array(1, 2, 3, 4), + array(1 => "one", 2 => "two", 3 => "three") +); + +/* Passing the entire array as argument to $arr1 and $arr2 */ +// Calling array_intersect() with default arguments +echo "-- Passing the entire 2-D array to \$arr1 and \$arr2 --\n"; +echo "- With default arguments -\n"; +var_dump( array_intersect($arr1, $arr2) ); + +// Calling array_intersect() with more arguments +// additional argument passed is the same as $arr1 +echo "- With more arguments -\n"; +var_dump( array_intersect($arr1, $arr2, $arr1) ); + +/* Passing the sub-array as argument to $arr1 and $arr2 */ +// Calling array_intersect() with default arguments +echo "-- Passing the sub-array to \$arr1 and \$arr2 --\n"; +echo "- With default arguments -\n"; +var_dump( array_intersect($arr1[0], $arr2[0]) ); + +// Calling array_intersect() with more arguments +// additional argument passed is the same as $arr1 +echo "- With more arguments -\n"; +var_dump( array_intersect($arr1[0], $arr2[0], $arr1[0]) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_intersect() : passing two dimensional array to both $arr1 and $arr2 arguments *** +-- Passing the entire 2-D array to $arr1 and $arr2 -- +- With default arguments - + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d +array(4) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(5) "hello" + [3]=> + string(5) "world" + } + [1]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + [2]=> + array(3) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" + } + [3]=> + array(3) { + ["ten"]=> + int(10) + ["twenty"]=> + float(20) + ["thirty"]=> + int(30) + } +} +- With more arguments - + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d +array(4) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(5) "hello" + [3]=> + string(5) "world" + } + [1]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + } + [2]=> + array(3) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" + } + [3]=> + array(3) { + ["ten"]=> + int(10) + ["twenty"]=> + float(20) + ["thirty"]=> + int(30) + } +} +-- Passing the sub-array to $arr1 and $arr2 -- +- With default arguments - +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +- With more arguments - +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +Done diff --git a/tests/std/array/array_key_exists.phpt b/tests/std/array/array_key_exists.phpt new file mode 100644 index 00000000..0e9bc66b --- /dev/null +++ b/tests/std/array/array_key_exists.phpt @@ -0,0 +1,197 @@ +--TEST-- +Test array_key_exists() function +--SKIPIF-- + +--FILE-- + "Jack", "Loc" => "Mars", "Id" => "MS123"), array('Red' => 'Rose', 'I' => 'You'), array(0 => 'Zero', 1 => 'One', 2 => 'Two', 3 => "Three")); + /* keys to search in $search_arrays. $keys[0] + is the key to be searched in $search_arrays[0] and so on */ + $keys = array(1, 'a', 2, 4, "Name", "Red", 0, 3); + $key_counter = 0; + foreach ($search_arrays as $search_array) { + $key = $keys[$key_counter++]; + echo "-- Iteration {$key_counter} --\n"; + var_dump(array_key_exists($key, $search_array)); + } + echo "\n*** Testing possible variations ***\n"; + // use different keys on each sub array of $search_arrays + $key_variations = array("", NULL, null, " ", '', "test", 1); + $key_counter = 0; + $key_count = count($key_variations); + echo "\n** Variation loop 1 **\n"; + $out_loop_count = 0; + foreach ($search_arrays as $search_array) { + $key_counter = 0; + $out_loop_count++; + echo "-- Iteration {$out_loop_count} --\n"; + while ($key_counter < $key_count) { + $key = $key_variations[$key_counter++]; + var_dump(array_key_exists($key, $search_array)); + } + } + // arrays with variation in elements + $search_arrays_v = array(array(), array(NULL), array(array(), 1, 2), array(1, 2, 3, "" => "value", NULL => "value", true => "value"), array(array(2, 4, 5), array("a", "b", "d"))); + // search for $key_variations in each sub array of $search_arrays_v + echo "\n** Variation loop 2 **\n"; + $out_loop_count = 0; + foreach ($search_arrays_v as $search_array) { + $key_counter = 0; + $out_loop_count++; + echo "-- Iteration {$out_loop_count} --\n"; + while ($key_counter < $key_count) { + $key = $key_variations[$key_counter++]; + var_dump(array_key_exists($key, $search_array)); + } + } + echo "\n*** Testing error conditions ***\n"; + // first args as array + try { + array_key_exists(array(), array()); + } catch (TypeError $exception) { + echo $exception->getMessage() . "\n"; + } + echo "\n*** Testing operation on objects ***\n"; + $key_check_obj = new key_check(); + //new object + try { + var_dump(array_key_exists("public_var", $key_check_obj)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + echo "Done\n"; +} +?> +--EXPECT-- +*** Testing basic functionalities *** +-- Iteration 1 -- +bool(true) +-- Iteration 2 -- +bool(false) +-- Iteration 3 -- +bool(true) +-- Iteration 4 -- +bool(false) +-- Iteration 5 -- +bool(true) +-- Iteration 6 -- +bool(true) +-- Iteration 7 -- +bool(true) + +*** Testing possible variations *** + +** Variation loop 1 ** +-- Iteration 1 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +-- Iteration 2 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +-- Iteration 3 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +-- Iteration 4 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +-- Iteration 5 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +-- Iteration 6 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +-- Iteration 7 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) + +** Variation loop 2 ** +-- Iteration 1 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +-- Iteration 2 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +-- Iteration 3 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +-- Iteration 4 -- +bool(true) +bool(true) +bool(true) +bool(false) +bool(true) +bool(false) +bool(true) +-- Iteration 5 -- +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) + +*** Testing error conditions *** +Cannot access offset of type array on array + +*** Testing operation on objects *** +array_key_exists(): Argument #2 ($array) must be of type array, key_check given +Done diff --git a/tests/std/array/array_key_exists_basic.phpt b/tests/std/array/array_key_exists_basic.phpt new file mode 100644 index 00000000..4753633d --- /dev/null +++ b/tests/std/array/array_key_exists_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +Test array_key_exists() function : basic functionality +--FILE-- + 'value', 'val'); +var_dump(array_key_exists($key1, $search)); +var_dump(array_key_exists($key2, $search)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_key_exists() : basic functionality *** +bool(true) +bool(false) +Done diff --git a/tests/std/array/array_key_exists_variation1.phpt b/tests/std/array/array_key_exists_variation1.phpt new file mode 100644 index 00000000..e45364dd --- /dev/null +++ b/tests/std/array/array_key_exists_variation1.phpt @@ -0,0 +1,154 @@ +--TEST-- +Test array_key_exists() function : usage variations - Pass different data types as $key arg +--SKIPIF-- + + +--FILE-- + 'val', 'two', 10 => 'value'); + //get an unset variable + $unset_var = 10; + unset($unset_var); + // heredoc string + $heredoc = <<getMessage() . "\n"; + } + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_key_exists() : usage variations *** + +-- Iteration 1 -- +bool(true) + +-- Iteration 2 -- +bool(true) + +-- Iteration 3 -- +bool(false) + +-- Iteration 4 -- +bool(false) + +-- Iteration 5 -- +bool(false) + +-- Iteration 6 -- +bool(false) + +-- Iteration 7 -- +bool(true) + +-- Iteration 8 -- +bool(true) + +-- Iteration 9 -- +bool(true) + +-- Iteration 10 -- +bool(true) + +-- Iteration 11 -- +bool(false) + +-- Iteration 12 -- +bool(false) + +-- Iteration 13 -- +Cannot access offset of type array on array + +-- Iteration 14 -- +bool(true) + +-- Iteration 15 -- +bool(true) + +-- Iteration 16 -- +bool(true) + +-- Iteration 17 -- +Cannot access offset of type classA on array + +-- Iteration 18 -- +bool(false) + +-- Iteration 19 -- +bool(false) + +-- Iteration 20 -- + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d +bool(false) +Done diff --git a/tests/std/array/array_key_exists_variation3.phpt b/tests/std/array/array_key_exists_variation3.phpt new file mode 100644 index 00000000..1eaab11b --- /dev/null +++ b/tests/std/array/array_key_exists_variation3.phpt @@ -0,0 +1,59 @@ +--TEST-- +Test array_key_exists() function : usage variations - floats and casting to ints +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; + } + echo "Cast float to int:\n"; + var_dump(array_key_exists((int)$key, $search)); +} + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_key_exists() : usage variations *** + +-- Iteration 1 -- +Pass float as $key: + +Deprecated: Implicit conversion from float 1.23456789E-10 to int loses precision in %s on line %d +bool(true) +Cast float to int: +bool(true) + +-- Iteration 1 -- +Pass float as $key: + +Deprecated: Implicit conversion from float 1.00000000000001 to int loses precision in %s on line %d +bool(true) +Cast float to int: +bool(true) + +-- Iteration 1 -- +Pass float as $key: + +Deprecated: Implicit conversion from float 1.99999999999999 to int loses precision in %s on line %d +bool(true) +Cast float to int: +bool(true) +Done diff --git a/tests/std/array/array_key_exists_variation4.phpt b/tests/std/array/array_key_exists_variation4.phpt new file mode 100644 index 00000000..8d768042 --- /dev/null +++ b/tests/std/array/array_key_exists_variation4.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test array_key_exists() function : usage variations - referenced variables +--FILE-- + 1, 'two' => 2, 'three' => 3); + +echo "\n-- \$search is a reference to \$array --\n"; +$search = &$array; +var_dump(array_key_exists('one', $search)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_key_exists() : usage variations *** + +-- $search is a reference to $array -- +bool(true) +Done diff --git a/tests/std/array/array_key_exists_variation5.phpt b/tests/std/array/array_key_exists_variation5.phpt new file mode 100644 index 00000000..41a28c5b --- /dev/null +++ b/tests/std/array/array_key_exists_variation5.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test array_key_exists() function : usage variations - multidimensional arrays +--FILE-- + 'val1', + 'one' => 'val2', + 'sub1' => array (1, 2, 3)); + +echo "\n-- Attempt to match key in sub-array --\n"; +// this key is in the sub-array +var_dump(array_key_exists(0, $multi_array)); + +echo "\n-- \$search arg points to sub-array --\n"; +var_dump(array_key_exists(0, $multi_array['sub1'])); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_key_exists() : usage variations *** + +-- Attempt to match key in sub-array -- +bool(false) + +-- $search arg points to sub-array -- +bool(true) +Done diff --git a/tests/std/array/array_key_exists_variation6.phpt b/tests/std/array/array_key_exists_variation6.phpt new file mode 100644 index 00000000..ef25b45a --- /dev/null +++ b/tests/std/array/array_key_exists_variation6.phpt @@ -0,0 +1,94 @@ +--TEST-- +Test array_key_exists() function : usage variations - equality test for certain data types +--SKIPIF-- + + +--FILE-- + null, + 'NULL' => NULL, + 'empty single quoted string' => '', + "empty double quoted string" => "", + 'undefined variable' => @$undefined, + 'unset variable' => @$unset); + +//iterate through original array +foreach($array as $name => $input) { + $iterator = 1; + echo "\n-- Key in \$search array is : $name --\n"; + $search[$input] = 'test'; + + //iterate through array again to see which values are considered equal + foreach($array as $key) { + echo "Iteration $iterator: "; + var_dump(array_key_exists($key, $search)); + $iterator++; + } + $search = null; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_key_exists() : usage variations *** + +-- Key in $search array is : null -- +Iteration 1: bool(true) +Iteration 2: bool(true) +Iteration 3: bool(true) +Iteration 4: bool(true) +Iteration 5: bool(true) +Iteration 6: bool(true) + +-- Key in $search array is : NULL -- +Iteration 1: bool(true) +Iteration 2: bool(true) +Iteration 3: bool(true) +Iteration 4: bool(true) +Iteration 5: bool(true) +Iteration 6: bool(true) + +-- Key in $search array is : empty single quoted string -- +Iteration 1: bool(true) +Iteration 2: bool(true) +Iteration 3: bool(true) +Iteration 4: bool(true) +Iteration 5: bool(true) +Iteration 6: bool(true) + +-- Key in $search array is : empty double quoted string -- +Iteration 1: bool(true) +Iteration 2: bool(true) +Iteration 3: bool(true) +Iteration 4: bool(true) +Iteration 5: bool(true) +Iteration 6: bool(true) + +-- Key in $search array is : undefined variable -- +Iteration 1: bool(true) +Iteration 2: bool(true) +Iteration 3: bool(true) +Iteration 4: bool(true) +Iteration 5: bool(true) +Iteration 6: bool(true) + +-- Key in $search array is : unset variable -- +Iteration 1: bool(true) +Iteration 2: bool(true) +Iteration 3: bool(true) +Iteration 4: bool(true) +Iteration 5: bool(true) +Iteration 6: bool(true) +Done diff --git a/tests/std/array/array_key_exists_variation7.phpt b/tests/std/array/array_key_exists_variation7.phpt new file mode 100644 index 00000000..2d001bd4 --- /dev/null +++ b/tests/std/array/array_key_exists_variation7.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_key_exists() function : usage variations - position of internal array pointer +--FILE-- + 'un', 'two' => 'deux', 'three' => 'trois'); + +echo "\n-- Call array_key_exists() --\n"; +var_dump($result = array_key_exists('one', $input)); + +echo "\n-- Position of Internal Pointer in Original Array: --\n"; +echo key($input) . " => " . current ($input) . "\n"; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_key_exists() : usage variations *** + +-- Call array_key_exists() -- +bool(true) + +-- Position of Internal Pointer in Original Array: -- +one => un +Done diff --git a/tests/std/array/array_key_exists_variation8.phpt b/tests/std/array/array_key_exists_variation8.phpt new file mode 100644 index 00000000..15810b91 --- /dev/null +++ b/tests/std/array/array_key_exists_variation8.phpt @@ -0,0 +1,391 @@ +--TEST-- +Test array_key_exists() function : usage variations - array keys are different data types +--SKIPIF-- + + +--FILE-- + array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative', + ), + + // null data +/*3*/ 'null uppercase' => array( + NULL => 'null 1', + ), + 'null lowercase' => array( + null => 'null 2', + ), + + // boolean data +/*4*/ 'bool lowercase' => array( + true => 'lowert', + false => 'lowerf', + ), + 'bool uppercase' => array( + TRUE => 'uppert', + FALSE => 'upperf', + ), + + // empty data +/*5*/ 'empty double quotes' => array( + "" => 'emptyd', + ), + 'empty single quotes' => array( + '' => 'emptys', + ), + + // string data +/*6*/ 'string' => array( + "stringd" => 'stringd', + 'strings' => 'strings', + $heredoc => 'stringh', + ), + + // undefined data +/*8*/ 'undefined' => array( + @$undefined_var => 'undefined', + ), + + // unset data +/*9*/ 'unset' => array( + @$unset_var => 'unset', + ), +); + +// loop through each element of $inputs to check the behavior of array_key_exists() +$iterator = 1; +foreach($inputs as $type => $input) { + echo "\n-- Iteration $iterator: $type data --\n"; + + //iterate over again to get all different key values + foreach ($inputs as $new_type => $new_input) { + echo "-- \$key arguments are $new_type data:\n"; + foreach ($new_input as $key => $search) { + var_dump(array_key_exists($key, $input)); + } + } + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_key_exists() : usage variations *** + +-- Iteration 1: int data -- +-- $key arguments are int data: +bool(true) +bool(true) +bool(true) +bool(true) +-- $key arguments are null uppercase data: +bool(false) +-- $key arguments are null lowercase data: +bool(false) +-- $key arguments are bool lowercase data: +bool(true) +bool(true) +-- $key arguments are bool uppercase data: +bool(true) +bool(true) +-- $key arguments are empty double quotes data: +bool(false) +-- $key arguments are empty single quotes data: +bool(false) +-- $key arguments are string data: +bool(false) +bool(false) +bool(false) +-- $key arguments are undefined data: +bool(false) +-- $key arguments are unset data: +bool(false) + +-- Iteration 2: null uppercase data -- +-- $key arguments are int data: +bool(false) +bool(false) +bool(false) +bool(false) +-- $key arguments are null uppercase data: +bool(true) +-- $key arguments are null lowercase data: +bool(true) +-- $key arguments are bool lowercase data: +bool(false) +bool(false) +-- $key arguments are bool uppercase data: +bool(false) +bool(false) +-- $key arguments are empty double quotes data: +bool(true) +-- $key arguments are empty single quotes data: +bool(true) +-- $key arguments are string data: +bool(false) +bool(false) +bool(false) +-- $key arguments are undefined data: +bool(true) +-- $key arguments are unset data: +bool(true) + +-- Iteration 3: null lowercase data -- +-- $key arguments are int data: +bool(false) +bool(false) +bool(false) +bool(false) +-- $key arguments are null uppercase data: +bool(true) +-- $key arguments are null lowercase data: +bool(true) +-- $key arguments are bool lowercase data: +bool(false) +bool(false) +-- $key arguments are bool uppercase data: +bool(false) +bool(false) +-- $key arguments are empty double quotes data: +bool(true) +-- $key arguments are empty single quotes data: +bool(true) +-- $key arguments are string data: +bool(false) +bool(false) +bool(false) +-- $key arguments are undefined data: +bool(true) +-- $key arguments are unset data: +bool(true) + +-- Iteration 4: bool lowercase data -- +-- $key arguments are int data: +bool(true) +bool(true) +bool(false) +bool(false) +-- $key arguments are null uppercase data: +bool(false) +-- $key arguments are null lowercase data: +bool(false) +-- $key arguments are bool lowercase data: +bool(true) +bool(true) +-- $key arguments are bool uppercase data: +bool(true) +bool(true) +-- $key arguments are empty double quotes data: +bool(false) +-- $key arguments are empty single quotes data: +bool(false) +-- $key arguments are string data: +bool(false) +bool(false) +bool(false) +-- $key arguments are undefined data: +bool(false) +-- $key arguments are unset data: +bool(false) + +-- Iteration 5: bool uppercase data -- +-- $key arguments are int data: +bool(true) +bool(true) +bool(false) +bool(false) +-- $key arguments are null uppercase data: +bool(false) +-- $key arguments are null lowercase data: +bool(false) +-- $key arguments are bool lowercase data: +bool(true) +bool(true) +-- $key arguments are bool uppercase data: +bool(true) +bool(true) +-- $key arguments are empty double quotes data: +bool(false) +-- $key arguments are empty single quotes data: +bool(false) +-- $key arguments are string data: +bool(false) +bool(false) +bool(false) +-- $key arguments are undefined data: +bool(false) +-- $key arguments are unset data: +bool(false) + +-- Iteration 6: empty double quotes data -- +-- $key arguments are int data: +bool(false) +bool(false) +bool(false) +bool(false) +-- $key arguments are null uppercase data: +bool(true) +-- $key arguments are null lowercase data: +bool(true) +-- $key arguments are bool lowercase data: +bool(false) +bool(false) +-- $key arguments are bool uppercase data: +bool(false) +bool(false) +-- $key arguments are empty double quotes data: +bool(true) +-- $key arguments are empty single quotes data: +bool(true) +-- $key arguments are string data: +bool(false) +bool(false) +bool(false) +-- $key arguments are undefined data: +bool(true) +-- $key arguments are unset data: +bool(true) + +-- Iteration 7: empty single quotes data -- +-- $key arguments are int data: +bool(false) +bool(false) +bool(false) +bool(false) +-- $key arguments are null uppercase data: +bool(true) +-- $key arguments are null lowercase data: +bool(true) +-- $key arguments are bool lowercase data: +bool(false) +bool(false) +-- $key arguments are bool uppercase data: +bool(false) +bool(false) +-- $key arguments are empty double quotes data: +bool(true) +-- $key arguments are empty single quotes data: +bool(true) +-- $key arguments are string data: +bool(false) +bool(false) +bool(false) +-- $key arguments are undefined data: +bool(true) +-- $key arguments are unset data: +bool(true) + +-- Iteration 8: string data -- +-- $key arguments are int data: +bool(false) +bool(false) +bool(false) +bool(false) +-- $key arguments are null uppercase data: +bool(false) +-- $key arguments are null lowercase data: +bool(false) +-- $key arguments are bool lowercase data: +bool(false) +bool(false) +-- $key arguments are bool uppercase data: +bool(false) +bool(false) +-- $key arguments are empty double quotes data: +bool(false) +-- $key arguments are empty single quotes data: +bool(false) +-- $key arguments are string data: +bool(true) +bool(true) +bool(true) +-- $key arguments are undefined data: +bool(false) +-- $key arguments are unset data: +bool(false) + +-- Iteration 9: undefined data -- +-- $key arguments are int data: +bool(false) +bool(false) +bool(false) +bool(false) +-- $key arguments are null uppercase data: +bool(true) +-- $key arguments are null lowercase data: +bool(true) +-- $key arguments are bool lowercase data: +bool(false) +bool(false) +-- $key arguments are bool uppercase data: +bool(false) +bool(false) +-- $key arguments are empty double quotes data: +bool(true) +-- $key arguments are empty single quotes data: +bool(true) +-- $key arguments are string data: +bool(false) +bool(false) +bool(false) +-- $key arguments are undefined data: +bool(true) +-- $key arguments are unset data: +bool(true) + +-- Iteration 10: unset data -- +-- $key arguments are int data: +bool(false) +bool(false) +bool(false) +bool(false) +-- $key arguments are null uppercase data: +bool(true) +-- $key arguments are null lowercase data: +bool(true) +-- $key arguments are bool lowercase data: +bool(false) +bool(false) +-- $key arguments are bool uppercase data: +bool(false) +bool(false) +-- $key arguments are empty double quotes data: +bool(true) +-- $key arguments are empty single quotes data: +bool(true) +-- $key arguments are string data: +bool(false) +bool(false) +bool(false) +-- $key arguments are undefined data: +bool(true) +-- $key arguments are unset data: +bool(true) +Done diff --git a/tests/std/array/array_key_first.phpt b/tests/std/array/array_key_first.phpt new file mode 100644 index 00000000..9d5452d3 --- /dev/null +++ b/tests/std/array/array_key_first.phpt @@ -0,0 +1,296 @@ +--TEST-- +Test array_key_first() function +--SKIPIF-- + + +--FILE-- + "aaa", "A" => "AAA", "c" => "ccc", "d" => "ddd", "e" => "eee" ), + array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), + array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), + array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + array( 12, "name", 'age', '45' ), + array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), + array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, + 5 => 57, "5.4" => 554, "5.7" => 557 ), + array( "foo" ), + array( 1 => "42" ) +); + +/* Loop to test normal functionality with different arrays inputs */ +echo "\n*** Normal testing with various array inputs ***\n"; + +$counter = 1; +foreach( $mixed_array as $sub_array ) +{ + echo "\n-- Input Array for Iteration $counter is --\n"; + var_dump( $sub_array ); + echo "\nFirst key is :\n"; + var_dump( array_key_first($sub_array) ); + $counter++; +} + +echo"\nDone"; +?> +--EXPECT-- +*** Normal testing with various array inputs *** + +-- Input Array for Iteration 1 is -- +array(0) { +} + +First key is : +NULL + +-- Input Array for Iteration 2 is -- +array(9) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) +} + +First key is : +int(0) + +-- Input Array for Iteration 3 is -- +array(5) { + [0]=> + string(3) "One" + [1]=> + string(4) "_Two" + [2]=> + string(5) "Three" + [3]=> + string(4) "Four" + [4]=> + string(4) "Five" +} + +First key is : +int(0) + +-- Input Array for Iteration 4 is -- +array(8) { + [0]=> + int(6) + [1]=> + string(3) "six" + [2]=> + int(7) + [3]=> + string(5) "seven" + [4]=> + int(8) + [5]=> + string(5) "eight" + [6]=> + int(9) + [7]=> + string(4) "nine" +} + +First key is : +int(0) + +-- Input Array for Iteration 5 is -- +array(5) { + ["a"]=> + string(3) "aaa" + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" + ["d"]=> + string(3) "ddd" + ["e"]=> + string(3) "eee" +} + +First key is : +string(1) "a" + +-- Input Array for Iteration 6 is -- +array(5) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} + +First key is : +int(1) + +-- Input Array for Iteration 7 is -- +array(5) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + int(7) + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} + +First key is : +int(1) + +-- Input Array for Iteration 8 is -- +array(12) { + ["f"]=> + string(3) "fff" + [1]=> + string(3) "one" + [4]=> + int(6) + [""]=> + int(3) + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" + [3]=> + float(3.7) + [5]=> + string(4) "Five" + [6]=> + float(8.6) + ["4name"]=> + string(5) "jonny" + ["a"]=> + NULL +} + +First key is : +string(1) "f" + +-- Input Array for Iteration 9 is -- +array(4) { + [0]=> + int(12) + [1]=> + string(4) "name" + [2]=> + string(3) "age" + [3]=> + string(2) "45" +} + +First key is : +int(0) + +-- Input Array for Iteration 10 is -- +array(3) { + [0]=> + array(3) { + [0]=> + string(3) "oNe" + [1]=> + string(3) "tWo" + [2]=> + int(4) + } + [1]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [2]=> + array(0) { + } +} + +First key is : +int(0) + +-- Input Array for Iteration 11 is -- +array(10) { + ["one"]=> + int(2) + ["three"]=> + int(3) + [0]=> + int(3) + [1]=> + int(4) + [3]=> + int(33) + [4]=> + int(44) + [5]=> + int(57) + [6]=> + int(6) + ["5.4"]=> + int(554) + ["5.7"]=> + int(557) +} + +First key is : +string(3) "one" + +-- Input Array for Iteration 12 is -- +array(1) { + [0]=> + string(3) "foo" +} + +First key is : +int(0) + +-- Input Array for Iteration 13 is -- +array(1) { + [1]=> + string(2) "42" +} + +First key is : +int(1) + +Done diff --git a/tests/std/array/array_key_first_variation.phpt b/tests/std/array/array_key_first_variation.phpt new file mode 100644 index 00000000..d619ed01 --- /dev/null +++ b/tests/std/array/array_key_first_variation.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test array_key_first() function (variation) +--FILE-- + +--EXPECT-- +*** Checking for internal array pointer not being changed by array_key_first *** + +Current Element is : int(1) + +Next Element is : int(2) + +First key is : int(0) + +Current Element after array_key_first operation is: int(2) + +Done diff --git a/tests/std/array/array_key_last.phpt b/tests/std/array/array_key_last.phpt new file mode 100644 index 00000000..a81d7ca9 --- /dev/null +++ b/tests/std/array/array_key_last.phpt @@ -0,0 +1,296 @@ +--TEST-- +Test array_key_last() function +--SKIPIF-- + + +--FILE-- + "aaa", "A" => "AAA", "c" => "ccc", "d" => "ddd", "e" => "eee" ), + array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), + array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), + array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + array( 12, "name", 'age', '45' ), + array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), + array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, + 5 => 57, "5.4" => 554, "5.7" => 557 ), + array( "foo" ), + array( 1 => "42" ) +); + +/* Loop to test normal functionality with different arrays inputs */ +echo "\n*** Normal testing with various array inputs ***\n"; + +$counter = 1; +foreach( $mixed_array as $sub_array ) +{ + echo "\n-- Input Array for Iteration $counter is --\n"; + var_dump( $sub_array ); + echo "\nLast key is :\n"; + var_dump( array_key_last($sub_array) ); + $counter++; +} + +echo"\nDone"; +?> +--EXPECT-- +*** Normal testing with various array inputs *** + +-- Input Array for Iteration 1 is -- +array(0) { +} + +Last key is : +NULL + +-- Input Array for Iteration 2 is -- +array(9) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) +} + +Last key is : +int(8) + +-- Input Array for Iteration 3 is -- +array(5) { + [0]=> + string(3) "One" + [1]=> + string(4) "_Two" + [2]=> + string(5) "Three" + [3]=> + string(4) "Four" + [4]=> + string(4) "Five" +} + +Last key is : +int(4) + +-- Input Array for Iteration 4 is -- +array(8) { + [0]=> + int(6) + [1]=> + string(3) "six" + [2]=> + int(7) + [3]=> + string(5) "seven" + [4]=> + int(8) + [5]=> + string(5) "eight" + [6]=> + int(9) + [7]=> + string(4) "nine" +} + +Last key is : +int(7) + +-- Input Array for Iteration 5 is -- +array(5) { + ["a"]=> + string(3) "aaa" + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" + ["d"]=> + string(3) "ddd" + ["e"]=> + string(3) "eee" +} + +Last key is : +string(1) "e" + +-- Input Array for Iteration 6 is -- +array(5) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} + +Last key is : +int(5) + +-- Input Array for Iteration 7 is -- +array(5) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + int(7) + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} + +Last key is : +int(5) + +-- Input Array for Iteration 8 is -- +array(12) { + ["f"]=> + string(3) "fff" + [1]=> + string(3) "one" + [4]=> + int(6) + [""]=> + int(3) + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" + [3]=> + float(3.7) + [5]=> + string(4) "Five" + [6]=> + float(8.6) + ["4name"]=> + string(5) "jonny" + ["a"]=> + NULL +} + +Last key is : +string(1) "a" + +-- Input Array for Iteration 9 is -- +array(4) { + [0]=> + int(12) + [1]=> + string(4) "name" + [2]=> + string(3) "age" + [3]=> + string(2) "45" +} + +Last key is : +int(3) + +-- Input Array for Iteration 10 is -- +array(3) { + [0]=> + array(3) { + [0]=> + string(3) "oNe" + [1]=> + string(3) "tWo" + [2]=> + int(4) + } + [1]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [2]=> + array(0) { + } +} + +Last key is : +int(2) + +-- Input Array for Iteration 11 is -- +array(10) { + ["one"]=> + int(2) + ["three"]=> + int(3) + [0]=> + int(3) + [1]=> + int(4) + [3]=> + int(33) + [4]=> + int(44) + [5]=> + int(57) + [6]=> + int(6) + ["5.4"]=> + int(554) + ["5.7"]=> + int(557) +} + +Last key is : +string(3) "5.7" + +-- Input Array for Iteration 12 is -- +array(1) { + [0]=> + string(3) "foo" +} + +Last key is : +int(0) + +-- Input Array for Iteration 13 is -- +array(1) { + [1]=> + string(2) "42" +} + +Last key is : +int(1) + +Done diff --git a/tests/std/array/array_key_last_variation.phpt b/tests/std/array/array_key_last_variation.phpt new file mode 100644 index 00000000..3b2a4867 --- /dev/null +++ b/tests/std/array/array_key_last_variation.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test array_key_last() function (variation) +--FILE-- + +--EXPECT-- +*** Checking for internal array pointer not being changed by array_key_last *** + +Current Element is : int(1) + +Next Element is : int(2) + +Last key is : int(8) + +Current Element after array_key_last operation is: int(2) + +Done diff --git a/tests/std/array/array_keys_basic.phpt b/tests/std/array/array_keys_basic.phpt new file mode 100644 index 00000000..dc54976d --- /dev/null +++ b/tests/std/array/array_keys_basic.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test array_keys() function (basic) +--FILE-- + 1, "b" => 2, 2 => 2.0, -23 => "asdasd", + array(1,2,3)); +var_dump(array_keys($basic_arr)); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing array_keys() on basic array operation *** +array(5) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + int(2) + [3]=> + int(-23) + [4]=> + int(3) +} +Done diff --git a/tests/std/array/array_keys_on_GLOBALS.phpt b/tests/std/array/array_keys_on_GLOBALS.phpt new file mode 100644 index 00000000..6231d5e6 --- /dev/null +++ b/tests/std/array/array_keys_on_GLOBALS.phpt @@ -0,0 +1,17 @@ +--TEST-- +Using array_keys() on $GLOBALS +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +bool(false) diff --git a/tests/std/array/array_keys_variation_001.phpt b/tests/std/array/array_keys_variation_001.phpt new file mode 100644 index 00000000..1e194ae8 --- /dev/null +++ b/tests/std/array/array_keys_variation_001.phpt @@ -0,0 +1,149 @@ +--TEST-- +Test array_keys() function (variation - 1) +--SKIPIF-- + +--FILE-- + "World"), + array("" => ""), + array(1,2,3, "d" => array(4,6, "d")), + array("a" => 1, "b" => 2, "c" =>3, "d" => array()), + array(0 => 0, 1 => 1, 2 => 2, 3 => 3), + array(0 =>3.000, 1 =>2, 1 =>3, "a"=>3, 3=>5, "5"=>3.000), + array(TRUE => TRUE, FALSE => FALSE, NULL => NULL, "\x000", "\000"), + array("a" => "abcd", "a" => "", "ab" => -6, "cd" => -0.5 ), + array(0 => array(), 1=> array(0), 2 => array(1), ""=> array(),""=>"" ) +); + +$i = 0; +/* loop through to test array_keys() with different arrays */ +foreach ($arrays as $array) { + echo "\n-- Iteration $i --\n"; + var_dump(array_keys($array)); + $i++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing array_keys() on various arrays *** +-- Iteration 0 -- +array(0) { +} + +-- Iteration 1 -- +array(1) { + [0]=> + int(0) +} + +-- Iteration 2 -- +array(1) { + [0]=> + int(0) +} + +-- Iteration 3 -- +array(1) { + [0]=> + string(5) "Hello" +} + +-- Iteration 4 -- +array(1) { + [0]=> + string(0) "" +} + +-- Iteration 5 -- +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + string(1) "d" +} + +-- Iteration 6 -- +array(4) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "d" +} + +-- Iteration 7 -- +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) +} + +-- Iteration 8 -- +array(5) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + string(1) "a" + [3]=> + int(3) + [4]=> + int(5) +} + +-- Iteration 9 -- +array(5) { + [0]=> + int(1) + [1]=> + int(0) + [2]=> + string(0) "" + [3]=> + int(2) + [4]=> + int(3) +} + +-- Iteration 10 -- +array(3) { + [0]=> + string(1) "a" + [1]=> + string(2) "ab" + [2]=> + string(2) "cd" +} + +-- Iteration 11 -- +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + string(0) "" +} +Done diff --git a/tests/std/array/array_keys_variation_002.phpt b/tests/std/array/array_keys_variation_002.phpt new file mode 100644 index 00000000..1765c217 --- /dev/null +++ b/tests/std/array/array_keys_variation_002.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test array_keys() function (variation - 2) +--FILE-- + 1, "b" => 2, "c" => 3))); +var_dump(array_keys(array())); // null array + +echo "Done\n"; +?> +--EXPECT-- +*** Testing array_keys() on an array created on the fly *** +array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" +} +array(0) { +} +Done diff --git a/tests/std/array/array_keys_variation_003.phpt b/tests/std/array/array_keys_variation_003.phpt new file mode 100644 index 00000000..b04c5445 --- /dev/null +++ b/tests/std/array/array_keys_variation_003.phpt @@ -0,0 +1,114 @@ +--TEST-- +Test array_keys() function (variation - 3) +--SKIPIF-- + +--FILE-- + TRUE, + FALSE => FALSE, + 1 => 1, + 0 => 0, + -1 => -1, + "1" => "1", + "0" => "0", + "-1" => "-1", + NULL, + array(), + "php" => "php", + "" => "" +); +$values = array(TRUE, FALSE, 1, 0, -1, "1", "0", "-1", NULL, array(), "php", ""); +foreach ($values as $value){ + var_dump($value); + var_dump(array_keys($types_arr, $value)); +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing array_keys() on all the types other than arrays *** +bool(true) +array(3) { + [0]=> + int(1) + [1]=> + int(-1) + [2]=> + string(3) "php" +} +bool(false) +array(4) { + [0]=> + int(0) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + string(0) "" +} +int(1) +array(1) { + [0]=> + int(1) +} +int(0) +array(2) { + [0]=> + int(0) + [1]=> + int(2) +} +int(-1) +array(1) { + [0]=> + int(-1) +} +string(1) "1" +array(1) { + [0]=> + int(1) +} +string(1) "0" +array(1) { + [0]=> + int(0) +} +string(2) "-1" +array(1) { + [0]=> + int(-1) +} +NULL +array(3) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + string(0) "" +} +array(0) { +} +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +string(3) "php" +array(1) { + [0]=> + string(3) "php" +} +string(0) "" +array(2) { + [0]=> + int(2) + [1]=> + string(0) "" +} +Done diff --git a/tests/std/array/array_keys_variation_004.phpt b/tests/std/array/array_keys_variation_004.phpt new file mode 100644 index 00000000..a919d69e --- /dev/null +++ b/tests/std/array/array_keys_variation_004.phpt @@ -0,0 +1,73 @@ +--TEST-- +Test array_keys() function (variation - 4) +--SKIPIF-- + + +--FILE-- + TRUE, + FALSE => FALSE, + 1 => 1, + 0 => 0, + -1 => -1, + "1" => "1", + "0" => "0", + "-1" => "-1", + NULL, + array(), + "php" => "php", + "" => "" +); +$values = array(TRUE, FALSE, 1, 0, -1, "1", "0", "-1", NULL, array(), "php", ""); +foreach ($values as $value){ + var_dump(array_keys($types_arr, $value, TRUE)); +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing array_keys() on all the types other than arrays *** +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(0) +} +array(1) { + [0]=> + int(-1) +} +array(1) { + [0]=> + int(2) +} +array(1) { + [0]=> + int(3) +} +array(1) { + [0]=> + string(3) "php" +} +array(1) { + [0]=> + string(0) "" +} +Done diff --git a/tests/std/array/array_keys_variation_005.phpt b/tests/std/array/array_keys_variation_005.phpt new file mode 100644 index 00000000..c9870ec6 --- /dev/null +++ b/tests/std/array/array_keys_variation_005.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test array_keys() function (variation - 5) +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +*** Testing array_keys() with resource type *** +array(1) { + [0]=> + int(0) +} +array(1) { + [0]=> + int(0) +} +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(1) +} diff --git a/tests/std/array/array_map_001.phpt b/tests/std/array/array_map_001.phpt new file mode 100644 index 00000000..964480cd --- /dev/null +++ b/tests/std/array/array_map_001.phpt @@ -0,0 +1,24 @@ +--TEST-- +array_map() and exceptions in the callback +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(17) "exception caught!" +Done diff --git a/tests/std/array/array_map_basic.phpt b/tests/std/array/array_map_basic.phpt new file mode 100644 index 00000000..70d260c1 --- /dev/null +++ b/tests/std/array/array_map_basic.phpt @@ -0,0 +1,62 @@ +--TEST-- +Test array_map() function : basic functionality +--FILE-- + +--EXPECT-- +*** Testing array_map() : basic functionality *** +-- With two integer array -- +array(3) { + [0]=> + int(4) + [1]=> + int(10) + [2]=> + int(18) +} +-- With single integer array -- +array(3) { + [0]=> + int(1) + [1]=> + int(4) + [2]=> + int(9) +} +-- With string array -- +array(2) { + [0]=> + string(12) "one = single" + [1]=> + string(12) "two = double" +} +Done diff --git a/tests/std/array/array_map_error.phpt b/tests/std/array/array_map_error.phpt new file mode 100644 index 00000000..aaacbebc --- /dev/null +++ b/tests/std/array/array_map_error.phpt @@ -0,0 +1,58 @@ +--TEST-- +Test array_map() function : error conditions +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } + echo "\n-- Testing array_map() function with less no. of arrays than callback function arguments --\n"; + $arr1 = array(1, 2); + try { + var_dump(array_map('callback2', $arr1)); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + echo "\n-- Testing array_map() function with more no. of arrays than callback function arguments --\n"; + $arr2 = array(3, 4); + $arr3 = array(5, 6); + var_dump(array_map('callback2', $arr1, $arr2, $arr3)); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : error conditions *** + +-- Testing array_map() function with one less than expected no. of arguments -- +Exception: array_map() expects at least 2 arguments, 1 given + +-- Testing array_map() function with less no. of arrays than callback function arguments -- +Exception: Too few arguments to function callback2(), 1 passed and exactly 2 expected + +-- Testing array_map() function with more no. of arrays than callback function arguments -- +array(2) { + [0]=> + int(3) + [1]=> + int(8) +} +Done diff --git a/tests/std/array/array_map_object1.phpt b/tests/std/array/array_map_object1.phpt new file mode 100644 index 00000000..1baeeba6 --- /dev/null +++ b/tests/std/array/array_map_object1.phpt @@ -0,0 +1,195 @@ +--TEST-- +Test array_map() function : usage variations - object functionality +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; + } +} +class SimpleClassPri +{ + private $var1 = 10; + private static function add($n) + { + return $var + $n; + } +} +class SimpleClassPro +{ + protected $var1 = 5; + protected static function mul($n) + { + return $var1 * $n; + } +} +class EmptyClass +{ +} +abstract class AbstractClass +{ + protected $var2 = 5; + abstract static function emptyFunction(); +} +// class deriving the above abstract class +class ChildClass extends AbstractClass +{ + private $var3; + public static function emptyFunction() + { + echo "defined in child\n"; + } +} +class FinalClass +{ + private $var4; + final static function finalMethod() + { + echo "This function can't be overloaded\n"; + } +} +class StaticClass +{ + static $var5 = 2; + public static function square($n) + { + return $n * $n; + } + private static function cube($n) + { + return $n * $n * $n; + } + protected static function retVal($n) + { + return array($n); + } +} +interface myInterface +{ + public function toImplement(); +} +class InterClass implements myInterface +{ + public static function square($n) + { + return $n * $n; + } + public function toImplement() + { + return 1; + } +} +function main() +{ + /* + * Testing array_map() for object functionalities: + * 1) simple class with variable and method + * 2) class without members + * 3) class with only one method and no variable + * 4) abstract and child class + * 5) class with static and final members + * 6) interface and implemented class + */ + echo "*** Testing array_map() : object functionality ***\n"; + echo "-- simple class with public variable and method --\n"; + test(array('SimpleClass', 'square'), array(1, 2)); + echo "\n-- simple class with private variable and method --\n"; + test(array('SimpleClassPri', 'add'), array(1)); + echo "\n-- simple class with protected variable and method --\n"; + test(array('SimpleClassPro', 'mul'), array(2)); + echo "\n-- class without members --\n"; + test(array('EmptyClass'), array(1, 2)); + echo "\n-- abstract class --\n"; + test(array('ChildClass', 'emptyFunction'), array(1, 2)); + echo "\n-- class with final method --\n"; + test(array('FinalClass', 'finalMethod'), array(1, 2)); + echo "\n-- class with static members --\n"; + test(array('StaticClass', 'square'), array(1, 2)); + test(array('StaticClass', 'cube'), array(2)); + test(array('StaticClass', 'retVal'), array(3, 4)); + echo "-- class implementing an interface --\n"; + test(array('InterClass', 'square'), array(1, 2)); +} +?> +--EXPECT-- +*** Testing array_map() : object functionality *** +-- simple class with public variable and method -- +SimpleClass::square +array(2) { + [0]=> + int(1) + [1]=> + int(4) +} + +-- simple class with private variable and method -- +SimpleClassPri::add +array_map(): Argument #1 ($callback) must be a valid callback or null, cannot access private method SimpleClassPri::add() + +-- simple class with protected variable and method -- +SimpleClassPro::mul +array_map(): Argument #1 ($callback) must be a valid callback or null, cannot access protected method SimpleClassPro::mul() + +-- class without members -- +EmptyClass +array_map(): Argument #1 ($callback) must be a valid callback or null, array callback must have exactly two members + +-- abstract class -- +ChildClass::emptyFunction +defined in child +defined in child +array(2) { + [0]=> + NULL + [1]=> + NULL +} + +-- class with final method -- +FinalClass::finalMethod +This function can't be overloaded +This function can't be overloaded +array(2) { + [0]=> + NULL + [1]=> + NULL +} + +-- class with static members -- +StaticClass::square +array(2) { + [0]=> + int(1) + [1]=> + int(4) +} +StaticClass::cube +array_map(): Argument #1 ($callback) must be a valid callback or null, cannot access private method StaticClass::cube() +StaticClass::retVal +array_map(): Argument #1 ($callback) must be a valid callback or null, cannot access protected method StaticClass::retVal() +-- class implementing an interface -- +InterClass::square +array(2) { + [0]=> + int(1) + [1]=> + int(4) +} diff --git a/tests/std/array/array_map_object2.phpt b/tests/std/array/array_map_object2.phpt new file mode 100644 index 00000000..3f281e0a --- /dev/null +++ b/tests/std/array/array_map_object2.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test array_map() function : object functionality - with non-existent class and method +--FILE-- +getMessage(), "\n"; + } + echo "-- with existent class and non-existent method --\n"; + try { + var_dump(array_map(array('SimpleClass', 'non-existent'), array(1, 2))); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : with non-existent class and method *** +-- with non-existent class -- +array_map(): Argument #1 ($callback) must be a valid callback or null, class "non-existent" not found +-- with existent class and non-existent method -- +array_map(): Argument #1 ($callback) must be a valid callback or null, class SimpleClass does not have a method "non-existent" +Done diff --git a/tests/std/array/array_map_object3.phpt b/tests/std/array/array_map_object3.phpt new file mode 100644 index 00000000..7786801a --- /dev/null +++ b/tests/std/array/array_map_object3.phpt @@ -0,0 +1,90 @@ +--TEST-- +Test array_map() function : object functionality - class methods as callback function +--FILE-- +parent_obj = new ParentClass(); + } + public $var2 = 5; + public static function staticChild($n) + { + return $n; + } + public function nonstaticChild($n) + { + return $n; + } +} +function main() +{ + /* + * Testing array_map() for object functionality with following callback function variations: + * 1) child class method using parent object + * 2) parent class method using child object + * 3) child class method using parent class + * 4) parent class method using child class + */ + echo "*** Testing array_map() : class methods as callback function ***\n"; + $arr1 = array(1, 5, 7); + $childobj = new ChildClass(); + $parentobj = new ParentClass(); + echo "-- accessing parent method from child class --\n"; + var_dump(array_map(array('ChildClass', 'staticParent1'), $arr1)); + echo "-- accessing child method from parent class --\n"; + try { + var_dump(array_map(array('ParentClass', 'staticChild'), $arr1)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + echo "-- accessing parent method using child class object --\n"; + var_dump(array_map(array($childobj, 'staticParent1'), $arr1)); + echo "-- accessing child method using parent class object --\n"; + try { + var_dump(array_map(array($parentobj, 'staticChild'), $arr1)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : class methods as callback function *** +-- accessing parent method from child class -- +array(3) { + [0]=> + int(1) + [1]=> + int(5) + [2]=> + int(7) +} +-- accessing child method from parent class -- +array_map(): Argument #1 ($callback) must be a valid callback or null, class ParentClass does not have a method "staticChild" +-- accessing parent method using child class object -- +array(3) { + [0]=> + int(1) + [1]=> + int(5) + [2]=> + int(7) +} +-- accessing child method using parent class object -- +array_map(): Argument #1 ($callback) must be a valid callback or null, class ParentClass does not have a method "staticChild" +Done diff --git a/tests/std/array/array_map_variation1.phpt b/tests/std/array/array_map_variation1.phpt new file mode 100644 index 00000000..68f77437 --- /dev/null +++ b/tests/std/array/array_map_variation1.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_map() function : usage variations - string keys +--FILE-- + "value"); + var_dump(array_map("cb1", $arr)); + var_dump(array_map("cb2", $arr, $arr)); + var_dump(array_map(null, $arr)); + var_dump(array_map(null, $arr, $arr)); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : string keys *** +array(1) { + ["stringkey"]=> + array(1) { + [0]=> + string(5) "value" + } +} +array(1) { + [0]=> + array(2) { + [0]=> + string(5) "value" + [1]=> + string(5) "value" + } +} +array(1) { + ["stringkey"]=> + string(5) "value" +} +array(1) { + [0]=> + array(2) { + [0]=> + string(5) "value" + [1]=> + string(5) "value" + } +} +Done diff --git a/tests/std/array/array_map_variation10.phpt b/tests/std/array/array_map_variation10.phpt new file mode 100644 index 00000000..1d79ffed --- /dev/null +++ b/tests/std/array/array_map_variation10.phpt @@ -0,0 +1,89 @@ +--TEST-- +Test array_map() function : usage variations - anonymous callback function +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} + +echo "-- anonymous function with NULL parameter --\n"; +var_dump( array_map( function() { return NULL; }, $array1)); + +echo "-- anonymous function with NULL body --\n"; +var_dump( array_map( function($a) { }, $array1)); + +echo "-- passing NULL as 'array1' --\n"; +try { + var_dump( array_map( function($a) { return array($a); }, NULL)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_map() : anonymous callback function *** +-- anonymous function with all parameters and body -- +array(3) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(3) + } + [1]=> + array(2) { + [0]=> + int(2) + [1]=> + int(4) + } + [2]=> + array(2) { + [0]=> + int(3) + [1]=> + int(5) + } +} +-- anonymous function with two parameters and passing one array -- +Exception: Too few arguments to function {closure:%s:%d}(), 1 passed and exactly 2 expected +-- anonymous function with NULL parameter -- +array(3) { + [0]=> + NULL + [1]=> + NULL + [2]=> + NULL +} +-- anonymous function with NULL body -- +array(3) { + [0]=> + NULL + [1]=> + NULL + [2]=> + NULL +} +-- passing NULL as 'array1' -- +array_map(): Argument #2 ($array) must be of type array, null given +Done diff --git a/tests/std/array/array_map_variation11.phpt b/tests/std/array/array_map_variation11.phpt new file mode 100644 index 00000000..7749af78 --- /dev/null +++ b/tests/std/array/array_map_variation11.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test array_map() function : usage variations - with recursive callback +--FILE-- + +--EXPECT-- +*** Testing array_map() : recursive callback function *** +array(3) { + [0]=> + int(1) + [1]=> + array(3) { + [0]=> + int(4) + [1]=> + int(9) + [2]=> + array(1) { + [0]=> + int(25) + } + } + [2]=> + array(1) { + [0]=> + int(16) + } +} +Done diff --git a/tests/std/array/array_map_variation12.phpt b/tests/std/array/array_map_variation12.phpt new file mode 100644 index 00000000..d3fa62e9 --- /dev/null +++ b/tests/std/array/array_map_variation12.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test array_map() function : usage variations - built-in function as callback +--FILE-- +getMessage(), "\n"; +} + +echo "-- with language construct --\n"; +try { + var_dump( array_map('echo', $array1)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_map() : built-in function *** +-- with built-in function 'pow' and two parameters -- +array(3) { + [0]=> + int(1) + [1]=> + int(16) + [2]=> + int(243) +} +-- with built-in function 'pow' and one parameter -- +pow() expects exactly 2 arguments, 1 given +-- with language construct -- +array_map(): Argument #1 ($callback) must be a valid callback or null, function "echo" not found or invalid function name +Done diff --git a/tests/std/array/array_map_variation13.phpt b/tests/std/array/array_map_variation13.phpt new file mode 100644 index 00000000..596e04af --- /dev/null +++ b/tests/std/array/array_map_variation13.phpt @@ -0,0 +1,97 @@ +--TEST-- +Test array_map() function : usage variations - callback function with different return types +--FILE-- + +--EXPECT-- +*** Testing array_map() : callback with diff return value *** +-- with integer return value -- +array(3) { + [0]=> + int(4) + [1]=> + int(6) + [2]=> + int(8) +} +-- with string return value -- +array(3) { + [0]=> + string(2) "13" + [1]=> + string(2) "24" + [2]=> + string(2) "35" +} +-- with bool return value -- +array(3) { + [0]=> + bool(true) + [1]=> + bool(true) + [2]=> + bool(true) +} +-- with null return value -- +array(3) { + [0]=> + NULL + [1]=> + NULL + [2]=> + NULL +} +-- with no return value -- +callback_without_ret called +callback_without_ret called +callback_without_ret called +array(3) { + [0]=> + NULL + [1]=> + NULL + [2]=> + NULL +} +Done diff --git a/tests/std/array/array_map_variation14.phpt b/tests/std/array/array_map_variation14.phpt new file mode 100644 index 00000000..b1276b92 --- /dev/null +++ b/tests/std/array/array_map_variation14.phpt @@ -0,0 +1,129 @@ +--TEST-- +Test array_map() function : usage variations - null value for 'callback' argument +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; +} + +echo "-- with empty array --\n"; +try { + var_dump( array_map(array(), $arr1, $arr2) ); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_map() : null value for 'callback' argument *** +-- with null -- +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + string(3) "one" + [2]=> + float(1.1) + } + [1]=> + array(3) { + [0]=> + int(2) + [1]=> + string(3) "two" + [2]=> + float(2.2) + } +} +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + string(3) "one" + [2]=> + float(1.1) + } + [1]=> + array(3) { + [0]=> + int(2) + [1]=> + string(3) "two" + [2]=> + float(2.2) + } +} +-- with unset variable -- +array(2) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + string(3) "one" + [2]=> + float(1.1) + } + [1]=> + array(3) { + [0]=> + int(2) + [1]=> + string(3) "two" + [2]=> + float(2.2) + } +} +-- with undefined variable -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +-- with empty string -- +array_map(): Argument #1 ($callback) must be a valid callback or null, function "" not found or invalid function name +-- with empty array -- +array_map(): Argument #1 ($callback) must be a valid callback or null, array callback must have exactly two members +Done diff --git a/tests/std/array/array_map_variation15.phpt b/tests/std/array/array_map_variation15.phpt new file mode 100644 index 00000000..d053a720 --- /dev/null +++ b/tests/std/array/array_map_variation15.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test array_map() function : usage variations - non existent 'callback' function +--FILE-- +getMessage(), "\n"; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_map() : non existent 'callback' function *** +array_map(): Argument #1 ($callback) must be a valid callback or null, function "non_existent" not found or invalid function name +Done diff --git a/tests/std/array/array_map_variation16.phpt b/tests/std/array/array_map_variation16.phpt new file mode 100644 index 00000000..7ee1f049 --- /dev/null +++ b/tests/std/array/array_map_variation16.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test array_map() function : usage variations - failing built-in functions & language constructs +--FILE-- +getMessage(), "\n"; + } +} + +echo "Done"; +?> +--EXPECT-- +array_map(): Argument #1 ($callback) must be a valid callback or null, function "echo" not found or invalid function name +array_map(): Argument #1 ($callback) must be a valid callback or null, function "array" not found or invalid function name +array_map(): Argument #1 ($callback) must be a valid callback or null, function "empty" not found or invalid function name +array_map(): Argument #1 ($callback) must be a valid callback or null, function "eval" not found or invalid function name +array_map(): Argument #1 ($callback) must be a valid callback or null, function "isset" not found or invalid function name +array_map(): Argument #1 ($callback) must be a valid callback or null, function "list" not found or invalid function name +array_map(): Argument #1 ($callback) must be a valid callback or null, function "print" not found or invalid function name +Done diff --git a/tests/std/array/array_map_variation17.phpt b/tests/std/array/array_map_variation17.phpt new file mode 100644 index 00000000..24cf2892 --- /dev/null +++ b/tests/std/array/array_map_variation17.phpt @@ -0,0 +1,133 @@ +--TEST-- +Test array_map() function : usage variations - unexpected values for 'callback' argument +--FILE-- +getMessage(), "\n"; + } + } + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : unexpected values for 'callback' argument *** + +-- Iteration 1 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 2 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 3 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 4 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 5 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 6 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 7 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 8 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 9 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 10 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 11 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 12 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 13 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 14 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, function "" not found or invalid function name + +-- Iteration 15 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, function "" not found or invalid function name + +-- Iteration 16 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, array callback must have exactly two members + +-- Iteration 17 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, first array member is not a valid class name or object + +-- Iteration 18 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, first array member is not a valid class name or object + +-- Iteration 19 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given + +-- Iteration 20 -- +array_map(): Argument #1 ($callback) must be a valid callback or null, no array or string given +Done diff --git a/tests/std/array/array_map_variation19.phpt b/tests/std/array/array_map_variation19.phpt new file mode 100644 index 00000000..a725117a --- /dev/null +++ b/tests/std/array/array_map_variation19.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test array_map() function : usage variations - callback pass semantics +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + string(10) "original.0" + [1]=> + string(10) "original.1" +} +array(2) { + [0]=> + &string(10) "original.0" + [1]=> + string(10) "original.1" +} diff --git a/tests/std/array/array_map_variation2.phpt b/tests/std/array/array_map_variation2.phpt new file mode 100644 index 00000000..6101ca2f --- /dev/null +++ b/tests/std/array/array_map_variation2.phpt @@ -0,0 +1,134 @@ +--TEST-- +Test array_map() function : usage variations - references +--SKIPIF-- + + +--FILE-- + "v1", "k2" => "v2"); + $arr[] =& $arr["k1"]; + $arr[] =& $arr; + var_dump(array_map("cb1", $arr)); + var_dump(array_map(null, $arr)); + var_dump(array_map(null, $arr, $arr)); + // break cycles + $arr[0] = null; + $arr[1] = null; + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : references *** +string(2) "v1" +string(2) "v2" +string(2) "v1" +array(4) { + ["k1"]=> + &string(2) "v1" + ["k2"]=> + string(2) "v2" + [0]=> + &string(2) "v1" + [1]=> + *RECURSION* +} +array(4) { + ["k1"]=> + array(1) { + [0]=> + string(2) "v1" + } + ["k2"]=> + array(1) { + [0]=> + string(2) "v2" + } + [0]=> + array(1) { + [0]=> + string(2) "v1" + } + [1]=> + array(1) { + [0]=> + array(4) { + ["k1"]=> + &string(2) "v1" + ["k2"]=> + string(2) "v2" + [0]=> + &string(2) "v1" + [1]=> + *RECURSION* + } + } +} +array(4) { + ["k1"]=> + &string(2) "v1" + ["k2"]=> + string(2) "v2" + [0]=> + &string(2) "v1" + [1]=> + *RECURSION* +} +array(4) { + [0]=> + array(2) { + [0]=> + &string(2) "v1" + [1]=> + &string(2) "v1" + } + [1]=> + array(2) { + [0]=> + string(2) "v2" + [1]=> + string(2) "v2" + } + [2]=> + array(2) { + [0]=> + &string(2) "v1" + [1]=> + &string(2) "v1" + } + [3]=> + array(2) { + [0]=> + &array(4) { + ["k1"]=> + &string(2) "v1" + ["k2"]=> + string(2) "v2" + [0]=> + &string(2) "v1" + [1]=> + *RECURSION* + } + [1]=> + &array(4) { + ["k1"]=> + &string(2) "v1" + ["k2"]=> + string(2) "v2" + [0]=> + &string(2) "v1" + [1]=> + *RECURSION* + } + } +} +Done diff --git a/tests/std/array/array_map_variation3.phpt b/tests/std/array/array_map_variation3.phpt new file mode 100644 index 00000000..778fdc6a --- /dev/null +++ b/tests/std/array/array_map_variation3.phpt @@ -0,0 +1,234 @@ +--TEST-- +Test array_map() function : usage variations - different arrays for 'arr1' argument +--SKIPIF-- + +--FILE-- + "one", 2 => "two", 3 => "three"), + // explicit numeric keys, string values + array("one" => 1, "two" => 2, "three" => 3), + // string keys & numeric values + array(1 => 10, 2 => 20, 4 => 40, 3 => 30), + // explicit numeric keys and numeric values + array("one" => "ten", "two" => "twenty", "three" => "thirty"), + // string key/value + array("one" => 1, 2 => "two", 4 => "four"), + //mixed + // associative array, containing null/empty/boolean values as key/value + /*13*/ + array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + // array with repetitive keys + /*18*/ + array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3), + ); + // loop through the various elements of $arrays to test array_map() + $iterator = 1; + foreach ($arrays as $arr1) { + echo "-- Iteration {$iterator} --\n"; + var_dump(array_map('callback', $arr1)); + $iterator++; + } + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : different arrays for 'arr1' argument *** +-- Iteration 1 -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +-- Iteration 2 -- +array(2) { + [0]=> + float(1.1) + [1]=> + float(2.2) +} +-- Iteration 3 -- +array(2) { + [0]=> + array(1) { + [0]=> + int(2) + } + [1]=> + array(1) { + [0]=> + int(1) + } +} +-- Iteration 4 -- +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} +-- Iteration 5 -- +array(0) { +} +-- Iteration 6 -- +array(1) { + [0]=> + NULL +} +-- Iteration 7 -- +array(6) { + [0]=> + string(1) "a" + [1]=> + string(4) "aaaa" + [2]=> + string(1) "b" + [3]=> + string(4) "bbbb" + [4]=> + string(1) "c" + [5]=> + string(5) "ccccc" +} +-- Iteration 8 -- +array(3) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" +} +-- Iteration 9 -- +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) +} +-- Iteration 10 -- +array(4) { + [1]=> + int(10) + [2]=> + int(20) + [4]=> + int(40) + [3]=> + int(30) +} +-- Iteration 11 -- +array(3) { + ["one"]=> + string(3) "ten" + ["two"]=> + string(6) "twenty" + ["three"]=> + string(6) "thirty" +} +-- Iteration 12 -- +array(3) { + ["one"]=> + int(1) + [2]=> + string(3) "two" + [4]=> + string(4) "four" +} +-- Iteration 13 -- +array(3) { + [""]=> + string(4) "null" + ["NULL"]=> + NULL + ["null"]=> + NULL +} +-- Iteration 14 -- +array(4) { + [1]=> + string(4) "true" + [0]=> + string(5) "false" + ["false"]=> + bool(false) + ["true"]=> + bool(true) +} +-- Iteration 15 -- +array(3) { + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" + ["emptys"]=> + string(0) "" +} +-- Iteration 16 -- +array(6) { + [1]=> + string(0) "" + [2]=> + string(0) "" + [3]=> + NULL + [4]=> + NULL + [5]=> + bool(false) + [6]=> + bool(true) +} +-- Iteration 17 -- +array(3) { + [""]=> + int(4) + [0]=> + int(5) + [1]=> + int(6) +} +-- Iteration 18 -- +array(3) { + ["One"]=> + int(10) + ["two"]=> + int(20) + ["three"]=> + int(3) +} +Done diff --git a/tests/std/array/array_map_variation4.phpt b/tests/std/array/array_map_variation4.phpt new file mode 100644 index 00000000..9190ffdf --- /dev/null +++ b/tests/std/array/array_map_variation4.phpt @@ -0,0 +1,147 @@ +--TEST-- +Test array_map() function : usage variations - associative array with different keys +--SKIPIF-- + +--FILE-- + "0"), + array(1 => "1"), + array(1 => "1", 2 => "2", 3 => "3", 4 => "4"), + // arrays with string keys + array('\tHello' => 111, 're\td' => 'color', '\v\fworld' => 2.2, 'pen\n' => 33), + /*8*/ + array("\tHello" => 111, "re\td" => "color", "\v\fworld" => 2.2, "pen\n" => 33), + array("hello", $heredoc => "string"), + // heredoc + // array with object, unset variable and resource variable + array(@$unset_var => "hello", $fp => 'resource'), + // array with mixed values + /*11*/ + array('hello' => 1, "fruit" => 2.2, $fp => 'resource', 133 => "int", @$unset_var => "unset", $heredoc => "heredoc"), + ); + // loop through the various elements of $arrays to test array_map() + $iterator = 1; + foreach ($arrays as $arr1) { + echo "-- Iteration {$iterator} --\n"; + var_dump(array_map('callback', $arr1)); + $iterator++; + } + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_map() : associative array with diff. keys for 'arr1' argument *** + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d +-- Iteration 1 -- +array(0) { +} +-- Iteration 2 -- +array(1) { + [0]=> + string(1) "0" +} +-- Iteration 3 -- +array(1) { + [1]=> + string(1) "1" +} +-- Iteration 4 -- +array(4) { + [1]=> + string(1) "1" + [2]=> + string(1) "2" + [3]=> + string(1) "3" + [4]=> + string(1) "4" +} +-- Iteration 5 -- +array(4) { + ["\tHello"]=> + int(111) + ["re\td"]=> + string(5) "color" + ["\v\fworld"]=> + float(2.2) + ["pen\n"]=> + int(33) +} +-- Iteration 6 -- +array(4) { + [" Hello"]=> + int(111) + ["re d"]=> + string(5) "color" + [" world"]=> + float(2.2) + ["pen +"]=> + int(33) +} +-- Iteration 7 -- +array(2) { + [0]=> + string(5) "hello" + ["Hello world"]=> + string(6) "string" +} +-- Iteration 8 -- +array(2) { + [""]=> + string(5) "hello" + [5]=> + string(8) "resource" +} +-- Iteration 9 -- +array(6) { + ["hello"]=> + int(1) + ["fruit"]=> + float(2.2) + [5]=> + string(8) "resource" + [133]=> + string(3) "int" + [""]=> + string(5) "unset" + ["Hello world"]=> + string(7) "heredoc" +} +Done diff --git a/tests/std/array/array_map_variation5.phpt b/tests/std/array/array_map_variation5.phpt new file mode 100644 index 00000000..dfb9ecf2 --- /dev/null +++ b/tests/std/array/array_map_variation5.phpt @@ -0,0 +1,169 @@ +--TEST-- +Test array_map() function : usage variations - associative array with different values +--SKIPIF-- + +--FILE-- + 0), + array("1" => 1), + array("one" => 1, 'two' => 2, "three" => 3, 4 => 4), + // arrays with float values + /*5*/ + array("float" => 2.3333), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => 33333333.3333), + // arrays with string values + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "pen\n"), + /*8*/ + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => 'pen\n'), + array(1 => "hello", "heredoc" => $heredoc), + // array with object, unset variable and resource variable + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp), + // array with mixed values + /*11*/ + array(1 => 'hello', 2 => new classA(), 222 => "fruit", 'resource' => $fp, "int" => 133, "float" => 444.432, "unset" => @$unset_var, "heredoc" => $heredoc), + ); + // loop through the various elements of $arrays to test array_map() + $iterator = 1; + foreach ($arrays as $arr1) { + echo "-- Iteration {$iterator} --\n"; + var_dump(array_map('callback', $arr1)); + $iterator++; + } + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_map() : associative array with diff. values for 'arr1' argument *** +-- Iteration 1 -- +array(0) { +} +-- Iteration 2 -- +array(1) { + [0]=> + int(0) +} +-- Iteration 3 -- +array(1) { + [1]=> + int(1) +} +-- Iteration 4 -- +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + [4]=> + int(4) +} +-- Iteration 5 -- +array(1) { + ["float"]=> + float(2.3333) +} +-- Iteration 6 -- +array(4) { + ["f1"]=> + float(1.2) + ["f2"]=> + float(3.33) + [3]=> + float(4.89999922839999) + ["f4"]=> + float(33333333.3333) +} +-- Iteration 7 -- +array(4) { + [111]=> + string(6) " Hello" + ["red"]=> + string(6) "col or" + [2]=> + string(7) " world" + [3]=> + string(4) "pen +" +} +-- Iteration 8 -- +array(4) { + [111]=> + string(7) "\tHello" + ["red"]=> + string(7) "col\tor" + [2]=> + string(9) "\v\fworld" + [3]=> + string(5) "pen\n" +} +-- Iteration 9 -- +array(2) { + [1]=> + string(5) "hello" + ["heredoc"]=> + string(11) "Hello world" +} +-- Iteration 10 -- +array(3) { + [11]=> + object(classA)#%d (0) { + } + ["unset"]=> + NULL + ["resource"]=> + resource(%d) of type (stream) +} +-- Iteration 11 -- +array(8) { + [1]=> + string(5) "hello" + [2]=> + object(classA)#%d (0) { + } + [222]=> + string(5) "fruit" + ["resource"]=> + resource(%d) of type (stream) + ["int"]=> + int(133) + ["float"]=> + float(444.432) + ["unset"]=> + NULL + ["heredoc"]=> + string(11) "Hello world" +} +Done diff --git a/tests/std/array/array_map_variation6.phpt b/tests/std/array/array_map_variation6.phpt new file mode 100644 index 00000000..d82eebb9 --- /dev/null +++ b/tests/std/array/array_map_variation6.phpt @@ -0,0 +1,60 @@ +--TEST-- +Test array_map() function : usage variations - array having subarrays +--FILE-- + 'a', 'b' => 2)); + var_dump(array_map('callback', $arr1)); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : array having subarrays *** +array(5) { + [0]=> + array(0) { + } + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [2]=> + array(2) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + } + [3]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(1) "a" + [3]=> + string(1) "b" + } + [4]=> + array(2) { + [1]=> + string(1) "a" + ["b"]=> + int(2) + } +} +Done diff --git a/tests/std/array/array_map_variation7.phpt b/tests/std/array/array_map_variation7.phpt new file mode 100644 index 00000000..6ac8b51b --- /dev/null +++ b/tests/std/array/array_map_variation7.phpt @@ -0,0 +1,101 @@ +--TEST-- +Test array_map() function : usage variations - arrays of different size +--SKIPIF-- + + +--FILE-- + $b); +} +function main() +{ + /* + * Test array_map() by passing array having different size + * 1) first array as empty array + * 2) second array as empty array + * 3) second array shorter than first array + * 4) first array shorter than second array + * 5) one more array than callback function arguments + */ + echo "*** Testing array_map() : arrays with diff. size ***\n"; + // calling array_map with different arrays + var_dump(array_map('callback', array(1, 2, 3), array())); + var_dump(array_map('callback', array(), array('a', 'b', 'c'))); + var_dump(array_map('callback', array(1, 2, 3), array('a', 'b'))); + var_dump(array_map('callback', array(012, 0x2f, 0x1a), array(2.3, 1240.0))); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : arrays with diff. size *** +array(3) { + [0]=> + array(1) { + [1]=> + NULL + } + [1]=> + array(1) { + [2]=> + NULL + } + [2]=> + array(1) { + [3]=> + NULL + } +} +array(3) { + [0]=> + array(1) { + [0]=> + string(1) "a" + } + [1]=> + array(1) { + [0]=> + string(1) "b" + } + [2]=> + array(1) { + [0]=> + string(1) "c" + } +} +array(3) { + [0]=> + array(1) { + [1]=> + string(1) "a" + } + [1]=> + array(1) { + [2]=> + string(1) "b" + } + [2]=> + array(1) { + [3]=> + NULL + } +} +array(3) { + [0]=> + array(1) { + [10]=> + float(2.3) + } + [1]=> + array(1) { + [47]=> + float(1240) + } + [2]=> + array(1) { + [26]=> + NULL + } +} +Done diff --git a/tests/std/array/array_map_variation8.phpt b/tests/std/array/array_map_variation8.phpt new file mode 100644 index 00000000..28391ff4 --- /dev/null +++ b/tests/std/array/array_map_variation8.phpt @@ -0,0 +1,65 @@ +--TEST-- +Test array_map() function : usage variations - array with references +--FILE-- + 0, 1 => &$value4, 2 => &$value2, 3 => "hello", 4 => &$value3, $value4 => &$value2); + echo "-- with one array --\n"; + var_dump(array_map('callback1', $arr1)); + echo "-- with two arrays --\n"; + var_dump(array_map('callback_cat', $arr1, $arr1)); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : array with references for 'arr1' argument *** +-- with one array -- +array(6) { + [0]=> + int(0) + [1]=> + string(5) "hello" + [2]=> + string(5) "hello" + [3]=> + string(5) "hello" + [4]=> + int(0) + ["hello"]=> + string(5) "hello" +} +-- with two arrays -- +array(6) { + [0]=> + string(2) "00" + [1]=> + string(10) "hellohello" + [2]=> + string(10) "hellohello" + [3]=> + string(10) "hellohello" + [4]=> + string(2) "00" + [5]=> + string(10) "hellohello" +} +Done diff --git a/tests/std/array/array_map_variation9.phpt b/tests/std/array/array_map_variation9.phpt new file mode 100644 index 00000000..4ac45686 --- /dev/null +++ b/tests/std/array/array_map_variation9.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test array_map() function : usage variations - binary safe checking +--SKIPIF-- + + +--FILE-- + $b); +} +function main() +{ + /* + * Test array_map() by passing array having binary values for $arr1 argument + */ + echo "*** Testing array_map() : array with binary data for 'arr1' argument ***\n"; + // array with binary data + $arr1 = array("hello", "world", "1", "22.22"); + echo "-- checking binary safe array with one parameter callback function --\n"; + var_dump(array_map('callback1', $arr1)); + echo "-- checking binary safe array with two parameter callback function --\n"; + try { + var_dump(array_map("callback2", $arr1)); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_map() : array with binary data for 'arr1' argument *** +-- checking binary safe array with one parameter callback function -- +array(4) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + [2]=> + string(1) "1" + [3]=> + string(5) "22.22" +} +-- checking binary safe array with two parameter callback function -- +Exception: Too few arguments to function callback2(), 1 passed and exactly 2 expected +Done diff --git a/tests/std/array/array_merge.phpt b/tests/std/array/array_merge.phpt new file mode 100644 index 00000000..5890f94a --- /dev/null +++ b/tests/std/array/array_merge.phpt @@ -0,0 +1,914 @@ +--TEST-- +Test array_merge() function +--INI-- +precision=14 +--SKIPIF-- + +--FILE-- + "string"), + array( "" => "string"), + array( -2 => 12), + array( "a" => 1, "b" => -2.344, "b" => "string", "c" => NULL, "d" => -2.344), + array( 4 => 1, 3 => -2.344, "3" => "string", "2" => NULL,1 => -2.344), + array( NULL, 1 => "Hi", "string" => "hello", + array("" => "World", "-2.34" => "a", "0" => "b")) +); + +$end_array = array( + array(), + array( 1 => "string"), + array( "" => "string"), + array( -2 => 12), + array( "a" => 1, "b" => -2.344, "b" => "string", "c" => NULL, "d" => -2.344), + array( 4 => 1, 3 => -2.344, "3" => "string", "2" => NULL, 1=> -2.344), + array( NULL, 1 => "Hi", "string" => "hello", + array("" => "World", "-2.34" => "a", "0" => "b")) +); + +/* loop through to merge two arrays */ +$count_outer = 0; +foreach($begin_array as $first) { + echo "\n\n--- Iteration $count_outer ---"; + $count_inner = 0; + foreach($end_array as $second) { + echo "\n-- Inner iteration $count_inner of Iteration $count_outer --\n"; + $result = array_merge($first, $second); + var_dump($result); + $count_inner++; + } + $count_outer++; +} + + +echo "\n*** Testing array_merge() with three or more arrays ***\n"; +var_dump( array_merge( $end_array[0], + $end_array[5], + $end_array[4], + $end_array[6] + ) + ); + +var_dump( array_merge( $end_array[0], + $end_array[5], + array("array on fly"), + array("nullarray" => array()) + ) + ); + + +echo "\n*** Testing single array argument ***\n"; +/* Empty array */ +var_dump(array_merge(array())); + +/* associative array with string keys, which will not be re-indexed */ +var_dump(array_merge($begin_array[4])); + +/* associative array with numeric keys, which will be re-indexed */ +var_dump(array_merge($begin_array[5])); + +/* associative array with mixed keys and sub-array as element */ +var_dump(array_merge($begin_array[6])); + +echo "\n*** Testing array_merge() with typecasting non-array to array ***\n"; +var_dump(array_merge($begin_array[4], (array)"type1", (array)10, (array)12.34)); + +echo "\n*** Testing array_merge without any arguments ***\n"; +var_dump(array_merge()); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing array_merge() basic functionality *** + +--- Iteration 0 --- +-- Inner iteration 0 of Iteration 0 -- +array(0) { +} + +-- Inner iteration 1 of Iteration 0 -- +array(1) { + [0]=> + string(6) "string" +} + +-- Inner iteration 2 of Iteration 0 -- +array(1) { + [""]=> + string(6) "string" +} + +-- Inner iteration 3 of Iteration 0 -- +array(1) { + [0]=> + int(12) +} + +-- Inner iteration 4 of Iteration 0 -- +array(4) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) +} + +-- Inner iteration 5 of Iteration 0 -- +array(4) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) +} + +-- Inner iteration 6 of Iteration 0 -- +array(4) { + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} + + +--- Iteration 1 --- +-- Inner iteration 0 of Iteration 1 -- +array(1) { + [0]=> + string(6) "string" +} + +-- Inner iteration 1 of Iteration 1 -- +array(2) { + [0]=> + string(6) "string" + [1]=> + string(6) "string" +} + +-- Inner iteration 2 of Iteration 1 -- +array(2) { + [0]=> + string(6) "string" + [""]=> + string(6) "string" +} + +-- Inner iteration 3 of Iteration 1 -- +array(2) { + [0]=> + string(6) "string" + [1]=> + int(12) +} + +-- Inner iteration 4 of Iteration 1 -- +array(5) { + [0]=> + string(6) "string" + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) +} + +-- Inner iteration 5 of Iteration 1 -- +array(5) { + [0]=> + string(6) "string" + [1]=> + int(1) + [2]=> + string(6) "string" + [3]=> + NULL + [4]=> + float(-2.344) +} + +-- Inner iteration 6 of Iteration 1 -- +array(5) { + [0]=> + string(6) "string" + [1]=> + NULL + [2]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [3]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} + + +--- Iteration 2 --- +-- Inner iteration 0 of Iteration 2 -- +array(1) { + [""]=> + string(6) "string" +} + +-- Inner iteration 1 of Iteration 2 -- +array(2) { + [""]=> + string(6) "string" + [0]=> + string(6) "string" +} + +-- Inner iteration 2 of Iteration 2 -- +array(1) { + [""]=> + string(6) "string" +} + +-- Inner iteration 3 of Iteration 2 -- +array(2) { + [""]=> + string(6) "string" + [0]=> + int(12) +} + +-- Inner iteration 4 of Iteration 2 -- +array(5) { + [""]=> + string(6) "string" + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) +} + +-- Inner iteration 5 of Iteration 2 -- +array(5) { + [""]=> + string(6) "string" + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) +} + +-- Inner iteration 6 of Iteration 2 -- +array(5) { + [""]=> + string(6) "string" + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} + + +--- Iteration 3 --- +-- Inner iteration 0 of Iteration 3 -- +array(1) { + [0]=> + int(12) +} + +-- Inner iteration 1 of Iteration 3 -- +array(2) { + [0]=> + int(12) + [1]=> + string(6) "string" +} + +-- Inner iteration 2 of Iteration 3 -- +array(2) { + [0]=> + int(12) + [""]=> + string(6) "string" +} + +-- Inner iteration 3 of Iteration 3 -- +array(2) { + [0]=> + int(12) + [1]=> + int(12) +} + +-- Inner iteration 4 of Iteration 3 -- +array(5) { + [0]=> + int(12) + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) +} + +-- Inner iteration 5 of Iteration 3 -- +array(5) { + [0]=> + int(12) + [1]=> + int(1) + [2]=> + string(6) "string" + [3]=> + NULL + [4]=> + float(-2.344) +} + +-- Inner iteration 6 of Iteration 3 -- +array(5) { + [0]=> + int(12) + [1]=> + NULL + [2]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [3]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} + + +--- Iteration 4 --- +-- Inner iteration 0 of Iteration 4 -- +array(4) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) +} + +-- Inner iteration 1 of Iteration 4 -- +array(5) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) + [0]=> + string(6) "string" +} + +-- Inner iteration 2 of Iteration 4 -- +array(5) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) + [""]=> + string(6) "string" +} + +-- Inner iteration 3 of Iteration 4 -- +array(5) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) + [0]=> + int(12) +} + +-- Inner iteration 4 of Iteration 4 -- +array(4) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) +} + +-- Inner iteration 5 of Iteration 4 -- +array(8) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) +} + +-- Inner iteration 6 of Iteration 4 -- +array(8) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} + + +--- Iteration 5 --- +-- Inner iteration 0 of Iteration 5 -- +array(4) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) +} + +-- Inner iteration 1 of Iteration 5 -- +array(5) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) + [4]=> + string(6) "string" +} + +-- Inner iteration 2 of Iteration 5 -- +array(5) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) + [""]=> + string(6) "string" +} + +-- Inner iteration 3 of Iteration 5 -- +array(5) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) + [4]=> + int(12) +} + +-- Inner iteration 4 of Iteration 5 -- +array(8) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) +} + +-- Inner iteration 5 of Iteration 5 -- +array(8) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) + [4]=> + int(1) + [5]=> + string(6) "string" + [6]=> + NULL + [7]=> + float(-2.344) +} + +-- Inner iteration 6 of Iteration 5 -- +array(8) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) + [4]=> + NULL + [5]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [6]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} + + +--- Iteration 6 --- +-- Inner iteration 0 of Iteration 6 -- +array(4) { + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} + +-- Inner iteration 1 of Iteration 6 -- +array(5) { + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } + [3]=> + string(6) "string" +} + +-- Inner iteration 2 of Iteration 6 -- +array(5) { + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } + [""]=> + string(6) "string" +} + +-- Inner iteration 3 of Iteration 6 -- +array(5) { + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } + [3]=> + int(12) +} + +-- Inner iteration 4 of Iteration 6 -- +array(8) { + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) +} + +-- Inner iteration 5 of Iteration 6 -- +array(8) { + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } + [3]=> + int(1) + [4]=> + string(6) "string" + [5]=> + NULL + [6]=> + float(-2.344) +} + +-- Inner iteration 6 of Iteration 6 -- +array(7) { + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } + [3]=> + NULL + [4]=> + string(2) "Hi" + [5]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} + +*** Testing array_merge() with three or more arrays *** +array(12) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) + [4]=> + NULL + [5]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [6]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} +array(6) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) + [4]=> + string(12) "array on fly" + ["nullarray"]=> + array(0) { + } +} + +*** Testing single array argument *** +array(0) { +} +array(4) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) +} +array(4) { + [0]=> + int(1) + [1]=> + string(6) "string" + [2]=> + NULL + [3]=> + float(-2.344) +} +array(4) { + [0]=> + NULL + [1]=> + string(2) "Hi" + ["string"]=> + string(5) "hello" + [2]=> + array(3) { + [""]=> + string(5) "World" + ["-2.34"]=> + string(1) "a" + [0]=> + string(1) "b" + } +} + +*** Testing array_merge() with typecasting non-array to array *** +array(7) { + ["a"]=> + int(1) + ["b"]=> + string(6) "string" + ["c"]=> + NULL + ["d"]=> + float(-2.344) + [0]=> + string(5) "type1" + [1]=> + int(10) + [2]=> + float(12.34) +} + +*** Testing array_merge without any arguments *** +array(0) { +} +Done diff --git a/tests/std/array/array_merge_basic.phpt b/tests/std/array/array_merge_basic.phpt new file mode 100644 index 00000000..e58d0cf5 --- /dev/null +++ b/tests/std/array/array_merge_basic.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test array_merge() function : basic functionality +--FILE-- + 1, 'b' => 2, 'c' => 3); + +var_dump(array_merge($array1, $array2)); + +var_dump(array_merge($array2, $array1)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge() : basic functionality *** +array(6) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(3) "two" + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + int(3) +} +array(6) { + ["a"]=> + int(1) + ["b"]=> + int(2) + ["c"]=> + int(3) + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} +Done diff --git a/tests/std/array/array_merge_recursive_basic1.phpt b/tests/std/array/array_merge_recursive_basic1.phpt new file mode 100644 index 00000000..97f38706 --- /dev/null +++ b/tests/std/array/array_merge_recursive_basic1.phpt @@ -0,0 +1,99 @@ +--TEST-- +Test array_merge_recursive() function : basic functionality - array with default keys +--FILE-- + +--EXPECT-- +*** Testing array_merge_recursive() : array with default keys *** +-- Without arguments -- +array(0) { +} +-- With default argument -- +array(2) { + [0]=> + int(1) + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} +-- With more arguments -- +array(4) { + [0]=> + int(1) + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [2]=> + int(3) + [3]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } +} +array(6) { + [0]=> + int(1) + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [2]=> + int(3) + [3]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [4]=> + array(2) { + [0]=> + int(6) + [1]=> + int(7) + } + [5]=> + array(2) { + [0]=> + string(4) "str1" + [1]=> + string(4) "str2" + } +} +Done diff --git a/tests/std/array/array_merge_recursive_basic2.phpt b/tests/std/array/array_merge_recursive_basic2.phpt new file mode 100644 index 00000000..ee311113 --- /dev/null +++ b/tests/std/array/array_merge_recursive_basic2.phpt @@ -0,0 +1,89 @@ +--TEST-- +Test array_merge_recursive() function : basic functionality - associative arrays +--FILE-- + "one", 2 => array(1, 2)); +$arr2 = array(2 => 'three', "four" => array("hello", 'world')); +$arr3 = array(1 => array(6, 7), 'four' => array("str1", 'str2')); + +// Calling array_merge_recursive() with default arguments +echo "-- With default argument --\n"; +var_dump( array_merge_recursive($arr1) ); + +// Calling array_merge_recursive() with more arguments +echo "-- With more arguments --\n"; +var_dump( array_merge_recursive($arr1,$arr2) ); +var_dump( array_merge_recursive($arr1,$arr2,$arr3) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge_recursive() : associative arrays *** +-- With default argument -- +array(2) { + [0]=> + string(3) "one" + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} +-- With more arguments -- +array(4) { + [0]=> + string(3) "one" + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [2]=> + string(5) "three" + ["four"]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } +} +array(5) { + [0]=> + string(3) "one" + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [2]=> + string(5) "three" + ["four"]=> + array(4) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + [2]=> + string(4) "str1" + [3]=> + string(4) "str2" + } + [3]=> + array(2) { + [0]=> + int(6) + [1]=> + int(7) + } +} +Done diff --git a/tests/std/array/array_merge_recursive_variation1.phpt b/tests/std/array/array_merge_recursive_variation1.phpt new file mode 100644 index 00000000..f94a7165 --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation1.phpt @@ -0,0 +1,205 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - unexpected values for $arr1 argument +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; + } + // with more arguments + echo "-- With more arguments --"; + try { + var_dump(array_merge_recursive($arr1, $arr2)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_merge_recursive() : Passing non array values to $arr1 argument *** + +-- Iteration 1 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, int given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, int given + +-- Iteration 2 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, int given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, int given + +-- Iteration 3 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, int given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, int given + +-- Iteration 4 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, int given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, int given + +-- Iteration 5 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, float given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, float given + +-- Iteration 6 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, float given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, float given + +-- Iteration 7 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, float given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, float given + +-- Iteration 8 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, float given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, float given + +-- Iteration 9 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, float given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, float given + +-- Iteration 10 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, null given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, null given + +-- Iteration 11 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, null given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, null given + +-- Iteration 12 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, true given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, true given + +-- Iteration 13 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, false given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, false given + +-- Iteration 14 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, true given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, true given + +-- Iteration 15 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, false given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, false given + +-- Iteration 16 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, string given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, string given + +-- Iteration 17 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, string given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, string given + +-- Iteration 18 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, string given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, string given + +-- Iteration 19 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, string given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, string given + +-- Iteration 20 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, string given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, string given + +-- Iteration 21 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, null given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, null given + +-- Iteration 22 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, null given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, null given + +-- Iteration 23 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, resource given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, resource given + +-- Iteration 24 -- +-- With default argument --array_merge_recursive(): Argument #1 must be of type array, A given +-- With more arguments --array_merge_recursive(): Argument #1 must be of type array, A given +Done diff --git a/tests/std/array/array_merge_recursive_variation10.phpt b/tests/std/array/array_merge_recursive_variation10.phpt new file mode 100644 index 00000000..7f03779c --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation10.phpt @@ -0,0 +1,169 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - two dimensional arrays +--FILE-- + array("hello", "world", "str1" => "hello", "str2" => 'world'), + array(1 => "one", 2 => "two", "one", 'two'), + array(1, 2, 3, 1) +); + +// initialize the second argument +$arr2 = array(1, "hello", "array" => array("hello", 'world')); + +echo "-- Passing the entire 2-d array --\n"; +echo "-- With default argument --\n"; +var_dump( array_merge_recursive($arr1) ); +echo "-- With more arguments --\n"; +var_dump( array_merge_recursive($arr1, $arr2) ); + +echo "-- Passing the sub-array --\n"; +echo "-- With default argument --\n"; +var_dump( array_merge_recursive($arr1["array"]) ); +echo "-- With more arguments --\n"; +var_dump( array_merge_recursive($arr1["array"], $arr2["array"]) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge_recursive() : two dimensional array for $arr1 argument *** +-- Passing the entire 2-d array -- +-- With default argument -- +array(4) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(1) + } + ["array"]=> + array(4) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + ["str1"]=> + string(5) "hello" + ["str2"]=> + string(5) "world" + } + [1]=> + array(4) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(3) "one" + [4]=> + string(3) "two" + } + [2]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(1) + } +} +-- With more arguments -- +array(6) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(1) + } + ["array"]=> + array(6) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + ["str1"]=> + string(5) "hello" + ["str2"]=> + string(5) "world" + [2]=> + string(5) "hello" + [3]=> + string(5) "world" + } + [1]=> + array(4) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(3) "one" + [4]=> + string(3) "two" + } + [2]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(1) + } + [3]=> + int(1) + [4]=> + string(5) "hello" +} +-- Passing the sub-array -- +-- With default argument -- +array(4) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + ["str1"]=> + string(5) "hello" + ["str2"]=> + string(5) "world" +} +-- With more arguments -- +array(6) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + ["str1"]=> + string(5) "hello" + ["str2"]=> + string(5) "world" + [2]=> + string(5) "hello" + [3]=> + string(5) "world" +} +Done diff --git a/tests/std/array/array_merge_recursive_variation2.phpt b/tests/std/array/array_merge_recursive_variation2.phpt new file mode 100644 index 00000000..ff656dc8 --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation2.phpt @@ -0,0 +1,148 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - unexpected values for $arr2 argument +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; + } + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_merge_recursive() : Passing non array values to $arr2 argument *** + +-- Iteration 1 --array_merge_recursive(): Argument #2 must be of type array, int given + +-- Iteration 2 --array_merge_recursive(): Argument #2 must be of type array, int given + +-- Iteration 3 --array_merge_recursive(): Argument #2 must be of type array, int given + +-- Iteration 4 --array_merge_recursive(): Argument #2 must be of type array, int given + +-- Iteration 5 --array_merge_recursive(): Argument #2 must be of type array, float given + +-- Iteration 6 --array_merge_recursive(): Argument #2 must be of type array, float given + +-- Iteration 7 --array_merge_recursive(): Argument #2 must be of type array, float given + +-- Iteration 8 --array_merge_recursive(): Argument #2 must be of type array, float given + +-- Iteration 9 --array_merge_recursive(): Argument #2 must be of type array, float given + +-- Iteration 10 --array_merge_recursive(): Argument #2 must be of type array, null given + +-- Iteration 11 --array_merge_recursive(): Argument #2 must be of type array, null given + +-- Iteration 12 --array_merge_recursive(): Argument #2 must be of type array, true given + +-- Iteration 13 --array_merge_recursive(): Argument #2 must be of type array, false given + +-- Iteration 14 --array_merge_recursive(): Argument #2 must be of type array, true given + +-- Iteration 15 --array_merge_recursive(): Argument #2 must be of type array, false given + +-- Iteration 16 --array_merge_recursive(): Argument #2 must be of type array, string given + +-- Iteration 17 --array_merge_recursive(): Argument #2 must be of type array, string given + +-- Iteration 18 --array_merge_recursive(): Argument #2 must be of type array, string given + +-- Iteration 19 --array_merge_recursive(): Argument #2 must be of type array, string given + +-- Iteration 20 --array_merge_recursive(): Argument #2 must be of type array, string given + +-- Iteration 21 --array_merge_recursive(): Argument #2 must be of type array, null given + +-- Iteration 22 --array_merge_recursive(): Argument #2 must be of type array, null given + +-- Iteration 23 --array_merge_recursive(): Argument #2 must be of type array, resource given + +-- Iteration 24 --array_merge_recursive(): Argument #2 must be of type array, A given +Done diff --git a/tests/std/array/array_merge_recursive_variation3.phpt b/tests/std/array/array_merge_recursive_variation3.phpt new file mode 100644 index 00000000..8e1ff9f5 --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation3.phpt @@ -0,0 +1,758 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - different arrays for 'arr1' argument +--SKIPIF-- + +--FILE-- +22 +'single quoted string' +"double quoted string" +2222 != 1111.\t 0000 = 0000\n +EOT; + +// arrays passed to $arr1 argument +$arrays = array ( +/*1*/ array(1, 2,), // with default keys and numeric values + array(1.1, 2.2), // with default keys & float values + array(false, true), // with default keys and boolean values + array(), // empty array +/*5*/ array(NULL), // with NULL + array("a\v\f", "aaaa\r", "b", "\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // with double quoted strings + array('a\v\f', 'aaaa\r', 'b', '\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // with single quoted strings + array("h1" => $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces), // with heredocs + + // associative arrays +/*9*/ array(1 => "one", 2 => "two"), // explicit numeric keys, string values + array("one" => 1, "two" => 2, "1" => 1 ), // string keys & numeric values + array( 1 => 10, 2 => 20, 4 => 40), // explicit numeric keys and numeric values + array( "one" => "ten", "two" => "twenty"), // string key/value + array("one" => 1, 2 => "two", 4 => "four"), //mixed + + // associative array, containing null/empty/boolean values as key/value +/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + + // array containing embedded arrays +/*15*/ array("str1", "array" => array("hello", 'world'), array(1, 2)) +); + +// initialise the second argument +$arr2 = array( 1 => "one", 2, "string" => "hello", "array" => array("a", "b", "c")); + +// loop through each sub array of $arrays and check the behavior of array_merge_recursive() +$iterator = 1; +foreach($arrays as $arr1) { + echo "-- Iteration $iterator --\n"; + + // with default argument + echo "-- With default argument --\n"; + var_dump( array_merge_recursive($arr1) ); + + // with more arguments + echo "-- With more arguments --\n"; + var_dump( array_merge_recursive($arr1, $arr2) ); + + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge_recursive() : Passing different arrays to $arr1 argument *** +-- Iteration 1 -- +-- With default argument -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +-- With more arguments -- +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 2 -- +-- With default argument -- +array(2) { + [0]=> + float(1.1) + [1]=> + float(2.2) +} +-- With more arguments -- +array(6) { + [0]=> + float(1.1) + [1]=> + float(2.2) + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 3 -- +-- With default argument -- +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} +-- With more arguments -- +array(6) { + [0]=> + bool(false) + [1]=> + bool(true) + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 4 -- +-- With default argument -- +array(0) { +} +-- With more arguments -- +array(4) { + [0]=> + string(3) "one" + [1]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 5 -- +-- With default argument -- +array(1) { + [0]=> + NULL +} +-- With more arguments -- +array(5) { + [0]=> + NULL + [1]=> + string(3) "one" + [2]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 6 -- +-- With default argument -- +array(4) { + [0]=> + string(3) "a " + [1]=> + string(5) "aaaa " + [2]=> + string(1) "b" + [3]=> + string(27) "\[\]\!\@\#$\%\^\&\*\(\)\{\}" +} +-- With more arguments -- +array(8) { + [0]=> + string(3) "a " + [1]=> + string(5) "aaaa " + [2]=> + string(1) "b" + [3]=> + string(27) "\[\]\!\@\#$\%\^\&\*\(\)\{\}" + [4]=> + string(3) "one" + [5]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 7 -- +-- With default argument -- +array(4) { + [0]=> + string(5) "a\v\f" + [1]=> + string(6) "aaaa\r" + [2]=> + string(1) "b" + [3]=> + string(28) "\[\]\!\@\#\$\%\^\&\*\(\)\{\}" +} +-- With more arguments -- +array(8) { + [0]=> + string(5) "a\v\f" + [1]=> + string(6) "aaaa\r" + [2]=> + string(1) "b" + [3]=> + string(28) "\[\]\!\@\#\$\%\^\&\*\(\)\{\}" + [4]=> + string(3) "one" + [5]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 8 -- +-- With default argument -- +array(3) { + ["h1"]=> + string(1) " +" + ["h2"]=> + string(88) "hello world +The quick brown fox jumped over; +the lazy dog +This is a double quoted string" + ["h3"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" +} +-- With more arguments -- +array(7) { + ["h1"]=> + string(1) " +" + ["h2"]=> + string(88) "hello world +The quick brown fox jumped over; +the lazy dog +This is a double quoted string" + ["h3"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" + [0]=> + string(3) "one" + [1]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 9 -- +-- With default argument -- +array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" +} +-- With more arguments -- +array(6) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 10 -- +-- With default argument -- +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [0]=> + int(1) +} +-- With more arguments -- +array(7) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [0]=> + int(1) + [1]=> + string(3) "one" + [2]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 11 -- +-- With default argument -- +array(3) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(40) +} +-- With more arguments -- +array(7) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(40) + [3]=> + string(3) "one" + [4]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 12 -- +-- With default argument -- +array(2) { + ["one"]=> + string(3) "ten" + ["two"]=> + string(6) "twenty" +} +-- With more arguments -- +array(6) { + ["one"]=> + string(3) "ten" + ["two"]=> + string(6) "twenty" + [0]=> + string(3) "one" + [1]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 13 -- +-- With default argument -- +array(3) { + ["one"]=> + int(1) + [0]=> + string(3) "two" + [1]=> + string(4) "four" +} +-- With more arguments -- +array(7) { + ["one"]=> + int(1) + [0]=> + string(3) "two" + [1]=> + string(4) "four" + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 14 -- +-- With default argument -- +array(3) { + [""]=> + string(4) "null" + ["NULL"]=> + NULL + ["null"]=> + NULL +} +-- With more arguments -- +array(7) { + [""]=> + string(4) "null" + ["NULL"]=> + NULL + ["null"]=> + NULL + [0]=> + string(3) "one" + [1]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 15 -- +-- With default argument -- +array(4) { + [0]=> + string(4) "true" + [1]=> + string(5) "false" + ["false"]=> + bool(false) + ["true"]=> + bool(true) +} +-- With more arguments -- +array(8) { + [0]=> + string(4) "true" + [1]=> + string(5) "false" + ["false"]=> + bool(false) + ["true"]=> + bool(true) + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 16 -- +-- With default argument -- +array(3) { + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" + ["emptys"]=> + string(0) "" +} +-- With more arguments -- +array(7) { + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" + ["emptys"]=> + string(0) "" + [0]=> + string(3) "one" + [1]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 17 -- +-- With default argument -- +array(6) { + [0]=> + string(0) "" + [1]=> + string(0) "" + [2]=> + NULL + [3]=> + NULL + [4]=> + bool(false) + [5]=> + bool(true) +} +-- With more arguments -- +array(10) { + [0]=> + string(0) "" + [1]=> + string(0) "" + [2]=> + NULL + [3]=> + NULL + [4]=> + bool(false) + [5]=> + bool(true) + [6]=> + string(3) "one" + [7]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 18 -- +-- With default argument -- +array(3) { + [""]=> + int(4) + [0]=> + int(5) + [1]=> + int(6) +} +-- With more arguments -- +array(7) { + [""]=> + int(4) + [0]=> + int(5) + [1]=> + int(6) + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 19 -- +-- With default argument -- +array(3) { + [0]=> + string(4) "str1" + ["array"]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} +-- With more arguments -- +array(6) { + [0]=> + string(4) "str1" + ["array"]=> + array(5) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + [2]=> + string(1) "a" + [3]=> + string(1) "b" + [4]=> + string(1) "c" + } + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" +} +Done diff --git a/tests/std/array/array_merge_recursive_variation4.phpt b/tests/std/array/array_merge_recursive_variation4.phpt new file mode 100644 index 00000000..ebdeed23 --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation4.phpt @@ -0,0 +1,330 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - associative array with different keys +--SKIPIF-- + +--FILE-- + "0", 1 => array(1 => "one")), + array(1 => "1", 2 => array(1 => "one", 2 => "two", 3 => 1, 4 => "4")), + // arrays with string keys + /*5*/ + array('\tHello' => array("hello", 'world'), '\v\fworld' => 2.2, 'pen\n' => 111), + array("\tHello" => array("hello", 'world'), "\v\fworld" => 2.2, "pen\n" => 111), + array("hello", $heredoc => array("heredoc", 'string'), "string"), + // array with object, unset variable and resource variable + /*8*/ + array(@$unset_var => array("unset"), $fp => 'resource', 11, "hello"), + ); + // initialise the second array + $arr2 = array(1 => "one", 2, "string" => "hello", "array" => array("a", "b", "c")); + // loop through each sub array of $arrays and check the behavior of array_merge_recursive() + $iterator = 1; + foreach ($arrays as $arr1) { + echo "-- Iteration {$iterator} --\n"; + // with default argument + echo "-- With default argument --\n"; + var_dump(array_merge_recursive($arr1)); + // with more arguments + echo "-- With more arguments --\n"; + var_dump(array_merge_recursive($arr1, $arr2)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_merge_recursive() : assoc. array with diff. keys to $arr1 argument *** + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d +-- Iteration 1 -- +-- With default argument -- +array(2) { + [0]=> + string(1) "0" + [1]=> + array(1) { + [1]=> + string(3) "one" + } +} +-- With more arguments -- +array(6) { + [0]=> + string(1) "0" + [1]=> + array(1) { + [1]=> + string(3) "one" + } + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 2 -- +-- With default argument -- +array(2) { + [0]=> + string(1) "1" + [1]=> + array(4) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + int(1) + [4]=> + string(1) "4" + } +} +-- With more arguments -- +array(6) { + [0]=> + string(1) "1" + [1]=> + array(4) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + int(1) + [4]=> + string(1) "4" + } + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 3 -- +-- With default argument -- +array(3) { + ["\tHello"]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + ["\v\fworld"]=> + float(2.2) + ["pen\n"]=> + int(111) +} +-- With more arguments -- +array(7) { + ["\tHello"]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + ["\v\fworld"]=> + float(2.2) + ["pen\n"]=> + int(111) + [0]=> + string(3) "one" + [1]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 4 -- +-- With default argument -- +array(3) { + [" Hello"]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [" world"]=> + float(2.2) + ["pen +"]=> + int(111) +} +-- With more arguments -- +array(7) { + [" Hello"]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [" world"]=> + float(2.2) + ["pen +"]=> + int(111) + [0]=> + string(3) "one" + [1]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 5 -- +-- With default argument -- +array(3) { + [0]=> + string(5) "hello" + ["Hello world"]=> + array(2) { + [0]=> + string(7) "heredoc" + [1]=> + string(6) "string" + } + [1]=> + string(6) "string" +} +-- With more arguments -- +array(7) { + [0]=> + string(5) "hello" + ["Hello world"]=> + array(2) { + [0]=> + string(7) "heredoc" + [1]=> + string(6) "string" + } + [1]=> + string(6) "string" + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 6 -- +-- With default argument -- +array(4) { + [""]=> + array(1) { + [0]=> + string(5) "unset" + } + [0]=> + string(8) "resource" + [1]=> + int(11) + [2]=> + string(5) "hello" +} +-- With more arguments -- +array(8) { + [""]=> + array(1) { + [0]=> + string(5) "unset" + } + [0]=> + string(8) "resource" + [1]=> + int(11) + [2]=> + string(5) "hello" + [3]=> + string(3) "one" + [4]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +Done diff --git a/tests/std/array/array_merge_recursive_variation5.phpt b/tests/std/array/array_merge_recursive_variation5.phpt new file mode 100644 index 00000000..b6425c87 --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation5.phpt @@ -0,0 +1,392 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - associative array with different values +--SKIPIF-- + +--FILE-- + 0, '1' => 0), + array("one" => 1, 'two' => 2, "three" => 1, 4 => 1), + // arrays with float values + /*3*/ + array("f1" => 2.3333, "f2" => 2.3333, "f3" => array(1.1, 2.22)), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => array(1.2, 'f4' => 1.2)), + // arrays with string values + /*5*/ + array(111 => "\tHello", "array" => "col\tor", 2 => "\v\fworld", 3 => "\tHello"), + array(111 => '\tHello', 'array' => 'col\tor', 2 => '\v\fworld', 3 => '\tHello'), + array(1 => "hello", "string" => $heredoc, $heredoc), + // array with object, unset variable and resource variable + /*8*/ + array(11 => new classA(), "string" => @$unset_var, "resource" => $fp, new classA(), $fp), + ); + // initialise the second array + $arr2 = array(1 => "one", 2, "string" => "hello", "array" => array("a", "b", "c")); + // loop through each sub array of $arrays and check the behavior of array_merge_recursive() + $iterator = 1; + foreach ($arrays as $arr1) { + echo "-- Iteration {$iterator} --\n"; + // with default argument + echo "-- With default argument --\n"; + var_dump(array_merge_recursive($arr1)); + // with more arguments + echo "-- With more arguments --\n"; + var_dump(array_merge_recursive($arr1, $arr2)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_merge_recursive() : assoc. array with diff. values to $arr1 argument *** +-- Iteration 1 -- +-- With default argument -- +array(2) { + [0]=> + int(0) + [1]=> + int(0) +} +-- With more arguments -- +array(6) { + [0]=> + int(0) + [1]=> + int(0) + [2]=> + string(3) "one" + [3]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 2 -- +-- With default argument -- +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(1) + [0]=> + int(1) +} +-- With more arguments -- +array(8) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(1) + [0]=> + int(1) + [1]=> + string(3) "one" + [2]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 3 -- +-- With default argument -- +array(3) { + ["f1"]=> + float(2.3333) + ["f2"]=> + float(2.3333) + ["f3"]=> + array(2) { + [0]=> + float(1.1) + [1]=> + float(2.22) + } +} +-- With more arguments -- +array(7) { + ["f1"]=> + float(2.3333) + ["f2"]=> + float(2.3333) + ["f3"]=> + array(2) { + [0]=> + float(1.1) + [1]=> + float(2.22) + } + [0]=> + string(3) "one" + [1]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 4 -- +-- With default argument -- +array(4) { + ["f1"]=> + float(1.2) + ["f2"]=> + float(3.33) + [0]=> + float(4.89999922839999) + ["f4"]=> + array(2) { + [0]=> + float(1.2) + ["f4"]=> + float(1.2) + } +} +-- With more arguments -- +array(8) { + ["f1"]=> + float(1.2) + ["f2"]=> + float(3.33) + [0]=> + float(4.89999922839999) + ["f4"]=> + array(2) { + [0]=> + float(1.2) + ["f4"]=> + float(1.2) + } + [1]=> + string(3) "one" + [2]=> + int(2) + ["string"]=> + string(5) "hello" + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 5 -- +-- With default argument -- +array(4) { + [0]=> + string(6) " Hello" + ["array"]=> + string(6) "col or" + [1]=> + string(7) " world" + [2]=> + string(6) " Hello" +} +-- With more arguments -- +array(7) { + [0]=> + string(6) " Hello" + ["array"]=> + array(4) { + [0]=> + string(6) "col or" + [1]=> + string(1) "a" + [2]=> + string(1) "b" + [3]=> + string(1) "c" + } + [1]=> + string(7) " world" + [2]=> + string(6) " Hello" + [3]=> + string(3) "one" + [4]=> + int(2) + ["string"]=> + string(5) "hello" +} +-- Iteration 6 -- +-- With default argument -- +array(4) { + [0]=> + string(7) "\tHello" + ["array"]=> + string(7) "col\tor" + [1]=> + string(9) "\v\fworld" + [2]=> + string(7) "\tHello" +} +-- With more arguments -- +array(7) { + [0]=> + string(7) "\tHello" + ["array"]=> + array(4) { + [0]=> + string(7) "col\tor" + [1]=> + string(1) "a" + [2]=> + string(1) "b" + [3]=> + string(1) "c" + } + [1]=> + string(9) "\v\fworld" + [2]=> + string(7) "\tHello" + [3]=> + string(3) "one" + [4]=> + int(2) + ["string"]=> + string(5) "hello" +} +-- Iteration 7 -- +-- With default argument -- +array(3) { + [0]=> + string(5) "hello" + ["string"]=> + string(11) "Hello world" + [1]=> + string(11) "Hello world" +} +-- With more arguments -- +array(6) { + [0]=> + string(5) "hello" + ["string"]=> + array(2) { + [0]=> + string(11) "Hello world" + [1]=> + string(5) "hello" + } + [1]=> + string(11) "Hello world" + [2]=> + string(3) "one" + [3]=> + int(2) + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +-- Iteration 8 -- +-- With default argument -- +array(5) { + [0]=> + object(classA)#%d (0) { + } + ["string"]=> + NULL + ["resource"]=> + resource(%d) of type (stream) + [1]=> + object(classA)#%d (0) { + } + [2]=> + resource(%d) of type (stream) +} +-- With more arguments -- +array(8) { + [0]=> + object(classA)#%d (0) { + } + ["string"]=> + array(2) { + [0]=> + NULL + [1]=> + string(5) "hello" + } + ["resource"]=> + resource(%d) of type (stream) + [1]=> + object(classA)#%d (0) { + } + [2]=> + resource(%d) of type (stream) + [3]=> + string(3) "one" + [4]=> + int(2) + ["array"]=> + array(3) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + } +} +Done diff --git a/tests/std/array/array_merge_recursive_variation6.phpt b/tests/std/array/array_merge_recursive_variation6.phpt new file mode 100644 index 00000000..9540a6cf --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation6.phpt @@ -0,0 +1,108 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - array with duplicate keys +--FILE-- + "one", 2 => "two", 2 => array(1, 2), 3 => "three", 1 => array("duplicate", 'strings')); +// array with string keys +$arr1_string_key = array("str1" => "hello", "str2" => 111, "str1" => "world", "str2" => 111.111); + +// initialize the second argument +$arr2 = array("one", "str1" => "two", array("one", "two")); + +echo "-- With default argument --\n"; +var_dump( array_merge_recursive($arr1_numeric_key) ); +var_dump( array_merge_recursive($arr1_string_key) ); + +echo "-- With more arguments --\n"; +var_dump( array_merge_recursive($arr1_numeric_key, $arr2) ); +var_dump( array_merge_recursive($arr1_string_key, $arr2) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge_recursive() : array with duplicate keys for $arr1 argument *** +-- With default argument -- +array(3) { + [0]=> + array(2) { + [0]=> + string(9) "duplicate" + [1]=> + string(7) "strings" + } + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [2]=> + string(5) "three" +} +array(2) { + ["str1"]=> + string(5) "world" + ["str2"]=> + float(111.111) +} +-- With more arguments -- +array(6) { + [0]=> + array(2) { + [0]=> + string(9) "duplicate" + [1]=> + string(7) "strings" + } + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [2]=> + string(5) "three" + [3]=> + string(3) "one" + ["str1"]=> + string(3) "two" + [4]=> + array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + } +} +array(4) { + ["str1"]=> + array(2) { + [0]=> + string(5) "world" + [1]=> + string(3) "two" + } + ["str2"]=> + float(111.111) + [0]=> + string(3) "one" + [1]=> + array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + } +} +Done diff --git a/tests/std/array/array_merge_recursive_variation7.phpt b/tests/std/array/array_merge_recursive_variation7.phpt new file mode 100644 index 00000000..e1e5c951 --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation7.phpt @@ -0,0 +1,79 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - array with reference variables +--SKIPIF-- + +--FILE-- + 0, + 1 => &$value4, + 2 => &$value2, + 3 => "hello", + 4 => &$value3, + $value4 => &$value2 +); + +// initialize the second argument +$arr2 = array($value4 => "hello", &$value2); + +echo "-- With default argument --\n"; +var_dump( array_merge_recursive($arr1) ); + +echo "-- With more arguments --\n"; +var_dump( array_merge_recursive($arr1, $arr2) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge_recursive() : array with reference variables for $arr1 argument *** +-- With default argument -- +array(6) { + [0]=> + int(0) + [1]=> + &string(5) "hello" + [2]=> + &string(5) "hello" + [3]=> + string(5) "hello" + [4]=> + &int(0) + ["hello"]=> + &string(5) "hello" +} +-- With more arguments -- +array(7) { + [0]=> + int(0) + [1]=> + &string(5) "hello" + [2]=> + &string(5) "hello" + [3]=> + string(5) "hello" + [4]=> + &int(0) + ["hello"]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "hello" + } + [5]=> + &string(5) "hello" +} +Done diff --git a/tests/std/array/array_merge_recursive_variation8.phpt b/tests/std/array/array_merge_recursive_variation8.phpt new file mode 100644 index 00000000..bd41e57e --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation8.phpt @@ -0,0 +1,68 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - binary safe checking +--FILE-- + "hello", b"world", "str1" => b"hello", "str2" => "world"); + +// initialize the second argument +$arr2 = array(b"str1" => b"binary", b"hello" => "binary", b"str2" => b"binary"); + +echo "-- With default argument --\n"; +var_dump( array_merge_recursive($arr1) ); + +echo "-- With more arguments --\n"; +var_dump( array_merge_recursive($arr1, $arr2) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge_recursive() : array with binary data for $arr1 argument *** +-- With default argument -- +array(5) { + [0]=> + string(1) "1" + ["hello"]=> + string(5) "hello" + [1]=> + string(5) "world" + ["str1"]=> + string(5) "hello" + ["str2"]=> + string(5) "world" +} +-- With more arguments -- +array(5) { + [0]=> + string(1) "1" + ["hello"]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(6) "binary" + } + [1]=> + string(5) "world" + ["str1"]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(6) "binary" + } + ["str2"]=> + array(2) { + [0]=> + string(5) "world" + [1]=> + string(6) "binary" + } +} +Done diff --git a/tests/std/array/array_merge_recursive_variation9.phpt b/tests/std/array/array_merge_recursive_variation9.phpt new file mode 100644 index 00000000..ff12e86b --- /dev/null +++ b/tests/std/array/array_merge_recursive_variation9.phpt @@ -0,0 +1,112 @@ +--TEST-- +Test array_merge_recursive() function : usage variations - common key and value(Bug#43559) +--FILE-- + 1, "b" => 2); +$arr2 = array("b" => 2, "c" => 4); +echo "-- Integer values --\n"; +var_dump( array_merge_recursive($arr1, $arr2) ); + +// float values +$arr1 = array("a" => 1.1, "b" => 2.2); +$arr2 = array("b" => 2.2, "c" => 3.3); +echo "-- Float values --\n"; +var_dump( array_merge_recursive($arr1, $arr2) ); + +// string values +$arr1 = array("a" => "hello", "b" => "world"); +$arr2 = array("b" => "world", "c" => "string"); +echo "-- String values --\n"; +var_dump( array_merge_recursive($arr1, $arr2) ); + +// boolean values +$arr1 = array("a" => true, "b" => false); +$arr2 = array("b" => false); +echo "-- Boolean values --\n"; +var_dump( array_merge_recursive($arr1, $arr2) ); + +// null values +$arr1 = array( "a" => NULL); +$arr2 = array( "a" => NULL); +echo "-- Null values --\n"; +var_dump( array_merge_recursive($arr1, $arr2) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge_recursive() : arrays with common key and value *** +-- Integer values -- +array(3) { + ["a"]=> + int(1) + ["b"]=> + array(2) { + [0]=> + int(2) + [1]=> + int(2) + } + ["c"]=> + int(4) +} +-- Float values -- +array(3) { + ["a"]=> + float(1.1) + ["b"]=> + array(2) { + [0]=> + float(2.2) + [1]=> + float(2.2) + } + ["c"]=> + float(3.3) +} +-- String values -- +array(3) { + ["a"]=> + string(5) "hello" + ["b"]=> + array(2) { + [0]=> + string(5) "world" + [1]=> + string(5) "world" + } + ["c"]=> + string(6) "string" +} +-- Boolean values -- +array(2) { + ["a"]=> + bool(true) + ["b"]=> + array(2) { + [0]=> + bool(false) + [1]=> + bool(false) + } +} +-- Null values -- +array(1) { + ["a"]=> + array(2) { + [0]=> + NULL + [1]=> + NULL + } +} +Done diff --git a/tests/std/array/array_merge_replace_recursive_refs.phpt b/tests/std/array/array_merge_replace_recursive_refs.phpt new file mode 100644 index 00000000..ac8be2ba --- /dev/null +++ b/tests/std/array/array_merge_replace_recursive_refs.phpt @@ -0,0 +1,38 @@ +--TEST-- +array_merge/replace_recursive() should unwrap references with rc=1 +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + array(1) { + [0]=> + int(24) + } +} +array(2) { + [0]=> + int(42) + [1]=> + int(24) +} diff --git a/tests/std/array/array_merge_variation1.phpt b/tests/std/array/array_merge_variation1.phpt new file mode 100644 index 00000000..0b98797a --- /dev/null +++ b/tests/std/array/array_merge_variation1.phpt @@ -0,0 +1,102 @@ +--TEST-- +Test array_merge() function : usage variations - Pass different data types to $arr1 arg +--SKIPIF-- + + +--FILE-- + +--EXPECTF-- +*** Testing array_merge() : usage variations *** + +-- Iteration 1 -- + +Fatal error: Uncaught TypeError: array_merge(): Argument #1 must be of type array, int given in %s:%d +Stack trace: +#0 %s(%d): array_merge(0, Array) +#1 {main} + thrown in %s on line %d diff --git a/tests/std/array/array_merge_variation10.phpt b/tests/std/array/array_merge_variation10.phpt new file mode 100644 index 00000000..1877cece --- /dev/null +++ b/tests/std/array/array_merge_variation10.phpt @@ -0,0 +1,64 @@ +--TEST-- +Test array_merge() function : usage variations - position of internal array pointer +--FILE-- + " . current($result) . "\n"; + +echo "\n-- Position of Internal Pointer in Original Array: --\n"; +echo "\$arr1: "; +echo key($arr1) . " => " . current ($arr1) . "\n"; +echo "\$arr2: "; +echo key($arr2) . " => " . current ($arr2) . "\n"; +echo "\$arr3: "; +echo key($arr3) . " => " . current ($arr3) . "\n"; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge() : usage variations *** + +-- Call array_merge() -- +array(9) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(4) "zero" + [4]=> + string(2) "un" + [5]=> + string(4) "deux" + [6]=> + string(4) "null" + [7]=> + string(4) "eins" + [8]=> + string(4) "zwei" +} + +-- Position of Internal Pointer in Result: -- +0 => zero + +-- Position of Internal Pointer in Original Array: -- +$arr1: 0 => zero +$arr2: 0 => zero +$arr3: 0 => null +Done diff --git a/tests/std/array/array_merge_variation2.phpt b/tests/std/array/array_merge_variation2.phpt new file mode 100644 index 00000000..b1657957 --- /dev/null +++ b/tests/std/array/array_merge_variation2.phpt @@ -0,0 +1,179 @@ +--TEST-- +Test array_merge() function : usage variations - Pass different data types as $arr2 arg +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; + } + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_merge() : usage variations *** + +-- Iteration 1 -- +array_merge(): Argument #2 must be of type array, int given + +-- Iteration 2 -- +array_merge(): Argument #2 must be of type array, int given + +-- Iteration 3 -- +array_merge(): Argument #2 must be of type array, int given + +-- Iteration 4 -- +array_merge(): Argument #2 must be of type array, int given + +-- Iteration 5 -- +array_merge(): Argument #2 must be of type array, float given + +-- Iteration 6 -- +array_merge(): Argument #2 must be of type array, float given + +-- Iteration 7 -- +array_merge(): Argument #2 must be of type array, float given + +-- Iteration 8 -- +array_merge(): Argument #2 must be of type array, float given + +-- Iteration 9 -- +array_merge(): Argument #2 must be of type array, float given + +-- Iteration 10 -- +array_merge(): Argument #2 must be of type array, null given + +-- Iteration 11 -- +array_merge(): Argument #2 must be of type array, null given + +-- Iteration 12 -- +array_merge(): Argument #2 must be of type array, true given + +-- Iteration 13 -- +array_merge(): Argument #2 must be of type array, false given + +-- Iteration 14 -- +array_merge(): Argument #2 must be of type array, true given + +-- Iteration 15 -- +array_merge(): Argument #2 must be of type array, false given + +-- Iteration 16 -- +array_merge(): Argument #2 must be of type array, string given + +-- Iteration 17 -- +array_merge(): Argument #2 must be of type array, string given + +-- Iteration 18 -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + +-- Iteration 19 -- +array_merge(): Argument #2 must be of type array, string given + +-- Iteration 20 -- +array_merge(): Argument #2 must be of type array, string given + +-- Iteration 21 -- +array_merge(): Argument #2 must be of type array, string given + +-- Iteration 22 -- +array_merge(): Argument #2 must be of type array, classA given + +-- Iteration 23 -- +array_merge(): Argument #2 must be of type array, null given + +-- Iteration 24 -- +array_merge(): Argument #2 must be of type array, null given + +-- Iteration 25 -- +array_merge(): Argument #2 must be of type array, resource given +Done diff --git a/tests/std/array/array_merge_variation3.phpt b/tests/std/array/array_merge_variation3.phpt new file mode 100644 index 00000000..64154540 --- /dev/null +++ b/tests/std/array/array_merge_variation3.phpt @@ -0,0 +1,336 @@ +--TEST-- +Test array_merge() function : usage variations - arrays of diff. data types +--SKIPIF-- + + +--FILE-- + array(0, 1, 12345, -2345), + // float data + /*2*/ + 'float' => array(10.5, -10.5, 123456789000.0, 1.23456789E-9, 0.5), + // null data + /*3*/ + 'null' => array(NULL, null), + // boolean data + /*4*/ + 'bool' => array(true, false, TRUE, FALSE), + // empty data + /*5*/ + 'empty string' => array("", ''), + /*6*/ + 'empty array' => array(), + // string data + /*7*/ + 'string' => array("string", 'string', $heredoc), + // object data + /*8*/ + 'object' => array(new classA()), + // undefined data + /*9*/ + 'undefined' => array(@$undefined_var), + // unset data + /*10*/ + 'unset' => array(@$unset_var), + // resource variable + /*11*/ + 'resource' => array($fp), + ); + // loop through each element of $inputs to check the behavior of array_merge + $iterator = 1; + foreach ($inputs as $key => $input) { + echo "\n-- Iteration {$iterator}: {$key} data --\n"; + var_dump(array_merge($input, $arr)); + var_dump(array_merge($arr, $input)); + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_merge() : usage variations *** + +-- Iteration 1: int data -- +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(12345) + [3]=> + int(-2345) + [4]=> + int(1) + [5]=> + int(2) +} +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(0) + [3]=> + int(1) + [4]=> + int(12345) + [5]=> + int(-2345) +} + +-- Iteration 2: float data -- +array(7) { + [0]=> + float(10.5) + [1]=> + float(-10.5) + [2]=> + float(123456789000) + [3]=> + float(1.23456789E-9) + [4]=> + float(0.5) + [5]=> + int(1) + [6]=> + int(2) +} +array(7) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + float(10.5) + [3]=> + float(-10.5) + [4]=> + float(123456789000) + [5]=> + float(1.23456789E-9) + [6]=> + float(0.5) +} + +-- Iteration 3: null data -- +array(4) { + [0]=> + NULL + [1]=> + NULL + [2]=> + int(1) + [3]=> + int(2) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + NULL + [3]=> + NULL +} + +-- Iteration 4: bool data -- +array(6) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + bool(true) + [3]=> + bool(false) + [4]=> + int(1) + [5]=> + int(2) +} +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + bool(true) + [3]=> + bool(false) + [4]=> + bool(true) + [5]=> + bool(false) +} + +-- Iteration 5: empty string data -- +array(4) { + [0]=> + string(0) "" + [1]=> + string(0) "" + [2]=> + int(1) + [3]=> + int(2) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(0) "" + [3]=> + string(0) "" +} + +-- Iteration 6: empty array data -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} + +-- Iteration 7: string data -- +array(5) { + [0]=> + string(6) "string" + [1]=> + string(6) "string" + [2]=> + string(11) "hello world" + [3]=> + int(1) + [4]=> + int(2) +} +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(6) "string" + [3]=> + string(6) "string" + [4]=> + string(11) "hello world" +} + +-- Iteration 8: object data -- +array(3) { + [0]=> + object(classA)#%d (0) { + } + [1]=> + int(1) + [2]=> + int(2) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + object(classA)#%d (0) { + } +} + +-- Iteration 9: undefined data -- +array(3) { + [0]=> + NULL + [1]=> + int(1) + [2]=> + int(2) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + NULL +} + +-- Iteration 10: unset data -- +array(3) { + [0]=> + NULL + [1]=> + int(1) + [2]=> + int(2) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + NULL +} + +-- Iteration 11: resource data -- +array(3) { + [0]=> + resource(%d) of type (stream) + [1]=> + int(1) + [2]=> + int(2) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + resource(%d) of type (stream) +} +Done diff --git a/tests/std/array/array_merge_variation4.phpt b/tests/std/array/array_merge_variation4.phpt new file mode 100644 index 00000000..4fa12783 --- /dev/null +++ b/tests/std/array/array_merge_variation4.phpt @@ -0,0 +1,308 @@ +--TEST-- +Test array_merge() function : usage variations - Diff. data types as array keys +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + +//get an unset variable +$unset_var = 10; +unset ($unset_var); + +// heredoc string +$heredoc = << array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative', + ), + + // null data +/*4*/ 'null uppercase' => array( + NULL => 'null 1', + ), + +/*5*/ 'null lowercase' => array( + null => 'null 2', + ), + + // boolean data +/*6*/ 'bool lowercase' => array( + true => 'lowert', + false => 'lowerf', + ), + +/*7*/ 'bool uppercase' => array( + TRUE => 'uppert', + FALSE => 'upperf', + ), + + // empty data +/*8*/ 'empty double quotes' => array( + "" => 'emptyd', + ), + +/*9*/ 'empty single quotes' => array( + '' => 'emptys', + ), + + // string data +/*10*/ 'string' => array( + "stringd" => 'stringd', + 'strings' => 'strings', + $heredoc => 'stringh', + ), + + // undefined data +/*11*/ 'undefined' => array( + @$undefined_var => 'undefined', + ), + + // unset data +/*12*/ 'unset' => array( + @$unset_var => 'unset', + ), +); + +// loop through each element of $inputs to check the behavior of array_merge +$iterator = 1; +foreach($inputs as $key => $input) { + echo "\n-- Iteration $iterator: $key data --\n"; + var_dump( array_merge($input, $arr) ); + var_dump( array_merge($arr, $input) ); + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge() : usage variations *** + +-- Iteration 1: int data -- +array(6) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(8) "positive" + [3]=> + string(8) "negative" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(6) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(8) "positive" + [3]=> + string(8) "negative" +} + +-- Iteration 2: null uppercase data -- +array(3) { + [""]=> + string(6) "null 1" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [""]=> + string(6) "null 1" +} + +-- Iteration 3: null lowercase data -- +array(3) { + [""]=> + string(6) "null 2" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [""]=> + string(6) "null 2" +} + +-- Iteration 4: bool lowercase data -- +array(4) { + [0]=> + string(6) "lowert" + [1]=> + string(6) "lowerf" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [0]=> + string(6) "lowert" + [1]=> + string(6) "lowerf" +} + +-- Iteration 5: bool uppercase data -- +array(4) { + [0]=> + string(6) "uppert" + [1]=> + string(6) "upperf" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(4) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [0]=> + string(6) "uppert" + [1]=> + string(6) "upperf" +} + +-- Iteration 6: empty double quotes data -- +array(3) { + [""]=> + string(6) "emptyd" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [""]=> + string(6) "emptyd" +} + +-- Iteration 7: empty single quotes data -- +array(3) { + [""]=> + string(6) "emptys" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [""]=> + string(6) "emptys" +} + +-- Iteration 8: string data -- +array(5) { + ["stringd"]=> + string(7) "stringd" + ["strings"]=> + string(7) "strings" + ["hello world"]=> + string(7) "stringh" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(5) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["stringd"]=> + string(7) "stringd" + ["strings"]=> + string(7) "strings" + ["hello world"]=> + string(7) "stringh" +} + +-- Iteration 9: undefined data -- +array(3) { + [""]=> + string(9) "undefined" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [""]=> + string(9) "undefined" +} + +-- Iteration 10: unset data -- +array(3) { + [""]=> + string(5) "unset" + ["one"]=> + int(1) + ["two"]=> + int(2) +} +array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + [""]=> + string(5) "unset" +} +Done diff --git a/tests/std/array/array_merge_variation5.phpt b/tests/std/array/array_merge_variation5.phpt new file mode 100644 index 00000000..5ef9699d --- /dev/null +++ b/tests/std/array/array_merge_variation5.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test array_merge() function : usage variations - numeric keys +--SKIPIF-- + +--FILE-- + 'one', 20 => 'twenty', 30 => 'thirty'); + +var_dump(array_merge($arr1, $arr2)); +var_dump(array_merge($arr2, $arr1)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge() : usage variations *** +array(7) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" + [4]=> + string(3) "one" + [5]=> + string(6) "twenty" + [6]=> + string(6) "thirty" +} +array(7) { + [0]=> + string(3) "one" + [1]=> + string(6) "twenty" + [2]=> + string(6) "thirty" + [3]=> + string(4) "zero" + [4]=> + string(3) "one" + [5]=> + string(3) "two" + [6]=> + string(5) "three" +} +Done diff --git a/tests/std/array/array_merge_variation6.phpt b/tests/std/array/array_merge_variation6.phpt new file mode 100644 index 00000000..b2297883 --- /dev/null +++ b/tests/std/array/array_merge_variation6.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test array_merge() function : usage variations - string keys +--FILE-- + 'zero', 'one' => 'un', 'two' => 'deux'); +$arr2 = array('zero' => 'zero', 'un' => 'eins', 'deux' => 'zwei'); + +var_dump(array_merge($arr1, $arr2)); +var_dump(array_merge($arr2, $arr1)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge() : usage variations *** +array(5) { + ["zero"]=> + string(4) "zero" + ["one"]=> + string(2) "un" + ["two"]=> + string(4) "deux" + ["un"]=> + string(4) "eins" + ["deux"]=> + string(4) "zwei" +} +array(5) { + ["zero"]=> + string(4) "zero" + ["un"]=> + string(4) "eins" + ["deux"]=> + string(4) "zwei" + ["one"]=> + string(2) "un" + ["two"]=> + string(4) "deux" +} +Done diff --git a/tests/std/array/array_merge_variation7.phpt b/tests/std/array/array_merge_variation7.phpt new file mode 100644 index 00000000..d0d4f53b --- /dev/null +++ b/tests/std/array/array_merge_variation7.phpt @@ -0,0 +1,61 @@ +--TEST-- +Test array_merge() function : usage variations - Mixed keys +--SKIPIF-- + +--FILE-- + 'twenty', 'thirty' => 30, true => 'bool'); +$arr2 = array(0, 1, 2, null => 'null', 0 => 'float'); + +var_dump(array_merge($arr1, $arr2)); +var_dump(array_merge($arr2, $arr1)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge() : usage variations *** +array(8) { + [0]=> + string(4) "zero" + [1]=> + string(6) "twenty" + ["thirty"]=> + int(30) + [2]=> + string(4) "bool" + [3]=> + string(5) "float" + [4]=> + int(1) + [5]=> + int(2) + [""]=> + string(4) "null" +} +array(8) { + [0]=> + string(5) "float" + [1]=> + int(1) + [2]=> + int(2) + [""]=> + string(4) "null" + [3]=> + string(4) "zero" + [4]=> + string(6) "twenty" + ["thirty"]=> + int(30) + [5]=> + string(4) "bool" +} +Done diff --git a/tests/std/array/array_merge_variation8.phpt b/tests/std/array/array_merge_variation8.phpt new file mode 100644 index 00000000..e4dbeba2 --- /dev/null +++ b/tests/std/array/array_merge_variation8.phpt @@ -0,0 +1,68 @@ +--TEST-- +Test array_merge() function : usage variations - multi-dimensional arrays +--FILE-- + +--EXPECT-- +*** Testing array_merge() : usage variations *** + +-- Merge a two-dimensional and a one-dimensional array -- +array(7) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + array(1) { + [0]=> + int(0) + } + [4]=> + int(1) + [5]=> + int(2) + [6]=> + int(3) +} + +-- Merge an array and a sub-array -- +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(0) +} +Done diff --git a/tests/std/array/array_merge_variation9.phpt b/tests/std/array/array_merge_variation9.phpt new file mode 100644 index 00000000..a615298e --- /dev/null +++ b/tests/std/array/array_merge_variation9.phpt @@ -0,0 +1,95 @@ +--TEST-- +Test array_merge() function : usage variations - referenced variables +--SKIPIF-- + +--FILE-- + 'val1', 'key2' => 'val2', 'key3' => 'val3'); + +echo "\n-- Merge an array made up of referenced variables to an assoc. array --\n"; +var_dump(array_merge($arr1, $arr2)); +var_dump(array_merge($arr2, $arr1)); + +$val2 = 'hello world'; + +echo "\n-- Change \$val2 --\n"; +var_dump(array_merge($arr1, $arr2)); +var_dump(array_merge($arr2, $arr1)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_merge() : usage variations *** + +-- Merge an array made up of referenced variables to an assoc. array -- +array(6) { + [0]=> + &string(3) "foo" + [1]=> + &string(3) "bar" + [2]=> + &string(3) "baz" + ["key1"]=> + string(4) "val1" + ["key2"]=> + string(4) "val2" + ["key3"]=> + string(4) "val3" +} +array(6) { + ["key1"]=> + string(4) "val1" + ["key2"]=> + string(4) "val2" + ["key3"]=> + string(4) "val3" + [0]=> + &string(3) "foo" + [1]=> + &string(3) "bar" + [2]=> + &string(3) "baz" +} + +-- Change $val2 -- +array(6) { + [0]=> + &string(3) "foo" + [1]=> + &string(11) "hello world" + [2]=> + &string(3) "baz" + ["key1"]=> + string(4) "val1" + ["key2"]=> + string(4) "val2" + ["key3"]=> + string(4) "val3" +} +array(6) { + ["key1"]=> + string(4) "val1" + ["key2"]=> + string(4) "val2" + ["key3"]=> + string(4) "val3" + [0]=> + &string(3) "foo" + [1]=> + &string(11) "hello world" + [2]=> + &string(3) "baz" +} +Done diff --git a/tests/std/array/array_multisort_basic1.phpt b/tests/std/array/array_multisort_basic1.phpt new file mode 100644 index 00000000..f73c6d32 --- /dev/null +++ b/tests/std/array/array_multisort_basic1.phpt @@ -0,0 +1,53 @@ +--TEST-- +Test array_multisort() function : basic functionality +--SKIPIF-- +--FILE-- + 2, "row2" => 1, "row3" => 1); +$ar2 = array("row1" => 2, "row2" => "aa", "row3" => "1"); + +echo "\n-- Testing array_multisort() function with all normal arguments --\n"; +var_dump( array_multisort($ar1, SORT_ASC, SORT_REGULAR, $ar2, SORT_DESC, SORT_STRING) ); +var_dump($ar1, $ar2); + +echo "\n-- Testing array_multisort() function with one argument --\n"; +var_dump( array_multisort($ar2) ); +var_dump($ar2); + + +?> +--EXPECT-- +*** Testing array_multisort() : basic functionality *** + +-- Testing array_multisort() function with all normal arguments -- +bool(true) +array(3) { + ["row2"]=> + int(1) + ["row3"]=> + int(1) + ["row1"]=> + int(2) +} +array(3) { + ["row2"]=> + string(2) "aa" + ["row3"]=> + string(1) "1" + ["row1"]=> + int(2) +} + +-- Testing array_multisort() function with one argument -- +bool(true) +array(3) { + ["row3"]=> + string(1) "1" + ["row1"]=> + int(2) + ["row2"]=> + string(2) "aa" +} diff --git a/tests/std/array/array_multisort_basic2.phpt b/tests/std/array/array_multisort_basic2.phpt new file mode 100644 index 00000000..9c13589b --- /dev/null +++ b/tests/std/array/array_multisort_basic2.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test array_multisort() function : basic functionality +--SKIPIF-- + +--FILE-- + 2, 1, 9 => 1); +$ar2 = array( 2, "aa" , "1"); + +echo "\n-- Testing array_multisort() function with all normal arguments --\n"; +var_dump( array_multisort($ar1, SORT_ASC, SORT_REGULAR, $ar2, SORT_ASC, SORT_NUMERIC) ); +var_dump($ar1, $ar2); + +?> +--EXPECT-- +*** Testing array_multisort() : basic functionality - renumbering of numeric keys *** + +-- Testing array_multisort() function with all normal arguments -- +bool(true) +array(3) { + [0]=> + int(1) + [1]=> + int(1) + ["strkey"]=> + int(2) +} +array(3) { + [0]=> + string(2) "aa" + [1]=> + string(1) "1" + [2]=> + int(2) +} diff --git a/tests/std/array/array_multisort_case.phpt b/tests/std/array/array_multisort_case.phpt new file mode 100644 index 00000000..cc619df3 --- /dev/null +++ b/tests/std/array/array_multisort_case.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test array_multisort() function : case-sensitive +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : case-sensitive +array(7) { + [0]=> + string(7) "First.3" + [1]=> + string(7) "First.2" + [2]=> + string(7) "First.1" + [3]=> + string(5) "Tenth" + [4]=> + string(6) "Second" + [5]=> + string(9) "Twentieth" + [6]=> + string(5) "Third" +} +array(7) { + [0]=> + string(6) "1 BB 3" + [1]=> + string(6) "1 bB 2" + [2]=> + string(6) "1 bb 1" + [3]=> + string(4) "10 d" + [4]=> + string(3) "2 a" + [5]=> + string(4) "20 c" + [6]=> + string(3) "3 e" +} diff --git a/tests/std/array/array_multisort_error.phpt b/tests/std/array/array_multisort_error.phpt new file mode 100644 index 00000000..d184b2ac --- /dev/null +++ b/tests/std/array/array_multisort_error.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test array_multisort() function : error conditions +--SKIPIF-- +--FILE-- +getMessage() . "\n"; +} + +echo "\n-- Testing array_multisort() function with repeated flags --\n"; +$ar1 = array(1); +try { + var_dump( array_multisort($ar1, SORT_STRING, SORT_NUMERIC) ); +} catch (\TypeError $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECT-- +*** Testing array_multisort() : error conditions *** + +-- Testing array_multisort() function with repeated flags -- +array_multisort(): Argument #3 must be an array or a sort flag that has not already been specified + +-- Testing array_multisort() function with repeated flags -- +array_multisort(): Argument #3 must be an array or a sort flag that has not already been specified diff --git a/tests/std/array/array_multisort_incase.phpt b/tests/std/array/array_multisort_incase.phpt new file mode 100644 index 00000000..043432c7 --- /dev/null +++ b/tests/std/array/array_multisort_incase.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test array_multisort() function : case-insensitive +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : case-insensitive +array(7) { + [0]=> + string(7) "First.1" + [1]=> + string(7) "First.2" + [2]=> + string(7) "First.3" + [3]=> + string(5) "Tenth" + [4]=> + string(6) "Second" + [5]=> + string(9) "Twentieth" + [6]=> + string(5) "Third" +} +array(7) { + [0]=> + string(6) "1 bb 1" + [1]=> + string(6) "1 bB 2" + [2]=> + string(6) "1 BB 3" + [3]=> + string(4) "10 d" + [4]=> + string(3) "2 a" + [5]=> + string(4) "20 c" + [6]=> + string(3) "3 e" +} diff --git a/tests/std/array/array_multisort_natural.phpt b/tests/std/array/array_multisort_natural.phpt new file mode 100644 index 00000000..1295a83c --- /dev/null +++ b/tests/std/array/array_multisort_natural.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_multisort() function : natural sorting +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : natural sorting +array(5) { + [0]=> + string(5) "First" + [1]=> + string(6) "Second" + [2]=> + string(5) "Third" + [3]=> + string(5) "Tenth" + [4]=> + string(9) "Twentieth" +} +array(5) { + [0]=> + string(3) "1 b" + [1]=> + string(3) "2 a" + [2]=> + string(3) "3 e" + [3]=> + string(4) "10 d" + [4]=> + string(4) "20 c" +} diff --git a/tests/std/array/array_multisort_natural_case.phpt b/tests/std/array/array_multisort_natural_case.phpt new file mode 100644 index 00000000..d7192342 --- /dev/null +++ b/tests/std/array/array_multisort_natural_case.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test array_multisort() function : natural sorting case-sensitive +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : natural sorting case-sensitive +array(7) { + [0]=> + string(7) "First.3" + [1]=> + string(7) "First.2" + [2]=> + string(7) "First.1" + [3]=> + string(6) "Second" + [4]=> + string(5) "Third" + [5]=> + string(5) "Tenth" + [6]=> + string(9) "Twentieth" +} +array(7) { + [0]=> + string(6) "1 BB 3" + [1]=> + string(6) "1 bB 2" + [2]=> + string(6) "1 bb 1" + [3]=> + string(3) "2 a" + [4]=> + string(3) "3 e" + [5]=> + string(4) "10 d" + [6]=> + string(4) "20 c" +} diff --git a/tests/std/array/array_multisort_natural_incase.phpt b/tests/std/array/array_multisort_natural_incase.phpt new file mode 100644 index 00000000..a73516b9 --- /dev/null +++ b/tests/std/array/array_multisort_natural_incase.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test array_multisort() function : natural sorting case-insensitive +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : natural sorting case-insensitive +array(7) { + [0]=> + string(7) "First.1" + [1]=> + string(7) "First.2" + [2]=> + string(7) "First.3" + [3]=> + string(6) "Second" + [4]=> + string(5) "Third" + [5]=> + string(5) "Tenth" + [6]=> + string(9) "Twentieth" +} +array(7) { + [0]=> + string(6) "1 bb 1" + [1]=> + string(6) "1 bB 2" + [2]=> + string(6) "1 BB 3" + [3]=> + string(3) "2 a" + [4]=> + string(3) "3 e" + [5]=> + string(4) "10 d" + [6]=> + string(4) "20 c" +} diff --git a/tests/std/array/array_multisort_stability.phpt b/tests/std/array/array_multisort_stability.phpt new file mode 100644 index 00000000..67814254 --- /dev/null +++ b/tests/std/array/array_multisort_stability.phpt @@ -0,0 +1,15 @@ +--TEST-- +array_multisort() is stable +--FILE-- + +--EXPECT-- +bool(true) diff --git a/tests/std/array/array_multisort_variation1.phpt b/tests/std/array/array_multisort_variation1.phpt new file mode 100644 index 00000000..5e69c985 --- /dev/null +++ b/tests/std/array/array_multisort_variation1.phpt @@ -0,0 +1,167 @@ +--TEST-- +Test array_multisort() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for ar1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_multisort($value)); + } catch (\ValueError|\TypeError $e) { + echo $e->getMessage() . "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_multisort() : usage variation *** + +--int 0-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag that has not already been specified + +--int 1-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag that has not already been specified + +--int 12345-- +array_multisort(): Argument #1 ($array) must be a valid sort flag + +--int -12345-- +array_multisort(): Argument #1 ($array) must be a valid sort flag + +--float 10.5-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--float -10.5-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--float 12.3456789000e10-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--float -12.3456789000e10-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--float .5-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--uppercase NULL-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--lowercase null-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--lowercase true-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--lowercase false-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--uppercase TRUE-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--uppercase FALSE-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--empty string DQ-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--empty string SQ-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--string DQ-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--string SQ-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--mixed case string-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--heredoc-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--instance of classWithToString-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--instance of classWithoutToString-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--undefined var-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag + +--unset var-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag diff --git a/tests/std/array/array_multisort_variation10.phpt b/tests/std/array/array_multisort_variation10.phpt new file mode 100644 index 00000000..6d61ae04 --- /dev/null +++ b/tests/std/array/array_multisort_variation10.phpt @@ -0,0 +1,14 @@ +--TEST-- +Test array_multisort() function : usage variation - testing with anonymous array arguments +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : Testing with anonymous arguments *** +bool(true) diff --git a/tests/std/array/array_multisort_variation11.phpt b/tests/std/array/array_multisort_variation11.phpt new file mode 100644 index 00000000..a3565022 --- /dev/null +++ b/tests/std/array/array_multisort_variation11.phpt @@ -0,0 +1,14 @@ +--TEST-- +Test array_multisort() function : usage variation - testing with empty array +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : Testing with empty array *** +bool(true) diff --git a/tests/std/array/array_multisort_variation2.phpt b/tests/std/array/array_multisort_variation2.phpt new file mode 100644 index 00000000..eab827e4 --- /dev/null +++ b/tests/std/array/array_multisort_variation2.phpt @@ -0,0 +1,186 @@ +--TEST-- +Test array_multisort() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // array data + 'empty array' => array(), + 'int indexed array' => $index_array, + 'associative array' => $assoc_array, + 'nested arrays' => array('foo', $index_array, $assoc_array), + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for SORT_REGULAR|SORT_NUMERIC|SORT_STRING|SORT_NATURAL|SORT_FLAG_CASE]] + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_multisort($ar1, $value)); + } catch (\ValueError|\TypeError $e) { + echo $e->getMessage() . "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_multisort() : usage variation *** + +--int 0-- +bool(true) + +--int 1-- +bool(true) + +--int 12345-- +array_multisort(): Argument #2 must be a valid sort flag + +--int -12345-- +array_multisort(): Argument #2 must be a valid sort flag + +--float 10.5-- +array_multisort(): Argument #2 must be an array or a sort flag + +--float -10.5-- +array_multisort(): Argument #2 must be an array or a sort flag + +--float 12.3456789000e10-- +array_multisort(): Argument #2 must be an array or a sort flag + +--float -12.3456789000e10-- +array_multisort(): Argument #2 must be an array or a sort flag + +--float .5-- +array_multisort(): Argument #2 must be an array or a sort flag + +--empty array-- +Array sizes are inconsistent + +--int indexed array-- +Array sizes are inconsistent + +--associative array-- +bool(true) + +--nested arrays-- +Array sizes are inconsistent + +--uppercase NULL-- +array_multisort(): Argument #2 must be an array or a sort flag + +--lowercase null-- +array_multisort(): Argument #2 must be an array or a sort flag + +--lowercase true-- +array_multisort(): Argument #2 must be an array or a sort flag + +--lowercase false-- +array_multisort(): Argument #2 must be an array or a sort flag + +--uppercase TRUE-- +array_multisort(): Argument #2 must be an array or a sort flag + +--uppercase FALSE-- +array_multisort(): Argument #2 must be an array or a sort flag + +--empty string DQ-- +array_multisort(): Argument #2 must be an array or a sort flag + +--empty string SQ-- +array_multisort(): Argument #2 must be an array or a sort flag + +--string DQ-- +array_multisort(): Argument #2 must be an array or a sort flag + +--string SQ-- +array_multisort(): Argument #2 must be an array or a sort flag + +--mixed case string-- +array_multisort(): Argument #2 must be an array or a sort flag + +--heredoc-- +array_multisort(): Argument #2 must be an array or a sort flag + +--instance of classWithToString-- +array_multisort(): Argument #2 must be an array or a sort flag + +--instance of classWithoutToString-- +array_multisort(): Argument #2 must be an array or a sort flag + +--undefined var-- +array_multisort(): Argument #2 must be an array or a sort flag + +--unset var-- +array_multisort(): Argument #2 must be an array or a sort flag diff --git a/tests/std/array/array_multisort_variation3.phpt b/tests/std/array/array_multisort_variation3.phpt new file mode 100644 index 00000000..f345b44a --- /dev/null +++ b/tests/std/array/array_multisort_variation3.phpt @@ -0,0 +1,168 @@ +--TEST-- +Test array_multisort() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for ar2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_multisort($ar1, SORT_REGULAR, $value)); + } catch (\ValueError|\TypeError $e) { + echo $e->getMessage() . "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_multisort() : usage variation *** + +--int 0-- +array_multisort(): Argument #3 must be an array or a sort flag that has not already been specified + +--int 1-- +array_multisort(): Argument #3 must be an array or a sort flag that has not already been specified + +--int 12345-- +array_multisort(): Argument #3 must be a valid sort flag + +--int -12345-- +array_multisort(): Argument #3 must be a valid sort flag + +--float 10.5-- +array_multisort(): Argument #3 must be an array or a sort flag + +--float -10.5-- +array_multisort(): Argument #3 must be an array or a sort flag + +--float 12.3456789000e10-- +array_multisort(): Argument #3 must be an array or a sort flag + +--float -12.3456789000e10-- +array_multisort(): Argument #3 must be an array or a sort flag + +--float .5-- +array_multisort(): Argument #3 must be an array or a sort flag + +--uppercase NULL-- +array_multisort(): Argument #3 must be an array or a sort flag + +--lowercase null-- +array_multisort(): Argument #3 must be an array or a sort flag + +--lowercase true-- +array_multisort(): Argument #3 must be an array or a sort flag + +--lowercase false-- +array_multisort(): Argument #3 must be an array or a sort flag + +--uppercase TRUE-- +array_multisort(): Argument #3 must be an array or a sort flag + +--uppercase FALSE-- +array_multisort(): Argument #3 must be an array or a sort flag + +--empty string DQ-- +array_multisort(): Argument #3 must be an array or a sort flag + +--empty string SQ-- +array_multisort(): Argument #3 must be an array or a sort flag + +--string DQ-- +array_multisort(): Argument #3 must be an array or a sort flag + +--string SQ-- +array_multisort(): Argument #3 must be an array or a sort flag + +--mixed case string-- +array_multisort(): Argument #3 must be an array or a sort flag + +--heredoc-- +array_multisort(): Argument #3 must be an array or a sort flag + +--instance of classWithToString-- +array_multisort(): Argument #3 must be an array or a sort flag + +--instance of classWithoutToString-- +array_multisort(): Argument #3 must be an array or a sort flag + +--undefined var-- +array_multisort(): Argument #3 must be an array or a sort flag + +--unset var-- +array_multisort(): Argument #3 must be an array or a sort flag diff --git a/tests/std/array/array_multisort_variation4.phpt b/tests/std/array/array_multisort_variation4.phpt new file mode 100644 index 00000000..6f88dda2 --- /dev/null +++ b/tests/std/array/array_multisort_variation4.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test array_multisort() function : usage variation - testing with multiple array arguments +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : Testing with multiple array arguments *** +bool(true) +array(4) { + [0]=> + int(3) + [1]=> + int(3) + [2]=> + int(3) + [3]=> + int(4) +} +array(4) { + [0]=> + int(2) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(9) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(9) + [3]=> + int(9) +} diff --git a/tests/std/array/array_multisort_variation5.phpt b/tests/std/array/array_multisort_variation5.phpt new file mode 100644 index 00000000..088e4628 --- /dev/null +++ b/tests/std/array/array_multisort_variation5.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test array_multisort() function : usage variation - testing with multiple array arguments +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : Testing all array sort specifiers *** +array(3) { + [0]=> + string(1) "1" + [1]=> + int(2) + [2]=> + string(2) "aa" +} +array(3) { + [0]=> + string(1) "1" + [1]=> + int(2) + [2]=> + string(2) "aa" +} +array(3) { + [0]=> + string(2) "aa" + [1]=> + string(1) "1" + [2]=> + int(2) +} diff --git a/tests/std/array/array_multisort_variation6.phpt b/tests/std/array/array_multisort_variation6.phpt new file mode 100644 index 00000000..3528e7e4 --- /dev/null +++ b/tests/std/array/array_multisort_variation6.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test array_multisort() function : usage variation - testing with multiple array arguments +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_multisort() : Testing all array sort specifiers *** +array(3) { + [0]=> + string(2) "aa" + [1]=> + int(2) + [2]=> + string(1) "1" +} +array(3) { + [0]=> + string(2) "aa" + [1]=> + int(2) + [2]=> + string(1) "1" +} +array(3) { + [0]=> + int(2) + [1]=> + string(1) "1" + [2]=> + string(2) "aa" +} diff --git a/tests/std/array/array_multisort_variation7.phpt b/tests/std/array/array_multisort_variation7.phpt new file mode 100644 index 00000000..a584182c --- /dev/null +++ b/tests/std/array/array_multisort_variation7.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_multisort() function : usage variation - test sort order of all types +--SKIPIF-- + + +--FILE-- + 0, 'float -10.5' => -10.5, array(), 'uppercase NULL' => NULL, 'lowercase true' => true, 'empty string DQ' => "", 'string DQ' => "string", 'instance of classWithToString' => new classWithToString(), 'instance of classWithoutToString' => new classWithoutToString(), 'undefined var' => @$undefined_var); + var_dump(array_multisort($inputs)); + var_dump($inputs); +} +?> +--EXPECT-- +*** Testing array_multisort() : usage variation - test sort order of all types*** +bool(true) +array(10) { + ["float -10.5"]=> + float(-10.5) + ["int 0"]=> + int(0) + [0]=> + array(0) { + } + ["uppercase NULL"]=> + NULL + ["empty string DQ"]=> + string(0) "" + ["undefined var"]=> + NULL + ["lowercase true"]=> + bool(true) + ["instance of classWithToString"]=> + object(classWithToString)#1 (0) { + } + ["string DQ"]=> + string(6) "string" + ["instance of classWithoutToString"]=> + object(classWithoutToString)#2 (0) { + } +} diff --git a/tests/std/array/array_multisort_variation8.phpt b/tests/std/array/array_multisort_variation8.phpt new file mode 100644 index 00000000..5213010c --- /dev/null +++ b/tests/std/array/array_multisort_variation8.phpt @@ -0,0 +1,58 @@ +--TEST-- +Test array_multisort() function : usage variation - test sort order of all types +--SKIPIF-- + + +--FILE-- + 0, 'float -10.5' => -10.5, array(), 'uppercase NULL' => NULL, 'lowercase true' => true, 'empty string DQ' => "", 'string DQ' => "string", 'instance of classWithToString' => new classWithToString(), 'undefined var' => @$undefined_var); + var_dump(array_multisort($inputs, SORT_STRING)); + var_dump($inputs); +} +?> +--EXPECT-- +*** Testing array_multisort() : usage variation - test sort order of all types*** +bool(true) +array(9) { + ["uppercase NULL"]=> + NULL + ["empty string DQ"]=> + string(0) "" + ["undefined var"]=> + NULL + ["float -10.5"]=> + float(-10.5) + ["int 0"]=> + int(0) + ["lowercase true"]=> + bool(true) + [0]=> + array(0) { + } + ["instance of classWithToString"]=> + object(classWithToString)#1 (0) { + } + ["string DQ"]=> + string(6) "string" +} diff --git a/tests/std/array/array_multisort_variation9.phpt b/tests/std/array/array_multisort_variation9.phpt new file mode 100644 index 00000000..d19d6cbe --- /dev/null +++ b/tests/std/array/array_multisort_variation9.phpt @@ -0,0 +1,63 @@ +--TEST-- +Test array_multisort() function : usage variation - test sort order of all types +--SKIPIF-- + + +--FILE-- + 0, 'float -10.5' => -10.5, array(), 'uppercase NULL' => NULL, 'lowercase true' => true, 'empty string DQ' => "", 'string DQ' => "string", 'instance of classWithToString' => new classWithToString(), 'instance of classWithoutToString' => new classWithoutToString(), 'undefined var' => @$undefined_var); + var_dump(array_multisort($inputs, SORT_NUMERIC)); + var_dump($inputs); +} +?> +--EXPECTF-- +*** Testing array_multisort() : usage variation - test sort order of all types*** + +Warning: Object of class classWithToString could not be converted to float in %s on line %d + +Warning: Object of class classWithToString could not be converted to float in %s on line %d + +Warning: Object of class classWithoutToString could not be converted to float in %s on line %d + +Warning: Object of class classWithoutToString could not be converted to float in %s on line %d +bool(true) +array(10) { + ["float -10.5"]=> + float(-10.5) + ["int 0"]=> + int(0) + [0]=> + array(0) { + } + ["uppercase NULL"]=> + NULL + ["empty string DQ"]=> + string(0) "" + ["string DQ"]=> + string(6) "string" + ["undefined var"]=> + NULL + ["lowercase true"]=> + bool(true) + ["instance of classWithToString"]=> + object(classWithToString)#1 (0) { + } + ["instance of classWithoutToString"]=> + object(classWithoutToString)#2 (0) { + } +} diff --git a/tests/std/array/array_next_error1.phpt b/tests/std/array/array_next_error1.phpt new file mode 100644 index 00000000..13911b89 --- /dev/null +++ b/tests/std/array/array_next_error1.phpt @@ -0,0 +1,18 @@ +--TEST-- +next - ensure warning is received when passing an indirect temporary. +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Notice: Only variables should be passed by reference in %s on line %d +int(2) diff --git a/tests/std/array/array_next_error2.phpt b/tests/std/array/array_next_error2.phpt new file mode 100644 index 00000000..68789be6 --- /dev/null +++ b/tests/std/array/array_next_error2.phpt @@ -0,0 +1,20 @@ +--TEST-- +next - ensure we cannot pass a temporary +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: next(): Argument #1 ($array) could not be passed by reference in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/tests/std/array/array_pad.phpt b/tests/std/array/array_pad.phpt new file mode 100644 index 00000000..67cb4234 --- /dev/null +++ b/tests/std/array/array_pad.phpt @@ -0,0 +1,80 @@ +--TEST-- +array_pad() tests +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + int(0) +} +array(0) { +} +array(1) { + [0]=> + int(0) +} +array(5) { + [0]=> + string(0) "" + [1]=> + int(-1) + [2]=> + float(2) + [3]=> + int(0) + [4]=> + int(0) +} +array(5) { + [0]=> + string(0) "" + [1]=> + int(-1) + [2]=> + float(2) + [3]=> + array(0) { + } + [4]=> + array(0) { + } +} +array(3) { + [0]=> + string(0) "" + [1]=> + int(-1) + [2]=> + float(2) +} +array(3) { + [0]=> + string(0) "" + [1]=> + int(-1) + [2]=> + float(2) +} +array(4) { + [0]=> + array(0) { + } + [1]=> + string(0) "" + [2]=> + int(-1) + [3]=> + float(2) +} diff --git a/tests/std/array/array_pad_too_large_padding.phpt b/tests/std/array/array_pad_too_large_padding.phpt new file mode 100644 index 00000000..41c25fd7 --- /dev/null +++ b/tests/std/array/array_pad_too_large_padding.phpt @@ -0,0 +1,21 @@ +--TEST-- +array_pad() with too large padding should fail +--FILE-- +getMessage() . "\n"; + } +} +function main() +{ + test(PHP_INT_MIN); + test(PHP_INT_MAX); +} +?> +--EXPECT-- +array_pad(): Argument #2 ($length) must not exceed the maximum allowed array size +array_pad(): Argument #2 ($length) must not exceed the maximum allowed array size diff --git a/tests/std/array/array_pad_variation3.phpt b/tests/std/array/array_pad_variation3.phpt new file mode 100644 index 00000000..fe2f7236 --- /dev/null +++ b/tests/std/array/array_pad_variation3.phpt @@ -0,0 +1,864 @@ +--TEST-- +Test array_pad() function : usage variations - possible values for 'pad_value' argument +--SKIPIF-- + + +--FILE-- + 'red', 'item' => 'pen'), + // null data + /*15*/ + NULL, + null, + // boolean data + /*17*/ + true, + false, + TRUE, + FALSE, + // empty data + /*21*/ + "", + '', + // string data + /*23*/ + "string", + 'string', + $heredoc, + // strings with different white spaces + /*26*/ + "\v\fHello\t world!! \rstring\n", + '\v\fHello\t world!! \rstring\n', + // object data + /*28*/ + new classA(), + // undefined data + /*29*/ + @$undefined_var, + // unset data + /*30*/ + @$unset_var, + // resource variable + /*31*/ + $fp, + // reference variable + /*32*/ + $reference, + ); + // loop through each element of $pad_values to check the behavior of array_pad() + $iterator = 1; + foreach ($pad_values as $pad_value) { + echo "-- Iteration {$iterator} --\n"; + var_dump(array_pad($input, $pad_size, $pad_value)); + // positive 'pad_size' + var_dump(array_pad($input, -$pad_size, $pad_value)); + // negative 'pad_size' + $iterator++; + } + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_pad() : possible values for $pad_value argument *** +-- Iteration 1 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(0) + [3]=> + int(0) +} +array(4) { + [0]=> + int(0) + [1]=> + int(0) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 2 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(1) + [3]=> + int(1) +} +array(4) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 3 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(12345) + [3]=> + int(12345) +} +array(4) { + [0]=> + int(12345) + [1]=> + int(12345) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 4 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(-2345) + [3]=> + int(-2345) +} +array(4) { + [0]=> + int(-2345) + [1]=> + int(-2345) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 5 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + float(10.5) + [3]=> + float(10.5) +} +array(4) { + [0]=> + float(10.5) + [1]=> + float(10.5) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 6 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + float(-10.5) + [3]=> + float(-10.5) +} +array(4) { + [0]=> + float(-10.5) + [1]=> + float(-10.5) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 7 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + float(123456789000) + [3]=> + float(123456789000) +} +array(4) { + [0]=> + float(123456789000) + [1]=> + float(123456789000) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 8 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + float(1.23456789E-9) + [3]=> + float(1.23456789E-9) +} +array(4) { + [0]=> + float(1.23456789E-9) + [1]=> + float(1.23456789E-9) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 9 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + float(0.5) + [3]=> + float(0.5) +} +array(4) { + [0]=> + float(0.5) + [1]=> + float(0.5) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 10 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(0) { + } + [3]=> + array(0) { + } +} +array(4) { + [0]=> + array(0) { + } + [1]=> + array(0) { + } + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 11 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + [0]=> + int(0) + } + [3]=> + array(1) { + [0]=> + int(0) + } +} +array(4) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(0) + } + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 12 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(1) { + [0]=> + int(1) + } + [3]=> + array(1) { + [0]=> + int(1) + } +} +array(4) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(1) + } + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 13 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [3]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } +} +array(4) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 14 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + array(2) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } + [3]=> + array(2) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } +} +array(4) { + [0]=> + array(2) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } + [1]=> + array(2) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 15 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + NULL + [3]=> + NULL +} +array(4) { + [0]=> + NULL + [1]=> + NULL + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 16 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + NULL + [3]=> + NULL +} +array(4) { + [0]=> + NULL + [1]=> + NULL + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 17 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + bool(true) + [3]=> + bool(true) +} +array(4) { + [0]=> + bool(true) + [1]=> + bool(true) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 18 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + bool(false) + [3]=> + bool(false) +} +array(4) { + [0]=> + bool(false) + [1]=> + bool(false) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 19 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + bool(true) + [3]=> + bool(true) +} +array(4) { + [0]=> + bool(true) + [1]=> + bool(true) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 20 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + bool(false) + [3]=> + bool(false) +} +array(4) { + [0]=> + bool(false) + [1]=> + bool(false) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 21 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(0) "" + [3]=> + string(0) "" +} +array(4) { + [0]=> + string(0) "" + [1]=> + string(0) "" + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 22 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(0) "" + [3]=> + string(0) "" +} +array(4) { + [0]=> + string(0) "" + [1]=> + string(0) "" + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 23 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(6) "string" + [3]=> + string(6) "string" +} +array(4) { + [0]=> + string(6) "string" + [1]=> + string(6) "string" + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 24 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(6) "string" + [3]=> + string(6) "string" +} +array(4) { + [0]=> + string(6) "string" + [1]=> + string(6) "string" + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 25 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(11) "hello world" + [3]=> + string(11) "hello world" +} +array(4) { + [0]=> + string(11) "hello world" + [1]=> + string(11) "hello world" + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 26 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(25) " Hello world!! string +" + [3]=> + string(25) " Hello world!! string +" +} +array(4) { + [0]=> + string(25) " Hello world!! string +" + [1]=> + string(25) " Hello world!! string +" + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 27 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(30) "\v\fHello\t world!! \rstring\n" + [3]=> + string(30) "\v\fHello\t world!! \rstring\n" +} +array(4) { + [0]=> + string(30) "\v\fHello\t world!! \rstring\n" + [1]=> + string(30) "\v\fHello\t world!! \rstring\n" + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 28 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + object(classA)#%d (0) { + } + [3]=> + object(classA)#%d (0) { + } +} +array(4) { + [0]=> + object(classA)#%d (0) { + } + [1]=> + object(classA)#%d (0) { + } + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 29 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + NULL + [3]=> + NULL +} +array(4) { + [0]=> + NULL + [1]=> + NULL + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 30 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + NULL + [3]=> + NULL +} +array(4) { + [0]=> + NULL + [1]=> + NULL + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 31 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + resource(%d) of type (stream) + [3]=> + resource(%d) of type (stream) +} +array(4) { + [0]=> + resource(%d) of type (stream) + [1]=> + resource(%d) of type (stream) + [2]=> + int(1) + [3]=> + int(2) +} +-- Iteration 32 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(5) "hello" + [3]=> + string(5) "hello" +} +array(4) { + [0]=> + string(5) "hello" + [1]=> + string(5) "hello" + [2]=> + int(1) + [3]=> + int(2) +} +Done diff --git a/tests/std/array/array_pad_variation4.phpt b/tests/std/array/array_pad_variation4.phpt new file mode 100644 index 00000000..0c7c6534 --- /dev/null +++ b/tests/std/array/array_pad_variation4.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_pad() function : usage variations - binary safe checking +--FILE-- + +--EXPECT-- +*** Testing array_pad() : Passing binary values to $pad_value argument *** +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + string(5) "hello" + [4]=> + string(5) "hello" + [5]=> + string(5) "hello" +} +array(6) { + [0]=> + string(5) "hello" + [1]=> + string(5) "hello" + [2]=> + string(5) "hello" + [3]=> + int(1) + [4]=> + int(2) + [5]=> + int(3) +} +Done diff --git a/tests/std/array/array_pad_variation5.phpt b/tests/std/array/array_pad_variation5.phpt new file mode 100644 index 00000000..40df2bf2 --- /dev/null +++ b/tests/std/array/array_pad_variation5.phpt @@ -0,0 +1,135 @@ +--TEST-- +Test array_pad() function : usage variations - two dimensional array for 'pad_value' argument +--FILE-- + 1, 'two' => 2) +); + +var_dump( array_pad($input, $pad_size, $pad_value) ); // positive 'pad_value' +var_dump( array_pad($input, -$pad_size, $pad_value) ); // negative 'pad_value' + +echo "Done"; +?> +--EXPECT-- +*** Testing array_pad() : Passing 2-d array to $pad_value argument *** +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [2]=> + array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) + } + } + [4]=> + array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [2]=> + array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) + } + } +} +array(5) { + [0]=> + array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [2]=> + array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) + } + } + [1]=> + array(3) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [2]=> + array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) + } + } + [2]=> + int(1) + [3]=> + int(2) + [4]=> + int(3) +} +Done diff --git a/tests/std/array/array_pad_variation6.phpt b/tests/std/array/array_pad_variation6.phpt new file mode 100644 index 00000000..7c12baa8 --- /dev/null +++ b/tests/std/array/array_pad_variation6.phpt @@ -0,0 +1,665 @@ +--TEST-- +Test array_pad() function : usage variations - different arrays for 'input' argument +--SKIPIF-- + +--FILE-- +22 +'single quoted string' +"double quoted string" +2222 != 1111.\t 0000 = 0000\n +EOT; + +// different arrays to be passed to $input argument +$inputs = array ( +/*1*/ array(1, 2), // with default keys and numeric values + array(1.1, 2.2), // with default keys & float values + array(false,true), // with default keys and boolean values + array(), // empty array +/*5*/ array(NULL), // with NULL + array("a\v\f", "aaaa\r", "b\tbbb", "\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // with double quoted strings + array('a\v\f', 'aaaa\r', 'b\tbbb', '\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // with single quoted strings + array("h1" => $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $numeric_string), // with heredocs + + // associative arrays +/*9*/ array(1 => "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values + array("one" => 1, "two" => 2, "three" => 3 ), // string keys & numeric values + array( 1 => 10, 2 => 20, 4 => 40, 3 => 30), // explicit numeric keys and numeric values + array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value + array("one" => 1, 2 => "two", 4 => "four"), //mixed + + // associative array, containing null/empty/boolean values as key/value +/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + + // array with repetitive keys +/*19*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) +); + +// initialize the $pad_size and $pad_value arguments +$pad_size = 6; +$pad_value = "HELLO"; + +// loop through each sub-array within $inputs to check the behavior of array_pad() +$iterator = 1; +foreach($inputs as $input) { + echo "-- Iteration $iterator --\n"; + var_dump( array_pad($input, $pad_size, $pad_value) ); // positive 'pad_size' + var_dump( array_pad($input, -$pad_size, $pad_value) ); // negative 'pad_size' + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_pad() : Passing different arrays to $input argument *** +-- Iteration 1 -- +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + int(1) + [5]=> + int(2) +} +-- Iteration 2 -- +array(6) { + [0]=> + float(1.1) + [1]=> + float(2.2) + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + float(1.1) + [5]=> + float(2.2) +} +-- Iteration 3 -- +array(6) { + [0]=> + bool(false) + [1]=> + bool(true) + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + bool(false) + [5]=> + bool(true) +} +-- Iteration 4 -- +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +-- Iteration 5 -- +array(6) { + [0]=> + NULL + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" + [5]=> + NULL +} +-- Iteration 6 -- +array(6) { + [0]=> + string(3) "a " + [1]=> + string(5) "aaaa " + [2]=> + string(5) "b bbb" + [3]=> + string(27) "\[\]\!\@\#$\%\^\&\*\(\)\{\}" + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(3) "a " + [3]=> + string(5) "aaaa " + [4]=> + string(5) "b bbb" + [5]=> + string(27) "\[\]\!\@\#$\%\^\&\*\(\)\{\}" +} +-- Iteration 7 -- +array(6) { + [0]=> + string(5) "a\v\f" + [1]=> + string(6) "aaaa\r" + [2]=> + string(6) "b\tbbb" + [3]=> + string(28) "\[\]\!\@\#\$\%\^\&\*\(\)\{\}" + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "a\v\f" + [3]=> + string(6) "aaaa\r" + [4]=> + string(6) "b\tbbb" + [5]=> + string(28) "\[\]\!\@\#\$\%\^\&\*\(\)\{\}" +} +-- Iteration 8 -- +array(6) { + ["h1"]=> + string(1) " +" + ["h2"]=> + string(86) "hello world +The big brown fox jumped over; +the lazy dog +This is a double quoted string" + ["h3"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" + [0]=> + string(90) "11 < 12. 123 >22 +'single quoted string' +"double quoted string" +2222 != 1111. 0000 = 0000 +" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + ["h1"]=> + string(1) " +" + ["h2"]=> + string(86) "hello world +The big brown fox jumped over; +the lazy dog +This is a double quoted string" + ["h3"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" + [2]=> + string(90) "11 < 12. 123 >22 +'single quoted string' +"double quoted string" +2222 != 1111. 0000 = 0000 +" +} +-- Iteration 9 -- +array(6) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + [2]=> + string(5) "three" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [3]=> + string(3) "one" + [4]=> + string(3) "two" + [5]=> + string(5) "three" +} +-- Iteration 10 -- +array(6) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) +} +-- Iteration 11 -- +array(6) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(40) + [3]=> + int(30) + [4]=> + string(5) "HELLO" + [5]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + int(10) + [3]=> + int(20) + [4]=> + int(40) + [5]=> + int(30) +} +-- Iteration 12 -- +array(6) { + ["one"]=> + string(3) "ten" + ["two"]=> + string(6) "twenty" + ["three"]=> + string(6) "thirty" + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + ["one"]=> + string(3) "ten" + ["two"]=> + string(6) "twenty" + ["three"]=> + string(6) "thirty" +} +-- Iteration 13 -- +array(6) { + ["one"]=> + int(1) + [0]=> + string(3) "two" + [1]=> + string(4) "four" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + ["one"]=> + int(1) + [3]=> + string(3) "two" + [4]=> + string(4) "four" +} +-- Iteration 14 -- +array(6) { + [""]=> + string(4) "null" + ["NULL"]=> + NULL + ["null"]=> + NULL + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [""]=> + string(4) "null" + ["NULL"]=> + NULL + ["null"]=> + NULL +} +-- Iteration 15 -- +array(6) { + [0]=> + string(4) "true" + [1]=> + string(5) "false" + ["false"]=> + bool(false) + ["true"]=> + bool(true) + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(4) "true" + [3]=> + string(5) "false" + ["false"]=> + bool(false) + ["true"]=> + bool(true) +} +-- Iteration 16 -- +array(6) { + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" + ["emptys"]=> + string(0) "" + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" + ["emptys"]=> + string(0) "" +} +-- Iteration 17 -- +array(6) { + [1]=> + string(0) "" + [2]=> + string(0) "" + [3]=> + NULL + [4]=> + NULL + [5]=> + bool(false) + [6]=> + bool(true) +} +array(6) { + [1]=> + string(0) "" + [2]=> + string(0) "" + [3]=> + NULL + [4]=> + NULL + [5]=> + bool(false) + [6]=> + bool(true) +} +-- Iteration 18 -- +array(6) { + [""]=> + int(4) + [0]=> + int(5) + [1]=> + int(6) + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [""]=> + int(4) + [3]=> + int(5) + [4]=> + int(6) +} +-- Iteration 19 -- +array(6) { + ["One"]=> + int(10) + ["two"]=> + int(20) + ["three"]=> + int(3) + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" +} +array(6) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + ["One"]=> + int(10) + ["two"]=> + int(20) + ["three"]=> + int(3) +} +Done diff --git a/tests/std/array/array_pad_variation7.phpt b/tests/std/array/array_pad_variation7.phpt new file mode 100644 index 00000000..06f2bfa6 --- /dev/null +++ b/tests/std/array/array_pad_variation7.phpt @@ -0,0 +1,122 @@ +--TEST-- +Test array_pad() function : usage variations - two dimensional array for 'input' argument +--FILE-- + 1, "two" => 2) +); + +// initialize the $pad_size and $pad_value arguments +$pad_size = 5; +$pad_value = "HELLO"; + +// entire 2-d array +echo "-- Entire 2-d array for \$input argument --\n"; +var_dump( array_pad($input, $pad_size, $pad_value) ); // positive 'pad_size' +var_dump( array_pad($input, -$pad_size, $pad_value) ); // negative 'pad_size' + +// sub array +echo "-- Sub array for \$input argument --\n"; +var_dump( array_pad($input[1], $pad_size, $pad_value) ); // positive 'pad_size' +var_dump( array_pad($input[1], -$pad_size, $pad_value) ); // negative 'pad_size' + +echo "Done"; +?> +--EXPECT-- +*** Testing array_pad() : Passing 2-D array to $input argument *** +-- Entire 2-d array for $input argument -- +array(5) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [2]=> + array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) + } + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" +} +array(5) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [3]=> + array(2) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + } + [4]=> + array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) + } +} +-- Sub array for $input argument -- +array(5) { + [0]=> + string(5) "hello" + [1]=> + string(5) "world" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "HELLO" + [4]=> + string(5) "HELLO" +} +array(5) { + [0]=> + string(5) "HELLO" + [1]=> + string(5) "HELLO" + [2]=> + string(5) "HELLO" + [3]=> + string(5) "hello" + [4]=> + string(5) "world" +} +Done diff --git a/tests/std/array/array_pop.phpt b/tests/std/array/array_pop.phpt new file mode 100644 index 00000000..fb0c74b0 --- /dev/null +++ b/tests/std/array/array_pop.phpt @@ -0,0 +1,277 @@ +--TEST-- +Test array_pop() function +--SKIPIF-- + +--FILE-- + "aaa", "A" => "AAA", "c" => "ccc", "d" => "ddd", "e" => "eee" ), + array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), + array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), + array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + array( 12, "name", 'age', '45' ), + array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), + array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, + 5 => 57, "5.4" => 554, "5.7" => 557 ) +); + +/* Loop to test normal functionality with different arrays inputs */ +echo "\n*** Normal testing with various array inputs ***\n"; + +$counter = 1; +foreach( $mixed_array as $sub_array ) +{ + echo "\n-- Input Array for Iteration $counter is --\n"; + var_dump( $sub_array ); + echo "\nOutput after Pop is :\n"; + var_dump( array_pop($sub_array) ); + $counter++; +} + +echo"\nDone"; +?> +--EXPECT-- +*** Normal testing with various array inputs *** + +-- Input Array for Iteration 1 is -- +array(0) { +} + +Output after Pop is : +NULL + +-- Input Array for Iteration 2 is -- +array(9) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) +} + +Output after Pop is : +int(9) + +-- Input Array for Iteration 3 is -- +array(5) { + [0]=> + string(3) "One" + [1]=> + string(4) "_Two" + [2]=> + string(5) "Three" + [3]=> + string(4) "Four" + [4]=> + string(4) "Five" +} + +Output after Pop is : +string(4) "Five" + +-- Input Array for Iteration 4 is -- +array(8) { + [0]=> + int(6) + [1]=> + string(3) "six" + [2]=> + int(7) + [3]=> + string(5) "seven" + [4]=> + int(8) + [5]=> + string(5) "eight" + [6]=> + int(9) + [7]=> + string(4) "nine" +} + +Output after Pop is : +string(4) "nine" + +-- Input Array for Iteration 5 is -- +array(5) { + ["a"]=> + string(3) "aaa" + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" + ["d"]=> + string(3) "ddd" + ["e"]=> + string(3) "eee" +} + +Output after Pop is : +string(3) "eee" + +-- Input Array for Iteration 6 is -- +array(5) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} + +Output after Pop is : +string(4) "five" + +-- Input Array for Iteration 7 is -- +array(5) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + int(7) + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} + +Output after Pop is : +string(4) "five" + +-- Input Array for Iteration 8 is -- +array(12) { + ["f"]=> + string(3) "fff" + [1]=> + string(3) "one" + [4]=> + int(6) + [""]=> + int(3) + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" + [3]=> + float(3.7) + [5]=> + string(4) "Five" + [6]=> + float(8.6) + ["4name"]=> + string(5) "jonny" + ["a"]=> + NULL +} + +Output after Pop is : +NULL + +-- Input Array for Iteration 9 is -- +array(4) { + [0]=> + int(12) + [1]=> + string(4) "name" + [2]=> + string(3) "age" + [3]=> + string(2) "45" +} + +Output after Pop is : +string(2) "45" + +-- Input Array for Iteration 10 is -- +array(3) { + [0]=> + array(3) { + [0]=> + string(3) "oNe" + [1]=> + string(3) "tWo" + [2]=> + int(4) + } + [1]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [2]=> + array(0) { + } +} + +Output after Pop is : +array(0) { +} + +-- Input Array for Iteration 11 is -- +array(10) { + ["one"]=> + int(2) + ["three"]=> + int(3) + [0]=> + int(3) + [1]=> + int(4) + [3]=> + int(33) + [4]=> + int(44) + [5]=> + int(57) + [6]=> + int(6) + ["5.4"]=> + int(554) + ["5.7"]=> + int(557) +} + +Output after Pop is : +int(557) + +Done diff --git a/tests/std/array/array_pop_variation.phpt b/tests/std/array/array_pop_variation.phpt new file mode 100644 index 00000000..af8b0cc0 --- /dev/null +++ b/tests/std/array/array_pop_variation.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_pop() function (variation) +--FILE-- + "aaa", "A" => "AAA", "c" => "ccc", "d" => "ddd", "e" => "eee" ), + array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), + array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), + array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + array( 12, "name", 'age', '45' ), + array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), + array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, + 5 => 57, "5.4" => 554, "5.7" => 557 ) +); + +echo"\n*** Checking for internal array pointer being reset when pop is called ***\n"; + +echo "\nCurrent Element is : "; +var_dump( current($mixed_array[1]) ); + +echo "\nNext Element is : "; +var_dump( next($mixed_array[1]) ); + +echo "\nNext Element is : "; +var_dump( next($mixed_array[1]) ); + +echo "\nPOPed Element is : "; +var_dump( array_pop($mixed_array[1]) ); + +echo "\nCurrent Element after POP operation is: "; +var_dump( current($mixed_array[1]) ); + +echo"\nDone"; +?> +--EXPECT-- +*** Checking for internal array pointer being reset when pop is called *** + +Current Element is : int(1) + +Next Element is : int(2) + +Next Element is : int(3) + +POPed Element is : int(9) + +Current Element after POP operation is: int(1) + +Done diff --git a/tests/std/array/array_product_empty_array.phpt b/tests/std/array/array_product_empty_array.phpt new file mode 100644 index 00000000..714030d1 --- /dev/null +++ b/tests/std/array/array_product_empty_array.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test array_product() function with empty array +--FILE-- + $carry * $value, 1)); +?> +--EXPECT-- +array_product() version: +int(1) +array_reduce() version: +int(1) diff --git a/tests/std/array/array_product_objects_operation_no_cast.phpt b/tests/std/array/array_product_objects_operation_no_cast.phpt new file mode 100644 index 00000000..7f4af375 --- /dev/null +++ b/tests/std/array/array_product_objects_operation_no_cast.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test array_product() function with objects that implement addition but not castable to numeric type +--EXTENSIONS-- +zend_test +--FILE-- + $carry * $value, 1)); +?> +--EXPECTF-- +array_product() version: + +Warning: array_product(): Multiplication is not supported on type DoOperationNoCast in %s on line %d + +Warning: array_product(): Multiplication is not supported on type DoOperationNoCast in %s on line %d + +Warning: array_product(): Multiplication is not supported on type DoOperationNoCast in %s on line %d +int(1) +array_reduce() version: +object(DoOperationNoCast)#5 (1) { + ["val":"DoOperationNoCast":private]=> + int(1500) +} diff --git a/tests/std/array/array_product_variation1.phpt b/tests/std/array/array_product_variation1.phpt new file mode 100644 index 00000000..ad92aa11 --- /dev/null +++ b/tests/std/array/array_product_variation1.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test array_product() function : variation +--FILE-- + true, "boolean (false)" => false, "string" => "hello", "numeric string" => "12", "resource" => STDERR, "object" => new A(), "null" => null, "array" => array(3, 2)); + foreach ($types as $desc => $type) { + echo $desc, "\n"; + var_dump(array_product([1, $type])); + echo "\n"; + } +} +?> +--EXPECTF-- +*** Testing array_product() : variation - using non numeric values *** +boolean (true) +int(1) + +boolean (false) +int(0) + +string + +Warning:%S Multiplication is not supported on type string in %s on line %d +int(0) + +numeric string +int(12) + +resource + +Warning:%S Multiplication is not supported on type resource in %s on line %d +int(3) + +object + +Warning:%S Multiplication is not supported on type A in %s on line %d +int(1) + +null +int(0) + +array + +Warning:%S Multiplication is not supported on type array in %s on line %d +int(1) + diff --git a/tests/std/array/array_product_variation2.phpt b/tests/std/array/array_product_variation2.phpt new file mode 100644 index 00000000..167e46ec --- /dev/null +++ b/tests/std/array/array_product_variation2.phpt @@ -0,0 +1,14 @@ +--TEST-- +Test array_product() function : variation +--FILE-- + 2, "janet" => 5)) ); +?> +--EXPECT-- +*** Testing array_product() : variations *** + +-- Testing array_product() function with a keyed array array -- +int(10) diff --git a/tests/std/array/array_product_variation3.phpt b/tests/std/array/array_product_variation3.phpt new file mode 100644 index 00000000..03c7da17 --- /dev/null +++ b/tests/std/array/array_product_variation3.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test array_product() function : variation +--FILE-- + +--EXPECT-- +*** Testing array_product() : variations - negative numbers*** + +-- Testing array_product() function with one negative number -- +int(-2) + +-- Testing array_product() function with two negative numbers -- +int(6) + +-- Testing array_product() function with three negative numbers -- +int(-24) + +-- Testing array_product() function with negative floats -- +float(-1.5) + +-- Testing array_product() function with negative floats -- +float(-9999999900000000) diff --git a/tests/std/array/array_product_variation4.phpt b/tests/std/array/array_product_variation4.phpt new file mode 100644 index 00000000..c142cea6 --- /dev/null +++ b/tests/std/array/array_product_variation4.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test array_product() function : variation +--FILE-- + +--EXPECT-- +*** Testing array_product() : variations *** + +-- Testing array_product() function with a very large array -- +float(INF) diff --git a/tests/std/array/array_product_variation5.phpt b/tests/std/array/array_product_variation5.phpt new file mode 100644 index 00000000..557c2b33 --- /dev/null +++ b/tests/std/array/array_product_variation5.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test array_product() function: resources in array +--FILE-- + $carry * $value, 1)); +} catch (TypeError $e) { + echo $e->getMessage(); +} +?> +--EXPECTF-- +array_product() version: + +Warning:%S Multiplication is not supported on type resource in %s on line %d +int(30) +array_reduce() version: +Unsupported operand types: int * resource%S +%a diff --git a/tests/std/array/array_product_variation6.phpt b/tests/std/array/array_product_variation6.phpt new file mode 100644 index 00000000..6526197c --- /dev/null +++ b/tests/std/array/array_product_variation6.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test array_product() function with objects castable to numeric type +--EXTENSIONS-- +gmp +--FILE-- + $carry * $value, 1)); +?> +--EXPECT-- +array_product() version: +int(150) +array_reduce() version: +object(GMP)#5 (1) { + ["num"]=> + string(3) "150" +} diff --git a/tests/std/array/array_push.phpt b/tests/std/array/array_push.phpt new file mode 100644 index 00000000..32fcf0d3 --- /dev/null +++ b/tests/std/array/array_push.phpt @@ -0,0 +1,320 @@ +--TEST-- +Test array_push() function +--SKIPIF-- + +--FILE-- + "aaa", "A" => "AAA", "c" => "ccc", "d" => "ddd", "e" => "eee" ), + array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), + array( 1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), + array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + array( 12, "name", 'age', '45' ), + array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array() ), + array( "one" => 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, + 5 => 57, "5.4" => 554, "5.7" => 557 ) +); + +/* Error Conditions */ +echo "\n*** Testing Edge Conditions ***\n"; + +/* Invalid Number of arguments */ +var_dump( array_push($mixed_array[1],1,2) ); + +/* Empty Array as argument */ +var_dump( array_push($empty_array, 2) ); + + +/* Loop to test normal functionality with different arrays inputs */ +echo "\n*** Testing with various array inputs ***\n"; + +$counter = 1; +foreach( $mixed_array as $sub_array ) +{ + echo "\n-- Input Array for Iteration $counter is --\n"; + var_dump( $sub_array ); + echo "\nOutput after push is :\n"; + var_dump( array_push($sub_array, 22, "abc") ); + $counter++; +} + +/* Checking for return value and the new array formed from push operation */ +echo "\n*** Checking for return value and the new array formed from push operation ***\n"; +var_dump( array_push($mixed_array[2], 22, 33, "44") ); +var_dump( $mixed_array[2] ); + +echo"\nDone"; +?> +--EXPECT-- +*** Testing Edge Conditions *** +int(11) +int(1) + +*** Testing with various array inputs *** + +-- Input Array for Iteration 1 is -- +array(0) { +} + +Output after push is : +int(2) + +-- Input Array for Iteration 2 is -- +array(11) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(1) + [10]=> + int(2) +} + +Output after push is : +int(13) + +-- Input Array for Iteration 3 is -- +array(5) { + [0]=> + string(3) "One" + [1]=> + string(4) "_Two" + [2]=> + string(5) "Three" + [3]=> + string(4) "Four" + [4]=> + string(4) "Five" +} + +Output after push is : +int(7) + +-- Input Array for Iteration 4 is -- +array(8) { + [0]=> + int(6) + [1]=> + string(3) "six" + [2]=> + int(7) + [3]=> + string(5) "seven" + [4]=> + int(8) + [5]=> + string(5) "eight" + [6]=> + int(9) + [7]=> + string(4) "nine" +} + +Output after push is : +int(10) + +-- Input Array for Iteration 5 is -- +array(5) { + ["a"]=> + string(3) "aaa" + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" + ["d"]=> + string(3) "ddd" + ["e"]=> + string(3) "eee" +} + +Output after push is : +int(7) + +-- Input Array for Iteration 6 is -- +array(5) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} + +Output after push is : +int(7) + +-- Input Array for Iteration 7 is -- +array(5) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + int(7) + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} + +Output after push is : +int(7) + +-- Input Array for Iteration 8 is -- +array(12) { + ["f"]=> + string(3) "fff" + [1]=> + string(3) "one" + [4]=> + int(6) + [""]=> + int(3) + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" + [3]=> + float(3.7) + [5]=> + string(4) "Five" + [6]=> + float(8.6) + ["4name"]=> + string(5) "jonny" + ["a"]=> + NULL +} + +Output after push is : +int(14) + +-- Input Array for Iteration 9 is -- +array(4) { + [0]=> + int(12) + [1]=> + string(4) "name" + [2]=> + string(3) "age" + [3]=> + string(2) "45" +} + +Output after push is : +int(6) + +-- Input Array for Iteration 10 is -- +array(3) { + [0]=> + array(3) { + [0]=> + string(3) "oNe" + [1]=> + string(3) "tWo" + [2]=> + int(4) + } + [1]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [2]=> + array(0) { + } +} + +Output after push is : +int(5) + +-- Input Array for Iteration 11 is -- +array(10) { + ["one"]=> + int(2) + ["three"]=> + int(3) + [0]=> + int(3) + [1]=> + int(4) + [3]=> + int(33) + [4]=> + int(44) + [5]=> + int(57) + [6]=> + int(6) + ["5.4"]=> + int(554) + ["5.7"]=> + int(557) +} + +Output after push is : +int(12) + +*** Checking for return value and the new array formed from push operation *** +int(8) +array(8) { + [0]=> + string(3) "One" + [1]=> + string(4) "_Two" + [2]=> + string(5) "Three" + [3]=> + string(4) "Four" + [4]=> + string(4) "Five" + [5]=> + int(22) + [6]=> + int(33) + [7]=> + string(2) "44" +} + +Done diff --git a/tests/std/array/array_push_basic.phpt b/tests/std/array/array_push_basic.phpt new file mode 100644 index 00000000..c0d66b70 --- /dev/null +++ b/tests/std/array/array_push_basic.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test array_push() function : basic functionality +--FILE-- + 'un', 'two' => 'deux'); + +echo "\n-- Push values onto an associative array --\n"; +var_dump(array_push($array_assoc, $var1, $var2)); +var_dump($array_assoc); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_push() : basic functionality *** + +-- Push values onto an indexed array -- +int(5) +array(5) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" + [4]=> + string(4) "four" +} + +-- Push values onto an associative array -- +int(4) +array(4) { + ["one"]=> + string(2) "un" + ["two"]=> + string(4) "deux" + [0]=> + string(5) "three" + [1]=> + string(4) "four" +} +Done diff --git a/tests/std/array/array_push_empty.phpt b/tests/std/array/array_push_empty.phpt new file mode 100644 index 00000000..1c7f935a --- /dev/null +++ b/tests/std/array/array_push_empty.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test array_push() function : push empty set to the array +--FILE-- + +--EXPECT-- +int(3) +int(3) +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +Done diff --git a/tests/std/array/array_push_error2.phpt b/tests/std/array/array_push_error2.phpt new file mode 100644 index 00000000..0ed0af6e --- /dev/null +++ b/tests/std/array/array_push_error2.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test array_push() function : error conditions - max int value as key +--FILE-- + 'max'); +try { + var_dump(array_push($array, 'new')); +} catch (\Error $e) { + echo $e->getMessage() . "\n"; +} +var_dump($array); + +?> +--EXPECTF-- +*** Testing array_push() : error conditions *** +Cannot add element to the array as the next element is already occupied +array(1) { + [%d]=> + string(3) "max" +} diff --git a/tests/std/array/array_push_variation2.phpt b/tests/std/array/array_push_variation2.phpt new file mode 100644 index 00000000..6533a67e --- /dev/null +++ b/tests/std/array/array_push_variation2.phpt @@ -0,0 +1,171 @@ +--TEST-- +Test array_push() function : usage variations - Pass different data types as $var arg +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +*** Testing array_push() : usage variations *** + +-- Iteration 1 -- +int(3) + +-- Iteration 2 -- +int(3) + +-- Iteration 3 -- +int(3) + +-- Iteration 4 -- +int(3) + +-- Iteration 5 -- +int(3) + +-- Iteration 6 -- +int(3) + +-- Iteration 7 -- +int(3) + +-- Iteration 8 -- +int(3) + +-- Iteration 9 -- +int(3) + +-- Iteration 10 -- +int(3) + +-- Iteration 11 -- +int(3) + +-- Iteration 12 -- +int(3) + +-- Iteration 13 -- +int(3) + +-- Iteration 14 -- +int(3) + +-- Iteration 15 -- +int(3) + +-- Iteration 16 -- +int(3) + +-- Iteration 17 -- +int(3) + +-- Iteration 18 -- +int(3) + +-- Iteration 19 -- +int(3) + +-- Iteration 20 -- +int(3) + +-- Iteration 21 -- +int(3) + +-- Iteration 22 -- +int(3) + +-- Iteration 23 -- +int(3) + +-- Iteration 24 -- +int(3) + +-- Iteration 25 -- +int(3) +Done diff --git a/tests/std/array/array_push_variation3.phpt b/tests/std/array/array_push_variation3.phpt new file mode 100644 index 00000000..4ce4e7d9 --- /dev/null +++ b/tests/std/array/array_push_variation3.phpt @@ -0,0 +1,65 @@ +--TEST-- +Test array_push() function : usage variations - multidimensional arrays +--FILE-- + +--EXPECT-- +*** Testing array_push() : usage variations *** + +-- Pass array as $var argument -- +int(4) +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + } +} + +-- Pass sub-array as $stack argument -- +int(3) +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + array(3) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + [2]=> + string(1) "a" + } +} +Done diff --git a/tests/std/array/array_push_variation5.phpt b/tests/std/array/array_push_variation5.phpt new file mode 100644 index 00000000..32e541ef --- /dev/null +++ b/tests/std/array/array_push_variation5.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test array_push() function : usage variations - position of internal array pointer +--FILE-- + 'un', 'two' => 'deux'); +$var0 = 'zero'; + +echo "\n-- Call array_push() --\n"; +var_dump($result = array_push($stack, $var0)); + +echo "\n-- Position of Internal Pointer in Original Array: --\n"; +echo key($stack) . " => " . current ($stack) . "\n"; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_push() : usage variations *** + +-- Call array_push() -- +int(3) + +-- Position of Internal Pointer in Original Array: -- +one => un +Done diff --git a/tests/std/array/array_push_variation6.phpt b/tests/std/array/array_push_variation6.phpt new file mode 100644 index 00000000..b5ebbb3c --- /dev/null +++ b/tests/std/array/array_push_variation6.phpt @@ -0,0 +1,138 @@ +--TEST-- +Test array_push() function : usage variations - array keys are different data types +--SKIPIF-- + + +--FILE-- + array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative', + ), + + // null data +/*3*/ 'null uppercase' => array( + NULL => 'null 1', + ), + 'null lowercase' => array( + null => 'null 2', + ), + + // boolean data +/*4*/ 'bool lowercase' => array( + true => 'lowert', + false => 'lowerf', + ), + 'bool uppercase' => array( + TRUE => 'uppert', + FALSE => 'upperf', + ), + + // empty data +/*5*/ 'empty double quotes' => array( + "" => 'emptyd', + ), + 'empty single quotes' => array( + '' => 'emptys', + ), + + // string data +/*6*/ 'string' => array( + "stringd" => 'stringd', + 'strings' => 'strings', + $heredoc => 'stringh', + ), + + // undefined data +/*8*/ 'undefined' => array( + @$undefined_var => 'undefined', + ), + + // unset data +/*9*/ 'unset' => array( + @$unset_var => 'unset', + ), +); + +// loop through each sub-array of $inputs to check the behavior of array_push() +$iterator = 1; +foreach($inputs as $key => $input) { + echo "\n-- Iteration $iterator : $key data --\n"; + echo "Before : "; + var_dump(count($input)); + echo "After : "; + var_dump( array_push($input, $var) ); + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_push() : usage variations *** + +-- Iteration 1 : int data -- +Before : int(4) +After : int(5) + +-- Iteration 2 : null uppercase data -- +Before : int(1) +After : int(2) + +-- Iteration 3 : null lowercase data -- +Before : int(1) +After : int(2) + +-- Iteration 4 : bool lowercase data -- +Before : int(2) +After : int(3) + +-- Iteration 5 : bool uppercase data -- +Before : int(2) +After : int(3) + +-- Iteration 6 : empty double quotes data -- +Before : int(1) +After : int(2) + +-- Iteration 7 : empty single quotes data -- +Before : int(1) +After : int(2) + +-- Iteration 8 : string data -- +Before : int(3) +After : int(4) + +-- Iteration 9 : undefined data -- +Before : int(1) +After : int(2) + +-- Iteration 10 : unset data -- +Before : int(1) +After : int(2) +Done diff --git a/tests/std/array/array_rand.phpt b/tests/std/array/array_rand.phpt new file mode 100644 index 00000000..24f6966b --- /dev/null +++ b/tests/std/array/array_rand.phpt @@ -0,0 +1,59 @@ +--TEST-- +array_rand() tests +--FILE-- +getMessage() . "\n"; +} + +try { + var_dump(array_rand(array(), 0)); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(array_rand(array(1,2,3), 0)); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(array_rand(array(1,2,3), -1)); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(array_rand(array(1,2,3), 10)); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +var_dump(array_rand(array(1,2,3), 3)); +var_dump(array_rand(array(1,2,3), 2)); + +?> +--EXPECTF-- +array_rand(): Argument #1 ($array) must not be empty +array_rand(): Argument #1 ($array) must not be empty +array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) +array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) +array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} +array(2) { + [0]=> + int(%d) + [1]=> + int(%d) +} diff --git a/tests/std/array/array_rand_basic1.phpt b/tests/std/array/array_rand_basic1.phpt new file mode 100644 index 00000000..0f2d79df --- /dev/null +++ b/tests/std/array/array_rand_basic1.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test array_rand() function : basic functionality - array with default keys +--FILE-- + +--EXPECTF-- +*** Testing array_rand() : array with default keys *** + +-- with all default and optional arguments -- +array(%d) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + [3]=> + int(%d) + [4]=> + int(%d) + [5]=> + int(%d) +} + +-- with default argument -- +int(%d) +Done diff --git a/tests/std/array/array_rand_basic2.phpt b/tests/std/array/array_rand_basic2.phpt new file mode 100644 index 00000000..747cb562 --- /dev/null +++ b/tests/std/array/array_rand_basic2.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test array_rand() function : basic functionality - with associative array for 'input' argument +--FILE-- + 1, 'two' => 2, 'three' => 3, + 'FoUr' => 'four', '#5' => 5, 'SIX' => 'six', + "seven" => 7, "#8" => "eight", "nine" => "NINE" +); + +$num_req = 6; + +// Calling array_rand() with optional argument +echo"\n-- with all default and optional arguments --\n"; +var_dump( array_rand($input,$num_req) ); + +// Calling array_rand() with default arguments +echo"\n-- with default argument --\n"; +var_dump( array_rand($input) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_rand() : with associative array *** + +-- with all default and optional arguments -- +array(6) { + [0]=> + string(%d) "%s" + [1]=> + string(%d) "%s" + [2]=> + string(%d) "%s" + [3]=> + string(%d) "%s" + [4]=> + string(%d) "%s" + [5]=> + string(%d) "%s" +} + +-- with default argument -- +string(%d) "%s" +Done diff --git a/tests/std/array/array_rand_variation3.phpt b/tests/std/array/array_rand_variation3.phpt new file mode 100644 index 00000000..34f2db6e --- /dev/null +++ b/tests/std/array/array_rand_variation3.phpt @@ -0,0 +1,144 @@ +--TEST-- +Test array_rand() function : usage variation - with MultiDimensional array +--FILE-- + +--EXPECTF-- +*** Testing array_rand() : with multi-dimensional array *** +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +*** Testing array_rand() with arrays having different types of values *** + +-- Iteration 1 -- +int(%d) +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 2 -- +int(%d) +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 3 -- +int(%d) +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 4 -- +int(%d) +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 5 -- +int(%d) +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 6 -- +int(%d) +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 7 -- +int(%d) +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} +Done diff --git a/tests/std/array/array_rand_variation4.phpt b/tests/std/array/array_rand_variation4.phpt new file mode 100644 index 00000000..c7d90783 --- /dev/null +++ b/tests/std/array/array_rand_variation4.phpt @@ -0,0 +1,163 @@ +--TEST-- +Test array_rand() function : usage variation - with associative arrays for 'input' parameter +--SKIPIF-- + +--FILE-- + 'one', 2 => 2, 1234567890 => 'big', -1 => 'negative key', + 0 => "zero key"), + + // array with string keys + array('one' => 1, "two" => 2.0, "three" => 'three', + '12twelve' => 12.00, "" => 'empty string', " " => "space key"), + + // array with hexa values as keys +/*3*/ array(0xabc => 2748, 0x12f => '303', 0xff => "255", -0xff => "-255"), + + // array with octal values as keys + array(0123 => 83, 012 => 10, 010 => "8", -034 => "-28", 0012 => '10'), + + // array with bool values as keys + array(TRUE => '1', true => true, TrUe => "TRUE", + FALSE => '0', false => false, FaLsE => "FALSE"), + + // array with special chars as keys +/*6*/ array('##' => "key1", '&$r' => 'key2', '!' => "key3", '<>' =>'key4', + "NULL" => 'key5', "\n" => 'newline as key', + "\t" => "tab as key", "'" => 'single quote as key', + '"' => 'double quote as key', "\0" => "null char as key") +); + +/* looping to test array_rand() function with different arrays having + * different types of keys +*/ +$counter = 1; +foreach($asso_arrays as $input) { + echo "\n-- Iteration $counter --\n"; + + // with default argument + echo"\nWith default argument\n"; + var_dump( array_rand($input) ); + + // with default and optional arguments + echo"\nWith num_req = 1\n"; + var_dump( array_rand($input, 1) ); // with $num_req=1 + echo"\nWith num_req = 2\n"; + var_dump( array_rand($input, 2) ); // with $num_req=2 + + $counter++; +} // end of for loop + + +echo "Done"; +?> +--EXPECTREGEX-- +\*\*\* Testing array_rand\(\) : with associative arrays \*\*\* + +-- Iteration 1 -- + +With default argument +int\([012-][12.e]*[23e]*[34]*[5]*[6]*[7]*[8]*[9]*[0]*\) + +With num_req = 1 +int\([012-][12.e]*[23e]*[34]*[5]*[6]*[7]*[8]*[9]*[0]*\) + +With num_req = 2 +array\(2\) { + \[0\]=> + int\([012-][12.e]*[23e]*[34]*[5]*[6]*[7]*[8]*[9]*[0]*\) + \[1\]=> + int\([012-][12.e]*[23e]*[34]*[5]*[6]*[7]*[8]*[9]*[0]*\) +} + +-- Iteration 2 -- + +With default argument +string\([0-9]*\) "[ot1 ]*[hnw2]*[eort]*[ew]*[e]*[l]*[v]*[e]*" + +With num_req = 1 +string\([0-9]*\) "[ot1 ]*[hnw2]*[eort]*[ew]*[e]*[l]*[v]*[e]*" + +With num_req = 2 +array\(2\) { + \[0\]=> + string\([0-9]*\) "[ot1 ]*[hnw2]*[eort]*[ew]*[e]*[l]*[v]*[e]*" + \[1\]=> + string\([0-9]*\) "[ot1 ]*[hnw2]*[eort]*[ew]*[e]*[l]*[v]*[e]*" +} + +-- Iteration 3 -- + +With default argument +int\([23-]*[2570]*[345]*[58]*\) + +With num_req = 1 +int\([23-]*[2570]*[345]*[58]*\) + +With num_req = 2 +array\(2\) { + \[0\]=> + int\([23-]*[2570]*[345]*[58]*\) + \[1\]=> + int\([23-]*[2570]*[345]*[58]*\) +} + +-- Iteration 4 -- + +With default argument +int\([18-]*[023]*[8]*\) + +With num_req = 1 +int\([18-]*[023]*[8]*\) + +With num_req = 2 +array\(2\) { + \[0\]=> + int\([18-]*[023]*[8]*\) + \[1\]=> + int\([18-]*[023]*[8]*\) +} + +-- Iteration 5 -- + +With default argument +int\([01]\) + +With num_req = 1 +int\([01]\) + +With num_req = 2 +array\(2\) { + \[0\]=> + int\([01]\) + \[1\]=> + int\([01]\) +} + +-- Iteration 6 -- + +With default argument +string\([0-9]*\) "[#&!N <\n\t'"\0]*[U#$>]*[rL]*[L]*" + +With num_req = 1 +string\([0-9]*\) "[#&!N <\n\t'"\0]*[U#$>]*[rL]*[L]*" + +With num_req = 2 +array\(2\) { + \[0\]=> + string\([0-9]*\) "[#&!N <\n\t'"\0]*[U#$>]*[rL]*[L]*" + \[1\]=> + string\([0-9]*\) "[#&!N <\n\t'"\0]*[U#$>]*[rL]*[L]*" +} +Done diff --git a/tests/std/array/array_rand_variation5.phpt b/tests/std/array/array_rand_variation5.phpt new file mode 100644 index 00000000..57f5ee03 --- /dev/null +++ b/tests/std/array/array_rand_variation5.phpt @@ -0,0 +1,76 @@ +--TEST-- +Test array_rand() function : usage variation - invalid values for 'req_num' parameter +--FILE-- + 'one', + 0xabc => 2748, 0x12f => '303', 0xff => "255", + 0123 => 83, 012 => 10, 010 => "8" +); + +// Testing array_rand() function with various invalid 'req_num' values +// with valid num_req values +echo"\n-- With default num_req value --\n"; +var_dump( array_rand($input) ); // with default $num_req value +echo"\n-- With num_req = 1 --\n"; +var_dump( array_rand($input, 1) ); // with valid $num_req value + +// with invalid num_req value +echo"\n-- With num_req = 0 --\n"; +try { + var_dump( array_rand($input, 0) ); // with $num_req=0 +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +echo"\n-- With num_req = -1 --\n"; +try { + var_dump( array_rand($input, -1) ); // with $num_req=-1 +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +echo"\n-- With num_req = -2 --\n"; +try { + var_dump( array_rand($input, -2) ); // with $num_req=-2 +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +echo"\n-- With num_req more than number of members in 'input' array --\n"; +try { + var_dump( array_rand($input, 13) ); // with $num_req=13 +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECTF-- +*** Testing array_rand() : with invalid values for 'req_num' *** + +-- With default num_req value -- +int(%d) + +-- With num_req = 1 -- +int(%d) + +-- With num_req = 0 -- +array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) + +-- With num_req = -1 -- +array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) + +-- With num_req = -2 -- +array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) + +-- With num_req more than number of members in 'input' array -- +array_rand(): Argument #2 ($num) must be between 1 and the number of elements in argument #1 ($array) diff --git a/tests/std/array/array_rand_variation6.phpt b/tests/std/array/array_rand_variation6.phpt new file mode 100644 index 00000000..e8113fc1 --- /dev/null +++ b/tests/std/array/array_rand_variation6.phpt @@ -0,0 +1,98 @@ +--TEST-- +Test array_rand() function : usage variation - with heredoc string as key in the 'input' array +--FILE-- + "heredoc1", + $heredoc_with_newline => "heredoc2", + $heredoc_with_characters => "heredoc3", + $heredoc_with_newline_and_tabs => "heredoc3", + $heredoc_with_alphanumerics => "heredoc4", + $heredoc_with_embedded_nulls => "heredoc5" +); + +// Test array_rand() function with different valid 'req_num' values +echo "\n-- with default parameters --\n"; +var_dump( array_rand($input) ); + +echo "\n-- with num_req = 1 --\n"; +var_dump( array_rand($input, 1) ); + +echo "\n-- with num_req = 3 --\n"; +var_dump( array_rand($input, 3) ); + +echo "\n-- with num_req = 6 --\n"; +var_dump( array_rand($input, 6) ); + + +echo "Done"; +?> +--EXPECTREGEX-- +\*\*\* Testing array_rand\(\) : with keys of input array as heredoc strings \*\*\* + +-- with default parameters -- +string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" + +-- with num_req = 1 -- +string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" + +-- with num_req = 3 -- +array\(3\) { + \[0\]=> + string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" + \[1\]=> + string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" + \[2\]=> + string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" +} + +-- with num_req = 6 -- +array\(6\) { + \[0\]=> + string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" + \[1\]=> + string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" + \[2\]=> + string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" + \[3\]=> + string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" + \[4\]=> + string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" + \[5\]=> + string\([0-9]*\) "[a-z \n \t \0 0-9 ]*" +} +Done diff --git a/tests/std/array/array_reduce.phpt b/tests/std/array/array_reduce.phpt new file mode 100644 index 00000000..f3e9c021 --- /dev/null +++ b/tests/std/array/array_reduce.phpt @@ -0,0 +1,90 @@ +--TEST-- +Test array_reduce() function +--INI-- +precision=14 +--SKIPIF-- + +--FILE-- + 42, 'bar' => 17, 'qux' => -2, 'quux' => 0); + var_dump(array_reduce($array, 'reduce_array', $initial), $initial); + echo "\n*** Testing array_reduce() to null ***\n"; + $initial = null; + var_dump(array_reduce($array, 'reduce_null', $initial), $initial); + echo "\nDone"; +} +?> +--EXPECT-- +*** Testing array_reduce() to integer *** +int(61) +int(42) + +*** Testing array_reduce() to float *** +float(6.1) +float(4.2) + +*** Testing array_reduce() to string *** +string(23) "quuxfoofoobarquxquxquux" +string(4) "quux" + +*** Testing array_reduce() to array *** +array(4) { + ["foo"]=> + int(44) + ["bar"]=> + int(18) + ["qux"]=> + int(0) + ["quux"]=> + int(1) +} +array(4) { + ["foo"]=> + int(42) + ["bar"]=> + int(17) + ["qux"]=> + int(-2) + ["quux"]=> + int(0) +} + +*** Testing array_reduce() to null *** +string(19) "foofoobarquxquxquux" +NULL + +Done diff --git a/tests/std/array/array_reduce_return_by_ref.phpt b/tests/std/array/array_reduce_return_by_ref.phpt new file mode 100644 index 00000000..8da7018c --- /dev/null +++ b/tests/std/array/array_reduce_return_by_ref.phpt @@ -0,0 +1,11 @@ +--TEST-- +Return by reference from array_reduce() callback +--FILE-- + +--EXPECT-- +int(2) diff --git a/tests/std/array/array_reduce_variation1.phpt b/tests/std/array/array_reduce_variation1.phpt new file mode 100644 index 00000000..97ed759e --- /dev/null +++ b/tests/std/array/array_reduce_variation1.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test array_reduce() function : variation +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } +} +?> +--EXPECT-- +*** Testing array_reduce() : variation *** + +--- Testing with a callback with too few parameters --- +int(2) + +--- Testing with a callback with too many parameters --- +Exception: Too few arguments to function threeArgs(), 2 passed and exactly 3 expected diff --git a/tests/std/array/array_reduce_variation3.phpt b/tests/std/array/array_reduce_variation3.phpt new file mode 100644 index 00000000..4cc6d011 --- /dev/null +++ b/tests/std/array/array_reduce_variation3.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test array_reduce() function : variation - object callbacks +--FILE-- + +--EXPECT-- +*** Testing array_reduce() : variation - object callbacks *** + +--- Static method callback --- +int(1) + +--- Instance method callback --- +int(1) diff --git a/tests/std/array/array_replace.phpt b/tests/std/array/array_replace.phpt new file mode 100644 index 00000000..c3edba00 --- /dev/null +++ b/tests/std/array/array_replace.phpt @@ -0,0 +1,114 @@ +--TEST-- +Test array_replace and array_replace_recursive +--FILE-- + 'dontclobber', + '1' => 'unclobbered', + 'test2' => 0.0, + 'test3' => array( + 'testarray2' => true, + 1 => array( + 'testsubarray1' => 'dontclobber2', + 'testsubarray2' => 'dontclobber3', + ), + ), +); + +$array2 = array( + 1 => 'clobbered', + 'test3' => array( + 'testarray2' => false, + ), + 'test4' => array( + 'clobbered3' => array(0, 1, 2), + ), +); + +$array3 = array(array(array(array()))); + +$array4 = array(); +$array4[] = &$array4; + +echo " -- Testing array_replace() --\n"; +$data = array_replace($array1, $array2); + +var_dump($data); + +echo " -- Testing array_replace_recursive() --\n"; +$data = array_replace_recursive($array1, $array2); + +var_dump($data); + +echo " -- Testing array_replace_recursive() w/ endless recusrsion --\n"; +try { + $data = array_replace_recursive($array3, $array4); + var_dump($data); +} catch (\Error $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECT-- + -- Testing array_replace() -- +array(5) { + [0]=> + string(11) "dontclobber" + [1]=> + string(9) "clobbered" + ["test2"]=> + float(0) + ["test3"]=> + array(1) { + ["testarray2"]=> + bool(false) + } + ["test4"]=> + array(1) { + ["clobbered3"]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + } +} + -- Testing array_replace_recursive() -- +array(5) { + [0]=> + string(11) "dontclobber" + [1]=> + string(9) "clobbered" + ["test2"]=> + float(0) + ["test3"]=> + array(2) { + ["testarray2"]=> + bool(false) + [1]=> + array(2) { + ["testsubarray1"]=> + string(12) "dontclobber2" + ["testsubarray2"]=> + string(12) "dontclobber3" + } + } + ["test4"]=> + array(1) { + ["clobbered3"]=> + array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + } + } +} + -- Testing array_replace_recursive() w/ endless recusrsion -- +Recursion detected diff --git a/tests/std/array/array_replace_merge_recursive_ref.phpt b/tests/std/array/array_replace_merge_recursive_ref.phpt new file mode 100644 index 00000000..e8d4f8e0 --- /dev/null +++ b/tests/std/array/array_replace_merge_recursive_ref.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test array_(replace|merge)_recursive with references +--FILE-- + &$one]; +$arr2 = ['k' => &$two]; +var_dump(current($one), current($two)); +array_replace_recursive($arr1, $arr2); +var_dump(current($one), current($two)); + +$one = [1]; +$two = [42]; +$arr1 = ['k' => &$one]; +$arr2 = ['k' => &$two]; +var_dump(current($one), current($two)); +array_merge_recursive($arr1, $arr2); +var_dump(current($one), current($two)); + +?> +--EXPECT-- +int(1) +int(42) +int(1) +int(42) +int(1) +int(42) +int(1) +int(42) diff --git a/tests/std/array/array_reverse_basic1.phpt b/tests/std/array/array_reverse_basic1.phpt new file mode 100644 index 00000000..6f7197d8 --- /dev/null +++ b/tests/std/array/array_reverse_basic1.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test array_reverse() function : basic functionality - simple array for 'array' argument +--FILE-- + +--EXPECT-- +*** Testing array_reverse() : basic functionality *** +array(6) { + [0]=> + float(13.33) + [1]=> + int(10) + [2]=> + string(4) "blue" + [3]=> + string(3) "red" + [4]=> + string(5) "green" + [5]=> + string(1) "a" +} +array(6) { + [5]=> + float(13.33) + [4]=> + int(10) + [3]=> + string(4) "blue" + [2]=> + string(3) "red" + [1]=> + string(5) "green" + [0]=> + string(1) "a" +} +array(6) { + [0]=> + float(13.33) + [1]=> + int(10) + [2]=> + string(4) "blue" + [3]=> + string(3) "red" + [4]=> + string(5) "green" + [5]=> + string(1) "a" +} +Done diff --git a/tests/std/array/array_reverse_basic2.phpt b/tests/std/array/array_reverse_basic2.phpt new file mode 100644 index 00000000..c10c12b0 --- /dev/null +++ b/tests/std/array/array_reverse_basic2.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_reverse() function : basic functionality - associative array for 'array' argument +--FILE-- + "hello", 123 => "number", 'string' => 'blue', "10" => 13.33); + +// Calling array_reverse() with default arguments +var_dump( array_reverse($array) ); + +// Calling array_reverse() with all possible arguments +var_dump( array_reverse($array, true) ); // expects the keys to be preserved +var_dump( array_reverse($array, false) ); // expects the keys not to be preserved + +echo "Done"; +?> +--EXPECT-- +*** Testing array_reverse() : basic functionality *** +array(4) { + [0]=> + float(13.33) + ["string"]=> + string(4) "blue" + [1]=> + string(6) "number" + ["a"]=> + string(5) "hello" +} +array(4) { + [10]=> + float(13.33) + ["string"]=> + string(4) "blue" + [123]=> + string(6) "number" + ["a"]=> + string(5) "hello" +} +array(4) { + [0]=> + float(13.33) + ["string"]=> + string(4) "blue" + [1]=> + string(6) "number" + ["a"]=> + string(5) "hello" +} +Done diff --git a/tests/std/array/array_reverse_variation3.phpt b/tests/std/array/array_reverse_variation3.phpt new file mode 100644 index 00000000..78299e68 --- /dev/null +++ b/tests/std/array/array_reverse_variation3.phpt @@ -0,0 +1,605 @@ +--TEST-- +Test array_reverse() function : usage variations - different array values for 'array' argument +--SKIPIF-- + +--FILE-- + "one", 2 => "two", 3 => "three"), + // explicit numeric keys, string values + array("one" => 1, "two" => 2, "three" => 3), + // string keys & numeric values + array(1 => 10, 2 => 20, 4 => 40, 3 => 30), + // explicit numeric keys and numeric values + array("one" => "ten", "two" => "twenty", "three" => "thirty"), + // string key/value + array("one" => 1, 2 => "two", 4 => "four"), + //mixed + // associative array, containing null/empty/boolean values as key/value + /*13*/ + array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + // array with repetitive keys + /*18*/ + array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3), + ); + // loop through the various elements of $arrays to test array_reverse() + $iterator = 1; + foreach ($arrays as $array) { + echo "-- Iteration {$iterator} --\n"; + // with default argument + echo "- with default argument -\n"; + var_dump(array_reverse($array)); + // with all possible arguments + echo "- with \$preserve keys = true -\n"; + var_dump(array_reverse($array, true)); + echo "- with \$preserve_keys = false -\n"; + var_dump(array_reverse($array, false)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_reverse() : usage variations *** +-- Iteration 1 -- +- with default argument - +array(2) { + [0]=> + int(2) + [1]=> + int(1) +} +- with $preserve keys = true - +array(2) { + [1]=> + int(2) + [0]=> + int(1) +} +- with $preserve_keys = false - +array(2) { + [0]=> + int(2) + [1]=> + int(1) +} +-- Iteration 2 -- +- with default argument - +array(2) { + [0]=> + float(2.2) + [1]=> + float(1.1) +} +- with $preserve keys = true - +array(2) { + [1]=> + float(2.2) + [0]=> + float(1.1) +} +- with $preserve_keys = false - +array(2) { + [0]=> + float(2.2) + [1]=> + float(1.1) +} +-- Iteration 3 -- +- with default argument - +array(2) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} +- with $preserve keys = true - +array(2) { + [1]=> + array(1) { + [0]=> + int(1) + } + [0]=> + array(1) { + [0]=> + int(2) + } +} +- with $preserve_keys = false - +array(2) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + array(1) { + [0]=> + int(2) + } +} +-- Iteration 4 -- +- with default argument - +array(2) { + [0]=> + bool(true) + [1]=> + bool(false) +} +- with $preserve keys = true - +array(2) { + [1]=> + bool(true) + [0]=> + bool(false) +} +- with $preserve_keys = false - +array(2) { + [0]=> + bool(true) + [1]=> + bool(false) +} +-- Iteration 5 -- +- with default argument - +array(0) { +} +- with $preserve keys = true - +array(0) { +} +- with $preserve_keys = false - +array(0) { +} +-- Iteration 6 -- +- with default argument - +array(1) { + [0]=> + NULL +} +- with $preserve keys = true - +array(1) { + [0]=> + NULL +} +- with $preserve_keys = false - +array(1) { + [0]=> + NULL +} +-- Iteration 7 -- +- with default argument - +array(6) { + [0]=> + string(5) "ccccc" + [1]=> + string(1) "c" + [2]=> + string(4) "bbbb" + [3]=> + string(1) "b" + [4]=> + string(4) "aaaa" + [5]=> + string(1) "a" +} +- with $preserve keys = true - +array(6) { + [5]=> + string(5) "ccccc" + [4]=> + string(1) "c" + [3]=> + string(4) "bbbb" + [2]=> + string(1) "b" + [1]=> + string(4) "aaaa" + [0]=> + string(1) "a" +} +- with $preserve_keys = false - +array(6) { + [0]=> + string(5) "ccccc" + [1]=> + string(1) "c" + [2]=> + string(4) "bbbb" + [3]=> + string(1) "b" + [4]=> + string(4) "aaaa" + [5]=> + string(1) "a" +} +-- Iteration 8 -- +- with default argument - +array(3) { + [0]=> + string(5) "three" + [1]=> + string(3) "two" + [2]=> + string(3) "one" +} +- with $preserve keys = true - +array(3) { + [3]=> + string(5) "three" + [2]=> + string(3) "two" + [1]=> + string(3) "one" +} +- with $preserve_keys = false - +array(3) { + [0]=> + string(5) "three" + [1]=> + string(3) "two" + [2]=> + string(3) "one" +} +-- Iteration 9 -- +- with default argument - +array(3) { + ["three"]=> + int(3) + ["two"]=> + int(2) + ["one"]=> + int(1) +} +- with $preserve keys = true - +array(3) { + ["three"]=> + int(3) + ["two"]=> + int(2) + ["one"]=> + int(1) +} +- with $preserve_keys = false - +array(3) { + ["three"]=> + int(3) + ["two"]=> + int(2) + ["one"]=> + int(1) +} +-- Iteration 10 -- +- with default argument - +array(4) { + [0]=> + int(30) + [1]=> + int(40) + [2]=> + int(20) + [3]=> + int(10) +} +- with $preserve keys = true - +array(4) { + [3]=> + int(30) + [4]=> + int(40) + [2]=> + int(20) + [1]=> + int(10) +} +- with $preserve_keys = false - +array(4) { + [0]=> + int(30) + [1]=> + int(40) + [2]=> + int(20) + [3]=> + int(10) +} +-- Iteration 11 -- +- with default argument - +array(3) { + ["three"]=> + string(6) "thirty" + ["two"]=> + string(6) "twenty" + ["one"]=> + string(3) "ten" +} +- with $preserve keys = true - +array(3) { + ["three"]=> + string(6) "thirty" + ["two"]=> + string(6) "twenty" + ["one"]=> + string(3) "ten" +} +- with $preserve_keys = false - +array(3) { + ["three"]=> + string(6) "thirty" + ["two"]=> + string(6) "twenty" + ["one"]=> + string(3) "ten" +} +-- Iteration 12 -- +- with default argument - +array(3) { + [0]=> + string(4) "four" + [1]=> + string(3) "two" + ["one"]=> + int(1) +} +- with $preserve keys = true - +array(3) { + [4]=> + string(4) "four" + [2]=> + string(3) "two" + ["one"]=> + int(1) +} +- with $preserve_keys = false - +array(3) { + [0]=> + string(4) "four" + [1]=> + string(3) "two" + ["one"]=> + int(1) +} +-- Iteration 13 -- +- with default argument - +array(3) { + ["null"]=> + NULL + ["NULL"]=> + NULL + [""]=> + string(4) "null" +} +- with $preserve keys = true - +array(3) { + ["null"]=> + NULL + ["NULL"]=> + NULL + [""]=> + string(4) "null" +} +- with $preserve_keys = false - +array(3) { + ["null"]=> + NULL + ["NULL"]=> + NULL + [""]=> + string(4) "null" +} +-- Iteration 14 -- +- with default argument - +array(4) { + ["true"]=> + bool(true) + ["false"]=> + bool(false) + [0]=> + string(5) "false" + [1]=> + string(4) "true" +} +- with $preserve keys = true - +array(4) { + ["true"]=> + bool(true) + ["false"]=> + bool(false) + [0]=> + string(5) "false" + [1]=> + string(4) "true" +} +- with $preserve_keys = false - +array(4) { + ["true"]=> + bool(true) + ["false"]=> + bool(false) + [0]=> + string(5) "false" + [1]=> + string(4) "true" +} +-- Iteration 15 -- +- with default argument - +array(3) { + ["emptys"]=> + string(0) "" + ["emptyd"]=> + string(0) "" + [""]=> + string(6) "emptys" +} +- with $preserve keys = true - +array(3) { + ["emptys"]=> + string(0) "" + ["emptyd"]=> + string(0) "" + [""]=> + string(6) "emptys" +} +- with $preserve_keys = false - +array(3) { + ["emptys"]=> + string(0) "" + ["emptyd"]=> + string(0) "" + [""]=> + string(6) "emptys" +} +-- Iteration 16 -- +- with default argument - +array(6) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + NULL + [3]=> + NULL + [4]=> + string(0) "" + [5]=> + string(0) "" +} +- with $preserve keys = true - +array(6) { + [6]=> + bool(true) + [5]=> + bool(false) + [4]=> + NULL + [3]=> + NULL + [2]=> + string(0) "" + [1]=> + string(0) "" +} +- with $preserve_keys = false - +array(6) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + NULL + [3]=> + NULL + [4]=> + string(0) "" + [5]=> + string(0) "" +} +-- Iteration 17 -- +- with default argument - +array(3) { + [0]=> + int(6) + [1]=> + int(5) + [""]=> + int(4) +} +- with $preserve keys = true - +array(3) { + [1]=> + int(6) + [0]=> + int(5) + [""]=> + int(4) +} +- with $preserve_keys = false - +array(3) { + [0]=> + int(6) + [1]=> + int(5) + [""]=> + int(4) +} +-- Iteration 18 -- +- with default argument - +array(3) { + ["three"]=> + int(3) + ["two"]=> + int(20) + ["One"]=> + int(10) +} +- with $preserve keys = true - +array(3) { + ["three"]=> + int(3) + ["two"]=> + int(20) + ["One"]=> + int(10) +} +- with $preserve_keys = false - +array(3) { + ["three"]=> + int(3) + ["two"]=> + int(20) + ["One"]=> + int(10) +} +Done diff --git a/tests/std/array/array_reverse_variation4.phpt b/tests/std/array/array_reverse_variation4.phpt new file mode 100644 index 00000000..1e367884 --- /dev/null +++ b/tests/std/array/array_reverse_variation4.phpt @@ -0,0 +1,317 @@ +--TEST-- +Test array_reverse() function : usage variations - assoc. array with diff. keys for 'array' argument +--SKIPIF-- + +--FILE-- + "0"), + array(1 => "1"), + array(1 => "1", 2 => "2", 3 => "3", 4 => "4"), + // arrays with string keys + array("\tHello" => 111, "re\td" => "color", "\v\fworld" => 2.2, "pen\n" => 33), + /*8*/ + array("\tHello" => 111, "re\td" => "color", "\v\fworld" => 2.2, "pen\n" => 33), + array("hello", $heredoc => "string"), + // heredoc + // array with object, unset variable and resource variable + array(@$unset_var => "hello", $fp => 'resource'), + // array with mixed values + /*11*/ + array('hello' => 1, "fruit" => 2.2, $fp => 'resource', 133 => "int", @$unset_var => "unset", $heredoc => "heredoc"), + ); + // loop through the various elements of $arrays to test array_reverse() + $iterator = 1; + foreach ($arrays as $array) { + echo "-- Iteration {$iterator} --\n"; + // with default argument + echo "- default argument -\n"; + var_dump(array_reverse($array)); + // with $preserve_keys argument + echo "- \$preserve keys = true -\n"; + var_dump(array_reverse($array, true)); + echo "- \$preserve_keys = false -\n"; + var_dump(array_reverse($array, false)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_reverse() : usage variations *** + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d +-- Iteration 1 -- +- default argument - +array(0) { +} +- $preserve keys = true - +array(0) { +} +- $preserve_keys = false - +array(0) { +} +-- Iteration 2 -- +- default argument - +array(1) { + [0]=> + string(1) "0" +} +- $preserve keys = true - +array(1) { + [0]=> + string(1) "0" +} +- $preserve_keys = false - +array(1) { + [0]=> + string(1) "0" +} +-- Iteration 3 -- +- default argument - +array(1) { + [0]=> + string(1) "1" +} +- $preserve keys = true - +array(1) { + [1]=> + string(1) "1" +} +- $preserve_keys = false - +array(1) { + [0]=> + string(1) "1" +} +-- Iteration 4 -- +- default argument - +array(4) { + [0]=> + string(1) "4" + [1]=> + string(1) "3" + [2]=> + string(1) "2" + [3]=> + string(1) "1" +} +- $preserve keys = true - +array(4) { + [4]=> + string(1) "4" + [3]=> + string(1) "3" + [2]=> + string(1) "2" + [1]=> + string(1) "1" +} +- $preserve_keys = false - +array(4) { + [0]=> + string(1) "4" + [1]=> + string(1) "3" + [2]=> + string(1) "2" + [3]=> + string(1) "1" +} +-- Iteration 5 -- +- default argument - +array(4) { + ["pen +"]=> + int(33) + [" world"]=> + float(2.2) + ["re d"]=> + string(5) "color" + [" Hello"]=> + int(111) +} +- $preserve keys = true - +array(4) { + ["pen +"]=> + int(33) + [" world"]=> + float(2.2) + ["re d"]=> + string(5) "color" + [" Hello"]=> + int(111) +} +- $preserve_keys = false - +array(4) { + ["pen +"]=> + int(33) + [" world"]=> + float(2.2) + ["re d"]=> + string(5) "color" + [" Hello"]=> + int(111) +} +-- Iteration 6 -- +- default argument - +array(4) { + ["pen +"]=> + int(33) + [" world"]=> + float(2.2) + ["re d"]=> + string(5) "color" + [" Hello"]=> + int(111) +} +- $preserve keys = true - +array(4) { + ["pen +"]=> + int(33) + [" world"]=> + float(2.2) + ["re d"]=> + string(5) "color" + [" Hello"]=> + int(111) +} +- $preserve_keys = false - +array(4) { + ["pen +"]=> + int(33) + [" world"]=> + float(2.2) + ["re d"]=> + string(5) "color" + [" Hello"]=> + int(111) +} +-- Iteration 7 -- +- default argument - +array(2) { + ["Hello world"]=> + string(6) "string" + [0]=> + string(5) "hello" +} +- $preserve keys = true - +array(2) { + ["Hello world"]=> + string(6) "string" + [0]=> + string(5) "hello" +} +- $preserve_keys = false - +array(2) { + ["Hello world"]=> + string(6) "string" + [0]=> + string(5) "hello" +} +-- Iteration 8 -- +- default argument - +array(2) { + [0]=> + string(8) "resource" + [""]=> + string(5) "hello" +} +- $preserve keys = true - +array(2) { + [5]=> + string(8) "resource" + [""]=> + string(5) "hello" +} +- $preserve_keys = false - +array(2) { + [0]=> + string(8) "resource" + [""]=> + string(5) "hello" +} +-- Iteration 9 -- +- default argument - +array(6) { + ["Hello world"]=> + string(7) "heredoc" + [""]=> + string(5) "unset" + [0]=> + string(3) "int" + [1]=> + string(8) "resource" + ["fruit"]=> + float(2.2) + ["hello"]=> + int(1) +} +- $preserve keys = true - +array(6) { + ["Hello world"]=> + string(7) "heredoc" + [""]=> + string(5) "unset" + [133]=> + string(3) "int" + [5]=> + string(8) "resource" + ["fruit"]=> + float(2.2) + ["hello"]=> + int(1) +} +- $preserve_keys = false - +array(6) { + ["Hello world"]=> + string(7) "heredoc" + [""]=> + string(5) "unset" + [0]=> + string(3) "int" + [1]=> + string(8) "resource" + ["fruit"]=> + float(2.2) + ["hello"]=> + int(1) +} +Done diff --git a/tests/std/array/array_reverse_variation5.phpt b/tests/std/array/array_reverse_variation5.phpt new file mode 100644 index 00000000..25425e07 --- /dev/null +++ b/tests/std/array/array_reverse_variation5.phpt @@ -0,0 +1,389 @@ +--TEST-- +Test array_reverse() function : usage variations - assoc. array with diff. value for 'array' argument +--INI-- +precision=12 +--SKIPIF-- + +--FILE-- + 0), + array("1" => 1), + array("one" => 1, 'two' => 2, "three" => 3, 4 => 4), + // arrays with float values + /*5*/ + array("float" => 2.3333), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => 33333333.333333), + // arrays with string values + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "pen\n"), + /*8*/ + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => 'pen\n'), + array(1 => "hello", "heredoc" => $heredoc), + // array with object, unset variable and resource variable + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp), + // array with mixed values + /*11*/ + array(1 => 'hello', 2 => new classA(), 222 => "fruit", 'resource' => $fp, "int" => 133, "float" => 444.432, "unset" => @$unset_var, "heredoc" => $heredoc), + ); + // loop through the various elements of $arrays to test array_reverse() + $iterator = 1; + foreach ($arrays as $array) { + echo "-- Iteration {$iterator} --\n"; + // with default argument + echo "- default argument -\n"; + var_dump(array_reverse($array)); + // with $preserve_keys argument + echo "- \$preserve keys = true -\n"; + var_dump(array_reverse($array, true)); + echo "- \$preserve_keys = false -\n"; + var_dump(array_reverse($array, false)); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_reverse() : usage variations *** +-- Iteration 1 -- +- default argument - +array(0) { +} +- $preserve keys = true - +array(0) { +} +- $preserve_keys = false - +array(0) { +} +-- Iteration 2 -- +- default argument - +array(1) { + [0]=> + int(0) +} +- $preserve keys = true - +array(1) { + [0]=> + int(0) +} +- $preserve_keys = false - +array(1) { + [0]=> + int(0) +} +-- Iteration 3 -- +- default argument - +array(1) { + [0]=> + int(1) +} +- $preserve keys = true - +array(1) { + [1]=> + int(1) +} +- $preserve_keys = false - +array(1) { + [0]=> + int(1) +} +-- Iteration 4 -- +- default argument - +array(4) { + [0]=> + int(4) + ["three"]=> + int(3) + ["two"]=> + int(2) + ["one"]=> + int(1) +} +- $preserve keys = true - +array(4) { + [4]=> + int(4) + ["three"]=> + int(3) + ["two"]=> + int(2) + ["one"]=> + int(1) +} +- $preserve_keys = false - +array(4) { + [0]=> + int(4) + ["three"]=> + int(3) + ["two"]=> + int(2) + ["one"]=> + int(1) +} +-- Iteration 5 -- +- default argument - +array(1) { + ["float"]=> + float(2.3333) +} +- $preserve keys = true - +array(1) { + ["float"]=> + float(2.3333) +} +- $preserve_keys = false - +array(1) { + ["float"]=> + float(2.3333) +} +-- Iteration 6 -- +- default argument - +array(4) { + ["f4"]=> + float(33333333.333333) + [0]=> + float(4.89999922839999) + ["f2"]=> + float(3.33) + ["f1"]=> + float(1.2) +} +- $preserve keys = true - +array(4) { + ["f4"]=> + float(33333333.333333) + [3]=> + float(4.89999922839999) + ["f2"]=> + float(3.33) + ["f1"]=> + float(1.2) +} +- $preserve_keys = false - +array(4) { + ["f4"]=> + float(33333333.333333) + [0]=> + float(4.89999922839999) + ["f2"]=> + float(3.33) + ["f1"]=> + float(1.2) +} +-- Iteration 7 -- +- default argument - +array(4) { + [0]=> + string(4) "pen +" + [1]=> + string(7) " world" + ["red"]=> + string(6) "col or" + [2]=> + string(6) " Hello" +} +- $preserve keys = true - +array(4) { + [3]=> + string(4) "pen +" + [2]=> + string(7) " world" + ["red"]=> + string(6) "col or" + [111]=> + string(6) " Hello" +} +- $preserve_keys = false - +array(4) { + [0]=> + string(4) "pen +" + [1]=> + string(7) " world" + ["red"]=> + string(6) "col or" + [2]=> + string(6) " Hello" +} +-- Iteration 8 -- +- default argument - +array(4) { + [0]=> + string(5) "pen\n" + [1]=> + string(9) "\v\fworld" + ["red"]=> + string(7) "col\tor" + [2]=> + string(7) "\tHello" +} +- $preserve keys = true - +array(4) { + [3]=> + string(5) "pen\n" + [2]=> + string(9) "\v\fworld" + ["red"]=> + string(7) "col\tor" + [111]=> + string(7) "\tHello" +} +- $preserve_keys = false - +array(4) { + [0]=> + string(5) "pen\n" + [1]=> + string(9) "\v\fworld" + ["red"]=> + string(7) "col\tor" + [2]=> + string(7) "\tHello" +} +-- Iteration 9 -- +- default argument - +array(2) { + ["heredoc"]=> + string(11) "Hello world" + [0]=> + string(5) "hello" +} +- $preserve keys = true - +array(2) { + ["heredoc"]=> + string(11) "Hello world" + [1]=> + string(5) "hello" +} +- $preserve_keys = false - +array(2) { + ["heredoc"]=> + string(11) "Hello world" + [0]=> + string(5) "hello" +} +-- Iteration 10 -- +- default argument - +array(3) { + ["resource"]=> + resource(%d) of type (stream) + ["unset"]=> + NULL + [0]=> + object(classA)#%d (0) { + } +} +- $preserve keys = true - +array(3) { + ["resource"]=> + resource(%d) of type (stream) + ["unset"]=> + NULL + [11]=> + object(classA)#%d (0) { + } +} +- $preserve_keys = false - +array(3) { + ["resource"]=> + resource(%d) of type (stream) + ["unset"]=> + NULL + [0]=> + object(classA)#%d (0) { + } +} +-- Iteration 11 -- +- default argument - +array(8) { + ["heredoc"]=> + string(11) "Hello world" + ["unset"]=> + NULL + ["float"]=> + float(444.432) + ["int"]=> + int(133) + ["resource"]=> + resource(%d) of type (stream) + [0]=> + string(5) "fruit" + [1]=> + object(classA)#%d (0) { + } + [2]=> + string(5) "hello" +} +- $preserve keys = true - +array(8) { + ["heredoc"]=> + string(11) "Hello world" + ["unset"]=> + NULL + ["float"]=> + float(444.432) + ["int"]=> + int(133) + ["resource"]=> + resource(%d) of type (stream) + [222]=> + string(5) "fruit" + [2]=> + object(classA)#%d (0) { + } + [1]=> + string(5) "hello" +} +- $preserve_keys = false - +array(8) { + ["heredoc"]=> + string(11) "Hello world" + ["unset"]=> + NULL + ["float"]=> + float(444.432) + ["int"]=> + int(133) + ["resource"]=> + resource(%d) of type (stream) + [0]=> + string(5) "fruit" + [1]=> + object(classA)#%d (0) { + } + [2]=> + string(5) "hello" +} +Done diff --git a/tests/std/array/array_reverse_variation6.phpt b/tests/std/array/array_reverse_variation6.phpt new file mode 100644 index 00000000..8ad3451d --- /dev/null +++ b/tests/std/array/array_reverse_variation6.phpt @@ -0,0 +1,204 @@ +--TEST-- +Test array_reverse() function : usage variations - two dimensional arrays for 'array' argument +--FILE-- + 'red', 'item' => 'pen', 'place' => 'LA'), + + // numeric array + array(1, 2, 3, 4, 5), + + // combination of numeric and associative arrays + array('a' => 'green', 'red', 'brown', 33, 88, 'orange', 'item' => 'ball') +); + +// calling array_reverse() with various types of 2-d arrays +// with default arguments +echo "-- with default argument --\n"; +var_dump( array_reverse($two_dimensional_array) ); // whole array +var_dump( array_reverse($two_dimensional_array[1]) ); // sub array + +// with $preserve_keys argument +echo "-- with all possible arguments --\n"; +// whole array +var_dump( array_reverse($two_dimensional_array, true) ); +var_dump( array_reverse($two_dimensional_array, false) ); +// sub array +var_dump( array_reverse($two_dimensional_array[1], true) ); +var_dump( array_reverse($two_dimensional_array[1], false) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_reverse() : usage variations *** +-- with default argument -- +array(3) { + [0]=> + array(7) { + ["a"]=> + string(5) "green" + [0]=> + string(3) "red" + [1]=> + string(5) "brown" + [2]=> + int(33) + [3]=> + int(88) + [4]=> + string(6) "orange" + ["item"]=> + string(4) "ball" + } + [1]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [2]=> + array(3) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + ["place"]=> + string(2) "LA" + } +} +array(5) { + [0]=> + int(5) + [1]=> + int(4) + [2]=> + int(3) + [3]=> + int(2) + [4]=> + int(1) +} +-- with all possible arguments -- +array(3) { + [2]=> + array(7) { + ["a"]=> + string(5) "green" + [0]=> + string(3) "red" + [1]=> + string(5) "brown" + [2]=> + int(33) + [3]=> + int(88) + [4]=> + string(6) "orange" + ["item"]=> + string(4) "ball" + } + [1]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [0]=> + array(3) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + ["place"]=> + string(2) "LA" + } +} +array(3) { + [0]=> + array(7) { + ["a"]=> + string(5) "green" + [0]=> + string(3) "red" + [1]=> + string(5) "brown" + [2]=> + int(33) + [3]=> + int(88) + [4]=> + string(6) "orange" + ["item"]=> + string(4) "ball" + } + [1]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [2]=> + array(3) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + ["place"]=> + string(2) "LA" + } +} +array(5) { + [4]=> + int(5) + [3]=> + int(4) + [2]=> + int(3) + [1]=> + int(2) + [0]=> + int(1) +} +array(5) { + [0]=> + int(5) + [1]=> + int(4) + [2]=> + int(3) + [3]=> + int(2) + [4]=> + int(1) +} +Done diff --git a/tests/std/array/array_search.phpt b/tests/std/array/array_search.phpt new file mode 100644 index 00000000..6219efd3 --- /dev/null +++ b/tests/std/array/array_search.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_search()/in_array() +--FILE-- +'d'); +$arr4 = array("a\0b"=>'e','key'=>'d', 'f'); + +var_dump(in_array(123, $arr2)); +var_dump(in_array(123, $arr1)); +var_dump(array_search(123, $arr1)); +var_dump(in_array('a', $arr1)); +var_dump(array_search('a', $arr1)); +var_dump(array_search('e', $arr4)); +var_dump(array_search('d', $arr4)); + +echo "Done\n"; +?> +--EXPECTF-- +bool(false) +bool(false) +bool(false) +bool(true) +int(0) +string(3) "a%0b" +string(3) "key" +Done diff --git a/tests/std/array/array_search1.phpt b/tests/std/array/array_search1.phpt new file mode 100644 index 00000000..33d9c75d --- /dev/null +++ b/tests/std/array/array_search1.phpt @@ -0,0 +1,28 @@ +--TEST-- +array_search() tests +--FILE-- +0, 2=>1, 4=>3, "a"=>"b", "c"=>"d"); + +var_dump(array_search("a",$a)); +var_dump(array_search("0",$a, true)); +var_dump(array_search("0",$a)); +var_dump(array_search(0,$a)); +var_dump(array_search(1,$a)); +var_dump(array_search("d",$a, true)); +var_dump(array_search("d",$a)); +var_dump(array_search(-1,$a, true)); + +echo "Done\n"; +?> +--EXPECT-- +bool(false) +bool(false) +int(1) +int(1) +int(2) +string(1) "c" +string(1) "c" +bool(false) +Done diff --git a/tests/std/array/array_search_variation1.phpt b/tests/std/array/array_search_variation1.phpt new file mode 100644 index 00000000..a2838810 --- /dev/null +++ b/tests/std/array/array_search_variation1.phpt @@ -0,0 +1,635 @@ +--TEST-- +Test array_search() function : usage variations - different needle values +--FILE-- + "A", 2 => "B", "C" => 3, 4 => 4, "one" => 1, "" => NULL, "b", "ab", "abcd"), + array(4, array(1, 2 => 3), "one" => 1, "5" => 5 ), + array(-1, -2, -3, -4, -2.989888, "-0.005" => "neg0.005", 2 => "float2", "-.9" => -.9), + array(TRUE, FALSE), + array("", array()), + array("abcd\x00abcd\x00abcd"), + array("abcd\tabcd\nabcd\rabcd\0abcdefghij") +); + +$array_compare = array ( + 4, + "4", + 4.00, + "b", + "5", + -2, + -2.0, + -2.98989, + "-.9", + "True", + "", + array(), + NULL, + "ab", + "abcd", + 0.0, + -0, + "abcd\x00abcd\x00abcd" +); +/* loop to check if elements in $array_compare exist in $arrays + using array_search() */ +$counter = 1; +foreach($arrays as $array) { + foreach($array_compare as $compare) { + echo "-- Iteration $counter --\n"; + //strict option OFF + var_dump(array_search($compare,$array)); + //strict option ON + var_dump(array_search($compare,$array,TRUE)); + //strict option OFF + var_dump(array_search($compare,$array,FALSE)); + $counter++; + } +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing array_search() with different needle values *** +-- Iteration 1 -- +bool(false) +bool(false) +bool(false) +-- Iteration 2 -- +bool(false) +bool(false) +bool(false) +-- Iteration 3 -- +bool(false) +bool(false) +bool(false) +-- Iteration 4 -- +bool(false) +bool(false) +bool(false) +-- Iteration 5 -- +bool(false) +bool(false) +bool(false) +-- Iteration 6 -- +bool(false) +bool(false) +bool(false) +-- Iteration 7 -- +bool(false) +bool(false) +bool(false) +-- Iteration 8 -- +bool(false) +bool(false) +bool(false) +-- Iteration 9 -- +bool(false) +bool(false) +bool(false) +-- Iteration 10 -- +bool(false) +bool(false) +bool(false) +-- Iteration 11 -- +bool(false) +bool(false) +bool(false) +-- Iteration 12 -- +bool(false) +bool(false) +bool(false) +-- Iteration 13 -- +int(0) +bool(false) +int(0) +-- Iteration 14 -- +bool(false) +bool(false) +bool(false) +-- Iteration 15 -- +bool(false) +bool(false) +bool(false) +-- Iteration 16 -- +int(0) +bool(false) +int(0) +-- Iteration 17 -- +int(0) +int(0) +int(0) +-- Iteration 18 -- +bool(false) +bool(false) +bool(false) +-- Iteration 19 -- +int(4) +int(4) +int(4) +-- Iteration 20 -- +int(4) +bool(false) +int(4) +-- Iteration 21 -- +int(4) +bool(false) +int(4) +-- Iteration 22 -- +int(5) +int(5) +int(5) +-- Iteration 23 -- +bool(false) +bool(false) +bool(false) +-- Iteration 24 -- +bool(false) +bool(false) +bool(false) +-- Iteration 25 -- +bool(false) +bool(false) +bool(false) +-- Iteration 26 -- +bool(false) +bool(false) +bool(false) +-- Iteration 27 -- +bool(false) +bool(false) +bool(false) +-- Iteration 28 -- +bool(false) +bool(false) +bool(false) +-- Iteration 29 -- +string(0) "" +bool(false) +string(0) "" +-- Iteration 30 -- +string(0) "" +bool(false) +string(0) "" +-- Iteration 31 -- +string(0) "" +string(0) "" +string(0) "" +-- Iteration 32 -- +int(6) +int(6) +int(6) +-- Iteration 33 -- +int(7) +int(7) +int(7) +-- Iteration 34 -- +string(0) "" +bool(false) +string(0) "" +-- Iteration 35 -- +string(0) "" +bool(false) +string(0) "" +-- Iteration 36 -- +bool(false) +bool(false) +bool(false) +-- Iteration 37 -- +int(0) +int(0) +int(0) +-- Iteration 38 -- +int(0) +bool(false) +int(0) +-- Iteration 39 -- +int(0) +bool(false) +int(0) +-- Iteration 40 -- +bool(false) +bool(false) +bool(false) +-- Iteration 41 -- +int(5) +bool(false) +int(5) +-- Iteration 42 -- +bool(false) +bool(false) +bool(false) +-- Iteration 43 -- +bool(false) +bool(false) +bool(false) +-- Iteration 44 -- +bool(false) +bool(false) +bool(false) +-- Iteration 45 -- +bool(false) +bool(false) +bool(false) +-- Iteration 46 -- +bool(false) +bool(false) +bool(false) +-- Iteration 47 -- +bool(false) +bool(false) +bool(false) +-- Iteration 48 -- +bool(false) +bool(false) +bool(false) +-- Iteration 49 -- +bool(false) +bool(false) +bool(false) +-- Iteration 50 -- +bool(false) +bool(false) +bool(false) +-- Iteration 51 -- +bool(false) +bool(false) +bool(false) +-- Iteration 52 -- +bool(false) +bool(false) +bool(false) +-- Iteration 53 -- +bool(false) +bool(false) +bool(false) +-- Iteration 54 -- +bool(false) +bool(false) +bool(false) +-- Iteration 55 -- +bool(false) +bool(false) +bool(false) +-- Iteration 56 -- +bool(false) +bool(false) +bool(false) +-- Iteration 57 -- +bool(false) +bool(false) +bool(false) +-- Iteration 58 -- +bool(false) +bool(false) +bool(false) +-- Iteration 59 -- +bool(false) +bool(false) +bool(false) +-- Iteration 60 -- +int(1) +int(1) +int(1) +-- Iteration 61 -- +int(1) +bool(false) +int(1) +-- Iteration 62 -- +bool(false) +bool(false) +bool(false) +-- Iteration 63 -- +string(3) "-.9" +bool(false) +string(3) "-.9" +-- Iteration 64 -- +bool(false) +bool(false) +bool(false) +-- Iteration 65 -- +bool(false) +bool(false) +bool(false) +-- Iteration 66 -- +bool(false) +bool(false) +bool(false) +-- Iteration 67 -- +bool(false) +bool(false) +bool(false) +-- Iteration 68 -- +bool(false) +bool(false) +bool(false) +-- Iteration 69 -- +bool(false) +bool(false) +bool(false) +-- Iteration 70 -- +bool(false) +bool(false) +bool(false) +-- Iteration 71 -- +bool(false) +bool(false) +bool(false) +-- Iteration 72 -- +bool(false) +bool(false) +bool(false) +-- Iteration 73 -- +int(0) +bool(false) +int(0) +-- Iteration 74 -- +int(0) +bool(false) +int(0) +-- Iteration 75 -- +int(0) +bool(false) +int(0) +-- Iteration 76 -- +int(0) +bool(false) +int(0) +-- Iteration 77 -- +int(0) +bool(false) +int(0) +-- Iteration 78 -- +int(0) +bool(false) +int(0) +-- Iteration 79 -- +int(0) +bool(false) +int(0) +-- Iteration 80 -- +int(0) +bool(false) +int(0) +-- Iteration 81 -- +int(0) +bool(false) +int(0) +-- Iteration 82 -- +int(0) +bool(false) +int(0) +-- Iteration 83 -- +int(1) +bool(false) +int(1) +-- Iteration 84 -- +int(1) +bool(false) +int(1) +-- Iteration 85 -- +int(1) +bool(false) +int(1) +-- Iteration 86 -- +int(0) +bool(false) +int(0) +-- Iteration 87 -- +int(0) +bool(false) +int(0) +-- Iteration 88 -- +int(1) +bool(false) +int(1) +-- Iteration 89 -- +int(1) +bool(false) +int(1) +-- Iteration 90 -- +int(0) +bool(false) +int(0) +-- Iteration 91 -- +bool(false) +bool(false) +bool(false) +-- Iteration 92 -- +bool(false) +bool(false) +bool(false) +-- Iteration 93 -- +bool(false) +bool(false) +bool(false) +-- Iteration 94 -- +bool(false) +bool(false) +bool(false) +-- Iteration 95 -- +bool(false) +bool(false) +bool(false) +-- Iteration 96 -- +bool(false) +bool(false) +bool(false) +-- Iteration 97 -- +bool(false) +bool(false) +bool(false) +-- Iteration 98 -- +bool(false) +bool(false) +bool(false) +-- Iteration 99 -- +bool(false) +bool(false) +bool(false) +-- Iteration 100 -- +bool(false) +bool(false) +bool(false) +-- Iteration 101 -- +int(0) +int(0) +int(0) +-- Iteration 102 -- +int(1) +int(1) +int(1) +-- Iteration 103 -- +int(0) +bool(false) +int(0) +-- Iteration 104 -- +bool(false) +bool(false) +bool(false) +-- Iteration 105 -- +bool(false) +bool(false) +bool(false) +-- Iteration 106 -- +bool(false) +bool(false) +bool(false) +-- Iteration 107 -- +bool(false) +bool(false) +bool(false) +-- Iteration 108 -- +bool(false) +bool(false) +bool(false) +-- Iteration 109 -- +bool(false) +bool(false) +bool(false) +-- Iteration 110 -- +bool(false) +bool(false) +bool(false) +-- Iteration 111 -- +bool(false) +bool(false) +bool(false) +-- Iteration 112 -- +bool(false) +bool(false) +bool(false) +-- Iteration 113 -- +bool(false) +bool(false) +bool(false) +-- Iteration 114 -- +bool(false) +bool(false) +bool(false) +-- Iteration 115 -- +bool(false) +bool(false) +bool(false) +-- Iteration 116 -- +bool(false) +bool(false) +bool(false) +-- Iteration 117 -- +bool(false) +bool(false) +bool(false) +-- Iteration 118 -- +bool(false) +bool(false) +bool(false) +-- Iteration 119 -- +bool(false) +bool(false) +bool(false) +-- Iteration 120 -- +bool(false) +bool(false) +bool(false) +-- Iteration 121 -- +bool(false) +bool(false) +bool(false) +-- Iteration 122 -- +bool(false) +bool(false) +bool(false) +-- Iteration 123 -- +bool(false) +bool(false) +bool(false) +-- Iteration 124 -- +bool(false) +bool(false) +bool(false) +-- Iteration 125 -- +bool(false) +bool(false) +bool(false) +-- Iteration 126 -- +int(0) +int(0) +int(0) +-- Iteration 127 -- +bool(false) +bool(false) +bool(false) +-- Iteration 128 -- +bool(false) +bool(false) +bool(false) +-- Iteration 129 -- +bool(false) +bool(false) +bool(false) +-- Iteration 130 -- +bool(false) +bool(false) +bool(false) +-- Iteration 131 -- +bool(false) +bool(false) +bool(false) +-- Iteration 132 -- +bool(false) +bool(false) +bool(false) +-- Iteration 133 -- +bool(false) +bool(false) +bool(false) +-- Iteration 134 -- +bool(false) +bool(false) +bool(false) +-- Iteration 135 -- +bool(false) +bool(false) +bool(false) +-- Iteration 136 -- +bool(false) +bool(false) +bool(false) +-- Iteration 137 -- +bool(false) +bool(false) +bool(false) +-- Iteration 138 -- +bool(false) +bool(false) +bool(false) +-- Iteration 139 -- +bool(false) +bool(false) +bool(false) +-- Iteration 140 -- +bool(false) +bool(false) +bool(false) +-- Iteration 141 -- +bool(false) +bool(false) +bool(false) +-- Iteration 142 -- +bool(false) +bool(false) +bool(false) +-- Iteration 143 -- +bool(false) +bool(false) +bool(false) +-- Iteration 144 -- +bool(false) +bool(false) +bool(false) +Done diff --git a/tests/std/array/array_search_variation2.phpt b/tests/std/array/array_search_variation2.phpt new file mode 100644 index 00000000..83c3a925 --- /dev/null +++ b/tests/std/array/array_search_variation2.phpt @@ -0,0 +1,98 @@ +--TEST-- +Test array_search() function : usage variations - different haystack values +--SKIPIF-- + +--FILE-- +'d', + 3, + ".001" =>-67, + "-.051" =>"k", + 0 =>"-.08", + "e" =>"5", + "y" =>NULL, + NULL =>"", + 0, + TRUE, + FALSE, + -27.39999999999, + " ", + "abcd\x00abcd\x00\abcd\x00abcdefghij", + "abcd\nabcd\tabcd\rabcd\0abcd" +); +$array_type = array(TRUE, FALSE, 1, 0, -1, "1", "0", "-1", NULL, array(), "PHP", ""); +/* loop to do loose and strict type check of elements in + $array_type on elements in $misc_array using array_search(); + checking PHP type comparison tables +*/ +$counter = 1; +foreach($array_type as $type) { + echo "-- Iteration $counter --\n"; + //loose type checking + var_dump( array_search($type,$misc_array ) ); + //strict type checking + var_dump( array_search($type,$misc_array,true) ); + //loose type checking + var_dump( array_search($type,$misc_array,false) ); + $counter++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing array_search() with different haystack values *** +-- Iteration 1 -- +int(0) +int(3) +int(0) +-- Iteration 2 -- +string(1) "y" +int(4) +string(1) "y" +-- Iteration 3 -- +int(3) +bool(false) +int(3) +-- Iteration 4 -- +string(1) "y" +int(2) +string(1) "y" +-- Iteration 5 -- +int(3) +bool(false) +int(3) +-- Iteration 6 -- +int(3) +bool(false) +int(3) +-- Iteration 7 -- +int(2) +bool(false) +int(2) +-- Iteration 8 -- +int(3) +bool(false) +int(3) +-- Iteration 9 -- +string(1) "y" +string(1) "y" +string(1) "y" +-- Iteration 10 -- +string(1) "y" +bool(false) +string(1) "y" +-- Iteration 11 -- +int(3) +bool(false) +int(3) +-- Iteration 12 -- +string(1) "y" +string(0) "" +string(1) "y" +Done diff --git a/tests/std/array/array_search_variation3.phpt b/tests/std/array/array_search_variation3.phpt new file mode 100644 index 00000000..674e9916 --- /dev/null +++ b/tests/std/array/array_search_variation3.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_search() function : usage variations - haystack as sub-array/object +--SKIPIF-- + +--FILE-- + "one", "two" => 2, 3 => 3); + public function foo() + { + echo "Public function\n"; + } +} +function main() +{ + /* checking for sub-arrays with array_search() */ + echo "*** Testing sub-arrays with array_search() ***\n"; + $sub_array = array("one", array(1, 2 => "two", "three" => 3), 4 => "four", "five" => 5, array('', 'i')); + var_dump(array_search("four", $sub_array)); + //checking for element in a sub-array + var_dump(array_search(3, $sub_array[1])); + var_dump(array_search(array('', 'i'), $sub_array)); + /* checking for objects in array_search() */ + echo "\n*** Testing objects with array_search() ***\n"; + $array_search_obj = new array_search_check(); + //creating new object + //error: as wrong datatype for second argument + try { + var_dump(array_search("array_var", $array_search_obj)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + //error: as wrong datatype for second argument + try { + var_dump(array_search("foo", $array_search_obj)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + //element found as "one" exists in array $array_var + var_dump(array_search("one", $array_search_obj->array_var)); + echo "Done\n"; +} +?> +--EXPECT-- +*** Testing sub-arrays with array_search() *** +int(4) +string(5) "three" +int(5) + +*** Testing objects with array_search() *** +array_search(): Argument #2 ($haystack) must be of type array, array_search_check given +array_search(): Argument #2 ($haystack) must be of type array, array_search_check given +int(1) +Done diff --git a/tests/std/array/array_search_variation4.phpt b/tests/std/array/array_search_variation4.phpt new file mode 100644 index 00000000..fa5cdf62 --- /dev/null +++ b/tests/std/array/array_search_variation4.phpt @@ -0,0 +1,68 @@ +--TEST-- +Test array_search() function : usage variations - haystack as resource/multi dimensional array +--FILE-- + TRUE, "b"=> TRUE, + array("c"=> TRUE, "d"=>TRUE) + ) + ) + ); + +//matching string having integer in beginning, result:true in loose type check +var_dump( array_search('123abc', array(123)) ); +var_dump( array_search('123abc', array(123), TRUE) ); // false in strict mode + +echo "Done\n"; +?> +--EXPECT-- +*** Testing resource type with array_search() *** +int(0) +bool(false) + +*** Testing miscelleneos inputs with array_search() *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +Done diff --git a/tests/std/array/array_shift_basic.phpt b/tests/std/array/array_shift_basic.phpt new file mode 100644 index 00000000..ad0d70ea --- /dev/null +++ b/tests/std/array/array_shift_basic.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test array_shift() function : basic functionality +--FILE-- + 'three', 'four' => 4); +echo "\n-- Before shift: --\n"; +var_dump($array); + +echo "\n-- After shift: --\n"; +echo "Returned value:\t"; +var_dump(array_shift($array)); +echo "New array:\n"; +var_dump($array); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_shift() : basic functionality *** + +-- Before shift: -- +array(4) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [3]=> + string(5) "three" + ["four"]=> + int(4) +} + +-- After shift: -- +Returned value: string(4) "zero" +New array: +array(3) { + [0]=> + string(3) "one" + [1]=> + string(5) "three" + ["four"]=> + int(4) +} +Done diff --git a/tests/std/array/array_shift_variation2.phpt b/tests/std/array/array_shift_variation2.phpt new file mode 100644 index 00000000..0ab7708b --- /dev/null +++ b/tests/std/array/array_shift_variation2.phpt @@ -0,0 +1,165 @@ +--TEST-- +Test array_shift() function : usage variations - Pass arrays of different data types +--SKIPIF-- + + +--FILE-- + array(0, 1, 12345, -2345), + // float data + /*2*/ + 'float' => array(10.5, -10.5, 123456789000.0, 1.23456789E-9, 0.5), + // null data + /*3*/ + 'null' => array(NULL, null), + // boolean data + /*4*/ + 'bool' => array(true, false, TRUE, FALSE), + // empty data + /*5*/ + 'empty string' => array("", ''), + /*6*/ + 'empty array' => array(), + // string data + /*7*/ + 'string' => array("string", 'string', $heredoc), + // object data + /*8*/ + 'object' => array(new classA()), + // undefined data + /*9*/ + 'undefined' => array(@$undefined_var), + // unset data + /*10*/ + 'unset' => array(@$unset_var), + // resource variable + /*11*/ + 'resource' => array($fp), + ); + // loop through each element of $inputs to check the behavior of array_shift + $iterator = 1; + foreach ($inputs as $key => $input) { + echo "\n-- Iteration {$iterator}: {$key} data --\n"; + var_dump(array_shift($input)); + var_dump($input); + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_shift() : usage variations *** + +-- Iteration 1: int data -- +int(0) +array(3) { + [0]=> + int(1) + [1]=> + int(12345) + [2]=> + int(-2345) +} + +-- Iteration 2: float data -- +float(10.5) +array(4) { + [0]=> + float(-10.5) + [1]=> + float(123456789000) + [2]=> + float(1.23456789E-9) + [3]=> + float(0.5) +} + +-- Iteration 3: null data -- +NULL +array(1) { + [0]=> + NULL +} + +-- Iteration 4: bool data -- +bool(true) +array(3) { + [0]=> + bool(false) + [1]=> + bool(true) + [2]=> + bool(false) +} + +-- Iteration 5: empty string data -- +string(0) "" +array(1) { + [0]=> + string(0) "" +} + +-- Iteration 6: empty array data -- +NULL +array(0) { +} + +-- Iteration 7: string data -- +string(6) "string" +array(2) { + [0]=> + string(6) "string" + [1]=> + string(11) "hello world" +} + +-- Iteration 8: object data -- +object(classA)#%d (0) { +} +array(0) { +} + +-- Iteration 9: undefined data -- +NULL +array(0) { +} + +-- Iteration 10: unset data -- +NULL +array(0) { +} + +-- Iteration 11: resource data -- +resource(%d) of type (stream) +array(0) { +} +Done diff --git a/tests/std/array/array_shift_variation3.phpt b/tests/std/array/array_shift_variation3.phpt new file mode 100644 index 00000000..a33626b8 --- /dev/null +++ b/tests/std/array/array_shift_variation3.phpt @@ -0,0 +1,160 @@ +--TEST-- +Test array_shift() function : usage variations - Pass array with different data types as keys +--SKIPIF-- + + +--FILE-- + array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative', + ), + + // null data +/*4*/ 'null uppercase' => array( + NULL => 'null 1', + ), + +/*5*/ 'null lowercase' => array( + null => 'null 2', + ), + + // boolean data +/*6*/ 'bool lowercase' => array( + true => 'lowert', + false => 'lowerf', + ), + +/*7*/ 'bool uppercase' => array( + TRUE => 'uppert', + FALSE => 'upperf', + ), + + // empty data +/*8*/ 'empty double quotes' => array( + "" => 'emptyd', + ), + +/*9*/ 'empty single quotes' => array( + '' => 'emptys', + ), + + // string data +/*10*/ 'string' => array( + "stringd" => 'stringd', + 'strings' => 'strings', + $heredoc => 'stringh', + ), + + // undefined data +/*11*/ 'undefined' => array( + @$undefined_var => 'undefined', + ), + + // unset data +/*12*/ 'unset' => array( + @$unset_var => 'unset', + ), +); + +// loop through each element of $inputs to check the behavior of array_shift() +$iterator = 1; +foreach($inputs as $key => $input) { + echo "\n-- Iteration $iterator : $key data --\n"; + var_dump( array_shift($input) ); + var_dump($input); + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_shift() : usage variations *** + +-- Iteration 1 : int data -- +string(4) "zero" +array(3) { + [0]=> + string(3) "one" + [1]=> + string(8) "positive" + [2]=> + string(8) "negative" +} + +-- Iteration 2 : null uppercase data -- +string(6) "null 1" +array(0) { +} + +-- Iteration 3 : null lowercase data -- +string(6) "null 2" +array(0) { +} + +-- Iteration 4 : bool lowercase data -- +string(6) "lowert" +array(1) { + [0]=> + string(6) "lowerf" +} + +-- Iteration 5 : bool uppercase data -- +string(6) "uppert" +array(1) { + [0]=> + string(6) "upperf" +} + +-- Iteration 6 : empty double quotes data -- +string(6) "emptyd" +array(0) { +} + +-- Iteration 7 : empty single quotes data -- +string(6) "emptys" +array(0) { +} + +-- Iteration 8 : string data -- +string(7) "stringd" +array(2) { + ["strings"]=> + string(7) "strings" + ["hello world"]=> + string(7) "stringh" +} + +-- Iteration 9 : undefined data -- +string(9) "undefined" +array(0) { +} + +-- Iteration 10 : unset data -- +string(5) "unset" +array(0) { +} +Done diff --git a/tests/std/array/array_shift_variation4.phpt b/tests/std/array/array_shift_variation4.phpt new file mode 100644 index 00000000..34c15055 --- /dev/null +++ b/tests/std/array/array_shift_variation4.phpt @@ -0,0 +1,104 @@ +--TEST-- +Test array_shift() function : usage variations - multi-dimensional arrays +--FILE-- + +--EXPECT-- +*** Testing array_shift() : usage variations *** + +-- Before shift: -- +---- $stack_first: +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} +---- $stack_last: +array(3) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} + +-- After shift: -- +---- Pop array from array: +Returned value: array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +New array: +array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" +} +---- Pop element from array within array: +Returned value: int(1) +New array: +array(3) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + array(2) { + [0]=> + int(2) + [1]=> + int(3) + } +} +Done diff --git a/tests/std/array/array_shift_variation5.phpt b/tests/std/array/array_shift_variation5.phpt new file mode 100644 index 00000000..0ba29b62 --- /dev/null +++ b/tests/std/array/array_shift_variation5.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test array_shift() function : usage variations - call recursively +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing array_shift() : usage variations *** + +-- Incorrect Method: -- + +Notice: Only variables should be passed by reference in %s on line %d + +Notice: Only variables should be passed by reference in %s on line %d +string(4) "zero" + +-- Correct Method: -- +string(4) "zero" +Done diff --git a/tests/std/array/array_shift_variation6.phpt b/tests/std/array/array_shift_variation6.phpt new file mode 100644 index 00000000..1f554887 --- /dev/null +++ b/tests/std/array/array_shift_variation6.phpt @@ -0,0 +1,80 @@ +--TEST-- +Test array_shift() function : usage variations - Referenced arrays +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_shift() : usage variations *** + +-- Variable is referenced array -- +Result: string(4) "zero" + +$original_array: +array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" +} + +$copied_array: +array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" +} + +-- Element is referenced array -- +Result: string(3) "one" + +$new_array: +array(3) { + [0]=> + &array(1) { + [0]=> + string(3) "two" + } + [1]=> + int(1) + [2]=> + string(3) "two" +} + +$copied_array +array(1) { + [0]=> + string(3) "two" +} +Done diff --git a/tests/std/array/array_shift_variation7.phpt b/tests/std/array/array_shift_variation7.phpt new file mode 100644 index 00000000..257047be --- /dev/null +++ b/tests/std/array/array_shift_variation7.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_shift() function : usage variations - position of internal pointer +--FILE-- + 'un', 'two' => 'deux'); + +echo "\n-- Call array_shift() --\n"; +var_dump($result = array_shift($stack)); + +echo "\n-- Position of Internal Pointer in Passed Array: --\n"; +echo key($stack) . " => " . current ($stack) . "\n"; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_shift() : usage variations *** + +-- Call array_shift() -- +string(2) "un" + +-- Position of Internal Pointer in Passed Array: -- +two => deux +Done diff --git a/tests/std/array/array_shift_variation8.phpt b/tests/std/array/array_shift_variation8.phpt new file mode 100644 index 00000000..16bcecc1 --- /dev/null +++ b/tests/std/array/array_shift_variation8.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test array_shift() function : usage variations - maintaining referenced elements +--SKIPIF-- + + +--FILE-- + +--EXPECTF-- +*** Testing array_shift() : usage variations *** + +-- Reference result of array_shift: -- + +Notice: Only variables should be assigned by reference in %s on line %d +a = 1, b = 2 + +-- Reference first element before array_shift: -- +a = 2, b = 2 +Done diff --git a/tests/std/array/array_shuffle_basic.phpt b/tests/std/array/array_shuffle_basic.phpt new file mode 100644 index 00000000..65d2f11d --- /dev/null +++ b/tests/std/array/array_shuffle_basic.phpt @@ -0,0 +1,98 @@ +--TEST-- +array_shuffle(): Test return type and value for expected input +--FILE-- + 1); +var_dump(shuffle($a)); +var_dump($a); +$a = array("a" => 1); +var_dump(shuffle($a)); +var_dump($a); +$a = array(array(1, 2, 3)); +var_dump(shuffle($a)); +var_dump($a); +$a = array(1, 1, 1, 1); +var_dump(shuffle($a)); +var_dump($a); +$arr1 = array(5 => 1, 6 => 2, 7 => 3, 8 => 9); +$arr2 = array(5 => 1, 6 => 2, 7 => 3, 8 => 9); +shuffle($arr1); +echo "this should be 0->...." . count(array_diff($arr1, $arr2)) . "\n"; +echo "this should be 4->...." . count(array_intersect($arr1, $arr2)) . "\n"; +$bigarray = range(1, 400); +shuffle($bigarray); +echo "this should be 400->...." . count($bigarray) . "\n"; +echo "*** testing pass by reference \n"; +$original = $bigarray; +shuffle($bigarray); +$diffarray = array_diff_assoc($original, $bigarray); +if (count($diffarray) < 350) { + // with 400 entries, the probability that 50 entries or more get the same + // key-> value association should be so close to zero it wont happen in the lifetime of the + // universe. + echo "shuffled array seems to be similar to original\n"; + var_dump($original); + var_dump($bigarray); +} else { + echo "test passed \n"; +} +?> +--EXPECT-- +*** testing array_shuffle +bool(true) +array(0) { +} +bool(true) +array(1) { + [0]=> + int(1) +} +bool(true) +array(1) { + [0]=> + int(1) +} +bool(true) +array(1) { + [0]=> + int(1) +} +bool(true) +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} +bool(true) +array(4) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(1) + [3]=> + int(1) +} +this should be 0->....0 +this should be 4->....4 +this should be 400->....400 +*** testing pass by reference +test passed diff --git a/tests/std/array/array_slice.phpt b/tests/std/array/array_slice.phpt new file mode 100644 index 00000000..f12f6d62 --- /dev/null +++ b/tests/std/array/array_slice.phpt @@ -0,0 +1,1419 @@ +--TEST-- +Testing array_slice() function +--FILE-- + "aaa", "A" => "AAA", "c" => "ccc", "d" => "ddd", "e" => "eee"), + array("1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five"), + array(1 => "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five"), + array("f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five"), + array(12, "name", 'age', '45'), + array( array("oNe", "tWo", 4), array(10, 20, 30, 40, 50), array()) + ); + +$num = 4; +$str = "john"; + +$counter = 1; +foreach ($var_array as $sub_array) +{ + /* variations with two arguments */ + /* offset values >, < and = 0 */ + + echo"\n*** Iteration ".$counter." ***\n"; + echo"\n*** Variation with first two Arguments ***\n"; + var_dump ( array_slice($sub_array, 1) ); + var_dump ( array_slice($sub_array, 0) ); + var_dump ( array_slice($sub_array, -2) ); + + /* variations with three arguments */ + /* offset value variations with length values */ + echo"\n*** Variation with first three Arguments ***\n"; + var_dump ( array_slice($sub_array, 1, 3) ); + var_dump ( array_slice($sub_array, 1, 0) ); + var_dump ( array_slice($sub_array, 1, -3) ); + var_dump ( array_slice($sub_array, 0, 3) ); + var_dump ( array_slice($sub_array, 0, 0) ); + var_dump ( array_slice($sub_array, 0, -3) ); + var_dump ( array_slice($sub_array, -2, 3) ); + var_dump ( array_slice($sub_array, -2, 0 ) ); + var_dump ( array_slice($sub_array, -2, -3) ); + + /* variations with four arguments */ + /* offset value, length value and preserve_key values variation */ + echo"\n*** Variation with first two arguments with preserve_key value TRUE ***\n"; + var_dump ( array_slice($sub_array, 1, 3, true) ); + var_dump ( array_slice($sub_array, 1, 0, true) ); + var_dump ( array_slice($sub_array, 1, -3, true) ); + var_dump ( array_slice($sub_array, 0, 3, true) ); + var_dump ( array_slice($sub_array, 0, 0, true) ); + var_dump ( array_slice($sub_array, 0, -3, true) ); + var_dump ( array_slice($sub_array, -2, 3, true) ); + var_dump ( array_slice($sub_array, -2, 0, true) ); + var_dump ( array_slice($sub_array, -2, -3, true) ); + $counter++; +} + + /* variation of offset and length to point to same element */ + echo"\n*** Typical Variation of offset and length Arguments ***\n"; + var_dump (array_slice($var_array[2], 1, -3, true) ); + var_dump (array_slice($var_array[2], 1, -3, false) ); + var_dump (array_slice($var_array[2], -3, -2, true) ); + var_dump (array_slice($var_array[2], -3, -2, false) ); + +?> +--EXPECT-- +*** Iteration 1 *** + +*** Variation with first two Arguments *** +array(0) { +} +array(0) { +} +array(0) { +} + +*** Variation with first three Arguments *** +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} + +*** Iteration 2 *** + +*** Variation with first two Arguments *** +array(8) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) + [4]=> + int(6) + [5]=> + int(7) + [6]=> + int(8) + [7]=> + int(9) +} +array(9) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) +} +array(2) { + [0]=> + int(8) + [1]=> + int(9) +} + +*** Variation with first three Arguments *** +array(3) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) +} +array(0) { +} +array(5) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) + [4]=> + int(6) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(0) { +} +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) +} +array(2) { + [0]=> + int(8) + [1]=> + int(9) +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(3) { + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) +} +array(0) { +} +array(5) { + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(0) { +} +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) +} +array(2) { + [7]=> + int(8) + [8]=> + int(9) +} +array(0) { +} +array(0) { +} + +*** Iteration 3 *** + +*** Variation with first two Arguments *** +array(4) { + [0]=> + string(3) "Two" + [1]=> + string(5) "Three" + [2]=> + string(4) "Four" + [3]=> + string(4) "Five" +} +array(5) { + [0]=> + string(3) "One" + [1]=> + string(3) "Two" + [2]=> + string(5) "Three" + [3]=> + string(4) "Four" + [4]=> + string(4) "Five" +} +array(2) { + [0]=> + string(4) "Four" + [1]=> + string(4) "Five" +} + +*** Variation with first three Arguments *** +array(3) { + [0]=> + string(3) "Two" + [1]=> + string(5) "Three" + [2]=> + string(4) "Four" +} +array(0) { +} +array(1) { + [0]=> + string(3) "Two" +} +array(3) { + [0]=> + string(3) "One" + [1]=> + string(3) "Two" + [2]=> + string(5) "Three" +} +array(0) { +} +array(2) { + [0]=> + string(3) "One" + [1]=> + string(3) "Two" +} +array(2) { + [0]=> + string(4) "Four" + [1]=> + string(4) "Five" +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(3) { + [1]=> + string(3) "Two" + [2]=> + string(5) "Three" + [3]=> + string(4) "Four" +} +array(0) { +} +array(1) { + [1]=> + string(3) "Two" +} +array(3) { + [0]=> + string(3) "One" + [1]=> + string(3) "Two" + [2]=> + string(5) "Three" +} +array(0) { +} +array(2) { + [0]=> + string(3) "One" + [1]=> + string(3) "Two" +} +array(2) { + [3]=> + string(4) "Four" + [4]=> + string(4) "Five" +} +array(0) { +} +array(0) { +} + +*** Iteration 4 *** + +*** Variation with first two Arguments *** +array(7) { + [0]=> + string(3) "six" + [1]=> + int(7) + [2]=> + string(5) "seven" + [3]=> + int(8) + [4]=> + string(5) "eight" + [5]=> + int(9) + [6]=> + string(4) "nine" +} +array(8) { + [0]=> + int(6) + [1]=> + string(3) "six" + [2]=> + int(7) + [3]=> + string(5) "seven" + [4]=> + int(8) + [5]=> + string(5) "eight" + [6]=> + int(9) + [7]=> + string(4) "nine" +} +array(2) { + [0]=> + int(9) + [1]=> + string(4) "nine" +} + +*** Variation with first three Arguments *** +array(3) { + [0]=> + string(3) "six" + [1]=> + int(7) + [2]=> + string(5) "seven" +} +array(0) { +} +array(4) { + [0]=> + string(3) "six" + [1]=> + int(7) + [2]=> + string(5) "seven" + [3]=> + int(8) +} +array(3) { + [0]=> + int(6) + [1]=> + string(3) "six" + [2]=> + int(7) +} +array(0) { +} +array(5) { + [0]=> + int(6) + [1]=> + string(3) "six" + [2]=> + int(7) + [3]=> + string(5) "seven" + [4]=> + int(8) +} +array(2) { + [0]=> + int(9) + [1]=> + string(4) "nine" +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(3) { + [1]=> + string(3) "six" + [2]=> + int(7) + [3]=> + string(5) "seven" +} +array(0) { +} +array(4) { + [1]=> + string(3) "six" + [2]=> + int(7) + [3]=> + string(5) "seven" + [4]=> + int(8) +} +array(3) { + [0]=> + int(6) + [1]=> + string(3) "six" + [2]=> + int(7) +} +array(0) { +} +array(5) { + [0]=> + int(6) + [1]=> + string(3) "six" + [2]=> + int(7) + [3]=> + string(5) "seven" + [4]=> + int(8) +} +array(2) { + [6]=> + int(9) + [7]=> + string(4) "nine" +} +array(0) { +} +array(0) { +} + +*** Iteration 5 *** + +*** Variation with first two Arguments *** +array(4) { + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" + ["d"]=> + string(3) "ddd" + ["e"]=> + string(3) "eee" +} +array(5) { + ["a"]=> + string(3) "aaa" + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" + ["d"]=> + string(3) "ddd" + ["e"]=> + string(3) "eee" +} +array(2) { + ["d"]=> + string(3) "ddd" + ["e"]=> + string(3) "eee" +} + +*** Variation with first three Arguments *** +array(3) { + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" + ["d"]=> + string(3) "ddd" +} +array(0) { +} +array(1) { + ["A"]=> + string(3) "AAA" +} +array(3) { + ["a"]=> + string(3) "aaa" + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" +} +array(0) { +} +array(2) { + ["a"]=> + string(3) "aaa" + ["A"]=> + string(3) "AAA" +} +array(2) { + ["d"]=> + string(3) "ddd" + ["e"]=> + string(3) "eee" +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(3) { + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" + ["d"]=> + string(3) "ddd" +} +array(0) { +} +array(1) { + ["A"]=> + string(3) "AAA" +} +array(3) { + ["a"]=> + string(3) "aaa" + ["A"]=> + string(3) "AAA" + ["c"]=> + string(3) "ccc" +} +array(0) { +} +array(2) { + ["a"]=> + string(3) "aaa" + ["A"]=> + string(3) "AAA" +} +array(2) { + ["d"]=> + string(3) "ddd" + ["e"]=> + string(3) "eee" +} +array(0) { +} +array(0) { +} + +*** Iteration 6 *** + +*** Variation with first two Arguments *** +array(4) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "four" + [3]=> + string(4) "five" +} +array(5) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + [2]=> + string(5) "three" + [3]=> + string(4) "four" + [4]=> + string(4) "five" +} +array(2) { + [0]=> + string(4) "four" + [1]=> + string(4) "five" +} + +*** Variation with first three Arguments *** +array(3) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "four" +} +array(0) { +} +array(1) { + [0]=> + string(3) "two" +} +array(3) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + [2]=> + string(5) "three" +} +array(0) { +} +array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" +} +array(2) { + [0]=> + string(4) "four" + [1]=> + string(4) "five" +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(3) { + [2]=> + string(3) "two" + [3]=> + string(5) "three" + [4]=> + string(4) "four" +} +array(0) { +} +array(1) { + [2]=> + string(3) "two" +} +array(3) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" +} +array(0) { +} +array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} +array(2) { + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} +array(0) { +} +array(0) { +} + +*** Iteration 7 *** + +*** Variation with first two Arguments *** +array(4) { + [0]=> + string(3) "two" + [1]=> + int(7) + [2]=> + string(4) "four" + [3]=> + string(4) "five" +} +array(5) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + [2]=> + int(7) + [3]=> + string(4) "four" + [4]=> + string(4) "five" +} +array(2) { + [0]=> + string(4) "four" + [1]=> + string(4) "five" +} + +*** Variation with first three Arguments *** +array(3) { + [0]=> + string(3) "two" + [1]=> + int(7) + [2]=> + string(4) "four" +} +array(0) { +} +array(1) { + [0]=> + string(3) "two" +} +array(3) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + [2]=> + int(7) +} +array(0) { +} +array(2) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" +} +array(2) { + [0]=> + string(4) "four" + [1]=> + string(4) "five" +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(3) { + [2]=> + string(3) "two" + [3]=> + int(7) + [4]=> + string(4) "four" +} +array(0) { +} +array(1) { + [2]=> + string(3) "two" +} +array(3) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + int(7) +} +array(0) { +} +array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} +array(2) { + [4]=> + string(4) "four" + [5]=> + string(4) "five" +} +array(0) { +} +array(0) { +} + +*** Iteration 8 *** + +*** Variation with first two Arguments *** +array(9) { + [0]=> + string(3) "one" + [1]=> + int(6) + [""]=> + string(5) "blank" + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" + [3]=> + float(3.7) + [4]=> + string(4) "Five" + [5]=> + float(8.6) +} +array(10) { + ["f"]=> + string(3) "fff" + [0]=> + string(3) "one" + [1]=> + int(6) + [""]=> + string(5) "blank" + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" + [3]=> + float(3.7) + [4]=> + string(4) "Five" + [5]=> + float(8.6) +} +array(2) { + [0]=> + string(4) "Five" + [1]=> + float(8.6) +} + +*** Variation with first three Arguments *** +array(3) { + [0]=> + string(3) "one" + [1]=> + int(6) + [""]=> + string(5) "blank" +} +array(0) { +} +array(6) { + [0]=> + string(3) "one" + [1]=> + int(6) + [""]=> + string(5) "blank" + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" +} +array(3) { + ["f"]=> + string(3) "fff" + [0]=> + string(3) "one" + [1]=> + int(6) +} +array(0) { +} +array(7) { + ["f"]=> + string(3) "fff" + [0]=> + string(3) "one" + [1]=> + int(6) + [""]=> + string(5) "blank" + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" +} +array(2) { + [0]=> + string(4) "Five" + [1]=> + float(8.6) +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(3) { + [1]=> + string(3) "one" + [4]=> + int(6) + [""]=> + string(5) "blank" +} +array(0) { +} +array(6) { + [1]=> + string(3) "one" + [4]=> + int(6) + [""]=> + string(5) "blank" + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" +} +array(3) { + ["f"]=> + string(3) "fff" + [1]=> + string(3) "one" + [4]=> + int(6) +} +array(0) { +} +array(7) { + ["f"]=> + string(3) "fff" + [1]=> + string(3) "one" + [4]=> + int(6) + [""]=> + string(5) "blank" + [2]=> + string(5) "float" + ["F"]=> + string(3) "FFF" + ["blank"]=> + string(0) "" +} +array(2) { + [5]=> + string(4) "Five" + [6]=> + float(8.6) +} +array(0) { +} +array(0) { +} + +*** Iteration 9 *** + +*** Variation with first two Arguments *** +array(3) { + [0]=> + string(4) "name" + [1]=> + string(3) "age" + [2]=> + string(2) "45" +} +array(4) { + [0]=> + int(12) + [1]=> + string(4) "name" + [2]=> + string(3) "age" + [3]=> + string(2) "45" +} +array(2) { + [0]=> + string(3) "age" + [1]=> + string(2) "45" +} + +*** Variation with first three Arguments *** +array(3) { + [0]=> + string(4) "name" + [1]=> + string(3) "age" + [2]=> + string(2) "45" +} +array(0) { +} +array(0) { +} +array(3) { + [0]=> + int(12) + [1]=> + string(4) "name" + [2]=> + string(3) "age" +} +array(0) { +} +array(1) { + [0]=> + int(12) +} +array(2) { + [0]=> + string(3) "age" + [1]=> + string(2) "45" +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(3) { + [1]=> + string(4) "name" + [2]=> + string(3) "age" + [3]=> + string(2) "45" +} +array(0) { +} +array(0) { +} +array(3) { + [0]=> + int(12) + [1]=> + string(4) "name" + [2]=> + string(3) "age" +} +array(0) { +} +array(1) { + [0]=> + int(12) +} +array(2) { + [2]=> + string(3) "age" + [3]=> + string(2) "45" +} +array(0) { +} +array(0) { +} + +*** Iteration 10 *** + +*** Variation with first two Arguments *** +array(2) { + [0]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [1]=> + array(0) { + } +} +array(3) { + [0]=> + array(3) { + [0]=> + string(3) "oNe" + [1]=> + string(3) "tWo" + [2]=> + int(4) + } + [1]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [2]=> + array(0) { + } +} +array(2) { + [0]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [1]=> + array(0) { + } +} + +*** Variation with first three Arguments *** +array(2) { + [0]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [1]=> + array(0) { + } +} +array(0) { +} +array(0) { +} +array(3) { + [0]=> + array(3) { + [0]=> + string(3) "oNe" + [1]=> + string(3) "tWo" + [2]=> + int(4) + } + [1]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [2]=> + array(0) { + } +} +array(0) { +} +array(0) { +} +array(2) { + [0]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [1]=> + array(0) { + } +} +array(0) { +} +array(0) { +} + +*** Variation with first two arguments with preserve_key value TRUE *** +array(2) { + [1]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [2]=> + array(0) { + } +} +array(0) { +} +array(0) { +} +array(3) { + [0]=> + array(3) { + [0]=> + string(3) "oNe" + [1]=> + string(3) "tWo" + [2]=> + int(4) + } + [1]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [2]=> + array(0) { + } +} +array(0) { +} +array(0) { +} +array(2) { + [1]=> + array(5) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + [3]=> + int(40) + [4]=> + int(50) + } + [2]=> + array(0) { + } +} +array(0) { +} +array(0) { +} + +*** Typical Variation of offset and length Arguments *** +array(1) { + [1]=> + string(3) "Two" +} +array(1) { + [0]=> + string(3) "Two" +} +array(1) { + [2]=> + string(5) "Three" +} +array(1) { + [0]=> + string(5) "Three" +} diff --git a/tests/std/array/array_slice_basic.phpt b/tests/std/array/array_slice_basic.phpt new file mode 100644 index 00000000..b82e4cc4 --- /dev/null +++ b/tests/std/array/array_slice_basic.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test array_slice() function : basic functionality +--FILE-- + 1, 'two' => 2, 3, 23 => 4); +$offset = 2; +$length = 2; +$preserve_keys = true; + +// Calling array_slice() with all possible arguments +echo "\n-- All arguments --\n"; +var_dump( array_slice($input, $offset, $length, $preserve_keys) ); + +// Calling array_slice() with mandatory arguments +echo "\n-- Mandatory arguments --\n"; +var_dump( array_slice($input, $offset) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_slice() : basic functionality *** + +-- All arguments -- +array(2) { + [0]=> + int(3) + [23]=> + int(4) +} + +-- Mandatory arguments -- +array(2) { + [0]=> + int(3) + [1]=> + int(4) +} +Done diff --git a/tests/std/array/array_slice_variation1.phpt b/tests/std/array/array_slice_variation1.phpt new file mode 100644 index 00000000..b1d80d3f --- /dev/null +++ b/tests/std/array/array_slice_variation1.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test array_slice() - Third parameter (NULL vs 0) +--FILE-- +getMessage(), "\n"; +} +try { + var_dump(array_slice(range(1, 3), 0, $a)); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +var_dump($a); + +?> +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(0) { +} +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(0) { +} +array(0) { +} +array(0) { +} +array(1) { + [0]=> + int(3) +} +array(1) { + [2]=> + int(3) +} +array_slice(): Argument #3 ($length) must be of type ?int, string given +array_slice(): Argument #3 ($length) must be of type ?int, string given +string(3) "foo" diff --git a/tests/std/array/array_slice_variation10.phpt b/tests/std/array/array_slice_variation10.phpt new file mode 100644 index 00000000..66be016b --- /dev/null +++ b/tests/std/array/array_slice_variation10.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test array_slice() function : usage variations - position of internal array pointer +--FILE-- + 'un', 'two' => 'deux', 23 => 'twenty-three', 'zero'); + +echo "\n-- Call array_slice() --\n"; +var_dump($result = array_slice($input, 2)); + +echo "-- Position of Internal Pointer in Result: --\n"; +echo key($result) . " => " . current($result) . "\n"; +echo "\n-- Position of Internal Pointer in Original Array: --\n"; +echo key($input) . " => " . current ($input) . "\n"; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_slice() : usage variations *** + +-- Call array_slice() -- +array(2) { + [0]=> + string(12) "twenty-three" + [1]=> + string(4) "zero" +} +-- Position of Internal Pointer in Result: -- +0 => twenty-three + +-- Position of Internal Pointer in Original Array: -- +one => un +Done diff --git a/tests/std/array/array_slice_variation11.phpt b/tests/std/array/array_slice_variation11.phpt new file mode 100644 index 00000000..b69f0174 --- /dev/null +++ b/tests/std/array/array_slice_variation11.phpt @@ -0,0 +1,99 @@ +--TEST-- +Test array_slice() function : usage variations - array has holes in buckets +--FILE-- + 'un', 'two' => 'deux', 23 => 'twenty-three', 'zero']; + dump_slice($input, 'two', 0, 1); + dump_slice($input, 'two', 0, 2); + dump_slice($input, 'two', 0, 3); + dump_slice($input, 23, 1, 2); + echo "\n-- Call array_slice() on array with packed keys--\n"; + $input = [10, 11, 12, 'thirteen']; + dump_slice($input, 0, 0, 1); + dump_slice($input, 1, 0, 1); + dump_slice($input, 1, 0, 3); + dump_slice($input, 1, -1, 1); + dump_slice($input, 1, 0, 3); + dump_slice($input, 1, -3, 3); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_slice() : usage variations *** + +-- Call array_slice() on array with string keys-- +array(1) { + ["one"]=> + string(2) "un" +} +array(2) { + ["one"]=> + string(2) "un" + [0]=> + string(12) "twenty-three" +} +array(3) { + ["one"]=> + string(2) "un" + [0]=> + string(12) "twenty-three" + [1]=> + string(4) "zero" +} +array(2) { + ["two"]=> + string(4) "deux" + [0]=> + string(4) "zero" +} + +-- Call array_slice() on array with packed keys-- +array(1) { + [0]=> + int(11) +} +array(1) { + [0]=> + int(10) +} +array(3) { + [0]=> + int(10) + [1]=> + int(12) + [2]=> + string(8) "thirteen" +} +array(1) { + [0]=> + string(8) "thirteen" +} +array(3) { + [0]=> + int(10) + [1]=> + int(12) + [2]=> + string(8) "thirteen" +} +array(3) { + [0]=> + int(10) + [1]=> + int(12) + [2]=> + string(8) "thirteen" +} +Done diff --git a/tests/std/array/array_slice_variation5.phpt b/tests/std/array/array_slice_variation5.phpt new file mode 100644 index 00000000..e2340695 --- /dev/null +++ b/tests/std/array/array_slice_variation5.phpt @@ -0,0 +1,185 @@ +--TEST-- +Test array_slice() function : usage variations - Pass different integers as $offset argument +--FILE-- + 1, 2 => 'two', 'three', 9 => 'nine', 'ten' => 10); + +for ($i = -7; $i <= 7; $i++) { + echo "\n-- \$offset is $i --\n"; + var_dump(array_slice($input, $i)); +} +echo "\n-- \$offset is maximum integer value --\n"; +var_dump(array_slice($input, PHP_INT_MAX)); + +echo "\n-- \$offset is minimum integer value --\n"; +var_dump(array_slice($input, -PHP_INT_MAX)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_slice() : usage variations *** + +-- $offset is -7 -- +array(5) { + ["one"]=> + int(1) + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is -6 -- +array(5) { + ["one"]=> + int(1) + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is -5 -- +array(5) { + ["one"]=> + int(1) + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is -4 -- +array(4) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is -3 -- +array(3) { + [0]=> + string(5) "three" + [1]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is -2 -- +array(2) { + [0]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is -1 -- +array(1) { + ["ten"]=> + int(10) +} + +-- $offset is 0 -- +array(5) { + ["one"]=> + int(1) + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is 1 -- +array(4) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is 2 -- +array(3) { + [0]=> + string(5) "three" + [1]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is 3 -- +array(2) { + [0]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $offset is 4 -- +array(1) { + ["ten"]=> + int(10) +} + +-- $offset is 5 -- +array(0) { +} + +-- $offset is 6 -- +array(0) { +} + +-- $offset is 7 -- +array(0) { +} + +-- $offset is maximum integer value -- +array(0) { +} + +-- $offset is minimum integer value -- +array(5) { + ["one"]=> + int(1) + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} +Done diff --git a/tests/std/array/array_slice_variation6.phpt b/tests/std/array/array_slice_variation6.phpt new file mode 100644 index 00000000..f6099e68 --- /dev/null +++ b/tests/std/array/array_slice_variation6.phpt @@ -0,0 +1,144 @@ +--TEST-- +Test array_slice() function : usage variations - pass different int values as $length arg +--FILE-- + 1, 2 => 'two', 'three', 9 => 'nine', 'ten' => 10); +$offset = 1; + +for ($i = -6; $i <= 6; $i++) { + echo "\n-- \$length is $i --\n"; + var_dump(array_slice($input, $offset, $i)); +} +echo "\n-- \$length is maximum integer value --\n"; +var_dump(array_slice($input, $offset, PHP_INT_MAX)); + +echo "\n-- \$length is minimum integer value --\n"; +var_dump(array_slice($input, $offset, -PHP_INT_MAX)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_slice() : usage variations *** + +-- $length is -6 -- +array(0) { +} + +-- $length is -5 -- +array(0) { +} + +-- $length is -4 -- +array(0) { +} + +-- $length is -3 -- +array(1) { + [0]=> + string(3) "two" +} + +-- $length is -2 -- +array(2) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" +} + +-- $length is -1 -- +array(3) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" +} + +-- $length is 0 -- +array(0) { +} + +-- $length is 1 -- +array(1) { + [0]=> + string(3) "two" +} + +-- $length is 2 -- +array(2) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" +} + +-- $length is 3 -- +array(3) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" +} + +-- $length is 4 -- +array(4) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $length is 5 -- +array(4) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $length is 6 -- +array(4) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $length is maximum integer value -- +array(4) { + [0]=> + string(3) "two" + [1]=> + string(5) "three" + [2]=> + string(4) "nine" + ["ten"]=> + int(10) +} + +-- $length is minimum integer value -- +array(0) { +} +Done diff --git a/tests/std/array/array_slice_variation7.phpt b/tests/std/array/array_slice_variation7.phpt new file mode 100644 index 00000000..58788bd9 --- /dev/null +++ b/tests/std/array/array_slice_variation7.phpt @@ -0,0 +1,251 @@ +--TEST-- +Test array_slice() function : usage variations - different data types as keys in an array +--SKIPIF-- + + +--FILE-- + array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative', + ), + + // null data +/*4*/ 'null uppercase' => array( + NULL => 'null 1', + ), + +/*5*/ 'null lowercase' => array( + null => 'null 2', + ), + + // boolean data +/*6*/ 'bool lowercase' => array( + true => 'lowert', + false => 'lowerf', + ), + +/*7*/ 'bool uppercase' => array( + TRUE => 'uppert', + FALSE => 'upperf', + ), + + // empty data +/*8*/ 'empty double quotes' => array( + "" => 'emptyd', + ), + +/*9*/ 'empty single quotes' => array( + '' => 'emptys', + ), + + // string data +/*10*/ 'string' => array( + "stringd" => 'stringd', + 'strings' => 'strings', + $heredoc => 'stringh', + ), + + // undefined data +/*11*/ 'undefined' => array( + @$undefined_var => 'undefined', + ), + + // unset data +/*12*/ 'unset' => array( + @$unset_var => 'unset', + ), +); + +// loop through each element of $inputs to check the behavior of array_slice() +$iterator = 1; +foreach($inputs as $type => $input) { + echo "\n-- Iteration $iterator : key type is $type --\n"; + echo "\$preserve_keys = TRUE\n"; + var_dump( array_slice($input, $offset, $length, true) ); + echo "\$preserve_keys = FALSE\n"; + var_dump( array_slice($input, $offset, $length, false) ); + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_slice() : usage variations *** + +-- Iteration 1 : key type is int -- +$preserve_keys = TRUE +array(4) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [12345]=> + string(8) "positive" + [-2345]=> + string(8) "negative" +} +$preserve_keys = FALSE +array(4) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(8) "positive" + [3]=> + string(8) "negative" +} + +-- Iteration 2 : key type is null uppercase -- +$preserve_keys = TRUE +array(1) { + [0]=> + string(6) "null 1" +} +$preserve_keys = FALSE +array(1) { + [0]=> + string(6) "null 1" +} + +-- Iteration 3 : key type is null lowercase -- +$preserve_keys = TRUE +array(1) { + [0]=> + string(6) "null 2" +} +$preserve_keys = FALSE +array(1) { + [0]=> + string(6) "null 2" +} + +-- Iteration 4 : key type is bool lowercase -- +$preserve_keys = TRUE +array(2) { + [1]=> + string(6) "lowert" + [0]=> + string(6) "lowerf" +} +$preserve_keys = FALSE +array(2) { + [0]=> + string(6) "lowert" + [1]=> + string(6) "lowerf" +} + +-- Iteration 5 : key type is bool uppercase -- +$preserve_keys = TRUE +array(2) { + [1]=> + string(6) "uppert" + [0]=> + string(6) "upperf" +} +$preserve_keys = FALSE +array(2) { + [0]=> + string(6) "uppert" + [1]=> + string(6) "upperf" +} + +-- Iteration 6 : key type is empty double quotes -- +$preserve_keys = TRUE +array(1) { + [""]=> + string(6) "emptyd" +} +$preserve_keys = FALSE +array(1) { + [""]=> + string(6) "emptyd" +} + +-- Iteration 7 : key type is empty single quotes -- +$preserve_keys = TRUE +array(1) { + [""]=> + string(6) "emptys" +} +$preserve_keys = FALSE +array(1) { + [""]=> + string(6) "emptys" +} + +-- Iteration 8 : key type is string -- +$preserve_keys = TRUE +array(3) { + ["stringd"]=> + string(7) "stringd" + ["strings"]=> + string(7) "strings" + ["hello world"]=> + string(7) "stringh" +} +$preserve_keys = FALSE +array(3) { + ["stringd"]=> + string(7) "stringd" + ["strings"]=> + string(7) "strings" + ["hello world"]=> + string(7) "stringh" +} + +-- Iteration 9 : key type is undefined -- +$preserve_keys = TRUE +array(1) { + [0]=> + string(9) "undefined" +} +$preserve_keys = FALSE +array(1) { + [0]=> + string(9) "undefined" +} + +-- Iteration 10 : key type is unset -- +$preserve_keys = TRUE +array(1) { + [""]=> + string(5) "unset" +} +$preserve_keys = FALSE +array(1) { + [""]=> + string(5) "unset" +} +Done diff --git a/tests/std/array/array_slice_variation8.phpt b/tests/std/array/array_slice_variation8.phpt new file mode 100644 index 00000000..6e0e8f00 --- /dev/null +++ b/tests/std/array/array_slice_variation8.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test array_slice() function : usage variations - multidimensional arrays +--FILE-- + 'nine'); + +echo "\n-- Slice a two-dimensional array --\n"; +var_dump(array_slice($input, 1, 3)); + +echo "\n-- \$input is a sub-array --\n"; +var_dump(array_slice($input[2], 1, 2)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_slice() : usage variations *** + +-- Slice a two-dimensional array -- +array(3) { + [0]=> + string(3) "one" + [1]=> + array(3) { + [0]=> + string(4) "zero" + [1]=> + string(2) "un" + [2]=> + string(4) "deux" + } + [2]=> + string(4) "nine" +} + +-- $input is a sub-array -- +array(2) { + [0]=> + string(2) "un" + [1]=> + string(4) "deux" +} +Done diff --git a/tests/std/array/array_slice_variation9.phpt b/tests/std/array/array_slice_variation9.phpt new file mode 100644 index 00000000..436ee467 --- /dev/null +++ b/tests/std/array/array_slice_variation9.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test array_slice() function : usage variations - referenced variables +--SKIPIF-- + +--FILE-- + &$val1, 2 => &$val2, 1 => &$val3); +var_dump(array_slice($input, 1, 2)); + +echo "-- Change \$val2 (\$preserve_keys = TRUE) --\n"; +$val2 = 'hello, world'; +var_dump(array_slice($input, 1, 2, true)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_slice() : usage variations *** + +-- Array of referenced variables ($preserve_keys = default) -- +array(2) { + [0]=> + &string(3) "two" + [1]=> + &string(5) "three" +} +-- Change $val2 ($preserve_keys = TRUE) -- +array(2) { + [2]=> + &string(12) "hello, world" + [1]=> + &string(5) "three" +} +Done diff --git a/tests/std/array/array_splice_basic.phpt b/tests/std/array/array_splice_basic.phpt new file mode 100644 index 00000000..6396ca75 --- /dev/null +++ b/tests/std/array/array_splice_basic.phpt @@ -0,0 +1,135 @@ +--TEST-- +Test array_splice(): basic functionality +--FILE-- + +--EXPECT-- +*** Testing array_splice() basic operations *** +test truncation +array(2) { + [0]=> + string(4) "blue" + [1]=> + string(6) "yellow" +} +array(2) { + [0]=> + string(3) "red" + [1]=> + string(5) "green" +} +test truncation with null length +array(2) { + [0]=> + string(4) "blue" + [1]=> + string(6) "yellow" +} +array(2) { + [0]=> + string(3) "red" + [1]=> + string(5) "green" +} +test removing entries from the middle +array(2) { + [0]=> + string(5) "green" + [1]=> + string(4) "blue" +} +array(2) { + [0]=> + string(3) "red" + [1]=> + string(6) "yellow" +} +test substitution at end +array(3) { + [0]=> + string(5) "green" + [1]=> + string(4) "blue" + [2]=> + string(6) "yellow" +} +array(2) { + [0]=> + string(3) "red" + [1]=> + string(6) "orange" +} +array(1) { + [0]=> + string(6) "yellow" +} +array(5) { + [0]=> + string(3) "red" + [1]=> + string(5) "green" + [2]=> + string(4) "blue" + [3]=> + string(5) "black" + [4]=> + string(6) "maroon" +} +test insertion +array(0) { +} +array(5) { + [0]=> + string(3) "red" + [1]=> + string(5) "green" + [2]=> + string(4) "blue" + [3]=> + string(6) "purple" + [4]=> + string(6) "yellow" +} diff --git a/tests/std/array/array_splice_variation1.phpt b/tests/std/array/array_splice_variation1.phpt new file mode 100644 index 00000000..ab13d75e --- /dev/null +++ b/tests/std/array/array_splice_variation1.phpt @@ -0,0 +1,113 @@ +--TEST-- +Test array_splice() function : usage variations - references +--SKIPIF-- + + +--FILE-- +&$numbers[3],4,&$numbers[5],"six"=>&$numbers[6],7,&$numbers[8],"nine"=>&$numbers[9]); +var_dump (array_splice ($input_array,4,3)); +var_dump ($input_array); + +echo "Test behaviour of replacement array containing references \n"; + +$three=3; +$four=4; +$input_array=array (0,1,2); +$b=array(&$three,"fourkey"=>&$four); +array_splice ($input_array,-1,1,$b); +var_dump ($input_array); + +echo "Test behaviour of replacement which is part of reference set \n"; + +$int=3; +$input_array=array (1,2); +$b=&$int; + +array_splice ($input_array,-1,1,$b); +var_dump ($input_array); +echo "Done\n"; +?> +--EXPECT-- +test behaviour when input array is in a reference set +array(1) { + [0]=> + int(2) +} +array(2) { + [0]=> + &array(1) { + [0]=> + int(1) + } + [1]=> + &array(1) { + [0]=> + int(1) + } +} +Test behaviour of input arrays containing references +array(3) { + [0]=> + int(4) + [1]=> + &int(5) + ["six"]=> + &int(6) +} +array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + &int(2) + ["three"]=> + &int(3) + [3]=> + int(7) + [4]=> + &int(8) + ["nine"]=> + &int(9) +} +Test behaviour of replacement array containing references +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + &int(3) + [3]=> + &int(4) +} +Test behaviour of replacement which is part of reference set +array(2) { + [0]=> + int(1) + [1]=> + int(3) +} +Done diff --git a/tests/std/array/array_splice_variation3.phpt b/tests/std/array/array_splice_variation3.phpt new file mode 100644 index 00000000..d456cdb5 --- /dev/null +++ b/tests/std/array/array_splice_variation3.phpt @@ -0,0 +1,844 @@ +--TEST-- +Test array_splice() function : usage variations - lengths and offsets +--FILE-- + +--EXPECT-- +*** array_splice() function : usage variations - lengths and offsets +absolute offset - absolute length - cut from beginning + - No replacement +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(4) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) +} + - With replacement +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(7) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + int(2) + [4]=> + int(3) + [5]=> + int(4) + [6]=> + int(5) +} +absolute offset - absolute length - cut from middle + - No replacement +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(4) + [3]=> + int(5) +} + - With replacement +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + string(1) "A" + [3]=> + string(1) "B" + [4]=> + string(1) "C" + [5]=> + int(4) + [6]=> + int(5) +} +absolute offset - absolute length - cut from end + - No replacement +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) +} + - With replacement +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} +array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + string(1) "A" + [5]=> + string(1) "B" + [6]=> + string(1) "C" +} +absolute offset - absolute length - attempt to cut past end + - No replacement +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) +} + - With replacement +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} +array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + string(1) "A" + [5]=> + string(1) "B" + [6]=> + string(1) "C" +} +absolute offset - absolute length - cut everything + - No replacement +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} +array(0) { +} + - With replacement +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} +array(3) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" +} +absolute offset - absolute length - cut nothing + - No replacement +array(0) { +} +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} + - With replacement +array(0) { +} +array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + string(1) "A" + [4]=> + string(1) "B" + [5]=> + string(1) "C" + [6]=> + int(3) + [7]=> + int(4) + [8]=> + int(5) +} +absolute offset - relative length - cut from beginning + - No replacement +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(4) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) +} + - With replacement +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(7) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + int(2) + [4]=> + int(3) + [5]=> + int(4) + [6]=> + int(5) +} +absolute offset - relative length - cut from middle + - No replacement +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(4) + [3]=> + int(5) +} + - With replacement +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + string(1) "A" + [3]=> + string(1) "B" + [4]=> + string(1) "C" + [5]=> + int(4) + [6]=> + int(5) +} +absolute offset - relative length - attempt to cut form before beginning + - No replacement +array(0) { +} +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} + - With replacement +array(0) { +} +array(9) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + int(0) + [4]=> + int(1) + [5]=> + int(2) + [6]=> + int(3) + [7]=> + int(4) + [8]=> + int(5) +} +absolute offset - relative length - cut nothing + - No replacement +array(0) { +} +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} + - With replacement +array(0) { +} +array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + string(1) "A" + [3]=> + string(1) "B" + [4]=> + string(1) "C" + [5]=> + int(2) + [6]=> + int(3) + [7]=> + int(4) + [8]=> + int(5) +} +relative offset - absolute length - cut from beginning + - No replacement +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(4) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) +} + - With replacement +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(7) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + int(2) + [4]=> + int(3) + [5]=> + int(4) + [6]=> + int(5) +} +relative offset - absolute length - cut from middle + - No replacement +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(4) + [3]=> + int(5) +} + - With replacement +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + string(1) "A" + [3]=> + string(1) "B" + [4]=> + string(1) "C" + [5]=> + int(4) + [6]=> + int(5) +} +relative offset - absolute length - cut from end + - No replacement +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) +} + - With replacement +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} +array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + string(1) "A" + [5]=> + string(1) "B" + [6]=> + string(1) "C" +} +relative offset - absolute length - attempt to cut past end + - No replacement +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) +} + - With replacement +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} +array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + string(1) "A" + [5]=> + string(1) "B" + [6]=> + string(1) "C" +} +relative offset - absolute length - cut everything + - No replacement +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} +array(0) { +} + - With replacement +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} +array(3) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" +} +relative offset - absolute length - cut nothing + - No replacement +array(0) { +} +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} + - With replacement +array(0) { +} +array(9) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + int(0) + [4]=> + int(1) + [5]=> + int(2) + [6]=> + int(3) + [7]=> + int(4) + [8]=> + int(5) +} +relative offset - relative length - cut from beginning + - No replacement +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(4) { + [0]=> + int(2) + [1]=> + int(3) + [2]=> + int(4) + [3]=> + int(5) +} + - With replacement +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(7) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + int(2) + [4]=> + int(3) + [5]=> + int(4) + [6]=> + int(5) +} +relative offset - relative length - cut from middle + - No replacement +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(4) + [3]=> + int(5) +} + - With replacement +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(7) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + string(1) "A" + [3]=> + string(1) "B" + [4]=> + string(1) "C" + [5]=> + int(4) + [6]=> + int(5) +} +relative offset - relative length - cut nothing + - No replacement +array(0) { +} +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} + - With replacement +array(0) { +} +array(9) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + string(1) "A" + [3]=> + string(1) "B" + [4]=> + string(1) "C" + [5]=> + int(2) + [6]=> + int(3) + [7]=> + int(4) + [8]=> + int(5) +} +Done diff --git a/tests/std/array/array_splice_variation4.phpt b/tests/std/array/array_splice_variation4.phpt new file mode 100644 index 00000000..6742b2ff --- /dev/null +++ b/tests/std/array/array_splice_variation4.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test array_splice() function : usage variations - non array replacement values +--FILE-- + +--EXPECTF-- +array(0) { +} +array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) +} +array(0) { +} +array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + float(2.1) +} +array(0) { +} +array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + bool(true) +} +array(0) { +} +array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + resource(%d) of type (stream) +} +Done diff --git a/tests/std/array/array_sum.phpt b/tests/std/array/array_sum.phpt new file mode 100644 index 00000000..9ba80beb --- /dev/null +++ b/tests/std/array/array_sum.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test array_sum() +--INI-- +precision=14 +memory_limit=128M +--FILE-- + +--EXPECTF-- +int(500500) +int(500500) +%st(5000050000) +%st(5000050000) diff --git a/tests/std/array/array_sum_basic.phpt b/tests/std/array/array_sum_basic.phpt new file mode 100644 index 00000000..7a7b13e9 --- /dev/null +++ b/tests/std/array/array_sum_basic.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test array_sum() function : basic functionality +--FILE-- + +--EXPECT-- +*** Testing array_sum() : basic functionality *** +-- array_sum() with integer array entries -- +int(15) +-- array_sum() with float array entries -- +float(11.2) +-- array_sum() with integer/float array entries -- +float(17.9) +Done diff --git a/tests/std/array/array_sum_empty_array.phpt b/tests/std/array/array_sum_empty_array.phpt new file mode 100644 index 00000000..17c80ce4 --- /dev/null +++ b/tests/std/array/array_sum_empty_array.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test array_sum() function with empty array +--FILE-- + $carry + $value, 0)); +?> +--EXPECT-- +array_sum() version: +int(0) +array_reduce() version: +int(0) diff --git a/tests/std/array/array_sum_objects_operation_no_cast.phpt b/tests/std/array/array_sum_objects_operation_no_cast.phpt new file mode 100644 index 00000000..d89b44ae --- /dev/null +++ b/tests/std/array/array_sum_objects_operation_no_cast.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test array_sum() function with objects that implement addition but not castable to numeric type +--EXTENSIONS-- +zend_test +--FILE-- + $carry + $value, 0)); +?> +--EXPECTF-- +array_sum() version: + +Warning: array_sum(): Addition is not supported on type DoOperationNoCast in %s on line %d + +Warning: array_sum(): Addition is not supported on type DoOperationNoCast in %s on line %d +int(0) +array_reduce() version: +object(DoOperationNoCast)#5 (1) { + ["val":"DoOperationNoCast":private]=> + int(31) +} diff --git a/tests/std/array/array_sum_objects_operation_no_cast_FFI.phpt b/tests/std/array/array_sum_objects_operation_no_cast_FFI.phpt new file mode 100644 index 00000000..a43f27b1 --- /dev/null +++ b/tests/std/array/array_sum_objects_operation_no_cast_FFI.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_sum() function with objects that implement addition but not castable to numeric type +--EXTENSIONS-- +ffi +--FILE-- +new("int[2]"); +$x[0] = 10; +$x[1] = 25; + +$input = [$x, 1]; + +echo "array_sum() version:\n"; +var_dump(array_sum($input)); + +echo "array_reduce() version:\n"; +var_dump(array_reduce($input, fn($carry, $value) => $carry + $value, 0)); +?> +--EXPECTF-- +array_sum() version: + +Warning: array_sum(): Addition is not supported on type FFI\CData in %s on line %d +int(1) +array_reduce() version: +object(FFI\CData:int32_t*)#4 (1) { + [0]=> + int(25) +} diff --git a/tests/std/array/array_sum_on_reference.phpt b/tests/std/array/array_sum_on_reference.phpt new file mode 100644 index 00000000..a11da5fd --- /dev/null +++ b/tests/std/array/array_sum_on_reference.phpt @@ -0,0 +1,15 @@ +--TEST-- +array_sum() on array with references +--FILE-- + +--EXPECT-- +int(200) +string(3) "100" diff --git a/tests/std/array/array_sum_variation2.phpt b/tests/std/array/array_sum_variation2.phpt new file mode 100644 index 00000000..a4cf7d74 --- /dev/null +++ b/tests/std/array/array_sum_variation2.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test array_sum() function : usage variations - array with different integer value +--FILE-- + +--EXPECT-- +*** Testing array_sum() : different integer array *** +-- Sum of Integer array -- +int(-573) +-- Sum of Octal array -- +int(35) +-- Sum of Hex array -- +int(-198) +-- Sum of mixed integer values -- +int(58) +Done diff --git a/tests/std/array/array_sum_variation3.phpt b/tests/std/array/array_sum_variation3.phpt new file mode 100644 index 00000000..3cb8bc7d --- /dev/null +++ b/tests/std/array/array_sum_variation3.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test array_sum() function : usage variations - array with different float values +--FILE-- + +--EXPECT-- +*** Testing array_sum() : array with different float values *** +-- simple float array -- +float(1.3) +-- float array with scientific notations e and E -- +float(23630.021) +float(23630.021) +-- Mixed float array -- +float(6531.5458) +Done diff --git a/tests/std/array/array_sum_variation4.phpt b/tests/std/array/array_sum_variation4.phpt new file mode 100644 index 00000000..22c72ad1 --- /dev/null +++ b/tests/std/array/array_sum_variation4.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_sum() function : usage variations - array with duplicate values +--FILE-- + +--EXPECT-- +*** Testing array_sum() : array with duplicate values *** +-- With integer array -- +int(117) +-- With float array -- +float(2.5) +Done diff --git a/tests/std/array/array_sum_variation5.phpt b/tests/std/array/array_sum_variation5.phpt new file mode 100644 index 00000000..f38f4507 --- /dev/null +++ b/tests/std/array/array_sum_variation5.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test array_sum() function : usage variations - array with reference variables as elements +--FILE-- + 10, + 1 => &$value4, + 2 => &$value2, + 3 => 200, + 4 => &$value3, +); + +var_dump( array_sum($input) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_sum() : array with elements as reference *** +int(305) +Done diff --git a/tests/std/array/array_sum_variation6.phpt b/tests/std/array/array_sum_variation6.phpt new file mode 100644 index 00000000..e0739ec1 --- /dev/null +++ b/tests/std/array/array_sum_variation6.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test array_sum() function : usage variations - associative array +--FILE-- + 1, 1 => 10, 2 => 0, 3 => -2, 4 => 23.56); +echo "-- with numeric keys --\n"; +var_dump( array_sum($input) ); + +// array with string keys +$input = array('a' => 20, "b" => 50, 'c' => 0, 'd' => -30, "e" => 100); +echo "-- with string keys --\n"; +var_dump( array_sum($input) ); +echo "Done"; +?> +--EXPECT-- +*** Testing array_sum() : with associative array *** +-- with numeric keys -- +float(32.56) +-- with string keys -- +int(140) +Done diff --git a/tests/std/array/array_sum_variation7.phpt b/tests/std/array/array_sum_variation7.phpt new file mode 100644 index 00000000..224d0d0a --- /dev/null +++ b/tests/std/array/array_sum_variation7.phpt @@ -0,0 +1,110 @@ +--TEST-- +Test array_sum() function : usage variations - 'input' array with unexpected values as array element +--SKIPIF-- + +--FILE-- +value = $value; + } +} + +function main() { +echo "*** Testing array_sum() : array with unexpected entries ***\n"; + +// string array +$input = array('Apple', 'Banana', 'Carrot', 'Mango', 'Orange'); +echo "-- array with string values --\n"; +var_dump( array_sum($input) ); + +// bool array +$input = array( true, true, false, true, false); +echo "-- array with bool values --\n"; +var_dump( array_sum($input) ); + +// array with null entry +$input = array(null, NULL); +echo "-- array with null values --\n"; +var_dump( array_sum($input) ); + +// array with subarray +$input = array( + array(1, 2), + array(), + array(0) +); +echo "-- array with subarrays --\n"; +var_dump( array_sum($input) ); + +// array of objects +$input = array( + new MyClass(2), + new MyClass(5), + new MyClass(10), + new MyClass(0) +); +echo "-- array with object values --\n"; +var_dump( array_sum($input) ); + +// Mixed values +$input = array( 5, -8, 7.2, -1.2, "10", "apple", 'Mango', true, false, null, NULL, array( array(1,2), array(0), array())); +echo "-- array with mixed values --\n"; +var_dump( array_sum($input) ); +echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_sum() : array with unexpected entries *** +-- array with string values -- + +%s: Addition is not supported on type string in %s on line %d + +%s: Addition is not supported on type string in %s on line %d + +%s: Addition is not supported on type string in %s on line %d + +%s: Addition is not supported on type string in %s on line %d + +%s: Addition is not supported on type string in %s on line %d +int(0) +-- array with bool values -- +int(3) +-- array with null values -- +int(0) +-- array with subarrays -- + +%s: Addition is not supported on type array in %s on line %d + +%s: Addition is not supported on type array in %s on line %d + +%s: Addition is not supported on type array in %s on line %d +int(0) +-- array with object values -- + +%s: Addition is not supported on type MyClass in %s on line %d + +%s: Addition is not supported on type MyClass in %s on line %d + +%s: Addition is not supported on type MyClass in %s on line %d + +%s: Addition is not supported on type MyClass in %s on line %d +int(0) +-- array with mixed values -- + +%s: Addition is not supported on type string in %s on line %d + +%s: Addition is not supported on type string in %s on line %d + +%s: Addition is not supported on type array in %s on line %d +float(14) +Done diff --git a/tests/std/array/array_sum_variation8.phpt b/tests/std/array/array_sum_variation8.phpt new file mode 100644 index 00000000..21ff8fcf --- /dev/null +++ b/tests/std/array/array_sum_variation8.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test array_sum() function: resources in array +--FILE-- + $carry + $value, 0)); +} catch (TypeError $e) { + echo $e->getMessage(); +} +?> +--EXPECTF-- +array_sum() version: + +Warning:%S Addition is not supported on type resource in %s on line %d +int(13) +array_reduce() version: +Unsupported operand types: int + resource%S +%a diff --git a/tests/std/array/array_sum_variation9.phpt b/tests/std/array/array_sum_variation9.phpt new file mode 100644 index 00000000..61af56b2 --- /dev/null +++ b/tests/std/array/array_sum_variation9.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test array_sum() function with objects castable to numeric type +--EXTENSIONS-- +gmp +--FILE-- + $carry + $value, 0)); +?> +--EXPECT-- +array_sum() version: +int(31) +array_reduce() version: +object(GMP)#5 (1) { + ["num"]=> + string(2) "31" +} diff --git a/tests/std/array/array_udiff_assoc_basic.phpt b/tests/std/array/array_udiff_assoc_basic.phpt new file mode 100644 index 00000000..293ff402 --- /dev/null +++ b/tests/std/array/array_udiff_assoc_basic.phpt @@ -0,0 +1,48 @@ +--TEST-- +array_udiff_assoc(): Test return type and value for expected input +--FILE-- +priv_member = $val; + } + static function comp_func_cr($a, $b) + { + if ($a->priv_member === $b->priv_member) { + return 0; + } + return $a->priv_member > $b->priv_member ? 1 : -1; + } +} +function main() +{ + $a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1 => new cr(4), 2 => new cr(-15)); + $b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1 => new cr(4), 2 => new cr(-15)); + $result = array_udiff_assoc($a, $b, array("cr", "comp_func_cr")); + var_dump($result); +} +?> +--EXPECTF-- +array(3) { + ["0.1"]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(9) + } + ["0.5"]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(12) + } + [0]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(23) + } +} diff --git a/tests/std/array/array_udiff_assoc_variation.phpt b/tests/std/array/array_udiff_assoc_variation.phpt new file mode 100644 index 00000000..02afa572 --- /dev/null +++ b/tests/std/array/array_udiff_assoc_variation.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_udiff_assoc() function : variation +--SKIPIF-- +--FILE-- + "one", "02" => "two", '3' => "three", "four", "0.5" => 5, 6 => 6, "seven" => "07"); +$arr2 = array("one" => "one", "02" => "two", '3' => "three"); +$arr3 = array("four", "0.5" => "five", 6 => 6, "seven" => 7); +$arr4 = array("four", "0.5" => "five", 6 => 6, "seven" => 7); + + +var_dump( array_udiff_assoc($arr1, $arr2, $arr3, $arr4, $key_compare_function) ); + + +?> +--EXPECT-- +*** Testing array_udiff_assoc() : variation - testing with multiple array arguments *** +array(2) { + [4]=> + string(4) "four" + ["0.5"]=> + int(5) +} diff --git a/tests/std/array/array_udiff_assoc_variation1.phpt b/tests/std/array/array_udiff_assoc_variation1.phpt new file mode 100644 index 00000000..1fd8eabb --- /dev/null +++ b/tests/std/array/array_udiff_assoc_variation1.phpt @@ -0,0 +1,161 @@ +--TEST-- +Test array_udiff_assoc() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_udiff_assoc($value, $array2, $key_comp_func)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_udiff_assoc() : usage variation *** + +--int 0-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_udiff_assoc(): Argument #1 ($array) must be of type array, null given diff --git a/tests/std/array/array_udiff_assoc_variation2.phpt b/tests/std/array/array_udiff_assoc_variation2.phpt new file mode 100644 index 00000000..b155ff4a --- /dev/null +++ b/tests/std/array/array_udiff_assoc_variation2.phpt @@ -0,0 +1,161 @@ +--TEST-- +Test array_udiff_assoc() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_udiff_assoc($array1, $value, $key_comp_func)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_udiff_assoc() : usage variation *** + +--int 0-- +array_udiff_assoc(): Argument #2 must be of type array, int given + +--int 1-- +array_udiff_assoc(): Argument #2 must be of type array, int given + +--int 12345-- +array_udiff_assoc(): Argument #2 must be of type array, int given + +--int -12345-- +array_udiff_assoc(): Argument #2 must be of type array, int given + +--float 10.5-- +array_udiff_assoc(): Argument #2 must be of type array, float given + +--float -10.5-- +array_udiff_assoc(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_udiff_assoc(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_udiff_assoc(): Argument #2 must be of type array, float given + +--float .5-- +array_udiff_assoc(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_udiff_assoc(): Argument #2 must be of type array, null given + +--lowercase null-- +array_udiff_assoc(): Argument #2 must be of type array, null given + +--lowercase true-- +array_udiff_assoc(): Argument #2 must be of type array, true given + +--lowercase false-- +array_udiff_assoc(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_udiff_assoc(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_udiff_assoc(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_udiff_assoc(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_udiff_assoc(): Argument #2 must be of type array, string given + +--string DQ-- +array_udiff_assoc(): Argument #2 must be of type array, string given + +--string SQ-- +array_udiff_assoc(): Argument #2 must be of type array, string given + +--mixed case string-- +array_udiff_assoc(): Argument #2 must be of type array, string given + +--heredoc-- +array_udiff_assoc(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_udiff_assoc(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_udiff_assoc(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_udiff_assoc(): Argument #2 must be of type array, null given + +--unset var-- +array_udiff_assoc(): Argument #2 must be of type array, null given diff --git a/tests/std/array/array_udiff_assoc_variation5.phpt b/tests/std/array/array_udiff_assoc_variation5.phpt new file mode 100644 index 00000000..3ce2c6cf --- /dev/null +++ b/tests/std/array/array_udiff_assoc_variation5.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test array_udiff_assoc() function : usage variation - incorrect comparison functions +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } + echo "\n-- comparison function taking too few parameters --\n"; + var_dump(array_udiff_assoc($arr1, $arr2, 'too_few_parameters')); +} +?> +--EXPECT-- +*** Testing array_udiff_assoc() : usage variation - differing comparison functions*** + +-- comparison function with an incorrect return value -- +array(1) { + [0]=> + int(1) +} + +-- comparison function taking too many parameters -- +array(1) { + [0]=> + int(1) +} + +-- comparison function taking too few parameters -- +array(1) { + [0]=> + int(1) +} diff --git a/tests/std/array/array_udiff_basic.phpt b/tests/std/array/array_udiff_basic.phpt new file mode 100644 index 00000000..cbac87a8 --- /dev/null +++ b/tests/std/array/array_udiff_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +array_udiff():Test return type and value for expected input +--FILE-- +priv_member = $val; + } + static function comp_func_cr($a, $b) + { + if ($a->priv_member === $b->priv_member) { + return 0; + } + return $a->priv_member > $b->priv_member ? 1 : -1; + } +} +function main() +{ + $a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1 => new cr(4), 2 => new cr(-15)); + $b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1 => new cr(4), 2 => new cr(-15)); + $result = array_udiff($a, $b, array("cr", "comp_func_cr")); + var_dump($result); +} +?> +--EXPECTF-- +array(2) { + ["0.5"]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(12) + } + [0]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(23) + } +} diff --git a/tests/std/array/array_udiff_uassoc_basic.phpt b/tests/std/array/array_udiff_uassoc_basic.phpt new file mode 100644 index 00000000..cbe99767 --- /dev/null +++ b/tests/std/array/array_udiff_uassoc_basic.phpt @@ -0,0 +1,55 @@ +--TEST-- +array_udiff_uassoc(): Test return type and value for expected input +--FILE-- +priv_member = $val; + } + static function comp_func_cr($a, $b) + { + if ($a->priv_member === $b->priv_member) { + return 0; + } + return $a->priv_member > $b->priv_member ? 1 : -1; + } + static function comp_func_key($a, $b) + { + if ($a === $b) { + return 0; + } + return $a > $b ? 1 : -1; + } +} +function main() +{ + $a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1 => new cr(4), 2 => new cr(-15)); + $b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1 => new cr(4), 2 => new cr(-15)); + $result = array_udiff_uassoc($a, $b, array("cr", "comp_func_cr"), array("cr", "comp_func_key")); + var_dump($result); +} +?> +--EXPECTF-- +array(3) { + ["0.1"]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(9) + } + ["0.5"]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(12) + } + [0]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(23) + } +} diff --git a/tests/std/array/array_udiff_uassoc_variation1.phpt b/tests/std/array/array_udiff_uassoc_variation1.phpt new file mode 100644 index 00000000..15436670 --- /dev/null +++ b/tests/std/array/array_udiff_uassoc_variation1.phpt @@ -0,0 +1,160 @@ +--TEST-- +Test array_udiff_uassoc() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => $undefined_var, + // unset data + 'unset var' => $unset_var, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_udiff_uassoc($value, $array2, $data_comp_func, $key_comp_func)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_udiff_uassoc() : usage variation *** + +--int 0-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_udiff_uassoc(): Argument #1 ($array) must be of type array, null given + diff --git a/tests/std/array/array_udiff_uassoc_variation2.phpt b/tests/std/array/array_udiff_uassoc_variation2.phpt new file mode 100644 index 00000000..4aa546e9 --- /dev/null +++ b/tests/std/array/array_udiff_uassoc_variation2.phpt @@ -0,0 +1,162 @@ +--TEST-- +Test array_udiff_uassoc() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_udiff_uassoc($array1, $value, $data_comp_func, $key_comp_func)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_udiff_uassoc() : usage variation *** + +--int 0-- +array_udiff_uassoc(): Argument #2 must be of type array, int given + +--int 1-- +array_udiff_uassoc(): Argument #2 must be of type array, int given + +--int 12345-- +array_udiff_uassoc(): Argument #2 must be of type array, int given + +--int -12345-- +array_udiff_uassoc(): Argument #2 must be of type array, int given + +--float 10.5-- +array_udiff_uassoc(): Argument #2 must be of type array, float given + +--float -10.5-- +array_udiff_uassoc(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_udiff_uassoc(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_udiff_uassoc(): Argument #2 must be of type array, float given + +--float .5-- +array_udiff_uassoc(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_udiff_uassoc(): Argument #2 must be of type array, null given + +--lowercase null-- +array_udiff_uassoc(): Argument #2 must be of type array, null given + +--lowercase true-- +array_udiff_uassoc(): Argument #2 must be of type array, true given + +--lowercase false-- +array_udiff_uassoc(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_udiff_uassoc(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_udiff_uassoc(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_udiff_uassoc(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_udiff_uassoc(): Argument #2 must be of type array, string given + +--string DQ-- +array_udiff_uassoc(): Argument #2 must be of type array, string given + +--string SQ-- +array_udiff_uassoc(): Argument #2 must be of type array, string given + +--mixed case string-- +array_udiff_uassoc(): Argument #2 must be of type array, string given + +--heredoc-- +array_udiff_uassoc(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_udiff_uassoc(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_udiff_uassoc(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_udiff_uassoc(): Argument #2 must be of type array, null given + +--unset var-- +array_udiff_uassoc(): Argument #2 must be of type array, null given diff --git a/tests/std/array/array_udiff_uassoc_variation6.phpt b/tests/std/array/array_udiff_uassoc_variation6.phpt new file mode 100644 index 00000000..38a26896 --- /dev/null +++ b/tests/std/array/array_udiff_uassoc_variation6.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test array_udiff_uassoc() function : usage variation +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } + echo "\n-- comparison function taking too few parameters --\n"; + var_dump(array_udiff_uassoc($arr1, $arr2, 'too_few_parameters', 'too_few_parameters')); +} +?> +--EXPECT-- +*** Testing array_udiff_uassoc() : usage variation - differing comparison functions*** + +-- comparison function with an incorrect return value -- +array(1) { + [0]=> + int(1) +} + +-- comparison function taking too many parameters -- +array(1) { + [0]=> + int(1) +} + +-- comparison function taking too few parameters -- +array(1) { + [0]=> + int(1) +} diff --git a/tests/std/array/array_udiff_variation1.phpt b/tests/std/array/array_udiff_variation1.phpt new file mode 100644 index 00000000..927d5200 --- /dev/null +++ b/tests/std/array/array_udiff_variation1.phpt @@ -0,0 +1,161 @@ +--TEST-- +Test array_udiff() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_udiff($value, $array2, $data_comp_func)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_udiff() : usage variation *** + +--int 0-- +array_udiff(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_udiff(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_udiff(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_udiff(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_udiff(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_udiff(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_udiff(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_udiff(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_udiff(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_udiff(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_udiff(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_udiff(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_udiff(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_udiff(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_udiff(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_udiff(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_udiff(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_udiff(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_udiff(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_udiff(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_udiff(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_udiff(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_udiff(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_udiff(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_udiff(): Argument #1 ($array) must be of type array, null given diff --git a/tests/std/array/array_udiff_variation2.phpt b/tests/std/array/array_udiff_variation2.phpt new file mode 100644 index 00000000..0035949f --- /dev/null +++ b/tests/std/array/array_udiff_variation2.phpt @@ -0,0 +1,161 @@ +--TEST-- +Test array_udiff() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_udiff($array1, $value, $data_comp_func)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_udiff() : usage variation *** + +--int 0-- +array_udiff(): Argument #2 must be of type array, int given + +--int 1-- +array_udiff(): Argument #2 must be of type array, int given + +--int 12345-- +array_udiff(): Argument #2 must be of type array, int given + +--int -12345-- +array_udiff(): Argument #2 must be of type array, int given + +--float 10.5-- +array_udiff(): Argument #2 must be of type array, float given + +--float -10.5-- +array_udiff(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_udiff(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_udiff(): Argument #2 must be of type array, float given + +--float .5-- +array_udiff(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_udiff(): Argument #2 must be of type array, null given + +--lowercase null-- +array_udiff(): Argument #2 must be of type array, null given + +--lowercase true-- +array_udiff(): Argument #2 must be of type array, true given + +--lowercase false-- +array_udiff(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_udiff(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_udiff(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_udiff(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_udiff(): Argument #2 must be of type array, string given + +--string DQ-- +array_udiff(): Argument #2 must be of type array, string given + +--string SQ-- +array_udiff(): Argument #2 must be of type array, string given + +--mixed case string-- +array_udiff(): Argument #2 must be of type array, string given + +--heredoc-- +array_udiff(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_udiff(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_udiff(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_udiff(): Argument #2 must be of type array, null given + +--unset var-- +array_udiff(): Argument #2 must be of type array, null given diff --git a/tests/std/array/array_udiff_variation5.phpt b/tests/std/array/array_udiff_variation5.phpt new file mode 100644 index 00000000..21a58df8 --- /dev/null +++ b/tests/std/array/array_udiff_variation5.phpt @@ -0,0 +1,53 @@ +--TEST-- +Test array_udiff() function : usage variation +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } + echo "\n-- comparison function taking too few parameters --\n"; + var_dump(array_udiff($arr1, $arr2, 'too_few_parameters')); +} +?> +--EXPECT-- +*** Testing array_udiff() : usage variation *** + +-- comparison function with an incorrect return value -- +array(1) { + [0]=> + int(1) +} + +-- comparison function taking too many parameters -- +array(0) { +} + +-- comparison function taking too few parameters -- +array(0) { +} diff --git a/tests/std/array/array_uintersect_assoc_basic.phpt b/tests/std/array/array_uintersect_assoc_basic.phpt new file mode 100644 index 00000000..0b8e6b5f --- /dev/null +++ b/tests/std/array/array_uintersect_assoc_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +array_uintersect_assoc(): Test return type and value for expected input +--FILE-- +priv_member = $val; + } + static function comp_func_cr($a, $b) + { + if ($a->priv_member === $b->priv_member) { + return 0; + } + return $a->priv_member > $b->priv_member ? 1 : -1; + } +} +function main() +{ + $a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1 => new cr(4), 2 => new cr(-15)); + $b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1 => new cr(4), 2 => new cr(-15)); + $result = array_uintersect_assoc($a, $b, array("cr", "comp_func_cr")); + var_dump($result); +} +?> +--EXPECTF-- +array(2) { + [1]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(4) + } + [2]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(-15) + } +} diff --git a/tests/std/array/array_uintersect_assoc_basic2.phpt b/tests/std/array/array_uintersect_assoc_basic2.phpt new file mode 100644 index 00000000..47bb916e --- /dev/null +++ b/tests/std/array/array_uintersect_assoc_basic2.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_uintersect_assoc() function : basic functionality - testing with multiple array arguments +--SKIPIF-- +--FILE-- + "one", "02" => "two", '3' => "three", "four", "0.5" => 5, 0 => 6, "0x7" => "seven"); +$arr2 = array("one" => "one", "02" => "two", '3' => "three"); +$arr3 = array("one" => "one", '3' => "three", "0.5" => 5); +$arr4 = array("one" => "one", '3' => "three", "0.5" => 5); + + +var_dump( array_uintersect_assoc($arr1, $arr2, $arr3, $arr4, $data_compare_function) ); + + +?> +--EXPECT-- +*** Testing array_uintersect_assoc() : basic functionality - testing with multiple array arguments *** +array(2) { + ["one"]=> + string(3) "one" + [3]=> + string(5) "three" +} diff --git a/tests/std/array/array_uintersect_assoc_variation1.phpt b/tests/std/array/array_uintersect_assoc_variation1.phpt new file mode 100644 index 00000000..1f70e037 --- /dev/null +++ b/tests/std/array/array_uintersect_assoc_variation1.phpt @@ -0,0 +1,161 @@ +--TEST-- +Test array_uintersect_assoc() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_uintersect_assoc($value, $array2, $data_compare_function)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_uintersect_assoc() : usage variation *** + +--int 0-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_uintersect_assoc(): Argument #1 ($array) must be of type array, null given diff --git a/tests/std/array/array_uintersect_assoc_variation2.phpt b/tests/std/array/array_uintersect_assoc_variation2.phpt new file mode 100644 index 00000000..ccef8840 --- /dev/null +++ b/tests/std/array/array_uintersect_assoc_variation2.phpt @@ -0,0 +1,161 @@ +--TEST-- +Test array_uintersect_assoc() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_uintersect_assoc($array1, $value, $data_compare_function)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_uintersect_assoc() : usage variation *** + +--int 0-- +array_uintersect_assoc(): Argument #2 must be of type array, int given + +--int 1-- +array_uintersect_assoc(): Argument #2 must be of type array, int given + +--int 12345-- +array_uintersect_assoc(): Argument #2 must be of type array, int given + +--int -12345-- +array_uintersect_assoc(): Argument #2 must be of type array, int given + +--float 10.5-- +array_uintersect_assoc(): Argument #2 must be of type array, float given + +--float -10.5-- +array_uintersect_assoc(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_uintersect_assoc(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_uintersect_assoc(): Argument #2 must be of type array, float given + +--float .5-- +array_uintersect_assoc(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_uintersect_assoc(): Argument #2 must be of type array, null given + +--lowercase null-- +array_uintersect_assoc(): Argument #2 must be of type array, null given + +--lowercase true-- +array_uintersect_assoc(): Argument #2 must be of type array, true given + +--lowercase false-- +array_uintersect_assoc(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_uintersect_assoc(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_uintersect_assoc(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_uintersect_assoc(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_uintersect_assoc(): Argument #2 must be of type array, string given + +--string DQ-- +array_uintersect_assoc(): Argument #2 must be of type array, string given + +--string SQ-- +array_uintersect_assoc(): Argument #2 must be of type array, string given + +--mixed case string-- +array_uintersect_assoc(): Argument #2 must be of type array, string given + +--heredoc-- +array_uintersect_assoc(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_uintersect_assoc(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_uintersect_assoc(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_uintersect_assoc(): Argument #2 must be of type array, null given + +--unset var-- +array_uintersect_assoc(): Argument #2 must be of type array, null given diff --git a/tests/std/array/array_uintersect_assoc_variation5.phpt b/tests/std/array/array_uintersect_assoc_variation5.phpt new file mode 100644 index 00000000..94fefc47 --- /dev/null +++ b/tests/std/array/array_uintersect_assoc_variation5.phpt @@ -0,0 +1,51 @@ +--TEST-- +Test array_uintersect_assoc() function : usage variation - differing comparison functions +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } + echo "\n-- comparison function taking too few parameters --\n"; + var_dump(array_uintersect_assoc($arr1, $arr2, 'too_few_parameters')); +} +?> +--EXPECT-- +*** Testing array_uintersect_assoc() : usage variation - differing comparison functions*** + +-- comparison function with an incorrect return value -- +array(0) { +} + +-- comparison function taking too many parameters -- +array(0) { +} + +-- comparison function taking too few parameters -- +array(0) { +} + diff --git a/tests/std/array/array_uintersect_basic.phpt b/tests/std/array/array_uintersect_basic.phpt new file mode 100644 index 00000000..7444cc07 --- /dev/null +++ b/tests/std/array/array_uintersect_basic.phpt @@ -0,0 +1,48 @@ +--TEST-- +array_uintersect(): Test return type and value for expected input +--FILE-- +priv_member = $val; + } + static function comp_func_cr($a, $b) + { + if ($a->priv_member === $b->priv_member) { + return 0; + } + return $a->priv_member > $b->priv_member ? 1 : -1; + } +} +function main() +{ + $a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1 => new cr(4), 2 => new cr(-15)); + $b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1 => new cr(4), 2 => new cr(-15)); + $result = array_uintersect($a, $b, array("cr", "comp_func_cr")); + var_dump($result); +} +?> +--EXPECTF-- +array(3) { + ["0.1"]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(9) + } + [1]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(4) + } + [2]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(-15) + } +} diff --git a/tests/std/array/array_uintersect_uassoc_basic.phpt b/tests/std/array/array_uintersect_uassoc_basic.phpt new file mode 100644 index 00000000..8f4e3afd --- /dev/null +++ b/tests/std/array/array_uintersect_uassoc_basic.phpt @@ -0,0 +1,50 @@ +--TEST-- +array_uintersect_uassoc(): Test return type and value for expected input +--FILE-- +priv_member = $val; + } + static function comp_func_cr($a, $b) + { + if ($a->priv_member === $b->priv_member) { + return 0; + } + return $a->priv_member > $b->priv_member ? 1 : -1; + } + static function comp_func_key($a, $b) + { + if ($a === $b) { + return 0; + } + return $a > $b ? 1 : -1; + } +} +function main() +{ + $a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1 => new cr(4), 2 => new cr(-15)); + $b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1 => new cr(4), 2 => new cr(-15)); + $result = array_uintersect_uassoc($a, $b, array("cr", "comp_func_cr"), array("cr", "comp_func_key")); + var_dump($result); +} +?> +--EXPECTF-- +array(2) { + [1]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(4) + } + [2]=> + object(cr)#%d (1) { + ["priv_member":"cr":private]=> + int(-15) + } +} diff --git a/tests/std/array/array_uintersect_uassoc_variation1.phpt b/tests/std/array/array_uintersect_uassoc_variation1.phpt new file mode 100644 index 00000000..9478f908 --- /dev/null +++ b/tests/std/array/array_uintersect_uassoc_variation1.phpt @@ -0,0 +1,162 @@ +--TEST-- +Test array_uintersect_uassoc() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_uintersect_uassoc($value, $array2, $data_compare_func, $key_compare_func)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_uintersect_uassoc() : usage variation *** + +--int 0-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_uintersect_uassoc(): Argument #1 ($array) must be of type array, null given diff --git a/tests/std/array/array_uintersect_uassoc_variation2.phpt b/tests/std/array/array_uintersect_uassoc_variation2.phpt new file mode 100644 index 00000000..85793cd1 --- /dev/null +++ b/tests/std/array/array_uintersect_uassoc_variation2.phpt @@ -0,0 +1,162 @@ +--TEST-- +Test array_uintersect_uassoc() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_uintersect_uassoc($array1, $value, $data_compare_func, $key_compare_func)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_uintersect_uassoc() : usage variation *** + +--int 0-- +array_uintersect_uassoc(): Argument #2 must be of type array, int given + +--int 1-- +array_uintersect_uassoc(): Argument #2 must be of type array, int given + +--int 12345-- +array_uintersect_uassoc(): Argument #2 must be of type array, int given + +--int -12345-- +array_uintersect_uassoc(): Argument #2 must be of type array, int given + +--float 10.5-- +array_uintersect_uassoc(): Argument #2 must be of type array, float given + +--float -10.5-- +array_uintersect_uassoc(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_uintersect_uassoc(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_uintersect_uassoc(): Argument #2 must be of type array, float given + +--float .5-- +array_uintersect_uassoc(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_uintersect_uassoc(): Argument #2 must be of type array, null given + +--lowercase null-- +array_uintersect_uassoc(): Argument #2 must be of type array, null given + +--lowercase true-- +array_uintersect_uassoc(): Argument #2 must be of type array, true given + +--lowercase false-- +array_uintersect_uassoc(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_uintersect_uassoc(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_uintersect_uassoc(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_uintersect_uassoc(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_uintersect_uassoc(): Argument #2 must be of type array, string given + +--string DQ-- +array_uintersect_uassoc(): Argument #2 must be of type array, string given + +--string SQ-- +array_uintersect_uassoc(): Argument #2 must be of type array, string given + +--mixed case string-- +array_uintersect_uassoc(): Argument #2 must be of type array, string given + +--heredoc-- +array_uintersect_uassoc(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_uintersect_uassoc(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_uintersect_uassoc(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_uintersect_uassoc(): Argument #2 must be of type array, null given + +--unset var-- +array_uintersect_uassoc(): Argument #2 must be of type array, null given diff --git a/tests/std/array/array_uintersect_uassoc_variation6.phpt b/tests/std/array/array_uintersect_uassoc_variation6.phpt new file mode 100644 index 00000000..54d4ecfb --- /dev/null +++ b/tests/std/array/array_uintersect_uassoc_variation6.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test array_uintersect_uassoc() function : usage variation - incorrect callbacks +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } + echo "\n-- comparison function taking too few parameters --\n"; + var_dump(array_uintersect_uassoc($arr1, $arr2, 'too_few_parameters', 'too_few_parameters')); +} +?> +--EXPECT-- +*** Testing array_uintersect_uassoc() : usage variation - incorrect callbacks *** + +-- comparison function with an incorrect return value -- +array(0) { +} + +-- comparison function taking too many parameters -- +array(0) { +} + +-- comparison function taking too few parameters -- +array(0) { +} diff --git a/tests/std/array/array_uintersect_variation1.phpt b/tests/std/array/array_uintersect_variation1.phpt new file mode 100644 index 00000000..f482c7a9 --- /dev/null +++ b/tests/std/array/array_uintersect_variation1.phpt @@ -0,0 +1,161 @@ +--TEST-- +Test array_uintersect() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array1 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_uintersect($value, $array2, $data_compare_function)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_uintersect() : usage variation *** + +--int 0-- +array_uintersect(): Argument #1 ($array) must be of type array, int given + +--int 1-- +array_uintersect(): Argument #1 ($array) must be of type array, int given + +--int 12345-- +array_uintersect(): Argument #1 ($array) must be of type array, int given + +--int -12345-- +array_uintersect(): Argument #1 ($array) must be of type array, int given + +--float 10.5-- +array_uintersect(): Argument #1 ($array) must be of type array, float given + +--float -10.5-- +array_uintersect(): Argument #1 ($array) must be of type array, float given + +--float 12.3456789000e10-- +array_uintersect(): Argument #1 ($array) must be of type array, float given + +--float -12.3456789000e10-- +array_uintersect(): Argument #1 ($array) must be of type array, float given + +--float .5-- +array_uintersect(): Argument #1 ($array) must be of type array, float given + +--uppercase NULL-- +array_uintersect(): Argument #1 ($array) must be of type array, null given + +--lowercase null-- +array_uintersect(): Argument #1 ($array) must be of type array, null given + +--lowercase true-- +array_uintersect(): Argument #1 ($array) must be of type array, true given + +--lowercase false-- +array_uintersect(): Argument #1 ($array) must be of type array, false given + +--uppercase TRUE-- +array_uintersect(): Argument #1 ($array) must be of type array, true given + +--uppercase FALSE-- +array_uintersect(): Argument #1 ($array) must be of type array, false given + +--empty string DQ-- +array_uintersect(): Argument #1 ($array) must be of type array, string given + +--empty string SQ-- +array_uintersect(): Argument #1 ($array) must be of type array, string given + +--string DQ-- +array_uintersect(): Argument #1 ($array) must be of type array, string given + +--string SQ-- +array_uintersect(): Argument #1 ($array) must be of type array, string given + +--mixed case string-- +array_uintersect(): Argument #1 ($array) must be of type array, string given + +--heredoc-- +array_uintersect(): Argument #1 ($array) must be of type array, string given + +--instance of classWithToString-- +array_uintersect(): Argument #1 ($array) must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_uintersect(): Argument #1 ($array) must be of type array, classWithoutToString given + +--undefined var-- +array_uintersect(): Argument #1 ($array) must be of type array, null given + +--unset var-- +array_uintersect(): Argument #1 ($array) must be of type array, null given diff --git a/tests/std/array/array_uintersect_variation2.phpt b/tests/std/array/array_uintersect_variation2.phpt new file mode 100644 index 00000000..6076204d --- /dev/null +++ b/tests/std/array/array_uintersect_variation2.phpt @@ -0,0 +1,161 @@ +--TEST-- +Test array_uintersect() function : usage variation +--SKIPIF-- + + +--FILE-- + 1, 'two' => 2); + //array of values to iterate over + $inputs = array( + // int data + 'int 0' => 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + // float data + 'float 10.5' => 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 123456789000.0, + 'float -12.3456789000e10' => -123456789000.0, + 'float .5' => 0.5, + // null data + 'uppercase NULL' => NULL, + 'lowercase null' => null, + // boolean data + 'lowercase true' => true, + 'lowercase false' => false, + 'uppercase TRUE' => TRUE, + 'uppercase FALSE' => FALSE, + // empty data + 'empty string DQ' => "", + 'empty string SQ' => '', + // string data + 'string DQ' => "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + // object data + 'instance of classWithToString' => new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + // undefined data + 'undefined var' => @$undefined_var, + // unset data + 'unset var' => @$unset_var, + ); + // loop through each element of the array for array2 + foreach ($inputs as $key => $value) { + echo "\n--{$key}--\n"; + try { + var_dump(array_uintersect($array1, $value, $data_compare_function)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + } +} +?> +--EXPECT-- +*** Testing array_uintersect() : usage variation *** + +--int 0-- +array_uintersect(): Argument #2 must be of type array, int given + +--int 1-- +array_uintersect(): Argument #2 must be of type array, int given + +--int 12345-- +array_uintersect(): Argument #2 must be of type array, int given + +--int -12345-- +array_uintersect(): Argument #2 must be of type array, int given + +--float 10.5-- +array_uintersect(): Argument #2 must be of type array, float given + +--float -10.5-- +array_uintersect(): Argument #2 must be of type array, float given + +--float 12.3456789000e10-- +array_uintersect(): Argument #2 must be of type array, float given + +--float -12.3456789000e10-- +array_uintersect(): Argument #2 must be of type array, float given + +--float .5-- +array_uintersect(): Argument #2 must be of type array, float given + +--uppercase NULL-- +array_uintersect(): Argument #2 must be of type array, null given + +--lowercase null-- +array_uintersect(): Argument #2 must be of type array, null given + +--lowercase true-- +array_uintersect(): Argument #2 must be of type array, true given + +--lowercase false-- +array_uintersect(): Argument #2 must be of type array, false given + +--uppercase TRUE-- +array_uintersect(): Argument #2 must be of type array, true given + +--uppercase FALSE-- +array_uintersect(): Argument #2 must be of type array, false given + +--empty string DQ-- +array_uintersect(): Argument #2 must be of type array, string given + +--empty string SQ-- +array_uintersect(): Argument #2 must be of type array, string given + +--string DQ-- +array_uintersect(): Argument #2 must be of type array, string given + +--string SQ-- +array_uintersect(): Argument #2 must be of type array, string given + +--mixed case string-- +array_uintersect(): Argument #2 must be of type array, string given + +--heredoc-- +array_uintersect(): Argument #2 must be of type array, string given + +--instance of classWithToString-- +array_uintersect(): Argument #2 must be of type array, classWithToString given + +--instance of classWithoutToString-- +array_uintersect(): Argument #2 must be of type array, classWithoutToString given + +--undefined var-- +array_uintersect(): Argument #2 must be of type array, null given + +--unset var-- +array_uintersect(): Argument #2 must be of type array, null given diff --git a/tests/std/array/array_uintersect_variation5.phpt b/tests/std/array/array_uintersect_variation5.phpt new file mode 100644 index 00000000..e3ad1e5a --- /dev/null +++ b/tests/std/array/array_uintersect_variation5.phpt @@ -0,0 +1,51 @@ +--TEST-- +Test array_uintersect() function : usage variation - differing comparison functions +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } + echo "\n-- comparison function taking too few parameters --\n"; + var_dump(array_uintersect($arr1, $arr2, 'too_few_parameters')); +} +?> +--EXPECT-- +*** Testing array_uintersect() : usage variation - differing comparison functions*** + +-- comparison function with an incorrect return value -- +array(0) { +} + +-- comparison function taking too many parameters -- +array(0) { +} + +-- comparison function taking too few parameters -- +array(0) { +} + diff --git a/tests/std/array/array_unique_basic.phpt b/tests/std/array/array_unique_basic.phpt new file mode 100644 index 00000000..d76c2e34 --- /dev/null +++ b/tests/std/array/array_unique_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +Test array_unique() function : basic functionality +--FILE-- + "one", 1 => "one", 2 => "two", '2' => "two"); +var_dump( array_unique($input) ); + +// mixed array +$input = array("1" => "one", "two", "one", 2 => "two", "three"); +var_dump( array_unique($input) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unique() : basic functionality *** +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} +array(3) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [4]=> + string(5) "three" +} +Done diff --git a/tests/std/array/array_unique_variation2.phpt b/tests/std/array/array_unique_variation2.phpt new file mode 100644 index 00000000..736aefdb --- /dev/null +++ b/tests/std/array/array_unique_variation2.phpt @@ -0,0 +1,229 @@ +--TEST-- +Test array_unique() function : usage variations - different arrays for 'input' argument +--SKIPIF-- + +--FILE-- +22 +'single quoted string' +"double quoted string" +2222 != 1111.\t 0000 = 0000\n +EOT; + +// arrays passed to $input argument +$inputs = array ( +/*1*/ array(1, 2, 2, 1), // with default keys and numeric values + array(1.1, 2.2, 1.1), // with default keys & float values + array(false, true, false), // with default keys and boolean values + array(), // empty array +/*5*/ array(NULL, null), // with NULL + array("a\v\f", "aaaa\r", "b", "aaaa\r", "\[\]\!\@\#\$\%\^\&\*\(\)\{\}"), // with double quoted strings + array('a\v\f', 'aaaa\r', 'b', 'aaaa\r', '\[\]\!\@\#\$\%\^\&\*\(\)\{\}'), // with single quoted strings + array("h1" => $blank_line, "h2" => $multiline_string, "h3" => $diff_whitespaces, $blank_line), // with heredocs + + // associative arrays +/*9*/ array(1 => "one", 2 => "two", 2 => "two"), // explicit numeric keys, string values + array("one" => 1, "two" => 2, "1" => 1 ), // string keys & numeric values + array( 1 => 10, 2 => 20, 4 => 40, 5 => 10), // explicit numeric keys and numeric values + array( "one" => "ten", "two" => "twenty", "10" => "ten"), // string key/value + array("one" => 1, 2 => "two", 4 => "four"), //mixed + + // associative array, containing null/empty/boolean values as key/value +/*14*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), +/*18*/ array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), +); + +// loop through each sub-array of $inputs to check the behavior of array_unique() +$iterator = 1; +foreach($inputs as $input) { + echo "-- Iteration $iterator --\n"; + var_dump( array_unique($input, SORT_STRING) ); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unique() : Passing different arrays to $input argument *** +-- Iteration 1 -- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +-- Iteration 2 -- +array(2) { + [0]=> + float(1.1) + [1]=> + float(2.2) +} +-- Iteration 3 -- +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} +-- Iteration 4 -- +array(0) { +} +-- Iteration 5 -- +array(1) { + [0]=> + NULL +} +-- Iteration 6 -- +array(4) { + [0]=> + string(3) "a " + [1]=> + string(5) "aaaa " + [2]=> + string(1) "b" + [4]=> + string(27) "\[\]\!\@\#$\%\^\&\*\(\)\{\}" +} +-- Iteration 7 -- +array(4) { + [0]=> + string(5) "a\v\f" + [1]=> + string(6) "aaaa\r" + [2]=> + string(1) "b" + [4]=> + string(28) "\[\]\!\@\#\$\%\^\&\*\(\)\{\}" +} +-- Iteration 8 -- +array(3) { + ["h1"]=> + string(1) " +" + ["h2"]=> + string(88) "hello world +The quick brown fox jumped over; +the lazy dog +This is a double quoted string" + ["h3"]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" +} +-- Iteration 9 -- +array(2) { + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} +-- Iteration 10 -- +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +-- Iteration 11 -- +array(3) { + [1]=> + int(10) + [2]=> + int(20) + [4]=> + int(40) +} +-- Iteration 12 -- +array(2) { + ["one"]=> + string(3) "ten" + ["two"]=> + string(6) "twenty" +} +-- Iteration 13 -- +array(3) { + ["one"]=> + int(1) + [2]=> + string(3) "two" + [4]=> + string(4) "four" +} +-- Iteration 14 -- +array(2) { + [""]=> + string(4) "null" + ["NULL"]=> + NULL +} +-- Iteration 15 -- +array(4) { + [1]=> + string(4) "true" + [0]=> + string(5) "false" + ["false"]=> + bool(false) + ["true"]=> + bool(true) +} +-- Iteration 16 -- +array(2) { + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" +} +-- Iteration 17 -- +array(2) { + [1]=> + string(0) "" + [6]=> + bool(true) +} +-- Iteration 18 -- +array(3) { + [""]=> + int(4) + [0]=> + int(5) + [1]=> + int(6) +} +Done diff --git a/tests/std/array/array_unique_variation3.phpt b/tests/std/array/array_unique_variation3.phpt new file mode 100644 index 00000000..015f42d3 --- /dev/null +++ b/tests/std/array/array_unique_variation3.phpt @@ -0,0 +1,109 @@ +--TEST-- +Test array_unique() function : usage variations - associative array with different keys +--SKIPIF-- + +--FILE-- + "0", 1 => "0"), + array(1 => "1", 2 => "2", 3 => 1, 4 => "4"), + // arrays with string keys + /*5*/ + array('\tHello' => 111, 're\td' => "color", '\v\fworld' => 2.2, 'pen\n' => 111), + array("\tHello" => 111, "re\td" => "color", "\v\fworld" => 2.2, "pen\n" => 111), + array("hello", $heredoc => "string", "string"), + // array with object, unset variable and resource variable + /*8*/ + array(@$unset_var => "hello", $fp => 'resource', 11, "hello"), + ); + // loop through each sub-array of $inputs to check the behavior of array_unique() + $iterator = 1; + foreach ($inputs as $input) { + echo "-- Iteration {$iterator} --\n"; + var_dump(array_unique($input)); + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_unique() : assoc. array with diff. keys passed to $input argument *** + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d +-- Iteration 1 -- +array(1) { + [0]=> + string(1) "0" +} +-- Iteration 2 -- +array(3) { + [1]=> + string(1) "1" + [2]=> + string(1) "2" + [4]=> + string(1) "4" +} +-- Iteration 3 -- +array(3) { + ["\tHello"]=> + int(111) + ["re\td"]=> + string(5) "color" + ["\v\fworld"]=> + float(2.2) +} +-- Iteration 4 -- +array(3) { + [" Hello"]=> + int(111) + ["re d"]=> + string(5) "color" + [" world"]=> + float(2.2) +} +-- Iteration 5 -- +array(2) { + [0]=> + string(5) "hello" + ["Hello world"]=> + string(6) "string" +} +-- Iteration 6 -- +array(3) { + [""]=> + string(5) "hello" + [5]=> + string(8) "resource" + [6]=> + int(11) +} +Done diff --git a/tests/std/array/array_unique_variation4.phpt b/tests/std/array/array_unique_variation4.phpt new file mode 100644 index 00000000..92ed76e6 --- /dev/null +++ b/tests/std/array/array_unique_variation4.phpt @@ -0,0 +1,106 @@ +--TEST-- +Test array_unique() function : usage variations - associative array with different values +--SKIPIF-- + +--FILE-- + 0, '1' => 0), + array("one" => 1, 'two' => 2, "three" => 1, 4 => 1), + // arrays with string values + /*5*/ + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "\tHello"), + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => '\tHello'), + array(1 => "hello", "heredoc" => $heredoc, $heredoc), + // array with object, unset variable and resource variable + /*8*/ + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp, new classA(), $fp), + ); + // loop through each sub-array of $inputs to check the behavior of array_unique() + $iterator = 1; + foreach ($inputs as $input) { + echo "-- Iteration {$iterator} --\n"; + var_dump(array_unique($input)); + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_unique() : assoc. array with diff. values to $input argument *** +-- Iteration 1 -- +array(1) { + [0]=> + int(0) +} +-- Iteration 2 -- +array(2) { + ["one"]=> + int(1) + ["two"]=> + int(2) +} +-- Iteration 3 -- +array(3) { + [111]=> + string(6) " Hello" + ["red"]=> + string(6) "col or" + [2]=> + string(7) " world" +} +-- Iteration 4 -- +array(3) { + [111]=> + string(7) "\tHello" + ["red"]=> + string(7) "col\tor" + [2]=> + string(9) "\v\fworld" +} +-- Iteration 5 -- +array(2) { + [1]=> + string(5) "hello" + ["heredoc"]=> + string(11) "Hello world" +} +-- Iteration 6 -- +array(3) { + [11]=> + object(classA)#%d (0) { + } + ["unset"]=> + NULL + ["resource"]=> + resource(%d) of type (stream) +} +Done diff --git a/tests/std/array/array_unique_variation5.phpt b/tests/std/array/array_unique_variation5.phpt new file mode 100644 index 00000000..8a2df526 --- /dev/null +++ b/tests/std/array/array_unique_variation5.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test array_unique() function : usage variations - array with duplicate keys +--FILE-- + "one", 2 => "two", 2 => "2", 3 => "three", 1 => "1", "1", "2"); +var_dump( array_unique($input) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unique() : array with duplicate keys for $input argument *** +array(3) { + [1]=> + string(1) "1" + [2]=> + string(1) "2" + [3]=> + string(5) "three" +} +Done diff --git a/tests/std/array/array_unique_variation6.phpt b/tests/std/array/array_unique_variation6.phpt new file mode 100644 index 00000000..f1a888d0 --- /dev/null +++ b/tests/std/array/array_unique_variation6.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test array_unique() function : usage variations - array with reference variables +--SKIPIF-- + +--FILE-- + 0, + 1 => &$value4, + 2 => &$value2, + 3 => "hello", + 4 => &$value3, + 5 => $value4 +); + +var_dump( array_unique($input, SORT_STRING) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unique() : array with reference variables for $input argument *** +array(2) { + [0]=> + int(0) + [1]=> + &string(5) "hello" +} +Done diff --git a/tests/std/array/array_unique_variation7.phpt b/tests/std/array/array_unique_variation7.phpt new file mode 100644 index 00000000..e5a7542b --- /dev/null +++ b/tests/std/array/array_unique_variation7.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test array_unique() function : usage variations - binary safe checking +--FILE-- + "hello", "str2" => "world"); + +var_dump( array_unique($input) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unique() : array with binary data for $input argument *** +array(3) { + [0]=> + string(1) "1" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" +} +Done diff --git a/tests/std/array/array_unique_variation8.phpt b/tests/std/array/array_unique_variation8.phpt new file mode 100644 index 00000000..ae9faffc --- /dev/null +++ b/tests/std/array/array_unique_variation8.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test array_unique() function : usage variations - two dimensional arrays +--FILE-- + "hello", "str2" => 'world'), + array(1 => "one", 2 => "two", "one", 'two'), + array(1, 2, 3, 1) +); + +var_dump( array_unique($input, SORT_STRING) ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing array_unique() : two dimensional array for $input argument *** + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d + +Warning: Array to string conversion in %s on line %d +array(1) { + [0]=> + array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(1) + } +} +Done diff --git a/tests/std/array/array_unique_variation9.phpt b/tests/std/array/array_unique_variation9.phpt new file mode 100644 index 00000000..aa083010 --- /dev/null +++ b/tests/std/array/array_unique_variation9.phpt @@ -0,0 +1,109 @@ +--TEST-- +Test array_unique() function : usage variations - more than 16 elements +--CREDITS-- +Matteo Beccati +--FILE-- + 'acls_channel', + 1 => 'acls_channel', + 2 => 'ad_zone_assoc', + 3 => 'ad_zone_assoc', + 4 => 'ad_zone_assoc', + 5 => 'affiliates', + 6 => 'affiliates', + 7 => 'affiliates', + 8 => 'banners', + 9 => 'banners', + 10 => 'banners', + 11 => 'campaigns', + 12 => 'campaigns', + 13 => 'campaigns', + 14 => 'campaigns_trackers', + 15 => 'campaigns_trackers', + 16 => 'campaigns_trackers', + 17 => 'clients', + 18 => 'clients', + 19 => 'clients', + 20 => 'data_intermediate_ad', + 21 => 'data_intermediate_ad', + 22 => 'data_summary_ad_hourly', + 23 => 'data_summary_ad_hourly', + 24 => 'data_summary_zone_country_daily', + 25 => 'data_summary_zone_country_daily', + 26 => 'data_summary_zone_country_daily', + 27 => 'data_summary_zone_country_forecast', + 28 => 'data_summary_zone_country_forecast', + 29 => 'data_summary_zone_country_forecast', + 30 => 'data_summary_zone_country_monthly', + 31 => 'data_summary_zone_country_monthly', + 32 => 'data_summary_zone_country_monthly', + 33 => 'data_summary_zone_domain_page_daily', + 34 => 'data_summary_zone_domain_page_daily', + 35 => 'data_summary_zone_domain_page_daily', + 36 => 'data_summary_zone_domain_page_forecast', + 37 => 'data_summary_zone_domain_page_forecast', + 38 => 'data_summary_zone_domain_page_forecast', + 39 => 'data_summary_zone_domain_page_monthly', + 40 => 'data_summary_zone_domain_page_monthly', + 41 => 'data_summary_zone_domain_page_monthly', + 42 => 'data_summary_zone_site_keyword_daily', + 43 => 'data_summary_zone_site_keyword_daily', + 44 => 'data_summary_zone_site_keyword_daily', + 45 => 'data_summary_zone_site_keyword_forecast', + 46 => 'data_summary_zone_site_keyword_forecast', + 47 => 'data_summary_zone_site_keyword_forecast', + 48 => 'data_summary_zone_site_keyword_monthly', + 49 => 'data_summary_zone_site_keyword_monthly', + 50 => 'data_summary_zone_site_keyword_monthly', + 51 => 'data_summary_zone_source_daily', + 52 => 'data_summary_zone_source_daily', + 53 => 'data_summary_zone_source_daily', + 54 => 'data_summary_zone_source_forecast', + 55 => 'data_summary_zone_source_forecast', + 56 => 'data_summary_zone_source_forecast', + 57 => 'data_summary_zone_source_monthly', + 58 => 'data_summary_zone_source_monthly', + 59 => 'data_summary_zone_source_monthly', + 60 => 'placement_zone_assoc', + 61 => 'placement_zone_assoc', + 62 => 'placement_zone_assoc', + 63 => 'trackers', + 64 => 'trackers', + 65 => 'trackers', + 66 => 'variables', + 67 => 'variables', + 68 => 'variables', +); + +print_r(array_unique($a)); +?> +--EXPECT-- +Array +( + [0] => acls_channel + [2] => ad_zone_assoc + [5] => affiliates + [8] => banners + [11] => campaigns + [14] => campaigns_trackers + [17] => clients + [20] => data_intermediate_ad + [22] => data_summary_ad_hourly + [24] => data_summary_zone_country_daily + [27] => data_summary_zone_country_forecast + [30] => data_summary_zone_country_monthly + [33] => data_summary_zone_domain_page_daily + [36] => data_summary_zone_domain_page_forecast + [39] => data_summary_zone_domain_page_monthly + [42] => data_summary_zone_site_keyword_daily + [45] => data_summary_zone_site_keyword_forecast + [48] => data_summary_zone_site_keyword_monthly + [51] => data_summary_zone_source_daily + [54] => data_summary_zone_source_forecast + [57] => data_summary_zone_source_monthly + [60] => placement_zone_assoc + [63] => trackers + [66] => variables +) diff --git a/tests/std/array/array_unshift.phpt b/tests/std/array/array_unshift.phpt new file mode 100644 index 00000000..265de4e8 --- /dev/null +++ b/tests/std/array/array_unshift.phpt @@ -0,0 +1,31 @@ +--TEST-- +array_unshift() tests +--FILE-- + +--EXPECT-- +int(1) +array(1) { + [0]=> + string(0) "" +} +int(2) +array(2) { + [0]=> + array(1) { + [0]=> + string(0) "" + } + [1]=> + string(0) "" +} +Done diff --git a/tests/std/array/array_unshift_basic1.phpt b/tests/std/array/array_unshift_basic1.phpt new file mode 100644 index 00000000..ef0de5e7 --- /dev/null +++ b/tests/std/array/array_unshift_basic1.phpt @@ -0,0 +1,58 @@ +--TEST-- +Test array_unshift() function : basic functionality - array with default keys for 'array' argument +--FILE-- + +--EXPECT-- +*** Testing array_unshift() : basic functionality with default key array *** +int(3) +array(3) { + [0]=> + int(10) + [1]=> + int(1) + [2]=> + int(2) +} +int(5) +array(5) { + [0]=> + int(222) + [1]=> + string(5) "hello" + [2]=> + float(12.33) + [3]=> + int(1) + [4]=> + int(2) +} +Done diff --git a/tests/std/array/array_unshift_basic2.phpt b/tests/std/array/array_unshift_basic2.phpt new file mode 100644 index 00000000..7c19dcda --- /dev/null +++ b/tests/std/array/array_unshift_basic2.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test array_unshift() function : basic functionality - associative arrays for 'array' argument +--FILE-- + "first", "s" => 'second', 1 => "one", 2 => 'two'); + +// Calling array_unshift() with default argument +$temp_array = $array; +// returns element count in the resulting array after arguments are pushed to +// beginning of the given array +var_dump( array_unshift($temp_array, 10) ); + +// dump the resulting array +var_dump($temp_array); + +// Calling array_unshift() with optional arguments +$temp_array = $array; +// returns element count in the resulting array after arguments are pushed to +// beginning of the given array +var_dump( array_unshift($temp_array, 222, "hello", 12.33) ); + +// dump the resulting array +var_dump($temp_array); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unshift() : basic functionality with associative array *** +int(5) +array(5) { + [0]=> + int(10) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + string(3) "one" + [2]=> + string(3) "two" +} +int(7) +array(7) { + [0]=> + int(222) + [1]=> + string(5) "hello" + [2]=> + float(12.33) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + string(3) "one" + [4]=> + string(3) "two" +} +Done diff --git a/tests/std/array/array_unshift_empty.phpt b/tests/std/array/array_unshift_empty.phpt new file mode 100644 index 00000000..43bad5b3 --- /dev/null +++ b/tests/std/array/array_unshift_empty.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test array_unshift() function : prepend array with empty set +--FILE-- + +--EXPECT-- +int(3) +int(3) +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +Done diff --git a/tests/std/array/array_unshift_object.phpt b/tests/std/array/array_unshift_object.phpt new file mode 100644 index 00000000..a7deb4b8 --- /dev/null +++ b/tests/std/array/array_unshift_object.phpt @@ -0,0 +1,273 @@ +--TEST-- +Test array_unshift() function : passing object for 'var' argument +--SKIPIF-- + + +--FILE-- + "first", "s" => 'second', 1, 2.222); + // array containing different types of objects as elements + $vars = array(new SimpleClass(), new EmptyClass(), new ChildClass(), new FinalClass(), new StaticClass()); + // loop through the various elements of $arrays to check the functionality of array_unshift + $iterator = 1; + foreach ($vars as $var) { + echo "-- Iteration {$iterator} --\n"; + /* with default argument */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump(array_unshift($temp_array, $var)); + // dump the resulting array + var_dump($temp_array); + /* with optional arguments */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump(array_unshift($temp_array, $var, "hello", 'world')); + // dump the resulting array + var_dump($temp_array); + $iterator++; + } + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_unshift() : Passing object to $var argument *** +-- Iteration 1 -- +int(5) +array(5) { + [0]=> + object(SimpleClass)#%d (1) { + ["var1"]=> + int(1) + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + object(SimpleClass)#%d (1) { + ["var1"]=> + int(1) + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 2 -- +int(5) +array(5) { + [0]=> + object(EmptyClass)#%d (0) { + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + object(EmptyClass)#%d (0) { + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 3 -- +int(5) +array(5) { + [0]=> + object(ChildClass)#%d (2) { + ["var2":protected]=> + int(5) + ["var3":"ChildClass":private]=> + NULL + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + object(ChildClass)#%d (2) { + ["var2":protected]=> + int(5) + ["var3":"ChildClass":private]=> + NULL + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 4 -- +int(5) +array(5) { + [0]=> + object(FinalClass)#%d (1) { + ["var4":"FinalClass":private]=> + NULL + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + object(FinalClass)#%d (1) { + ["var4":"FinalClass":private]=> + NULL + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 5 -- +int(5) +array(5) { + [0]=> + object(StaticClass)#%d (0) { + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + object(StaticClass)#%d (0) { + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +Done diff --git a/tests/std/array/array_unshift_variation2.phpt b/tests/std/array/array_unshift_variation2.phpt new file mode 100644 index 00000000..b23b151f --- /dev/null +++ b/tests/std/array/array_unshift_variation2.phpt @@ -0,0 +1,1048 @@ +--TEST-- +Test array_unshift() function : usage variations - all possible values for 'var' argument +--SKIPIF-- + + +--FILE-- + "first", "s" => 'second', 1, 2.222); + // get a resource variable + $fp = fopen(__FILE__, "r"); + // heredoc string + $heredoc = << 'red', 'item' => 'pen'), + // null data + /*15*/ + NULL, + null, + // boolean data + /*17*/ + true, + false, + TRUE, + FALSE, + // empty data + /*21*/ + "", + '', + // string data + /*23*/ + "string", + 'string', + $heredoc, + // object data + /*26*/ + new classA(), + // undefined data + @$undefined_var, + // unset data + @$unset_var, + // resource variable + /*29*/ + $fp, + ); + // loop through each element of $vars to check the functionality of array_unshift() + $iterator = 1; + foreach ($vars as $var) { + echo "-- Iteration {$iterator} --\n"; + $temp_array = $array; + /* with default argument */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + var_dump(array_unshift($temp_array, $var)); + // dump the resulting array + var_dump($temp_array); + /* with optional arguments */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump(array_unshift($temp_array, $var, "hello", 'world')); + // dump the resulting array + var_dump($temp_array); + $iterator++; + } + // close the file resource used + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_unshift() : all possible values for $var argument *** +-- Iteration 1 -- +int(5) +array(5) { + [0]=> + int(0) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + int(0) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 2 -- +int(5) +array(5) { + [0]=> + int(1) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + int(1) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 3 -- +int(5) +array(5) { + [0]=> + int(12345) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + int(12345) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 4 -- +int(5) +array(5) { + [0]=> + int(-2345) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + int(-2345) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 5 -- +int(5) +array(5) { + [0]=> + float(10.5) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + float(10.5) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 6 -- +int(5) +array(5) { + [0]=> + float(-10.5) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + float(-10.5) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 7 -- +int(5) +array(5) { + [0]=> + float(123456789000) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + float(123456789000) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 8 -- +int(5) +array(5) { + [0]=> + float(1.23456789E-9) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + float(1.23456789E-9) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 9 -- +int(5) +array(5) { + [0]=> + float(0.5) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + float(0.5) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 10 -- +int(5) +array(5) { + [0]=> + array(0) { + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + array(0) { + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 11 -- +int(5) +array(5) { + [0]=> + array(1) { + [0]=> + int(0) + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + array(1) { + [0]=> + int(0) + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 12 -- +int(5) +array(5) { + [0]=> + array(1) { + [0]=> + int(1) + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + array(1) { + [0]=> + int(1) + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 13 -- +int(5) +array(5) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + array(2) { + [0]=> + int(1) + [1]=> + int(2) + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 14 -- +int(5) +array(5) { + [0]=> + array(2) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + array(2) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 15 -- +int(5) +array(5) { + [0]=> + NULL + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + NULL + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 16 -- +int(5) +array(5) { + [0]=> + NULL + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + NULL + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 17 -- +int(5) +array(5) { + [0]=> + bool(true) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + bool(true) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 18 -- +int(5) +array(5) { + [0]=> + bool(false) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + bool(false) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 19 -- +int(5) +array(5) { + [0]=> + bool(true) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + bool(true) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 20 -- +int(5) +array(5) { + [0]=> + bool(false) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + bool(false) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 21 -- +int(5) +array(5) { + [0]=> + string(0) "" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(0) "" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 22 -- +int(5) +array(5) { + [0]=> + string(0) "" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(0) "" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 23 -- +int(5) +array(5) { + [0]=> + string(6) "string" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(6) "string" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 24 -- +int(5) +array(5) { + [0]=> + string(6) "string" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(6) "string" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 25 -- +int(5) +array(5) { + [0]=> + string(11) "hello world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(11) "hello world" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 26 -- +int(5) +array(5) { + [0]=> + object(classA)#%d (0) { + } + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + object(classA)#%d (0) { + } + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 27 -- +int(5) +array(5) { + [0]=> + NULL + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + NULL + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 28 -- +int(5) +array(5) { + [0]=> + NULL + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + NULL + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 29 -- +int(5) +array(5) { + [0]=> + resource(%d) of type (stream) + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + resource(%d) of type (stream) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +Done diff --git a/tests/std/array/array_unshift_variation3.phpt b/tests/std/array/array_unshift_variation3.phpt new file mode 100644 index 00000000..6ed96472 --- /dev/null +++ b/tests/std/array/array_unshift_variation3.phpt @@ -0,0 +1,568 @@ +--TEST-- +Test array_unshift() function : usage variations - different array values for 'array' argument +--SKIPIF-- + +--FILE-- + "one", 2 => "two", 3 => "three"), // explicit numeric keys, string values + array("one" => 1, "two" => 2, "three" => 3 ), // string keys & numeric values + array( 1 => 10, 2 => 20, 4 => 40, 3 => 30), // explicit numeric keys and numeric values + array( "one" => "ten", "two" => "twenty", "three" => "thirty"), // string key/value + array("one" => 1, 2 => "two", 4 => "four"), //mixed + + // associative array, containing null/empty/boolean values as key/value +/*13*/ array(NULL => "NULL", null => "null", "NULL" => NULL, "null" => null), + array(true => "true", false => "false", "false" => false, "true" => true), + array("" => "emptyd", '' => 'emptys', "emptyd" => "", 'emptys' => ''), + array(1 => '', 2 => "", 3 => NULL, 4 => null, 5 => false, 6 => true), + array('' => 1, "" => 2, NULL => 3, null => 4, false => 5, true => 6), + + // array with repetitive keys +/*18*/ array("One" => 1, "two" => 2, "One" => 10, "two" => 20, "three" => 3) +); + +// loop through the various elements of $arrays to test array_unshift() +$iterator = 1; +foreach($arrays as $array) { + echo "-- Iteration $iterator --\n"; + + /* with default argument */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump( array_unshift($temp_array, $var) ); + + // dump the resulting array + var_dump($temp_array); + + /* with optional arguments */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump( array_unshift($temp_array, $var, "hello", 'world') ); + + // dump the resulting array + var_dump($temp_array); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unshift() : different arrays for $array argument *** +-- Iteration 1 -- +int(3) +array(3) { + [0]=> + int(10) + [1]=> + int(1) + [2]=> + int(2) +} +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + int(1) + [4]=> + int(2) +} +-- Iteration 2 -- +int(3) +array(3) { + [0]=> + int(10) + [1]=> + float(1.1) + [2]=> + float(2.2) +} +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + float(1.1) + [4]=> + float(2.2) +} +-- Iteration 3 -- +int(3) +array(3) { + [0]=> + int(10) + [1]=> + array(1) { + [0]=> + int(2) + } + [2]=> + array(1) { + [0]=> + int(1) + } +} +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + array(1) { + [0]=> + int(2) + } + [4]=> + array(1) { + [0]=> + int(1) + } +} +-- Iteration 4 -- +int(3) +array(3) { + [0]=> + int(10) + [1]=> + bool(false) + [2]=> + bool(true) +} +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + bool(false) + [4]=> + bool(true) +} +-- Iteration 5 -- +int(1) +array(1) { + [0]=> + int(10) +} +int(3) +array(3) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" +} +-- Iteration 6 -- +int(2) +array(2) { + [0]=> + int(10) + [1]=> + NULL +} +int(4) +array(4) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + NULL +} +-- Iteration 7 -- +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(1) "a" + [2]=> + string(4) "aaaa" + [3]=> + string(1) "b" + [4]=> + string(4) "bbbb" + [5]=> + string(1) "c" + [6]=> + string(5) "ccccc" +} +int(9) +array(9) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(1) "a" + [4]=> + string(4) "aaaa" + [5]=> + string(1) "b" + [6]=> + string(4) "bbbb" + [7]=> + string(1) "c" + [8]=> + string(5) "ccccc" +} +-- Iteration 8 -- +int(4) +array(4) { + [0]=> + int(10) + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + string(5) "three" +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(3) "one" + [4]=> + string(3) "two" + [5]=> + string(5) "three" +} +-- Iteration 9 -- +int(4) +array(4) { + [0]=> + int(10) + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) +} +-- Iteration 10 -- +int(5) +array(5) { + [0]=> + int(10) + [1]=> + int(10) + [2]=> + int(20) + [3]=> + int(40) + [4]=> + int(30) +} +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + int(10) + [4]=> + int(20) + [5]=> + int(40) + [6]=> + int(30) +} +-- Iteration 11 -- +int(4) +array(4) { + [0]=> + int(10) + ["one"]=> + string(3) "ten" + ["two"]=> + string(6) "twenty" + ["three"]=> + string(6) "thirty" +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["one"]=> + string(3) "ten" + ["two"]=> + string(6) "twenty" + ["three"]=> + string(6) "thirty" +} +-- Iteration 12 -- +int(4) +array(4) { + [0]=> + int(10) + ["one"]=> + int(1) + [1]=> + string(3) "two" + [2]=> + string(4) "four" +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["one"]=> + int(1) + [3]=> + string(3) "two" + [4]=> + string(4) "four" +} +-- Iteration 13 -- +int(4) +array(4) { + [0]=> + int(10) + [""]=> + string(4) "null" + ["NULL"]=> + NULL + ["null"]=> + NULL +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [""]=> + string(4) "null" + ["NULL"]=> + NULL + ["null"]=> + NULL +} +-- Iteration 14 -- +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(4) "true" + [2]=> + string(5) "false" + ["false"]=> + bool(false) + ["true"]=> + bool(true) +} +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(4) "true" + [4]=> + string(5) "false" + ["false"]=> + bool(false) + ["true"]=> + bool(true) +} +-- Iteration 15 -- +int(4) +array(4) { + [0]=> + int(10) + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" + ["emptys"]=> + string(0) "" +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [""]=> + string(6) "emptys" + ["emptyd"]=> + string(0) "" + ["emptys"]=> + string(0) "" +} +-- Iteration 16 -- +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(0) "" + [2]=> + string(0) "" + [3]=> + NULL + [4]=> + NULL + [5]=> + bool(false) + [6]=> + bool(true) +} +int(9) +array(9) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(0) "" + [4]=> + string(0) "" + [5]=> + NULL + [6]=> + NULL + [7]=> + bool(false) + [8]=> + bool(true) +} +-- Iteration 17 -- +int(4) +array(4) { + [0]=> + int(10) + [""]=> + int(4) + [1]=> + int(5) + [2]=> + int(6) +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [""]=> + int(4) + [3]=> + int(5) + [4]=> + int(6) +} +-- Iteration 18 -- +int(4) +array(4) { + [0]=> + int(10) + ["One"]=> + int(10) + ["two"]=> + int(20) + ["three"]=> + int(3) +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["One"]=> + int(10) + ["two"]=> + int(20) + ["three"]=> + int(3) +} +Done diff --git a/tests/std/array/array_unshift_variation4.phpt b/tests/std/array/array_unshift_variation4.phpt new file mode 100644 index 00000000..908557fc --- /dev/null +++ b/tests/std/array/array_unshift_variation4.phpt @@ -0,0 +1,316 @@ +--TEST-- +Test array_unshift() function : usage variations - assoc. array with diff. keys for 'array' argument +--SKIPIF-- + +--FILE-- + "0"), + array(1 => "1"), + array(1 => "1", 2 => "2", 3 => "3", 4 => "4"), + // arrays with string keys + /*7*/ + array('\tHello' => 111, 're\td' => "color", '\v\fworld' => 2.2, 'pen\n' => 33), + array("\tHello" => 111, "re\td" => "color", "\v\fworld" => 2.2, "pen\n" => 33), + array("hello", $heredoc => "string"), + // heredoc + // array with object, unset variable and resource variable + array(@$unset_var => "hello", $fp => 'resource'), + // array with mixed keys + /*11*/ + array('hello' => 1, "fruit" => 2.2, $fp => 'resource', 133 => "int", @$unset_var => "unset", $heredoc => "heredoc"), + ); + // loop through the various elements of $arrays to test array_unshift() + $iterator = 1; + foreach ($arrays as $array) { + echo "-- Iteration {$iterator} --\n"; + /* with default argument */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump(array_unshift($temp_array, $var)); + // dump the resulting array + var_dump($temp_array); + /* with optional arguments */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump(array_unshift($temp_array, $var, "hello", 'world')); + // dump the resulting array + var_dump($temp_array); + $iterator++; + } + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_unshift() : associative array with different keys *** + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d + +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d +-- Iteration 1 -- +int(1) +array(1) { + [0]=> + int(10) +} +int(3) +array(3) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" +} +-- Iteration 2 -- +int(2) +array(2) { + [0]=> + int(10) + [1]=> + string(1) "0" +} +int(4) +array(4) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(1) "0" +} +-- Iteration 3 -- +int(2) +array(2) { + [0]=> + int(10) + [1]=> + string(1) "1" +} +int(4) +array(4) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(1) "1" +} +-- Iteration 4 -- +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(1) "1" + [2]=> + string(1) "2" + [3]=> + string(1) "3" + [4]=> + string(1) "4" +} +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(1) "1" + [4]=> + string(1) "2" + [5]=> + string(1) "3" + [6]=> + string(1) "4" +} +-- Iteration 5 -- +int(5) +array(5) { + [0]=> + int(10) + ["\tHello"]=> + int(111) + ["re\td"]=> + string(5) "color" + ["\v\fworld"]=> + float(2.2) + ["pen\n"]=> + int(33) +} +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["\tHello"]=> + int(111) + ["re\td"]=> + string(5) "color" + ["\v\fworld"]=> + float(2.2) + ["pen\n"]=> + int(33) +} +-- Iteration 6 -- +int(5) +array(5) { + [0]=> + int(10) + [" Hello"]=> + int(111) + ["re d"]=> + string(5) "color" + [" world"]=> + float(2.2) + ["pen +"]=> + int(33) +} +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [" Hello"]=> + int(111) + ["re d"]=> + string(5) "color" + [" world"]=> + float(2.2) + ["pen +"]=> + int(33) +} +-- Iteration 7 -- +int(3) +array(3) { + [0]=> + int(10) + [1]=> + string(5) "hello" + ["Hello world"]=> + string(6) "string" +} +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(5) "hello" + ["Hello world"]=> + string(6) "string" +} +-- Iteration 8 -- +int(3) +array(3) { + [0]=> + int(10) + [""]=> + string(5) "hello" + [1]=> + string(8) "resource" +} +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [""]=> + string(5) "hello" + [3]=> + string(8) "resource" +} +-- Iteration 9 -- +int(7) +array(7) { + [0]=> + int(10) + ["hello"]=> + int(1) + ["fruit"]=> + float(2.2) + [1]=> + string(8) "resource" + [2]=> + string(3) "int" + [""]=> + string(5) "unset" + ["Hello world"]=> + string(7) "heredoc" +} +int(9) +array(9) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["hello"]=> + int(1) + ["fruit"]=> + float(2.2) + [3]=> + string(8) "resource" + [4]=> + string(3) "int" + [""]=> + string(5) "unset" + ["Hello world"]=> + string(7) "heredoc" +} +Done diff --git a/tests/std/array/array_unshift_variation5.phpt b/tests/std/array/array_unshift_variation5.phpt new file mode 100644 index 00000000..303971f6 --- /dev/null +++ b/tests/std/array/array_unshift_variation5.phpt @@ -0,0 +1,383 @@ +--TEST-- +Test array_unshift() function : usage variations - assoc. array with diff values for 'array' argument +--INI-- +precision=12 +--SKIPIF-- + +--FILE-- + 0), + array("1" => 1), + array("one" => 1, 'two' => 2, "three" => 3, 4 => 4), + // arrays with float values + /*5*/ + array("float" => 2.3333), + array("f1" => 1.2, 'f2' => 3.33, 3 => 4.89999922839999, 'f4' => 33333333.333333), + // arrays with string values + /*7*/ + array(111 => "\tHello", "red" => "col\tor", 2 => "\v\fworld", 3 => "pen\n"), + array(111 => '\tHello', "red" => 'col\tor', 2 => '\v\fworld', 3 => 'pen\n'), + array(1 => "hello", "heredoc" => $heredoc), + // array with object, unset variable and resource variable + array(11 => new classA(), "unset" => @$unset_var, "resource" => $fp), + // array with mixed values + /*11*/ + array(1 => 'hello', 2 => new classA(), 222 => "fruit", 'resource' => $fp, "int" => 133, "float" => 444.432, "unset" => @$unset_var, "heredoc" => $heredoc), + ); + // loop through the various elements of $arrays to test array_unshift() + $iterator = 1; + foreach ($arrays as $array) { + echo "-- Iteration {$iterator} --\n"; + /* with default argument */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump(array_unshift($temp_array, $var)); + // dump the resulting array + var_dump($temp_array); + /* with optional arguments */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump(array_unshift($temp_array, $var, "hello", 'world')); + // dump the resulting array + var_dump($temp_array); + $iterator++; + } + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_unshift() : associative array with different values *** +-- Iteration 1 -- +int(1) +array(1) { + [0]=> + int(10) +} +int(3) +array(3) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" +} +-- Iteration 2 -- +int(2) +array(2) { + [0]=> + int(10) + [1]=> + int(0) +} +int(4) +array(4) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + int(0) +} +-- Iteration 3 -- +int(2) +array(2) { + [0]=> + int(10) + [1]=> + int(1) +} +int(4) +array(4) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + int(1) +} +-- Iteration 4 -- +int(5) +array(5) { + [0]=> + int(10) + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + [1]=> + int(4) +} +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + [3]=> + int(4) +} +-- Iteration 5 -- +int(2) +array(2) { + [0]=> + int(10) + ["float"]=> + float(2.3333) +} +int(4) +array(4) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["float"]=> + float(2.3333) +} +-- Iteration 6 -- +int(5) +array(5) { + [0]=> + int(10) + ["f1"]=> + float(1.2) + ["f2"]=> + float(3.33) + [1]=> + float(4.89999922839999) + ["f4"]=> + float(33333333.333333) +} +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f1"]=> + float(1.2) + ["f2"]=> + float(3.33) + [3]=> + float(4.89999922839999) + ["f4"]=> + float(33333333.333333) +} +-- Iteration 7 -- +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(6) " Hello" + ["red"]=> + string(6) "col or" + [2]=> + string(7) " world" + [3]=> + string(4) "pen +" +} +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(6) " Hello" + ["red"]=> + string(6) "col or" + [4]=> + string(7) " world" + [5]=> + string(4) "pen +" +} +-- Iteration 8 -- +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(7) "\tHello" + ["red"]=> + string(7) "col\tor" + [2]=> + string(9) "\v\fworld" + [3]=> + string(5) "pen\n" +} +int(7) +array(7) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(7) "\tHello" + ["red"]=> + string(7) "col\tor" + [4]=> + string(9) "\v\fworld" + [5]=> + string(5) "pen\n" +} +-- Iteration 9 -- +int(3) +array(3) { + [0]=> + int(10) + [1]=> + string(5) "hello" + ["heredoc"]=> + string(11) "Hello world" +} +int(5) +array(5) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(5) "hello" + ["heredoc"]=> + string(11) "Hello world" +} +-- Iteration 10 -- +int(4) +array(4) { + [0]=> + int(10) + [1]=> + object(classA)#%d (0) { + } + ["unset"]=> + NULL + ["resource"]=> + resource(%d) of type (stream) +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + object(classA)#%d (0) { + } + ["unset"]=> + NULL + ["resource"]=> + resource(%d) of type (stream) +} +-- Iteration 11 -- +int(9) +array(9) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + object(classA)#%d (0) { + } + [3]=> + string(5) "fruit" + ["resource"]=> + resource(%d) of type (stream) + ["int"]=> + int(133) + ["float"]=> + float(444.432) + ["unset"]=> + NULL + ["heredoc"]=> + string(11) "Hello world" +} +int(11) +array(11) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + string(5) "hello" + [4]=> + object(classA)#%d (0) { + } + [5]=> + string(5) "fruit" + ["resource"]=> + resource(%d) of type (stream) + ["int"]=> + int(133) + ["float"]=> + float(444.432) + ["unset"]=> + NULL + ["heredoc"]=> + string(11) "Hello world" +} +Done diff --git a/tests/std/array/array_unshift_variation6.phpt b/tests/std/array/array_unshift_variation6.phpt new file mode 100644 index 00000000..89f7e228 --- /dev/null +++ b/tests/std/array/array_unshift_variation6.phpt @@ -0,0 +1,191 @@ +--TEST-- +Test array_unshift() function : usage variations - two dimensional arrays for 'array' argument +--FILE-- + 'red', 'item' => 'pen', 'place' => 'LA'), + + // numeric array + array(1, 2, 3, 4, 5), + + // combination of numeric and associative arrays + array('a' => 'green', 'red', 'brown', 33, 88, 'orange', 'item' => 'ball') +); + +/* Passing the entire $two_dimensional_array to $array */ + +/* With default argument */ +// returns element count in the resulting array after arguments are pushed to +// beginning of the given array +$temp_array = $two_dimensional_array; +var_dump( array_unshift($temp_array, $var) ); // whole 2-d array + +// dumps the resulting array +var_dump($temp_array); + +/* With optional arguments */ +// returns element count in the resulting array after arguments are pushed to +// beginning of the given array +$temp_array = $two_dimensional_array; +var_dump( array_unshift($temp_array, $var, "hello", 'world') ); // whole 2-d array + +// dumps the resulting array +var_dump($temp_array); + +/* Passing the sub-array within the $two_dimensional_array to $array argument */ + +/* With default argument */ +// returns element count in the resulting array after arguments are pushed to +// beginning of the given array +$temp_array = $two_dimensional_array[0]; +var_dump( array_unshift($temp_array, $var) ); // sub array + +// dumps the resulting array +var_dump($temp_array); + +/* With optional arguments */ +// returns element count in the resulting array after arguments are pushed to +// beginning of the given array +$temp_array = $two_dimensional_array[0]; +var_dump( array_unshift($temp_array, $var, "hello", 'world') ); // sub array + +// dumps the resulting array +var_dump($temp_array); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unshift() : two dimensional arrays for $array argument *** +int(4) +array(4) { + [0]=> + int(10) + [1]=> + array(3) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + ["place"]=> + string(2) "LA" + } + [2]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [3]=> + array(7) { + ["a"]=> + string(5) "green" + [0]=> + string(3) "red" + [1]=> + string(5) "brown" + [2]=> + int(33) + [3]=> + int(88) + [4]=> + string(6) "orange" + ["item"]=> + string(4) "ball" + } +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + [3]=> + array(3) { + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + ["place"]=> + string(2) "LA" + } + [4]=> + array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + } + [5]=> + array(7) { + ["a"]=> + string(5) "green" + [0]=> + string(3) "red" + [1]=> + string(5) "brown" + [2]=> + int(33) + [3]=> + int(88) + [4]=> + string(6) "orange" + ["item"]=> + string(4) "ball" + } +} +int(4) +array(4) { + [0]=> + int(10) + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + ["place"]=> + string(2) "LA" +} +int(6) +array(6) { + [0]=> + int(10) + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["color"]=> + string(3) "red" + ["item"]=> + string(3) "pen" + ["place"]=> + string(2) "LA" +} +Done diff --git a/tests/std/array/array_unshift_variation7.phpt b/tests/std/array/array_unshift_variation7.phpt new file mode 100644 index 00000000..f42ac1cf --- /dev/null +++ b/tests/std/array/array_unshift_variation7.phpt @@ -0,0 +1,211 @@ +--TEST-- +Test array_unshift() function : usage variations - double quoted strings for 'var' argument +--FILE-- + "first", "s" => 'second', 1, 2.222); + +// different variations of double quoted strings to be passed to $var argument +$vars = array ( + "\$ -> This represents the dollar sign. hello dollar!!!", + "\t\r\v The quick brown fo\fx jumped over the lazy dog", + "This is a text with special chars: \!\@\#\$\%\^\&\*\(\)\\", + "hello world\\t", + "This is \ta text in bold letters\r\s\malong with slashes\n : HELLO WORLD\t" +); + +// loop through the various elements of $arrays to test array_unshift() +$iterator = 1; +foreach($vars as $var) { + echo "-- Iteration $iterator --\n"; + $temp_array = $array; // assign $array to another temporary $temp_array + + /* with default argument */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + var_dump( array_unshift($temp_array, $var) ); + +// dump the resulting array + var_dump($temp_array); + + /* with optional arguments */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump( array_unshift($temp_array, $var, "hello", 'world') ); + + // dump the resulting array + var_dump($temp_array); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unshift() : double quoted strings for $var argument *** +-- Iteration 1 -- +int(5) +array(5) { + [0]=> + string(53) "$ -> This represents the dollar sign. hello dollar!!!" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(53) "$ -> This represents the dollar sign. hello dollar!!!" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 2 -- +int(5) +array(5) { + [0]=> + string(49) " The quick brown fo x jumped over the lazy dog" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(49) " The quick brown fo x jumped over the lazy dog" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 3 -- +int(5) +array(5) { + [0]=> + string(55) "This is a text with special chars: \!\@\#$\%\^\&\*\(\)\" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(55) "This is a text with special chars: \!\@\#$\%\^\&\*\(\)\" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 4 -- +int(5) +array(5) { + [0]=> + string(13) "hello world\t" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(13) "hello world\t" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 5 -- +int(5) +array(5) { + [0]=> + string(70) "This is a text in bold letters \s\malong with slashes + : HELLO WORLD " + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(70) "This is a text in bold letters \s\malong with slashes + : HELLO WORLD " + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +Done diff --git a/tests/std/array/array_unshift_variation8.phpt b/tests/std/array/array_unshift_variation8.phpt new file mode 100644 index 00000000..ff87f370 --- /dev/null +++ b/tests/std/array/array_unshift_variation8.phpt @@ -0,0 +1,209 @@ +--TEST-- +Test array_unshift() function : usage variations - single quoted strings for 'var' argument +--FILE-- + "first", "s" => 'second', 1, 2.222); + +// different variations of single quoted strings to be passed to $var argument +$vars = array ( + '\$ -> This represents the dollar sign. hello dollar!!!', + '\t\r\v The quick brown fo\fx jumped over the lazy dog', + 'This is a text with special chars: \!\@\#\$\%\^\&\*\(\)\\', + 'hello world\\t', + 'This is \ta text in bold letters\r\s\malong with slashes\n : HELLO WORLD\t' +); + +// loop through the various elements of $arrays to test array_unshift() +$iterator = 1; +foreach($vars as $var) { + echo "-- Iteration $iterator --\n"; + $temp_array = $array; // assign $array to another temporary $temp_array + + /* with default argument */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + var_dump( array_unshift($temp_array, $var) ); + + // dump the resulting array + var_dump($temp_array); + + /* with optional arguments */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump( array_unshift($temp_array, $var, "hello", 'world') ); + + // dump the resulting array + var_dump($temp_array); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unshift() : single quoted strings for $var argument *** +-- Iteration 1 -- +int(5) +array(5) { + [0]=> + string(54) "\$ -> This represents the dollar sign. hello dollar!!!" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(54) "\$ -> This represents the dollar sign. hello dollar!!!" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 2 -- +int(5) +array(5) { + [0]=> + string(53) "\t\r\v The quick brown fo\fx jumped over the lazy dog" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(53) "\t\r\v The quick brown fo\fx jumped over the lazy dog" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 3 -- +int(5) +array(5) { + [0]=> + string(56) "This is a text with special chars: \!\@\#\$\%\^\&\*\(\)\" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(56) "This is a text with special chars: \!\@\#\$\%\^\&\*\(\)\" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 4 -- +int(5) +array(5) { + [0]=> + string(13) "hello world\t" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(13) "hello world\t" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 5 -- +int(5) +array(5) { + [0]=> + string(74) "This is \ta text in bold letters\r\s\malong with slashes\n : HELLO WORLD\t" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(74) "This is \ta text in bold letters\r\s\malong with slashes\n : HELLO WORLD\t" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +Done diff --git a/tests/std/array/array_unshift_variation9.phpt b/tests/std/array/array_unshift_variation9.phpt new file mode 100644 index 00000000..133f8f91 --- /dev/null +++ b/tests/std/array/array_unshift_variation9.phpt @@ -0,0 +1,304 @@ +--TEST-- +Test array_unshift() function : usage variations - heredoc strings for 'var' argument +--FILE-- +22 +2222 != 1111.\t 0000 = 0000\n +EOT; + +// heredoc with quote chars & slash +$quote_char_string = << "first", "s" => 'second', 1, 2.222); + +// different heredoc strings to be passed to $var argument +$vars = array( + $empty_string, + $blank_line, + $multiline_string, + $diff_whitespaces, + $numeric_string, + $quote_char_string +); + +// loop through the various elements of $arrays to test array_unshift() +$iterator = 1; +foreach($vars as $var) { + echo "-- Iteration $iterator --\n"; + $temp_array = $array; // assign $array to another temporary $temp_array + + /* with default argument */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + var_dump( array_unshift($temp_array, $var) ); + + // dump the resulting array + var_dump($temp_array); + + /* with all possible arguments */ + // returns element count in the resulting array after arguments are pushed to + // beginning of the given array + $temp_array = $array; + var_dump( array_unshift($temp_array, $var, "hello", 'world') ); + + // dump the resulting array + var_dump($temp_array); + $iterator++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_unshift() : heredoc strings for $var argument *** +-- Iteration 1 -- +int(5) +array(5) { + [0]=> + string(0) "" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(0) "" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 2 -- +int(5) +array(5) { + [0]=> + string(1) " +" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(1) " +" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 3 -- +int(5) +array(5) { + [0]=> + string(86) "hello world +The big brown fox jumped over; +the lazy dog +This is a double quoted string" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(86) "hello world +The big brown fox jumped over; +the lazy dog +This is a double quoted string" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 4 -- +int(5) +array(5) { + [0]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(88) "hello world +1111 != 2222 +heredoc +double quoted string. with different white spaces" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 5 -- +int(5) +array(5) { + [0]=> + string(44) "11 < 12. 123 >22 +2222 != 1111. 0000 = 0000 +" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(44) "11 < 12. 123 >22 +2222 != 1111. 0000 = 0000 +" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +-- Iteration 6 -- +int(5) +array(5) { + [0]=> + string(123) "This's a string with quotes: +"strings in double quote"; +'strings in single quote'; +this\line is single quoted /with\slashes" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [1]=> + int(1) + [2]=> + float(2.222) +} +int(7) +array(7) { + [0]=> + string(123) "This's a string with quotes: +"strings in double quote"; +'strings in single quote'; +this\line is single quoted /with\slashes" + [1]=> + string(5) "hello" + [2]=> + string(5) "world" + ["f"]=> + string(5) "first" + ["s"]=> + string(6) "second" + [3]=> + int(1) + [4]=> + float(2.222) +} +Done diff --git a/tests/std/array/array_user_key_compare.phpt b/tests/std/array/array_user_key_compare.phpt new file mode 100644 index 00000000..3bb02c10 --- /dev/null +++ b/tests/std/array/array_user_key_compare.phpt @@ -0,0 +1,27 @@ +--TEST-- +Fix UMR in array_user_key_compare (MOPB24) +--SKIPIF-- + + +--FILE-- + 1, "B" => 1); + uksort($arr, "array_compare"); + var_dump($a); +} +?> +--EXPECTF-- +Warning: array_compare(): Argument #1 ($key1) must be passed by reference, value given in %s on line %d + +Warning: array_compare(): Argument #2 ($key2) must be passed by reference, value given in %s on line %d +string(1) "B" diff --git a/tests/std/array/array_values.phpt b/tests/std/array/array_values.phpt new file mode 100644 index 00000000..443a4676 --- /dev/null +++ b/tests/std/array/array_values.phpt @@ -0,0 +1,233 @@ +--TEST-- +Test array_values() function +--INI-- +precision=14 +--FILE-- + 1, "b" => 2, "c" =>3), + array(0 => 0, 1 => 1, 2 => 2), + array(TRUE, FALSE, NULL, true, false, null, "TRUE", "FALSE", + "NULL", "\x000", "\000"), + array("Hi" => 1, "Hello" => 2, "World" => 3), + array("a" => "abcd", "a" => "", "ab" => -6, "cd" => -0.5 ), + array(0 => array(), 1=> array(0), 2 => array(1), ""=> array(), ""=>"" ) +); + +$i = 0; +/* loop through to test array_values() with different arrays given above */ +foreach ($arrays as $array) { + echo "\n-- Iteration $i --\n"; + var_dump( array_values($array) ); + $i++; +} + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing array_values() on basic array *** +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + float(2) + [3]=> + string(6) "asdasd" + [4]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} + +*** Testing array_values() on various arrays *** +-- Iteration 0 -- +array(0) { +} + +-- Iteration 1 -- +array(1) { + [0]=> + int(0) +} + +-- Iteration 2 -- +array(1) { + [0]=> + int(-1) +} + +-- Iteration 3 -- +array(1) { + [0]=> + array(0) { + } +} + +-- Iteration 4 -- +array(1) { + [0]=> + string(5) "Hello" +} + +-- Iteration 5 -- +array(1) { + [0]=> + string(0) "" +} + +-- Iteration 6 -- +array(2) { + [0]=> + string(0) "" + [1]=> + array(0) { + } +} + +-- Iteration 7 -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} + +-- Iteration 8 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + array(0) { + } +} + +-- Iteration 9 -- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + array(2) { + [0]=> + int(4) + [1]=> + int(6) + } +} + +-- Iteration 10 -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} + +-- Iteration 11 -- +array(3) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) +} + +-- Iteration 12 -- +array(11) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + NULL + [3]=> + bool(true) + [4]=> + bool(false) + [5]=> + NULL + [6]=> + string(4) "TRUE" + [7]=> + string(5) "FALSE" + [8]=> + string(4) "NULL" + [9]=> + string(2) "%00" + [10]=> + string(1) "%0" +} + +-- Iteration 13 -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} + +-- Iteration 14 -- +array(3) { + [0]=> + string(0) "" + [1]=> + int(-6) + [2]=> + float(-0.5) +} + +-- Iteration 15 -- +array(4) { + [0]=> + array(0) { + } + [1]=> + array(1) { + [0]=> + int(0) + } + [2]=> + array(1) { + [0]=> + int(1) + } + [3]=> + string(0) "" +} +Done diff --git a/tests/std/array/array_values_basic.phpt b/tests/std/array/array_values_basic.phpt new file mode 100644 index 00000000..f7434ad6 --- /dev/null +++ b/tests/std/array/array_values_basic.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test array_values() function : basic functionality +--FILE-- + 3, 10 => 'ten'); + +// Calling array_values() with all possible arguments +var_dump( array_values($input) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_values() : basic functionality *** +array(5) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(3) "two" + [3]=> + int(3) + [4]=> + string(3) "ten" +} +Done diff --git a/tests/std/array/array_values_variation.phpt b/tests/std/array/array_values_variation.phpt new file mode 100644 index 00000000..15eb77da --- /dev/null +++ b/tests/std/array/array_values_variation.phpt @@ -0,0 +1,76 @@ +--TEST-- +Test array_values() function (variation) +--SKIPIF-- + +--INI-- +precision=14 +--FILE-- + $resource1, "b" => $resource2); +var_dump( array_values($arr_resource) ); + +echo "\n*** Testing array_values() with range checking ***\n"; +$arr_range = array( + 2147483647, + 2147483648, + -2147483647, + -2147483648, + -0, + 0, + -2147483649 +); +var_dump( array_values($arr_range) ); + +echo "\n*** Testing array_values() on an array created on the fly ***\n"; +var_dump( array_values(array(1,2,3)) ); +var_dump( array_values(array()) ); // null array + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing array_values() with resource type *** +array(2) { + [0]=> + resource(%d) of type (stream) + [1]=> + resource(%d) of type (stream) +} + +*** Testing array_values() with range checking *** +array(7) { + [0]=> + int(2147483647) + [1]=> + float(2147483648) + [2]=> + int(-2147483647) + [3]=> + float(-2147483648) + [4]=> + int(0) + [5]=> + int(0) + [6]=> + float(-2147483649) +} + +*** Testing array_values() on an array created on the fly *** +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(0) { +} +Done diff --git a/tests/std/array/array_values_variation2.phpt b/tests/std/array/array_values_variation2.phpt new file mode 100644 index 00000000..c4efdb92 --- /dev/null +++ b/tests/std/array/array_values_variation2.phpt @@ -0,0 +1,173 @@ +--TEST-- +Test array_values() function : usage variations - arrays of different data types +--SKIPIF-- + + +--FILE-- + array(0, 1, 12345, -2345), + // float data + /*2*/ + 'float' => array(10.5, -10.5, 123456789000.0, 1.23456789E-9, 0.5), + // null data + /*3*/ + 'null' => array(NULL, null), + // boolean data + /*4*/ + 'bool' => array(true, false, TRUE, FALSE), + // empty data + /*5*/ + 'empty string' => array("", ''), + /*6*/ + 'empty array' => array(), + // string data + /*7*/ + 'string' => array("string", 'string', $heredoc), + // object data + /*8*/ + 'object' => array(new classA()), + // undefined data + /*9*/ + 'undefined' => array(@$undefined_var), + // unset data + /*10*/ + 'unset' => array(@$unset_var), + // resource variable + /*11*/ + 'resource' => array($fp), + ); + // loop through each element of $inputs to check the behavior of array_values() + $iterator = 1; + foreach ($inputs as $key => $input) { + echo "\n-- Iteration {$iterator}: {$key} data --\n"; + var_dump(array_values($input)); + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_values() : usage variations *** + +-- Iteration 1: int data -- +array(4) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(12345) + [3]=> + int(-2345) +} + +-- Iteration 2: float data -- +array(5) { + [0]=> + float(10.5) + [1]=> + float(-10.5) + [2]=> + float(123456789000) + [3]=> + float(1.23456789E-9) + [4]=> + float(0.5) +} + +-- Iteration 3: null data -- +array(2) { + [0]=> + NULL + [1]=> + NULL +} + +-- Iteration 4: bool data -- +array(4) { + [0]=> + bool(true) + [1]=> + bool(false) + [2]=> + bool(true) + [3]=> + bool(false) +} + +-- Iteration 5: empty string data -- +array(2) { + [0]=> + string(0) "" + [1]=> + string(0) "" +} + +-- Iteration 6: empty array data -- +array(0) { +} + +-- Iteration 7: string data -- +array(3) { + [0]=> + string(6) "string" + [1]=> + string(6) "string" + [2]=> + string(11) "hello world" +} + +-- Iteration 8: object data -- +array(1) { + [0]=> + object(classA)#%d (0) { + } +} + +-- Iteration 9: undefined data -- +array(1) { + [0]=> + NULL +} + +-- Iteration 10: unset data -- +array(1) { + [0]=> + NULL +} + +-- Iteration 11: resource data -- +array(1) { + [0]=> + resource(%d) of type (stream) +} +Done diff --git a/tests/std/array/array_values_variation3.phpt b/tests/std/array/array_values_variation3.phpt new file mode 100644 index 00000000..43efed83 --- /dev/null +++ b/tests/std/array/array_values_variation3.phpt @@ -0,0 +1,169 @@ +--TEST-- +Test array_values() function : usage variations - array keys different data types +--SKIPIF-- + + +--FILE-- + array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative', + ), + + // null data +/*4*/ 'null uppercase' => array( + NULL => 'null 1', + ), + +/*5*/ 'null lowercase' => array( + null => 'null 2', + ), + + // boolean data +/*6*/ 'bool lowercase' => array( + true => 'lowert', + false => 'lowerf', + ), + +/*7*/ 'bool uppercase' => array( + TRUE => 'uppert', + FALSE => 'upperf', + ), + + // empty data +/*8*/ 'empty double quotes' => array( + "" => 'emptyd', + ), + +/*9*/ 'empty single quotes' => array( + '' => 'emptys', + ), + + // string data +/*10*/ 'string' => array( + "stringd" => 'stringd', + 'strings' => 'strings', + $heredoc => 'stringh', + ), + + // undefined data +/*11*/ 'undefined' => array( + @$undefined_var => 'undefined', + ), + + // unset data +/*12*/ 'unset' => array( + @$unset_var => 'unset', + ), +); + +// loop through each element of $inputs to check the behavior of array_values() +$iterator = 1; +foreach($inputs as $key => $input) { + echo "\n-- Iteration $iterator: $key data --\n"; + var_dump( array_values($input) ); + $iterator++; +}; +echo "Done"; +?> +--EXPECT-- +*** Testing array_values() : usage variations *** + +-- Iteration 1: int data -- +array(4) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + string(8) "positive" + [3]=> + string(8) "negative" +} + +-- Iteration 2: null uppercase data -- +array(1) { + [0]=> + string(6) "null 1" +} + +-- Iteration 3: null lowercase data -- +array(1) { + [0]=> + string(6) "null 2" +} + +-- Iteration 4: bool lowercase data -- +array(2) { + [0]=> + string(6) "lowert" + [1]=> + string(6) "lowerf" +} + +-- Iteration 5: bool uppercase data -- +array(2) { + [0]=> + string(6) "uppert" + [1]=> + string(6) "upperf" +} + +-- Iteration 6: empty double quotes data -- +array(1) { + [0]=> + string(6) "emptyd" +} + +-- Iteration 7: empty single quotes data -- +array(1) { + [0]=> + string(6) "emptys" +} + +-- Iteration 8: string data -- +array(3) { + [0]=> + string(7) "stringd" + [1]=> + string(7) "strings" + [2]=> + string(7) "stringh" +} + +-- Iteration 9: undefined data -- +array(1) { + [0]=> + string(9) "undefined" +} + +-- Iteration 10: unset data -- +array(1) { + [0]=> + string(5) "unset" +} +Done diff --git a/tests/std/array/array_values_variation4.phpt b/tests/std/array/array_values_variation4.phpt new file mode 100644 index 00000000..17e7bdd4 --- /dev/null +++ b/tests/std/array/array_values_variation4.phpt @@ -0,0 +1,93 @@ +--TEST-- +Test array_values() function : usage variations - multi-dimensional arrays +--FILE-- + 'zero', 'un' => 'one', 'sub' => array (1, 2, 3)); + +echo "\n-- Array values of a two-dimensional array --\n"; +var_dump(array_values($input)); + +echo "\n-- Array values of a sub-array --\n"; +var_dump(array_values($input['sub'])); + +// get an infinitely recursive array +$input[] = &$input; +echo "\n-- Array values of an infinitely recursive array --\n"; +var_dump(array_values($input)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_values() : usage variations *** + +-- Array values of a two-dimensional array -- +array(3) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} + +-- Array values of a sub-array -- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} + +-- Array values of an infinitely recursive array -- +array(4) { + [0]=> + string(4) "zero" + [1]=> + string(3) "one" + [2]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [3]=> + &array(4) { + ["zero"]=> + string(4) "zero" + ["un"]=> + string(3) "one" + ["sub"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + [0]=> + *RECURSION* + } +} +Done diff --git a/tests/std/array/array_values_variation5.phpt b/tests/std/array/array_values_variation5.phpt new file mode 100644 index 00000000..8dbd7ca3 --- /dev/null +++ b/tests/std/array/array_values_variation5.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test array_values() function : usage variations - internal array pointer +--FILE-- + 'un', 'two' => 'deux', 'three' => 'trois'); + +echo "\n-- Call array_values() --\n"; +var_dump($result = array_values($input)); + +echo "-- Position of Internal Pointer in Result: --\n"; +echo key($result) . " => " . current($result) . "\n"; +echo "\n-- Position of Internal Pointer in Original Array: --\n"; +echo key($input) . " => " . current ($input) . "\n"; + +echo "Done"; +?> +--EXPECT-- +*** Testing array_values() : usage variations *** + +-- Call array_values() -- +array(3) { + [0]=> + string(2) "un" + [1]=> + string(4) "deux" + [2]=> + string(5) "trois" +} +-- Position of Internal Pointer in Result: -- +0 => un + +-- Position of Internal Pointer in Original Array: -- +one => un +Done diff --git a/tests/std/array/array_values_variation6.phpt b/tests/std/array/array_values_variation6.phpt new file mode 100644 index 00000000..b4c953c4 --- /dev/null +++ b/tests/std/array/array_values_variation6.phpt @@ -0,0 +1,50 @@ +--TEST-- +Test array_values() function : usage variations - Referenced variables +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_values() : usage variations *** + +-- $input is an array made up of referenced variables: -- +array(3) { + [0]=> + &string(3) "one" + [1]=> + &string(3) "two" + [2]=> + &string(5) "three" +} +Change $val2 and check result of array_values(): +array(3) { + [0]=> + &string(3) "one" + [1]=> + &string(4) "deux" + [2]=> + &string(5) "three" +} +Done diff --git a/tests/std/array/array_values_variation7.phpt b/tests/std/array/array_values_variation7.phpt new file mode 100644 index 00000000..b17451ed --- /dev/null +++ b/tests/std/array/array_values_variation7.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test array_values() function : usage variations - Internal order check +--FILE-- + 'three', 2 => 'two', 1 => 'one', 0 => 'zero'); + +echo "\n-- \$input argument: --\n"; +var_dump($input); + +echo "\n-- Result of array_values() --\n"; +var_dump(array_values($input)); + +echo "Done"; +?> +--EXPECT-- +*** Testing array_values() : usage variations *** + +-- $input argument: -- +array(4) { + [3]=> + string(5) "three" + [2]=> + string(3) "two" + [1]=> + string(3) "one" + [0]=> + string(4) "zero" +} + +-- Result of array_values() -- +array(4) { + [0]=> + string(5) "three" + [1]=> + string(3) "two" + [2]=> + string(3) "one" + [3]=> + string(4) "zero" +} +Done diff --git a/tests/std/array/array_values_variation_64bit.phpt b/tests/std/array/array_values_variation_64bit.phpt new file mode 100644 index 00000000..066d35da --- /dev/null +++ b/tests/std/array/array_values_variation_64bit.phpt @@ -0,0 +1,74 @@ +--TEST-- +Test array_values() function +--SKIPIF-- + +--INI-- +precision=14 +--FILE-- + $resource1, "b" => $resource2); +var_dump( array_values($arr_resource) ); + +echo "\n*** Testing array_values() with range checking ***\n"; +$arr_range = array( + 2147483647, + 2147483648, + -2147483647, + -2147483648, + -0, + 0, + -2147483649 +); +var_dump( array_values($arr_range) ); + +echo "\n*** Testing array_values() on an array created on the fly ***\n"; +var_dump( array_values(array(1,2,3)) ); +var_dump( array_values(array()) ); // null array + +?> +--EXPECTF-- +*** Testing array_values() with resource type *** +array(2) { + [0]=> + resource(%d) of type (stream) + [1]=> + resource(%d) of type (stream) +} + +*** Testing array_values() with range checking *** +array(7) { + [0]=> + int(2147483647) + [1]=> + int(2147483648) + [2]=> + int(-2147483647) + [3]=> + int(-2147483648) + [4]=> + int(0) + [5]=> + int(0) + [6]=> + int(-2147483649) +} + +*** Testing array_values() on an array created on the fly *** +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +array(0) { +} diff --git a/tests/std/array/array_walk.phpt b/tests/std/array/array_walk.phpt new file mode 100644 index 00000000..db454a5a --- /dev/null +++ b/tests/std/array/array_walk.phpt @@ -0,0 +1,38 @@ +--TEST-- +array_walk() tests +--SKIPIF-- + +--FILE-- +getMessage()); + } + echo "Done\n"; +} +?> +--EXPECT-- +int(1) +int(0) +string(4) "data" +int(2) +int(1) +string(4) "data" +bool(true) +string(4) "data" +Done diff --git a/tests/std/array/array_walk_basic1.phpt b/tests/std/array/array_walk_basic1.phpt new file mode 100644 index 00000000..f4db6f29 --- /dev/null +++ b/tests/std/array/array_walk_basic1.phpt @@ -0,0 +1,75 @@ +--TEST-- +Test array_walk() function : basic functionality - regular array +--FILE-- + +--EXPECT-- +*** Testing array_walk() : basic functionality *** +-- Using array_walk() with default parameters to show array contents -- +string(5) "lemon" +int(0) + +string(6) "orange" +int(1) + +string(6) "banana" +int(2) + +string(5) "apple" +int(3) + +bool(true) +-- Using array_walk() with all parameters -- +string(5) "lemon" +int(0) +string(5) "Added" + +string(6) "orange" +int(1) +string(5) "Added" + +string(6) "banana" +int(2) +string(5) "Added" + +string(5) "apple" +int(3) +string(5) "Added" + +bool(true) +Done diff --git a/tests/std/array/array_walk_basic2.phpt b/tests/std/array/array_walk_basic2.phpt new file mode 100644 index 00000000..42df9939 --- /dev/null +++ b/tests/std/array/array_walk_basic2.phpt @@ -0,0 +1,91 @@ +--TEST-- +Test array_walk() function : basic functionality - associative array +--FILE-- + "lemon", "a" => "orange", "b" => "banana", "c" => "apple"); + echo "-- Using array_walk with default parameters to show array contents --\n"; + var_dump(array_walk($fruits, 'test_print')); + echo "-- Using array_walk with one optional parameter to modify contents --\n"; + var_dump(array_walk($fruits, 'test_alter', 'fruit')); + echo "-- Using array_walk with default parameters to show modified array contents --\n"; + var_dump(array_walk($fruits, 'test_print')); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_walk() : basic functionality *** +-- Using array_walk with default parameters to show array contents -- +string(5) "lemon" +string(1) "d" + +string(6) "orange" +string(1) "a" + +string(6) "banana" +string(1) "b" + +string(5) "apple" +string(1) "c" + +bool(true) +-- Using array_walk with one optional parameter to modify contents -- +string(5) "lemon" +string(1) "d" +string(5) "fruit" + +string(6) "orange" +string(1) "a" +string(5) "fruit" + +string(6) "banana" +string(1) "b" +string(5) "fruit" + +string(5) "apple" +string(1) "c" +string(5) "fruit" + +bool(true) +-- Using array_walk with default parameters to show modified array contents -- +string(5) "lemon" +string(1) "d" + +string(6) "orange" +string(1) "a" + +string(6) "banana" +string(1) "b" + +string(5) "apple" +string(1) "c" + +bool(true) +Done diff --git a/tests/std/array/array_walk_closure.phpt b/tests/std/array/array_walk_closure.phpt new file mode 100644 index 00000000..e7ddf112 --- /dev/null +++ b/tests/std/array/array_walk_closure.phpt @@ -0,0 +1,247 @@ +--TEST-- +array_walk() closure tests +--SKIPIF-- + + +--FILE-- +sum += $value; +} +function sum_it_up_array($value, $key, $udata) +{ + var_dump($udata); + $udata['sum'] += $value; +} +function main() +{ + $ar = ["one" => 1, "two" => 2, "three" => 3]; + var_dump(array_walk($ar, function () { + var_dump(func_get_args()); + })); + echo "\nclosure with array\n"; + $ar = ["one" => 1, "two" => 2, "three" => 3]; + $user_data = ["sum" => 42]; + $func = function ($value, $key, &$udata) { + var_dump($udata); + $udata["sum"] += $value; + }; + var_dump(array_walk($ar, $func, $user_data)); + echo "End result:"; + var_dump($user_data["sum"]); + echo "\nclosure with use\n"; + $ar = ["one" => 1, "two" => 2, "three" => 3]; + $user_data = ["sum" => 42]; + $func = function ($value, $key) use (&$user_data) { + var_dump($user_data); + $user_data["sum"] += $value; + }; + var_dump(array_walk($ar, $func, $user_data)); + echo "End result:"; + var_dump($user_data["sum"]); + echo "\nclosure with object\n"; + $ar = ["one" => 1, "two" => 2, "three" => 3]; + $user_data = (object) ["sum" => 42]; + $func = function ($value, $key, &$udata) { + var_dump($udata); + $udata->sum += $value; + }; + var_dump(array_walk($ar, $func, $user_data)); + echo "End result:"; + var_dump($user_data->sum); + echo "\nfunction with object\n"; + $ar = ["one" => 1, "two" => 2, "three" => 3]; + $user_data = (object) ["sum" => 42]; + var_dump(array_walk($ar, "sum_it_up_object", $user_data)); + echo "End result:"; + var_dump($user_data->sum); + echo "\nfunction with array\n"; + $ar = ["one" => 1, "two" => 2, "three" => 3]; + $user_data = ["sum" => 42]; + var_dump(array_walk($ar, "sum_it_up_array", $user_data)); + echo "End result:"; + var_dump($user_data['sum']); + echo "\nclosure and exception\n"; + $ar = ["one" => 1, "two" => 2, "three" => 3]; + try { + var_dump(array_walk($ar, function ($v, $k) { + if ($v == 2) { + throw new Exception(); + } + })); + } catch (Exception $e) { + var_dump($e->getTrace()); + } + echo "Done\n"; +} +?> +--EXPECTF-- +array(2) { + [0]=> + int(1) + [1]=> + string(3) "one" +} +array(2) { + [0]=> + int(2) + [1]=> + string(3) "two" +} +array(2) { + [0]=> + int(3) + [1]=> + string(5) "three" +} +bool(true) + +closure with array + +Warning: {closure:%s:%d}(): Argument #3 ($udata) must be passed by reference, value given in %s on line %d +array(1) { + ["sum"]=> + int(42) +} + +Warning: {closure:%s:%d}(): Argument #3 ($udata) must be passed by reference, value given in %s on line %d +array(1) { + ["sum"]=> + int(42) +} + +Warning: {closure:%s:%d}(): Argument #3 ($udata) must be passed by reference, value given in %s on line %d +array(1) { + ["sum"]=> + int(42) +} +bool(true) +End result:int(42) + +closure with use +array(1) { + ["sum"]=> + int(42) +} +array(1) { + ["sum"]=> + int(43) +} +array(1) { + ["sum"]=> + int(45) +} +bool(true) +End result:int(48) + +closure with object + +Warning: {closure:%s:%d}(): Argument #3 ($udata) must be passed by reference, value given in %s on line %d +object(stdClass)#1 (1) { + ["sum"]=> + int(42) +} + +Warning: {closure:%s:%d}(): Argument #3 ($udata) must be passed by reference, value given in %s on line %d +object(stdClass)#1 (1) { + ["sum"]=> + int(43) +} + +Warning: {closure:%s:%d}(): Argument #3 ($udata) must be passed by reference, value given in %s on line %d +object(stdClass)#1 (1) { + ["sum"]=> + int(45) +} +bool(true) +End result:int(48) + +function with object +object(stdClass)#2 (1) { + ["sum"]=> + int(42) +} +object(stdClass)#2 (1) { + ["sum"]=> + int(43) +} +object(stdClass)#2 (1) { + ["sum"]=> + int(45) +} +bool(true) +End result:int(48) + +function with array +array(1) { + ["sum"]=> + int(42) +} +array(1) { + ["sum"]=> + int(42) +} +array(1) { + ["sum"]=> + int(42) +} +bool(true) +End result:int(42) + +closure and exception +array(2) { + [0]=> + array(2) { + ["function"]=> + string(%d) "{closure:%s:%d}" + ["args"]=> + array(2) { + [0]=> + int(2) + [1]=> + string(3) "two" + } + } + [1]=> + array(4) { + ["file"]=> + string(%d) "%s" + ["line"]=> + int(%d) + ["function"]=> + string(10) "array_walk" + ["args"]=> + array(2) { + [0]=> + array(3) { + ["one"]=> + int(1) + ["two"]=> + int(2) + ["three"]=> + int(3) + } + [1]=> + object(Closure)#%d (4) { + ["name"]=> + string(%d) "{closure:%s:%d}" + ["file"]=> + string(%d) "%s" + ["line"]=> + int(%d) + ["parameter"]=> + array(2) { + ["$v"]=> + string(10) "" + ["$k"]=> + string(10) "" + } + } + } + } +} +Done diff --git a/tests/std/array/array_walk_error2.phpt b/tests/std/array/array_walk_error2.phpt new file mode 100644 index 00000000..7ab3b22a --- /dev/null +++ b/tests/std/array/array_walk_error2.phpt @@ -0,0 +1,64 @@ +--TEST-- +Test array_walk() function : error conditions - callback parameters +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } + try { + var_dump(array_walk($input, "callback2", 4)); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + // expected: Warning is suppressed + try { + var_dump(@array_walk($input, "callback1")); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + try { + var_dump(@array_walk($input, "callback2", 4)); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + echo "-- Testing array_walk() function with too many callback parameters --\n"; + try { + var_dump(array_walk($input, "callback1", 20, 10)); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_walk() : error conditions - callback parameters *** +Exception: Too few arguments to function callback1(), 2 passed and exactly 3 expected +Exception: Too few arguments to function callback2(), 3 passed and exactly 4 expected +Exception: Too few arguments to function callback1(), 2 passed and exactly 3 expected +Exception: Too few arguments to function callback2(), 3 passed and exactly 4 expected +-- Testing array_walk() function with too many callback parameters -- +Exception: array_walk() expects at most 3 arguments, 4 given +Done diff --git a/tests/std/array/array_walk_object1.phpt b/tests/std/array/array_walk_object1.phpt new file mode 100644 index 00000000..9c241124 --- /dev/null +++ b/tests/std/array/array_walk_object1.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test array_walk() function : object functionality +--FILE-- +pri_value = $setVal; + $this->pub_value = $setVal; + $this->pro_value = $setVal; + } +}; + +function main() { +echo "*** Testing array_walk() : object functionality ***\n"; + +// object for 'input' argument +$input = new MyClass(10); + +var_dump( array_walk($input, "callback", 1)); + +echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_walk() : object functionality *** +string(18) "%r\0%rMyClass%r\0%rpri_value" +int(10) +int(1) + +string(9) "pub_value" +int(10) +int(1) + +string(12) "%r\0%r*%r\0%rpro_value" +int(10) +int(1) + +bool(true) +Done diff --git a/tests/std/array/array_walk_object2.phpt b/tests/std/array/array_walk_object2.phpt new file mode 100644 index 00000000..f49be31a --- /dev/null +++ b/tests/std/array/array_walk_object2.phpt @@ -0,0 +1,94 @@ +--TEST-- +Test array_walk() function : object functionality - array of objects +--FILE-- +getValue()); + echo "key : "; + var_dump($key); +} + +function callback_public($value, $key) +{ + echo "value : "; + var_dump($value->pub_value); +} +function callback_protected($value, $key) +{ + echo "value : "; + var_dump($value->get_pro_value()); +} + +class MyClass +{ + private $pri_value; + public $pub_value; + protected $pro_value; + public function __construct($setVal) + { + $this->pri_value = $setVal; + $this->pub_value = $setVal; + $this->pro_value = $setVal; + } + public function getValue() + { + return $this->pri_value; + } + public function get_pro_value() + { + return $this->pro_value; + } +}; + +function main() { +echo "*** Testing array_walk() : array of objects ***\n"; + +// array containing objects of MyClass +$input = array ( + new MyClass(3), + new MyClass(10), + new MyClass(20), + new MyClass(-10) +); + +echo "-- For private member --\n"; +var_dump( array_walk($input, "callback_private", 1)); +echo "-- For public member --\n"; +var_dump( array_walk($input, "callback_public")); +echo "-- For protected member --\n"; +var_dump( array_walk($input, "callback_protected")); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing array_walk() : array of objects *** +-- For private member -- +value : int(3) +key : int(0) +value : int(10) +key : int(1) +value : int(20) +key : int(2) +value : int(-10) +key : int(3) +bool(true) +-- For public member -- +value : int(3) +value : int(10) +value : int(20) +value : int(-10) +bool(true) +-- For protected member -- +value : int(3) +value : int(10) +value : int(20) +value : int(-10) +bool(true) +Done diff --git a/tests/std/array/array_walk_objects.phpt b/tests/std/array/array_walk_objects.phpt new file mode 100644 index 00000000..a481d3c5 --- /dev/null +++ b/tests/std/array/array_walk_objects.phpt @@ -0,0 +1,46 @@ +--TEST-- +array_walk() and objects +--FILE-- +foo = "foo"; + $stdclass->bar = "bar"; + array_walk($stdclass, "walk"); + $t = new test(); + array_walk($t, "walk"); + $var = array(); + array_walk($var, "walk"); + $var_str = ""; + try { + array_walk($var_str, "walk"); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + echo "Done\n"; +} +?> +--EXPECTF-- +string(3) "foo" +string(3) "foo" +string(3) "bar" +string(3) "bar" +string(13) "%r\0%rtest%r\0%rvar_pri" +string(12) "test_private" +string(10) "%r\0%r*%r\0%rvar_pro" +string(14) "test_protected" +string(7) "var_pub" +string(11) "test_public" +array_walk(): Argument #1 ($array) must be of type array, string given +Done diff --git a/tests/std/array/array_walk_rec_objects.phpt b/tests/std/array/array_walk_rec_objects.phpt new file mode 100644 index 00000000..a26e8989 --- /dev/null +++ b/tests/std/array/array_walk_rec_objects.phpt @@ -0,0 +1,46 @@ +--TEST-- +array_walk_recursive() and objects +--FILE-- +foo = "foo"; + $stdclass->bar = "bar"; + array_walk_recursive($stdclass, "walk"); + $t = new test(); + array_walk_recursive($t, "walk"); + $var = array(); + array_walk_recursive($var, "walk"); + $var_str = ""; + try { + array_walk_recursive($var_str, "walk"); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + echo "Done\n"; +} +?> +--EXPECTF-- +string(3) "foo" +string(3) "foo" +string(3) "bar" +string(3) "bar" +string(13) "%0test%0var_pri" +string(12) "test_private" +string(10) "%0*%0var_pro" +string(14) "test_protected" +string(7) "var_pub" +string(11) "test_public" +array_walk_recursive(): Argument #1 ($array) must be of type array, string given +Done diff --git a/tests/std/array/array_walk_recursive.phpt b/tests/std/array/array_walk_recursive.phpt new file mode 100644 index 00000000..3c331cfb --- /dev/null +++ b/tests/std/array/array_walk_recursive.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test array_walk_recursive() +--SKIPIF-- +--FILE-- + +--EXPECT-- +1 foo +2 foo +3 foo +bool(true) +1 bar +2 bar +3 bar +bool(true) diff --git a/tests/std/array/array_walk_recursive1.phpt b/tests/std/array/array_walk_recursive1.phpt new file mode 100644 index 00000000..cd57bc5a --- /dev/null +++ b/tests/std/array/array_walk_recursive1.phpt @@ -0,0 +1,44 @@ +--TEST-- +array_walk_recursive() tests +--SKIPIF-- + +--FILE-- +getMessage()); + } + echo "Done\n"; +} +?> +--EXPECT-- +int(1) +int(0) +string(4) "data" +int(2) +int(1) +string(4) "data" +int(2) +int(0) +string(4) "data" +int(3) +int(1) +string(4) "data" +bool(true) +string(4) "data" +Done diff --git a/tests/std/array/array_walk_recursive_basic1.phpt b/tests/std/array/array_walk_recursive_basic1.phpt new file mode 100644 index 00000000..fbdbd52c --- /dev/null +++ b/tests/std/array/array_walk_recursive_basic1.phpt @@ -0,0 +1,75 @@ +--TEST-- +Test array_walk_recursive() function : basic functionality - regular array +--FILE-- + +--EXPECT-- +*** Testing array_walk_recursive() : basic functionality *** +-- Using array_walk_recursive() with default parameters to show array contents -- +string(5) "lemon" +int(0) + +string(6) "orange" +int(0) + +string(6) "banana" +int(1) + +string(5) "apple" +int(0) + +bool(true) +-- Using array_walk_recursive() with all parameters -- +string(5) "lemon" +int(0) +string(5) "Added" + +string(6) "orange" +int(0) +string(5) "Added" + +string(6) "banana" +int(1) +string(5) "Added" + +string(5) "apple" +int(0) +string(5) "Added" + +bool(true) +Done diff --git a/tests/std/array/array_walk_recursive_basic2.phpt b/tests/std/array/array_walk_recursive_basic2.phpt new file mode 100644 index 00000000..9664cb92 --- /dev/null +++ b/tests/std/array/array_walk_recursive_basic2.phpt @@ -0,0 +1,91 @@ +--TEST-- +Test array_walk_recursive() function : basic functionality - associative array +--FILE-- + "lemon", "b" => array("c" => "orange", "d" => "banana"), "e" => array("f" => "apple")); + echo "-- Using array_walk_recursive with default parameters to show array contents --\n"; + var_dump(array_walk_recursive($fruits, 'test_print')); + echo "-- Using array_walk_recursive with one optional parameter to modify contents --\n"; + var_dump(array_walk_recursive($fruits, 'test_alter', 'fruit')); + echo "-- Using array_walk_recursive with default parameters to show modified array contents --\n"; + var_dump(array_walk_recursive($fruits, 'test_print')); + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_walk_recursive() : basic functionality *** +-- Using array_walk_recursive with default parameters to show array contents -- +string(5) "lemon" +string(1) "a" + +string(6) "orange" +string(1) "c" + +string(6) "banana" +string(1) "d" + +string(5) "apple" +string(1) "f" + +bool(true) +-- Using array_walk_recursive with one optional parameter to modify contents -- +string(5) "lemon" +string(1) "a" +string(5) "fruit" + +string(6) "orange" +string(1) "c" +string(5) "fruit" + +string(6) "banana" +string(1) "d" +string(5) "fruit" + +string(5) "apple" +string(1) "f" +string(5) "fruit" + +bool(true) +-- Using array_walk_recursive with default parameters to show modified array contents -- +string(5) "lemon" +string(1) "a" + +string(6) "orange" +string(1) "c" + +string(6) "banana" +string(1) "d" + +string(5) "apple" +string(1) "f" + +bool(true) +Done diff --git a/tests/std/array/array_walk_recursive_error2.phpt b/tests/std/array/array_walk_recursive_error2.phpt new file mode 100644 index 00000000..e3b9514f --- /dev/null +++ b/tests/std/array/array_walk_recursive_error2.phpt @@ -0,0 +1,64 @@ +--TEST-- +Test array_walk_recursive() function : error conditions - callback parameters +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; + } + try { + var_dump(array_walk_recursive($input, "callback2", 4)); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + // expected: Warning is suppressed + try { + var_dump(@array_walk_recursive($input, "callback1")); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + try { + var_dump(@array_walk_recursive($input, "callback2", 4)); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + echo "-- Testing array_walk_recursive() function with too many callback parameters --\n"; + try { + var_dump(array_walk_recursive($input, "callback1", 20, 10)); + } catch (Throwable $e) { + echo "Exception: " . $e->getMessage() . "\n"; + } + echo "Done"; +} +?> +--EXPECT-- +*** Testing array_walk_recursive() : error conditions - callback parameters *** +Exception: Too few arguments to function callback1(), 2 passed and exactly 3 expected +Exception: Too few arguments to function callback2(), 3 passed and exactly 4 expected +Exception: Too few arguments to function callback1(), 2 passed and exactly 3 expected +Exception: Too few arguments to function callback2(), 3 passed and exactly 4 expected +-- Testing array_walk_recursive() function with too many callback parameters -- +Exception: array_walk_recursive() expects at most 3 arguments, 4 given +Done diff --git a/tests/std/array/array_walk_recursive_object1.phpt b/tests/std/array/array_walk_recursive_object1.phpt new file mode 100644 index 00000000..cefcff95 --- /dev/null +++ b/tests/std/array/array_walk_recursive_object1.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test array_walk_recursive() function : object functionality +--FILE-- +pri_value = $setVal; + $this->pub_value = $setVal; + $this->pro_value = $setVal; + } +}; + +function main() { +echo "*** Testing array_walk_recursive() : object functionality ***\n"; + +// object for 'input' argument +$input = new MyClass(10); + +var_dump( array_walk_recursive($input, "callback", 1)); + +echo "Done"; +} +?> +--EXPECTF-- +*** Testing array_walk_recursive() : object functionality *** +string(18) "%r\0%rMyClass%r\0%rpri_value" +int(10) +int(1) + +string(9) "pub_value" +int(10) +int(1) + +string(12) "%r\0%r*%r\0%rpro_value" +int(10) +int(1) + +bool(true) +Done diff --git a/tests/std/array/array_walk_recursive_object2.phpt b/tests/std/array/array_walk_recursive_object2.phpt new file mode 100644 index 00000000..faa3a78a --- /dev/null +++ b/tests/std/array/array_walk_recursive_object2.phpt @@ -0,0 +1,96 @@ +--TEST-- +Test array_walk_recursive() function : object functionality - array of objects +--FILE-- +getValue()); + echo "key : "; + var_dump($key); +} + +function callback_public($value, $key) +{ + echo "value : "; + var_dump($value->pub_value); +} +function callback_protected($value, $key) +{ + echo "value : "; + var_dump($value->get_pro_value()); +} + +class MyClass +{ + private $pri_value; + public $pub_value; + protected $pro_value; + public function __construct($setVal) + { + $this->pri_value = $setVal; + $this->pub_value = $setVal; + $this->pro_value = $setVal; + } + public function getValue() + { + return $this->pri_value; + } + public function get_pro_value() + { + return $this->pro_value; + } +}; + +function main() { +echo "*** Testing array_walk_recursive() : array of objects ***\n"; + +// array containing objects of MyClass +$input = array ( + array( + new MyClass(3), + new MyClass(10), + ), + new MyClass(20), + array(new MyClass(-10)) +); + +echo "-- For private member --\n"; +var_dump( array_walk_recursive($input, "callback_private", 1)); +echo "-- For public member --\n"; +var_dump( array_walk_recursive($input, "callback_public")); +echo "-- For protected member --\n"; +var_dump( array_walk_recursive($input, "callback_protected")); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing array_walk_recursive() : array of objects *** +-- For private member -- +value : int(3) +key : int(0) +value : int(10) +key : int(1) +value : int(20) +key : int(1) +value : int(-10) +key : int(0) +bool(true) +-- For public member -- +value : int(3) +value : int(10) +value : int(20) +value : int(-10) +bool(true) +-- For protected member -- +value : int(3) +value : int(10) +value : int(20) +value : int(-10) +bool(true) +Done diff --git a/tests/std/array/array_walk_recursive_variation3.phpt b/tests/std/array/array_walk_recursive_variation3.phpt new file mode 100644 index 00000000..c887d86e --- /dev/null +++ b/tests/std/array/array_walk_recursive_variation3.phpt @@ -0,0 +1,116 @@ +--TEST-- +Test array_walk_recursive() function : usage variations - 'input' array with different values +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_walk_recursive() : 'input' array with different values*** + +-- Iteration 1 -- +1 : 0 1 +1 : 1 0 +1 : 2 -10 +1 : 0 19 +1 : 1 -33 +1 : 0 90 +1 : 1 31 +1 : 2 -110 +bool(true) + +-- Iteration 2 -- +2 : 0 3.4 +2 : 1 0.8 +2 : 2 -2.9 +2 : 0 625 +2 : 1 0.0082 +bool(true) + +-- Iteration 3 -- +3 : 0 Mango +3 : 0 Apple +3 : 1 Orange +3 : 2 Lemon +bool(true) + +-- Iteration 4 -- +4 : 0 1 +4 : 1 +4 : 0 1 +4 : 1 +bool(true) + +-- Iteration 5 -- +5 : 0 +5 : 0 +bool(true) + +-- Iteration 6 -- +bool(true) + +-- Iteration 7 -- +7 : 0 binary +bool(true) + +-- Iteration 8 -- +8 : 0 16 +8 : 1 8.345 +8 : 0 Fruits +8 : 0 1 +8 : 1 +8 : 0 +8 : 0 -98 +8 : 1 0.005 +8 : 2 banana +bool(true) +Done diff --git a/tests/std/array/array_walk_recursive_variation4.phpt b/tests/std/array/array_walk_recursive_variation4.phpt new file mode 100644 index 00000000..a40644ce --- /dev/null +++ b/tests/std/array/array_walk_recursive_variation4.phpt @@ -0,0 +1,67 @@ +--TEST-- +Test array_walk_recursive() function : usage variations - 'input' array with subarray +--FILE-- + +--EXPECT-- +*** Testing array_walk_recursive() : array with subarray *** +int(0) +int(1) + +int(0) +int(1) + +int(1) +int(2) + +int(2) +int(3) + +int(0) +string(5) "Mango" + +int(1) +string(6) "Orange" + +int(0) +int(1) + +int(1) +int(2) + +int(2) +int(3) + +int(0) +int(1) + +bool(true) +Done diff --git a/tests/std/array/array_walk_recursive_variation5.phpt b/tests/std/array/array_walk_recursive_variation5.phpt new file mode 100644 index 00000000..55bc642e --- /dev/null +++ b/tests/std/array/array_walk_recursive_variation5.phpt @@ -0,0 +1,59 @@ +--TEST-- +Test array_walk_recursive() function : usage variations - 'input' argument containing reference variables +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_walk_recursive() : array with references *** +int(0) +int(10) + +int(0) +int(-20) + +int(1) +int(-35) + +int(0) +int(10) + +int(1) +int(0) + +int(0) +int(50) + +bool(true) +Done diff --git a/tests/std/array/array_walk_recursive_variation6.phpt b/tests/std/array/array_walk_recursive_variation6.phpt new file mode 100644 index 00000000..78926a6d --- /dev/null +++ b/tests/std/array/array_walk_recursive_variation6.phpt @@ -0,0 +1,127 @@ +--TEST-- +Test array_walk_recursive() function : usage variations - 'input' argument as diff. associative arrays +--FILE-- + array(1 => 25, 5 => 12, 0 => -80), 1 => array(-2 => 100, 5 => 30)); +echo "-- Associative array with numeric keys --\n"; +var_dump( array_walk_recursive($input, "for_numeric", 10)); + +// String keys +$input = array( "a" => "Apple", 'z' => array('b' => 'Bananna', "c" => "carrot"), 'x' => array('o' => "Orange")); +echo "-- Associative array with string keys --\n"; +var_dump( array_walk_recursive($input, "for_string")); + +// binary key +$input = array( b"a" => "Apple", b"b" => "Banana"); +echo "-- Associative array with binary keys --\n"; +var_dump( array_walk_recursive($input, "for_string")); + +// Mixed keys - numeric/string +$input = array( 0 => array(0 => 1, 1 => 2), "x" => array("a" => "Apple", "b" => "Banana"), 2 =>3); +echo "-- Associative array with numeric/string keys --\n"; +var_dump( array_walk_recursive($input, "for_mixed")); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing array_walk_recursive() : 'input' as an associative array *** +-- Associative array with numeric keys -- +int(1) +int(25) +int(10) + +int(5) +int(12) +int(10) + +int(0) +int(-80) +int(10) + +int(-2) +int(100) +int(10) + +int(5) +int(30) +int(10) + +bool(true) +-- Associative array with string keys -- +string(1) "a" +string(5) "Apple" + +string(1) "b" +string(7) "Bananna" + +string(1) "c" +string(6) "carrot" + +string(1) "o" +string(6) "Orange" + +bool(true) +-- Associative array with binary keys -- +string(1) "a" +string(5) "Apple" + +string(1) "b" +string(6) "Banana" + +bool(true) +-- Associative array with numeric/string keys -- +int(0) +int(1) + +int(1) +int(2) + +string(1) "a" +string(5) "Apple" + +string(1) "b" +string(6) "Banana" + +int(2) +int(3) + +bool(true) +Done diff --git a/tests/std/array/array_walk_recursive_variation7.phpt b/tests/std/array/array_walk_recursive_variation7.phpt new file mode 100644 index 00000000..012e05b2 --- /dev/null +++ b/tests/std/array/array_walk_recursive_variation7.phpt @@ -0,0 +1,81 @@ +--TEST-- +Test array_walk_recursive() function : usage variations - anonymous callback function +--FILE-- + +--EXPECT-- +*** Testing array_walk_recursive() : anonymous function as callback *** +-- Anonymous function with one argument -- +int(2) + +int(5) + +int(10) + +int(0) + +bool(true) +-- Anonymous function with two arguments -- +int(0) +int(2) + +int(1) +int(5) + +int(0) +int(10) + +int(1) +int(0) + +bool(true) +-- Anonymous function with three arguments -- +int(0) +int(2) +int(10) + +int(1) +int(5) +int(10) + +int(0) +int(10) +int(10) + +int(1) +int(0) +int(10) + +bool(true) +-- Anonymous function with null argument -- +1 +1 +1 +1 +bool(true) +Done diff --git a/tests/std/array/array_walk_recursive_variation8.phpt b/tests/std/array/array_walk_recursive_variation8.phpt new file mode 100644 index 00000000..c3cd3454 --- /dev/null +++ b/tests/std/array/array_walk_recursive_variation8.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test array_walk_recursive() function : usage variations - buit-in function as callback +--FILE-- + 1, 65), array(98, 100), array(6 => -4)); + +echo "-- With 'pow' built-in function --\n"; +var_dump( array_walk_recursive($input, 'pow')); + +echo "-- With 'min' built-in function --\n"; +var_dump( array_walk_recursive($input, "min")); + +echo "-- With 'echo' language construct --\n"; +try { + var_dump( array_walk_recursive($input, "echo")); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_walk_recursive() : built-in function as callback *** +-- With 'pow' built-in function -- +bool(true) +-- With 'min' built-in function -- +bool(true) +-- With 'echo' language construct -- +array_walk_recursive(): Argument #2 ($callback) must be a valid callback, function "echo" not found or invalid function name +Done diff --git a/tests/std/array/array_walk_recursive_variation9.phpt b/tests/std/array/array_walk_recursive_variation9.phpt new file mode 100644 index 00000000..58847eb9 --- /dev/null +++ b/tests/std/array/array_walk_recursive_variation9.phpt @@ -0,0 +1,101 @@ +--TEST-- +Test array_walk_recursive() function : usage variations - different callback functions +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_walk_recursive() : callback function variation *** +-- callback function with both parameters -- +int(0) +string(5) "Apple" + +int(1) +string(6) "Banana" + +int(1) +string(5) "Mango" + +int(0) +string(6) "Orange" + +bool(true) +-- callback function with only one parameter -- +string(5) "Apple" + +string(6) "Banana" + +string(5) "Mango" + +string(6) "Orange" + +bool(true) +-- callback function without parameters -- +callback3() called +callback3() called +callback3() called +callback3() called +bool(true) +-- passing one more parameter to function with two parameters -- +int(0) +string(5) "Apple" + +int(1) +string(6) "Banana" + +int(1) +string(5) "Mango" + +int(0) +string(6) "Orange" + +bool(true) +Done diff --git a/tests/std/array/array_walk_variation3.phpt b/tests/std/array/array_walk_variation3.phpt new file mode 100644 index 00000000..840cbf19 --- /dev/null +++ b/tests/std/array/array_walk_variation3.phpt @@ -0,0 +1,116 @@ +--TEST-- +Test array_walk() function : usage variations - 'input' array with different values +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_walk() : 'input' array with different values*** + +-- Iteration 1 -- +1 : 0 1 +1 : 1 0 +1 : 2 -10 +1 : 3 19 +1 : 4 -33 +1 : 5 90 +1 : 6 31 +1 : 7 -110 +bool(true) + +-- Iteration 2 -- +2 : 0 3.4 +2 : 1 0.8 +2 : 2 -2.9 +2 : 3 625 +2 : 4 0.0082 +bool(true) + +-- Iteration 3 -- +3 : 0 Mango +3 : 1 Apple +3 : 2 Orange +3 : 3 Lemon +bool(true) + +-- Iteration 4 -- +4 : 0 1 +4 : 1 +4 : 2 1 +4 : 3 +bool(true) + +-- Iteration 5 -- +5 : 0 +5 : 1 +bool(true) + +-- Iteration 6 -- +bool(true) + +-- Iteration 7 -- +7 : 0 binary +bool(true) + +-- Iteration 8 -- +8 : 0 16 +8 : 1 8.345 +8 : 2 Fruits +8 : 3 1 +8 : 4 +8 : 5 +8 : 6 -98 +8 : 7 0.005 +8 : 8 banana +bool(true) +Done diff --git a/tests/std/array/array_walk_variation4.phpt b/tests/std/array/array_walk_variation4.phpt new file mode 100644 index 00000000..46958129 --- /dev/null +++ b/tests/std/array/array_walk_variation4.phpt @@ -0,0 +1,78 @@ +--TEST-- +Test array_walk() function : usage variations - 'input' array with subarray +--FILE-- + +--EXPECT-- +*** Testing array_walk() : array with subarray *** +int(0) +array(0) { +} + +int(1) +array(1) { + [0]=> + int(1) +} + +int(2) +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} + +int(3) +array(2) { + [0]=> + string(5) "Mango" + [1]=> + string(6) "Orange" +} + +int(4) +array(1) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } +} + +bool(true) +Done diff --git a/tests/std/array/array_walk_variation5.phpt b/tests/std/array/array_walk_variation5.phpt new file mode 100644 index 00000000..f41fe67e --- /dev/null +++ b/tests/std/array/array_walk_variation5.phpt @@ -0,0 +1,59 @@ +--TEST-- +Test array_walk() function : usage variations - 'input' argument containing reference variables +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_walk() : array with references *** +int(0) +int(10) + +int(1) +int(-20) + +int(2) +int(-35) + +int(3) +int(10) + +int(4) +int(0) + +int(5) +int(50) + +bool(true) +Done diff --git a/tests/std/array/array_walk_variation6.phpt b/tests/std/array/array_walk_variation6.phpt new file mode 100644 index 00000000..600f67c5 --- /dev/null +++ b/tests/std/array/array_walk_variation6.phpt @@ -0,0 +1,123 @@ +--TEST-- +Test array_walk() function : usage variations - 'input' argument as diff. associative arrays +--FILE-- + 25, 5 => 12, 0 => -80, -2 => 100, 5 => 30); +echo "-- Associative array with numeric keys --\n"; +var_dump( array_walk($input, "for_numeric", 10)); + +// String keys +$input = array( "a" => "Apple", 'b' => 'Bananna', "c" => "carrot", 'o' => "Orange"); +echo "-- Associative array with string keys --\n"; +var_dump( array_walk($input, "for_string")); + +// binary keys +$input = array( b"a" => "Apple", b"b" => "Banana"); +echo "-- Associative array with binary keys --\n"; +var_dump( array_walk($input, "for_string")); + +// Mixed keys - numeric/string +$input = array( 0 => 1, 1 => 2, "a" => "Apple", "b" => "Banana", 2 =>3); +echo "-- Associative array with numeric/string keys --\n"; +var_dump( array_walk($input, "for_mixed")); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing array_walk() : 'input' as an associative array *** +-- Associative array with numeric keys -- +int(1) +int(25) +int(10) + +int(5) +int(30) +int(10) + +int(0) +int(-80) +int(10) + +int(-2) +int(100) +int(10) + +bool(true) +-- Associative array with string keys -- +string(1) "a" +string(5) "Apple" + +string(1) "b" +string(7) "Bananna" + +string(1) "c" +string(6) "carrot" + +string(1) "o" +string(6) "Orange" + +bool(true) +-- Associative array with binary keys -- +string(1) "a" +string(5) "Apple" + +string(1) "b" +string(6) "Banana" + +bool(true) +-- Associative array with numeric/string keys -- +int(0) +int(1) + +int(1) +int(2) + +string(1) "a" +string(5) "Apple" + +string(1) "b" +string(6) "Banana" + +int(2) +int(3) + +bool(true) +Done diff --git a/tests/std/array/array_walk_variation7.phpt b/tests/std/array/array_walk_variation7.phpt new file mode 100644 index 00000000..e5b80ba8 --- /dev/null +++ b/tests/std/array/array_walk_variation7.phpt @@ -0,0 +1,81 @@ +--TEST-- +Test array_walk() function : usage variations - anonymous callback function +--FILE-- + +--EXPECT-- +*** Testing array_walk() : anonymous function as callback *** +-- Anonymous function with one argument -- +int(2) + +int(5) + +int(10) + +int(0) + +bool(true) +-- Anonymous function with two arguments -- +int(0) +int(2) + +int(1) +int(5) + +int(2) +int(10) + +int(3) +int(0) + +bool(true) +-- Anonymous function with three arguments -- +int(0) +int(2) +int(10) + +int(1) +int(5) +int(10) + +int(2) +int(10) +int(10) + +int(3) +int(0) +int(10) + +bool(true) +-- Anonymous function with null argument -- +1 +1 +1 +1 +bool(true) +Done diff --git a/tests/std/array/array_walk_variation8.phpt b/tests/std/array/array_walk_variation8.phpt new file mode 100644 index 00000000..0ba4fe9f --- /dev/null +++ b/tests/std/array/array_walk_variation8.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test array_walk() function : usage variations - buit-in function as callback +--FILE-- + 1, 65, 98, 100, 6 => -4); + +echo "-- With 'pow' built-in function --\n"; +var_dump( array_walk($input, 'pow')); + +echo "-- With 'min' built-in function --\n"; +var_dump( array_walk($input, "min")); + +echo "-- With 'echo' language construct --\n"; +try { + var_dump( array_walk($input, "echo")); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing array_walk() : built-in function as callback *** +-- With 'pow' built-in function -- +bool(true) +-- With 'min' built-in function -- +bool(true) +-- With 'echo' language construct -- +array_walk(): Argument #2 ($callback) must be a valid callback, function "echo" not found or invalid function name +Done diff --git a/tests/std/array/array_walk_variation9.phpt b/tests/std/array/array_walk_variation9.phpt new file mode 100644 index 00000000..434264de --- /dev/null +++ b/tests/std/array/array_walk_variation9.phpt @@ -0,0 +1,101 @@ +--TEST-- +Test array_walk() function : usage variations - different callback functions +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing array_walk() : callback function variation *** +-- callback function with both parameters -- +int(0) +string(5) "Apple" + +int(1) +string(6) "Banana" + +int(2) +string(5) "Mango" + +int(3) +string(6) "Orange" + +bool(true) +-- callback function with only one parameter -- +string(5) "Apple" + +string(6) "Banana" + +string(5) "Mango" + +string(6) "Orange" + +bool(true) +-- callback function without parameters -- +callback3() called +callback3() called +callback3() called +callback3() called +bool(true) +-- passing one more parameter to function with two parameters -- +int(0) +string(5) "Apple" + +int(1) +string(6) "Banana" + +int(2) +string(5) "Mango" + +int(3) +string(6) "Orange" + +bool(true) +Done diff --git a/tests/std/array/arsort_basic.phpt b/tests/std/array/arsort_basic.phpt new file mode 100644 index 00000000..c636a627 --- /dev/null +++ b/tests/std/array/arsort_basic.phpt @@ -0,0 +1,239 @@ +--TEST-- +Test arsort() function : basic functionality +--FILE-- + "lemon", "o" => "orange", + "O" => "Orange", "O1" => "Orange1", "o2" => "orange2", "O3" => "Orange3", "o20" => "orange20", + "b" => "banana", +); +// an array containing unsorted numeric values with indices +$unsorted_numerics = array( 1 => 100, 2 => 33, 3 => 555, 4 => 22 ); + +echo "\n-- Testing arsort() by supplying string array, 'flag' value is default --\n"; +$temp_array = $unsorted_strings; +var_dump( arsort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying numeric array, 'flag' value is default --\n"; +$temp_array = $unsorted_numerics; +var_dump( arsort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying string array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_strings; +var_dump( arsort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying numeric array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_numerics; +var_dump( arsort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying string array, 'flag' = SORT_STRING --\n"; +$temp_array = $unsorted_strings; +var_dump( arsort($temp_array, SORT_STRING) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( arsort($temp_array, SORT_STRING|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying string array (natural), 'flag' = SORT_NATURAL --\n"; +$temp_array = $unsorted_strings; +var_dump( arsort($temp_array, SORT_NATURAL) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( arsort($temp_array, SORT_NATURAL|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying numeric array, 'flag' = SORT_NUMERIC --\n"; +$temp_array = $unsorted_numerics; +var_dump( arsort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing arsort() : basic functionality *** + +-- Testing arsort() by supplying string array, 'flag' value is default -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["o"]=> + string(6) "orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" + ["O3"]=> + string(7) "Orange3" + ["O1"]=> + string(7) "Orange1" + ["O"]=> + string(6) "Orange" +} + +-- Testing arsort() by supplying numeric array, 'flag' value is default -- +bool(true) +array(4) { + [3]=> + int(555) + [1]=> + int(100) + [2]=> + int(33) + [4]=> + int(22) +} + +-- Testing arsort() by supplying string array, 'flag' = SORT_REGULAR -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["o"]=> + string(6) "orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" + ["O3"]=> + string(7) "Orange3" + ["O1"]=> + string(7) "Orange1" + ["O"]=> + string(6) "Orange" +} + +-- Testing arsort() by supplying numeric array, 'flag' = SORT_REGULAR -- +bool(true) +array(4) { + [3]=> + int(555) + [1]=> + int(100) + [2]=> + int(33) + [4]=> + int(22) +} + +-- Testing arsort() by supplying string array, 'flag' = SORT_STRING -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["o"]=> + string(6) "orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" + ["O3"]=> + string(7) "Orange3" + ["O1"]=> + string(7) "Orange1" + ["O"]=> + string(6) "Orange" +} + +-- Testing arsort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE -- +bool(true) +array(8) { + ["O3"]=> + string(7) "Orange3" + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["O1"]=> + string(7) "Orange1" + ["o"]=> + string(6) "orange" + ["O"]=> + string(6) "Orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" +} + +-- Testing arsort() by supplying string array (natural), 'flag' = SORT_NATURAL -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["o"]=> + string(6) "orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" + ["O3"]=> + string(7) "Orange3" + ["O1"]=> + string(7) "Orange1" + ["O"]=> + string(6) "Orange" +} + +-- Testing arsort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["O3"]=> + string(7) "Orange3" + ["o2"]=> + string(7) "orange2" + ["O1"]=> + string(7) "Orange1" + ["o"]=> + string(6) "orange" + ["O"]=> + string(6) "Orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" +} + +-- Testing arsort() by supplying numeric array, 'flag' = SORT_NUMERIC -- +bool(true) +array(4) { + [3]=> + int(555) + [1]=> + int(100) + [2]=> + int(33) + [4]=> + int(22) +} +Done diff --git a/tests/std/array/arsort_object1.phpt b/tests/std/array/arsort_object1.phpt new file mode 100644 index 00000000..edefd9f1 --- /dev/null +++ b/tests/std/array/arsort_object1.phpt @@ -0,0 +1,220 @@ +--TEST-- +Test arsort() function : object functionality - sort objects +--FILE-- +class_value = $value; + } +} +// class declaration for string objects +class for_string_arsort +{ + public $class_value; + // initializing object member value + function __construct($value) + { + $this->class_value = $value; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * testing arsort() by providing integer/string object arrays with following flag values + * 1. Default flag value + * 2. SORT_REGULAR - compare items normally + */ + echo "*** Testing arsort() : object functionality ***\n"; + // array of integer objects + $unsorted_int_obj = array(1 => new for_integer_arsort(11), 2 => new for_integer_arsort(66), 3 => new for_integer_arsort(23), 4 => new for_integer_arsort(-5), 5 => new for_integer_arsort(0.001), 6 => new for_integer_arsort(0)); + // array of string objects + $unsorted_str_obj = array("a" => new for_string_arsort("axx"), "b" => new for_string_arsort("t"), "c" => new for_string_arsort("w"), "d" => new for_string_arsort("py"), "e" => new for_string_arsort("apple"), "f" => new for_string_arsort("Orange"), "g" => new for_string_arsort("Lemon"), "h" => new for_string_arsort("aPPle")); + echo "\n-- Testing arsort() by supplying various object arrays, 'flag' value is default --\n"; + // testing arsort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(arsort($temp_array)); + var_dump($temp_array); + // testing arsort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(arsort($temp_array)); + var_dump($temp_array); + echo "\n-- Testing arsort() by supplying various object arrays, 'flag' value is SORT_REGULAR --\n"; + // testing arsort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(arsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing arsort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(arsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done\n"; +} +?> +--EXPECT-- +*** Testing arsort() : object functionality *** + +-- Testing arsort() by supplying various object arrays, 'flag' value is default -- +bool(true) +array(6) { + [2]=> + object(for_integer_arsort)#2 (1) { + ["class_value"]=> + int(66) + } + [3]=> + object(for_integer_arsort)#3 (1) { + ["class_value"]=> + int(23) + } + [1]=> + object(for_integer_arsort)#1 (1) { + ["class_value"]=> + int(11) + } + [5]=> + object(for_integer_arsort)#5 (1) { + ["class_value"]=> + float(0.001) + } + [6]=> + object(for_integer_arsort)#6 (1) { + ["class_value"]=> + int(0) + } + [4]=> + object(for_integer_arsort)#4 (1) { + ["class_value"]=> + int(-5) + } +} +bool(true) +array(8) { + ["c"]=> + object(for_string_arsort)#9 (1) { + ["class_value"]=> + string(1) "w" + } + ["b"]=> + object(for_string_arsort)#8 (1) { + ["class_value"]=> + string(1) "t" + } + ["d"]=> + object(for_string_arsort)#10 (1) { + ["class_value"]=> + string(2) "py" + } + ["a"]=> + object(for_string_arsort)#7 (1) { + ["class_value"]=> + string(3) "axx" + } + ["e"]=> + object(for_string_arsort)#11 (1) { + ["class_value"]=> + string(5) "apple" + } + ["h"]=> + object(for_string_arsort)#14 (1) { + ["class_value"]=> + string(5) "aPPle" + } + ["f"]=> + object(for_string_arsort)#12 (1) { + ["class_value"]=> + string(6) "Orange" + } + ["g"]=> + object(for_string_arsort)#13 (1) { + ["class_value"]=> + string(5) "Lemon" + } +} + +-- Testing arsort() by supplying various object arrays, 'flag' value is SORT_REGULAR -- +bool(true) +array(6) { + [2]=> + object(for_integer_arsort)#2 (1) { + ["class_value"]=> + int(66) + } + [3]=> + object(for_integer_arsort)#3 (1) { + ["class_value"]=> + int(23) + } + [1]=> + object(for_integer_arsort)#1 (1) { + ["class_value"]=> + int(11) + } + [5]=> + object(for_integer_arsort)#5 (1) { + ["class_value"]=> + float(0.001) + } + [6]=> + object(for_integer_arsort)#6 (1) { + ["class_value"]=> + int(0) + } + [4]=> + object(for_integer_arsort)#4 (1) { + ["class_value"]=> + int(-5) + } +} +bool(true) +array(8) { + ["c"]=> + object(for_string_arsort)#9 (1) { + ["class_value"]=> + string(1) "w" + } + ["b"]=> + object(for_string_arsort)#8 (1) { + ["class_value"]=> + string(1) "t" + } + ["d"]=> + object(for_string_arsort)#10 (1) { + ["class_value"]=> + string(2) "py" + } + ["a"]=> + object(for_string_arsort)#7 (1) { + ["class_value"]=> + string(3) "axx" + } + ["e"]=> + object(for_string_arsort)#11 (1) { + ["class_value"]=> + string(5) "apple" + } + ["h"]=> + object(for_string_arsort)#14 (1) { + ["class_value"]=> + string(5) "aPPle" + } + ["f"]=> + object(for_string_arsort)#12 (1) { + ["class_value"]=> + string(6) "Orange" + } + ["g"]=> + object(for_string_arsort)#13 (1) { + ["class_value"]=> + string(5) "Lemon" + } +} +Done diff --git a/tests/std/array/arsort_object2.phpt b/tests/std/array/arsort_object2.phpt new file mode 100644 index 00000000..3db1891a --- /dev/null +++ b/tests/std/array/arsort_object2.phpt @@ -0,0 +1,232 @@ +--TEST-- +Test arsort() function : object functionality - sorting objects with diff. accessibility of member vars +--FILE-- +public_class_value = $value1; + $this->private_class_value = $value2; + $this->protected_class_value = $value3; + } +} +// class declaration for string objects +class for_string_arsort +{ + public $public_class_value; + private $private_class_value; + protected $protected_class_value; + // initializing object member value + function __construct($value1, $value2, $value3) + { + $this->public_class_value = $value1; + $this->private_class_value = $value2; + $this->protected_class_value = $value3; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * testing arsort() by providing integer/string object arrays with following flag values + * 1. Default flag value + 2. SORT_REGULAR - compare items normally + */ + echo "*** Testing arsort() : object functionality ***\n"; + // array of integer objects + $unsorted_int_obj = array(1 => new for_integer_arsort(11, 33, 2), 2 => new for_integer_arsort(44, 66, 3), 3 => new for_integer_arsort(23, 32, 6), 4 => new for_integer_arsort(-88, -5, -4)); + // array of string objects + $unsorted_str_obj = array("a" => new for_string_arsort("axx", "AXX", "d"), "b" => new for_string_arsort("T", "t", "q"), "c" => new for_string_arsort("w", "W", "c"), "d" => new for_string_arsort("PY", "py", "s")); + echo "\n-- Testing arsort() by supplying various object arrays, 'flag' value is default --\n"; + // testing arsort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(arsort($temp_array)); + var_dump($temp_array); + // testing arsort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(arsort($temp_array)); + var_dump($temp_array); + echo "\n-- Testing arsort() by supplying various object arrays, 'flag' value is SORT_REGULAR --\n"; + // testing arsort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(arsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing arsort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(arsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done\n"; +} +?> +--EXPECT-- +*** Testing arsort() : object functionality *** + +-- Testing arsort() by supplying various object arrays, 'flag' value is default -- +bool(true) +array(4) { + [2]=> + object(for_integer_arsort)#2 (3) { + ["public_class_value"]=> + int(44) + ["private_class_value":"for_integer_arsort":private]=> + int(66) + ["protected_class_value":protected]=> + int(3) + } + [3]=> + object(for_integer_arsort)#3 (3) { + ["public_class_value"]=> + int(23) + ["private_class_value":"for_integer_arsort":private]=> + int(32) + ["protected_class_value":protected]=> + int(6) + } + [1]=> + object(for_integer_arsort)#1 (3) { + ["public_class_value"]=> + int(11) + ["private_class_value":"for_integer_arsort":private]=> + int(33) + ["protected_class_value":protected]=> + int(2) + } + [4]=> + object(for_integer_arsort)#4 (3) { + ["public_class_value"]=> + int(-88) + ["private_class_value":"for_integer_arsort":private]=> + int(-5) + ["protected_class_value":protected]=> + int(-4) + } +} +bool(true) +array(4) { + ["c"]=> + object(for_string_arsort)#7 (3) { + ["public_class_value"]=> + string(1) "w" + ["private_class_value":"for_string_arsort":private]=> + string(1) "W" + ["protected_class_value":protected]=> + string(1) "c" + } + ["a"]=> + object(for_string_arsort)#5 (3) { + ["public_class_value"]=> + string(3) "axx" + ["private_class_value":"for_string_arsort":private]=> + string(3) "AXX" + ["protected_class_value":protected]=> + string(1) "d" + } + ["b"]=> + object(for_string_arsort)#6 (3) { + ["public_class_value"]=> + string(1) "T" + ["private_class_value":"for_string_arsort":private]=> + string(1) "t" + ["protected_class_value":protected]=> + string(1) "q" + } + ["d"]=> + object(for_string_arsort)#8 (3) { + ["public_class_value"]=> + string(2) "PY" + ["private_class_value":"for_string_arsort":private]=> + string(2) "py" + ["protected_class_value":protected]=> + string(1) "s" + } +} + +-- Testing arsort() by supplying various object arrays, 'flag' value is SORT_REGULAR -- +bool(true) +array(4) { + [2]=> + object(for_integer_arsort)#2 (3) { + ["public_class_value"]=> + int(44) + ["private_class_value":"for_integer_arsort":private]=> + int(66) + ["protected_class_value":protected]=> + int(3) + } + [3]=> + object(for_integer_arsort)#3 (3) { + ["public_class_value"]=> + int(23) + ["private_class_value":"for_integer_arsort":private]=> + int(32) + ["protected_class_value":protected]=> + int(6) + } + [1]=> + object(for_integer_arsort)#1 (3) { + ["public_class_value"]=> + int(11) + ["private_class_value":"for_integer_arsort":private]=> + int(33) + ["protected_class_value":protected]=> + int(2) + } + [4]=> + object(for_integer_arsort)#4 (3) { + ["public_class_value"]=> + int(-88) + ["private_class_value":"for_integer_arsort":private]=> + int(-5) + ["protected_class_value":protected]=> + int(-4) + } +} +bool(true) +array(4) { + ["c"]=> + object(for_string_arsort)#7 (3) { + ["public_class_value"]=> + string(1) "w" + ["private_class_value":"for_string_arsort":private]=> + string(1) "W" + ["protected_class_value":protected]=> + string(1) "c" + } + ["a"]=> + object(for_string_arsort)#5 (3) { + ["public_class_value"]=> + string(3) "axx" + ["private_class_value":"for_string_arsort":private]=> + string(3) "AXX" + ["protected_class_value":protected]=> + string(1) "d" + } + ["b"]=> + object(for_string_arsort)#6 (3) { + ["public_class_value"]=> + string(1) "T" + ["private_class_value":"for_string_arsort":private]=> + string(1) "t" + ["protected_class_value":protected]=> + string(1) "q" + } + ["d"]=> + object(for_string_arsort)#8 (3) { + ["public_class_value"]=> + string(2) "PY" + ["private_class_value":"for_string_arsort":private]=> + string(2) "py" + ["protected_class_value":protected]=> + string(1) "s" + } +} +Done diff --git a/tests/std/array/arsort_variation10.phpt b/tests/std/array/arsort_variation10.phpt new file mode 100644 index 00000000..30127b84 --- /dev/null +++ b/tests/std/array/arsort_variation10.phpt @@ -0,0 +1,108 @@ +--TEST-- +Test arsort() function : usage variations - sort octal values +--FILE-- + 01235, 0321 => 0321, 0345 => 0345, 066 => 066, 0772 => 0772, + 077 => 077, -066 => -066, -0345 => -0345, 0 => 0 +); + +echo "\n-- Testing arsort() by supplying octal value array, 'flag' value is default --\n"; +$temp_array = $unsorted_oct_array; +var_dump( arsort($temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing arsort() by supplying octal value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $unsorted_oct_array; +var_dump( arsort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing arsort() by supplying octal value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $unsorted_oct_array; +var_dump( arsort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing arsort() : usage variations *** + +-- Testing arsort() by supplying octal value array, 'flag' value is default -- +bool(true) +array(9) { + [669]=> + int(669) + [506]=> + int(506) + [229]=> + int(229) + [209]=> + int(209) + [63]=> + int(63) + [54]=> + int(54) + [0]=> + int(0) + [-54]=> + int(-54) + [-229]=> + int(-229) +} + +-- Testing arsort() by supplying octal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(9) { + [669]=> + int(669) + [506]=> + int(506) + [229]=> + int(229) + [209]=> + int(209) + [63]=> + int(63) + [54]=> + int(54) + [0]=> + int(0) + [-54]=> + int(-54) + [-229]=> + int(-229) +} + +-- Testing arsort() by supplying octal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(9) { + [669]=> + int(669) + [506]=> + int(506) + [229]=> + int(229) + [209]=> + int(209) + [63]=> + int(63) + [54]=> + int(54) + [0]=> + int(0) + [-54]=> + int(-54) + [-229]=> + int(-229) +} +Done diff --git a/tests/std/array/arsort_variation11.phpt b/tests/std/array/arsort_variation11.phpt new file mode 100644 index 00000000..8d0f99a2 --- /dev/null +++ b/tests/std/array/arsort_variation11.phpt @@ -0,0 +1,155 @@ +--TEST-- +Test arsort() function : usage variations - sort mixed values, 'sort_flags' as default/SORT_REGULAR (OK to fail as result is unpredectable) +--SKIPIF-- + +--FILE-- + array(), + "array2" => array ( "sub_array[2,1]" => array(33,-5,6), "sub_array[2,2]" => array(11), + "sub_array[2,3]" => array(22,-55), "sub_array[2,4]" => array() + ), + 4 => 4, "4" => "4", 4 => 4.01, "b" => "b", "5" => "5", -2 => -2, -2 => -2.01, + -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", NULL => NULL, + "ab" => "ab", "abcd" => "abcd", 0 => 0.01, -0 => -0, '' => '' , + "abcd\x00abcd\x00abcd" => "abcd\x00abcd\x00abcd", 0 => 0.001 +); + +echo "\n-- Testing arsort() by supplying mixed value array, 'flag' value is default --\n"; +$temp_array = $mixed_values; +var_dump( arsort($temp_array) ); +var_dump($temp_array); + +echo "\n-- Testing arsort() by supplying mixed value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $mixed_values; +var_dump( arsort($temp_array, SORT_REGULAR) ); +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing arsort() : usage variations *** + +-- Testing arsort() by supplying mixed value array, 'flag' value is default -- +bool(true) +array(13) { + ["array2"]=> + array(4) { + ["sub_array[2,1]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[2,2]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[2,3]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[2,4]"]=> + array(0) { + } + } + ["array1"]=> + array(0) { + } + ["b"]=> + string(1) "b" + ["abcd%0abcd%0abcd"]=> + string(14) "abcd%0abcd%0abcd" + ["abcd"]=> + string(4) "abcd" + ["ab"]=> + string(2) "ab" + ["True"]=> + string(4) "True" + [5]=> + string(1) "5" + [4]=> + float(4.01) + [0]=> + float(0.001) + ["-.9"]=> + string(3) "-.9" + [-2]=> + float(-2.98989) + [""]=> + string(0) "" +} + +-- Testing arsort() by supplying mixed value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(13) { + ["array2"]=> + array(4) { + ["sub_array[2,1]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[2,2]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[2,3]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[2,4]"]=> + array(0) { + } + } + ["array1"]=> + array(0) { + } + ["b"]=> + string(1) "b" + ["abcd%0abcd%0abcd"]=> + string(14) "abcd%0abcd%0abcd" + ["abcd"]=> + string(4) "abcd" + ["ab"]=> + string(2) "ab" + ["True"]=> + string(4) "True" + [5]=> + string(1) "5" + [4]=> + float(4.01) + [0]=> + float(0.001) + ["-.9"]=> + string(3) "-.9" + [-2]=> + float(-2.98989) + [""]=> + string(0) "" +} +Done diff --git a/tests/std/array/arsort_variation3.phpt b/tests/std/array/arsort_variation3.phpt new file mode 100644 index 00000000..e54d9c3b --- /dev/null +++ b/tests/std/array/arsort_variation3.phpt @@ -0,0 +1,320 @@ +--TEST-- +Test arsort() function : usage variations - sort integer/float values +--FILE-- + 11, 2 => -11, 3 => 21, 4 => -21, 5 => 31, 6 => -31, 7 => 0, 8 => 41, 10 =>-41), + + // float value array + array(1 => 10.5, 2 => -10.5, 3 => 10.5e2, 4 => 10.6E-2, 5 => .5, 6 => .0001, 7 => -.1), + + // mixed value array + array(1 => .0001, 2 => .0021, 3 => -.01, 4 => -1, 5 => 0, 6 => .09, 7 => 2, 8 => -.9, 9 => 10.6E-2, 10 => -10.6E-2, 11 => 33), + + // array values contains minimum and maximum ranges + array(1 => 2147483647, 2 => 2147483648, 3 => -2147483647, 4 => -2147483648, 5 => -0, 6 => 0, 7 => -2147483649) +); + +// set of possible flag values +$flag_value = array("SORT_REGULAR" => SORT_REGULAR, "SORT_NUMERIC" => SORT_NUMERIC); + +$count = 1; +echo "\n-- Testing arsort() by supplying various integer/float arrays --\n"; + +// loop through to test arsort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort_flag -\n"; + $temp_array = $array; + var_dump(arsort($temp_array) ); + var_dump($temp_array); + + // loop through $flag_value array and setting all possible flag values + foreach($flag_value as $key => $flag){ + echo "- Sort_flag = $key -\n"; + $temp_array = $array; + var_dump(arsort($temp_array, $flag) ); + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing arsort() : usage variations *** + +-- Testing arsort() by supplying various integer/float arrays -- + +-- Iteration 1 -- +- With default sort_flag - +bool(true) +array(9) { + [8]=> + int(41) + [5]=> + int(31) + [3]=> + int(21) + [1]=> + int(11) + [7]=> + int(0) + [2]=> + int(-11) + [4]=> + int(-21) + [6]=> + int(-31) + [10]=> + int(-41) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(9) { + [8]=> + int(41) + [5]=> + int(31) + [3]=> + int(21) + [1]=> + int(11) + [7]=> + int(0) + [2]=> + int(-11) + [4]=> + int(-21) + [6]=> + int(-31) + [10]=> + int(-41) +} +- Sort_flag = SORT_NUMERIC - +bool(true) +array(9) { + [8]=> + int(41) + [5]=> + int(31) + [3]=> + int(21) + [1]=> + int(11) + [7]=> + int(0) + [2]=> + int(-11) + [4]=> + int(-21) + [6]=> + int(-31) + [10]=> + int(-41) +} + +-- Iteration 2 -- +- With default sort_flag - +bool(true) +array(7) { + [3]=> + float(1050) + [1]=> + float(10.5) + [5]=> + float(0.5) + [4]=> + float(0.106) + [6]=> + float(0.0001) + [7]=> + float(-0.1) + [2]=> + float(-10.5) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(7) { + [3]=> + float(1050) + [1]=> + float(10.5) + [5]=> + float(0.5) + [4]=> + float(0.106) + [6]=> + float(0.0001) + [7]=> + float(-0.1) + [2]=> + float(-10.5) +} +- Sort_flag = SORT_NUMERIC - +bool(true) +array(7) { + [3]=> + float(1050) + [1]=> + float(10.5) + [5]=> + float(0.5) + [4]=> + float(0.106) + [6]=> + float(0.0001) + [7]=> + float(-0.1) + [2]=> + float(-10.5) +} + +-- Iteration 3 -- +- With default sort_flag - +bool(true) +array(11) { + [11]=> + int(33) + [7]=> + int(2) + [9]=> + float(0.106) + [6]=> + float(0.09) + [2]=> + float(0.0021) + [1]=> + float(0.0001) + [5]=> + int(0) + [3]=> + float(-0.01) + [10]=> + float(-0.106) + [8]=> + float(-0.9) + [4]=> + int(-1) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(11) { + [11]=> + int(33) + [7]=> + int(2) + [9]=> + float(0.106) + [6]=> + float(0.09) + [2]=> + float(0.0021) + [1]=> + float(0.0001) + [5]=> + int(0) + [3]=> + float(-0.01) + [10]=> + float(-0.106) + [8]=> + float(-0.9) + [4]=> + int(-1) +} +- Sort_flag = SORT_NUMERIC - +bool(true) +array(11) { + [11]=> + int(33) + [7]=> + int(2) + [9]=> + float(0.106) + [6]=> + float(0.09) + [2]=> + float(0.0021) + [1]=> + float(0.0001) + [5]=> + int(0) + [3]=> + float(-0.01) + [10]=> + float(-0.106) + [8]=> + float(-0.9) + [4]=> + int(-1) +} + +-- Iteration 4 -- +- With default sort_flag - +bool(true) +array(7) { + [2]=> + %s(2147483648) + [1]=> + int(2147483647) + [5]=> + int(0) + [6]=> + int(0) + [3]=> + int(-2147483647) + [4]=> + %s(-2147483648) + [7]=> + %s(-2147483649) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(7) { + [2]=> + %s(2147483648) + [1]=> + int(2147483647) + [5]=> + int(0) + [6]=> + int(0) + [3]=> + int(-2147483647) + [4]=> + %s(-2147483648) + [7]=> + %s(-2147483649) +} +- Sort_flag = SORT_NUMERIC - +bool(true) +array(7) { + [2]=> + %s(2147483648) + [1]=> + int(2147483647) + [5]=> + int(0) + [6]=> + int(0) + [3]=> + int(-2147483647) + [4]=> + %s(-2147483648) + [7]=> + %s(-2147483649) +} +Done diff --git a/tests/std/array/arsort_variation4.phpt b/tests/std/array/arsort_variation4.phpt new file mode 100644 index 00000000..5e0bd2cd --- /dev/null +++ b/tests/std/array/arsort_variation4.phpt @@ -0,0 +1,78 @@ +--TEST-- +Test arsort() function : usage variations - sort reference variables +--SKIPIF-- + + +--FILE-- + &$value1 , 2 => &$value2, 3 => &$value3); + +echo "\n-- Testing arsort() by supplying reference variable array, 'flag' value is default --\n"; +$temp_array = $unsorted_numerics; +var_dump( arsort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying reference variable array, 'flag' = SORT_REGULAR --\n"; +$temp_array = &$unsorted_numerics; +var_dump( arsort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing arsort() by supplying reference variable array, 'flag' = SORT_NUMERIC --\n"; +$temp_array = &$unsorted_numerics; +var_dump( arsort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing arsort() :usage variations *** + +-- Testing arsort() by supplying reference variable array, 'flag' value is default -- +bool(true) +array(3) { + [3]=> + &int(555) + [1]=> + &int(100) + [2]=> + &int(33) +} + +-- Testing arsort() by supplying reference variable array, 'flag' = SORT_REGULAR -- +bool(true) +array(3) { + [3]=> + &int(555) + [1]=> + &int(100) + [2]=> + &int(33) +} + +-- Testing arsort() by supplying reference variable array, 'flag' = SORT_NUMERIC -- +bool(true) +array(3) { + [3]=> + &int(555) + [1]=> + &int(100) + [2]=> + &int(33) +} +Done diff --git a/tests/std/array/arsort_variation5.phpt b/tests/std/array/arsort_variation5.phpt new file mode 100644 index 00000000..eb3f2f95 --- /dev/null +++ b/tests/std/array/arsort_variation5.phpt @@ -0,0 +1,236 @@ +--TEST-- +Test arsort() function : usage variations - sort strings +--FILE-- + null, "NULL" => NULL, "\a" => "\a", "\cx" => "\cx", "\e" => "\e", + "\f" => "\f", "\n" =>"\n", "\r" => "\r", "\t" => "\t", "\xhh" => "\xhh", + "\ddd" => "\ddd", "\v" => "\v" + ), + + // array contains combination of capital/small letters + array ('l' => "lemoN", 'O' => "Orange", 'b' => "banana", 'a' => "apple", 'Te' => "Test", + 'T' => "TTTT", 't' => "ttt", 'w' => "ww", 'x' => "x", 'X' => "X", 'o' => "oraNGe", + 'B' => "BANANA" + ) +); + +$flags = array("SORT_REGULAR" => SORT_REGULAR, "SORT_STRING" => SORT_STRING); + +$count = 1; +echo "\n-- Testing arsort() by supplying various string arrays --\n"; + +// loop through to test arsort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort_flag -\n"; + $temp_array = $array; + var_dump(arsort($temp_array) ); // expecting : bool(true) + var_dump($temp_array); + + // loop through $flags array and setting all possible flag values + foreach($flags as $key => $flag){ + echo "- Sort_flag = $key -\n"; + $temp_array = $array; + var_dump(arsort($temp_array, $flag) ); // expecting : bool(true) + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing arsort() : usage variations *** + +-- Testing arsort() by supplying various string arrays -- + +-- Iteration 1 -- +- With default sort_flag - +bool(true) +array(12) { + ["\xhh"]=> + string(4) "\xhh" + ["\ddd"]=> + string(4) "\ddd" + ["\cx"]=> + string(3) "\cx" + ["\a"]=> + string(2) "\a" + [""]=> + string(1) "" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + ["null"]=> + NULL + ["NULL"]=> + NULL +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(12) { + ["\xhh"]=> + string(4) "\xhh" + ["\ddd"]=> + string(4) "\ddd" + ["\cx"]=> + string(3) "\cx" + ["\a"]=> + string(2) "\a" + [""]=> + string(1) "" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + ["null"]=> + NULL + ["NULL"]=> + NULL +} +- Sort_flag = SORT_STRING - +bool(true) +array(12) { + ["\xhh"]=> + string(4) "\xhh" + ["\ddd"]=> + string(4) "\ddd" + ["\cx"]=> + string(3) "\cx" + ["\a"]=> + string(2) "\a" + [""]=> + string(1) "" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + ["null"]=> + NULL + ["NULL"]=> + NULL +} + +-- Iteration 2 -- +- With default sort_flag - +bool(true) +array(12) { + ["x"]=> + string(1) "x" + ["w"]=> + string(2) "ww" + ["t"]=> + string(3) "ttt" + ["o"]=> + string(6) "oraNGe" + ["l"]=> + string(5) "lemoN" + ["b"]=> + string(6) "banana" + ["a"]=> + string(5) "apple" + ["X"]=> + string(1) "X" + ["Te"]=> + string(4) "Test" + ["T"]=> + string(4) "TTTT" + ["O"]=> + string(6) "Orange" + ["B"]=> + string(6) "BANANA" +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(12) { + ["x"]=> + string(1) "x" + ["w"]=> + string(2) "ww" + ["t"]=> + string(3) "ttt" + ["o"]=> + string(6) "oraNGe" + ["l"]=> + string(5) "lemoN" + ["b"]=> + string(6) "banana" + ["a"]=> + string(5) "apple" + ["X"]=> + string(1) "X" + ["Te"]=> + string(4) "Test" + ["T"]=> + string(4) "TTTT" + ["O"]=> + string(6) "Orange" + ["B"]=> + string(6) "BANANA" +} +- Sort_flag = SORT_STRING - +bool(true) +array(12) { + ["x"]=> + string(1) "x" + ["w"]=> + string(2) "ww" + ["t"]=> + string(3) "ttt" + ["o"]=> + string(6) "oraNGe" + ["l"]=> + string(5) "lemoN" + ["b"]=> + string(6) "banana" + ["a"]=> + string(5) "apple" + ["X"]=> + string(1) "X" + ["Te"]=> + string(4) "Test" + ["T"]=> + string(4) "TTTT" + ["O"]=> + string(6) "Orange" + ["B"]=> + string(6) "BANANA" +} +Done diff --git a/tests/std/array/arsort_variation6.phpt b/tests/std/array/arsort_variation6.phpt new file mode 100644 index 00000000..1cf1bb5f --- /dev/null +++ b/tests/std/array/arsort_variation6.phpt @@ -0,0 +1,108 @@ +--TEST-- +Test arsort() function : usage variations - sort hexadecimal values +--FILE-- + 0x1AB, 0xFFF => 0xFFF, 0xF => 0xF, 0xFF => 0xFF, 0x2AA => 0x2AA, 0xBB => 0xBB, + 0x1ab => 0x1ab, 0xff => 0xff, -0xff => -0xFF, 0 => 0, -0x2aa => -0x2aa + ); + +echo "\n-- Testing arsort() by supplying hexadecimal value array, 'flag' value is default --\n"; +$temp_array = $unsorted_hex_array; +var_dump(arsort($temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing arsort() by supplying hexadecimal value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $unsorted_hex_array; +var_dump(arsort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing arsort() by supplying hexadecimal value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $unsorted_hex_array; +var_dump(arsort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing arsort() : usage variations *** + +-- Testing arsort() by supplying hexadecimal value array, 'flag' value is default -- +bool(true) +array(9) { + [4095]=> + int(4095) + [682]=> + int(682) + [427]=> + int(427) + [255]=> + int(255) + [187]=> + int(187) + [15]=> + int(15) + [0]=> + int(0) + [-255]=> + int(-255) + [-682]=> + int(-682) +} + +-- Testing arsort() by supplying hexadecimal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(9) { + [4095]=> + int(4095) + [682]=> + int(682) + [427]=> + int(427) + [255]=> + int(255) + [187]=> + int(187) + [15]=> + int(15) + [0]=> + int(0) + [-255]=> + int(-255) + [-682]=> + int(-682) +} + +-- Testing arsort() by supplying hexadecimal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(9) { + [4095]=> + int(4095) + [682]=> + int(682) + [427]=> + int(427) + [255]=> + int(255) + [187]=> + int(187) + [15]=> + int(15) + [0]=> + int(0) + [-255]=> + int(-255) + [-682]=> + int(-682) +} +Done diff --git a/tests/std/array/arsort_variation7.phpt b/tests/std/array/arsort_variation7.phpt new file mode 100644 index 00000000..ecd2afc4 --- /dev/null +++ b/tests/std/array/arsort_variation7.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test arsort() function : usage variations - sort bool values +--FILE-- + true, 2 => false, 3 => TRUE, 4 => FALSE); + +echo "\n-- Testing arsort() by supplying bool value array, 'flag' value is default --\n"; +$temp_array = $bool_values; +var_dump(arsort($temp_array) ); +var_dump($temp_array); + +echo "\n-- Testing arsort() by supplying bool value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $bool_values; +var_dump(arsort($temp_array, SORT_REGULAR) ); +var_dump($temp_array); + +echo "\n-- Testing arsort() by supplying bool value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $bool_values; +var_dump(arsort($temp_array, SORT_NUMERIC) ); +var_dump($temp_array); + +echo "\n-- Testing arsort() by supplying bool value array, 'flag' value is SORT_STRING --\n"; +$temp_array = $bool_values; +var_dump(arsort($temp_array, SORT_STRING) ); +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing arsort() : usage variations *** + +-- Testing arsort() by supplying bool value array, 'flag' value is default -- +bool(true) +array(4) { + [1]=> + bool(true) + [3]=> + bool(true) + [2]=> + bool(false) + [4]=> + bool(false) +} + +-- Testing arsort() by supplying bool value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(4) { + [1]=> + bool(true) + [3]=> + bool(true) + [2]=> + bool(false) + [4]=> + bool(false) +} + +-- Testing arsort() by supplying bool value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(4) { + [1]=> + bool(true) + [3]=> + bool(true) + [2]=> + bool(false) + [4]=> + bool(false) +} + +-- Testing arsort() by supplying bool value array, 'flag' value is SORT_STRING -- +bool(true) +array(4) { + [1]=> + bool(true) + [3]=> + bool(true) + [2]=> + bool(false) + [4]=> + bool(false) +} +Done diff --git a/tests/std/array/arsort_variation8.phpt b/tests/std/array/arsort_variation8.phpt new file mode 100644 index 00000000..267f8ddc --- /dev/null +++ b/tests/std/array/arsort_variation8.phpt @@ -0,0 +1,174 @@ +--TEST-- +Test arsort() function : usage variations - sort array with diff. sub arrays, 'sort_flags' as default/SORT_REGULAR +--FILE-- + array(), + + // array contains null sub array + "array[1]" => array( "sub_array[1][0]" => array() ), + + // array of arrays along with some values + "array[2]" => array("data[2,0]" => 44, "data[2,1]" => 11, "sub_array[2][0] " => array(64,61) ), + + // array contains sub arrays + "array[3]" => array ( "sub_array[3][0]" => array(33,-5,6), "sub_array[3][1]" => array(11), + "sub_array[3][2]" => array(22,-55), "sub_array[3][3]" => array() ) +); + + +$count = 1; +echo "\n-- Testing arsort() by supplying various arrays containing sub arrays --\n"; + +// loop through to test arsort() with different arrays +foreach ($various_arrays as $array) { + + echo "\n-- Iteration $count --\n"; + // testing arsort() function by supplying different arrays, flag value is default + echo "- With default sort_flag -\n"; + $temp_array = $array; + var_dump(arsort($temp_array) ); + var_dump($temp_array); + + // testing arsort() function by supplying different arrays, flag value = SORT_REGULAR + echo "- Sort_flag = SORT_REGULAR -\n"; + $temp_array = $array; + var_dump(arsort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing arsort() : usage variations *** + +-- Testing arsort() by supplying various arrays containing sub arrays -- + +-- Iteration 1 -- +- With default sort_flag - +bool(true) +array(0) { +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(0) { +} + +-- Iteration 2 -- +- With default sort_flag - +bool(true) +array(1) { + ["sub_array[1][0]"]=> + array(0) { + } +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(1) { + ["sub_array[1][0]"]=> + array(0) { + } +} + +-- Iteration 3 -- +- With default sort_flag - +bool(true) +array(3) { + ["sub_array[2][0] "]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } + ["data[2,0]"]=> + int(44) + ["data[2,1]"]=> + int(11) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(3) { + ["sub_array[2][0] "]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } + ["data[2,0]"]=> + int(44) + ["data[2,1]"]=> + int(11) +} + +-- Iteration 4 -- +- With default sort_flag - +bool(true) +array(4) { + ["sub_array[3][0]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[3][2]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[3][1]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[3][3]"]=> + array(0) { + } +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(4) { + ["sub_array[3][0]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[3][2]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[3][1]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[3][3]"]=> + array(0) { + } +} +Done diff --git a/tests/std/array/arsort_variation9.phpt b/tests/std/array/arsort_variation9.phpt new file mode 100644 index 00000000..cfad3b44 --- /dev/null +++ b/tests/std/array/arsort_variation9.phpt @@ -0,0 +1,252 @@ +--TEST-- +Test arsort() function : usage variations - sorting arrays with/without keys, 'sort_flags' as default/SORT_REGULAR +--FILE-- + 55, 66, 22, 33, 11), + array ("a" => "orange", "banana", "c" => "apple"), + array(1, 2, 3, 4, 5, 6), + array("first", 5 => "second", "third"), + array(1, 1, 8 => 1, 4 => 1, 19, 3 => 13), + array('bar' => 'baz', "foo" => 1), + array('a'=>1,'b'=>array('e'=>2,'f'=>3),'c'=>array('g'=>4),'d'=>5), +); + +$count = 1; +echo "\n-- Testing arsort() by supplying various arrays with key values --\n"; + +// loop through to test arsort() with different arrays, +// to test the new keys for the elements in the sorted array +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort_flag -\n"; + $temp_array = $array; + var_dump(arsort($temp_array) ); + var_dump($temp_array); + + echo "- Sort_flag = SORT_REGULAR -\n"; + $temp_array = $array; + var_dump(arsort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing arsort() : usage variations *** + +-- Testing arsort() by supplying various arrays with key values -- + +-- Iteration 1 -- +- With default sort_flag - +bool(true) +array(5) { + [6]=> + int(66) + [5]=> + int(55) + [8]=> + int(33) + [7]=> + int(22) + [9]=> + int(11) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(5) { + [6]=> + int(66) + [5]=> + int(55) + [8]=> + int(33) + [7]=> + int(22) + [9]=> + int(11) +} + +-- Iteration 2 -- +- With default sort_flag - +bool(true) +array(3) { + ["a"]=> + string(6) "orange" + [0]=> + string(6) "banana" + ["c"]=> + string(5) "apple" +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(3) { + ["a"]=> + string(6) "orange" + [0]=> + string(6) "banana" + ["c"]=> + string(5) "apple" +} + +-- Iteration 3 -- +- With default sort_flag - +bool(true) +array(6) { + [5]=> + int(6) + [4]=> + int(5) + [3]=> + int(4) + [2]=> + int(3) + [1]=> + int(2) + [0]=> + int(1) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(6) { + [5]=> + int(6) + [4]=> + int(5) + [3]=> + int(4) + [2]=> + int(3) + [1]=> + int(2) + [0]=> + int(1) +} + +-- Iteration 4 -- +- With default sort_flag - +bool(true) +array(3) { + [6]=> + string(5) "third" + [5]=> + string(6) "second" + [0]=> + string(5) "first" +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(3) { + [6]=> + string(5) "third" + [5]=> + string(6) "second" + [0]=> + string(5) "first" +} + +-- Iteration 5 -- +- With default sort_flag - +bool(true) +array(6) { + [9]=> + int(19) + [3]=> + int(13) + [0]=> + int(1) + [1]=> + int(1) + [8]=> + int(1) + [4]=> + int(1) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(6) { + [9]=> + int(19) + [3]=> + int(13) + [0]=> + int(1) + [1]=> + int(1) + [8]=> + int(1) + [4]=> + int(1) +} + +-- Iteration 6 -- +- With default sort_flag - +bool(true) +array(2) { + ["bar"]=> + string(3) "baz" + ["foo"]=> + int(1) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(2) { + ["bar"]=> + string(3) "baz" + ["foo"]=> + int(1) +} + +-- Iteration 7 -- +- With default sort_flag - +bool(true) +array(4) { + ["b"]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } + ["c"]=> + array(1) { + ["g"]=> + int(4) + } + ["d"]=> + int(5) + ["a"]=> + int(1) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(4) { + ["b"]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } + ["c"]=> + array(1) { + ["g"]=> + int(4) + } + ["d"]=> + int(5) + ["a"]=> + int(1) +} +Done diff --git a/tests/std/array/asort_basic.phpt b/tests/std/array/asort_basic.phpt new file mode 100644 index 00000000..13f03a92 --- /dev/null +++ b/tests/std/array/asort_basic.phpt @@ -0,0 +1,239 @@ +--TEST-- +Test asort() function : basic functionality +--FILE-- + "lemon", "o" => "orange", + "O" => "Orange", "O1" => "Orange1", "o2" => "orange2", "O3" => "Orange3", "o20" => "orange20", + "b" => "banana", +); +// an array containing unsorted numeric values with indices +$unsorted_numerics = array( 1 => 100, 2 => 33, 3 => 555, 4 => 22 ); + +echo "\n-- Testing asort() by supplying string array, 'flag' value is default --\n"; +$temp_array = $unsorted_strings; +var_dump( asort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying numeric array, 'flag' value is default --\n"; +$temp_array = $unsorted_numerics; +var_dump( asort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying string array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_strings; +var_dump( asort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying numeric array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_numerics; +var_dump( asort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying string array, 'flag' = SORT_STRING --\n"; +$temp_array = $unsorted_strings; +var_dump( asort($temp_array, SORT_STRING) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( asort($temp_array, SORT_STRING|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying string array (natural), 'flag' = SORT_NATURAL --\n"; +$temp_array = $unsorted_strings; +var_dump( asort($temp_array, SORT_NATURAL) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( asort($temp_array, SORT_NATURAL|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying numeric array, 'flag' = SORT_NUMERIC --\n"; +$temp_array = $unsorted_numerics; +var_dump( asort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing asort() : basic functionality *** + +-- Testing asort() by supplying string array, 'flag' value is default -- +bool(true) +array(8) { + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["O3"]=> + string(7) "Orange3" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" +} + +-- Testing asort() by supplying numeric array, 'flag' value is default -- +bool(true) +array(4) { + [4]=> + int(22) + [2]=> + int(33) + [1]=> + int(100) + [3]=> + int(555) +} + +-- Testing asort() by supplying string array, 'flag' = SORT_REGULAR -- +bool(true) +array(8) { + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["O3"]=> + string(7) "Orange3" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" +} + +-- Testing asort() by supplying numeric array, 'flag' = SORT_REGULAR -- +bool(true) +array(4) { + [4]=> + int(22) + [2]=> + int(33) + [1]=> + int(100) + [3]=> + int(555) +} + +-- Testing asort() by supplying string array, 'flag' = SORT_STRING -- +bool(true) +array(8) { + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["O3"]=> + string(7) "Orange3" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" +} + +-- Testing asort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE -- +bool(true) +array(8) { + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" + ["O3"]=> + string(7) "Orange3" +} + +-- Testing asort() by supplying string array (natural), 'flag' = SORT_NATURAL -- +bool(true) +array(8) { + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["O3"]=> + string(7) "Orange3" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" +} + +-- Testing asort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE -- +bool(true) +array(8) { + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["o2"]=> + string(7) "orange2" + ["O3"]=> + string(7) "Orange3" + ["o20"]=> + string(8) "orange20" +} + +-- Testing asort() by supplying numeric array, 'flag' = SORT_NUMERIC -- +bool(true) +array(4) { + [4]=> + int(22) + [2]=> + int(33) + [1]=> + int(100) + [3]=> + int(555) +} +Done diff --git a/tests/std/array/asort_object1.phpt b/tests/std/array/asort_object1.phpt new file mode 100644 index 00000000..a4c68a40 --- /dev/null +++ b/tests/std/array/asort_object1.phpt @@ -0,0 +1,220 @@ +--TEST-- +Test asort() function : object functionality - sort objects +--FILE-- +class_value = $value; + } +} +// class declaration for string objects +class for_string_asort +{ + public $class_value; + // initializing object member value + function __construct($value) + { + $this->class_value = $value; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * testing asort() by providing integer/string object arrays with following flag values + * 1. Default flag value + * 2. SORT_REGULAR - compare items normally + */ + echo "*** Testing asort() : object functionality ***\n"; + // array of integer objects + $unsorted_int_obj = array(1 => new for_integer_asort(11), 2 => new for_integer_asort(66), 3 => new for_integer_asort(23), 4 => new for_integer_asort(-5), 5 => new for_integer_asort(0.001), 6 => new for_integer_asort(0)); + // array of string objects + $unsorted_str_obj = array("a" => new for_string_asort("axx"), "b" => new for_string_asort("t"), "c" => new for_string_asort("w"), "d" => new for_string_asort("py"), "e" => new for_string_asort("apple"), "f" => new for_string_asort("Orange"), "g" => new for_string_asort("Lemon"), "h" => new for_string_asort("aPPle")); + echo "\n-- Testing asort() by supplying various object arrays, 'flag' value is default --\n"; + // testing asort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(asort($temp_array)); + var_dump($temp_array); + // testing asort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(asort($temp_array)); + var_dump($temp_array); + echo "\n-- Testing asort() by supplying various object arrays, 'flag' value is SORT_REGULAR --\n"; + // testing asort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(asort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing asort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(asort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done\n"; +} +?> +--EXPECTF-- +*** Testing asort() : object functionality *** + +-- Testing asort() by supplying various object arrays, 'flag' value is default -- +bool(true) +array(6) { + [4]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(-5) + } + [6]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(0) + } + [5]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + float(0.001) + } + [1]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(11) + } + [3]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(23) + } + [2]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(66) + } +} +bool(true) +array(8) { + ["g"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } + ["f"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + ["h"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + ["e"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + ["a"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + ["d"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(2) "py" + } + ["b"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(1) "t" + } + ["c"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(1) "w" + } +} + +-- Testing asort() by supplying various object arrays, 'flag' value is SORT_REGULAR -- +bool(true) +array(6) { + [4]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(-5) + } + [6]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(0) + } + [5]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + float(0.001) + } + [1]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(11) + } + [3]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(23) + } + [2]=> + object(for_integer_asort)#%d (1) { + ["class_value"]=> + int(66) + } +} +bool(true) +array(8) { + ["g"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } + ["f"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + ["h"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + ["e"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + ["a"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + ["d"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(2) "py" + } + ["b"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(1) "t" + } + ["c"]=> + object(for_string_asort)#%d (1) { + ["class_value"]=> + string(1) "w" + } +} +Done diff --git a/tests/std/array/asort_object2.phpt b/tests/std/array/asort_object2.phpt new file mode 100644 index 00000000..ca2f1538 --- /dev/null +++ b/tests/std/array/asort_object2.phpt @@ -0,0 +1,232 @@ +--TEST-- +Test asort() function : object functionality - sorting objects with diff. accessibility of member vars +--FILE-- +public_class_value = $value1; + $this->private_class_value = $value2; + $this->protected_class_value = $value3; + } +} +// class declaration for string objects +class for_string_asort +{ + public $public_class_value; + private $private_class_value; + protected $protected_class_value; + // initializing object member value + function __construct($value1, $value2, $value3) + { + $this->public_class_value = $value1; + $this->private_class_value = $value2; + $this->protected_class_value = $value3; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * testing asort() by providing integer/string object arrays with following flag values + * 1. Default flag value + 2. SORT_REGULAR - compare items normally + */ + echo "*** Testing asort() : object functionality ***\n"; + // array of integer objects + $unsorted_int_obj = array(1 => new for_integer_asort(11, 33, 2), 2 => new for_integer_asort(44, 66, 3), 3 => new for_integer_asort(23, 32, 6), 4 => new for_integer_asort(-88, -5, -4)); + // array of string objects + $unsorted_str_obj = array("a" => new for_string_asort("axx", "AXX", "d"), "b" => new for_string_asort("T", "t", "q"), "c" => new for_string_asort("w", "W", "c"), "d" => new for_string_asort("PY", "py", "s")); + echo "\n-- Testing asort() by supplying various object arrays, 'flag' value is default --\n"; + // testing asort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(asort($temp_array)); + var_dump($temp_array); + // testing asort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(asort($temp_array)); + var_dump($temp_array); + echo "\n-- Testing asort() by supplying various object arrays, 'flag' value is SORT_REGULAR --\n"; + // testing asort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(asort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing asort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(asort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done\n"; +} +?> +--EXPECTF-- +*** Testing asort() : object functionality *** + +-- Testing asort() by supplying various object arrays, 'flag' value is default -- +bool(true) +array(4) { + [4]=> + object(for_integer_asort)#%d (3) { + ["public_class_value"]=> + int(-88) + ["private_class_value":"for_integer_asort":private]=> + int(-5) + ["protected_class_value":protected]=> + int(-4) + } + [1]=> + object(for_integer_asort)#%d (3) { + ["public_class_value"]=> + int(11) + ["private_class_value":"for_integer_asort":private]=> + int(33) + ["protected_class_value":protected]=> + int(2) + } + [3]=> + object(for_integer_asort)#%d (3) { + ["public_class_value"]=> + int(23) + ["private_class_value":"for_integer_asort":private]=> + int(32) + ["protected_class_value":protected]=> + int(6) + } + [2]=> + object(for_integer_asort)#%d (3) { + ["public_class_value"]=> + int(44) + ["private_class_value":"for_integer_asort":private]=> + int(66) + ["protected_class_value":protected]=> + int(3) + } +} +bool(true) +array(4) { + ["d"]=> + object(for_string_asort)#%d (3) { + ["public_class_value"]=> + string(2) "PY" + ["private_class_value":"for_string_asort":private]=> + string(2) "py" + ["protected_class_value":protected]=> + string(1) "s" + } + ["b"]=> + object(for_string_asort)#%d (3) { + ["public_class_value"]=> + string(1) "T" + ["private_class_value":"for_string_asort":private]=> + string(1) "t" + ["protected_class_value":protected]=> + string(1) "q" + } + ["a"]=> + object(for_string_asort)#%d (3) { + ["public_class_value"]=> + string(3) "axx" + ["private_class_value":"for_string_asort":private]=> + string(3) "AXX" + ["protected_class_value":protected]=> + string(1) "d" + } + ["c"]=> + object(for_string_asort)#%d (3) { + ["public_class_value"]=> + string(1) "w" + ["private_class_value":"for_string_asort":private]=> + string(1) "W" + ["protected_class_value":protected]=> + string(1) "c" + } +} + +-- Testing asort() by supplying various object arrays, 'flag' value is SORT_REGULAR -- +bool(true) +array(4) { + [4]=> + object(for_integer_asort)#%d (3) { + ["public_class_value"]=> + int(-88) + ["private_class_value":"for_integer_asort":private]=> + int(-5) + ["protected_class_value":protected]=> + int(-4) + } + [1]=> + object(for_integer_asort)#%d (3) { + ["public_class_value"]=> + int(11) + ["private_class_value":"for_integer_asort":private]=> + int(33) + ["protected_class_value":protected]=> + int(2) + } + [3]=> + object(for_integer_asort)#%d (3) { + ["public_class_value"]=> + int(23) + ["private_class_value":"for_integer_asort":private]=> + int(32) + ["protected_class_value":protected]=> + int(6) + } + [2]=> + object(for_integer_asort)#%d (3) { + ["public_class_value"]=> + int(44) + ["private_class_value":"for_integer_asort":private]=> + int(66) + ["protected_class_value":protected]=> + int(3) + } +} +bool(true) +array(4) { + ["d"]=> + object(for_string_asort)#%d (3) { + ["public_class_value"]=> + string(2) "PY" + ["private_class_value":"for_string_asort":private]=> + string(2) "py" + ["protected_class_value":protected]=> + string(1) "s" + } + ["b"]=> + object(for_string_asort)#%d (3) { + ["public_class_value"]=> + string(1) "T" + ["private_class_value":"for_string_asort":private]=> + string(1) "t" + ["protected_class_value":protected]=> + string(1) "q" + } + ["a"]=> + object(for_string_asort)#%d (3) { + ["public_class_value"]=> + string(3) "axx" + ["private_class_value":"for_string_asort":private]=> + string(3) "AXX" + ["protected_class_value":protected]=> + string(1) "d" + } + ["c"]=> + object(for_string_asort)#%d (3) { + ["public_class_value"]=> + string(1) "w" + ["private_class_value":"for_string_asort":private]=> + string(1) "W" + ["protected_class_value":protected]=> + string(1) "c" + } +} +Done diff --git a/tests/std/array/asort_stability.phpt b/tests/std/array/asort_stability.phpt new file mode 100644 index 00000000..aeb3b9c1 --- /dev/null +++ b/tests/std/array/asort_stability.phpt @@ -0,0 +1,12 @@ +--TEST-- +asort() is stable +--FILE-- + +--EXPECT-- +bool(true) diff --git a/tests/std/array/asort_variation10.phpt b/tests/std/array/asort_variation10.phpt new file mode 100644 index 00000000..5c8d9041 --- /dev/null +++ b/tests/std/array/asort_variation10.phpt @@ -0,0 +1,108 @@ +--TEST-- +Test asort() function : usage variations - sort octal values +--FILE-- + 01235, 0321 => 0321, 0345 => 0345, 066 => 066, 0772 => 0772, + 077 => 077, -066 => -066, -0345 => -0345, 0 => 0 +); + +echo "\n-- Testing asort() by supplying octal value array, 'flag' value is default --\n"; +$temp_array = $unsorted_oct_array; +var_dump( asort($temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing asort() by supplying octal value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $unsorted_oct_array; +var_dump( asort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing asort() by supplying octal value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $unsorted_oct_array; +var_dump( asort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing asort() : usage variations *** + +-- Testing asort() by supplying octal value array, 'flag' value is default -- +bool(true) +array(9) { + [-229]=> + int(-229) + [-54]=> + int(-54) + [0]=> + int(0) + [54]=> + int(54) + [63]=> + int(63) + [209]=> + int(209) + [229]=> + int(229) + [506]=> + int(506) + [669]=> + int(669) +} + +-- Testing asort() by supplying octal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(9) { + [-229]=> + int(-229) + [-54]=> + int(-54) + [0]=> + int(0) + [54]=> + int(54) + [63]=> + int(63) + [209]=> + int(209) + [229]=> + int(229) + [506]=> + int(506) + [669]=> + int(669) +} + +-- Testing asort() by supplying octal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(9) { + [-229]=> + int(-229) + [-54]=> + int(-54) + [0]=> + int(0) + [54]=> + int(54) + [63]=> + int(63) + [209]=> + int(209) + [229]=> + int(229) + [506]=> + int(506) + [669]=> + int(669) +} +Done diff --git a/tests/std/array/asort_variation11.phpt b/tests/std/array/asort_variation11.phpt new file mode 100644 index 00000000..ef1938b6 --- /dev/null +++ b/tests/std/array/asort_variation11.phpt @@ -0,0 +1,155 @@ +--TEST-- +Test asort() function : usage variations - sort mixed values, 'sort_flags' as default/SORT_REGULAR (OK to fail as result is unpredectable) +--SKIPIF-- + +--FILE-- + array(), + "array2" => array ( "sub_array[2,1]" => array(33,-5,6), "sub_array[2,2]" => array(11), + "sub_array[2,3]" => array(22,-55), "sub_array[2,4]" => array() + ), + 4 => 4, "4" => "4", 4 => 4.01, "b" => "b", "5" => "5", -2 => -2, -2 => -2.01, + -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", NULL => NULL, + "ab" => "ab", "abcd" => "abcd", 0 => 0.01, -0 => -0, '' => '' , + "abcd\x00abcd\x00abcd" => "abcd\x00abcd\x00abcd", 0 => 0.001 +); + +echo "\n-- Testing asort() by supplying mixed value array, 'flag' value is default --\n"; +$temp_array = $mixed_values; +var_dump( asort($temp_array) ); +var_dump($temp_array); + +echo "\n-- Testing asort() by supplying mixed value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $mixed_values; +var_dump( asort($temp_array, SORT_REGULAR) ); +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing asort() : usage variations *** + +-- Testing asort() by supplying mixed value array, 'flag' value is default -- +bool(true) +array(13) { + [""]=> + string(0) "" + [-2]=> + float(-2.98989) + ["-.9"]=> + string(3) "-.9" + [0]=> + float(0.001) + [4]=> + float(4.01) + [5]=> + string(1) "5" + ["True"]=> + string(4) "True" + ["ab"]=> + string(2) "ab" + ["abcd"]=> + string(4) "abcd" + ["abcd%0abcd%0abcd"]=> + string(14) "abcd%0abcd%0abcd" + ["b"]=> + string(1) "b" + ["array1"]=> + array(0) { + } + ["array2"]=> + array(4) { + ["sub_array[2,1]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[2,2]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[2,3]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[2,4]"]=> + array(0) { + } + } +} + +-- Testing asort() by supplying mixed value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(13) { + [""]=> + string(0) "" + [-2]=> + float(-2.98989) + ["-.9"]=> + string(3) "-.9" + [0]=> + float(0.001) + [4]=> + float(4.01) + [5]=> + string(1) "5" + ["True"]=> + string(4) "True" + ["ab"]=> + string(2) "ab" + ["abcd"]=> + string(4) "abcd" + ["abcd%0abcd%0abcd"]=> + string(14) "abcd%0abcd%0abcd" + ["b"]=> + string(1) "b" + ["array1"]=> + array(0) { + } + ["array2"]=> + array(4) { + ["sub_array[2,1]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[2,2]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[2,3]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[2,4]"]=> + array(0) { + } + } +} +Done diff --git a/tests/std/array/asort_variation3.phpt b/tests/std/array/asort_variation3.phpt new file mode 100644 index 00000000..7736c727 --- /dev/null +++ b/tests/std/array/asort_variation3.phpt @@ -0,0 +1,320 @@ +--TEST-- +Test asort() function : usage variations - sort integer/float values +--FILE-- + 11, 2 => -11, 3 => 21, 4 => -21, 5 => 31, 6 => -31, 7 => 0, 8 => 41, 10 =>-41), + + // float value array + array(1 => 10.5, 2 => -10.5, 3 => 10.5e2, 4 => 10.6E-2, 5 => .5, 6 => .0001, 7 => -.1), + + // mixed value array + array(1 => .0001, 2 => .0021, 3 => -.01, 4 => -1, 5 => 0, 6 => .09, 7 => 2, 8 => -.9, 9 => 10.6E-2, 10 => -10.6E-2, 11 => 33), + + // array values contains minimum and maximum ranges + array(1 => 2147483647, 2 => 2147483648, 3 => -2147483647, 4 => -2147483648, 5 => -0, 6 => 0, 7 => -2147483649) +); + +// set of possible flag values +$flag_value = array("SORT_REGULAR" => SORT_REGULAR, "SORT_NUMERIC" => SORT_NUMERIC); + +$count = 1; +echo "\n-- Testing asort() by supplying various integer/float arrays --\n"; + +// loop through to test asort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort_flag -\n"; + $temp_array = $array; + var_dump(asort($temp_array) ); + var_dump($temp_array); + + // loop through $flag_value array and setting all possible flag values + foreach($flag_value as $key => $flag){ + echo "- Sort_flag = $key -\n"; + $temp_array = $array; + var_dump(asort($temp_array, $flag) ); + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing asort() : usage variations *** + +-- Testing asort() by supplying various integer/float arrays -- + +-- Iteration 1 -- +- With default sort_flag - +bool(true) +array(9) { + [10]=> + int(-41) + [6]=> + int(-31) + [4]=> + int(-21) + [2]=> + int(-11) + [7]=> + int(0) + [1]=> + int(11) + [3]=> + int(21) + [5]=> + int(31) + [8]=> + int(41) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(9) { + [10]=> + int(-41) + [6]=> + int(-31) + [4]=> + int(-21) + [2]=> + int(-11) + [7]=> + int(0) + [1]=> + int(11) + [3]=> + int(21) + [5]=> + int(31) + [8]=> + int(41) +} +- Sort_flag = SORT_NUMERIC - +bool(true) +array(9) { + [10]=> + int(-41) + [6]=> + int(-31) + [4]=> + int(-21) + [2]=> + int(-11) + [7]=> + int(0) + [1]=> + int(11) + [3]=> + int(21) + [5]=> + int(31) + [8]=> + int(41) +} + +-- Iteration 2 -- +- With default sort_flag - +bool(true) +array(7) { + [2]=> + float(-10.5) + [7]=> + float(-0.1) + [6]=> + float(0.0001) + [4]=> + float(0.106) + [5]=> + float(0.5) + [1]=> + float(10.5) + [3]=> + float(1050) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(7) { + [2]=> + float(-10.5) + [7]=> + float(-0.1) + [6]=> + float(0.0001) + [4]=> + float(0.106) + [5]=> + float(0.5) + [1]=> + float(10.5) + [3]=> + float(1050) +} +- Sort_flag = SORT_NUMERIC - +bool(true) +array(7) { + [2]=> + float(-10.5) + [7]=> + float(-0.1) + [6]=> + float(0.0001) + [4]=> + float(0.106) + [5]=> + float(0.5) + [1]=> + float(10.5) + [3]=> + float(1050) +} + +-- Iteration 3 -- +- With default sort_flag - +bool(true) +array(11) { + [4]=> + int(-1) + [8]=> + float(-0.9) + [10]=> + float(-0.106) + [3]=> + float(-0.01) + [5]=> + int(0) + [1]=> + float(0.0001) + [2]=> + float(0.0021) + [6]=> + float(0.09) + [9]=> + float(0.106) + [7]=> + int(2) + [11]=> + int(33) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(11) { + [4]=> + int(-1) + [8]=> + float(-0.9) + [10]=> + float(-0.106) + [3]=> + float(-0.01) + [5]=> + int(0) + [1]=> + float(0.0001) + [2]=> + float(0.0021) + [6]=> + float(0.09) + [9]=> + float(0.106) + [7]=> + int(2) + [11]=> + int(33) +} +- Sort_flag = SORT_NUMERIC - +bool(true) +array(11) { + [4]=> + int(-1) + [8]=> + float(-0.9) + [10]=> + float(-0.106) + [3]=> + float(-0.01) + [5]=> + int(0) + [1]=> + float(0.0001) + [2]=> + float(0.0021) + [6]=> + float(0.09) + [9]=> + float(0.106) + [7]=> + int(2) + [11]=> + int(33) +} + +-- Iteration 4 -- +- With default sort_flag - +bool(true) +array(7) { + [7]=> + %s(-2147483649) + [4]=> + %s(-2147483648) + [3]=> + int(-2147483647) + [5]=> + int(0) + [6]=> + int(0) + [1]=> + int(2147483647) + [2]=> + %s(2147483648) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(7) { + [7]=> + %s(-2147483649) + [4]=> + %s(-2147483648) + [3]=> + int(-2147483647) + [5]=> + int(0) + [6]=> + int(0) + [1]=> + int(2147483647) + [2]=> + %s(2147483648) +} +- Sort_flag = SORT_NUMERIC - +bool(true) +array(7) { + [7]=> + %s(-2147483649) + [4]=> + %s(-2147483648) + [3]=> + int(-2147483647) + [5]=> + int(0) + [6]=> + int(0) + [1]=> + int(2147483647) + [2]=> + %s(2147483648) +} +Done diff --git a/tests/std/array/asort_variation4.phpt b/tests/std/array/asort_variation4.phpt new file mode 100644 index 00000000..3621e0cc --- /dev/null +++ b/tests/std/array/asort_variation4.phpt @@ -0,0 +1,78 @@ +--TEST-- +Test asort() function : usage variations - sort reference variables +--SKIPIF-- + + +--FILE-- + &$value1 , 2 => &$value2, 3 => &$value3); + +echo "\n-- Testing asort() by supplying reference variable array, 'flag' value is default --\n"; +$temp_array = $unsorted_numerics; +var_dump( asort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying reference variable array, 'flag' = SORT_REGULAR --\n"; +$temp_array = &$unsorted_numerics; +var_dump( asort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing asort() by supplying reference variable array, 'flag' = SORT_NUMERIC --\n"; +$temp_array = &$unsorted_numerics; +var_dump( asort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing asort() :usage variations *** + +-- Testing asort() by supplying reference variable array, 'flag' value is default -- +bool(true) +array(3) { + [2]=> + &int(33) + [1]=> + &int(100) + [3]=> + &int(555) +} + +-- Testing asort() by supplying reference variable array, 'flag' = SORT_REGULAR -- +bool(true) +array(3) { + [2]=> + &int(33) + [1]=> + &int(100) + [3]=> + &int(555) +} + +-- Testing asort() by supplying reference variable array, 'flag' = SORT_NUMERIC -- +bool(true) +array(3) { + [2]=> + &int(33) + [1]=> + &int(100) + [3]=> + &int(555) +} +Done diff --git a/tests/std/array/asort_variation5.phpt b/tests/std/array/asort_variation5.phpt new file mode 100644 index 00000000..f39c4829 --- /dev/null +++ b/tests/std/array/asort_variation5.phpt @@ -0,0 +1,236 @@ +--TEST-- +Test asort() function : usage variations - sort strings +--FILE-- + null, "NULL" => NULL, "\a" => "\a", "\cx" => "\cx", "\e" => "\e", + "\f" => "\f", "\n" =>"\n", "\r" => "\r", "\t" => "\t", "\xhh" => "\xhh", + "\ddd" => "\ddd", "\v" => "\v" + ), + + // array contains combination of capital/small letters + array ('l' => "lemoN", 'O' => "Orange", 'b' => "banana", 'a' => "apple", 'Te' => "Test", + 'T' => "TTTT", 't' => "ttt", 'w' => "ww", 'x' => "x", 'X' => "X", 'o' => "oraNGe", + 'B' => "BANANA" + ) +); + +$flags = array("SORT_REGULAR" => SORT_REGULAR, "SORT_STRING" => SORT_STRING); + +$count = 1; +echo "\n-- Testing asort() by supplying various string arrays --\n"; + +// loop through to test asort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort_flag -\n"; + $temp_array = $array; + var_dump(asort($temp_array) ); // expecting : bool(true) + var_dump($temp_array); + + // loop through $flags array and setting all possible flag values + foreach($flags as $key => $flag){ + echo "- Sort_flag = $key -\n"; + $temp_array = $array; + var_dump(asort($temp_array, $flag) ); // expecting : bool(true) + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing asort() : usage variations *** + +-- Testing asort() by supplying various string arrays -- + +-- Iteration 1 -- +- With default sort_flag - +bool(true) +array(12) { + ["null"]=> + NULL + ["NULL"]=> + NULL + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [""]=> + string(1) "" + ["\a"]=> + string(2) "\a" + ["\cx"]=> + string(3) "\cx" + ["\ddd"]=> + string(4) "\ddd" + ["\xhh"]=> + string(4) "\xhh" +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(12) { + ["null"]=> + NULL + ["NULL"]=> + NULL + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [""]=> + string(1) "" + ["\a"]=> + string(2) "\a" + ["\cx"]=> + string(3) "\cx" + ["\ddd"]=> + string(4) "\ddd" + ["\xhh"]=> + string(4) "\xhh" +} +- Sort_flag = SORT_STRING - +bool(true) +array(12) { + ["null"]=> + NULL + ["NULL"]=> + NULL + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [""]=> + string(1) "" + ["\a"]=> + string(2) "\a" + ["\cx"]=> + string(3) "\cx" + ["\ddd"]=> + string(4) "\ddd" + ["\xhh"]=> + string(4) "\xhh" +} + +-- Iteration 2 -- +- With default sort_flag - +bool(true) +array(12) { + ["B"]=> + string(6) "BANANA" + ["O"]=> + string(6) "Orange" + ["T"]=> + string(4) "TTTT" + ["Te"]=> + string(4) "Test" + ["X"]=> + string(1) "X" + ["a"]=> + string(5) "apple" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemoN" + ["o"]=> + string(6) "oraNGe" + ["t"]=> + string(3) "ttt" + ["w"]=> + string(2) "ww" + ["x"]=> + string(1) "x" +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(12) { + ["B"]=> + string(6) "BANANA" + ["O"]=> + string(6) "Orange" + ["T"]=> + string(4) "TTTT" + ["Te"]=> + string(4) "Test" + ["X"]=> + string(1) "X" + ["a"]=> + string(5) "apple" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemoN" + ["o"]=> + string(6) "oraNGe" + ["t"]=> + string(3) "ttt" + ["w"]=> + string(2) "ww" + ["x"]=> + string(1) "x" +} +- Sort_flag = SORT_STRING - +bool(true) +array(12) { + ["B"]=> + string(6) "BANANA" + ["O"]=> + string(6) "Orange" + ["T"]=> + string(4) "TTTT" + ["Te"]=> + string(4) "Test" + ["X"]=> + string(1) "X" + ["a"]=> + string(5) "apple" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemoN" + ["o"]=> + string(6) "oraNGe" + ["t"]=> + string(3) "ttt" + ["w"]=> + string(2) "ww" + ["x"]=> + string(1) "x" +} +Done diff --git a/tests/std/array/asort_variation6.phpt b/tests/std/array/asort_variation6.phpt new file mode 100644 index 00000000..7782f95d --- /dev/null +++ b/tests/std/array/asort_variation6.phpt @@ -0,0 +1,108 @@ +--TEST-- +Test asort() function : usage variations - sort hexadecimal values +--FILE-- + 0x1AB, 0xFFF => 0xFFF, 0xF => 0xF, 0xFF => 0xFF, 0x2AA => 0x2AA, 0xBB => 0xBB, + 0x1ab => 0x1ab, 0xff => 0xff, -0xff => -0xFF, 0 => 0, -0x2aa => -0x2aa + ); + +echo "\n-- Testing asort() by supplying hexadecimal value array, 'flag' value is default --\n"; +$temp_array = $unsorted_hex_array; +var_dump(asort($temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing asort() by supplying hexadecimal value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $unsorted_hex_array; +var_dump(asort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing asort() by supplying hexadecimal value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $unsorted_hex_array; +var_dump(asort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing asort() : usage variations *** + +-- Testing asort() by supplying hexadecimal value array, 'flag' value is default -- +bool(true) +array(9) { + [-682]=> + int(-682) + [-255]=> + int(-255) + [0]=> + int(0) + [15]=> + int(15) + [187]=> + int(187) + [255]=> + int(255) + [427]=> + int(427) + [682]=> + int(682) + [4095]=> + int(4095) +} + +-- Testing asort() by supplying hexadecimal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(9) { + [-682]=> + int(-682) + [-255]=> + int(-255) + [0]=> + int(0) + [15]=> + int(15) + [187]=> + int(187) + [255]=> + int(255) + [427]=> + int(427) + [682]=> + int(682) + [4095]=> + int(4095) +} + +-- Testing asort() by supplying hexadecimal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(9) { + [-682]=> + int(-682) + [-255]=> + int(-255) + [0]=> + int(0) + [15]=> + int(15) + [187]=> + int(187) + [255]=> + int(255) + [427]=> + int(427) + [682]=> + int(682) + [4095]=> + int(4095) +} +Done diff --git a/tests/std/array/asort_variation7.phpt b/tests/std/array/asort_variation7.phpt new file mode 100644 index 00000000..64363d25 --- /dev/null +++ b/tests/std/array/asort_variation7.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test asort() function : usage variations - sort bool values +--FILE-- + true, 2 => false, 3 => TRUE, 4 => FALSE); + +echo "\n-- Testing asort() by supplying bool value array, 'flag' value is default --\n"; +$temp_array = $bool_values; +var_dump(asort($temp_array) ); +var_dump($temp_array); + +echo "\n-- Testing asort() by supplying bool value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $bool_values; +var_dump(asort($temp_array, SORT_REGULAR) ); +var_dump($temp_array); + +echo "\n-- Testing asort() by supplying bool value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $bool_values; +var_dump(asort($temp_array, SORT_NUMERIC) ); +var_dump($temp_array); + +echo "\n-- Testing asort() by supplying bool value array, 'flag' value is SORT_STRING --\n"; +$temp_array = $bool_values; +var_dump(asort($temp_array, SORT_STRING) ); +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing asort() : usage variations *** + +-- Testing asort() by supplying bool value array, 'flag' value is default -- +bool(true) +array(4) { + [2]=> + bool(false) + [4]=> + bool(false) + [1]=> + bool(true) + [3]=> + bool(true) +} + +-- Testing asort() by supplying bool value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(4) { + [2]=> + bool(false) + [4]=> + bool(false) + [1]=> + bool(true) + [3]=> + bool(true) +} + +-- Testing asort() by supplying bool value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(4) { + [2]=> + bool(false) + [4]=> + bool(false) + [1]=> + bool(true) + [3]=> + bool(true) +} + +-- Testing asort() by supplying bool value array, 'flag' value is SORT_STRING -- +bool(true) +array(4) { + [2]=> + bool(false) + [4]=> + bool(false) + [1]=> + bool(true) + [3]=> + bool(true) +} +Done diff --git a/tests/std/array/asort_variation8.phpt b/tests/std/array/asort_variation8.phpt new file mode 100644 index 00000000..038c92df --- /dev/null +++ b/tests/std/array/asort_variation8.phpt @@ -0,0 +1,174 @@ +--TEST-- +Test asort() function : usage variations - sort array with diff. sub arrays, 'sort_flags' as default/SORT_REGULAR +--FILE-- + array(), + + // array contains null sub array + "array[1]" => array( "sub_array[1][0]" => array() ), + + // array of arrays along with some values + "array[2]" => array("data[2,0]" => 44, "data[2,1]" => 11, "sub_array[2][0] " => array(64,61) ), + + // array contains sub arrays + "array[3]" => array ( "sub_array[3][0]" => array(33,-5,6), "sub_array[3][1]" => array(11), + "sub_array[3][2]" => array(22,-55), "sub_array[3][3]" => array() ) +); + + +$count = 1; +echo "\n-- Testing asort() by supplying various arrays containing sub arrays --\n"; + +// loop through to test asort() with different arrays +foreach ($various_arrays as $array) { + + echo "\n-- Iteration $count --\n"; + // testing asort() function by supplying different arrays, flag value is default + echo "- With default sort_flag -\n"; + $temp_array = $array; + var_dump(asort($temp_array) ); + var_dump($temp_array); + + // testing asort() function by supplying different arrays, flag value = SORT_REGULAR + echo "- Sort_flag = SORT_REGULAR -\n"; + $temp_array = $array; + var_dump(asort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing asort() : usage variations *** + +-- Testing asort() by supplying various arrays containing sub arrays -- + +-- Iteration 1 -- +- With default sort_flag - +bool(true) +array(0) { +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(0) { +} + +-- Iteration 2 -- +- With default sort_flag - +bool(true) +array(1) { + ["sub_array[1][0]"]=> + array(0) { + } +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(1) { + ["sub_array[1][0]"]=> + array(0) { + } +} + +-- Iteration 3 -- +- With default sort_flag - +bool(true) +array(3) { + ["data[2,1]"]=> + int(11) + ["data[2,0]"]=> + int(44) + ["sub_array[2][0] "]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(3) { + ["data[2,1]"]=> + int(11) + ["data[2,0]"]=> + int(44) + ["sub_array[2][0] "]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } +} + +-- Iteration 4 -- +- With default sort_flag - +bool(true) +array(4) { + ["sub_array[3][3]"]=> + array(0) { + } + ["sub_array[3][1]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[3][2]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[3][0]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(4) { + ["sub_array[3][3]"]=> + array(0) { + } + ["sub_array[3][1]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[3][2]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[3][0]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } +} +Done diff --git a/tests/std/array/asort_variation9.phpt b/tests/std/array/asort_variation9.phpt new file mode 100644 index 00000000..ff2d9077 --- /dev/null +++ b/tests/std/array/asort_variation9.phpt @@ -0,0 +1,252 @@ +--TEST-- +Test asort() function : usage variations - sorting arrays with/without keys, 'sort_flags' as default/SORT_REGULAR +--FILE-- + 55, 66, 22, 33, 11), + array ("a" => "orange", "banana", "c" => "apple"), + array(1, 2, 3, 4, 5, 6), + array("first", 5 => "second", "third"), + array(1, 1, 8 => 1, 4 => 1, 19, 3 => 13), + array('bar' => 'baz', "foo" => 1), + array('a'=>1,'b'=>array('e'=>2,'f'=>3),'c'=>array('g'=>4),'d'=>5), +); + +$count = 1; +echo "\n-- Testing asort() by supplying various arrays with key values --\n"; + +// loop through to test asort() with different arrays, +// to test the new keys for the elements in the sorted array +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort_flag -\n"; + $temp_array = $array; + var_dump(asort($temp_array) ); + var_dump($temp_array); + + echo "- Sort_flag = SORT_REGULAR -\n"; + $temp_array = $array; + var_dump(asort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing asort() : usage variations *** + +-- Testing asort() by supplying various arrays with key values -- + +-- Iteration 1 -- +- With default sort_flag - +bool(true) +array(5) { + [9]=> + int(11) + [7]=> + int(22) + [8]=> + int(33) + [5]=> + int(55) + [6]=> + int(66) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(5) { + [9]=> + int(11) + [7]=> + int(22) + [8]=> + int(33) + [5]=> + int(55) + [6]=> + int(66) +} + +-- Iteration 2 -- +- With default sort_flag - +bool(true) +array(3) { + ["c"]=> + string(5) "apple" + [0]=> + string(6) "banana" + ["a"]=> + string(6) "orange" +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(3) { + ["c"]=> + string(5) "apple" + [0]=> + string(6) "banana" + ["a"]=> + string(6) "orange" +} + +-- Iteration 3 -- +- With default sort_flag - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) +} + +-- Iteration 4 -- +- With default sort_flag - +bool(true) +array(3) { + [0]=> + string(5) "first" + [5]=> + string(6) "second" + [6]=> + string(5) "third" +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(3) { + [0]=> + string(5) "first" + [5]=> + string(6) "second" + [6]=> + string(5) "third" +} + +-- Iteration 5 -- +- With default sort_flag - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(1) + [8]=> + int(1) + [4]=> + int(1) + [3]=> + int(13) + [9]=> + int(19) +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(1) + [8]=> + int(1) + [4]=> + int(1) + [3]=> + int(13) + [9]=> + int(19) +} + +-- Iteration 6 -- +- With default sort_flag - +bool(true) +array(2) { + ["foo"]=> + int(1) + ["bar"]=> + string(3) "baz" +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(2) { + ["foo"]=> + int(1) + ["bar"]=> + string(3) "baz" +} + +-- Iteration 7 -- +- With default sort_flag - +bool(true) +array(4) { + ["a"]=> + int(1) + ["d"]=> + int(5) + ["c"]=> + array(1) { + ["g"]=> + int(4) + } + ["b"]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } +} +- Sort_flag = SORT_REGULAR - +bool(true) +array(4) { + ["a"]=> + int(1) + ["d"]=> + int(5) + ["c"]=> + array(1) { + ["g"]=> + int(4) + } + ["b"]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } +} +Done diff --git a/tests/std/array/bug12776.phpt b/tests/std/array/bug12776.phpt new file mode 100644 index 00000000..89da38b1 --- /dev/null +++ b/tests/std/array/bug12776.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #12776 (array_walk crash) +--SKIPIF-- + + +--FILE-- + 'v'); + array_walk($arr, 'test'); + print "First value: " . $globalArray[0]; + print "\nDone\n"; +} +?> +--EXPECT-- +val: v; key: k +First value: k +Done diff --git a/tests/std/array/bug14580.phpt b/tests/std/array/bug14580.phpt new file mode 100644 index 00000000..8f4c7d5b --- /dev/null +++ b/tests/std/array/bug14580.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #14580 (key() not binary safe) +--FILE-- + "foo\0bar"); + $key = key($arr); + echo strlen($key), ': '; + echo urlencode($key), "\n"; +?> +--EXPECT-- +7: foo%00bar diff --git a/tests/std/array/bug20381.phpt b/tests/std/array/bug20381.phpt new file mode 100644 index 00000000..0da52d9f --- /dev/null +++ b/tests/std/array/bug20381.phpt @@ -0,0 +1,79 @@ +--TEST-- +Bug #20381 (array_merge_recursive mangles input arrays) +--FILE-- + 1, + 'a2' => array( 1, 2, 3 ), + 'a3' => array( + 'a' => array( 10, 20, 30 ), + 'b' => 'b' + ) + ); +$b = array( 'a1' => 2, + 'a2' => array( 3, 4, 5 ), + 'a3' => array( + 'c' => 'cc', + 'a' => array( 10, 40 ) + ) + ); + +var_dump($a); +array_merge_recursive( $a, $b ); +var_dump($a); +?> +--EXPECT-- +array(3) { + ["a1"]=> + int(1) + ["a2"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + ["a3"]=> + array(2) { + ["a"]=> + array(3) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + } + ["b"]=> + string(1) "b" + } +} +array(3) { + ["a1"]=> + int(1) + ["a2"]=> + array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + } + ["a3"]=> + array(2) { + ["a"]=> + array(3) { + [0]=> + int(10) + [1]=> + int(20) + [2]=> + int(30) + } + ["b"]=> + string(1) "b" + } +} diff --git a/tests/std/array/bug20865.phpt b/tests/std/array/bug20865.phpt new file mode 100644 index 00000000..6fa79f6a --- /dev/null +++ b/tests/std/array/bug20865.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #20865 (array_key_exists and NULL key) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) diff --git a/tests/std/array/bug21918.phpt b/tests/std/array/bug21918.phpt new file mode 100644 index 00000000..e855aacd --- /dev/null +++ b/tests/std/array/bug21918.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #21918 (different handling of positive vs. negative array indexes) +--FILE-- +'a', '-2'=>'b', 3=>'c', '4'=>'d', 5=>'e', '6001'=>'f', '07'=>'g'); + +foreach($a as $k => $v) { + var_dump($k); + var_dump($v); +} + +echo "==Normal==\n"; +$b = array(); +$b[] = 'a'; + +foreach($b as $k => $v) { + var_dump($k); + var_dump($v); +} + +echo "==Negative==\n"; +$c = array('-2' => 'a'); + +foreach($c as $k => $v) { + var_dump($k); + var_dump($v); +} + +?> +--EXPECT-- +==Mixed== +int(-1) +string(1) "a" +int(-2) +string(1) "b" +int(3) +string(1) "c" +int(4) +string(1) "d" +int(5) +string(1) "e" +int(6001) +string(1) "f" +string(2) "07" +string(1) "g" +==Normal== +int(0) +string(1) "a" +==Negative== +int(-2) +string(1) "a" diff --git a/tests/std/array/bug21998.phpt b/tests/std/array/bug21998.phpt new file mode 100644 index 00000000..e1bb0033 --- /dev/null +++ b/tests/std/array/bug21998.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #21998 (array_pop() does not reset the current array position) +--FILE-- + +--EXPECT-- +int(0) +string(1) "c" +int(0) +string(1) "b" +int(0) +string(1) "a" +NULL diff --git a/tests/std/array/bug22088.phpt b/tests/std/array/bug22088.phpt new file mode 100644 index 00000000..4352cff9 --- /dev/null +++ b/tests/std/array/bug22088.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #22088 (array_shift() leaves next index to be +1 too much) +--FILE-- + 1, 'b' => 2, 'c' => 3); +$last = array_shift ($a); +$a[] = 'a'; +var_dump($a); + +?> +--EXPECT-- +array(3) { + [0]=> + string(1) "b" + [1]=> + string(1) "c" + [2]=> + string(1) "a" +} +array(3) { + ["b"]=> + int(2) + ["c"]=> + int(3) + [0]=> + string(1) "a" +} diff --git a/tests/std/array/bug22463.phpt b/tests/std/array/bug22463.phpt new file mode 100644 index 00000000..973b3863 --- /dev/null +++ b/tests/std/array/bug22463.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #22463 (array_reduce() segfaults) +--FILE-- + +--EXPECT-- +int(5) diff --git a/tests/std/array/bug23581.phpt b/tests/std/array/bug23581.phpt new file mode 100644 index 00000000..5cede9a3 --- /dev/null +++ b/tests/std/array/bug23581.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #23581 (array_map(NULL, array, array, ...) yields an undefined result) +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + array(3) { + [0]=> + int(1) + [1]=> + int(4) + [2]=> + int(7) + } + [1]=> + array(3) { + [0]=> + int(2) + [1]=> + int(5) + [2]=> + int(8) + } + [2]=> + array(3) { + [0]=> + int(3) + [1]=> + int(6) + [2]=> + int(9) + } +} diff --git a/tests/std/array/bug23788.phpt b/tests/std/array/bug23788.phpt new file mode 100644 index 00000000..014773be --- /dev/null +++ b/tests/std/array/bug23788.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #23788 (*_replace() clobbers referenced array elements) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + &int(123) + [1]=> + &bool(true) +} +array(2) { + [0]=> + &int(123) + [1]=> + &bool(true) +} diff --git a/tests/std/array/bug24198.phpt b/tests/std/array/bug24198.phpt new file mode 100644 index 00000000..a1a30afb --- /dev/null +++ b/tests/std/array/bug24198.phpt @@ -0,0 +1,25 @@ +--TEST--n +Bug #24198 (array_merge_recursive() invalid recursion detection) +--FILE-- + 'aa','b' => 'bb'); + +var_dump(array_merge_recursive($c, $c)); +?> +--EXPECT-- +array(2) { + ["a"]=> + array(2) { + [0]=> + string(2) "aa" + [1]=> + string(2) "aa" + } + ["b"]=> + array(2) { + [0]=> + string(2) "bb" + [1]=> + string(2) "bb" + } +} diff --git a/tests/std/array/bug24766.phpt b/tests/std/array/bug24766.phpt new file mode 100644 index 00000000..ebe2f392 --- /dev/null +++ b/tests/std/array/bug24766.phpt @@ -0,0 +1,45 @@ +--TEST-- +Bug #24766 (strange result array from unpack) +--FILE-- + 18, 2 => 52); +var_dump($a, $b); +$k = array_keys($a); +$l = array_keys($b); +var_dump($k, $l); +$i=$k[0]; +var_dump($a[$i]); +$i=$l[0]; +var_dump($b[$i]); +?> +--EXPECT-- +array(2) { + [1]=> + int(18) + [2]=> + int(52) +} +array(2) { + [1]=> + int(18) + [2]=> + int(52) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +int(18) +int(18) diff --git a/tests/std/array/bug24897.phpt b/tests/std/array/bug24897.phpt new file mode 100644 index 00000000..45bcde34 --- /dev/null +++ b/tests/std/array/bug24897.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #24897 (inconsistent behaviour or shuffle() & array_multisort()) +--FILE-- + 2); +shuffle($a); +var_dump($a); + +$a = array(1 => 2); +array_multisort($a); +var_dump($a); +?> +--EXPECT-- +array(1) { + [0]=> + int(2) +} +array(1) { + [0]=> + int(2) +} diff --git a/tests/std/array/bug24980.phpt b/tests/std/array/bug24980.phpt new file mode 100644 index 00000000..da98e10e --- /dev/null +++ b/tests/std/array/bug24980.phpt @@ -0,0 +1,52 @@ +--TEST-- +Bug #24980 (array_reduce() uses first element as default running total) +--FILE-- + +--EXPECT-- +running_total is 0, current_value is 2 +running_total is 4, current_value is 3 +running_total is 13, current_value is 5 +running_total is 38, current_value is 7 +Total is 87 +string(3) "abc" +int(15) +int(1200) +int(1) diff --git a/tests/std/array/bug25359.phpt b/tests/std/array/bug25359.phpt new file mode 100644 index 00000000..a718fb9e --- /dev/null +++ b/tests/std/array/bug25359.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #25359 (array_multisort() does not work in a function if array is global or reference) +--FILE-- + +--EXPECT-- +array(5) { + [0]=> + string(5) "first" + [1]=> + string(6) "second" + [2]=> + string(5) "third" + [3]=> + string(5) "forth" + [4]=> + string(5) "fifth" +} diff --git a/tests/std/array/bug25708.phpt b/tests/std/array/bug25708.phpt new file mode 100644 index 00000000..f5e49c0e --- /dev/null +++ b/tests/std/array/bug25708.phpt @@ -0,0 +1,230 @@ +--TEST-- +Bug #25708 (extract($GLOBALS, EXTR_REFS) mangles $GLOBALS) +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +NULL +NULL +int(1) +int(2) +-- +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(3) +int(1) +int(3) +-- +int(4) +int(3) +int(4) +int(3) +-- +int(3) +int(3) +int(3) +-- +int(4) +string(1) "x" +int(4) +string(1) "x" +int(3) +-- +int(1) +int(2) +----a +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(3) +int(1) +int(3) +-- +int(4) +int(3) +int(4) +int(3) +-- +int(3) +int(3) +int(3) +-- +int(4) +string(1) "x" +int(4) +string(1) "x" +int(3) +-- +int(1) +int(2) +----ra +NULL +NULL +int(1) +int(2) +-- +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(3) +int(1) +int(3) +-- +int(4) +int(3) +int(4) +int(3) +-- +int(3) +int(3) +int(3) +-- +int(4) +string(1) "x" +int(4) +string(1) "x" +int(3) +-- +int(1) +int(2) +---- +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(2) +int(1) +int(2) +-- +int(1) +int(3) +int(1) +int(3) +-- +int(4) +int(3) +int(4) +int(3) +-- +int(3) +int(3) +int(3) +-- +int(4) +string(1) "x" +int(4) +string(1) "x" +int(3) +-- +int(1) +int(2) +----r +string(2) "ok" +string(2) "ok" diff --git a/tests/std/array/bug25758.phpt b/tests/std/array/bug25758.phpt new file mode 100644 index 00000000..a2d2952d --- /dev/null +++ b/tests/std/array/bug25758.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #25758 (var_export does not escape ' & \ inside array keys) +--FILE-- + array("quote'")); + echo var_export($a, true); +?> +--EXPECT-- +array ( + 'quote\'' => + array ( + 0 => 'quote\'', + ), +) diff --git a/tests/std/array/bug26458.phpt b/tests/std/array/bug26458.phpt new file mode 100644 index 00000000..67c1586d --- /dev/null +++ b/tests/std/array/bug26458.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #26458 (var_dump(), var_export() & debug_zval_dump() are not binary safe for array keys) +--FILE-- + "Hello world"); +var_dump($test); +var_export($test); +debug_zval_dump($test); +?> +--EXPECTF-- +array(1) { + ["A%0B"]=> + string(11) "Hello world" +} +array ( + 'A' . "\0" . 'B' => 'Hello world', +)array(1) %s{ + ["A%0B"]=> + string(11) "Hello world" %s +} diff --git a/tests/std/array/bug28739.phpt b/tests/std/array/bug28739.phpt new file mode 100644 index 00000000..d861e209 --- /dev/null +++ b/tests/std/array/bug28739.phpt @@ -0,0 +1,71 @@ +--TEST-- +Bug #28739 (*diff() and *intersect() not clearing the fci cache before work) +--FILE-- +x = $x; + } +} +function a($a, $b) +{ + var_dump(__FUNCTION__); + return $a->x - $b->x; +} +function b($a, $b) +{ + var_dump(__FUNCTION__); + return $a->x - $b->x; +} +function main() +{ + $p1 = array(new p(2), new p(1), new p(0)); + $p2 = array(new p(0), new p(2), new p(3)); + uasort($p1, 'a'); + print_r($p1); + echo "Now diffing:\n"; + print_r(array_udiff($p1, $p2, 'b')); +} +?> +--EXPECT-- +string(1) "a" +string(1) "a" +Array +( + [2] => p Object + ( + [x] => 0 + ) + + [1] => p Object + ( + [x] => 1 + ) + + [0] => p Object + ( + [x] => 2 + ) + +) +Now diffing: +string(1) "b" +string(1) "b" +string(1) "b" +string(1) "b" +string(1) "b" +string(1) "b" +string(1) "b" +string(1) "b" +string(1) "b" +Array +( + [1] => p Object + ( + [x] => 1 + ) + +) diff --git a/tests/std/array/bug28974.phpt b/tests/std/array/bug28974.phpt new file mode 100644 index 00000000..a2bd86f6 --- /dev/null +++ b/tests/std/array/bug28974.phpt @@ -0,0 +1,89 @@ +--TEST-- +Bug #28974 (array_(p)slice() treats large lengths incorrectly - overflow) +--FILE-- + +--EXPECT-- +Array +( + [0] => 0 + [1] => 1 + [2] => 2 + [3] => 3 + [4] => 4 + [5] => 5 +) +Array +( + [0] => 2 + [1] => 3 + [2] => 4 + [3] => 5 +) +Array +( + [0] => 2 + [1] => 3 + [2] => 4 + [3] => 5 +) +print_r(array_splice($a,2,1)); +Array +( + [0] => 2 +) +$a is :Array +( + [0] => 0 + [1] => 1 + [2] => 3 + [3] => 4 + [4] => 5 +) +print_r(array_splice($b,2,2147483645)); +Array +( + [0] => 2 + [1] => 3 + [2] => 4 + [3] => 5 +) +$b is :Array +( + [0] => 0 + [1] => 1 +) +print_r(array_splice($c,2,2147483646)); +Array +( + [0] => 2 + [1] => 3 + [2] => 4 + [3] => 5 +) +$c is :Array +( + [0] => 0 + [1] => 1 +) diff --git a/tests/std/array/bug29253.phpt b/tests/std/array/bug29253.phpt new file mode 100644 index 00000000..c690df5d --- /dev/null +++ b/tests/std/array/bug29253.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #29253 (array_diff with $GLOBALS argument fails) +--SKIPIF-- + + +--FILE-- + +--EXPECTF-- +array(2) { + ["zz"]=> + %A + ["gg"]=> + string(4) "afad" +} +string(4) "afad" diff --git a/tests/std/array/bug29493.phpt b/tests/std/array/bug29493.phpt new file mode 100644 index 00000000..428028b7 --- /dev/null +++ b/tests/std/array/bug29493.phpt @@ -0,0 +1,108 @@ +--TEST-- +Bug #29493 (extract(EXTR_REFS) fails if array has multiple referrals) +--SKIPIF-- + + +--FILE-- + 'aaa'); + // refcount($a) = 1 + // refcount($a['foo']) = 1 + $b = $a; + // refcount($a) = 2 + // refcount($a['foo']) = 1 + $b['foo'] = 'bbb'; + // refcount($a) = 1 + // refcount($a['foo']) = 1 + var_dump($a, $b); + extract($a, EXTR_REFS); + $foo = 'noo'; + var_dump($a, $b); +} +function t2() +{ + $a = array('foo' => 'aaa'); + // refcount($a) = 1 + // refcount($a['foo']) = 1 + $b =& $a; + // refcount($a) = 2 + // is_ref($a) = true + // refcount($a['foo']) = 1 + $b['foo'] = 'bbb'; + // refcount($a) = 2 + // refcount($a['foo']) = 1 + var_dump($a, $b); + extract($a, EXTR_REFS); + $foo = 'noo'; + var_dump($a, $b); +} +function t3() +{ + $a = array('foo' => 'aaa'); + // refcount($a) = 1 + // refcount($a['foo']) = 1 + $b =& $a; + // refcount($a) = 2 + // is_ref($a) = true + // refcount($a['foo']) = 1 + unset($b); + // refcount($a) = 1 + // is_ref($a) = true + // refcount($a['foo']) = 1 + var_dump($a); + extract($a, EXTR_REFS); + $foo = 'noo'; + var_dump($a); +} +function main() +{ + t1(); + t2(); + t3(); +} +?> +--EXPECT-- +array(1) { + ["foo"]=> + string(3) "aaa" +} +array(1) { + ["foo"]=> + string(3) "bbb" +} +array(1) { + ["foo"]=> + &string(3) "noo" +} +array(1) { + ["foo"]=> + string(3) "bbb" +} +array(1) { + ["foo"]=> + string(3) "bbb" +} +array(1) { + ["foo"]=> + string(3) "bbb" +} +array(1) { + ["foo"]=> + &string(3) "noo" +} +array(1) { + ["foo"]=> + &string(3) "noo" +} +array(1) { + ["foo"]=> + string(3) "aaa" +} +array(1) { + ["foo"]=> + &string(3) "noo" +} diff --git a/tests/std/array/bug30074.phpt b/tests/std/array/bug30074.phpt new file mode 100644 index 00000000..7902e966 --- /dev/null +++ b/tests/std/array/bug30074.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #30074 (EG(uninitialized_zval_ptr) gets set to reference using EXTR_REFS, affecting later values) +--SKIPIF-- + + +--FILE-- +$undefined), EXTR_REFS); +var_dump(array($a)); +echo "Done\n"; +?> +--EXPECTF-- +Warning: Undefined variable $undefined in %s on line %d +array(1) { + [0]=> + NULL +} +Done diff --git a/tests/std/array/bug30266.phpt b/tests/std/array/bug30266.phpt new file mode 100644 index 00000000..b31df8ef --- /dev/null +++ b/tests/std/array/bug30266.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #30266 (Invalid opcode 137/1/8) and array_walk +--SKIPIF-- + +--FILE-- +b = $val; + throw new Exception("Error"); + } +} +function test($item2, $key, $userd) +{ + $userd->crash($item2); +} +function main() +{ + $fruits = array("d" => "lemon", "a" => "orange", "b" => "banana", "c" => "apple"); + $myobj = new testc(); + try { + array_walk($fruits, 'test', $myobj); + } catch (Exception $e) { + echo "Caught: " . $e->getMessage() . "\n"; + } +} +?> +--EXPECT-- +Caught: Error diff --git a/tests/std/array/bug30833.phpt b/tests/std/array/bug30833.phpt new file mode 100644 index 00000000..c79c33fa --- /dev/null +++ b/tests/std/array/bug30833.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #30833 (array_count_values() modifies input array) +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + string(3) "abc" + [1]=> + string(4) "0000" +} +array(2) { + ["abc"]=> + int(1) + ["0000"]=> + int(1) +} +array(2) { + [0]=> + string(3) "abc" + [1]=> + string(4) "0000" +} +Done diff --git a/tests/std/array/bug31158.phpt b/tests/std/array/bug31158.phpt new file mode 100644 index 00000000..f5fe6c2e --- /dev/null +++ b/tests/std/array/bug31158.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #31158 (array_splice on $GLOBALS crashes) +--INI-- +error_reporting = E_ALL +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: array_splice(): Argument #1 ($array) could not be passed by reference in %s:%d +Stack trace: +#0 %s(%d): __() +#1 {main} + thrown in %s on line %d diff --git a/tests/std/array/bug31213.phpt b/tests/std/array/bug31213.phpt new file mode 100644 index 00000000..7a378294 --- /dev/null +++ b/tests/std/array/bug31213.phpt @@ -0,0 +1,56 @@ +--TEST-- +Bug #31213 (Sideeffects caused by bug #29493) +--SKIPIF-- + + +--FILE-- + $a, '_b' => &$b); + var_dump($a, $b); + if ($use_extract) { + extract($arr, EXTR_REFS); + } else { + $_a =& $arr['_a']; + $_b =& $arr['_b']; + } + $_a++; + $_b++; + var_dump($a, $b, $_a, $_b, $arr); +} +function main() +{ + test(false); + test(true); +} +?> +--EXPECT-- +int(1) +int(1) +int(1) +int(2) +int(2) +int(2) +array(2) { + ["_a"]=> + &int(2) + ["_b"]=> + &int(2) +} +int(1) +int(1) +int(1) +int(2) +int(2) +int(2) +array(2) { + ["_a"]=> + &int(2) + ["_b"]=> + &int(2) +} diff --git a/tests/std/array/bug33382.phpt b/tests/std/array/bug33382.phpt new file mode 100644 index 00000000..0153da90 --- /dev/null +++ b/tests/std/array/bug33382.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #33382 (array_reverse() fails after *sort() ) +--FILE-- + +--EXPECT-- +array(5) { + [0]=> + int(5) + [1]=> + int(4) + [2]=> + int(3) + [3]=> + int(2) + [4]=> + int(1) +} +Done diff --git a/tests/std/array/bug33989.phpt b/tests/std/array/bug33989.phpt new file mode 100644 index 00000000..44ba60d8 --- /dev/null +++ b/tests/std/array/bug33989.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #33989 (extract($GLOBALS,EXTR_REFS) crashes PHP) +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +ok diff --git a/tests/std/array/bug34066.phpt b/tests/std/array/bug34066.phpt new file mode 100644 index 00000000..5fa475b6 --- /dev/null +++ b/tests/std/array/bug34066.phpt @@ -0,0 +1,574 @@ +--TEST-- +Bug #34066 (recursive array_walk causes segfault) +--FILE-- + 0) { + print "{$prefix}{$key}={$val}\n"; + } else { + print "{$prefix}{$key}\n"; + } + print "gen_xml(prefix={$prefix}) end\n"; +} +function main() +{ + $order = array("DocID" => "1", "DocDate" => "19.09.06", "ReSubmissionDate" => "", "DocTyp" => "Stapelauftrag", "CustID" => "00000", "CustomerAddress" => array(array("Name1" => 'name1', "Name2" => 'name2', "Name3" => "", "City" => 'city', "Street" => 'street', "Postal" => 'postcode', "IATA" => "90", "Country" => "Deutschland", "ShortName" => 'short', "ContactKey" => "", "EMail" => 'email@example.com')), "Text1" => "", "Text2" => "", "Wildcard1" => "", "Wildcard2" => "", "Dispatch" => "Paketdienst", "Weight" => "0,0", "BillingCustID" => "4300200000", "ExtDocNr" => "00000000003", "AnalysisLock" => "", "PrintFlag" => "", "FormType" => "0", "Curr" => "EUR", "ExChangeRate" => "1,0000", "WIRRate" => "0", "OneTimeCustomer" => array(array("BankCode" => "", "BankAccount" => "")), "Language" => "0", "PriceGroup" => "1", "PrFlag" => "0", "SalesTaxKey" => "1", "ProceedKey" => "0", "CustDiscountGroup" => "0", "Discount" => array(array("FinDisc1" => "0,00", "Disc1Base" => "145,72", "Disc1Value" => "0,00", "FinDisc2" => "0,00", "Disc2Base" => "145,72", "Disc2Value" => "0,00", "FinDisc3" => "0,00", "Disc3Base" => "145,72", "Disc3Value" => "0,00", "ValueSummary" => "0,00")), "Contact" => array(array("Repr" => "999", "Region" => "99", "Commission" => "0,00", "Agent" => "000000")), "Booking" => array(array("CostUnit" => "0000000000", "CostCentre" => "0000000000", "AccountingArea" => "01")), "InvoiceCycleKey" => "0", "AnalysisKey" => "", "OrderNumber" => "", "OrderDate" => "", "OrderCode" => "", "DocItems" => array("DocItem" => array("PosType" => "1", "ItemRef" => "1002", "CRef" => "", "Desc1" => "Pr�sentation Niederlande per", "Desc2" => "", "ArticleGroup" => "102", "PosTypeVersion" => "E", "Delivery" => array(array("DelWeek" => "", "DelDay" => "", "DelTime" => "")), "PricePu" => "145,72", "PriceUnit" => "0", "PriceCalculation" => "0", "ItemVal" => "145,72", "InputKey" => "0", "AveragePurchasePrice" => "0", "Tax" => array(array("TaxCode" => "00", "TaxBra" => "000", "TaxBraAccess" => "0", "TaxSumIndex" => "0")), "DiscountArticle" => array(array("DiscPC" => "0,00", "DiscKey" => "1")), "ProceedKeyArticle" => "01", "ActionKey" => "00", "ContactCommissionArticle" => "0,00", "QuantdependentPriceKey" => "", "Quant" => "1", "QuantUnit" => "", "Meas" => array(array("Count" => "1", "Length" => "0,000", "Width" => "0,000", "Height" => "0,000")), "DecimalPlace" => "0", "MultiplierQuant" => "1,000000", "DifferingQuantUnit" => "", "DecimalPlaceConversion" => "0", "WeightArticle" => array(array("Amount" => "0", "Unit" => "0")), "Wreath" => "0,000", "Stock" => "1", "CostUnitArticle" => "", "SerialNbKey" => "0", "TextComplementKey" => "0", "PartsListPrintKey" => "", "Prod" => "0000000000")), "Payment" => array("PaymentKey" => "0", "ReminderKey" => "00", "PayTerms" => array(array("PayTerm" => "1", "PayDays" => "000", "CashDiscDays1" => "000", "CashDiscDays2" => "000", "CashDiscPer1" => "0,00", "CashDiscPer2" => "0,00"), array("PayTerm" => "2", "PayDays" => "000", "CashDiscDays1" => "000", "CashDiscDays2" => "000", "CashDiscPer1" => "0,00", "CashDiscPer2" => "0,00"))), "NetAmountByTurnOverTax" => array(array("TurnOverTaxFree" => "145,72", "TurnOverTax1" => "0,00", "TurnOverTax2" => "0,00", "TurnOverTax3" => "0,00", "TurnOverTax4" => "0,00", "TurnOverTax5" => "0,00", "TurnOverTax6" => "0,00", "TurnOverTax7" => "0,00", "TurnOverTax8" => "0,00")), "GrossAmount" => "145,72", "ProceedAmount" => "145,72", "NetAmountByPayTerm2" => array(array("Sum0" => "0,00", "Sum1" => "0,00", "Sum2" => "0,00", "Sum3" => "0,00", "Sum4" => "0,00", "Sum5" => "0,00", "Sum6" => "0,00", "Sum7" => "0,00", "Sum8" => "0,00")), "TaxCodes" => array(array("TaxCode1" => "0", "TaxCode2" => "0", "TaxCode3" => "0", "TaxCode4" => "0", "TaxCode5" => "0", "TaxCode6" => "0", "TaxCode7" => "0", "TaxCode8" => "0"))); + $docs = array(array("Version" => "1.0", "ProducerName" => "xxxxxxxx", "ProductName" => "Classic Line", "xmlns" => "x-schema:CL310_DezABFSchema.XML"), "Company" => array(array("MandateNumber" => "111", "MandateName" => "xxx xxxxxxx-xxxxx xxxxxxx", "MandateCurr" => "EUR")), "Doc" => $order); + dump2xml($docs); + echo "Done\n"; +} +?> +--EXPECT-- +gen_xml(prefix=/Docs/) +gen_xml(prefix=/Docs/@) +/Docs/@Version=1.0 +gen_xml(prefix=/Docs/@) end +gen_xml(prefix=/Docs/@) +/Docs/@ProducerName=xxxxxxxx +gen_xml(prefix=/Docs/@) end +gen_xml(prefix=/Docs/@) +/Docs/@ProductName=Classic Line +gen_xml(prefix=/Docs/@) end +gen_xml(prefix=/Docs/@) +/Docs/@xmlns=x-schema:CL310_DezABFSchema.XML +gen_xml(prefix=/Docs/@) end +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +gen_xml(prefix=/Docs/Company/) +gen_xml(prefix=/Docs/Company/@) +/Docs/Company/@MandateNumber=111 +gen_xml(prefix=/Docs/Company/@) end +gen_xml(prefix=/Docs/Company/@) +/Docs/Company/@MandateName=xxx xxxxxxx-xxxxx xxxxxxx +gen_xml(prefix=/Docs/Company/@) end +gen_xml(prefix=/Docs/Company/@) +/Docs/Company/@MandateCurr=EUR +gen_xml(prefix=/Docs/Company/@) end +gen_xml(prefix=/Docs/Company/) end +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/DocID=1 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/DocDate=19.09.06 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/ReSubmissionDate +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/DocTyp=Stapelauftrag +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/CustID=00000 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/CustomerAddress/) +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@Name1=name1 +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@Name2=name2 +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@Name3 +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@City=city +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@Street=street +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@Postal=postcode +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@IATA=90 +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@Country=Deutschland +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@ShortName=short +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@ContactKey +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) +/Docs/Doc/CustomerAddress/@EMail=email@example.com +gen_xml(prefix=/Docs/Doc/CustomerAddress/@) end +gen_xml(prefix=/Docs/Doc/CustomerAddress/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/Text1 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/Text2 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/Wildcard1 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/Wildcard2 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/Dispatch=Paketdienst +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/Weight=0,0 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/BillingCustID=4300200000 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/ExtDocNr=00000000003 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/AnalysisLock +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/PrintFlag +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/FormType=0 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/Curr=EUR +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/ExChangeRate=1,0000 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/WIRRate=0 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/OneTimeCustomer/) +gen_xml(prefix=/Docs/Doc/OneTimeCustomer/@) +/Docs/Doc/OneTimeCustomer/@BankCode +gen_xml(prefix=/Docs/Doc/OneTimeCustomer/@) end +gen_xml(prefix=/Docs/Doc/OneTimeCustomer/@) +/Docs/Doc/OneTimeCustomer/@BankAccount +gen_xml(prefix=/Docs/Doc/OneTimeCustomer/@) end +gen_xml(prefix=/Docs/Doc/OneTimeCustomer/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/Language=0 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/PriceGroup=1 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/PrFlag=0 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/SalesTaxKey=1 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/ProceedKey=0 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/CustDiscountGroup=0 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/Discount/) +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@FinDisc1=0,00 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@Disc1Base=145,72 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@Disc1Value=0,00 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@FinDisc2=0,00 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@Disc2Base=145,72 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@Disc2Value=0,00 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@FinDisc3=0,00 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@Disc3Base=145,72 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@Disc3Value=0,00 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/@) +/Docs/Doc/Discount/@ValueSummary=0,00 +gen_xml(prefix=/Docs/Doc/Discount/@) end +gen_xml(prefix=/Docs/Doc/Discount/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/Contact/) +gen_xml(prefix=/Docs/Doc/Contact/@) +/Docs/Doc/Contact/@Repr=999 +gen_xml(prefix=/Docs/Doc/Contact/@) end +gen_xml(prefix=/Docs/Doc/Contact/@) +/Docs/Doc/Contact/@Region=99 +gen_xml(prefix=/Docs/Doc/Contact/@) end +gen_xml(prefix=/Docs/Doc/Contact/@) +/Docs/Doc/Contact/@Commission=0,00 +gen_xml(prefix=/Docs/Doc/Contact/@) end +gen_xml(prefix=/Docs/Doc/Contact/@) +/Docs/Doc/Contact/@Agent=000000 +gen_xml(prefix=/Docs/Doc/Contact/@) end +gen_xml(prefix=/Docs/Doc/Contact/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/Booking/) +gen_xml(prefix=/Docs/Doc/Booking/@) +/Docs/Doc/Booking/@CostUnit=0000000000 +gen_xml(prefix=/Docs/Doc/Booking/@) end +gen_xml(prefix=/Docs/Doc/Booking/@) +/Docs/Doc/Booking/@CostCentre=0000000000 +gen_xml(prefix=/Docs/Doc/Booking/@) end +gen_xml(prefix=/Docs/Doc/Booking/@) +/Docs/Doc/Booking/@AccountingArea=01 +gen_xml(prefix=/Docs/Doc/Booking/@) end +gen_xml(prefix=/Docs/Doc/Booking/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/InvoiceCycleKey=0 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/AnalysisKey +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/OrderNumber +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/OrderDate +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/OrderCode +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/DocItems/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/PosType=1 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/ItemRef=1002 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/CRef +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/Desc1=Pr�sentation Niederlande per +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/Desc2 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/ArticleGroup=102 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/PosTypeVersion=E +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Delivery/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Delivery/@) +/Docs/Doc/DocItems/DocItem/Delivery/@DelWeek +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Delivery/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Delivery/@) +/Docs/Doc/DocItems/DocItem/Delivery/@DelDay +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Delivery/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Delivery/@) +/Docs/Doc/DocItems/DocItem/Delivery/@DelTime +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Delivery/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Delivery/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/PricePu=145,72 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/PriceUnit=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/PriceCalculation=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/ItemVal=145,72 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/InputKey=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/AveragePurchasePrice=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/@) +/Docs/Doc/DocItems/DocItem/Tax/@TaxCode=00 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/@) +/Docs/Doc/DocItems/DocItem/Tax/@TaxBra=000 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/@) +/Docs/Doc/DocItems/DocItem/Tax/@TaxBraAccess=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/@) +/Docs/Doc/DocItems/DocItem/Tax/@TaxSumIndex=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Tax/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/DiscountArticle/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/DiscountArticle/@) +/Docs/Doc/DocItems/DocItem/DiscountArticle/@DiscPC=0,00 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/DiscountArticle/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/DiscountArticle/@) +/Docs/Doc/DocItems/DocItem/DiscountArticle/@DiscKey=1 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/DiscountArticle/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/DiscountArticle/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/ProceedKeyArticle=01 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/ActionKey=00 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/ContactCommissionArticle=0,00 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/QuantdependentPriceKey +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/Quant=1 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/QuantUnit +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/@) +/Docs/Doc/DocItems/DocItem/Meas/@Count=1 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/@) +/Docs/Doc/DocItems/DocItem/Meas/@Length=0,000 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/@) +/Docs/Doc/DocItems/DocItem/Meas/@Width=0,000 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/@) +/Docs/Doc/DocItems/DocItem/Meas/@Height=0,000 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/Meas/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/DecimalPlace=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/MultiplierQuant=1,000000 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/DifferingQuantUnit +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/DecimalPlaceConversion=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/WeightArticle/) +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/WeightArticle/@) +/Docs/Doc/DocItems/DocItem/WeightArticle/@Amount=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/WeightArticle/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/WeightArticle/@) +/Docs/Doc/DocItems/DocItem/WeightArticle/@Unit=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/WeightArticle/@) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/WeightArticle/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/Wreath=0,000 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/Stock=1 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/CostUnitArticle +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/SerialNbKey=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/TextComplementKey=0 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/PartsListPrintKey +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) +/Docs/Doc/DocItems/DocItem/Prod=0000000000 +gen_xml(prefix=/Docs/Doc/DocItems/DocItem/) end +gen_xml(prefix=/Docs/Doc/DocItems/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/Payment/) +/Docs/Doc/Payment/PaymentKey=0 +gen_xml(prefix=/Docs/Doc/Payment/) end +gen_xml(prefix=/Docs/Doc/Payment/) +/Docs/Doc/Payment/ReminderKey=00 +gen_xml(prefix=/Docs/Doc/Payment/) end +gen_xml(prefix=/Docs/Doc/Payment/) +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/) +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@PayTerm=1 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@PayDays=000 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@CashDiscDays1=000 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@CashDiscDays2=000 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@CashDiscPer1=0,00 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@CashDiscPer2=0,00 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/) +/Docs/Doc/Payment/PayTerms +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@PayTerm=2 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@PayDays=000 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@CashDiscDays1=000 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@CashDiscDays2=000 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@CashDiscPer1=0,00 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) +/Docs/Doc/Payment/PayTerms/@CashDiscPer2=0,00 +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/@) end +gen_xml(prefix=/Docs/Doc/Payment/PayTerms/) end +gen_xml(prefix=/Docs/Doc/Payment/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/) +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) +/Docs/Doc/NetAmountByTurnOverTax/@TurnOverTaxFree=145,72 +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) +/Docs/Doc/NetAmountByTurnOverTax/@TurnOverTax1=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) +/Docs/Doc/NetAmountByTurnOverTax/@TurnOverTax2=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) +/Docs/Doc/NetAmountByTurnOverTax/@TurnOverTax3=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) +/Docs/Doc/NetAmountByTurnOverTax/@TurnOverTax4=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) +/Docs/Doc/NetAmountByTurnOverTax/@TurnOverTax5=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) +/Docs/Doc/NetAmountByTurnOverTax/@TurnOverTax6=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) +/Docs/Doc/NetAmountByTurnOverTax/@TurnOverTax7=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) +/Docs/Doc/NetAmountByTurnOverTax/@TurnOverTax8=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByTurnOverTax/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/GrossAmount=145,72 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +/Docs/Doc/ProceedAmount=145,72 +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/) +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) +/Docs/Doc/NetAmountByPayTerm2/@Sum0=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) +/Docs/Doc/NetAmountByPayTerm2/@Sum1=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) +/Docs/Doc/NetAmountByPayTerm2/@Sum2=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) +/Docs/Doc/NetAmountByPayTerm2/@Sum3=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) +/Docs/Doc/NetAmountByPayTerm2/@Sum4=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) +/Docs/Doc/NetAmountByPayTerm2/@Sum5=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) +/Docs/Doc/NetAmountByPayTerm2/@Sum6=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) +/Docs/Doc/NetAmountByPayTerm2/@Sum7=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) +/Docs/Doc/NetAmountByPayTerm2/@Sum8=0,00 +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/@) end +gen_xml(prefix=/Docs/Doc/NetAmountByPayTerm2/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/Doc/) +gen_xml(prefix=/Docs/Doc/TaxCodes/) +gen_xml(prefix=/Docs/Doc/TaxCodes/@) +/Docs/Doc/TaxCodes/@TaxCode1=0 +gen_xml(prefix=/Docs/Doc/TaxCodes/@) end +gen_xml(prefix=/Docs/Doc/TaxCodes/@) +/Docs/Doc/TaxCodes/@TaxCode2=0 +gen_xml(prefix=/Docs/Doc/TaxCodes/@) end +gen_xml(prefix=/Docs/Doc/TaxCodes/@) +/Docs/Doc/TaxCodes/@TaxCode3=0 +gen_xml(prefix=/Docs/Doc/TaxCodes/@) end +gen_xml(prefix=/Docs/Doc/TaxCodes/@) +/Docs/Doc/TaxCodes/@TaxCode4=0 +gen_xml(prefix=/Docs/Doc/TaxCodes/@) end +gen_xml(prefix=/Docs/Doc/TaxCodes/@) +/Docs/Doc/TaxCodes/@TaxCode5=0 +gen_xml(prefix=/Docs/Doc/TaxCodes/@) end +gen_xml(prefix=/Docs/Doc/TaxCodes/@) +/Docs/Doc/TaxCodes/@TaxCode6=0 +gen_xml(prefix=/Docs/Doc/TaxCodes/@) end +gen_xml(prefix=/Docs/Doc/TaxCodes/@) +/Docs/Doc/TaxCodes/@TaxCode7=0 +gen_xml(prefix=/Docs/Doc/TaxCodes/@) end +gen_xml(prefix=/Docs/Doc/TaxCodes/@) +/Docs/Doc/TaxCodes/@TaxCode8=0 +gen_xml(prefix=/Docs/Doc/TaxCodes/@) end +gen_xml(prefix=/Docs/Doc/TaxCodes/) end +gen_xml(prefix=/Docs/Doc/) end +gen_xml(prefix=/Docs/) end +Done diff --git a/tests/std/array/bug34066_1.phpt b/tests/std/array/bug34066_1.phpt new file mode 100644 index 00000000..d23acf4d --- /dev/null +++ b/tests/std/array/bug34066_1.phpt @@ -0,0 +1,501 @@ +--TEST-- +Bug #34066 (recursive array_walk causes segfault) +--FILE-- + 0) { + print "{$prefix}{$key}={$val}\n"; + } else { + print "{$prefix}{$key}\n"; + } + print "gen_xml(prefix={$prefix}) end\n"; +} +function main() +{ + $order = array("DocID" => "1", "DocDate" => "19.09.06", "ReSubmissionDate" => "", "DocTyp" => "Stapelauftrag", "CustID" => "00000", "CustomerAddress" => array(array("Name1" => 'name1', "Name2" => 'name2', "Name3" => "", "City" => 'city', "Street" => 'street', "Postal" => 'postcode', "IATA" => "90", "Country" => "Deutschland", "ShortName" => 'short', "ContactKey" => "", "EMail" => 'email@example.com')), "Text1" => "", "Text2" => "", "Wildcard1" => "", "Wildcard2" => "", "Dispatch" => "Paketdienst", "Weight" => "0,0", "BillingCustID" => "4300200000", "ExtDocNr" => "00000000003", "AnalysisLock" => "", "PrintFlag" => "", "FormType" => "0", "Curr" => "EUR", "ExChangeRate" => "1,0000", "WIRRate" => "0", "OneTimeCustomer" => array(array("BankCode" => "", "BankAccount" => "")), "Language" => "0", "PriceGroup" => "1", "PrFlag" => "0", "SalesTaxKey" => "1", "ProceedKey" => "0", "CustDiscountGroup" => "0", "Discount" => array(array("FinDisc1" => "0,00", "Disc1Base" => "145,72", "Disc1Value" => "0,00", "FinDisc2" => "0,00", "Disc2Base" => "145,72", "Disc2Value" => "0,00", "FinDisc3" => "0,00", "Disc3Base" => "145,72", "Disc3Value" => "0,00", "ValueSummary" => "0,00")), "Contact" => array(array("Repr" => "999", "Region" => "99", "Commission" => "0,00", "Agent" => "000000")), "Booking" => array(array("CostUnit" => "0000000000", "CostCentre" => "0000000000", "AccountingArea" => "01")), "InvoiceCycleKey" => "0", "AnalysisKey" => "", "OrderNumber" => "", "OrderDate" => "", "OrderCode" => "", "DocItems" => array("DocItem" => array("PosType" => "1", "ItemRef" => "1002", "CRef" => "", "Desc1" => "Pr�sentation Niederlande per", "Desc2" => "", "ArticleGroup" => "102", "PosTypeVersion" => "E", "Delivery" => array(array("DelWeek" => "", "DelDay" => "", "DelTime" => "")), "PricePu" => "145,72", "PriceUnit" => "0", "PriceCalculation" => "0", "ItemVal" => "145,72", "InputKey" => "0", "AveragePurchasePrice" => "0", "Tax" => array(array("TaxCode" => "00", "TaxBra" => "000", "TaxBraAccess" => "0", "TaxSumIndex" => "0")), "DiscountArticle" => array(array("DiscPC" => "0,00", "DiscKey" => "1")), "ProceedKeyArticle" => "01", "ActionKey" => "00", "ContactCommissionArticle" => "0,00", "QuantdependentPriceKey" => "", "Quant" => "1", "QuantUnit" => "", "Meas" => array(array("Count" => "1", "Length" => "0,000", "Width" => "0,000", "Height" => "0,000")), "DecimalPlace" => "0", "MultiplierQuant" => "1,000000", "DifferingQuantUnit" => "", "DecimalPlaceConversion" => "0", "WeightArticle" => array(array("Amount" => "0", "Unit" => "0")), "Wreath" => "0,000", "Stock" => "1", "CostUnitArticle" => "", "SerialNbKey" => "0", "TextComplementKey" => "0", "PartsListPrintKey" => "", "Prod" => "0000000000")), "Payment" => array("PaymentKey" => "0", "ReminderKey" => "00", "PayTerms" => array(array("PayTerm" => "1", "PayDays" => "000", "CashDiscDays1" => "000", "CashDiscDays2" => "000", "CashDiscPer1" => "0,00", "CashDiscPer2" => "0,00"), array("PayTerm" => "2", "PayDays" => "000", "CashDiscDays1" => "000", "CashDiscDays2" => "000", "CashDiscPer1" => "0,00", "CashDiscPer2" => "0,00"))), "NetAmountByTurnOverTax" => array(array("TurnOverTaxFree" => "145,72", "TurnOverTax1" => "0,00", "TurnOverTax2" => "0,00", "TurnOverTax3" => "0,00", "TurnOverTax4" => "0,00", "TurnOverTax5" => "0,00", "TurnOverTax6" => "0,00", "TurnOverTax7" => "0,00", "TurnOverTax8" => "0,00")), "GrossAmount" => "145,72", "ProceedAmount" => "145,72", "NetAmountByPayTerm2" => array(array("Sum0" => "0,00", "Sum1" => "0,00", "Sum2" => "0,00", "Sum3" => "0,00", "Sum4" => "0,00", "Sum5" => "0,00", "Sum6" => "0,00", "Sum7" => "0,00", "Sum8" => "0,00")), "TaxCodes" => array(array("TaxCode1" => "0", "TaxCode2" => "0", "TaxCode3" => "0", "TaxCode4" => "0", "TaxCode5" => "0", "TaxCode6" => "0", "TaxCode7" => "0", "TaxCode8" => "0"))); + $docs = array(array("Version" => "1.0", "ProducerName" => "xxxxxxxx", "ProductName" => "Classic Line", "xmlns" => "x-schema:CL310_DezABFSchema.XML"), "Company" => array(array("MandateNumber" => "111", "MandateName" => "xxx xxxxxxx-xxxxx xxxxxxx", "MandateCurr" => "EUR")), "Doc" => $order); + dump2xml($docs); + echo "Done\n"; +} +?> +--EXPECT-- +gen_xml(prefix=/Docs/) +/Docs/Version=1.0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ProducerName=xxxxxxxx +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ProductName=Classic Line +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/xmlns=x-schema:CL310_DezABFSchema.XML +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/MandateNumber=111 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/MandateName=xxx xxxxxxx-xxxxx xxxxxxx +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/MandateCurr=EUR +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DocID=1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DocDate=19.09.06 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ReSubmissionDate +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DocTyp=Stapelauftrag +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CustID=00000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Name1=name1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Name2=name2 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Name3 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/City=city +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Street=street +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Postal=postcode +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/IATA=90 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Country=Deutschland +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ShortName=short +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ContactKey +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/EMail=email@example.com +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Text1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Text2 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Wildcard1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Wildcard2 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Dispatch=Paketdienst +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Weight=0,0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/BillingCustID=4300200000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ExtDocNr=00000000003 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/AnalysisLock +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PrintFlag +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/FormType=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Curr=EUR +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ExChangeRate=1,0000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/WIRRate=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/BankCode +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/BankAccount +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Language=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PriceGroup=1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PrFlag=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/SalesTaxKey=1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ProceedKey=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CustDiscountGroup=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/FinDisc1=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Disc1Base=145,72 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Disc1Value=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/FinDisc2=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Disc2Base=145,72 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Disc2Value=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/FinDisc3=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Disc3Base=145,72 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Disc3Value=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ValueSummary=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Repr=999 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Region=99 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Commission=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Agent=000000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CostUnit=0000000000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CostCentre=0000000000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/AccountingArea=01 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/InvoiceCycleKey=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/AnalysisKey +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/OrderNumber +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/OrderDate +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/OrderCode +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PosType=1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ItemRef=1002 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CRef +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Desc1=Pr�sentation Niederlande per +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Desc2 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ArticleGroup=102 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PosTypeVersion=E +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DelWeek +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DelDay +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DelTime +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PricePu=145,72 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PriceUnit=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PriceCalculation=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ItemVal=145,72 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/InputKey=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/AveragePurchasePrice=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxCode=00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxBra=000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxBraAccess=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxSumIndex=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DiscPC=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DiscKey=1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ProceedKeyArticle=01 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ActionKey=00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ContactCommissionArticle=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/QuantdependentPriceKey +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Quant=1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/QuantUnit +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Count=1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Length=0,000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Width=0,000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Height=0,000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DecimalPlace=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/MultiplierQuant=1,000000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DifferingQuantUnit +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/DecimalPlaceConversion=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Amount=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Unit=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Wreath=0,000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Stock=1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CostUnitArticle +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/SerialNbKey=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TextComplementKey=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PartsListPrintKey +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Prod=0000000000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PaymentKey=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ReminderKey=00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PayTerm=1 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PayDays=000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CashDiscDays1=000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CashDiscDays2=000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CashDiscPer1=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CashDiscPer2=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PayTerm=2 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/PayDays=000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CashDiscDays1=000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CashDiscDays2=000 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CashDiscPer1=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/CashDiscPer2=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TurnOverTaxFree=145,72 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TurnOverTax1=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TurnOverTax2=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TurnOverTax3=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TurnOverTax4=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TurnOverTax5=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TurnOverTax6=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TurnOverTax7=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TurnOverTax8=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/GrossAmount=145,72 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/ProceedAmount=145,72 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Sum0=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Sum1=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Sum2=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Sum3=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Sum4=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Sum5=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Sum6=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Sum7=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/Sum8=0,00 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxCode1=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxCode2=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxCode3=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxCode4=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxCode5=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxCode6=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxCode7=0 +gen_xml(prefix=/Docs/) end +gen_xml(prefix=/Docs/) +/Docs/TaxCode8=0 +gen_xml(prefix=/Docs/) end +Done diff --git a/tests/std/array/bug34227.phpt b/tests/std/array/bug34227.phpt new file mode 100644 index 00000000..b7c094c7 --- /dev/null +++ b/tests/std/array/bug34227.phpt @@ -0,0 +1,85 @@ +--TEST-- +Bug #34277 (array_filter() crashes with references and objects) +--FILE-- +m2(); + } + function m2() + { + $this->m3(); + } + function m3() + { + $this->m4(); + } + function m4() + { + $this->m5(); + } + function m5() + { + $this->m6(); + } + function m6() + { + $this->m7(); + } + function m7() + { + $this->m8(); + } + function m8() + { + $this->m9(); + } + function m9() + { + $this->m10(); + } + function m10() + { + $this->m11(1, 2, 3, 4, 5, 6, 7, 8, 9, 10); + } + function m11($a1, $a2, $a3, $a4, $a5, $a6, $a7, $a8, $a9, $a10) + { + $arr = explode('a', 'b'); + } +} +function f($str) +{ + $obj = new C(); + $obj->m1(); + return TRUE; +} +function p5($a1, $a2, $a3, $a4, $a5, $a6, $a7, $a8, $a9, $a10, $a11, $a12) +{ + $ret = array_filter(array(0), 'f'); +} +function p4() +{ + p5(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12); +} +function p3() +{ + p4(); +} +function p2() +{ + p3(); +} +function p1() +{ + p2(); +} +function main() +{ + p1(); + echo "ok\n"; +} +?> +--EXPECT-- +ok diff --git a/tests/std/array/bug34982.phpt b/tests/std/array/bug34982.phpt new file mode 100644 index 00000000..b6629fc2 --- /dev/null +++ b/tests/std/array/bug34982.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #34982 (array_walk_recursive() modifies elements outside function scope) +--FILE-- + +--EXPECT-- +Array +( + [0] => changed + [1] => Array + ( + [0] => changed + ) + +) +Array +( + [0] => element 1 + [1] => Array + ( + [0] => subelement1 + ) + +) diff --git a/tests/std/array/bug35014.phpt b/tests/std/array/bug35014.phpt new file mode 100644 index 00000000..3935657f --- /dev/null +++ b/tests/std/array/bug35014.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #35014 (array_product() always returns 0) (32bit) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(0) +int(3) +int(9) +float(1) +float(9999999800000000) +float(2.8404260053902914E+20) +float(8589934590) diff --git a/tests/std/array/bug35014_64bit.phpt b/tests/std/array/bug35014_64bit.phpt new file mode 100644 index 00000000..29fa9e18 --- /dev/null +++ b/tests/std/array/bug35014_64bit.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #35014 (array_product() always returns 0) (64bit) +--SKIPIF-- + +--INI-- +precision=14 +--FILE-- + +--EXPECT-- +int(0) +int(3) +int(9) +float(1) +int(9999999800000001) +float(1.219953680144986E+30) +float(3.6893488147419103E+19) diff --git a/tests/std/array/bug35022.phpt b/tests/std/array/bug35022.phpt new file mode 100644 index 00000000..a7787aaf --- /dev/null +++ b/tests/std/array/bug35022.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #35022 (Regression in the behavior of key/current functions) +--SKIPIF-- + +--FILE-- + " . current($state) . "\n"; + } +} +function main() +{ + $state = array("one" => 1, "two" => 2, "three" => 3); + foo($state); + reset($state); + var_dump(key($state), current($state)); +} +?> +--EXPECT-- +three => 3 +two => 2 +one => 1 +string(3) "one" +int(1) diff --git a/tests/std/array/bug35821.phpt b/tests/std/array/bug35821.phpt new file mode 100644 index 00000000..0887f064 --- /dev/null +++ b/tests/std/array/bug35821.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #35821 (array_map() segfaults when exception is throwed from the callback) +--SKIPIF-- + +--FILE-- +ThrowException(); + } +} +function main() +{ + $arr = array(new Element(), new Element(), new Element()); + array_map(array('Element', 'CallBack'), $arr); + echo "Done\n"; +} +?> +--EXPECTF-- +Fatal error: Uncaught Exception in %s:%d +Stack trace: +#0 %s(%d): Element->ThrowException() +#1 [internal function]: Element::CallBack(Object(Element)) +#2 %s(%d): array_map(Array, Array) +#3 {main} + thrown in %s on line %d diff --git a/tests/std/array/bug36975.phpt b/tests/std/array/bug36975.phpt new file mode 100644 index 00000000..67a34325 --- /dev/null +++ b/tests/std/array/bug36975.phpt @@ -0,0 +1,62 @@ +--TEST-- +Bug #36975 (natcasesort() causes array_pop() to misbehave) +--FILE-- + 'foo', 0 => 'baz'); +array_pop($b); +$b[] = 'bar'; +array_push($b, 'bar'); +print_r($b); + +$c = array(0, 0, 0, 0, 0); +asort($c); +array_pop($c); +$c[] = 'foo'; +$c[] = 'bar'; +var_dump($c); +?> +--EXPECT-- +natcasesort success! +array(6) { + [0]=> + string(2) "aa" + [1]=> + string(2) "aa" + [2]=> + string(2) "bb" + [3]=> + string(2) "bb" + [4]=> + string(2) "cc" + [5]=> + string(2) "cc" +} +Array +( + [1] => foo + [2] => bar + [3] => bar +) +array(6) { + [0]=> + int(0) + [1]=> + int(0) + [2]=> + int(0) + [3]=> + int(0) + [4]=> + string(3) "foo" + [5]=> + string(3) "bar" +} diff --git a/tests/std/array/bug38464.phpt b/tests/std/array/bug38464.phpt new file mode 100644 index 00000000..5480109b --- /dev/null +++ b/tests/std/array/bug38464.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #38464 (array_count_values() mishandles numeric strings) +--FILE-- + +--EXPECT-- +array(5) { + ["-000"]=> + int(1) + [" 001"]=> + int(1) + [1]=> + int(1) + [" 123"]=> + int(1) + ["+123"]=> + int(1) +} diff --git a/tests/std/array/bug39576.phpt b/tests/std/array/bug39576.phpt new file mode 100644 index 00000000..7e3b52d6 --- /dev/null +++ b/tests/std/array/bug39576.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #39576 (array_walk() doesn't separate userdata zval) +--SKIPIF-- + +--FILE-- +name = 'test'; + $test->_columns['name'] = new stdClass(); + array_walk(get_object_vars($test), 'test', $test->_columns); + var_dump($test); + array_intersect_key(get_object_vars($test), $test->_primary); + echo "Done\n"; +} +?> +--EXPECTF-- +Notice: Only variables should be passed by reference in %s on line %d + +Warning: test(): Argument #3 ($columns) must be passed by reference, value given in %s on line %d + +Warning: test(): Argument #3 ($columns) must be passed by reference, value given in %s on line %d + +Warning: test(): Argument #3 ($columns) must be passed by reference, value given in %s on line %d + +Warning: test(): Argument #3 ($columns) must be passed by reference, value given in %s on line %d +object(Test)#%d (4) { + ["_table"]=> + string(0) "" + ["_columns"]=> + array(1) { + ["name"]=> + object(stdClass)#%d (0) { + } + } + ["_primary"]=> + array(0) { + } + ["name"]=> + string(4) "test" +} +Done diff --git a/tests/std/array/bug40191.phpt b/tests/std/array/bug40191.phpt new file mode 100644 index 00000000..c1a0d6b6 --- /dev/null +++ b/tests/std/array/bug40191.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #40191 (use of array_unique() with objects triggers segfault) +--FILE-- +append('foo'); +$arrObj->append('bar'); +$arrObj->append('foo'); + +try { + $arr = array_unique($arrObj); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +echo "Done\n"; +?> +--EXPECT-- +array_unique(): Argument #1 ($array) must be of type array, ArrayObject given +Done diff --git a/tests/std/array/bug40709.phpt b/tests/std/array/bug40709.phpt new file mode 100644 index 00000000..4a04deb7 --- /dev/null +++ b/tests/std/array/bug40709.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #40709 (array_reduce() behaves strange with one item stored arrays) +--FILE-- + +--EXPECT-- +result for arr1: 1,2,3 +result for arr2: 1 +result for arr1: 1,2,3 +result for arr2: 1 +Done diff --git a/tests/std/array/bug41686.phpt b/tests/std/array/bug41686.phpt new file mode 100644 index 00000000..b94acb60 --- /dev/null +++ b/tests/std/array/bug41686.phpt @@ -0,0 +1,56 @@ +--TEST-- +Bug #41686 (Omitting length param in array_slice not possible) +--FILE-- +1,'b'=>1,'c'=>2); + +var_dump( + array_slice($a, 1), + array_slice($a, 1, 2, TRUE), + array_slice($a, 1, NULL, TRUE), + array_slice($b, 1), + array_slice($b, 1, 2, TRUE), + array_slice($b, 1, NULL, TRUE) +); + +echo "Done\n"; +?> +--EXPECT-- +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +array(2) { + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + [1]=> + int(2) + [2]=> + int(3) +} +array(2) { + ["b"]=> + int(1) + ["c"]=> + int(2) +} +array(2) { + ["b"]=> + int(1) + ["c"]=> + int(2) +} +array(2) { + ["b"]=> + int(1) + ["c"]=> + int(2) +} +Done diff --git a/tests/std/array/bug42177.phpt b/tests/std/array/bug42177.phpt new file mode 100644 index 00000000..c838a7db --- /dev/null +++ b/tests/std/array/bug42177.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #42177 (Warning "array_merge_recursive(): recursion detected" comes again...) +--SKIPIF-- + +--FILE-- + 1, 'key3' => 2 ); +$a2 = array(); +$a1 = array_merge_recursive( $a1, $a2 ); +$a1 = array_merge_recursive( $a1, $a2 ); +unset( $a1, $a2 ); + +$a1 = array(); +$a2 = array( 'key1' => 1, 'key3' => 2 ); +$a1 = array_merge_recursive( $a1, $a2 ); +$a1 = array_merge_recursive( $a1, $a2 ); +unset( $a1, $a2 ); + +$a1 = array(); +$a2 = array( 'key1' => &$a1 ); +$a1 = array_merge_recursive( $a1, $a2 ); +try { + $a1 = array_merge_recursive( $a1, $a2 ); +} catch (\Error $e) { + echo $e->getMessage() . " on line " . $e->getLine() . "\n"; +} +unset( $a1, $a2 ); + +$x = 'foo'; +$y =& $x; +$a1 = array($x, $y, $x, $y); +$a2 = array( 'key1' => $a1, $x, $y ); +$a1 = array_merge_recursive( $a1, $a2 ); +$a1 = array_merge_recursive( $a1, $a2 ); +unset( $a1, $a2 ); + +?> +--EXPECT-- +Recursion detected on line 19 diff --git a/tests/std/array/bug42233.phpt b/tests/std/array/bug42233.phpt new file mode 100644 index 00000000..a538761b --- /dev/null +++ b/tests/std/array/bug42233.phpt @@ -0,0 +1,38 @@ +--TEST-- +Bug #42233 (extract(): scandic characters not allowed as variable name) +--SKIPIF-- + + +--FILE-- + '1', + 'æ' => '2', + 'æøåäö' => '3', +); + +var_dump($test); +var_dump(extract($test)); +var_dump($a); +var_dump($æ); +var_dump($æøåäö); + +echo "Done.\n"; +?> +--EXPECT-- +array(3) { + ["a"]=> + string(1) "1" + ["æ"]=> + string(1) "2" + ["æøåäö"]=> + string(1) "3" +} +int(3) +string(1) "1" +string(1) "2" +string(1) "3" +Done. diff --git a/tests/std/array/bug42838.phpt b/tests/std/array/bug42838.phpt new file mode 100644 index 00000000..2298db2b --- /dev/null +++ b/tests/std/array/bug42838.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #42838 (Wrong results in array_diff_uassoc()) +--FILE-- + $b ? 1 : -1; +} +function main() +{ + $array1 = array("a" => "green", "b" => "Brown", 'c' => 'blue', 0 => 'red'); + $array2 = array("a" => "green", "b" => "Brown", 'c' => 'blue', 0 => 'red'); + $result = array_diff_uassoc($array1, $array2, "key_compare_func"); + print_r($result); +} +?> +--EXPECT-- +Array +( +) diff --git a/tests/std/array/bug42850.phpt b/tests/std/array/bug42850.phpt new file mode 100644 index 00000000..7b1cccac --- /dev/null +++ b/tests/std/array/bug42850.phpt @@ -0,0 +1,64 @@ +--TEST-- +Bug #42850 (array_walk_recursive() leaves references) +--FILE-- + 'val1', array('key2' => 'val2')); + var_dump($data); + array_walk_recursive($data, 'apply_dumb'); + $data2 = $data; + $data2[0] = 'altered'; + var_dump($data); + var_dump($data2); + myfunc($data); + var_dump($data); +} +?> +--EXPECT-- +array(2) { + ["key1"]=> + string(4) "val1" + [0]=> + array(1) { + ["key2"]=> + string(4) "val2" + } +} +array(2) { + ["key1"]=> + string(4) "val1" + [0]=> + array(1) { + ["key2"]=> + string(4) "val2" + } +} +array(2) { + ["key1"]=> + string(4) "val1" + [0]=> + string(7) "altered" +} +array(2) { + ["key1"]=> + string(4) "val1" + [0]=> + array(1) { + ["key2"]=> + string(4) "val2" + } +} diff --git a/tests/std/array/bug43495.phpt b/tests/std/array/bug43495.phpt new file mode 100644 index 00000000..37c4f6b6 --- /dev/null +++ b/tests/std/array/bug43495.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #43495 (array_merge_recursive() crashes with recursive arrays) +--FILE-- +array("key2"=>array())); +$a["key1"]["key2"]["key3"]=&$a; + +$b=array("key1"=>array("key2"=>array())); +$b["key1"]["key2"]["key3"]=&$b; + + +try { + array_merge_recursive($a,$b); +} catch (\Error $e) { + echo $e->getMessage() . "\n"; +} + +/* Break recursion */ +$a["key1"]["key2"]["key3"] = null; +$b["key1"]["key2"]["key3"] = null; + +?> +--EXPECT-- +Recursion detected diff --git a/tests/std/array/bug43505.phpt b/tests/std/array/bug43505.phpt new file mode 100644 index 00000000..3a7b1151 --- /dev/null +++ b/tests/std/array/bug43505.phpt @@ -0,0 +1,40 @@ +--TEST-- +Bug #43505 (Assign by reference bug) +--INI-- +error_reporting=0 +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +array(1) { + ["test"]=> + &NULL +} +array(1) { + ["test"]=> + &NULL +} diff --git a/tests/std/array/bug43541.phpt b/tests/std/array/bug43541.phpt new file mode 100644 index 00000000..847f61ad --- /dev/null +++ b/tests/std/array/bug43541.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #43541 (length parameter omitted or not does not work when casted to float) +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} diff --git a/tests/std/array/bug44181.phpt b/tests/std/array/bug44181.phpt new file mode 100644 index 00000000..0432d51f --- /dev/null +++ b/tests/std/array/bug44181.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #44181 (extract EXTR_OVERWRITE|EXTR_REFS can fail to create references) +--SKIPIF-- + + +--FILE-- + 'original.foo'); + +$foo = 'test'; +$ref = &$a; + +extract($a, EXTR_OVERWRITE|EXTR_REFS); +$foo = 'changed.foo'; + +var_dump($a['foo']); +echo "Done\n"; +?> +--EXPECTF-- +string(%d) "changed.foo" +Done diff --git a/tests/std/array/bug44182.phpt b/tests/std/array/bug44182.phpt new file mode 100644 index 00000000..86504a7a --- /dev/null +++ b/tests/std/array/bug44182.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #44182 (extract EXTR_REFS can fail to split copy-on-write references) +--SKIPIF-- + + +--FILE-- + 'original.foo'); + +$nonref = $a['foo']; +$ref = &$a; + +extract($a, EXTR_REFS); +$a['foo'] = 'changed.foo'; + +var_dump($nonref); +echo "Done\n"; +?> +--EXPECTF-- +string(%d) "original.foo" +Done diff --git a/tests/std/array/bug44929.phpt b/tests/std/array/bug44929.phpt new file mode 100644 index 00000000..efcbcda1 --- /dev/null +++ b/tests/std/array/bug44929.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #44929 (natsort doesn't handle leading zeros well) +--FILE-- + +--EXPECT-- +array(12) { + [6]=> + string(4) "-123" + [8]=> + string(2) "00" + [9]=> + string(1) "0" + [11]=> + string(3) "0-0" + [7]=> + string(5) "0.002" + [10]=> + string(3) "0_0" + [0]=> + string(3) "001" + [4]=> + string(2) "03" + [2]=> + string(3) "005" + [1]=> + string(3) "008" + [3]=> + string(5) "00011" + [5]=> + string(6) "000014" +} diff --git a/tests/std/array/bug45312.phpt b/tests/std/array/bug45312.phpt new file mode 100644 index 00000000..f005c508 --- /dev/null +++ b/tests/std/array/bug45312.phpt @@ -0,0 +1,52 @@ +--TEST-- +Bug #45312 (Segmentation fault on second request for array functions) +--FILE-- +priv_member = $val; + } + static function comp_func_cr($a, $b) + { + if ($a->priv_member === $b->priv_member) { + return 0; + } + return $a->priv_member > $b->priv_member ? 1 : -1; + } + static function comp_func_cr2($a, $b) + { + echo "."; + if ($a->priv_member === $b->priv_member) { + return 0; + } + return $a->priv_member < $b->priv_member ? 1 : -1; + } + function dump() + { + echo $this->priv_member . "\n"; + } +} +function main() +{ + $a = array("0.1" => new cr(9), "0.5" => new cr(12), 0 => new cr(23), 1 => new cr(4), 2 => new cr(-15)); + $b = array("0.2" => new cr(9), "0.5" => new cr(22), 0 => new cr(3), 1 => new cr(4), 2 => new cr(-15)); + $result = array_udiff_assoc($a, $b, array("cr", "comp_func_cr")); + foreach ($result as $val) { + $val->dump(); + } + $result = array_udiff_assoc($a, $b, array("cr", "comp_func_cr2")); + foreach ($result as $val) { + $val->dump(); + } +} +?> +--EXPECT-- +9 +12 +23 +....9 +12 +23 diff --git a/tests/std/array/bug46873.phpt b/tests/std/array/bug46873.phpt new file mode 100644 index 00000000..2c5f262c --- /dev/null +++ b/tests/std/array/bug46873.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #46873 (extract($foo) crashes if $foo['foo'] exists) +--SKIPIF-- + + +--FILE-- + 1, 'bar' => 2, 'test' => 3); +extract($foo); +var_dump($foo, $bar, $test); +?> +--EXPECT-- +int(1) +int(2) +int(3) diff --git a/tests/std/array/bug48224.phpt b/tests/std/array/bug48224.phpt new file mode 100644 index 00000000..5b46e183 --- /dev/null +++ b/tests/std/array/bug48224.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #48224 (array_rand no longer shuffles) +--FILE-- + +--EXPECT-- +bool(true) diff --git a/tests/std/array/bug48854.phpt b/tests/std/array/bug48854.phpt new file mode 100644 index 00000000..ed5b8e1a --- /dev/null +++ b/tests/std/array/bug48854.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #48854 (array_merge_recursive modifies arrays after first one) +--FILE-- + 5, + 'children' => array( + 'dogs' => 0, + ), +); + +$array2 = array( + 'friends' => 10, + 'children' => array( + 'cats' => 5, + ), +); + +$merged = array_merge_recursive($array1, $array2); + +var_dump($array1, $array2); + +?> +--EXPECT-- +array(2) { + ["friends"]=> + int(5) + ["children"]=> + array(1) { + ["dogs"]=> + int(0) + } +} +array(2) { + ["friends"]=> + int(10) + ["children"]=> + array(1) { + ["cats"]=> + int(5) + } +} diff --git a/tests/std/array/bug50006.phpt b/tests/std/array/bug50006.phpt new file mode 100644 index 00000000..c7c59752 --- /dev/null +++ b/tests/std/array/bug50006.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #50006 (Segfault caused by uksort()) +--FILE-- + 0, 'bar-bazbazbaz-' => 0, 'foo' => 0); + uksort($data, 'magic_sort_cmp'); + print_r($data); +} +?> +--EXPECT-- +Array +( + [foo] => 0 + [bar-bazbazbaz.] => 0 + [bar-bazbazbaz-] => 0 +) diff --git a/tests/std/array/bug50006_1.phpt b/tests/std/array/bug50006_1.phpt new file mode 100644 index 00000000..9a565f87 --- /dev/null +++ b/tests/std/array/bug50006_1.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #50006 (Segfault caused by uksort()) - usort variant +--FILE-- + +--EXPECT-- +Array +( + [0] => foo + [1] => bar-bazbazbaz. + [2] => bar-bazbazbaz- +) diff --git a/tests/std/array/bug50006_2.phpt b/tests/std/array/bug50006_2.phpt new file mode 100644 index 00000000..82956367 --- /dev/null +++ b/tests/std/array/bug50006_2.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #50006 (Segfault caused by uksort()) - uasort variant +--FILE-- + +--EXPECT-- +Array +( + [2] => foo + [0] => bar-bazbazbaz. + [1] => bar-bazbazbaz- +) diff --git a/tests/std/array/bug51552.phpt b/tests/std/array/bug51552.phpt new file mode 100644 index 00000000..609b9eaf --- /dev/null +++ b/tests/std/array/bug51552.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #51552 (debug_backtrace() causes segmentation fault and/or memory issues) +--FILE-- + +--EXPECT-- +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 diff --git a/tests/std/array/bug52534.phpt b/tests/std/array/bug52534.phpt new file mode 100644 index 00000000..dfff3fdb --- /dev/null +++ b/tests/std/array/bug52534.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #52534 (var_export array with negative key) +--FILE-- + 'Hello'); + +var_export($aArray); + +?> +--EXPECT-- +array ( + -1 => 'Hello', +) diff --git a/tests/std/array/bug52719.phpt b/tests/std/array/bug52719.phpt new file mode 100644 index 00000000..91bb4ec1 --- /dev/null +++ b/tests/std/array/bug52719.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #52719: array_walk_recursive crashes if third param of the function is by reference +--SKIPIF-- + + +--FILE-- + +--EXPECTF-- +Warning: {closure:%s:%d}(): Argument #3 ($userdata) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #3 ($userdata) must be passed by reference, value given in %s on line %d +Done diff --git a/tests/std/array/bug61058.phpt b/tests/std/array/bug61058.phpt new file mode 100644 index 00000000..e5960a55 --- /dev/null +++ b/tests/std/array/bug61058.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #61058 (array_fill leaks if start index is PHP_INT_MAX) +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Cannot add element to the array as the next element is already occupied diff --git a/tests/std/array/bug61730.phpt b/tests/std/array/bug61730.phpt new file mode 100644 index 00000000..ff137151 --- /dev/null +++ b/tests/std/array/bug61730.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #61730 (Segfault from array_walk modifying an array passed by reference) +--FILE-- + +--EXPECT-- +int(0) +int(3) +int(6) +int(9) +Array +( +) diff --git a/tests/std/array/bug61967.phpt b/tests/std/array/bug61967.phpt new file mode 100644 index 00000000..ee107e5b --- /dev/null +++ b/tests/std/array/bug61967.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #61967: unset array item in array_walk_recursive cause inconsistent array +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +int(0) +int(1) +int(2) +int(3) +int(4) diff --git a/tests/std/array/bug62607.phpt b/tests/std/array/bug62607.phpt new file mode 100644 index 00000000..a2a3dfd3 --- /dev/null +++ b/tests/std/array/bug62607.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #62607: array_walk_recursive move internal pointer +--SKIPIF-- + + +--FILE-- +'b'); +echo 'Before -> '.current($arr).PHP_EOL; +array_walk_recursive($arr, function(&$val){}); +echo 'After -> '.current($arr); +?> +--EXPECT-- +Before -> b +After -> b diff --git a/tests/std/array/bug65251.phpt b/tests/std/array/bug65251.phpt new file mode 100644 index 00000000..93fe5276 --- /dev/null +++ b/tests/std/array/bug65251.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #65251: array_merge_recursive() recursion detection broken +--INI-- +report_memleaks=0 +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} + +echo "===DONE===\n"; +?> +--EXPECT-- +===DONE=== diff --git a/tests/std/array/bug65304.phpt b/tests/std/array/bug65304.phpt new file mode 100644 index 00000000..8ed4c508 --- /dev/null +++ b/tests/std/array/bug65304.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #65304 (Use of max int in array_sum) +--FILE-- + +--EXPECTF-- +float(%s) +float(%s) diff --git a/tests/std/array/bug67693.phpt b/tests/std/array/bug67693.phpt new file mode 100644 index 00000000..c9aa2d86 --- /dev/null +++ b/tests/std/array/bug67693.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #67693 - incorrect push to empty array +--FILE-- + 0); + +array_pop($array); + +array_push($array, 0); +array_push($array, 0); + +var_dump($array); + +echo"\nDone"; +?> +--EXPECT-- +array(2) { + [-1]=> + int(0) + [0]=> + int(0) +} + +Done diff --git a/tests/std/array/bug68553.phpt b/tests/std/array/bug68553.phpt new file mode 100644 index 00000000..f17af0a5 --- /dev/null +++ b/tests/std/array/bug68553.phpt @@ -0,0 +1,85 @@ +--TEST-- +Bug #68553 (array_column: null values in $index_key become incrementing keys in result) +--SKIPIF-- + +--FILE-- + 10], + ['a' => 20], + ['a' => true], + ['a' => false], + ['a' => fopen(__FILE__, "r")], + ['a' => -5], + ['a' => 7.38], + ['a' => null, "test"], + ['a' => null], +]; + +var_dump(array_column($a, null, 'a')); + +try { + var_dump(array_column([['a' => new stdClass]], null, 'a')); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(array_column([['a' => []]], null, 'a')); +} catch (Error $e) { + echo $e->getMessage(), "\n"; +} +?> +--EXPECTF-- +Warning: Resource ID#%d used as offset, casting to integer (%d) in %s on line %d + +Deprecated: Implicit conversion from float 7.38 to int loses precision in %s on line %d +array(8) { + [10]=> + array(1) { + ["a"]=> + int(10) + } + [20]=> + array(1) { + ["a"]=> + int(20) + } + [1]=> + array(1) { + ["a"]=> + bool(true) + } + [0]=> + array(1) { + ["a"]=> + bool(false) + } + [%d]=> + array(1) { + ["a"]=> + resource(%d) of type (stream) + } + [-5]=> + array(1) { + ["a"]=> + int(-5) + } + [7]=> + array(1) { + ["a"]=> + float(7.38) + } + [""]=> + array(1) { + ["a"]=> + NULL + } +} +Cannot access offset of type stdClass on array +Cannot access offset of type array on array diff --git a/tests/std/array/bug69068.phpt b/tests/std/array/bug69068.phpt new file mode 100644 index 00000000..a069b44b --- /dev/null +++ b/tests/std/array/bug69068.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #69068: Exchanging array during array_walk -> memory errors +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(1) +int(2) +int(4) +int(5) +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} diff --git a/tests/std/array/bug69068_2.phpt b/tests/std/array/bug69068_2.phpt new file mode 100644 index 00000000..cd744128 --- /dev/null +++ b/tests/std/array/bug69068_2.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #69068: Exchanging array during array_walk -> memory errors (variation) +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +int(1) +int(2) +int(4) +int(5) +array(2) { + [0]=> + int(40) + [1]=> + int(50) +} +array(2) { + [0]=> + int(4) + [1]=> + int(5) +} diff --git a/tests/std/array/bug69166.phpt b/tests/std/array/bug69166.phpt new file mode 100644 index 00000000..d0b5fadd --- /dev/null +++ b/tests/std/array/bug69166.phpt @@ -0,0 +1,17 @@ +--TEST-- +Fixed #69166 (Assigning array_values() to array does not reset key counter) +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} diff --git a/tests/std/array/bug69198.phpt b/tests/std/array/bug69198.phpt new file mode 100644 index 00000000..5d4130e7 --- /dev/null +++ b/tests/std/array/bug69198.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #69198 (Compact function generate array with length but no content) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: compact(): Undefined variable $willNeverBeDefined in %s on line %d +array(0) { +} +bool(true) +bool(true) +bool(true) diff --git a/tests/std/array/bug69299.phpt b/tests/std/array/bug69299.phpt new file mode 100644 index 00000000..77c76166 --- /dev/null +++ b/tests/std/array/bug69299.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #69299 (Regression in array_filter's $flag argument in PHP 7) +--FILE-- + 'bar', 'fiz' => 'buz'); +$filtered = array_filter($toFilter, function ($value, $key) { + if ($value === 'buz' + || $key === 'foo' + ) { + return false; + } + return true; +}, ARRAY_FILTER_USE_BOTH); +var_dump($filtered); +?> +--EXPECT-- +array(0) { +} diff --git a/tests/std/array/bug69371.phpt b/tests/std/array/bug69371.phpt new file mode 100644 index 00000000..a4350e66 --- /dev/null +++ b/tests/std/array/bug69371.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #69371 (Hash table collision leads to inaccessible array keys) +--SKIPIF-- +--FILE-- + 1, + "d6_filter_format" => 2, + "d6_user" => 3, + "d6_field_instance_widget_settings" => 4, + "d6_field_formatter_settings" => 5, +); + +$weights = array( + 5, 1, 3, 2, 0 +); +array_multisort($weights, SORT_DESC, SORT_NUMERIC, $array); + +var_dump($array["d6_node_type"]); + +?> +--EXPECT-- +int(1) diff --git a/tests/std/array/bug69413.phpt b/tests/std/array/bug69413.phpt new file mode 100644 index 00000000..3a0ab8d0 --- /dev/null +++ b/tests/std/array/bug69413.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #69413: Warning in array_count_values() about array values not being string/int +--FILE-- + +--EXPECT-- +array(2) { + ["a"]=> + int(1) + ["b"]=> + int(1) +} diff --git a/tests/std/array/bug69674.phpt b/tests/std/array/bug69674.phpt new file mode 100644 index 00000000..0d58b6ae --- /dev/null +++ b/tests/std/array/bug69674.phpt @@ -0,0 +1,8 @@ +--TEST-- +Bug #69674 (SIGSEGV array.c:953) +--FILE-- + +--EXPECT-- +bool(false) diff --git a/tests/std/array/bug69723.phpt b/tests/std/array/bug69723.phpt new file mode 100644 index 00000000..90422a52 --- /dev/null +++ b/tests/std/array/bug69723.phpt @@ -0,0 +1,32 @@ +--TEST-- +Bug #69723 (Passing parameters by reference and array_column) +--FILE-- + 'superman', 'nanana' => 'no nana'], ['superhero' => 'acuaman', 'nanana' => 'no nana']]; + var_dump(array_column($array, 'superhero')); + byReference($array); + var_dump(array_column($array, 'superhero')); +} +?> +--EXPECT-- +array(2) { + [0]=> + string(8) "superman" + [1]=> + string(7) "acuaman" +} +array(2) { + [0]=> + string(5) "robin" + [1]=> + string(5) "robin" +} diff --git a/tests/std/array/bug70250.phpt b/tests/std/array/bug70250.phpt new file mode 100644 index 00000000..29e54ea9 --- /dev/null +++ b/tests/std/array/bug70250.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #70250 (extract() turns array elements to references) +--SKIPIF-- + + +--FILE-- + 'value']; + +$ref = &$array['key']; + +unset($ref); + +extract($array); + +$key = "bad"; + +var_dump($array); +?> +--EXPECT-- +array(1) { + ["key"]=> + string(5) "value" +} diff --git a/tests/std/array/bug70668.phpt b/tests/std/array/bug70668.phpt new file mode 100644 index 00000000..b35107a0 --- /dev/null +++ b/tests/std/array/bug70668.phpt @@ -0,0 +1,63 @@ +--TEST-- +Bug #70668 (array_keys() doesn't respect references when $strict is true) +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + int(0) +} +array(1) { + [0]=> + int(1) +} +array(1) { + [0]=> + int(2) +} +array(1) { + [0]=> + int(3) +} +array(1) { + [0]=> + int(4) +} +array(1) { + [0]=> + int(5) +} +array(1) { + [0]=> + int(6) +} +array(1) { + [0]=> + int(7) +} diff --git a/tests/std/array/bug70713.phpt b/tests/std/array/bug70713.phpt new file mode 100644 index 00000000..6a1af9b6 --- /dev/null +++ b/tests/std/array/bug70713.phpt @@ -0,0 +1,29 @@ +--TEST-- +Bug #70713: Use After Free Vulnerability in array_walk()/array_walk_recursive() +--SKIPIF-- + +--FILE-- + new obj()); + try { + array_walk_recursive($arr, 'settype'); + } catch (\TypeError $e) { + echo $e->getMessage() . "\n"; + } +} +?> +--EXPECT-- +Iterated value is no longer an array or object diff --git a/tests/std/array/bug70808.phpt b/tests/std/array/bug70808.phpt new file mode 100644 index 00000000..df82da8c --- /dev/null +++ b/tests/std/array/bug70808.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #70808 (array_merge_recursive corrupts memory of unset items) +--FILE-- + array(0, 1)); +$arr2 = array("key" => array(2)); + +unset($arr1["key"][1]); + +$result = array_merge_recursive($arr1, $arr2); +print_r($result); +?> +--EXPECT-- +Array +( + [key] => Array + ( + [0] => 0 + [2] => 2 + ) + +) diff --git a/tests/std/array/bug70910.phpt b/tests/std/array/bug70910.phpt new file mode 100644 index 00000000..f4aed175 --- /dev/null +++ b/tests/std/array/bug70910.phpt @@ -0,0 +1,19 @@ +--TEST-- +Bug #70910 (extract() breaks variable references) +--SKIPIF-- + + +--FILE-- + 'new value']; + +extract($hash); +var_dump($var === $ref); +?> +--EXPECT-- +bool(true) diff --git a/tests/std/array/bug71220.phpt b/tests/std/array/bug71220.phpt new file mode 100644 index 00000000..5c5f43ee --- /dev/null +++ b/tests/std/array/bug71220.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #71220 (Null pointer deref (segfault) in compact via ob_start) +--FILE-- +getMessage(); +} +?> +--EXPECT-- +Cannot call compact() dynamically diff --git a/tests/std/array/bug71334.phpt b/tests/std/array/bug71334.phpt new file mode 100644 index 00000000..31b720a5 --- /dev/null +++ b/tests/std/array/bug71334.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #71334: Cannot access array keys while uksort() +--SKIPIF-- +--FILE-- + [1], '-' => [2], 'bar-test' => [3]]; + public function _mySort($x, $y) + { + if (!isset($this->a[$x])) { + throw new Exception('Missing X: "' . $x . '"'); + } + if (!isset($this->a[$y])) { + throw new Exception('Missing Y: "' . $y . '"'); + } + return $x <=> $y; + } + public function __construct() + { + uksort($this->a, [$this, '_mySort']); + } +} +function main() +{ + new myClass(); + echo "Done"; +} +?> +--EXPECT-- +Done diff --git a/tests/std/array/bug71603.phpt b/tests/std/array/bug71603.phpt new file mode 100644 index 00000000..099c1b97 --- /dev/null +++ b/tests/std/array/bug71603.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #71603 (compact() maintains references in php7) +--FILE-- + +--EXPECT-- +string(4) "okey" diff --git a/tests/std/array/bug71660.phpt b/tests/std/array/bug71660.phpt new file mode 100644 index 00000000..067f5333 --- /dev/null +++ b/tests/std/array/bug71660.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #71660 (array_column behaves incorrectly after foreach by reference) +--FILE-- + 12345, 'name' => 'sam'); +foreach ($arr as &$v) { + $v = $v; +} + +$arr = [$arr]; + +var_dump(array_column($arr, 'name', 'id')); +?> +--EXPECT-- +array(1) { + [12345]=> + string(3) "sam" +} diff --git a/tests/std/array/bug71837.phpt b/tests/std/array/bug71837.phpt new file mode 100644 index 00000000..686d144c --- /dev/null +++ b/tests/std/array/bug71837.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #71837 (Wrong arrays behaviour) +--FILE-- + +--EXPECT-- +Array +( + [0] => Array + ( + [0] => Array + ( + [0] => 100 + ) + + ) + +) diff --git a/tests/std/array/bug72031.phpt b/tests/std/array/bug72031.phpt new file mode 100644 index 00000000..00c3eac3 --- /dev/null +++ b/tests/std/array/bug72031.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #72031: array_column() against an array of objects discards all values matching null +--FILE-- +prop = $prop; + } +} +function main() +{ + $objects = [new myObj(-1), new myObj(0), new myObj(1), new myObj(2), new myObj(null), new myObj(true), new myObj(false), new myObj('abc'), new myObj('')]; + var_dump(array_column($objects, 'prop')); +} +?> +--EXPECT-- +array(9) { + [0]=> + int(-1) + [1]=> + int(0) + [2]=> + int(1) + [3]=> + int(2) + [4]=> + NULL + [5]=> + bool(true) + [6]=> + bool(false) + [7]=> + string(3) "abc" + [8]=> + string(0) "" +} diff --git a/tests/std/array/bug72116.phpt b/tests/std/array/bug72116.phpt new file mode 100644 index 00000000..182f6994 --- /dev/null +++ b/tests/std/array/bug72116.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #72116 (insertion after array_fill fails) +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + string(2) ".." + [1]=> + string(1) "a" +} diff --git a/tests/std/array/bug72369.phpt b/tests/std/array/bug72369.phpt new file mode 100644 index 00000000..e20b410d --- /dev/null +++ b/tests/std/array/bug72369.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #72369 (array_merge() produces references in PHP7) +--SKIPIF-- + +--FILE-- + &$x]; +unset($x); +$a = ['test' => 'yyy']; +$a = array_merge($a, $d); +debug_zval_dump($a); +?> +--EXPECTF-- +array(1) refcount(%d){ + ["test"]=> + string(3) "xxx" interned +} diff --git a/tests/std/array/bug72622.phpt b/tests/std/array/bug72622.phpt new file mode 100644 index 00000000..78813e8d --- /dev/null +++ b/tests/std/array/bug72622.phpt @@ -0,0 +1,37 @@ +--TEST-- +Bug #72622 (array_walk + array_replace_recursive create references from nothing) +--SKIPIF-- + + +--FILE-- + 'foo']; + $arr4 = walk(['foo' => 'bar']); + $arr5 = array_replace_recursive($arr3, $arr4); + $arr5['foo'] = 'baz'; + var_dump($arr3, $arr4, $arr5); +} +?> +--EXPECT-- +array(1) { + ["foo"]=> + string(3) "foo" +} +array(1) { + ["foo"]=> + string(3) "bar" +} +array(1) { + ["foo"]=> + string(3) "baz" +} diff --git a/tests/std/array/bug74345.phpt b/tests/std/array/bug74345.phpt new file mode 100644 index 00000000..afa08886 --- /dev/null +++ b/tests/std/array/bug74345.phpt @@ -0,0 +1,49 @@ +--TEST-- +Bug #74345: Call trampoline leaked if callback not invoked +--SKIPIF-- +--FILE-- +getMessage(), "\n"; + } + try { + array_map($cb, null, null); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + array_filter([], $cb); + array_reduce([], $cb); + + $array = []; + array_walk($array, $cb); + array_walk_recursive($array, $cb); + usort($array, $cb); + + try { + preg_replace_callback('/./', $cb, new stdClass); + } catch (Error $e) { + echo $e->getMessage(), "\n"; + } + + echo "===DONE===\n"; +} +?> +--EXPECT-- +array_map(): Argument #2 ($array) must be of type array, null given +array_map(): Argument #2 ($array) must be of type array, null given +preg_replace_callback(): Argument #3 ($subject) must be of type array|string, stdClass given +===DONE=== diff --git a/tests/std/array/bug74361.phpt b/tests/std/array/bug74361.phpt new file mode 100644 index 00000000..6e745902 --- /dev/null +++ b/tests/std/array/bug74361.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug #74361: Compaction in array_rand() violates COW +--FILE-- + 4]; +var_dump(array_rand($array)); + +?> +--EXPECT-- +int(4) diff --git a/tests/std/array/bug74361_2.phpt b/tests/std/array/bug74361_2.phpt new file mode 100644 index 00000000..4f4bdcf5 --- /dev/null +++ b/tests/std/array/bug74361_2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #74361: Compaction in array_rand() violates COW (variation) +--FILE-- + +--EXPECT-- +int(9) +int(10) +int(11) +int(12) +int(13) +int(14) +int(15) diff --git a/tests/std/array/bug75433.phpt b/tests/std/array/bug75433.phpt new file mode 100644 index 00000000..caf4816a --- /dev/null +++ b/tests/std/array/bug75433.phpt @@ -0,0 +1,18 @@ +--TEST-- +array_values() preserves next index from source array when shallow-copying +--FILE-- + +--EXPECT-- +Array +( + [0] => 1 + [1] => 2 + [2] => 4 +) diff --git a/tests/std/array/bug75653.phpt b/tests/std/array/bug75653.phpt new file mode 100644 index 00000000..d11c1e0c --- /dev/null +++ b/tests/std/array/bug75653.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #75653: array_values don't work on empty array +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + string(5) "data2" + [1]=> + string(5) "data3" +} diff --git a/tests/std/array/bug76505.phpt b/tests/std/array/bug76505.phpt new file mode 100644 index 00000000..ad0b2c86 --- /dev/null +++ b/tests/std/array/bug76505.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #76505 (array_merge_recursive() is duplicating sub-array keys) +--FILE-- + array( + 2 => 100, + 98 => 200, + ) +); + +$array2 = array( + 'k' => array( + 64 => 300 + ) +); + +$array3 = array_merge_recursive( $array1, $array2 ); + +var_dump($array3); +?> +--EXPECT-- +array(1) { + ["k"]=> + array(3) { + [2]=> + int(100) + [98]=> + int(200) + [99]=> + int(300) + } +} diff --git a/tests/std/array/bug76713.phpt b/tests/std/array/bug76713.phpt new file mode 100644 index 00000000..9daae219 --- /dev/null +++ b/tests/std/array/bug76713.phpt @@ -0,0 +1,35 @@ +--TEST-- +Bug #76713 (Segmentation fault caused by property corruption) +--FILE-- +name; + } +} +function main() +{ + $obj = new Stdclass(); + $obj->prop = str_pad("a", 10, 'a'); + test($obj); + test($obj); + test($obj); + var_dump($obj->prop); + $obj2 = new C(); + $obj2->name = str_pad("b", 10, 'b'); + test($obj2); + test($obj2); + test($obj2); + var_dump($obj2->prop); +} +?> +--EXPECT-- +string(10) "aaaaaaaaaa" +string(10) "bbbbbbbbbb" diff --git a/tests/std/array/bug76778.phpt b/tests/std/array/bug76778.phpt new file mode 100644 index 00000000..e07b6f35 --- /dev/null +++ b/tests/std/array/bug76778.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #76778 (array_reduce leaks memory if callback throws exception) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +===DONE=== diff --git a/tests/std/array/bug77135.phpt b/tests/std/array/bug77135.phpt new file mode 100644 index 00000000..c524ba7a --- /dev/null +++ b/tests/std/array/bug77135.phpt @@ -0,0 +1,91 @@ +--TEST-- +Test extract() with $this +--SKIPIF-- + + +--FILE-- + EXTR_OVERWRITE, 'EXTR_SKIP' => EXTR_SKIP, 'EXTR_PREFIX_SAME' => EXTR_PREFIX_SAME, 'EXTR_PREFIX_ALL' => EXTR_PREFIX_ALL, 'EXTR_PREFIX_INVALID' => EXTR_PREFIX_INVALID, 'EXTR_IF_EXISTS' => EXTR_IF_EXISTS, 'EXTR_PREFIX_IF_EXISTS' => EXTR_PREFIX_IF_EXISTS]; + foreach ($options as $name => $flags) { + echo "{$name}\n"; + $this->handle($name, $flags); + $this->handle("{$name}_REFS", $flags | EXTR_REFS); + echo "\n"; + } + } + private function handle(string $name, int $flags): void + { + $array = ["this" => "value"]; + try { + $result = extract($array, $flags, "x"); + echo " extract() = {$result}\n"; + echo " \$this = " . get_class($this) . "\n"; + echo " \$v_this = " . (isset($x_this) ? $x_this : "NULL") . "\n"; + } catch (\Throwable $e) { + echo " Exception: " . $e->getMessage() . "\n"; + } + } +} +function main() +{ + (new Extract())->run(); +} +?> +--EXPECT-- +EXTR_OVERWRITE + Exception: Cannot re-assign $this + Exception: Cannot re-assign $this + +EXTR_SKIP + extract() = 0 + $this = Extract + $v_this = NULL + extract() = 0 + $this = Extract + $v_this = NULL + +EXTR_PREFIX_SAME + extract() = 1 + $this = Extract + $v_this = value + extract() = 1 + $this = Extract + $v_this = value + +EXTR_PREFIX_ALL + extract() = 1 + $this = Extract + $v_this = value + extract() = 1 + $this = Extract + $v_this = value + +EXTR_PREFIX_INVALID + extract() = 1 + $this = Extract + $v_this = value + extract() = 1 + $this = Extract + $v_this = value + +EXTR_IF_EXISTS + extract() = 0 + $this = Extract + $v_this = NULL + extract() = 0 + $this = Extract + $v_this = NULL + +EXTR_PREFIX_IF_EXISTS + extract() = 0 + $this = Extract + $v_this = NULL + extract() = 0 + $this = Extract + $v_this = NULL diff --git a/tests/std/array/bug77395.phpt b/tests/std/array/bug77395.phpt new file mode 100644 index 00000000..817b36f8 --- /dev/null +++ b/tests/std/array/bug77395.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #77395 (segfault about array_multisort) +--SKIPIF-- +--FILE-- + 'bb'], ['aa' => 'bb']]; + try { + array_multisort(array_column($data, 'bb'), SORT_DESC, $data); + // PHP Warning error + } catch (\ValueError $e) { + echo $e->getMessage() . "\n"; + } +} +?> +--EXPECT-- +Array sizes are inconsistent diff --git a/tests/std/array/bug77669.phpt b/tests/std/array/bug77669.phpt new file mode 100644 index 00000000..c267d2b5 --- /dev/null +++ b/tests/std/array/bug77669.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #77669: Crash in extract() when overwriting extracted array +--SKIPIF-- + +--FILE-- + +--EXPECT-- +===DONE=== diff --git a/tests/std/array/bug77793.phpt b/tests/std/array/bug77793.phpt new file mode 100644 index 00000000..bf5caa44 --- /dev/null +++ b/tests/std/array/bug77793.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #77793: Segmentation fault in extract() when overwriting reference with itself +--SKIPIF-- + + +--FILE-- + $str . 'bar']; +$var = &$vars['var']; +extract($vars); +var_dump($vars, $var); + +?> +--EXPECT-- +array(1) { + ["var"]=> + &string(6) "foobar" +} +string(6) "foobar" diff --git a/tests/std/array/bug77931.phpt b/tests/std/array/bug77931.phpt new file mode 100644 index 00000000..d876d4b0 --- /dev/null +++ b/tests/std/array/bug77931.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #77931: Warning for array_map mentions wrong type +--FILE-- +getMessage(), "\n"; +} +try { + array_map('trim', array(), array(), true); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} +try { + array_map('trim', array(), array(), array(), null); +} catch (TypeError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECT-- +array_map(): Argument #3 must be of type array, int given +array_map(): Argument #4 must be of type array, true given +array_map(): Argument #5 must be of type array, null given diff --git a/tests/std/array/bug78759.phpt b/tests/std/array/bug78759.phpt new file mode 100644 index 00000000..4ab6414d --- /dev/null +++ b/tests/std/array/bug78759.phpt @@ -0,0 +1,20 @@ +--TEST-- +Bug #78759: array_search in $GLOBALS +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +int(22) +string(1) "a" +string(1) "a" diff --git a/tests/std/array/bug79839.phpt b/tests/std/array/bug79839.phpt new file mode 100644 index 00000000..8cd49751 --- /dev/null +++ b/tests/std/array/bug79839.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #79839: array_walk() does not respect property types +--SKIPIF-- + + +--FILE-- +getMessage(), "\n"; + } + var_dump($test); +} +?> +--EXPECT-- +Cannot assign array to reference held by property Test::$prop of type int +object(Test)#1 (1) { + ["prop"]=> + int(42) +} diff --git a/tests/std/array/bug79868.phpt b/tests/std/array/bug79868.phpt new file mode 100644 index 00000000..5c6267d6 --- /dev/null +++ b/tests/std/array/bug79868.phpt @@ -0,0 +1,15 @@ +--TEST-- +Bug #79868: Sorting with array_unique gives unwanted result +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + string(1) "b" + [1]=> + string(1) "a" +} diff --git a/tests/std/array/bug79930.phpt b/tests/std/array/bug79930.phpt new file mode 100644 index 00000000..bb4e1dd8 --- /dev/null +++ b/tests/std/array/bug79930.phpt @@ -0,0 +1,33 @@ +--TEST-- +Bug #79930: array_merge_recursive() crashes when called with array with single reference +--FILE-- + $a . 'b', +]; + +// Create rc=1 reference. +array_walk($array, function () {}); + +$m = array_merge_recursive(['value' => 'a'], $array); + +var_dump($a, $array, $m); + +?> +--EXPECT-- +string(1) "a" +array(1) { + ["value"]=> + string(2) "ab" +} +array(1) { + ["value"]=> + array(2) { + [0]=> + string(1) "a" + [1]=> + string(2) "ab" + } +} diff --git a/tests/std/array/compact.phpt b/tests/std/array/compact.phpt new file mode 100644 index 00000000..c10c7dd1 --- /dev/null +++ b/tests/std/array/compact.phpt @@ -0,0 +1,42 @@ +--TEST-- +compact() +--SKIPIF-- + + +--FILE-- + +--EXPECTF-- +Warning: compact(): Undefined variable $c\u0327ity in %s on line %d +array(2) { + ["event"]=> + string(8) "SIGGRAPH" + ["state"]=> + string(2) "CA" +} + +Warning: compact(): Argument #1 must be string or array of strings, true given in %s on line %d + +Warning: compact(): Argument #2 must be string or array of strings, int given in %s on line %d +array(1) { + ["bar"]=> + string(3) "baz" +} diff --git a/tests/std/array/compact_basic.phpt b/tests/std/array/compact_basic.phpt new file mode 100644 index 00000000..42f1ccce --- /dev/null +++ b/tests/std/array/compact_basic.phpt @@ -0,0 +1,78 @@ +--TEST-- +Test compact() function : basic functionality +--SKIPIF-- + + +--FILE-- +"val"); +$e=NULL; +$f="string"; + +// simple array test +var_dump (compact(array("a", "b", "c", "d", "e", "f"))); +// simple parameter test +var_dump (compact("a", "b", "c", "d", "e", "f")); +var_dump (compact(array("keyval"=>"a", "b"=>"b"))); +var_dump(compact(array("g"))); + +echo "Done"; +?> +--EXPECTF-- +*** Testing compact() : basic functionality *** +array(6) { + ["a"]=> + int(1) + ["b"]=> + float(0.2) + ["c"]=> + bool(true) + ["d"]=> + array(1) { + ["key"]=> + string(3) "val" + } + ["e"]=> + NULL + ["f"]=> + string(6) "string" +} +array(6) { + ["a"]=> + int(1) + ["b"]=> + float(0.2) + ["c"]=> + bool(true) + ["d"]=> + array(1) { + ["key"]=> + string(3) "val" + } + ["e"]=> + NULL + ["f"]=> + string(6) "string" +} +array(2) { + ["a"]=> + int(1) + ["b"]=> + float(0.2) +} + +Warning: compact(): Undefined variable $g in %s on line %d +array(0) { +} +Done diff --git a/tests/std/array/compact_no_this.phpt b/tests/std/array/compact_no_this.phpt new file mode 100644 index 00000000..aa60e846 --- /dev/null +++ b/tests/std/array/compact_no_this.phpt @@ -0,0 +1,27 @@ +--TEST-- +compact() without object context +--SKIPIF-- + +--FILE-- +test() +); + +var_dump(compact('this')); + +var_dump((function(){ return compact('this'); })()); + +?> +--EXPECT-- +array(0) { +} +array(0) { +} +array(0) { +} diff --git a/tests/std/array/compact_order.phpt b/tests/std/array/compact_order.phpt new file mode 100644 index 00000000..bf6051cc --- /dev/null +++ b/tests/std/array/compact_order.phpt @@ -0,0 +1,25 @@ +--TEST-- +compact() and hashmap order +--FILE-- + +--EXPECT-- +array(2) { + ["foo"]=> + NULL + ["bar"]=> + NULL +} +array(2) { + ["bar"]=> + NULL + ["foo"]=> + NULL +} diff --git a/tests/std/array/compact_this.phpt b/tests/std/array/compact_this.phpt new file mode 100644 index 00000000..20657e90 --- /dev/null +++ b/tests/std/array/compact_this.phpt @@ -0,0 +1,46 @@ +--TEST-- +compact() with object context +--FILE-- +test() +); + +var_dump( + (new class { + function test(){ + return compact([['this']]); + } + })->test() +); + +var_dump( + (new class { + function test(){ + return (function(){ return compact('this'); })(); + } + })->test() +); + +?> +--EXPECTF-- +array(1) { + ["this"]=> + object(%s)#1 (0) { + } +} +array(1) { + ["this"]=> + object(%s)#1 (0) { + } +} +array(1) { + ["this"]=> + object(%s)#1 (0) { + } +} diff --git a/tests/std/array/compact_variation1.phpt b/tests/std/array/compact_variation1.phpt new file mode 100644 index 00000000..f07ccd93 --- /dev/null +++ b/tests/std/array/compact_variation1.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test compact() function : usage variations - arrays containing references. +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; +} + +try { + var_dump(compact($arr2)); +} catch (Error $e) { + echo $e->getMessage() . "\n"; +} + +var_dump(compact($arr3)); + +?> +--EXPECT-- +*** Testing compact() : usage variations - arrays containing references *** +Recursion detected +Recursion detected +array(1) { + ["c"]=> + int(3) +} diff --git a/tests/std/array/compact_variation2.phpt b/tests/std/array/compact_variation2.phpt new file mode 100644 index 00000000..48d772fc --- /dev/null +++ b/tests/std/array/compact_variation2.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test compact() function: ensure compact() doesn't pick up variables declared outside of current scope. +--SKIPIF-- + + +--FILE-- + +--EXPECTF-- +*** Testing compact() : usage variations - variables outside of current scope *** + +Warning: compact(): Undefined variable $a in %s on line %d +array(2) { + ["b"]=> + string(3) "f.b" + ["c"]=> + string(3) "f.c" +} + +Warning: compact(): Undefined variable $a in %s on line %d +array(2) { + ["b"]=> + string(3) "f.b" + ["c"]=> + string(3) "f.c" +} diff --git a/tests/std/array/compare_function.inc b/tests/std/array/compare_function.inc new file mode 100644 index 00000000..4fa672e7 --- /dev/null +++ b/tests/std/array/compare_function.inc @@ -0,0 +1,13 @@ + diff --git a/tests/std/array/count_basic.phpt b/tests/std/array/count_basic.phpt new file mode 100644 index 00000000..6d778b4b --- /dev/null +++ b/tests/std/array/count_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test count() function : basic functionality +--FILE-- + +--EXPECT-- +*** Testing count() : basic functionality *** + +-- One Dimensional Array: -- +int(3) + +-- Two Dimensional Array: -- +$mode = COUNT_NORMAL: int(3) +$mode = 0: int(3) +$mode = COUNT_RECURSIVE: int(6) +$mode = 1: int(6) +Done diff --git a/tests/std/array/count_invalid.phpt b/tests/std/array/count_invalid.phpt new file mode 100644 index 00000000..061ed5fa --- /dev/null +++ b/tests/std/array/count_invalid.phpt @@ -0,0 +1,56 @@ +--TEST-- +Only arrays and countable objects can be counted +--SKIPIF-- +--FILE-- +getMessage() . \PHP_EOL; +} + +try { + $result = count("string"); + var_dump($result); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +try { + $result = count(123); + var_dump($result); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +try { + $result = count(true); + var_dump($result); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +try { + $result = count(false); + var_dump($result); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +try { + $result = count((object) []); + var_dump($result); +} catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; +} + +?> +--EXPECT-- +count(): Argument #1 ($value) must be of type Countable|array +count(): Argument #1 ($value) must be of type Countable|array +count(): Argument #1 ($value) must be of type Countable|array +count(): Argument #1 ($value) must be of type Countable|array +count(): Argument #1 ($value) must be of type Countable|array +int(1) diff --git a/tests/std/array/count_invalid_mode.phpt b/tests/std/array/count_invalid_mode.phpt new file mode 100644 index 00000000..ef4b2655 --- /dev/null +++ b/tests/std/array/count_invalid_mode.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test count() function : invalid modes in weak type mode +--SKIPIF-- +--FILE-- +getMessage() . \PHP_EOL; + } +} +?> +--EXPECT-- +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) diff --git a/tests/std/array/count_recursive.phpt b/tests/std/array/count_recursive.phpt new file mode 100644 index 00000000..e85c08a5 --- /dev/null +++ b/tests/std/array/count_recursive.phpt @@ -0,0 +1,131 @@ +--TEST-- +Test count() function +--SKIPIF-- + +--FILE-- + 1, "b" => 2, array("c" => 3, array("d" => 5))); + print "COUNT_NORMAL: should be 3, is " . count($arr, COUNT_NORMAL) . "\n"; + print "COUNT_RECURSIVE: should be 6, is " . count($arr, COUNT_RECURSIVE) . "\n"; + print "-- Testing various types with no second argument --\n"; + print "COUNT_NORMAL: should be 2, is " . count(array("a", array("b"))) . "\n"; + $arr = array('a' => array(NULL, NULL, NULL), 1 => array(NULL => 1, 1 => NULL), array(array(array(array(array(NULL)))))); + print "-- Testing really cool arrays --\n"; + print "COUNT_NORMAL: should be 3, is " . count($arr, COUNT_NORMAL) . "\n"; + print "COUNT_RECURSIVE: should be 13, is " . count($arr, COUNT_RECURSIVE) . "\n"; + echo "\n*** Testing possible variations of count() function on arrays ***"; + $count_array = array(array(), array(1 => "string"), array("" => "string", 0 => "a", NULL => "b", -1 => "c", array(array(array(NULL)))), array(-2 => 12, array(array(1, 2, array(array("0"))))), array("a" => 1, "b" => -2.344, "b" => "string", "c" => NULL, "d" => -2.344), array(4 => 1, 3 => -2.344, "3" => "string", "2" => NULL, 1 => -2.344, array()), array(TRUE => TRUE, FALSE => FALSE, "" => "", " " => " ", NULL => NULL, "\x000" => "\x000", "\x00" => "\x00"), array(NULL, 1 => "Hi", "string" => "hello", array("" => "World", "-2.34" => "a", "0" => "b"))); + $i = 0; + foreach ($count_array as $count_value) { + echo "\n-- Iteration {$i} --\n"; + print "COUNT_NORMAL is " . count($count_value, COUNT_NORMAL) . "\n"; + print "COUNT_RECURSIVE is " . count($count_value, COUNT_RECURSIVE) . "\n"; + $i++; + } + print "\n-- Testing count() on an empty sub-array --\n"; + $arr = array(1, array(3, 4, array())); + print "COUNT_NORMAL: should be 2, is " . count($arr, COUNT_NORMAL) . "\n"; + print "COUNT_RECURSIVE: should be 5, is " . count($arr, COUNT_RECURSIVE) . "\n"; + echo "\n-- Testing count() on objects with Countable interface --\n"; + $obj = new count_class(); + print "COUNT_NORMAL: should be 3, is " . count($obj) . "\n"; + echo "\n-- Testing count() on resource type --\n"; + $resource1 = fopen(__FILE__, "r"); + // Creating file(stream type) resource + $resource2 = opendir("."); + // Creating dir resource + /* creating an array with resources as elements */ + $arr_resource = array("a" => $resource1, "b" => $resource2); + var_dump(count($arr_resource)); + echo "\n-- Testing count() on arrays containing references --\n"; + $arr = array(1, array("a", "b", "c")); + $arr[2] =& $arr[1]; + echo "Count normal" . \PHP_EOL; + var_dump(count($arr, COUNT_NORMAL)); + echo "Count recursive" . \PHP_EOL; + var_dump(count($arr, COUNT_RECURSIVE)); + /* closing the resource handles */ + fclose($resource1); + closedir($resource2); +} +?> +--EXPECT-- +*** Testing basic functionality of count() function *** +-- Testing arrays -- +COUNT_NORMAL: should be 2, is 2 +COUNT_RECURSIVE: should be 8, is 8 +-- Testing hashes -- +COUNT_NORMAL: should be 3, is 3 +COUNT_RECURSIVE: should be 6, is 6 +-- Testing various types with no second argument -- +COUNT_NORMAL: should be 2, is 2 +-- Testing really cool arrays -- +COUNT_NORMAL: should be 3, is 3 +COUNT_RECURSIVE: should be 13, is 13 + +*** Testing possible variations of count() function on arrays *** +-- Iteration 0 -- +COUNT_NORMAL is 0 +COUNT_RECURSIVE is 0 + +-- Iteration 1 -- +COUNT_NORMAL is 1 +COUNT_RECURSIVE is 1 + +-- Iteration 2 -- +COUNT_NORMAL is 4 +COUNT_RECURSIVE is 7 + +-- Iteration 3 -- +COUNT_NORMAL is 2 +COUNT_RECURSIVE is 8 + +-- Iteration 4 -- +COUNT_NORMAL is 4 +COUNT_RECURSIVE is 4 + +-- Iteration 5 -- +COUNT_NORMAL is 5 +COUNT_RECURSIVE is 5 + +-- Iteration 6 -- +COUNT_NORMAL is 6 +COUNT_RECURSIVE is 6 + +-- Iteration 7 -- +COUNT_NORMAL is 4 +COUNT_RECURSIVE is 7 + +-- Testing count() on an empty sub-array -- +COUNT_NORMAL: should be 2, is 2 +COUNT_RECURSIVE: should be 5, is 5 + +-- Testing count() on objects with Countable interface -- +COUNT_NORMAL: should be 3, is 3 + +-- Testing count() on resource type -- +int(2) + +-- Testing count() on arrays containing references -- +Count normal +int(3) +Count recursive +int(9) diff --git a/tests/std/array/count_symbol_table.phpt b/tests/std/array/count_symbol_table.phpt new file mode 100644 index 00000000..0fe69871 --- /dev/null +++ b/tests/std/array/count_symbol_table.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test count() function : count on symbol table +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +int(2) +int(1) diff --git a/tests/std/array/count_variation3.phpt b/tests/std/array/count_variation3.phpt new file mode 100644 index 00000000..37d6fb63 --- /dev/null +++ b/tests/std/array/count_variation3.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test count() function : usage variations - Infinitely recursive array +--FILE-- + +--EXPECTF-- +*** Testing count() : usage variations *** + +-- $mode not set: -- +int(4) + +-- $mode = 1: -- + +Warning:%S Recursion detected in %s on line %d +int(4) +Done diff --git a/tests/std/array/current_basic.phpt b/tests/std/array/current_basic.phpt new file mode 100644 index 00000000..48d4e5a0 --- /dev/null +++ b/tests/std/array/current_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test current() function : basic functionality +--FILE-- + 3); +var_dump(current($array)); +next($array); +var_dump(current($array)); +end($array); +var_dump(current($array)); +next($array); +var_dump(current($array)); +?> +--EXPECT-- +*** Testing current() : basic functionality *** +string(4) "zero" +string(3) "one" +int(3) +bool(false) diff --git a/tests/std/array/current_variation2.phpt b/tests/std/array/current_variation2.phpt new file mode 100644 index 00000000..723841d5 --- /dev/null +++ b/tests/std/array/current_variation2.phpt @@ -0,0 +1,112 @@ +--TEST-- +Test current() function : usage variations - arrays containing different data types +--SKIPIF-- + + +--FILE-- + array(0, 1, 12345, -2345), + // float data + /*2*/ + 'float' => array(10.5, -10.5, 123456789000.0, 1.23456789E-9, 0.5), + // null data + /*3*/ + 'null' => array(NULL, null), + // boolean data + /*4*/ + 'bool' => array(true, false, TRUE, FALSE), + // empty data + /*5*/ + 'empty string' => array("", ''), + /*6*/ + 'empty array' => array(), + // string data + /*7*/ + 'string' => array("string", 'string', $heredoc), + // object data + /*8*/ + 'object' => array(new classA()), + // undefined data + /*9*/ + 'undefined' => array(@$undefined_var), + // unset data + /*10*/ + 'unset' => array(@$unset_var), + // resource variable + /*11*/ + 'resource' => array($fp), + ); + // loop through each element of $inputs to check the behavior of current() + $iterator = 1; + foreach ($inputs as $key => $input) { + echo "\n-- Iteration {$iterator} : {$key} data --\n"; + var_dump(current($input)); + $iterator++; + } + fclose($fp); +} +?> +--EXPECTF-- +*** Testing current() : usage variations *** + +-- Iteration 1 : int data -- +int(0) + +-- Iteration 2 : float data -- +float(10.5) + +-- Iteration 3 : null data -- +NULL + +-- Iteration 4 : bool data -- +bool(true) + +-- Iteration 5 : empty string data -- +string(0) "" + +-- Iteration 6 : empty array data -- +bool(false) + +-- Iteration 7 : string data -- +string(6) "string" + +-- Iteration 8 : object data -- +object(classA)#%d (0) { +} + +-- Iteration 9 : undefined data -- +NULL + +-- Iteration 10 : unset data -- +NULL + +-- Iteration 11 : resource data -- +resource(%d) of type (stream) diff --git a/tests/std/array/current_variation3.phpt b/tests/std/array/current_variation3.phpt new file mode 100644 index 00000000..cba2fa2a --- /dev/null +++ b/tests/std/array/current_variation3.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test current() function : usage variations - referenced variables +--FILE-- + +--EXPECT-- +*** Testing current() : usage variations *** + +-- Initial position of internal pointer -- +string(4) "zero" + +-- Position after calling next() -- +$array1: string(3) "one" +$array2: string(3) "one" diff --git a/tests/std/array/current_variation4.phpt b/tests/std/array/current_variation4.phpt new file mode 100644 index 00000000..8f24296f --- /dev/null +++ b/tests/std/array/current_variation4.phpt @@ -0,0 +1,63 @@ +--TEST-- +Test current() function : usage variations - multi-dimensional arrays +--FILE-- + +--EXPECT-- +*** Testing current() : usage variations *** + +-- Two Dimensional Array -- +Initial Position: string(4) "zero" +Next Position: array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} +End Position: string(3) "two" + +-- Access an Array Within an Array -- +Initial Position: int(1) + +-- Recursive, Multidimensional Array -- +Current Position: string(3) "two" +string(3) "two" +int(1) diff --git a/tests/std/array/current_variation5.phpt b/tests/std/array/current_variation5.phpt new file mode 100644 index 00000000..c5ef89b7 --- /dev/null +++ b/tests/std/array/current_variation5.phpt @@ -0,0 +1,43 @@ +--TEST-- +Test current() function : usage variations - reference & normal parameters +--FILE-- + +--EXPECT-- +*** Testing current() : usage variations *** + +-- Function: reference parameter -- +string(3) "yes" +string(5) "maybe" +string(5) "maybe" +string(2) "no" + +-- Function: normal parameter -- +string(3) "yes" +string(5) "maybe" +string(5) "maybe" +string(2) "no" diff --git a/tests/std/array/current_variation6.phpt b/tests/std/array/current_variation6.phpt new file mode 100644 index 00000000..d7fb0dcc --- /dev/null +++ b/tests/std/array/current_variation6.phpt @@ -0,0 +1,20 @@ +--TEST-- +Test current() function : internal pointer maintenance at the end of array +--FILE-- + 1, "bar" => 2, "baz" => 3]; +reset($array); +while ($cur = current($array)) { + var_dump($cur); + next($array); +} + +unset($array["baz"]); +$array[] = 4; +var_dump(current($array)); +?> +--EXPECT-- +int(1) +int(2) +int(3) +int(4) diff --git a/tests/std/array/data.inc b/tests/std/array/data.inc new file mode 100644 index 00000000..c8ad4fe2 --- /dev/null +++ b/tests/std/array/data.inc @@ -0,0 +1,13 @@ +'PHP: Hypertext Preprocessor', + 5=>'Test', + 'test'=>27, + 1000=>'test', + "-1000"=>array('banana', 'orange'), + 'monkey', + $tmp=>-1/3 +); +?> diff --git a/tests/std/array/end.phpt b/tests/std/array/end.phpt new file mode 100644 index 00000000..5876ed2f --- /dev/null +++ b/tests/std/array/end.phpt @@ -0,0 +1,177 @@ +--TEST-- +Test end() function +--SKIPIF-- + +--INI-- +precision=14 +--FILE-- + "A", 2 => "B", "C" => 3, 4 => 4, "one" => 1, "" => NULL), array(1, array(1, 2 => 3), "one" => 1, "5" => 5), array(-1, -2, -3, -4, "-0.005" => "neg0.005", 2.0 => "float2", "neg.9" => -0.9), array(1.0005, 2.0, -3.0, -4.9999999), array(true, false), array("PHP", "Web2.0", "SOA"), array(1, array()), array(1, 2, ""), array(" "), array(2147483647, 2147483648, -2147483647, -2147483648), array(0x7fffffff, -0x80000000, 017777777777, -020000000000), array(-670.0, -4100.03, 1.0E-5, -100000.0, 2.0)); + /* loop through $arrays to print the last element of each sub-array */ + echo "*** Testing end() on different arrays ***\n"; + $counter = 1; + foreach ($arrays as $sub_array) { + echo "-- Iteration {$counter} --\n"; + var_dump(end($sub_array)); + /* ensure that internal pointer is moved to last element */ + var_dump(current($sub_array)); + $counter++; + } + /* checking for end() on sub-arrays */ + echo "\n*** Testing end() with sub-arrays ***\n"; + $test_array = array(1, array(1 => "one", "two" => 2, "" => "f")); + var_dump(end($test_array)); + var_dump(end($test_array[1])); + /* checking working of end() when array elements are deleted */ + echo "\n*** Testing end() when array elements are deleted ***\n"; + $array_test = array("a", "b", "d", 7, "u" => "U", -4, "-.008" => "neg.008"); + // remove first element from array + echo "\n-- Remove first element from array --\n"; + unset($array_test[0]); + var_dump(end($array_test)); + // remove last element from array, rewind and check end() + echo "\n-- Remove last element from array --\n"; + unset($array_test['-.008']); + var_dump(end($array_test)); + reset($array_test); + var_dump(end($array_test)); + // remove any element !first, !last, rewind and check end() + echo "\n-- Remove any element from array apart from first and last element --\n"; + unset($array_test[7]); + var_dump(end($array_test)); + var_dump(reset($array_test)); + var_dump(end($array_test)); + /* Checking on OBJECTS type */ + echo "\n*** Testing end() on objects ***\n"; + $object1 = new foo(); + //new object created + $object2 = new foo1(); + $array_object = array(); + $array_object[0] =& $object1; + $array_object[1] =& $object2; + var_dump(end($array_object)); + var_dump($array_object); + /* Checking on RESOURCE type */ + echo "\n*** Testing end() on resource type ***\n"; + //file type resource + $file_handle = fopen(__FILE__, "r"); + //directory type resource + $dir_handle = opendir(__DIR__); + //store resources in array + $resources = array($file_handle, $dir_handle); + var_dump(end($resources)); + var_dump(current($resources)); + echo "Done\n"; + /* cleaning resource handles */ + fclose($file_handle); + //file resource handle deleted + closedir($dir_handle); +} +?> +--EXPECTF-- +*** Testing end() on different arrays *** +-- Iteration 1 -- +int(0) +int(0) +-- Iteration 2 -- +int(100) +int(100) +-- Iteration 3 -- +string(1) "y" +string(1) "y" +-- Iteration 4 -- +NULL +NULL +-- Iteration 5 -- +int(5) +int(5) +-- Iteration 6 -- +float(-0.9) +float(-0.9) +-- Iteration 7 -- +float(-4.9999999) +float(-4.9999999) +-- Iteration 8 -- +bool(false) +bool(false) +-- Iteration 9 -- +string(3) "SOA" +string(3) "SOA" +-- Iteration 10 -- +array(0) { +} +array(0) { +} +-- Iteration 11 -- +string(0) "" +string(0) "" +-- Iteration 12 -- +string(1) " " +string(1) " " +-- Iteration 13 -- +float(-2147483648) +float(-2147483648) +-- Iteration 14 -- +float(-2147483648) +float(-2147483648) +-- Iteration 15 -- +float(2) +float(2) + +*** Testing end() with sub-arrays *** +array(3) { + [1]=> + string(3) "one" + ["two"]=> + int(2) + [""]=> + string(1) "f" +} +string(1) "f" + +*** Testing end() when array elements are deleted *** + +-- Remove first element from array -- +string(7) "neg.008" + +-- Remove last element from array -- +int(-4) +int(-4) + +-- Remove any element from array apart from first and last element -- +int(-4) +string(1) "b" +int(-4) + +*** Testing end() on objects *** +object(foo1)#%d (0) { +} +array(2) { + [0]=> + &object(foo)#%d (0) { + } + [1]=> + &object(foo1)#%d (0) { + } +} + +*** Testing end() on resource type *** +resource(%d) of type (stream) +resource(%d) of type (stream) +Done diff --git a/tests/std/array/end_64bit.phpt b/tests/std/array/end_64bit.phpt new file mode 100644 index 00000000..33383ef5 --- /dev/null +++ b/tests/std/array/end_64bit.phpt @@ -0,0 +1,173 @@ +--TEST-- +Test end() function +--SKIPIF-- + +--INI-- +precision=14 +--FILE-- + "A", 2 => "B", "C" => 3, 4 => 4, "one" => 1, "" => NULL), array(1, array(1, 2 => 3), "one" => 1, "5" => 5), array(-1, -2, -3, -4, "-0.005" => "neg0.005", 2 => "float2", "neg.9" => -0.9), array(1.0005, 2.0, -3.0, -4.9999999), array(true, false), array("PHP", "Web2.0", "SOA"), array(1, array()), array(1, 2, ""), array(" "), array(2147483647, 2147483648, -2147483647, -2147483648), array(0x7fffffff, -0x80000000, 017777777777, -020000000000), array(-670.0, -4100.03, 1.0E-5, -100000.0, 2.0)); + /* loop through $arrays to print the last element of each sub-array */ + echo "*** Testing end() on different arrays ***\n"; + $counter = 1; + foreach ($arrays as $sub_array) { + echo "-- Iteration {$counter} --\n"; + var_dump(end($sub_array)); + /* ensure that internal pointer is moved to last element */ + var_dump(current($sub_array)); + $counter++; + } + /* checking for end() on sub-arrays */ + echo "\n*** Testing end() with sub-arrays ***\n"; + $test_array = array(1, array(1 => "one", "two" => 2, "" => "f")); + var_dump(end($test_array)); + var_dump(end($test_array[1])); + /* checking working of end() when array elements are deleted */ + echo "\n*** Testing end() when array elements are deleted ***\n"; + $array_test = array("a", "b", "d", 7, "u" => "U", -4, "-.008" => "neg.008"); + // remove first element from array + echo "\n-- Remove first element from array --\n"; + unset($array_test[0]); + var_dump(end($array_test)); + // remove last element from array, rewind and check end() + echo "\n-- Remove last element from array --\n"; + unset($array_test['-.008']); + var_dump(end($array_test)); + reset($array_test); + var_dump(end($array_test)); + // remove any element !first, !last, rewind and check end() + echo "\n-- Remove any element from array apart from first and last element --\n"; + unset($array_test[7]); + var_dump(end($array_test)); + var_dump(reset($array_test)); + var_dump(end($array_test)); + /* Checking on OBJECTS type */ + echo "\n*** Testing end() on objects ***\n"; + $object1 = new foo(); + //new object created + $object2 = new foo1(); + $array_object = array(); + $array_object[0] =& $object1; + $array_object[1] =& $object2; + var_dump(end($array_object)); + var_dump($array_object); + /* Checking on RESOURCE type */ + echo "\n*** Testing end() on resource type ***\n"; + //file type resource + $file_handle = fopen(__FILE__, "r"); + //directory type resource + $dir_handle = opendir(__DIR__); + //store resources in array + $resources = array($file_handle, $dir_handle); + var_dump(end($resources)); + var_dump(current($resources)); + echo "Done\n"; +} +?> +--EXPECTF-- +*** Testing end() on different arrays *** +-- Iteration 1 -- +int(0) +int(0) +-- Iteration 2 -- +int(100) +int(100) +-- Iteration 3 -- +string(1) "y" +string(1) "y" +-- Iteration 4 -- +NULL +NULL +-- Iteration 5 -- +int(5) +int(5) +-- Iteration 6 -- +float(-0.9) +float(-0.9) +-- Iteration 7 -- +float(-4.9999999) +float(-4.9999999) +-- Iteration 8 -- +bool(false) +bool(false) +-- Iteration 9 -- +string(3) "SOA" +string(3) "SOA" +-- Iteration 10 -- +array(0) { +} +array(0) { +} +-- Iteration 11 -- +string(0) "" +string(0) "" +-- Iteration 12 -- +string(1) " " +string(1) " " +-- Iteration 13 -- +int(-2147483648) +int(-2147483648) +-- Iteration 14 -- +int(-2147483648) +int(-2147483648) +-- Iteration 15 -- +float(2) +float(2) + +*** Testing end() with sub-arrays *** +array(3) { + [1]=> + string(3) "one" + ["two"]=> + int(2) + [""]=> + string(1) "f" +} +string(1) "f" + +*** Testing end() when array elements are deleted *** + +-- Remove first element from array -- +string(7) "neg.008" + +-- Remove last element from array -- +int(-4) +int(-4) + +-- Remove any element from array apart from first and last element -- +int(-4) +string(1) "b" +int(-4) + +*** Testing end() on objects *** +object(foo1)#%d (0) { +} +array(2) { + [0]=> + &object(foo)#%d (0) { + } + [1]=> + &object(foo1)#%d (0) { + } +} + +*** Testing end() on resource type *** +resource(%d) of type (stream) +resource(%d) of type (stream) +Done diff --git a/tests/std/array/end_basic.phpt b/tests/std/array/end_basic.phpt new file mode 100644 index 00000000..04c49e1c --- /dev/null +++ b/tests/std/array/end_basic.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test end() function : basic functionality +--FILE-- + 'two'); + +echo "\n-- Initial Position: --\n"; +echo key($array) . " => " . current($array) . "\n"; + +echo "\n-- Call to end() --\n"; +var_dump(end($array)); + +echo "\n-- Current Position: --\n"; +echo key($array) . " => " . current($array) . "\n"; + +echo "\n-- Add a new element to array --\n"; +$array[2] = 'foo'; +var_dump(end($array)); +?> +--EXPECT-- +*** Testing end() : basic functionality *** + +-- Initial Position: -- +0 => zero + +-- Call to end() -- +string(3) "two" + +-- Current Position: -- +200 => two + +-- Add a new element to array -- +string(3) "foo" diff --git a/tests/std/array/end_variation2.phpt b/tests/std/array/end_variation2.phpt new file mode 100644 index 00000000..3bf399a4 --- /dev/null +++ b/tests/std/array/end_variation2.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test end() function : usage variations - Multi-dimensional arrays +--FILE-- + 'z', array(9, 8, 7)); + +echo "\n-- Pass a two-dimensional array as \$array_arg --\n"; +var_dump(end($array_arg)); + +echo "\n-- Pass a sub-array as \$array_arg --\n"; +var_dump(end($array_arg[0])); +?> +--EXPECT-- +*** Testing end() : usage variations *** + +-- Pass a two-dimensional array as $array_arg -- +array(3) { + [0]=> + int(9) + [1]=> + int(8) + [2]=> + int(7) +} + +-- Pass a sub-array as $array_arg -- +int(7) diff --git a/tests/std/array/end_variation3.phpt b/tests/std/array/end_variation3.phpt new file mode 100644 index 00000000..8d2b78ab --- /dev/null +++ b/tests/std/array/end_variation3.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test end() function : usage variations - Referenced variables +--FILE-- + +--EXPECT-- +*** Testing end() : usage variations *** + +-- Initial position of internal pointer -- +string(4) "zero" + +-- Position after calling end() -- +$array1: string(3) "two" +$array2: string(3) "two" diff --git a/tests/std/array/extract_error.phpt b/tests/std/array/extract_error.phpt new file mode 100644 index 00000000..594f158d --- /dev/null +++ b/tests/std/array/extract_error.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test extract() function (error conditions) +--SKIPIF-- + + +--FILE-- +getMessage() . "\n"; +} + +try { + var_dump( extract($arr, 7 , "wddr") ); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +/* Two Arguments, second as prefix but without prefix string as third argument */ +try { + var_dump( extract($arr,EXTR_PREFIX_IF_EXISTS) ); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +?> +--EXPECT-- +*** Testing Error Conditions *** +extract(): Argument #2 ($flags) must be a valid extract type +extract(): Argument #2 ($flags) must be a valid extract type +extract(): Argument #3 ($prefix) is required when using this extract type diff --git a/tests/std/array/extract_error_variation1.phpt b/tests/std/array/extract_error_variation1.phpt new file mode 100644 index 00000000..224f31a6 --- /dev/null +++ b/tests/std/array/extract_error_variation1.phpt @@ -0,0 +1,19 @@ +--TEST-- +Test extract() function - error condition - Invalid prefix. +--SKIPIF-- + + +--FILE-- + "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five"]; + +try { + extract($a, EXTR_PREFIX_ALL, '85bogus'); +} catch (\ValueError $e) { + echo $e->getMessage(); +} +?> +--EXPECT-- +extract(): Argument #3 ($prefix) must be a valid identifier diff --git a/tests/std/array/extract_safety.phpt b/tests/std/array/extract_safety.phpt new file mode 100644 index 00000000..12e9ef5a --- /dev/null +++ b/tests/std/array/extract_safety.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test extract() for overwrite of GLOBALS +--SKIPIF-- + + +--FILE-- + "bar"); +var_dump(extract(array("GLOBALS" => $splat, EXTR_OVERWRITE))); + +unset ($splat); + +var_dump($GLOBALS["str"]); + +echo "\nDone"; +?> +--EXPECT-- +string(4) "John" +int(1) +string(4) "John" + +Done diff --git a/tests/std/array/extract_typed_ref.phpt b/tests/std/array/extract_typed_ref.phpt new file mode 100644 index 00000000..9f9b1544 --- /dev/null +++ b/tests/std/array/extract_typed_ref.phpt @@ -0,0 +1,31 @@ +--TEST-- +extract() into typed references must respect their type +--SKIPIF-- + + +--FILE-- +i; + $s =& $test->s; + try { + extract(['i' => 'foo', 's' => 42]); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + var_dump($test->i, $test->s); +} +?> +--EXPECT-- +Cannot assign string to reference held by property Test::$i of type int +int(0) +string(0) "" diff --git a/tests/std/array/extract_variation1.phpt b/tests/std/array/extract_variation1.phpt new file mode 100644 index 00000000..c37a5128 --- /dev/null +++ b/tests/std/array/extract_variation1.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test extract() function (variation 1) +--SKIPIF-- + + +--FILE-- + +--EXPECTF-- +int(4) +string(4) "John" +int(%d) +int(4) +string(4) "John" + +Done diff --git a/tests/std/array/extract_variation10.phpt b/tests/std/array/extract_variation10.phpt new file mode 100644 index 00000000..2e6c0c9d --- /dev/null +++ b/tests/std/array/extract_variation10.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test extract() function - ensure EXTR_REFS doesn't mess with isRef flag on COW references to array elements. +--SKIPIF-- + + +--FILE-- + 'original.foo'); +$nonref = $a['foo']; +$ref = &$a; +extract($a, EXTR_REFS); +$a['foo'] = 'changed.foo'; +var_dump($nonref); +?> +--EXPECT-- +string(12) "original.foo" diff --git a/tests/std/array/extract_variation11.phpt b/tests/std/array/extract_variation11.phpt new file mode 100644 index 00000000..208ded28 --- /dev/null +++ b/tests/std/array/extract_variation11.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test extract() function - ensure EXTR_REFS works when array is referenced and keys clash with variables in current scope. +--SKIPIF-- + + +--FILE-- + 'original.foo'); +$ref = &$a; +$foo = 'test'; +extract($a, EXTR_OVERWRITE|EXTR_REFS); +$foo = 'changed.foo'; +var_dump($a['foo']); +?> +--EXPECT-- +string(11) "changed.foo" diff --git a/tests/std/array/extract_variation2.phpt b/tests/std/array/extract_variation2.phpt new file mode 100644 index 00000000..657dc78b --- /dev/null +++ b/tests/std/array/extract_variation2.phpt @@ -0,0 +1,74 @@ +--TEST-- +Test extract() function (variation 2) +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +-- Iteration 0 -- +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) +int(0) + +-- Iteration 1 -- +int(0) +int(0) +int(0) +int(0) +int(9) +int(0) +int(9) +int(9) +int(0) + +-- Iteration 2 -- +int(0) +int(0) +int(0) +int(0) +int(5) +int(0) +int(5) +int(5) +int(0) +Done diff --git a/tests/std/array/extract_variation3.phpt b/tests/std/array/extract_variation3.phpt new file mode 100644 index 00000000..cce0da67 --- /dev/null +++ b/tests/std/array/extract_variation3.phpt @@ -0,0 +1,74 @@ +--TEST-- +Test extract() function (variation 3) +--SKIPIF-- + + +--FILE-- + "aaa", "A" => "AAA", "c" => "ccc", "d" => "ddd", "e" => "eee" ), + array( "1" => "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ), +); + +$counter = 0; + +foreach ( $mixed_array as $sub_array ) { + echo "\n-- Iteration $counter --\n"; + $counter++; + + var_dump ( extract($sub_array)); /* Single Argument */ + + /* variations of two arguments */ + var_dump ( extract($sub_array, EXTR_OVERWRITE)); + var_dump ( extract($sub_array, EXTR_SKIP)); + var_dump ( extract($sub_array, EXTR_IF_EXISTS)); + + /* variations of three arguments with use of various extract types*/ + var_dump ( extract($sub_array, EXTR_PREFIX_INVALID, "ssd")); + var_dump ( extract($sub_array, EXTR_PREFIX_SAME, "sss")); + var_dump ( extract($sub_array, EXTR_PREFIX_ALL, "bb")); + var_dump ( extract($sub_array, EXTR_PREFIX_ALL, "")); // "_" taken as default prefix + var_dump ( extract($sub_array, EXTR_PREFIX_IF_EXISTS, "bb")); +} + +echo "Done\n"; +?> +--EXPECT-- +-- Iteration 0 -- +int(0) +int(0) +int(0) +int(0) +int(8) +int(0) +int(8) +int(8) +int(0) + +-- Iteration 1 -- +int(5) +int(5) +int(0) +int(5) +int(5) +int(5) +int(5) +int(5) +int(5) + +-- Iteration 2 -- +int(0) +int(0) +int(0) +int(0) +int(5) +int(0) +int(5) +int(5) +int(0) +Done diff --git a/tests/std/array/extract_variation4.phpt b/tests/std/array/extract_variation4.phpt new file mode 100644 index 00000000..343b681e --- /dev/null +++ b/tests/std/array/extract_variation4.phpt @@ -0,0 +1,74 @@ +--TEST-- +Test extract() function (variation 4) +--SKIPIF-- + + +--FILE-- + "one", 2 => "two", 3 => 7, 4 => "four", 5 => "five" ), + array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ), + array( 12, "name", 'age', '45' ), +); + +$counter = 0; + +foreach ( $mixed_array as $sub_array ) { + echo "\n-- Iteration $counter --\n"; + $counter++; + + var_dump ( extract($sub_array)); /* Single Argument */ + + /* variations of two arguments */ + var_dump ( extract($sub_array, EXTR_OVERWRITE)); + var_dump ( extract($sub_array, EXTR_SKIP)); + var_dump ( extract($sub_array, EXTR_IF_EXISTS)); + + /* variations of three arguments with use of various extract types*/ + var_dump ( extract($sub_array, EXTR_PREFIX_INVALID, "ssd")); + var_dump ( extract($sub_array, EXTR_PREFIX_SAME, "sss")); + var_dump ( extract($sub_array, EXTR_PREFIX_ALL, "bb")); + var_dump ( extract($sub_array, EXTR_PREFIX_ALL, "")); // "_" taken as default prefix + var_dump ( extract($sub_array, EXTR_PREFIX_IF_EXISTS, "bb")); +} + +echo "Done\n"; +?> +--EXPECT-- +-- Iteration 0 -- +int(0) +int(0) +int(0) +int(0) +int(5) +int(0) +int(5) +int(5) +int(0) + +-- Iteration 1 -- +int(4) +int(4) +int(0) +int(4) +int(12) +int(4) +int(11) +int(11) +int(4) + +-- Iteration 2 -- +int(0) +int(0) +int(0) +int(0) +int(4) +int(0) +int(4) +int(4) +int(0) +Done diff --git a/tests/std/array/extract_variation5.phpt b/tests/std/array/extract_variation5.phpt new file mode 100644 index 00000000..edc3ad5e --- /dev/null +++ b/tests/std/array/extract_variation5.phpt @@ -0,0 +1,62 @@ +--TEST-- +Test extract() function (variation 5) +--SKIPIF-- + + +--FILE-- + 1, "one" => 2, "three" => 3, 3, 4, 3 => 33, 4 => 44, 5, 6, + 5 => 57, "5.4" => 554, "5.7" => 557 ) +); + +$counter = 0; + +foreach ( $mixed_array as $sub_array ) { + echo "\n-- Iteration $counter --\n"; + $counter++; + + var_dump ( extract($sub_array)); /* Single Argument */ + + /* variations of two arguments */ + var_dump ( extract($sub_array, EXTR_OVERWRITE)); + var_dump ( extract($sub_array, EXTR_SKIP)); + var_dump ( extract($sub_array, EXTR_IF_EXISTS)); + + /* variations of three arguments with use of various extract types*/ + var_dump ( extract($sub_array, EXTR_PREFIX_INVALID, "ssd")); + var_dump ( extract($sub_array, EXTR_PREFIX_SAME, "sss")); + var_dump ( extract($sub_array, EXTR_PREFIX_ALL, "bb")); + var_dump ( extract($sub_array, EXTR_PREFIX_ALL, "")); // "_" taken as default prefix + var_dump ( extract($sub_array, EXTR_PREFIX_IF_EXISTS, "bb")); +} + +echo "Done\n"; +?> +--EXPECT-- +-- Iteration 0 -- +int(0) +int(0) +int(0) +int(0) +int(3) +int(0) +int(3) +int(3) +int(0) + +-- Iteration 1 -- +int(2) +int(2) +int(0) +int(2) +int(8) +int(2) +int(8) +int(8) +int(2) +Done diff --git a/tests/std/array/extract_variation6.phpt b/tests/std/array/extract_variation6.phpt new file mode 100644 index 00000000..21648f23 --- /dev/null +++ b/tests/std/array/extract_variation6.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test extract() function (variation 6) +--SKIPIF-- + + +--FILE-- + 'aaa'); +var_dump ( extract($a, EXTR_REFS)); +var_dump($foo); + +$b = $a; +$b['foo'] = 'bbb'; +var_dump ( extract($a, EXTR_REFS)); +var_dump($foo); +var_dump($a); + +echo "Done\n"; +?> +--EXPECT-- +int(1) +string(3) "aaa" +int(1) +string(3) "bbb" +array(1) { + ["foo"]=> + &string(3) "bbb" +} +Done diff --git a/tests/std/array/extract_variation7.phpt b/tests/std/array/extract_variation7.phpt new file mode 100644 index 00000000..e37de2b7 --- /dev/null +++ b/tests/std/array/extract_variation7.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test extract() function (variation 7) +--SKIPIF-- + + +--FILE-- + "one", "2" => "two", "3" => "three", "4" => "four", "5" => "five" ); +var_dump ( extract($a, EXTR_PREFIX_ALL, "same")); + +$b = array( "f" => "fff", "1" => "one", 4 => 6, "" => "blank", 2 => "float", "F" => "FFF", + "blank" => "", 3 => 3.7, 5 => 7, 6 => 8.6, '5' => "Five", "4name" => "jonny", "a" => NULL, NULL => 3 ); +var_dump ( extract($b, EXTR_PREFIX_ALL, "same")); +var_dump ( extract($b, EXTR_PREFIX_ALL, "diff")); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing for EXTR_PREFIX_ALL called twice with same prefix string *** +int(5) +int(11) +int(11) +Done diff --git a/tests/std/array/extract_variation8.phpt b/tests/std/array/extract_variation8.phpt new file mode 100644 index 00000000..2a5b33db --- /dev/null +++ b/tests/std/array/extract_variation8.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test extract() function (variation 8) +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +*** Testing for Numerical prefixes *** +int(3) +int(1) + +Done diff --git a/tests/std/array/extract_variation9.phpt b/tests/std/array/extract_variation9.phpt new file mode 100644 index 00000000..ca847552 --- /dev/null +++ b/tests/std/array/extract_variation9.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test extract() function (variation 9) +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +*** Testing for object *** +int(1) +Done diff --git a/tests/std/array/gh14140.phpt b/tests/std/array/gh14140.phpt new file mode 100644 index 00000000..ffba9617 --- /dev/null +++ b/tests/std/array/gh14140.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-14140: Floating point bug in range operation on Apple Silicon hardware +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Array +( + [0] => -0.03 + [1] => -0.02 + [2] => -0.01 + [3] => 0 + [4] => 0.01 + [5] => 0.02 + [6] => 0.03 +) diff --git a/tests/std/array/gh14775.phpt b/tests/std/array/gh14775.phpt new file mode 100644 index 00000000..9902d7f6 --- /dev/null +++ b/tests/std/array/gh14775.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-14775: Range negative step overflow +--SKIPIF-- + + +--FILE-- +getMessage() . PHP_EOL; +} +--EXPECTF-- +range(): Argument #3 ($step) must be greater than %s diff --git a/tests/std/array/gh15982.phpt b/tests/std/array/gh15982.phpt new file mode 100644 index 00000000..2eb9eceb --- /dev/null +++ b/tests/std/array/gh15982.phpt @@ -0,0 +1,11 @@ +--TEST-- +GH-15982 (Assertion failure with array_find when references are involved) +--FILE-- + true)); +?> +--EXPECT-- +string(5) "hello" diff --git a/tests/std/array/gh16053.phpt b/tests/std/array/gh16053.phpt new file mode 100644 index 00000000..c290078e --- /dev/null +++ b/tests/std/array/gh16053.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-16053: Assertion failure in Zend/zend_hash.c +--FILE-- + $x); + $arr2 = array("string" => "hello"); + var_dump($arr1); + var_dump(array_merge_recursive($arr1, $arr2)); +} +?> +--EXPECTF-- +array(1) { + ["string"]=> + object(test)#%d (0) { + } +} +array(1) { + ["string"]=> + array(1) { + [0]=> + string(5) "hello" + } +} diff --git a/tests/std/array/gh16649/array_splice_normal_destructor.phpt b/tests/std/array/gh16649/array_splice_normal_destructor.phpt new file mode 100644 index 00000000..882ad1d9 --- /dev/null +++ b/tests/std/array/gh16649/array_splice_normal_destructor.phpt @@ -0,0 +1,22 @@ +--TEST-- +GH-16649: array_splice with normal destructor should work fine +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Destructor called +array(1) { + [0]=> + string(1) "1" +} diff --git a/tests/std/array/gh16649/array_splice_uaf_add_elements.phpt b/tests/std/array/gh16649/array_splice_uaf_add_elements.phpt new file mode 100644 index 00000000..66aa5c4f --- /dev/null +++ b/tests/std/array/gh16649/array_splice_uaf_add_elements.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-16649: array_splice UAF when destructor adds elements to array +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/tests/std/array/gh16649/array_splice_uaf_array_deallocated.phpt b/tests/std/array/gh16649/array_splice_uaf_array_deallocated.phpt new file mode 100644 index 00000000..85133e23 --- /dev/null +++ b/tests/std/array/gh16649/array_splice_uaf_array_deallocated.phpt @@ -0,0 +1,24 @@ +--TEST-- +GH-16649: array_splice UAF when array is released entirely +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/tests/std/array/gh16649/array_splice_uaf_complex_modification.phpt b/tests/std/array/gh16649/array_splice_uaf_complex_modification.phpt new file mode 100644 index 00000000..f6e64ca3 --- /dev/null +++ b/tests/std/array/gh16649/array_splice_uaf_complex_modification.phpt @@ -0,0 +1,27 @@ +--TEST-- +GH-16649: array_splice UAF with complex array modification +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/tests/std/array/gh16649/array_splice_uaf_multiple_destructors.phpt b/tests/std/array/gh16649/array_splice_uaf_multiple_destructors.phpt new file mode 100644 index 00000000..c39ef6d0 --- /dev/null +++ b/tests/std/array/gh16649/array_splice_uaf_multiple_destructors.phpt @@ -0,0 +1,35 @@ +--TEST-- +GH-16649: array_splice UAF with multiple destructors +--SKIPIF-- + +--FILE-- +id = $id; + } + + function __destruct() { + global $arr; + echo "Destructor {$this->id} called\n"; + if ($this->id == 2) { + $arr = null; + } + } +} + +$arr = ["start", new MultiDestructor(1), new MultiDestructor(2), "end"]; + +try { + array_splice($arr, 1, 2); + echo "ERROR: Should have thrown exception\n"; +} catch (Error $e) { + echo "Exception caught: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Destructor 1 called +Destructor 2 called +Exception caught: Array was modified during array_splice operation diff --git a/tests/std/array/gh16649/array_splice_uaf_original_case.phpt b/tests/std/array/gh16649/array_splice_uaf_original_case.phpt new file mode 100644 index 00000000..e4357414 --- /dev/null +++ b/tests/std/array/gh16649/array_splice_uaf_original_case.phpt @@ -0,0 +1,31 @@ +--TEST-- +GH-16649: array_splice UAF with destructor modifying array (original case) +--SKIPIF-- + +--FILE-- + "1", "3" => new C, "2" => "2"]; + +try { + array_splice($arr, 1, 2); + echo "ERROR: Should have thrown exception\n"; +} catch (Error $e) { + echo "Exception caught: " . $e->getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/tests/std/array/gh16649/array_splice_uaf_packed_to_hash.phpt b/tests/std/array/gh16649/array_splice_uaf_packed_to_hash.phpt new file mode 100644 index 00000000..13dd56a9 --- /dev/null +++ b/tests/std/array/gh16649/array_splice_uaf_packed_to_hash.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-16649: array_splice UAF when array is converted from packed to hash +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/tests/std/array/gh16649/array_splice_with_replacement.phpt b/tests/std/array/gh16649/array_splice_with_replacement.phpt new file mode 100644 index 00000000..f06932dc --- /dev/null +++ b/tests/std/array/gh16649/array_splice_with_replacement.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-16649: array_splice with replacement array when destructor modifies array +--SKIPIF-- + +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +Exception caught: Array was modified during array_splice operation diff --git a/tests/std/array/gh16905.phpt b/tests/std/array/gh16905.phpt new file mode 100644 index 00000000..d3a64ddb --- /dev/null +++ b/tests/std/array/gh16905.phpt @@ -0,0 +1,89 @@ +--TEST-- +GH-16905 (Internal iterator functions can't handle UNDEF properties) +--SKIPIF-- + +--FILE-- +b = 1; + $x->c = 2; + var_dump(reset($x)); + var_dump(current($x)); + var_dump(end($x)); + var_dump(reset($x)); + var_dump(next($x)); + var_dump(end($x)); + var_dump(prev($x)); + var_dump(key($x)); + var_dump(current($x)); + $x2 = new TestAllUndef(); + var_dump(key($x2)); + var_dump(current($x2)); + $x2->a = 1; + var_dump(key($x2)); + var_dump(current($x2)); + reset($x2); + var_dump(key($x2)); + var_dump(current($x2)); +} +?> +--EXPECTF-- +Deprecated: reset(): Calling reset() on an object is deprecated in %s on line %d +int(1) + +Deprecated: current(): Calling current() on an object is deprecated in %s on line %d +int(1) + +Deprecated: end(): Calling end() on an object is deprecated in %s on line %d +int(2) + +Deprecated: reset(): Calling reset() on an object is deprecated in %s on line %d +int(1) + +Deprecated: next(): Calling next() on an object is deprecated in %s on line %d +int(2) + +Deprecated: end(): Calling end() on an object is deprecated in %s on line %d +int(2) + +Deprecated: prev(): Calling prev() on an object is deprecated in %s on line %d +int(1) + +Deprecated: key(): Calling key() on an object is deprecated in %s on line %d +string(1) "b" + +Deprecated: current(): Calling current() on an object is deprecated in %s on line %d +int(1) + +Deprecated: key(): Calling key() on an object is deprecated in %s on line %d +NULL + +Deprecated: current(): Calling current() on an object is deprecated in %s on line %d +bool(false) + +Deprecated: key(): Calling key() on an object is deprecated in %s on line %d +NULL + +Deprecated: current(): Calling current() on an object is deprecated in %s on line %d +bool(false) + +Deprecated: reset(): Calling reset() on an object is deprecated in %s on line %d + +Deprecated: key(): Calling key() on an object is deprecated in %s on line %d +string(1) "a" + +Deprecated: current(): Calling current() on an object is deprecated in %s on line %d +int(1) diff --git a/tests/std/array/gh16957.phpt b/tests/std/array/gh16957.phpt new file mode 100644 index 00000000..74094906 --- /dev/null +++ b/tests/std/array/gh16957.phpt @@ -0,0 +1,43 @@ +--TEST-- +GH-16957 (Assertion failure in array_shift with self-referencing array) +--SKIPIF-- + +--FILE-- + 1, 300 => 'two'); +var_dump($shifted = array_shift($new_array2)); +var_dump($new_array2); +var_dump($new_array2 === $shifted); +?> +--EXPECT-- +array(2) { + [0]=> + int(1) + [1]=> + string(3) "two" +} +array(2) { + [0]=> + int(1) + [1]=> + string(3) "two" +} +bool(true) +array(2) { + [0]=> + int(1) + [1]=> + string(3) "two" +} +array(2) { + [0]=> + int(1) + [1]=> + string(3) "two" +} +bool(true) diff --git a/tests/std/array/gh17447.phpt b/tests/std/array/gh17447.phpt new file mode 100644 index 00000000..e107efbd --- /dev/null +++ b/tests/std/array/gh17447.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-17447 (Assertion failure when array poping a self addressing variable) +--FILE-- + +--EXPECT-- +array(0) { +} +array(0) { +} diff --git a/tests/std/array/gh17977.phpt b/tests/std/array/gh17977.phpt new file mode 100644 index 00000000..4a4f344d --- /dev/null +++ b/tests/std/array/gh17977.phpt @@ -0,0 +1,18 @@ +--TEST-- +array_any() / array_all() leak +--DESCRIPTION-- +Found in GH-16831#issuecomment-2700410631 +--FILE-- + 1], static fn () => true)); +var_dump(array_all([$key => 1], static fn () => false)); + +?> +--EXPECT-- +bool(true) +bool(false) diff --git a/tests/std/array/gh18480.phpt b/tests/std/array/gh18480.phpt new file mode 100644 index 00000000..21571de2 --- /dev/null +++ b/tests/std/array/gh18480.phpt @@ -0,0 +1,45 @@ +--TEST-- +GH-18480 (array_splice overflow with large offset / length values) +--SKIPIF-- + + +--FILE-- + PHP_INT_MAX]; + $offset = PHP_INT_MAX; + var_dump(array_splice($a,$offset, $length)); + $a = ["a" => PHP_INT_MAX]; + $offset = PHP_INT_MIN; + var_dump(array_splice($a,$offset, $length)); +} +--EXPECTF-- +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(1) { + [0]=> + int(%d) +} +array(0) { +} +array(1) { + ["a"]=> + int(%d) +} diff --git a/tests/std/array/gh19300_1.phpt b/tests/std/array/gh19300_1.phpt new file mode 100644 index 00000000..a7182257 --- /dev/null +++ b/tests/std/array/gh19300_1.phpt @@ -0,0 +1,42 @@ +--TEST-- +GH-19300 (Nested array_multisort invocation with error breaks) - correct invocation variation +--SKIPIF-- +--FILE-- +data; + } +} +function main() +{ + $inputs = [new MyStringable('3'), new MyStringable('1'), new MyStringable('2')]; + var_dump(array_multisort($inputs, SORT_STRING)); + var_dump($inputs); +} +?> +--EXPECT-- +bool(true) +array(3) { + [0]=> + object(MyStringable)#2 (1) { + ["data":"MyStringable":private]=> + string(1) "1" + } + [1]=> + object(MyStringable)#3 (1) { + ["data":"MyStringable":private]=> + string(1) "2" + } + [2]=> + object(MyStringable)#1 (1) { + ["data":"MyStringable":private]=> + string(1) "3" + } +} diff --git a/tests/std/array/gh19300_2.phpt b/tests/std/array/gh19300_2.phpt new file mode 100644 index 00000000..41a54f2e --- /dev/null +++ b/tests/std/array/gh19300_2.phpt @@ -0,0 +1,39 @@ +--TEST-- +GH-19300 (Nested array_multisort invocation with error breaks) - error variation +--SKIPIF-- +--FILE-- +getMessage(), "\n"; + } +} +function main() +{ + set_error_handler('error_handle'); + $inputs = [new stdClass(), new stdClass(), new stdClass()]; + var_dump(array_multisort($inputs, SORT_NUMERIC)); + var_dump($inputs); +} +?> +--EXPECT-- +array_multisort(): Argument #1 ($array) must be an array or a sort flag +array_multisort(): Argument #1 ($array) must be an array or a sort flag +array_multisort(): Argument #1 ($array) must be an array or a sort flag +array_multisort(): Argument #1 ($array) must be an array or a sort flag +bool(true) +array(3) { + [0]=> + object(stdClass)#1 (0) { + } + [1]=> + object(stdClass)#2 (0) { + } + [2]=> + object(stdClass)#3 (0) { + } +} diff --git a/tests/std/array/gh19926.phpt b/tests/std/array/gh19926.phpt new file mode 100644 index 00000000..ecff0cfa --- /dev/null +++ b/tests/std/array/gh19926.phpt @@ -0,0 +1,25 @@ +--TEST-- +GH-19926 (Assertion failure zend_hash_internal_pointer_reset_ex) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Exception caught, no assertion failure diff --git a/tests/std/array/gh19926_pointer.phpt b/tests/std/array/gh19926_pointer.phpt new file mode 100644 index 00000000..c134f3b5 --- /dev/null +++ b/tests/std/array/gh19926_pointer.phpt @@ -0,0 +1,19 @@ +--TEST-- +GH-19926 (internal pointer behavior after array_splice) +--FILE-- + +--EXPECT-- +Before array_splice: int(3) +After array_splice: int(999) diff --git a/tests/std/array/gh20043.phpt b/tests/std/array/gh20043.phpt new file mode 100644 index 00000000..d5c7e064 --- /dev/null +++ b/tests/std/array/gh20043.phpt @@ -0,0 +1,12 @@ +--TEST-- +GH-20043 (array_unique assertion failure with RC1 array causing an exception on sort) +--FILE-- +getMessage(); +} +?> +--EXPECT-- +Object of class stdClass could not be converted to string diff --git a/tests/std/array/gh9244.phpt b/tests/std/array/gh9244.phpt new file mode 100644 index 00000000..04c34d42 --- /dev/null +++ b/tests/std/array/gh9244.phpt @@ -0,0 +1,11 @@ +--TEST-- +Bug GH-9244 (Segfault with array_multisort + array_shift) +--FILE-- + 1, 'bar' => 2]; +$order = [4, 3]; +array_multisort($order, $items); +var_dump(array_shift($items)); +?> +--EXPECT-- +int(2) diff --git a/tests/std/array/gh9296.phpt b/tests/std/array/gh9296.phpt new file mode 100644 index 00000000..cfbc5cbb --- /dev/null +++ b/tests/std/array/gh9296.phpt @@ -0,0 +1,17 @@ +--TEST-- +GH-9296: incorrect ksort(..., SORT_REGULAR) behaviour on arrays with numeric and string keys +--FILE-- + 0, 600 => 1]; +ksort($array, SORT_REGULAR); +var_dump($array); +var_dump(array_key_first($array) <=> array_key_last($array)); +?> +--EXPECT-- +array(2) { + [600]=> + int(1) + ["aaa"]=> + int(0) +} +int(-1) diff --git a/tests/std/array/in_array_variation1.phpt b/tests/std/array/in_array_variation1.phpt new file mode 100644 index 00000000..0c88a453 --- /dev/null +++ b/tests/std/array/in_array_variation1.phpt @@ -0,0 +1,635 @@ +--TEST-- +Test in_array() function : usage variations - different needdle values +--FILE-- + "A", 2 => "B", "C" => 3, 4 => 4, "one" => 1, "" => NULL, "b", "ab", "abcd"), + array(4, array(1, 2 => 3), "one" => 1, "5" => 5 ), + array(-1, -2, -3, -4, -2.989888, "-0.005" => "neg0.005", 2 => "float2", "-.9" => -.9), + array(TRUE, FALSE), + array("", array()), + array("abcd\x00abcd\x00abcd"), + array("abcd\tabcd\nabcd\rabcd\0abcdefghij") +); + +$array_compare = array ( + 4, + "4", + 4.00, + "b", + "5", + -2, + -2.0, + -2.98989, + "-.9", + "True", + "", + array(), + NULL, + "ab", + "abcd", + 0.0, + -0, + "abcd\x00abcd\x00abcd" +); +/* loop to check if elements in $array_compare exist in $arrays + using in_array() */ +$counter = 1; +foreach($arrays as $array) { + foreach($array_compare as $compare) { + echo "-- Iteration $counter --\n"; + //strict option OFF + var_dump(in_array($compare,$array)); + //strict option ON + var_dump(in_array($compare,$array,TRUE)); + //strict option OFF + var_dump(in_array($compare,$array,FALSE)); + $counter++; + } +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing in_array() with different needle values *** +-- Iteration 1 -- +bool(false) +bool(false) +bool(false) +-- Iteration 2 -- +bool(false) +bool(false) +bool(false) +-- Iteration 3 -- +bool(false) +bool(false) +bool(false) +-- Iteration 4 -- +bool(false) +bool(false) +bool(false) +-- Iteration 5 -- +bool(false) +bool(false) +bool(false) +-- Iteration 6 -- +bool(false) +bool(false) +bool(false) +-- Iteration 7 -- +bool(false) +bool(false) +bool(false) +-- Iteration 8 -- +bool(false) +bool(false) +bool(false) +-- Iteration 9 -- +bool(false) +bool(false) +bool(false) +-- Iteration 10 -- +bool(false) +bool(false) +bool(false) +-- Iteration 11 -- +bool(false) +bool(false) +bool(false) +-- Iteration 12 -- +bool(false) +bool(false) +bool(false) +-- Iteration 13 -- +bool(true) +bool(false) +bool(true) +-- Iteration 14 -- +bool(false) +bool(false) +bool(false) +-- Iteration 15 -- +bool(false) +bool(false) +bool(false) +-- Iteration 16 -- +bool(true) +bool(false) +bool(true) +-- Iteration 17 -- +bool(true) +bool(true) +bool(true) +-- Iteration 18 -- +bool(false) +bool(false) +bool(false) +-- Iteration 19 -- +bool(true) +bool(true) +bool(true) +-- Iteration 20 -- +bool(true) +bool(false) +bool(true) +-- Iteration 21 -- +bool(true) +bool(false) +bool(true) +-- Iteration 22 -- +bool(true) +bool(true) +bool(true) +-- Iteration 23 -- +bool(false) +bool(false) +bool(false) +-- Iteration 24 -- +bool(false) +bool(false) +bool(false) +-- Iteration 25 -- +bool(false) +bool(false) +bool(false) +-- Iteration 26 -- +bool(false) +bool(false) +bool(false) +-- Iteration 27 -- +bool(false) +bool(false) +bool(false) +-- Iteration 28 -- +bool(false) +bool(false) +bool(false) +-- Iteration 29 -- +bool(true) +bool(false) +bool(true) +-- Iteration 30 -- +bool(true) +bool(false) +bool(true) +-- Iteration 31 -- +bool(true) +bool(true) +bool(true) +-- Iteration 32 -- +bool(true) +bool(true) +bool(true) +-- Iteration 33 -- +bool(true) +bool(true) +bool(true) +-- Iteration 34 -- +bool(true) +bool(false) +bool(true) +-- Iteration 35 -- +bool(true) +bool(false) +bool(true) +-- Iteration 36 -- +bool(false) +bool(false) +bool(false) +-- Iteration 37 -- +bool(true) +bool(true) +bool(true) +-- Iteration 38 -- +bool(true) +bool(false) +bool(true) +-- Iteration 39 -- +bool(true) +bool(false) +bool(true) +-- Iteration 40 -- +bool(false) +bool(false) +bool(false) +-- Iteration 41 -- +bool(true) +bool(false) +bool(true) +-- Iteration 42 -- +bool(false) +bool(false) +bool(false) +-- Iteration 43 -- +bool(false) +bool(false) +bool(false) +-- Iteration 44 -- +bool(false) +bool(false) +bool(false) +-- Iteration 45 -- +bool(false) +bool(false) +bool(false) +-- Iteration 46 -- +bool(false) +bool(false) +bool(false) +-- Iteration 47 -- +bool(false) +bool(false) +bool(false) +-- Iteration 48 -- +bool(false) +bool(false) +bool(false) +-- Iteration 49 -- +bool(false) +bool(false) +bool(false) +-- Iteration 50 -- +bool(false) +bool(false) +bool(false) +-- Iteration 51 -- +bool(false) +bool(false) +bool(false) +-- Iteration 52 -- +bool(false) +bool(false) +bool(false) +-- Iteration 53 -- +bool(false) +bool(false) +bool(false) +-- Iteration 54 -- +bool(false) +bool(false) +bool(false) +-- Iteration 55 -- +bool(false) +bool(false) +bool(false) +-- Iteration 56 -- +bool(false) +bool(false) +bool(false) +-- Iteration 57 -- +bool(false) +bool(false) +bool(false) +-- Iteration 58 -- +bool(false) +bool(false) +bool(false) +-- Iteration 59 -- +bool(false) +bool(false) +bool(false) +-- Iteration 60 -- +bool(true) +bool(true) +bool(true) +-- Iteration 61 -- +bool(true) +bool(false) +bool(true) +-- Iteration 62 -- +bool(false) +bool(false) +bool(false) +-- Iteration 63 -- +bool(true) +bool(false) +bool(true) +-- Iteration 64 -- +bool(false) +bool(false) +bool(false) +-- Iteration 65 -- +bool(false) +bool(false) +bool(false) +-- Iteration 66 -- +bool(false) +bool(false) +bool(false) +-- Iteration 67 -- +bool(false) +bool(false) +bool(false) +-- Iteration 68 -- +bool(false) +bool(false) +bool(false) +-- Iteration 69 -- +bool(false) +bool(false) +bool(false) +-- Iteration 70 -- +bool(false) +bool(false) +bool(false) +-- Iteration 71 -- +bool(false) +bool(false) +bool(false) +-- Iteration 72 -- +bool(false) +bool(false) +bool(false) +-- Iteration 73 -- +bool(true) +bool(false) +bool(true) +-- Iteration 74 -- +bool(true) +bool(false) +bool(true) +-- Iteration 75 -- +bool(true) +bool(false) +bool(true) +-- Iteration 76 -- +bool(true) +bool(false) +bool(true) +-- Iteration 77 -- +bool(true) +bool(false) +bool(true) +-- Iteration 78 -- +bool(true) +bool(false) +bool(true) +-- Iteration 79 -- +bool(true) +bool(false) +bool(true) +-- Iteration 80 -- +bool(true) +bool(false) +bool(true) +-- Iteration 81 -- +bool(true) +bool(false) +bool(true) +-- Iteration 82 -- +bool(true) +bool(false) +bool(true) +-- Iteration 83 -- +bool(true) +bool(false) +bool(true) +-- Iteration 84 -- +bool(true) +bool(false) +bool(true) +-- Iteration 85 -- +bool(true) +bool(false) +bool(true) +-- Iteration 86 -- +bool(true) +bool(false) +bool(true) +-- Iteration 87 -- +bool(true) +bool(false) +bool(true) +-- Iteration 88 -- +bool(true) +bool(false) +bool(true) +-- Iteration 89 -- +bool(true) +bool(false) +bool(true) +-- Iteration 90 -- +bool(true) +bool(false) +bool(true) +-- Iteration 91 -- +bool(false) +bool(false) +bool(false) +-- Iteration 92 -- +bool(false) +bool(false) +bool(false) +-- Iteration 93 -- +bool(false) +bool(false) +bool(false) +-- Iteration 94 -- +bool(false) +bool(false) +bool(false) +-- Iteration 95 -- +bool(false) +bool(false) +bool(false) +-- Iteration 96 -- +bool(false) +bool(false) +bool(false) +-- Iteration 97 -- +bool(false) +bool(false) +bool(false) +-- Iteration 98 -- +bool(false) +bool(false) +bool(false) +-- Iteration 99 -- +bool(false) +bool(false) +bool(false) +-- Iteration 100 -- +bool(false) +bool(false) +bool(false) +-- Iteration 101 -- +bool(true) +bool(true) +bool(true) +-- Iteration 102 -- +bool(true) +bool(true) +bool(true) +-- Iteration 103 -- +bool(true) +bool(false) +bool(true) +-- Iteration 104 -- +bool(false) +bool(false) +bool(false) +-- Iteration 105 -- +bool(false) +bool(false) +bool(false) +-- Iteration 106 -- +bool(false) +bool(false) +bool(false) +-- Iteration 107 -- +bool(false) +bool(false) +bool(false) +-- Iteration 108 -- +bool(false) +bool(false) +bool(false) +-- Iteration 109 -- +bool(false) +bool(false) +bool(false) +-- Iteration 110 -- +bool(false) +bool(false) +bool(false) +-- Iteration 111 -- +bool(false) +bool(false) +bool(false) +-- Iteration 112 -- +bool(false) +bool(false) +bool(false) +-- Iteration 113 -- +bool(false) +bool(false) +bool(false) +-- Iteration 114 -- +bool(false) +bool(false) +bool(false) +-- Iteration 115 -- +bool(false) +bool(false) +bool(false) +-- Iteration 116 -- +bool(false) +bool(false) +bool(false) +-- Iteration 117 -- +bool(false) +bool(false) +bool(false) +-- Iteration 118 -- +bool(false) +bool(false) +bool(false) +-- Iteration 119 -- +bool(false) +bool(false) +bool(false) +-- Iteration 120 -- +bool(false) +bool(false) +bool(false) +-- Iteration 121 -- +bool(false) +bool(false) +bool(false) +-- Iteration 122 -- +bool(false) +bool(false) +bool(false) +-- Iteration 123 -- +bool(false) +bool(false) +bool(false) +-- Iteration 124 -- +bool(false) +bool(false) +bool(false) +-- Iteration 125 -- +bool(false) +bool(false) +bool(false) +-- Iteration 126 -- +bool(true) +bool(true) +bool(true) +-- Iteration 127 -- +bool(false) +bool(false) +bool(false) +-- Iteration 128 -- +bool(false) +bool(false) +bool(false) +-- Iteration 129 -- +bool(false) +bool(false) +bool(false) +-- Iteration 130 -- +bool(false) +bool(false) +bool(false) +-- Iteration 131 -- +bool(false) +bool(false) +bool(false) +-- Iteration 132 -- +bool(false) +bool(false) +bool(false) +-- Iteration 133 -- +bool(false) +bool(false) +bool(false) +-- Iteration 134 -- +bool(false) +bool(false) +bool(false) +-- Iteration 135 -- +bool(false) +bool(false) +bool(false) +-- Iteration 136 -- +bool(false) +bool(false) +bool(false) +-- Iteration 137 -- +bool(false) +bool(false) +bool(false) +-- Iteration 138 -- +bool(false) +bool(false) +bool(false) +-- Iteration 139 -- +bool(false) +bool(false) +bool(false) +-- Iteration 140 -- +bool(false) +bool(false) +bool(false) +-- Iteration 141 -- +bool(false) +bool(false) +bool(false) +-- Iteration 142 -- +bool(false) +bool(false) +bool(false) +-- Iteration 143 -- +bool(false) +bool(false) +bool(false) +-- Iteration 144 -- +bool(false) +bool(false) +bool(false) +Done diff --git a/tests/std/array/in_array_variation2.phpt b/tests/std/array/in_array_variation2.phpt new file mode 100644 index 00000000..39762322 --- /dev/null +++ b/tests/std/array/in_array_variation2.phpt @@ -0,0 +1,95 @@ +--TEST-- +Test in_array() function : usage variations - different haystack values +--FILE-- +'d', + 3, + ".001" =>-67, + "-.051" =>"k", + 0 =>"-.08", + "e" =>"5", + "y" =>NULL, + NULL =>"", + 0, + TRUE, + FALSE, + -27.39999999999, + " ", + "abcd\x00abcd\x00\abcd\x00abcdefghij", + "abcd\nabcd\tabcd\rabcd\0abcd" +); +$array_type = array(TRUE, FALSE, 1, 0, -1, "1", "0", "-1", NULL, array(), "PHP", ""); +/* loop to do loose and strict type check of elements in + $array_type on elements in $misc_array using in_array(); + checking PHP type comparison tables +*/ +$counter = 1; +foreach($array_type as $type) { + echo "-- Iteration $counter --\n"; + //loose type checking + var_dump( in_array($type,$misc_array ) ); + //strict type checking + var_dump( in_array($type,$misc_array,true) ); + //loose type checking + var_dump( in_array($type,$misc_array,false) ); + $counter++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing in_array() with different haystack values *** +-- Iteration 1 -- +bool(true) +bool(true) +bool(true) +-- Iteration 2 -- +bool(true) +bool(true) +bool(true) +-- Iteration 3 -- +bool(true) +bool(false) +bool(true) +-- Iteration 4 -- +bool(true) +bool(true) +bool(true) +-- Iteration 5 -- +bool(true) +bool(false) +bool(true) +-- Iteration 6 -- +bool(true) +bool(false) +bool(true) +-- Iteration 7 -- +bool(true) +bool(false) +bool(true) +-- Iteration 8 -- +bool(true) +bool(false) +bool(true) +-- Iteration 9 -- +bool(true) +bool(true) +bool(true) +-- Iteration 10 -- +bool(true) +bool(false) +bool(true) +-- Iteration 11 -- +bool(true) +bool(false) +bool(true) +-- Iteration 12 -- +bool(true) +bool(true) +bool(true) +Done diff --git a/tests/std/array/in_array_variation3.phpt b/tests/std/array/in_array_variation3.phpt new file mode 100644 index 00000000..de0a5e7d --- /dev/null +++ b/tests/std/array/in_array_variation3.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test in_array() function : usage variations - haystack as sub-array/object +--SKIPIF-- + +--FILE-- + "one", "two" => 2, 3 => 3); + public function foo() + { + echo "Public function\n"; + } +} +function main() +{ + /* Test in_array() with haystack as sub-array and object */ + /* checking for sub-arrays with in_array() */ + echo "*** Testing sub-arrays with in_array() ***\n"; + $sub_array = array("one", array(1, 2 => "two", "three" => 3), 4 => "four", "five" => 5, array('', 'i')); + var_dump(in_array("four", $sub_array)); + //checking for element in a sub-array + var_dump(in_array(3, $sub_array[1])); + var_dump(in_array(array('', 'i'), $sub_array)); + /* checking for objects in in_array() */ + echo "\n*** Testing objects with in_array() ***\n"; + $in_array_obj = new in_array_check(); + //creating new object + //error: as wrong datatype for second argument + try { + var_dump(in_array("array_var", $in_array_obj)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + //error: as wrong datatype for second argument + try { + var_dump(in_array("foo", $in_array_obj)); + } catch (TypeError $e) { + echo $e->getMessage(), "\n"; + } + //element found as "one" exists in array $array_var + var_dump(in_array("one", $in_array_obj->array_var)); + echo "Done\n"; +} +?> +--EXPECT-- +*** Testing sub-arrays with in_array() *** +bool(true) +bool(true) +bool(true) + +*** Testing objects with in_array() *** +in_array(): Argument #2 ($haystack) must be of type array, in_array_check given +in_array(): Argument #2 ($haystack) must be of type array, in_array_check given +bool(true) +Done diff --git a/tests/std/array/in_array_variation4.phpt b/tests/std/array/in_array_variation4.phpt new file mode 100644 index 00000000..c7c91278 --- /dev/null +++ b/tests/std/array/in_array_variation4.phpt @@ -0,0 +1,70 @@ +--TEST-- +Test in_array() function : usage variations - haystack as resource/multi dimensional array +--FILE-- + TRUE, "b"=> TRUE, + array("c"=> TRUE, "d"=>TRUE) + ) + ) + ); + +//matching string having integer in beginning, result:true in loose type check +var_dump( in_array('123abc', array(123)) ); +var_dump( in_array('123abc', array(123), TRUE) ); // false in strict mode + +echo "Done\n"; +?> +--EXPECT-- +*** Testing resource type with in_array() *** +bool(true) +bool(false) + +*** Testing miscelleneos inputs with in_array() *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(true) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +Done diff --git a/tests/std/array/in_array_with_ref.phpt b/tests/std/array/in_array_with_ref.phpt new file mode 100644 index 00000000..2ad3667d --- /dev/null +++ b/tests/std/array/in_array_with_ref.phpt @@ -0,0 +1,14 @@ +--TEST-- +in_array() with references +--FILE-- + +--EXPECT-- +bool(true) +bool(true) diff --git a/tests/std/array/key_basic.phpt b/tests/std/array/key_basic.phpt new file mode 100644 index 00000000..f6b9300b --- /dev/null +++ b/tests/std/array/key_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test key() function : basic functionality +--FILE-- + 'one', 'two', 'three' => 3); +echo "\n-- Initial Position: --\n"; +var_dump(key($array)); + +echo "\n-- Next Position: --\n"; +next($array); +var_dump(key($array)); + +echo "\n-- End Position: --\n"; +end($array); +var_dump(key($array)); + +echo "\n-- Past end of the array --\n"; +next($array); +var_dump(key($array)); +?> +--EXPECT-- +*** Testing key() : basic functionality *** + +-- Initial Position: -- +int(0) + +-- Next Position: -- +int(99) + +-- End Position: -- +string(5) "three" + +-- Past end of the array -- +NULL diff --git a/tests/std/array/key_exists_basic.phpt b/tests/std/array/key_exists_basic.phpt new file mode 100644 index 00000000..37fed4e2 --- /dev/null +++ b/tests/std/array/key_exists_basic.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test function key_exists() by calling it with its expected arguments +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 1); +var_dump(key_exists('bar', $a)); +var_dump(key_exists('foo', $a)); +?> +--EXPECT-- +*** test key_exists() by calling it with its expected arguments *** +bool(true) +bool(false) diff --git a/tests/std/array/key_exists_variation1.phpt b/tests/std/array/key_exists_variation1.phpt new file mode 100644 index 00000000..b902a9ea --- /dev/null +++ b/tests/std/array/key_exists_variation1.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test function key_exists() by calling it with its expected arguments +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 1, 'foo' => array('bar' => 2, 'baz' => 3)); +var_dump(key_exists('baz', $a)); +var_dump(key_exists('baz', $a['foo'])); +?> +--EXPECT-- +*** test key_exists() by calling it with its expected arguments *** +bool(false) +bool(true) diff --git a/tests/std/array/key_exists_variation2.phpt b/tests/std/array/key_exists_variation2.phpt new file mode 100644 index 00000000..cb2b9502 --- /dev/null +++ b/tests/std/array/key_exists_variation2.phpt @@ -0,0 +1,64 @@ +--TEST-- +Test function key_exists() by calling it with its expected arguments +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 'bar', 'foo' => 'baz'); + var_dump(key_exists(0, $a)); + echo "integer\n"; + // 1 has index = 0 + $b = array(1, 'foo' => 'baz'); + var_dump(key_exists(0, $b)); + // 42 has index = 0, netherless its position is the latest + $c = array('foo' => 'baz', 42); + var_dump(key_exists(0, $c)); + echo "string\n"; + // 'bar' has index = 0, netherless it is a string + $d = array('bar', 'foo' => 'baz'); + var_dump(key_exists(0, $d)); + // 'baz' has index = 0, netherless its position is the latest + $e = array('foo' => 'baz', 'baz'); + var_dump(key_exists(0, $e)); + echo "obj\n"; + $obj = new ObjectA(); + // object has index = 0, netherless its position is the latest + $f = array('foo' => 'baz', $obj); + var_dump(key_exists(0, $f)); + // object has index = 0, netherless its position is the first + $g = array($obj, 'foo' => 'baz'); + var_dump(key_exists(0, $g)); + echo "stream resource\n"; + // stream resource has index = 0, netherless its position is the first + $st = fopen('php://memory', '+r'); + $h = array($st, 'foo' => 'baz'); + var_dump(key_exists(0, $h)); + // stream resource has index = 0, netherless its position is the latest + $i = array('foo' => 'baz', $st); + var_dump(key_exists(0, $i)); +} +?> +--EXPECT-- +*** test key_exists() by using mixed type of arrays *** +bool(false) +integer +bool(true) +bool(true) +string +bool(true) +bool(true) +obj +bool(true) +bool(true) +stream resource +bool(true) +bool(true) diff --git a/tests/std/array/key_variation2.phpt b/tests/std/array/key_variation2.phpt new file mode 100644 index 00000000..a81c3350 --- /dev/null +++ b/tests/std/array/key_variation2.phpt @@ -0,0 +1,132 @@ +--TEST-- +Test key() function : usage variations +--SKIPIF-- + + +--FILE-- + array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative', + ), + + // null data +/*4*/ 'null uppercase' => array( + NULL => 'null 1', + ), + +/*5*/ 'null lowercase' => array( + null => 'null 2', + ), + + // boolean data +/*6*/ 'bool lowercase' => array( + true => 'lowert', + false => 'lowerf', + ), + +/*7*/ 'bool uppercase' => array( + TRUE => 'uppert', + FALSE => 'upperf', + ), + + // empty data +/*8*/ 'empty double quotes' => array( + "" => 'emptyd', + ), + +/*9*/ 'empty single quotes' => array( + '' => 'emptys', + ), + + // string data +/*10*/ 'string' => array( + "stringd" => 'stringd', + 'strings' => 'strings', + $heredoc => 'stringh', + ), + + // undefined data +/*11*/ 'undefined' => array( + @$undefined_var => 'undefined', + ), + + // unset data +/*12*/ 'unset' => array( + @$unset_var => 'unset', + ), +); + +// loop through each element of $inputs to check the behavior of key() +$iterator = 1; +foreach($inputs as $key => $input) { + echo "\n-- Iteration $iterator : $key data --\n"; + while (key($input) !== NULL) { + var_dump(key($input)); + next($input); + } + $iterator++; +}; +?> +--EXPECT-- +*** Testing key() : usage variations *** + +-- Iteration 1 : int data -- +int(0) +int(1) +int(12345) +int(-2345) + +-- Iteration 2 : null uppercase data -- +string(0) "" + +-- Iteration 3 : null lowercase data -- +string(0) "" + +-- Iteration 4 : bool lowercase data -- +int(1) +int(0) + +-- Iteration 5 : bool uppercase data -- +int(1) +int(0) + +-- Iteration 6 : empty double quotes data -- +string(0) "" + +-- Iteration 7 : empty single quotes data -- +string(0) "" + +-- Iteration 8 : string data -- +string(7) "stringd" +string(7) "strings" +string(11) "hello world" + +-- Iteration 9 : undefined data -- +string(0) "" + +-- Iteration 10 : unset data -- +string(0) "" diff --git a/tests/std/array/key_variation3.phpt b/tests/std/array/key_variation3.phpt new file mode 100644 index 00000000..dfebd4bd --- /dev/null +++ b/tests/std/array/key_variation3.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test key() function : usage variations +--FILE-- + +--EXPECT-- +*** Testing key() : usage variations *** + +-- Initial position of internal pointer -- +int(0) + +-- Position after calling next() -- +$array1: int(1) +$array2: int(1) diff --git a/tests/std/array/key_variation4.phpt b/tests/std/array/key_variation4.phpt new file mode 100644 index 00000000..a71e6732 --- /dev/null +++ b/tests/std/array/key_variation4.phpt @@ -0,0 +1,56 @@ +--TEST-- +Test key() function : usage variations +--FILE-- + +--EXPECT-- +*** Testing key() : usage variations *** + +-- Two Dimensional Array -- +Initial Position: int(0) +Next Position: int(1) +End Position: int(2) + +-- Access an Array Within an Array -- +Initial Position: int(0) + +-- Recursive, Multidimensional Array -- +Current Position: int(2) +int(2) +int(0) diff --git a/tests/std/array/krsort_basic.phpt b/tests/std/array/krsort_basic.phpt new file mode 100644 index 00000000..6137e1b2 --- /dev/null +++ b/tests/std/array/krsort_basic.phpt @@ -0,0 +1,240 @@ +--TEST-- +Test krsort() function : basic functionality +--FILE-- + "l", "orange" => "o", "banana" => "b" ); +$unsorted_strings = array( + "l" => "lemon", "o" => "orange", + "O" => "Orange", "O1" => "Orange1", "o2" => "orange2", "O3" => "Orange3", "o20" => "orange20", + "b" => "banana", +); +// an array containing unsorted numeric values with indices +$unsorted_numerics = array( 100 => 4, 33 => 3, 555 => 2, 22 => 1 ); + +echo "\n-- Testing krsort() by supplying string array, 'flag' value is default --\n"; +$temp_array = $unsorted_strings; +var_dump( krsort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing krsort() by supplying numeric array, 'flag' value is default --\n"; +$temp_array = $unsorted_numerics; +var_dump( krsort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing krsort() by supplying string array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_strings; +var_dump( krsort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing krsort() by supplying numeric array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_numerics; +var_dump( krsort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing krsort() by supplying string array, 'flag' = SORT_STRING --\n"; +$temp_array = $unsorted_strings; +var_dump( krsort($temp_array, SORT_STRING) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing krsort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( krsort($temp_array, SORT_STRING|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing krsort() by supplying string array (natural), 'flag' = SORT_NATURAL --\n"; +$temp_array = $unsorted_strings; +var_dump( krsort($temp_array, SORT_NATURAL) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing krsort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( krsort($temp_array, SORT_NATURAL|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing krsort() by supplying numeric array, 'flag' = SORT_NUMERIC --\n"; +$temp_array = $unsorted_numerics; +var_dump( krsort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing krsort() : basic functionality *** + +-- Testing krsort() by supplying string array, 'flag' value is default -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["o"]=> + string(6) "orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" + ["O3"]=> + string(7) "Orange3" + ["O1"]=> + string(7) "Orange1" + ["O"]=> + string(6) "Orange" +} + +-- Testing krsort() by supplying numeric array, 'flag' value is default -- +bool(true) +array(4) { + [555]=> + int(2) + [100]=> + int(4) + [33]=> + int(3) + [22]=> + int(1) +} + +-- Testing krsort() by supplying string array, 'flag' = SORT_REGULAR -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["o"]=> + string(6) "orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" + ["O3"]=> + string(7) "Orange3" + ["O1"]=> + string(7) "Orange1" + ["O"]=> + string(6) "Orange" +} + +-- Testing krsort() by supplying numeric array, 'flag' = SORT_REGULAR -- +bool(true) +array(4) { + [555]=> + int(2) + [100]=> + int(4) + [33]=> + int(3) + [22]=> + int(1) +} + +-- Testing krsort() by supplying string array, 'flag' = SORT_STRING -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["o"]=> + string(6) "orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" + ["O3"]=> + string(7) "Orange3" + ["O1"]=> + string(7) "Orange1" + ["O"]=> + string(6) "Orange" +} + +-- Testing krsort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE -- +bool(true) +array(8) { + ["O3"]=> + string(7) "Orange3" + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["O1"]=> + string(7) "Orange1" + ["o"]=> + string(6) "orange" + ["O"]=> + string(6) "Orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" +} + +-- Testing krsort() by supplying string array (natural), 'flag' = SORT_NATURAL -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["o2"]=> + string(7) "orange2" + ["o"]=> + string(6) "orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" + ["O3"]=> + string(7) "Orange3" + ["O1"]=> + string(7) "Orange1" + ["O"]=> + string(6) "Orange" +} + +-- Testing krsort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE -- +bool(true) +array(8) { + ["o20"]=> + string(8) "orange20" + ["O3"]=> + string(7) "Orange3" + ["o2"]=> + string(7) "orange2" + ["O1"]=> + string(7) "Orange1" + ["o"]=> + string(6) "orange" + ["O"]=> + string(6) "Orange" + ["l"]=> + string(5) "lemon" + ["b"]=> + string(6) "banana" +} + +-- Testing krsort() by supplying numeric array, 'flag' = SORT_NUMERIC -- +bool(true) +array(4) { + [555]=> + int(2) + [100]=> + int(4) + [33]=> + int(3) + [22]=> + int(1) +} +Done diff --git a/tests/std/array/krsort_object.phpt b/tests/std/array/krsort_object.phpt new file mode 100644 index 00000000..6e75ce1f --- /dev/null +++ b/tests/std/array/krsort_object.phpt @@ -0,0 +1,220 @@ +--TEST-- +Test krsort() function : object functionality - sort objects +--FILE-- +class_value = $value; + } +} +// class declaration for string objects +class StringObject +{ + public $class_value; + // initializing object member value + function __construct($value) + { + $this->class_value = $value; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * testing krsort() by providing array of integer/string objects with following flag values: + * 1.Default flag value + * 2.SORT_REGULAR - compare items normally + */ + echo "*** Testing krsort() : object functionality ***\n"; + // array of integer objects with different key values + $unsorted_int_obj = array(10 => new IntegerObject(11), 20 => new IntegerObject(66), 3 => new IntegerObject(23), 4 => new IntegerObject(-5), 50 => new IntegerObject(0.001), 6 => new IntegerObject(0)); + // array of string objects with different key values + $unsorted_str_obj = array("axx" => new StringObject("axx"), "t" => new StringObject("t"), "w" => new StringObject("w"), "py" => new StringObject("py"), "apple" => new StringObject("apple"), "Orange" => new StringObject("Orange"), "Lemon" => new StringObject("Lemon"), "aPPle" => new StringObject("aPPle")); + echo "\n-- Testing krsort() by supplying various object arrays, 'flag' value is default --\n"; + // testing krsort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(krsort($temp_array)); + var_dump($temp_array); + // testing krsort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(krsort($temp_array)); + var_dump($temp_array); + echo "\n-- Testing krsort() by supplying various object arrays, 'flag' value is SORT_REGULAR --\n"; + // testing krsort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(krsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing krsort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(krsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done\n"; +} +?> +--EXPECTF-- +*** Testing krsort() : object functionality *** + +-- Testing krsort() by supplying various object arrays, 'flag' value is default -- +bool(true) +array(6) { + [50]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + float(0.001) + } + [20]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(66) + } + [10]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(11) + } + [6]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(0) + } + [4]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(-5) + } + [3]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(23) + } +} +bool(true) +array(8) { + ["w"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(1) "w" + } + ["t"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(1) "t" + } + ["py"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(2) "py" + } + ["axx"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + ["apple"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + ["aPPle"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + ["Orange"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + ["Lemon"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } +} + +-- Testing krsort() by supplying various object arrays, 'flag' value is SORT_REGULAR -- +bool(true) +array(6) { + [50]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + float(0.001) + } + [20]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(66) + } + [10]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(11) + } + [6]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(0) + } + [4]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(-5) + } + [3]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(23) + } +} +bool(true) +array(8) { + ["w"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(1) "w" + } + ["t"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(1) "t" + } + ["py"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(2) "py" + } + ["axx"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + ["apple"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + ["aPPle"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + ["Orange"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + ["Lemon"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } +} +Done diff --git a/tests/std/array/krsort_variation10.phpt b/tests/std/array/krsort_variation10.phpt new file mode 100644 index 00000000..104ed032 --- /dev/null +++ b/tests/std/array/krsort_variation10.phpt @@ -0,0 +1,93 @@ +--TEST-- +Test krsort() function : usage variations - sort heredoc strings +--FILE-- + "Heredoc", + $simple_heredoc2 => "HEREDOC", + $multiline_heredoc => "heredoc string\twith!@# and 123\nTest this!!!" +); + +echo "\n-- Testing krsort() by supplying heredoc string array, 'flag' value is default --\n"; +$temp_array = $array; +var_dump(krsort($temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying heredoc string array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $array; +var_dump(krsort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying heredoc string array, 'flag' = SORT_STRING --\n"; +$temp_array = $array; +var_dump(krsort($temp_array, SORT_STRING) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing krsort() : usage variations *** + +-- Testing krsort() by supplying heredoc string array, 'flag' value is default -- +bool(true) +array(3) { + ["heredoc string with!@# and 123 +Test this!!!"]=> + string(43) "heredoc string with!@# and 123 +Test this!!!" + ["Heredoc"]=> + string(7) "Heredoc" + ["HEREDOC"]=> + string(7) "HEREDOC" +} + +-- Testing krsort() by supplying heredoc string array, 'flag' = SORT_REGULAR -- +bool(true) +array(3) { + ["heredoc string with!@# and 123 +Test this!!!"]=> + string(43) "heredoc string with!@# and 123 +Test this!!!" + ["Heredoc"]=> + string(7) "Heredoc" + ["HEREDOC"]=> + string(7) "HEREDOC" +} + +-- Testing krsort() by supplying heredoc string array, 'flag' = SORT_STRING -- +bool(true) +array(3) { + ["heredoc string with!@# and 123 +Test this!!!"]=> + string(43) "heredoc string with!@# and 123 +Test this!!!" + ["Heredoc"]=> + string(7) "Heredoc" + ["HEREDOC"]=> + string(7) "HEREDOC" +} +Done diff --git a/tests/std/array/krsort_variation11.phpt b/tests/std/array/krsort_variation11.phpt new file mode 100644 index 00000000..9e0e696f --- /dev/null +++ b/tests/std/array/krsort_variation11.phpt @@ -0,0 +1,77 @@ +--TEST-- +Test krsort() function : usage variations - sort bool values +--SKIPIF-- +--FILE-- + true, false => false, TRUE => TRUE, FALSE => FALSE); + +echo "\n-- Testing krsort() by supplying boolean value array, 'flag' value is default --\n"; +$temp_array = $bool_values; +var_dump(krsort($temp_array) ); +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying boolean value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $bool_values; +var_dump(krsort($temp_array, SORT_REGULAR) ); +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying boolean value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $bool_values; +var_dump(krsort($temp_array, SORT_NUMERIC) ); +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying boolean value array, 'flag' value is SORT_STRING --\n"; +$temp_array = $bool_values; +var_dump(krsort($temp_array, SORT_STRING) ); +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing krsort() : usage variations *** + +-- Testing krsort() by supplying boolean value array, 'flag' value is default -- +bool(true) +array(2) { + [1]=> + bool(true) + [0]=> + bool(false) +} + +-- Testing krsort() by supplying boolean value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(2) { + [1]=> + bool(true) + [0]=> + bool(false) +} + +-- Testing krsort() by supplying boolean value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(2) { + [1]=> + bool(true) + [0]=> + bool(false) +} + +-- Testing krsort() by supplying boolean value array, 'flag' value is SORT_STRING -- +bool(true) +array(2) { + [1]=> + bool(true) + [0]=> + bool(false) +} +Done diff --git a/tests/std/array/krsort_variation3.phpt b/tests/std/array/krsort_variation3.phpt new file mode 100644 index 00000000..979d3844 --- /dev/null +++ b/tests/std/array/krsort_variation3.phpt @@ -0,0 +1,204 @@ +--TEST-- +Test krsort() function : usage variations - sort integer/float values +--FILE-- + 11, -2 => -11, 3 => 21, -4 => -21, 5 => 31, -6 => -31, 7 => 0, 8 => 41, -10 =>-41), + + // mixed value array with different types of keys + array(1 => .0001, 2 => .0021, -3 => -.01, 4 => -1, 5 => 0, 6 => .09, 7 => 2, -8 => -.9, 9 => 10.6E-2, + -10 => -10.6E-2, 11 => 33) +); + +// set of possible flag values +$flags = array("SORT_REGULAR" => SORT_REGULAR, "SORT_NUMERIC" => SORT_NUMERIC); + +$count = 1; +echo "\n-- Testing krsort() by supplying various integer/float arrays --\n"; + +// loop through to test krsort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort flag -\n"; + $temp_array = $array; + var_dump(krsort($temp_array) ); + var_dump($temp_array); + + // loop through $flags array and call krsort() with all possible sort flag values + foreach($flags as $key => $flag){ + echo "- Sort flag = $key -\n"; + $temp_array = $array; + var_dump(krsort($temp_array, $flag) ); + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing krsort() : usage variations *** + +-- Testing krsort() by supplying various integer/float arrays -- + +-- Iteration 1 -- +- With default sort flag - +bool(true) +array(9) { + [8]=> + int(41) + [7]=> + int(0) + [5]=> + int(31) + [3]=> + int(21) + [1]=> + int(11) + [-2]=> + int(-11) + [-4]=> + int(-21) + [-6]=> + int(-31) + [-10]=> + int(-41) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(9) { + [8]=> + int(41) + [7]=> + int(0) + [5]=> + int(31) + [3]=> + int(21) + [1]=> + int(11) + [-2]=> + int(-11) + [-4]=> + int(-21) + [-6]=> + int(-31) + [-10]=> + int(-41) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(9) { + [8]=> + int(41) + [7]=> + int(0) + [5]=> + int(31) + [3]=> + int(21) + [1]=> + int(11) + [-2]=> + int(-11) + [-4]=> + int(-21) + [-6]=> + int(-31) + [-10]=> + int(-41) +} + +-- Iteration 2 -- +- With default sort flag - +bool(true) +array(11) { + [11]=> + int(33) + [9]=> + float(0.106) + [7]=> + int(2) + [6]=> + float(0.09) + [5]=> + int(0) + [4]=> + int(-1) + [2]=> + float(0.0021) + [1]=> + float(0.0001) + [-3]=> + float(-0.01) + [-8]=> + float(-0.9) + [-10]=> + float(-0.106) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(11) { + [11]=> + int(33) + [9]=> + float(0.106) + [7]=> + int(2) + [6]=> + float(0.09) + [5]=> + int(0) + [4]=> + int(-1) + [2]=> + float(0.0021) + [1]=> + float(0.0001) + [-3]=> + float(-0.01) + [-8]=> + float(-0.9) + [-10]=> + float(-0.106) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(11) { + [11]=> + int(33) + [9]=> + float(0.106) + [7]=> + int(2) + [6]=> + float(0.09) + [5]=> + int(0) + [4]=> + int(-1) + [2]=> + float(0.0021) + [1]=> + float(0.0001) + [-3]=> + float(-0.01) + [-8]=> + float(-0.9) + [-10]=> + float(-0.106) +} +Done diff --git a/tests/std/array/krsort_variation4.phpt b/tests/std/array/krsort_variation4.phpt new file mode 100644 index 00000000..1f28d021 --- /dev/null +++ b/tests/std/array/krsort_variation4.phpt @@ -0,0 +1,109 @@ +--TEST-- +Test krsort() function : usage variations - sort octal values +--FILE-- + 01, 0321 => 02, 0345 => 03, 066 => 04, 0772 => 05, + 077 => 06, -066 => -01, -0345 => -02, 0 => 0 +); + +echo "\n-- Testing krsort() by supplying octal value array, 'flag' value is default --\n"; +$temp_array = $unsorted_oct_array; +var_dump( krsort($temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying octal value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $unsorted_oct_array; +var_dump( krsort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying octal value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $unsorted_oct_array; +var_dump( krsort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing krsort() : usage variations *** + +-- Testing krsort() by supplying octal value array, 'flag' value is default -- +bool(true) +array(9) { + [669]=> + int(1) + [506]=> + int(5) + [229]=> + int(3) + [209]=> + int(2) + [63]=> + int(6) + [54]=> + int(4) + [0]=> + int(0) + [-54]=> + int(-1) + [-229]=> + int(-2) +} + +-- Testing krsort() by supplying octal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(9) { + [669]=> + int(1) + [506]=> + int(5) + [229]=> + int(3) + [209]=> + int(2) + [63]=> + int(6) + [54]=> + int(4) + [0]=> + int(0) + [-54]=> + int(-1) + [-229]=> + int(-2) +} + +-- Testing krsort() by supplying octal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(9) { + [669]=> + int(1) + [506]=> + int(5) + [229]=> + int(3) + [209]=> + int(2) + [63]=> + int(6) + [54]=> + int(4) + [0]=> + int(0) + [-54]=> + int(-1) + [-229]=> + int(-2) +} +Done diff --git a/tests/std/array/krsort_variation5.phpt b/tests/std/array/krsort_variation5.phpt new file mode 100644 index 00000000..616a23c8 --- /dev/null +++ b/tests/std/array/krsort_variation5.phpt @@ -0,0 +1,227 @@ +--TEST-- +Test krsort() function : usage variations - sort strings +--SKIPIF-- + +--FILE-- + null, NULL => NULL, "\a" => "\a", "\cx" => "\cx", "\e" => "\e", + "\f" => "\f", "\n" =>"\n", "\r" => "\r", "\t" => "\t", "\xhh" => "\xhh", + "\ddd" => "\ddd", "\v" => "\v" + ), + + // array containing different strings with key values + array ( 'Lemon' => "lemoN", 'o' => "Orange", 'B' => "banana", 'Apple' => "apple", 'te' => "Test", + 't' => "TTTT", 'T' => "ttt", 'W' => "ww", 'X' => "x", 'x' => "X", 'O' => "oraNGe", + 'B' => "BANANA" + ) +); + +$flags = array("SORT_REGULAR" => SORT_REGULAR, "SORT_STRING" => SORT_STRING); + +$count = 1; +echo "\n-- Testing krsort() by supplying various string arrays --\n"; + +// loop through to test krsort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort flag -\n"; + $temp_array = $array; + var_dump(krsort($temp_array) ); // expecting : bool(true) + var_dump($temp_array); + + // loop through $flags array and call krsort() with all possible sort flag values + foreach($flags as $key => $flag){ + echo "- Sort flag = $key -\n"; + $temp_array = $array; + var_dump(krsort($temp_array, $flag) ); // expecting : bool(true) + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing krsort() : usage variations *** + +-- Testing krsort() by supplying various string arrays -- + +-- Iteration 1 -- +- With default sort flag - +bool(true) +array(11) { + ["\xhh"]=> + string(4) "\xhh" + ["\ddd"]=> + string(4) "\ddd" + ["\cx"]=> + string(3) "\cx" + ["\a"]=> + string(2) "\a" + [""]=> + string(1) "" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + [""]=> + NULL +} +- Sort flag = SORT_REGULAR - +bool(true) +array(11) { + ["\xhh"]=> + string(4) "\xhh" + ["\ddd"]=> + string(4) "\ddd" + ["\cx"]=> + string(3) "\cx" + ["\a"]=> + string(2) "\a" + [""]=> + string(1) "" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + [""]=> + NULL +} +- Sort flag = SORT_STRING - +bool(true) +array(11) { + ["\xhh"]=> + string(4) "\xhh" + ["\ddd"]=> + string(4) "\ddd" + ["\cx"]=> + string(3) "\cx" + ["\a"]=> + string(2) "\a" + [""]=> + string(1) "" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + [""]=> + NULL +} + +-- Iteration 2 -- +- With default sort flag - +bool(true) +array(11) { + ["x"]=> + string(1) "X" + ["te"]=> + string(4) "Test" + ["t"]=> + string(4) "TTTT" + ["o"]=> + string(6) "Orange" + ["X"]=> + string(1) "x" + ["W"]=> + string(2) "ww" + ["T"]=> + string(3) "ttt" + ["O"]=> + string(6) "oraNGe" + ["Lemon"]=> + string(5) "lemoN" + ["B"]=> + string(6) "BANANA" + ["Apple"]=> + string(5) "apple" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(11) { + ["x"]=> + string(1) "X" + ["te"]=> + string(4) "Test" + ["t"]=> + string(4) "TTTT" + ["o"]=> + string(6) "Orange" + ["X"]=> + string(1) "x" + ["W"]=> + string(2) "ww" + ["T"]=> + string(3) "ttt" + ["O"]=> + string(6) "oraNGe" + ["Lemon"]=> + string(5) "lemoN" + ["B"]=> + string(6) "BANANA" + ["Apple"]=> + string(5) "apple" +} +- Sort flag = SORT_STRING - +bool(true) +array(11) { + ["x"]=> + string(1) "X" + ["te"]=> + string(4) "Test" + ["t"]=> + string(4) "TTTT" + ["o"]=> + string(6) "Orange" + ["X"]=> + string(1) "x" + ["W"]=> + string(2) "ww" + ["T"]=> + string(3) "ttt" + ["O"]=> + string(6) "oraNGe" + ["Lemon"]=> + string(5) "lemoN" + ["B"]=> + string(6) "BANANA" + ["Apple"]=> + string(5) "apple" +} +Done diff --git a/tests/std/array/krsort_variation6.phpt b/tests/std/array/krsort_variation6.phpt new file mode 100644 index 00000000..c737cb4b --- /dev/null +++ b/tests/std/array/krsort_variation6.phpt @@ -0,0 +1,109 @@ +--TEST-- +Test krsort() function : usage variations - sort hexadecimal values +--FILE-- + 0x1AB, 0xFFF => 0xFFF, 0xF => 0xF, 0xFF => 0xFF, 0x2AA => 0x2AA, 0xBB => 0xBB, + 0x1ab => 0x1ab, 0xff => 0xff, -0xff => -0xFF, 0 => 0, -0x2aa => -0x2aa +); + +echo "\n-- Testing krsort() by supplying hexadecimal value array, 'flag' value is default --\n"; +$temp_array = $unsorted_hex_array; +var_dump(krsort( $temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying hexadecimal value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $unsorted_hex_array; +var_dump(krsort( $temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying hexadecimal value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $unsorted_hex_array; +var_dump(krsort( $temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing krsort() : usage variations *** + +-- Testing krsort() by supplying hexadecimal value array, 'flag' value is default -- +bool(true) +array(9) { + [4095]=> + int(4095) + [682]=> + int(682) + [427]=> + int(427) + [255]=> + int(255) + [187]=> + int(187) + [15]=> + int(15) + [0]=> + int(0) + [-255]=> + int(-255) + [-682]=> + int(-682) +} + +-- Testing krsort() by supplying hexadecimal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(9) { + [4095]=> + int(4095) + [682]=> + int(682) + [427]=> + int(427) + [255]=> + int(255) + [187]=> + int(187) + [15]=> + int(15) + [0]=> + int(0) + [-255]=> + int(-255) + [-682]=> + int(-682) +} + +-- Testing krsort() by supplying hexadecimal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(9) { + [4095]=> + int(4095) + [682]=> + int(682) + [427]=> + int(427) + [255]=> + int(255) + [187]=> + int(187) + [15]=> + int(15) + [0]=> + int(0) + [-255]=> + int(-255) + [-682]=> + int(-682) +} +Done diff --git a/tests/std/array/krsort_variation7.phpt b/tests/std/array/krsort_variation7.phpt new file mode 100644 index 00000000..9d25d93a --- /dev/null +++ b/tests/std/array/krsort_variation7.phpt @@ -0,0 +1,172 @@ +--TEST-- +Test krsort() function : usage variations - sort array with diff. sub arrays +--FILE-- + array(), + + // array contains null sub array + 2 => array( 1 => array() ), + + // array of arrays along with some values + 3 => array(4 => 44, 1 => 11, 3 => array(64,61) ), + + // array contains sub arrays + 4 => array ( 3 => array(33,-5,6), 1 => array(11), + 2 => array(22,-55), 0 => array() ) +); + + +$count = 1; +echo "\n-- Testing krsort() by supplying various arrays containing sub arrays --\n"; + +// loop through to test krsort() with different arrays +foreach ($various_arrays as $array) { + + echo "\n-- Iteration $count --\n"; + echo "- With default sort flag -\n"; + $temp_array = $array; + var_dump( krsort($temp_array) ); + var_dump($temp_array); + + echo "- Sort flag = SORT_REGULAR -\n"; + $temp_array = $array; + var_dump( krsort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing krsort() : usage variations *** + +-- Testing krsort() by supplying various arrays containing sub arrays -- + +-- Iteration 1 -- +- With default sort flag - +bool(true) +array(0) { +} +- Sort flag = SORT_REGULAR - +bool(true) +array(0) { +} + +-- Iteration 2 -- +- With default sort flag - +bool(true) +array(1) { + [1]=> + array(0) { + } +} +- Sort flag = SORT_REGULAR - +bool(true) +array(1) { + [1]=> + array(0) { + } +} + +-- Iteration 3 -- +- With default sort flag - +bool(true) +array(3) { + [4]=> + int(44) + [3]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } + [1]=> + int(11) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(3) { + [4]=> + int(44) + [3]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } + [1]=> + int(11) +} + +-- Iteration 4 -- +- With default sort flag - +bool(true) +array(4) { + [3]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [1]=> + array(1) { + [0]=> + int(11) + } + [0]=> + array(0) { + } +} +- Sort flag = SORT_REGULAR - +bool(true) +array(4) { + [3]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [1]=> + array(1) { + [0]=> + int(11) + } + [0]=> + array(0) { + } +} +Done diff --git a/tests/std/array/krsort_variation8.phpt b/tests/std/array/krsort_variation8.phpt new file mode 100644 index 00000000..458ee1e3 --- /dev/null +++ b/tests/std/array/krsort_variation8.phpt @@ -0,0 +1,156 @@ +--TEST-- +Test krsort() function : usage variations - sort mixed values, 'sort_flags' as default/SORT_REGULAR (OK to fail as result is unpredectable) +--SKIPIF-- + +--FILE-- + array(), + "array2" => array ( "sub_array[2,1]" => array(33,-5,6), "sub_array[2,2]" => array(11), + "sub_array[2,3]" => array(22,-55), "sub_array[2,4]" => array() + ), + 4 => 4, "4" => "4", 4 => 4.01, "b" => "b", "5" => "5", -2 => -2, -2 => -2.01, + -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", NULL => NULL, + "ab" => "ab", "abcd" => "abcd", 0 => 0.01, -0 => -0, '' => '' , + "abcd\x00abcd\x00abcd" => "abcd\x00abcd\x00abcd", 0 => 0.001 +); + +echo "\n-- Testing krsort() by supplying mixed value array, 'flag' value is default --\n"; +$temp_array = $mixed_values; +var_dump( krsort($temp_array) ); +var_dump($temp_array); + +echo "\n-- Testing krsort() by supplying mixed value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $mixed_values; +var_dump( krsort($temp_array, SORT_REGULAR) ); +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing krsort() : usage variations *** + +-- Testing krsort() by supplying mixed value array, 'flag' value is default -- +bool(true) +array(13) { + ["b"]=> + string(1) "b" + ["array2"]=> + array(4) { + ["sub_array[2,1]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[2,2]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[2,3]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[2,4]"]=> + array(0) { + } + } + ["array1"]=> + array(0) { + } + ["abcd%0abcd%0abcd"]=> + string(14) "abcd%0abcd%0abcd" + ["abcd"]=> + string(4) "abcd" + ["ab"]=> + string(2) "ab" + ["True"]=> + string(4) "True" + [5]=> + string(1) "5" + [4]=> + float(4.01) + [0]=> + float(0.001) + ["-.9"]=> + string(3) "-.9" + [-2]=> + float(-2.98989) + [""]=> + string(0) "" +} + +-- Testing krsort() by supplying mixed value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(13) { + ["b"]=> + string(1) "b" + ["array2"]=> + array(4) { + ["sub_array[2,1]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[2,2]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[2,3]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[2,4]"]=> + array(0) { + } + } + ["array1"]=> + array(0) { + } + ["abcd%0abcd%0abcd"]=> + string(14) "abcd%0abcd%0abcd" + ["abcd"]=> + string(4) "abcd" + ["ab"]=> + string(2) "ab" + ["True"]=> + string(4) "True" + [5]=> + string(1) "5" + [4]=> + float(4.01) + [0]=> + float(0.001) + ["-.9"]=> + string(3) "-.9" + [-2]=> + float(-2.98989) + [""]=> + string(0) "" +} +Done diff --git a/tests/std/array/krsort_variation9.phpt b/tests/std/array/krsort_variation9.phpt new file mode 100644 index 00000000..b0309f37 --- /dev/null +++ b/tests/std/array/krsort_variation9.phpt @@ -0,0 +1,252 @@ +--TEST-- +Test krsort() function : usage variations - sort array with/without key values +--FILE-- + 55, 66, 22, 33, 11), + array ("a" => "orange", "banana", "c" => "apple"), + array(1, 2, 3, 4, 5, 6), + array("first", 5 => "second", 1 => "third"), + array(1, 1, 8 => 1, 4 => 1, 19, 3 => 13), + array('bar' => 'baz', "foo" => 1), + array('a' => 1,'b' => array('e' => 2,'f' => 3),'c' => array('g' => 4),'d' => 5), +); + +$count = 1; +echo "\n-- Testing krsort() by supplying various arrays with/without key values --\n"; + +// loop through to test krsort() with different arrays, +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort flag -\n"; + $temp_array = $array; + var_dump( krsort($temp_array) ); + var_dump($temp_array); + + echo "- Sort flag = SORT_REGULAR -\n"; + $temp_array = $array; + var_dump( krsort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing krsort() : usage variations *** + +-- Testing krsort() by supplying various arrays with/without key values -- + +-- Iteration 1 -- +- With default sort flag - +bool(true) +array(5) { + [9]=> + int(11) + [8]=> + int(33) + [7]=> + int(22) + [6]=> + int(66) + [5]=> + int(55) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(5) { + [9]=> + int(11) + [8]=> + int(33) + [7]=> + int(22) + [6]=> + int(66) + [5]=> + int(55) +} + +-- Iteration 2 -- +- With default sort flag - +bool(true) +array(3) { + ["c"]=> + string(5) "apple" + ["a"]=> + string(6) "orange" + [0]=> + string(6) "banana" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(3) { + ["c"]=> + string(5) "apple" + ["a"]=> + string(6) "orange" + [0]=> + string(6) "banana" +} + +-- Iteration 3 -- +- With default sort flag - +bool(true) +array(6) { + [5]=> + int(6) + [4]=> + int(5) + [3]=> + int(4) + [2]=> + int(3) + [1]=> + int(2) + [0]=> + int(1) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(6) { + [5]=> + int(6) + [4]=> + int(5) + [3]=> + int(4) + [2]=> + int(3) + [1]=> + int(2) + [0]=> + int(1) +} + +-- Iteration 4 -- +- With default sort flag - +bool(true) +array(3) { + [5]=> + string(6) "second" + [1]=> + string(5) "third" + [0]=> + string(5) "first" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(3) { + [5]=> + string(6) "second" + [1]=> + string(5) "third" + [0]=> + string(5) "first" +} + +-- Iteration 5 -- +- With default sort flag - +bool(true) +array(6) { + [9]=> + int(19) + [8]=> + int(1) + [4]=> + int(1) + [3]=> + int(13) + [1]=> + int(1) + [0]=> + int(1) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(6) { + [9]=> + int(19) + [8]=> + int(1) + [4]=> + int(1) + [3]=> + int(13) + [1]=> + int(1) + [0]=> + int(1) +} + +-- Iteration 6 -- +- With default sort flag - +bool(true) +array(2) { + ["foo"]=> + int(1) + ["bar"]=> + string(3) "baz" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(2) { + ["foo"]=> + int(1) + ["bar"]=> + string(3) "baz" +} + +-- Iteration 7 -- +- With default sort flag - +bool(true) +array(4) { + ["d"]=> + int(5) + ["c"]=> + array(1) { + ["g"]=> + int(4) + } + ["b"]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } + ["a"]=> + int(1) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(4) { + ["d"]=> + int(5) + ["c"]=> + array(1) { + ["g"]=> + int(4) + } + ["b"]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } + ["a"]=> + int(1) +} +Done diff --git a/tests/std/array/ksort_basic.phpt b/tests/std/array/ksort_basic.phpt new file mode 100644 index 00000000..96135981 --- /dev/null +++ b/tests/std/array/ksort_basic.phpt @@ -0,0 +1,238 @@ +--TEST-- +Test ksort() function : basic functionality +--FILE-- + "lemon", "o" => "orange", + "O" => "Orange", "O1" => "Orange1", "o2" => "orange2", "O3" => "Orange3", "o20" => "orange20", + "b" => "banana", +); +// an array containing unsorted numeric values with indices +$unsorted_numerics = array( 100 => 4, 33 => 3, 555 => 2, 22 => 1 ); + +echo "\n-- Testing ksort() by supplying string array, 'flag' value is default --\n"; +$temp_array = $unsorted_strings; +var_dump( ksort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing ksort() by supplying numeric array, 'flag' value is default --\n"; +$temp_array = $unsorted_numerics; +var_dump( ksort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing ksort() by supplying string array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_strings; +var_dump( ksort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing ksort() by supplying numeric array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_numerics; +var_dump( ksort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing ksort() by supplying string array, 'flag' = SORT_STRING --\n"; +$temp_array = $unsorted_strings; +var_dump( ksort($temp_array, SORT_STRING) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing ksort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( ksort($temp_array, SORT_STRING|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing ksort() by supplying string array (natural), 'flag' = SORT_NATURAL --\n"; +$temp_array = $unsorted_strings; +var_dump( ksort($temp_array, SORT_NATURAL) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing ksort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( ksort($temp_array, SORT_NATURAL|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing ksort() by supplying numeric array, 'flag' = SORT_NUMERIC --\n"; +$temp_array = $unsorted_numerics; +var_dump( ksort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing ksort() : basic functionality *** + +-- Testing ksort() by supplying string array, 'flag' value is default -- +bool(true) +array(8) { + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["O3"]=> + string(7) "Orange3" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" +} + +-- Testing ksort() by supplying numeric array, 'flag' value is default -- +bool(true) +array(4) { + [22]=> + int(1) + [33]=> + int(3) + [100]=> + int(4) + [555]=> + int(2) +} + +-- Testing ksort() by supplying string array, 'flag' = SORT_REGULAR -- +bool(true) +array(8) { + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["O3"]=> + string(7) "Orange3" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" +} + +-- Testing ksort() by supplying numeric array, 'flag' = SORT_REGULAR -- +bool(true) +array(4) { + [22]=> + int(1) + [33]=> + int(3) + [100]=> + int(4) + [555]=> + int(2) +} + +-- Testing ksort() by supplying string array, 'flag' = SORT_STRING -- +bool(true) +array(8) { + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["O3"]=> + string(7) "Orange3" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" +} + +-- Testing ksort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE -- +bool(true) +array(8) { + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" + ["O3"]=> + string(7) "Orange3" +} + +-- Testing ksort() by supplying string array (natural), 'flag' = SORT_NATURAL -- +bool(true) +array(8) { + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["O3"]=> + string(7) "Orange3" + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["o2"]=> + string(7) "orange2" + ["o20"]=> + string(8) "orange20" +} + +-- Testing ksort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE -- +bool(true) +array(8) { + ["b"]=> + string(6) "banana" + ["l"]=> + string(5) "lemon" + ["o"]=> + string(6) "orange" + ["O"]=> + string(6) "Orange" + ["O1"]=> + string(7) "Orange1" + ["o2"]=> + string(7) "orange2" + ["O3"]=> + string(7) "Orange3" + ["o20"]=> + string(8) "orange20" +} + +-- Testing ksort() by supplying numeric array, 'flag' = SORT_NUMERIC -- +bool(true) +array(4) { + [22]=> + int(1) + [33]=> + int(3) + [100]=> + int(4) + [555]=> + int(2) +} +Done diff --git a/tests/std/array/ksort_object.phpt b/tests/std/array/ksort_object.phpt new file mode 100644 index 00000000..86e2d6b4 --- /dev/null +++ b/tests/std/array/ksort_object.phpt @@ -0,0 +1,220 @@ +--TEST-- +Test ksort() function : object functionality - sort objects +--FILE-- +class_value = $value; + } +} +// class declaration for string objects +class StringObject +{ + public $class_value; + // initializing object member value + function __construct($value) + { + $this->class_value = $value; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * testing ksort() by providing array ofinteger/string objects with following flag values: + * 1.SORT_NUMERIC - compare items numerically + * 2.SORT_STRING - compare items as strings + */ + echo "*** Testing ksort() : object functionality ***\n"; + // array of integer objects + $unsorted_int_obj = array(11 => new IntegerObject(11), 66 => new IntegerObject(66), 23 => new IntegerObject(23), -5 => new IntegerObject(-5), 1 => new IntegerObject(0.001), 0 => new IntegerObject(0)); + // array of string objects + $unsorted_str_obj = array("axx" => new StringObject("axx"), "t" => new StringObject("t"), "w" => new StringObject("w"), "py" => new StringObject("py"), "apple" => new StringObject("apple"), "Orange" => new StringObject("Orange"), "Lemon" => new StringObject("Lemon"), "aPPle" => new StringObject("aPPle")); + echo "\n-- Testing ksort() by supplying various object arrays, 'flag' value is default --\n"; + // testing ksort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(ksort($temp_array)); + var_dump($temp_array); + // testing ksort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(ksort($temp_array)); + var_dump($temp_array); + echo "\n-- Testing ksort() by supplying various object arrays, 'flag' value is SORT_REGULAR --\n"; + // testing ksort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(ksort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing ksort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(ksort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done\n"; +} +?> +--EXPECTF-- +*** Testing ksort() : object functionality *** + +-- Testing ksort() by supplying various object arrays, 'flag' value is default -- +bool(true) +array(6) { + [-5]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(-5) + } + [0]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(0) + } + [1]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + float(0.001) + } + [11]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(11) + } + [23]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(23) + } + [66]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(66) + } +} +bool(true) +array(8) { + ["Lemon"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } + ["Orange"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + ["aPPle"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + ["apple"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + ["axx"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + ["py"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(2) "py" + } + ["t"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(1) "t" + } + ["w"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(1) "w" + } +} + +-- Testing ksort() by supplying various object arrays, 'flag' value is SORT_REGULAR -- +bool(true) +array(6) { + [-5]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(-5) + } + [0]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(0) + } + [1]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + float(0.001) + } + [11]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(11) + } + [23]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(23) + } + [66]=> + object(IntegerObject)#%d (1) { + ["class_value"]=> + int(66) + } +} +bool(true) +array(8) { + ["Lemon"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } + ["Orange"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + ["aPPle"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + ["apple"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + ["axx"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + ["py"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(2) "py" + } + ["t"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(1) "t" + } + ["w"]=> + object(StringObject)#%d (1) { + ["class_value"]=> + string(1) "w" + } +} +Done diff --git a/tests/std/array/ksort_variation10.phpt b/tests/std/array/ksort_variation10.phpt new file mode 100644 index 00000000..6d151b92 --- /dev/null +++ b/tests/std/array/ksort_variation10.phpt @@ -0,0 +1,108 @@ +--TEST-- +Test ksort() function : usage variations - sort octal values +--FILE-- + 01, 0321 => 02, 0345 => 03, 066 => 04, 0772 => 05, + 077 => 06, -066 => -01, -0345 => -02, 0 => 0 +); + +echo "\n-- Testing ksort() by supplying octal value array, 'flag' value is default --\n"; +$temp_array = $unsorted_oct_array; +var_dump( ksort($temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying octal value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $unsorted_oct_array; +var_dump( ksort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying octal value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $unsorted_oct_array; +var_dump( ksort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing ksort() : usage variations *** + +-- Testing ksort() by supplying octal value array, 'flag' value is default -- +bool(true) +array(9) { + [-229]=> + int(-2) + [-54]=> + int(-1) + [0]=> + int(0) + [54]=> + int(4) + [63]=> + int(6) + [209]=> + int(2) + [229]=> + int(3) + [506]=> + int(5) + [669]=> + int(1) +} + +-- Testing ksort() by supplying octal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(9) { + [-229]=> + int(-2) + [-54]=> + int(-1) + [0]=> + int(0) + [54]=> + int(4) + [63]=> + int(6) + [209]=> + int(2) + [229]=> + int(3) + [506]=> + int(5) + [669]=> + int(1) +} + +-- Testing ksort() by supplying octal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(9) { + [-229]=> + int(-2) + [-54]=> + int(-1) + [0]=> + int(0) + [54]=> + int(4) + [63]=> + int(6) + [209]=> + int(2) + [229]=> + int(3) + [506]=> + int(5) + [669]=> + int(1) +} +Done diff --git a/tests/std/array/ksort_variation11.phpt b/tests/std/array/ksort_variation11.phpt new file mode 100644 index 00000000..59b18aa6 --- /dev/null +++ b/tests/std/array/ksort_variation11.phpt @@ -0,0 +1,93 @@ +--TEST-- +Test ksort() function : usage variations - sort heredoc strings +--FILE-- + "Heredoc", + $simple_heredoc2 => "HEREDOC", + $multiline_heredoc => "heredoc string\twith!@# and 123\nTest this!!!" +); + +echo "\n-- Testing ksort() by supplying heredoc string array, 'flag' value is default --\n"; +$temp_array = $array; +var_dump(ksort($temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying heredoc string array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $array; +var_dump(ksort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying heredoc string array, 'flag' = SORT_STRING --\n"; +$temp_array = $array; +var_dump(ksort($temp_array, SORT_STRING) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing ksort() : usage variations *** + +-- Testing ksort() by supplying heredoc string array, 'flag' value is default -- +bool(true) +array(3) { + ["HEREDOC"]=> + string(7) "HEREDOC" + ["Heredoc"]=> + string(7) "Heredoc" + ["heredoc string with!@# and 123 +Test this!!!"]=> + string(43) "heredoc string with!@# and 123 +Test this!!!" +} + +-- Testing ksort() by supplying heredoc string array, 'flag' = SORT_REGULAR -- +bool(true) +array(3) { + ["HEREDOC"]=> + string(7) "HEREDOC" + ["Heredoc"]=> + string(7) "Heredoc" + ["heredoc string with!@# and 123 +Test this!!!"]=> + string(43) "heredoc string with!@# and 123 +Test this!!!" +} + +-- Testing ksort() by supplying heredoc string array, 'flag' = SORT_STRING -- +bool(true) +array(3) { + ["HEREDOC"]=> + string(7) "HEREDOC" + ["Heredoc"]=> + string(7) "Heredoc" + ["heredoc string with!@# and 123 +Test this!!!"]=> + string(43) "heredoc string with!@# and 123 +Test this!!!" +} +Done diff --git a/tests/std/array/ksort_variation3.phpt b/tests/std/array/ksort_variation3.phpt new file mode 100644 index 00000000..35954ba6 --- /dev/null +++ b/tests/std/array/ksort_variation3.phpt @@ -0,0 +1,204 @@ +--TEST-- +Test ksort() function : usage variations - sort integer/float values +--FILE-- + 11, -2 => -11, 3 => 21, -4 => -21, 5 => 31, -6 => -31, 7 => 0, 8 => 41, -10 =>-41), + + // mixed value array with different types of keys + array(1 => .0001, 2 => .0021, -3 => -.01, 4 => -1, 5 => 0, 6 => .09, 7 => 2, -8 => -.9, + 9 => 10.6E-2, -10 => -10.6E-2, 11 => 33) +); + +// set of possible flag values +$flags = array("SORT_REGULAR" => SORT_REGULAR, "SORT_NUMERIC" => SORT_NUMERIC); + +$count = 1; +echo "\n-- Testing ksort() by supplying various integer/float arrays --\n"; + +// loop through to test ksort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort flag -\n"; + $temp_array = $array; + var_dump(ksort($temp_array) ); + var_dump($temp_array); + + // loop through $flags array and call ksort() with all possible sort flag values + foreach($flags as $key => $flag){ + echo "- Sort flag = $key -\n"; + $temp_array = $array; + var_dump(ksort($temp_array, $flag) ); + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing ksort() : usage variations *** + +-- Testing ksort() by supplying various integer/float arrays -- + +-- Iteration 1 -- +- With default sort flag - +bool(true) +array(9) { + [-10]=> + int(-41) + [-6]=> + int(-31) + [-4]=> + int(-21) + [-2]=> + int(-11) + [1]=> + int(11) + [3]=> + int(21) + [5]=> + int(31) + [7]=> + int(0) + [8]=> + int(41) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(9) { + [-10]=> + int(-41) + [-6]=> + int(-31) + [-4]=> + int(-21) + [-2]=> + int(-11) + [1]=> + int(11) + [3]=> + int(21) + [5]=> + int(31) + [7]=> + int(0) + [8]=> + int(41) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(9) { + [-10]=> + int(-41) + [-6]=> + int(-31) + [-4]=> + int(-21) + [-2]=> + int(-11) + [1]=> + int(11) + [3]=> + int(21) + [5]=> + int(31) + [7]=> + int(0) + [8]=> + int(41) +} + +-- Iteration 2 -- +- With default sort flag - +bool(true) +array(11) { + [-10]=> + float(-0.106) + [-8]=> + float(-0.9) + [-3]=> + float(-0.01) + [1]=> + float(0.0001) + [2]=> + float(0.0021) + [4]=> + int(-1) + [5]=> + int(0) + [6]=> + float(0.09) + [7]=> + int(2) + [9]=> + float(0.106) + [11]=> + int(33) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(11) { + [-10]=> + float(-0.106) + [-8]=> + float(-0.9) + [-3]=> + float(-0.01) + [1]=> + float(0.0001) + [2]=> + float(0.0021) + [4]=> + int(-1) + [5]=> + int(0) + [6]=> + float(0.09) + [7]=> + int(2) + [9]=> + float(0.106) + [11]=> + int(33) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(11) { + [-10]=> + float(-0.106) + [-8]=> + float(-0.9) + [-3]=> + float(-0.01) + [1]=> + float(0.0001) + [2]=> + float(0.0021) + [4]=> + int(-1) + [5]=> + int(0) + [6]=> + float(0.09) + [7]=> + int(2) + [9]=> + float(0.106) + [11]=> + int(33) +} +Done diff --git a/tests/std/array/ksort_variation4.phpt b/tests/std/array/ksort_variation4.phpt new file mode 100644 index 00000000..30dc42bf --- /dev/null +++ b/tests/std/array/ksort_variation4.phpt @@ -0,0 +1,77 @@ +--TEST-- +Test ksort() function : usage variations - sort bool values +--SKIPIF-- +--FILE-- + true, false => false, TRUE => TRUE, FALSE => FALSE); + +echo "\n-- Testing ksort() by supplying boolean value array, 'flag' value is default --\n"; +$temp_array = $bool_values; +var_dump(ksort($temp_array) ); +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying boolean value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $bool_values; +var_dump(ksort($temp_array, SORT_REGULAR) ); +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying boolean value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $bool_values; +var_dump(ksort($temp_array, SORT_NUMERIC) ); +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying boolean value array, 'flag' value is SORT_STRING --\n"; +$temp_array = $bool_values; +var_dump(ksort($temp_array, SORT_STRING) ); +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing ksort() : usage variations *** + +-- Testing ksort() by supplying boolean value array, 'flag' value is default -- +bool(true) +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} + +-- Testing ksort() by supplying boolean value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} + +-- Testing ksort() by supplying boolean value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} + +-- Testing ksort() by supplying boolean value array, 'flag' value is SORT_STRING -- +bool(true) +array(2) { + [0]=> + bool(false) + [1]=> + bool(true) +} +Done diff --git a/tests/std/array/ksort_variation5.phpt b/tests/std/array/ksort_variation5.phpt new file mode 100644 index 00000000..b948ddbd --- /dev/null +++ b/tests/std/array/ksort_variation5.phpt @@ -0,0 +1,227 @@ +--TEST-- +Test ksort() function : usage variations - sort strings +--SKIPIF-- + +--FILE-- + null, NULL => NULL, "\a" => "\a", "\cx" => "\cx", "\e" => "\e", + "\f" => "\f", "\n" =>"\n", "\r" => "\r", "\t" => "\t", "\xhh" => "\xhh", + "\ddd" => "\ddd", "\v" => "\v" + ), + + // array containing different strings with key values + array ( 'Lemon' => "lemoN", 'o' => "Orange", 'B' => "banana", 'Apple' => "apple", 'te' => "Test", + 't' => "TTTT", 'T' => "ttt", 'W' => "ww", 'X' => "x", 'x' => "X", 'O' => "oraNGe", + 'B' => "BANANA" + ) +); + +$flags = array("SORT_REGULAR" => SORT_REGULAR, "SORT_STRING" => SORT_STRING); + +$count = 1; +echo "\n-- Testing ksort() by supplying various string arrays --\n"; + +// loop through to test ksort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort flag -\n"; + $temp_array = $array; + var_dump(ksort($temp_array) ); // expecting : bool(true) + var_dump($temp_array); + + // loop through $flags array and call ksort() with all possible sort flag values + foreach($flags as $key => $flag){ + echo "- Sort flag = $key -\n"; + $temp_array = $array; + var_dump(ksort($temp_array, $flag) ); // expecting : bool(true) + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing ksort() : usage variations *** + +-- Testing ksort() by supplying various string arrays -- + +-- Iteration 1 -- +- With default sort flag - +bool(true) +array(11) { + [""]=> + NULL + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [""]=> + string(1) "" + ["\a"]=> + string(2) "\a" + ["\cx"]=> + string(3) "\cx" + ["\ddd"]=> + string(4) "\ddd" + ["\xhh"]=> + string(4) "\xhh" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(11) { + [""]=> + NULL + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [""]=> + string(1) "" + ["\a"]=> + string(2) "\a" + ["\cx"]=> + string(3) "\cx" + ["\ddd"]=> + string(4) "\ddd" + ["\xhh"]=> + string(4) "\xhh" +} +- Sort flag = SORT_STRING - +bool(true) +array(11) { + [""]=> + NULL + [" "]=> + string(1) " " + [" +"]=> + string(1) " +" + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [" "]=> + string(1) " " + [""]=> + string(1) "" + ["\a"]=> + string(2) "\a" + ["\cx"]=> + string(3) "\cx" + ["\ddd"]=> + string(4) "\ddd" + ["\xhh"]=> + string(4) "\xhh" +} + +-- Iteration 2 -- +- With default sort flag - +bool(true) +array(11) { + ["Apple"]=> + string(5) "apple" + ["B"]=> + string(6) "BANANA" + ["Lemon"]=> + string(5) "lemoN" + ["O"]=> + string(6) "oraNGe" + ["T"]=> + string(3) "ttt" + ["W"]=> + string(2) "ww" + ["X"]=> + string(1) "x" + ["o"]=> + string(6) "Orange" + ["t"]=> + string(4) "TTTT" + ["te"]=> + string(4) "Test" + ["x"]=> + string(1) "X" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(11) { + ["Apple"]=> + string(5) "apple" + ["B"]=> + string(6) "BANANA" + ["Lemon"]=> + string(5) "lemoN" + ["O"]=> + string(6) "oraNGe" + ["T"]=> + string(3) "ttt" + ["W"]=> + string(2) "ww" + ["X"]=> + string(1) "x" + ["o"]=> + string(6) "Orange" + ["t"]=> + string(4) "TTTT" + ["te"]=> + string(4) "Test" + ["x"]=> + string(1) "X" +} +- Sort flag = SORT_STRING - +bool(true) +array(11) { + ["Apple"]=> + string(5) "apple" + ["B"]=> + string(6) "BANANA" + ["Lemon"]=> + string(5) "lemoN" + ["O"]=> + string(6) "oraNGe" + ["T"]=> + string(3) "ttt" + ["W"]=> + string(2) "ww" + ["X"]=> + string(1) "x" + ["o"]=> + string(6) "Orange" + ["t"]=> + string(4) "TTTT" + ["te"]=> + string(4) "Test" + ["x"]=> + string(1) "X" +} +Done diff --git a/tests/std/array/ksort_variation6.phpt b/tests/std/array/ksort_variation6.phpt new file mode 100644 index 00000000..b9c35b54 --- /dev/null +++ b/tests/std/array/ksort_variation6.phpt @@ -0,0 +1,109 @@ +--TEST-- +Test ksort() function : usage variations - sort hexadecimal values +--FILE-- + 0x1AB, 0xFFF => 0xFFF, 0xF => 0xF, 0xFF => 0xFF, 0x2AA => 0x2AA, 0xBB => 0xBB, + 0x1ab => 0x1ab, 0xff => 0xff, -0xff => -0xFF, 0 => 0, -0x2aa => -0x2aa +); + +echo "\n-- Testing ksort() by supplying hexadecimal value array, 'flag' value is default --\n"; +$temp_array = $unsorted_hex_array; +var_dump(ksort( $temp_array) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying hexadecimal value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $unsorted_hex_array; +var_dump(ksort( $temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying hexadecimal value array, 'flag' value is SORT_NUMERIC --\n"; +$temp_array = $unsorted_hex_array; +var_dump(ksort( $temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing ksort() : usage variations *** + +-- Testing ksort() by supplying hexadecimal value array, 'flag' value is default -- +bool(true) +array(9) { + [-682]=> + int(-682) + [-255]=> + int(-255) + [0]=> + int(0) + [15]=> + int(15) + [187]=> + int(187) + [255]=> + int(255) + [427]=> + int(427) + [682]=> + int(682) + [4095]=> + int(4095) +} + +-- Testing ksort() by supplying hexadecimal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(9) { + [-682]=> + int(-682) + [-255]=> + int(-255) + [0]=> + int(0) + [15]=> + int(15) + [187]=> + int(187) + [255]=> + int(255) + [427]=> + int(427) + [682]=> + int(682) + [4095]=> + int(4095) +} + +-- Testing ksort() by supplying hexadecimal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(9) { + [-682]=> + int(-682) + [-255]=> + int(-255) + [0]=> + int(0) + [15]=> + int(15) + [187]=> + int(187) + [255]=> + int(255) + [427]=> + int(427) + [682]=> + int(682) + [4095]=> + int(4095) +} +Done diff --git a/tests/std/array/ksort_variation7.phpt b/tests/std/array/ksort_variation7.phpt new file mode 100644 index 00000000..7ca42069 --- /dev/null +++ b/tests/std/array/ksort_variation7.phpt @@ -0,0 +1,172 @@ +--TEST-- +Test ksort() function : usage variations - sort array with diff. sub arrays +--FILE-- + array(), + + // array contains null sub array + 2 => array( 1 => array() ), + + // array of arrays along with some values + 3 => array(4 => 44, 1 => 11, 3 => array(64,61) ), + + // array contains sub arrays + 4 => array ( 3 => array(33,-5,6), 1 => array(11), + 2 => array(22,-55), 0 => array() ) +); + + +$count = 1; +echo "\n-- Testing ksort() by supplying various arrays containing sub arrays --\n"; + +// loop through to test ksort() with different arrays +foreach ($various_arrays as $array) { + + echo "\n-- Iteration $count --\n"; + echo "- With default sort flag -\n"; + $temp_array = $array; + var_dump( ksort($temp_array) ); + var_dump($temp_array); + + echo "- Sort flag = SORT_REGULAR -\n"; + $temp_array = $array; + var_dump( ksort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing ksort() : usage variations *** + +-- Testing ksort() by supplying various arrays containing sub arrays -- + +-- Iteration 1 -- +- With default sort flag - +bool(true) +array(0) { +} +- Sort flag = SORT_REGULAR - +bool(true) +array(0) { +} + +-- Iteration 2 -- +- With default sort flag - +bool(true) +array(1) { + [1]=> + array(0) { + } +} +- Sort flag = SORT_REGULAR - +bool(true) +array(1) { + [1]=> + array(0) { + } +} + +-- Iteration 3 -- +- With default sort flag - +bool(true) +array(3) { + [1]=> + int(11) + [3]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } + [4]=> + int(44) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(3) { + [1]=> + int(11) + [3]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } + [4]=> + int(44) +} + +-- Iteration 4 -- +- With default sort flag - +bool(true) +array(4) { + [0]=> + array(0) { + } + [1]=> + array(1) { + [0]=> + int(11) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [3]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } +} +- Sort flag = SORT_REGULAR - +bool(true) +array(4) { + [0]=> + array(0) { + } + [1]=> + array(1) { + [0]=> + int(11) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [3]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } +} +Done diff --git a/tests/std/array/ksort_variation8.phpt b/tests/std/array/ksort_variation8.phpt new file mode 100644 index 00000000..0a788726 --- /dev/null +++ b/tests/std/array/ksort_variation8.phpt @@ -0,0 +1,155 @@ +--TEST-- +Test ksort() function : usage variations - sort mixed values, 'sort_flags' as default/SORT_REGULAR (OK to fail as result is unpredectable) +--SKIPIF-- + +--FILE-- + array(), + "array2" => array ( "sub_array[2,1]" => array(33,-5,6), "sub_array[2,2]" => array(11), + "sub_array[2,3]" => array(22,-55), "sub_array[2,4]" => array() + ), + 4 => 4, "4" => "4", 4 => 4.01, "b" => "b", "5" => "5", -2 => -2, -2 => -2.01, + -2 => -2.98989, "-.9" => "-.9", "True" => "True", "" => "", NULL => NULL, + "ab" => "ab", "abcd" => "abcd", 0 => 0.01, -0 => -0, '' => '' , + "abcd\x00abcd\x00abcd" => "abcd\x00abcd\x00abcd", 0 => 0.001 +); + +echo "\n-- Testing ksort() by supplying mixed value array, 'flag' value is default --\n"; +$temp_array = $mixed_values; +var_dump( ksort($temp_array) ); +var_dump($temp_array); + +echo "\n-- Testing ksort() by supplying mixed value array, 'flag' value is SORT_REGULAR --\n"; +$temp_array = $mixed_values; +var_dump( ksort($temp_array, SORT_REGULAR) ); +var_dump($temp_array); + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing ksort() : usage variations *** + +-- Testing ksort() by supplying mixed value array, 'flag' value is default -- +bool(true) +array(13) { + [""]=> + string(0) "" + [-2]=> + float(-2.98989) + ["-.9"]=> + string(3) "-.9" + [0]=> + float(0.001) + [4]=> + float(4.01) + [5]=> + string(1) "5" + ["True"]=> + string(4) "True" + ["ab"]=> + string(2) "ab" + ["abcd"]=> + string(4) "abcd" + ["abcd%0abcd%0abcd"]=> + string(14) "abcd%0abcd%0abcd" + ["array1"]=> + array(0) { + } + ["array2"]=> + array(4) { + ["sub_array[2,1]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[2,2]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[2,3]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[2,4]"]=> + array(0) { + } + } + ["b"]=> + string(1) "b" +} + +-- Testing ksort() by supplying mixed value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(13) { + [""]=> + string(0) "" + [-2]=> + float(-2.98989) + ["-.9"]=> + string(3) "-.9" + [0]=> + float(0.001) + [4]=> + float(4.01) + [5]=> + string(1) "5" + ["True"]=> + string(4) "True" + ["ab"]=> + string(2) "ab" + ["abcd"]=> + string(4) "abcd" + ["abcd%0abcd%0abcd"]=> + string(14) "abcd%0abcd%0abcd" + ["array1"]=> + array(0) { + } + ["array2"]=> + array(4) { + ["sub_array[2,1]"]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + ["sub_array[2,2]"]=> + array(1) { + [0]=> + int(11) + } + ["sub_array[2,3]"]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + ["sub_array[2,4]"]=> + array(0) { + } + } + ["b"]=> + string(1) "b" +} +Done diff --git a/tests/std/array/ksort_variation9.phpt b/tests/std/array/ksort_variation9.phpt new file mode 100644 index 00000000..0023a9e0 --- /dev/null +++ b/tests/std/array/ksort_variation9.phpt @@ -0,0 +1,251 @@ +--TEST-- +Test ksort() function : usage variations - sorting arrays with/without keys +--FILE-- + 55, 66, 22, 33, 11), + array ("a" => "orange", "banana", "c" => "apple"), + array(1, 2, 3, 4, 5, 6), + array("first", 5 => "second", 1 => "third"), + array(1, 1, 8 => 1, 4 => 1, 19, 3 => 13), + array('bar' => 'baz', "foo" => 1), + array('a' => 1,'b' => array('e' => 2,'f' => 3),'c' => array('g' => 4),'d' => 5), +); + +$count = 1; +echo "\n-- Testing ksort() by supplying various arrays with/without key values --\n"; + +// loop through to test ksort() with different arrays, +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With default sort flag -\n"; + $temp_array = $array; + var_dump( ksort($temp_array) ); + var_dump($temp_array); + + echo "- Sort flag = SORT_REGULAR -\n"; + $temp_array = $array; + var_dump( ksort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing ksort() : usage variations *** + +-- Testing ksort() by supplying various arrays with/without key values -- + +-- Iteration 1 -- +- With default sort flag - +bool(true) +array(5) { + [5]=> + int(55) + [6]=> + int(66) + [7]=> + int(22) + [8]=> + int(33) + [9]=> + int(11) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(5) { + [5]=> + int(55) + [6]=> + int(66) + [7]=> + int(22) + [8]=> + int(33) + [9]=> + int(11) +} + +-- Iteration 2 -- +- With default sort flag - +bool(true) +array(3) { + [0]=> + string(6) "banana" + ["a"]=> + string(6) "orange" + ["c"]=> + string(5) "apple" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(3) { + [0]=> + string(6) "banana" + ["a"]=> + string(6) "orange" + ["c"]=> + string(5) "apple" +} + +-- Iteration 3 -- +- With default sort flag - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) +} + +-- Iteration 4 -- +- With default sort flag - +bool(true) +array(3) { + [0]=> + string(5) "first" + [1]=> + string(5) "third" + [5]=> + string(6) "second" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(3) { + [0]=> + string(5) "first" + [1]=> + string(5) "third" + [5]=> + string(6) "second" +} + +-- Iteration 5 -- +- With default sort flag - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(1) + [3]=> + int(13) + [4]=> + int(1) + [8]=> + int(1) + [9]=> + int(19) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(1) + [3]=> + int(13) + [4]=> + int(1) + [8]=> + int(1) + [9]=> + int(19) +} + +-- Iteration 6 -- +- With default sort flag - +bool(true) +array(2) { + ["bar"]=> + string(3) "baz" + ["foo"]=> + int(1) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(2) { + ["bar"]=> + string(3) "baz" + ["foo"]=> + int(1) +} + +-- Iteration 7 -- +- With default sort flag - +bool(true) +array(4) { + ["a"]=> + int(1) + ["b"]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } + ["c"]=> + array(1) { + ["g"]=> + int(4) + } + ["d"]=> + int(5) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(4) { + ["a"]=> + int(1) + ["b"]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } + ["c"]=> + array(1) { + ["g"]=> + int(4) + } + ["d"]=> + int(5) +} +Done diff --git a/tests/std/array/locale_sort.phpt b/tests/std/array/locale_sort.phpt new file mode 100644 index 00000000..2caccce7 --- /dev/null +++ b/tests/std/array/locale_sort.phpt @@ -0,0 +1,60 @@ +--TEST-- +Sort with SORT_LOCALE_STRING +--SKIPIF-- + +--FILE-- + "Alberta", +"BC" => "Colombie-Britannique", +"MB" => "Manitoba", +"NB" => "Nouveau-Brunswick", +"NL" => "Terre-Neuve-et-Labrador", +"NS" => "Nouvelle-cosse", +"ON" => "Ontario", +"PE" => "le-du-Prince-douard", +"QC" => "Qubec", +"SK" => "Saskatchewan", +"NT" => "Territoires du Nord-Ouest", +"NU" => "Nunavut", +"YT" => "Territoire du Yukon"); +asort($table, SORT_LOCALE_STRING); +var_dump($table); +?> +--EXPECT-- +array(13) { + ["AB"]=> + string(7) "Alberta" + ["BC"]=> + string(20) "Colombie-Britannique" + ["PE"]=> + string(21) "le-du-Prince-douard" + ["MB"]=> + string(8) "Manitoba" + ["NB"]=> + string(17) "Nouveau-Brunswick" + ["NS"]=> + string(15) "Nouvelle-cosse" + ["NU"]=> + string(7) "Nunavut" + ["ON"]=> + string(7) "Ontario" + ["QC"]=> + string(6) "Qubec" + ["SK"]=> + string(12) "Saskatchewan" + ["NL"]=> + string(23) "Terre-Neuve-et-Labrador" + ["YT"]=> + string(19) "Territoire du Yukon" + ["NT"]=> + string(25) "Territoires du Nord-Ouest" +} diff --git a/tests/std/array/max.phpt b/tests/std/array/max.phpt new file mode 100644 index 00000000..06546100 --- /dev/null +++ b/tests/std/array/max.phpt @@ -0,0 +1,45 @@ +--TEST-- +max() tests +--INI-- +precision=14 +--FILE-- +getMessage() . "\n"; +} + +try { + var_dump(max(array())); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(max(new stdclass)); +} catch (\TypeError $e) { + echo $e->getMessage() . "\n"; +} + +var_dump(max(2,1,2)); +var_dump(max(2.1,2.11,2.09)); +var_dump(max("", "t", "b")); +var_dump(max(false, true, false)); +var_dump(max(true, false, true)); +var_dump(max(1, true, false, true)); +var_dump(max(0, true, false, true)); + +?> +--EXPECT-- +max(): Argument #1 ($value) must be of type array, int given +max(): Argument #1 ($value) must contain at least one element +max(): Argument #1 ($value) must be of type array, stdClass given +int(2) +float(2.11) +string(1) "t" +bool(true) +bool(true) +int(1) +bool(true) diff --git a/tests/std/array/max_basic.phpt b/tests/std/array/max_basic.phpt new file mode 100644 index 00000000..4880e97d --- /dev/null +++ b/tests/std/array/max_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test return type and value for expected input max() +--FILE-- + +--EXPECT-- +*** Testing sequences of numbers *** +int(2) +int(2) +float(2.11) +string(1) "t" +bool(true) +bool(true) +int(1) +bool(true) +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} + +Done diff --git a/tests/std/array/max_basiclong_64bit.phpt b/tests/std/array/max_basiclong_64bit.phpt new file mode 100644 index 00000000..6d40be03 --- /dev/null +++ b/tests/std/array/max_basiclong_64bit.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test max function : 64bit long tests +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(9223372036854775807) +int(9223372036854775807) diff --git a/tests/std/array/max_int_float_optimisation.phpt b/tests/std/array/max_int_float_optimisation.phpt new file mode 100644 index 00000000..0f5df35d --- /dev/null +++ b/tests/std/array/max_int_float_optimisation.phpt @@ -0,0 +1,61 @@ +--TEST-- +Check max() optimisation for int and float types +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Start as int optimisation: +int(10) +int(10) +int(10) +int(10) +int(10) +int(10) +string(2) "15" +Check that int not representable as float works: +int(-9223372036854775807) +float(1.8446744073709552E+19) +float(INF) +Start as float optimisation: +float(10.5) +float(10.5) +float(10.5) +float(10.5) +float(10.5) +float(10.5) +string(4) "15.5" +Check that int not representable as float works: +int(-9223372036854775807) +float(1.8446744073709552E+19) +float(INF) diff --git a/tests/std/array/max_variation1.phpt b/tests/std/array/max_variation1.phpt new file mode 100644 index 00000000..a87033ce --- /dev/null +++ b/tests/std/array/max_variation1.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test variations in usage of max() +--FILE-- + +--EXPECTF-- +*** Testing boundary conditions *** +int(2147483646) +%s(2147483648) +%s(2147483648) +int(-2147483646) +int(-2147483647) +int(-2147483647) + +*** Testing large number of arguments *** +int(21) + +Done diff --git a/tests/std/array/max_variation2.phpt b/tests/std/array/max_variation2.phpt new file mode 100644 index 00000000..8577a095 --- /dev/null +++ b/tests/std/array/max_variation2.phpt @@ -0,0 +1,53 @@ +--TEST-- +Test variations in usage of max() +--FILE-- + +--EXPECTF-- +*** Testing arrays *** +int(2) +int(2) +float(2.11) +string(1) "t" +bool(true) +bool(true) +int(1) +bool(true) +array(2) { + [0]=> + int(2) + [1]=> + int(3) +} +int(2147483646) +%s(2147483648) +%s(2147483648) +int(-2147483646) +int(-2147483647) +int(-2147483647) + +Done diff --git a/tests/std/array/min.phpt b/tests/std/array/min.phpt new file mode 100644 index 00000000..97be4ad6 --- /dev/null +++ b/tests/std/array/min.phpt @@ -0,0 +1,45 @@ +--TEST-- +min() tests +--INI-- +precision=14 +--FILE-- +getMessage() . "\n"; +} + +try { + var_dump(min(array())); +} catch (\ValueError $e) { + echo $e->getMessage() . "\n"; +} + +try { + var_dump(min(new stdclass)); +} catch (\TypeError $e) { + echo $e->getMessage() . "\n"; +} + +var_dump(min(2,1,2)); +var_dump(min(2.1,2.11,2.09)); +var_dump(min("", "t", "b")); +var_dump(min(false, true, false)); +var_dump(min(true, false, true)); +var_dump(min(1, true, false, true)); +var_dump(min(0, true, false, true)); + +?> +--EXPECT-- +min(): Argument #1 ($value) must be of type array, int given +min(): Argument #1 ($value) must contain at least one element +min(): Argument #1 ($value) must be of type array, stdClass given +int(1) +float(2.09) +string(0) "" +bool(false) +bool(false) +bool(false) +int(0) diff --git a/tests/std/array/min_basic.phpt b/tests/std/array/min_basic.phpt new file mode 100644 index 00000000..6706dd90 --- /dev/null +++ b/tests/std/array/min_basic.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test return type and value for expected input min() +--FILE-- + +--EXPECT-- +*** Testing sequences of numbers *** +int(1) +int(-2) +float(2.09) +string(0) "" +bool(false) +bool(false) +bool(false) +int(0) +int(0) + +Done diff --git a/tests/std/array/min_basiclong_64bit.phpt b/tests/std/array/min_basiclong_64bit.phpt new file mode 100644 index 00000000..50e5dda1 --- /dev/null +++ b/tests/std/array/min_basiclong_64bit.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test min function : 64bit long tests +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(-9223372036854775808) +int(-9223372036854775808) diff --git a/tests/std/array/min_int_float_optimisation.phpt b/tests/std/array/min_int_float_optimisation.phpt new file mode 100644 index 00000000..e383b833 --- /dev/null +++ b/tests/std/array/min_int_float_optimisation.phpt @@ -0,0 +1,61 @@ +--TEST-- +Check min() optimisation for int and float types +--SKIPIF-- + +--FILE-- + +--EXPECT-- +Start as int optimisation: +int(2) +int(2) +int(2) +int(2) +int(2) +int(2) +string(1) "1" +Check that int not representable as float works: +int(9223372036854775806) +float(-1.8446744073709552E+19) +int(9223372036854775806) +Start as float optimisation: +float(2.5) +float(2.5) +float(2.5) +float(2.5) +float(2.5) +float(2.5) +string(3) "1.5" +Check that int not representable as float works: +int(9223372036854775806) +float(-1.8446744073709552E+19) +int(9223372036854775806) diff --git a/tests/std/array/min_variation1.phpt b/tests/std/array/min_variation1.phpt new file mode 100644 index 00000000..d09b2196 --- /dev/null +++ b/tests/std/array/min_variation1.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test variations in usage of min() +--FILE-- + +--EXPECTF-- +*** Testing boundary conditions *** +int(2147483645) +int(2147483647) +int(2147483646) +int(-2147483647) +%s(-2147483648) +%s(-2147483649) + +*** Testing large number of arguments *** +int(0) + +Done diff --git a/tests/std/array/min_variation2.phpt b/tests/std/array/min_variation2.phpt new file mode 100644 index 00000000..44acde72 --- /dev/null +++ b/tests/std/array/min_variation2.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test variations in usage of min() +--FILE-- + +--EXPECTF-- +*** Testing arrays *** +int(1) +int(-2) +float(2.09) +string(0) "" +bool(false) +bool(false) +bool(false) +int(0) +int(0) +int(2147483645) +int(2147483647) +int(2147483646) +int(-2147483647) +%s(-2147483648) +%s(-2147483649) + +Done diff --git a/tests/std/array/natcasesort_basic.phpt b/tests/std/array/natcasesort_basic.phpt new file mode 100644 index 00000000..8891d0bb --- /dev/null +++ b/tests/std/array/natcasesort_basic.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test natcasesort() function : basic functionality +--FILE-- + +--EXPECT-- +*** Testing natcasesort() : basic functionality *** + +-- Before sorting: -- +array(5) { + [0]=> + string(3) "A01" + [1]=> + string(2) "a1" + [2]=> + string(3) "b10" + [3]=> + string(3) "a01" + [4]=> + string(3) "b01" +} + +-- After Sorting: -- +bool(true) +array(5) { + [0]=> + string(3) "A01" + [3]=> + string(3) "a01" + [1]=> + string(2) "a1" + [4]=> + string(3) "b01" + [2]=> + string(3) "b10" +} +Done diff --git a/tests/std/array/natcasesort_object1.phpt b/tests/std/array/natcasesort_object1.phpt new file mode 100644 index 00000000..5014b8f3 --- /dev/null +++ b/tests/std/array/natcasesort_object1.phpt @@ -0,0 +1,81 @@ +--TEST-- +Test natcasesort() function : object functionality - array of objects +--FILE-- +class_value = $value; + } + // return string value + function __tostring(): string { + return (string) $this->class_value; + } +} +function main() +{ + /* + * Pass natcasesort() an array of objects to test how it re-orders them + */ + echo "*** Testing natcasesort() : object functionality ***\n"; + // array of string objects + $unsorted_str_obj = array(new for_string_natcasesort("axx"), new for_string_natcasesort("t"), new for_string_natcasesort("w"), new for_string_natcasesort("py"), new for_string_natcasesort("apple"), new for_string_natcasesort("Orange"), new for_string_natcasesort("Lemon"), new for_string_natcasesort("aPPle")); + echo "\n-- Testing natcasesort() by supplying various object arrays --\n"; + // testing natcasesort() function by supplying string object array + var_dump(natcasesort($unsorted_str_obj)); + var_dump($unsorted_str_obj); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing natcasesort() : object functionality *** + +-- Testing natcasesort() by supplying various object arrays -- +bool(true) +array(8) { + [4]=> + object(for_string_natcasesort)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + [7]=> + object(for_string_natcasesort)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + [0]=> + object(for_string_natcasesort)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + [6]=> + object(for_string_natcasesort)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } + [5]=> + object(for_string_natcasesort)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + [3]=> + object(for_string_natcasesort)#%d (1) { + ["class_value"]=> + string(2) "py" + } + [1]=> + object(for_string_natcasesort)#%d (1) { + ["class_value"]=> + string(1) "t" + } + [2]=> + object(for_string_natcasesort)#%d (1) { + ["class_value"]=> + string(1) "w" + } +} +Done diff --git a/tests/std/array/natcasesort_object2.phpt b/tests/std/array/natcasesort_object2.phpt new file mode 100644 index 00000000..4e744a2b --- /dev/null +++ b/tests/std/array/natcasesort_object2.phpt @@ -0,0 +1,83 @@ +--TEST-- +Test natcasesort() function : object functionality - mixed visibility within objects +--FILE-- +public_class_value = $value1; + $this->private_class_value = $value2; + $this->protected_class_value = $value3; + } + // return string value + function __tostring(): string { + return (string) $this->public_class_value; + } +} +function main() +{ + /* + * Pass natcasesort() an array of objects which have properties of different + * visibilities to test how it re-orders the array. + */ + echo "*** Testing natcasesort() : object functionality ***\n"; + // array of string objects + $unsorted_str_obj = array(new for_string_natcasesort("axx", "AXX", "ass"), new for_string_natcasesort("t", "eee", "abb"), new for_string_natcasesort("w", "W", "c"), new for_string_natcasesort("py", "PY", "pt")); + echo "\n-- Testing natcasesort() by supplying object arrays --\n"; + // testing natcasesort() function by supplying string object array + $temp_array = $unsorted_str_obj; + var_dump(natcasesort($temp_array)); + var_dump($temp_array); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing natcasesort() : object functionality *** + +-- Testing natcasesort() by supplying object arrays -- +bool(true) +array(4) { + [0]=> + object(for_string_natcasesort)#%d (3) { + ["public_class_value"]=> + string(3) "axx" + ["private_class_value":"for_string_natcasesort":private]=> + string(3) "AXX" + ["protected_class_value":protected]=> + string(3) "ass" + } + [3]=> + object(for_string_natcasesort)#%d (3) { + ["public_class_value"]=> + string(2) "py" + ["private_class_value":"for_string_natcasesort":private]=> + string(2) "PY" + ["protected_class_value":protected]=> + string(2) "pt" + } + [1]=> + object(for_string_natcasesort)#%d (3) { + ["public_class_value"]=> + string(1) "t" + ["private_class_value":"for_string_natcasesort":private]=> + string(3) "eee" + ["protected_class_value":protected]=> + string(3) "abb" + } + [2]=> + object(for_string_natcasesort)#%d (3) { + ["public_class_value"]=> + string(1) "w" + ["private_class_value":"for_string_natcasesort":private]=> + string(1) "W" + ["protected_class_value":protected]=> + string(1) "c" + } +} +Done diff --git a/tests/std/array/natcasesort_variation10.phpt b/tests/std/array/natcasesort_variation10.phpt new file mode 100644 index 00000000..89d54ac8 --- /dev/null +++ b/tests/std/array/natcasesort_variation10.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test natcasesort() function : usage variations - position of internal array pointer +--FILE-- + " . current ($array_arg) . "\n"; + +echo "\n-- Call natcasesort() --\n"; +var_dump(natcasesort($array_arg)); +var_dump($array_arg); + +echo "\n-- Position of Internal Pointer in Passed Array: --\n"; +echo key($array_arg) . " => " . current ($array_arg) . "\n"; + +echo "Done"; +?> +--EXPECT-- +*** Testing natcasesort() : usage variations *** + +-- Initial Position of Internal Pointer: -- +0 => img13 + +-- Call natcasesort() -- +bool(true) +array(4) { + [3]=> + string(4) "img1" + [2]=> + string(4) "img2" + [0]=> + string(5) "img13" + [1]=> + string(5) "img20" +} + +-- Position of Internal Pointer in Passed Array: -- +3 => img1 +Done diff --git a/tests/std/array/natcasesort_variation11.phpt b/tests/std/array/natcasesort_variation11.phpt new file mode 100644 index 00000000..1a24eae0 --- /dev/null +++ b/tests/std/array/natcasesort_variation11.phpt @@ -0,0 +1,199 @@ +--TEST-- +Test natcasesort() function : usage variations - Different array keys +--SKIPIF-- + + +--FILE-- + array( + 0 => 'zero', + 1 => 'one', + 12345 => 'positive', + -2345 => 'negative', + ), + + // null data +/*4*/ 'null uppercase' => array( + NULL => 'null 1', + ), + +/*5*/ 'null lowercase' => array( + null => 'null 2', + ), + + // boolean data +/*6*/ 'bool lowercase' => array( + true => 'lowert', + false => 'lowerf', + ), + +/*7*/ 'bool uppercase' => array( + TRUE => 'uppert', + FALSE => 'upperf', + ), + + // empty data +/*8*/ 'empty double quotes' => array( + "" => 'emptyd', + ), + +/*9*/ 'empty single quotes' => array( + '' => 'emptys', + ), + + // string data +/*10*/ 'string' => array( + "stringd" => 'stringd', + 'strings' => 'strings', + $heredoc => 'stringh', + ), + + // undefined data +/*11*/ 'undefined' => array( + @$undefined_var => 'undefined', + ), + + // unset data +/*12*/ 'unset' => array( + @$unset_var => 'unset', + ), + + // duplicate values +/*13*/ 'duplicate' => array( + 'foo' => 'bar', + 'baz' => 'bar', + 'hello' => 'world' + ), + +); + +// loop through each element of $inputs to check the behavior of natcasesort() +$iterator = 1; +foreach($inputs as $input) { + echo "\n-- Iteration $iterator --\n"; + var_dump( natcasesort($input) ); + var_dump($input); + $iterator++; +}; + +echo "Done"; +?> +--EXPECT-- +*** Testing natcasesort() : usage variations *** + +-- Iteration 1 -- +bool(true) +array(4) { + [-2345]=> + string(8) "negative" + [1]=> + string(3) "one" + [12345]=> + string(8) "positive" + [0]=> + string(4) "zero" +} + +-- Iteration 2 -- +bool(true) +array(1) { + [""]=> + string(6) "null 1" +} + +-- Iteration 3 -- +bool(true) +array(1) { + [""]=> + string(6) "null 2" +} + +-- Iteration 4 -- +bool(true) +array(2) { + [0]=> + string(6) "lowerf" + [1]=> + string(6) "lowert" +} + +-- Iteration 5 -- +bool(true) +array(2) { + [0]=> + string(6) "upperf" + [1]=> + string(6) "uppert" +} + +-- Iteration 6 -- +bool(true) +array(1) { + [""]=> + string(6) "emptyd" +} + +-- Iteration 7 -- +bool(true) +array(1) { + [""]=> + string(6) "emptys" +} + +-- Iteration 8 -- +bool(true) +array(3) { + ["stringd"]=> + string(7) "stringd" + ["hello world"]=> + string(7) "stringh" + ["strings"]=> + string(7) "strings" +} + +-- Iteration 9 -- +bool(true) +array(1) { + [""]=> + string(9) "undefined" +} + +-- Iteration 10 -- +bool(true) +array(1) { + [""]=> + string(5) "unset" +} + +-- Iteration 11 -- +bool(true) +array(3) { + ["foo"]=> + string(3) "bar" + ["baz"]=> + string(3) "bar" + ["hello"]=> + string(5) "world" +} +Done diff --git a/tests/std/array/natcasesort_variation2.phpt b/tests/std/array/natcasesort_variation2.phpt new file mode 100644 index 00000000..f32c0151 --- /dev/null +++ b/tests/std/array/natcasesort_variation2.phpt @@ -0,0 +1,185 @@ +--TEST-- +Test natcasesort() function : usage variations - Pass arrays of different data types +--SKIPIF-- + + +--FILE-- + array(0, 1, 12345, -2345), + // float data + /*2*/ + 'float' => array(10.5, -10.5, 123456789000.0, 1.23456789E-9, 0.5), + // null data + /*3*/ + 'null' => array(NULL, null), + // boolean data + /*4*/ + 'bool' => array(true, false, TRUE, FALSE), + // empty data + /*5*/ + 'empty string' => array("", ''), + /*6*/ + 'empty array' => array(), + // string data + /*7*/ + 'string' => array("string", 'string', $heredoc), + // object data + /*8*/ + 'object' => array(new classA()), + // undefined data + /*9*/ + 'undefined' => array(@$undefined_var), + // unset data + /*10*/ + 'unset' => array(@$unset_var), + // resource variable + /*11*/ + 'resource' => array($fp), + ); + // loop through each element of $inputs to check the behavior of natcasesort() + $iterator = 1; + foreach ($inputs as $input) { + echo "\n-- Iteration {$iterator} --\n"; + var_dump(natcasesort($input)); + var_dump($input); + $iterator++; + } + fclose($fp); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing natcasesort() : usage variation *** + +-- Iteration 1 -- +bool(true) +array(4) { + [3]=> + int(-2345) + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(12345) +} + +-- Iteration 2 -- +bool(true) +array(5) { + [1]=> + float(-10.5) + [4]=> + float(0.5) + [3]=> + float(1.23456789E-9) + [0]=> + float(10.5) + [2]=> + float(123456789000) +} + +-- Iteration 3 -- +bool(true) +array(2) { + [0]=> + NULL + [1]=> + NULL +} + +-- Iteration 4 -- +bool(true) +array(4) { + [1]=> + bool(false) + [3]=> + bool(false) + [0]=> + bool(true) + [2]=> + bool(true) +} + +-- Iteration 5 -- +bool(true) +array(2) { + [0]=> + string(0) "" + [1]=> + string(0) "" +} + +-- Iteration 6 -- +bool(true) +array(0) { +} + +-- Iteration 7 -- +bool(true) +array(3) { + [2]=> + string(11) "hello world" + [0]=> + string(6) "string" + [1]=> + string(6) "string" +} + +-- Iteration 8 -- +bool(true) +array(1) { + [0]=> + object(classA)#%d (0) { + } +} + +-- Iteration 9 -- +bool(true) +array(1) { + [0]=> + NULL +} + +-- Iteration 10 -- +bool(true) +array(1) { + [0]=> + NULL +} + +-- Iteration 11 -- +bool(true) +array(1) { + [0]=> + resource(%d) of type (stream) +} +Done diff --git a/tests/std/array/natcasesort_variation3.phpt b/tests/std/array/natcasesort_variation3.phpt new file mode 100644 index 00000000..3cb87328 --- /dev/null +++ b/tests/std/array/natcasesort_variation3.phpt @@ -0,0 +1,129 @@ +--TEST-- +Test natcasesort() function : usage variations - different numeric types +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing natcasesort() : usage variation *** + +-- Iteration 1 -- +bool(true) +array(9) { + [1]=> + int(-11) + [3]=> + int(-21) + [5]=> + int(-31) + [8]=> + int(-41) + [6]=> + int(0) + [0]=> + int(11) + [2]=> + int(21) + [4]=> + int(31) + [7]=> + int(41) +} + +-- Iteration 1 -- +bool(true) +array(7) { + [6]=> + float(-0.1) + [1]=> + float(-10.5) + [5]=> + float(0.01) + [4]=> + float(0.5) + [3]=> + float(0.106) + [0]=> + float(10.5) + [2]=> + float(1050) +} + +-- Iteration 1 -- +bool(true) +array(11) { + [2]=> + float(-0.01) + [7]=> + float(-0.9) + [9]=> + float(-0.106) + [3]=> + int(-1) + [4]=> + int(0) + [0]=> + float(0.0001) + [1]=> + float(0.0021) + [5]=> + float(0.09) + [8]=> + float(0.106) + [6]=> + int(2) + [10]=> + int(33) +} + +-- Iteration 1 -- +bool(true) +array(7) { + [2]=> + int(-2147483647) + [3]=> + float(-2147483648) + [6]=> + float(-2147483649) + [4]=> + int(0) + [5]=> + int(0) + [0]=> + int(2147483647) + [1]=> + float(2147483648) +} +Done diff --git a/tests/std/array/natcasesort_variation4.phpt b/tests/std/array/natcasesort_variation4.phpt new file mode 100644 index 00000000..4e3477bb --- /dev/null +++ b/tests/std/array/natcasesort_variation4.phpt @@ -0,0 +1,81 @@ +--TEST-- +Test natcasesort() function : usage variations - different string types +--FILE-- + +--EXPECT-- +*** Testing natcasesort() : usage variation *** +bool(true) +array(11) { + [0]=> + NULL + [1]=> + NULL + [5]=> + string(1) " " + [6]=> + string(1) " +" + [7]=> + string(1) " " + [10]=> + string(1) " " + [4]=> + string(1) "" + [2]=> + string(2) "\a" + [3]=> + string(3) "\cx" + [9]=> + string(4) "\ddd" + [8]=> + string(4) "\xhh" +} +bool(true) +array(12) { + [3]=> + string(5) "apple" + [2]=> + string(6) "banana" + [11]=> + string(6) "BANANA" + [0]=> + string(5) "lemoN" + [1]=> + string(6) "Orange" + [10]=> + string(6) "oraNGe" + [4]=> + string(4) "Test" + [6]=> + string(3) "ttt" + [5]=> + string(4) "TTTT" + [7]=> + string(2) "ww" + [8]=> + string(1) "x" + [9]=> + string(1) "X" +} +Done diff --git a/tests/std/array/natcasesort_variation5.phpt b/tests/std/array/natcasesort_variation5.phpt new file mode 100644 index 00000000..03025f2c --- /dev/null +++ b/tests/std/array/natcasesort_variation5.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test natcasesort() function : usage variations - different hex values +--FILE-- + +--EXPECT-- +*** Testing natcasesort() : usage variation *** +bool(true) +array(11) { + [8]=> + int(-255) + [10]=> + int(-682) + [9]=> + int(0) + [2]=> + int(15) + [5]=> + int(187) + [3]=> + int(255) + [7]=> + int(255) + [0]=> + int(427) + [6]=> + int(427) + [4]=> + int(682) + [1]=> + int(4095) +} +Done diff --git a/tests/std/array/natcasesort_variation6.phpt b/tests/std/array/natcasesort_variation6.phpt new file mode 100644 index 00000000..7145f8bf --- /dev/null +++ b/tests/std/array/natcasesort_variation6.phpt @@ -0,0 +1,53 @@ +--TEST-- +Test natcasesort() function : usage variations - referenced variables +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing natcasesort() : usage variation *** + +-- Initial test -- +bool(true) +array(3) { + [1]=> + &int(33) + [0]=> + &int(100) + [2]=> + &int(555) +} + +-- Change $value1 -- +bool(true) +array(3) { + [0]=> + &int(-29) + [1]=> + &int(33) + [2]=> + &int(555) +} +Done diff --git a/tests/std/array/natcasesort_variation7.phpt b/tests/std/array/natcasesort_variation7.phpt new file mode 100644 index 00000000..70ee9e92 --- /dev/null +++ b/tests/std/array/natcasesort_variation7.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test natcasesort() function : usage variations - recursive arrays +--FILE-- + +--EXPECT-- +*** Testing natcasesort() : usage variations *** +array(5) { + [0]=> + int(1) + [1]=> + float(3) + [2]=> + string(4) "zero" + [3]=> + string(1) "2" + [4]=> + *RECURSION* +} +bool(true) +array(5) { + [0]=> + int(1) + [3]=> + string(1) "2" + [1]=> + float(3) + [4]=> + *RECURSION* + [2]=> + string(4) "zero" +} +Done diff --git a/tests/std/array/natcasesort_variation8.phpt b/tests/std/array/natcasesort_variation8.phpt new file mode 100644 index 00000000..d040f228 --- /dev/null +++ b/tests/std/array/natcasesort_variation8.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test natcasesort() function : usage variations - octal values +--FILE-- + +--EXPECT-- +*** Testing natcasesort() : usage variation *** +bool(true) +array(9) { + [6]=> + int(-54) + [7]=> + int(-229) + [8]=> + int(0) + [3]=> + int(54) + [5]=> + int(63) + [1]=> + int(209) + [2]=> + int(229) + [4]=> + int(506) + [0]=> + int(669) +} +Done diff --git a/tests/std/array/natcasesort_variation9.phpt b/tests/std/array/natcasesort_variation9.phpt new file mode 100644 index 00000000..037db9e7 --- /dev/null +++ b/tests/std/array/natcasesort_variation9.phpt @@ -0,0 +1,104 @@ +--TEST-- +Test natcasesort() function : usage variations - mixed array +--FILE-- + +--EXPECTF-- +*** Testing natcasesort() : usage variation *** +bool(true) +array(22) { + [12]=> + string(0) "" + [13]=> + NULL + [19]=> + string(0) "" + [21]=> + bool(false) + [10]=> + string(3) "-.9" + [7]=> + int(-2) + [8]=> + float(-2) + [9]=> + float(-2.98989) + [2]=> + int(-4) + [16]=> + float(0) + [17]=> + int(0) + [20]=> + bool(true) + [3]=> + string(1) "4" + [4]=> + float(4) + [6]=> + string(1) "5" + [14]=> + string(2) "ab" + [15]=> + string(4) "abcd" + [18]=> + string(14) "abcd%0abcd%0abcd" + [0]=> + array(0) { + } + [1]=> + array(4) { + [0]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + [1]=> + array(1) { + [0]=> + int(11) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [3]=> + array(0) { + } + } + [5]=> + string(1) "b" + [11]=> + string(4) "True" +} +Done diff --git a/tests/std/array/natsort_basic.phpt b/tests/std/array/natsort_basic.phpt new file mode 100644 index 00000000..555abe1a --- /dev/null +++ b/tests/std/array/natsort_basic.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test natsort(): basic functionality +--FILE-- + +--EXPECT-- +Standard sorting +Array +( + [0] => img1.png + [1] => img10.png + [2] => img12.png + [3] => img2.png +) + +Natural order sorting +Array +( + [3] => img1.png + [2] => img2.png + [1] => img10.png + [0] => img12.png +) diff --git a/tests/std/array/negative_index.phpt b/tests/std/array/negative_index.phpt new file mode 100644 index 00000000..a9f442ac --- /dev/null +++ b/tests/std/array/negative_index.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test arrays starting with negative indices +--FILE-- + true, true, true]; +$c = ["string" => true, -2 => true, true, true]; +unset($c["string"]); +$d[-2] = true; +$d[] = true; +$d[] = true; +$e = [-2 => false]; +array_pop($e); +$e[] = true; +$e[] = true; +$e[] = true; + +var_dump($a === $b && $b === $c && $c === $d && $d == $e); +var_dump($a); +?> +--EXPECT-- +bool(true) +array(3) { + [-2]=> + bool(true) + [-1]=> + bool(true) + [0]=> + bool(true) +} diff --git a/tests/std/array/negative_index_empty_array.phpt b/tests/std/array/negative_index_empty_array.phpt new file mode 100644 index 00000000..322ac6e8 --- /dev/null +++ b/tests/std/array/negative_index_empty_array.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test empty arrays with first added index being negative +--FILE-- + +--EXPECT-- +array(2) { + [-5]=> + string(2) "-5" + [-4]=> + string(8) "after -5" +} diff --git a/tests/std/array/next_basic.phpt b/tests/std/array/next_basic.phpt new file mode 100644 index 00000000..d006d7d5 --- /dev/null +++ b/tests/std/array/next_basic.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test next() function : basic functionality +--FILE-- + " . current($array) . "\n"; +var_dump(next($array)); + +echo key($array) . " => " . current($array) . "\n"; +var_dump(next($array)); + +echo key($array) . " => " . current($array) . "\n"; +var_dump(next($array)); +?> +--EXPECT-- +*** Testing next() : basic functionality *** +0 => zero +string(3) "one" +1 => one +string(3) "two" +2 => two +bool(false) diff --git a/tests/std/array/next_variation2.phpt b/tests/std/array/next_variation2.phpt new file mode 100644 index 00000000..6293652a --- /dev/null +++ b/tests/std/array/next_variation2.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test next() function : usage variation - Mulit-dimensional arrays +--FILE-- + 'z', array(9, 8, 7)); + +echo "\n-- Pass a two-dimensional array as \$array_arg --\n"; +var_dump(next($array_arg)); +var_dump(next($array_arg)); + +echo "\n-- Pass a sub-array as \$array_arg --\n"; +var_dump(next($array_arg[0])); +?> +--EXPECT-- +*** Testing next() : usage variations *** + +-- Pass a two-dimensional array as $array_arg -- +array(3) { + [0]=> + int(9) + [1]=> + int(8) + [2]=> + int(7) +} +bool(false) + +-- Pass a sub-array as $array_arg -- +int(8) diff --git a/tests/std/array/packed_001.phpt b/tests/std/array/packed_001.phpt new file mode 100644 index 00000000..7a36ed3f --- /dev/null +++ b/tests/std/array/packed_001.phpt @@ -0,0 +1,85 @@ +--TEST-- +array_keys() and array_values() w/ packed optimization +--FILE-- +1, 1=>2, 2=>3], + [1=>1, 2=>2, 3=>3], + [0=>1, 2=>3], + $x, +]; + +foreach ($inputs as $input) { + print_r(array_keys($input)); + print_r(array_values($input)); +} +?> +--EXPECT-- +Array +( +) +Array +( +) +Array +( + [0] => 0 + [1] => 1 + [2] => 2 +) +Array +( + [0] => 1 + [1] => 2 + [2] => 3 +) +Array +( + [0] => 0 + [1] => 1 + [2] => 2 +) +Array +( + [0] => 1 + [1] => 2 + [2] => 3 +) +Array +( + [0] => 1 + [1] => 2 + [2] => 3 +) +Array +( + [0] => 1 + [1] => 2 + [2] => 3 +) +Array +( + [0] => 0 + [1] => 2 +) +Array +( + [0] => 1 + [1] => 3 +) +Array +( + [0] => 0 + [1] => 2 +) +Array +( + [0] => 1 + [1] => 3 +) diff --git a/tests/std/array/prev_basic.phpt b/tests/std/array/prev_basic.phpt new file mode 100644 index 00000000..ffbafd4c --- /dev/null +++ b/tests/std/array/prev_basic.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test prev() function : basic functionality +--FILE-- + " . current($array) . "\n"; +var_dump(prev($array)); + +echo key($array) . " => " . current($array) . "\n"; +var_dump(prev($array)); + +echo key($array) . " => " . current($array) . "\n"; +var_dump(prev($array)); + +echo "\n*** Testing an array with differing values/keys ***\n"; +$array2 = array('one', 2 => "help", 3, false, 'stringkey2' => 'val2', 'stringkey1' => 'val1'); +end($array2); +$length = count($array2); +for ($i = $length; $i > 0; $i--) { + var_dump(prev($array2)); +} + +?> +--EXPECT-- +*** Testing prev() : basic functionality *** +2 => two +string(3) "one" +1 => one +string(4) "zero" +0 => zero +bool(false) + +*** Testing an array with differing values/keys *** +string(4) "val2" +bool(false) +int(3) +string(4) "help" +string(3) "one" +bool(false) diff --git a/tests/std/array/prev_error2.phpt b/tests/std/array/prev_error2.phpt new file mode 100644 index 00000000..6d9457f8 --- /dev/null +++ b/tests/std/array/prev_error2.phpt @@ -0,0 +1,26 @@ +--TEST-- +prev - ensure warning is received when passing an indirect temporary. +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +-- Passing an indirect temporary variable -- + +Notice: Only variables should be passed by reference in %s on line %d +int(1) diff --git a/tests/std/array/prev_error3.phpt b/tests/std/array/prev_error3.phpt new file mode 100644 index 00000000..807de141 --- /dev/null +++ b/tests/std/array/prev_error3.phpt @@ -0,0 +1,18 @@ +--TEST-- +prev - ensure we cannot pass a temporary +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught Error: prev(): Argument #1 ($array) could not be passed by reference in %s:%d +Stack trace: +#0 {main} + thrown in %s on line %d diff --git a/tests/std/array/prev_variation2.phpt b/tests/std/array/prev_variation2.phpt new file mode 100644 index 00000000..dd7f9b63 --- /dev/null +++ b/tests/std/array/prev_variation2.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test prev() function : usage variation - Multi-dimensional arrays +--FILE-- + 'z'); +end($array_arg); + +echo "\n-- Pass a two-dimensional array as \$array_arg --\n"; +var_dump(prev($array_arg)); +var_dump(prev($array_arg)); + +echo "\n-- Pass a sub-array as \$array_arg --\n"; +var_dump(prev($array_arg[0])); +?> +--EXPECT-- +*** Testing prev() : usage variations *** + +-- Pass a two-dimensional array as $array_arg -- +array(3) { + [0]=> + int(9) + [1]=> + int(8) + [2]=> + int(7) +} +bool(false) + +-- Pass a sub-array as $array_arg -- +int(8) diff --git a/tests/std/array/range/bug21182.phpt b/tests/std/array/range/bug21182.phpt new file mode 100644 index 00000000..af4602ab --- /dev/null +++ b/tests/std/array/range/bug21182.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #21182 (range modifies arguments) +--FILE-- + +--EXPECT-- +a1: 20 +a2: 20 : type : string diff --git a/tests/std/array/range/bug24220.phpt b/tests/std/array/range/bug24220.phpt new file mode 100644 index 00000000..018296aa --- /dev/null +++ b/tests/std/array/range/bug24220.phpt @@ -0,0 +1,91 @@ +--TEST-- +Bug #24220 (range() numeric string handling) +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + int(2003) + [1]=> + int(2004) +} +array(26) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "d" + [4]=> + string(1) "e" + [5]=> + string(1) "f" + [6]=> + string(1) "g" + [7]=> + string(1) "h" + [8]=> + string(1) "i" + [9]=> + string(1) "j" + [10]=> + string(1) "k" + [11]=> + string(1) "l" + [12]=> + string(1) "m" + [13]=> + string(1) "n" + [14]=> + string(1) "o" + [15]=> + string(1) "p" + [16]=> + string(1) "q" + [17]=> + string(1) "r" + [18]=> + string(1) "s" + [19]=> + string(1) "t" + [20]=> + string(1) "u" + [21]=> + string(1) "v" + [22]=> + string(1) "w" + [23]=> + string(1) "x" + [24]=> + string(1) "y" + [25]=> + string(1) "z" +} +array(10) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) +} diff --git a/tests/std/array/range/bug32021.phpt b/tests/std/array/range/bug32021.phpt new file mode 100644 index 00000000..a555b964 --- /dev/null +++ b/tests/std/array/range/bug32021.phpt @@ -0,0 +1,18 @@ +--TEST-- +Bug #32021 (Crash caused by range('', 'z')) +--SKIPIF-- +--FILE-- + +--EXPECTF-- +%s: Argument #1 ($start) must not be empty, casted to 0 in %s on line %d + +%s: Argument #1 ($start) must be a single byte string if argument #2 ($end) is a single byte string, argument #2 ($end) converted to 0 in %s on line %d +array(1) { + [0]=> + int(0) +} +DONE diff --git a/tests/std/array/range/bug41121.phpt b/tests/std/array/range/bug41121.phpt new file mode 100644 index 00000000..b2d133ef --- /dev/null +++ b/tests/std/array/range/bug41121.phpt @@ -0,0 +1,128 @@ +--TEST-- +Bug #41121 (range() overflow handling for large numbers on 32bit machines) +--INI-- +precision=14 +--SKIPIF-- + +--FILE-- + high +var_dump(range(2147483647, 2147483645, 1 )); +var_dump(range(2147483648, 2147483645, 1 )); + +?> +--EXPECT-- +array(3) { + [0]=> + int(2147483400) + [1]=> + int(2147483500) + [2]=> + int(2147483600) +} +array(3) { + [0]=> + float(2147483646) + [1]=> + float(2147483647) + [2]=> + float(2147483648) +} +array(12) { + [0]=> + float(2147483646) + [1]=> + float(2147483647) + [2]=> + float(2147483648) + [3]=> + float(2147483649) + [4]=> + float(2147483650) + [5]=> + float(2147483651) + [6]=> + float(2147483652) + [7]=> + float(2147483653) + [8]=> + float(2147483654) + [9]=> + float(2147483655) + [10]=> + float(2147483656) + [11]=> + float(2147483657) +} +array(4) { + [0]=> + int(2147483630) + [1]=> + int(2147483635) + [2]=> + int(2147483640) + [3]=> + int(2147483645) +} +array(4) { + [0]=> + float(-2147483645) + [1]=> + float(-2147483646) + [2]=> + float(-2147483647) + [3]=> + float(-2147483648) +} +array(5) { + [0]=> + float(-2147483645) + [1]=> + float(-2147483646) + [2]=> + float(-2147483647) + [3]=> + float(-2147483648) + [4]=> + float(-2147483649) +} +array(4) { + [0]=> + int(-2147483630) + [1]=> + int(-2147483635) + [2]=> + int(-2147483640) + [3]=> + int(-2147483645) +} +array(3) { + [0]=> + int(2147483647) + [1]=> + int(2147483646) + [2]=> + int(2147483645) +} +array(4) { + [0]=> + float(2147483648) + [1]=> + float(2147483647) + [2]=> + float(2147483646) + [3]=> + float(2147483645) +} diff --git a/tests/std/array/range/bug54459.phpt b/tests/std/array/range/bug54459.phpt new file mode 100644 index 00000000..9eed6dea --- /dev/null +++ b/tests/std/array/range/bug54459.phpt @@ -0,0 +1,219 @@ +--TEST-- +Bug #54459 (Range function accuracy) +--INI-- +precision=14 +--SKIPIF-- + +--FILE-- + $v){ + echo $i, ' = ', $v, PHP_EOL; +} +foreach (range("90", "100", .1) as $i => $v){ + echo $i, ' = ', $v, PHP_EOL; +} +?> +--EXPECT-- +0 = 90 +1 = 90.1 +2 = 90.2 +3 = 90.3 +4 = 90.4 +5 = 90.5 +6 = 90.6 +7 = 90.7 +8 = 90.8 +9 = 90.9 +10 = 91 +11 = 91.1 +12 = 91.2 +13 = 91.3 +14 = 91.4 +15 = 91.5 +16 = 91.6 +17 = 91.7 +18 = 91.8 +19 = 91.9 +20 = 92 +21 = 92.1 +22 = 92.2 +23 = 92.3 +24 = 92.4 +25 = 92.5 +26 = 92.6 +27 = 92.7 +28 = 92.8 +29 = 92.9 +30 = 93 +31 = 93.1 +32 = 93.2 +33 = 93.3 +34 = 93.4 +35 = 93.5 +36 = 93.6 +37 = 93.7 +38 = 93.8 +39 = 93.9 +40 = 94 +41 = 94.1 +42 = 94.2 +43 = 94.3 +44 = 94.4 +45 = 94.5 +46 = 94.6 +47 = 94.7 +48 = 94.8 +49 = 94.9 +50 = 95 +51 = 95.1 +52 = 95.2 +53 = 95.3 +54 = 95.4 +55 = 95.5 +56 = 95.6 +57 = 95.7 +58 = 95.8 +59 = 95.9 +60 = 96 +61 = 96.1 +62 = 96.2 +63 = 96.3 +64 = 96.4 +65 = 96.5 +66 = 96.6 +67 = 96.7 +68 = 96.8 +69 = 96.9 +70 = 97 +71 = 97.1 +72 = 97.2 +73 = 97.3 +74 = 97.4 +75 = 97.5 +76 = 97.6 +77 = 97.7 +78 = 97.8 +79 = 97.9 +80 = 98 +81 = 98.1 +82 = 98.2 +83 = 98.3 +84 = 98.4 +85 = 98.5 +86 = 98.6 +87 = 98.7 +88 = 98.8 +89 = 98.9 +90 = 99 +91 = 99.1 +92 = 99.2 +93 = 99.3 +94 = 99.4 +95 = 99.5 +96 = 99.6 +97 = 99.7 +98 = 99.8 +99 = 99.9 +100 = 100 +0 = 90 +1 = 90.1 +2 = 90.2 +3 = 90.3 +4 = 90.4 +5 = 90.5 +6 = 90.6 +7 = 90.7 +8 = 90.8 +9 = 90.9 +10 = 91 +11 = 91.1 +12 = 91.2 +13 = 91.3 +14 = 91.4 +15 = 91.5 +16 = 91.6 +17 = 91.7 +18 = 91.8 +19 = 91.9 +20 = 92 +21 = 92.1 +22 = 92.2 +23 = 92.3 +24 = 92.4 +25 = 92.5 +26 = 92.6 +27 = 92.7 +28 = 92.8 +29 = 92.9 +30 = 93 +31 = 93.1 +32 = 93.2 +33 = 93.3 +34 = 93.4 +35 = 93.5 +36 = 93.6 +37 = 93.7 +38 = 93.8 +39 = 93.9 +40 = 94 +41 = 94.1 +42 = 94.2 +43 = 94.3 +44 = 94.4 +45 = 94.5 +46 = 94.6 +47 = 94.7 +48 = 94.8 +49 = 94.9 +50 = 95 +51 = 95.1 +52 = 95.2 +53 = 95.3 +54 = 95.4 +55 = 95.5 +56 = 95.6 +57 = 95.7 +58 = 95.8 +59 = 95.9 +60 = 96 +61 = 96.1 +62 = 96.2 +63 = 96.3 +64 = 96.4 +65 = 96.5 +66 = 96.6 +67 = 96.7 +68 = 96.8 +69 = 96.9 +70 = 97 +71 = 97.1 +72 = 97.2 +73 = 97.3 +74 = 97.4 +75 = 97.5 +76 = 97.6 +77 = 97.7 +78 = 97.8 +79 = 97.9 +80 = 98 +81 = 98.1 +82 = 98.2 +83 = 98.3 +84 = 98.4 +85 = 98.5 +86 = 98.6 +87 = 98.7 +88 = 98.8 +89 = 98.9 +90 = 99 +91 = 99.1 +92 = 99.2 +93 = 99.3 +94 = 99.4 +95 = 99.5 +96 = 99.6 +97 = 99.7 +98 = 99.8 +99 = 99.9 +100 = 100 diff --git a/tests/std/array/range/gh13094.phpt b/tests/std/array/range/gh13094.phpt new file mode 100644 index 00000000..2e70adb6 --- /dev/null +++ b/tests/std/array/range/gh13094.phpt @@ -0,0 +1,29 @@ +--TEST-- +GH-13094 (range(9.9, '0') causes segmentation fault) +--FILE-- + +--EXPECT-- +array(10) { + [0]=> + float(9.9) + [1]=> + float(8.9) + [2]=> + float(7.9) + [3]=> + float(6.9) + [4]=> + float(5.9) + [5]=> + float(4.9) + [6]=> + float(3.9000000000000004) + [7]=> + float(2.9000000000000004) + [8]=> + float(1.9000000000000004) + [9]=> + float(0.9000000000000004) +} diff --git a/tests/std/array/range/range_bug70239_0.phpt b/tests/std/array/range/range_bug70239_0.phpt new file mode 100644 index 00000000..52f046a7 --- /dev/null +++ b/tests/std/array/range/range_bug70239_0.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #70239 Creating a huge array doesn't result in exhausted, but segfault, var 1 +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +range(): Argument #2 ($end) must be a finite number, INF provided diff --git a/tests/std/array/range/range_bug70239_1.phpt b/tests/std/array/range/range_bug70239_1.phpt new file mode 100644 index 00000000..681d594a --- /dev/null +++ b/tests/std/array/range/range_bug70239_1.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #70239 Creating a huge array doesn't result in exhausted, but segfault, var 2 +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECT-- +range(): Argument #1 ($start) must be a finite number, INF provided diff --git a/tests/std/array/range/range_bug70239_2.phpt b/tests/std/array/range/range_bug70239_2.phpt new file mode 100644 index 00000000..a4ec3c55 --- /dev/null +++ b/tests/std/array/range/range_bug70239_2.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #70239 Creating a huge array doesn't result in exhausted, but segfault, var 3 +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECTF-- +The supplied range exceeds the maximum array size: start=0 end=%d step=1 diff --git a/tests/std/array/range/range_bug70239_3.phpt b/tests/std/array/range/range_bug70239_3.phpt new file mode 100644 index 00000000..7099eb1e --- /dev/null +++ b/tests/std/array/range/range_bug70239_3.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #70239 Creating a huge array doesn't result in exhausted, but segfault, var 4 +--FILE-- +getMessage() . "\n"; +} +?> +--EXPECTF-- +The supplied range exceeds the maximum array size: start=-%d end=0 step=1 diff --git a/tests/std/array/range/range_bug71132.phpt b/tests/std/array/range/range_bug71132.phpt new file mode 100644 index 00000000..5e3bcc8f --- /dev/null +++ b/tests/std/array/range/range_bug71132.phpt @@ -0,0 +1,10 @@ +--TEST-- +Bug #71132 (range function produces 2 segfaults with long integers) +--FILE-- + +--EXPECT-- +int(514) +int(514) diff --git a/tests/std/array/range/range_bug71197.phpt b/tests/std/array/range/range_bug71197.phpt new file mode 100644 index 00000000..2031ec7c --- /dev/null +++ b/tests/std/array/range/range_bug71197.phpt @@ -0,0 +1,8 @@ +--TEST-- +Bug #71197 (range function produces another 2 segfaults with long integers) +--FILE-- + +--EXPECT-- diff --git a/tests/std/array/range/range_bug72017.phpt b/tests/std/array/range/range_bug72017.phpt new file mode 100644 index 00000000..b5a56d7f --- /dev/null +++ b/tests/std/array/range/range_bug72017.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug #72017 (incorrect truncation due to floating point precision issue) +--FILE-- + +--EXPECT-- +array(4) { + [0]=> + float(4.5) + [1]=> + float(4.4) + [2]=> + float(4.3) + [3]=> + float(4.2) +} diff --git a/tests/std/array/range/range_inputs_float_NAN_values.phpt b/tests/std/array/range/range_inputs_float_NAN_values.phpt new file mode 100644 index 00000000..03ed069f --- /dev/null +++ b/tests/std/array/range/range_inputs_float_NAN_values.phpt @@ -0,0 +1,69 @@ +--TEST-- +Test range() function with non finite numbers +--INI-- +serialize_precision=14 +--FILE-- +getMessage(), PHP_EOL; + } + } +} + +?> +--EXPECT-- +float(NAN) +float(NAN) +float(NAN) +range(NAN, NAN); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, NAN); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, NAN); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, 5.5); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, NAN); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, NAN); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, NAN); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, 5.5); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, NAN); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, NAN); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, NAN); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(NAN, 5.5); +range(): Argument #1 ($start) must be a finite number, NAN provided +range(5.5, NAN); +range(): Argument #2 ($end) must be a finite number, NAN provided +range(5.5, NAN); +range(): Argument #2 ($end) must be a finite number, NAN provided +range(5.5, NAN); +range(): Argument #2 ($end) must be a finite number, NAN provided +range(5.5, 5.5); +array(1) { + [0]=> + float(5.5) +} diff --git a/tests/std/array/range/range_inputs_float_basic.phpt b/tests/std/array/range/range_inputs_float_basic.phpt new file mode 100644 index 00000000..c6ba7fd7 --- /dev/null +++ b/tests/std/array/range/range_inputs_float_basic.phpt @@ -0,0 +1,149 @@ +--TEST-- +range(): float boundary inputs +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECT-- +Increasing Range +array(6) { + [0]=> + float(1.5) + [1]=> + float(2.5) + [2]=> + float(3.5) + [3]=> + float(4.5) + [4]=> + float(5.5) + [5]=> + float(6.5) +} + +Decreasing range +array(6) { + [0]=> + float(6.5) + [1]=> + float(5.5) + [2]=> + float(4.5) + [3]=> + float(3.5) + [4]=> + float(2.5) + [5]=> + float(1.5) +} + +Boundaries are equal +array(1) { + [0]=> + float(5.5) +} + +Passing int step +array(4) { + [0]=> + float(1.5) + [1]=> + float(4.5) + [2]=> + float(7.5) + [3]=> + float(10.5) +} +array(4) { + [0]=> + float(10.5) + [1]=> + float(7.5) + [2]=> + float(4.5) + [3]=> + float(1.5) +} +array(4) { + [0]=> + float(1.5) + [1]=> + float(4.5) + [2]=> + float(7.5) + [3]=> + float(10.5) +} + +Passing float step +array(7) { + [0]=> + float(1.6) + [1]=> + float(1.7) + [2]=> + float(1.8) + [3]=> + float(1.9) + [4]=> + float(2) + [5]=> + float(2.1) + [6]=> + float(2.2) +} +array(7) { + [0]=> + float(2.2) + [1]=> + float(2.1) + [2]=> + float(2) + [3]=> + float(1.9) + [4]=> + float(1.8) + [5]=> + float(1.7) + [6]=> + float(1.6) +} +array(7) { + [0]=> + float(1.6) + [1]=> + float(1.7) + [2]=> + float(1.8) + [3]=> + float(1.9) + [4]=> + float(2) + [5]=> + float(2.1) + [6]=> + float(2.2) +} +Done diff --git a/tests/std/array/range/range_inputs_float_small_step_exhaustion.phpt b/tests/std/array/range/range_inputs_float_small_step_exhaustion.phpt new file mode 100644 index 00000000..b00b3142 --- /dev/null +++ b/tests/std/array/range/range_inputs_float_small_step_exhaustion.phpt @@ -0,0 +1,18 @@ +--TEST-- +Creating a range that exceeds the maximum array size +--FILE-- +getMessage(), \PHP_EOL; +} +try { + var_dump(range(PHP_INT_MIN, PHP_INT_MAX, 1)); +} catch (\ValueError $e) { + echo $e->getMessage(), \PHP_EOL; +} +?> +--EXPECTF-- +The supplied range exceeds the maximum array size: start=0.0 end=100000000000.0 step=0.1 +The supplied range exceeds the maximum array size: start=-%d end=%d step=1 diff --git a/tests/std/array/range/range_inputs_int_basic.phpt b/tests/std/array/range/range_inputs_int_basic.phpt new file mode 100644 index 00000000..1995470a --- /dev/null +++ b/tests/std/array/range/range_inputs_int_basic.phpt @@ -0,0 +1,189 @@ +--TEST-- +range(): integer boundary inputs +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECT-- +Increasing Range +array(10) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) +} + +Decreasing range +array(10) { + [0]=> + int(10) + [1]=> + int(9) + [2]=> + int(8) + [3]=> + int(7) + [4]=> + int(6) + [5]=> + int(5) + [6]=> + int(4) + [7]=> + int(3) + [8]=> + int(2) + [9]=> + int(1) +} + +Boundaries are equal +array(1) { + [0]=> + int(5) +} + +Passing int step +array(4) { + [0]=> + int(1) + [1]=> + int(4) + [2]=> + int(7) + [3]=> + int(10) +} +array(4) { + [0]=> + int(10) + [1]=> + int(7) + [2]=> + int(4) + [3]=> + int(1) +} +array(4) { + [0]=> + int(1) + [1]=> + int(4) + [2]=> + int(7) + [3]=> + int(10) +} + +Passing float step +array(11) { + [0]=> + float(1) + [1]=> + float(1.1) + [2]=> + float(1.2) + [3]=> + float(1.3) + [4]=> + float(1.4) + [5]=> + float(1.5) + [6]=> + float(1.6) + [7]=> + float(1.7) + [8]=> + float(1.8) + [9]=> + float(1.9) + [10]=> + float(2) +} +array(11) { + [0]=> + float(2) + [1]=> + float(1.9) + [2]=> + float(1.8) + [3]=> + float(1.7) + [4]=> + float(1.6) + [5]=> + float(1.5) + [6]=> + float(1.4) + [7]=> + float(1.3) + [8]=> + float(1.2) + [9]=> + float(1.1) + [10]=> + float(1) +} +array(11) { + [0]=> + float(1) + [1]=> + float(1.1) + [2]=> + float(1.2) + [3]=> + float(1.3) + [4]=> + float(1.4) + [5]=> + float(1.5) + [6]=> + float(1.6) + [7]=> + float(1.7) + [8]=> + float(1.8) + [9]=> + float(1.9) + [10]=> + float(2) +} +Done diff --git a/tests/std/array/range/range_inputs_int_with_float_step.phpt b/tests/std/array/range/range_inputs_int_with_float_step.phpt new file mode 100644 index 00000000..2d479ac4 --- /dev/null +++ b/tests/std/array/range/range_inputs_int_with_float_step.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test range() function with integer inputs and float step +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(3) + [2]=> + int(5) +} diff --git a/tests/std/array/range/range_inputs_null_variations.phpt b/tests/std/array/range/range_inputs_null_variations.phpt new file mode 100644 index 00000000..a3ff352c --- /dev/null +++ b/tests/std/array/range/range_inputs_null_variations.phpt @@ -0,0 +1,98 @@ +--TEST-- +Test range() function with null as argument. +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECTF-- +range(null, null) +array(1) { + [0]=> + int(0) +} +null with int boundary +array(6) { + [0]=> + int(0) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(3) + [4]=> + int(4) + [5]=> + int(5) +} +array(6) { + [0]=> + int(5) + [1]=> + int(4) + [2]=> + int(3) + [3]=> + int(2) + [4]=> + int(1) + [5]=> + int(0) +} +null with float boundary +array(5) { + [0]=> + float(0) + [1]=> + float(1) + [2]=> + float(2) + [3]=> + float(3) + [4]=> + float(4) +} +array(5) { + [0]=> + float(4.5) + [1]=> + float(3.5) + [2]=> + float(2.5) + [3]=> + float(1.5) + [4]=> + float(0.5) +} +null with string boundary + +Warning:%S Argument #1 ($start) must be a single byte string if argument #2 ($end) is a single byte string, argument #2 ($end) converted to 0 in %s on line %d +array(1) { + [0]=> + int(0) +} + +Warning:%S Argument #2 ($end) must be a single byte string if argument #1 ($start) is a single byte string, argument #1 ($start) converted to 0 in %s on line %d +array(1) { + [0]=> + int(0) +} +Done diff --git a/tests/std/array/range/range_inputs_numeric_basic.phpt b/tests/std/array/range/range_inputs_numeric_basic.phpt new file mode 100644 index 00000000..09e9e415 --- /dev/null +++ b/tests/std/array/range/range_inputs_numeric_basic.phpt @@ -0,0 +1,74 @@ +--TEST-- +range(): mixed numeric types boundary inputs +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECT-- +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) +} +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) +} +array(4) { + [0]=> + float(1.5) + [1]=> + float(2.5) + [2]=> + float(3.5) + [3]=> + float(4.5) +} +array(4) { + [0]=> + float(1.5) + [1]=> + float(2.5) + [2]=> + float(3.5) + [3]=> + float(4.5) +} +array(4) { + [0]=> + int(9) + [1]=> + int(10) + [2]=> + int(11) + [3]=> + int(12) +} +array(4) { + [0]=> + int(9) + [1]=> + int(10) + [2]=> + int(11) + [3]=> + int(12) +} diff --git a/tests/std/array/range/range_inputs_string_basic.phpt b/tests/std/array/range/range_inputs_string_basic.phpt new file mode 100644 index 00000000..00ce49e6 --- /dev/null +++ b/tests/std/array/range/range_inputs_string_basic.phpt @@ -0,0 +1,153 @@ +--TEST-- +Test range() function with basic/expected string inputs +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECT-- +-- Chars as Low and High -- +-- An array of elements from low to high -- +array(26) { + [0]=> + string(1) "a" + [1]=> + string(1) "b" + [2]=> + string(1) "c" + [3]=> + string(1) "d" + [4]=> + string(1) "e" + [5]=> + string(1) "f" + [6]=> + string(1) "g" + [7]=> + string(1) "h" + [8]=> + string(1) "i" + [9]=> + string(1) "j" + [10]=> + string(1) "k" + [11]=> + string(1) "l" + [12]=> + string(1) "m" + [13]=> + string(1) "n" + [14]=> + string(1) "o" + [15]=> + string(1) "p" + [16]=> + string(1) "q" + [17]=> + string(1) "r" + [18]=> + string(1) "s" + [19]=> + string(1) "t" + [20]=> + string(1) "u" + [21]=> + string(1) "v" + [22]=> + string(1) "w" + [23]=> + string(1) "x" + [24]=> + string(1) "y" + [25]=> + string(1) "z" +} + +-- An array of elements from high to low -- +array(26) { + [0]=> + string(1) "z" + [1]=> + string(1) "y" + [2]=> + string(1) "x" + [3]=> + string(1) "w" + [4]=> + string(1) "v" + [5]=> + string(1) "u" + [6]=> + string(1) "t" + [7]=> + string(1) "s" + [8]=> + string(1) "r" + [9]=> + string(1) "q" + [10]=> + string(1) "p" + [11]=> + string(1) "o" + [12]=> + string(1) "n" + [13]=> + string(1) "m" + [14]=> + string(1) "l" + [15]=> + string(1) "k" + [16]=> + string(1) "j" + [17]=> + string(1) "i" + [18]=> + string(1) "h" + [19]=> + string(1) "g" + [20]=> + string(1) "f" + [21]=> + string(1) "e" + [22]=> + string(1) "d" + [23]=> + string(1) "c" + [24]=> + string(1) "b" + [25]=> + string(1) "a" +} + +-- Low and High are equal -- +array(1) { + [0]=> + string(1) "q" +} + +-- Testing basic string with step -- +array(4) { + [0]=> + string(1) "a" + [1]=> + string(1) "c" + [2]=> + string(1) "e" + [3]=> + string(1) "g" +} +Done diff --git a/tests/std/array/range/range_inputs_string_digits.phpt b/tests/std/array/range/range_inputs_string_digits.phpt new file mode 100644 index 00000000..b218c582 --- /dev/null +++ b/tests/std/array/range/range_inputs_string_digits.phpt @@ -0,0 +1,97 @@ +--TEST-- +Test range() function with string digits +--FILE-- + +--EXPECT-- +Only digits +array(9) { + [0]=> + string(1) "1" + [1]=> + string(1) "2" + [2]=> + string(1) "3" + [3]=> + string(1) "4" + [4]=> + string(1) "5" + [5]=> + string(1) "6" + [6]=> + string(1) "7" + [7]=> + string(1) "8" + [8]=> + string(1) "9" +} +array(9) { + [0]=> + string(1) "9" + [1]=> + string(1) "8" + [2]=> + string(1) "7" + [3]=> + string(1) "6" + [4]=> + string(1) "5" + [5]=> + string(1) "4" + [6]=> + string(1) "3" + [7]=> + string(1) "2" + [8]=> + string(1) "1" +} +Only digits and char +array(9) { + [0]=> + string(1) "9" + [1]=> + string(1) ":" + [2]=> + string(1) ";" + [3]=> + string(1) "<" + [4]=> + string(1) "=" + [5]=> + string(1) ">" + [6]=> + string(1) "?" + [7]=> + string(1) "@" + [8]=> + string(1) "A" +} +array(9) { + [0]=> + string(1) "A" + [1]=> + string(1) "@" + [2]=> + string(1) "?" + [3]=> + string(1) ">" + [4]=> + string(1) "=" + [5]=> + string(1) "<" + [6]=> + string(1) ";" + [7]=> + string(1) ":" + [8]=> + string(1) "9" +} +Done diff --git a/tests/std/array/range/range_inputs_string_digits_float_step.phpt b/tests/std/array/range/range_inputs_string_digits_float_step.phpt new file mode 100644 index 00000000..45a53827 --- /dev/null +++ b/tests/std/array/range/range_inputs_string_digits_float_step.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test range() function where boundary are string digits and step is a float +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECT-- +array(11) { + [0]=> + float(1) + [1]=> + float(1.1) + [2]=> + float(1.2) + [3]=> + float(1.3) + [4]=> + float(1.4) + [5]=> + float(1.5) + [6]=> + float(1.6) + [7]=> + float(1.7) + [8]=> + float(1.8) + [9]=> + float(1.9) + [10]=> + float(2) +} diff --git a/tests/std/array/range/range_inputs_string_invalid.phpt b/tests/std/array/range/range_inputs_string_invalid.phpt new file mode 100644 index 00000000..f86d1670 --- /dev/null +++ b/tests/std/array/range/range_inputs_string_invalid.phpt @@ -0,0 +1,85 @@ +--TEST-- +Test range() function with unexpected string inputs +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECTF-- +Range will ignore any byte after the first one + +Warning:%S Argument #1 ($start) must be a single byte, subsequent bytes are ignored in %s on line %d + +Warning:%S Argument #2 ($end) must be a single byte, subsequent bytes are ignored in %s on line %d +array(2) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" +} +Range cannot operate on an empty string + +Warning:%S Argument #2 ($end) must not be empty, casted to 0 in %s on line %d + +Warning:%S Argument #2 ($end) must be a single byte string if argument #1 ($start) is a single byte string, argument #1 ($start) converted to 0 in %s on line %d +array(1) { + [0]=> + int(0) +} + +Warning:%S Argument #1 ($start) must not be empty, casted to 0 in %s on line %d + +Warning:%S Argument #1 ($start) must be a single byte string if argument #2 ($end) is a single byte string, argument #2 ($end) converted to 0 in %s on line %d +array(1) { + [0]=> + int(0) +} +Mixing numeric float string and character + +Warning:%S Argument #1 ($start) must be a single byte string if argument #2 ($end) is a single byte string, argument #2 ($end) converted to 0 in %s on line %d +array(4) { + [0]=> + float(3.5) + [1]=> + float(2.5) + [2]=> + float(1.5) + [3]=> + float(0.5) +} + +Warning:%S Argument #2 ($end) must be a single byte string if argument #1 ($start) is a single byte string, argument #1 ($start) converted to 0 in %s on line %d +array(4) { + [0]=> + float(0) + [1]=> + float(1) + [2]=> + float(2) + [3]=> + float(3) +} +Fractional step cannot be used on character ranges + +Warning:%S Argument #3 ($step) must be of type int when generating an array of characters, inputs converted to 0 in %s on line %d +array(1) { + [0]=> + float(0) +} +Done diff --git a/tests/std/array/range/range_inputs_string_numeric.phpt b/tests/std/array/range/range_inputs_string_numeric.phpt new file mode 100644 index 00000000..fc45811a --- /dev/null +++ b/tests/std/array/range/range_inputs_string_numeric.phpt @@ -0,0 +1,189 @@ +--TEST-- +range(): numeric string boundary inputs +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECT-- +Increasing Range +array(10) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + [6]=> + int(7) + [7]=> + int(8) + [8]=> + int(9) + [9]=> + int(10) +} + +Decreasing range +array(10) { + [0]=> + int(10) + [1]=> + int(9) + [2]=> + int(8) + [3]=> + int(7) + [4]=> + int(6) + [5]=> + int(5) + [6]=> + int(4) + [7]=> + int(3) + [8]=> + int(2) + [9]=> + int(1) +} + +Boundaries are equal +array(1) { + [0]=> + string(1) "5" +} + +Passing int step +array(4) { + [0]=> + int(1) + [1]=> + int(4) + [2]=> + int(7) + [3]=> + int(10) +} +array(4) { + [0]=> + int(10) + [1]=> + int(7) + [2]=> + int(4) + [3]=> + int(1) +} +array(4) { + [0]=> + int(1) + [1]=> + int(4) + [2]=> + int(7) + [3]=> + int(10) +} + +Passing float step +array(11) { + [0]=> + float(1) + [1]=> + float(1.1) + [2]=> + float(1.2) + [3]=> + float(1.3) + [4]=> + float(1.4) + [5]=> + float(1.5) + [6]=> + float(1.6) + [7]=> + float(1.7) + [8]=> + float(1.8) + [9]=> + float(1.9) + [10]=> + float(2) +} +array(11) { + [0]=> + float(2) + [1]=> + float(1.9) + [2]=> + float(1.8) + [3]=> + float(1.7) + [4]=> + float(1.6) + [5]=> + float(1.5) + [6]=> + float(1.4) + [7]=> + float(1.3) + [8]=> + float(1.2) + [9]=> + float(1.1) + [10]=> + float(1) +} +array(11) { + [0]=> + float(1) + [1]=> + float(1.1) + [2]=> + float(1.2) + [3]=> + float(1.3) + [4]=> + float(1.4) + [5]=> + float(1.5) + [6]=> + float(1.6) + [7]=> + float(1.7) + [8]=> + float(1.8) + [9]=> + float(1.9) + [10]=> + float(2) +} +Done diff --git a/tests/std/array/range/range_inputs_string_variations.phpt b/tests/std/array/range/range_inputs_string_variations.phpt new file mode 100644 index 00000000..27dd535f --- /dev/null +++ b/tests/std/array/range/range_inputs_string_variations.phpt @@ -0,0 +1,148 @@ +--TEST-- +Test range() function with unexpected string input variations or unusual step. +--INI-- +serialize_precision=14 +--FILE-- + +--EXPECT-- +int compatible float as step +array(4) { + [0]=> + string(1) "a" + [1]=> + string(1) "c" + [2]=> + string(1) "e" + [3]=> + string(1) "g" +} +A to z range() +array(58) { + [0]=> + string(1) "A" + [1]=> + string(1) "B" + [2]=> + string(1) "C" + [3]=> + string(1) "D" + [4]=> + string(1) "E" + [5]=> + string(1) "F" + [6]=> + string(1) "G" + [7]=> + string(1) "H" + [8]=> + string(1) "I" + [9]=> + string(1) "J" + [10]=> + string(1) "K" + [11]=> + string(1) "L" + [12]=> + string(1) "M" + [13]=> + string(1) "N" + [14]=> + string(1) "O" + [15]=> + string(1) "P" + [16]=> + string(1) "Q" + [17]=> + string(1) "R" + [18]=> + string(1) "S" + [19]=> + string(1) "T" + [20]=> + string(1) "U" + [21]=> + string(1) "V" + [22]=> + string(1) "W" + [23]=> + string(1) "X" + [24]=> + string(1) "Y" + [25]=> + string(1) "Z" + [26]=> + string(1) "[" + [27]=> + string(1) "\" + [28]=> + string(1) "]" + [29]=> + string(1) "^" + [30]=> + string(1) "_" + [31]=> + string(1) "`" + [32]=> + string(1) "a" + [33]=> + string(1) "b" + [34]=> + string(1) "c" + [35]=> + string(1) "d" + [36]=> + string(1) "e" + [37]=> + string(1) "f" + [38]=> + string(1) "g" + [39]=> + string(1) "h" + [40]=> + string(1) "i" + [41]=> + string(1) "j" + [42]=> + string(1) "k" + [43]=> + string(1) "l" + [44]=> + string(1) "m" + [45]=> + string(1) "n" + [46]=> + string(1) "o" + [47]=> + string(1) "p" + [48]=> + string(1) "q" + [49]=> + string(1) "r" + [50]=> + string(1) "s" + [51]=> + string(1) "t" + [52]=> + string(1) "u" + [53]=> + string(1) "v" + [54]=> + string(1) "w" + [55]=> + string(1) "x" + [56]=> + string(1) "y" + [57]=> + string(1) "z" +} +Done diff --git a/tests/std/array/range/range_negative_step_decreasing_ranges.phpt b/tests/std/array/range/range_negative_step_decreasing_ranges.phpt new file mode 100644 index 00000000..6a9ff3a7 --- /dev/null +++ b/tests/std/array/range/range_negative_step_decreasing_ranges.phpt @@ -0,0 +1,33 @@ +--TEST-- +range() allows $step parameter to be negative for decreasing ranges +--INI-- +precision=14 +--FILE-- + +--EXPECT-- +array(3) { + [0]=> + string(1) "c" + [1]=> + string(1) "b" + [2]=> + string(1) "a" +} +array(3) { + [0]=> + int(3) + [1]=> + int(2) + [2]=> + int(1) +} +array(2) { + [0]=> + float(3.5) + [1]=> + float(2) +} diff --git a/tests/std/array/range/range_step_errors.phpt b/tests/std/array/range/range_step_errors.phpt new file mode 100644 index 00000000..e950c527 --- /dev/null +++ b/tests/std/array/range/range_step_errors.phpt @@ -0,0 +1,134 @@ +--TEST-- +range() programattic errors for the $step parameter +--INI-- +precision=14 +--FILE-- +getMessage(), "\n"; +} +try { + var_dump( range(1, 7, 0) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump( range('A', 'H', 0) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump( range('A', 'H', 0.0) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +echo "Step cannot be INF\n"; +try { + var_dump( range(1.0, 7.0, 10.0**400) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump( range(1, 7, 10.0**400) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump( range('A', 'H', 10.0**400) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +echo "Step cannot be NAN\n"; +try { + var_dump( range(1.0, 7.0, fdiv(0, 0)) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump( range(1, 7, fdiv(0, 0)) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump( range('A', 'H', fdiv(0, 0)) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +echo "Step must be within the range of input parameters\n"; +echo "-- Testing ( (low < high) && (high-low < step) ) --\n"; +try { + var_dump( range(1.0, 7.0, 6.5) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +echo "-- Testing ( (low > high) && (low-high < step) ) --\n"; +try { + var_dump( range(7.0, 1.0, 6.5) ); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +echo "-- Testing ( (low < high) && (high-low < step) ) for characters --\n"; +try { + var_dump(range('a', 'z', 100)); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +echo "-- Testing ( (low > high) && (low-high < step) ) for characters --\n"; +try { + var_dump(range('z', 'a', 100)); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +echo "Step must not be negative for increasing ranges\n"; +try { + var_dump(range('a', 'c', -1)); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(range(1, 3, -1)); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} +try { + var_dump(range(1.5, 3.5, -1.5)); +} catch (\ValueError $e) { + echo $e->getMessage(), "\n"; +} + +?> +--EXPECTF-- +Step cannot be 0 +range(): Argument #3 ($step) cannot be 0 +range(): Argument #3 ($step) cannot be 0 +range(): Argument #3 ($step) cannot be 0 +range(): Argument #3 ($step) cannot be 0 +Step cannot be INF +range(): Argument #3 ($step) must be a finite number, INF provided +range(): Argument #3 ($step) must be a finite number, INF provided +range(): Argument #3 ($step) must be a finite number, INF provided +Step cannot be NAN +range(): Argument #3 ($step) must be a finite number, NAN provided +range(): Argument #3 ($step) must be a finite number, NAN provided +range(): Argument #3 ($step) must be a finite number, NAN provided +Step must be within the range of input parameters +-- Testing ( (low < high) && (high-low < step) ) -- +range(): Argument #3 ($step) must be less than the range spanned by argument #1 ($start) and argument #2 ($end) +-- Testing ( (low > high) && (low-high < step) ) -- +range(): Argument #3 ($step) must be less than the range spanned by argument #1 ($start) and argument #2 ($end) +-- Testing ( (low < high) && (high-low < step) ) for characters -- +range(): Argument #3 ($step) must be less than the range spanned by argument #1 ($start) and argument #2 ($end) +-- Testing ( (low > high) && (low-high < step) ) for characters -- +range(): Argument #3 ($step) must be less than the range spanned by argument #1 ($start) and argument #2 ($end) +Step must not be negative for increasing ranges +range(): Argument #3 ($step) must be greater than 0 for increasing ranges +range(): Argument #3 ($step) must be greater than 0 for increasing ranges +range(): Argument #3 ($step) must be greater than 0 for increasing ranges diff --git a/tests/std/array/range/range_variation1.phpt b/tests/std/array/range/range_variation1.phpt new file mode 100644 index 00000000..0747fab3 --- /dev/null +++ b/tests/std/array/range/range_variation1.phpt @@ -0,0 +1,60 @@ +--TEST-- +Test range() function (variation-2) +--INI-- +precision=14 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing max/outof range values *** +array(2) { + [0]=> + int(2147483645) + [1]=> + int(2147483646) +} +array(3) { + [0]=> + float(2147483646) + [1]=> + float(2147483647) + [2]=> + float(2147483648) +} +array(2) { + [0]=> + int(-2147483647) + [1]=> + int(-2147483646) +} +array(2) { + [0]=> + float(-2147483648) + [1]=> + float(-2147483647) +} +array(3) { + [0]=> + float(-2147483649) + [1]=> + float(-2147483648) + [2]=> + float(-2147483647) +} + +Done diff --git a/tests/std/array/range/range_variation1_64bit.phpt b/tests/std/array/range/range_variation1_64bit.phpt new file mode 100644 index 00000000..555dbc2e --- /dev/null +++ b/tests/std/array/range/range_variation1_64bit.phpt @@ -0,0 +1,60 @@ +--TEST-- +Test range() function (variation-2) +--INI-- +precision=14 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +*** Testing max/outof range values *** +array(2) { + [0]=> + int(2147483645) + [1]=> + int(2147483646) +} +array(3) { + [0]=> + int(2147483646) + [1]=> + int(2147483647) + [2]=> + int(2147483648) +} +array(2) { + [0]=> + int(-2147483647) + [1]=> + int(-2147483646) +} +array(2) { + [0]=> + int(-2147483648) + [1]=> + int(-2147483647) +} +array(3) { + [0]=> + int(-2147483649) + [1]=> + int(-2147483648) + [2]=> + int(-2147483647) +} + +Done diff --git a/tests/std/array/rcn_in_place.phpt b/tests/std/array/rcn_in_place.phpt new file mode 100644 index 00000000..e6a7b5b6 --- /dev/null +++ b/tests/std/array/rcn_in_place.phpt @@ -0,0 +1,57 @@ +--TEST-- +RCN check for in-place array modifications +--FILE-- + 0)); +var_dump(array_intersect(range(0, 1), [])); +var_dump(array_uintersect(range(0, 1), [], fn () => 0)); +var_dump(array_intersect_uassoc(range(0, 1), [], fn () => 0)); +var_dump(array_uintersect_uassoc(range(0, 1), [], fn () => 0, fn () => 0)); +?> +--EXPECT-- +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(2) { + [0]=> + int(0) + [1]=> + int(1) +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} +array(0) { +} diff --git a/tests/std/array/reset_basic.phpt b/tests/std/array/reset_basic.phpt new file mode 100644 index 00000000..d533d28d --- /dev/null +++ b/tests/std/array/reset_basic.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test reset() function : basic functionality +--FILE-- + 'two'); + +echo "\n-- Initial Position: --\n"; +echo key($array) . " => " . current($array) . "\n"; + +echo "\n-- Call to next() --\n"; +var_dump(next($array)); + +echo "\n-- Current Position: --\n"; +echo key($array) . " => " . current($array) . "\n"; + +echo "\n-- Call to reset() --\n"; +var_dump(reset($array)); +?> +--EXPECT-- +*** Testing reset() : basic functionality *** + +-- Initial Position: -- +0 => zero + +-- Call to next() -- +string(3) "one" + +-- Current Position: -- +1 => one + +-- Call to reset() -- +string(4) "zero" diff --git a/tests/std/array/reset_variation2.phpt b/tests/std/array/reset_variation2.phpt new file mode 100644 index 00000000..13d1347f --- /dev/null +++ b/tests/std/array/reset_variation2.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test reset() function : usage variations - unset first element +--FILE-- + " . key($array) . "\n"; + +echo "\n-- Unset First element in array and check reset() --\n"; +unset($array[0]); +var_dump(reset($array)); +?> +--EXPECT-- +*** Testing reset() : usage variations *** + +-- Initial Position: -- +a => 0 + +-- Unset First element in array and check reset() -- +string(1) "b" diff --git a/tests/std/array/reset_variation3.phpt b/tests/std/array/reset_variation3.phpt new file mode 100644 index 00000000..9bfc290b --- /dev/null +++ b/tests/std/array/reset_variation3.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test reset() function : usage variations - Referenced variables +--FILE-- + +--EXPECT-- +*** Testing reset() : usage variations *** + +-- Initial position of internal pointer -- +string(4) "zero" + +-- Position after calling next() -- +$array1: string(3) "one" +$array2: string(3) "one" + +-- Position after calling reset() -- +string(4) "zero" +$array1: string(4) "zero" +$array2: string(4) "zero" diff --git a/tests/std/array/rsort_basic.phpt b/tests/std/array/rsort_basic.phpt new file mode 100644 index 00000000..a7ad5f37 --- /dev/null +++ b/tests/std/array/rsort_basic.phpt @@ -0,0 +1,235 @@ +--TEST-- +Test rsort() function : basic functionality +--FILE-- + "lemon", "o" => "orange", + "O" => "Orange", "O1" => "Orange1", "o2" => "orange2", "O3" => "Orange3", "o20" => "orange20", + "b" => "banana", +); + +// array with default keys containing unsorted numeric values +$unsorted_numerics = array( 100, 33, 555, 22 ); + +echo "\n-- Testing rsort() by supplying string array, 'flag' value is default --\n"; +$temp_array = $unsorted_strings; +var_dump( rsort($temp_array) ); +var_dump( $temp_array); + +echo "\n-- Testing rsort() by supplying numeric array, 'flag' value is default --\n"; +$temp_array = $unsorted_numerics; +var_dump( rsort($temp_array) ); +var_dump( $temp_array); + +echo "\n-- Testing rsort() by supplying string array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_strings; +var_dump( rsort($temp_array, SORT_REGULAR) ); +var_dump( $temp_array); + +echo "\n-- Testing rsort() by supplying numeric array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_numerics; +var_dump( rsort($temp_array, SORT_REGULAR) ); +var_dump( $temp_array); + +echo "\n-- Testing rsort() by supplying string array, 'flag' = SORT_STRING --\n"; +$temp_array = $unsorted_strings; +var_dump( rsort($temp_array, SORT_STRING) ); +var_dump( $temp_array); + +echo "\n-- Testing rsort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( rsort($temp_array, SORT_STRING|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing rsort() by supplying string array (natural), 'flag' = SORT_NATURAL --\n"; +$temp_array = $unsorted_strings; +var_dump( rsort($temp_array, SORT_NATURAL) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing rsort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( rsort($temp_array, SORT_NATURAL|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing rsort() by supplying numeric array, 'flag' = SORT_NUMERIC --\n"; +$temp_array = $unsorted_numerics; +var_dump( rsort($temp_array, SORT_NUMERIC) ); +var_dump( $temp_array); + +echo "Done"; +?> +--EXPECT-- +*** Testing rsort() : basic functionality *** + +-- Testing rsort() by supplying string array, 'flag' value is default -- +bool(true) +array(8) { + [0]=> + string(8) "orange20" + [1]=> + string(7) "orange2" + [2]=> + string(6) "orange" + [3]=> + string(5) "lemon" + [4]=> + string(6) "banana" + [5]=> + string(7) "Orange3" + [6]=> + string(7) "Orange1" + [7]=> + string(6) "Orange" +} + +-- Testing rsort() by supplying numeric array, 'flag' value is default -- +bool(true) +array(4) { + [0]=> + int(555) + [1]=> + int(100) + [2]=> + int(33) + [3]=> + int(22) +} + +-- Testing rsort() by supplying string array, 'flag' = SORT_REGULAR -- +bool(true) +array(8) { + [0]=> + string(8) "orange20" + [1]=> + string(7) "orange2" + [2]=> + string(6) "orange" + [3]=> + string(5) "lemon" + [4]=> + string(6) "banana" + [5]=> + string(7) "Orange3" + [6]=> + string(7) "Orange1" + [7]=> + string(6) "Orange" +} + +-- Testing rsort() by supplying numeric array, 'flag' = SORT_REGULAR -- +bool(true) +array(4) { + [0]=> + int(555) + [1]=> + int(100) + [2]=> + int(33) + [3]=> + int(22) +} + +-- Testing rsort() by supplying string array, 'flag' = SORT_STRING -- +bool(true) +array(8) { + [0]=> + string(8) "orange20" + [1]=> + string(7) "orange2" + [2]=> + string(6) "orange" + [3]=> + string(5) "lemon" + [4]=> + string(6) "banana" + [5]=> + string(7) "Orange3" + [6]=> + string(7) "Orange1" + [7]=> + string(6) "Orange" +} + +-- Testing rsort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE -- +bool(true) +array(8) { + [0]=> + string(7) "Orange3" + [1]=> + string(8) "orange20" + [2]=> + string(7) "orange2" + [3]=> + string(7) "Orange1" + [4]=> + string(6) "orange" + [5]=> + string(6) "Orange" + [6]=> + string(5) "lemon" + [7]=> + string(6) "banana" +} + +-- Testing rsort() by supplying string array (natural), 'flag' = SORT_NATURAL -- +bool(true) +array(8) { + [0]=> + string(8) "orange20" + [1]=> + string(7) "orange2" + [2]=> + string(6) "orange" + [3]=> + string(5) "lemon" + [4]=> + string(6) "banana" + [5]=> + string(7) "Orange3" + [6]=> + string(7) "Orange1" + [7]=> + string(6) "Orange" +} + +-- Testing rsort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE -- +bool(true) +array(8) { + [0]=> + string(8) "orange20" + [1]=> + string(7) "Orange3" + [2]=> + string(7) "orange2" + [3]=> + string(7) "Orange1" + [4]=> + string(6) "orange" + [5]=> + string(6) "Orange" + [6]=> + string(5) "lemon" + [7]=> + string(6) "banana" +} + +-- Testing rsort() by supplying numeric array, 'flag' = SORT_NUMERIC -- +bool(true) +array(4) { + [0]=> + int(555) + [1]=> + int(100) + [2]=> + int(33) + [3]=> + int(22) +} +Done diff --git a/tests/std/array/rsort_object1.phpt b/tests/std/array/rsort_object1.phpt new file mode 100644 index 00000000..4dc1feeb --- /dev/null +++ b/tests/std/array/rsort_object1.phpt @@ -0,0 +1,218 @@ +--TEST-- +Test rsort() function : object functionality +--FILE-- +class_value = $value; + } +} +// class declaration for string objects +class for_string_rsort +{ + public $class_value; + // initializing object member value + function __construct($value) + { + $this->class_value = $value; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * Test basic functionality of rsort() with objects + */ + echo "*** Testing rsort() : object functionality ***\n"; + // array of integer objects + $unsorted_int_obj = array(new for_integer_rsort(11), new for_integer_rsort(66), new for_integer_rsort(23), new for_integer_rsort(-5), new for_integer_rsort(0.001), new for_integer_rsort(0)); + // array of string objects + $unsorted_str_obj = array(new for_string_rsort("axx"), new for_string_rsort("t"), new for_string_rsort("w"), new for_string_rsort("py"), new for_string_rsort("apple"), new for_string_rsort("Orange"), new for_string_rsort("Lemon"), new for_string_rsort("aPPle")); + echo "\n-- Sort flag = default --\n"; + // testing rsort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(rsort($temp_array)); + var_dump($temp_array); + // testing rsort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(rsort($temp_array)); + var_dump($temp_array); + echo "\n-- Sort flag = SORT_REGULAR --\n"; + // testing rsort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(rsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing rsort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(rsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing rsort() : object functionality *** + +-- Sort flag = default -- +bool(true) +array(6) { + [0]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(66) + } + [1]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(23) + } + [2]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(11) + } + [3]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + float(0.001) + } + [4]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(0) + } + [5]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(-5) + } +} +bool(true) +array(8) { + [0]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(1) "w" + } + [1]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(1) "t" + } + [2]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(2) "py" + } + [3]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + [4]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + [5]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + [6]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + [7]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } +} + +-- Sort flag = SORT_REGULAR -- +bool(true) +array(6) { + [0]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(66) + } + [1]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(23) + } + [2]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(11) + } + [3]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + float(0.001) + } + [4]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(0) + } + [5]=> + object(for_integer_rsort)#%d (1) { + ["class_value"]=> + int(-5) + } +} +bool(true) +array(8) { + [0]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(1) "w" + } + [1]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(1) "t" + } + [2]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(2) "py" + } + [3]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + [4]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + [5]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + [6]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + [7]=> + object(for_string_rsort)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } +} +Done diff --git a/tests/std/array/rsort_object2.phpt b/tests/std/array/rsort_object2.phpt new file mode 100644 index 00000000..a7e4fde7 --- /dev/null +++ b/tests/std/array/rsort_object2.phpt @@ -0,0 +1,230 @@ +--TEST-- +Test rsort() function : object functionality - different visibilities +--FILE-- +public_class_value = $value1; + $this->private_class_value = $value2; + $this->protected_class_value = $value3; + } +} +// class declaration for string objects +class for_string_rsort +{ + public $public_class_value; + private $private_class_value; + protected $protected_class_value; + // initializing object member value + function __construct($value1, $value2, $value3) + { + $this->public_class_value = $value1; + $this->private_class_value = $value2; + $this->protected_class_value = $value3; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * Test functionality of rsort() with objects where properties have different visibilities + */ + echo "*** Testing rsort() : object functionality ***\n"; + // array of integer objects + $unsorted_int_obj = array(new for_integer_rsort(11, 33, 30), new for_integer_rsort(66, 44, 4), new for_integer_rsort(-88, -5, 5), new for_integer_rsort(0.001, 99.5, 0.1)); + // array of string objects + $unsorted_str_obj = array(new for_string_rsort("axx", "AXX", "ass"), new for_string_rsort("t", "eee", "abb"), new for_string_rsort("w", "W", "c"), new for_string_rsort("py", "PY", "pt")); + echo "\n-- Sort flag = default --\n"; + // testing rsort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(rsort($temp_array)); + var_dump($temp_array); + // testing rsort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(rsort($temp_array)); + var_dump($temp_array); + echo "\n-- Sort flag = SORT_REGULAR --\n"; + // testing rsort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(rsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing rsort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(rsort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done"; +} +?> +--EXPECTF-- +*** Testing rsort() : object functionality *** + +-- Sort flag = default -- +bool(true) +array(4) { + [0]=> + object(for_integer_rsort)#%d (3) { + ["public_class_value"]=> + int(66) + ["private_class_value":"for_integer_rsort":private]=> + int(44) + ["protected_class_value":protected]=> + int(4) + } + [1]=> + object(for_integer_rsort)#%d (3) { + ["public_class_value"]=> + int(11) + ["private_class_value":"for_integer_rsort":private]=> + int(33) + ["protected_class_value":protected]=> + int(30) + } + [2]=> + object(for_integer_rsort)#%d (3) { + ["public_class_value"]=> + float(0.001) + ["private_class_value":"for_integer_rsort":private]=> + float(99.5) + ["protected_class_value":protected]=> + float(0.1) + } + [3]=> + object(for_integer_rsort)#%d (3) { + ["public_class_value"]=> + int(-88) + ["private_class_value":"for_integer_rsort":private]=> + int(-5) + ["protected_class_value":protected]=> + int(5) + } +} +bool(true) +array(4) { + [0]=> + object(for_string_rsort)#%d (3) { + ["public_class_value"]=> + string(1) "w" + ["private_class_value":"for_string_rsort":private]=> + string(1) "W" + ["protected_class_value":protected]=> + string(1) "c" + } + [1]=> + object(for_string_rsort)#%d (3) { + ["public_class_value"]=> + string(1) "t" + ["private_class_value":"for_string_rsort":private]=> + string(3) "eee" + ["protected_class_value":protected]=> + string(3) "abb" + } + [2]=> + object(for_string_rsort)#%d (3) { + ["public_class_value"]=> + string(2) "py" + ["private_class_value":"for_string_rsort":private]=> + string(2) "PY" + ["protected_class_value":protected]=> + string(2) "pt" + } + [3]=> + object(for_string_rsort)#%d (3) { + ["public_class_value"]=> + string(3) "axx" + ["private_class_value":"for_string_rsort":private]=> + string(3) "AXX" + ["protected_class_value":protected]=> + string(3) "ass" + } +} + +-- Sort flag = SORT_REGULAR -- +bool(true) +array(4) { + [0]=> + object(for_integer_rsort)#%d (3) { + ["public_class_value"]=> + int(66) + ["private_class_value":"for_integer_rsort":private]=> + int(44) + ["protected_class_value":protected]=> + int(4) + } + [1]=> + object(for_integer_rsort)#%d (3) { + ["public_class_value"]=> + int(11) + ["private_class_value":"for_integer_rsort":private]=> + int(33) + ["protected_class_value":protected]=> + int(30) + } + [2]=> + object(for_integer_rsort)#%d (3) { + ["public_class_value"]=> + float(0.001) + ["private_class_value":"for_integer_rsort":private]=> + float(99.5) + ["protected_class_value":protected]=> + float(0.1) + } + [3]=> + object(for_integer_rsort)#%d (3) { + ["public_class_value"]=> + int(-88) + ["private_class_value":"for_integer_rsort":private]=> + int(-5) + ["protected_class_value":protected]=> + int(5) + } +} +bool(true) +array(4) { + [0]=> + object(for_string_rsort)#%d (3) { + ["public_class_value"]=> + string(1) "w" + ["private_class_value":"for_string_rsort":private]=> + string(1) "W" + ["protected_class_value":protected]=> + string(1) "c" + } + [1]=> + object(for_string_rsort)#%d (3) { + ["public_class_value"]=> + string(1) "t" + ["private_class_value":"for_string_rsort":private]=> + string(3) "eee" + ["protected_class_value":protected]=> + string(3) "abb" + } + [2]=> + object(for_string_rsort)#%d (3) { + ["public_class_value"]=> + string(2) "py" + ["private_class_value":"for_string_rsort":private]=> + string(2) "PY" + ["protected_class_value":protected]=> + string(2) "pt" + } + [3]=> + object(for_string_rsort)#%d (3) { + ["public_class_value"]=> + string(3) "axx" + ["private_class_value":"for_string_rsort":private]=> + string(3) "AXX" + ["protected_class_value":protected]=> + string(3) "ass" + } +} +Done diff --git a/tests/std/array/rsort_variation10.phpt b/tests/std/array/rsort_variation10.phpt new file mode 100644 index 00000000..6f9248c1 --- /dev/null +++ b/tests/std/array/rsort_variation10.phpt @@ -0,0 +1,102 @@ +--TEST-- +Test rsort() function : usage variations - Octal values +--FILE-- + +--EXPECT-- +*** Testing rsort() : variation *** + +-- Sort flag = default -- +bool(true) +array(9) { + [0]=> + int(669) + [1]=> + int(506) + [2]=> + int(229) + [3]=> + int(209) + [4]=> + int(63) + [5]=> + int(54) + [6]=> + int(0) + [7]=> + int(-54) + [8]=> + int(-229) +} + +-- Sort flag = SORT_REGULAR -- +bool(true) +array(9) { + [0]=> + int(669) + [1]=> + int(506) + [2]=> + int(229) + [3]=> + int(209) + [4]=> + int(63) + [5]=> + int(54) + [6]=> + int(0) + [7]=> + int(-54) + [8]=> + int(-229) +} + +-- Sort flag = SORT_NUMERIC -- +bool(true) +array(9) { + [0]=> + int(669) + [1]=> + int(506) + [2]=> + int(229) + [3]=> + int(209) + [4]=> + int(63) + [5]=> + int(54) + [6]=> + int(0) + [7]=> + int(-54) + [8]=> + int(-229) +} +Done diff --git a/tests/std/array/rsort_variation11.phpt b/tests/std/array/rsort_variation11.phpt new file mode 100644 index 00000000..fe91f79e --- /dev/null +++ b/tests/std/array/rsort_variation11.phpt @@ -0,0 +1,187 @@ +--TEST-- +Test rsort() function : usage variations - mixed array +--FILE-- + +--EXPECTF-- +*** Testing rsort() : variation *** + +-- Sort flag = default -- +bool(true) +array(22) { + [0]=> + array(4) { + [0]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + [1]=> + array(1) { + [0]=> + int(11) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [3]=> + array(0) { + } + } + [1]=> + array(0) { + } + [2]=> + string(1) "b" + [3]=> + string(14) "abcd%0abcd%0abcd" + [4]=> + string(4) "abcd" + [5]=> + string(2) "ab" + [6]=> + string(4) "True" + [7]=> + string(1) "5" + [8]=> + string(1) "4" + [9]=> + float(4) + [10]=> + string(3) "-.9" + [11]=> + int(-2) + [12]=> + float(-2) + [13]=> + float(-2.98989) + [14]=> + bool(true) + [15]=> + string(0) "" + [16]=> + NULL + [17]=> + float(0) + [18]=> + int(0) + [19]=> + int(-4) + [20]=> + string(0) "" + [21]=> + bool(false) +} + +-- Sort flag = SORT_REGULAR -- +bool(true) +array(22) { + [0]=> + array(4) { + [0]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + [1]=> + array(1) { + [0]=> + int(11) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [3]=> + array(0) { + } + } + [1]=> + array(0) { + } + [2]=> + string(1) "b" + [3]=> + string(14) "abcd%0abcd%0abcd" + [4]=> + string(4) "abcd" + [5]=> + string(2) "ab" + [6]=> + string(4) "True" + [7]=> + string(1) "5" + [8]=> + string(1) "4" + [9]=> + float(4) + [10]=> + string(3) "-.9" + [11]=> + int(-2) + [12]=> + float(-2) + [13]=> + float(-2.98989) + [14]=> + bool(true) + [15]=> + string(0) "" + [16]=> + NULL + [17]=> + float(0) + [18]=> + int(0) + [19]=> + int(-4) + [20]=> + string(0) "" + [21]=> + bool(false) +} +Done diff --git a/tests/std/array/rsort_variation3.phpt b/tests/std/array/rsort_variation3.phpt new file mode 100644 index 00000000..f2648f04 --- /dev/null +++ b/tests/std/array/rsort_variation3.phpt @@ -0,0 +1,319 @@ +--TEST-- +Test rsort() function : usage variations - numeric values +--SKIPIF-- + +--FILE-- + SORT_REGULAR, "SORT_NUMERIC" => SORT_NUMERIC); + +$count = 1; + +// loop through to test rsort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With Default sort flag -\n"; + $temp_array = $array; + var_dump(rsort($temp_array) ); + var_dump($temp_array); + + // loop through $flag_value array and setting all possible flag values + foreach($flag_value as $key => $flag){ + echo "- Sort flag = $key -\n"; + $temp_array = $array; + var_dump(rsort($temp_array, $flag) ); + var_dump($temp_array); + } + $count++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing rsort() : variation *** + +-- Iteration 1 -- +- With Default sort flag - +bool(true) +array(9) { + [0]=> + int(41) + [1]=> + int(31) + [2]=> + int(21) + [3]=> + int(11) + [4]=> + int(0) + [5]=> + int(-11) + [6]=> + int(-21) + [7]=> + int(-31) + [8]=> + int(-41) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(9) { + [0]=> + int(41) + [1]=> + int(31) + [2]=> + int(21) + [3]=> + int(11) + [4]=> + int(0) + [5]=> + int(-11) + [6]=> + int(-21) + [7]=> + int(-31) + [8]=> + int(-41) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(9) { + [0]=> + int(41) + [1]=> + int(31) + [2]=> + int(21) + [3]=> + int(11) + [4]=> + int(0) + [5]=> + int(-11) + [6]=> + int(-21) + [7]=> + int(-31) + [8]=> + int(-41) +} + +-- Iteration 2 -- +- With Default sort flag - +bool(true) +array(7) { + [0]=> + float(1050) + [1]=> + float(10.5) + [2]=> + float(0.5) + [3]=> + float(0.106) + [4]=> + float(0.01) + [5]=> + float(-0.1) + [6]=> + float(-10.5) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(7) { + [0]=> + float(1050) + [1]=> + float(10.5) + [2]=> + float(0.5) + [3]=> + float(0.106) + [4]=> + float(0.01) + [5]=> + float(-0.1) + [6]=> + float(-10.5) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(7) { + [0]=> + float(1050) + [1]=> + float(10.5) + [2]=> + float(0.5) + [3]=> + float(0.106) + [4]=> + float(0.01) + [5]=> + float(-0.1) + [6]=> + float(-10.5) +} + +-- Iteration 3 -- +- With Default sort flag - +bool(true) +array(11) { + [0]=> + int(33) + [1]=> + int(2) + [2]=> + float(0.106) + [3]=> + float(0.09) + [4]=> + float(0.0021) + [5]=> + float(0.0001) + [6]=> + int(0) + [7]=> + float(-0.01) + [8]=> + float(-0.106) + [9]=> + float(-0.9) + [10]=> + int(-1) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(11) { + [0]=> + int(33) + [1]=> + int(2) + [2]=> + float(0.106) + [3]=> + float(0.09) + [4]=> + float(0.0021) + [5]=> + float(0.0001) + [6]=> + int(0) + [7]=> + float(-0.01) + [8]=> + float(-0.106) + [9]=> + float(-0.9) + [10]=> + int(-1) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(11) { + [0]=> + int(33) + [1]=> + int(2) + [2]=> + float(0.106) + [3]=> + float(0.09) + [4]=> + float(0.0021) + [5]=> + float(0.0001) + [6]=> + int(0) + [7]=> + float(-0.01) + [8]=> + float(-0.106) + [9]=> + float(-0.9) + [10]=> + int(-1) +} + +-- Iteration 4 -- +- With Default sort flag - +bool(true) +array(7) { + [0]=> + float(2147483648) + [1]=> + int(2147483647) + [2]=> + int(0) + [3]=> + int(0) + [4]=> + int(-2147483647) + [5]=> + float(-2147483648) + [6]=> + float(-2147483649) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(7) { + [0]=> + float(2147483648) + [1]=> + int(2147483647) + [2]=> + int(0) + [3]=> + int(0) + [4]=> + int(-2147483647) + [5]=> + float(-2147483648) + [6]=> + float(-2147483649) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(7) { + [0]=> + float(2147483648) + [1]=> + int(2147483647) + [2]=> + int(0) + [3]=> + int(0) + [4]=> + int(-2147483647) + [5]=> + float(-2147483648) + [6]=> + float(-2147483649) +} +Done diff --git a/tests/std/array/rsort_variation4.phpt b/tests/std/array/rsort_variation4.phpt new file mode 100644 index 00000000..baea5484 --- /dev/null +++ b/tests/std/array/rsort_variation4.phpt @@ -0,0 +1,62 @@ +--TEST-- +Test rsort() function : usage variations - referenced variables +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +*** Testing rsort() : variation *** + +-- 'flag' value is default -- +bool(true) +array(3) { + [0]=> + &int(555) + [1]=> + &int(100) + [2]=> + &int(33) +} + +-- 'flag' = SORT_REGULAR -- +bool(true) +array(3) { + [0]=> + &int(555) + [1]=> + &int(100) + [2]=> + &int(33) +} +Done diff --git a/tests/std/array/rsort_variation5.phpt b/tests/std/array/rsort_variation5.phpt new file mode 100644 index 00000000..6b05443b --- /dev/null +++ b/tests/std/array/rsort_variation5.phpt @@ -0,0 +1,215 @@ +--TEST-- +Test rsort() function : usage variations - String values +--FILE-- + SORT_REGULAR, "SORT_STRING" => SORT_STRING); + +$count = 1; +// loop through to test rsort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With Default sort flag -\n"; + $temp_array = $array; + var_dump(rsort($temp_array) ); + var_dump($temp_array); + + // loop through $flags array and setting all possible flag values + foreach($flags as $key => $flag){ + echo "- Sort flag = $key -\n"; + + $temp_array = $array; + var_dump(rsort($temp_array, $flag) ); + var_dump($temp_array); + } + $count++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing rsort() : variation *** + +-- Iteration 1 -- +- With Default sort flag - +bool(true) +array(11) { + [0]=> + string(4) "\xhh" + [1]=> + string(4) "\ddd" + [2]=> + string(3) "\cx" + [3]=> + string(2) "\a" + [4]=> + string(1) "" + [5]=> + string(1) " " + [6]=> + string(1) " " + [7]=> + string(1) " +" + [8]=> + string(1) " " + [9]=> + NULL + [10]=> + NULL +} +- Sort flag = SORT_REGULAR - +bool(true) +array(11) { + [0]=> + string(4) "\xhh" + [1]=> + string(4) "\ddd" + [2]=> + string(3) "\cx" + [3]=> + string(2) "\a" + [4]=> + string(1) "" + [5]=> + string(1) " " + [6]=> + string(1) " " + [7]=> + string(1) " +" + [8]=> + string(1) " " + [9]=> + NULL + [10]=> + NULL +} +- Sort flag = SORT_STRING - +bool(true) +array(11) { + [0]=> + string(4) "\xhh" + [1]=> + string(4) "\ddd" + [2]=> + string(3) "\cx" + [3]=> + string(2) "\a" + [4]=> + string(1) "" + [5]=> + string(1) " " + [6]=> + string(1) " " + [7]=> + string(1) " +" + [8]=> + string(1) " " + [9]=> + NULL + [10]=> + NULL +} + +-- Iteration 2 -- +- With Default sort flag - +bool(true) +array(12) { + [0]=> + string(1) "x" + [1]=> + string(2) "ww" + [2]=> + string(3) "ttt" + [3]=> + string(6) "oraNGe" + [4]=> + string(5) "lemoN" + [5]=> + string(6) "banana" + [6]=> + string(5) "apple" + [7]=> + string(1) "X" + [8]=> + string(4) "Test" + [9]=> + string(4) "TTTT" + [10]=> + string(6) "Orange" + [11]=> + string(6) "BANANA" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(12) { + [0]=> + string(1) "x" + [1]=> + string(2) "ww" + [2]=> + string(3) "ttt" + [3]=> + string(6) "oraNGe" + [4]=> + string(5) "lemoN" + [5]=> + string(6) "banana" + [6]=> + string(5) "apple" + [7]=> + string(1) "X" + [8]=> + string(4) "Test" + [9]=> + string(4) "TTTT" + [10]=> + string(6) "Orange" + [11]=> + string(6) "BANANA" +} +- Sort flag = SORT_STRING - +bool(true) +array(12) { + [0]=> + string(1) "x" + [1]=> + string(2) "ww" + [2]=> + string(3) "ttt" + [3]=> + string(6) "oraNGe" + [4]=> + string(5) "lemoN" + [5]=> + string(6) "banana" + [6]=> + string(5) "apple" + [7]=> + string(1) "X" + [8]=> + string(4) "Test" + [9]=> + string(4) "TTTT" + [10]=> + string(6) "Orange" + [11]=> + string(6) "BANANA" +} +Done diff --git a/tests/std/array/rsort_variation6.phpt b/tests/std/array/rsort_variation6.phpt new file mode 100644 index 00000000..3394402e --- /dev/null +++ b/tests/std/array/rsort_variation6.phpt @@ -0,0 +1,114 @@ +--TEST-- +Test rsort() function : usage variations - Hexadecimal vales +--FILE-- + +--EXPECT-- +*** Testing rsort() : variation *** + +-- 'flag' value is default -- +bool(true) +array(11) { + [0]=> + int(4095) + [1]=> + int(682) + [2]=> + int(427) + [3]=> + int(427) + [4]=> + int(255) + [5]=> + int(255) + [6]=> + int(187) + [7]=> + int(15) + [8]=> + int(0) + [9]=> + int(-255) + [10]=> + int(-682) +} + +-- 'flag' value is SORT_REGULAR -- +bool(true) +array(11) { + [0]=> + int(4095) + [1]=> + int(682) + [2]=> + int(427) + [3]=> + int(427) + [4]=> + int(255) + [5]=> + int(255) + [6]=> + int(187) + [7]=> + int(15) + [8]=> + int(0) + [9]=> + int(-255) + [10]=> + int(-682) +} + +-- 'flag' value is SORT_NUMERIC -- +bool(true) +array(11) { + [0]=> + int(4095) + [1]=> + int(682) + [2]=> + int(427) + [3]=> + int(427) + [4]=> + int(255) + [5]=> + int(255) + [6]=> + int(187) + [7]=> + int(15) + [8]=> + int(0) + [9]=> + int(-255) + [10]=> + int(-682) +} +Done diff --git a/tests/std/array/rsort_variation7.phpt b/tests/std/array/rsort_variation7.phpt new file mode 100644 index 00000000..28b02a74 --- /dev/null +++ b/tests/std/array/rsort_variation7.phpt @@ -0,0 +1,90 @@ +--TEST-- +Test rsort() function : usage variations - boolean values +--FILE-- + +--EXPECT-- +*** Testing rsort() : variation *** + +-- 'flag' value is default -- +bool(true) +array(4) { + [0]=> + bool(true) + [1]=> + bool(true) + [2]=> + bool(false) + [3]=> + bool(false) +} + +-- 'flag' value is SORT_REGULAR -- +bool(true) +array(4) { + [0]=> + bool(true) + [1]=> + bool(true) + [2]=> + bool(false) + [3]=> + bool(false) +} + +-- 'flag' value is SORT_NUMERIC -- +bool(true) +array(4) { + [0]=> + bool(true) + [1]=> + bool(true) + [2]=> + bool(false) + [3]=> + bool(false) +} + +-- 'flag' value is SORT_STRING -- +bool(true) +array(4) { + [0]=> + bool(true) + [1]=> + bool(true) + [2]=> + bool(false) + [3]=> + bool(false) +} +Done diff --git a/tests/std/array/rsort_variation8.phpt b/tests/std/array/rsort_variation8.phpt new file mode 100644 index 00000000..8d8aa15f --- /dev/null +++ b/tests/std/array/rsort_variation8.phpt @@ -0,0 +1,174 @@ +--TEST-- +Test rsort() function : usage variations - multi-dimensional arrays +--FILE-- + +--EXPECT-- +*** Testing rsort() : variation *** + +-- Iteration 1 -- + +-- 'flag' value is default -- +bool(true) +array(0) { +} + +-- 'flag' value is SORT_REGULAR -- +bool(true) +array(0) { +} + +-- Iteration 2 -- + +-- 'flag' value is default -- +bool(true) +array(1) { + [0]=> + array(0) { + } +} + +-- 'flag' value is SORT_REGULAR -- +bool(true) +array(1) { + [0]=> + array(0) { + } +} + +-- Iteration 3 -- + +-- 'flag' value is default -- +bool(true) +array(3) { + [0]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } + [1]=> + int(44) + [2]=> + int(11) +} + +-- 'flag' value is SORT_REGULAR -- +bool(true) +array(3) { + [0]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } + [1]=> + int(44) + [2]=> + int(11) +} + +-- Iteration 4 -- + +-- 'flag' value is default -- +bool(true) +array(4) { + [0]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + [1]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [2]=> + array(1) { + [0]=> + int(11) + } + [3]=> + array(0) { + } +} + +-- 'flag' value is SORT_REGULAR -- +bool(true) +array(4) { + [0]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + [1]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [2]=> + array(1) { + [0]=> + int(11) + } + [3]=> + array(0) { + } +} +Done diff --git a/tests/std/array/rsort_variation9.phpt b/tests/std/array/rsort_variation9.phpt new file mode 100644 index 00000000..f46c2270 --- /dev/null +++ b/tests/std/array/rsort_variation9.phpt @@ -0,0 +1,254 @@ +--TEST-- +Test rsort() function : usage variations - mixed associative arrays +--FILE-- + 55, 6 => 66, 2 => 22, 3 => 33, 1 => 11), + + // two-dimensional assoc. and default key array + array("fruits" => array("a" => "orange", "b" => "banana", "c" => "apple"), + "numbers" => array(1, 2, 3, 4, 5, 6), + "holes" => array("first", 5 => "second", "third")), + + // numeric assoc. and default key array + array(1, 1, 8 => 1, 4 => 1, 19, 3 => 13), + + // mixed assoc. array + array('bar' => 'baz', "foo" => 1), + + // assoc. only multi-dimensional array + array('a' => 1,'b' => array('e' => 2,'f' => 3),'c' => array('g' => 4),'d' => 5), +); + +$count = 1; + +// loop through to test rsort() with different arrays, +// to test the new keys for the elements in the sorted array +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "-- Sort flag = default --\n"; + $temp_array = $array; + var_dump(rsort($temp_array) ); + var_dump($temp_array); + + echo "-- Sort flag = SORT_REGULAR --\n"; + $temp_array = $array; + var_dump(rsort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing rsort() : variation *** + +-- Iteration 1 -- +-- Sort flag = default -- +bool(true) +array(5) { + [0]=> + int(66) + [1]=> + int(55) + [2]=> + int(33) + [3]=> + int(22) + [4]=> + int(11) +} +-- Sort flag = SORT_REGULAR -- +bool(true) +array(5) { + [0]=> + int(66) + [1]=> + int(55) + [2]=> + int(33) + [3]=> + int(22) + [4]=> + int(11) +} + +-- Iteration 2 -- +-- Sort flag = default -- +bool(true) +array(3) { + [0]=> + array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } + [1]=> + array(3) { + ["a"]=> + string(6) "orange" + ["b"]=> + string(6) "banana" + ["c"]=> + string(5) "apple" + } + [2]=> + array(3) { + [0]=> + string(5) "first" + [5]=> + string(6) "second" + [6]=> + string(5) "third" + } +} +-- Sort flag = SORT_REGULAR -- +bool(true) +array(3) { + [0]=> + array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } + [1]=> + array(3) { + ["a"]=> + string(6) "orange" + ["b"]=> + string(6) "banana" + ["c"]=> + string(5) "apple" + } + [2]=> + array(3) { + [0]=> + string(5) "first" + [5]=> + string(6) "second" + [6]=> + string(5) "third" + } +} + +-- Iteration 3 -- +-- Sort flag = default -- +bool(true) +array(6) { + [0]=> + int(19) + [1]=> + int(13) + [2]=> + int(1) + [3]=> + int(1) + [4]=> + int(1) + [5]=> + int(1) +} +-- Sort flag = SORT_REGULAR -- +bool(true) +array(6) { + [0]=> + int(19) + [1]=> + int(13) + [2]=> + int(1) + [3]=> + int(1) + [4]=> + int(1) + [5]=> + int(1) +} + +-- Iteration 4 -- +-- Sort flag = default -- +bool(true) +array(2) { + [0]=> + string(3) "baz" + [1]=> + int(1) +} +-- Sort flag = SORT_REGULAR -- +bool(true) +array(2) { + [0]=> + string(3) "baz" + [1]=> + int(1) +} + +-- Iteration 5 -- +-- Sort flag = default -- +bool(true) +array(4) { + [0]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } + [1]=> + array(1) { + ["g"]=> + int(4) + } + [2]=> + int(5) + [3]=> + int(1) +} +-- Sort flag = SORT_REGULAR -- +bool(true) +array(4) { + [0]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } + [1]=> + array(1) { + ["g"]=> + int(4) + } + [2]=> + int(5) + [3]=> + int(1) +} +Done diff --git a/tests/std/array/shuffle_basic1.phpt b/tests/std/array/shuffle_basic1.phpt new file mode 100644 index 00000000..d2af45db --- /dev/null +++ b/tests/std/array/shuffle_basic1.phpt @@ -0,0 +1,144 @@ +--TEST-- +Test shuffle() function : basic functionality - array with default keys +--FILE-- + +--EXPECTF-- +*** Testing shuffle() : with arrays having default keys *** + +-- input array of integers before shuffle() function is applied -- +array(9) { + [0]=> + int(0) + [1]=> + int(10) + [2]=> + int(20) + [3]=> + int(30) + [4]=> + int(40) + [5]=> + int(50) + [6]=> + int(60) + [7]=> + int(70) + [8]=> + int(80) +} + +-- return value from shuffle() function -- +bool(true) + +-- resultant array after shuffle() function is applied -- +array(9) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + [3]=> + int(%d) + [4]=> + int(%d) + [5]=> + int(%d) + [6]=> + int(%d) + [7]=> + int(%d) + [8]=> + int(%d) +} + +-- input array of strings before shuffle() function is applied -- +array(9) { + [0]=> + string(3) "one" + [1]=> + string(3) "two" + [2]=> + string(5) "three" + [3]=> + string(4) "four" + [4]=> + string(4) "five" + [5]=> + string(1) " " + [6]=> + string(3) "six" + [7]=> + string(1) " " + [8]=> + string(5) "seven" +} + +-- return value from shuffle() function -- +bool(true) + +-- resultant array after shuffle() function is applied -- +array(9) { + [0]=> + string(%d) "%s" + [1]=> + string(%d) "%s" + [2]=> + string(%d) "%s" + [3]=> + string(%d) "%s" + [4]=> + string(%d) "%s" + [5]=> + string(%d) "%s" + [6]=> + string(%d) "%s" + [7]=> + string(%d) "%s" + [8]=> + string(%d) "%s" +} +Done diff --git a/tests/std/array/shuffle_basic2.phpt b/tests/std/array/shuffle_basic2.phpt new file mode 100644 index 00000000..b6c86cb4 --- /dev/null +++ b/tests/std/array/shuffle_basic2.phpt @@ -0,0 +1,83 @@ +--TEST-- +Test shuffle() function : basic functionality - with associative array +--FILE-- + 1, 2 => 02, 'three' => 3, + 4 => 4, '#5' => 5, 'SIX' => 6, + "seven" => 0x7, "#8" => 012, "nine" => 9 +); + +// printing the input array before the shuffle operation +echo "\n-- input array before shuffle() function is applied --\n"; +var_dump( $array_arg ); + +// applying shuffle() function on the input array +echo "\n-- return value from shuffle() function --\n"; +var_dump( shuffle($array_arg) ); // prints the return value from shuffle() function + +echo "\n-- resultant array after shuffle() function is applied --\n"; +var_dump( $array_arg ); + +echo "Done"; +?> +--EXPECTF-- +*** Testing shuffle() : with associative array *** + +-- input array before shuffle() function is applied -- +array(9) { + ["one"]=> + int(1) + [2]=> + int(2) + ["three"]=> + int(3) + [4]=> + int(4) + ["#5"]=> + int(5) + ["SIX"]=> + int(6) + ["seven"]=> + int(7) + ["#8"]=> + int(10) + ["nine"]=> + int(9) +} + +-- return value from shuffle() function -- +bool(true) + +-- resultant array after shuffle() function is applied -- +array(9) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + [3]=> + int(%d) + [4]=> + int(%d) + [5]=> + int(%d) + [6]=> + int(%d) + [7]=> + int(%d) + [8]=> + int(%d) +} +Done diff --git a/tests/std/array/shuffle_variation2.phpt b/tests/std/array/shuffle_variation2.phpt new file mode 100644 index 00000000..ab90db3f --- /dev/null +++ b/tests/std/array/shuffle_variation2.phpt @@ -0,0 +1,206 @@ +--TEST-- +Test shuffle() function : usage variation - with MultiDimensional array +--FILE-- + +--EXPECTF-- +*** Testing shuffle() : with multi-dimensional array *** +bool(true) + +The output array is: +array(7) { + [0]=> + array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + } + [1]=> + array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + } + [2]=> + array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + } + [3]=> + array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + } + [4]=> + array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + } + [5]=> + array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + } + [6]=> + array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + } +} + +*** Testing shuffle() with arrays having different types of values *** + +-- Iteration 1 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 2 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 3 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 4 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 5 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 6 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} + +-- Iteration 7 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) +} +Done diff --git a/tests/std/array/shuffle_variation3.phpt b/tests/std/array/shuffle_variation3.phpt new file mode 100644 index 00000000..87abe349 --- /dev/null +++ b/tests/std/array/shuffle_variation3.phpt @@ -0,0 +1,227 @@ +--TEST-- +Test shuffle() function : usage variation - arrays with diff types of values +--FILE-- + +--EXPECTF-- +*** Testing shuffle() : arrays with diff types of values *** + +*** Testing shuffle() with arrays having different types of values *** + +-- Iteration 1 -- +bool(true) + +The output array is: +array(4) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + [3]=> + int(%d) +} + +-- Iteration 2 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(-%d) + [1]=> + int(-%d) + [2]=> + int(-%d) +} + +-- Iteration 3 -- +bool(true) + +The output array is: +array(7) { + [0]=> + float(%f) + [1]=> + float(%f) + [2]=> + float(%f) + [3]=> + float(%f) + [4]=> + float(%f) + [5]=> + float(%f) + [6]=> + float(%f) +} + +-- Iteration 4 -- +bool(true) + +The output array is: +array(6) { + [0]=> + float(-%f) + [1]=> + float(-%f) + [2]=> + float(-%f) + [3]=> + float(-%f) + [4]=> + float(-%f) + [5]=> + float(-%f) +} + +-- Iteration 5 -- +bool(true) + +The output array is: +array(5) { + [0]=> + string(%d) "%s" + [1]=> + string(%d) "%s" + [2]=> + string(%d) "%s" + [3]=> + string(%d) "%s" + [4]=> + string(%d) "%s" +} + +-- Iteration 6 -- +bool(true) + +The output array is: +array(4) { + [0]=> + bool(%s) + [1]=> + bool(%s) + [2]=> + bool(%s) + [3]=> + bool(%s) +} + +-- Iteration 7 -- +bool(true) + +The output array is: +array(6) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + [3]=> + int(%d) + [4]=> + int(%d) + [5]=> + int(%d) +} + +-- Iteration 8 -- +bool(true) + +The output array is: +array(5) { + [0]=> + int(-%d) + [1]=> + int(-%d) + [2]=> + int(-%d) + [3]=> + int(-%d) + [4]=> + int(-%d) +} + +-- Iteration 9 -- +bool(true) + +The output array is: +array(4) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + [3]=> + int(%d) +} + +-- Iteration 10 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(-%d) + [1]=> + int(-%d) + [2]=> + int(-%d) +} +Done diff --git a/tests/std/array/shuffle_variation4.phpt b/tests/std/array/shuffle_variation4.phpt new file mode 100644 index 00000000..1d3269e7 --- /dev/null +++ b/tests/std/array/shuffle_variation4.phpt @@ -0,0 +1,225 @@ +--TEST-- +Test shuffle() function : usage variation - associative arrays with diff types of values +--FILE-- + 0, 1 => 1, "two" => 2, "max_int" => 2147483647 ), + + // array with negative int values + array("minus_one" => -1, 'minus_two' => -2, "min_int" => -2147483647 ), + + // array with positive float values +/*3*/ array("float1" => 0.23, 'float2' => 1.34, "exp1" => 0e2, 'exp2' => 200e-2, "exp3" => 10e0), + + // array with negative float values + array(-0 => -0.23, -1 => -1.34, -200 => -200e-2, -30 => -30e0, -2147473649.80), + + // array with single and double quoted strings +/*5*/ array('1' => 'one', "str1" => "123numbers", '' => 'hello\tworld', "" => "hello world\0", "12.34floatnum"), + + // array with bool values + array('1' => TRUE, "1" => TRUE, "0" => FALSE, '0' => FALSE), + + // array with positive hexa values +/*7*/ array("hex1" => 0x123, 'hex2' => 0xabc, "hex\t3" => 0xABC, "hex\04" => 0xAb1), + + // array with negative hexa values + array(NULL => -0x123, "NULL" => -0xabc, "-ABC" => -0xABC, -0xAB1 => -0xAb1), + + // array with positive octal values +/*9*/ array(0123 => 0123, "0234" => 0234, '034' => 034, 00 => 00), + + // array with negative octal values + array(-0123 => -0123, "-0234" => -0234, '-034' => -034), + + // array with null values +/*11*/ array(NULL => NULL, "null" => NULL, "NULL" => NULL) + +); + +// looping to test shuffle() with each sub-array in the $array_arg array +echo "\n*** Testing shuffle() with arrays having different types of values ***\n"; +$counter = 1; +foreach($array_arg as $arr) { + echo "\n-- Iteration $counter --\n"; + var_dump( shuffle($arr) ); + echo "\nThe output array is:\n"; + var_dump( $arr ); + $counter++; +} + +echo "Done"; +?> +--EXPECTF-- +*** Testing shuffle() : associative arrays with diff types of values *** + +*** Testing shuffle() with arrays having different types of values *** + +-- Iteration 1 -- +bool(true) + +The output array is: +array(4) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + [3]=> + int(%d) +} + +-- Iteration 2 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(-%d) + [1]=> + int(-%d) + [2]=> + int(-%d) +} + +-- Iteration 3 -- +bool(true) + +The output array is: +array(5) { + [0]=> + float(%f) + [1]=> + float(%f) + [2]=> + float(%f) + [3]=> + float(%f) + [4]=> + float(%f) +} + +-- Iteration 4 -- +bool(true) + +The output array is: +array(5) { + [0]=> + float(-%f) + [1]=> + float(-%f) + [2]=> + float(-%f) + [3]=> + float(-%f) + [4]=> + float(-%f) +} + +-- Iteration 5 -- +bool(true) + +The output array is: +array(4) { + [0]=> + string(%d) "%s" + [1]=> + string(%d) "%s" + [2]=> + string(%d) "%s" + [3]=> + string(%d) "%s" +} + +-- Iteration 6 -- +bool(true) + +The output array is: +array(2) { + [0]=> + bool(%s) + [1]=> + bool(%s) +} + +-- Iteration 7 -- +bool(true) + +The output array is: +array(4) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + [3]=> + int(%d) +} + +-- Iteration 8 -- +bool(true) + +The output array is: +array(4) { + [0]=> + int(-%d) + [1]=> + int(-%d) + [2]=> + int(-%d) + [3]=> + int(-%d) +} + +-- Iteration 9 -- +bool(true) + +The output array is: +array(4) { + [0]=> + int(%d) + [1]=> + int(%d) + [2]=> + int(%d) + [3]=> + int(%d) +} + +-- Iteration 10 -- +bool(true) + +The output array is: +array(3) { + [0]=> + int(-%d) + [1]=> + int(-%d) + [2]=> + int(-%d) +} + +-- Iteration 11 -- +bool(true) + +The output array is: +array(3) { + [0]=> + NULL + [1]=> + NULL + [2]=> + NULL +} +Done diff --git a/tests/std/array/shuffle_variation5.phpt b/tests/std/array/shuffle_variation5.phpt new file mode 100644 index 00000000..7ad0c016 --- /dev/null +++ b/tests/std/array/shuffle_variation5.phpt @@ -0,0 +1,114 @@ +--TEST-- +Test shuffle() function : usage variation - arrays with diff heredoc strings +--FILE-- + "heredoc1", + $heredoc_with_newline => "heredoc2", + $heredoc_with_characters => "heredoc3", + $heredoc_with_newline_and_tabs => "heredoc3", + $heredoc_with_alphanumerics => "heredoc4", + $heredoc_with_embedded_nulls => "heredoc5" +); + +// test shuffle() with array containing heredoc strings as values +echo "\n-- with array of heredoc strings --\n"; +var_dump( shuffle($heredoc_array) ); +echo "\nThe output array is:\n"; +var_dump( $heredoc_array ); + +// test shuffle() with array containing heredoc strings as its keys +echo "\n-- with array having heredoc strings as keys --\n"; +var_dump( shuffle($heredoc_asso_array) ); +echo "\nThe output array is:\n"; +var_dump( $heredoc_asso_array ); + +echo "Done"; +?> +--EXPECTREGEX-- +\*\*\* Testing shuffle\(\) : with array containing heredoc strings \*\*\* + +-- with array of heredoc strings -- +bool\(true\) + +The output array is: +array\(6\) { + \[0\]=> + string\([0-9]*\) "[0-9 a-z \n \0 \t]*" + \[1\]=> + string\([0-9]*\) "[0-9 a-z \n \0 \t]*" + \[2\]=> + string\([0-9]*\) "[0-9 a-z \n \0 \t]*" + \[3\]=> + string\([0-9]*\) "[0-9 a-z \n \0 \t]*" + \[4\]=> + string\([0-9]*\) "[0-9 a-z \n \0 \t]*" + \[5\]=> + string\([0-9]*\) "[0-9 a-z \n \0 \t]*" +} + +-- with array having heredoc strings as keys -- +bool\(true\) + +The output array is: +array\(6\) { + \[0\]=> + string\(8\) "[heredoc 1-5]*" + \[1\]=> + string\(8\) "[heredoc 1-5]*" + \[2\]=> + string\(8\) "[heredoc 1-5]*" + \[3\]=> + string\(8\) "[heredoc 1-5]*" + \[4\]=> + string\(8\) "[heredoc 1-5]*" + \[5\]=> + string\(8\) "[heredoc 1-5]*" +} +Done diff --git a/tests/std/array/sizeof_basic2.phpt b/tests/std/array/sizeof_basic2.phpt new file mode 100644 index 00000000..e77a0d6a --- /dev/null +++ b/tests/std/array/sizeof_basic2.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test sizeof() function : basic functionality - for non-scalar type(array) +--FILE-- + "Saffron", "Peace" => "White", "Growth" => "Green"); +$mixed_array = array(1, 2, "Aggression" => "Saffron", 10 => "Ten", "Ten" => 10); + +echo "-- Testing sizeof() with integer array in default, COUNT_NORMAL, COUNT_RECURSIVE modes --\n"; +echo "default mode: "; +var_dump( sizeof($int_array) ); +echo "\n"; +echo "COUNT_NORMAL mode: "; +var_dump( sizeof($int_array, COUNT_NORMAL) ); +echo "\n"; +echo "COUNT_RECURSIVE mode: "; +var_dump( sizeof($int_array, COUNT_RECURSIVE) ); +echo "\n"; + +echo "-- Testing sizeof() with string array in default, COUNT_NORMAL, COUNT_RECURSIVE modes --\n"; +echo "default mode: "; +var_dump( sizeof($string_array) ); +echo "\n"; +echo "COUNT_NORMAL mode: "; +var_dump( sizeof($string_array, COUNT_NORMAL) ); +echo "\n"; +echo "COUNT_RECURSIVE mode: "; +var_dump( sizeof($string_array, COUNT_RECURSIVE) ); +echo "\n"; + +echo "-- Testing sizeof() with indexed array in default, COUNT_NORMAL, COUNT_RECURSIVE modes --\n"; +echo "default mode: "; +var_dump( sizeof($indexed_array) ); +echo "\n"; +echo "COUNT_NORMAL mode: "; +var_dump( sizeof($indexed_array, COUNT_NORMAL) ); +echo "\n"; +echo "COUNT_RECURSIVE mode: "; +var_dump( sizeof($indexed_array, COUNT_RECURSIVE) ); +echo "\n"; + +echo "-- Testing sizeof() with mixed array in default, COUNT_NORMAL, COUNT_RECURSIVE modes --\n"; +echo "default mode: "; +var_dump( sizeof($mixed_array) ); +echo "\n"; +echo "COUNT_NORMAL mode: "; +var_dump( sizeof($mixed_array, COUNT_NORMAL) ); +echo "\n"; +echo "COUNT_RECURSIVE mode: "; +var_dump( sizeof($mixed_array, COUNT_RECURSIVE) ); + +echo "Done"; +?> +--EXPECT-- +*** Testing sizeof() : basic functionality *** +-- Testing sizeof() with integer array in default, COUNT_NORMAL, COUNT_RECURSIVE modes -- +default mode: int(4) + +COUNT_NORMAL mode: int(4) + +COUNT_RECURSIVE mode: int(4) + +-- Testing sizeof() with string array in default, COUNT_NORMAL, COUNT_RECURSIVE modes -- +default mode: int(3) + +COUNT_NORMAL mode: int(3) + +COUNT_RECURSIVE mode: int(3) + +-- Testing sizeof() with indexed array in default, COUNT_NORMAL, COUNT_RECURSIVE modes -- +default mode: int(3) + +COUNT_NORMAL mode: int(3) + +COUNT_RECURSIVE mode: int(3) + +-- Testing sizeof() with mixed array in default, COUNT_NORMAL, COUNT_RECURSIVE modes -- +default mode: int(5) + +COUNT_NORMAL mode: int(5) + +COUNT_RECURSIVE mode: int(5) +Done diff --git a/tests/std/array/sizeof_object1.phpt b/tests/std/array/sizeof_object1.phpt new file mode 100644 index 00000000..681f28f3 --- /dev/null +++ b/tests/std/array/sizeof_object1.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test sizeof() function : object functionality - object with Countable interface +--FILE-- + +--EXPECT-- +*** Testing sizeof() : object functionality *** +-- Testing sizeof() with an object which implements Countable interface -- +-- Testing sizeof() in default mode -- +int(3) +-- Testing sizeof() in COUNT_NORMAL mode -- +int(3) +-- Testing sizeof() in COUNT_RECURSIVE mode -- +int(3) +Done diff --git a/tests/std/array/sizeof_object2.phpt b/tests/std/array/sizeof_object2.phpt new file mode 100644 index 00000000..675ebcab --- /dev/null +++ b/tests/std/array/sizeof_object2.phpt @@ -0,0 +1,112 @@ +--TEST-- +Test sizeof() function : object functionality - objects without Countable interface +--FILE-- +getMessage() . \PHP_EOL; + } + echo "COUNT_NORMAL Mode: "; + try { + var_dump(sizeof($var, COUNT_NORMAL)); + } catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; + } + echo "COUNT_RECURSIVE Mode: "; + try { + var_dump(sizeof($var, COUNT_RECURSIVE)); + } catch (\TypeError $e) { + echo $e->getMessage() . \PHP_EOL; + } + $counter++; + } + echo "Done"; +} +?> +--EXPECT-- +*** Testing sizeof() : object functionality *** +--- Testing sizeof() with objects which doesn't implement Countable interface --- +-- Iteration 1 -- +Default Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, test given +COUNT_NORMAL Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, test given +COUNT_RECURSIVE Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, test given +-- Iteration 2 -- +Default Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, test1 given +COUNT_NORMAL Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, test1 given +COUNT_RECURSIVE Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, test1 given +-- Iteration 3 -- +Default Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, test2 given +COUNT_NORMAL Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, test2 given +COUNT_RECURSIVE Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, test2 given +-- Iteration 4 -- +Default Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, child_test2 given +COUNT_NORMAL Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, child_test2 given +COUNT_RECURSIVE Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, child_test2 given +-- Iteration 5 -- +Default Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, concrete_class given +COUNT_NORMAL Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, concrete_class given +COUNT_RECURSIVE Mode: sizeof(): Argument #1 ($value) must be of type Countable|array, concrete_class given +Done diff --git a/tests/std/array/sizeof_variation2.phpt b/tests/std/array/sizeof_variation2.phpt new file mode 100644 index 00000000..baa917a2 --- /dev/null +++ b/tests/std/array/sizeof_variation2.phpt @@ -0,0 +1,156 @@ +--TEST-- +Test sizeof() function : usage variations - different array values for 'var' argument +--FILE-- + $fp), + array(1, array(3, 4, array(6, array(8)))), + array("a" => 1, 'b' => 2, array( "c" =>3, array( "d" => 5))), + array(), + /* 5 */ array(1, 2, 3, 4), + array("Saffron", "White", "Green"), + array('saffron', 'white', 'green'), + array(1 => "Hi", 2 => "Hello" ), + array("color" => "red", "item" => "pen"), + /* 10 */ array('color' => 'red', 'item' => 'pen'), + array(TRUE => "red", FALSE => "pen" ), + array(false => 'red', true => 'pen' ), + array('color' => "red", "item" => 'pen', 1 => "Hi", "" => "Hello" ), + /* 14 */ array($fp, "resource1" => $fp, 'resource2' => $fp, array( $fp, 'type' => $fp) ) +); + +// loop through each element of the values array for 'var' argument +// check the working of sizeof() +$counter = 1; +for($i = 0; $i < count($values); $i++) +{ + echo "-- Iteration $counter --\n"; + $var = $values[$i]; + + echo "Default Mode: "; + var_dump( sizeof($var) ); + echo "\n"; + + echo "COUNT_NORMAL Mode: "; + var_dump( sizeof($var, COUNT_NORMAL) ); + echo "\n"; + + echo "COUNT_RECURSIVE Mode: "; + var_dump( sizeof($var, COUNT_RECURSIVE) ); + echo "\n"; + + $counter++; +} + +echo "Done"; +?> +--EXPECT-- +*** Testing sizeof() : usage variations *** +--- Testing sizeof() with different array values for 'var' argument --- +-- Iteration 1 -- +Default Mode: int(2) + +COUNT_NORMAL Mode: int(2) + +COUNT_RECURSIVE Mode: int(2) + +-- Iteration 2 -- +Default Mode: int(2) + +COUNT_NORMAL Mode: int(2) + +COUNT_RECURSIVE Mode: int(8) + +-- Iteration 3 -- +Default Mode: int(3) + +COUNT_NORMAL Mode: int(3) + +COUNT_RECURSIVE Mode: int(6) + +-- Iteration 4 -- +Default Mode: int(0) + +COUNT_NORMAL Mode: int(0) + +COUNT_RECURSIVE Mode: int(0) + +-- Iteration 5 -- +Default Mode: int(4) + +COUNT_NORMAL Mode: int(4) + +COUNT_RECURSIVE Mode: int(4) + +-- Iteration 6 -- +Default Mode: int(3) + +COUNT_NORMAL Mode: int(3) + +COUNT_RECURSIVE Mode: int(3) + +-- Iteration 7 -- +Default Mode: int(3) + +COUNT_NORMAL Mode: int(3) + +COUNT_RECURSIVE Mode: int(3) + +-- Iteration 8 -- +Default Mode: int(2) + +COUNT_NORMAL Mode: int(2) + +COUNT_RECURSIVE Mode: int(2) + +-- Iteration 9 -- +Default Mode: int(2) + +COUNT_NORMAL Mode: int(2) + +COUNT_RECURSIVE Mode: int(2) + +-- Iteration 10 -- +Default Mode: int(2) + +COUNT_NORMAL Mode: int(2) + +COUNT_RECURSIVE Mode: int(2) + +-- Iteration 11 -- +Default Mode: int(2) + +COUNT_NORMAL Mode: int(2) + +COUNT_RECURSIVE Mode: int(2) + +-- Iteration 12 -- +Default Mode: int(2) + +COUNT_NORMAL Mode: int(2) + +COUNT_RECURSIVE Mode: int(2) + +-- Iteration 13 -- +Default Mode: int(4) + +COUNT_NORMAL Mode: int(4) + +COUNT_RECURSIVE Mode: int(4) + +-- Iteration 14 -- +Default Mode: int(4) + +COUNT_NORMAL Mode: int(4) + +COUNT_RECURSIVE Mode: int(6) + +Done diff --git a/tests/std/array/sizeof_variation3.phpt b/tests/std/array/sizeof_variation3.phpt new file mode 100644 index 00000000..4b4a3d7b --- /dev/null +++ b/tests/std/array/sizeof_variation3.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test sizeof() function : usage variations - checking for infinite recursion in COUNT_RECURSIVE mode +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +*** Testing sizeof() : usage variations *** +-- Testing sizeof() for infinite recursion with arrays as argument in COUNT_RECURSIVE mode -- +int(13) + +int(2) +Done diff --git a/tests/std/array/sort_basic.phpt b/tests/std/array/sort_basic.phpt new file mode 100644 index 00000000..8f50c6e1 --- /dev/null +++ b/tests/std/array/sort_basic.phpt @@ -0,0 +1,240 @@ +--TEST-- +Test sort() function : basic functionality +--FILE-- + "lemon", "o" => "orange", + "O" => "Orange", "O1" => "Orange1", "o2" => "orange2", "O3" => "Orange3", "o20" => "orange20", + "b" => "banana", +); + +// array with default keys containing unsorted numeric values +$unsorted_numerics = array( 100, 33, 555, 22 ); + +echo "\n-- Testing sort() by supplying string array, 'flag' value is default --\n"; +$temp_array = $unsorted_strings; +var_dump( sort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing sort() by supplying numeric array, 'flag' value is default --\n"; +$temp_array = $unsorted_numerics; +var_dump( sort($temp_array) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing sort() by supplying string array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_strings; +var_dump( sort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing sort() by supplying numeric array, 'flag' = SORT_REGULAR --\n"; +$temp_array = $unsorted_numerics; +var_dump( sort($temp_array, SORT_REGULAR) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing sort() by supplying string array, 'flag' = SORT_STRING --\n"; +$temp_array = $unsorted_strings; +var_dump( sort($temp_array, SORT_STRING) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing sort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( sort($temp_array, SORT_STRING|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing sort() by supplying string array (natural), 'flag' = SORT_NATURAL --\n"; +$temp_array = $unsorted_strings; +var_dump( sort($temp_array, SORT_NATURAL) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing sort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE --\n"; +$temp_array = $unsorted_strings; +var_dump( sort($temp_array, SORT_NATURAL|SORT_FLAG_CASE) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "\n-- Testing sort() by supplying numeric array, 'flag' = SORT_NUMERIC --\n"; +$temp_array = $unsorted_numerics; +var_dump( sort($temp_array, SORT_NUMERIC) ); // expecting : bool(true) +var_dump( $temp_array); + +echo "Done\n"; +?> +--EXPECT-- +*** Testing sort() : basic functionality *** + +-- Testing sort() by supplying string array, 'flag' value is default -- +bool(true) +array(8) { + [0]=> + string(6) "Orange" + [1]=> + string(7) "Orange1" + [2]=> + string(7) "Orange3" + [3]=> + string(6) "banana" + [4]=> + string(5) "lemon" + [5]=> + string(6) "orange" + [6]=> + string(7) "orange2" + [7]=> + string(8) "orange20" +} + +-- Testing sort() by supplying numeric array, 'flag' value is default -- +bool(true) +array(4) { + [0]=> + int(22) + [1]=> + int(33) + [2]=> + int(100) + [3]=> + int(555) +} + +-- Testing sort() by supplying string array, 'flag' = SORT_REGULAR -- +bool(true) +array(8) { + [0]=> + string(6) "Orange" + [1]=> + string(7) "Orange1" + [2]=> + string(7) "Orange3" + [3]=> + string(6) "banana" + [4]=> + string(5) "lemon" + [5]=> + string(6) "orange" + [6]=> + string(7) "orange2" + [7]=> + string(8) "orange20" +} + +-- Testing sort() by supplying numeric array, 'flag' = SORT_REGULAR -- +bool(true) +array(4) { + [0]=> + int(22) + [1]=> + int(33) + [2]=> + int(100) + [3]=> + int(555) +} + +-- Testing sort() by supplying string array, 'flag' = SORT_STRING -- +bool(true) +array(8) { + [0]=> + string(6) "Orange" + [1]=> + string(7) "Orange1" + [2]=> + string(7) "Orange3" + [3]=> + string(6) "banana" + [4]=> + string(5) "lemon" + [5]=> + string(6) "orange" + [6]=> + string(7) "orange2" + [7]=> + string(8) "orange20" +} + +-- Testing sort() by supplying string array (case insensitive), 'flag' = SORT_STRING|SORT_FLAG_CASE -- +bool(true) +array(8) { + [0]=> + string(6) "banana" + [1]=> + string(5) "lemon" + [2]=> + string(6) "orange" + [3]=> + string(6) "Orange" + [4]=> + string(7) "Orange1" + [5]=> + string(7) "orange2" + [6]=> + string(8) "orange20" + [7]=> + string(7) "Orange3" +} + +-- Testing sort() by supplying string array (natural), 'flag' = SORT_NATURAL -- +bool(true) +array(8) { + [0]=> + string(6) "Orange" + [1]=> + string(7) "Orange1" + [2]=> + string(7) "Orange3" + [3]=> + string(6) "banana" + [4]=> + string(5) "lemon" + [5]=> + string(6) "orange" + [6]=> + string(7) "orange2" + [7]=> + string(8) "orange20" +} + +-- Testing sort() by supplying string array (natural, case insensitive), 'flag' = SORT_NATURAL|SORT_FLAG_CASE -- +bool(true) +array(8) { + [0]=> + string(6) "banana" + [1]=> + string(5) "lemon" + [2]=> + string(6) "orange" + [3]=> + string(6) "Orange" + [4]=> + string(7) "Orange1" + [5]=> + string(7) "orange2" + [6]=> + string(7) "Orange3" + [7]=> + string(8) "orange20" +} + +-- Testing sort() by supplying numeric array, 'flag' = SORT_NUMERIC -- +bool(true) +array(4) { + [0]=> + int(22) + [1]=> + int(33) + [2]=> + int(100) + [3]=> + int(555) +} +Done diff --git a/tests/std/array/sort_object1.phpt b/tests/std/array/sort_object1.phpt new file mode 100644 index 00000000..3a9f2a14 --- /dev/null +++ b/tests/std/array/sort_object1.phpt @@ -0,0 +1,218 @@ +--TEST-- +Test sort() function : object functionality - sorting objects, 'sort_flags' as default/SORT_REGULAR +--FILE-- +class_value = $value; + } +} +// class declaration for string objects +class for_string_sort +{ + public $class_value; + // initializing object member value + function __construct($value) + { + $this->class_value = $value; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * testing sort() by providing integer/string object arrays with flag values are default, SORT_REGULAR + */ + echo "*** Testing sort() : object functionality ***\n"; + // array of integer objects + $unsorted_int_obj = array(new for_integer_sort(11), new for_integer_sort(66), new for_integer_sort(23), new for_integer_sort(-5), new for_integer_sort(0.001), new for_integer_sort(0)); + // array of string objects + $unsorted_str_obj = array(new for_string_sort("axx"), new for_string_sort("t"), new for_string_sort("w"), new for_string_sort("py"), new for_string_sort("apple"), new for_string_sort("Orange"), new for_string_sort("Lemon"), new for_string_sort("aPPle")); + echo "\n-- Testing sort() by supplying various object arrays, 'flag' value is default --\n"; + // testing sort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(sort($temp_array)); + var_dump($temp_array); + // testing sort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(sort($temp_array)); + var_dump($temp_array); + echo "\n-- Testing sort() by supplying various object arrays, 'flag' value is SORT_REGULAR --\n"; + // testing sort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(sort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing sort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(sort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done\n"; +} +?> +--EXPECTF-- +*** Testing sort() : object functionality *** + +-- Testing sort() by supplying various object arrays, 'flag' value is default -- +bool(true) +array(6) { + [0]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(-5) + } + [1]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(0) + } + [2]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + float(0.001) + } + [3]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(11) + } + [4]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(23) + } + [5]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(66) + } +} +bool(true) +array(8) { + [0]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } + [1]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + [2]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + [3]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + [4]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + [5]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(2) "py" + } + [6]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(1) "t" + } + [7]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(1) "w" + } +} + +-- Testing sort() by supplying various object arrays, 'flag' value is SORT_REGULAR -- +bool(true) +array(6) { + [0]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(-5) + } + [1]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(0) + } + [2]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + float(0.001) + } + [3]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(11) + } + [4]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(23) + } + [5]=> + object(for_integer_sort)#%d (1) { + ["class_value"]=> + int(66) + } +} +bool(true) +array(8) { + [0]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(5) "Lemon" + } + [1]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(6) "Orange" + } + [2]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(5) "aPPle" + } + [3]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(5) "apple" + } + [4]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(3) "axx" + } + [5]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(2) "py" + } + [6]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(1) "t" + } + [7]=> + object(for_string_sort)#%d (1) { + ["class_value"]=> + string(1) "w" + } +} +Done diff --git a/tests/std/array/sort_object2.phpt b/tests/std/array/sort_object2.phpt new file mode 100644 index 00000000..294078da --- /dev/null +++ b/tests/std/array/sort_object2.phpt @@ -0,0 +1,230 @@ +--TEST-- +Test sort() function : object functionality - sorting objects with diff. accessibility of member vars +--FILE-- +public_class_value = $value1; + $this->private_class_value = $value2; + $this->protected_class_value = $value3; + } +} +// class declaration for string objects +class for_string_sort +{ + public $public_class_value; + private $private_class_value; + protected $protected_class_value; + // initializing object member value + function __construct($value1, $value2, $value3) + { + $this->public_class_value = $value1; + $this->private_class_value = $value2; + $this->protected_class_value = $value3; + } + // return string value + function __tostring(): string { + return (string) $this->value; + } +} +function main() +{ + /* + * testing sort() by providing integer/string object arrays with flag values are default, SORT_REGULAR + */ + echo "*** Testing sort() : object functionality ***\n"; + // array of integer objects + $unsorted_int_obj = array(new for_integer_sort(11, 33, 30), new for_integer_sort(66, 44, 4), new for_integer_sort(-88, -5, 5), new for_integer_sort(0.001, 99.5, 0.1)); + // array of string objects + $unsorted_str_obj = array(new for_string_sort("axx", "AXX", "ass"), new for_string_sort("t", "eee", "abb"), new for_string_sort("w", "W", "c"), new for_string_sort("py", "PY", "pt")); + echo "\n-- Testing sort() by supplying various object arrays, 'flag' value is default --\n"; + // testing sort() function by supplying integer object array, flag value is default + $temp_array = $unsorted_int_obj; + var_dump(sort($temp_array)); + var_dump($temp_array); + // testing sort() function by supplying string object array, flag value is default + $temp_array = $unsorted_str_obj; + var_dump(sort($temp_array)); + var_dump($temp_array); + echo "\n-- Testing sort() by supplying various object arrays, 'flag' value is SORT_REGULAR --\n"; + // testing sort() function by supplying integer object array, flag value = SORT_REGULAR + $temp_array = $unsorted_int_obj; + var_dump(sort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + // testing sort() function by supplying string object array, flag value = SORT_REGULAR + $temp_array = $unsorted_str_obj; + var_dump(sort($temp_array, SORT_REGULAR)); + var_dump($temp_array); + echo "Done\n"; +} +?> +--EXPECTF-- +*** Testing sort() : object functionality *** + +-- Testing sort() by supplying various object arrays, 'flag' value is default -- +bool(true) +array(4) { + [0]=> + object(for_integer_sort)#%d (3) { + ["public_class_value"]=> + int(-88) + ["private_class_value":"for_integer_sort":private]=> + int(-5) + ["protected_class_value":protected]=> + int(5) + } + [1]=> + object(for_integer_sort)#%d (3) { + ["public_class_value"]=> + float(0.001) + ["private_class_value":"for_integer_sort":private]=> + float(99.5) + ["protected_class_value":protected]=> + float(0.1) + } + [2]=> + object(for_integer_sort)#%d (3) { + ["public_class_value"]=> + int(11) + ["private_class_value":"for_integer_sort":private]=> + int(33) + ["protected_class_value":protected]=> + int(30) + } + [3]=> + object(for_integer_sort)#%d (3) { + ["public_class_value"]=> + int(66) + ["private_class_value":"for_integer_sort":private]=> + int(44) + ["protected_class_value":protected]=> + int(4) + } +} +bool(true) +array(4) { + [0]=> + object(for_string_sort)#%d (3) { + ["public_class_value"]=> + string(3) "axx" + ["private_class_value":"for_string_sort":private]=> + string(3) "AXX" + ["protected_class_value":protected]=> + string(3) "ass" + } + [1]=> + object(for_string_sort)#%d (3) { + ["public_class_value"]=> + string(2) "py" + ["private_class_value":"for_string_sort":private]=> + string(2) "PY" + ["protected_class_value":protected]=> + string(2) "pt" + } + [2]=> + object(for_string_sort)#%d (3) { + ["public_class_value"]=> + string(1) "t" + ["private_class_value":"for_string_sort":private]=> + string(3) "eee" + ["protected_class_value":protected]=> + string(3) "abb" + } + [3]=> + object(for_string_sort)#%d (3) { + ["public_class_value"]=> + string(1) "w" + ["private_class_value":"for_string_sort":private]=> + string(1) "W" + ["protected_class_value":protected]=> + string(1) "c" + } +} + +-- Testing sort() by supplying various object arrays, 'flag' value is SORT_REGULAR -- +bool(true) +array(4) { + [0]=> + object(for_integer_sort)#%d (3) { + ["public_class_value"]=> + int(-88) + ["private_class_value":"for_integer_sort":private]=> + int(-5) + ["protected_class_value":protected]=> + int(5) + } + [1]=> + object(for_integer_sort)#%d (3) { + ["public_class_value"]=> + float(0.001) + ["private_class_value":"for_integer_sort":private]=> + float(99.5) + ["protected_class_value":protected]=> + float(0.1) + } + [2]=> + object(for_integer_sort)#%d (3) { + ["public_class_value"]=> + int(11) + ["private_class_value":"for_integer_sort":private]=> + int(33) + ["protected_class_value":protected]=> + int(30) + } + [3]=> + object(for_integer_sort)#%d (3) { + ["public_class_value"]=> + int(66) + ["private_class_value":"for_integer_sort":private]=> + int(44) + ["protected_class_value":protected]=> + int(4) + } +} +bool(true) +array(4) { + [0]=> + object(for_string_sort)#%d (3) { + ["public_class_value"]=> + string(3) "axx" + ["private_class_value":"for_string_sort":private]=> + string(3) "AXX" + ["protected_class_value":protected]=> + string(3) "ass" + } + [1]=> + object(for_string_sort)#%d (3) { + ["public_class_value"]=> + string(2) "py" + ["private_class_value":"for_string_sort":private]=> + string(2) "PY" + ["protected_class_value":protected]=> + string(2) "pt" + } + [2]=> + object(for_string_sort)#%d (3) { + ["public_class_value"]=> + string(1) "t" + ["private_class_value":"for_string_sort":private]=> + string(3) "eee" + ["protected_class_value":protected]=> + string(3) "abb" + } + [3]=> + object(for_string_sort)#%d (3) { + ["public_class_value"]=> + string(1) "w" + ["private_class_value":"for_string_sort":private]=> + string(1) "W" + ["protected_class_value":protected]=> + string(1) "c" + } +} +Done diff --git a/tests/std/array/sort_variation10.phpt b/tests/std/array/sort_variation10.phpt new file mode 100644 index 00000000..36dfcb85 --- /dev/null +++ b/tests/std/array/sort_variation10.phpt @@ -0,0 +1,106 @@ +--TEST-- +Test sort() function : usage variations - sort octal values +--FILE-- + +--EXPECT-- +*** Testing sort() : usage variations *** + +-- Testing sort() by supplying octal value array, 'flag' value is default -- +bool(true) +array(9) { + [0]=> + int(-229) + [1]=> + int(-54) + [2]=> + int(0) + [3]=> + int(54) + [4]=> + int(63) + [5]=> + int(209) + [6]=> + int(229) + [7]=> + int(506) + [8]=> + int(669) +} + +-- Testing sort() by supplying octal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(9) { + [0]=> + int(-229) + [1]=> + int(-54) + [2]=> + int(0) + [3]=> + int(54) + [4]=> + int(63) + [5]=> + int(209) + [6]=> + int(229) + [7]=> + int(506) + [8]=> + int(669) +} + +-- Testing sort() by supplying octal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(9) { + [0]=> + int(-229) + [1]=> + int(-54) + [2]=> + int(0) + [3]=> + int(54) + [4]=> + int(63) + [5]=> + int(209) + [6]=> + int(229) + [7]=> + int(506) + [8]=> + int(669) +} +Done diff --git a/tests/std/array/sort_variation11.phpt b/tests/std/array/sort_variation11.phpt new file mode 100644 index 00000000..909a5546 --- /dev/null +++ b/tests/std/array/sort_variation11.phpt @@ -0,0 +1,185 @@ +--TEST-- +Test sort() function : usage variations - sort mixed values, 'sort_flag' as default/SORT_REGULAR (OK to fail as result is unpredectable) +--FILE-- + +--EXPECTF-- +*** Testing sort() : usage variations *** + +-- Testing sort() by supplying mixed value array, 'flag' value is default -- +bool(true) +array(22) { + [0]=> + string(0) "" + [1]=> + NULL + [2]=> + string(0) "" + [3]=> + float(0) + [4]=> + bool(false) + [5]=> + int(-4) + [6]=> + float(-2.98989) + [7]=> + int(-2) + [8]=> + float(-2) + [9]=> + string(3) "-.9" + [10]=> + int(0) + [11]=> + string(1) "4" + [12]=> + float(4) + [13]=> + string(1) "5" + [14]=> + string(4) "True" + [15]=> + string(2) "ab" + [16]=> + string(4) "abcd" + [17]=> + string(14) "abcd%0abcd%0abcd" + [18]=> + string(1) "b" + [19]=> + array(0) { + } + [20]=> + array(4) { + [0]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + [1]=> + array(1) { + [0]=> + int(11) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [3]=> + array(0) { + } + } + [21]=> + bool(true) +} + +-- Testing sort() by supplying mixed value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(22) { + [0]=> + string(0) "" + [1]=> + NULL + [2]=> + string(0) "" + [3]=> + float(0) + [4]=> + bool(false) + [5]=> + int(-4) + [6]=> + float(-2.98989) + [7]=> + int(-2) + [8]=> + float(-2) + [9]=> + string(3) "-.9" + [10]=> + int(0) + [11]=> + string(1) "4" + [12]=> + float(4) + [13]=> + string(1) "5" + [14]=> + string(4) "True" + [15]=> + string(2) "ab" + [16]=> + string(4) "abcd" + [17]=> + string(14) "abcd%0abcd%0abcd" + [18]=> + string(1) "b" + [19]=> + array(0) { + } + [20]=> + array(4) { + [0]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } + [1]=> + array(1) { + [0]=> + int(11) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [3]=> + array(0) { + } + } + [21]=> + bool(true) +} +Done diff --git a/tests/std/array/sort_variation3.phpt b/tests/std/array/sort_variation3.phpt new file mode 100644 index 00000000..194d2b9f --- /dev/null +++ b/tests/std/array/sort_variation3.phpt @@ -0,0 +1,322 @@ +--TEST-- +Test sort() function : usage variations - sort integer/float values +--FILE-- + SORT_REGULAR, "SORT_NUMERIC" => SORT_NUMERIC); + +$count = 1; +echo "\n-- Testing sort() by supplying various integer/float arrays --\n"; + +// loop through to test sort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With Default sort flag -\n"; + $temp_array = $array; + var_dump(sort($temp_array) ); + var_dump($temp_array); + + // loop through $flag_value array and setting all possible flag values + foreach($flag_value as $key => $flag){ + echo "- Sort flag = $key -\n"; + $temp_array = $array; + var_dump(sort($temp_array, $flag) ); + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECTF-- +*** Testing sort() : usage variations *** + +-- Testing sort() by supplying various integer/float arrays -- + +-- Iteration 1 -- +- With Default sort flag - +bool(true) +array(9) { + [0]=> + int(-41) + [1]=> + int(-31) + [2]=> + int(-21) + [3]=> + int(-11) + [4]=> + int(0) + [5]=> + int(11) + [6]=> + int(21) + [7]=> + int(31) + [8]=> + int(41) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(9) { + [0]=> + int(-41) + [1]=> + int(-31) + [2]=> + int(-21) + [3]=> + int(-11) + [4]=> + int(0) + [5]=> + int(11) + [6]=> + int(21) + [7]=> + int(31) + [8]=> + int(41) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(9) { + [0]=> + int(-41) + [1]=> + int(-31) + [2]=> + int(-21) + [3]=> + int(-11) + [4]=> + int(0) + [5]=> + int(11) + [6]=> + int(21) + [7]=> + int(31) + [8]=> + int(41) +} + +-- Iteration 2 -- +- With Default sort flag - +bool(true) +array(7) { + [0]=> + float(-10.5) + [1]=> + float(-0.1) + [2]=> + float(0.01) + [3]=> + float(0.106) + [4]=> + float(0.5) + [5]=> + float(10.5) + [6]=> + float(1050) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(7) { + [0]=> + float(-10.5) + [1]=> + float(-0.1) + [2]=> + float(0.01) + [3]=> + float(0.106) + [4]=> + float(0.5) + [5]=> + float(10.5) + [6]=> + float(1050) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(7) { + [0]=> + float(-10.5) + [1]=> + float(-0.1) + [2]=> + float(0.01) + [3]=> + float(0.106) + [4]=> + float(0.5) + [5]=> + float(10.5) + [6]=> + float(1050) +} + +-- Iteration 3 -- +- With Default sort flag - +bool(true) +array(11) { + [0]=> + int(-1) + [1]=> + float(-0.9) + [2]=> + float(-0.106) + [3]=> + float(-0.01) + [4]=> + int(0) + [5]=> + float(0.0001) + [6]=> + float(0.0021) + [7]=> + float(0.09) + [8]=> + float(0.106) + [9]=> + int(2) + [10]=> + int(33) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(11) { + [0]=> + int(-1) + [1]=> + float(-0.9) + [2]=> + float(-0.106) + [3]=> + float(-0.01) + [4]=> + int(0) + [5]=> + float(0.0001) + [6]=> + float(0.0021) + [7]=> + float(0.09) + [8]=> + float(0.106) + [9]=> + int(2) + [10]=> + int(33) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(11) { + [0]=> + int(-1) + [1]=> + float(-0.9) + [2]=> + float(-0.106) + [3]=> + float(-0.01) + [4]=> + int(0) + [5]=> + float(0.0001) + [6]=> + float(0.0021) + [7]=> + float(0.09) + [8]=> + float(0.106) + [9]=> + int(2) + [10]=> + int(33) +} + +-- Iteration 4 -- +- With Default sort flag - +bool(true) +array(7) { + [0]=> + %s(-2147483649) + [1]=> + %s(-2147483648) + [2]=> + int(-2147483647) + [3]=> + int(0) + [4]=> + int(0) + [5]=> + int(2147483647) + [6]=> + %s(2147483648) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(7) { + [0]=> + %s(-2147483649) + [1]=> + %s(-2147483648) + [2]=> + int(-2147483647) + [3]=> + int(0) + [4]=> + int(0) + [5]=> + int(2147483647) + [6]=> + %s(2147483648) +} +- Sort flag = SORT_NUMERIC - +bool(true) +array(7) { + [0]=> + %s(-2147483649) + [1]=> + %s(-2147483648) + [2]=> + int(-2147483647) + [3]=> + int(0) + [4]=> + int(0) + [5]=> + int(2147483647) + [6]=> + %s(2147483648) +} +Done diff --git a/tests/std/array/sort_variation4.phpt b/tests/std/array/sort_variation4.phpt new file mode 100644 index 00000000..9a355065 --- /dev/null +++ b/tests/std/array/sort_variation4.phpt @@ -0,0 +1,78 @@ +--TEST-- +Test sort() function : usage variations - sort reference values +--SKIPIF-- + + +--FILE-- + +--EXPECT-- +*** Testing sort() :usage variations *** + +-- Testing sort() by supplying reference variable array, 'flag' value is default -- +bool(true) +array(3) { + [0]=> + &int(33) + [1]=> + &int(100) + [2]=> + &int(555) +} + +-- Testing sort() by supplying reference variable array, 'flag' = SORT_REGULAR -- +bool(true) +array(3) { + [0]=> + &int(33) + [1]=> + &int(100) + [2]=> + &int(555) +} + +-- Testing sort() by supplying reference variable array, 'flag' = SORT_NUMERIC -- +bool(true) +array(3) { + [0]=> + &int(33) + [1]=> + &int(100) + [2]=> + &int(555) +} +Done diff --git a/tests/std/array/sort_variation5.phpt b/tests/std/array/sort_variation5.phpt new file mode 100644 index 00000000..6c49342d --- /dev/null +++ b/tests/std/array/sort_variation5.phpt @@ -0,0 +1,227 @@ +--TEST-- +Test sort() function : usage variations - sort strings +--FILE-- + SORT_REGULAR, "SORT_STRING" => SORT_STRING); + +$count = 1; +echo "\n-- Testing sort() by supplying various string arrays --\n"; + +// loop through to test sort() with different arrays +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With Default sort flag -\n"; + $temp_array = $array; + var_dump(sort($temp_array) ); // expecting : bool(true) + var_dump($temp_array); + + // loop through $flags array and setting all possible flag values + foreach($flags as $key => $flag){ + echo "- Sort flag = $key -\n"; + $temp_array = $array; + var_dump(sort($temp_array, $flag) ); // expecting : bool(true) + var_dump($temp_array); + } + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing sort() : usage variations *** + +-- Testing sort() by supplying various string arrays -- + +-- Iteration 1 -- +- With Default sort flag - +bool(true) +array(12) { + [0]=> + NULL + [1]=> + NULL + [2]=> + string(1) " " + [3]=> + string(1) " +" + [4]=> + string(1) " " + [5]=> + string(1) " " + [6]=> + string(1) " " + [7]=> + string(1) "" + [8]=> + string(2) "\a" + [9]=> + string(3) "\cx" + [10]=> + string(4) "\ddd" + [11]=> + string(4) "\xhh" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(12) { + [0]=> + NULL + [1]=> + NULL + [2]=> + string(1) " " + [3]=> + string(1) " +" + [4]=> + string(1) " " + [5]=> + string(1) " " + [6]=> + string(1) " " + [7]=> + string(1) "" + [8]=> + string(2) "\a" + [9]=> + string(3) "\cx" + [10]=> + string(4) "\ddd" + [11]=> + string(4) "\xhh" +} +- Sort flag = SORT_STRING - +bool(true) +array(12) { + [0]=> + NULL + [1]=> + NULL + [2]=> + string(1) " " + [3]=> + string(1) " +" + [4]=> + string(1) " " + [5]=> + string(1) " " + [6]=> + string(1) " " + [7]=> + string(1) "" + [8]=> + string(2) "\a" + [9]=> + string(3) "\cx" + [10]=> + string(4) "\ddd" + [11]=> + string(4) "\xhh" +} + +-- Iteration 2 -- +- With Default sort flag - +bool(true) +array(12) { + [0]=> + string(6) "BANANA" + [1]=> + string(6) "Orange" + [2]=> + string(4) "TTTT" + [3]=> + string(4) "Test" + [4]=> + string(1) "X" + [5]=> + string(5) "apple" + [6]=> + string(6) "banana" + [7]=> + string(5) "lemoN" + [8]=> + string(6) "oraNGe" + [9]=> + string(3) "ttt" + [10]=> + string(2) "ww" + [11]=> + string(1) "x" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(12) { + [0]=> + string(6) "BANANA" + [1]=> + string(6) "Orange" + [2]=> + string(4) "TTTT" + [3]=> + string(4) "Test" + [4]=> + string(1) "X" + [5]=> + string(5) "apple" + [6]=> + string(6) "banana" + [7]=> + string(5) "lemoN" + [8]=> + string(6) "oraNGe" + [9]=> + string(3) "ttt" + [10]=> + string(2) "ww" + [11]=> + string(1) "x" +} +- Sort flag = SORT_STRING - +bool(true) +array(12) { + [0]=> + string(6) "BANANA" + [1]=> + string(6) "Orange" + [2]=> + string(4) "TTTT" + [3]=> + string(4) "Test" + [4]=> + string(1) "X" + [5]=> + string(5) "apple" + [6]=> + string(6) "banana" + [7]=> + string(5) "lemoN" + [8]=> + string(6) "oraNGe" + [9]=> + string(3) "ttt" + [10]=> + string(2) "ww" + [11]=> + string(1) "x" +} +Done diff --git a/tests/std/array/sort_variation6.phpt b/tests/std/array/sort_variation6.phpt new file mode 100644 index 00000000..fcde3b3d --- /dev/null +++ b/tests/std/array/sort_variation6.phpt @@ -0,0 +1,117 @@ +--TEST-- +Test sort() function : usage variations - sort hexadecimal values +--FILE-- + +--EXPECT-- +*** Testing sort() : usage variations *** + +-- Testing sort() by supplying hexadecimal value array, 'flag' value is default -- +bool(true) +array(11) { + [0]=> + int(-682) + [1]=> + int(-255) + [2]=> + int(0) + [3]=> + int(15) + [4]=> + int(187) + [5]=> + int(255) + [6]=> + int(255) + [7]=> + int(427) + [8]=> + int(427) + [9]=> + int(682) + [10]=> + int(4095) +} + +-- Testing sort() by supplying hexadecimal value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(11) { + [0]=> + int(-682) + [1]=> + int(-255) + [2]=> + int(0) + [3]=> + int(15) + [4]=> + int(187) + [5]=> + int(255) + [6]=> + int(255) + [7]=> + int(427) + [8]=> + int(427) + [9]=> + int(682) + [10]=> + int(4095) +} + +-- Testing sort() by supplying hexadecimal value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(11) { + [0]=> + int(-682) + [1]=> + int(-255) + [2]=> + int(0) + [3]=> + int(15) + [4]=> + int(187) + [5]=> + int(255) + [6]=> + int(255) + [7]=> + int(427) + [8]=> + int(427) + [9]=> + int(682) + [10]=> + int(4095) +} +Done diff --git a/tests/std/array/sort_variation7.phpt b/tests/std/array/sort_variation7.phpt new file mode 100644 index 00000000..75d2dd16 --- /dev/null +++ b/tests/std/array/sort_variation7.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test sort() function : usage variations - sort boolean values +--FILE-- + +--EXPECT-- +*** Testing sort() : usage variations *** + +-- Testing sort() by supplying bool value array, 'flag' value is default -- +bool(true) +array(4) { + [0]=> + bool(false) + [1]=> + bool(false) + [2]=> + bool(true) + [3]=> + bool(true) +} + +-- Testing sort() by supplying bool value array, 'flag' value is SORT_REGULAR -- +bool(true) +array(4) { + [0]=> + bool(false) + [1]=> + bool(false) + [2]=> + bool(true) + [3]=> + bool(true) +} + +-- Testing sort() by supplying bool value array, 'flag' value is SORT_NUMERIC -- +bool(true) +array(4) { + [0]=> + bool(false) + [1]=> + bool(false) + [2]=> + bool(true) + [3]=> + bool(true) +} + +-- Testing sort() by supplying bool value array, 'flag' value is SORT_STRING -- +bool(true) +array(4) { + [0]=> + bool(false) + [1]=> + bool(false) + [2]=> + bool(true) + [3]=> + bool(true) +} +Done diff --git a/tests/std/array/sort_variation8.phpt b/tests/std/array/sort_variation8.phpt new file mode 100644 index 00000000..562766e7 --- /dev/null +++ b/tests/std/array/sort_variation8.phpt @@ -0,0 +1,172 @@ +--TEST-- +Test sort() function : usage variations - sort array with diff. sub arrays, 'sort_flags' as default/SORT_REGULAR +--FILE-- + +--EXPECT-- +*** Testing sort() : usage variations *** + +-- Testing sort() by supplying various arrays containing sub arrays -- + +-- Iteration 1 -- +- With Default sort flag - +bool(true) +array(0) { +} +- Sort flag = SORT_REGULAR - +bool(true) +array(0) { +} + +-- Iteration 2 -- +- With Default sort flag - +bool(true) +array(1) { + [0]=> + array(0) { + } +} +- Sort flag = SORT_REGULAR - +bool(true) +array(1) { + [0]=> + array(0) { + } +} + +-- Iteration 3 -- +- With Default sort flag - +bool(true) +array(3) { + [0]=> + int(11) + [1]=> + int(44) + [2]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } +} +- Sort flag = SORT_REGULAR - +bool(true) +array(3) { + [0]=> + int(11) + [1]=> + int(44) + [2]=> + array(2) { + [0]=> + int(64) + [1]=> + int(61) + } +} + +-- Iteration 4 -- +- With Default sort flag - +bool(true) +array(4) { + [0]=> + array(0) { + } + [1]=> + array(1) { + [0]=> + int(11) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [3]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } +} +- Sort flag = SORT_REGULAR - +bool(true) +array(4) { + [0]=> + array(0) { + } + [1]=> + array(1) { + [0]=> + int(11) + } + [2]=> + array(2) { + [0]=> + int(22) + [1]=> + int(-55) + } + [3]=> + array(3) { + [0]=> + int(33) + [1]=> + int(-5) + [2]=> + int(6) + } +} +Done diff --git a/tests/std/array/sort_variation9.phpt b/tests/std/array/sort_variation9.phpt new file mode 100644 index 00000000..7791a81c --- /dev/null +++ b/tests/std/array/sort_variation9.phpt @@ -0,0 +1,253 @@ +--TEST-- +Test sort() function : usage variations - sort diff. associative arrays, 'sort_flags' as default/SORT_REGULAR +--FILE-- + 55, 6 => 66, 2 => 22, 3 => 33, 1 => 11), + array ("fruits" => array("a" => "orange", "b" => "banana", "c" => "apple"), + "numbers" => array(1, 2, 3, 4, 5, 6), + "holes" => array("first", 5 => "second", "third") + ), + array(1, 1, 8 => 1, 4 => 1, 19, 3 => 13), + array('bar' => 'baz', "foo" => 1), + array('a' => 1,'b' => array('e' => 2,'f' => 3),'c' => array('g' => 4),'d' => 5), +); + +$count = 1; +echo "\n-- Testing sort() by supplying various arrays with key values --\n"; + +// loop through to test sort() with different arrays, +// to test the new keys for the elements in the sorted array +foreach ($various_arrays as $array) { + echo "\n-- Iteration $count --\n"; + + echo "- With Default sort flag -\n"; + $temp_array = $array; + var_dump(sort($temp_array) ); + var_dump($temp_array); + + echo "- Sort flag = SORT_REGULAR -\n"; + $temp_array = $array; + var_dump(sort($temp_array, SORT_REGULAR) ); + var_dump($temp_array); + $count++; +} + +echo "Done\n"; +?> +--EXPECT-- +*** Testing sort() : usage variations *** + +-- Testing sort() by supplying various arrays with key values -- + +-- Iteration 1 -- +- With Default sort flag - +bool(true) +array(5) { + [0]=> + int(11) + [1]=> + int(22) + [2]=> + int(33) + [3]=> + int(55) + [4]=> + int(66) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(5) { + [0]=> + int(11) + [1]=> + int(22) + [2]=> + int(33) + [3]=> + int(55) + [4]=> + int(66) +} + +-- Iteration 2 -- +- With Default sort flag - +bool(true) +array(3) { + [0]=> + array(3) { + [0]=> + string(5) "first" + [5]=> + string(6) "second" + [6]=> + string(5) "third" + } + [1]=> + array(3) { + ["a"]=> + string(6) "orange" + ["b"]=> + string(6) "banana" + ["c"]=> + string(5) "apple" + } + [2]=> + array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } +} +- Sort flag = SORT_REGULAR - +bool(true) +array(3) { + [0]=> + array(3) { + [0]=> + string(5) "first" + [5]=> + string(6) "second" + [6]=> + string(5) "third" + } + [1]=> + array(3) { + ["a"]=> + string(6) "orange" + ["b"]=> + string(6) "banana" + ["c"]=> + string(5) "apple" + } + [2]=> + array(6) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(4) + [4]=> + int(5) + [5]=> + int(6) + } +} + +-- Iteration 3 -- +- With Default sort flag - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(1) + [3]=> + int(1) + [4]=> + int(13) + [5]=> + int(19) +} +- Sort flag = SORT_REGULAR - +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(1) + [3]=> + int(1) + [4]=> + int(13) + [5]=> + int(19) +} + +-- Iteration 4 -- +- With Default sort flag - +bool(true) +array(2) { + [0]=> + int(1) + [1]=> + string(3) "baz" +} +- Sort flag = SORT_REGULAR - +bool(true) +array(2) { + [0]=> + int(1) + [1]=> + string(3) "baz" +} + +-- Iteration 5 -- +- With Default sort flag - +bool(true) +array(4) { + [0]=> + int(1) + [1]=> + int(5) + [2]=> + array(1) { + ["g"]=> + int(4) + } + [3]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } +} +- Sort flag = SORT_REGULAR - +bool(true) +array(4) { + [0]=> + int(1) + [1]=> + int(5) + [2]=> + array(1) { + ["g"]=> + int(4) + } + [3]=> + array(2) { + ["e"]=> + int(2) + ["f"]=> + int(3) + } +} +Done diff --git a/tests/std/array/uasort_basic1.phpt b/tests/std/array/uasort_basic1.phpt new file mode 100644 index 00000000..9ff9d33d --- /dev/null +++ b/tests/std/array/uasort_basic1.phpt @@ -0,0 +1,106 @@ +--TEST-- +Test uasort() function : basic functionality +--FILE-- + $value2) { + return 1; + } + else + return -1; +} + +function main() { +echo "*** Testing uasort() : basic functionality ***\n"; + +// Int array with default keys +$int_values = array(1, 8, 9, 3, 2, 6, 7); +echo "-- Numeric array with default keys --\n"; +var_dump( uasort($int_values, 'cmp') ); +var_dump($int_values); + +// String array with default keys +$string_values = array("This", "is", 'a', "test"); +echo "-- String array with default keys --\n"; +var_dump( uasort($string_values, 'cmp') ); +var_dump($string_values); + +// Associative array with numeric keys +$numeric_key_arg = array(1=> 1, 2 => 2, 3 => 7, 5 => 4, 4 => 9); +echo "-- Associative array with numeric keys --\n"; +var_dump( uasort($numeric_key_arg, 'cmp') ); +var_dump($numeric_key_arg); + +// Associative array with string keys +$string_key_arg = array('one' => 4, 'two' => 2, 'three' => 1, 'four' => 10); +echo "-- Associative array with string keys --\n"; +var_dump( uasort($string_key_arg, 'cmp') ); +var_dump($string_key_arg); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing uasort() : basic functionality *** +-- Numeric array with default keys -- +bool(true) +array(7) { + [0]=> + int(1) + [4]=> + int(2) + [3]=> + int(3) + [5]=> + int(6) + [6]=> + int(7) + [1]=> + int(8) + [2]=> + int(9) +} +-- String array with default keys -- +bool(true) +array(4) { + [0]=> + string(4) "This" + [2]=> + string(1) "a" + [1]=> + string(2) "is" + [3]=> + string(4) "test" +} +-- Associative array with numeric keys -- +bool(true) +array(5) { + [1]=> + int(1) + [2]=> + int(2) + [5]=> + int(4) + [3]=> + int(7) + [4]=> + int(9) +} +-- Associative array with string keys -- +bool(true) +array(4) { + ["three"]=> + int(1) + ["two"]=> + int(2) + ["one"]=> + int(4) + ["four"]=> + int(10) +} +Done diff --git a/tests/std/array/uasort_basic2.phpt b/tests/std/array/uasort_basic2.phpt new file mode 100644 index 00000000..49708b30 --- /dev/null +++ b/tests/std/array/uasort_basic2.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test uasort() function : basic functionality - duplicate values +--FILE-- + $value2) { + return 1; + } + else + return -1; +} + +function main() { +echo "*** Testing uasort() : basic functionality with duplicate values ***\n"; + +// increasing values +$int_values1 = array(1, 1, 2, 2, 3, 3); +echo "-- Numeric array with increasing values --\n"; +var_dump( uasort($int_values1, 'cmp') ); +var_dump($int_values1); + +// decreasing values +$int_values2 = array(3, 3, 2, 2, 1, 1); +echo "-- Numeric array with decreasing values --\n"; +var_dump( uasort($int_values2, 'cmp') ); +var_dump($int_values2); + +// increasing and decreasing values +$int_values3 = array(1, 2, 3, 3, 2, 1); +echo "-- Numeric array with increasing and decreasing values --\n"; +var_dump( uasort($int_values3, 'cmp') ); +var_dump($int_values3); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing uasort() : basic functionality with duplicate values *** +-- Numeric array with increasing values -- +bool(true) +array(6) { + [0]=> + int(1) + [1]=> + int(1) + [2]=> + int(2) + [3]=> + int(2) + [4]=> + int(3) + [5]=> + int(3) +} +-- Numeric array with decreasing values -- +bool(true) +array(6) { + [4]=> + int(1) + [5]=> + int(1) + [2]=> + int(2) + [3]=> + int(2) + [0]=> + int(3) + [1]=> + int(3) +} +-- Numeric array with increasing and decreasing values -- +bool(true) +array(6) { + [0]=> + int(1) + [5]=> + int(1) + [1]=> + int(2) + [4]=> + int(2) + [2]=> + int(3) + [3]=> + int(3) +} +Done diff --git a/tests/std/array/uasort_object1.phpt b/tests/std/array/uasort_object1.phpt new file mode 100644 index 00000000..972418fd --- /dev/null +++ b/tests/std/array/uasort_object1.phpt @@ -0,0 +1,140 @@ +--TEST-- +Test uasort() function : object functionality +--FILE-- + $value2) { + return 1; + } + else + return -1; +} + +// comparison function for SimpleClass2 objects which has more than one members +function multiple_cmp($value1, $value2) +{ + if($value1->getValue() == $value2->getValue()) + return 0; + else if($value1->getValue() > $value2->getValue()) + return 1; + else + return -1; +} + +// Simple class with single member variable +class SimpleClass1 +{ + private $int_value; + + public function __construct($value) { + $this->int_value = $value; + } +} + +// Simple class with more than one member variables +class SimpleClass2 +{ + private $int_value; + protected $float_value; + public $string_value; + public function __construct($int, $float, $str) { + $this->int_value = $int; + $this->float_value = $float; + $this->string_value = $str; + } + public function getValue() { + return $this->int_value; + } +} + +function main() { +echo "*** Testing uasort() : object functionality ***\n"; + +// array of SimpleClass objects with only one member +$array_arg = array( + 0 => new SimpleClass1(10), + 1 => new SimpleClass1(1), + 2 => new SimpleClass1(100), + 3 => new SimpleClass1(50) +); +var_dump( uasort($array_arg, 'simple_cmp') ); +var_dump($array_arg); + +// array of SimpleClass objects having more than one members +$array_arg = array( + 0 => new SimpleClass2(2, 3.4, "mango"), + 1 => new SimpleClass2(10, 1.2, "apple"), + 2 => new SimpleClass2(5, 2.5, "orange"), +); +var_dump( uasort($array_arg, 'multiple_cmp') ); +var_dump($array_arg); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing uasort() : object functionality *** +bool(true) +array(4) { + [1]=> + object(SimpleClass1)#2 (1) { + ["int_value":"SimpleClass1":private]=> + int(1) + } + [0]=> + object(SimpleClass1)#1 (1) { + ["int_value":"SimpleClass1":private]=> + int(10) + } + [3]=> + object(SimpleClass1)#4 (1) { + ["int_value":"SimpleClass1":private]=> + int(50) + } + [2]=> + object(SimpleClass1)#3 (1) { + ["int_value":"SimpleClass1":private]=> + int(100) + } +} +bool(true) +array(3) { + [0]=> + object(SimpleClass2)#5 (3) { + ["int_value":"SimpleClass2":private]=> + int(2) + ["float_value":protected]=> + float(3.4) + ["string_value"]=> + string(5) "mango" + } + [2]=> + object(SimpleClass2)#7 (3) { + ["int_value":"SimpleClass2":private]=> + int(5) + ["float_value":protected]=> + float(2.5) + ["string_value"]=> + string(6) "orange" + } + [1]=> + object(SimpleClass2)#6 (3) { + ["int_value":"SimpleClass2":private]=> + int(10) + ["float_value":protected]=> + float(1.2) + ["string_value"]=> + string(5) "apple" + } +} +Done diff --git a/tests/std/array/uasort_object2.phpt b/tests/std/array/uasort_object2.phpt new file mode 100644 index 00000000..bb4672db --- /dev/null +++ b/tests/std/array/uasort_object2.phpt @@ -0,0 +1,175 @@ +--TEST-- +Test uasort() function : object functionality - sort diff. objects +--FILE-- + $value2) { + return 1; + } + else + return -1; +} + +// Simple class with single member variable +class SimpleClass +{ + private $int_value; + + public function __construct($value) { + $this->int_value = $value; + } +} + +// Class without any member +class EmptyClass +{ +} + +// Class with static member +class StaticClass +{ + public static $static_value; + public function __construct($value) { + StaticClass::$static_value = $value; + } +} + +// Abstract class +abstract class AbstractClass +{ + public $pub_value; + public abstract function abstractMethod(); +} + +// Child class extending abstract class +class ChildClass extends AbstractClass +{ + public $child_value = 100; + public function abstractMethod() { + $pub_value = 5; + } + public function __construct($value) { + $this->child_value = $value; + } +} + +function main() { +echo "*** Testing uasort() : object functionality ***\n"; + +// Testing uasort with StaticClass objects as elements of 'array_arg' +echo "-- Testing uasort() with StaticClass objects --\n"; +$array_arg = array( + 0 => new StaticClass(20), + 1 => new StaticClass(50), + 2 => new StaticClass(15), + 3 => new StaticClass(70), +); +var_dump( uasort($array_arg, 'cmp_function') ); +var_dump($array_arg); + +// Testing uasort with EmptyClass objects as elements of 'array_arg' +echo "-- Testing uasort() with EmptyClass objects --\n"; +$array_arg = array( + 0 => new EmptyClass(), + 1 => new EmptyClass(), + 2 => new EmptyClass(), + 3 => new EmptyClass(), +); +var_dump( uasort($array_arg, 'cmp_function') ); +var_dump($array_arg); + +// Testing uasort with ChildClass objects as elements of 'array_arg' +echo "-- Testing uasort() with ChildClass objects --\n"; +$array_arg = array( + 0 => new ChildClass(20), + 1 => new ChildClass(500), + 2 => new ChildClass(15), + 3 => new ChildClass(700), +); +var_dump( uasort($array_arg, 'cmp_function') ); +var_dump($array_arg); + +echo "Done"; +} +?> +--EXPECTF-- +*** Testing uasort() : object functionality *** +-- Testing uasort() with StaticClass objects -- +bool(true) +array(4) { + [0]=> + object(StaticClass)#%d (0) { + } + [1]=> + object(StaticClass)#%d (0) { + } + [2]=> + object(StaticClass)#%d (0) { + } + [3]=> + object(StaticClass)#%d (0) { + } +} +-- Testing uasort() with EmptyClass objects -- +bool(true) +array(4) { + [0]=> + object(EmptyClass)#%d (0) { + } + [1]=> + object(EmptyClass)#%d (0) { + } + [2]=> + object(EmptyClass)#%d (0) { + } + [3]=> + object(EmptyClass)#%d (0) { + } +} +-- Testing uasort() with ChildClass objects -- +bool(true) +array(4) { + [2]=> + object(ChildClass)#%d (2) { + ["pub_value"]=> + NULL + ["child_value"]=> + int(15) + } + [0]=> + object(ChildClass)#%d (2) { + ["pub_value"]=> + NULL + ["child_value"]=> + int(20) + } + [1]=> + object(ChildClass)#%d (2) { + ["pub_value"]=> + NULL + ["child_value"]=> + int(500) + } + [3]=> + object(ChildClass)#%d (2) { + ["pub_value"]=> + NULL + ["child_value"]=> + int(700) + } +} +Done diff --git a/tests/std/array/uasort_variation10.phpt b/tests/std/array/uasort_variation10.phpt new file mode 100644 index 00000000..507ce5b0 --- /dev/null +++ b/tests/std/array/uasort_variation10.phpt @@ -0,0 +1,68 @@ +--TEST-- +Test uasort() function : usage variations - sort array with reference variables +--SKIPIF-- + +--FILE-- + $value2) { + return 1; + } + else { + return -1; + } +} + +function main() { +echo "*** Testing uasort() : 'array_arg' with elements as reference ***\n"; + +// different variables which are used as elements of 'array_arg' +$value1 = -5; +$value2 = 100; +$value3 = 0; +$value4 = &$value1; + +// array_args an array containing elements with reference variables +$array_arg = array( + 0 => 10, + 1 => &$value4, + 2 => &$value2, + 3 => 200, + 4 => &$value3, +); + +echo "-- Sorting 'array_arg' containing different references --\n"; +var_dump( uasort($array_arg, 'cmp_function') ); // expecting: bool(true) +var_dump($array_arg); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing uasort() : 'array_arg' with elements as reference *** +-- Sorting 'array_arg' containing different references -- +bool(true) +array(5) { + [1]=> + &int(-5) + [4]=> + &int(0) + [0]=> + int(10) + [2]=> + &int(100) + [3]=> + int(200) +} +Done diff --git a/tests/std/array/uasort_variation11.phpt b/tests/std/array/uasort_variation11.phpt new file mode 100644 index 00000000..aa8ec3d9 --- /dev/null +++ b/tests/std/array/uasort_variation11.phpt @@ -0,0 +1,72 @@ +--TEST-- +Test uasort() function : usage variations - different associative arrays +--FILE-- + $value2) { + return 1; + } + else + return -1; +} + +function main() { +echo "*** Testing uasort() : sorting different associative arrays ***\n"; + +// Array with duplicate string and integer keys +$array_arg = array(0 => 2, "a" => 8, "d" => 9, 3 => 3, 5 => 2, "o" => 6, "z" => -99, 0 => 1, "z" => 3); +echo "-- Array with duplicate keys --\n"; +var_dump( uasort($array_arg, 'cmp') ); +var_dump($array_arg); + +// Array with default and assigned keys +$array_arg = array(0 => "Banana", 1 => "Mango", "Orange", 2 => "Apple", "Pineapple"); +echo "-- Array with default/assigned keys --\n"; +var_dump( uasort($array_arg, 'cmp') ); +var_dump($array_arg); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing uasort() : sorting different associative arrays *** +-- Array with duplicate keys -- +bool(true) +array(7) { + [0]=> + int(1) + [5]=> + int(2) + [3]=> + int(3) + ["z"]=> + int(3) + ["o"]=> + int(6) + ["a"]=> + int(8) + ["d"]=> + int(9) +} +-- Array with default/assigned keys -- +bool(true) +array(4) { + [2]=> + string(5) "Apple" + [0]=> + string(6) "Banana" + [1]=> + string(5) "Mango" + [3]=> + string(9) "Pineapple" +} +Done diff --git a/tests/std/array/uasort_variation3.phpt b/tests/std/array/uasort_variation3.phpt new file mode 100644 index 00000000..f287841b --- /dev/null +++ b/tests/std/array/uasort_variation3.phpt @@ -0,0 +1,127 @@ +--TEST-- +Test uasort() function : usage variations - sort array with all possible keys +--SKIPIF-- + +--FILE-- + $value2) { + return -1; + } + else { + return 1; + } +} + +function main() { +echo "*** Testing uasort() : Sorting array with all possible keys ***\n"; + +// different heredoc strings +//empty heredoc string +$empty_heredoc = << 10, // expecting: value will be replaced by 'TRUE' + -2 => 9, + 012 => 7, + 0x34 => 6, + + // string keys + 'key' => 5, //single quoted key + "two" => 4, //double quoted key + '' => 3, + "" => 2, + " " => 0, // space as key + + // bool keys + true => 15, + false => 5, + TRUE => 100, + FALSE => 25, + + // null keys + null => 20, // expecting: value will be replaced by 'NULL' + NULL => 35, + + // binary key + "a".chr(0)."b" => 45, + b"binary" => 30, + + //heredoc keys + $empty_heredoc => 90, + $simple_heredoc => 75, + $multiline_heredoc => 200, +); + +var_dump( uasort($array_arg, 'cmp_function') ); +echo "-- Sorted array after uasort() function call --\n"; +var_dump($array_arg); + +echo "Done"; +} +?> +--EXPECTF-- +*** Testing uasort() : Sorting array with all possible keys *** +bool(true) +-- Sorted array after uasort() function call -- +array(15) { + ["multiline heredoc with 123 +and speci@! ch@r.. +check also"]=> + int(200) + [1]=> + int(100) + [""]=> + int(90) + ["simple"]=> + int(75) + ["a%0b"]=> + int(45) + [54]=> + int(35) + ["binary"]=> + int(30) + [0]=> + int(25) + [53]=> + int(20) + [-2]=> + int(9) + [10]=> + int(7) + [52]=> + int(6) + ["key"]=> + int(5) + ["two"]=> + int(4) + [" "]=> + int(0) +} +Done diff --git a/tests/std/array/uasort_variation4.phpt b/tests/std/array/uasort_variation4.phpt new file mode 100644 index 00000000..20febefd --- /dev/null +++ b/tests/std/array/uasort_variation4.phpt @@ -0,0 +1,140 @@ +--TEST-- +Test uasort() function : usage variations - sort different numeric values +--FILE-- + $value2) { + return 1; + } + else { + return -1; + } +} + +function main() { +echo "*** Testing uasort() : different numeric arrays as 'array_arg' ***\n"; + +// Int array +$int_values = array(0 => 3, 1 => 2, 3 => 100, 4 => 150, 5 => 25, 6 => 350, 7 => 0, 8 => -3, 9 => -1200); +echo "-- Sorting Integer array --\n"; +var_dump( uasort($int_values, 'cmp_function') ); // expecting: bool(true) +var_dump($int_values); + +// Octal array +$octal_values = array(0 => 056, 1 => 023, 2 => 00, 3 => 015, 4 => -045, 5 => 01, 6 => -07); +echo "-- Sorting Octal array --\n"; +var_dump( uasort($octal_values, 'cmp_function') ); // expecting: bool(true) +var_dump($octal_values); + +// Hexadecimal array +$hex_values = array(0 => 0xAE, 1 => 0x2B, 2 => 0X10, 3 => -0xCF, 4 => 0X12, 5 => -0XF2); +echo "-- Sorting Hex array --\n"; +var_dump( uasort($hex_values, 'cmp_function') ); // expecting: bool(true) +var_dump($hex_values); + +// Float array +$float_values = array( 0 => 10.2, 1 => 2.4, 2 => -3.4, 3 => 0, 4 => 0.5, 5 => 7.3e3, 6 => -9.34E-2); +echo "-- Sorting Float array --\n"; +var_dump( uasort($float_values, 'cmp_function') ); // expecting: bool(true) +var_dump($float_values); + +// empty array +$empty_array = array(); +echo "-- Sorting empty array --\n"; +var_dump( uasort($empty_array, 'cmp_function') ); // expecting: bool(true) +var_dump($empty_array); + +echo "Done"; +} +?> +--EXPECT-- +*** Testing uasort() : different numeric arrays as 'array_arg' *** +-- Sorting Integer array -- +bool(true) +array(9) { + [9]=> + int(-1200) + [8]=> + int(-3) + [7]=> + int(0) + [1]=> + int(2) + [0]=> + int(3) + [5]=> + int(25) + [3]=> + int(100) + [4]=> + int(150) + [6]=> + int(350) +} +-- Sorting Octal array -- +bool(true) +array(7) { + [4]=> + int(-37) + [6]=> + int(-7) + [2]=> + int(0) + [5]=> + int(1) + [3]=> + int(13) + [1]=> + int(19) + [0]=> + int(46) +} +-- Sorting Hex array -- +bool(true) +array(6) { + [5]=> + int(-242) + [3]=> + int(-207) + [2]=> + int(16) + [4]=> + int(18) + [1]=> + int(43) + [0]=> + int(174) +} +-- Sorting Float array -- +bool(true) +array(7) { + [2]=> + float(-3.4) + [6]=> + float(-0.0934) + [3]=> + int(0) + [4]=> + float(0.5) + [1]=> + float(2.4) + [0]=> + float(10.2) + [5]=> + float(7300) +} +-- Sorting empty array -- +bool(true) +array(0) { +} +Done diff --git a/tests/std/array/uasort_variation5.phpt b/tests/std/array/uasort_variation5.phpt new file mode 100644 index 00000000..26521981 --- /dev/null +++ b/tests/std/array/uasort_variation5.phpt @@ -0,0 +1,135 @@ +--TEST-- +Test uasort() function : usage variations - sort diff. strings +--FILE-- + $value2) { + return 1; + } + else { + return -1; + } +} + +function main() { +// Different heredoc strings to be sorted +$empty_heredoc =<< ' ', 1 => 'test', 3 => 'Hello', 4 => 'HELLO', + 5 => '', 6 => '\t', 7 => '0', 8 => '123Hello', 9 => '\'', 10 => '@#$%' +); +echo "-- Sorting Single Quoted String values --\n"; +var_dump( uasort($single_quoted_values, 'cmp_function') ); // expecting: bool(true) +var_dump($single_quoted_values); + +// Double quoted strings +$double_quoted_values = array( + 0 => " ", 1 => "test", 3 => "Hello", 4 => "HELLO", + 5 => "", 6 => "\t", 7 => "0", 8 => "123Hello", 9 => "\"", 10 => "@#$%" +); +echo "-- Sorting Double Quoted String values --\n"; +var_dump( uasort($double_quoted_values, 'cmp_function') ); // expecting: bool(true) +var_dump($double_quoted_values); + +// Heredoc strings +$heredoc_values = array(0 => $empty_heredoc, 1 => $simple_heredoc1, 2 => $simple_heredoc2, 3 => $multiline_heredoc); +echo "-- Sorting Heredoc String values --\n"; +var_dump( uasort($heredoc_values, 'cmp_function') ); // expecting: bool(true) +var_dump($heredoc_values); + +echo "Done"; +} +?> +--EXPECTF-- +*** Testing uasort() : different string arrays as 'array_arg' *** +-- Sorting Single Quoted String values -- +bool(true) +array(10) { + [5]=> + string(0) "" + [0]=> + string(1) " " + [9]=> + string(1) "'" + [7]=> + string(1) "0" + [8]=> + string(8) "123Hello" + [10]=> + string(4) "@#$%" + [4]=> + string(5) "HELLO" + [3]=> + string(5) "Hello" + [6]=> + string(2) "\t" + [1]=> + string(4) "test" +} +-- Sorting Double Quoted String values -- +bool(true) +array(10) { + [5]=> + string(0) "" + [6]=> + string(1) " " + [0]=> + string(1) " " + [9]=> + string(1) """ + [7]=> + string(1) "0" + [8]=> + string(8) "123Hello" + [10]=> + string(4) "@#$%" + [4]=> + string(5) "HELLO" + [3]=> + string(5) "Hello" + [1]=> + string(4) "test" +} +-- Sorting Heredoc String values -- +bool(true) +array(4) { + [0]=> + string(0) "" + [2]=> + string(7) "HEREDOC" + [1]=> + string(7) "Heredoc" + [3]=> + string(4%d) "heredoc string with!@# and 123 +Test this!!!" +} +Done diff --git a/tests/std/array/uasort_variation6.phpt b/tests/std/array/uasort_variation6.phpt new file mode 100644 index 00000000..23acfc8e --- /dev/null +++ b/tests/std/array/uasort_variation6.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test uasort() function : usage variations - sort array having subarrays +--FILE-- + $value2) { + return 1; + } else { + return -1; + } +} +function main() +{ + echo "*** Testing uasort() : sorting array having different subarrays ***\n"; + $array_args = array(0 => array(2, 10, -1), 1 => array(100), 2 => array(), 3 => array(0), 4 => array(-1), 5 => array(-9, 34, 54, 0, 20), 6 => array(''), 7 => array("apple", "Apple", "APPLE", "aPPle", "aPpLe")); + $temp_array = $array_args; + // sorting array_arg as whole array + var_dump(uasort($temp_array, 'cmp_function')); + // expecting: bool(true) + var_dump($temp_array); +} +?> +--EXPECT-- +*** Testing uasort() : sorting array having different subarrays *** +bool(true) +array(8) { + [2]=> + array(0) { + } + [6]=> + array(1) { + [0]=> + string(0) "" + } + [4]=> + array(1) { + [0]=> + int(-1) + } + [3]=> + array(1) { + [0]=> + int(0) + } + [1]=> + array(1) { + [0]=> + int(100) + } + [0]=> + array(3) { + [0]=> + int(2) + [1]=> + int(10) + [2]=> + int(-1) + } + [5]=> + array(5) { + [0]=> + int(-9) + [1]=> + int(34) + [2]=> + int(54) + [3]=> + int(0) + [4]=> + int(20) + } + [7]=> + array(5) { + [0]=> + string(5) "apple" + [1]=> + string(5) "Apple" + [2]=> + string(5) "APPLE" + [3]=> + string(5) "aPPle" + [4]=> + string(5) "aPpLe" + } +} diff --git a/tests/std/array/uasort_variation7.phpt b/tests/std/array/uasort_variation7.phpt new file mode 100644 index 00000000..5340dd90 --- /dev/null +++ b/tests/std/array/uasort_variation7.phpt @@ -0,0 +1,86 @@ +--TEST-- +Test uasort() function : usage variations - anonymous function as 'cmp_function' +--SKIPIF-- + + +--FILE-- + $value2) { return 1; } + else { return -1; } +}; + +$array_arg = array(0 => 100, 1 => 3, 2 => -70, 3 => 24, 4 => 90); +echo "-- Anonymous 'cmp_function' with parameters passed by value --\n"; +var_dump( uasort($array_arg, $cmp_function) ); +var_dump($array_arg); + +$cmp_function = function(&$value1, &$value2) { + if ($value1 == $value2) { return 0; } + else if ($value1 > $value2) { return 1; } + else { return -1; } +}; + +$array_arg = array("b" => "Banana", "m" => "Mango", "a" => "Apple", "p" => "Pineapple"); +echo "-- Anonymous 'cmp_function' with parameters passed by reference --\n"; +var_dump( uasort($array_arg, $cmp_function ) ); +var_dump($array_arg); + +echo "Done"; +?> +--EXPECTF-- +*** Testing uasort() : anonymous function as 'cmp_function' *** +-- Anonymous 'cmp_function' with parameters passed by value -- +bool(true) +array(5) { + [2]=> + int(-70) + [1]=> + int(3) + [3]=> + int(24) + [4]=> + int(90) + [0]=> + int(100) +} +-- Anonymous 'cmp_function' with parameters passed by reference -- + +Warning: {closure:%s:%d}(): Argument #1 ($value1) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #2 ($value2) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #1 ($value1) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #2 ($value2) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #1 ($value1) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #2 ($value2) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #1 ($value1) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #2 ($value2) must be passed by reference, value given in %s on line %d +bool(true) +array(4) { + ["a"]=> + string(5) "Apple" + ["b"]=> + string(6) "Banana" + ["m"]=> + string(5) "Mango" + ["p"]=> + string(9) "Pineapple" +} +Done diff --git a/tests/std/array/uasort_variation8.phpt b/tests/std/array/uasort_variation8.phpt new file mode 100644 index 00000000..9250af55 --- /dev/null +++ b/tests/std/array/uasort_variation8.phpt @@ -0,0 +1,57 @@ +--TEST-- +Test uasort() function : usage variations - built-in function as 'cmp_function' +--FILE-- + "Banana", "m" => "Mango", "a" => "apple", "p" => "Pineapple", "o" => "orange"); +$builtin_fun_arg = $array_arg; +$languageConstruct_fun_arg = $array_arg; + +// Testing library functions as comparison function +echo "-- Testing uasort() with built-in 'cmp_function': strcasecmp() --\n"; +var_dump( uasort($builtin_fun_arg, 'strcasecmp') ); // expecting: bool(true) +var_dump($builtin_fun_arg); + +echo "-- Testing uasort() with built-in 'cmp_function': strcmp() --\n"; +var_dump( uasort($array_arg, 'strcmp') ); // expecting: bool(true) +var_dump($array_arg); + +echo "Done"; +?> +--EXPECT-- +*** Testing uasort() : built in function as 'cmp_function' *** +-- Testing uasort() with built-in 'cmp_function': strcasecmp() -- +bool(true) +array(5) { + ["a"]=> + string(5) "apple" + ["b"]=> + string(6) "Banana" + ["m"]=> + string(5) "Mango" + ["o"]=> + string(6) "orange" + ["p"]=> + string(9) "Pineapple" +} +-- Testing uasort() with built-in 'cmp_function': strcmp() -- +bool(true) +array(5) { + ["b"]=> + string(6) "Banana" + ["m"]=> + string(5) "Mango" + ["p"]=> + string(9) "Pineapple" + ["a"]=> + string(5) "apple" + ["o"]=> + string(6) "orange" +} +Done diff --git a/tests/std/array/uksort_basic.phpt b/tests/std/array/uksort_basic.phpt new file mode 100644 index 00000000..12b8c0bc --- /dev/null +++ b/tests/std/array/uksort_basic.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test uksort(): basic functionality +--FILE-- + $value) { + echo "{$key}: {$value}\n"; + } +} +?> +--EXPECT-- +4: 1 +1: 2 +0: 3 +2: 5 +3: 6 diff --git a/tests/std/array/unexpected_array_mod_bug.phpt b/tests/std/array/unexpected_array_mod_bug.phpt new file mode 100644 index 00000000..f211e898 --- /dev/null +++ b/tests/std/array/unexpected_array_mod_bug.phpt @@ -0,0 +1,31 @@ +--TEST-- +Crash when function parameter modified via reference +--SKIPIF-- + +--FILE-- + $b; +} +function main() +{ + $my_var = array(1 => "entry_1", 2 => "entry_2", 3 => "entry_3", 4 => "entry_4", 5 => "entry_5"); + usort($my_var, "usercompare"); + var_dump($my_var); +} +?> +--EXPECT-- +array(5) { + [0]=> + string(7) "entry_1" + [1]=> + string(7) "entry_2" + [2]=> + string(7) "entry_3" + [3]=> + string(7) "entry_4" + [4]=> + string(7) "entry_5" +} diff --git a/tests/std/array/unexpected_array_mod_bug_variation1.phpt b/tests/std/array/unexpected_array_mod_bug_variation1.phpt new file mode 100644 index 00000000..b5a1ee24 --- /dev/null +++ b/tests/std/array/unexpected_array_mod_bug_variation1.phpt @@ -0,0 +1,33 @@ +--TEST-- +Crash when function parameter modified via reference while keeping orig refcount +--FILE-- + "entry_1", + 2 => "entry_2", + 3 => "entry_3", + 4 => "entry_4", + 5 => "entry_5" +); +usort($array, function($a, $b) use (&$array, &$ref) { + unset($array[2]); + $ref = $array; + return $a <=> $b; +}); +var_dump($array); + +?> +--EXPECT-- +array(5) { + [0]=> + string(7) "entry_1" + [1]=> + string(7) "entry_2" + [2]=> + string(7) "entry_3" + [3]=> + string(7) "entry_4" + [4]=> + string(7) "entry_5" +} diff --git a/tests/std/array/usort_basic.phpt b/tests/std/array/usort_basic.phpt new file mode 100644 index 00000000..2c98a6de --- /dev/null +++ b/tests/std/array/usort_basic.phpt @@ -0,0 +1,104 @@ +--TEST-- +Test usort() function : basic functionality +--FILE-- + $value2) { + return 1; + } else { + return -1; + } +} +function main() +{ + /* + * Test basic functionality of usort() with indexed and associative arrays + */ + echo "*** Testing usort() : basic functionality ***\n"; + // Int array with default keys + $int_values = array(1, 8, 9, 3, 2, 6, 7); + echo "\n-- Numeric array with default keys --\n"; + var_dump(usort($int_values, 'cmp')); + var_dump($int_values); + // String array with default keys + $string_values = array("This", "is", 'a', "test"); + echo "\n-- String array with default keys --\n"; + var_dump(usort($string_values, 'cmp')); + var_dump($string_values); + // Associative array with numeric keys + $numeric_key_arg = array(1 => 1, 2 => 2, 3 => 7, 5 => 4, 4 => 9); + echo "\n-- Associative array with numeric keys --\n"; + var_dump(usort($numeric_key_arg, 'cmp')); + var_dump($numeric_key_arg); + // Associative array with string keys + $string_key_arg = array('one' => 4, 'two' => 2, 'three' => 1, 'four' => 10); + echo "\n-- Associative array with string keys --\n"; + var_dump(usort($string_key_arg, 'cmp')); + var_dump($string_key_arg); +} +?> +--EXPECT-- +*** Testing usort() : basic functionality *** + +-- Numeric array with default keys -- +bool(true) +array(7) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(6) + [4]=> + int(7) + [5]=> + int(8) + [6]=> + int(9) +} + +-- String array with default keys -- +bool(true) +array(4) { + [0]=> + string(4) "This" + [1]=> + string(1) "a" + [2]=> + string(2) "is" + [3]=> + string(4) "test" +} + +-- Associative array with numeric keys -- +bool(true) +array(5) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(4) + [3]=> + int(7) + [4]=> + int(9) +} + +-- Associative array with string keys -- +bool(true) +array(4) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(4) + [3]=> + int(10) +} diff --git a/tests/std/array/usort_object1.phpt b/tests/std/array/usort_object1.phpt new file mode 100644 index 00000000..5c338852 --- /dev/null +++ b/tests/std/array/usort_object1.phpt @@ -0,0 +1,123 @@ +--TEST-- +Test usort() function : object functionality - different number of properties +--FILE-- + $value2) { + return 1; + } else { + return -1; + } +} +// comparison function for SimpleClass2 objects which has more than one member +function multiple_cmp($value1, $value2) +{ + if ($value1->getValue() == $value2->getValue()) { + return 0; + } else if ($value1->getValue() > $value2->getValue()) { + return 1; + } else { + return -1; + } +} +// Simple class with single property +class SimpleClass1 +{ + private $int_value; + public function __construct($value) + { + $this->int_value = $value; + } +} +// Simple class with more than one property +class SimpleClass2 +{ + private $int_value; + protected $float_value; + public $string_value; + public function __construct($int, $float, $str) + { + $this->int_value = $int; + $this->float_value = $float; + $this->string_value = $str; + } + public function getValue() + { + return $this->int_value; + } +} +function main() +{ + /* + * Pass an array of objects which have a different number of properties + * to test behaviour of usort() + */ + echo "*** Testing usort() : object functionality ***\n"; + // array of SimpleClass objects with only one property + $array_arg = array(0 => new SimpleClass1(10), 1 => new SimpleClass1(1), 2 => new SimpleClass1(100), 3 => new SimpleClass1(50)); + var_dump(usort($array_arg, 'simple_cmp')); + var_dump($array_arg); + // array of SimpleClass objects having more than one properties + $array_arg = array(0 => new SimpleClass2(2, 3.4, "mango"), 1 => new SimpleClass2(10, 1.2, "apple"), 2 => new SimpleClass2(5, 2.5, "orange")); + var_dump(usort($array_arg, 'multiple_cmp')); + var_dump($array_arg); +} +?> +--EXPECTF-- +*** Testing usort() : object functionality *** +bool(true) +array(4) { + [0]=> + object(SimpleClass1)#%d (1) { + ["int_value":"SimpleClass1":private]=> + int(1) + } + [1]=> + object(SimpleClass1)#%d (1) { + ["int_value":"SimpleClass1":private]=> + int(10) + } + [2]=> + object(SimpleClass1)#%d (1) { + ["int_value":"SimpleClass1":private]=> + int(50) + } + [3]=> + object(SimpleClass1)#%d (1) { + ["int_value":"SimpleClass1":private]=> + int(100) + } +} +bool(true) +array(3) { + [0]=> + object(SimpleClass2)#%d (3) { + ["int_value":"SimpleClass2":private]=> + int(2) + ["float_value":protected]=> + float(3.4) + ["string_value"]=> + string(5) "mango" + } + [1]=> + object(SimpleClass2)#%d (3) { + ["int_value":"SimpleClass2":private]=> + int(5) + ["float_value":protected]=> + float(2.5) + ["string_value"]=> + string(6) "orange" + } + [2]=> + object(SimpleClass2)#%d (3) { + ["int_value":"SimpleClass2":private]=> + int(10) + ["float_value":protected]=> + float(1.2) + ["string_value"]=> + string(5) "apple" + } +} diff --git a/tests/std/array/usort_object2.phpt b/tests/std/array/usort_object2.phpt new file mode 100644 index 00000000..661d8390 --- /dev/null +++ b/tests/std/array/usort_object2.phpt @@ -0,0 +1,139 @@ +--TEST-- +Test usort() function : object functionality - Different types of classes +--FILE-- + $value2) { + return 1; + } else { + return -1; + } +} +// Class without any member +class EmptyClass +{ +} +// Class with static member +class StaticClass +{ + public static $static_value; + public function __construct($value) + { + StaticClass::$static_value = $value; + } +} +// Abstract class +abstract class AbstractClass +{ + public $pub_value; + abstract public function abstractMethod(); +} +// Child class extending abstract class +class ChildClass extends AbstractClass +{ + public $child_value = 100; + public function abstractMethod() + { + $pub_value = 5; + } + public function __construct($value) + { + $this->child_value = $value; + } +} +function main() +{ + /* + * Pass an array of objects which are either: + * 1. Empty + * 2. Static + * 2. Inherited + * to test behaviour of usort() + */ + echo "*** Testing usort() : object functionality ***\n"; + // Testing uasort with StaticClass objects as elements of 'array_arg' + echo "-- Testing usort() with StaticClass objects --\n"; + $array_arg = array(0 => new StaticClass(20), 1 => new StaticClass(50), 2 => new StaticClass(15), 3 => new StaticClass(70)); + var_dump(usort($array_arg, 'cmp_function')); + var_dump($array_arg); + // Testing uasort with EmptyClass objects as elements of 'array_arg' + echo "-- Testing usort() with EmptyClass objects --\n"; + $array_arg = array(0 => new EmptyClass(), 1 => new EmptyClass(), 2 => new EmptyClass(), 3 => new EmptyClass()); + var_dump(usort($array_arg, 'cmp_function')); + var_dump($array_arg); + // Testing uasort with ChildClass objects as elements of 'array_arg' + echo "-- Testing usort() with ChildClass objects --\n"; + $array_arg = array(0 => new ChildClass(20), 1 => new ChildClass(500), 2 => new ChildClass(15), 3 => new ChildClass(700)); + var_dump(usort($array_arg, 'cmp_function')); + var_dump($array_arg); +} +?> +--EXPECTF-- +*** Testing usort() : object functionality *** +-- Testing usort() with StaticClass objects -- +bool(true) +array(4) { + [0]=> + object(StaticClass)#%d (0) { + } + [1]=> + object(StaticClass)#%d (0) { + } + [2]=> + object(StaticClass)#%d (0) { + } + [3]=> + object(StaticClass)#%d (0) { + } +} +-- Testing usort() with EmptyClass objects -- +bool(true) +array(4) { + [0]=> + object(EmptyClass)#%d (0) { + } + [1]=> + object(EmptyClass)#%d (0) { + } + [2]=> + object(EmptyClass)#%d (0) { + } + [3]=> + object(EmptyClass)#%d (0) { + } +} +-- Testing usort() with ChildClass objects -- +bool(true) +array(4) { + [0]=> + object(ChildClass)#%d (2) { + ["pub_value"]=> + NULL + ["child_value"]=> + int(15) + } + [1]=> + object(ChildClass)#%d (2) { + ["pub_value"]=> + NULL + ["child_value"]=> + int(20) + } + [2]=> + object(ChildClass)#%d (2) { + ["pub_value"]=> + NULL + ["child_value"]=> + int(500) + } + [3]=> + object(ChildClass)#%d (2) { + ["pub_value"]=> + NULL + ["child_value"]=> + int(700) + } +} diff --git a/tests/std/array/usort_stability.phpt b/tests/std/array/usort_stability.phpt new file mode 100644 index 00000000..e3ca4e16 --- /dev/null +++ b/tests/std/array/usort_stability.phpt @@ -0,0 +1,15 @@ +--TEST-- +usort() is stable +--FILE-- + +--EXPECT-- +bool(true) diff --git a/tests/std/array/usort_variation10.phpt b/tests/std/array/usort_variation10.phpt new file mode 100644 index 00000000..6085e6fb --- /dev/null +++ b/tests/std/array/usort_variation10.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test usort() function : usage variations - duplicate keys and values +--FILE-- + $value2) { + return 1; + } else { + return -1; + } +} +function main() +{ + /* + * Pass an array with duplicate keys and values to usort() to test behaviour + */ + echo "*** Testing usort() : usage variation ***\n"; + // Array with duplicate string and integer keys and values + $array_arg = array(0 => 2, "a" => 8, "d" => 9, 3 => 3, 5 => 2, "o" => 6, "z" => -99, 0 => 1, "z" => 3); + echo "\n-- Array with duplicate keys --\n"; + var_dump(usort($array_arg, 'cmp')); + var_dump($array_arg); + // Array with default and assigned keys + $array_arg = array(0 => "Banana", 1 => "Mango", "Orange", 2 => "Apple", "Pineapple"); + echo "\n-- Array with default/assigned keys --\n"; + var_dump(usort($array_arg, 'cmp')); + var_dump($array_arg); +} +?> +--EXPECT-- +*** Testing usort() : usage variation *** + +-- Array with duplicate keys -- +bool(true) +array(7) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) + [3]=> + int(3) + [4]=> + int(6) + [5]=> + int(8) + [6]=> + int(9) +} + +-- Array with default/assigned keys -- +bool(true) +array(4) { + [0]=> + string(5) "Apple" + [1]=> + string(6) "Banana" + [2]=> + string(5) "Mango" + [3]=> + string(9) "Pineapple" +} diff --git a/tests/std/array/usort_variation11.phpt b/tests/std/array/usort_variation11.phpt new file mode 100644 index 00000000..fef77fc4 --- /dev/null +++ b/tests/std/array/usort_variation11.phpt @@ -0,0 +1,87 @@ +--TEST-- +Test usort() function : usage variations - malformed comparison function returning boolean +--SKIPIF-- + +--FILE-- + $b; +} +function main() +{ + $range = array(2, 4, 8, 16, 32, 64, 128); + foreach ($range as $r) { + $backup = $array = range(0, $r); + shuffle($array); + usort($array, "ucmp"); + if ($array != $backup) { + var_dump($array); + var_dump($backup); + die("Array not sorted (usort)"); + } + shuffle($array); + $array = array_flip($array); + uksort($array, "ucmp"); + $array = array_keys($array); + if ($array != $backup) { + var_dump($array); + var_dump($backup); + die("Array not sorted (uksort)"); + } + shuffle($array); + $array = array_combine($array, $array); + uasort($array, "ucmp"); + $array = array_keys($array); + if ($array != $backup) { + var_dump($array); + var_dump($backup); + die("Array not sorted (uasort)"); + } + } + echo "okey"; +} +?> +--EXPECTF-- +Deprecated: usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uksort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uasort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uksort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uasort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uksort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uasort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uksort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uasort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uksort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uasort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uksort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uasort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: usort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uksort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d + +Deprecated: uasort(): Returning bool from comparison function is deprecated, return an integer less than, equal to, or greater than zero in %s on line %d +okey diff --git a/tests/std/array/usort_variation3.phpt b/tests/std/array/usort_variation3.phpt new file mode 100644 index 00000000..54db46e4 --- /dev/null +++ b/tests/std/array/usort_variation3.phpt @@ -0,0 +1,100 @@ +--TEST-- +Test usort() function : usage variations - diff. array values +--FILE-- + $value2) { + return -1; + } else { + return 1; + } +} +function main() +{ + /* + * Pass an array with different data types as keys to usort() to test how it is re-ordered + */ + echo "*** Testing usort() : usage variation ***\n"; + // different heredoc strings + // single line heredoc string + $simple_heredoc = << 9, + 8 => 8, + 012 => 7, + 0x34 => 6, + // string keys + 'key' => 5, + //single quoted key + "two" => 4, + //double quoted key + " " => 0, + // space as key + // bool keys + TRUE => 100, + FALSE => 25, + // null keys + NULL => 35, + // binary key + "a" . chr(0) . "b" => 45, + "binary" => 30, + //heredoc keys + $simple_heredoc => 75, + $multiline_heredoc => 200, + // default key + 1, + ); + var_dump(usort($array_arg, 'cmp_function')); + echo "\n-- Sorted array after usort() function call --\n"; + var_dump($array_arg); +} +?> +--EXPECT-- +*** Testing usort() : usage variation *** +bool(true) + +-- Sorted array after usort() function call -- +array(15) { + [0]=> + int(200) + [1]=> + int(100) + [2]=> + int(75) + [3]=> + int(45) + [4]=> + int(35) + [5]=> + int(30) + [6]=> + int(25) + [7]=> + int(9) + [8]=> + int(8) + [9]=> + int(7) + [10]=> + int(6) + [11]=> + int(5) + [12]=> + int(4) + [13]=> + int(1) + [14]=> + int(0) +} diff --git a/tests/std/array/usort_variation4.phpt b/tests/std/array/usort_variation4.phpt new file mode 100644 index 00000000..b8f86003 --- /dev/null +++ b/tests/std/array/usort_variation4.phpt @@ -0,0 +1,132 @@ +--TEST-- +Test usort() function : usage variations - numeric data +--FILE-- + $value2) { + return 1; + } else { + return -1; + } +} +function main() +{ + /* + * Pass arrays of numeric data to usort() to test how it is re-ordered + */ + echo "*** Testing usort() : usage variation ***\n"; + // Int array + $int_values = array(0 => 3, 1 => 2, 3 => 100, 4 => 150, 5 => 25, 6 => 350, 7 => 0, 8 => -3, 9 => -1200); + echo "\n-- Sorting Integer array --\n"; + var_dump(usort($int_values, 'cmp_function')); + var_dump($int_values); + // Octal array + $octal_values = array(0 => 056, 1 => 023, 2 => 00, 3 => 015, 4 => -045, 5 => 01, 6 => -07); + echo "\n-- Sorting Octal array --\n"; + var_dump(usort($octal_values, 'cmp_function')); + var_dump($octal_values); + // Hexadecimal array + $hex_values = array(0 => 0xae, 1 => 0x2b, 2 => 0x10, 3 => -0xcf, 4 => 0x12, 5 => -0xf2); + echo "\n-- Sorting Hex array --\n"; + var_dump(usort($hex_values, 'cmp_function')); + var_dump($hex_values); + // Float array + $float_values = array(0 => 10.2, 1 => 2.4, 2 => -3.4, 3 => 0, 4 => 0.5, 5 => 7300.0, 6 => -0.0934); + echo "\n-- Sorting Float array --\n"; + var_dump(usort($float_values, 'cmp_function')); + var_dump($float_values); + // empty array + $empty_array = array(); + echo "\n-- Sorting empty array --\n"; + var_dump(usort($empty_array, 'cmp_function')); + var_dump($empty_array); +} +?> +--EXPECT-- +*** Testing usort() : usage variation *** + +-- Sorting Integer array -- +bool(true) +array(9) { + [0]=> + int(-1200) + [1]=> + int(-3) + [2]=> + int(0) + [3]=> + int(2) + [4]=> + int(3) + [5]=> + int(25) + [6]=> + int(100) + [7]=> + int(150) + [8]=> + int(350) +} + +-- Sorting Octal array -- +bool(true) +array(7) { + [0]=> + int(-37) + [1]=> + int(-7) + [2]=> + int(0) + [3]=> + int(1) + [4]=> + int(13) + [5]=> + int(19) + [6]=> + int(46) +} + +-- Sorting Hex array -- +bool(true) +array(6) { + [0]=> + int(-242) + [1]=> + int(-207) + [2]=> + int(16) + [3]=> + int(18) + [4]=> + int(43) + [5]=> + int(174) +} + +-- Sorting Float array -- +bool(true) +array(7) { + [0]=> + float(-3.4) + [1]=> + float(-0.0934) + [2]=> + int(0) + [3]=> + float(0.5) + [4]=> + float(2.4) + [5]=> + float(10.2) + [6]=> + float(7300) +} + +-- Sorting empty array -- +bool(true) +array(0) { +} diff --git a/tests/std/array/usort_variation5.phpt b/tests/std/array/usort_variation5.phpt new file mode 100644 index 00000000..b0b93e20 --- /dev/null +++ b/tests/std/array/usort_variation5.phpt @@ -0,0 +1,116 @@ +--TEST-- +Test usort() function : usage variations - string data +--FILE-- + $value2) { + return 1; + } else { + return -1; + } +} +function main() +{ + /* + * Pass arrays of string data to usort() to test how it is re-ordered + */ + echo "*** Testing usort() : usage variation ***\n"; + // Different heredoc strings to be sorted + $empty_heredoc = << ' ', 1 => 'test', 3 => 'Hello', 4 => 'HELLO', 5 => '', 6 => '\t', 7 => '0', 8 => '123Hello', 9 => '\'', 10 => '@#$%'); + echo "\n-- Sorting Single Quoted String values --\n"; + var_dump(usort($single_quoted_values, 'cmp_function')); + var_dump($single_quoted_values); + // Double quoted strings + $double_quoted_values = array(0 => " ", 1 => "test", 3 => "Hello", 4 => "HELLO", 5 => "", 6 => "\t", 7 => "0", 8 => "123Hello", 9 => "\"", 10 => "@#\$%"); + echo "\n-- Sorting Double Quoted String values --\n"; + var_dump(usort($double_quoted_values, 'cmp_function')); + var_dump($double_quoted_values); + // Heredoc strings + $heredoc_values = array(0 => $empty_heredoc, 1 => $simple_heredoc1, 2 => $simple_heredoc2, 3 => $multiline_heredoc); + echo "\n-- Sorting Heredoc String values --\n"; + var_dump(usort($heredoc_values, 'cmp_function')); + var_dump($heredoc_values); +} +?> +--EXPECTF-- +*** Testing usort() : usage variation *** + +-- Sorting Single Quoted String values -- +bool(true) +array(10) { + [0]=> + string(0) "" + [1]=> + string(1) " " + [2]=> + string(1) "'" + [3]=> + string(1) "0" + [4]=> + string(8) "123Hello" + [5]=> + string(4) "@#$%" + [6]=> + string(5) "HELLO" + [7]=> + string(5) "Hello" + [8]=> + string(2) "\t" + [9]=> + string(4) "test" +} + +-- Sorting Double Quoted String values -- +bool(true) +array(10) { + [0]=> + string(0) "" + [1]=> + string(1) " " + [2]=> + string(1) " " + [3]=> + string(1) """ + [4]=> + string(1) "0" + [5]=> + string(8) "123Hello" + [6]=> + string(4) "@#$%" + [7]=> + string(5) "HELLO" + [8]=> + string(5) "Hello" + [9]=> + string(4) "test" +} + +-- Sorting Heredoc String values -- +bool(true) +array(4) { + [0]=> + string(0) "" + [1]=> + string(7) "HEREDOC" + [2]=> + string(7) "Heredoc" + [3]=> + string(%d) "heredoc string with!@# and 123 +Test this!!!" +} diff --git a/tests/std/array/usort_variation6.phpt b/tests/std/array/usort_variation6.phpt new file mode 100644 index 00000000..b1024907 --- /dev/null +++ b/tests/std/array/usort_variation6.phpt @@ -0,0 +1,116 @@ +--TEST-- +Test usort() function : usage variations - multi-dimensional arrays +--FILE-- + $value2) { + return 1; + } else { + return -1; + } +} +function main() +{ + /* + * Pass a multi-dimensional array as $array_arg argument to usort() + * to test how array is re-ordered + */ + echo "*** Testing usort() : usage variation ***\n"; + $array_args = array(0 => array(2, 10, -1), 1 => array(100), 2 => array(), 3 => array(0), 4 => array(-1), 5 => array(-9, 34, 54, 0, 20), 6 => array(''), 7 => array("apple", "Apple", "APPLE", "aPPle", "aPpLe")); + $temp_array = $array_args; + echo "\n-- Pass usort() a two-dimensional array --\n"; + // sorting array_arg as whole array + var_dump(usort($temp_array, 'cmp_function')); + echo "-- Array after call to usort() --\n"; + var_dump($temp_array); + echo "\n-- Pass usort() a sub-array --\n"; + var_dump(usort($array_args[5], 'cmp_function')); + echo "-- Array after call to usort() --\n"; + var_dump($array_args[5]); +} +?> +--EXPECT-- +*** Testing usort() : usage variation *** + +-- Pass usort() a two-dimensional array -- +bool(true) +-- Array after call to usort() -- +array(8) { + [0]=> + array(0) { + } + [1]=> + array(1) { + [0]=> + string(0) "" + } + [2]=> + array(1) { + [0]=> + int(-1) + } + [3]=> + array(1) { + [0]=> + int(0) + } + [4]=> + array(1) { + [0]=> + int(100) + } + [5]=> + array(3) { + [0]=> + int(2) + [1]=> + int(10) + [2]=> + int(-1) + } + [6]=> + array(5) { + [0]=> + int(-9) + [1]=> + int(34) + [2]=> + int(54) + [3]=> + int(0) + [4]=> + int(20) + } + [7]=> + array(5) { + [0]=> + string(5) "apple" + [1]=> + string(5) "Apple" + [2]=> + string(5) "APPLE" + [3]=> + string(5) "aPPle" + [4]=> + string(5) "aPpLe" + } +} + +-- Pass usort() a sub-array -- +bool(true) +-- Array after call to usort() -- +array(5) { + [0]=> + int(-9) + [1]=> + int(0) + [2]=> + int(20) + [3]=> + int(34) + [4]=> + int(54) +} diff --git a/tests/std/array/usort_variation7.phpt b/tests/std/array/usort_variation7.phpt new file mode 100644 index 00000000..ae036a58 --- /dev/null +++ b/tests/std/array/usort_variation7.phpt @@ -0,0 +1,85 @@ +--TEST-- +Test usort() function : usage variations - Anonymous comparison function +--SKIPIF-- + + +--FILE-- + $value2) { return 1; } + else { return -1; } +}; + +$array_arg = array(0 => 100, 1 => 3, 2 => -70, 3 => 24, 4 => 90); + +echo "\n-- Anonymous 'cmp_function' with parameters passed by value --\n"; +var_dump( usort($array_arg, $cmp_function) ); +var_dump($array_arg); + +$array_arg = array("b" => "Banana", "m" => "Mango", "a" => "Apple", "p" => "Pineapple"); + +$cmp_function = function(&$value1, &$value2) { + if ($value1 == $value2) { return 0; } + else if ($value1 > $value2) { return 1; } + else { return -1; } +}; + +echo "\n-- Anonymous 'cmp_function' with parameters passed by reference --\n"; +var_dump( usort($array_arg, $cmp_function) ); +var_dump($array_arg); +?> +--EXPECTF-- +*** Testing usort() : usage variation *** + +-- Anonymous 'cmp_function' with parameters passed by value -- +bool(true) +array(5) { + [0]=> + int(-70) + [1]=> + int(3) + [2]=> + int(24) + [3]=> + int(90) + [4]=> + int(100) +} + +-- Anonymous 'cmp_function' with parameters passed by reference -- + +Warning: {closure:%s:%d}(): Argument #1 ($value1) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #2 ($value2) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #1 ($value1) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #2 ($value2) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #1 ($value1) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #2 ($value2) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #1 ($value1) must be passed by reference, value given in %s on line %d + +Warning: {closure:%s:%d}(): Argument #2 ($value2) must be passed by reference, value given in %s on line %d +bool(true) +array(4) { + [0]=> + string(5) "Apple" + [1]=> + string(6) "Banana" + [2]=> + string(5) "Mango" + [3]=> + string(9) "Pineapple" +} diff --git a/tests/std/array/usort_variation8.phpt b/tests/std/array/usort_variation8.phpt new file mode 100644 index 00000000..2775e097 --- /dev/null +++ b/tests/std/array/usort_variation8.phpt @@ -0,0 +1,60 @@ +--TEST-- +Test usort() function : usage variations - use built in functions as $cmp_function arg +--FILE-- + "Banana", "m" => "Mango", "a" => "apple", + "p" => "Pineapple", "o" => "orange"); + +// Testing library functions as comparison function +echo "\n-- Testing usort() with built-in 'cmp_function': strcasecmp() --\n"; +$temp_array1 = $array_arg; +var_dump( usort($temp_array1, 'strcasecmp') ); +var_dump($temp_array1); + +echo "\n-- Testing usort() with built-in 'cmp_function': strcmp() --\n"; +$temp_array2 = $array_arg; +var_dump( usort($temp_array2, 'strcmp') ); +var_dump($temp_array2); + +?> +--EXPECT-- +*** Testing usort() : usage variation *** + +-- Testing usort() with built-in 'cmp_function': strcasecmp() -- +bool(true) +array(5) { + [0]=> + string(5) "apple" + [1]=> + string(6) "Banana" + [2]=> + string(5) "Mango" + [3]=> + string(6) "orange" + [4]=> + string(9) "Pineapple" +} + +-- Testing usort() with built-in 'cmp_function': strcmp() -- +bool(true) +array(5) { + [0]=> + string(6) "Banana" + [1]=> + string(5) "Mango" + [2]=> + string(9) "Pineapple" + [3]=> + string(5) "apple" + [4]=> + string(6) "orange" +} diff --git a/tests/std/array/usort_variation9.phpt b/tests/std/array/usort_variation9.phpt new file mode 100644 index 00000000..a28bb4a4 --- /dev/null +++ b/tests/std/array/usort_variation9.phpt @@ -0,0 +1,51 @@ +--TEST-- +Test usort() function : usage variations - referenced variables +--SKIPIF-- + +--FILE-- + $value2) { + return 1; + } else { + return -1; + } +} +function main() +{ + /* + * Pass an array of referenced variables as $array_arg to test behaviour + */ + echo "*** Testing usort() : usage variation ***\n"; + // different variables which are used as elements of $array_arg + $value1 = -5; + $value2 = 100; + $value3 = 0; + $value4 =& $value1; + // array_args an array containing elements with reference variables + $array_arg = array(0 => 10, 1 => &$value4, 2 => &$value2, 3 => 200, 4 => &$value3); + echo "\n-- Sorting \$array_arg containing different references --\n"; + var_dump(usort($array_arg, 'cmp_function')); + var_dump($array_arg); +} +?> +--EXPECT-- +*** Testing usort() : usage variation *** + +-- Sorting $array_arg containing different references -- +bool(true) +array(5) { + [0]=> + &int(-5) + [1]=> + &int(0) + [2]=> + int(10) + [3]=> + &int(100) + [4]=> + int(200) +} diff --git a/tests/std/array/var_export.phpt b/tests/std/array/var_export.phpt new file mode 100644 index 00000000..5c23ad26 --- /dev/null +++ b/tests/std/array/var_export.phpt @@ -0,0 +1,13 @@ +--TEST-- +var_export() and objects with numeric indexes properties +--FILE-- + "bar"); +var_export($a); +?> +--EXPECT-- +(object) array( + '0' => 1, + '1' => 3, + 'foo' => 'bar', +) diff --git a/tests/std/array/var_export2.phpt b/tests/std/array/var_export2.phpt new file mode 100644 index 00000000..6db44d5c --- /dev/null +++ b/tests/std/array/var_export2.phpt @@ -0,0 +1,13 @@ +--TEST-- +var_export() and empty array keys +--FILE-- + 'null', "" => 'empty', "0" => 'nul'); +var_export($a); +?> +--EXPECT-- +array ( + '' . "\0" . '' => 'null', + '' => 'empty', + 0 => 'nul', +) diff --git a/tests/std/array/var_export3.phpt b/tests/std/array/var_export3.phpt new file mode 100644 index 00000000..76c40155 --- /dev/null +++ b/tests/std/array/var_export3.phpt @@ -0,0 +1,25 @@ +--TEST-- +var_export() and classes +--FILE-- +mann = 42; + $this->kvinne = 43; + } +} +function main() +{ + $kake = new kake(); + var_export($kake); +} +?> +--EXPECT-- +\kake::__set_state(array( + 'mann' => 42, + 'kvinne' => 43, +)) From ac0d7f61510604938a86c893c056100f0ca4383a Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 11:41:16 +0800 Subject: [PATCH 20/37] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E5=BF=85?= =?UTF-8?q?=E9=9C=80=E5=8F=82=E6=95=B0=E8=AE=A1=E6=95=B0=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在生成包装函数参数时添加必需参数数量验证 - 实现参数不足时抛出 ArgumentCountError 异常 - 为可空参数移除默认 null 值传递逻辑 - 添加测试用例验证可空参数无默认值时仍需传入 - 生成详细的错误消息包含函数名和期望参数数量 --- src/Php/Translator.php | 30 +++++++++++++++---- .../nullable-required-param-check.phpt | 23 ++++++++++++++ 2 files changed, 48 insertions(+), 5 deletions(-) create mode 100644 tests/aot/type_decl/nullable-required-param-check.phpt diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 70ab0473..9439af7b 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -2850,10 +2850,13 @@ CODE; return $code; } - protected function genWrapperFunctionArgs(string $fn, FunctionDef $functionDef): string + protected function genWrapperFunctionArgs(string $fn, FunctionDef $functionDef, string $displayName): string { $cppCode = ''; $callParams = ''; + if ($functionDef->argCountRequired > 0) { + $cppCode .= $this->genWrapperRequiredArgCountCheck($functionDef, $displayName); + } foreach ($functionDef->argInfoList as $k => $argInfo) { $var = 'arg_' . $argInfo->name; if ($argInfo->variadic) { @@ -2874,8 +2877,6 @@ CODE; } else { if ($argInfo->byRef) { $argExpr = 'php::getCallArgByRef(' . $k . ')'; - } elseif ($argInfo->nullable) { - $argExpr = 'php::getCallArg(' . $k . ', php::null)'; } else { $argExpr = 'php::getCallArg(' . $k . ')'; } @@ -2905,13 +2906,32 @@ CODE; return $cppCode; } + private function genWrapperRequiredArgCountCheck(FunctionDef $functionDef, string $displayName): string + { + $required = $functionDef->argCountRequired; + $message = 'php::concat({' + . 'php::Str(' . $this->genCharPtr('Too few arguments to function ' . $displayName . '(), ', true) . '), ' + . 'php::toString(php::getCallArgNum()), ' + . 'php::Str(' . $this->genCharPtr(' passed and exactly ' . $required . ' expected', true) . ')' + . '})'; + + $code = $this->getIndent() . 'if (UNEXPECTED(php::getCallArgNum() < ' . $required . ')) {' . PHP_EOL; + $this->indentLevel++; + $code .= $this->getIndent() . 'php::throwException(zend_ce_argument_count_error, (' . $message . ').toCString());' . PHP_EOL; + $code .= $this->getIndent() . 'return;' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + + return $code; + } + protected function genMethodWrapper(ClassDef $classDef, MethodDef $methodDef): string { $name = $classDef->getNamespacedName(); $cppCode = 'ZEND_METHOD(' . $name . ', ' . $methodDef->name . '){' . PHP_EOL; $cppCode .= $this->getIndent() . self::TYPE_OBJECT . ' this_(&execute_data->This);' . PHP_EOL; $fn = self::PREFIX . $this->getNativeMethodName($classDef, $methodDef); - $cppCode .= $this->genWrapperFunctionArgs($fn, $methodDef->functionDef); + $cppCode .= $this->genWrapperFunctionArgs($fn, $methodDef->functionDef, $classDef->getNamespacedName(false) . '::' . $methodDef->name); return $cppCode; } @@ -3733,7 +3753,7 @@ CODE; $name = $this->escapeZendFnName($functionDef->getNamespacedName()); $cppCode = 'ZEND_FUNCTION(' . $name . '){' . PHP_EOL; $fn = self::PREFIX . $this->getNativeName($functionDef->name, $functionDef->namespace); - $cppCode .= $this->genWrapperFunctionArgs($fn, $functionDef); + $cppCode .= $this->genWrapperFunctionArgs($fn, $functionDef, $functionDef->getNamespacedName()); return $cppCode; } diff --git a/tests/aot/type_decl/nullable-required-param-check.phpt b/tests/aot/type_decl/nullable-required-param-check.phpt new file mode 100644 index 00000000..e9bc531e --- /dev/null +++ b/tests/aot/type_decl/nullable-required-param-check.phpt @@ -0,0 +1,23 @@ +--TEST-- +Nullable parameter without default is still required +--FILE-- +getMessage()); + } +} +?> +--EXPECT-- +string(18) "ArgumentCountError" +string(84) "Too few arguments to function expect_nullable_int(), 0 passed and exactly 1 expected" From 90f9da03689878434579c5620b0b4db5ad22840b Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 11:50:47 +0800 Subject: [PATCH 21/37] =?UTF-8?q?feat(php):=20=E4=B8=BA=E9=97=AD=E5=8C=85?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8=E6=B7=BB=E5=8A=A0=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E9=AA=8C=E8=AF=81=E5=92=8C=E5=8F=AF=E5=8F=98=E5=8F=82=E6=95=B0?= =?UTF-8?q?=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现了必需参数数量计算和参数计数验证逻辑 - 添加了参数不足时抛出异常的功能 - 支持可变参数的循环获取和数组构建 - 实现了参数默认值的条件解析处理 - 集成了参数类型检查和引用参数错误处理 --- src/Php/Generator/ClosureGenerator.php | 35 +++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/src/Php/Generator/ClosureGenerator.php b/src/Php/Generator/ClosureGenerator.php index 06193d73..c2654141 100644 --- a/src/Php/Generator/ClosureGenerator.php +++ b/src/Php/Generator/ClosureGenerator.php @@ -38,12 +38,45 @@ trait ClosureGenerator $this->context->inClosure = true; $this->indentLevel++; + $requiredArgCount = 0; + foreach ($params as $param) { + if ($param->variadic || $param->default !== null) { + break; + } + $requiredArgCount++; + } + if ($requiredArgCount > 0) { + $message = 'php::concat({' + . 'php::Str(' . $this->genCharPtr('Too few arguments to function {closure}(), ', true) . '), ' + . 'php::toString(php::getCallArgNum()), ' + . 'php::Str(' . $this->genCharPtr(' passed and exactly ' . $requiredArgCount . ' expected', true) . ')' + . '})'; + $code .= $this->getIndent() . 'if (UNEXPECTED(php::getCallArgNum() < ' . $requiredArgCount . ')) {' . PHP_EOL; + $this->indentLevel++; + $code .= $this->getIndent() . 'return php::throwException(zend_ce_argument_count_error, (' . $message . ').toCString());' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + } + foreach ($params as $i => $param) { if ($param->byRef) { $this->fatalError($expr, 'Closure cannot use reference parameter'); } $var = $this->parseIdentifier($param->var); - $code .= 'auto ' . $var . ' = php::getCallArg(' . $i . ');' . PHP_EOL; + if ($param->variadic) { + $code .= $this->getIndent() . self::TYPE_ARRAY . ' ' . $var . ';' . PHP_EOL; + $code .= $this->getIndent() . 'for (uint32_t i = ' . $i . '; i < php::getCallArgNum(); i++) {' . PHP_EOL; + $this->indentLevel++; + $code .= $this->getIndent() . $var . '.append(php::getCallArg(i));' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + $this->addArgument($var, self::TYPE_ARRAY); + continue; + } + $argExpr = $param->default === null + ? 'php::getCallArg(' . $i . ')' + : 'php::getCallArg(' . $i . ', ' . $this->parseParamDefaultValue($param->default) . ')'; + $code .= $this->getIndent() . 'auto ' . $var . ' = ' . $argExpr . ';' . PHP_EOL; $this->addArgument($var, self::TYPE_VAR); } From 91f70856629654e3c297ae558f25054d34d3f92b Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 11:59:25 +0800 Subject: [PATCH 22/37] =?UTF-8?q?feat(closure):=20=E4=B8=BA=E9=97=AD?= =?UTF-8?q?=E5=8C=85=E6=B7=BB=E5=8A=A0=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在ClosureGenerator中实现对nullable、union和intersection类型的返回值检查 - 为闭包参数添加运行时类型验证和错误提示 - 扩展CPP_RESERVED_NAMES数组,添加更多C++保留关键字 - 在FunctionContext中增加闭包返回类型检查相关属性 - 实现闭包参数和返回值的类型检查生成器方法 - 修复变量名转义逻辑,确保与PHPX关键字冲突的变量名被正确处理 --- src/Php/CompilerBase.php | 45 ++++++++- src/Php/Constants.php | 84 ++++++++++++---- src/Php/Context/FunctionContext.php | 4 + src/Php/Generator/ClosureGenerator.php | 36 +++++++ src/Php/Generator/TypeCheckGenerator.php | 117 ++++++++++++++++++++++- src/Php/Generator/Utils.php | 6 +- 6 files changed, 269 insertions(+), 23 deletions(-) diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 73608a11..733299df 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1632,6 +1632,13 @@ class CompilerBase extends \PhpAot\Core\Translator if ($v->expr === null) { if ($this->functionDef->returnType === self::TYPE_VOID and !$this->context->inClosure) { return 'return;'; + } elseif ($this->context->inClosure && $this->context->closureReturnTypeCheck) { + $tmpVar = $this->genTmpVarName(); + $this->addLocalVar($tmpVar, self::TYPE_VAR); + $code = $tmpVar . ' = ' . self::VALUE_NULL . ';' . PHP_EOL; + $code .= $this->genClosureReturnCheck($tmpVar); + $code .= $this->getIndent() . 'return ' . $tmpVar . ';'; + return $code; } elseif ($this->functionDef->returnTypeCheck && !$this->context->inClosure) { $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_VAR); @@ -1679,7 +1686,13 @@ class CompilerBase extends \PhpAot\Core\Translator $exprCode = $this->convertExprType($expr, $returnType, $type); // Union/nullable return type: always use tmpVar for runtime check - if ($this->functionDef->returnTypeCheck && !$this->context->inClosure) { + if ($this->context->inClosure && $this->context->closureReturnTypeCheck) { + $tmpVar = $this->genTmpVarName(); + $this->addLocalVar($tmpVar, self::TYPE_VAR); + $code = $tmpVar . ' = ' . $exprCode . ';' . PHP_EOL; + $code .= $this->genClosureReturnCheck($tmpVar); + $this->context->afterStmtLines[] = $this->getIndent() . 'return ' . $tmpVar . ';'; + } elseif ($this->functionDef->returnTypeCheck && !$this->context->inClosure) { $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_VAR); $code = $tmpVar . ' = ' . $exprCode . ';' . PHP_EOL; @@ -5845,6 +5858,14 @@ class CompilerBase extends \PhpAot\Core\Translator protected function genReturnCode(): string { + if ($this->context->inClosure && $this->context->closureReturnTypeCheck) { + $tmpVar = $this->genTmpVarName(); + $this->addLocalVar($tmpVar, self::TYPE_VAR); + $code = $tmpVar . ' = ' . self::VALUE_NULL . ';' . PHP_EOL; + $code .= $this->genClosureReturnCheck($tmpVar); + $code .= $this->getIndent() . 'return ' . $tmpVar . ';'; + return $code; + } if ($this->functionDef->returnType === self::TYPE_VOID) { return ''; } @@ -5903,9 +5924,25 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isCallExpr($expr->expr)) { $nativeCall = $expr->expr->getAttribute('nativeCall'); if ($nativeCall and $this->getFunction($nativeCall)->returnType === self::TYPE_VOID) { + if ($this->context->closureReturnTypeCheck) { + $tmpVar = $this->genTmpVarName(); + $this->addLocalVar($tmpVar, self::TYPE_VAR); + return $beforeCode . PHP_EOL . $code . ';' . PHP_EOL + . $tmpVar . ' = ' . self::VALUE_NULL . ';' . PHP_EOL + . $this->genClosureReturnCheck($tmpVar) + . $this->getIndent() . 'return ' . $tmpVar . ';'; + } return $beforeCode . PHP_EOL . $code . ';' . PHP_EOL . 'return ' . self::VALUE_NULL . ';'; } } + if ($this->context->closureReturnTypeCheck) { + $tmpVar = $this->genTmpVarName(); + $this->addLocalVar($tmpVar, self::TYPE_VAR); + return $beforeCode . PHP_EOL + . $tmpVar . ' = ' . $code . ';' . PHP_EOL + . $this->genClosureReturnCheck($tmpVar) + . $this->getIndent() . 'return ' . $tmpVar . ';'; + } return $beforeCode . PHP_EOL . 'return ' . $code . ';'; }; @@ -5917,7 +5954,11 @@ class CompilerBase extends \PhpAot\Core\Translator $cb = function () use ($expr) { $fnCode = $this->parseStmts($expr->stmts); if (!$this->isReturnStmtInLastLine($expr->stmts)) { - $fnCode .= 'return ' . self::VALUE_NULL . ';' . PHP_EOL; + if ($this->context->closureReturnTypeCheck) { + $fnCode .= $this->genReturnCode() . PHP_EOL; + } else { + $fnCode .= 'return ' . self::VALUE_NULL . ';' . PHP_EOL; + } } return $fnCode; }; diff --git a/src/Php/Constants.php b/src/Php/Constants.php index 5609f319..770a214e 100644 --- a/src/Php/Constants.php +++ b/src/Php/Constants.php @@ -11,53 +11,103 @@ namespace PhpAot\Php; class Constants { public const array CPP_RESERVED_NAMES = [ + 'alignas', + 'alignof', + 'and', + 'and_eq', + 'asm', 'auto', + 'bitand', + 'bitor', + 'bool', 'break', 'case', 'catch', + 'char', + 'char8_t', + 'char16_t', + 'char32_t', 'class', - 'struct', + 'compl', 'const', + 'consteval', + 'constexpr', + 'constinit', + 'const_cast', 'continue', + 'decltype', 'default', + 'delete', 'do', + 'double', + 'dynamic_cast', 'else', 'elseif', 'enum', + 'explicit', + 'export', 'extends', + 'extern', + 'false', 'final', 'finally', + 'float', 'for', + 'friend', 'function', 'global', + 'goto', 'if', - 'bool', + 'inline', 'int', - 'short', 'long', - 'unsigned', - 'void', - 'signed', - 'double', - 'float', - 'false', - 'for', - 'if', - 'int', + 'mutable', + 'namespace', 'new', + 'noexcept', + 'not', + 'not_eq', + 'nullptr', 'null', - 'var', - 'char', 'or', - 'and', + 'or_eq', + 'operator', 'private', 'protected', 'public', + 'register', + 'reinterpret_cast', + 'requires', 'return', + 'short', + 'signed', + 'sizeof', 'static', - 'pipe', + 'static_assert', + 'static_cast', + 'struct', + 'switch', 'template', - 'namespace', + 'this', + 'thread_local', + 'throw', + 'true', + 'try', + 'typedef', + 'typeid', + 'typename', + 'union', + 'unsigned', + 'using', + 'var', + 'virtual', + 'void', + 'volatile', + 'wchar_t', + 'while', + 'xor', + 'xor_eq', + 'pipe', 'errno', // Linux error code 'this_', // phpx keywords ]; diff --git a/src/Php/Context/FunctionContext.php b/src/Php/Context/FunctionContext.php index e344d411..6f3c145b 100644 --- a/src/Php/Context/FunctionContext.php +++ b/src/Php/Context/FunctionContext.php @@ -50,6 +50,8 @@ class FunctionContext public array $arguments = []; public bool $inLoop = false; public bool $inClosure = false; + public ?array $closureReturnTypeCheck = null; + public string $closureReturnTypeStr = ''; /** True if any break N (N > 1) appears in this function. */ public bool $hasMultiLevelBreak = false; @@ -92,6 +94,8 @@ class FunctionContext $this->scopeLevel = 0; $this->inLoop = false; $this->inClosure = false; + $this->closureReturnTypeCheck = null; + $this->closureReturnTypeStr = ''; $this->inAssignExpr = false; } diff --git a/src/Php/Generator/ClosureGenerator.php b/src/Php/Generator/ClosureGenerator.php index c2654141..9ee09f9a 100644 --- a/src/Php/Generator/ClosureGenerator.php +++ b/src/Php/Generator/ClosureGenerator.php @@ -8,7 +8,12 @@ namespace PhpAot\Php\Generator; +use PhpAot\Php\ArgInfo; use PhpAot\Php\Context\FunctionContext; +use PhpParser\Node; +use PhpParser\Node\IntersectionType; +use PhpParser\Node\NullableType; +use PhpParser\Node\UnionType; use PhpParser\NodeAbstract; trait ClosureGenerator @@ -36,6 +41,13 @@ trait ClosureGenerator $this->context = new FunctionContext(); $this->context->inClosure = true; + if ($expr->returnType instanceof NullableType || $expr->returnType instanceof UnionType || $expr->returnType instanceof IntersectionType) { + $returnTypeInfo = $this->buildTypeCheckFromNode($expr->returnType); + if (!empty($returnTypeInfo['check'])) { + $this->context->closureReturnTypeCheck = $returnTypeInfo['check']; + $this->context->closureReturnTypeStr = $returnTypeInfo['typeStr']; + } + } $this->indentLevel++; $requiredArgCount = 0; @@ -71,6 +83,7 @@ trait ClosureGenerator $this->indentLevel--; $code .= $this->getIndent() . '}' . PHP_EOL; $this->addArgument($var, self::TYPE_ARRAY); + $code .= $this->genClosureParamTypeCheck($param, $var, $i, true); continue; } $argExpr = $param->default === null @@ -78,6 +91,7 @@ trait ClosureGenerator : 'php::getCallArg(' . $i . ', ' . $this->parseParamDefaultValue($param->default) . ')'; $code .= $this->getIndent() . 'auto ' . $var . ' = ' . $argExpr . ';' . PHP_EOL; $this->addArgument($var, self::TYPE_VAR); + $code .= $this->genClosureParamTypeCheck($param, $var, $i, false); } foreach ($uses as $i => $useItem) { @@ -149,4 +163,26 @@ trait ClosureGenerator return $code; } + + private function genClosureParamTypeCheck(Node\Param $param, string $var, int $index, bool $variadic): string + { + if (!$param->type instanceof NullableType && !$param->type instanceof UnionType && !$param->type instanceof IntersectionType) { + return ''; + } + + $typeInfo = $this->buildTypeCheckFromNode($param->type); + if (empty($typeInfo['check'])) { + return ''; + } + + $argInfo = new ArgInfo(); + $argInfo->name = $var; + $argInfo->type = self::TYPE_VAR; + $argInfo->variadic = $variadic; + $argInfo->typeCheck = $typeInfo['check']; + $argInfo->typeStr = $typeInfo['typeStr']; + $argInfo->typeNode = $param->type; + + return $this->genClosureParamCheck($argInfo, $index); + } } diff --git a/src/Php/Generator/TypeCheckGenerator.php b/src/Php/Generator/TypeCheckGenerator.php index 242b44c0..990ad37f 100644 --- a/src/Php/Generator/TypeCheckGenerator.php +++ b/src/Php/Generator/TypeCheckGenerator.php @@ -265,10 +265,11 @@ trait TypeCheckGenerator protected function genUnionParamTypeErrorExpr(ArgInfo $argInfo, string $valueExpr, string $argNoExpr): string { $fnName = $this->getTypeCheckCallableName(); + $paramName = $this->unescapeVarName($argInfo->name); return 'php::concat({' . 'php::Str(' . $this->genCharPtr($fnName . '(): Argument #', true) . '), ' . 'php::toString(' . $argNoExpr . '), ' - . 'php::Str(' . $this->genCharPtr(' ($' . $argInfo->name . ') must be of type ', true) . '), ' + . 'php::Str(' . $this->genCharPtr(' ($' . $paramName . ') must be of type ', true) . '), ' . 'php::Str(' . $this->genCharPtr($argInfo->typeStr, true) . '), ' . 'php::Str(", "), ' . $valueExpr . '.typeStr(), ' @@ -310,4 +311,118 @@ trait TypeCheckGenerator return $code; } + protected function genClosureParamCheck(ArgInfo $argInfo, int $argIndex): string + { + if (empty($argInfo->typeCheck)) { + return ''; + } + + if ($argInfo->variadic) { + return $this->genClosureVariadicParamCheck($argInfo, $argIndex); + } + + $conditions = []; + foreach ($argInfo->typeCheck as $entry) { + $cond = $this->genSingleTypeCondition($argInfo->name, $entry); + if ($cond !== '') { + $conditions[] = $cond; + } + } + if (empty($conditions)) { + return ''; + } + + $orExpr = implode(' || ', $conditions); + $msgExpr = $this->genClosureParamTypeErrorExpr($argInfo, $argInfo->name, (string) ($argIndex + 1)); + + $code = $this->getIndent() . 'if (UNEXPECTED(!(' . $orExpr . '))) {' . PHP_EOL; + $this->indentLevel++; + $code .= $this->getIndent() . 'return php::throwException(zend_ce_type_error, (' . $msgExpr . ').toCString());' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + + return $code; + } + + protected function genClosureVariadicParamCheck(ArgInfo $argInfo, int $argIndex): string + { + $valueVar = $this->genTmpVarName(); + $iterVar = $this->genTmpVarName(); + $argNoVar = $this->genTmpVarName(); + + $conditions = []; + foreach ($argInfo->typeCheck as $entry) { + $cond = $this->genSingleTypeCondition($valueVar, $entry); + if ($cond !== '') { + $conditions[] = $cond; + } + } + if (empty($conditions)) { + return ''; + } + + $orExpr = implode(' || ', $conditions); + $msgExpr = $this->genClosureParamTypeErrorExpr($argInfo, $valueVar, $argNoVar); + + $code = $this->getIndent() . 'for (auto ' . $iterVar . ' = ' . $argInfo->name . '.begin(); ' . $iterVar . ' != ' . $argInfo->name . '.end(); ++' . $iterVar . ') {' . PHP_EOL; + $this->indentLevel++; + $code .= $this->getIndent() . self::TYPE_VAR . ' ' . $valueVar . ' = ' . $iterVar . '.value();' . PHP_EOL; + $code .= $this->getIndent() . self::TYPE_INT . ' ' . $argNoVar . ' = ' . ($argIndex + 1) . ' + ' . $iterVar . '.index();' . PHP_EOL; + $code .= $this->getIndent() . 'if (UNEXPECTED(!(' . $orExpr . '))) {' . PHP_EOL; + $this->indentLevel++; + $code .= $this->getIndent() . 'return php::throwException(zend_ce_type_error, (' . $msgExpr . ').toCString());' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + + return $code; + } + + protected function genClosureParamTypeErrorExpr(ArgInfo $argInfo, string $valueExpr, string $argNoExpr): string + { + $paramName = $this->unescapeVarName($argInfo->name); + return 'php::concat({' + . 'php::Str(' . $this->genCharPtr('{closure}(): Argument #', true) . '), ' + . 'php::toString(' . $argNoExpr . '), ' + . 'php::Str(' . $this->genCharPtr(' ($' . $paramName . ') must be of type ', true) . '), ' + . 'php::Str(' . $this->genCharPtr($argInfo->typeStr, true) . '), ' + . 'php::Str(", "), ' + . $valueExpr . '.typeStr(), ' + . 'php::Str(" given")' + . '})'; + } + + protected function genClosureReturnCheck(string $varName): string + { + $typeCheck = $this->context->closureReturnTypeCheck; + if (empty($typeCheck)) { + return ''; + } + + $conditions = []; + foreach ($typeCheck as $entry) { + $cond = $this->genSingleTypeCondition($varName, $entry); + if ($cond !== '') { + $conditions[] = $cond; + } + } + if (empty($conditions)) { + return ''; + } + + $orExpr = implode(' || ', $conditions); + $typeStr = $this->context->closureReturnTypeStr; + $msgExpr = 'php::concat(php::concat(php::Str(' . $this->genCharPtr('{closure}', true) . ' "(): Return value must be of type " ' + . $this->genCharPtr($typeStr, true) . ' ", "), ' . $varName . '.typeStr()), php::Str(" given"))'; + + $code = $this->getIndent() . 'if (UNEXPECTED(!(' . $orExpr . '))) {' . PHP_EOL; + $this->indentLevel++; + $code .= $this->getIndent() . 'return php::throwException(zend_ce_type_error, (' . $msgExpr . ').toCString());' . PHP_EOL; + $this->indentLevel--; + $code .= $this->getIndent() . '}' . PHP_EOL; + + return $code; + } + } diff --git a/src/Php/Generator/Utils.php b/src/Php/Generator/Utils.php index 284bcf8f..85fd3fa7 100644 --- a/src/Php/Generator/Utils.php +++ b/src/Php/Generator/Utils.php @@ -62,12 +62,12 @@ trait Utils protected function escapeVarName(string $name): string { - if (in_array($name, Constants::CPP_RESERVED_NAMES)) { - return '_php__var__' . $name; - } if ($name === 'this') { return 'this_'; } + if (in_array($name, Constants::CPP_RESERVED_NAMES, true)) { + return '_php__var__' . $name; + } return $name; } From 0bfa2869c59241e5b2fb8020e3aec6cfbcd81419 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 12:09:59 +0800 Subject: [PATCH 23/37] =?UTF-8?q?feat(compiler):=20=E6=94=AF=E6=8C=81?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E5=8F=82=E6=95=B0=E5=92=8C=E6=8F=90=E5=8D=87?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了对函数和构造函数中命名参数的支持 - 实现了提升属性(Property Promotion)功能 - 新增了对 C++ 保留关键字作为参数名的支持 - 完善了闭包类型检查和参数验证逻辑 - 增加了内部函数调用的命名参数验证 - 优化了参数类型检查和错误提示信息 - 添加了相关测试用例验证功能正确性 --- phpunit/src/FunctionTest.php | 10 +++ src/Php/Analysis/SsaBuilder.php | 5 +- src/Php/ArgInfo.php | 1 + src/Php/CompilerBase.php | 80 +++++++++++++++++- src/Php/Generator/ClosureGenerator.php | 8 +- src/Php/Generator/PropertyPromotion.php | 3 +- src/Php/Generator/TypeCheckGenerator.php | 4 +- src/Php/Optimizer/FuncCallOptimizer.php | 6 ++ src/Php/Preprocessor.php | 12 ++- .../closure/closure-composite-type-check.phpt | 82 +++++++++++++++++++ tests/aot/closure/closure-param-defaults.phpt | 41 ++++++++++ tests/aot/functions/internal-named-args.phpt | 16 ++++ tests/aot/named_args/007.phpt | 37 +++++++++ .../aot/optimizations/reserved-param-ssa.phpt | 21 +++++ 14 files changed, 311 insertions(+), 15 deletions(-) create mode 100644 tests/aot/closure/closure-composite-type-check.phpt create mode 100644 tests/aot/closure/closure-param-defaults.phpt create mode 100644 tests/aot/functions/internal-named-args.phpt create mode 100644 tests/aot/named_args/007.phpt create mode 100644 tests/aot/optimizations/reserved-param-ssa.phpt diff --git a/phpunit/src/FunctionTest.php b/phpunit/src/FunctionTest.php index d04e7e4b..2209d56f 100644 --- a/phpunit/src/FunctionTest.php +++ b/phpunit/src/FunctionTest.php @@ -27,4 +27,14 @@ class FunctionTest extends \BaseTest $this->exec('Named argument `value` overwrites previous argument', 'native-call-named-overwrites-positional.php'); } + public function testInternalCallUnknownNamedArgument() + { + $this->exec('Unknown named argument `foo`', 'internal-call-unknown-named-arg.php'); + } + + public function testInternalCallMissingRequiredNamedArgument() + { + $this->exec('Named argument `replace` is missing default value', 'internal-call-missing-required-named-arg.php'); + } + } diff --git a/src/Php/Analysis/SsaBuilder.php b/src/Php/Analysis/SsaBuilder.php index abf5bb23..46ea8a1c 100644 --- a/src/Php/Analysis/SsaBuilder.php +++ b/src/Php/Analysis/SsaBuilder.php @@ -206,8 +206,9 @@ class SsaBuilder private array $argInfoList = [] ) { foreach ($this->argInfoList as $argInfo) { - $this->params[] = $argInfo->name; - $this->paramByRef[$argInfo->name] = $argInfo->byRef ?? false; + $paramName = $argInfo->phpName ?: $argInfo->name; + $this->params[] = $paramName; + $this->paramByRef[$paramName] = $argInfo->byRef ?? false; } } diff --git a/src/Php/ArgInfo.php b/src/Php/ArgInfo.php index 70902959..93843742 100644 --- a/src/Php/ArgInfo.php +++ b/src/Php/ArgInfo.php @@ -15,6 +15,7 @@ use PhpParser\NodeAbstract; class ArgInfo { public string $name; + public string $phpName = ''; public string $type; public string $default = ''; public ?ArrayInitPlan $arrayInitPlan = null; diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 733299df..af79a610 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1873,7 +1873,7 @@ class CompilerBase extends \PhpAot\Core\Translator { $argNameIndex = []; foreach ($functionDef->argInfoList as $k => $argInfo) { - $argNameIndex[$argInfo->name] = $k; + $argNameIndex[$argInfo->phpName ?: $this->unescapeVarName($argInfo->name)] = $k; } return $argNameIndex; } @@ -2841,6 +2841,7 @@ class CompilerBase extends \PhpAot\Core\Translator if (!$ref) { return; } + $this->validateInternalNamedCallArgs($ref, $expr->args); $minArgs = $ref->getNumberOfRequiredParameters(); $maxArgs = $ref->getNumberOfParameters(); $actualArgCount = count($expr->args); @@ -2852,6 +2853,77 @@ class CompilerBase extends \PhpAot\Core\Translator } } + protected function validateInternalNamedCallArgs(\ReflectionFunctionAbstract $ref, array $callArgs): void + { + $hasNamedArg = false; + $seenNamedArgs = []; + $providedArgIndexes = []; + $argNameIndex = []; + $requiredArgIndexes = []; + $variadicArgIndex = null; + + foreach ($ref->getParameters() as $i => $param) { + $argNameIndex[$param->getName()] = $i; + if (!$param->isOptional() && !$param->isVariadic()) { + $requiredArgIndexes[$i] = $param->getName(); + } + if ($param->isVariadic()) { + $variadicArgIndex = $i; + } + } + + foreach ($callArgs as $i => $arg) { + if ($this->isPlaceholderExpr($arg)) { + continue; + } + if ($arg->name === null) { + if ($hasNamedArg) { + $this->fatalError($arg, 'Cannot use positional argument after named argument'); + } + $providedArgIndexes[$i] = true; + continue; + } + if (!$this->isIdExpr($arg->name)) { + $this->fatalError($arg, 'Named argument must be a string'); + } + + $argName = $arg->name->name; + if (isset($seenNamedArgs[$argName])) { + $this->fatalError($arg, "Duplicate named argument `{$argName}`"); + } + if (!array_key_exists($argName, $argNameIndex)) { + if ($variadicArgIndex === null) { + $this->fatalError($arg, "Unknown named argument `{$argName}`"); + } + $seenNamedArgs[$argName] = true; + $hasNamedArg = true; + continue; + } + + $argIndex = $argNameIndex[$argName]; + if ($variadicArgIndex !== null && $argIndex === $variadicArgIndex) { + $seenNamedArgs[$argName] = true; + $hasNamedArg = true; + continue; + } + if (isset($providedArgIndexes[$argIndex])) { + $this->fatalError($arg, "Named argument `{$argName}` overwrites previous argument"); + } + + $seenNamedArgs[$argName] = true; + $providedArgIndexes[$argIndex] = true; + $hasNamedArg = true; + } + + if ($hasNamedArg) { + foreach ($requiredArgIndexes as $index => $name) { + if (!isset($providedArgIndexes[$index])) { + $this->fatalError($callArgs[array_key_last($callArgs)] ?? null, "Named argument `{$name}` is missing default value"); + } + } + } + } + protected function parseFuncCall(Expr\FuncCall $expr): string { if ($this->isVarExpr($expr->name)) { @@ -2954,7 +3026,8 @@ class CompilerBase extends \PhpAot\Core\Translator break; } } - $this->fatalError($errorNode ?? reset($callArgs), 'Named argument `' . $argInfo->name . '` is missing default value'); + $argName = $argInfo->phpName ?: $this->unescapeVarName($argInfo->name); + $this->fatalError($errorNode ?? reset($callArgs), 'Named argument `' . $argName . '` is missing default value'); } $args[$k] = new Node\Arg($argInfo->defaultValue); } @@ -3891,7 +3964,8 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isTypedObject($object)) { $class = $this->getObjectType($object); if ($class and $argInfo->class and !$this->isInheritedFrom($class, $argInfo->class)) { - $this->fatalError($arg, "Argument `{$argInfo->name}` must be an instance of `{$argInfo->class}`, `{$class}` given"); + $argName = $argInfo->phpName ?: $this->unescapeVarName($argInfo->name); + $this->fatalError($arg, "Argument `{$argName}` must be an instance of `{$argInfo->class}`, `{$class}` given"); } } } diff --git a/src/Php/Generator/ClosureGenerator.php b/src/Php/Generator/ClosureGenerator.php index 9ee09f9a..401a9523 100644 --- a/src/Php/Generator/ClosureGenerator.php +++ b/src/Php/Generator/ClosureGenerator.php @@ -75,6 +75,7 @@ trait ClosureGenerator $this->fatalError($expr, 'Closure cannot use reference parameter'); } $var = $this->parseIdentifier($param->var); + $phpName = is_string($param->var->name) ? $param->var->name : $this->unescapeVarName($var); if ($param->variadic) { $code .= $this->getIndent() . self::TYPE_ARRAY . ' ' . $var . ';' . PHP_EOL; $code .= $this->getIndent() . 'for (uint32_t i = ' . $i . '; i < php::getCallArgNum(); i++) {' . PHP_EOL; @@ -83,7 +84,7 @@ trait ClosureGenerator $this->indentLevel--; $code .= $this->getIndent() . '}' . PHP_EOL; $this->addArgument($var, self::TYPE_ARRAY); - $code .= $this->genClosureParamTypeCheck($param, $var, $i, true); + $code .= $this->genClosureParamTypeCheck($param, $var, $phpName, $i, true); continue; } $argExpr = $param->default === null @@ -91,7 +92,7 @@ trait ClosureGenerator : 'php::getCallArg(' . $i . ', ' . $this->parseParamDefaultValue($param->default) . ')'; $code .= $this->getIndent() . 'auto ' . $var . ' = ' . $argExpr . ';' . PHP_EOL; $this->addArgument($var, self::TYPE_VAR); - $code .= $this->genClosureParamTypeCheck($param, $var, $i, false); + $code .= $this->genClosureParamTypeCheck($param, $var, $phpName, $i, false); } foreach ($uses as $i => $useItem) { @@ -164,7 +165,7 @@ trait ClosureGenerator return $code; } - private function genClosureParamTypeCheck(Node\Param $param, string $var, int $index, bool $variadic): string + private function genClosureParamTypeCheck(Node\Param $param, string $var, string $phpName, int $index, bool $variadic): string { if (!$param->type instanceof NullableType && !$param->type instanceof UnionType && !$param->type instanceof IntersectionType) { return ''; @@ -177,6 +178,7 @@ trait ClosureGenerator $argInfo = new ArgInfo(); $argInfo->name = $var; + $argInfo->phpName = $phpName; $argInfo->type = self::TYPE_VAR; $argInfo->variadic = $variadic; $argInfo->typeCheck = $typeInfo['check']; diff --git a/src/Php/Generator/PropertyPromotion.php b/src/Php/Generator/PropertyPromotion.php index 1ef954de..edea815e 100644 --- a/src/Php/Generator/PropertyPromotion.php +++ b/src/Php/Generator/PropertyPromotion.php @@ -15,7 +15,8 @@ trait PropertyPromotion protected function genPropertyPromotion(ArgInfo $argInfo): string { $code = ''; - $code .= 'this_.setProperty(' . $this->genCharPtr($argInfo->name) . ', ' . $argInfo->name . ')'; + $propertyName = $argInfo->phpName ?: $this->unescapeVarName($argInfo->name); + $code .= 'this_.setProperty(' . $this->genCharPtr($propertyName) . ', ' . $argInfo->name . ')'; $code .= ";\n"; return $code; } diff --git a/src/Php/Generator/TypeCheckGenerator.php b/src/Php/Generator/TypeCheckGenerator.php index 990ad37f..c0ee0699 100644 --- a/src/Php/Generator/TypeCheckGenerator.php +++ b/src/Php/Generator/TypeCheckGenerator.php @@ -265,7 +265,7 @@ trait TypeCheckGenerator protected function genUnionParamTypeErrorExpr(ArgInfo $argInfo, string $valueExpr, string $argNoExpr): string { $fnName = $this->getTypeCheckCallableName(); - $paramName = $this->unescapeVarName($argInfo->name); + $paramName = $argInfo->phpName ?: $this->unescapeVarName($argInfo->name); return 'php::concat({' . 'php::Str(' . $this->genCharPtr($fnName . '(): Argument #', true) . '), ' . 'php::toString(' . $argNoExpr . '), ' @@ -381,7 +381,7 @@ trait TypeCheckGenerator protected function genClosureParamTypeErrorExpr(ArgInfo $argInfo, string $valueExpr, string $argNoExpr): string { - $paramName = $this->unescapeVarName($argInfo->name); + $paramName = $argInfo->phpName ?: $this->unescapeVarName($argInfo->name); return 'php::concat({' . 'php::Str(' . $this->genCharPtr('{closure}(): Argument #', true) . '), ' . 'php::toString(' . $argNoExpr . '), ' diff --git a/src/Php/Optimizer/FuncCallOptimizer.php b/src/Php/Optimizer/FuncCallOptimizer.php index f0b9a08d..9a82847c 100644 --- a/src/Php/Optimizer/FuncCallOptimizer.php +++ b/src/Php/Optimizer/FuncCallOptimizer.php @@ -195,6 +195,12 @@ trait FuncCallOptimizer protected function parseFuncCallWithOptimizer(string $name, Node\Expr\FuncCall $expr): string|false { + foreach ($expr->args as $arg) { + if ($arg instanceof Node\Arg && $arg->name !== null) { + return false; + } + } + $config = $this->getFuncCallConfig()[$name] ?? null; if ($config === null) { return false; diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index feff1478..13097bb8 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -249,21 +249,25 @@ class Preprocessor extends CompilerBase $last = array_key_last($params); foreach ($params as $i => $param) { + if (!is_string($param->var->name)) { + $this->fatalError($param, 'Parameter name must be a string'); + } + $phpName = $param->var->name; + $name = $this->escapeVarName($phpName); // .stub 存根定义 C++ Native 函数,必须设置函数的参数类型 if ($this->stubFile and !$param->type) { - throw new \RuntimeException('No type for ' . $this->parseIdentifier($param->var)); + throw new \RuntimeException('No type for ' . $phpName); } // 构造方法属性定义语法(Constructor Property Promotion) if ($param->isPromoted()) { if (!$this->classDef or !$this->methodDef or $this->methodDef->name !== '__construct') { $this->fatalError($param, 'Promoted properties are not supported'); } - $name = $this->parseIdentifier($param->var); $nullable = $param->type instanceof NullableType; // Promoted property defaults belong to the constructor parameter, // not to the property default table. The property itself must stay // uninitialized until __construct assigns it. - $this->addClassProperty($name, $param->flags, $param->type, null, $nullable, $param); + $this->addClassProperty($phpName, $param->flags, $param->type, null, $nullable, $param); } if ($param->variadic) { if ($i !== $last) { @@ -272,13 +276,13 @@ class Preprocessor extends CompilerBase $this->fatalError($param, 'Variadic parameters cannot be passed by reference'); } } - $name = $this->parseIdentifier($param->var); if ($this->method and $name === 'this_') { $this->fatalError($param, 'Cannot use `$this` as parameter of class method'); } $argInfo = new ArgInfo(); $type = $this->parseParameterType($param, $argInfo, $name); $argInfo->name = $name; + $argInfo->phpName = $phpName; $argInfo->type = $type; $argInfo->byRef = $param->byRef; $argInfo->variadic = $param->variadic; diff --git a/tests/aot/closure/closure-composite-type-check.phpt b/tests/aot/closure/closure-composite-type-check.phpt new file mode 100644 index 00000000..457acac4 --- /dev/null +++ b/tests/aot/closure/closure-composite-type-check.phpt @@ -0,0 +1,82 @@ +--TEST-- +Closure composite type declarations use runtime type checks +--ENV-- +USE_ZEND_ALLOC=0 +--FILE-- +getMessage(), "\n"; + } + try { + $union([]); + } catch (\TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + $variadic(1, []); + } catch (\TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + $intersection(new ClosureOnlyA()); + } catch (\TypeError $e) { + echo $e->getMessage(), "\n"; + } + try { + $returnUnion([]); + } catch (\TypeError $e) { + echo $e->getMessage(), "\n"; + } +} +?> +--EXPECT-- +NULL +string(2) "ok" +array(2) { + [0]=> + int(1) + [1]=> + string(3) "two" +} +string(11) "ClosureBoth" +int(42) +{closure}(): Argument #1 ($value) must be of type ?int, string given +{closure}(): Argument #1 ($union) must be of type int|string, array given +{closure}(): Argument #2 ($values) must be of type int|string, array given +{closure}(): Argument #1 ($value) must be of type ClosureIA&ClosureIB, object given +{closure}(): Return value must be of type int|string, array given diff --git a/tests/aot/closure/closure-param-defaults.phpt b/tests/aot/closure/closure-param-defaults.phpt new file mode 100644 index 00000000..51eff8ec --- /dev/null +++ b/tests/aot/closure/closure-param-defaults.phpt @@ -0,0 +1,41 @@ +--TEST-- +Closure parameters handle defaults and variadic arguments +--ENV-- +USE_ZEND_ALLOC=0 +--FILE-- +getMessage()); + } +} +?> +--EXPECT-- +int(42) +array(3) { + [0]=> + int(1) + [1]=> + string(3) "two" + [2]=> + NULL +} +string(18) "ArgumentCountError" +string(74) "Too few arguments to function {closure}(), 0 passed and exactly 1 expected" diff --git a/tests/aot/functions/internal-named-args.phpt b/tests/aot/functions/internal-named-args.phpt new file mode 100644 index 00000000..6d93c617 --- /dev/null +++ b/tests/aot/functions/internal-named-args.phpt @@ -0,0 +1,16 @@ +--TEST-- +Internal function named arguments are validated before optimization +--FILE-- + +--EXPECT-- +int(3) +string(3) "xbc" +string(2) "de" diff --git a/tests/aot/named_args/007.phpt b/tests/aot/named_args/007.phpt new file mode 100644 index 00000000..705bdaff --- /dev/null +++ b/tests/aot/named_args/007.phpt @@ -0,0 +1,37 @@ +--TEST-- +Named arguments and promoted properties with C++ reserved parameter names +--FILE-- +union); + var_dump($object->class); +} +?> +--EXPECT-- +array(2) { + [0]=> + int(10) + [1]=> + int(20) +} +int(42) +string(5) "named" diff --git a/tests/aot/optimizations/reserved-param-ssa.phpt b/tests/aot/optimizations/reserved-param-ssa.phpt new file mode 100644 index 00000000..15d0ac61 --- /dev/null +++ b/tests/aot/optimizations/reserved-param-ssa.phpt @@ -0,0 +1,21 @@ +--TEST-- +SSA optimizations handle parameters with C++ reserved names +--FILE-- + +--EXPECT-- +int(12) From 00f79ecdc1eccd0aa84c4ac6c3628f04748906d9 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 12:21:23 +0800 Subject: [PATCH 24/37] =?UTF-8?q?feat(php):=20=E5=AE=9E=E7=8E=B0PHP?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E8=B0=83=E7=94=A8=E4=B8=AD=E7=9A=84=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E5=8F=82=E6=95=B0=E5=92=8C=E5=8F=82=E6=95=B0=E8=A7=A3?= =?UTF-8?q?=E5=8C=85=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加对命名参数语法的支持,包括参数验证和解析逻辑 - 实现参数解包功能,支持...操作符展开数组参数 - 添加hasNamedCallArg和hasUnpackBeforeNamedArg辅助方法进行参数检查 - 实现genCallUserFuncArray方法用于处理复杂参数场景 - 添加对参数顺序的验证,防止解包后使用命名参数的情况 - 更新parseCallArgs方法以支持分离命名参数和位置参数 - 添加相关测试用例验证新功能的正确性 --- phpunit/src/FunctionTest.php | 5 + src/Php/CompilerBase.php | 186 ++++++++++++++++--- tests/aot/functions/unpack-before-named.phpt | 49 +++++ 3 files changed, 210 insertions(+), 30 deletions(-) create mode 100644 tests/aot/functions/unpack-before-named.phpt diff --git a/phpunit/src/FunctionTest.php b/phpunit/src/FunctionTest.php index 2209d56f..4ade96d3 100644 --- a/phpunit/src/FunctionTest.php +++ b/phpunit/src/FunctionTest.php @@ -37,4 +37,9 @@ class FunctionTest extends \BaseTest $this->exec('Named argument `replace` is missing default value', 'internal-call-missing-required-named-arg.php'); } + public function testUnpackAfterNamedArgument() + { + $this->exec('Cannot use argument unpacking after named arguments', 'unpack-after-named-arg.php'); + } + } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index af79a610..c70aa403 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1899,6 +1899,13 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isPlaceholderExpr($arg)) { continue; } + if ($arg instanceof Node\Arg && $arg->unpack) { + if ($hasNamedArg) { + $this->fatalError($arg, 'Cannot use argument unpacking after named arguments'); + } + $providedArgIndexes[$i] = true; + continue; + } if ($arg->name === null) { if ($hasNamedArg) { $this->fatalError($arg, 'Cannot use positional argument after named argument'); @@ -2853,6 +2860,44 @@ class CompilerBase extends \PhpAot\Core\Translator } } + protected function hasNamedCallArg(array $args): bool + { + foreach ($args as $arg) { + if ($arg instanceof Node\Arg && $arg->name !== null) { + return true; + } + } + return false; + } + + protected function hasUnpackBeforeNamedArg(array $args): bool + { + $hasUnpack = false; + foreach ($args as $arg) { + if (!$arg instanceof Node\Arg) { + continue; + } + if ($arg->unpack) { + $hasUnpack = true; + } elseif ($hasUnpack && $arg->name !== null) { + return true; + } + } + return false; + } + + protected function genCallUserFuncArray(string $callback, array $args, string $funcName = '', string $className = ''): string + { + return 'php::call(' . $this->getFuncPtr('call_user_func_array') . ', ' + . Symbol::argList() . '{' . $callback . ', ' . $this->parseCallArgs($args, $funcName, $className, false, true) . '})'; + } + + protected function getFunctionCallbackExpr(string $nativeFn): string + { + $functionDef = $this->getFunction($nativeFn); + return $this->getLiteralString($functionDef->getNamespacedName()); + } + protected function validateInternalNamedCallArgs(\ReflectionFunctionAbstract $ref, array $callArgs): void { $hasNamedArg = false; @@ -2876,6 +2921,13 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isPlaceholderExpr($arg)) { continue; } + if ($arg instanceof Node\Arg && $arg->unpack) { + if ($hasNamedArg) { + $this->fatalError($arg, 'Cannot use argument unpacking after named arguments'); + } + $providedArgIndexes[$i] = true; + continue; + } if ($arg->name === null) { if ($hasNamedArg) { $this->fatalError($arg, 'Cannot use positional argument after named argument'); @@ -2946,6 +2998,9 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->genPlaceHolder($this->identifierToStr($expr->name)); } $this->checkNativeCallArgs($expr, $this->getFunction($nativeFn), $expr->args, $name); + if ($this->hasUnpackBeforeNamedArg($expr->args)) { + return $this->genCallUserFuncArray($this->getFunctionCallbackExpr($nativeFn), $expr->args, $name); + } try { return self::PREFIX . $nativeFn . '(' . $this->parseNativeCallArgs($expr->args, $nativeFn) . ')'; } catch (PlaceHolder) { @@ -2971,8 +3026,12 @@ class CompilerBase extends \PhpAot\Core\Translator if (empty($expr->args)) { return 'php::call(' . $fn . ')'; } + if ($this->hasNamedCallArg($expr->args)) { + $callback = $name !== '' ? $this->getLiteralString($name) : $fn; + return $this->genCallUserFuncArray($callback, $expr->args, $name); + } try { - return 'php::call(' . $fn . ', ' . $this->parseCallArgs($expr->args, $name) . ')'; + return 'php::call(' . $fn . ', ' . $this->parseCallArgs($expr->args, $name, '', $name !== '') . ')'; } catch (PlaceHolder) { return $this->genPlaceHolder($placeHolder); } @@ -3135,22 +3194,88 @@ class CompilerBase extends \PhpAot\Core\Translator return $variadicParam !== null && $variadicParam->isPassedByReference(); } - protected function parseCallArgs(array $args, string $funcName = '', string $className = ''): string + protected function parseCallArgs( + array $args, + string $funcName = '', + string $className = '', + bool $separateNamedArgs = true, + bool $forceArrayArgs = false + ): string { $list_args = []; - $last = array_key_last($args); + $arrayArgsVar = null; + $namedArgsVar = null; + $namedArgs = []; + $hasNamedArg = false; + + $ensureArrayArgs = function () use (&$arrayArgsVar, &$list_args): string { + if ($arrayArgsVar === null) { + $arrayArgsVar = $this->genTmpVarName(); + $this->context->beforeStmtLines[] = self::TYPE_ARRAY . ' ' . $arrayArgsVar . '{' . implode(', ', $list_args) . '};'; + $list_args = []; + } + return $arrayArgsVar; + }; + + $ensureNamedArgs = function () use (&$namedArgsVar): string { + if ($namedArgsVar === null) { + $namedArgsVar = $this->genTmpVarName(); + $this->context->beforeStmtLines[] = self::TYPE_ARRAY . ' ' . $namedArgsVar . ';'; + $this->context->afterStmtLines[] = $namedArgsVar . '.unset();'; + } + return $namedArgsVar; + }; + + $addPositionalArg = function (string $value) use (&$arrayArgsVar, &$list_args): void { + if ($arrayArgsVar !== null) { + $this->context->beforeStmtLines[] = $arrayArgsVar . '.append(' . $value . ');'; + } else { + $list_args[] = $value; + } + }; + + if ($forceArrayArgs) { + $ensureArrayArgs(); + } + foreach ($args as $i => $arg) { if ($this->isPlaceholderExpr($arg)) { throw new PlaceHolder(); } + if ($arg->unpack) { + if ($hasNamedArg) { + $this->fatalError($arg, 'Cannot use argument unpacking after named arguments'); + } + $arrayArgs = $ensureArrayArgs(); + $this->context->beforeStmtLines[] = $arrayArgs . '.merge(' . $this->parseArrayArg($arg) . ');'; + continue; + } if ($arg->name !== null) { - return $this->parseNamedCallArgs($args, $i, $list_args); + $hasNamedArg = true; + if (!$this->isIdExpr($arg->name)) { + $this->fatalError($arg, 'Named argument must be a string'); + } + if (array_key_exists($arg->name->name, $namedArgs)) { + $this->fatalError($arg, "Duplicate named argument `{$arg->name->name}`"); + } + $namedArgs[$arg->name->name] = true; + if ($separateNamedArgs) { + $namedArgsArray = $ensureNamedArgs(); + $this->context->beforeStmtLines[] = $namedArgsArray . '.set(' . $this->getLiteralString($arg->name->name) . ', ' . $this->parseCallArgValue($arg) . ');'; + } else { + $arrayArgs = $ensureArrayArgs(); + $this->context->beforeStmtLines[] = $arrayArgs . '.set(' . $this->getLiteralString($arg->name->name) . ', ' . $this->parseCallArgValue($arg) . ');'; + } + continue; + } + if ($hasNamedArg) { + $this->fatalError($arg, 'Cannot use positional argument after named argument'); } $byRef = $funcName && $this->isReferenceArgument($funcName, $className, $i); if ($this->isVarExpr($arg->value)) { $name = $this->parseIdentifier($arg->value); if ($byRef) { - $list_args[] = $this->parseArgRefVar($arg, $name); + $addPositionalArg($this->parseArgRefVar($arg, $name)); continue; } if (!$this->hasVar($name)) { @@ -3173,9 +3298,9 @@ class CompilerBase extends \PhpAot\Core\Translator if ($byRef) { $ref = $this->addTmpVar(self::TYPE_REF); $this->context->beforeStmtLines[] = $ref . ' = ' . $globalVar . '.toReference();'; - $list_args[] = '&' . $ref; + $addPositionalArg('&' . $ref); } else { - $list_args[] = $globalVar; + $addPositionalArg($globalVar); } continue; } @@ -3186,7 +3311,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($arg->value->dim === null) { $this->fatalError($arg, 'Array dimension must be a constant expression'); } - $list_args[] = $array . '.itemRef(' . $this->identifierToStr($arg->value->dim) . ')'; + $addPositionalArg($array . '.itemRef(' . $this->identifierToStr($arg->value->dim) . ')'); continue; } } elseif ($this->isFuncCallExpr($arg->value)) { @@ -3199,12 +3324,12 @@ class CompilerBase extends \PhpAot\Core\Translator $name = $this->parseVariable($inner); // 消除 refval() 函数调用,直接使用变量 $arg->value = $inner; - $list_args[] = $this->parseArgRefVar($arg, $name); + $addPositionalArg($this->parseArgRefVar($arg, $name)); continue; } $expr = $this->expandRefvalExpr($inner, $arg); if ($expr !== null) { - $list_args[] = $expr; + $addPositionalArg($expr); continue; } $this->fatalError($arg, 'The refval function only accepts a variable, array element, or object property'); @@ -3217,30 +3342,19 @@ class CompilerBase extends \PhpAot\Core\Translator $tmpRef = $this->genTmpVarName(); $this->addLocalVar($tmpRef, self::TYPE_REF); $this->context->beforeStmtLines[] = $tmpRef . ' = ' . $this->parseChainedExpr($arg->value, self::OP_REFVAL) . ';'; - $list_args[] = '&' . $tmpRef; + $addPositionalArg('&' . $tmpRef); continue; } } - // 变长参数展开的语法,例如:array_merge(...$arr) - if ($arg->unpack) { - if ($i !== $last) { - $this->fatalError($arg, 'The unpack expression for variadic arguments must be the last'); - } - // 如果第一个参数是数组变量,数组展开语法直接传递该变量,没必要创建临时变量 - // 例如:function (array $args) { var_dump(...$args); } - if ($i === 0 and $this->isVarExpr($arg->value) and $this->getVarType($arg->value->name) === self::TYPE_ARRAY) { - return $this->parseIdentifier($arg->value); - } else { - $tmpVar = $this->genTmpVarName(); - $this->context->beforeStmtLines[] = self::TYPE_ARRAY . ' ' . $tmpVar . '{' . implode(', ', $list_args) . '};'; - $this->context->beforeStmtLines[] = $tmpVar . '.merge(' . $this->parseArrayArg($arg) . ');'; - return $tmpVar; - } - } - $list_args[] = $this->parseCallArgValue($arg); + $value = $this->parseCallArgValue($arg); + $addPositionalArg($value); } - return Symbol::argList() . '{' . implode(', ', $list_args) . '}'; + if ($arrayArgsVar !== null) { + return $namedArgsVar !== null ? $arrayArgsVar . ', ' . $namedArgsVar . '.array()' : $arrayArgsVar; + } + $callArgs = Symbol::argList() . '{' . implode(', ', $list_args) . '}'; + return $namedArgsVar !== null ? $callArgs . ', ' . $namedArgsVar . '.array()' : $callArgs; } protected function parseCallArgValue(Node\Arg $arg): string @@ -4826,6 +4940,9 @@ class CompilerBase extends \PhpAot\Core\Translator if ($nativeFunc) { $expr->setAttribute('nativeCall', $nativeFunc); try { + if ($this->hasUnpackBeforeNamedArg($expr->args)) { + return $this->genCallUserFuncArray($this->genArray([$object, $method]), $expr->args, $funcName, $class); + } return $this->parseNativeMethodCall($object, $nativeFunc, $expr->args); } catch (PlaceHolder) { return $this->genPlaceHolder($this->genArray([$object, $method])); @@ -4879,9 +4996,12 @@ class CompilerBase extends \PhpAot\Core\Translator if (empty($expr->args)) { return $object . '.call(' . $methodPtr . ')'; } + if ($this->hasNamedCallArg($expr->args)) { + return $this->genCallUserFuncArray($this->genArray([$object, $method]), $expr->args, $funcName, $class); + } try { $class = empty($class) ? self::DYNAMIC_CALLED_CLASS : $class; - return $object . '.call(' . $methodPtr . ', ' . $this->parseCallArgs($expr->args, $funcName, $class) . ')'; + return $object . '.call(' . $methodPtr . ', ' . $this->parseCallArgs($expr->args, $funcName, $class, false) . ')'; } catch (PlaceHolder) { return $this->genPlaceHolder($this->genArray([$object, $method])); } @@ -4969,6 +5089,9 @@ class CompilerBase extends \PhpAot\Core\Translator if ($nativeFunc) { try { + if ($this->hasUnpackBeforeNamedArg($expr->args)) { + return $this->genCallUserFuncArray($this->genArray($callScope), $expr->args, $method, $class); + } $args = $this->parseNativeCallArgs($expr->args, $nativeFunc); $expr->setAttribute('nativeCall', $nativeFunc); } catch (PlaceHolder) { @@ -5004,6 +5127,9 @@ class CompilerBase extends \PhpAot\Core\Translator if (empty($expr->args)) { return $call . '(' . $fn . ')'; } + if ($this->hasNamedCallArg($expr->args)) { + return $this->genCallUserFuncArray($placeHolder, $expr->args); + } try { $callArgs = $this->parseCallArgs($expr->args); return $call . '(' . $fn . ', ' . $callArgs . ')'; diff --git a/tests/aot/functions/unpack-before-named.phpt b/tests/aot/functions/unpack-before-named.phpt new file mode 100644 index 00000000..fb756b14 --- /dev/null +++ b/tests/aot/functions/unpack-before-named.phpt @@ -0,0 +1,49 @@ +--TEST-- +Argument unpacking can be followed by named arguments +--FILE-- +$method(...[5], b: 6)); +} +?> +--EXPECT-- +array(2) { + [0]=> + int(1) + [1]=> + int(2) +} +array(2) { + [0]=> + int(3) + [1]=> + int(4) +} +array(2) { + [0]=> + int(5) + [1]=> + int(6) +} From 4ad8c0a6fa7d3219c930df9191946b72b5d332ca Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 12:52:48 +0800 Subject: [PATCH 25/37] =?UTF-8?q?feat(php):=20=E5=AE=9E=E7=8E=B0=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E6=83=B0=E6=80=A7=E6=B1=82=E5=80=BC=E5=92=8C?= =?UTF-8?q?=E8=AF=AD=E5=8F=A5=E4=B8=8A=E4=B8=8B=E6=96=87=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在三元运算符解析中添加分支语句收集和处理逻辑 - 实现match表达式的惰性求值支持 - 添加条件表达式和函数调用参数的惰性求值机制 - 重构代码结构以支持语句前后的代码块插入 - 更新变量赋值和返回语句的生成逻辑 - 添加lambda包装器用于复杂表达式求值 - 优化临时变量管理和作用域控制 --- src/Php/CompilerBase.php | 147 ++++++++++++++++-- tests/aot/class/new-unpack-named.phpt | 29 ++++ tests/aot/coalesce/value-selection-lazy.phpt | 48 ++++++ tests/aot/control_flow/match-lazy-eval.phpt | 50 ++++++ tests/aot/nullsafe/nullsafe-args-lazy.phpt | 38 +++++ tests/aot/operator/ternary-lazy-eval.phpt | 44 ++++++ .../aot/parent_call/parent-unpack-named.phpt | 35 +++++ 7 files changed, 378 insertions(+), 13 deletions(-) create mode 100644 tests/aot/class/new-unpack-named.phpt create mode 100644 tests/aot/coalesce/value-selection-lazy.phpt create mode 100644 tests/aot/control_flow/match-lazy-eval.phpt create mode 100644 tests/aot/nullsafe/nullsafe-args-lazy.phpt create mode 100644 tests/aot/operator/ternary-lazy-eval.phpt create mode 100644 tests/aot/parent_call/parent-unpack-named.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index c70aa403..2f7eabac 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -3532,12 +3532,54 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->parseValueSelection($expr, $expr->cond, $expr->else, self::OP_NOT_EMPTY); } $cond = $this->parseExpr($expr->cond); + $ifBeforeStmtCount = count($this->context->beforeStmtLines); + $ifAfterStmtCount = count($this->context->afterStmtLines); $if = $this->parseExpr($expr->if); + $ifBeforeStmts = array_slice($this->context->beforeStmtLines, $ifBeforeStmtCount); + $ifAfterStmts = array_slice($this->context->afterStmtLines, $ifAfterStmtCount); + $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $ifBeforeStmtCount); + $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $ifAfterStmtCount); + + $elseBeforeStmtCount = count($this->context->beforeStmtLines); + $elseAfterStmtCount = count($this->context->afterStmtLines); $else = $this->parseExpr($expr->else); - if ($this->detectTypeOfExpr($expr->if) !== $this->detectTypeOfExpr($expr->else)) { + $elseBeforeStmts = array_slice($this->context->beforeStmtLines, $elseBeforeStmtCount); + $elseAfterStmts = array_slice($this->context->afterStmtLines, $elseAfterStmtCount); + $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $elseBeforeStmtCount); + $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $elseAfterStmtCount); + + $hasBranchStmts = $ifBeforeStmts || $ifAfterStmts || $elseBeforeStmts || $elseAfterStmts; + $typeChanged = $this->detectTypeOfExpr($expr->if) !== $this->detectTypeOfExpr($expr->else); + if (!$hasBranchStmts && $typeChanged) { $if = 'php::Var(' . $if . ')'; $else = 'php::Var(' . $else . ')'; } + if ($hasBranchStmts) { + $appendStmtLines = function (string &$code, array $stmts): void { + if ($stmts) { + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts); + } + }; + $appendReturn = function (string &$code, string $value, array $beforeStmts, array $afterStmts) use ($appendStmtLines): void { + $appendStmtLines($code, $beforeStmts); + if ($afterStmts) { + $tmpVar = $this->addTmpVar(self::TYPE_VAR); + $code .= $this->getIndent() . "{$tmpVar} = {$value};"; + $appendStmtLines($code, $afterStmts); + $code .= $this->getIndent() . 'return ' . $tmpVar . ';'; + } else { + $code .= $this->getIndent() . 'return php::Var(' . $value . ');'; + } + }; + $code = '[&]() -> ' . self::TYPE_VAR . '{'; + $code .= $this->getIndent() . 'if (' . $cond . ') {'; + $appendReturn($code, $if, $ifBeforeStmts, $ifAfterStmts); + $code .= $this->getIndent() . '} else {'; + $appendReturn($code, $else, $elseBeforeStmts, $elseAfterStmts); + $code .= $this->getIndent() . '}'; + $code .= $this->getIndent() . '}()'; + return $code; + } return '(' . $cond . ') ? (' . $if . ') : (' . $else . ')'; } @@ -3554,31 +3596,72 @@ class CompilerBase extends \PhpAot\Core\Translator $var = $tmpVar; } + $parseExprWithStmts = function (NodeAbstract $node): array { + $beforeStmtCount = count($this->context->beforeStmtLines); + $afterStmtCount = count($this->context->afterStmtLines); + $value = $this->parseExpr($node); + $beforeStmts = array_slice($this->context->beforeStmtLines, $beforeStmtCount); + $afterStmts = array_slice($this->context->afterStmtLines, $afterStmtCount); + $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $beforeStmtCount); + $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $afterStmtCount); + return [$value, $beforeStmts, $afterStmts]; + }; + + $appendStmtLines = function (string &$code, array $stmts): void { + if ($stmts) { + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts); + } + }; + + $appendMatchReturn = function (string &$code, NodeAbstract $body) use ($parseExprWithStmts, $appendStmtLines): void { + [$value, $beforeStmts, $afterStmts] = $parseExprWithStmts($body); + $appendStmtLines($code, $beforeStmts); + if ($afterStmts) { + $tmpVar = $this->addTmpVar(self::TYPE_VAR); + $code .= $this->getIndent() . "{$tmpVar} = {$value};"; + $appendStmtLines($code, $afterStmts); + $code .= $this->getIndent() . 'return ' . $tmpVar . ';'; + } else { + $code .= $this->getIndent() . 'return ' . $value . ';'; + } + }; + $code = '[&]() -> ' . self::TYPE_VAR . '{'; $default = null; - foreach ($expr->arms as $i => $arm) { + foreach ($expr->arms as $arm) { if ($arm->conds === null) { $default = $arm->body; continue; } - $prefix = $i === 0 ? 'if' : 'else if'; - $condList = []; + $matched = $this->genTmpVarName(); + $code .= $this->getIndent() . 'bool ' . $matched . ' = false;'; foreach ($arm->conds as $cond) { if ($this->isMatchExpr($cond)) { $this->fatalError($arm, 'Match expression cannot be used as a condition'); } - $condList[] = 'php::same(' . $var . ', ' . $this->parseExpr($cond) . ')'; + [$condValue, $beforeStmts, $afterStmts] = $parseExprWithStmts($cond); + $code .= $this->getIndent() . 'if (!' . $matched . ') {'; + $appendStmtLines($code, $beforeStmts); + if ($afterStmts) { + $condTmpVar = $this->addTmpVar(self::TYPE_VAR); + $code .= $this->getIndent() . "{$condTmpVar} = {$condValue};"; + $appendStmtLines($code, $afterStmts); + $condValue = $condTmpVar; + } + $code .= $this->getIndent() . $matched . ' = php::same(' . $var . ', ' . $condValue . ');'; + $code .= $this->getIndent() . '}'; } - $code .= $prefix . '(' . implode(' || ', $condList) . ') {'; - $code .= 'return ' . $this->parseExpr($arm->body) . ';'; - $code .= '}'; + $code .= $this->getIndent() . 'if (' . $matched . ') {'; + $appendMatchReturn($code, $arm->body); + $code .= $this->getIndent() . '}'; } - $else = count($expr->arms) === 0 ? '' : 'else '; if ($default) { - $code .= $else . ' { return ' . $this->parseExpr($default) . '; }'; + $code .= $this->getIndent() . '{'; + $appendMatchReturn($code, $default); + $code .= $this->getIndent() . '}'; } else { - $code .= $else . ' { return php::throwException("UnhandledMatchError", "Unhandled match case"); }'; + $code .= $this->getIndent() . '{ return php::throwException("UnhandledMatchError", "Unhandled match case"); }'; } $code .= '}()'; @@ -3698,12 +3781,38 @@ class CompilerBase extends \PhpAot\Core\Translator $leftExpr = $chainOpResult; } + $rightBeforeStmtCount = count($this->context->beforeStmtLines); + $rightAfterStmtCount = count($this->context->afterStmtLines); $rightExpr = $this->parseIdentifier($right); + $rightBeforeStmts = array_slice($this->context->beforeStmtLines, $rightBeforeStmtCount); + $rightAfterStmts = array_slice($this->context->afterStmtLines, $rightAfterStmtCount); + $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $rightBeforeStmtCount); + $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $rightAfterStmtCount); $this->checkVarMustExist($right, $rightExpr); $tmpVar = $this->addTmpVar(self::TYPE_VAR); - $this->context->beforeStmtLines[] = '// Expr: ' . $this->printer->prettyPrintExpr($expr) . PHP_EOL . - $tmpVar . ' = ' . $condExpr . ' ? ' . $leftExpr . ' : ' . $rightExpr . ';'; + if ($rightBeforeStmts || $rightAfterStmts) { + $code = '// Expr: ' . $this->printer->prettyPrintExpr($expr) . PHP_EOL . + 'if (' . $condExpr . ') {' . PHP_EOL . + $this->getIndent() . $tmpVar . ' = ' . $leftExpr . ';' . PHP_EOL . + '} else {' . PHP_EOL; + if ($rightBeforeStmts) { + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $rightBeforeStmts) . PHP_EOL; + } + if ($rightAfterStmts) { + $rightTmpVar = $this->addTmpVar(self::TYPE_VAR); + $code .= $this->getIndent() . $rightTmpVar . ' = ' . $rightExpr . ';' . PHP_EOL; + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $rightAfterStmts) . PHP_EOL; + $code .= $this->getIndent() . $tmpVar . ' = ' . $rightTmpVar . ';' . PHP_EOL; + } else { + $code .= $this->getIndent() . $tmpVar . ' = ' . $rightExpr . ';' . PHP_EOL; + } + $code .= '}'; + $this->context->beforeStmtLines[] = $code; + } else { + $this->context->beforeStmtLines[] = '// Expr: ' . $this->printer->prettyPrintExpr($expr) . PHP_EOL . + $tmpVar . ' = ' . $condExpr . ' ? ' . $leftExpr . ' : ' . $rightExpr . ';'; + } $expr->setAttribute('replace', $tmpVar); return $tmpVar; @@ -6225,8 +6334,20 @@ class CompilerBase extends \PhpAot\Core\Translator if ($item[0] == 'property') { $code .= $this->getIndent() . "{$tmpVar} = {$object}.attr({$item[1]}, {$update});"; } else { + $beforeStmtCount = count($this->context->beforeStmtLines); + $afterStmtCount = count($this->context->afterStmtLines); $args = $this->parseCallArgs($item[2]); + $argBeforeStmts = array_slice($this->context->beforeStmtLines, $beforeStmtCount); + $argAfterStmts = array_slice($this->context->afterStmtLines, $afterStmtCount); + $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $beforeStmtCount); + $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $afterStmtCount); + if ($argBeforeStmts) { + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $argBeforeStmts); + } $code .= $this->getIndent() . "{$tmpVar} = {$object}.call({$item[1]}, {$args});"; + if ($argAfterStmts) { + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $argAfterStmts); + } } $object = $tmpVar; } diff --git a/tests/aot/class/new-unpack-named.phpt b/tests/aot/class/new-unpack-named.phpt new file mode 100644 index 00000000..a66e8f59 --- /dev/null +++ b/tests/aot/class/new-unpack-named.phpt @@ -0,0 +1,29 @@ +--TEST-- +new object with unpack before named arguments +--FILE-- +a . ':' . $this->b . "\n"; + } +} + +function main(): void +{ + $known = new PairValue(...[1], b: 2); + $known->show(); + + $class = PairValue::class; + $dynamic = new $class(...[3], b: 4); + $dynamic->show(); +} +?> +--EXPECT-- +1:2 +3:4 diff --git a/tests/aot/coalesce/value-selection-lazy.phpt b/tests/aot/coalesce/value-selection-lazy.phpt new file mode 100644 index 00000000..72f09f6e --- /dev/null +++ b/tests/aot/coalesce/value-selection-lazy.phpt @@ -0,0 +1,48 @@ +--TEST-- +Coalesce and shorthand ternary evaluate right side lazily +--FILE-- + +--EXPECT-- +string(4) "left" +args:coalesce-run +value:coalesce-run +body:coalesce-run:coalesce-run +string(25) "coalesce-run:coalesce-run" +string(6) "truthy" +args:shorthand-run +value:shorthand-run +body:shorthand-run:shorthand-run +string(27) "shorthand-run:shorthand-run" diff --git a/tests/aot/control_flow/match-lazy-eval.phpt b/tests/aot/control_flow/match-lazy-eval.phpt new file mode 100644 index 00000000..15142428 --- /dev/null +++ b/tests/aot/control_flow/match-lazy-eval.phpt @@ -0,0 +1,50 @@ +--TEST-- +Match expression evaluates conditions and bodies lazily +--FILE-- + build(...makeArgs('A'), value: makeValue('A')), + marker(name: 'b'), marker(name: 'skip') => build(...makeArgs('B'), value: makeValue('B')), + marker(name: 'c') => build(...makeArgs('C'), value: makeValue('C')), + default => build(...makeArgs('D'), value: makeValue('D')), + }; +} + +function main(): void +{ + var_dump(test_match('b')); +} +?> +--EXPECT-- +cond:a +cond:b +args:B +value:B +body:B:B +string(3) "B:B" diff --git a/tests/aot/nullsafe/nullsafe-args-lazy.phpt b/tests/aot/nullsafe/nullsafe-args-lazy.phpt new file mode 100644 index 00000000..59ada435 --- /dev/null +++ b/tests/aot/nullsafe/nullsafe-args-lazy.phpt @@ -0,0 +1,38 @@ +--TEST-- +Nullsafe method call does not evaluate arguments when receiver is null +--FILE-- +set(...makeArgs(), value: makeValue())); + + $recorder = new Recorder(); + var_dump($recorder?->set(...makeArgs(), value: makeValue())); +} +?> +--EXPECT-- +NULL +makeArgs +makeValue +string(4) "7:ok" diff --git a/tests/aot/operator/ternary-lazy-eval.phpt b/tests/aot/operator/ternary-lazy-eval.phpt new file mode 100644 index 00000000..1d7f288e --- /dev/null +++ b/tests/aot/operator/ternary-lazy-eval.phpt @@ -0,0 +1,44 @@ +--TEST-- +Ternary expression evaluates only selected branch +--FILE-- + +--EXPECT-- +args:T +value:T +body:T:T +string(3) "T:T" +args:F +value:F +body:F:F +string(3) "F:F" diff --git a/tests/aot/parent_call/parent-unpack-named.phpt b/tests/aot/parent_call/parent-unpack-named.phpt new file mode 100644 index 00000000..494a0ca6 --- /dev/null +++ b/tests/aot/parent_call/parent-unpack-named.phpt @@ -0,0 +1,35 @@ +--TEST-- +parent::method() with unpack before named arguments +--FILE-- +combine(9, 9) . "\n"; + echo $child->callParent() . "\n"; +} +?> +--EXPECT-- +child +1:2 From cff27c7c795b366a9785a4753515621ae2ad6c04 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 13:18:49 +0800 Subject: [PATCH 26/37] =?UTF-8?q?refactor(parser):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E4=BA=8C=E5=85=83=E6=93=8D=E4=BD=9C=E7=AC=A6=E5=92=8C=E6=8E=A7?= =?UTF-8?q?=E5=88=B6=E6=B5=81=E7=9A=84=E8=A7=A3=E6=9E=90=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现逻辑运算符短路求值功能,支持 && 和 || 操作符的惰性求值 - 添加 parseShortCircuitLogicalOp 方法处理逻辑运算符的特殊解析逻辑 - 新增 parseExprWithCapturedStmts 方法捕获表达式解析过程中的语句 - 实现 appendCapturedStmtLines 和 genConditionWithCapturedStmts 辅助方法 - 重构 for 循环条件和循环体表达式的解析逻辑 - 修改三元运算符解析以支持条件表达式的语句捕获 - 重构 if 语句解析使用递归函数处理 if-elseif-else 链 - 更新 while 和 do-while 循环处理条件表达式中的副作用 - 重构 switch 语句解析逻辑,改进 case 条件的匹配机制 - 添加多个测试用例验证条件表达式副作用的执行时机 --- src/Php/CompilerBase.php | 237 ++++++++++++++---- src/Php/Parser/BinaryOpTrait.php | 48 +++- .../control_flow/condition-side-effects.phpt | 62 +++++ .../do-while-condition-side-effects.phpt | 29 +++ .../for-condition-side-effects.phpt | 56 +++++ .../operator/logical-short-circuit-lazy.phpt | 41 +++ tests/aot/operator/ternary-lazy-eval.phpt | 12 + tests/aot/switch/switch-side-effects.phpt | 55 ++++ 8 files changed, 483 insertions(+), 57 deletions(-) create mode 100644 tests/aot/control_flow/condition-side-effects.phpt create mode 100644 tests/aot/control_flow/do-while-condition-side-effects.phpt create mode 100644 tests/aot/control_flow/for-condition-side-effects.phpt create mode 100644 tests/aot/operator/logical-short-circuit-lazy.phpt create mode 100644 tests/aot/switch/switch-side-effects.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 2f7eabac..9beeb199 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1350,6 +1350,40 @@ class CompilerBase extends \PhpAot\Core\Translator return ''; } + protected function parseExprWithCapturedStmts(NodeAbstract $expr): array + { + $beforeStmtCount = count($this->context->beforeStmtLines); + $afterStmtCount = count($this->context->afterStmtLines); + $value = $this->parseExpr($expr); + $beforeStmts = array_slice($this->context->beforeStmtLines, $beforeStmtCount); + $afterStmts = array_slice($this->context->afterStmtLines, $afterStmtCount); + $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $beforeStmtCount); + $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $afterStmtCount); + return [$value, $beforeStmts, $afterStmts]; + } + + protected function appendCapturedStmtLines(string &$code, array $stmts): void + { + if ($stmts) { + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL; + } + } + + protected function genConditionWithCapturedStmts(NodeAbstract $cond, string $openPrefix): string + { + [$condExpr, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($cond); + $code = ''; + $this->appendCapturedStmtLines($code, $beforeStmts); + if ($afterStmts) { + $tmpVar = $this->addTmpVar(self::TYPE_VAR); + $code .= $this->getIndent() . $tmpVar . ' = ' . $condExpr . ';' . PHP_EOL; + $this->appendCapturedStmtLines($code, $afterStmts); + $condExpr = $tmpVar; + } + $code .= $openPrefix . '(' . $condExpr . ') {' . PHP_EOL; + return $code; + } + protected function parseBlockStmts(array $stmts): string { $this->indentLevel++; @@ -2592,24 +2626,65 @@ class CompilerBase extends \PhpAot\Core\Translator $list_expr = []; foreach ($init as $expr) { - $list_expr[] = $this->parseExpr($expr); + [$initExpr, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($expr); + $this->appendCapturedStmtLines($code, $beforeStmts); + $list_expr[] = $initExpr; + if ($afterStmts) { + $list_expr[] = implode(";\n" . $this->getIndent(), $afterStmts); + } } $list_expr[] = ''; $code .= implode(";\n" . $this->getIndent(), $list_expr); $list_cond = []; + $hasCondStmts = false; foreach ($cond as $expr) { - $list_cond[] = $this->parseExpr($expr); + [$condExpr, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($expr); + $hasCondStmts = $hasCondStmts || $beforeStmts || $afterStmts; + $list_cond[] = [$condExpr, $beforeStmts, $afterStmts]; } $code .= $this->parseBeforeStmtLines() . PHP_EOL; $code .= 'for (;'; - $code .= implode(', ', $list_cond); + if ($hasCondStmts) { + $condCode = '[&]() -> bool {'; + if (empty($list_cond)) { + $condCode .= $this->getIndent() . 'return true;'; + } else { + $condResult = $this->genTmpVarName(); + $condCode .= $this->getIndent() . 'bool ' . $condResult . ' = true;' . PHP_EOL; + foreach ($list_cond as [$condExpr, $beforeStmts, $afterStmts]) { + $this->appendCapturedStmtLines($condCode, $beforeStmts); + if ($afterStmts) { + $tmpVar = $this->addTmpVar(self::TYPE_VAR); + $condCode .= $this->getIndent() . $tmpVar . ' = ' . $condExpr . ';' . PHP_EOL; + $this->appendCapturedStmtLines($condCode, $afterStmts); + $condExpr = $tmpVar; + } + $condCode .= $this->getIndent() . $condResult . ' = ' . $this->convertBoolExpr($condExpr) . ';' . PHP_EOL; + } + $condCode .= $this->getIndent() . 'return ' . $condResult . ';'; + } + $condCode .= $this->getIndent() . '}()'; + $code .= $condCode; + } else { + $code .= implode(', ', array_map(static fn($item) => $item[0], $list_cond)); + } $code .= '; '; $list_loop = []; foreach ($loop as $expr) { - $list_loop[] = $this->parseExpr($expr); + [$loopExpr, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($expr); + if ($beforeStmts || $afterStmts) { + $loopCode = '[&]() {'; + $this->appendCapturedStmtLines($loopCode, $beforeStmts); + $loopCode .= $this->getIndent() . $loopExpr . ';' . PHP_EOL; + $this->appendCapturedStmtLines($loopCode, $afterStmts); + $loopCode .= $this->getIndent() . '}()'; + $list_loop[] = $loopCode; + } else { + $list_loop[] = $loopExpr; + } } $code .= implode(', ', $list_loop); $code .= ') {' . PHP_EOL; @@ -3531,7 +3606,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($expr->if === null) { return $this->parseValueSelection($expr, $expr->cond, $expr->else, self::OP_NOT_EMPTY); } - $cond = $this->parseExpr($expr->cond); + [$cond, $condBeforeStmts, $condAfterStmts] = $this->parseExprWithCapturedStmts($expr->cond); $ifBeforeStmtCount = count($this->context->beforeStmtLines); $ifAfterStmtCount = count($this->context->afterStmtLines); $if = $this->parseExpr($expr->if); @@ -3548,7 +3623,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $elseBeforeStmtCount); $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $elseAfterStmtCount); - $hasBranchStmts = $ifBeforeStmts || $ifAfterStmts || $elseBeforeStmts || $elseAfterStmts; + $hasBranchStmts = $condBeforeStmts || $condAfterStmts || $ifBeforeStmts || $ifAfterStmts || $elseBeforeStmts || $elseAfterStmts; $typeChanged = $this->detectTypeOfExpr($expr->if) !== $this->detectTypeOfExpr($expr->else); if (!$hasBranchStmts && $typeChanged) { $if = 'php::Var(' . $if . ')'; @@ -3557,7 +3632,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($hasBranchStmts) { $appendStmtLines = function (string &$code, array $stmts): void { if ($stmts) { - $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts); + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL; } }; $appendReturn = function (string &$code, string $value, array $beforeStmts, array $afterStmts) use ($appendStmtLines): void { @@ -3572,6 +3647,13 @@ class CompilerBase extends \PhpAot\Core\Translator } }; $code = '[&]() -> ' . self::TYPE_VAR . '{'; + $appendStmtLines($code, $condBeforeStmts); + if ($condAfterStmts) { + $condTmpVar = $this->addTmpVar(self::TYPE_VAR); + $code .= $this->getIndent() . "{$condTmpVar} = {$cond};"; + $appendStmtLines($code, $condAfterStmts); + $cond = $condTmpVar; + } $code .= $this->getIndent() . 'if (' . $cond . ') {'; $appendReturn($code, $if, $ifBeforeStmts, $ifAfterStmts); $code .= $this->getIndent() . '} else {'; @@ -3609,7 +3691,7 @@ class CompilerBase extends \PhpAot\Core\Translator $appendStmtLines = function (string &$code, array $stmts): void { if ($stmts) { - $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts); + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL; } }; @@ -3700,29 +3782,34 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseIf(Node\Stmt\If_ $v): string { - $cond = $this->parseExpr($v->cond); + $arms = [[$v->cond, $v->stmts]]; + foreach ($v->elseifs as $elseif) { + $arms[] = [$elseif->cond, $elseif->stmts]; + } - $code = $this->parseBeforeStmtLines() . PHP_EOL; - $code .= 'if (' . $cond . ') {' . PHP_EOL; - $code .= $this->parseBlockStmts($v->stmts); - $code .= $this->getIndent() . '}'; + $emitIfChain = function (int $index) use (&$emitIfChain, $arms, $v): string { + if (!isset($arms[$index])) { + if (!$v->else) { + return ''; + } + return $this->parseBlockStmts($v->else->stmts); + } - if ($v->elseifs) { - foreach ($v->elseifs as $elseif) { - $elseifCond = $this->parseExpr($elseif->cond); - $code .= ' else if (' . $elseifCond . ') {' . PHP_EOL; - $code .= $this->parseBlockStmts($elseif->stmts); + [$cond, $stmts] = $arms[$index]; + $code = $this->genConditionWithCapturedStmts($cond, 'if '); + $code .= $this->parseBlockStmts($stmts); + $tail = $emitIfChain($index + 1); + if ($tail !== '') { + $code .= $this->getIndent() . '} else {' . PHP_EOL; + $code .= $tail; + $code .= $this->getIndent() . '}'; + } else { $code .= $this->getIndent() . '}'; } - } - - if ($v->else) { - $code .= ' else {' . PHP_EOL; - $code .= $this->parseBlockStmts($v->else->stmts); - $code .= $this->getIndent() . '}'; - } + return $code; + }; - return $code . PHP_EOL; + return $this->parseBeforeStmtLines() . PHP_EOL . $emitIfChain(0) . PHP_EOL; } /** @@ -3735,11 +3822,23 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseWhile(Node\Stmt\While_ $v): string { - $cond = $this->parseExpr($v->cond); $stmts = $v->stmts; + [$cond, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($v->cond); $code = $this->parseBeforeStmtLines() . PHP_EOL; - $code .= 'while (' . $cond . ') {' . PHP_EOL; + if ($beforeStmts || $afterStmts) { + $code .= 'while (true) {' . PHP_EOL; + $this->appendCapturedStmtLines($code, $beforeStmts); + if ($afterStmts) { + $tmpVar = $this->addTmpVar(self::TYPE_VAR); + $code .= $this->getIndent() . $tmpVar . ' = ' . $cond . ';' . PHP_EOL; + $this->appendCapturedStmtLines($code, $afterStmts); + $cond = $tmpVar; + } + $code .= $this->getIndent() . 'if (!(' . $cond . ')) { break; }' . PHP_EOL; + } else { + $code .= 'while (' . $cond . ') {' . PHP_EOL; + } $code .= $this->parseBlockStmts($stmts); $code .= $this->genLoopEndFlagCheck(); $code .= $this->getIndent() . '}' . PHP_EOL; @@ -3755,7 +3854,20 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseDo(Node\Stmt\Do_ $v): string { $stmts = $v->stmts; - $cond = $this->parseExpr($v->cond); + [$cond, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($v->cond); + if ($beforeStmts || $afterStmts) { + $condCode = '[&]() -> bool {'; + $this->appendCapturedStmtLines($condCode, $beforeStmts); + if ($afterStmts) { + $tmpVar = $this->addTmpVar(self::TYPE_VAR); + $condCode .= $this->getIndent() . $tmpVar . ' = ' . $cond . ';' . PHP_EOL; + $this->appendCapturedStmtLines($condCode, $afterStmts); + $cond = $tmpVar; + } + $condCode .= $this->getIndent() . 'return ' . $this->convertBoolExpr($cond) . ';'; + $condCode .= $this->getIndent() . '}()'; + $cond = $condCode; + } $code = $this->parseBeforeStmtLines() . PHP_EOL; $code .= 'do {' . PHP_EOL; $code .= $this->parseBlockStmts($stmts); @@ -4597,7 +4709,11 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isVarExpr($cond)) { $this->requireVar($v, $this->parseIdentifier($cond)); } - $var_def = $type . ' ' . $tmp_var . ' = ' . $this->parseExpr($cond) . ';' . PHP_EOL; + [$condExpr, $condBeforeStmts, $condAfterStmts] = $this->parseExprWithCapturedStmts($cond); + $var_def = ''; + $this->appendCapturedStmtLines($var_def, $condBeforeStmts); + $var_def .= $type . ' ' . $tmp_var . ' = ' . $condExpr . ';' . PHP_EOL; + $this->appendCapturedStmtLines($var_def, $condAfterStmts); // 保存作用域,switch 可能会解析失败,在这个过程中会增加变量,需重置 $localVars = $this->context->localVars; @@ -4634,33 +4750,23 @@ class CompilerBase extends \PhpAot\Core\Translator _fail: - if (count($v->cases) == 1) { - if (!empty($v->cases[0]->cond)) { - $code = 'if (' . $tmp_var . '==' . $this->parseIdentifier($v->cases[0]->cond) . ') {' . PHP_EOL; - } else { - $code = 'if (1) {' . PHP_EOL; - } - $code .= $this->parseStmts($v->cases[0]->stmts); - $code .= $this->getIndent() . '}'; - return $var_def . $code; - } - $code = 'do {' . PHP_EOL; $this->indentLevel++; - $condList = []; - $defaultCase = false; - $defaultOnly = true; + $switchMatched = $this->genTmpVarName(); + $code .= $this->getIndent() . 'bool ' . $switchMatched . ' = false;' . PHP_EOL; + $caseConds = []; foreach ($v->cases as $case) { if (empty($case->cond)) { - $defaultCase = true; + $isDefault = true; } else { - $condList[] = $tmp_var . '==' . $this->parseIdentifier($case->cond); + $isDefault = false; + $caseConds[] = $case->cond; } - $this->indentLevel++; $stmts = $case->stmts; if (empty($stmts)) { continue; } + $this->indentLevel++; if (count($stmts) === 1 and $stmts[0] instanceof Node\Stmt\Block) { $stmts = $stmts[0]->stmts; } @@ -4673,13 +4779,34 @@ class CompilerBase extends \PhpAot\Core\Translator $this->fatalError($case, 'switch case must end with return/break/exit/throw, ' . $lastExpr->getType() . ' given'); } - if ($defaultCase) { - $else = $defaultOnly ? '' : 'else'; - $code .= $this->getIndent() . $else . ' {' . PHP_EOL; + if ($isDefault) { + $code .= $this->getIndent() . 'if (!' . $switchMatched . ') {' . PHP_EOL; } else { - $code .= $this->getIndent() . 'if (' . implode(' || ', $condList) . ') {' . PHP_EOL; - $defaultOnly = false; - $condList = []; + $groupMatched = $this->genTmpVarName(); + $code .= $this->getIndent() . 'bool ' . $groupMatched . ' = false;' . PHP_EOL; + foreach ($caseConds as $caseCond) { + $caseBeforeStmtCount = count($this->context->beforeStmtLines); + $caseAfterStmtCount = count($this->context->afterStmtLines); + $caseCondExpr = $this->parseIdentifier($caseCond); + $caseBeforeStmts = array_slice($this->context->beforeStmtLines, $caseBeforeStmtCount); + $caseAfterStmts = array_slice($this->context->afterStmtLines, $caseAfterStmtCount); + $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $caseBeforeStmtCount); + $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $caseAfterStmtCount); + + $code .= $this->getIndent() . 'if (!' . $switchMatched . ' && !' . $groupMatched . ') {' . PHP_EOL; + $this->appendCapturedStmtLines($code, $caseBeforeStmts); + if ($caseAfterStmts) { + $caseTmpVar = $this->addTmpVar(self::TYPE_VAR); + $code .= $this->getIndent() . $caseTmpVar . ' = ' . $caseCondExpr . ';' . PHP_EOL; + $this->appendCapturedStmtLines($code, $caseAfterStmts); + $caseCondExpr = $caseTmpVar; + } + $code .= $this->getIndent() . $groupMatched . ' = php::equals(' . $tmp_var . ', ' . $caseCondExpr . ');' . PHP_EOL; + $code .= $this->getIndent() . '}' . PHP_EOL; + } + $code .= $this->getIndent() . 'if (' . $groupMatched . ') {' . PHP_EOL; + $code .= $this->getIndent() . $switchMatched . ' = true;' . PHP_EOL; + $caseConds = []; } $code .= $this->parseStmts($stmts); @@ -6342,11 +6469,11 @@ class CompilerBase extends \PhpAot\Core\Translator $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $beforeStmtCount); $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $afterStmtCount); if ($argBeforeStmts) { - $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $argBeforeStmts); + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $argBeforeStmts) . PHP_EOL; } $code .= $this->getIndent() . "{$tmpVar} = {$object}.call({$item[1]}, {$args});"; if ($argAfterStmts) { - $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $argAfterStmts); + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $argAfterStmts) . PHP_EOL; } } $object = $tmpVar; diff --git a/src/Php/Parser/BinaryOpTrait.php b/src/Php/Parser/BinaryOpTrait.php index f752e65d..ceef608c 100644 --- a/src/Php/Parser/BinaryOpTrait.php +++ b/src/Php/Parser/BinaryOpTrait.php @@ -283,12 +283,56 @@ trait BinaryOpTrait protected function parseBinaryOpLogicalAnd(Expr\BinaryOp\LogicalAnd|Expr\BinaryOp\BooleanAnd $expr): string { - return $this->convertBoolExpr($this->parseBinaryOp($expr->left, $expr->right, '&&')); + return $this->parseShortCircuitLogicalOp($expr->left, $expr->right, '&&'); } protected function parseBinaryOpLogicalOr(Expr\BinaryOp\LogicalOr|Expr\BinaryOp\BooleanOr $expr): string { - return $this->convertBoolExpr($this->parseBinaryOp($expr->left, $expr->right, '||')); + return $this->parseShortCircuitLogicalOp($expr->left, $expr->right, '||'); + } + + protected function parseShortCircuitLogicalOp(NodeAbstract $left, NodeAbstract $right, string $op): string + { + $leftExpr = $this->parseNumericIdentifier($left); + $this->checkVarMustExist($left, $leftExpr); + + $rightBeforeStmtCount = count($this->context->beforeStmtLines); + $rightAfterStmtCount = count($this->context->afterStmtLines); + $rightExpr = $this->parseNumericIdentifier($right); + $rightBeforeStmts = array_slice($this->context->beforeStmtLines, $rightBeforeStmtCount); + $rightAfterStmts = array_slice($this->context->afterStmtLines, $rightAfterStmtCount); + $this->context->beforeStmtLines = array_slice($this->context->beforeStmtLines, 0, $rightBeforeStmtCount); + $this->context->afterStmtLines = array_slice($this->context->afterStmtLines, 0, $rightAfterStmtCount); + $this->checkVarMustExist($right, $rightExpr); + + $leftBool = $this->convertBoolExpr((string) $leftExpr); + if (!$rightBeforeStmts && !$rightAfterStmts) { + return '(' . $leftBool . ' ' . $op . ' ' . $this->convertBoolExpr((string) $rightExpr) . ')'; + } + + $appendStmtLines = function (string &$code, array $stmts): void { + if ($stmts) { + $code .= $this->getIndent() . implode(PHP_EOL . $this->getIndent(), $stmts) . PHP_EOL; + } + }; + $shortCircuitValue = $op === '&&' ? 'false' : 'true'; + $rightCondition = $op === '&&' ? $leftBool : '!(' . $leftBool . ')'; + + $code = '[&]() -> bool {'; + $code .= $this->getIndent() . 'if (' . $rightCondition . ') {'; + $appendStmtLines($code, $rightBeforeStmts); + if ($rightAfterStmts) { + $rightTmpVar = $this->addTmpVar(self::TYPE_VAR); + $code .= $this->getIndent() . $rightTmpVar . ' = ' . $rightExpr . ';'; + $appendStmtLines($code, $rightAfterStmts); + $rightExpr = $rightTmpVar; + } + $code .= $this->getIndent() . 'return ' . $this->convertBoolExpr((string) $rightExpr) . ';'; + $code .= $this->getIndent() . '}'; + $code .= $this->getIndent() . 'return ' . $shortCircuitValue . ';'; + $code .= $this->getIndent() . '}()'; + + return $code; } protected function parseBinaryOpLogicalXor(Expr\BinaryOp\LogicalXor $expr): string diff --git a/tests/aot/control_flow/condition-side-effects.phpt b/tests/aot/control_flow/condition-side-effects.phpt new file mode 100644 index 00000000..84f6e0bb --- /dev/null +++ b/tests/aot/control_flow/condition-side-effects.phpt @@ -0,0 +1,62 @@ +--TEST-- +If and while conditions evaluate side effects at the correct time +--FILE-- + +--EXPECT-- +args:elseif-false +value:elseif-false +probe:elseif-false:elseif-false +args:elseif-true +value:elseif-true +probe:elseif-true:elseif-true +elseif true +loop:0 +body:0 +loop:1 +body:1 +loop:2 +body:2 +loop:3 diff --git a/tests/aot/control_flow/do-while-condition-side-effects.phpt b/tests/aot/control_flow/do-while-condition-side-effects.phpt new file mode 100644 index 00000000..d81a6ff7 --- /dev/null +++ b/tests/aot/control_flow/do-while-condition-side-effects.phpt @@ -0,0 +1,29 @@ +--TEST-- +Do-while condition evaluates side effects after continue +--FILE-- + +--EXPECT-- +body:0 +cond:1 +body:1 +cond:2 +body:2 +cond:3 diff --git a/tests/aot/control_flow/for-condition-side-effects.phpt b/tests/aot/control_flow/for-condition-side-effects.phpt new file mode 100644 index 00000000..f4e839cf --- /dev/null +++ b/tests/aot/control_flow/for-condition-side-effects.phpt @@ -0,0 +1,56 @@ +--TEST-- +For condition and loop expressions evaluate side effects at the correct time +--FILE-- + +--EXPECT-- +args:cond-0 +cond:cond-0:0 +body:0 +args:step-0 +step:step-0:0 +args:cond-1 +cond:cond-1:1 +body:1 +args:step-1 +step:step-1:1 +args:cond-2 +cond:cond-2:2 +body:2 +args:step-2 +step:step-2:2 +args:cond-3 +cond:cond-3:3 diff --git a/tests/aot/operator/logical-short-circuit-lazy.phpt b/tests/aot/operator/logical-short-circuit-lazy.phpt new file mode 100644 index 00000000..fef51c0a --- /dev/null +++ b/tests/aot/operator/logical-short-circuit-lazy.phpt @@ -0,0 +1,41 @@ +--TEST-- +Logical && and || evaluate right side lazily +--FILE-- + +--EXPECT-- +bool(false) +args:and-run +value:and-run +check:and-run:and-run +bool(true) +bool(true) +args:or-run +value:or-run +check:or-run:or-run +bool(true) diff --git a/tests/aot/operator/ternary-lazy-eval.phpt b/tests/aot/operator/ternary-lazy-eval.phpt index 1d7f288e..1cb575e5 100644 --- a/tests/aot/operator/ternary-lazy-eval.phpt +++ b/tests/aot/operator/ternary-lazy-eval.phpt @@ -20,6 +20,12 @@ function build(string $id, string $value): string return $id . ':' . $value; } +function condition(string $id, string $value): bool +{ + echo "cond:$id:$value\n"; + return true; +} + function choose(bool $flag): string { return $flag @@ -29,11 +35,17 @@ function choose(bool $flag): string function main(): void { + var_dump(condition(...makeArgs('C'), value: makeValue('C')) ? build('T', 'T') : build('F', 'F')); var_dump(choose(true)); var_dump(choose(false)); } ?> --EXPECT-- +args:C +value:C +cond:C:C +body:T:T +string(3) "T:T" args:T value:T body:T:T diff --git a/tests/aot/switch/switch-side-effects.phpt b/tests/aot/switch/switch-side-effects.phpt new file mode 100644 index 00000000..c57e54d1 --- /dev/null +++ b/tests/aot/switch/switch-side-effects.phpt @@ -0,0 +1,55 @@ +--TEST-- +Switch condition and case expressions evaluate side effects in order +--FILE-- + +--EXPECT-- +args:subject +value:b +subject:subject:b +args:a +value:a +case:a:a +args:b +value:b +case:b:b +B From 54bca6942ec33b49da65228e507329f35c4f6ac3 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 16:34:47 +0800 Subject: [PATCH 27/37] =?UTF-8?q?feat(parser):=20=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E5=B1=9E=E6=80=A7=E8=B5=8B=E5=80=BC=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=A3=80=E6=9F=A5=E5=92=8C=E4=BA=8C=E5=85=83=E8=BF=90?= =?UTF-8?q?=E7=AE=97=E6=93=8D=E4=BD=9C=E6=95=B0=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现对象属性赋值时的类型验证检查机制 - 添加静态属性赋值的类型安全保护 - 引入有序操作数解析以支持复杂表达式计算 - 增加对函数调用参数的类型安全检查 - 优化二元运算符操作数的类型转换处理 - 添加测试用例验证类型检查功能正确性 - 扩展属性定义实体以支持类型检查配置 - 实现操作数材料化以处理副作用表达式 --- src/Php/CompilerBase.php | 103 +++++++++++++- src/Php/Entity/PropertyDef.php | 2 + src/Php/Optimizer/FuncCallOptimizer.php | 8 +- src/Php/Parser/AssignOpTrait.php | 3 + src/Php/Parser/BinaryOpTrait.php | 132 ++++++++++++++++-- src/Php/Preprocessor.php | 5 + src/Php/Translator.php | 4 - src/Php/UniversalMethodCall.php | 4 +- tests/aot/arrow_fn/002.phpt | 2 +- .../objprop-nullable-union-default-null.phpt | 4 +- .../objprop-typed-object-null-unset.phpt | 13 +- tests/aot/static/static_prop_write.phpt | 4 +- tests/aot/type_hits/008.phpt | 34 +++++ 13 files changed, 283 insertions(+), 35 deletions(-) create mode 100644 tests/aot/type_hits/008.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 9beeb199..819c0dab 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -3536,6 +3536,20 @@ class CompilerBase extends \PhpAot\Core\Translator return $expr; } + protected function parseOrderedArg(Node\Arg $arg): string + { + if ($this->isArrayDimFetch($arg->value) and $this->isStdContainerExpr($arg->value)) { + return $this->parseArg($arg); + } + if ($this->isVarExpr($arg->value) and $arg->value->name === 'GLOBALS') { + return 'php_globals_array()'; + } + if ($this->isVarExpr($arg->value) and $this->isStdContainer($arg->value->name)) { + return $this->convertArrayExpr($this->parseIdentifier($arg->value) . '_ref'); + } + return $this->parseOrderedOperand($arg->value, false); + } + protected function parseArrayArg(Node\Arg $expr): string { $value = $expr->value; @@ -4252,7 +4266,6 @@ class CompilerBase extends \PhpAot\Core\Translator protected function getTypeConvertedArg(Node\Arg $arg, ArgInfo $argInfo): string { - $expr = $this->parseArg($arg); $type = $this->detectTypeOfExpr($arg->value); if ($argInfo->byRef) { @@ -4282,6 +4295,7 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->convertToRef($arg->value); } + $expr = $this->parseOrderedArg($arg); $expr = $this->materializeCallArgValue($arg->value, $expr); $this->checkVarAssignExpr($arg, $argInfo->type, $type); @@ -4400,6 +4414,93 @@ class CompilerBase extends \PhpAot\Core\Translator } } + protected function wrapObjectPropertyAssignTypeCheck(NodeAbstract $left, Expr $right, string $rightExpr): string + { + if (!$left->hasAttribute('nativePropertyDef')) { + return $rightExpr; + } + + /** @var PropertyDef $def */ + $def = $left->getAttribute('nativePropertyDef'); + $typeCheck = $this->getObjectPropertyAssignTypeCheck($def); + if (empty($typeCheck)) { + return $rightExpr; + } + + $rightClass = $this->detectClassOfExpr($right); + if ($rightClass !== '') { + return $rightExpr; + } + + $tmpVar = $this->addTmpVar(self::TYPE_VAR); + $conditions = []; + foreach ($typeCheck as $entry) { + $cond = $this->genSingleTypeCondition($tmpVar, $entry); + if ($cond !== '') { + $conditions[] = $cond; + } + } + if (empty($conditions)) { + return $rightExpr; + } + + $propDisplay = $this->getObjectPropertyTypeCheckDisplayName($left); + $typeStr = $this->getObjectPropertyTypeCheckTypeString($def); + $msgExpr = 'php::concat(php::concat(php::Str(' . $this->genCharPtr($propDisplay, true) . ' " must be of type " ' + . $this->genCharPtr($typeStr, true) . ' ", "), ' . $tmpVar . '.typeStr()), php::Str(" given"))'; + + return '([&]() -> ' . self::TYPE_VAR . ' { ' + . $tmpVar . ' = ' . $rightExpr . '; ' + . 'if (UNEXPECTED(!(' . implode(' || ', $conditions) . '))) { ' + . 'php::throwException(zend_ce_type_error, (' . $msgExpr . ').toCString()); ' + . '} ' + . 'return ' . $tmpVar . '; ' + . '}())'; + } + + private function getObjectPropertyAssignTypeCheck(PropertyDef $def): array + { + if (!empty($def->typeCheck)) { + return $def->typeCheck; + } + if ($def->type !== self::TYPE_OBJECT || $def->class === '') { + return []; + } + + $check = []; + if ($def->nullable) { + $check[] = ['kind' => 'isNull']; + } + $check[] = ['kind' => 'instanceof', 'class' => $def->class]; + return $check; + } + + private function getObjectPropertyTypeCheckDisplayName(NodeAbstract $left): string + { + $propName = $this->parseIdentifier($left->name); + if ($left->hasAttribute('nativeClassDef')) { + $class = $left->getAttribute('nativeClassDef')->getNamespacedName(false); + return $class . '::$' . $propName; + } + + if ($left instanceof Expr\StaticPropertyFetch) { + return $this->identifierToStr($left->class, literal: true) . '::$' . $propName; + } + + return '$' . $propName; + } + + private function getObjectPropertyTypeCheckTypeString(PropertyDef $def): string + { + if ($def->typeStr !== '') { + return $def->typeStr; + } + if ($def->class !== '') { + return ($def->nullable ? '?' : '') . $def->class; + } + return $def->type; + } + protected function parseUnset(Node\Stmt\Unset_ $node): string { $vars = $node->vars; diff --git a/src/Php/Entity/PropertyDef.php b/src/Php/Entity/PropertyDef.php index 7448d4f6..69c569b6 100644 --- a/src/Php/Entity/PropertyDef.php +++ b/src/Php/Entity/PropertyDef.php @@ -19,6 +19,8 @@ class PropertyDef public ?ArrayInitPlan $arrayInitPlan = null; public bool $nullable = false; public string $class = ''; + public array $typeCheck = []; + public string $typeStr = ''; public function __construct(string $name, int $flags, string $type, ?string $default = null, bool $nullable = false) { diff --git a/src/Php/Optimizer/FuncCallOptimizer.php b/src/Php/Optimizer/FuncCallOptimizer.php index 9a82847c..6c5bd757 100644 --- a/src/Php/Optimizer/FuncCallOptimizer.php +++ b/src/Php/Optimizer/FuncCallOptimizer.php @@ -346,7 +346,7 @@ trait FuncCallOptimizer if ($this->isVarExpr($arg) and $arg->name === 'GLOBALS') { return 'php_globals_array()'; } - return $this->parseIdentifier($arg); + return $this->parseOrderedOperand($arg, false); } protected function getRefArg(Node\Expr\FuncCall $expr, int $i): string @@ -447,7 +447,7 @@ trait FuncCallOptimizer $base = ($variadicType !== '' && ($variadicType[0] ?? '') === self::ARG_OPTIONAL) ? substr($variadicType, 1) : $variadicType; $args = []; foreach ($expr->args as $index => $arg) { - $raw = $this->parseExpr($arg->value); + $raw = $this->parseOrderedOperand($arg->value, false); $args[] = match ($base) { self::ARG_TYPE_STR => $this->convertStringExpr($raw), self::ARG_TYPE_INT => $this->convertIntExpr($raw), @@ -491,9 +491,9 @@ trait FuncCallOptimizer return false; } - $args = [$this->parseExpr($expr->args[0]->value)]; + $args = [$this->parseOrderedOperand($expr->args[0]->value, false)]; if (count($expr->args) >= 2) { - $args[] = $this->parseExpr($expr->args[1]->value); + $args[] = $this->parseOrderedOperand($expr->args[1]->value, false); } return $target . '(' . implode(', ', $args) . ')'; diff --git a/src/Php/Parser/AssignOpTrait.php b/src/Php/Parser/AssignOpTrait.php index e07de024..6fde564a 100644 --- a/src/Php/Parser/AssignOpTrait.php +++ b/src/Php/Parser/AssignOpTrait.php @@ -275,6 +275,9 @@ trait AssignOpTrait } $rightExpr = $this->parseAssignRightExpr($right); + if ($this->isPropertyFetch($left) || $this->isStaticPropertyFetch($left)) { + $rightExpr = $this->wrapObjectPropertyAssignTypeCheck($left, $right, $rightExpr); + } $leftExprType = $this->detectTypeOfExpr($left); $rightExprType = $this->detectTypeOfExpr($right); if ($finalVarType === self::TYPE_VAR) { diff --git a/src/Php/Parser/BinaryOpTrait.php b/src/Php/Parser/BinaryOpTrait.php index ceef608c..1a1e4a22 100644 --- a/src/Php/Parser/BinaryOpTrait.php +++ b/src/Php/Parser/BinaryOpTrait.php @@ -19,8 +19,8 @@ trait BinaryOpTrait protected function parseBinaryOp(NodeAbstract $left, NodeAbstract $right, string $op): string { // 运算逻辑,优先转为数字 - $leftExpr = $this->parseNumericIdentifier($left); - $rightExpr = $this->parseNumericIdentifier($right); + $leftExpr = $this->parseOrderedBinaryOperand($left); + $rightExpr = $this->parseOrderedBinaryOperand($right); $this->checkVarMustExist($left, $leftExpr); $this->checkVarMustExist($right, $rightExpr); @@ -130,6 +130,110 @@ trait BinaryOpTrait return '((' . $leftExpr . ') ' . $op . ' (' . $rightExpr . '))'; } + protected function shouldMaterializeOrderedOperand(NodeAbstract $expr): bool + { + if ($expr instanceof Expr\BinaryOp) { + return $this->shouldMaterializeOrderedOperand($expr->left) + || $this->shouldMaterializeOrderedOperand($expr->right); + } + + return $expr instanceof Expr\FuncCall + || $expr instanceof Expr\MethodCall + || $expr instanceof Expr\StaticCall + || $expr instanceof Expr\New_ + || $expr instanceof Expr\Assign + || $expr instanceof Expr\AssignRef + || $expr instanceof Expr\AssignOp + || $expr instanceof Expr\PostInc + || $expr instanceof Expr\PostDec + || $expr instanceof Expr\PreInc + || $expr instanceof Expr\PreDec + || $expr instanceof Expr\Print_ + || $expr instanceof Expr\Array_ + || $expr instanceof Expr\ArrayDimFetch + || $expr instanceof Expr\PropertyFetch + || $expr instanceof Expr\StaticPropertyFetch + || $expr instanceof Expr\Ternary + || $expr instanceof Expr\Match_ + || $expr instanceof Expr\NullsafeMethodCall + || $expr instanceof Expr\NullsafePropertyFetch + || $expr instanceof Expr\Clone_ + || $expr instanceof Expr\Include_ + || $expr instanceof Expr\Eval_; + } + + protected function parseOrderedBinaryOperand(NodeAbstract $expr): float|int|string + { + return $this->parseOrderedOperand($expr, true); + } + + protected function parseOrderedOperand(NodeAbstract $expr, bool $numeric): float|int|string + { + if (!$this->shouldMaterializeOrderedOperand($expr)) { + return $numeric ? $this->parseNumericIdentifier($expr) : $this->parseIdentifier($expr); + } + + [$value, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($expr); + $this->appendCapturedStmtLinesToContext($beforeStmts); + + $type = $this->getOrderedOperandTmpType($expr, (string) $value); + $tmpVar = $this->addTmpVar($type); + $this->context->beforeStmtLines[] = $tmpVar . ' = ' . $value . ';'; + $this->appendCapturedStmtLinesToContext($afterStmts); + return $tmpVar; + } + + protected function getOrderedOperandTmpType(NodeAbstract $expr, string $value): string + { + if ($expr instanceof Expr\BinaryOp) { + $type = $this->detectTypeOfExpr($expr); + return in_array($type, [self::TYPE_BIGINT, self::TYPE_DECIMAL, self::TYPE_BIGFLOAT], true) ? $type : self::TYPE_VAR; + } + + if ( + $expr instanceof Expr\FuncCall + || $expr instanceof Expr\MethodCall + || $expr instanceof Expr\StaticCall + ) { + $type = $this->detectTypeOfExpr($expr); + return in_array($type, [self::TYPE_BIGINT, self::TYPE_DECIMAL, self::TYPE_BIGFLOAT], true) ? $type : self::TYPE_VAR; + } + + if ($expr instanceof Expr\PropertyFetch) { + $nativePropertyVar = $expr->getAttribute('nativePropertyVar'); + if (is_string($nativePropertyVar) && $nativePropertyVar === $value) { + if (isset($this->context->objectProps[$nativePropertyVar])) { + return $this->context->objectProps[$nativePropertyVar]['type']; + } + if (!str_contains($nativePropertyVar, '.attr(') && $expr->hasAttribute('nativePropertyDef')) { + return $expr->getAttribute('nativePropertyDef')->type; + } + } + return self::TYPE_VAR; + } + + if ($expr instanceof Expr\StaticPropertyFetch) { + if ($expr->hasAttribute('nativePropertyDef') && !str_contains($value, 'getStaticProperty')) { + return $expr->getAttribute('nativePropertyDef')->type; + } + return self::TYPE_VAR; + } + + if ($expr instanceof Expr\ArrayDimFetch) { + return self::TYPE_VAR; + } + + $type = $this->detectTypeOfExpr($expr); + return $type === self::TYPE_VOID ? self::TYPE_VAR : $type; + } + + protected function appendCapturedStmtLinesToContext(array $stmts): void + { + foreach ($stmts as $stmt) { + $this->context->beforeStmtLines[] = $stmt; + } + } + protected function parseBinaryOpPlus(Expr\BinaryOp\Plus $expr): string { return $this->parseBinaryOp($expr->left, $expr->right, '+'); @@ -196,16 +300,16 @@ trait BinaryOpTrait { $leftType = $this->detectTypeOfExpr($expr->left); if ($leftType === self::TYPE_BIGINT) { - $leftExpr = $this->parseExpr($expr->left); - $rightExpr = $this->parseExpr($expr->right); + $leftExpr = $this->parseOrderedOperand($expr->left, false); + $rightExpr = $this->parseOrderedOperand($expr->right, false); $rightType = $this->detectTypeOfExpr($expr->right); if ($rightType !== self::TYPE_BIGINT) { $rightExpr = $this->convertBigIntExpr($rightExpr, $rightType); } return 'php::BigInt::pow(' . $leftExpr . ', ' . $rightExpr . ')'; } - $left = $this->parseIdentifier($expr->left); - $right = $this->parseIdentifier($expr->right); + $left = $this->parseOrderedOperand($expr->left, false); + $right = $this->parseOrderedOperand($expr->right, false); return 'php::fn::pow(' . $left . ', ' . $right . ')'; } @@ -230,7 +334,7 @@ trait BinaryOpTrait if ($this->isScalarBool($expr)) { return $this->getBoolValue($expr); } - return $this->parseIdentifier($expr); + return $this->parseOrderedOperand($expr, false); } protected function parseBinaryOpEqual(Expr\BinaryOp\Equal $expr): string @@ -353,7 +457,7 @@ trait BinaryOpTrait protected function parseBinaryOpSpaceship(Expr\BinaryOp\Spaceship $expr): string { return $this->genBigNumericCmp($expr) - ?? 'php::compare(' . $this->parseIdentifier($expr->left) . ', ' . $this->parseIdentifier($expr->right) . ')'; + ?? 'php::compare(' . $this->parseOrderedOperand($expr->left, false) . ', ' . $this->parseOrderedOperand($expr->right, false) . ')'; } protected function genBigNumericCmp(Expr\BinaryOp $expr, string $suffix = ''): ?string @@ -362,8 +466,8 @@ trait BinaryOpTrait $rightType = $this->detectTypeOfExpr($expr->right); if ($leftType === self::TYPE_BIGFLOAT || $rightType === self::TYPE_BIGFLOAT) { - $leftExpr = $this->parseExpr($expr->left); - $rightExpr = $this->parseExpr($expr->right); + $leftExpr = $this->parseOrderedOperand($expr->left, false); + $rightExpr = $this->parseOrderedOperand($expr->right, false); if ($leftType !== self::TYPE_BIGFLOAT) { $leftExpr = $this->convertBigFloatExpr($leftExpr, $leftType); } @@ -373,8 +477,8 @@ trait BinaryOpTrait return 'php::BigFloat::cmp(' . $leftExpr . ', ' . $rightExpr . ')' . $suffix; } if ($leftType === self::TYPE_BIGINT || $rightType === self::TYPE_BIGINT) { - $leftExpr = $this->parseExpr($expr->left); - $rightExpr = $this->parseExpr($expr->right); + $leftExpr = $this->parseOrderedOperand($expr->left, false); + $rightExpr = $this->parseOrderedOperand($expr->right, false); if ($leftType !== self::TYPE_BIGINT) { $leftExpr = $this->convertBigIntExpr($leftExpr, $leftType); } @@ -384,8 +488,8 @@ trait BinaryOpTrait return 'php::BigInt::cmp(' . $leftExpr . ', ' . $rightExpr . ')' . $suffix; } if ($leftType === self::TYPE_DECIMAL || $rightType === self::TYPE_DECIMAL) { - $leftExpr = $this->parseExpr($expr->left); - $rightExpr = $this->parseExpr($expr->right); + $leftExpr = $this->parseOrderedOperand($expr->left, false); + $rightExpr = $this->parseOrderedOperand($expr->right, false); if ($leftType !== self::TYPE_DECIMAL) { $leftExpr = $this->convertDecimalExpr($leftExpr, $leftType, $expr->left); } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 13097bb8..0fce7e30 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -629,6 +629,11 @@ class Preprocessor extends CompilerBase $propDef = new PropertyDef($name, $flags, $type, $default, $nullable); $propDef->class = $class; $propDef->arrayInitPlan = $arrayInitPlan; + if ($typeNode instanceof NullableType || $typeNode instanceof UnionType || $typeNode instanceof IntersectionType) { + $typeInfo = $this->buildTypeCheckFromNode($typeNode); + $propDef->typeCheck = $typeInfo['check']; + $propDef->typeStr = $typeInfo['typeStr']; + } $this->classDef->properties[$name] = $propDef; return $propDef; } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 9439af7b..b65c848f 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -561,10 +561,6 @@ class Translator extends Preprocessor $this->climate->red('The target name `' . $name . '` must be a valid identifier'); exit(1); } - if (in_array($name, Constants::CPP_RESERVED_NAMES)) { - $this->climate->red('The target name `' . $name . '` must not be a reserved keyword'); - exit(1); - } $realTargetPath = $this->rootPath . '/' . $name; if (is_dir($realTargetPath)) { $this->climate->red('The target name `' . $name . '` must not be a directory'); diff --git a/src/Php/UniversalMethodCall.php b/src/Php/UniversalMethodCall.php index 2316f822..cbe8bf91 100644 --- a/src/Php/UniversalMethodCall.php +++ b/src/Php/UniversalMethodCall.php @@ -674,7 +674,7 @@ trait UniversalMethodCall } $argExprs = []; foreach ($args as $i => $arg) { - $expr = $this->parseExpr($arg->value); + $expr = $this->parseOrderedOperand($arg->value, false); if (in_array($i, $intCastArgs, true)) { $expr = 'php::toInt(' . $expr . ')'; } @@ -804,7 +804,7 @@ trait UniversalMethodCall { $userArgs = []; foreach ($args as $arg) { - $userArgs[] = $this->parseExpr($arg->value); + $userArgs[] = $this->parseOrderedOperand($arg->value, false); } if ($receiverPos === 0) { diff --git a/tests/aot/arrow_fn/002.phpt b/tests/aot/arrow_fn/002.phpt index 56ba5c2d..67cb80b3 100644 --- a/tests/aot/arrow_fn/002.phpt +++ b/tests/aot/arrow_fn/002.phpt @@ -5,7 +5,7 @@ arrow function 2 function main() { $array = [1, 5, 9]; - $fn1 = fn($x) => var_dump(0, ...$array); + $fn1 = fn() => var_dump(0, ...$array); $fn1(); } ?> diff --git a/tests/aot/optimizations/objprop-nullable-union-default-null.phpt b/tests/aot/optimizations/objprop-nullable-union-default-null.phpt index 430acdae..7e3ac712 100644 --- a/tests/aot/optimizations/objprop-nullable-union-default-null.phpt +++ b/tests/aot/optimizations/objprop-nullable-union-default-null.phpt @@ -23,7 +23,7 @@ class FlexibleDefaults { $this->nullable = null; $this->nullableObject = null; - $this->union = null; + $this->union = ''; var_dump($this->nullable); var_dump($this->nullableObject); var_dump($this->union); @@ -43,4 +43,4 @@ NULL string(2) "ok" NULL NULL -NULL +string(0) "" diff --git a/tests/aot/optimizations/objprop-typed-object-null-unset.phpt b/tests/aot/optimizations/objprop-typed-object-null-unset.phpt index 9da6fa2d..76fb6c85 100644 --- a/tests/aot/optimizations/objprop-typed-object-null-unset.phpt +++ b/tests/aot/optimizations/objprop-typed-object-null-unset.phpt @@ -1,5 +1,5 @@ --TEST-- -SSA object prop: typed object property allows null and unset +SSA object prop: typed object property rejects null and supports unset --FILE-- prop)); var_dump($this->prop->name()); - $this->prop = null; + try { + $this->prop = null; + } catch (TypeError $e) { + var_dump($e->getMessage()); + } var_dump(isset($this->prop)); - var_dump($this->prop); $this->prop = new ObjPropValue(); unset($this->prop); @@ -51,8 +54,8 @@ function main(): void { --EXPECT-- bool(true) string(5) "value" -bool(false) -NULL +string(61) "ObjPropHolder::$prop must be of type ObjPropValue, null given" +bool(true) bool(false) string(5) "value" string(5) "value" diff --git a/tests/aot/static/static_prop_write.phpt b/tests/aot/static/static_prop_write.phpt index 7b71c01d..d25a74a8 100644 --- a/tests/aot/static/static_prop_write.phpt +++ b/tests/aot/static/static_prop_write.phpt @@ -13,12 +13,12 @@ class Select { class Worker { - public static ?stdClass $globalEvent = null; + public static ?Select $globalEvent = null; public static string $eventLoopClass = 'Select'; public static function init() { self::$globalEvent = new static::$eventLoopClass(); - self::$globalEvent->setErrorHandler(function ($exception) { + self::$globalEvent->setErrorHandler(function () { var_dump(__FUNCTION__); }); } diff --git a/tests/aot/type_hits/008.phpt b/tests/aot/type_hits/008.phpt new file mode 100644 index 00000000..bbacd54c --- /dev/null +++ b/tests/aot/type_hits/008.phpt @@ -0,0 +1,34 @@ +--TEST-- +type hits +--FILE-- +getMessage()); + } + } +} + +function main() { + Worker::init(); +} +?> +--EXPECT-- +string(8) "stdClass" +NULL +string(60) "Worker::$globalEvent must be of type ?stdClass, object given" From f8c37f91c37540743790ce97ab8d09c6f79daa30 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 17:08:29 +0800 Subject: [PATCH 28/37] =?UTF-8?q?test(type):=20=E6=B7=BB=E5=8A=A0=E7=B1=BB?= =?UTF-8?q?=E5=9E=8B=E6=A3=80=E6=9F=A5=E5=92=8C=E5=B1=9E=E6=80=A7=E8=B5=8B?= =?UTF-8?q?=E5=80=BC=E7=9B=B8=E5=85=B3=E6=B5=8B=E8=AF=95=E7=94=A8=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加实例属性类型检查消息包含类名的测试用例 - 添加属性联合赋值操作使用运行时类型检查的测试用例 - 添加动态属性赋值TypeError捕获的测试用例 - 添加二元运算符操作数从左到右求值顺序的测试用例 - 添加原生优化调用参数从左到右求值的测试用例 - 添加构造函数属性提升联合参数检查的测试用例 fix(assign): 修复属性赋值时的类型检查问题 - 在属性赋值操作中添加对象属性类型检查包装 - 修复属性赋值表达式中的类型验证逻辑 - 添加静态属性赋值的类型检查支持 fix(ctor): 修复构造函数属性提升的参数验证顺序 - 将构造函数属性提升移到参数类型验证之后执行 - 在数组初始化计划后添加错误检查机制 --- ...ternal-call-missing-required-named-arg.php | 6 +++ .../code/internal-call-unknown-named-arg.php | 6 +++ phpunit/code/unpack-after-named-arg.php | 10 +++++ src/Php/Parser/AssignOpTrait.php | 10 +++++ src/Php/Translator.php | 15 ++++---- .../promotion-union-param-check.phpt | 24 ++++++++++++ tests/aot/operator/binary-eval-order.phpt | 38 +++++++++++++++++++ tests/aot/stdlib/native-arg-eval-order.phpt | 23 +++++++++++ tests/aot/type_hits/009.phpt | 25 ++++++++++++ tests/aot/type_hits/010.phpt | 32 ++++++++++++++++ tests/aot/type_hits/011.phpt | 30 +++++++++++++++ 11 files changed, 212 insertions(+), 7 deletions(-) create mode 100644 phpunit/code/internal-call-missing-required-named-arg.php create mode 100644 phpunit/code/internal-call-unknown-named-arg.php create mode 100644 phpunit/code/unpack-after-named-arg.php create mode 100644 tests/aot/object_ctor/promotion-union-param-check.phpt create mode 100644 tests/aot/operator/binary-eval-order.phpt create mode 100644 tests/aot/stdlib/native-arg-eval-order.phpt create mode 100644 tests/aot/type_hits/009.phpt create mode 100644 tests/aot/type_hits/010.phpt create mode 100644 tests/aot/type_hits/011.phpt diff --git a/phpunit/code/internal-call-missing-required-named-arg.php b/phpunit/code/internal-call-missing-required-named-arg.php new file mode 100644 index 00000000..750e71ca --- /dev/null +++ b/phpunit/code/internal-call-missing-required-named-arg.php @@ -0,0 +1,6 @@ +parseIdentifier($left->var); $propName = $this->identifierToStr($left->name, literal: true); $rightExpr = $this->trimBrackets($this->parseExpr($right)); + $rightExpr = $this->wrapObjectPropertyAssignTypeCheck($left, $right, $rightExpr); $tmp = $this->genTmpVarName(); $this->addLocalVar($tmp, self::TYPE_VAR); @@ -585,7 +586,16 @@ trait AssignOpTrait $var = $this->parseIdentifier($expr->var); $this->context->inAssignExpr = $inAssignExpr; + if ($this->isPropertyFetch($expr->var)) { + $this->assertCanAssignObjectProp($expr->var, $expr->expr); + } elseif ($this->isStaticPropertyFetch($expr->var)) { + $this->assertCanAssignStaticProp($expr->var, $expr->expr); + } + $right = $this->parseExpr($expr->expr); + if ($this->isPropertyFetch($expr->var) || $this->isStaticPropertyFetch($expr->var)) { + $right = $this->wrapObjectPropertyAssignTypeCheck($expr->var, $expr->expr, $right); + } if ($this->isVarExpr($expr->expr) and !$this->hasVar($right)) { $this->errorUndefinedVariable($expr->expr); } diff --git a/src/Php/Translator.php b/src/Php/Translator.php index b65c848f..4e7d8059 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -1790,6 +1790,7 @@ CODE; if (!$property->isStatic() && $property->arrayInitPlan && $property->default) { $body = "auto value = {$property->arrayInitPlan->expr};\n"; $body .= 'zend_update_property(obj->ce, obj, ' . $this->genZendStrl($property->name) . ", value.ptr());\n"; + $body .= "php::throwErrorIfOccurred();\n"; $code .= $this->wrapArrayInitPlan($property->arrayInitPlan, $body); } } @@ -3120,19 +3121,19 @@ CODE; $this->indentLevel++; $code .= $this->genScopeVarDecl(); $code .= "\n"; - // Constructor Property Promotion - foreach ($this->functionDef->argInfoList as $argInfo) { - if (!$argInfo->property) { - continue; - } - $code .= $this->genPropertyPromotion($argInfo); - } // Runtime union/nullable parameter type checks foreach ($this->functionDef->argInfoList as $i => $argInfo) { if (!empty($argInfo->typeCheck)) { $code .= $this->genUnionParamCheck($argInfo, $i); } } + // Constructor Property Promotion happens after parameter type validation. + foreach ($this->functionDef->argInfoList as $argInfo) { + if (!$argInfo->property) { + continue; + } + $code .= $this->genPropertyPromotion($argInfo); + } $this->indentLevel--; // 构建 PHP 级别的函数名用于 debug backtrace if ($this->class) { diff --git a/tests/aot/object_ctor/promotion-union-param-check.phpt b/tests/aot/object_ctor/promotion-union-param-check.phpt new file mode 100644 index 00000000..501e95dc --- /dev/null +++ b/tests/aot/object_ctor/promotion-union-param-check.phpt @@ -0,0 +1,24 @@ +--TEST-- +Constructor property promotion checks union parameter before assignment +--ENV-- +USE_ZEND_ALLOC=0 +--FILE-- +getMessage()); + } +} +?> +--EXPECT-- +string(96) "PromotedUnionHolder::__construct(): Argument #1 ($value) must be of type int|string, array given" diff --git a/tests/aot/operator/binary-eval-order.phpt b/tests/aot/operator/binary-eval-order.phpt new file mode 100644 index 00000000..5e77f978 --- /dev/null +++ b/tests/aot/operator/binary-eval-order.phpt @@ -0,0 +1,38 @@ +--TEST-- +Binary operator operands are evaluated left-to-right +--FILE-- + (print "spaceship-right\n")); + var_dump((print "pow-left\n") ** (print "pow-right\n")); + var_dump(((print "logic-left\n") && false && (print "logic-right\n")) + (print "logic-after\n")); +} +?> +--EXPECT-- +sub-left +sub-right +int(0) +nested-left +nested-right-left +nested-right-right +int(2) +eq-left +eq-right +bool(true) +same-left +same-right +bool(true) +spaceship-left +spaceship-right +int(0) +pow-left +pow-right +int(1) +logic-left +logic-after +int(1) diff --git a/tests/aot/stdlib/native-arg-eval-order.phpt b/tests/aot/stdlib/native-arg-eval-order.phpt new file mode 100644 index 00000000..ac72de80 --- /dev/null +++ b/tests/aot/stdlib/native-arg-eval-order.phpt @@ -0,0 +1,23 @@ +--TEST-- +Native optimized calls evaluate arguments left-to-right +--FILE-- +'; +var_dump($text->replace((print "method-left\n") ? "x" : "x", (print "method-right\n") ? "y" : "y")); +?> +--EXPECT-- +repeat-left +repeat-right +string(2) "xx" +round-left +round-right +float(2.3) +cmp-left +cmp-right +int(-1) +method-left +method-right +string(3) "" diff --git a/tests/aot/type_hits/009.phpt b/tests/aot/type_hits/009.phpt new file mode 100644 index 00000000..28763bbe --- /dev/null +++ b/tests/aot/type_hits/009.phpt @@ -0,0 +1,25 @@ +--TEST-- +type hits: instance property type check message includes class name +--FILE-- +union = null; + } catch (TypeError $e) { + var_dump($e->getMessage()); + } + } +} + +function main() +{ + (new TypeHitPropertyMessage())->setInvalid(); +} +?> +--EXPECT-- +string(69) "TypeHitPropertyMessage::$union must be of type int|string, null given" diff --git a/tests/aot/type_hits/010.phpt b/tests/aot/type_hits/010.phpt new file mode 100644 index 00000000..ab024bd4 --- /dev/null +++ b/tests/aot/type_hits/010.phpt @@ -0,0 +1,32 @@ +--TEST-- +type hits: property coalesce assignment uses runtime type check +--ENV-- +USE_ZEND_ALLOC=0 +--FILE-- +union ??= null; + } catch (TypeError $e) { + var_dump($e->getMessage()); + } + + $this->union = "ok"; + $this->union ??= null; + var_dump($this->union); + } +} + +function main(): void +{ + (new TypeHitCoalesceProperty())->run(); +} +?> +--EXPECT-- +string(70) "TypeHitCoalesceProperty::$union must be of type int|string, null given" +string(2) "ok" diff --git a/tests/aot/type_hits/011.phpt b/tests/aot/type_hits/011.phpt new file mode 100644 index 00000000..4c195609 --- /dev/null +++ b/tests/aot/type_hits/011.phpt @@ -0,0 +1,30 @@ +--TEST-- +AOT dynamic property assignment TypeError can be caught +--FILE-- +$prop = $value; + var_dump('not reached'); + } catch (TypeError $e) { + var_dump(get_class($e)); + var_dump(str_contains($e->getMessage(), 'Cannot assign null to property TypeHitDynamicProperty::$union')); + } +} + +function main(): void +{ + $obj = new TypeHitDynamicProperty(); + assign_dynamic($obj, 'union', null); + $obj->union = 'ok'; + var_dump($obj->union); +} +?> +--EXPECT-- +string(9) "TypeError" +bool(true) +string(2) "ok" From 2a9fcfb6658b2e0e1806e831f603af4898fbd080 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 17:18:24 +0800 Subject: [PATCH 29/37] =?UTF-8?q?fix(php):=20=E4=BF=AE=E5=A4=8Dthrow?= =?UTF-8?q?=E8=AF=AD=E5=8F=A5=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E5=92=8C?= =?UTF-8?q?=E5=AF=B9=E8=B1=A1=E8=BD=AC=E6=8D=A2=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了表达式类型检测来确保只抛出对象类型 - 重构了throw语句的C++代码生成逻辑 - 优化了catch块中的类型检查条件构建方式 - 添加了对抛出非对象类型的静态错误检查 - 新增了throw标量值的测试用例 --- phpunit/code/throw-scalar.php | 6 ++++++ phpunit/src/ThrowTest.php | 9 +++++++++ src/Php/CompilerBase.php | 21 ++++++++++++++------- 3 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 phpunit/code/throw-scalar.php create mode 100644 phpunit/src/ThrowTest.php diff --git a/phpunit/code/throw-scalar.php b/phpunit/code/throw-scalar.php new file mode 100644 index 00000000..2ade20a9 --- /dev/null +++ b/phpunit/code/throw-scalar.php @@ -0,0 +1,6 @@ +exec('Can only throw objects', 'throw-scalar.php'); + } +} diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 819c0dab..311d6e9e 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -5697,19 +5697,24 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->method === '__destruct') { $this->warning($expr, "Throwing exception in {$this->getFullClassName()}::__destruct() may cause memory leak"); } + $type = $this->detectTypeOfExpr($expr->expr); if ($this->isNewExpr($expr->expr)) { $ex = $this->parseExpr($expr->expr); + return 'php::throwException(' . $ex . ')'; } elseif ($this->isVarExpr($expr->expr)) { $ex = $this->parseIdentifier($expr->expr); - if ($this->getVarType($ex) != self::TYPE_OBJECT) { - goto _to_object; + if ($type == self::TYPE_OBJECT) { + return 'php::throwException(' . $ex . ')'; } } else { - $ex = $this->parseIdentifier($expr->expr); - _to_object: - $ex = $this->convertObjectExpr($ex); + $ex = $this->parseExpr($expr->expr); } - return 'php::throwException(' . $ex . ')'; + if ($type != self::TYPE_VAR) { + $this->fatalError($expr, 'Can only throw objects'); + } + $tmp = $this->genTmpVarName(); + $this->addLocalVar($tmp, self::TYPE_VAR); + return '([&]() -> php::Var { ' . $tmp . ' = ' . $ex . '; if (!' . $tmp . '.isObject()) { php::throwError("Can only throw objects"); } return php::throwException(php::Object(' . $tmp . ')); })()'; } protected function parseTryCatch(mixed $v): string @@ -5760,16 +5765,18 @@ class CompilerBase extends \PhpAot\Core\Translator $code .= $this->parseBeforeStmtLines() . PHP_EOL; $code .= $this->getIndent() . 'if (' . $var . ' && '; + $conditions = []; foreach ($types as $type) { if ($this->isNameExpr($type) or $this->isFullNameExpr($type)) { $class = $this->getNamespacedClassName($this->parseIdentifier($type)); $ce = $this->getClassEntryPtr($class); - $code .= Symbol::instanceOf() . '(' . $var . ', ' . $ce . ')'; + $conditions[] = Symbol::instanceOf() . '(' . $var . ', ' . $ce . ')'; } else { $this->fatalError($type, 'Unsupported catch type'); } } + $code .= implode(' || ', $conditions); $code .= ') {' . PHP_EOL; $this->indentLevel++; $code .= $this->parseStmts($catch->stmts); From 3d6e0b5689feee5c0cfc8ee22cfe1b9c6b85b0f3 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 17:34:58 +0800 Subject: [PATCH 30/37] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E8=A7=A3=E5=8C=85=E5=90=8E=E4=BD=8D=E7=BD=AE?= =?UTF-8?q?=E5=8F=82=E6=95=B0=E7=9A=84=E9=AA=8C=E8=AF=81=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在函数调用参数验证中添加了对参数解包的支持 - 实现了 hasUnpackCallArg 方法用于检测参数解包 - 添加了 shouldUseDynamicCallForNativeArgs 方法优化动态调用判断 - 修复了参数解包后不能跟位置参数的错误检查逻辑 - 更新了命名参数和解包参数的验证顺序 - 添加了多个测试用例验证参数解包功能的正确性 - 增加了 AOT 测试确保多异常捕获和抛出异常对象的功能正常 --- .../dynamic-call-positional-after-unpack.php | 11 ++++ .../native-call-positional-after-unpack.php | 10 +++ phpunit/code/new-positional-after-unpack.php | 13 ++++ phpunit/src/FunctionTest.php | 15 +++++ src/Php/CompilerBase.php | 65 +++++++++++++++++-- tests/aot/exception/multi-catch.phpt | 29 +++++++++ tests/aot/exception/throw-invalid.phpt | 32 +++++++++ tests/aot/functions/unpack-fixed-native.phpt | 45 +++++++++++++ 8 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 phpunit/code/dynamic-call-positional-after-unpack.php create mode 100644 phpunit/code/native-call-positional-after-unpack.php create mode 100644 phpunit/code/new-positional-after-unpack.php create mode 100644 tests/aot/exception/multi-catch.phpt create mode 100644 tests/aot/exception/throw-invalid.phpt create mode 100644 tests/aot/functions/unpack-fixed-native.phpt diff --git a/phpunit/code/dynamic-call-positional-after-unpack.php b/phpunit/code/dynamic-call-positional-after-unpack.php new file mode 100644 index 00000000..6f907784 --- /dev/null +++ b/phpunit/code/dynamic-call-positional-after-unpack.php @@ -0,0 +1,11 @@ +exec('Cannot use argument unpacking after named arguments', 'unpack-after-named-arg.php'); } + public function testNativeCallPositionalAfterUnpack() + { + $this->exec('Cannot use positional argument after argument unpacking', 'native-call-positional-after-unpack.php'); + } + + public function testDynamicCallPositionalAfterUnpack() + { + $this->exec('Cannot use positional argument after argument unpacking', 'dynamic-call-positional-after-unpack.php'); + } + + public function testNewPositionalAfterUnpack() + { + $this->exec('Cannot use positional argument after argument unpacking', 'new-positional-after-unpack.php'); + } + } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 311d6e9e..e374ec1f 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -1894,6 +1894,10 @@ class CompilerBase extends \PhpAot\Core\Translator { $this->validateNativeNamedCallArgs($funcDef, $args); + if ($this->hasUnpackCallArg($args)) { + return; + } + $argc = count($args); $type = str_contains($name, '::') ? 'Method' : 'Function'; if ($argc < $funcDef->argCountRequired) { @@ -1924,6 +1928,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function validateNativeNamedCallArgs(FunctionDef $functionDef, array $callArgs): void { $hasNamedArg = false; + $hasUnpack = false; $seenNamedArgs = []; $providedArgIndexes = []; $argNameIndex = $this->getFunctionArgNameIndex($functionDef); @@ -1937,10 +1942,14 @@ class CompilerBase extends \PhpAot\Core\Translator if ($hasNamedArg) { $this->fatalError($arg, 'Cannot use argument unpacking after named arguments'); } + $hasUnpack = true; $providedArgIndexes[$i] = true; continue; } if ($arg->name === null) { + if ($hasUnpack) { + $this->fatalError($arg, 'Cannot use positional argument after argument unpacking'); + } if ($hasNamedArg) { $this->fatalError($arg, 'Cannot use positional argument after named argument'); } @@ -2924,6 +2933,9 @@ class CompilerBase extends \PhpAot\Core\Translator return; } $this->validateInternalNamedCallArgs($ref, $expr->args); + if ($this->hasUnpackCallArg($expr->args)) { + return; + } $minArgs = $ref->getNumberOfRequiredParameters(); $maxArgs = $ref->getNumberOfParameters(); $actualArgCount = count($expr->args); @@ -2961,6 +2973,37 @@ class CompilerBase extends \PhpAot\Core\Translator return false; } + protected function hasUnpackCallArg(array $args): bool + { + foreach ($args as $arg) { + if ($arg instanceof Node\Arg && $arg->unpack) { + return true; + } + } + return false; + } + + protected function shouldUseDynamicCallForNativeArgs(string $nativeFunc, array $args): bool + { + if (!$this->hasUnpackCallArg($args)) { + return false; + } + if ($this->hasUnpackBeforeNamedArg($args)) { + return true; + } + + $variadicArgIndex = $this->getVariadicArgIndex($this->getFunction($nativeFunc)); + foreach ($args as $i => $arg) { + if (!$arg instanceof Node\Arg || !$arg->unpack) { + continue; + } + if ($variadicArgIndex === null || $i < $variadicArgIndex) { + return true; + } + } + return false; + } + protected function genCallUserFuncArray(string $callback, array $args, string $funcName = '', string $className = ''): string { return 'php::call(' . $this->getFuncPtr('call_user_func_array') . ', ' @@ -2976,6 +3019,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function validateInternalNamedCallArgs(\ReflectionFunctionAbstract $ref, array $callArgs): void { $hasNamedArg = false; + $hasUnpack = false; $seenNamedArgs = []; $providedArgIndexes = []; $argNameIndex = []; @@ -3000,10 +3044,14 @@ class CompilerBase extends \PhpAot\Core\Translator if ($hasNamedArg) { $this->fatalError($arg, 'Cannot use argument unpacking after named arguments'); } + $hasUnpack = true; $providedArgIndexes[$i] = true; continue; } if ($arg->name === null) { + if ($hasUnpack) { + $this->fatalError($arg, 'Cannot use positional argument after argument unpacking'); + } if ($hasNamedArg) { $this->fatalError($arg, 'Cannot use positional argument after named argument'); } @@ -3042,7 +3090,7 @@ class CompilerBase extends \PhpAot\Core\Translator $hasNamedArg = true; } - if ($hasNamedArg) { + if ($hasNamedArg && !$hasUnpack) { foreach ($requiredArgIndexes as $index => $name) { if (!isset($providedArgIndexes[$index])) { $this->fatalError($callArgs[array_key_last($callArgs)] ?? null, "Named argument `{$name}` is missing default value"); @@ -3073,7 +3121,7 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->genPlaceHolder($this->identifierToStr($expr->name)); } $this->checkNativeCallArgs($expr, $this->getFunction($nativeFn), $expr->args, $name); - if ($this->hasUnpackBeforeNamedArg($expr->args)) { + if ($this->shouldUseDynamicCallForNativeArgs($nativeFn, $expr->args)) { return $this->genCallUserFuncArray($this->getFunctionCallbackExpr($nativeFn), $expr->args, $name); } try { @@ -3282,6 +3330,7 @@ class CompilerBase extends \PhpAot\Core\Translator $namedArgsVar = null; $namedArgs = []; $hasNamedArg = false; + $hasUnpack = false; $ensureArrayArgs = function () use (&$arrayArgsVar, &$list_args): string { if ($arrayArgsVar === null) { @@ -3321,6 +3370,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($hasNamedArg) { $this->fatalError($arg, 'Cannot use argument unpacking after named arguments'); } + $hasUnpack = true; $arrayArgs = $ensureArrayArgs(); $this->context->beforeStmtLines[] = $arrayArgs . '.merge(' . $this->parseArrayArg($arg) . ');'; continue; @@ -3346,6 +3396,9 @@ class CompilerBase extends \PhpAot\Core\Translator if ($hasNamedArg) { $this->fatalError($arg, 'Cannot use positional argument after named argument'); } + if ($hasUnpack) { + $this->fatalError($arg, 'Cannot use positional argument after argument unpacking'); + } $byRef = $funcName && $this->isReferenceArgument($funcName, $className, $i); if ($this->isVarExpr($arg->value)) { $name = $this->parseIdentifier($arg->value); @@ -3362,7 +3415,7 @@ class CompilerBase extends \PhpAot\Core\Translator $this->fatalError($arg, 'Undefined variable `$' . $obj . '`'); } if ($byRef) { - $list_args[] = $obj . '.attrRef(' . $this->identifierToStr($arg->value->name) . ')'; + $addPositionalArg($obj . '.attrRef(' . $this->identifierToStr($arg->value->name) . ')'); continue; } } elseif ($this->isArrayDimFetch($arg->value) and $this->isVarExpr($arg->value->var)) { @@ -5277,8 +5330,8 @@ class CompilerBase extends \PhpAot\Core\Translator if ($nativeFunc) { $expr->setAttribute('nativeCall', $nativeFunc); try { - if ($this->hasUnpackBeforeNamedArg($expr->args)) { - return $this->genCallUserFuncArray($this->genArray([$object, $method]), $expr->args, $funcName, $class); + if ($this->shouldUseDynamicCallForNativeArgs($nativeFunc, $expr->args)) { + return $this->genCallUserFuncArray($this->genArray([$object, $method]), $expr->args, $methodName, $class); } return $this->parseNativeMethodCall($object, $nativeFunc, $expr->args); } catch (PlaceHolder) { @@ -5426,7 +5479,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($nativeFunc) { try { - if ($this->hasUnpackBeforeNamedArg($expr->args)) { + if ($this->shouldUseDynamicCallForNativeArgs($nativeFunc, $expr->args)) { return $this->genCallUserFuncArray($this->genArray($callScope), $expr->args, $method, $class); } $args = $this->parseNativeCallArgs($expr->args, $nativeFunc); diff --git a/tests/aot/exception/multi-catch.phpt b/tests/aot/exception/multi-catch.phpt new file mode 100644 index 00000000..ec53d1f2 --- /dev/null +++ b/tests/aot/exception/multi-catch.phpt @@ -0,0 +1,29 @@ +--TEST-- +AOT multi-catch handles alternative exception types +--FILE-- +getMessage()); + } + } +} +?> +--EXPECT-- +string(5) "first" +string(6) "second" diff --git a/tests/aot/exception/throw-invalid.phpt b/tests/aot/exception/throw-invalid.phpt new file mode 100644 index 00000000..483b0515 --- /dev/null +++ b/tests/aot/exception/throw-invalid.phpt @@ -0,0 +1,32 @@ +--TEST-- +AOT invalid throw object matches PHP error +--FILE-- +getMessage()); + } + + try { + throw_non_throwable_object(); + } catch (Error $e) { + var_dump($e->getMessage()); + } +} +?> +--EXPECT-- +string(22) "Can only throw objects" +string(52) "Cannot throw objects that do not implement Throwable" diff --git a/tests/aot/functions/unpack-fixed-native.phpt b/tests/aot/functions/unpack-fixed-native.phpt new file mode 100644 index 00000000..11731c61 --- /dev/null +++ b/tests/aot/functions/unpack-fixed-native.phpt @@ -0,0 +1,45 @@ +--TEST-- +Argument unpacking can fill fixed native parameters +--FILE-- +method(...[9, 10]); + NativeUnpackTarget::staticMethod(...[11, 12]); +} + +?> +--EXPECT-- +1,2 +3:4,5 +6:7,8 +m=9,10 +s=11,12 From 399f77d5c57e37f62f0dac9b32f2d55a45e00de4 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 17:48:57 +0800 Subject: [PATCH 31/37] =?UTF-8?q?feat(php):=20=E5=AE=9E=E7=8E=B0=E5=AF=B9?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E5=8F=82=E6=95=B0=E5=BC=95=E7=94=A8=E4=BC=A0?= =?UTF-8?q?=E9=80=92=E7=9A=84=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加了 AOT 调用参数信息获取功能 - 实现了按索引和名称获取参数信息的方法 - 增加了对命名参数引用传递的判断支持 - 添加了引用参数值解析功能 - 优化了新对象构造函数参数传递逻辑 - 完善了对动态调用和继承链的参数分析 - 新增静态函数、方法和构造函数引用参数测试用例 --- src/Php/CompilerBase.php | 179 ++++++++++++++++++++++++++- tests/aot/ref/static-byref-call.phpt | 54 ++++++++ 2 files changed, 230 insertions(+), 3 deletions(-) create mode 100644 tests/aot/ref/static-byref-call.phpt diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index e374ec1f..0cc2070d 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -3298,6 +3298,11 @@ class CompilerBase extends \PhpAot\Core\Translator protected function isReferenceArgument($funcName, $className, $argIndex): bool { + $argInfo = $this->getAotCallArgInfo($funcName, $className, $argIndex); + if ($argInfo !== null) { + return $argInfo->byRef; + } + if ($className) { // 动态调用类方法,无法判断参数是否为引用 if ($className === self::DYNAMIC_CALLED_CLASS) { @@ -3317,6 +3322,119 @@ class CompilerBase extends \PhpAot\Core\Translator return $variadicParam !== null && $variadicParam->isPassedByReference(); } + protected function getAotCallArgInfo(string $funcName, string $className, int $argIndex): ?ArgInfo + { + if ($className !== '') { + if ($className === self::DYNAMIC_CALLED_CLASS || !$this->hasClass($className)) { + return null; + } + $classDef = $this->getClass($className); + while (true) { + if ($classDef->hasMethod($funcName)) { + return $this->getArgInfoByIndex($classDef->getMethod($funcName)->functionDef, $argIndex); + } + if (!$classDef->extends || !$this->hasClass($classDef->extends)) { + return null; + } + $classDef = $this->getClass($classDef->extends); + } + } + + if (!$this->hasFunction($funcName)) { + return null; + } + return $this->getArgInfoByIndex($this->getFunction($funcName), $argIndex); + } + + protected function getAotCallArgInfoByName(string $funcName, string $className, string $argName): ?ArgInfo + { + $functionDef = null; + if ($className !== '') { + if ($className === self::DYNAMIC_CALLED_CLASS || !$this->hasClass($className)) { + return null; + } + $classDef = $this->getClass($className); + while (true) { + if ($classDef->hasMethod($funcName)) { + $functionDef = $classDef->getMethod($funcName)->functionDef; + break; + } + if (!$classDef->extends || !$this->hasClass($classDef->extends)) { + return null; + } + $classDef = $this->getClass($classDef->extends); + } + } elseif ($this->hasFunction($funcName)) { + $functionDef = $this->getFunction($funcName); + } + + if ($functionDef === null) { + return null; + } + + $variadicArgInfo = null; + foreach ($functionDef->argInfoList as $argInfo) { + if ($argInfo->variadic) { + $variadicArgInfo = $argInfo; + } + if (($argInfo->phpName ?: $this->unescapeVarName($argInfo->name)) === $argName) { + return $argInfo; + } + } + return $variadicArgInfo; + } + + protected function getArgInfoByIndex(FunctionDef $functionDef, int $argIndex): ?ArgInfo + { + if (array_key_exists($argIndex, $functionDef->argInfoList)) { + return $functionDef->argInfoList[$argIndex]; + } + if ($functionDef->hasVariadicArg()) { + return $functionDef->argInfoList[array_key_last($functionDef->argInfoList)]; + } + return null; + } + + protected function isReferenceNamedArgument(string $funcName, string $className, string $argName): bool + { + $argInfo = $this->getAotCallArgInfoByName($funcName, $className, $argName); + if ($argInfo !== null) { + return $argInfo->byRef; + } + + if ($className) { + if ($className === self::DYNAMIC_CALLED_CLASS) { + return false; + } + $ref = Reflection::getClass($className); + if (!$ref) { + return false; + } + try { + $params = $ref->getMethod($funcName)->getParameters(); + } catch (\ReflectionException) { + return false; + } + } else { + $ref = Reflection::getFunction($funcName); + if (!$ref) { + return false; + } + $params = $ref->getParameters(); + } + + $variadicParam = null; + foreach ($params as $param) { + if ($param->isVariadic()) { + $variadicParam = $param; + } + if ($param->getName() === $argName) { + return $param->isPassedByReference(); + } + } + return $variadicParam !== null && $variadicParam->isPassedByReference(); + } + protected function parseCallArgs( array $args, string $funcName = '', @@ -3384,12 +3502,16 @@ class CompilerBase extends \PhpAot\Core\Translator $this->fatalError($arg, "Duplicate named argument `{$arg->name->name}`"); } $namedArgs[$arg->name->name] = true; + $byRef = $funcName && $this->isReferenceNamedArgument($funcName, $className, $arg->name->name); + $value = ($byRef || $this->isRefvalCall($arg->value)) + ? $this->parseReferenceCallArgValue($arg) + : $this->parseCallArgValue($arg); if ($separateNamedArgs) { $namedArgsArray = $ensureNamedArgs(); - $this->context->beforeStmtLines[] = $namedArgsArray . '.set(' . $this->getLiteralString($arg->name->name) . ', ' . $this->parseCallArgValue($arg) . ');'; + $this->context->beforeStmtLines[] = $namedArgsArray . '.set(' . $this->getLiteralString($arg->name->name) . ', ' . $value . ');'; } else { $arrayArgs = $ensureArrayArgs(); - $this->context->beforeStmtLines[] = $arrayArgs . '.set(' . $this->getLiteralString($arg->name->name) . ', ' . $this->parseCallArgValue($arg) . ');'; + $this->context->beforeStmtLines[] = $arrayArgs . '.set(' . $this->getLiteralString($arg->name->name) . ', ' . $value . ');'; } continue; } @@ -3507,6 +3629,54 @@ class CompilerBase extends \PhpAot\Core\Translator return $value instanceof Expr\PropertyFetch; } + protected function parseReferenceCallArgValue(Node\Arg $arg): string + { + if ($this->isRefvalCall($arg->value)) { + if (count($arg->value->args) !== 1) { + $this->fatalError($arg, 'The refval function only accepts one parameter'); + } + $arg->value = $arg->value->args[0]->value; + } + + if ($this->isVarExpr($arg->value)) { + return $this->parseArgRefVar($arg, $this->parseIdentifier($arg->value)); + } + + if ($this->isPropertyFetch($arg->value) and $this->isVarExpr($arg->value->var)) { + $obj = $this->parseIdentifier($arg->value->var); + if (!$this->hasVar($obj)) { + $this->fatalError($arg, 'Undefined variable `$' . $obj . '`'); + } + return $obj . '.attrRef(' . $this->identifierToStr($arg->value->name) . ')'; + } + + if ($this->isArrayDimFetch($arg->value) and $this->isVarExpr($arg->value->var)) { + $array = $this->parseIdentifier($arg->value->var); + if ($array === 'GLOBALS') { + $globalVar = $this->parseGlobalsArrayDimFetch($arg->value); + $ref = $this->addTmpVar(self::TYPE_REF); + $this->context->beforeStmtLines[] = $ref . ' = ' . $globalVar . '.toReference();'; + return '&' . $ref; + } + if (!$this->hasVar($array)) { + $this->fatalError($arg, 'Undefined variable `$' . $array . '`'); + } + if ($arg->value->dim === null) { + $this->fatalError($arg, 'Array dimension must be a constant expression'); + } + return $array . '.itemRef(' . $this->identifierToStr($arg->value->dim) . ')'; + } + + if ($this->isScalar($arg->value)) { + $this->fatalError($arg, 'The constants cannot be used as an argument for a reference-type parameter'); + } + + $tmpRef = $this->genTmpVarName(); + $this->addLocalVar($tmpRef, self::TYPE_REF); + $this->context->beforeStmtLines[] = $tmpRef . ' = ' . $this->parseChainedExpr($arg->value, self::OP_REFVAL) . ';'; + return '&' . $tmpRef; + } + /** * 展开 refval() 调用中的数组元素或对象属性,返回对应的 C++ 引用表达式。 * 若为普通变量则返回 null,由调用方自行处理。 @@ -4017,6 +4187,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseNew(Expr\New_ $expr): string { + $ctorClassName = ''; // 匿名类 if ($expr->class instanceof Node\Stmt\Class_) { if ($expr->class->name === null) { @@ -4043,6 +4214,7 @@ class CompilerBase extends \PhpAot\Core\Translator . $className . '_defined = true; php::eval((const char *)' . $className . '_code);}'; $className = '\\' . $className; $cePtr = $this->getClassEntryPtr($className); + $ctorClassName = $className; } else { $this->fatalError($expr, 'must be anonymous class'); } @@ -4062,6 +4234,7 @@ class CompilerBase extends \PhpAot\Core\Translator } else { $className = $this->getNamespacedClassName($className); } + $ctorClassName = $className; if ($this->hasClass($className)) { $classDef = $this->getClass($className); if ($classDef->flags & Modifiers::ABSTRACT) { @@ -4079,7 +4252,7 @@ class CompilerBase extends \PhpAot\Core\Translator if (empty($args)) { return 'php::newObject(' . $cePtr . ')'; } - return 'php::newObject(' . $cePtr . ', ' . $this->parseCallArgs($args) . ')'; + return 'php::newObject(' . $cePtr . ', ' . $this->parseCallArgs($args, '__construct', $ctorClassName) . ')'; } protected function parseClone(Expr\Clone_ $expr): string diff --git a/tests/aot/ref/static-byref-call.phpt b/tests/aot/ref/static-byref-call.phpt new file mode 100644 index 00000000..a0bfbc74 --- /dev/null +++ b/tests/aot/ref/static-byref-call.phpt @@ -0,0 +1,54 @@ +--TEST-- +Static function, method, and constructor calls pass by-reference args automatically +--FILE-- +mutate($value); + new RefChild($value); + mutate_named_arg(...['named-function'], value: $value); + $target->mutateNamed(...['named-method'], value: $value); + $fn = 'mutate_named_arg'; + $fn(...['dynamic-refval'], value: refval($value)); + echo $value, PHP_EOL; +} + +?> +--EXPECT-- +start:function:ctor:method:ctor:named-function:named-method:dynamic-refval From 4214e1e278ebdf1482ef91efdb4e175bce321734 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 18:31:38 +0800 Subject: [PATCH 32/37] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E5=AF=B9?= =?UTF-8?q?=E6=9E=84=E9=80=A0=E5=87=BD=E6=95=B0=E6=9E=90=E6=9E=84=E5=87=BD?= =?UTF-8?q?=E6=95=B0=E8=BF=94=E5=9B=9E=E7=B1=BB=E5=9E=8B=E5=92=8C=E9=AD=94?= =?UTF-8?q?=E6=9C=AF=E6=96=B9=E6=B3=95=E7=9A=84=E4=B8=A5=E6=A0=BC=E6=A3=80?= =?UTF-8?q?=E6=9F=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 实现构造函数和析构函数不能声明返回类型的检查 - 实现克隆方法返回类型必须为void的验证 - 添加魔术方法静态性和可见性检查规则 - 实现魔术方法参数数量和类型的严格校验 - 添加魔术方法参数类型检查如__get方法必须接受字符串参数 - 实现可选参数不能在必需参数之前的检查 - 添加闭包引用参数和变长引用参数的错误检查 - 优化参数计数错误消息中的预期参数数量提示 - 添加AOT编译器语言设计原则文档说明 --- CLAUDE.md | 14 ++ phpunit/code/clone-invalid-return-type.php | 13 ++ phpunit/code/closure-ref-param.php | 8 ++ phpunit/code/constructor-return-type.php | 13 ++ phpunit/code/destructor-return-type.php | 12 ++ phpunit/code/magic-call-static.php | 13 ++ phpunit/code/magic-callstatic-nonstatic.php | 13 ++ phpunit/code/magic-destruct-args.php | 12 ++ phpunit/code/magic-get-param-type.php | 13 ++ phpunit/code/magic-get-protected.php | 13 ++ phpunit/code/magic-set-state-nonstatic.php | 13 ++ phpunit/code/magic-tostring-args.php | 13 ++ .../method-optional-before-required-param.php | 12 ++ .../code/optional-before-required-param.php | 9 ++ phpunit/code/variadic-ref-param.php | 9 ++ phpunit/src/ClassTest.php | 50 +++++++ phpunit/src/FunctionTest.php | 20 +++ src/Php/Generator/ClosureGenerator.php | 3 +- src/Php/MagicMethodDetector.php | 128 ++++++++++++------ src/Php/Preprocessor.php | 48 +++++-- src/Php/Translator.php | 3 +- tests/aot/closure/closure-param-defaults.phpt | 12 ++ .../nullable-required-param-check.phpt | 15 ++ 23 files changed, 411 insertions(+), 48 deletions(-) create mode 100644 phpunit/code/clone-invalid-return-type.php create mode 100644 phpunit/code/closure-ref-param.php create mode 100644 phpunit/code/constructor-return-type.php create mode 100644 phpunit/code/destructor-return-type.php create mode 100644 phpunit/code/magic-call-static.php create mode 100644 phpunit/code/magic-callstatic-nonstatic.php create mode 100644 phpunit/code/magic-destruct-args.php create mode 100644 phpunit/code/magic-get-param-type.php create mode 100644 phpunit/code/magic-get-protected.php create mode 100644 phpunit/code/magic-set-state-nonstatic.php create mode 100644 phpunit/code/magic-tostring-args.php create mode 100644 phpunit/code/method-optional-before-required-param.php create mode 100644 phpunit/code/optional-before-required-param.php create mode 100644 phpunit/code/variadic-ref-param.php diff --git a/CLAUDE.md b/CLAUDE.md index bf389d0a..89b2fe0f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -8,6 +8,20 @@ Swoole-Compiler is an AOT (Ahead-of-Time) compiler that translates PHP source co **Prerequisites**: PHP 8.2+, GCC 9+ (C++17), CMake 3.24+. The `swoole/phpx` extension must be compiled (see README.md). +## AOT Language Design Principles + +The AOT compiler should not blindly mirror every PHP language behavior. Most PHP syntax and semantics should remain compatible with ZendPHP, but some legal PHP constructs are historical baggage or language-design mistakes that conflict with static compilation, clear semantics, or robust generated C++ code. + +When reviewing or changing compiler behavior: + +- Prefer PHP compatibility for common, well-defined syntax that does not weaken the AOT static model. +- Reject PHP historical baggage when the syntax is ambiguous, surprising, or only preserved for legacy compatibility. +- Diagnose such cases as early as possible during preprocessing/static compilation, instead of deferring to runtime TypeCheck or ZendVM errors. +- Provide precise errors that include the relevant function/method name, parameter/property name, and type information where applicable. +- Compare with other statically compiled languages such as C/C++, Java, C#, Go, Rust, Kotlin, and TypeScript before deciding whether AOT should preserve or reject a PHP behavior. + +Example: `function test($a = 1, $b, $c) {}` is legal in PHP, but the default value for `$a` is effectively ignored and all parameters become required. This is a PHP historical compatibility artifact. AOT should reject it during preprocessing instead of preserving the behavior. + ## Build & Test Commands ```bash diff --git a/phpunit/code/clone-invalid-return-type.php b/phpunit/code/clone-invalid-return-type.php new file mode 100644 index 00000000..19392f3f --- /dev/null +++ b/phpunit/code/clone-invalid-return-type.php @@ -0,0 +1,13 @@ +exec("Type 'static' cannot be part of an intersection type", 'intersection_type_static_not_allowed.php'); } + + public function testConstructorCannotDeclareReturnType() + { + $this->exec('Method `ConstructorReturnType::__construct()` cannot declare a return type', 'constructor-return-type.php'); + } + + public function testDestructorCannotDeclareReturnType() + { + $this->exec('Method `DestructorReturnType::__destruct()` cannot declare a return type', 'destructor-return-type.php'); + } + + public function testCloneReturnTypeMustBeVoid() + { + $this->exec('Method `CloneInvalidReturnType::__clone()` return type must be void when declared', 'clone-invalid-return-type.php'); + } + + public function testCallMagicMethodCannotBeStatic() + { + $this->exec('Method MagicCallStaticInvalid::__call() cannot be static', 'magic-call-static.php'); + } + + public function testCallStaticMagicMethodMustBeStatic() + { + $this->exec('Method MagicCallStaticNonStaticInvalid::__callStatic() must be static', 'magic-callstatic-nonstatic.php'); + } + + public function testToStringMagicMethodCannotTakeArguments() + { + $this->exec('Method MagicToStringArgsInvalid::__toString() must take exactly 0 arguments', 'magic-tostring-args.php'); + } + + public function testSetStateMagicMethodMustBeStatic() + { + $this->exec('Method MagicSetStateNonStaticInvalid::__set_state() must be static', 'magic-set-state-nonstatic.php'); + } + + public function testDestructMagicMethodCannotTakeArguments() + { + $this->exec('Method MagicDestructArgsInvalid::__destruct() must take exactly 0 arguments', 'magic-destruct-args.php'); + } + + public function testGetMagicMethodParameterMustBeString() + { + $this->exec('Method MagicGetParamTypeInvalid::__get() must take string as argument', 'magic-get-param-type.php'); + } + + public function testMagicMethodMustBePublic() + { + $this->exec('Method MagicGetProtectedInvalid::__get() must have public visibility', 'magic-get-protected.php'); + } } diff --git a/phpunit/src/FunctionTest.php b/phpunit/src/FunctionTest.php index e98a3bae..0881e86c 100644 --- a/phpunit/src/FunctionTest.php +++ b/phpunit/src/FunctionTest.php @@ -57,4 +57,24 @@ class FunctionTest extends \BaseTest $this->exec('Cannot use positional argument after argument unpacking', 'new-positional-after-unpack.php'); } + public function testClosureReferenceParameter() + { + $this->exec('Closure cannot use reference parameter', 'closure-ref-param.php'); + } + + public function testVariadicReferenceParameter() + { + $this->exec('Variadic parameters cannot be passed by reference', 'variadic-ref-param.php'); + } + + public function testOptionalParameterBeforeRequiredParameter() + { + $this->exec('test(): optional parameter `$a` cannot be declared before required parameter `$c`', 'optional-before-required-param.php'); + } + + public function testMethodOptionalParameterBeforeRequiredParameter() + { + $this->exec('OptionalBeforeRequired::method(): optional parameter `$first` cannot be declared before required parameter `$second`', 'method-optional-before-required-param.php'); + } + } diff --git a/src/Php/Generator/ClosureGenerator.php b/src/Php/Generator/ClosureGenerator.php index 401a9523..60c4cc3f 100644 --- a/src/Php/Generator/ClosureGenerator.php +++ b/src/Php/Generator/ClosureGenerator.php @@ -58,10 +58,11 @@ trait ClosureGenerator $requiredArgCount++; } if ($requiredArgCount > 0) { + $expected = $requiredArgCount === count($params) ? 'exactly' : 'at least'; $message = 'php::concat({' . 'php::Str(' . $this->genCharPtr('Too few arguments to function {closure}(), ', true) . '), ' . 'php::toString(php::getCallArgNum()), ' - . 'php::Str(' . $this->genCharPtr(' passed and exactly ' . $requiredArgCount . ' expected', true) . ')' + . 'php::Str(' . $this->genCharPtr(' passed and ' . $expected . ' ' . $requiredArgCount . ' expected', true) . ')' . '})'; $code .= $this->getIndent() . 'if (UNEXPECTED(php::getCallArgNum() < ' . $requiredArgCount . ')) {' . PHP_EOL; $this->indentLevel++; diff --git a/src/Php/MagicMethodDetector.php b/src/Php/MagicMethodDetector.php index f7f8b2d6..469fc69a 100644 --- a/src/Php/MagicMethodDetector.php +++ b/src/Php/MagicMethodDetector.php @@ -20,130 +20,182 @@ trait MagicMethodDetector $returnTypeUndeclared = $fnDef->returnTypeUndeclared; $nameLower = strtolower($name); + $methodName = $this->class . "::{$name}"; + $isStatic = (bool) ($methodDef->flags & \PhpParser\Modifiers::STATIC); + + $mustBeStatic = ['__callstatic' => true, '__set_state' => true]; + $mustNotBeStatic = [ + '__construct' => true, + '__destruct' => true, + '__clone' => true, + '__call' => true, + '__get' => true, + '__set' => true, + '__isset' => true, + '__unset' => true, + '__sleep' => true, + '__wakeup' => true, + '__serialize' => true, + '__unserialize' => true, + '__debuginfo' => true, + '__tostring' => true, + '__invoke' => true, + ]; + if (isset($mustBeStatic[$nameLower]) && !$isStatic) { + $this->fatalError($v, 'Method ' . $methodName . '() must be static'); + } + if (isset($mustNotBeStatic[$nameLower]) && $isStatic) { + $this->fatalError($v, 'Method ' . $methodName . '() cannot be static'); + } + + $mustBePublic = [ + '__call' => true, + '__callstatic' => true, + '__get' => true, + '__set' => true, + '__isset' => true, + '__unset' => true, + '__sleep' => true, + '__wakeup' => true, + '__serialize' => true, + '__unserialize' => true, + '__debuginfo' => true, + '__tostring' => true, + '__invoke' => true, + '__set_state' => true, + ]; + if (isset($mustBePublic[$nameLower]) && !($methodDef->flags & \PhpParser\Modifiers::PUBLIC)) { + $this->fatalError($v, 'Method ' . $methodName . '() must have public visibility'); + } + + $exactArgCount = [ + '__destruct' => 0, + '__clone' => 0, + '__tostring' => 0, + '__sleep' => 0, + '__wakeup' => 0, + '__serialize' => 0, + '__debuginfo' => 0, + '__call' => 2, + '__callstatic' => 2, + '__set' => 2, + '__get' => 1, + '__isset' => 1, + '__unset' => 1, + '__set_state' => 1, + '__unserialize' => 1, + ]; + if (array_key_exists($nameLower, $exactArgCount) && count($argInfoList) !== $exactArgCount[$nameLower]) { + $this->fatalError($v, 'Method ' . $methodName . '() must take exactly ' . $exactArgCount[$nameLower] . ' arguments'); + } if ($nameLower == '__call' or $nameLower == '__callstatic') { - if (count($argInfoList) != 2) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 2 arguments"); - } if ($argInfoList[0]->undeclared) { $argInfoList[0]->type = self::TYPE_STR; } elseif ($argInfoList[0]->type !== self::TYPE_STR) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take string as first argument"); + $this->fatalError($v, 'Method ' . $methodName . '() must take string as first argument'); } if ($argInfoList[1]->undeclared) { $argInfoList[1]->type = self::TYPE_ARRAY; } elseif ($argInfoList[1]->type !== self::TYPE_ARRAY) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take array as second argument"); + $this->fatalError($v, 'Method ' . $methodName . '() must take array as second argument'); } } elseif ($nameLower == '__set') { - if (count($argInfoList) != 2) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 2 arguments"); - } if ($argInfoList[0]->undeclared) { $argInfoList[0]->type = self::TYPE_STR; } elseif ($argInfoList[0]->type !== self::TYPE_STR) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take string as first argument"); + $this->fatalError($v, 'Method ' . $methodName . '() must take string as first argument'); } if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_VOID; } elseif ($fnDef->returnType !== self::TYPE_VOID) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return void"); + $this->fatalError($v, 'Method ' . $methodName . '() must return void'); } } elseif ($nameLower == '__get') { - if (count($argInfoList) != 1) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); + if ($argInfoList[0]->undeclared) { + $argInfoList[0]->type = self::TYPE_STR; + } elseif ($argInfoList[0]->type !== self::TYPE_STR) { + $this->fatalError($v, 'Method ' . $methodName . '() must take string as argument'); } } elseif ($nameLower == '__tostring') { if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_STR; } elseif ($fnDef->returnType !== self::TYPE_STR) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return string"); + $this->fatalError($v, 'Method ' . $methodName . '() must return string'); } } elseif ($nameLower == '__serialize') { if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_ARRAY; } elseif ($fnDef->returnType !== self::TYPE_ARRAY) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array"); + $this->fatalError($v, 'Method ' . $methodName . '() must return array'); } } elseif ($nameLower == '__unserialize') { - if (count($argInfoList) != 1) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); - } if ($argInfoList[0]->undeclared) { $argInfoList[0]->type = self::TYPE_ARRAY; } elseif ($argInfoList[0]->type !== self::TYPE_ARRAY) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take array as argument"); + $this->fatalError($v, 'Method ' . $methodName . '() must take array as argument'); } if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_VOID; } elseif ($fnDef->returnType !== self::TYPE_VOID) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return void"); + $this->fatalError($v, 'Method ' . $methodName . '() must return void'); } } elseif ($nameLower == '__isset') { - if (count($argInfoList) != 1) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); - } if ($argInfoList[0]->undeclared) { $argInfoList[0]->type = self::TYPE_STR; } elseif ($argInfoList[0]->type !== self::TYPE_STR) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take string as argument"); + $this->fatalError($v, 'Method ' . $methodName . '() must take string as argument'); } if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_BOOL; } elseif ($fnDef->returnType !== self::TYPE_BOOL) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return bool"); + $this->fatalError($v, 'Method ' . $methodName . '() must return bool'); } } elseif ($nameLower == '__unset') { - if (count($argInfoList) != 1) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); - } if ($argInfoList[0]->undeclared) { $argInfoList[0]->type = self::TYPE_STR; } elseif ($argInfoList[0]->type !== self::TYPE_STR) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take string as argument"); + $this->fatalError($v, 'Method ' . $methodName . '() must take string as argument'); } if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_VOID; } elseif ($fnDef->returnType !== self::TYPE_VOID) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return void"); + $this->fatalError($v, 'Method ' . $methodName . '() must return void'); } } elseif ($nameLower == '__set_state') { - if (count($argInfoList) != 1) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take exactly 1 argument"); - } if ($argInfoList[0]->undeclared) { $argInfoList[0]->type = self::TYPE_ARRAY; } elseif ($argInfoList[0]->type !== self::TYPE_ARRAY) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must take array as argument"); + $this->fatalError($v, 'Method ' . $methodName . '() must take array as argument'); } if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_OBJECT; } elseif ($fnDef->returnType !== self::TYPE_OBJECT) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return object"); + $this->fatalError($v, 'Method ' . $methodName . '() must return object'); } } elseif ($nameLower == '__debuginfo') { if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_ARRAY; } elseif ($fnDef->returnType !== self::TYPE_ARRAY) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array"); + $this->fatalError($v, 'Method ' . $methodName . '() must return array'); } } elseif ($nameLower == '__sleep') { if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_ARRAY; } elseif ($fnDef->returnType !== self::TYPE_ARRAY) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return array"); + $this->fatalError($v, 'Method ' . $methodName . '() must return array'); } } elseif ($nameLower == '__wakeup') { if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_VOID; } elseif ($fnDef->returnType !== self::TYPE_VOID) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return void"); + $this->fatalError($v, 'Method ' . $methodName . '() must return void'); } } elseif ($nameLower == '__clone') { if ($returnTypeUndeclared) { $fnDef->returnType = self::TYPE_VOID; } elseif ($fnDef->returnType !== self::TYPE_VOID) { - $this->fatalError($v, 'Method ' . $this->class . "::{$name}() must return void"); + $this->fatalError($v, 'Method ' . $methodName . '() must return void'); } } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 0fce7e30..05a1988a 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -245,8 +245,17 @@ class Preprocessor extends CompilerBase { $list = []; $functionDef->argCountRequired = count($params); - $defaultValueCount = 0; + $lastRequiredIndex = -1; + $lastRequiredName = ''; $last = array_key_last($params); + foreach ($params as $i => $param) { + if (!$param->default && !$param->variadic) { + $lastRequiredIndex = $i; + if (is_string($param->var->name)) { + $lastRequiredName = $param->var->name; + } + } + } foreach ($params as $i => $param) { if (!is_string($param->var->name)) { @@ -276,6 +285,14 @@ class Preprocessor extends CompilerBase $this->fatalError($param, 'Variadic parameters cannot be passed by reference'); } } + if ($param->default && $i < $lastRequiredIndex) { + $this->fatalError( + $param, + $this->getFunctionDisplayName($functionDef) + . '(): optional parameter `$' . $phpName . '` cannot be declared before required parameter `$' + . $lastRequiredName . '`' + ); + } if ($this->method and $name === 'this_') { $this->fatalError($param, 'Cannot use `$this` as parameter of class method'); } @@ -325,17 +342,23 @@ class Preprocessor extends CompilerBase $argInfo->arrayInitPlan = $arrayInitPlan; $argInfo->defaultValue = $param->default; } - $defaultValueCount++; } elseif ($param->variadic) { // 变长参数可以视为空数组默认值 - $defaultValueCount++; $argInfo->default = '{}'; $argInfo->defaultValue = new Node\Expr\Array_(); } $functionDef->argInfoList[] = $argInfo; } $functionDef->params = implode(', ', $list); - $functionDef->argCountRequired -= $defaultValueCount; + $functionDef->argCountRequired = $lastRequiredIndex + 1; + } + + protected function getFunctionDisplayName(FunctionDef $functionDef): string + { + if ($this->class) { + return $this->class . '::' . $functionDef->name; + } + return $functionDef->getNamespacedName(); } protected function parseFunctionDecl(Node\Stmt\Function_|Node\Stmt\ClassMethod $v): FunctionDef @@ -352,6 +375,16 @@ class Preprocessor extends CompilerBase if ($v->byRef) { $this->fatalError($v, 'The return type of the function `' . $v->name . '` cannot be a reference type'); } + if ($this->method and $v->returnType !== null) { + $methodName = $this->class . '::' . $this->method; + if (in_array($this->method, ['__construct', '__destruct'], true)) { + $this->fatalError($v, 'Method `' . $methodName . '()` cannot declare a return type'); + } + if ($this->method === '__clone' + and (!$v->returnType instanceof Node\Identifier or strtolower($v->returnType->name) !== 'void')) { + $this->fatalError($v, 'Method `' . $methodName . '()` return type must be void when declared'); + } + } $fnName = $this->parseIdentifier($v->name); $class = ''; @@ -435,6 +468,9 @@ class Preprocessor extends CompilerBase } else { $flags = Modifiers::PUBLIC; } + if (isset($this->symbolDeclInFile[$fullClassNameLower])) { + $this->fatalError($class, "Duplicate class `{$fullClassName}`"); + } $this->classDef = new ClassDef($this->class, $flags, $this->namespace); $this->addClass($fullClassName, $this->classDef); @@ -466,10 +502,6 @@ class Preprocessor extends CompilerBase } else { $this->classDef->trait = $class; } - if (isset($this->symbolDeclInFile[$fullClassNameLower])) { - $this->fatalError($class, "Duplicate class `{$fullClassName}`"); - } - $this->symbolDeclInFile[$fullClassNameLower] = $this->file; $code = ''; diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 4e7d8059..2eef2ce0 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -2906,10 +2906,11 @@ CODE; private function genWrapperRequiredArgCountCheck(FunctionDef $functionDef, string $displayName): string { $required = $functionDef->argCountRequired; + $expected = $required === count($functionDef->argInfoList) ? 'exactly' : 'at least'; $message = 'php::concat({' . 'php::Str(' . $this->genCharPtr('Too few arguments to function ' . $displayName . '(), ', true) . '), ' . 'php::toString(php::getCallArgNum()), ' - . 'php::Str(' . $this->genCharPtr(' passed and exactly ' . $required . ' expected', true) . ')' + . 'php::Str(' . $this->genCharPtr(' passed and ' . $expected . ' ' . $required . ' expected', true) . ')' . '})'; $code = $this->getIndent() . 'if (UNEXPECTED(php::getCallArgNum() < ' . $required . ')) {' . PHP_EOL; diff --git a/tests/aot/closure/closure-param-defaults.phpt b/tests/aot/closure/closure-param-defaults.phpt index 51eff8ec..8a0c84a8 100644 --- a/tests/aot/closure/closure-param-defaults.phpt +++ b/tests/aot/closure/closure-param-defaults.phpt @@ -25,6 +25,16 @@ function main(): void var_dump(get_class($e)); var_dump($e->getMessage()); } + + $requiredWithDefault = function ($value, $default = 42) { + var_dump($value, $default); + }; + try { + $requiredWithDefault(); + } catch (\Throwable $e) { + var_dump(get_class($e)); + var_dump($e->getMessage()); + } } ?> --EXPECT-- @@ -39,3 +49,5 @@ array(3) { } string(18) "ArgumentCountError" string(74) "Too few arguments to function {closure}(), 0 passed and exactly 1 expected" +string(18) "ArgumentCountError" +string(75) "Too few arguments to function {closure}(), 0 passed and at least 1 expected" diff --git a/tests/aot/type_decl/nullable-required-param-check.phpt b/tests/aot/type_decl/nullable-required-param-check.phpt index e9bc531e..78174c6c 100644 --- a/tests/aot/type_decl/nullable-required-param-check.phpt +++ b/tests/aot/type_decl/nullable-required-param-check.phpt @@ -7,6 +7,11 @@ function expect_nullable_int(?int $x): void var_dump($x); } +function expect_nullable_with_default(?int $x, int $fallback = 1): void +{ + var_dump($x, $fallback); +} + function main(): void { $fn = 'expect_nullable_int'; @@ -16,8 +21,18 @@ function main(): void var_dump(get_class($e)); var_dump($e->getMessage()); } + + $fn = 'expect_nullable_with_default'; + try { + $fn(); + } catch (\Throwable $e) { + var_dump(get_class($e)); + var_dump($e->getMessage()); + } } ?> --EXPECT-- string(18) "ArgumentCountError" string(84) "Too few arguments to function expect_nullable_int(), 0 passed and exactly 1 expected" +string(18) "ArgumentCountError" +string(94) "Too few arguments to function expect_nullable_with_default(), 0 passed and at least 1 expected" From 13258d34a60bfff35317546a7fe3b2688e0fb2ea Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 18:40:14 +0800 Subject: [PATCH 33/37] =?UTF-8?q?fix(parser):=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E6=9E=84=E9=80=A0=E5=87=BD=E6=95=B0=E8=BF=94=E5=9B=9E=E5=80=BC?= =?UTF-8?q?=E5=92=8Cvoid=E8=A1=A8=E8=BE=BE=E5=BC=8F=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在赋值操作中添加void表达式检查,防止将void用作赋值值 - 添加构造函数返回值检测,禁止构造函数返回值 - 添加函数参数中的void表达式检查 - 新增构造函数返回值测试用例 - 新增父类构造函数作为值使用的测试用例 - 更新文档说明构造函数语义一致性要求 --- CLAUDE.md | 2 ++ phpunit/code/constructor-return-value.php | 14 +++++++++++ .../parent-constructor-used-as-argument.php | 21 ++++++++++++++++ .../code/parent-constructor-used-as-value.php | 21 ++++++++++++++++ phpunit/src/ClassTest.php | 15 +++++++++++ src/Php/CompilerBase.php | 25 +++++++++++++++++++ src/Php/Parser/AssignOpTrait.php | 3 +++ 7 files changed, 101 insertions(+) create mode 100644 phpunit/code/constructor-return-value.php create mode 100644 phpunit/code/parent-constructor-used-as-argument.php create mode 100644 phpunit/code/parent-constructor-used-as-value.php diff --git a/CLAUDE.md b/CLAUDE.md index 89b2fe0f..f3b46f15 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -22,6 +22,8 @@ When reviewing or changing compiler behavior: Example: `function test($a = 1, $b, $c) {}` is legal in PHP, but the default value for `$a` is effectively ignored and all parameters become required. This is a PHP historical compatibility artifact. AOT should reject it during preprocessing instead of preserving the behavior. +Example: PHP permits `return $value;` inside `__construct()` and lets callers consume `parent::__construct()` as a value, even though constructors cannot declare a return type. AOT treats constructors consistently with C++/Java-style semantics: constructors initialize objects and must not return values. `return;` is allowed, but `return $value;` or using a constructor call as a value must be rejected during static compilation. + ## Build & Test Commands ```bash diff --git a/phpunit/code/constructor-return-value.php b/phpunit/code/constructor-return-value.php new file mode 100644 index 00000000..c373b92b --- /dev/null +++ b/phpunit/code/constructor-return-value.php @@ -0,0 +1,14 @@ +exec('Method `ConstructorReturnType::__construct()` cannot declare a return type', 'constructor-return-type.php'); } + public function testConstructorCannotReturnValue() + { + $this->exec('Method `ConstructorReturnValue::__construct()` cannot return a value', 'constructor-return-value.php'); + } + + public function testParentConstructorCannotBeUsedAsValue() + { + $this->exec('Cannot use void expression as assignment value', 'parent-constructor-used-as-value.php'); + } + + public function testParentConstructorCannotBeUsedAsArgument() + { + $this->exec('Cannot use void expression as function argument', 'parent-constructor-used-as-argument.php'); + } + public function testDestructorCannotDeclareReturnType() { $this->exec('Method `DestructorReturnType::__destruct()` cannot declare a return type', 'destructor-return-type.php'); diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 0cc2070d..912ab209 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -887,6 +887,23 @@ class CompilerBase extends \PhpAot\Core\Translator return strtolower($fullClassName . '::' . $method); } + protected function isCurrentConstructor(): bool + { + return $this->method === '__construct'; + } + + protected function getCurrentMethodDisplayName(): string + { + return $this->getFullClassName() . '::' . $this->method; + } + + protected function assertExprCanBeUsedAsValue(NodeAbstract $expr, string $context = 'value'): void + { + if ($this->detectTypeOfExpr($expr) === self::TYPE_VOID) { + $this->fatalError($expr, 'Cannot use void expression as ' . $context); + } + } + public function getNamespacedClassName(string $class, string $currentNamespace = ''): string { if ($class === '') { @@ -1686,6 +1703,12 @@ class CompilerBase extends \PhpAot\Core\Translator } // 实际函数的返回值 $type = $this->detectTypeOfExpr($v->expr); + if ($this->isCurrentConstructor() && !$this->context->inClosure) { + $this->fatalError($v, 'Method `' . $this->getCurrentMethodDisplayName() . '()` cannot return a value'); + } + if ($type === self::TYPE_VOID) { + $this->fatalError($v, 'Cannot return void expression'); + } $expr = $this->parseExpr($v->expr); $returnType = $this->getReturnType(); @@ -3609,6 +3632,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseCallArgValue(Node\Arg $arg): string { + $this->assertExprCanBeUsedAsValue($arg->value, 'function argument'); return $this->materializeCallArgValue($arg->value, $this->parseArg($arg)); } @@ -4493,6 +4517,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function getTypeConvertedArg(Node\Arg $arg, ArgInfo $argInfo): string { $type = $this->detectTypeOfExpr($arg->value); + $this->assertExprCanBeUsedAsValue($arg->value, 'function argument'); if ($argInfo->byRef) { if ($this->isRefvalCall($arg->value)) { diff --git a/src/Php/Parser/AssignOpTrait.php b/src/Php/Parser/AssignOpTrait.php index d79072cd..1db08b7d 100644 --- a/src/Php/Parser/AssignOpTrait.php +++ b/src/Php/Parser/AssignOpTrait.php @@ -155,6 +155,9 @@ trait AssignOpTrait $this->fatalError($left, 'Cannot re-assign $this'); } $finalVarType = $type = $this->detectTypeOfExpr($right); + if ($type === self::TYPE_VOID) { + $this->fatalError($right, 'Cannot use void expression as assignment value'); + } if ($this->isVarExpr($left)) { if ($this->isStdContainer($var)) { From 5027650611a199542cb94a6995043ddc7124c16e Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 18:52:36 +0800 Subject: [PATCH 34/37] =?UTF-8?q?feat(php):=20=E6=B7=BB=E5=8A=A0=E8=A1=A8?= =?UTF-8?q?=E8=BE=BE=E5=BC=8F=E7=B1=BB=E5=9E=8B=E6=A3=80=E6=9F=A5=E7=A1=AE?= =?UTF-8?q?=E4=BF=9Dvoid=E8=A1=A8=E8=BE=BE=E5=BC=8F=E4=B8=8D=E8=83=BD?= =?UTF-8?q?=E4=BD=9C=E4=B8=BA=E5=80=BC=E6=88=96=E6=9D=A1=E4=BB=B6=E4=BD=BF?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在二元操作符解析中添加对左右操作数的类型检查 - 在有序操作数解析中添加对操作数的类型检查 - 修正类型检测逻辑,移除对void类型的特殊处理 - 在幂运算解析中添加对左右操作数的类型检查 - 在比较表达式解析中添加对操作数的类型检查 - 在短路逻辑操作符解析中添加对左右操作数的类型检查 - 添加assertExprCanBeUsedAsCondition方法用于条件表达式验证 - 在数组解析中添加对键值的类型检查 - 在for循环条件中添加对表达式的类型检查 - 在三元操作符解析中添加对条件和分支的类型检查 - 在match表达式解析中添加对条件和分支的类型检查 - 在位运算、布尔运算、打印、克隆等操作中添加类型检查 - 在类型转换操作中添加对操作数的类型检查 - 添加测试用例验证void表达式在各种场景下的使用限制 --- phpunit/code/void-expression-array-value.php | 21 +++++++++ .../code/void-expression-binary-operand.php | 21 +++++++++ phpunit/code/void-expression-condition.php | 23 ++++++++++ phpunit/code/void-expression-match-arm.php | 23 ++++++++++ .../code/void-expression-ternary-branch.php | 21 +++++++++ phpunit/src/ClassTest.php | 25 ++++++++++ src/Php/CompilerBase.php | 46 +++++++++++++++++++ src/Php/Parser/BinaryOpTrait.php | 12 ++++- 8 files changed, 191 insertions(+), 1 deletion(-) create mode 100644 phpunit/code/void-expression-array-value.php create mode 100644 phpunit/code/void-expression-binary-operand.php create mode 100644 phpunit/code/void-expression-condition.php create mode 100644 phpunit/code/void-expression-match-arm.php create mode 100644 phpunit/code/void-expression-ternary-branch.php diff --git a/phpunit/code/void-expression-array-value.php b/phpunit/code/void-expression-array-value.php new file mode 100644 index 00000000..a91279fd --- /dev/null +++ b/phpunit/code/void-expression-array-value.php @@ -0,0 +1,21 @@ + parent::__construct(), + }; + } +} + +function main(): void +{ + new VoidExpressionMatchChild(); +} diff --git a/phpunit/code/void-expression-ternary-branch.php b/phpunit/code/void-expression-ternary-branch.php new file mode 100644 index 00000000..95fa2f09 --- /dev/null +++ b/phpunit/code/void-expression-ternary-branch.php @@ -0,0 +1,21 @@ +exec('Cannot use void expression as function argument', 'parent-constructor-used-as-argument.php'); } + public function testVoidExpressionCannotBeUsedAsBinaryOperand() + { + $this->exec('Cannot use void expression as binary operand', 'void-expression-binary-operand.php'); + } + + public function testVoidExpressionCannotBeUsedAsCondition() + { + $this->exec('Cannot use void expression as condition', 'void-expression-condition.php'); + } + + public function testVoidExpressionCannotBeUsedAsTernaryBranch() + { + $this->exec('Cannot use void expression as ternary branch', 'void-expression-ternary-branch.php'); + } + + public function testVoidExpressionCannotBeUsedAsArrayValue() + { + $this->exec('Cannot use void expression as array value', 'void-expression-array-value.php'); + } + + public function testVoidExpressionCannotBeUsedAsMatchArm() + { + $this->exec('Cannot use void expression as match arm', 'void-expression-match-arm.php'); + } + public function testDestructorCannotDeclareReturnType() { $this->exec('Method `DestructorReturnType::__destruct()` cannot declare a return type', 'destructor-return-type.php'); diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 912ab209..9bd09c47 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -904,6 +904,13 @@ class CompilerBase extends \PhpAot\Core\Translator } } + protected function assertExprCanBeUsedAsCondition(NodeAbstract $expr, string $context = 'condition'): void + { + if ($this->detectTypeOfExpr($expr) === self::TYPE_VOID) { + $this->fatalError($expr, 'Cannot use void expression as ' . $context); + } + } + public function getNamespacedClassName(string $class, string $currentNamespace = ''): string { if ($class === '') { @@ -1388,6 +1395,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function genConditionWithCapturedStmts(NodeAbstract $cond, string $openPrefix): string { + $this->assertExprCanBeUsedAsCondition($cond); [$condExpr, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($cond); $code = ''; $this->appendCapturedStmtLines($code, $beforeStmts); @@ -2463,8 +2471,10 @@ class CompilerBase extends \PhpAot\Core\Translator $list = []; $this->indentLevel++; foreach ($items as $item) { + $this->assertExprCanBeUsedAsValue($item->value, 'array value'); $value = $this->parseIdentifier($item->value); if ($item->key) { + $this->assertExprCanBeUsedAsValue($item->key, 'array key'); $key = $this->parseArrayKey($item->key); $list[] = $this->getIndent() . '{ ' . $key . ', ' . self::TYPE_VAR . '(' . $value . ') }'; } else { @@ -2671,6 +2681,7 @@ class CompilerBase extends \PhpAot\Core\Translator $list_cond = []; $hasCondStmts = false; foreach ($cond as $expr) { + $this->assertExprCanBeUsedAsCondition($expr, 'for condition'); [$condExpr, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($expr); $hasCondStmts = $hasCondStmts || $beforeStmts || $afterStmts; $list_cond[] = [$condExpr, $beforeStmts, $afterStmts]; @@ -3867,6 +3878,9 @@ class CompilerBase extends \PhpAot\Core\Translator if ($expr->if === null) { return $this->parseValueSelection($expr, $expr->cond, $expr->else, self::OP_NOT_EMPTY); } + $this->assertExprCanBeUsedAsCondition($expr->cond, 'ternary condition'); + $this->assertExprCanBeUsedAsValue($expr->if, 'ternary branch'); + $this->assertExprCanBeUsedAsValue($expr->else, 'ternary branch'); [$cond, $condBeforeStmts, $condAfterStmts] = $this->parseExprWithCapturedStmts($expr->cond); $ifBeforeStmtCount = count($this->context->beforeStmtLines); $ifAfterStmtCount = count($this->context->afterStmtLines); @@ -3928,6 +3942,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseMatch(Expr\Match_ $expr): string { + $this->assertExprCanBeUsedAsValue($expr->cond, 'match condition'); $var = $this->parseIdentifier($expr->cond); if ($this->isVarExpr($expr->cond)) { if (!$this->hasVar($var)) { @@ -3957,6 +3972,7 @@ class CompilerBase extends \PhpAot\Core\Translator }; $appendMatchReturn = function (string &$code, NodeAbstract $body) use ($parseExprWithStmts, $appendStmtLines): void { + $this->assertExprCanBeUsedAsValue($body, 'match arm'); [$value, $beforeStmts, $afterStmts] = $parseExprWithStmts($body); $appendStmtLines($code, $beforeStmts); if ($afterStmts) { @@ -3982,6 +3998,7 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->isMatchExpr($cond)) { $this->fatalError($arm, 'Match expression cannot be used as a condition'); } + $this->assertExprCanBeUsedAsValue($cond, 'match arm condition'); [$condValue, $beforeStmts, $afterStmts] = $parseExprWithStmts($cond); $code .= $this->getIndent() . 'if (!' . $matched . ') {'; $appendStmtLines($code, $beforeStmts); @@ -4034,6 +4051,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseBitwiseNot(Expr\BitwiseNot $expr): string { $type = $this->detectTypeOfExpr($expr->expr); + $this->assertExprCanBeUsedAsValue($expr->expr, 'bitwise operand'); if ($type === self::TYPE_BIGINT) { return 'php::BigInt::bitNot(' . $this->parseExpr($expr->expr) . ')'; } @@ -4078,12 +4096,14 @@ class CompilerBase extends \PhpAot\Core\Translator */ protected function parseBooleanNot(Expr\BooleanNot $expr): string { + $this->assertExprCanBeUsedAsCondition($expr->expr, 'boolean operand'); return '!(' . $this->parseExpr($expr->expr) . ')'; } protected function parseWhile(Node\Stmt\While_ $v): string { $stmts = $v->stmts; + $this->assertExprCanBeUsedAsCondition($v->cond, 'while condition'); [$cond, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($v->cond); $code = $this->parseBeforeStmtLines() . PHP_EOL; @@ -4109,12 +4129,14 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePrint(Expr\Print_ $expr): string { + $this->assertExprCanBeUsedAsValue($expr->expr, 'print operand'); return 'php::print(' . $this->parseExpr($expr->expr) . ')'; } protected function parseDo(Node\Stmt\Do_ $v): string { $stmts = $v->stmts; + $this->assertExprCanBeUsedAsCondition($v->cond, 'do-while condition'); [$cond, $beforeStmts, $afterStmts] = $this->parseExprWithCapturedStmts($v->cond); if ($beforeStmts || $afterStmts) { $condCode = '[&]() -> bool {'; @@ -4143,6 +4165,8 @@ class CompilerBase extends \PhpAot\Core\Translator */ protected function parseValueSelection(NodeAbstract $expr, Expr $left, Expr $right, string $op): string { + $this->assertExprCanBeUsedAsValue($left, 'selection value'); + $this->assertExprCanBeUsedAsValue($right, 'selection value'); $leftExpr = $this->parseIdentifier($left); if ($this->isVarExpr($left)) { $this->checkVarMustExist($left, $leftExpr); @@ -4281,11 +4305,13 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseClone(Expr\Clone_ $expr): string { + $this->assertExprCanBeUsedAsValue($expr->expr, 'clone operand'); return 'php::clone(' . $this->parseExpr($expr->expr) . ')'; } protected function parseInstanceof(Expr\Instanceof_ $expr): string { + $this->assertExprCanBeUsedAsValue($expr->expr, 'instanceof operand'); if ($this->isNameExpr($expr->class)) { $className = $this->getNamespacedClassName($this->parseIdentifier($expr->class)); $className = $this->getClassEntryPtr($className); @@ -4297,11 +4323,13 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseCastInt(Expr\Cast\Int_ $node): string { + $this->assertExprCanBeUsedAsValue($node->expr, 'cast operand'); return $this->convertIntExpr($this->parseExpr($node->expr)); } protected function parseCastString(Expr\Cast\String_ $node): string { + $this->assertExprCanBeUsedAsValue($node->expr, 'cast operand'); return $this->convertExprToStringByType( $this->parseExpr($node->expr), $this->detectTypeOfExpr($node->expr) @@ -4310,11 +4338,13 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseCastBool(Expr\Cast\Bool_ $node): string { + $this->assertExprCanBeUsedAsValue($node->expr, 'cast operand'); return $this->convertBoolExpr($this->parseExpr($node->expr)); } protected function parseCastObject(Expr\Cast\Object_ $node): string { + $this->assertExprCanBeUsedAsValue($node->expr, 'cast operand'); return $this->convertObjectExpr($this->parseExpr($node->expr)); } @@ -4383,6 +4413,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseUnaryMinus(Expr\UnaryMinus $expr): string { $type = $this->detectTypeOfExpr($expr->expr); + $this->assertExprCanBeUsedAsValue($expr->expr, 'unary operand'); if ($type === self::TYPE_BIGFLOAT) { return 'php::BigFloat::neg(' . $this->parseExpr($expr->expr) . ')'; } @@ -4399,6 +4430,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseUnaryPlus(Expr\UnaryPlus $expr): string { + $this->assertExprCanBeUsedAsValue($expr->expr, 'unary operand'); return $this->parseExpr($expr->expr); } @@ -4407,6 +4439,9 @@ class CompilerBase extends \PhpAot\Core\Translator $parts = $expr->parts; $list = []; foreach ($parts as $part) { + if (!$part instanceof Node\InterpolatedStringPart) { + $this->assertExprCanBeUsedAsValue($part, 'string interpolation value'); + } $list[] = $this->parseExpr($part); } @@ -5058,6 +5093,7 @@ class CompilerBase extends \PhpAot\Core\Translator $cond = $v->cond; $tmp_var = $this->genTmpVarName(); $type = $this->detectTypeOfExpr($cond); + $this->assertExprCanBeUsedAsValue($cond, 'switch condition'); if ($this->isVarExpr($cond)) { $this->requireVar($v, $this->parseIdentifier($cond)); } @@ -5137,6 +5173,7 @@ class CompilerBase extends \PhpAot\Core\Translator $groupMatched = $this->genTmpVarName(); $code .= $this->getIndent() . 'bool ' . $groupMatched . ' = false;' . PHP_EOL; foreach ($caseConds as $caseCond) { + $this->assertExprCanBeUsedAsValue($caseCond, 'switch case condition'); $caseBeforeStmtCount = count($this->context->beforeStmtLines); $caseAfterStmtCount = count($this->context->afterStmtLines); $caseCondExpr = $this->parseIdentifier($caseCond); @@ -5178,6 +5215,9 @@ class CompilerBase extends \PhpAot\Core\Translator foreach ($v->vars as $var) { $varName = $this->escapeVarName($var->var->name); $type = $var->default ? $this->detectTypeOfExpr($var->default) : self::TYPE_VAR; + if ($var->default) { + $this->assertExprCanBeUsedAsValue($var->default, 'static variable default value'); + } $globalVar = $this->addStaticVar($var->var, $varName, $type); $list[] = self::TYPE_VAR . ' &' . $varName . ' = ' . $this->escapeGlobalVar($globalVar) . ';'; @@ -5206,6 +5246,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseEval(Expr\Eval_ $expr): string { + $this->assertExprCanBeUsedAsValue($expr->expr, 'eval operand'); // 对 eval() 指令的 PHP 代码段禁止字面量优化 $expr->expr->setAttribute('noLiteralString', true); return 'php::eval(' . $this->identifierToStr($expr->expr) . ')'; @@ -5213,6 +5254,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseInclude(Expr\Include_ $expr): string { + $this->assertExprCanBeUsedAsValue($expr->expr, 'include operand'); switch ($expr->type) { case Expr\Include_::TYPE_INCLUDE: $type = 'php::INCLUDE'; @@ -5406,6 +5448,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseCastArray(Expr\Cast\Array_ $expr): string { + $this->assertExprCanBeUsedAsValue($expr->expr, 'cast operand'); return $this->convertArrayExpr($this->parseExpr($expr->expr)); } @@ -5426,6 +5469,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parseCastDouble(mixed $expr): string { + $this->assertExprCanBeUsedAsValue($expr->expr, 'cast operand'); return $this->convertFloatExpr($this->parseIdentifier($expr->expr)); } @@ -6859,10 +6903,12 @@ class CompilerBase extends \PhpAot\Core\Translator $items = $node->items; foreach ($items as $item) { + $this->assertExprCanBeUsedAsValue($item->value, $item->unpack ? 'array unpack value' : 'array value'); $value = $this->parseIdentifier($item->value); if ($item->unpack) { $this->context->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.merge(' . $value . ');'; } elseif ($item->key) { + $this->assertExprCanBeUsedAsValue($item->key, 'array key'); $key = $this->parseArrayKey($item->key); $this->context->beforeStmtLines[] = $this->getIndent() . $tmpVar . '.set(' . $key . ', ' . $value . ');'; } else { diff --git a/src/Php/Parser/BinaryOpTrait.php b/src/Php/Parser/BinaryOpTrait.php index 1a1e4a22..66112bd0 100644 --- a/src/Php/Parser/BinaryOpTrait.php +++ b/src/Php/Parser/BinaryOpTrait.php @@ -18,6 +18,9 @@ trait BinaryOpTrait { protected function parseBinaryOp(NodeAbstract $left, NodeAbstract $right, string $op): string { + $this->assertExprCanBeUsedAsValue($left, 'binary operand'); + $this->assertExprCanBeUsedAsValue($right, 'binary operand'); + // 运算逻辑,优先转为数字 $leftExpr = $this->parseOrderedBinaryOperand($left); $rightExpr = $this->parseOrderedBinaryOperand($right); @@ -169,6 +172,7 @@ trait BinaryOpTrait protected function parseOrderedOperand(NodeAbstract $expr, bool $numeric): float|int|string { + $this->assertExprCanBeUsedAsValue($expr, 'operand'); if (!$this->shouldMaterializeOrderedOperand($expr)) { return $numeric ? $this->parseNumericIdentifier($expr) : $this->parseIdentifier($expr); } @@ -224,7 +228,7 @@ trait BinaryOpTrait } $type = $this->detectTypeOfExpr($expr); - return $type === self::TYPE_VOID ? self::TYPE_VAR : $type; + return $type; } protected function appendCapturedStmtLinesToContext(array $stmts): void @@ -298,6 +302,8 @@ trait BinaryOpTrait protected function parseBinaryOpPow(Expr\BinaryOp\Pow $expr): string { + $this->assertExprCanBeUsedAsValue($expr->left, 'binary operand'); + $this->assertExprCanBeUsedAsValue($expr->right, 'binary operand'); $leftType = $this->detectTypeOfExpr($expr->left); if ($leftType === self::TYPE_BIGINT) { $leftExpr = $this->parseOrderedOperand($expr->left, false); @@ -330,6 +336,7 @@ trait BinaryOpTrait protected function parseCompareExpr(NodeAbstract $expr): string { + $this->assertExprCanBeUsedAsValue($expr, 'comparison operand'); // PHPX 与 bool 值比较会出现重载错误,所以需要转换成 bool 值 if ($this->isScalarBool($expr)) { return $this->getBoolValue($expr); @@ -397,6 +404,9 @@ trait BinaryOpTrait protected function parseShortCircuitLogicalOp(NodeAbstract $left, NodeAbstract $right, string $op): string { + $this->assertExprCanBeUsedAsCondition($left, 'logical operand'); + $this->assertExprCanBeUsedAsCondition($right, 'logical operand'); + $leftExpr = $this->parseNumericIdentifier($left); $this->checkVarMustExist($left, $leftExpr); From 64cf047f072fd37f961e4f28d32a74006b971e69 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 19:29:27 +0800 Subject: [PATCH 35/37] =?UTF-8?q?fix(parser):=20=E8=A7=A3=E5=86=B3?= =?UTF-8?q?=E7=A9=BA=E5=AE=89=E5=85=A8=E6=93=8D=E4=BD=9C=E7=AC=A6=E5=9C=A8?= =?UTF-8?q?=E5=86=99=E5=85=A5=E4=B8=8A=E4=B8=8B=E6=96=87=E4=B8=AD=E7=9A=84?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 在赋值操作中添加空安全操作符检查,防止在写入上下文中使用 - 修复前置递增、后置操作、递减和unset操作中的空安全检查 - 添加对空安全属性访问的类型检测和错误处理 - 禁止对void函数调用结果进行赋值或二元运算 - 修复继承中私有属性重声明的错误处理逻辑 - 添加空安全写入操作的相关测试用例 --- .../accessibility/private-prop-in-parent.php | 18 +++++ .../accessibility/private-prop-in-trait.php | 18 +++++ .../internal-void-function-assignment.php | 6 ++ .../internal-void-function-binary-operand.php | 6 ++ .../code/nullsafe-nested-private-property.php | 24 +++++++ phpunit/code/nullsafe-private-property.php | 14 ++++ phpunit/code/nullsafe-write-assign-op.php | 12 ++++ .../code/nullsafe-write-assign-ref-left.php | 13 ++++ .../code/nullsafe-write-assign-ref-right.php | 12 ++++ phpunit/code/nullsafe-write-assign.php | 12 ++++ phpunit/code/nullsafe-write-inc.php | 12 ++++ phpunit/code/nullsafe-write-unset.php | 12 ++++ phpunit/src/FunctionTest.php | 10 +++ phpunit/src/InheritanceErrorTest.php | 14 +++- phpunit/src/NativePropertyTest.php | 40 +++++++++++ src/Php/CompilerBase.php | 68 +++++++++++++++++-- src/Php/Parser/AssignOpTrait.php | 7 ++ src/Php/Translator.php | 4 +- 18 files changed, 294 insertions(+), 8 deletions(-) create mode 100644 phpunit/code/accessibility/private-prop-in-parent.php create mode 100644 phpunit/code/accessibility/private-prop-in-trait.php create mode 100644 phpunit/code/internal-void-function-assignment.php create mode 100644 phpunit/code/internal-void-function-binary-operand.php create mode 100644 phpunit/code/nullsafe-nested-private-property.php create mode 100644 phpunit/code/nullsafe-private-property.php create mode 100644 phpunit/code/nullsafe-write-assign-op.php create mode 100644 phpunit/code/nullsafe-write-assign-ref-left.php create mode 100644 phpunit/code/nullsafe-write-assign-ref-right.php create mode 100644 phpunit/code/nullsafe-write-assign.php create mode 100644 phpunit/code/nullsafe-write-inc.php create mode 100644 phpunit/code/nullsafe-write-unset.php diff --git a/phpunit/code/accessibility/private-prop-in-parent.php b/phpunit/code/accessibility/private-prop-in-parent.php new file mode 100644 index 00000000..0a044bfe --- /dev/null +++ b/phpunit/code/accessibility/private-prop-in-parent.php @@ -0,0 +1,18 @@ +prop); + } +} +class User extends Base { + public $prop; +} + +function main() { + $u = new User(); + $u->prop = 12; + var_dump($u); + $u->dump(); +} diff --git a/phpunit/code/accessibility/private-prop-in-trait.php b/phpunit/code/accessibility/private-prop-in-trait.php new file mode 100644 index 00000000..d94013c7 --- /dev/null +++ b/phpunit/code/accessibility/private-prop-in-trait.php @@ -0,0 +1,18 @@ +prop = 12; + var_dump($u); +} diff --git a/phpunit/code/internal-void-function-assignment.php b/phpunit/code/internal-void-function-assignment.php new file mode 100644 index 00000000..1339725c --- /dev/null +++ b/phpunit/code/internal-void-function-assignment.php @@ -0,0 +1,6 @@ +child = new NullsafeNestedChild(); + } +} + +class NullsafeNestedChild +{ + private int $value = 1; +} + +function main(): void +{ + $owner = new NullsafeNestedOwner(); + var_dump($owner?->child?->value); +} diff --git a/phpunit/code/nullsafe-private-property.php b/phpunit/code/nullsafe-private-property.php new file mode 100644 index 00000000..4ed46c0e --- /dev/null +++ b/phpunit/code/nullsafe-private-property.php @@ -0,0 +1,14 @@ +value); +} diff --git a/phpunit/code/nullsafe-write-assign-op.php b/phpunit/code/nullsafe-write-assign-op.php new file mode 100644 index 00000000..81727455 --- /dev/null +++ b/phpunit/code/nullsafe-write-assign-op.php @@ -0,0 +1,12 @@ +value += 2; +} diff --git a/phpunit/code/nullsafe-write-assign-ref-left.php b/phpunit/code/nullsafe-write-assign-ref-left.php new file mode 100644 index 00000000..9eeac740 --- /dev/null +++ b/phpunit/code/nullsafe-write-assign-ref-left.php @@ -0,0 +1,13 @@ +value =& $value; +} diff --git a/phpunit/code/nullsafe-write-assign-ref-right.php b/phpunit/code/nullsafe-write-assign-ref-right.php new file mode 100644 index 00000000..9e5a3c44 --- /dev/null +++ b/phpunit/code/nullsafe-write-assign-ref-right.php @@ -0,0 +1,12 @@ +value; +} diff --git a/phpunit/code/nullsafe-write-assign.php b/phpunit/code/nullsafe-write-assign.php new file mode 100644 index 00000000..c6c66f66 --- /dev/null +++ b/phpunit/code/nullsafe-write-assign.php @@ -0,0 +1,12 @@ +value = 2; +} diff --git a/phpunit/code/nullsafe-write-inc.php b/phpunit/code/nullsafe-write-inc.php new file mode 100644 index 00000000..25725f27 --- /dev/null +++ b/phpunit/code/nullsafe-write-inc.php @@ -0,0 +1,12 @@ +value++; +} diff --git a/phpunit/code/nullsafe-write-unset.php b/phpunit/code/nullsafe-write-unset.php new file mode 100644 index 00000000..77ee238c --- /dev/null +++ b/phpunit/code/nullsafe-write-unset.php @@ -0,0 +1,12 @@ +value); +} diff --git a/phpunit/src/FunctionTest.php b/phpunit/src/FunctionTest.php index 0881e86c..e547d5cb 100644 --- a/phpunit/src/FunctionTest.php +++ b/phpunit/src/FunctionTest.php @@ -77,4 +77,14 @@ class FunctionTest extends \BaseTest $this->exec('OptionalBeforeRequired::method(): optional parameter `$first` cannot be declared before required parameter `$second`', 'method-optional-before-required-param.php'); } + public function testInternalVoidFunctionCannotBeAssigned() + { + $this->exec('Cannot use void expression as assignment value', 'internal-void-function-assignment.php'); + } + + public function testInternalVoidFunctionCannotBeUsedAsBinaryOperand() + { + $this->exec('Cannot use void expression as binary operand', 'internal-void-function-binary-operand.php'); + } + } diff --git a/phpunit/src/InheritanceErrorTest.php b/phpunit/src/InheritanceErrorTest.php index dcc38a33..8731232a 100644 --- a/phpunit/src/InheritanceErrorTest.php +++ b/phpunit/src/InheritanceErrorTest.php @@ -138,9 +138,19 @@ class InheritanceErrorTest extends TestCase $this->assertCompiles('inheritance_prop_visibility_widen.php'); } - public function testPrivateParentPropertyMayBeRedeclared() + public function testPrivateParentPropertyCannotBeRedeclared() { - $this->assertCompiles('inheritance_private_prop_redeclare.php'); + $this->exec('property shadowing across inheritance is not allowed', 'inheritance_private_prop_redeclare.php'); + } + + public function testPrivateParentPropertyCannotBeShadowedByPublicProperty() + { + $this->exec('property shadowing across inheritance is not allowed', 'accessibility/private-prop-in-parent.php'); + } + + public function testPrivateTraitPropertyCannotBeShadowedByPublicProperty() + { + $this->exec('property shadowing across inheritance is not allowed', 'accessibility/private-prop-in-trait.php'); } public function testConstantTypeMismatch() diff --git a/phpunit/src/NativePropertyTest.php b/phpunit/src/NativePropertyTest.php index b01b6b80..11c31544 100644 --- a/phpunit/src/NativePropertyTest.php +++ b/phpunit/src/NativePropertyTest.php @@ -51,4 +51,44 @@ class NativePropertyTest extends \BaseTest { $this->exec('Cannot access protected property `value` of class `NativeProtectedOwner`', 'native-property-protected-unrelated-class.php'); } + + public function testCannotAccessPrivateNativePropertyThroughNullsafe(): void + { + $this->exec('Cannot access private property `value` of class `NullsafePrivateOwner`', 'nullsafe-private-property.php'); + } + + public function testCannotAccessNestedPrivateNativePropertyThroughNullsafe(): void + { + $this->exec('Cannot access private property `value` of class `NullsafeNestedChild`', 'nullsafe-nested-private-property.php'); + } + + public function testCannotAssignThroughNullsafeProperty(): void + { + $this->exec("Can't use nullsafe operator in write context", 'nullsafe-write-assign.php'); + } + + public function testCannotUseCompoundAssignThroughNullsafeProperty(): void + { + $this->exec("Can't use nullsafe operator in write context", 'nullsafe-write-assign-op.php'); + } + + public function testCannotIncrementThroughNullsafeProperty(): void + { + $this->exec("Can't use nullsafe operator in write context", 'nullsafe-write-inc.php'); + } + + public function testCannotUnsetThroughNullsafeProperty(): void + { + $this->exec("Can't use nullsafe operator in write context", 'nullsafe-write-unset.php'); + } + + public function testCannotAssignReferenceToNullsafeProperty(): void + { + $this->exec("Can't use nullsafe operator in write context", 'nullsafe-write-assign-ref-left.php'); + } + + public function testCannotTakeReferenceOfNullsafeProperty(): void + { + $this->exec('Cannot take reference of a nullsafe chain', 'nullsafe-write-assign-ref-right.php'); + } } diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 9bd09c47..e4a6d079 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -2768,6 +2768,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePreInc(Expr\PreInc $expr): string { + $this->assertNotNullsafeWriteContext($expr->var); $oriInAssignExpr = $this->context->inAssignExpr; $this->context->inAssignExpr = true; @@ -3825,6 +3826,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePostOp(Expr\PostDec|Expr\PostInc $expr, string $op): string { + $this->assertNotNullsafeWriteContext($expr->var); $result = $this->genDynamicPropIncDec($expr->var, $op, false); if ($result !== null) { return $result; @@ -4030,6 +4032,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function parsePreDec(Expr\PreDec $expr): string { + $this->assertNotNullsafeWriteContext($expr->var); $oriInAssignExpr = $this->context->inAssignExpr; $this->context->inAssignExpr = true; @@ -4792,6 +4795,7 @@ class CompilerBase extends \PhpAot\Core\Translator $vars = $node->vars; $lines = []; foreach ($vars as $var) { + $this->assertNotNullsafeWriteContext($var); if ($this->isArrayDimFetch($var)) { if ($var->dim === null) { $this->fatalError($var, 'Cannot use [] for array unset'); @@ -5365,11 +5369,19 @@ class CompilerBase extends \PhpAot\Core\Translator */ protected function checkLeftValue(NodeAbstract $expr): void { + $this->assertNotNullsafeWriteContext($expr); if (!$this->isVarExpr($expr) && !$this->isArrayDimFetch($expr) && !$this->isPropertyFetch($expr) && !$this->isStaticPropertyFetch($expr)) { $this->fatalError($expr, 'The left value of assignment operation can only be variable, array item, object property, class static property'); } } + protected function assertNotNullsafeWriteContext(NodeAbstract $expr): void + { + if ($expr instanceof Expr\NullsafePropertyFetch) { + $this->fatalError($expr, "Can't use nullsafe operator in write context"); + } + } + protected function getChainedFunc(string $op): string { return match ($op) { @@ -5477,9 +5489,7 @@ class CompilerBase extends \PhpAot\Core\Translator { if ($this->isInternalFunction($name)) { $returnType = Reflection::getFunctionReturnType($name); - // void 类型将被忽略,类型推测仅用于赋值操作的右值,即使返回值为 void , 赋值操作也应该继续运行,右值会被当做 null - // 例如 $a = var_dump('hello'); 虽然 var_dump 返回值为 void ,但是 $a 的类型是 mixed,值为 null - if ($returnType and $returnType !== 'void') { + if ($returnType) { return $this->getTypeFromZendType($returnType); } } @@ -5489,7 +5499,7 @@ class CompilerBase extends \PhpAot\Core\Translator protected function detectMethodCallReturnType(string $class, string $method): string { $returnType = Reflection::getMethodReturnType($class, $method); - if ($returnType and $returnType !== 'void') { + if ($returnType) { return $this->getTypeFromZendType($returnType); } return self::TYPE_VAR; @@ -6774,6 +6784,17 @@ class CompilerBase extends \PhpAot\Core\Translator return $beforeCode . PHP_EOL . $code . ';' . PHP_EOL . 'return ' . self::VALUE_NULL . ';'; } } + if ($this->detectTypeOfExpr($expr->expr) === self::TYPE_VOID) { + if ($this->context->closureReturnTypeCheck) { + $tmpVar = $this->genTmpVarName(); + $this->addLocalVar($tmpVar, self::TYPE_VAR); + return $beforeCode . PHP_EOL . $code . ';' . PHP_EOL + . $tmpVar . ' = ' . self::VALUE_NULL . ';' . PHP_EOL + . $this->genClosureReturnCheck($tmpVar) + . $this->getIndent() . 'return ' . $tmpVar . ';'; + } + return $beforeCode . PHP_EOL . $code . ';' . PHP_EOL . 'return ' . self::VALUE_NULL . ';'; + } if ($this->context->closureReturnTypeCheck) { $tmpVar = $this->genTmpVarName(); $this->addLocalVar($tmpVar, self::TYPE_VAR); @@ -6829,7 +6850,7 @@ class CompilerBase extends \PhpAot\Core\Translator while (1) { if ($expr instanceof Expr\NullsafePropertyFetch) { - $list[] = ['property', $this->identifierToStr($expr->name, literal: true)]; + $list[] = ['property', $this->identifierToStr($expr->name, literal: true), $expr]; $expr = $expr->var; } elseif ($expr instanceof Expr\NullsafeMethodCall) { $list[] = ['method', $this->identifierToStr($expr->name, literal: true), $expr->args]; @@ -6852,6 +6873,7 @@ class CompilerBase extends \PhpAot\Core\Translator } $list = array_reverse($list); + $this->checkNullsafePropertyAccesses($expr, $list); $last = array_key_last($list); $tmpFn = $this->genTmpVarName(); @@ -6886,6 +6908,42 @@ class CompilerBase extends \PhpAot\Core\Translator return "{$tmpFn}()"; } + private function checkNullsafePropertyAccesses(NodeAbstract $baseExpr, array $list): void + { + $className = $this->detectClassOfExpr($baseExpr); + if ($className === '') { + return; + } + + foreach ($list as $item) { + if ($item[0] !== 'property') { + $className = ''; + continue; + } + + /** @var Expr\NullsafePropertyFetch $node */ + $node = $item[2]; + if (!$this->isIdExpr($node->name)) { + $className = ''; + continue; + } + + $property = $this->parseIdentifier($node->name); + $this->findNativeProperty($node, $property, $className); + if (!$node->hasAttribute('nativePropertyDef')) { + $className = ''; + continue; + } + + /** @var PropertyDef $def */ + $def = $node->getAttribute('nativePropertyDef'); + $className = $def->type === self::TYPE_OBJECT ? $def->class : ''; + if ($className === '') { + return; + } + } + } + protected function parseFullyQualifiedName(Node\Name\FullyQualified $expr): string { return $expr->name; diff --git a/src/Php/Parser/AssignOpTrait.php b/src/Php/Parser/AssignOpTrait.php index 1db08b7d..eab77ac8 100644 --- a/src/Php/Parser/AssignOpTrait.php +++ b/src/Php/Parser/AssignOpTrait.php @@ -143,6 +143,7 @@ trait AssignOpTrait protected function parseAssignFinally(Expr $left, Expr $right): string { + $this->assertNotNullsafeWriteContext($left); if ($left instanceof Expr\List_) { return $this->parseAssignToList($left, $right); } @@ -325,6 +326,7 @@ trait AssignOpTrait protected function parseAssignOp(Expr\AssignOp $node, string $op): string { + $this->assertNotNullsafeWriteContext($node->var); $oriInAssignExpr = $this->context->inAssignExpr; $this->context->inAssignExpr = true; $var = $this->parseIdentifier($node->var); @@ -521,6 +523,11 @@ trait AssignOpTrait protected function parseAssignRef(Expr\AssignRef $expr): string { + $this->assertNotNullsafeWriteContext($expr->var); + if ($expr->expr instanceof Expr\NullsafePropertyFetch) { + $this->fatalError($expr->expr, 'Cannot take reference of a nullsafe chain'); + } + $this->context->inAssignExpr = true; $left = $this->parseIdentifier($expr->var); $this->context->inAssignExpr = false; diff --git a/src/Php/Translator.php b/src/Php/Translator.php index 2eef2ce0..3cf325a5 100644 --- a/src/Php/Translator.php +++ b/src/Php/Translator.php @@ -3441,7 +3441,9 @@ CODE; if ($chainNode->hasProperty($name)) { $parentProp = $chainNode->getProperty($name); if ($parentProp->flags & Modifiers::PRIVATE) { - continue; + $this->fatalError($classStmt, + "Declaration of `{$className}::\${$name}` conflicts with private property " . + "`{$parentClass}::\${$name}`; property shadowing across inheritance is not allowed"); } if ($childProp->type !== $parentProp->type || $childProp->class !== $parentProp->class) { $this->fatalError($classStmt, From 4b1b20c7ca18b417cef05f2773c7eb1b96eb2592 Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 19:58:04 +0800 Subject: [PATCH 36/37] =?UTF-8?q?refactor(php):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=AE=BF=E9=97=AE=E8=A7=A3=E6=9E=90=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E5=B9=B6=E5=BC=95=E5=85=A5=E7=BC=96=E8=AF=91=E9=98=B6?= =?UTF-8?q?=E6=AE=B5=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入 PropertyAccessResolver 类统一处理属性访问逻辑 - 添加编译阶段管理 (idle/prepare/convert) 确保模块正确使用时机 - 将 isSameClassName、isSameOrSubclassOf、canAccessProtectedProperty 方法委托给 resolver - 实现 PropertyAccessResult DTO 承载属性访问解析结果 - 为 Preprocessor 和 Translator 添加编译阶段进入/恢复逻辑 - 创建 CompilerPhaseTest 验证阶段管理功能 - 更新文档说明重构计划和模块拆分方向 - 修改函数返回值测试以适配重构后的测试需求 --- docs/README.md | 13 + docs/REFACTORING_PLAN.md | 396 ++++++++++++++++++ phpunit/src/CompilerPhaseTest.php | 61 +++ src/Php/CompilerBase.php | 99 ++--- src/Php/Preprocessor.php | 113 ++--- src/Php/Resolver/PropertyAccessResolver.php | 109 +++++ src/Php/Resolver/PropertyAccessResult.php | 24 ++ src/Php/Translator.php | 33 +- .../closure/read-private-prop-in-closure.phpt | 35 ++ tests/aot/functions/return-value.phpt | 8 +- 10 files changed, 765 insertions(+), 126 deletions(-) create mode 100644 docs/REFACTORING_PLAN.md create mode 100644 phpunit/src/CompilerPhaseTest.php create mode 100644 src/Php/Resolver/PropertyAccessResolver.php create mode 100644 src/Php/Resolver/PropertyAccessResult.php create mode 100644 tests/aot/closure/read-private-prop-in-closure.phpt diff --git a/docs/README.md b/docs/README.md index e6bd8505..2a6856c8 100644 --- a/docs/README.md +++ b/docs/README.md @@ -119,6 +119,19 @@ --- +### 9. [核心重构计划](REFACTORING_PLAN.md) +**必读指数**: ⭐⭐⭐⭐ + +内容概要: +- 核心类职责拆分方向 +- TypeSystem、SymbolResolver、PropertyAccessResolver、CallResolver 等模块规划 +- 渐进式重构阶段计划 +- 测试门禁和风险控制要求 + +**适合人群**: 核心开发者、架构重构参与者 + +--- + ## 🎯 快速导航 ### 按使用场景 diff --git a/docs/REFACTORING_PLAN.md b/docs/REFACTORING_PLAN.md new file mode 100644 index 00000000..18d5095c --- /dev/null +++ b/docs/REFACTORING_PLAN.md @@ -0,0 +1,396 @@ +# AOT 编译器核心重构计划 + +## 背景 + +当前 AOT 编译器核心类承担了过多职责,尤其是 `CompilerBase`、`Translator` 等类同时包含 AST 分发、类型推导、属性访问解析、调用解析、代码生成、诊断信息、上下文状态维护等逻辑。随着功能持续增加,这种结构会带来以下问题: + +- 封装性不足,修改一个语义点时容易影响多个代码路径。 +- 代码复用不足,同类逻辑在普通属性、静态属性、nullsafe、assignment、isset/empty/refval 等路径中重复实现。 +- 编译期检查容易出现绕过路径,例如某些动态 fallback 没有复用静态 resolver。 +- 单个类代码量过大,review、测试定位和长期维护成本持续升高。 +- 设计边界不清晰,类型系统、符号解析、属性访问、调用生成之间耦合过深。 + +本计划用于指导后续逐步重构,目标是改善架构质量,同时避免一次性大规模重写带来的行为回归风险。 + +## 核心原则 + +1. 渐进式重构,禁止一次性重写核心编译流程。 +2. 优先抽离无状态或低状态依赖的纯逻辑,再抽离依赖编译上下文的逻辑。 +3. 每一步重构应尽量保持行为不变,行为变更必须单独说明并补测试。 +4. 新模块应围绕稳定领域建模,而不是简单按 AST 节点机械拆分。 +5. 优先使用小型 service/helper、明确 DTO、resolver、emitter;仅在边界稳定后再引入 Visitor、Strategy 等模式。 +6. 所有错误信息保持 PHP 风格,不暴露实现细节,不使用 “AOT 禁止” 这类表述。 +7. 每个阶段必须有 phpunit 或 phpt 回归验证,尤其是属性、类型、调用、继承、异常等高风险路径。 + +## 目标架构方向 + +### CompilerBase + +最终应收敛为编译上下文、公共工具、AST 调度入口和跨模块协作层,不再直接承载大量领域逻辑。 + +保留职责: + +- 当前文件、函数、类、方法上下文管理。 +- 临时变量、局部变量、作用域状态维护。 +- AST 顶层分发入口。 +- fatal/warning 的统一入口。 +- 与下层 resolver/emitter 的协作。 + +逐步移出职责: + +- 类型声明解析和类型兼容判断。 +- 属性可见性、属性 offset、typed property 检查。 +- 函数和方法调用解析。 +- 复杂表达式代码生成。 +- union/intersection/nullable runtime typecheck 生成。 + +### Translator + +保留文件级、类级、函数级编译流程控制,逐步减少具体语义检查和表达式生成逻辑。 + +保留职责: + +- 文件扫描和转换入口。 +- 类、函数、方法代码块生成流程。 +- class/function/constant/property metadata 注册。 +- 编译产物组织。 + +逐步移出职责: + +- 继承兼容检查的细节逻辑。 +- trait 属性冲突检查细节。 +- 参数、返回值、属性类型兼容判断。 + +## 模块拆分计划 + +### 1. TypeSystem + +职责: + +- 类型声明解析。 +- PHP 类型到 AOT 内部类型映射。 +- nullable、union、intersection 类型展开。 +- 参数、返回值、属性、常量的类型兼容判断。 +- 静态类型与 runtime typecheck 的边界定义。 +- 类型字符串格式化。 + +建议子模块: + +- `TypeResolver` +- `TypeCompatibility` +- `TypeCheckEmitter` +- `TypeStringFormatter` + +设计要求: + +- union、intersection、nullable 在静态阶段仍可按 mixed/any 处理,但必须保留 runtime typecheck 信息。 +- `self`、`parent`、`static` 等特殊类型名的解析规则必须集中,避免多个路径实现不一致。 +- 类型错误信息必须包含函数、方法、参数、属性等必要上下文。 + +### 2. SymbolResolver + +职责: + +- 命名空间解析。 +- use alias 解析。 +- `self`、`parent`、`static` 解析。 +- 类、接口、trait、函数、常量名称规范化。 +- 动态符号和静态可解析符号的边界判断。 + +建议接口: + +- `resolveClassName(NodeAbstract $node): SymbolResolution` +- `resolveFunctionName(NodeAbstract $node): SymbolResolution` +- `resolveMethodScope(NodeAbstract $node): SymbolResolution` +- `resolveClassConstScope(NodeAbstract $node): SymbolResolution` + +设计要求: + +- 不同调用路径不能重复实现 `self/parent/static` 规则。 +- 对无法静态确定的符号,应明确返回 dynamic 状态,而不是默默退化为字符串拼接。 + +### 3. PropertyAccessResolver + +职责: + +- 对象属性访问解析。 +- 静态属性访问解析。 +- nullsafe 属性访问静态检查。 +- private/protected/public 可见性检查。 +- native property offset 查找。 +- typed property 写入 typecheck 信息生成入口。 +- static-vs-instance 属性误用检查。 + +建议接口: + +- `resolveInstancePropertyAccess(PropertyAccessRequest $request): PropertyAccessResult` +- `resolveStaticPropertyAccess(StaticPropertyAccessRequest $request): PropertyAccessResult` +- `assertReadable(PropertyAccessResult $result): void` +- `assertWritable(PropertyAccessResult $result): void` +- `emitRead(PropertyAccessResult $result): string` +- `emitWrite(PropertyAccessResult $result, string $value): string` + +需要统一覆盖的路径: + +- `$obj->prop` +- `$obj?->prop` +- `Class::$prop` +- `self::$prop` +- `parent::$prop` +- `static::$prop` +- `isset($obj->prop)` +- `empty($obj->prop)` +- `refval($obj->prop)` +- 普通赋值、复合赋值、自增自减、unset。 + +第一优先级建议从本模块开始,因为近期问题集中在属性访问和可见性绕过,测试边界相对清晰。 + +### 4. CallResolver + +职责: + +- 函数调用解析。 +- 对象方法调用解析。 +- 静态方法调用解析。 +- native call 与 dynamic call 选择。 +- named args、unpack、by-ref 参数处理。 +- closure 和动态 callable 退化规则。 + +建议接口: + +- `resolveFunctionCall(CallRequest $request): CallResolution` +- `resolveMethodCall(MethodCallRequest $request): CallResolution` +- `resolveStaticCall(StaticCallRequest $request): CallResolution` +- `emitCall(CallResolution $resolution): string` + +设计要求: + +- 静态 function 和内置 function 参数信息明确时,可以自动转引用。 +- 动态调用、closure、编译期无法获取参数 by-ref 信息时,必须要求显式 `refval()`。 +- 使用 unpack 并追加尾部 named args 时,应退化为 dynamic call,不能走 native call。 + +### 5. ExpressionEmitter + +职责: + +- 表达式级代码生成。 +- 将大型 `parseExpr()` 分发逻辑逐步拆分。 +- 复用 resolver 结果生成 C++ 代码。 + +建议按领域拆分,而不是一开始拆成大量 AST visitor: + +- `AssignmentEmitter` +- `PropertyEmitter` +- `CallEmitter` +- `ArrayEmitter` +- `ControlExprEmitter` +- `ObjectEmitter` + +设计要求: + +- 先保持现有 `parseExpr()` 作为调度入口。 +- 每次只迁移一组表达式,迁移后跑对应测试组。 +- 对表达式副作用、求值顺序、临时变量生成必须保守处理。 + +### 6. Diagnostic + +职责: + +- 统一 fatal/warning 构造。 +- 提供上下文增强能力。 +- 保证错误消息风格接近 PHP。 + +建议能力: + +- 当前函数/方法名。 +- 参数名。 +- 属性名和类名。 +- 源码位置。 +- 声明位置与使用位置。 + +设计要求: + +- 错误信息不出现 “AOT” 作为行为主体。 +- 对用户可修复的问题,应包含准确符号名。 +- 编译期能发现的问题优先编译期 fatal,不应依赖运行时 typecheck 异常兜底。 + +## 阶段计划 + +### 阶段 1:属性访问解析模块化 + +目标: + +- 抽离 `findNativeProperty()`、`findNativeStaticProperty()`、`canAccessProtectedProperty()` 等属性访问解析逻辑。 +- 保持生成代码基本不变。 +- 建立统一的 `PropertyAccessResult`,承载属性声明、声明类、访问类、是否 native、offset、是否 dynamic 等信息。 + +范围: + +- 普通对象属性读取。 +- 静态属性读取。 +- nullsafe 属性静态检查。 +- 属性可见性检查。 + +当前进展: + +- 已建立 `PropertyAccessResolver` 和 `PropertyAccessResult` 作为属性访问解析的第一层抽象。 +- `CompilerBase::findNativeProperty()` 保留为兼容入口,并委托 resolver 执行 native property 查找、static-vs-instance 检查和可见性检查。 +- `CompilerBase::isSameClassName()`、`isSameOrSubclassOf()`、`canAccessProtectedProperty()` 已委托 resolver,避免规则继续扩散。 +- 已添加 `prepare/convert/idle` 编译阶段状态;`PropertyAccessResolver` 只能在 convert 阶段创建和使用,避免预处理阶段误用不完整的类表状态。 +- 当前迁移保持生成代码不变,后续阶段再统一 read/write emitter。 + +验证: + +- `phpunit/src/NativePropertyTest.php` +- `phpunit/src/InheritanceErrorTest.php` +- object property 相关 phpt。 +- static property 相关 phpt。 +- nullsafe 相关 phpt。 + +### 阶段 2:属性写入路径统一 + +目标: + +- 所有属性写入路径先 resolve,再 emit。 +- typed property runtime typecheck 从散落逻辑收敛到属性写入模块。 +- 消除 assignment、compound assignment、inc/dec、unset 各自实现属性访问规则的问题。 + +范围: + +- `$obj->prop = $value` +- `$obj->prop += $value` +- `$obj->prop++` +- `unset($obj->prop)` +- `Class::$prop = $value` +- `??=` 相关属性路径。 + +验证: + +- typed property 相关 phpunit/phpt。 +- object property optimization 相关 phpt。 +- nullsafe 写上下文错误测试。 +- private/protected/static 属性错误测试。 + +### 阶段 3:类型系统模块化 + +目标: + +- 抽离类型声明解析、类型兼容、runtime typecheck 生成。 +- 明确静态类型推导和运行时 typecheck 的职责边界。 +- 减少参数、返回值、属性、常量各自重复处理类型规则。 + +范围: + +- `parseTypeDecl()`。 +- `buildTypeCheckFromNode()`。 +- 参数 typecheck。 +- 返回值 typecheck。 +- 属性 typecheck。 +- 常量类型处理。 + +验证: + +- union、intersection、nullable 类型测试。 +- 参数、返回值、属性 typecheck 测试。 +- namespace constant 测试。 +- constructor、void expression 相关测试。 + +### 阶段 4:调用解析模块化 + +目标: + +- 统一函数、方法、静态方法调用解析。 +- 明确 native call、dynamic call、closure call 的退化规则。 +- 集中处理 named args、unpack、by-ref 参数。 + +范围: + +- `parseFuncCall()`。 +- `parseMethodCall()`。 +- `parseStaticCall()`。 +- call args 解析。 +- native/internal/user function 调用路径。 + +验证: + +- named args、unpack 相关 phpt。 +- by-ref 参数相关 phpt。 +- closure 相关 phpt。 +- parent/self/static call 相关 phpt。 + +### 阶段 5:表达式生成器拆分 + +目标: + +- 将 `parseExpr()` 背后的大量表达式生成逻辑迁移到领域 emitter。 +- `CompilerBase` 保持调度和共享上下文能力。 +- 降低单文件和单类代码量。 + +范围: + +- AssignmentEmitter。 +- PropertyEmitter。 +- CallEmitter。 +- ArrayEmitter。 +- ControlExprEmitter。 + +验证: + +- 每迁移一个 emitter,跑对应测试组。 +- 最后跑核心 phpunit 和选定 phpt 回归集。 + +### 阶段 6:Translator 收敛 + +目标: + +- 将继承兼容、trait 合并、类成员校验等逻辑抽离成专门 checker。 +- `Translator` 聚焦编译流程组织。 + +建议子模块: + +- `InheritanceChecker` +- `TraitCompositionChecker` +- `ClassMemberValidator` +- `FunctionSignatureChecker` + +验证: + +- 继承错误 phpunit。 +- trait 相关 phpt。 +- interface/abstract/final/readonly 相关 phpt。 + +## 测试门禁 + +每个重构 PR 或阶段至少满足: + +- 相关 phpunit 必须通过。 +- 相关 phpt 必须通过。 +- 如果修改 C++/phpx,需要补 gtest 并通过对应测试。 +- 如果引入新编译期错误,需要新增固定 fixture 到 `phpunit/code` 或新增 phpt。 +- 不使用 `file_put_contents()` 临时生成源码作为新测试方式。 + +建议按模块维护最小回归集: + +- 属性模块:`NativePropertyTest`、`InheritanceErrorTest`、object property、static property、nullsafe。 +- 类型模块:type_decl、type_hits、typed property、union/intersection/nullable。 +- 调用模块:function call、method call、parent_call、closure、named args、unpack、by-ref。 +- 控制流和表达式:ternary、match、goto、loop、array、coalesce、void expression。 + +## 风险控制 + +- 不在同一个变更中同时做大规模文件移动和行为变更。 +- 每次迁移前先补当前行为的测试,尤其是历史 bug 对应路径。 +- 保留旧入口一段时间,通过 adapter 调用新模块,降低切换风险。 +- 对动态 PHP 语义保持保守,无法静态确定时不要过度优化。 +- 对 AOT 明确不兼容 PHP 历史包袱的地方,应在文档和错误信息中表达为语言规则,而不是实现限制。 + +## 推荐下一步 + +从 `PropertyAccessResolver` 开始。 + +理由: + +- 最近 bug 多集中在属性访问、可见性、typed property、nullsafe、static-vs-instance 路径。 +- 现有测试较容易扩展。 +- 属性访问是类型系统、优化器、调用生成之外相对独立的领域,适合先建立 resolver/result 模式。 +- 完成后可直接减少 `CompilerBase` 中的复杂分支,并为后续 ExpressionEmitter 拆分打基础。 diff --git a/phpunit/src/CompilerPhaseTest.php b/phpunit/src/CompilerPhaseTest.php new file mode 100644 index 00000000..b767aa61 --- /dev/null +++ b/phpunit/src/CompilerPhaseTest.php @@ -0,0 +1,61 @@ +forTest = true; + return $compiler; + } + + public function enterPreparePhase(): void + { + $this->enterCompilerPhase(self::PHASE_PREPARE); + } + + public function enterConvertPhase(): void + { + $this->enterCompilerPhase(self::PHASE_CONVERT); + } + + public function probePropertyAccessResolver(): bool + { + return $this->canAccessProtectedProperty('ProbeClass', 'ProbeClass'); + } +} + +class CompilerPhaseTest extends \PHPUnit\Framework\TestCase +{ + public function testPropertyAccessResolverCannotBeUsedOutsideConvertPhase(): void + { + $compiler = CompilerPhaseProbe::createProbe(ROOT_PATH); + + $this->expectException(TestError::class); + $this->expectExceptionMessage('PropertyAccessResolver can only be used during convert phase'); + + $compiler->probePropertyAccessResolver(); + } + + public function testPropertyAccessResolverCannotBeUsedDuringPreparePhase(): void + { + $compiler = CompilerPhaseProbe::createProbe(ROOT_PATH); + $compiler->enterPreparePhase(); + + $this->expectException(TestError::class); + $this->expectExceptionMessage('PropertyAccessResolver can only be used during convert phase'); + + $compiler->probePropertyAccessResolver(); + } + + public function testPropertyAccessResolverCanBeUsedDuringConvertPhase(): void + { + $compiler = CompilerPhaseProbe::createProbe(ROOT_PATH); + $compiler->enterConvertPhase(); + + $this->assertTrue($compiler->probePropertyAccessResolver()); + } +} diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index e4a6d079..8ef0bf04 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -43,6 +43,7 @@ use PhpAot\Php\Platform\Macos; use PhpAot\Php\Platform\PlatformBase; use PhpAot\Php\Platform\PlatformFactory; use PhpAot\Php\Platform\Windows; +use PhpAot\Php\Resolver\PropertyAccessResolver; use PhpParser\Modifiers; use PhpParser\Node; use PhpParser\Node\ArrayItem; @@ -163,8 +164,12 @@ class CompilerBase extends \PhpAot\Core\Translator public const string BUILD_MODE_EXT = 'ext'; public const string ENTRY_FUNCTION = 'main'; public const string PHPX_VENDOR_DIR = '/vendor/swoole/phpx'; + protected const string PHASE_IDLE = 'idle'; + protected const string PHASE_PREPARE = 'prepare'; + protected const string PHASE_CONVERT = 'convert'; protected string $lang = 'PHP'; + protected string $compilerPhase = self::PHASE_IDLE; protected string $cppCompiler = ''; protected array $literalStrings = []; protected int $literalStringIndex = 0; @@ -845,6 +850,25 @@ class CompilerBase extends \PhpAot\Core\Translator $this->methodDef = null; } + protected function enterCompilerPhase(string $phase): string + { + $previous = $this->compilerPhase; + $this->compilerPhase = $phase; + return $previous; + } + + protected function restoreCompilerPhase(string $phase): void + { + $this->compilerPhase = $phase; + } + + protected function assertCompilerPhase(string $expected, string $feature): void + { + if ($this->compilerPhase !== $expected) { + $this->error("Internal compiler error: {$feature} can only be used during {$expected} phase, current phase is {$this->compilerPhase}"); + } + } + protected function resetClass(): void { $this->class = ''; @@ -5810,31 +5834,29 @@ class CompilerBase extends \PhpAot\Core\Translator return null; } + private function createPropertyAccessResolver(): PropertyAccessResolver + { + $this->assertCompilerPhase(self::PHASE_CONVERT, 'PropertyAccessResolver'); + return new PropertyAccessResolver( + fn(string $class): ?ClassDef => $this->classes[$this->escapeClass($class)] ?? null, + fn(string $class): string => $this->classExtends[strtolower(ltrim($class, '\\'))] ?? '', + fn(NodeAbstract $expr, string $message) => $this->fatalError($expr, $message), + ); + } + protected function isSameClassName(string $classA, string $classB): bool { - return strcasecmp(ltrim($classA, '\\'), ltrim($classB, '\\')) === 0; + return $this->createPropertyAccessResolver()->isSameClassName($classA, $classB); } protected function isSameOrSubclassOf(string $class, string $parent): bool { - $class = strtolower(ltrim($class, '\\')); - $parent = strtolower(ltrim($parent, '\\')); - while ($class !== '') { - if ($class === $parent) { - return true; - } - $class = $this->classExtends[$class] ?? ''; - } - return false; + return $this->createPropertyAccessResolver()->isSameOrSubclassOf($class, $parent); } protected function canAccessProtectedProperty(string $scope, string $declaringClass): bool { - if ($scope === '') { - return false; - } - return $this->isSameOrSubclassOf($scope, $declaringClass) - || $this->isSameOrSubclassOf($declaringClass, $scope); + return $this->createPropertyAccessResolver()->canAccessProtectedProperty($scope, $declaringClass); } /** @@ -5843,49 +5865,12 @@ class CompilerBase extends \PhpAot\Core\Translator */ protected function findNativeProperty(NodeAbstract $expr, string $property, string $class, bool $static = false): ?string { - $class = ltrim($class, '\\'); - $findClass = $class; $scope = $this->class ? $this->getFullClassName() : ''; - $propertyDef = null; - $classDef = null; - while (true) { - if ($this->hasClass($findClass)) { - $classDef = $this->getClass($findClass); - if ($classDef->hasProperty($property)) { - $propertyDef = $classDef->getProperty($property); - if (!$static and $propertyDef->isStatic()) { - $this->fatalError($expr, "Cannot access static property `{$class}::\${$property}` as non-static instance property."); - } - if ($static and !$propertyDef->isStatic()) { - $this->fatalError($expr, "Cannot access non-static property `{$class}::\${$property}` as static property."); - } - if ($propertyDef->isPublic()) { - break; - } - if ($propertyDef->isProtected()) { - if ($this->canAccessProtectedProperty($scope, $findClass)) { - break; - } - $displayClass = ltrim($class, '\\'); - $this->fatalError($expr, "Cannot access protected property `{$property}` of class `{$displayClass}`"); - } else { - if ($this->isSameClassName($scope, $findClass)) { - break; - } - $displayClass = ltrim($class, '\\'); - $this->fatalError($expr, "Cannot access private property `{$property}` of class `{$displayClass}`"); - } - } elseif ($classDef->extends) { - $findClass = $classDef->extends; - continue; - } - } - break; - } - if ($propertyDef and $classDef) { - $expr->setAttribute('nativePropertyDef', $propertyDef); - $expr->setAttribute('nativeClassDef', $classDef); - return $this->getPropertyOffset($classDef->getNamespacedName(false), $property); + $result = $this->createPropertyAccessResolver()->resolveNativeProperty($expr, $property, $class, $scope, $static); + if ($result !== null) { + $expr->setAttribute('nativePropertyDef', $result->propertyDef); + $expr->setAttribute('nativeClassDef', $result->classDef); + return $this->getPropertyOffset($result->classDef->getNamespacedName(false), $result->property); } return null; } diff --git a/src/Php/Preprocessor.php b/src/Php/Preprocessor.php index 05a1988a..9422772a 100644 --- a/src/Php/Preprocessor.php +++ b/src/Php/Preprocessor.php @@ -93,62 +93,67 @@ class Preprocessor extends CompilerBase public function prepareFile(string $file): void { - $phpCode = $this->loadFile($file); - $this->symbolCallInFile[$this->file] = []; - $this->resetFile(); - $this->resetFunction(); - $this->resetMethod(); - $this->resetClass(); - $this->resetNamespace(); - - $this->climate->info('prepare: ' . $this->getRelativePath($this->file)); + $previousPhase = $this->enterCompilerPhase(self::PHASE_PREPARE); try { - $ast = $this->parser->parse($phpCode); - } catch (\PhpParser\Error $e) { - $this->climate->red("Fatal error: {$e->getMessage()} in {$this->file}"); - throw new SyntaxError($e->getMessage(), $e->getCode()); - } - - $traverser = new NodeTraverser(); - $traverser->addVisitor(new Visitor()); - $stmts = $traverser->traverse($ast); - - foreach ($stmts as $v) { - $type = $v->getType(); - switch ($type) { - case 'Stmt_Namespace': - $this->prepareNamespace($v); - break; - case 'Stmt_Enum': - case 'Stmt_Class': - case 'Stmt_Trait': - $this->prepareClass($v); - break; - case 'Stmt_Interface': - $this->parseInterface($v); - break; - case 'Stmt_Function': - $this->prepareFunction($v); - break; - case 'Stmt_Use': - $this->parseUse($v); - break; - case 'Stmt_GroupUse': - $this->parseGroupUse($v); - break; - case 'Stmt_Declare': - case 'Stmt_Nop': - break; - case 'Stmt_Const': - $this->parseConstDef($v); - break; - case 'Stmt_Expression': - $this->foundStrayCode($v); - break; - default: - $this->fatalError($v, 'Unsupported statement: ' . $type); - break; + $phpCode = $this->loadFile($file); + $this->symbolCallInFile[$this->file] = []; + $this->resetFile(); + $this->resetFunction(); + $this->resetMethod(); + $this->resetClass(); + $this->resetNamespace(); + + $this->climate->info('prepare: ' . $this->getRelativePath($this->file)); + try { + $ast = $this->parser->parse($phpCode); + } catch (\PhpParser\Error $e) { + $this->climate->red("Fatal error: {$e->getMessage()} in {$this->file}"); + throw new SyntaxError($e->getMessage(), $e->getCode()); + } + + $traverser = new NodeTraverser(); + $traverser->addVisitor(new Visitor()); + $stmts = $traverser->traverse($ast); + + foreach ($stmts as $v) { + $type = $v->getType(); + switch ($type) { + case 'Stmt_Namespace': + $this->prepareNamespace($v); + break; + case 'Stmt_Enum': + case 'Stmt_Class': + case 'Stmt_Trait': + $this->prepareClass($v); + break; + case 'Stmt_Interface': + $this->parseInterface($v); + break; + case 'Stmt_Function': + $this->prepareFunction($v); + break; + case 'Stmt_Use': + $this->parseUse($v); + break; + case 'Stmt_GroupUse': + $this->parseGroupUse($v); + break; + case 'Stmt_Declare': + case 'Stmt_Nop': + break; + case 'Stmt_Const': + $this->parseConstDef($v); + break; + case 'Stmt_Expression': + $this->foundStrayCode($v); + break; + default: + $this->fatalError($v, 'Unsupported statement: ' . $type); + break; + } } + } finally { + $this->restoreCompilerPhase($previousPhase); } } diff --git a/src/Php/Resolver/PropertyAccessResolver.php b/src/Php/Resolver/PropertyAccessResolver.php new file mode 100644 index 00000000..dd092c27 --- /dev/null +++ b/src/Php/Resolver/PropertyAccessResolver.php @@ -0,0 +1,109 @@ +getParentClass)($class); + } + return false; + } + + public function canAccessProtectedProperty(string $scope, string $declaringClass): bool + { + if ($scope === '') { + return false; + } + return $this->isSameOrSubclassOf($scope, $declaringClass) + || $this->isSameOrSubclassOf($declaringClass, $scope); + } + + public function resolveNativeProperty( + NodeAbstract $expr, + string $property, + string $class, + string $scope, + bool $static = false, + ): ?PropertyAccessResult { + $class = ltrim($class, '\\'); + $findClass = $class; + + while (true) { + $classDef = ($this->getClassDef)($findClass); + if ($classDef === null) { + break; + } + + if ($classDef->hasProperty($property)) { + $propertyDef = $classDef->getProperty($property); + if (!$static && $propertyDef->isStatic()) { + $this->fatal($expr, "Cannot access static property `{$class}::\${$property}` as non-static instance property."); + } + if ($static && !$propertyDef->isStatic()) { + $this->fatal($expr, "Cannot access non-static property `{$class}::\${$property}` as static property."); + } + if ($propertyDef->isPublic()) { + return new PropertyAccessResult($class, $findClass, $property, $classDef, $propertyDef); + } + if ($propertyDef->isProtected()) { + if ($this->canAccessProtectedProperty($scope, $findClass)) { + return new PropertyAccessResult($class, $findClass, $property, $classDef, $propertyDef); + } + $displayClass = ltrim($class, '\\'); + $this->fatal($expr, "Cannot access protected property `{$property}` of class `{$displayClass}`"); + } + if ($this->isSameClassName($scope, $findClass)) { + return new PropertyAccessResult($class, $findClass, $property, $classDef, $propertyDef); + } + $displayClass = ltrim($class, '\\'); + $this->fatal($expr, "Cannot access private property `{$property}` of class `{$displayClass}`"); + } + + if (!$classDef->extends) { + break; + } + $findClass = $classDef->extends; + } + + return null; + } + + private function fatal(NodeAbstract $expr, string $message): never + { + ($this->fatalError)($expr, $message); + } +} diff --git a/src/Php/Resolver/PropertyAccessResult.php b/src/Php/Resolver/PropertyAccessResult.php new file mode 100644 index 00000000..18c0fc8f --- /dev/null +++ b/src/Php/Resolver/PropertyAccessResult.php @@ -0,0 +1,24 @@ +loadFile($file); - $this->localHeaders = []; - while (true) { - try { - $cppCode = $this->doConvert($phpCode); - $cppFile = $this->getCppFile($file); - $this->save($cppCode, $cppFile); - $this->phpSrcFiles[] = $file; - // 生成 stub 文件,依赖 convert 阶段的 use 等信息 - $this->genStubFile($this->file); - return $cppFile; - } catch (Redo $e) { - continue; + $previousPhase = $this->enterCompilerPhase(self::PHASE_CONVERT); + try { + $file = realpath($file); + $phpCode = $this->loadFile($file); + $this->localHeaders = []; + while (true) { + try { + $cppCode = $this->doConvert($phpCode); + $cppFile = $this->getCppFile($file); + $this->save($cppCode, $cppFile); + $this->phpSrcFiles[] = $file; + // 生成 stub 文件,依赖 convert 阶段的 use 等信息 + $this->genStubFile($this->file); + return $cppFile; + } catch (Redo $e) { + continue; + } } + } finally { + $this->restoreCompilerPhase($previousPhase); } } diff --git a/tests/aot/closure/read-private-prop-in-closure.phpt b/tests/aot/closure/read-private-prop-in-closure.phpt new file mode 100644 index 00000000..14727d6f --- /dev/null +++ b/tests/aot/closure/read-private-prop-in-closure.phpt @@ -0,0 +1,35 @@ +--TEST-- +closure 001 +--FILE-- +arr; + }); + } +} + +function main() +{ + $foo = new Foo(); + $foo->run(); +} +?> +--EXPECT-- +array(3) { + [0]=> + int(1) + [1]=> + int(2) + [2]=> + int(3) +} diff --git a/tests/aot/functions/return-value.phpt b/tests/aot/functions/return-value.phpt index 651046de..00ff4a68 100644 --- a/tests/aot/functions/return-value.phpt +++ b/tests/aot/functions/return-value.phpt @@ -2,9 +2,15 @@ object link operator --FILE-- From 87c54236a0f42f238506dfe8902611654a69737b Mon Sep 17 00:00:00 2001 From: tianfenghan Date: Tue, 30 Jun 2026 20:10:51 +0800 Subject: [PATCH 37/37] =?UTF-8?q?refactor(php):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E5=B1=9E=E6=80=A7=E8=AE=BF=E9=97=AE=E8=A7=A3=E6=9E=90=E9=80=BB?= =?UTF-8?q?=E8=BE=91=E4=BB=A5=E4=BD=BF=E7=94=A8=E4=B8=93=E9=97=A8=E7=9A=84?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=99=A8=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 将 findNativeProperty 方法替换为更具体的 resolveNativeInstanceProperty 和 resolveNativeStaticProperty - 添加 resolveNullsafePropertyChain 方法处理空安全属性链检查 - 引入 PropertyAccessResult 类来统一属性访问结果的返回格式 - 使用 isNativePropertyAccess 方法替代直接的属性检查 - 移除旧的泛型 findNativeProperty 入口点以避免布尔参数扩散 - 更新 AssignOpTrait 中的属性访问检查逻辑 - 修改动态属性递增递减操作中的原生属性检查方式 - 调整编译器基类中的属性解析实现细节 --- docs/REFACTORING_PLAN.md | 5 +- src/Php/CompilerBase.php | 99 ++++++++++++--------- src/Php/Parser/AssignOpTrait.php | 4 +- src/Php/Resolver/PropertyAccessResolver.php | 51 +++++++++++ 4 files changed, 112 insertions(+), 47 deletions(-) diff --git a/docs/REFACTORING_PLAN.md b/docs/REFACTORING_PLAN.md index 18d5095c..b97deaf9 100644 --- a/docs/REFACTORING_PLAN.md +++ b/docs/REFACTORING_PLAN.md @@ -234,7 +234,10 @@ 当前进展: - 已建立 `PropertyAccessResolver` 和 `PropertyAccessResult` 作为属性访问解析的第一层抽象。 -- `CompilerBase::findNativeProperty()` 保留为兼容入口,并委托 resolver 执行 native property 查找、static-vs-instance 检查和可见性检查。 +- 实例属性读取已通过 resolver 的 `resolveNativeInstanceProperty()` 显式接口完成 native property 查找、static-vs-instance 检查和可见性检查。 +- `findNativeStaticProperty()` 已通过 resolver 的 `resolveNativeStaticProperty()` 显式接口完成静态属性检查。 +- nullsafe 属性链检查已通过 resolver 的 `resolveNullsafePropertyChain()` 显式接口完成类名推进和可见性检查。 +- 旧的 `CompilerBase::findNativeProperty()` 泛型入口已移除,避免后续继续扩散带 `$static` 布尔参数的访问模式。 - `CompilerBase::isSameClassName()`、`isSameOrSubclassOf()`、`canAccessProtectedProperty()` 已委托 resolver,避免规则继续扩散。 - 已添加 `prepare/convert/idle` 编译阶段状态;`PropertyAccessResolver` 只能在 convert 阶段创建和使用,避免预处理阶段误用不完整的类表状态。 - 当前迁移保持生成代码不变,后续阶段再统一 read/write emitter。 diff --git a/src/Php/CompilerBase.php b/src/Php/CompilerBase.php index 8ef0bf04..edf43899 100644 --- a/src/Php/CompilerBase.php +++ b/src/Php/CompilerBase.php @@ -43,6 +43,7 @@ use PhpAot\Php\Platform\Macos; use PhpAot\Php\Platform\PlatformBase; use PhpAot\Php\Platform\PlatformFactory; use PhpAot\Php\Platform\Windows; +use PhpAot\Php\Resolver\PropertyAccessResult; use PhpAot\Php\Resolver\PropertyAccessResolver; use PhpParser\Modifiers; use PhpParser\Node; @@ -2771,7 +2772,7 @@ class CompilerBase extends \PhpAot\Core\Translator */ protected function genDynamicPropIncDec($var, string $op, bool $isPre): ?string { - if (!$this->isPropertyFetch($var) || $var->getAttribute('nativeProperty')) { + if (!$this->isPropertyFetch($var) || $this->isNativePropertyAccess($var)) { return null; } @@ -4893,13 +4894,14 @@ class CompilerBase extends \PhpAot\Core\Translator if ($this->classDef->trait) { goto _dynamic_attr; } - $nativeProperty = $this->findNativeProperty($expr, $propertyName, $this->getFullClassName()); + $result = $this->resolveNativeInstanceProperty($expr, $propertyName, $this->getFullClassName()); + $nativeProperty = $result ? $this->applyNativePropertyAccessResult($expr, $result) : null; } elseif ($this->isTypedObject($objectName)) { $className = $this->getObjectType($objectName); - $nativeProperty = $this->findNativeProperty($expr, $propertyName, $className); + $result = $this->resolveNativeInstanceProperty($expr, $propertyName, $className); + $nativeProperty = $result ? $this->applyNativePropertyAccessResult($expr, $result) : null; } if ($nativeProperty) { - $expr->setAttribute('nativeProperty', $nativeProperty); return $nativeProperty; } } @@ -5427,7 +5429,7 @@ class CompilerBase extends \PhpAot\Core\Translator // 单属性读取(非链式) if ($this->isPropertyFetch($expr) and $this->isVarExpr($expr->var) and $this->isIdExpr($expr->name)) { $prop = $this->parsePropertyFetch($expr); - if ($expr->hasAttribute('nativeProperty')) { + if ($this->isNativePropertyAccess($expr)) { if ($op === self::OP_REFVAL) { return $prop . '.toReference()'; } @@ -5436,7 +5438,7 @@ class CompilerBase extends \PhpAot\Core\Translator } if ($this->isStaticPropertyFetch($expr) and $this->isNameExpr($expr->class) and $this->isIdExpr($expr->name)) { $prop = $this->parseStaticPropertyFetch($expr); - if ($expr->hasAttribute('nativeProperty')) { + if ($this->isNativePropertyAccess($expr)) { if ($op === self::OP_REFVAL) { return $prop . '.toReference()'; } @@ -5825,10 +5827,9 @@ class CompilerBase extends \PhpAot\Core\Translator } else { $class = $this->getNamespacedClassName($class); } - $nativeProperty = $this->findNativeProperty($expr, $propertyName, $class, true); - if ($nativeProperty) { - $expr->setAttribute('nativeProperty', $nativeProperty); - return $nativeProperty; + $result = $this->resolveNativeStaticProperty($expr, $propertyName, $class); + if ($result !== null) { + return $this->applyNativePropertyAccessResult($expr, $result); } } return null; @@ -5859,20 +5860,30 @@ class CompilerBase extends \PhpAot\Core\Translator return $this->createPropertyAccessResolver()->canAccessProtectedProperty($scope, $declaringClass); } - /** - * @param NodeAbstract $expr 仅用于输出错误日志 - * @param string $class 必须传入带有完整命名空间的类名 - */ - protected function findNativeProperty(NodeAbstract $expr, string $property, string $class, bool $static = false): ?string + private function resolveNativeInstanceProperty(NodeAbstract $expr, string $property, string $class): ?PropertyAccessResult { $scope = $this->class ? $this->getFullClassName() : ''; - $result = $this->createPropertyAccessResolver()->resolveNativeProperty($expr, $property, $class, $scope, $static); - if ($result !== null) { - $expr->setAttribute('nativePropertyDef', $result->propertyDef); - $expr->setAttribute('nativeClassDef', $result->classDef); - return $this->getPropertyOffset($result->classDef->getNamespacedName(false), $result->property); - } - return null; + return $this->createPropertyAccessResolver()->resolveNativeInstanceProperty($expr, $property, $class, $scope); + } + + private function resolveNativeStaticProperty(NodeAbstract $expr, string $property, string $class): ?PropertyAccessResult + { + $scope = $this->class ? $this->getFullClassName() : ''; + return $this->createPropertyAccessResolver()->resolveNativeStaticProperty($expr, $property, $class, $scope); + } + + private function applyNativePropertyAccessResult(NodeAbstract $expr, PropertyAccessResult $result): string + { + $offset = $this->getPropertyOffset($result->classDef->getNamespacedName(false), $result->property); + $expr->setAttribute('nativePropertyDef', $result->propertyDef); + $expr->setAttribute('nativeClassDef', $result->classDef); + $expr->setAttribute('nativeProperty', $offset); + return $offset; + } + + protected function isNativePropertyAccess(NodeAbstract $expr): bool + { + return $expr->hasAttribute('nativeProperty'); } protected function parseNativeStaticPropertyFetch(Expr\StaticPropertyFetch $expr): string|bool @@ -5913,7 +5924,7 @@ class CompilerBase extends \PhpAot\Core\Translator return $refVar; } - if ($expr->hasAttribute('nativeProperty')) { + if ($this->isNativePropertyAccess($expr)) { $classPtr = $this->getClassEntryPtr($class); return Symbol::getStaticProperty() . '(' . $classPtr . ', ' . $nativeProp . ')'; } else { @@ -6895,37 +6906,37 @@ class CompilerBase extends \PhpAot\Core\Translator private function checkNullsafePropertyAccesses(NodeAbstract $baseExpr, array $list): void { - $className = $this->detectClassOfExpr($baseExpr); - if ($className === '') { - return; - } - + $properties = []; foreach ($list as $item) { if ($item[0] !== 'property') { - $className = ''; - continue; + break; } /** @var Expr\NullsafePropertyFetch $node */ $node = $item[2]; if (!$this->isIdExpr($node->name)) { - $className = ''; - continue; + break; } - $property = $this->parseIdentifier($node->name); - $this->findNativeProperty($node, $property, $className); - if (!$node->hasAttribute('nativePropertyDef')) { - $className = ''; - continue; - } + $properties[] = [ + 'node' => $node, + 'property' => $this->parseIdentifier($node->name), + ]; + } - /** @var PropertyDef $def */ - $def = $node->getAttribute('nativePropertyDef'); - $className = $def->type === self::TYPE_OBJECT ? $def->class : ''; - if ($className === '') { - return; - } + if (!$properties) { + return; + } + + $scope = $this->class ? $this->getFullClassName() : ''; + $results = $this->createPropertyAccessResolver()->resolveNullsafePropertyChain( + $this->detectClassOfExpr($baseExpr), + $properties, + $scope, + self::TYPE_OBJECT, + ); + foreach ($results as $index => $result) { + $this->applyNativePropertyAccessResult($properties[$index]['node'], $result); } } diff --git a/src/Php/Parser/AssignOpTrait.php b/src/Php/Parser/AssignOpTrait.php index eab77ac8..abdaedf3 100644 --- a/src/Php/Parser/AssignOpTrait.php +++ b/src/Php/Parser/AssignOpTrait.php @@ -260,7 +260,7 @@ trait AssignOpTrait $this->checkVarAssignExpr($left, $finalVarType, $type); } } - } elseif ($this->isPropertyFetch($left) and !$left->getAttribute('nativeProperty')) { + } elseif ($this->isPropertyFetch($left) and !$this->isNativePropertyAccess($left)) { return $this->parseAssignPropertyFetch($left, $right); } elseif ($this->isArrayDimFetch($left) and $this->isVarExpr($left->var)) { $tmp = $this->parseIdentifier($left->var); @@ -397,7 +397,7 @@ trait AssignOpTrait return $this->parseArrayDimStore($node->var->var, $dim, $tmpVar); } - if ($this->isPropertyFetch($node->var) and !$node->var->getAttribute('nativeProperty')) { + if ($this->isPropertyFetch($node->var) and !$this->isNativePropertyAccess($node->var)) { $obj = $this->parseIdentifier($node->var->var); $propName = $this->identifierToStr($node->var->name, literal: true); $binaryOp = $this->removeAssignOp($op); diff --git a/src/Php/Resolver/PropertyAccessResolver.php b/src/Php/Resolver/PropertyAccessResolver.php index dd092c27..9fe2a1ca 100644 --- a/src/Php/Resolver/PropertyAccessResolver.php +++ b/src/Php/Resolver/PropertyAccessResolver.php @@ -102,6 +102,57 @@ final class PropertyAccessResolver return null; } + public function resolveNativeInstanceProperty( + NodeAbstract $expr, + string $property, + string $class, + string $scope, + ): ?PropertyAccessResult { + return $this->resolveNativeProperty($expr, $property, $class, $scope); + } + + public function resolveNativeStaticProperty( + NodeAbstract $expr, + string $property, + string $class, + string $scope, + ): ?PropertyAccessResult { + return $this->resolveNativeProperty($expr, $property, $class, $scope, true); + } + + /** + * @param array $properties + * @return array + */ + public function resolveNullsafePropertyChain( + string $baseClass, + array $properties, + string $scope, + string $objectType, + ): array { + if ($baseClass === '') { + return []; + } + + $className = $baseClass; + $resolved = []; + foreach ($properties as $index => $property) { + $result = $this->resolveNativeProperty($property['node'], $property['property'], $className, $scope); + if ($result === null) { + break; + } + + $resolved[$index] = $result; + $def = $result->propertyDef; + if ($def->type !== $objectType || $def->class === '') { + break; + } + $className = $def->class; + } + + return $resolved; + } + private function fatal(NodeAbstract $expr, string $message): never { ($this->fatalError)($expr, $message);