>我有一个PHP文件看起来像这样:
<?php
$ERRORS = array(
'0' => "Unauthorized access",
'1' => "Wrong username / password",
'2' => "Missing field(s)",
'3' => "Passwords do not match!"
);
var_dump($ERRORS);
function getErrorMessage($errorCode){
var_dump($ERRORS);
// More code to output the corresponding message
}
?>
执行时,前var_dump($ERRORS)
输出
16( "缺少字段" [3]=> 字符串(23( "密码不匹配!" }
但是函数内部的var_dump
返回NULL
造成这种情况的原因是什么,我该如何预防?
这是因为您的变量范围是局部的。在功能内部访问它。你需要让它全球化。
<?php
global $ERRORS;
$ERRORS = array(
'0' => "Unauthorized access",
'1' => "Wrong username / password",
'2' => "Missing field(s)",
'3' => "Passwords do not match!"
);
var_dump($ERRORS);
function getErrorMessage($errorCode){
global $ERRORS;
var_dump($ERRORS);
// More code to output the corresponding message
}
?>
我不会使用global
我会使用normal
方式
<?php
$ERRORS = array(
'0' => "Unauthorized access",
'1' => "Wrong username / password",
'2' => "Missing field(s)",
'3' => "Passwords do not match!"
);
var_dump($ERRORS);
function getErrorMessage($errorCode, $ERRORS)
{
var_dump($ERRORS);
// More code to output the corresponding message
}
全球是IMO的垃圾,因为没有办法知道它是被设置的。 当然,在一个文件中看起来很好,但是当您有一个由数百个文件和 10 多千行代码组成的站点时,几乎不可能找到全局设置或更改的位置。(我花了数百小时挖掘较旧的第三方代码以获取类似的东西(
就个人而言,我不惜一切代价避免使用它。
最好用getErrors((方法将其制作为类,这就是我的做法(除了我会构建一个实际的\Exception类(
final class AppError
{
//constant value should match array key for the error
/*
Unknown Error was intentionally left out, this is for internal
use granted with only 4 errors and the constants it would be
hard to give an invalid error code, but as the class grows
we are future proofing it.
*/
const ER_ACCESS = 0;
const ER_LOGIN = 1; //this is a login error it seems, and this looks better / is shorter then ER_USER_PASS
const ER_MISSING = 2;
const ER_PASSWORD = 3;
public static $ERRORS = [
'-1' => "Unknown Error", //I added this
//'0' => "No Error", //I changed this number
'1' => "Unauthorized access",
'2' => "Wrong username / password",
'3' => "Missing field(s)",
'4' => "Passwords do not match!" //isn't this the wrong password
];
private function __construct(){ //no construction }
public static function getErrors( $code = null)
{
//on null return all
if(in_null($code))
return self::$ERRORS;
//on false or 0 return empty string
if(!$code) return '';
/*
Example:
Consider this, you could have a function that checks for
errors and returns an error code or false on no errors. So,
by returning an empty string here we can avoid having to check
before passing that into this class.
*/
//code not set in array = unknown error
if(!isset(self::$ERRORS[$code]))
return self::$ERRORS['-1'];
return self::$ERRORS[$code];
}
}
然后
var_dump( AppError::getErrors() );
function getErrorMessage($errorCode)
{
var_dump( AppError::getErrors() );
// More code to output the corresponding message
}
现在你也可以这样做(作为奖励(
var_dump(AppError::getErrors(0)); //"Wrong username"
现在您可能想知道为什么我添加了这些const E_* = #
?
如果您用类似上面示例(编号代码(的内容填充代码。然后稍后在添加一堆错误后,您决定组织它们并重新编号它们,您必须查看所有代码并找到这些数字并修复它们。使用常量,我们不关心常量是什么值,它可以是
pumpernickel
的,也无关紧要。很难看
0
并知道这是一个Unauthorized access
错误。 因此,通过使用常量,我们可以提高整体代码的可读性。 当您看到ER_ACCESS
而不是0
时,就会清楚它是什么。
Summery这会移动类中的所有依赖项,我们可以保持一切整洁。基本上是关注点分离,类外的代码不应该关心该错误代码的值是什么,主要是你只需要正确的字符串消息。如何做到这一点是一个黑匣子,其实现对应用程序的其余部分无关紧要。
您可能还会注意到我为类和private
构造函数使用了final
。这些保护类以后不会被修改或以非预期的方式使用。Final 意味着该类无法扩展,因此子类不能修改任何方法.PHP如果您尝试使用new AppError()
创建该类的新实例,则会引发错误。这意味着访问类中方法的唯一方法是使用静态调用class::method()
。
这是一件挑剔的事情,但我想我会这样做,因为为了完整起见,我会在real
上班。 我也在解释上超越了一点,那是因为我不知道你的面向对象编程水平,使用我概述的类是 IMO 正确的方法。
现在使用常量非常简单(镜像上面的例子(
var_dump(AppError::getErrors(AppError::ER_ACCESS)); //"Unauthorized access"
请注意,我没有测试任何内容,因此如果有任何语法错误,请原谅我。
我建议的最后一件事是看看异常在php中是如何工作的,所有很酷的孩子都使用它们,它会让你做一些事情,比如throw
和catch
错误。
http://php.net/manual/en/language.exceptions.php
附言当我写这篇文章时,这个问题已经得到了回答(我不在乎要点(,只是 OP 看起来不错并且有一个写得很好的问题,所以我想我会把一些全面的东西放在一起来展示 OOP 的可能性。
享受!