PHP:未找到 PSR-4 class?
PHP: PSR-4 class not found?
Class 'LoginController' 未找到,我使用 PSR-4 自动加载来加载所有控制器。
"autoload": {
"psr-4": {
"App\": "app/"
}
}
在这里,当我需要在控制器上调用方法时,我只需找到 class,创建该 class 的新实例,然后调用 class 上的方法我刚创建。
if (!isset($result['error'])) {
$handler = $result['handler'];
$class = $handler[0];
$class = substr($class, strrpos($class, '\') + 1);
$class = new $class();
$method = $handler[1];
var_dump($class); // it doesn't get this far
$class->$method();
}
出于某种原因,$class = new $class();
行抛出 LoginController.php
找不到,但我确定 PSR-4 自动加载器是用来自动加载它的?
<?php declare(strict_types = 1);
namespace App\Controllers\Frontend\Guest;
class LoginController
{
public function getView()
{
echo 'it worked?';
}
}
LoginController 的路径是 /app/Controllers/Frontend/Guest/LoginController.php
我这样声明我的路由,
$router->get('/', ['App\Controllers\Frontend\Guest\LoginController', 'getView']);
一些改变,让它工作。
不重要但也不需要的是 psr-4 中的 / 斜线
{
"require": {
"baryshev/tree-route": "^2.0.0"
}
"autoload": {
"psr-4": {
"App\": "app"
}
}
}
我没有看到您需要包含的 require 'vendor/autoload.php';
,以便作曲家可以自动加载您的 classes/packages。
好吧,假设它在那里,下面的代码本质上是对命名空间的基本命名,你不想这样做,因为你需要命名空间作为 class 名称的一部分,以便作曲家自动加载它:
$class = $handler[0];
$class = substr($class, strrpos($class, '\') + 1);
$class = new $class();
而是使用 $result['handler'][0]
的完整值。
此外,您应该检查 class 是否存在以及 class 中是否存在该方法,以便您可以处理任何错误,因为路由匹配但不存在于您的代码中。 (该路由器不检查 class 是否存在)。
所以一个工作示例:
<?php
require 'vendor/autoload.php';
$router = new \TreeRoute\Router();
$router->addRoute(['GET', 'POST'], '/', ['App\Controllers\Frontend\Guest\LoginController', 'getView']);
$method = $_SERVER['REQUEST_METHOD'];
$url = $_SERVER['REQUEST_URI'];
$result = $router->dispatch($method, $url);
if (!isset($result['error'])) {
// check controller
if (class_exists($result['handler'][0])) {
$class = $result['handler'][0];
$class = new $class();
// check method
if (method_exists($class, $result['handler'][1])) {
$class->{$result['handler'][1]}($result['params']);
} else {
// method not found, do something
}
} else {
// controller not found, do something
}
}
else {
switch ($result['error']['code']) {
case 404 :
echo 'Not found handler here...';
break;
case 405 :
$allowedMethods = $result['allowed'];
if ($method == 'OPTIONS') {
echo 'OPTIONS method handler here...';
}
else {
echo 'Method not allowed handler here...';
}
break;
}
}
这已经过测试并使用您在问题中也提到的以下文件系统结构,如果它不一样,它将无法工作。
对 LoginController.php
没有任何改变,效果很好。
结果:
it worked?
Class 'LoginController' 未找到,我使用 PSR-4 自动加载来加载所有控制器。
"autoload": {
"psr-4": {
"App\": "app/"
}
}
在这里,当我需要在控制器上调用方法时,我只需找到 class,创建该 class 的新实例,然后调用 class 上的方法我刚创建。
if (!isset($result['error'])) {
$handler = $result['handler'];
$class = $handler[0];
$class = substr($class, strrpos($class, '\') + 1);
$class = new $class();
$method = $handler[1];
var_dump($class); // it doesn't get this far
$class->$method();
}
出于某种原因,$class = new $class();
行抛出 LoginController.php
找不到,但我确定 PSR-4 自动加载器是用来自动加载它的?
<?php declare(strict_types = 1);
namespace App\Controllers\Frontend\Guest;
class LoginController
{
public function getView()
{
echo 'it worked?';
}
}
LoginController 的路径是 /app/Controllers/Frontend/Guest/LoginController.php
我这样声明我的路由,
$router->get('/', ['App\Controllers\Frontend\Guest\LoginController', 'getView']);
一些改变,让它工作。
不重要但也不需要的是 psr-4 中的 / 斜线
{
"require": {
"baryshev/tree-route": "^2.0.0"
}
"autoload": {
"psr-4": {
"App\": "app"
}
}
}
我没有看到您需要包含的 require 'vendor/autoload.php';
,以便作曲家可以自动加载您的 classes/packages。
好吧,假设它在那里,下面的代码本质上是对命名空间的基本命名,你不想这样做,因为你需要命名空间作为 class 名称的一部分,以便作曲家自动加载它:
$class = $handler[0];
$class = substr($class, strrpos($class, '\') + 1);
$class = new $class();
而是使用 $result['handler'][0]
的完整值。
此外,您应该检查 class 是否存在以及 class 中是否存在该方法,以便您可以处理任何错误,因为路由匹配但不存在于您的代码中。 (该路由器不检查 class 是否存在)。
所以一个工作示例:
<?php
require 'vendor/autoload.php';
$router = new \TreeRoute\Router();
$router->addRoute(['GET', 'POST'], '/', ['App\Controllers\Frontend\Guest\LoginController', 'getView']);
$method = $_SERVER['REQUEST_METHOD'];
$url = $_SERVER['REQUEST_URI'];
$result = $router->dispatch($method, $url);
if (!isset($result['error'])) {
// check controller
if (class_exists($result['handler'][0])) {
$class = $result['handler'][0];
$class = new $class();
// check method
if (method_exists($class, $result['handler'][1])) {
$class->{$result['handler'][1]}($result['params']);
} else {
// method not found, do something
}
} else {
// controller not found, do something
}
}
else {
switch ($result['error']['code']) {
case 404 :
echo 'Not found handler here...';
break;
case 405 :
$allowedMethods = $result['allowed'];
if ($method == 'OPTIONS') {
echo 'OPTIONS method handler here...';
}
else {
echo 'Method not allowed handler here...';
}
break;
}
}
这已经过测试并使用您在问题中也提到的以下文件系统结构,如果它不一样,它将无法工作。
对 LoginController.php
没有任何改变,效果很好。
结果:
it worked?