PHPDoc 和后期(静态或动态)绑定

发布于 2024-11-04 05:40:33 字数 880 浏览 5 评论 0原文

大多数 PHP IDE 依赖 phpdoc 来获取有关表达式类型的提示。然而,我经常使用这种模式,这似乎没有被涵盖:

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;  }
}

现在我可以使用这样的类:

Textbox::Make()           // <-- late static binding, returns Textbox
   ->WithLabel('foo')     // <-- late dynamic binding, returns Textbox
   ->WithText('bar')      // <-- normal binding, returns Textbox
   ->Render();

有什么方法可以用某些东西替换 '???' 以便输入信息正确吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

紫竹語嫣☆ 2024-11-11 05:40:43

对于可以扩展的类中的静态方法:

/** @return static */

对于最终静态方法:

/** @return Control */

对于非静态方法:

/** @return $this */

但在 phpdoc 手册中没有记录

注意,现在任何 Intelij IED(如 PhpStorm 2019)都支持所有三个 static$thisself (作为 PhpDoc 中的返回类型)。

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, and self (as return type in PhpDoc).

空气里的味道 2024-11-11 05:40:43

更新的答案作为参考最流行的 PHP IDE (PHPStorm 8):

对于@return,您可以使用:

  • self
  • $this

对于@method > 你可以使用:

  • $this

示例:

/**
 * 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

PHPStorm 10 (EAP) 更新

看来现在 static 也可以使用,但仅限于 @return.

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

Update for PHPStorm 10 (EAP)

It seems that now static can be used too, but only for @return.

捂风挽笑 2024-11-11 05:40:43

更新了 cvsguimaraes 的答案以包含静态选项:

/**
 * Class Bar
 * @method $this parentMethodA
 */
class Bar
{
    /**
     * @return $this
     */
    public function parentMethodB()
    {
        return $this;
    }

    /**
     * @return self
     */
    public function parentMethodC()
    {
        return $this;
    }

    /**
     * @return static
     */
    public static function staticMethod()
    {
        return new static();
    }

    /**
     * @param $id
     *
     * @return bool
     */
    public function load($id)
    {
        // test
        return $id ? true : false;
    }

    /**
     * @param null $id
     *
     * @return static
     */
    public static function get($id = NULL){
        $obj = static::staticMethod();

        if (is_null($id)) {
            return $obj;
        }

        if ($obj->load($id)) {
            return $obj;
        }

        return false;
    }
}


/**
 * Class Foo
 * @method $this childMethodA
 */
class Foo extends Bar
{
    /**
     * @return $this
     */
    public function childMethodB()
    {
        return $this;
    }

    /**
     * @return self
     */
    public function childMethodC()
    {
        return $this;
    }
}

/**
 * Class Bar
 */
class Baz extends Bar 
{

}

$p = new Foo();

/** @var Foo $Foo */
$Foo = 'Foo';
$Baz = 'Bar';

//  IntelliJ recognizes the following as:
$t1 = $p->parentMethodA(); //Instance of Foo
$t2 = $p->parentMethodB(); //Instance of Foo
$t3 = $p->parentMethodC(); //Instance of Model
$t4 = $p->childMethodA(); //Instance of Foo
$t5 = $p->childMethodB(); //Instance of Foo
$t6 = $p->childMethodC(); //Instance of Foo
$t7 = $Foo::staticMethod(); //Instance of Foo
$t8 = Foo::staticMethod(); //Instance of Foo
$t9 = $p::staticMethod(); //Instance of Foo
$t10 = $Foo::get(); //Instance of Foo
$t12 = Bar::get(); //Instance of Bar
$t11 = $Baz::get(); // Unknown

Updated cvsguimaraes' answer to include static options:

/**
 * Class Bar
 * @method $this parentMethodA
 */
class Bar
{
    /**
     * @return $this
     */
    public function parentMethodB()
    {
        return $this;
    }

    /**
     * @return self
     */
    public function parentMethodC()
    {
        return $this;
    }

    /**
     * @return static
     */
    public static function staticMethod()
    {
        return new static();
    }

    /**
     * @param $id
     *
     * @return bool
     */
    public function load($id)
    {
        // test
        return $id ? true : false;
    }

    /**
     * @param null $id
     *
     * @return static
     */
    public static function get($id = NULL){
        $obj = static::staticMethod();

        if (is_null($id)) {
            return $obj;
        }

        if ($obj->load($id)) {
            return $obj;
        }

        return false;
    }
}


/**
 * Class Foo
 * @method $this childMethodA
 */
class Foo extends Bar
{
    /**
     * @return $this
     */
    public function childMethodB()
    {
        return $this;
    }

    /**
     * @return self
     */
    public function childMethodC()
    {
        return $this;
    }
}

/**
 * Class Bar
 */
class Baz extends Bar 
{

}

$p = new Foo();

/** @var Foo $Foo */
$Foo = 'Foo';
$Baz = 'Bar';

//  IntelliJ recognizes the following as:
$t1 = $p->parentMethodA(); //Instance of Foo
$t2 = $p->parentMethodB(); //Instance of Foo
$t3 = $p->parentMethodC(); //Instance of Model
$t4 = $p->childMethodA(); //Instance of Foo
$t5 = $p->childMethodB(); //Instance of Foo
$t6 = $p->childMethodC(); //Instance of Foo
$t7 = $Foo::staticMethod(); //Instance of Foo
$t8 = Foo::staticMethod(); //Instance of Foo
$t9 = $p::staticMethod(); //Instance of Foo
$t10 = $Foo::get(); //Instance of Foo
$t12 = Bar::get(); //Instance of Bar
$t11 = $Baz::get(); // Unknown
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文