Автозаполнение Zend Studio при расширении классов
Я программирую на PHP уже 7 лет - действительно наслаждаюсь подходом ООП с автозаполнением MVC и Zend Studio.
Хотя это не так сложно, как в 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. И автозаполнение действительно важно при программировании больших корпоративных веб-сайтов - где появляются программы...
1 Спасибо за ответ - у меня не было возможности опробовать его - но я вижу, что допустил некоторые ошибки в примере.
Возможно, я упускаю суть, потому что я действительно не могу понять, почему это должна быть плохая абстракция.:)
Дело в том, что второй класс - это абстрактный класс. И если я вызову self - я получу экземпляр класса B, который может не иметь нужного мне метода (как theire в классе 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 не может восстановить новый класс
Саймон
1 ответ
Ваш пример кода не работает.
Прежде всего, позвонив B::GetDead()
не буду звонить DeadPerson::GetDead()
, Назначение этого в заявлении var $person = B::GetDead()
звучит совершенно задом наперед, так как это старый синтаксис PHP 4 для открытых свойств, и, кроме того, он не работает: вы не можете назначать значения по умолчанию, которые должны выполнять код.
Второе: класс, способный создавать экземпляры своих копий, странный. Если вы не хотите внедрить Singleton, чего следует избегать любой ценой. Вызов статических методов для класса, имя которого вы уже знаете, звучит как плохая абстракция.
Таким образом, вы можете подумать, что страдаете от плохой поддержки автозаполнения из вашей IDE, но на самом деле вы страдаете от плохой абстракции кода, которая не разделяет проблемы должным образом.
Ваш пример не показывает достаточно вашей реальной проблемы, но если вы перейдете к Codereview, ваша проблема кода может быть решена.