Php public static function return

PHP RFC: Static return type

The static special class name in PHP refers to the class a method was actually called on, even if the method is inherited. This is known as “late static binding” (LSB). This RFC proposes to make static also usable as a return type (next to the already usable self and parent types).

There are a number of typical use-cases where static return types appear (currently in the form of @return static ).

One are named constructors:

class Test { public function createFromWhatever($whatever): static { return new static($whatever); } }

Here we want to specify that XXX::createFromWhatever() will always create an instance of XXX , not of some parent class.

Another are withXXX() style interfaces for mutating immutable objects:

class Test { public function withWhatever($whatever): static { $clone = clone $this; $clone->whatever = $whatever; return $clone; } }

Here we want to specify that $foobar->withWhatever() will return a new object of class get_class($foobar) , not of some parent class.

Finally, the likely most common use case are fluent methods:

class Test { public function doWhatever(): static { // Do whatever. return $this; } }

Here we actually have a stronger contract than in the previous two cases, in that we require not just an object of the same class to be returned, but exactly the same object. However, from the type system perspective, the important property we need is that the return value is an instance of the same class, not a parent class.

Читайте также:  Сколько максимум можно имплементировать интерфейсов java

Proposal

Allowed positions

The static type is only allowed inside return types, where it may also appear as part of a complex type expression, such as ?static or static|array .

To understand why static cannot be used as a parameter type (apart from the fact that this just makes little sense from a practical perspective), consider the following example:

class A { public function test(static $a) {} } class B extends A {} function call_with_new_a(A $a) { $a->test(new A); } call_with_new_a(new B);

Under the Liskov substitution principle (LSP), we should be able to substitute class B anywhere class A is expected. However, in this example passing B instead of A will throw a TypeError , because B::test() does not accept a A as a parameter.

More generally, static is only sound in covariant contexts, which at present are only return types.

For property types, we have the additional problem that the static type conflicts with the static modifier:

class A { // Is this an untyped static property, // or an instance property of type static? public static $a; }

For this reason, we disallow static types in properties/parameters already at the grammar level, rather than emitting a nicer error message in the compiler.

Variance and Subtyping

For the purpose of variance checks, static is considered a subtype of self . That is, the following inheritance is legal:

class A { public function test(): self {} } class B extends A { public function test(): static {} } class C extends B {}

When considering just class B , replacing a self type with a static type results in identical behavior. However, the return value of C::test() is further restricted relative to a self type. For this reason static is considered a subtype of self .

The converse replacement shown in the following is not legal:

class A { public function test(): static {} } class B extends A { public function test(): self {} } class C extends B { // To spell out the inherited signature: public function test(): B {} }

In this case, the effective return type of C::test() is B , even though the original type on A::test() would have required it to be C . This violates covariance/LSP.

It should be noted that self here refers to the resolved type of the current class, it does not have to be spelled as self in particular. For example, the following is also legal:

class A { public function test(): A {} } class B extends A {} class C extends B { public function test(): static {} }

Here, self is C , which is a subtype of A , making the replacement with static legal.

Reflection

While internally the static type is treated as a special builtin type, it will be reported as a class type in reflection, for symmetry with self and parent .

class Test { public function method(): static {} } $rm = new ReflectionMethod(Test::class, 'method'); $rt = $rm->getReturnType(); var_dump($rt->isBuiltin()); // false var_dump($rt->getName()); // "static"

Backward Incompatible Changes

There are no backwards incompatible changes in this proposal.

Future Scope

For the fluent method example above, many projects will use a @return $this annotation, rather than @return static . We could in principle also support this syntax natively:

class Test { public function doWhatever(): $this { // Do whatever. return $this; } }

However, $this is not a real type, and it is unclear what the advantage of specifying $this rather than static would be from a type system level perspective.

Vote

Voting started 2020-01-28 and ends 2020-02-11.

Источник

Returning variable keys via public static function within a class

I’ve been having a bit of trouble doing, what I believe is possible (although I’m not sure). What I do know is that what I’m attempting to do is a bit nonsensical and not the best way to do it.

What I’m attempting to do is to return the value of key via static function. I’ve been trying to view (via var_dump() ) what’s inside of my static function ( myClass::myData(); ) however, it comes up NULL . I’m still pretty new to PHP, but I’ve been working around trying to find things to work on (even if they’re pretty nonsensical) to get better acquainted. If this is at all possible, I’d like to complete it this way. I’ve been searching for an answer to this for about 2 hours, so yes, I have looked around to try and fix this issue myself first, but to no avail. Additionally, if this simply can’t be done, what is the best way to do something like this? I appreciate any responses! EDIT: Obviously I feel a bit foolish for not returning my data at the end of my function. Now when the class is dumped (via var_dump() ), the information in my function is returned, however, I’m still not able to selectively return the data:

class myClass < public static function myData() < $data = [ 'index' =>'key', 'index1' => 'key1' ]; return $data; > > myClass::myData(); //here 

I know the information is contained in the public static function, however, how would I selectively return key1 from index1 I really appreciate the help, everyone! EDIT 2: I was able to figure it out with all of your help. Just a note, the example I’m using here, is obviously not the code I’m working with. The semicolon was a simple mistake, and is not in my actual code. Here’s the final product:

class myClass < public static function myData() < $d = [ 'index' =>'key', 'index1' => 'key1' ]; return $data; > > $data = myClass::myData(); print $data['index1']; // prints key1 

Источник

Оцените статью