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