我有一个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)
输出
array(4){[0] =&gt;字符串(19)&#34;未经授权的访问&#34; [1] =&GT; string(25)&#34;用户名/密码错误&#34; [2] =&GT; string(16)&#34; Missing field(s)&#34; [3] =&GT;字符串(23)&#34;密码不匹配!&#34; }
但函数内的var_dump
会返回NULL
这是什么原因,我该如何预防?
答案 0 :(得分:2)
这是因为您的变量范围是本地的。在函数内访问它。你需要让它全球化。
<?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
}
?>
答案 1 :(得分:2)
我不会使用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
}
Global是垃圾IMO,因为没有办法告诉它是否已设置。当然在单个文件中看起来很好,但是当你有一个由数百个文件和数万行代码组成的站点时,几乎不可能找到全局设置或更改的位置。 (我花了几百个小时来挖掘旧的第三方代码以获得类似的东西)
我个人不惜一切代价避免使用它。
使用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 这会移动类中的所有依赖项,因为我们可以保持一切都很整洁。基本上它是一个关注点的分离,你在课堂外的代码不应该关心错误代码的价值,主要是你只需要正确的字符串消息。这样做是一个黑匣子,其实施对你的其他应用程序并不重要。
您可能还会注意到我使用final
作为类和private
构造函数。这些可以保护课程不被以后修改或以其无意的方式使用。 Final意味着该类无法扩展,因此子类不能修改任何方法。如果您尝试使用new AppError()
创建类的新实例,PHP将引发错误。这意味着访问类中方法的唯一方法是使用静态调用class::method()
。
这是一种挑剔的事情,但我想我会这样做,因为为了完整起见,我会在real
中强迫这个班级。由于我不知道你的面向对象编程水平和使用我所概述的类是IMO正确的方法,因此我也进行了一些解释。
现在使用常量非常简单(镜像上面的例子)
var_dump(AppError::getErrors(AppError::ER_ACCESS)); //"Unauthorized access"
注意我没有测试任何这些,所以如果有任何语法错误,请原谅我。
我建议的最后一件事是看看异常如何在php中运行,所有酷孩子都使用它们,它会让你做throw
和catch
错误。< / p>
http://php.net/manual/en/language.exceptions.php
P.S。当我写这篇文章时我已经回答了这个问题(我并不关心这些问题),只是OP似乎很好并且有一个写得很好的问题,所以我想我会把一些全面的东西放在一起来展示OOP的可能性。
享受!