【问题标题】:Zend Studio autocomplete when extending classes扩展类时 Zend Studio 自动完成
【发布时间】:2012-12-03 10:13:01
【问题描述】:

我已经编写 PHP 7 年了 - 非常喜欢 MVC 和 Zend Studio 自动完成的 OOP 方法。

虽然它不像 Visual Studio 那样复杂,但您通常可以通过以下提示来解决任何自动完成错误:

/* @var $this Model_User */

我的问题是 - 在扩展其他类时,您究竟如何欺骗 Zend Studio - 而无需再次创建所有方法并重新注释它们。

例如:

class LivingPerson extends DeadPerson {
    // This class is just to demonstrate 
}

class DeadPerson {

    public $name;
    public $lastname;

    /**
     * Get the most popular DOH' out there
     * @param string|NULL $param
     * @return DeadPerson
     */
    public static function GetDead($param=NULL) {
        $caller = get_called_class();
        $person = new $caller();
        $person->name = 'Michael';
        $person->lastname = 'Jackson';
        return $person;
    }
}

现在 - 如果我这样做:

var $person = DeadPerson::GetDead(); 

Zend Studio 现在将重新调整返回为“DeadPerson”的对象,这是真的...... 但是,如果我从我扩展的类中调用它,它显然仍然认为它是一个“DeadPerson”对象,即使它是 实际上现在是一个“LivingPerson”对象,因为我使用 get_call_class() 来创建 LivingPerson 类的新实例。

我能想到解决此问题的唯一方法是执行以下操作:

class LivingPerson extends DeadPerson {
    // This class is just to demonstrate 
    
    /**
     * Get the most popular DOH' out there
     * @param string|NULL $param
     * @return LivingPerson
     */
    public static function GetDead($param=NULL) {
        return parent::GetDead($param);
    }
}

但这有点愚蠢,因为我需要同时维护 DeadPerson 和 LivingPerson 类的参数。 在编写大型企业网站时,自动完成功能非常重要——程序员们来这里...


1 感谢您的回复 - 我没有机会尝试一下 - 但我可以看到我在示例中犯了一些错误。

我可能没有抓住重点,因为我真的不明白为什么它应该是糟糕的抽象。 :)

问题是,第二个类是一个抽象类。如果我调用 self - 我将获得 B 类的一个实例,它可能没有我需要的方法(就像它们在 A 类上一样)。

例子:

interface Model_Interface {
    public function setData($data);
}

abstract class Model implements Model_Interface
{
    protected $data;

    // I do some mysql magic
    public static function FetchSingle($sql,$args=NULL) {
        $args=func_get_args();
        
        // DO mysql query etc. etc.
        
        $caller=get_called_class(); // This will make new instance of Shopping_User class instead of Model_User
        $class=new $caller();
        $caller->setData($sql->UserID);
        
    }
    
    public function setData($data) {
        $this->data = (object)$data;
    }
    
    public function __get($name) {
        return (isset($this->data->$name)) ? $this->data->$name : NULL;
    }
}

abstract class Model_User extends Model{

    /**
    /* Get user by user id.
    /* @param $userId
    /* @return Model_User
     **/
    public static function GetById($userId) {
        return self::FetchSingle('SELECT * FROM `User` WHERE `UserID` = %s', $userId);
    }
    
    public function getUrl() {
        return '/what/ever/';
    }
    
    public function getName() {
        return $this->name;
    }
}

class Shopping_User extends Model_User {
    public function getCart() {
        return 'shopping card stuff';
    }
}

尚未测试上述内容 - 但它应该让您了解我想要完成的工作。

见.. 与 Shopping 用户相同的类具有与“普通”用户相同的属性。但 IDE 无法重新调整新类

西蒙

【问题讨论】:

  • 尝试将$caller = get_called_class(); $person = new $caller(); 替换为$person = new static;。只是猜测。
  • 好吧,问题不在于我没有得到正确的对象。事实上,我得到了 LivingPerson。问题是,Zend Studio 仍然认为 GetDead() 返回的是一个 DeadPerson 对象,因为它无法弄清楚,DeadPerson 已被扩展,并且由于 get_call_class 返回 LivingPerson 的新实例。

标签: php autocomplete zend-studio


【解决方案1】:

您的示例代码不起作用。

首先,调用B::GetDead() 不会调用DeadPerson::GetDead()。在声明 var $person = B::GetDead() 中分配它听起来完全倒退,因为这是旧的 PHP 4 公共属性语法,而且它不起作用:您不能分配需要执行代码的默认值。

第二:能够实例化自身副本的类很奇怪。除非你想实现一个 Singleton,否则应该不惜一切代价避免。在您已经知道名称的类上调用静态方法听起来像是糟糕的抽象。

因此,您可能认为您的 IDE 仅支持糟糕的自动完成功能,但实际上您的代码抽象不佳,无法充分分离关注点。

您的示例没有充分说明您的实际问题,但如果您前往Codereview,您的代码问题可能会得到解决。

【讨论】:

  • 抱歉——我对 stockoverflow 有点陌生,但上面的回复实际上是对您回复的评论 :)
  • DeadPerson::GetDead() - 不是属性。这是一种方法。它返回一个类的实例,以及它的所有属性。我认为这是完全有效的。 See 在其他编程语言中从正在扩展的类中调用“self”将为您提供子类的名称(在本例中为 LivingPerson)。但是 PHP 似乎无法自己解决这个问题,所以这就是 get_call_class() 很方便的原因。
  • 我明白你在尝试什么,但你不应该这样做。不要使用静态方法。将数据库内容与模型分开。首先:通过编辑来改进你的问题。如果这不起作用,请开始一个新问题并将其链接到此处。
猜你喜欢
  • 2010-11-09
  • 2012-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多