【问题标题】:PHP: Namespace resolution in object method chainsPHP:对象方法链中的命名空间解析
【发布时间】:2011-08-30 18:56:58
【问题描述】:

我们在几个核心系统中使用方法链接。我们正在尝试将其中一些系统命名为远离我们的模块。但是,我无法通过链接工作来获得任何类型的命名空间解析。

所以虽然这有效(像往常一样):

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

另一方面:

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

抛出错误:

Parse error: syntax error, unexpected T_NS_SEPARATOR

有没有办法解决这个问题?

我几乎已经假设这是不行的。但要求确保我没有遗漏任何东西。

根据您的观点(绝对是我的观点),这是一个错误。

【问题讨论】:

  • 您可以命名一个类或一个函数,但不能命名一个方法。
  • 似乎你也在努力为所有东西命名空间。为什么需要像这样对属性/方法进行分组?

标签: php namespaces chaining method-chaining


【解决方案1】:

命名空间的解析可以发生在方法User,而不是作为方法本身的属性

在代码中:

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

因此,方法User 的返回是来自命名空间CoreUser 类,方法User_Friends() 是其中的一部分。

编辑 我建议你再看看docs 以及“Basics”文章。

编辑 2 使用__NAMESPACE__ 从重载方法中确定要在哪个命名空间中操作:

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];
    }
}

【讨论】:

  • 这不可能发生,因为方法用户不存在。 __call() 方法将其作为后备和路由处理。
  • 那么上面使用的命名空间代码将在重载__call方法中使用。底线 - 一个不命名类的方法。该类可能具有以动态方式利用名称空间的多态性,但该方法本身不知道名称空间。我上面使用的代码是为了演示概念,而不是字面的解决方案。
  • 那么你需要使用像-&gt;Core_User()这样的命名约定并将_替换为\` in __call()`
  • @Chris 是的,我明白了。遗憾的是,重载方法无法对命名空间做出假设。
  • @Mchl 这是唯一可行的想法之一。不幸的是,我们在方法名称中使用下划线,因此它不是一个可行的分隔符。
【解决方案2】:

这没有任何意义。 GLOBALS['model'] 是一个对象(我假设,因为您正在使用 -&gt; 访问它的成员)并且对象成员不能(也不需要)命名空间(因为它们属于特定的类/对象)。

由于您使用_call() 来神奇地调用不存在的方法,因此您需要假设一个导航约定,例如$GLOBALS['model']-&gt;Core_User()-&gt;User_Friends()-&gt;getAll();,然后在您的__call() 中将_ 替换为\

【讨论】:

    猜你喜欢
    • 2012-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    相关资源
    最近更新 更多