PHP константы, содержащие массивы?

325

Это не удалось:

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

По-видимому, константы не могут содержать массивы. Каков наилучший способ обойти это?

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

//...

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

Это кажется ненужным усилием.

  • 15
    PHP 5.6 поддерживает постоянные массивы, см. Мой ответ ниже.
  • 1
    Когда вам нужно использовать массив в качестве константы, вы пытаетесь сделать перечисление? Если это так, то используйте SplEnum: php.net/manual/en/class.splenum.php
Показать ещё 1 комментарий
Теги:
arrays
constants
scalar

19 ответов

472
Лучший ответ

ПРИМЕЧАНИЕ. Хотя это и есть принятый ответ, стоит отметить, что в PHP 5.6+ вы можете иметь константные массивы - см. ответ Андреа Фаулдс ниже.

Вы также можете сериализовать свой массив, а затем поместить его в константу:

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

# use it
$my_fruits = unserialize (FRUITS);
  • 40
    Просто хочу сказать, что я люблю это решение :)
  • 16
    Ницца. Но плохой момент в том, что вы не можете определить константу класса таким образом.
Показать ещё 15 комментариев
627

С PHP 5.6 вы можете объявить константу массива с помощью const:

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

Также работает короткий синтаксис, как и следовало ожидать:

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

Если у вас есть PHP 7, вы можете, наконец, использовать define(), как вы вначале пытались:

<?php
define('DEFAULT_ROLES', array('guy', 'development team'));
  • 31
    Это должно быть поддержано, поскольку все другие ответы устарели или просто написаны дезинформированными пользователями.
  • 0
    Это единственный синтаксис? Вы можете использовать старую функцию определения? define ('ARRAY_CONSTANT', массив ('item1', 'item2', 'item3'));
Показать ещё 7 комментариев
129

Вы можете сохранить их как статические переменные класса:

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

Если вам не нравится идея о том, что массив может быть изменен другими, геттер может помочь:

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

ИЗМЕНИТЬ

Начиная с PHP5.4, возможно даже получить доступ к значениям массива без необходимости в промежуточных переменных, т.е. работает следующее:

$x = Constants::getArray()['index'];
  • 1
    +1. Я собираюсь const AtomicValue =42; public static $fooArray = ('how','di') это годами: const AtomicValue =42; public static $fooArray = ('how','di')
  • 9
    Хотя мне кажется смешным, что мы не можем создавать неизменяемые массивы в php, это обеспечивает достойный обходной путь.
Показать ещё 2 комментария
38

Если вы используете PHP 5.6 или выше, используйте ответ Андреа Фаулдс

Я использую его вот так. Надеюсь, это поможет другим.

config.php

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

В файле, где мне нужны константы.

require('config.php');
print_r(app::config('app_id'));
  • 0
    Я сделал то же самое, что и ты. Так что искал оптимизацию производительности, хорошо это или что-то еще, если лучше.
  • 0
    Я согласен с этим решением. Как это просто и легко понять ...
12

Это то, что я использую. Это похоже на пример, предоставленный soulmerge, но таким образом вы можете получить полный массив или просто одно значение в массиве.

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

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

Используйте его следующим образом:

Constants::getArray(); // Full array
// OR 
Constants::getArray(1); // Value of 1 which is 'orange'
8

Вы можете сохранить его как строку JSON в константе. С точки зрения приложения, JSON может быть полезен и в других случаях.

define ("FRUITS", json_encode(array ("apple", "cherry", "banana")));    
$fruits = json_decode (FRUITS);    
var_dump($fruits);
  • 0
    Это именно то, о чем я думал. Разве это не законно хороший ответ?
  • 0
    Это действительно хорошо работает с AngularJS, потому что он использует JSON. Я чувствую, что это намного лучше, чем ответ сериализации, но есть ли причина, почему сериализация лучше? Может быть, это быстрее?
Показать ещё 1 комментарий
3

Начиная с PHP 5.6, вы можете определить постоянные массивы с помощью ключевого слова const, как показано ниже

const DEFAULT_ROLES = ['test', 'development', 'team'];

и доступны различные элементы, как показано ниже:

echo DEFAULT_ROLES[1]; 
....

Начиная с PHP 7, постоянные массивы можно определить с помощью define, как показано ниже:

define('DEFAULT_ROLES', [
    'test',
    'development',
    'team'
]);

и к другим элементам можно обращаться так же, как и раньше.

3

Я знаю это немного старый вопрос, но вот мое решение:

<?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;

Я определил его, потому что мне нужно было хранить объекты и массивы в константах, поэтому я установил также runkit для php, чтобы я мог сделать переменную $const сверхглобальной.

Вы можете использовать его как $const->define("my_constant",array("my","values")); или просто $const->my_constant = array("my","values");

