【问题标题】:What is the most "elegant" way to define a global constant array in PHP在 PHP 中定义全局常量数组的最“优雅”方式是什么
【发布时间】:2011-06-05 23:05:58
【问题描述】:

我想知道您认为定义常量数组变量的最佳和最简洁的方式类似于 define 函数的工作方式。我在谷歌看到很多人问这个问题,到目前为止,我想出的最简单的解决方案是在 define 语句中使用 PHP serialize 函数,像这样

define ("MY_ARRAY", serialize (array ("key1" => $value1,"key2" => $value2, ..)));

然后要使用定义的常量,您可以执行以下操作:

$MY_ARRAY = unserialize (MY_ARRAY)
print_r ($MY_ARRAY);

如果您的代码中有很多 defines,不确定 serialize 功能是否会减慢您的速度。你怎么看?

【问题讨论】:

  • 你需要全局变量做什么。也许有更好的方法。
  • $GLOBALS['MY_ARRAY'] = array();
  • PeeHaa,如果我想从同一命名空间中的任何类或函数中访问常量数组,我需要它是全局的!
  • dqhendricks - 您的解决方案非常有吸引力,但您不是总是在想要访问它时使用 $GLOBALS['MY_ARRAY'] 吗?另外,$GLOBALS 也是不变的吗?我认为没有!
  • $GLOBALS 是一个超级全局变量,可用于代码的每个部分,就像 $_POST 或 $_GET。虽然你是对的,但它并不是一个真正的常数。 PHP 不允许使用常量数组。

标签: php arrays constants global


【解决方案1】:
$GLOBALS['MY_ARRAY'] = array();

【讨论】:

  • 有人可以用 $_POST["MY_ARRAY"} 或 $_GET["MY_ARRAY"] 覆盖 MY_ARRAY 并以这种方式注入他们自己的代码吗?
  • 不,这就是发明超级全局数组的原因。过去人们习惯于在 PHP 配置中设置它,以便 post 变量成为全局变量,直到他们意识到这是黑客的梦想。可以肯定的是,在您的测试服务器上尝试一下,看看会发生什么。
  • $GLOBALS 与 $_POST 或 $_GET 变量没有任何关系。
  • define 是否也使变量“超全局”?
  • 好吧,如果你在一个仍然启用了 register_globals 的邪恶主机上,这将是相关的。但除此之外,是的,它们是完全分开的。
【解决方案2】:

序列化,尤其是反序列化非常尴尬。 (另一方面,还不清楚为什么脚本语言不能将数组作为常量......)

但这真的取决于使用模式。通常,您需要全局定义来存储配置设置。全局变量和常量是一个合适的用途(尽管“全局变量是邪恶的!!1!”模因)。但建议至少将所有内容放入某种注册表对象或数组中:

class config {
     var $MY_ARRAY = array("key1"=>...);
     var $data_dir = "/tmp/";
} 

这提供了config::$MY_ARRAY 最简单的访问语法。这不是一个常数,但你可以很容易地伪造它。只需使用 ArrayObject 或 ArrayAccess 并以使属性只读的方式实现它。 (让offsetSet 抛出错误。)

如果您想要一个全局数组常量解决方法,那么另一种选择(我从define manual page 中窃取了这个想法)是使用函数代替常量:

function MY_ARRAY() {
     return array("key1" => $value1,);
}

访问也不是很稳定,但MY_ARRAY() 足够短。尽管在 PHP 5.3 之前无法使用 MY_ARRAY()["key1"] 进行良好的数组访问;但这又可以用MY_ARRAY("key1") 伪造。

【讨论】:

  • 马里奥,序列化可能出现什么问题?此外,函数或类都不会进入全局范围。
  • @techexpert,序列化真的没有错。但是unserialize(MY_ARRAY) 读起来很长,而且你总是需要一个临时变量来解包。这种方式违背了易于访问常量的目的。您不妨定义一个函数my_const_array("NAME") 来从注册表中获取它。
  • 我真的很想为数组找到“define”语句的替代方法,这样您就可以以一种干净的方式将变量传递给任何函数,例如:call_function(MY_ARRAY)
  • 我会说同样的 2 个例外,我指出 dqhendricks 的答案,在这里申请,但也要投票以获得一个简洁的答案!!!谢谢! ;)
  • 经过测试,它不起作用(我错过了什么吗?):class MyClass { var $test = array('foo', 'bar');回声 MyClass::$test; (在这里试过:sandbox.onlinephpfunctions.com/:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 2012-08-08
  • 2012-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多