I have been programming PHP for 7 years now- really enjoy the OOP approach with MVC and Zend Studio autocompletion.
Though it's not as complex as Visual Studio you can usually get around any autocompletion mistakes by making hints as this for example:
/* @var $this Model_User */
My question is - how exactly can you trick Zend Studio when extending other classes - without creating all the methods again and commenting them all over.
For example:
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;
}
}
Now - if I do:
var $person = DeadPerson::GetDead();
Zend Studio will now reconize the object that where returned as "DeadPerson", which is true... But, if I call it from the class which i'm extending from, it obviously still think it's a "DeadPerson" object even though it's actually now a "LivingPerson" object as i've used the get_called_class() to create a new instance of the LivingPerson class.
The only way I can think of getting around this issue is by doing something like:
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);
}
}
But it's kinda stupid as I then need to maintain params on both the DeadPerson and LivingPerson class. And the autocomplete is really essential when programming large corporate websites - where programmeres come an go...
1 Thanks for the reply - I didn't get a chance to try it out - but I can see that i made some mistakes in the example.
I might be missing the point, because I really can't understand why it should be bad abstraction. :)
The thing is, that the second class is an abstract class. And if i call self - i will get an instance of the B class, which might not have the method's i need (as theire on class A).
Example:
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';
}
}
Haven't tested the above- but it should give you an idea of what i'm trying to accomplish.
See.. it the same class as the Shopping user have the same properties as the "normal" user. But the IDE cannot reconize the new class
Simon