450

This failed:

 define('DEFAULT_ROLES', array('guy', 'development team'));

Apparently, constants can't hold arrays. What is the best way to get around this?

define('DEFAULT_ROLES', 'guy|development team');

//...

$default = explode('|', DEFAULT_ROLES);

This seems like unnecessary effort.

user229044
  • 232,980
  • 40
  • 330
  • 338
Nick Heiner
  • 119,074
  • 188
  • 476
  • 699
  • 22
    PHP 5.6 supports constant arrays, see my answer below. – Andrea Dec 11 '14 at 00:14
  • 1
    When would you need to use an array as a constant, are you trying to do an enumeration? If so, then use SplEnum: http://php.net/manual/en/class.splenum.php – ziGi Dec 11 '14 at 00:22
  • 2
    @ziGi Came upon this issue today, have different types of images to store that require specific dimensions, it became useful to store these dimensions as constant arrays instead of one for width and one for height. – Matt K Sep 11 '15 at 21:09

17 Answers17

1001

Since PHP 5.6, you can declare an array constant with const:

<?php
const DEFAULT_ROLES = array('guy', 'development team');

The short syntax works too, as you'd expect:

<?php
const DEFAULT_ROLES = ['guy', 'development team'];

If you have PHP 7, you can finally use define(), just as you had first tried:

<?php
define('DEFAULT_ROLES', array('guy', 'development team'));
Andrea
  • 19,134
  • 4
  • 43
  • 65
  • 56
    This needs to be upvoted as all other answers are outdated or just written by misinformed users. – Andreas Bergström Dec 19 '14 at 13:09
  • Is that the only syntax? Are you able to use the old define function? define('ARRAY_CONSTANT', array('item1', 'item2', 'item3')); – Jack Dec 20 '14 at 00:31
  • 7
    @JackNicholsonn Unfortunately you can't use `define()` here in PHP 5.6, but [this has been fixed for PHP 7.0](https://github.com/php/php-src/commit/0833fd4619978c0522056b44dd53cd3b9d974cdd). :) – Andrea Dec 21 '14 at 03:10
  • 1
    @AndreasBergström No, this question is too new. This question was made in 2009! This syntax will be nearly useless for most users now-a-days. Almost anyone has PHP 5.6 on their servers. The other answers are perfectly fine since they also offer alternatives. The accepted answer is the only viable way so far, if you don't want to use classes. – Ismael Miguel Jan 14 '15 at 15:29
  • @IsmaelMiguel dont be so sure they all have 5.6. Anyone on windows server just now got the 5.6 sql server drivers from microsoft about a month ago. – M H Jul 09 '15 at 05:28
  • almost there! 8 more upvotes!! :p. Altho if this answer incoroporated the PHP < 5.6 answer it would be even more good – Damon Jun 14 '16 at 16:37
  • Aaaarrrgh... In PHP 5.6 you can define value of constant as a function returns value if you use `define` keyword. You can use arrays when you define it with `const` but no function returns value. And no option to mix it somehow. Only in php7. sigh... – vaso123 Jan 18 '17 at 14:53
  • @vaso123 one workaround is to do something like: `eval("const $constname = " . var_export($somevariable) . ";");` – not sure I'd recommend this though – Andrea Jan 18 '17 at 15:05
  • @Andrea Lol... Never, no way. `eval` is evil. To `define(serialize([...]));` is does the job for me, luckily I have only 2 arrays and these arrays are not too big. I could write a helper class to get those values, I just want to use advantages of my IDE. Next time... when we will start use PHP 7. – vaso123 Jan 19 '17 at 08:51
  • Short syntax obviously works for PHP7 as well, don't know why you wouldn't use it ([] instead of array()). – klidifia Mar 15 '20 at 20:48
  • Because it's what the original question did. – Andrea Mar 15 '20 at 20:55
521

PHP 5.6+ introduced const arrays - see Andrea Faulds' answer.

You can also serialize your array and then put it into the constant:

# define constant, serialize array
define ("FRUITS", serialize (array ("apple", "cherry", "banana")));

# use it
$my_fruits = unserialize (FRUITS);
Machavity
  • 30,841
  • 27
  • 92
  • 100
  • 23
    This code is elegant but pretty slow. It's far better using a public static class method that returns the array. – noun Sep 03 '13 at 15:13
  • 4
    just putting a note here that in PHP 5.6 you can now have const arrays.. `const fruits = ['apple', 'cherry', 'banana'];` – Alex K Nov 28 '14 at 12:57
147

You can store them as static variables of a class:

class Constants {
    public static $array = array('guy', 'development team');
}
# Warning: array can be changed lateron, so this is not a real constant value:
Constants::$array[] = 'newValue';

If you don't like the idea that the array can be changed by others, a getter might help:

class Constants {
    private static $array = array('guy', 'development team');
    public static function getArray() {
        return self::$array;
    }
}
$constantArray = Constants::getArray();

EDIT

Since PHP5.4, it is even possible to access array values without the need for intermediate variables, i.e. the following works:

