【问题标题】:Class not found with composer psr4composer psr4 找不到类
【发布时间】:2019-07-09 22:52:41
【问题描述】:

我正在使用 composer 加载一个简单的控制器类,但我遇到了自动加载器的问题。它总是会给我这个错误: Fatal error: Uncaught Error: Class 'Controller' not found.

我的 composer.json 文件如下所示:

{
    "require": {
        "nikic/fast-route": "^1.3"
    },
    "autoload": {
      "psr-4": {
        "Controllers\\": "src/Controllers/"
      }
    }
}

在我的项目根目录中,我有 src 文件夹,其中包含 Controllers 子文件夹。

我需要自动加载并在我的班级中使用 Controllers 命名空间。 在我使用快速路由路由器加载控制器的索引上,我在自动加载器之后有 use \Controllers\Controller; 语句。

我的实现有什么问题?

这里是完整的代码:

require_once __DIR__.'/vendor/autoload.php';

use Controllers\Controller;

$dispatcher = FastRoute\simpleDispatcher(function(FastRoute\RouteCollector $router) {

    $router->addRoute('GET', '/', 'Controller/index');
    $router->addRoute('GET', '/azienda', 'Controller/about');
    $router->addRoute('GET', '/servizi', 'Controller/services');
    $router->addRoute('GET', '/contatti', 'Controller/contacts');

});

// Fetch method and URI from somewhere
$httpMethod = $_SERVER['REQUEST_METHOD'];
$uri = $_SERVER['REQUEST_URI'];

// Strip query string (?foo=bar) and decode URI
if(false !== $pos = strpos($uri, '?')){
    $uri = substr($uri, 0, $pos);
}
$uri = rawurldecode($uri);

$routeInfo = $dispatcher->dispatch($httpMethod, $uri);
switch ($routeInfo[0]) {
    case FastRoute\Dispatcher::NOT_FOUND:
        // ... 404 Not Found
        break;
    case FastRoute\Dispatcher::METHOD_NOT_ALLOWED:
        $allowedMethods = $routeInfo[1];
        // ... 405 Method Not Allowed
        break;
    case FastRoute\Dispatcher::FOUND:
        $handler = $routeInfo[1];
        $vars = $routeInfo[2];
        list($class, $method) = explode("/", $handler, 2);
        call_user_func_array([new $class, $method], $vars);
        break;
}

【问题讨论】:

    标签: composer-php


    【解决方案1】:

    当您使用变量作为类名(如new $class)时,它们需要包含完整的限定名。在您的情况下,$class 包含 Controller 而此类的 FQN 是 Controllers\Controller

    必须使用完全限定名(带有命名空间前缀的类名)。请注意,由于动态类名、函数名或常量名中的限定名和完全限定名之间没有区别,因此不需要前导反斜杠。

    https://www.php.net/manual/en/language.namespaces.dynamic.php

    您需要将 FQN 放入您的调度程序配置中:

    $router->addRoute('GET', '/', 'Controllers\Controller::index');
    $router->addRoute('GET', '/azienda', 'Controllers\Controller::about');
    $router->addRoute('GET', '/servizi', 'Controllers\Controller::services');
    $router->addRoute('GET', '/contatti', 'Controllers\Controller::contacts');
    

    并以这种方式处理调度结果:

    case FastRoute\Dispatcher::FOUND:
        $handler = $routeInfo[1];
        $vars = $routeInfo[2];
        list($class, $method) = explode('::', $handler, 2);
        call_user_func_array([new $class, $method], $vars);
        break;
    

    【讨论】:

    • 我不知道这一点,也因为通常如果类在同一个文件上,它会毫无问题地工作(当我开发和调试时,通常我将所有代码放在一个文件上)。如果你可以链接我的 php 手册,我会更深入地了解。感谢您的澄清。 PS:为什么你把这些方法称为静态的?
    • 您可以使用任何您想要的名称,只要您能够将其共同转换为正确的可调用名称 - ::explode 是安全的,它是用于方法名称的 FQN 的约定(包括非静态)由 PHP(__METHOD__ 将返回这样的字符串)。
    猜你喜欢
    • 2023-01-24
    • 1970-01-01
    • 2017-12-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-28
    • 2016-12-08
    • 2013-04-16
    相关资源
    最近更新 更多