Search code examples
phpnamespaceschainingmethod-chaining

PHP: Namespace resolution in object method chains


We use method chaining in several of our core systems. We're trying to namespace some of those systems away from our modules. However I'm having trouble getting any kind of namespace resolution with chaining to work.

So while this works (as usual):

$GLOBALS['model']->User()->User_Friends()->getAll();

this, on the other hand:

$GLOBALS['model']->Core\User()->User_Friends()->getAll();

throws the error:

Parse error: syntax error, unexpected T_NS_SEPARATOR

Is there any way around this?

I'm almost already assuming this is a no-go. But asking to make sure I'm not missing something.

Depending on your point-of-view (definitely mine), it is a bug.


Solution

  • The resolution of the namespace can occur within the method User, not as a property of the method itself.

    In code:

    class model {
      private $user = false;
      public function User () {
        if ($this->user == false)
           $this->user = new Core\User(); // <--- namespace use happens here
        return $this->user;
      }
    }
    

    Thus, the return of the method User is the User class from the namespace Core, of which the method User_Friends() is a part.

    EDIT I suggest you take another look at the docs as well as the "Basics" article.

    EDIT 2 Using __NAMESPACE__ to determine which namespace to operate in, from within an overloaded method:

    class model {
        private $objects = array();
        public function __call($name, $arguments=false) {
            $ns = __NAMESPACE__;
            if (strlen($ns) < 1)
                $ns = 'none';
            if (!isset($this->objects[$ns]))
                $this->objects[$ns] = array();
            if (!isset($this->objects[$ns][$name])) {
                $class_desc = (strlen($ns) > 0 ? __NAMESPACE__ . '\\' : ''). $name;
                $this->objects[$ns][$name] = new $class_desc($arguments);
            }
            return $this->objects[$ns][$name];
        }
    }