我找不到这个致命的错误:
致命错误:未捕获错误:Class' HomeController'找不到
但文件已包含在内。
require_once self::CONTROLLERS_PATH . $this->controller . '.php';
var_dump(file_exists(self::CONTROLLERS_PATH . $this->controller . '.php'));
new $this->controller;
我通过var_dumping file_exists
调试它,返回true。我检查了命名空间,一切看起来都不错。如果我转储$this->controller
,则其值与预期值相同 - string(14) "HomeController"
。如果我像new HomeController();
那样对其进行硬编码,则会初始化该类。但是为什么它不能从变量中运行呢?你可以在下面看到我的代码。这是我的文件结构:
App.php
<?php
namespace App\Core;
class App
{
protected $controller = 'HomeController';
protected $method = 'index';
protected $params = [];
const CONTROLLERS_PATH = '../App/Controllers/';
public function __construct ()
{
$url = $this->parseUrl();
if(file_exists(self::CONTROLLERS_PATH . ucfirst($url[0]) . '.php'))
{
$this->controller = ucfirst($url[0]); //Update $this->controller value
unset($url[0]);
echo 'file exists';
}
require_once self::CONTROLLERS_PATH . $this->controller . '.php';
var_dump(file_exists(self::CONTROLLERS_PATH . $this->controller . '.php'));
var_dump($this->controller);
new $this->controller;
if(isset($url[1]))
{
if(method_exists($this->controller, $url[1]))
{
$this->method = $url[1];
unset($url[1]);
echo 'method exists';
}
}
$this->params = $url ? array_values($url): [];
call_user_func_array([$this->controller, $this->method], $this->params);
var_dump($url);
}
public function parseUrl()
{
if(isset($_GET['url']))
{
return $url = explode('/', filter_var(rtrim($_GET['url'], '/'), FILTER_SANITIZE_URL));
}
}
}
HomeController.php
<?php
namespace App\Controllers;
class HomeController
{
public function index()
{
echo 'asd';
}
}
答案 0 :(得分:2)
通过变量名实例化类时,您始终必须包含整个命名空间。并且必须首先将其存储为字符串 一个例子:
import matplotlib.pyplot as plt
import numpy as np
import time
import matplotlib as mpl
mpl.rcParams['lines.linewidth'] = 2
plt.ion()
%matplotlib notebook
x = np.arange(-10, 10, 0.01)
fig = plt.figure(figsize = (12, 7))
ax = fig.add_subplot(111)
ax.grid()
plt.show()
for j in range(1,5):
ax.set_title(r"%6.2f $y = \frac{\sin{(\pi x j)}}{(\pi x j)}$" % j)
y = np.sin( np.pi*x*j )/( np.pi*x*j )
line, = ax.plot(x, y, 'b')
fig.canvas.draw()
time.sleep(1)
if j != 4:
line.remove()
在你的情况下:
namespace Api;
Class test {
public function __construct() {
echo "test";
}
}
$className = 'test';
$classNameNamespaced = "\\Api\\".$className;
$a = new $classNameNamespaced; // echoes "test"
答案 1 :(得分:0)
由于代码位于命名空间中,new $this->controller
与new HomeController
不同,即使$this->controller
的值为HomeController
。
表达式new HomeController
在编译时进行评估,由于名称空间,它被扩展为new \App\Controllers\HomeController
(Name resolution rules上的规则#6)。解释器需要完全限定的类名才能找到它。
在运行时期间评估表达式new $this->controller
,它导致new HomeController
与new \HomeController
相同。在根命名空间中没有定义任何类HomeController
,因此会出现错误。
您可以通过将完整的类名构建为字符串来轻松实现:
$class = 'App\\Controllers\\'.$this->controller;
new $class;
在文档页面"Namespaces and dynamic language features"中查找更多示例。
但加载类的最佳方法是使用autoloader generated by Composer。