PHP常量数组

68

这是在PHP中将数组作为常量的唯一方法吗?还是说这段代码不好:

class MyClass
{
    private static $myArray = array('test1','test2','test3');

    public static function getMyArray()
    {
       return self::$myArray;
    } 
}

1
它不是常量吗?它只是静态的... 在我看来,如果你通过方法指向数组,就可以操纵它...我认为在PHP中无法声明非基本类型为常量... - TheHe
我知道它不是常量,这就是我的问题所在。模仿具有常量行为的数组的唯一方法是什么? - Marty Wallace
3
从PHP 5.6.0(2014年8月28日)开始,可以定义一个数组常量([参见https://dev59.com/1Wct5IYBdhLWcg3wZMfn#30031923])。 - cgaldiolo
7个回答

82

你的代码没问题 - 在PHP 5.6之前,数组无法声明为常量,因此静态方法可能是最好的选择。你应该考虑通过注释将此变量标记为常量:

/** @const */
private static $myArray = array(...);

自PHP 5.6.0版本以后,你可以将数组声明为常量:

const myArray = array(...);

6
请注意,变量$myArray本身是可更改的,在这个意义上它比常量不够安全。如果您不能使用private或protected修饰符,则我认为在PHP中无法保证数组的安全性。 - e-motiv
1
仅当键是常量时才有效,但是当您的键来自表达式时,上述解决方案不可行。 - Mubashar

20

从 PHP 5.6.0(2014年8月28日)开始,可以定义一个数组常量(请参见PHP 5.6.0新特性)。

class MyClass
{
    const MYARRAY = array('test1','test2','test3');

    public static function getMyArray()
    {
        /* use `self` to access class constants from inside the class definition. */
        return self::MYARRAY;
    } 
}

/* use the class name to access class constants from outside the class definition. */
echo MyClass::MYARRAY[0]; // echo 'test1'
echo MyClass::getMyArray()[1]; // echo 'test2'

$my = new MyClass();
echo $my->getMyArray()[2]; // echo 'test3'

从PHP 7.0.0(2015年12月3日)开始,可以使用define()定义数组常量。在PHP 5.6中,只能使用const定义数组常量。(详情请参见 PHP 7.0.0新特性

define('MYARRAY', array('test1','test2','test3'));

9

我自己也在查找答案时遇到了这个问题。一开始我以为我必须在需要使用数组的每个函数中都传递它。但是,我的数组和mysql的经验让我想知道序列化是否可行。当然它是可行的。

define("MYARRAY",     serialize($myarray));

function something() {
    $myarray= unserialize(MYARRAY);
}

这将在全局范围内定义它,而不是在类上下文中定义。在某些情况下很有帮助,我以前也使用过这种行为。 - Anthony

2

我建议使用以下内容:

class MyClass
{
    public static function getMyArray()
    {
       return array('test1','test2','test3');
    } 
}

这样你就拥有了一个const数组,你可以确保没有人能够更改它,甚至是Class本身的方法。
可能的微优化(不确定现在的PHP编译器能优化多少):
class MyClass
{
    public static function getMyArray()
    {
       static $myArray = array('test1','test2','test3');
       return $myArray;
    } 
}

1
你创建了一个静态数组,而不是常量数组。静态变量是可变的;常量是不可变的。你的代码还不错,但它并没有达到你想要的效果。
在PHP 5.6中,你可以声明const数组。请参见我之前的解释
也许你想要像这样的东西:
class MyClass
{
    const MY_ARRAY = array('test1','test2','test3');

    public function getMyArray()
    {
       return MY_ARRAY;
    } 
}

请注意,常量没有$前缀,这表示它们是不可变的。 $foo是一个变量; FOO不是。此外,常量名称始终大写,至少在我接触过的编程语言中是如此。这不是由编译器强制执行的;它只是一种(几乎?)普遍的编码样式约定。可见性关键字publicprotectedprivate不适用于常量。最后,static可能会或可能不会应用,这取决于您是否希望该函数是static

1
将其标记为静态的是一个很好的替代方案。以下是封装静态数组以获得某种程度的“常量”行为的示例。
class ArrayConstantExample {

    private static $consts = array(
        'CONST_MY_ARRAY' => array(
            1,2,3,4
        )
    );

    public static function constant($name) {
        return self::$consts[$name];
    }

}

var_dump( ArrayConstantExample::constant('CONST_MY_ARRAY') );

打印:
array(4) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) }

只是一个快速提示:这并不会使变量成为常量。它只是使代码中的变量看起来更像常量。尽管它可能让开发人员感觉更好,但它与其他答案一样容易被误用。只是想防止读者以为这实际上是常量。 - Andrew Ensley
我的代码在接受的答案基础上添加了对数组的封装。你有一定正确,因为数组仍然可以在同一个类内修改。我想表达的是,你可以在类外访问该数组,但不能修改它。 - Joe

1
从PHP 5.6开始,可以将常量定义为标量表达式,也可以定义数组常量。
class foo {
   const KEYS = [1, 3, 6, 7];
}
//
echo foo::KEYS[0]; // 1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接