NuSphere Forums Forum Index
NuSphere Forums
Reply to topic
Magic __get method and code complete


Joined: 19 Aug 2009
Posts: 4
Reply with quote
Hi there!

I am newbie here, and search along with FAQ didn't answer on my question.
So, the question is:

For instance, I have a class, let's say Application. This class contains application components, such as User, View, etc. All these components are accessed using __get method. The following code may explain this:

Code:
    class Application
    {
       /**
        * PHP magic __get method.
        *
        * @param string $name Name of requested variable
        * @return mixed
        */
       
        public function __get($name)
        {
            $getter = 'get' . $name;
            if (!method_exists($this, $getter))
                throw new Exception('Getter for ' . $name . ' is undefined');
           
            return $this->{$getter}();
        }
       
        /**
         * Readonly property. Database connection identifier.
         *
         * @var PDO
         */
       
        private $_db = null;
       
        /**
         * Db connection getter. Also if connection is still not established, connects to the mysql server.
         * So called lazy loading.
         *
         * @return PDO
         */
       
        public function GetDb()
        {
            if ($this->_db == null)
            {
               $this->_db = new PDO(<some parameters>);
            }
           
            return $this->_db;
        }
}


So in my scripts I access my PDO object this way:
Code:
$application = new Application();
$db = $application->db;
// now editor don't know what $db is.
$db = $application->GetDb();
// and here phped knows that $db contains PDO object

I believe that PhpEd nicely define type of Application::GetDb(), because of @return PDO.
Also Application doesn't have property $db - property _db is accessed instead.

May I somehow appoint, that $application->db actually is the same as _db or may be GetDb?

Thanks a lot, looking forward any answer. Cheers Smile
View user's profileFind all posts by glock18Send private message


Joined: 28 May 2006
Posts: 14
Reply with quote
Actually $_db is not $db and not getDb(), and due to their loose coupling the relation may be different from case to case. Tricking the IDE therefore is quite dangerous.

However, you could at least make PhpED know about the accessable $db member during design time by using a workarround. I frequently use that concept for a simple Proxy Pattern or a smart base class which allows me to handle public members comfortably.

Simplified for your case it looks like this:

Code:

class Application
{
    public $db; // will be unset, so magic methods will be used
    protected $_db; // won't be unset

    function __construct()
    {
        $objectVars = get_object_vars($this);
        foreach ($objectVars as $name=>$value)
        {
            if ($name[0]=='_') continue; // spare private and protected members
            unset($this->$name); // unset public members
        }
    }
}
View user's profileFind all posts by SchnapoSend private message
Magic __get method and code complete


Joined: 19 Aug 2009
Posts: 4
Reply with quote
Hi once again!

I've browsed internet a little, and found nice article regarding this subject:

http://greg.chiaraquartet.net/archives/140-phpDocumentor-and-__get__set__call-give-us-your-ideas-RFC.html

In two words, this article says, that I should place the following PhpDoc comments before class declaration (in terms of my task):

Code:
   /**
    * Application singleton called with Base::App() method.
    *
         * @property-read PDO $db
         */

        class Application {}


I tried so, but unfortunately nothing seem to happen. May anyone say whether this feature is supported by NuSphere PhpEd or not?[/code]
View user's profileFind all posts by glock18Send private message


Joined: 19 Aug 2009
Posts: 4
Reply with quote
Schnapo,

Your solution looks reasonable, but is actual trick. I'll keep it in mind, but I still hope to find correct way, using phpDoc.

Thanks for response.
View user's profileFind all posts by glock18Send private message


Joined: 28 May 2006
Posts: 14
Reply with quote
Well yes, for your application it is a quite dirty trick. It makes more sense in other situations like proxying or for adding advanced member management to classes. I use it for instance to add transactions at object level.

I think a feature request ist required, for PhpED to recognize @property annotations.
View user's profileFind all posts by SchnapoSend private message
Magic __get method and code complete


Joined: 19 Aug 2009
Posts: 4
Reply with quote
Schnapo, you may be interested. I've found solution, which doesn't force dev to modify class constructor and member list.

It seem to be slightly buggy though, but I found a great usage for it... So the PhpDoc comment before class declaration should be:
Code:
   /**
    * Application singleton called with Base::App() method.
    *
    * show off @property, @property-read, @property-write
    *
    * @property PDO $db
    */

        class Application {}


What seems to be buggy, is that autocomplete on these properties cuts off first character of property. So the property in autocomplete will be just a letter "b".

So this method is not the one you need, if you use variables of basic php types (such as integer, boolean, etc).
But in the case, when this property is an object, Base::App()->db will display the code complete list for PDO class. That is pretty nice Smile And still quite useful.

Hope, it may be useful for someone.
View user's profileFind all posts by glock18Send private message


Joined: 28 May 2006
Posts: 14
Reply with quote
I currently don't understand what you mean with "cuts off first character"... it works like a charm here.
View user's profileFind all posts by SchnapoSend private message
Magic __get method and code complete
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
All times are GMT - 5 Hours  
Page 1 of 1  

  
  
 Reply to topic