$x = Constants::getArray()['index'];
soulmerge
  • 73,842
  • 19
  • 118
  • 155
  • 1
    +1. I am going for this for years: `const AtomicValue =42; public static $fooArray = ('how','di')` – Frank N May 07 '12 at 09:16
  • 9
    While it seems ridiculous to me that we can't create immutable arrays in php, this provides a decent workaround. – Akoi Meexx Aug 28 '12 at 07:13
  • If you are using the constant a lot, I would definitely avoid a function call, they are quite expensive. Static is the way to go. – Chris Seufert Oct 31 '14 at 00:59
  • 1
    This solution was far more awesome than I expected: I only needed part of the array's values, therefore instead of simply getting the array, I used some parameters in the function. In my case Constants::getRelatedIDs($myID) gets me an inner array with just the values I needed (I also do some ID validation inside this function). @cseufert getting the whole array and filtering for each case would be much more expensive for me... – Armfoot May 07 '15 at 10:29
  • 1
    having a function (getArray) with private static member is best representation for constants as they can be changes – Kamaldeep singh Bhatia Jan 23 '17 at 16:08
41

If you are using PHP 5.6 or above, use Andrea Faulds answer

I am using it like this. I hope, it will help others.

config.php

class app{
    private static $options = array(
        'app_id' => 'hello',
    );
    public static function config($key){
        return self::$options[$key];
    }
}

In file, where I need constants.

require('config.php');
print_r(app::config('app_id'));
Community
  • 1
  • 1
Jashwant
  • 28,410
  • 16
  • 70
  • 105
12

This is what I use. It is similar to the example provided by soulmerge, but this way you can get the full array or just a single value in the array.

class Constants {
    private static $array = array(0 => 'apple', 1 => 'orange');

    public static function getArray($index = false) {
        return $index !== false ? self::$array[$index] : self::$array;
    }
}

Use it like this:

Constants::getArray(); // Full array
// OR 
Constants::getArray(1); // Value of 1 which is 'orange'
Syclone
  • 1,235
  • 13
  • 14
10

PHP 7+

As of PHP 7, you can just use the define() function to define a constant array :

define('ANIMALS', [
    'dog',
    'cat',
    'bird'
]);

echo ANIMALS[1]; // outputs "cat"
Rabin Lama Dong
  • 2,422
  • 1
  • 27
  • 33
9

You can store it as a JSON string in a constant. And application point of view, JSON can be useful in other cases.

define ("FRUITS", json_encode(array ("apple", "cherry", "banana")));    
$fruits = json_decode (FRUITS);    
var_dump($fruits);
Mahesh Talpade
  • 137
  • 1
  • 4
  • This is exactly what I was thinking. Is this not a legitimately good answer? – Con Antonakos Jul 01 '14 at 19:35
  • This works really well with AngularJS because it consumes JSON. I feel like this is much better that the serialize answer, but is there some reason why serialize is better? Is it faster perhaps? – Drellgor Sep 19 '14 at 18:04
  • Yes serialize is technically faster. However, for small sets, which is what's needed mostly, I prefer this method as it's safer. When you unserialize, code might be executed. Even if in this case this is a very low risk, I think we should reserve the usage or unserialize for extreme cases only. – Mario Awad Dec 08 '14 at 13:21
4

I know it's a bit old question, but here is my solution:

<?php
class Constant {

    private $data = [];

    public function define($constant, $value) {
        if (!isset($this->data[$constant])) {
            $this->data[$constant] = $value;
        } else {
            trigger_error("Cannot redefine constant $constant", E_USER_WARNING);
        }
    }

    public function __get($constant) {
        if (isset($this->data[$constant])) {
            return $this->data[$constant];
        } else {
            trigger_error("Use of undefined constant $constant - assumed '$constant'", E_USER_NOTICE);
            return $constant;
        }
    }

    public function __set($constant,$value) {
        $this->define($constant, $value);
    }

}
$const = new Constant;

I defined it because I needed to store objects and arrays in constants so I installed also runkit to php so I could make the $const variable superglobal.

You can use it as $const->define("my_constant",array("my","values")); or just $const->my_constant = array("my","values");

To get the value just simply call $const->my_constant;

Rikudou_Sennin
  • 1,357
  • 10
  • 27
4

Yes, You can define an array as constant. 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. It is possible to define constants as a resource, but it should be avoided, as it can cause unexpected results.

<?php
    // Works as of PHP 5.3.0
    const CONSTANT = 'Hello World';
    echo CONSTANT;

    // Works as of PHP 5.6.0
    const ANOTHER_CONST = CONSTANT.'; Goodbye World';
    echo ANOTHER_CONST;

    const ANIMALS = array('dog', 'cat', 'bird');
    echo ANIMALS[1]; // outputs "cat"

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

With the reference of this link

Have a happy coding.

Sahil Patel
  • 1,570
  • 2
  • 15
  • 34
4

Can even work with Associative Arrays.. for example in a class.

class Test {

