简体   繁体   English

PHP:找不到PSR-4类?

[英]PHP: PSR-4 class not found?

Class 'LoginController' not found, I load all my Controllers using PSR-4 autoloading. 找不到类'LoginController',我使用PSR-4自动加载功能加载所有控制器。

"autoload": {
    "psr-4": {
        "App\\": "app/"
    }
}

In here, when ever I need to call methods on controllers I simply find the class, create a new instance of that class and then call the method on the class I just created. 在这里,当我需要在控制器上调用方法时,我只需找到该类,创建该类的新实例,然后在刚创建的类上调用该方法。

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();
} 

For some reason, the $class = new $class(); 由于某种原因, $class = new $class(); line is throwing that LoginController.php cannot be found, but I'm sure that PSR-4 autoloader was meant to auto load it in? LoginController.php无法找到LoginController.php ,但是我确定PSR-4自动加载器是要自动加载其中的吗?

<?php declare(strict_types = 1);

namespace App\Controllers\Frontend\Guest;

class LoginController 
{
    public function getView() 
    {
        echo 'it worked?';
    }
}

The path to LoginController is /app/Controllers/Frontend/Guest/LoginController.php I am declaring my routes like so, LoginController的路径是/app/Controllers/Frontend/Guest/LoginController.php我这样声明自己的路线,

$router->get('/', ['App\Controllers\Frontend\Guest\LoginController', 'getView']);

Some changes, to make it work. 进行一些更改以使其起作用。

Not important but also not required is the / slash in the psr-4 psr-4中的/斜杠并不重要,但也不是必需的

{
    "require": {
        "baryshev/tree-route": "^2.0.0"
    }
    "autoload": {
        "psr-4": {
            "App\\": "app"
        }
    }
}

I don't see require 'vendor/autoload.php'; 我看不到require 'vendor/autoload.php'; which you need to include so composer can autoload your classes/packages. 您需要包括这些内容,以便作曲家可以自动加载您的类/程序包。

Ok presuming that's in there, the following code is essentially basename'ing the namespace, which you don't want to do, as you need the namespace as part of the class name for composer to autoload it: 好的,假设在那儿,下面的代码本质上就是对名称空间进行基名化,这是您不想做的,因为您需要将名称空间作为类名的一部分,以便作曲家自动加载它:

$class = $handler[0];
$class = substr($class, strrpos($class, '\\') + 1);
$class = new $class();

Instead just use the full value of $result['handler'][0] . 而是只使用$result['handler'][0]的完整值。

Also, you should check that both the class exists and that the method exists in that class so you can handle any errors because a route matches but does not exist in your code. 另外,您应该检查该类是否存在,以及该方法是否在该类中存在,以便您可以处理任何错误,因为路由匹配但在代码中不存在。 (that router does not check if the class exists). (该路由器不检查该类是否存在)。

So a working example: 因此,一个工作示例:

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

This was tested and working with the following filesystem structure which you have also noted in your question if it's not the same, it won't work. 这已经过测试,并且可以使用以下文件系统结构,您在问题中还指出了该文件系统结构是否不同,将无法正常工作。

在此处输入图片说明

No change to LoginController.php that works fine. 无需更改即可正常运行的LoginController.php

Result: 结果:

it worked?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM