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



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

  • 当请求的页面在服务器上不存在时(如http://localhost/test/)
  • 当请求的URL与现有控制器和方法不匹配时(如http://localhost/test/task/)

我有以下错误:

Fatal error: Uncaught Error: Class 'TwigLoaderFilesystemLoader' 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错误(例如,如果DB中不存在文章的$_GET ID(,那么一切都很好,并且我的404错误模板也被正确呈现。

如何调用404错误

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

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

应用程序类

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

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/{optional_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 ControllersArticleController(); // <-- 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 ControllersArticleController();
Http::error404();

渲染类

这是我的渲染类。当带有error404方法的Http类呈现errors/404 Twig模板时,致命错误出现在该文件中,如下面的第32行所示。

require_once 'librairies/autoload.php';
use TwigEnvironment;
use TwigLoaderFilesystemLoader;
use TwigTwigFunction;
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;
}
}

我只添加了我认为与我的问题有关的代码。请毫不犹豫地询问是否有任何需要澄清的地方。

七天来,我一直在寻找这个错误的解决方案,但一直没有找到解决方案。你的帮助是我最后的手段。非常感谢!

我删除了应用程序文件中所有不必要的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让我走上正轨!

最新更新