    const 
        CAN = [
            "can bark", "can meow", "can fly"
        ],
        ANIMALS = [
            self::CAN[0] => "dog",
            self::CAN[1] => "cat",
            self::CAN[2] => "bird"
        ];

    static function noParameter() {
        return self::ANIMALS[self::CAN[0]];
    }

    static function withParameter($which, $animal) {
        return "who {$which}? a {$animal}.";
    }

}

echo Test::noParameter() . "s " . Test::CAN[0] . ".<br>";
echo Test::withParameter(
    array_keys(Test::ANIMALS)[2], Test::ANIMALS["can fly"]
);

// dogs can bark.
// who can fly? a bird.
Thielicious
  • 4,122
  • 2
  • 25
  • 35
4

if you're using PHP 7 & 7+, you can use fetch like this as well

define('TEAM', ['guy', 'development team']);
echo TEAM[0]; 
// output from system will be "guy"
Mohit Rathod
  • 1,057
  • 1
  • 19
  • 33
  • 1
    This is identical to [this answer](https://stackoverflow.com/a/44946921/315024) posted 2 years earlier. – Walf Aug 10 '22 at 08:26
3

Using explode and implode function we can improvise a solution :

$array = array('lastname', 'email', 'phone');
define('DEFAULT_ROLES', implode (',' , $array));
echo explode(',' ,DEFAULT_ROLES ) [1]; 

This will echo email.

If you want it to optimize it more you can define 2 functions to do the repetitive things for you like this :

//function to define constant
function custom_define ($const , $array) {
    define($const, implode (',' , $array));
}

//function to access constant  
function return_by_index ($index,$const = DEFAULT_ROLES) {
            $explodedResult = explode(',' ,$const ) [$index];
    if (isset ($explodedResult))
        return explode(',' ,$const ) [$index] ;
}

Hope that helps . Happy coding .

MD. Sahib Bin Mahboob
  • 20,246
  • 2
  • 23
  • 45
3

Doing some sort of ser/deser or encode/decode trick seems ugly and requires you to remember what exactly you did when you are trying to use the constant. I think the class private static variable with accessor is a decent solution, but I'll do you one better. Just have a public static getter method that returns the definition of the constant array. This requires a minimum of extra code and the array definition cannot be accidentally modified.

class UserRoles {
    public static function getDefaultRoles() {
        return array('guy', 'development team');
    }
}

initMyRoles( UserRoles::getDefaultRoles() );

If you want to really make it look like a defined constant you could give it an all caps name, but then it would be confusing to remember to add the '()' parentheses after the name.

class UserRoles {
    public static function DEFAULT_ROLES() { return array('guy', 'development team'); }
}

//but, then the extra () looks weird...
initMyRoles( UserRoles::DEFAULT_ROLES() );

I suppose you could make the method global to be closer to the define() functionality you were asking for, but you really should scope the constant name anyhow and avoid globals.

Daniel Skarbek
  • 554
  • 4
  • 14
3

You can define like this

define('GENERIC_DOMAIN',json_encode(array(
    'gmail.com','gmail.co.in','yahoo.com'
)));

$domains = json_decode(GENERIC_DOMAIN);
var_dump($domains);
Fawwad
  • 131
  • 1
  • 5
1

Constants can only contain scalar values, I suggest you store the serialization (or JSON encoded representation) of the array.

Alix Axel
  • 151,645
  • 95
  • 393
  • 500
1

If you are looking this from 2009, and you don't like AbstractSingletonFactoryGenerators, here are a few other options.

Remember, arrays are "copied" when assigned, or in this case, returned, so you are practically getting the same array every time. (See copy-on-write behaviour of arrays in PHP.)

function FRUITS_ARRAY(){
  return array('chicken', 'mushroom', 'dirt');
}

function FRUITS_ARRAY(){
  static $array = array('chicken', 'mushroom', 'dirt');
  return $array;
}

function WHAT_ANIMAL( $key ){
  static $array = (
    'Merrick' => 'Elephant',
    'Sprague' => 'Skeleton',
    'Shaun'   => 'Sheep',
  );
  return $array[ $key ];
}

function ANIMAL( $key = null ){
  static $array = (
    'Merrick' => 'Elephant',
    'Sprague' => 'Skeleton',
    'Shaun'   => 'Sheep',
  );
  return $key !== null ? $array[ $key ] : $array;
}
biziclop
  • 14,466
  • 3
  • 49
  • 65
  • We've been able to define arrays as constants for many years now, I don't think there's a lot of value to obtuse workarounds anymore. – miken32 Nov 28 '18 at 21:47
  • 1
    @miken32 while true, the provided solution is interesting, was not supplied by anyone else, and can be conceptually applied to other languages as needed (add it to your tool box) – puiu Feb 26 '19 at 18:30
0

Warning if you use the spl_autoload_register(..) function and you define constants with arrays, the class registration order is in alphabetical order. I didn't get my constant containing an array because I declared it in class B and wanted to use it in my class A, I thought constants were global no matter where they are declared, but it is wrong ! The order of the files in which the constants are initialized is important. Hoping to have helped.