67

Is this the only way to have arrays as constants in php or is this bad code:

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

    public static function getMyArray()
    {
       return self::$myArray;
    } 
}
Niko
  • 26,516
  • 9
  • 93
  • 110
Marty Wallace
  • 34,046
  • 53
  • 137
  • 200
  • 1
    it's not constant? it's only static... imho you can manipulate the array if you point to it through the method... i don't think it's possible to declare a non-primitive type as constant in php... – TheHe Aug 26 '12 at 10:05
  • I know its not constant, this is the point of my question. Is the only way to mimic an array with constant behaviour – Marty Wallace Aug 26 '12 at 10:08
  • 3
    Starting with PHP 5.6.0 (28 Aug 2014), it is possible to define an array constant ([see http://stackoverflow.com/a/30031923/1873197](http://stackoverflow.com/a/30031923/1873197) – cgaldiolo May 04 '15 at 13:56

7 Answers7

82

Your code is fine - arrays cannot be declared constant in PHP before version 5.6, so the static approach is probably the best way to go. You should consider marking this variable as constant via a comment:

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

With PHP 5.6.0 or newer, you can declare arrays constant:

const myArray = array(...);
Niko
  • 26,516
  • 9
  • 93
  • 110
  • 6
    Beware though that the variable $myArray itself can be changed and in that sense it is less secure than a constant. If you can't use private or protect, then I think there is no solution for security in php on arrays. – e-motiv Oct 30 '13 at 22:23
  • 1
    works when the keys are constant only however above solution is not workable when your keys are coming out of an expression – Mubashar Oct 26 '18 at 00:30
20

Starting with PHP 5.6.0 (28 Aug 2014), it is possible to define an array constant (See PHP 5.6.0 new features).

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'

With PHP 7.0.0 (03 Dec 2015) array constants can be defined with define(). In PHP 5.6, they could only be defined with const. (See PHP 7.0.0 new features)

define('MYARRAY', array('test1','test2','test3'));
cgaldiolo
  • 3,497
  • 1
  • 20
  • 17
9

I came across this thread looking for the answer myself. After thinking I would have to pass my array through every function it was needed in. My experience with arrays and mysql made me wonder if serialize would work. Of course it does.

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

function something() {
    $myarray= unserialize(MYARRAY);
}
pokeybit
  • 1,032
  • 11
  • 18
  • That defines it in the global scope, though, not in the class context. It's helpful in certain cases, though, I've used this behavior before. – Anthony Jul 31 '14 at 18:37
2

I suggest using the following:

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

This way you do have a const array and you're guaranteed that noone can change it, not even a method in the Class itself.

Possible micro-optimization (not sure how much PHP compilers optimize nowadays):

class MyClass
{
    public static function getMyArray()
    {
       static $myArray = array('test1','test2','test3');
       return $myArray;
    } 
}
Kira M. Backes
  • 530
  • 3
  • 10
1

Marking it static is a good alternative. Here's an example of encapsulating a static array to get somewhat of constant behavior.

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') );

Prints:

array(4) { [0]=> int(1) [1]=> int(2) [2]=> int(3) [3]=> int(4) }
Joe
  • 509
  • 1
  • 8
  • 24
  • Just a quick FYI: This doesn't make the variable constant. It just makes it look more like it in the code. While it might make the developer feel better, it's no safer from abuse than any of the other answers. Just want to prevent readers from thinking this is actually constant in any way. – Andrew Ensley Feb 25 '15 at 19:05
  • My code adds to the accepted answer to encapsulate the array. You are somewhat correct because the array can still be modified inside the same class. The point I'm making is that you can access the array outside the class, but cannot change it. – Joe Feb 25 '15 at 19:42
1

You have created a static array, not a constant array. Static variables are mutable; constants are immutable. Your code is not bad, but it doesn't do what you intend it to do.

In PHP 5.6, you can declare const arrays. Please see my previous explanation.

Perhaps you want something like this:

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

    public function getMyArray()
    {
       return MY_ARRAY;
    } 
}

Note that constants have no $ prefix, which indicates their immutability. $foo is a variable; FOO is not. Additionally, constant names are always capitalized, at least in the programming languages I've been exposed to. This is not enforced by the compiler; it is simply an (almost?) universal coding style convention. Visibility keywords public, protected, and private do not apply to constants. Finally, static may or may apply depending on whether or not you want the function to be static.

Community
  • 1
  • 1
jfmercer
  • 3,641
  • 3
  • 29
  • 35
1

From PHP 5.6 onwards, it is possible to define a constant as a scalar expression, and it is also possible to define an array constant.

class foo {
   const KEYS = [1, 3, 6, 7];
}
//
echo foo::KEYS[0]; // 1
Tunaki
  • 132,869
  • 46
  • 340
  • 423
Rabih
  • 298
  • 1
  • 6
  • 18