parent
eb5510e64a
commit
934628e2c2
6 changed files with 228 additions and 0 deletions
@ -0,0 +1,24 @@ |
|||||||
|
--TEST-- |
||||||
|
array keys filtered by closure keep keys for strict comparison |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function has_only_string_keys(array $array): bool |
||||||
|
{ |
||||||
|
return $array |
||||||
|
&& array_keys($array) === array_filter(array_keys($array), function ($key) { |
||||||
|
return is_string($key); |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
var_dump(has_only_string_keys(['a' => 1, 'b' => 2])); |
||||||
|
var_dump(has_only_string_keys(['a' => 1, 0 => 2])); |
||||||
|
var_dump(has_only_string_keys([])); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
bool(false) |
||||||
|
bool(false) |
||||||
@ -0,0 +1,23 @@ |
|||||||
|
--TEST-- |
||||||
|
array keys compared with range for list detection |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function is_non_empty_list_legacy(array $array): bool |
||||||
|
{ |
||||||
|
return $array && array_keys($array) === range(0, count($array) - 1); |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
var_dump(is_non_empty_list_legacy(['x', 'y'])); |
||||||
|
var_dump(is_non_empty_list_legacy([1 => 'x', 2 => 'y'])); |
||||||
|
var_dump(is_non_empty_list_legacy(['0' => 'x', '1' => 'y'])); |
||||||
|
var_dump(is_non_empty_list_legacy([])); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
bool(false) |
||||||
|
bool(true) |
||||||
|
bool(false) |
||||||
@ -0,0 +1,41 @@ |
|||||||
|
--TEST-- |
||||||
|
static arrow function with typed parameter return clone in array_map |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class CloneMapItem |
||||||
|
{ |
||||||
|
public int $value; |
||||||
|
|
||||||
|
public function __construct(int $value) |
||||||
|
{ |
||||||
|
$this->value = $value; |
||||||
|
} |
||||||
|
|
||||||
|
public function __clone() |
||||||
|
{ |
||||||
|
$this->value++; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function clone_items(array $items): array |
||||||
|
{ |
||||||
|
return array_map(static fn (CloneMapItem $item): CloneMapItem => clone $item, $items); |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$items = [new CloneMapItem(1), new CloneMapItem(10)]; |
||||||
|
$cloned = clone_items($items); |
||||||
|
|
||||||
|
var_dump($items[0]->value, $items[1]->value); |
||||||
|
var_dump($cloned[0]->value, $cloned[1]->value); |
||||||
|
var_dump($items[0] === $cloned[0]); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
int(1) |
||||||
|
int(10) |
||||||
|
int(2) |
||||||
|
int(11) |
||||||
|
bool(false) |
||||||
@ -0,0 +1,56 @@ |
|||||||
|
--TEST-- |
||||||
|
closure typed argument with catch chain and dynamic instanceof |
||||||
|
--ENV-- |
||||||
|
USE_ZEND_ALLOC=0 |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
class ExpectedClosureException extends Exception {} |
||||||
|
class ExpectedClosureError extends Error {} |
||||||
|
|
||||||
|
function catches_expected(Closure $expression, string $class): bool |
||||||
|
{ |
||||||
|
$actual = 'none'; |
||||||
|
|
||||||
|
try { |
||||||
|
$expression(); |
||||||
|
} catch (Exception $e) { |
||||||
|
$actual = get_class($e); |
||||||
|
if ($e instanceof $class) { |
||||||
|
echo "matched-exception:$actual\n"; |
||||||
|
return true; |
||||||
|
} |
||||||
|
} catch (Throwable $e) { |
||||||
|
$actual = get_class($e); |
||||||
|
if ($e instanceof $class) { |
||||||
|
echo "matched-throwable:$actual\n"; |
||||||
|
return true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
echo "miss:$actual\n"; |
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
var_dump(catches_expected(function () { |
||||||
|
throw new ExpectedClosureException('ok'); |
||||||
|
}, ExpectedClosureException::class)); |
||||||
|
|
||||||
|
var_dump(catches_expected(function () { |
||||||
|
throw new ExpectedClosureError('err'); |
||||||
|
}, ExpectedClosureError::class)); |
||||||
|
|
||||||
|
var_dump(catches_expected(function () { |
||||||
|
throw new Exception('base'); |
||||||
|
}, ExpectedClosureException::class)); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
matched-exception:ExpectedClosureException |
||||||
|
bool(true) |
||||||
|
matched-throwable:ExpectedClosureError |
||||||
|
bool(true) |
||||||
|
miss:Exception |
||||||
|
bool(false) |
||||||
@ -0,0 +1,54 @@ |
|||||||
|
--TEST-- |
||||||
|
array_search keys with array_slice and array_reverse preserving keys |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function select_version_flags(array $flagsByVersions, int $minVersion, ?int $maxVersion): array |
||||||
|
{ |
||||||
|
ksort($flagsByVersions); |
||||||
|
|
||||||
|
$index = array_search($minVersion, array_keys($flagsByVersions)); |
||||||
|
if ($index === false) { |
||||||
|
return []; |
||||||
|
} |
||||||
|
$flagsByVersions = array_slice($flagsByVersions, $index, null, true); |
||||||
|
|
||||||
|
if ($maxVersion !== null) { |
||||||
|
$index = array_search($maxVersion, array_keys($flagsByVersions)); |
||||||
|
if ($index === false) { |
||||||
|
return []; |
||||||
|
} |
||||||
|
$flagsByVersions = array_slice($flagsByVersions, 0, $index + 1, true); |
||||||
|
} |
||||||
|
|
||||||
|
$result = []; |
||||||
|
foreach (array_reverse($flagsByVersions, true) as $version => $flags) { |
||||||
|
$result[] = $version . ':' . implode('|', $flags); |
||||||
|
} |
||||||
|
return $result; |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$flags = [ |
||||||
|
80400 => ['D'], |
||||||
|
80000 => ['A'], |
||||||
|
80200 => ['B'], |
||||||
|
80300 => ['C'], |
||||||
|
]; |
||||||
|
|
||||||
|
var_dump(select_version_flags($flags, 80200, 80400)); |
||||||
|
var_dump(select_version_flags($flags, 80100, null)); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
string(7) "80400:D" |
||||||
|
[1]=> |
||||||
|
string(7) "80300:C" |
||||||
|
[2]=> |
||||||
|
string(7) "80200:B" |
||||||
|
} |
||||||
|
array(0) { |
||||||
|
} |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
--TEST-- |
||||||
|
filter_var IP validation with strict false checks and flags |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
|
||||||
|
function classify_ip(string $value): string |
||||||
|
{ |
||||||
|
if (false === filter_var($value, FILTER_VALIDATE_IP)) { |
||||||
|
return 'invalid'; |
||||||
|
} |
||||||
|
if (false !== filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { |
||||||
|
return 'ipv4'; |
||||||
|
} |
||||||
|
if (false !== filter_var($value, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) { |
||||||
|
return 'ipv6'; |
||||||
|
} |
||||||
|
return 'unknown'; |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
var_dump(classify_ip('127.0.0.1')); |
||||||
|
var_dump(classify_ip('2001:db8::1')); |
||||||
|
var_dump(classify_ip('not-an-ip')); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
string(4) "ipv4" |
||||||
|
string(4) "ipv6" |
||||||
|
string(7) "invalid" |
||||||
Loading…
Reference in new issue