PHP константы, содержащие массивы?
@ziGi Сегодня мы столкнулись с этой проблемой, для хранения различных типов изображений, требующих определенных размеров, стало полезно хранить эти измерения в виде постоянных массивов вместо одного по ширине и одного по высоте.
19 ответов
ПРИМЕЧАНИЕ. Хотя это и есть принятый ответ, стоит отметить, что в PHP 5.6+ вы можете иметь константные массивы — см. ответ Андреа Фаулдс ниже.
Вы также можете сериализовать свой массив, а затем поместить его в константу:
# define constant, serialize array define ("FRUITS", serialize (array ("apple", "cherry", "banana"))); # use it $my_fruits = unserialize (FRUITS);
Фелипе, вы можете сделать $fruit = $my_fruits[0] . FRUITS — это строка (не массив — это результат сериализации массива), поэтому вам нужно отменить ее сериализацию, чтобы получить обратно массив.
Это было именно то, что мне нужно было передать несколько значений в объект, который определяется пользователем! IE: типы сотрудников в виде массива.
Этот код элегантный, но довольно медленный. Намного лучше использовать публичный статический метод класса, который возвращает массив.
просто отметьте здесь, что в PHP 5.6 теперь вы можете иметь константные массивы .. const fruits = [‘apple’, ‘cherry’, ‘banana’];
Это хорошая альтернатива значениям, разделенным трубами. Я думаю, что медленный вызов serialize() / unserialize() преувеличивает вклад, который он внесет в общее время выполнения скрипта.
@Loenix, это говорит о том, что вы можете создавать постоянные массивы начиная с php 5.6, но если кто-то (как я) имеет более раннюю версию php, это совершенно правильно.
@Soaku В этом случае вам следует использовать решение Рави Хирани или явную функцию, возвращающую массив, во всех случаях эта функция не рекомендуется.
@ Леникс, почему? Это реальный способ хранения массива в константе, в то время как решение RaviHirani не использует реальную константу. И это еще дольше в использовании, чем это. И как бы вы осудили что-то, что просто фрагмент?
@ Soaku, потому что это не массив, а строка, и вам придется десериализовать его каждый раз, когда вы его используете. Поэтому предпочтите функцию, возвращающую массив, который лучше подходит для представлений, и это реальное решение, похожее на константу.
@Loenix, возможно, но его решение также требует некоторого бонуса, набираемого каждый раз, когда вы его используете, даже если он не нужен. Решение Rikudou_Sennin выглядит лучше,
С PHP 5.6 вы можете объявить константу массива с помощью const :
Также работает короткий синтаксис, как и следовало ожидать:
Если у вас есть PHP 7, вы можете, наконец, использовать define() , как вы вначале пытались:
Это должно быть поддержано, поскольку все другие ответы устарели или просто написаны дезинформированными пользователями.
Это единственный синтаксис? Вы можете использовать старую функцию определения? define (‘ARRAY_CONSTANT’, массив (‘item1’, ‘item2’, ‘item3’));
@JackNicholsonn К сожалению, вы не можете использовать define() здесь, в PHP 5.6, но это было исправлено в PHP 7.0 . 🙂
@ AndreasBergström Нет, этот вопрос слишком новый. Этот вопрос был сделан в 2009 году! Этот синтаксис будет почти бесполезен для большинства пользователей в наши дни. Почти каждый имеет PHP 5.6 на своих серверах. Другие ответы прекрасно, так как они также предлагают альтернативы. Принятый ответ пока является единственным жизнеспособным способом, если вы не хотите использовать классы.
@IsmaelMiguel не уверен, что у них всех 5,6. Любой на сервере Windows только что получил драйверы сервера 5.6 sql от Microsoft около месяца назад.
почти готово! Еще 8 голосов !! :п. Хотя если бы этот ответ включал ответ PHP
Aaaarrrgh . В PHP 5.6 вы можете определить значение константы, так как функция возвращает значение, если вы используете ключевое слово define . Вы можете использовать массивы, когда определяете его с помощью const но никакая функция не возвращает значение. И нет возможности смешать это как-то. Только в php7. вздох.
@ vaso123 один из обходных путей — сделать что-то вроде: eval(«const $constname = » . var_export($somevariable) . «;»); — не уверен, что я бы порекомендовал это, хотя
@ Андреа Лол . Никогда, ни за что. eval это зло. define(serialize([. ])); Это делает работу для меня, к счастью, у меня есть только 2 массива, и эти массивы не слишком велики. Я мог бы написать вспомогательный класс для получения этих значений, я просто хочу использовать преимущества своей IDE. В следующий раз . когда мы начнем использовать PHP 7.
Вы можете сохранить их как статические переменные класса:
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. Я собираюсь const AtomicValue =42; public static $fooArray = (‘how’,’di’) это годами: const AtomicValue =42; public static $fooArray = (‘how’,’di’)
Хотя мне кажется смешным, что мы не можем создавать неизменяемые массивы в php, это обеспечивает достойный обходной путь.
Если вы часто используете константу, я бы определенно избегал вызова функций, они довольно дорогие. Статика это путь.
Это решение оказалось намного более удивительным, чем я ожидал: мне нужна была только часть значений массива, поэтому вместо простого получения массива я использовал некоторые параметры в функции. В моем случае Constants :: getRelatedIDs ($ myID) возвращает мне внутренний массив только с теми значениями, которые мне нужны (я также провожу некоторую проверку идентификатора внутри этой функции). @cseufert получение всего массива и фильтрация для каждого случая было бы намного дороже для меня .
Я использую его вот так. Надеюсь, это поможет другим.
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'));
Я сделал то же самое, что и ты. Так что искал оптимизацию производительности, хорошо это или что-то еще, если лучше.
Это то, что я использую. Это похоже на пример, предоставленный 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'
Вы можете сохранить его как строку JSON в константе. С точки зрения приложения, JSON может быть полезен и в других случаях.
define ("FRUITS", json_encode(array ("apple", "cherry", "banana"))); $fruits = json_decode (FRUITS); var_dump($fruits);
Это действительно хорошо работает с AngularJS, потому что он использует JSON. Я чувствую, что это намного лучше, чем ответ сериализации, но есть ли причина, почему сериализация лучше? Может быть, это быстрее?
Да, сериализация технически быстрее. Тем не менее, для небольших наборов, которые в основном нужны, я предпочитаю этот метод, так как он безопаснее. Когда вы десериализуете, код может быть выполнен. Даже если в этом случае это очень низкий риск, я думаю, что мы должны зарезервировать использование или не сериализовать только для крайних случаев.
Начиная с PHP 5.6, вы можете определить постоянные массивы с помощью ключевого слова const , как показано ниже
const DEFAULT_ROLES = ['test', 'development', 'team'];
и доступны различные элементы, как показано ниже:
Начиная с PHP 7, постоянные массивы можно определить с помощью define , как показано ниже:
define('DEFAULT_ROLES', [ 'test', 'development', 'team' ]);
и к другим элементам можно обращаться так же, как и раньше.
Я знаю это немного старый вопрос, но вот мое решение:
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;
Ух ты, я не ожидал такого пути . Я даже не знал о __get и __set . Я должен сказать, что этот метод великолепен.
Да, вы можете определить массив как постоянный. Начиная с PHP 5.6 и далее, можно определить константу как скалярное выражение, а также определить константу массива. В качестве ресурса можно определить константы, но его следует избегать, так как это может вызвать неожиданные результаты.
Иметь счастливое кодирование.
Вы можете определить как это
define('GENERIC_DOMAIN',json_encode(array( 'gmail.com','gmail.co.in','yahoo.com' ))); $domains = json_decode(GENERIC_DOMAIN); var_dump($domains);
Выполнение какого-либо трюка 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(), которую вы запрашивали, но вы действительно должны обладать постоянным именем так или иначе и избегать глобальных привязок.
Use reflection in PHP to get a list of constants
PHP lacks a good way of creating enumerations. The best practice is to create constants and use those as possible values. The downside is that you normaly write them hard coded multiple times.
For example you’ve got the following status options:
A nice way of getting a list without hard coding is to use reflection.
public function getStatusOptions() < $reflector = new ReflectionClass(get_class($this)); $constants = $reflector->getConstants(); $values = []; foreach($constants as $constant => $value) < $prefix = "STATUS_"; if(strpos($constant, $prefix) !==false) < $values[] = $value; >> return $values; >
Or you can abstract it even further and build a static helper function to use for all classes. When doing so you can also add options to get it as an associative array or to exclude spicific ones from the list [1] :
/** * Return array of constants for a class * * @param string $class Class name * @param null|string $prefix Prefix like e.g. "KEY_" * @param boolean $assoc Return associative array with constant name as key * @param array $exclude Array of excluding values * * @return array Assoc array of constants */ public static function getConstants($class, $prefix = null, $assoc = false, $exclude = []) < $reflector = new ReflectionClass($class); $constants = $reflector->getConstants(); $values = []; foreach($constants as $constant => $value) < if(($prefix && strpos($constant, $prefix) !==false) || $prefix === null) < if(in_array($value, $exclude)) < continue; >if($assoc) < $values[$constant] = $value; >else < $values[] = $value; >> > return $values; >
Add XDebug to unstable PHP version
My packages support the two latest minor versions of PHP. As the first alpha of PHP 8.3 was just released, I’m upgrading the packages to PHP 8.3 and dropping PHP 8.1 from them. This way I’m able to use readonly for my classes. I use XDebug in
Reduce input of functions to improve readability
One of the elements we evaluate when reading a function call are the parameters given to it. To understand what’s happening inside (not how, just what) it’s necessary to see the relevant data as part of the function call. Counterintuitiv, this sometimes means to increase the amount of parameters or
Where and how to use abstraction
Abstraction is one if the first things a developer learns when starting programming. It’s repeated again and again from «Clean Code» to every other introduction book. It’s so ingrained, that we don’t really question why. As most developers I also started to use abstraction everywhere. Abstraction as a goal in