2

我已经编写 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 无法重新调整新类

西蒙

4

1 回答 1

0

您的示例代码不起作用。

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

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

因此,您可能认为您的 IDE 仅支持糟糕的自动完成功能,但实际上您会遭受糟糕的代码抽象,即没有足够正确地分离关注点。

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

于 2012-12-15T20:28:57.647 回答