parent
2a75143036
commit
bc799fda0a
9 changed files with 348 additions and 1 deletions
@ -0,0 +1,38 @@ |
|||||||
|
--TEST-- |
||||||
|
class_alias with ::class constant |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
class AliasOriginal |
||||||
|
{ |
||||||
|
public static function name(): string |
||||||
|
{ |
||||||
|
return static::class; |
||||||
|
} |
||||||
|
|
||||||
|
public static function ok(): string |
||||||
|
{ |
||||||
|
return 'ok'; |
||||||
|
} |
||||||
|
|
||||||
|
public function value(): string |
||||||
|
{ |
||||||
|
return self::class; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main() |
||||||
|
{ |
||||||
|
class_alias(AliasOriginal::class, 'AliasCopy'); |
||||||
|
|
||||||
|
$obj = new AliasCopy(); |
||||||
|
var_dump($obj instanceof AliasOriginal); |
||||||
|
var_dump($obj instanceof AliasCopy); |
||||||
|
var_dump($obj->value()); |
||||||
|
var_dump(AliasCopy::ok()); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
|
string(13) "AliasOriginal" |
||||||
|
string(2) "ok" |
||||||
@ -0,0 +1,38 @@ |
|||||||
|
--TEST-- |
||||||
|
static closure use by reference through internal callback |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$seen = []; |
||||||
|
$values = [1, 2, 3]; |
||||||
|
|
||||||
|
$result = array_map( |
||||||
|
static function (int $value) use (&$seen): int { |
||||||
|
$seen[] = $value; |
||||||
|
return $value * 10; |
||||||
|
}, |
||||||
|
$values |
||||||
|
); |
||||||
|
|
||||||
|
var_dump($result); |
||||||
|
var_dump($seen); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
int(10) |
||||||
|
[1]=> |
||||||
|
int(20) |
||||||
|
[2]=> |
||||||
|
int(30) |
||||||
|
} |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
int(1) |
||||||
|
[1]=> |
||||||
|
int(2) |
||||||
|
[2]=> |
||||||
|
int(3) |
||||||
|
} |
||||||
@ -0,0 +1,47 @@ |
|||||||
|
--TEST-- |
||||||
|
static closure use by reference through typed Closure parameter |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
function apply_items(iterable $items, Closure $callback): array |
||||||
|
{ |
||||||
|
$out = []; |
||||||
|
foreach ($items as $item) { |
||||||
|
$out[] = $callback($item); |
||||||
|
} |
||||||
|
return $out; |
||||||
|
} |
||||||
|
|
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$seen = []; |
||||||
|
$prefix = 'v'; |
||||||
|
|
||||||
|
$result = apply_items( |
||||||
|
[1, 2, 3], |
||||||
|
static function (int $value) use (&$seen, $prefix): string { |
||||||
|
$seen[] = $value; |
||||||
|
return $prefix . ($value * 10); |
||||||
|
} |
||||||
|
); |
||||||
|
|
||||||
|
var_dump($result); |
||||||
|
var_dump($seen); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
string(3) "v10" |
||||||
|
[1]=> |
||||||
|
string(3) "v20" |
||||||
|
[2]=> |
||||||
|
string(3) "v30" |
||||||
|
} |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
int(1) |
||||||
|
[1]=> |
||||||
|
int(2) |
||||||
|
[2]=> |
||||||
|
int(3) |
||||||
|
} |
||||||
@ -0,0 +1,51 @@ |
|||||||
|
--TEST-- |
||||||
|
__callStatic forwards to static method through call_user_func_array |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
class StaticForwarder |
||||||
|
{ |
||||||
|
public static function __callStatic($name, $arguments): bool |
||||||
|
{ |
||||||
|
if ('all' === substr($name, 0, 3)) { |
||||||
|
$method = lcfirst(substr($name, 3)); |
||||||
|
$args = $arguments; |
||||||
|
foreach ($arguments[0] as $entry) { |
||||||
|
$args[0] = $entry; |
||||||
|
if (!call_user_func_array(['static', $method], $args)) { |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
if ('nullOr' === substr($name, 0, 6)) { |
||||||
|
if ($arguments[0] !== null) { |
||||||
|
$method = lcfirst(substr($name, 6)); |
||||||
|
return call_user_func_array(['static', $method], $arguments); |
||||||
|
} |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
return false; |
||||||
|
} |
||||||
|
|
||||||
|
public static function lengthBetween($value, int $min, int $max): bool |
||||||
|
{ |
||||||
|
$len = strlen($value); |
||||||
|
return $len >= $min && $len <= $max; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
function main() |
||||||
|
{ |
||||||
|
var_dump(StaticForwarder::__callStatic('allLengthBetween', [['aa', 'bbbb'], 2, 4])); |
||||||
|
var_dump(StaticForwarder::__callStatic('allLengthBetween', [['a', 'bbbb'], 2, 4])); |
||||||
|
var_dump(StaticForwarder::__callStatic('nullOrLengthBetween', [null, 2, 4])); |
||||||
|
var_dump(StaticForwarder::__callStatic('nullOrLengthBetween', ['abc', 2, 4])); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
bool(false) |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
--TEST-- |
||||||
|
internal function with union return type does not crash type detection |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
function main() |
||||||
|
{ |
||||||
|
$funcs = get_extension_funcs('date'); |
||||||
|
var_dump(is_array($funcs)); |
||||||
|
|
||||||
|
if (get_extension_funcs('extension_does_not_exist')) { |
||||||
|
echo "unexpected\n"; |
||||||
|
} else { |
||||||
|
echo "false branch\n"; |
||||||
|
} |
||||||
|
|
||||||
|
$count = count(get_extension_funcs('date') ?: []); |
||||||
|
var_dump($count > 0); |
||||||
|
|
||||||
|
$tz = new DateTimeZone('UTC'); |
||||||
|
$transitions = $tz->getTransitions(0, 1); |
||||||
|
var_dump(is_array($transitions)); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
bool(true) |
||||||
|
false branch |
||||||
|
bool(true) |
||||||
|
bool(true) |
||||||
@ -0,0 +1,20 @@ |
|||||||
|
--TEST-- |
||||||
|
concat assignment treats null as empty string |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
function main(): void |
||||||
|
{ |
||||||
|
$s = null; |
||||||
|
$s .= 'a'; |
||||||
|
$s .= 123; |
||||||
|
var_dump($s); |
||||||
|
|
||||||
|
$items = []; |
||||||
|
$items['x'] = null; |
||||||
|
$items['x'] .= 'b'; |
||||||
|
var_dump($items['x']); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
string(4) "a123" |
||||||
|
string(1) "b" |
||||||
@ -0,0 +1,78 @@ |
|||||||
|
--TEST-- |
||||||
|
inherited static property accessed through static:: remains isolated per class |
||||||
|
--FILE-- |
||||||
|
<?php |
||||||
|
class StaticOptionBase |
||||||
|
{ |
||||||
|
protected static $enabled = true; |
||||||
|
protected static $events = []; |
||||||
|
|
||||||
|
public static function setEnabled(bool $enabled): void |
||||||
|
{ |
||||||
|
static::$enabled = $enabled; |
||||||
|
static::$events[] = static::class . ':' . ($enabled ? 'on' : 'off'); |
||||||
|
} |
||||||
|
|
||||||
|
public static function state(): array |
||||||
|
{ |
||||||
|
return [static::class, static::$enabled, static::$events]; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class StaticOptionChildA extends StaticOptionBase |
||||||
|
{ |
||||||
|
protected static $enabled = false; |
||||||
|
protected static $events = []; |
||||||
|
} |
||||||
|
|
||||||
|
class StaticOptionChildB extends StaticOptionBase |
||||||
|
{ |
||||||
|
protected static $enabled = true; |
||||||
|
protected static $events = []; |
||||||
|
} |
||||||
|
|
||||||
|
function main() |
||||||
|
{ |
||||||
|
StaticOptionChildA::setEnabled(true); |
||||||
|
StaticOptionChildB::setEnabled(false); |
||||||
|
StaticOptionChildA::setEnabled(false); |
||||||
|
|
||||||
|
var_dump(StaticOptionBase::state()); |
||||||
|
var_dump(StaticOptionChildA::state()); |
||||||
|
var_dump(StaticOptionChildB::state()); |
||||||
|
} |
||||||
|
?> |
||||||
|
--EXPECT-- |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
string(16) "StaticOptionBase" |
||||||
|
[1]=> |
||||||
|
bool(true) |
||||||
|
[2]=> |
||||||
|
array(0) { |
||||||
|
} |
||||||
|
} |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
string(18) "StaticOptionChildA" |
||||||
|
[1]=> |
||||||
|
bool(false) |
||||||
|
[2]=> |
||||||
|
array(2) { |
||||||
|
[0]=> |
||||||
|
string(21) "StaticOptionChildA:on" |
||||||
|
[1]=> |
||||||
|
string(22) "StaticOptionChildA:off" |
||||||
|
} |
||||||
|
} |
||||||
|
array(3) { |
||||||
|
[0]=> |
||||||
|
string(18) "StaticOptionChildB" |
||||||
|
[1]=> |
||||||
|
bool(false) |
||||||
|
[2]=> |
||||||
|
array(1) { |
||||||
|
[0]=> |
||||||
|
string(22) "StaticOptionChildB:off" |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue