Twig\Loader\FilesystemLoader未找到时触发404错误
Twig\Loader\FilesystemLoader not found when triggering 404 error
我是 PHP 的 OOP 和 MVC 新手,目前我正在通过制作自己的自定义 MVC 应用程序进行测试来学习。我还没有使用 Symfony,但我已经集成了 Twig,当我在控制器外部调用 404 错误时遇到问题,在以下两种情况下:
- 当请求的页面在服务器上不存在时(如 http:///localhost/test/)
- 请求时 URL 与现有控制器和方法不匹配(如 http:///localhost/test/task/)
我遇到以下错误:
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 让我走上正轨!
我是 PHP 的 OOP 和 MVC 新手,目前我正在通过制作自己的自定义 MVC 应用程序进行测试来学习。我还没有使用 Symfony,但我已经集成了 Twig,当我在控制器外部调用 404 错误时遇到问题,在以下两种情况下:
- 当请求的页面在服务器上不存在时(如 http:///localhost/test/)
- 请求时 URL 与现有控制器和方法不匹配(如 http:///localhost/test/task/)
我遇到以下错误:
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 让我走上正轨!