我已经编程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_called_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课程中保持params。 在编写大型企业网站时,自动完成功能非常重要 - 程序会随之而来......
我可能会忽略这一点,因为我真的无法理解为什么它应该是糟糕的抽象。 :)
问题是,第二个类是一个抽象类。如果我调用自我 - 我会得到一个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';
}
}
没有测试过上述内容 - 但它应该让你知道我想要完成的任务。
请参阅..与购物用户相同的类具有与“普通”用户相同的属性。但是IDE无法重新组合新类
西蒙
答案 0 :(得分:0)
您的示例代码不起作用。
首先,调用B::GetDead()
不会调用DeadPerson::GetDead()
。在语句var $person = B::GetDead()
中分配它听起来完全落后,因为这是公共属性的旧PHP 4语法,而且它不起作用:您不能分配需要执行代码的默认值。
第二:能够实例化自身副本的类很奇怪。除非您想要实现Singleton,否则应该不惜一切代价避免使用。在您已经知道的名称类上调用静态方法听起来像是一个糟糕的抽象。
因此,您可能认为自己只受到来自IDE的自动完成支持不良的困扰,但实际上您遇到了糟糕的代码抽象问题,而这种问题并没有足够正确地区分问题。
您的示例没有显示您真正的问题,但如果您转到Codereview,您的代码问题可能会得到解决。