Twig\Loader\FilesystemLoader未找到时触发404错误

Twig\Loader\FilesystemLoader not found when triggering 404 error

我是 PHP 的 OOP 和 MVC 新手,目前我正在通过制作自己的自定义 MVC 应用程序进行测试来学习。我还没有使用 Symfony,但我已经集成了 Twig,当我在控制器外部调用 404 错误时遇到问题,在以下两种情况下:

我遇到以下错误:

Fatal error: Uncaught Error: Class 'Twig\Loader\FilesystemLoader' not found in /Applications/XAMPP/xamppfiles/htdocs/librairies/Renderer.php:32
Stack trace: #0 /Applications/XAMPP/xamppfiles/htdocs/librairies/Renderer.php(21): Renderer::loadTwig() 
#1 /Applications/XAMPP/xamppfiles/htdocs/librairies/Http.php(26): Renderer::render('errors/404', Array) 
#2 /Applications/XAMPP/xamppfiles/htdocs/librairies/Application.php(35): Http::error404() 
#3 /Applications/XAMPP/xamppfiles/htdocs/index.php(9): Application::process() 
#4 {main} thrown in /Applications/XAMPP/xamppfiles/htdocs/librairies/Renderer.php on line 32

但是,如果我使用现有方法调用正确的控制器,一切正常(如 http:///localhost/article/show/123)。 如果我在控制器方法中调用 404 错误(例如,如果数据库中不存在文章的 $_GET ID),一切正常,我的 404 错误模板也正确呈现。

如何调用 404 错误?

我使用呈现我的 404 错误 Twig 模板的静态方法 Http::error404()

class Http
{
    /**
     * Display a 404 error - page not found
     *
     * @return void
     */
    public static function error404(): void
    {
        header('HTTP/1.1 404 Not Found');
        $pageTitle = "Erreur 404 - Page non-trouvée";
        Renderer::render('errors/404', compact('pageTitle'));
        exit;
    }
}

申请class

我的应用程序使用一个名为应用程序的迷你路由器。它检查控制器和被调用的方法是否存在。如果不是,用Http::error404()调用404错误,就是在这种情况下出现上面的致命错误。

class Application
{
    /**
     * This is the app process, called in index.php file.
     * Use controllers and methods directly in URL.
     * URL are rewritten by .htaccess file at app root.
     *
     * Usage :    https://example.com/controller/task/{optionnal_parameter}
     *            Ex : https://example.com/article/show/145
     *
     * @return void
     */
    public static function process()
    {
        // By default, call homepage
        $controllerName = 'ArticleController';
        $task = 'home';

        if (!empty($_GET['controller'])) {
            $controllerName = ucfirst($_GET['controller'] . 'controller');
        }

        if (!empty($_GET['task'])) {
            $task = $_GET['task'];
        }

        $controllerPath = "\controllers\" . $controllerName;

        // Check if this controller & method exists
        if (!method_exists($controllerPath, $task)) {
            Http::error404(); // <-- Here, i'm not in a controller (line 35)
        }

        $controller = new $controllerPath();
        $controller->$task();
    }
}

这里有一件奇怪的事情:如果我在调用 404 错误之前定义任何控制器,一切都会按我希望的方式运行,并且我的 404 错误模板会正确呈现。但这不是一个干净优雅的解决方案...

        // Check if this controller & method exists
        if (!method_exists($controllerPath, $task)) {
            new \Controllers\ArticleController(); // <-- Not clean, but solve my fatal error
            Http::error404();
        }

同样的事情发生在我的 404.php 文件中,当一个文件被调用但它不存在时,由服务器调用并在 .htaccess 中声明。我的 404 PHP 文件只包含几行:

require_once 'librairies/autoload.php';

Http::error404();

如果我定义了任何控制器,它工作完美并且致命错误消失。

require_once 'librairies/autoload.php';

new Controllers\ArticleController();
Http::error404();

渲染Class

这是我的效果图class。致命错误出现在这个文件中,如下面第32行所示,when Http class with error404 method render errors/404 Twig template.

require_once 'librairies/autoload.php';

use Twig\Environment;
use Twig\Loader\FilesystemLoader;
use Twig\TwigFunction;

class Renderer
{
    /**
     * Print a HTML template with $var injection
     *
     * @param string $path
     * @param array $var
     */
    public static function render(string $path, $var = [])
    {
        $template = self::loadTwig()->load("$path.html.twig");
        echo $template->display($var);
    }

    /**
     * Load Twig
     *
     * @return Environment
     */
    public static function loadTwig()
    {
        $loader = new FilesystemLoader('templates'); // <-- Line 32 is here !

        $twig = new Environment($loader, [
            'auto_reload' => true,
            'autoescape' => 'html'
        ]);
        $twig->addFunction(
            new TwigFunction('notificationDisplay', function() { return Notification::display(); })
        );
        return $twig;
    }
}

我只添加了我认为与我的问题相关的代码。如果有任何需要澄清的地方,请不要犹豫。

我已经找了7天这个错误的解决方案,一直没有找到解决方案。你的帮助是我最后的手段。非常感谢!

我删除了应用程序文件中所有不必要的 require_once 自动加载器,只保留了 index.php 中的一个,如@NicoHaase 所述。

从那时起,不再找到 Twig,所有请求都会出现相同的错误消息!

解决方案很容易找到:在我的 index.php 文件中,我使用了错误的自动加载器。我正在调用我的自定义自动加载器而不是来自 Composer 的自动加载器...

我只是改变:

require_once 'librairies/autoload.php';

\Application::process();

收件人:

require_once 'vendor/autoload.php';

\Application::process();

现在一切正常!感谢@NicoHaase 和@DarkBee 让我走上正轨!