【问题标题】:Is it possible to declare an array as constant [duplicate]是否可以将数组声明为常量[重复]
【发布时间】:2011-04-17 17:31:28
【问题描述】:

我们可以定义一个常量

define("aconstant','avalue');

我们不能像下面这样定义数组吗?

define("months",array("January", "February", ---); 

【问题讨论】:

标签: php


【解决方案1】:

更新:这在 PHP 7 中是可能的 (reference)

// Works as of PHP 7
define('ANIMALS', array(
    'dog',
    'cat',
    'bird'
));
echo ANIMALS[1]; // outputs "cat"

原始答案

来自 php.net...

常量的值;只有 标量和空值是 允许。标量值是整数、浮点数、字符串或布尔值。 可以定义资源常量,但不是 推荐并可能导致不可预知的行为。

$months = array("January,"February",...) 会很好。

【讨论】:

  • 以防万一有人没有注意到其他答案,您可以在 PHP 5.6 或更高版本中创建一个“const”数组。
  • $months = array("January,"February",...) 不是少了引号吗?
  • 为了清楚起见,PHP 7 的介绍也包括关联数组。 define('MY_ANIMALS', array('dog' => 'Ottie', 'cat' => 'Garfield', 'bird'=>'Tweetie')); echo MY_ANIMALS['cat']; //outputs 'Garfield'
  • Pre 7: define('ANIMALS', json_encode( array('dog', 'cat', 'bird') ) ); 然后在引用时:json_decode(ANIMALS, true); 有点不方便,但有时(例如,如果您存储数据库的结构以便在框架内进行更智能的查询)它是这样做比不必要地调用数据库更值得。
  • 这同样适用于 PHP 7 中的类常量。
【解决方案2】:

从 PHP 5.6 开始,可以使用to declare constant arrays。链接文档使用示例const ARR = ['a', 'b'];。你也可以const ARR = array('a', 'b');。然而,在 5.6 中有一个奇怪的怪癖:您可以使用 const 声明常量数组,但不能使用 define()。这是 PHP 7.0 中的 has been corrected

【讨论】:

    【解决方案3】:

    您可以使用 JSON 格式将数组保存在字符串中,然后将此字符串分配给常量。

    $months = array("January","February","March");
    define('MONTHS', json_encode($months));
    

    当你想使用它时:

    $months = json_decode(MONTHS);
    

    【讨论】:

    • PHP 5.x 的最佳答案!
    【解决方案4】:

    自 PHP 5.6 起,您可以使用 const 来实现此目的(通过 nikic)。

    const months = ["January", "February"];
    var_dump("January" === months[0]);
    

    【讨论】:

    • 这真的应该有更多的赞成票(不仅仅是我的^^)。
    • @Levit:一旦我可以真正使用 5.6,我会投票赞成 :)
    • @cHao:好一个! ^^ 尽管如此,我还是喜欢在 5.6 中实现这一点,而这实际上是 5.6 以后最干净/完美的答案。即使仍然主要使用 5.3 并且在不到 1% 的所有 php 网站上运行 5.6,这值得超过 1 个赞成票,只是为了指出该功能的存在(以及从现在开始的许多年,当这些版本更多时标准,这不是 1 个赞成票,而使用变量的建议有超过 200 个赞成票 + 被接受)。对不起,我真的很喜欢你的评论! ^^
    • 谢谢!我没有意识到 5.6 支持这个......非常值得从 5.5 升级我们的服务器以获得这个功能。谢谢!
    • 澄清一下,这只能在一个类中实现?
    【解决方案5】:

    如果你必须有一个常量,那么使用一个分隔字符串并分解成一个数组怎么样?

    define("MONTHS", "January;February;March");
    $months = explode(";",MONTHS);
    

    【讨论】:

    • 不错的选择,我很想看看性能与序列化的对比。
    • 我想需要一个大数组才能真正产生显着差异。
    【解决方案6】:

    不,你不能。见PHP: Syntax - Manual

    只有标量数据布尔值、整数、浮点数字符串)可以包含在常量中。 可以将常量定义为资源,但应该避免, 因为它可能会导致意想不到的结果。

    【讨论】:

    • +1 我想知道为什么 PHP 一开始就允许定义常量资源?
    • @BoltClock 是独角兽:我不太清楚,从来没有遇到过解释。但是考虑到 php 的发展历史,这并不奇怪,因为一些“历史原因”.. :)
    【解决方案7】:

    您可以通过 hack 将数组放入常量中:

    define('MONTHS', serialize(array('January', 'February' ...)));
    

    但是你必须在需要时 unserialize() 那个常量值,我想这并不是那么有用。

    作为替代方案,定义多个常量:

    define('MONTH_1', 'January');
    define('MONTH_2', 'February');
    ...
    

    并使用constant()函数查找值:

    echo constant('MONTH_'.$month);
    

    【讨论】:

    • +1,但我想知道,json_encode 和 json_decode 呢?哪一个更适合内存和性能?
    • @CengizFrostclaw: serialize 在大多数情况下会更好。即使它最终变慢了一点(我猜这与事实相反),它本身就支持 PHP 概念,如引用和类型化对象,这些概念无法通过 JSON 来回运行。
    • @cHao,是的,序列化更快,但也很危险,因为它可能会执行代码。即使这里不适用,我认为具有安全意识的开发人员应该习惯使用最不危险的方法。在这种情况下,性能差异可以忽略不计,我认为 JSON 方法在这里更好。
    • @MarioAwad:在这种情况下,安全不是问题——常量是由程序员定义的,而不是用户定义的。我不会unserialize($input),但我当然不会担心我写的字符串,而且根据定义不会被篡改。
    • @MarioAwad:我们不应该习惯盲目地使用“最不危险”的方法;那就是货物崇拜。我们应该习惯评估危险。坦率地说,对于纯内部的东西,与用户输入相关的安全风险根本不存在。更大的危险是你得到的可能不是你输入的,而 JSON 有时可能会很糟糕。 (尝试json_encodeing 任何引用自身的东西。)我承认explode 在这种情况下会更简单。但是 JSON 是多余的(而且在代码方面,允许传入意外的数据结构)。
    猜你喜欢
    • 2015-06-16
    • 2017-04-24
    • 1970-01-01
    • 2016-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-06
    • 1970-01-01
    相关资源
    最近更新 更多