Чтобы получить значение, просто вызовите $const->my_constant;

  • 0
    Ух ты, я не ожидал такого пути ... Я даже не знал о __get и __set ... Я должен сказать, что этот метод великолепен.
  • 0
    Это так называемые магические методы, проверьте документацию php о них.
2

Да, вы можете определить массив как постоянный. Начиная с PHP 5.6 и далее, можно определить константу как скалярное выражение, а также определить константу массива. В качестве ресурса можно определить константы, но его следует избегать, так как это может вызвать неожиданные результаты.

<?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"
?>

С ссылкой эта ссылка

Иметь счастливое кодирование.

2

Вы можете определить как это

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

$domains = json_decode(GENERIC_DOMAIN);
var_dump($domains);
2

Выполнение какого-либо трюка ser/deser или encode/decode кажется уродливым и требует, чтобы вы помнили, что именно вы делали, когда пытаетесь использовать константу. Я думаю, что приватная статическая переменная класса с accessor - это достойное решение, но я сделаю вам еще лучше. Просто используйте открытый метод getter, который возвращает определение константного массива. Для этого требуется минимум дополнительного кода, и определение массива не может быть случайно изменено.

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

initMyRoles( UserRoles::getDefaultRoles() );

Если вы хотите, чтобы он выглядел как определенная константа, вы могли бы дать ему все имена колпачков, но тогда было бы странно забывать добавлять круглые скобки() после имени.

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

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

Я полагаю, вы могли бы сделать метод глобальным ближе к функции define(), которую вы запрашивали, но вы действительно должны обладать постоянным именем так или иначе и избегать глобальных привязок.

2

Используя функцию "Взрыв" и "Взрыв", мы можем импровизировать решение:

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

Это будет эхо email.

Если вы хотите, чтобы он оптимизировал его, вы можете определить 2 функции, чтобы делать повторяющиеся вещи для вас следующим образом:

//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] ;
}

Надеюсь, что это поможет. Счастливое кодирование.

  • 0
    Вы можете предотвратить взрыв два раза, выполнив: $ explodeResult = explode (',', $ const); if (isset ($ explodeResult) [$ index]) {return $ explodeResult [$ index];}
  • 0
    @ Seed да, это хороший момент. Я обновлю свой ответ соответственно
1

Константы могут содержать только скалярные значения, я предлагаю вам хранить сериализацию (или кодированное JSON представление) массива.

  • 1
    Это ничего не добавляет к принятому ответу, поэтому, возможно, его следует удалить?
  • 4
    @IanDunn: Я бы сказал, что принятый ответ не объясняет почему или что он ничего не добавляет к моему ответу, но ... Вы можете проголосовать за удаление.
Показать ещё 1 комментарий
0

Может даже работать с Ассоциативными массивами.. например, в классе.

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.
0

PHP 7 +

С PHP 7 вы можете просто использовать функцию define() для определения константного массива:

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

echo ANIMALS[1]; // outputs "cat"
0

Я согласен с eyze, константы, как правило, являются значениями одного значения, необходимыми для всей жизни вашего приложения. Вы можете подумать об использовании конфигурационного файла вместо констант для такого рода вещей.

Если вам действительно нужны постоянные массивы, вы можете использовать соглашения об именах, чтобы несколько имитировать массивы: например, DB_Name, DB_USER, DB_HOST и т.д.

-1
define('MY_ARRAY_CONSTANT_DELIMETER', '|');       
define('MY_ARRAY',implode(MY_ARRAY_CONSTANT_DELIMETER,array(1,2,3,4)));

//retrieving the array
$my_array = explode(MY_ARRAY_CONSTANT_DELIMETER, MY_ARRAY);
  • 0
    Цитата: «Очевидно, что константы не могут содержать массивы. Каков лучший способ обойти это? Define ('DEFAULT_ROLES', 'guy | development team'); // ... $ default = explode ('|', DEFAULT_ROLES); это кажется ненужным усилием. " ОП не хотел отвечать о том, как это сделать, но как проще всего хранить массивы в константе.
-2

Вы также можете взорвать массив в ряд констант. (довольно старое школьное решение). В конце концов, массив постоянный, поэтому единственной причиной, по которой вам это нужно, является глобальный, быстрый, поиск определенных ключей.

Отсюда следует:

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

Повернулся бы:

define('DEFAULT_ROLES_0', 'guy');
define('DEFAULT_ROLES_1', 'development team');

Да, там есть загрязнение пространства имен (и много префикса, чтобы предотвратить его).

-3

Это правильно, вы не можете использовать массивы для константы, только для масштабирования и нулевого значения. Идея использования массива для констант кажется мне немного отсталой.

Вместо этого я предлагаю вам определить свой собственный постоянный класс и использовать его для получения константы.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню