有什么方法可以从 Yii2 中的错误消息中隐藏文件系统路径
Is there any way to hide filesystem path from error messages in Yii2
生产服务器上有一个应用程序,有时我需要进行一些快速修改。但是,Yii2 在出错时会显示错误文件的完整文件系统路径。
我唯一知道并尝试过的事情:
像defined('YII_DEBUG') or
define('YII_DEBUG', false);
一样在web\index.php
中停止调试
暂时关闭网站,如 that,或 public(通过更改 IIS 中的绑定)并通过服务器远程桌面的内部循环访问它。
我想知道是否有任何方法可以让 Yii 停止考虑文件的完整系统路径并考虑一些通用路径,例如 @app\views\site\index.php
而不是 C:\www\app\views\site\index.php
我发现负责显示错误的方法是 renderCallStackItem
,它位于 vendor\yiisoft\yii2\web\ErrorHandler.php
中。我刚刚更改了它 returns 的文件参数,如下所示:
public function renderCallStackItem($file, $line, $class, $method, $args, $index)
{
$lines = [];
$begin = $end = 0;
if ($file !== null && $line !== null) {
$line--; // adjust line number from one-based to zero-based
$lines = @file($file);
if ($line < 0 || $lines === false || ($lineCount = count($lines)) < $line) {
return '';
}
$half = (int) (($index === 1 ? $this->maxSourceLines : $this->maxTraceSourceLines) / 2);
$begin = $line - $half > 0 ? $line - $half : 0;
$end = $line + $half < $lineCount ? $line + $half : $lineCount - 1;
}
return $this->renderFile($this->callStackItemView, [
'file' => str_replace(Yii::$app->basePath, '...',$file), //Change is here
'line' => $line,
'class' => $class,
'method' => $method,
'index' => $index,
'lines' => $lines,
'begin' => $begin,
'end' => $end,
'args' => $args,
]);
}
我已使用 str_replace
从错误消息中删除应用程序的 basePath。我通过在框架源代码中对文件进行硬编码来完成此操作。
现在的问题,我不知道如何覆盖OOP中的方法?即我想创建从 vendor\yiisoft\yii2\web\ErrorHandler.php
扩展的新 ErrorHandler
class。 问题是我如何才能让 Yii2 为整个应用程序更改其 ErrorHandler class?
解决方案如下:
1- 更改 config/web.php
\
中的默认 ErrorHandler class
'errorHandler' => [
'errorAction' => 'site/error',
'class' => 'app\components\saidbakr\FoxErrorHandler',
],
- 使用以下代码在
components/saidbakr
中创建一个名为 FoxErrorHandler.php
的新 class:
نتامعلخعرؤنلبغ́خا
<?php
namespace app\components\saidbakr;
use Yii;
class FoxErrorHandler extends \yii\web\ErrorHandler
{
public function renderCallStackItem($file, $line, $class, $method, $args, $index)
{
$lines = [];
$begin = $end = 0;
if ($file !== null && $line !== null) {
$line--; // adjust line number from one-based to zero-based
$lines = @file($file);
if ($line < 0 || $lines === false || ($lineCount = count($lines)) < $line) {
return '';
}
$half = (int) (($index === 1 ? $this->maxSourceLines : $this->maxTraceSourceLines) / 2);
$begin = $line - $half > 0 ? $line - $half : 0;
$end = $line + $half < $lineCount ? $line + $half : $lineCount - 1;
}
return $this->renderFile($this->callStackItemView, [
'file' => str_replace(Yii::$app->basePath, '...',$file),//Look Here
'line' => $line,
'class' => $class,
'method' => $method,
'index' => $index,
'lines' => $lines,
'begin' => $begin,
'end' => $end,
'args' => $args,
]);
}
}
以上class代码只是继承自ErrorHandler,方法renderCallStackItem
是对原始方法的复制,对$file
值稍作修改。
更新
在某些情况下,错误或调试消息的 header 可能包含受影响文件的完整文件系统路径。它是一个名为 previuosExceptionView
的模板,它在 ErrorHandler
class 中有一个名为 previousExceptionView
的 属性。我们应该在 children 错误处理程序 class FoxErrorHandler
中覆盖此 属性,如下所示:
...
class FoxErrorHandler extends \yii\web\ErrorHandler
{
public $previousExceptionView = '@app/components/saidbakr/previousException.php';
public function renderCallStackItem($file, $line, $class, $method, $args, $index)
{
....
然后,在 $previousExceptionView
的考虑路径中,我们应该将一个名为 previousException.php
的文件从 \vendor\yiisoft\yii2\views\errorHandler
复制到该路径,即 @app/components/saidbakr/previousException.php
,然后我们必须编辑它文件路径输出,文件 previousException.php
应如下所示:
<?php
/* @var $exception \yii\base\Exception */
/* @var $handler \app\components\saidbakr\FoxErrorHandler */
?>
<div class="previous">
<span class="arrow">↵</span>
<h2>
<span>Caused by:</span>
<?php $name = $handler->getExceptionName($exception);
if ($name !== null): ?>
<span><?= $handler->htmlEncode($name) ?></span> –
<?= $handler->addTypeLinks(get_class($exception)) ?>
<?php else: ?>
<span><?= $handler->htmlEncode(get_class($exception)) ?></span>
<?php endif; ?>
</h2>
<h3><?= nl2br($handler->htmlEncode($exception->getMessage())) ?></h3>
<!-- in the next line we are going to remove the full filesystem path and replace it with triple dots -->
<p>in <span class="file"><?= str_replace(Yii::$app->basePath, '...',$exception->getFile()) ?></span> at line <span class="line"><?= $exception->getLine() ?></span></p>
<!-- End Edit -->
<?php if ($exception instanceof \yii\db\Exception && !empty($exception->errorInfo)) {
echo '<pre>Error Info: ' . print_r($exception->errorInfo, true) . '</pre>';
} ?>
<?= $handler->renderPreviousExceptions($exception) ?>
</div>
生产服务器上有一个应用程序,有时我需要进行一些快速修改。但是,Yii2 在出错时会显示错误文件的完整文件系统路径。
我唯一知道并尝试过的事情:
像
defined('YII_DEBUG') or define('YII_DEBUG', false);
一样在暂时关闭网站,如 that,或 public(通过更改 IIS 中的绑定)并通过服务器远程桌面的内部循环访问它。
web\index.php
中停止调试
我想知道是否有任何方法可以让 Yii 停止考虑文件的完整系统路径并考虑一些通用路径,例如 @app\views\site\index.php
而不是 C:\www\app\views\site\index.php
我发现负责显示错误的方法是 renderCallStackItem
,它位于 vendor\yiisoft\yii2\web\ErrorHandler.php
中。我刚刚更改了它 returns 的文件参数,如下所示:
public function renderCallStackItem($file, $line, $class, $method, $args, $index)
{
$lines = [];
$begin = $end = 0;
if ($file !== null && $line !== null) {
$line--; // adjust line number from one-based to zero-based
$lines = @file($file);
if ($line < 0 || $lines === false || ($lineCount = count($lines)) < $line) {
return '';
}
$half = (int) (($index === 1 ? $this->maxSourceLines : $this->maxTraceSourceLines) / 2);
$begin = $line - $half > 0 ? $line - $half : 0;
$end = $line + $half < $lineCount ? $line + $half : $lineCount - 1;
}
return $this->renderFile($this->callStackItemView, [
'file' => str_replace(Yii::$app->basePath, '...',$file), //Change is here
'line' => $line,
'class' => $class,
'method' => $method,
'index' => $index,
'lines' => $lines,
'begin' => $begin,
'end' => $end,
'args' => $args,
]);
}
我已使用 str_replace
从错误消息中删除应用程序的 basePath。我通过在框架源代码中对文件进行硬编码来完成此操作。
现在的问题,我不知道如何覆盖OOP中的方法?即我想创建从 vendor\yiisoft\yii2\web\ErrorHandler.php
扩展的新 ErrorHandler
class。 问题是我如何才能让 Yii2 为整个应用程序更改其 ErrorHandler class?
解决方案如下:
1- 更改 config/web.php
\
'errorHandler' => [
'errorAction' => 'site/error',
'class' => 'app\components\saidbakr\FoxErrorHandler',
],
- 使用以下代码在
components/saidbakr
中创建一个名为FoxErrorHandler.php
的新 class:
نتامعلخعرؤنلبغ́خا
<?php
namespace app\components\saidbakr;
use Yii;
class FoxErrorHandler extends \yii\web\ErrorHandler
{
public function renderCallStackItem($file, $line, $class, $method, $args, $index)
{
$lines = [];
$begin = $end = 0;
if ($file !== null && $line !== null) {
$line--; // adjust line number from one-based to zero-based
$lines = @file($file);
if ($line < 0 || $lines === false || ($lineCount = count($lines)) < $line) {
return '';
}
$half = (int) (($index === 1 ? $this->maxSourceLines : $this->maxTraceSourceLines) / 2);
$begin = $line - $half > 0 ? $line - $half : 0;
$end = $line + $half < $lineCount ? $line + $half : $lineCount - 1;
}
return $this->renderFile($this->callStackItemView, [
'file' => str_replace(Yii::$app->basePath, '...',$file),//Look Here
'line' => $line,
'class' => $class,
'method' => $method,
'index' => $index,
'lines' => $lines,
'begin' => $begin,
'end' => $end,
'args' => $args,
]);
}
}
以上class代码只是继承自ErrorHandler,方法renderCallStackItem
是对原始方法的复制,对$file
值稍作修改。
更新
在某些情况下,错误或调试消息的 header 可能包含受影响文件的完整文件系统路径。它是一个名为 previuosExceptionView
的模板,它在 ErrorHandler
class 中有一个名为 previousExceptionView
的 属性。我们应该在 children 错误处理程序 class FoxErrorHandler
中覆盖此 属性,如下所示:
...
class FoxErrorHandler extends \yii\web\ErrorHandler
{
public $previousExceptionView = '@app/components/saidbakr/previousException.php';
public function renderCallStackItem($file, $line, $class, $method, $args, $index)
{
....
然后,在 $previousExceptionView
的考虑路径中,我们应该将一个名为 previousException.php
的文件从 \vendor\yiisoft\yii2\views\errorHandler
复制到该路径,即 @app/components/saidbakr/previousException.php
,然后我们必须编辑它文件路径输出,文件 previousException.php
应如下所示:
<?php
/* @var $exception \yii\base\Exception */
/* @var $handler \app\components\saidbakr\FoxErrorHandler */
?>
<div class="previous">
<span class="arrow">↵</span>
<h2>
<span>Caused by:</span>
<?php $name = $handler->getExceptionName($exception);
if ($name !== null): ?>
<span><?= $handler->htmlEncode($name) ?></span> –
<?= $handler->addTypeLinks(get_class($exception)) ?>
<?php else: ?>
<span><?= $handler->htmlEncode(get_class($exception)) ?></span>
<?php endif; ?>
</h2>
<h3><?= nl2br($handler->htmlEncode($exception->getMessage())) ?></h3>
<!-- in the next line we are going to remove the full filesystem path and replace it with triple dots -->
<p>in <span class="file"><?= str_replace(Yii::$app->basePath, '...',$exception->getFile()) ?></span> at line <span class="line"><?= $exception->getLine() ?></span></p>
<!-- End Edit -->
<?php if ($exception instanceof \yii\db\Exception && !empty($exception->errorInfo)) {
echo '<pre>Error Info: ' . print_r($exception->errorInfo, true) . '</pre>';
} ?>
<?= $handler->renderPreviousExceptions($exception) ?>
</div>