私は 7 年間 PHP をプログラミングしています。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」として返されたオブジェクトを再認識します。これは本当です... get_called_class() を使用して LivingPerson クラスの新しいインスタンスを作成したため、実際には「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 クラスの両方でパラメーターを維持する必要があるため、ちょっとばかげています。そして、オートコンプリートは、大規模な企業 Web サイトをプログラミングする際に非常に重要です。
1 返信ありがとうございます。試してみる機会がありませんでしたが、例でいくつか間違いを犯したことがわかります。
なぜそれが悪い抽象化であるべきなのか本当に理解できないので、私は要点を見逃しているかもしれません。:)
問題は、2 番目のクラスが抽象クラスであることです。そして、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';
}
}
上記をテストしていませんが、私が達成しようとしていることのアイデアが得られるはずです。
見てください..ショッピングユーザーと同じクラスは、「通常の」ユーザーと同じプロパティを持っています。しかし、IDE は新しいクラスを認識できません
サイモン