【问题标题】:Require dynamic class using namespace in PHP在 PHP 中需要使用命名空间的动态类
【发布时间】:2015-10-01 14:25:31
【问题描述】:

我当时正在研究几个 PHP 框架,然后当然决定构建自己的框架。但我面临一个问题。我有一个动态处理 HTTP 请求的 Router 类,它基本上将 URL 分解为元素,将其除以斜杠并将其存储到一个数组中,然后调用一个函数来检查第一个元素是否是有效的 Controller。如果它是有效的,该函数应该需要它,但这就是我被卡住的地方,因为似乎我不能需要这样的文件:

if (file_exists(CONTROLLERS_DIR . $this->url[0] . '.php')) { require \App\Controllers\$this->url[0] }

如何使用命名空间来要求这样的文件?

谢谢。

【问题讨论】:

  • if (file_exists(CONTOLLERS_DIR . $this->url[0])) { require CONTOLLERS_DIR . $this->url[0] } ?
  • 您遇到什么错误?你检查过$this->url[0] 的值吗?对吗?
  • 其实我用的是自动加载器,所以我不需要检查文件是否存在。我只需要它。我只是在这里用它来简单地解释我要做什么......顺便说一下,我得到的错误是:'unexpected $this after / should be identifier'。
  • 但我仍然不能这样做:new \App\Controllers\$this->url[0];
  • 您不能在 require/include 语句中执行字符串连接。 $ctrl = '\\App\\Contrllers\\'.$this->url[0]; $c = new $ctrl; 哦,你也得逃避你的斜线。请参阅此处了解我是如何做到这一点的:github.com/r3wt/RedBeanFVM/blob/master/RedBeanFVM/…

标签: php model-view-controller namespaces require


【解决方案1】:

“我怎样才能使用命名空间要求这样的文件?”
你不能。命名空间与它无关。

“PHP 命名空间提供了一种对相关类、接口、函数和常量进行分组的方式。” ~Namespaces overview


require 是关于文件依赖的,不管命名空间:

if (file_exists(CONTROLLERS_DIR . $this->url[0] . '.php')) { 
    require(CONTROLLERS_DIR . $this->url[0] . '.php');
}

编辑:您可能希望使用在运行时检索到的命名空间和类名来实例化一个类,例如:

namespace \App\Controllers;
class C {
    protected $_i;
    public function __construct($i){ $this->_i = $i; }
    public function foo(){ echo $this->_i; }
}

在某处:

$className = "C";                   // or $className = $this->whatever...
$class = "\\App\\Controllers\\".$className;
$instance = new $class(7);
$instance->foo();                   // outputs 7

【讨论】:

  • 这不能回答问题。编辑:也许确实如此,但答案仍然不够简洁。请修改。
  • @r3wt:我同意,现在看看 :)
【解决方案2】:

我已经构建了几个框架,我理解你想要做什么...... 基本上当你有一些路径时,例如“HelloWorld\addComment”

您想要创建控制器实例

\App\Controllers\HelloWorldController

有多种解决方法,我喜欢的一种是:

使用 spl 自动加载器 http://php.net/manual/en/function.spl-autoload.php

在我提供的链接中,您可以获得所需的示例。

然后你就可以结束了

$controller = new \App\Controllers\HelloWorldController();

您应该将 HelloWorldController 放在正确的命名空间中 + 维护与命名空间匹配的目录结构

app     
   Controllers
       HelloWorldController

spl 自动加载器会为您做正确的事,通常默认实现就足够了 - 但创建自己的 spl 自动加载器和register it

很容易

稍后你可以通过method_exist或反射测试$controller是否有你需要的方法...

【讨论】:

    猜你喜欢
    • 2019-11-13
    • 2012-08-10
    • 2015-06-21
    • 1970-01-01
    • 2011-05-29
    • 2012-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多