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