如何在 PHPDoc 中弃用 PHP 的魔法属性?

Posted

技术标签:

【中文标题】如何在 PHPDoc 中弃用 PHP 的魔法属性?【英文标题】:How to deprecate PHP's magic property in PHPDoc? 【发布时间】:2016-09-29 23:24:46 【问题描述】:

有没有办法将magic property 标记为已弃用?考虑以下简化代码:

/**
 * Example class
 *
 * @property string $foo A foo variable.
 */
class Example 
    /**
     * Magic getter
     */
    public function __get($var) 
        if('foo' === $var) 
            // do & return something
        
     

现在,如何指示其他开发人员,他们不应再使用Example::$foo?我想到的唯一可行的解​​决方案是:

/**
 * Example class
 */
class Example 
    /**
     * A foo variable.
     *
     * @var string
     * @deprecated
     */
    public $foo;

    /**
     * Magic getter
     */
    public function __get($var) 
        if('foo' === $var) 
            // do & return something
        
     

但这既破坏了我的代码(不调用getter),也感觉不是很优雅。

【问题讨论】:

抛出警告或异常,并记录下来? Seems legit to me - 不编译? @self 我不想破坏旧的依赖关系 - 只是表明它不应该在新代码中使用。 @RobbieAverill Magic __get() 方法在我明确声明类内的公共属性时未被调用。 您不应该将其设置为私有以便仍然使用魔法吸气剂吗?公共上下文不会调用魔术方法。据我所知。你有 3 个选择:属性不存在 -> 属性重载 -> 调用魔法上下文属性是私有的,不能从类内部访问 __get() 被称为显式 【参考方案1】:

@mixin 方法至少适用于 phpStorm:

/**
 * class or trait for the @mixin annotation
 */
trait DeprecatedExampleTrait 

    /**
     * Declare it as private to increase the warning level
     * @deprecated
     * @var string
     */
    public $foo;


/**
 * Example class
 *
 * @mixin DeprecatedExampleTrait
 *
 * @property string $newFoo A foo variable.
 */
class Example 
    /**
     * Magic getter
     */
    public function __get($var) 
        if (in_array($var, ['foo', 'newFoo'])) 
            // do & return something
        
    


$example = new Example;
$example->foo;

截图:

【讨论】:

天哪,这太可怕了。 PHPDoc 需要多长时间才能获得一些必要的升级? /哭【参考方案2】:

这对于 PHPDoc 是不可能的,因为 @deprecated 只能与结构元素 (documentation) 相关联。

如果让开发人员知道他们不应再使用这个神奇的属性真的很重要,您可以触发E_USER_DEPRECATED 错误:

/**
 * Example class
 *
 * @property string $foo A foo variable.
 */
class Example 

    public function __get($name)
    
        if ($name === 'foo') 
            trigger_error('Property $foo is deprecated and should no longer be used', E_USER_DEPRECATED);
        
        // ...
    

【讨论】:

属性is a structural element。 是的,但这里的问题是您是否可以将@deprecated@property 关联,这是不可能的,因为您只能将@deprecatedreal 关联属性/类/接口/方法 是的,您的示例与问题不匹配。在问题中,它是一个 real 属性 请再次阅读问题@RobbieAverill,因为问题显然是关于@property 的使用。 @pamelus 试图避免使用真实财产,因为这会破坏他的代码。 我明白了,所以 OP 正在尝试记录一个不存在的属性。在这种情况下,我倾向于建议创建一个具体的 getFoo() 方法并弃用 that,而不是覆盖 __get() 方法。您不需要触发任何错误来通知用户停止使用某些东西 - 弃用标签就足够了【参考方案3】:

为防止用户使用您已弃用的属性,您只需从类头中删除此属性的 PHPDoc。

/**
  * Example class
  *
  */
 class Example 
     /**
      * Magic getter
      */
     public function __get($var) 
         if('foo' === $var) 
             // do & return something
         
      
 

这样,您将保持旧代码正常工作,而 IDE 自动完成工具等将不再显示该属性。

【讨论】:

这个答案已经在接受的答案中 @Isaac,接受的答案包括创建一个(否则未使用的)特征并将其包含在主类的 PHPDoc 中。虽然我的回答是从 PHPDoc 中删除不推荐使用的属性。所以不,这两个是完全不同的方法。 这将使魔术道具开始显示为 IDE 无法识别,而不是实际服务于在它仍然存在时记录它的目的(以及它可能被弃用的原因)。

以上是关于如何在 PHPDoc 中弃用 PHP 的魔法属性?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 API 29 中弃用 getExternalStorageDirectory 时读取或写入文件?

UIAlertView 已弃用:首先在 iOS 9.0 中弃用 - UIAlertView 已弃用。将 UIAlertController 与首选样式一起使用

thumbnailImageAtTime:timeOption 已弃用:首先在 iOS 7 中弃用

Firebase 实例 ID:在 21.0.0 中弃用 getId()

Android P 中弃用的 DialogFragment 类

在 rails 3 中弃用 after_save 解决方案