parent
019c626c37
commit
fb79fb832c
5 changed files with 244 additions and 20 deletions
@ -0,0 +1,126 @@ |
||||
--TEST-- |
||||
Object static calls use the runtime class rather than the declared type |
||||
--FILE-- |
||||
<?php |
||||
|
||||
class ObjectStaticCallBase |
||||
{ |
||||
public static function identify(): string |
||||
{ |
||||
return 'base'; |
||||
} |
||||
|
||||
public static function calledClass(): string |
||||
{ |
||||
return static::class; |
||||
} |
||||
|
||||
public static function increment(int &$value): string |
||||
{ |
||||
$value++; |
||||
return static::class; |
||||
} |
||||
} |
||||
|
||||
final class ObjectStaticCallChild extends ObjectStaticCallBase |
||||
{ |
||||
public static function identify(): string |
||||
{ |
||||
return 'child'; |
||||
} |
||||
} |
||||
|
||||
function callOnTypedObject(ObjectStaticCallBase $object): array |
||||
{ |
||||
return [$object::identify(), $object::calledClass()]; |
||||
} |
||||
|
||||
function callOnMixedObject(mixed $object): array |
||||
{ |
||||
return [$object::identify(), $object::calledClass()]; |
||||
} |
||||
|
||||
function callOnGenericObject(object $object): array |
||||
{ |
||||
return [$object::identify(), $object::calledClass()]; |
||||
} |
||||
|
||||
function callOnExactLocalObject(): array |
||||
{ |
||||
$object = new ObjectStaticCallChild(); |
||||
return [$object::identify(), $object::calledClass()]; |
||||
} |
||||
|
||||
function callViaGetClass(ObjectStaticCallBase $object): array |
||||
{ |
||||
return [get_class($object)::identify(), get_class($object)::calledClass()]; |
||||
} |
||||
|
||||
function callOnClassString(string $class): array |
||||
{ |
||||
return [$class::identify(), $class::calledClass()]; |
||||
} |
||||
|
||||
function callReferenceArgument(ObjectStaticCallBase $object): array |
||||
{ |
||||
$value = 1; |
||||
$class = $object::increment($value); |
||||
return [$class, $value]; |
||||
} |
||||
|
||||
function main(): void |
||||
{ |
||||
$object = new ObjectStaticCallChild(); |
||||
var_dump(callOnTypedObject($object)); |
||||
var_dump(callOnMixedObject($object)); |
||||
var_dump(callOnGenericObject($object)); |
||||
var_dump(callOnExactLocalObject()); |
||||
var_dump(callViaGetClass($object)); |
||||
var_dump(callOnClassString(ObjectStaticCallChild::class)); |
||||
var_dump(callReferenceArgument($object)); |
||||
} |
||||
|
||||
?> |
||||
--EXPECT-- |
||||
array(2) { |
||||
[0]=> |
||||
string(5) "child" |
||||
[1]=> |
||||
string(21) "ObjectStaticCallChild" |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
string(5) "child" |
||||
[1]=> |
||||
string(21) "ObjectStaticCallChild" |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
string(5) "child" |
||||
[1]=> |
||||
string(21) "ObjectStaticCallChild" |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
string(5) "child" |
||||
[1]=> |
||||
string(21) "ObjectStaticCallChild" |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
string(5) "child" |
||||
[1]=> |
||||
string(21) "ObjectStaticCallChild" |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
string(5) "child" |
||||
[1]=> |
||||
string(21) "ObjectStaticCallChild" |
||||
} |
||||
array(2) { |
||||
[0]=> |
||||
string(21) "ObjectStaticCallChild" |
||||
[1]=> |
||||
int(2) |
||||
} |
||||
@ -0,0 +1,70 @@ |
||||
--TEST-- |
||||
Trait self static calls resolve to the consuming class across namespaces |
||||
--FILE-- |
||||
<?php |
||||
|
||||
namespace TraitSelfCall\Template { |
||||
trait Dispatch |
||||
{ |
||||
public function namedCall(): string |
||||
{ |
||||
return self::privateHelper(); |
||||
} |
||||
|
||||
public function dynamicCall(): string |
||||
{ |
||||
$method = 'helper'; |
||||
return self::$method(); |
||||
} |
||||
|
||||
public function selfMembers(): array |
||||
{ |
||||
return [self::class, self::LABEL, self::$label]; |
||||
} |
||||
|
||||
private static function privateHelper(): string |
||||
{ |
||||
return 'trait-helper'; |
||||
} |
||||
|
||||
public static function helper(): string |
||||
{ |
||||
return 'trait-helper'; |
||||
} |
||||
} |
||||
} |
||||
|
||||
namespace TraitSelfCall\Consumer { |
||||
use TraitSelfCall\Template\Dispatch; |
||||
|
||||
final class Example |
||||
{ |
||||
use Dispatch; |
||||
|
||||
private const LABEL = 'consumer-constant'; |
||||
private static string $label = 'consumer-property'; |
||||
} |
||||
} |
||||
|
||||
namespace { |
||||
function main(): void |
||||
{ |
||||
$object = new TraitSelfCall\Consumer\Example(); |
||||
var_dump($object->namedCall()); |
||||
var_dump($object->dynamicCall()); |
||||
var_dump($object->selfMembers()); |
||||
} |
||||
} |
||||
|
||||
?> |
||||
--EXPECT-- |
||||
string(12) "trait-helper" |
||||
string(12) "trait-helper" |
||||
array(3) { |
||||
[0]=> |
||||
string(30) "TraitSelfCall\Consumer\Example" |
||||
[1]=> |
||||
string(17) "consumer-constant" |
||||
[2]=> |
||||
string(17) "consumer-property" |
||||
} |
||||
Loading…
Reference in new issue