Most PHP IDEs rely on phpdoc to get hints about the type of an expression. Yet, I use frequently this pattern, which doesn't seem to be covered:
class Control {
private $label = '';
/** @return ??? */
public static function Make(){ return new static(); }
/** @return ??? */
public function WithLabel($value){ $this->label = $value; return $this; }
/** @return void */
public function Render(){ /* ... */ }
}
class Textbox extends Control {
private $text = '';
/** @return ??? */
public function WithText($text){ $this->width = $text; return $this; }
}
Now I can use the classes like this:
Textbox::Make() // <-- late static binding, returns Textbox
->WithLabel('foo') // <-- late dynamic binding, returns Textbox
->WithText('bar') // <-- normal binding, returns Textbox
->Render();
Is there any way to replace the '???'s with something so that the typing information is correct?
Whenever a PHP interpreter gets the request to compile a function. If it sees any static property, then it leaves the property pending for run time and the property gets its value during runtime from the function it is being called. This is called late static binding.
In addition to this, any static function or variable is usually executed during runtime and not during compile time. Hence, if a value needs to be dynamically assigned to a variable that is static, it happens during runtime, and this is known as late static binding.
The compiler performs a process called binding when an object is assigned to an object variable. The early binding (static binding) refers to compile time binding and late binding (dynamic binding) refers to runtime binding.
PHP implements a feature called late static bindings which can be used to reference the called class in a context of static inheritance. More precisely, late static bindings work by storing the class named in the last "non-forwarding call".
For static methods in classes that may be extended:
/** @return static */
For final-static methods:
/** @return Control */
For non-static methods:
/** @return $this */
but it's not documented in phpdoc manual
Note that nowadays any Intelij IED (like PhpStorm 2019), does support all three
static
,$this
, andself
(as return type in PhpDoc).
Updated answer taking as reference the most popular PHP IDE (PHPStorm 8):
For @return
you can use:
self
$this
For @method
you can use:
$this
Example:
/**
* Class Model
* @method $this parentMethodA
*/
class Model
{
/**
* @return $this
*/
public function parentMethodB()
{
return $this;
}
/**
* @return self
*/
public function parentMethodC()
{
return $this;
}
}
/**
* Class Person
* @method $this childMethodA
*/
class Person extends Model
{
/**
* @return $this
*/
public function childMethodB()
{
return $this;
}
/**
* @return self
*/
public function childMethodC()
{
return $this;
}
}
$p = new Person();
//In the following lines IDE will recognize those variables as:
$t1 = $p->parentMethodA(); //Instance of Person
$t2 = $p->parentMethodB(); //Instance of Person
$t3 = $p->parentMethodC(); //Instance of Model
$t4 = $p->parentMethodA(); //Instance of Person
$t5 = $p->parentMethodB(); //Instance of Person
$t6 = $p->parentMethodC(); //Instance of Person
It seems that now static
can be used too, but only for @return
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With