Intereting Posts
Кэширование PHP – быстрее ли сохранять в базе данных или создавать файл? Как удалить файлы из каталога на основе даты создания в php? Не удалось получить соединение: php_network_getaddresses: getaddrinfo не удалось: имя или услуга неизвестны Как отображать адрес электронной почты для пользователей, но скрывать от робота? Есть ли простой способ сделать это с помощью PHP, Javascript или JQuery? PHP объединяет два ассоциативных массива в один массив Как проверить, является ли символ буквой или номером? Urban Airship – отправьте PUSH на 1 конкретное устройство (маркер устройства) PHP чтение shell_exec в прямом эфире Как проверить типы файлов загруженных файлов на PHP? можно ли добавить их как общую сумму, используя этот код? Laravel 5 Seeder – несколько рядов в DB Я нарушаю любую «хорошую практику php» в следующем массиве php, который имеет дело с 3 (человеческими) языками? Простой способ подсчета гласных в строке в PHP? Преобразовать число в формат xx.xx миллионов? Как выполнить запрос XPath на DOMNode?

Динамические константы в PHP?

Есть ли способ динамически создавать константы класса? Я знаю, это звучит немного странно, но позвольте мне объяснить, что я пытаюсь сделать:

  • У меня есть класс Enum, атрибуты которого определяются статическими определениями const
  • Этот класс расширяет класс PHP SplEnum
  • Вместо того, чтобы вводить каждое из этих определений в коде, я хотел бы, чтобы статический инициализатор вышел в базу данных и вытащил перечисленные значения

Может быть, что-то вроде этого:

 class myEnum extends SplEnum { public static function init () { $myNameValuePair = DB_Functions::get_enum_list(); foreach ( $myNameValuePair as $name => $value) { $const = array ( self , $name ); $const = $value; } } } 

Я понимаю, что это на самом деле не работает, поскольку оно не устанавливает константные переменные CONST, а скорее статические. Может быть, моя идея – это волосы, а у вас есть лучшая техника. В любом случае, любой метод достижения конечной цели очень ценится.

ОБНОВИТЬ

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

  1. Сигнатуры функции ограничения . Я хочу иметь возможность запросить «набор» значений в качестве входных данных для функции. Например:

    public function do_something (ENUM_Types $ type) {}

  2. Простой и компактный . Разрешите простой и компактный синтаксис при использовании в коде. Например, с использованием констант я могу написать условное утверждение, например:

    if ($ my_var === ENUM_Types :: TypeA) {}

  3. Динамическое перечисление . Я бы хотел, чтобы это перечисление управлялось через интерфейс и хранилось в базе данных (я использую экраны администратора WordPress для этого, если кто-то заботится). Во время выполнения этот «список» следует вытащить из БД и сделать доступным для кода как перечисление (или аналогичную структуру, которая достигает целей выше).

Solutions Collecting From Web of "Динамические константы в PHP?"

Оберните значения «enum» в одноэлементном режиме и реализуйте (нестатический) магический метод __get :

 <?php class DynamicEnums { private static $singleton; private $enum_values; public static function singleton() { if (!self::$singleton) { self::$singleton = new DynamicEnums(); } return self::$singleton; } function __construct() { $this->enum_values = array( //fetch from somewhere 'one' => 'two', 'buckle' => 'my shoe!', ); } function __get($name) { return $this->enum_values[$name]; //or throw Exception? } public static function values() { return self::singleton()->enum_values; //warning... mutable! } } 

Для бонусных очков создайте функцию (non-OO), которая возвращает singleton:

 function DynamicEnums() { return DynamicEnums::singleton(); } 

Потребители «DynamicEnums» выглядели бы так:

 echo DynamicEnums::singleton()->one; echo DynamicEnums()->one; //can you feel the magic? print_r(DynamicEnums::values()); 

[edit] Больше enum-like.

В: Есть ли способ динамически создавать константы класса?

Ответ «Да», но не делайте этого 🙂

 class EnumFactory { public static function create($class, array $constants) { $declaration = ''; foreach($constants as $name => $value) { $declaration .= 'const ' . $name . ' = ' . $value . ';'; } eval("class $class { $declaration }"); } } EnumFactory::create('darkSide', array('FOO' => 1, 'BAR' => 2)); echo darkSide::FOO . ' ' . darkSide::BAR; 

Следующий вопрос…

Q: Сигнатуры функции Constrain. Я хочу иметь возможность запросить «набор» значений в качестве входных данных для функции. Например: public function do_something ( ENUM_Types $type ) {}

Согласно руководству , в этом случае $type должен быть экземпляром класса ENUM_Types . Но для константы это невозможно (они не могут содержать объекты).

Но подождите … Мы можем использовать такой трюк:

 class Enum { protected static $_constantToClassMap = array(); protected static function who() { return __CLASS__; } public static function registerConstants($constants) { $class = static::who(); foreach ($constants as $name => $value) { self::$_constantToClassMap[$class . '_' . $name] = new $class(); } } public static function __callStatic($name, $arguments) { return self::$_constantToClassMap[static::who() . '_' . $name]; } } class EnumFactory { public static function create($class, $constants) { $declaration = ''; foreach($constants as $name => $value) { $declaration .= 'const ' . $name . ' = ' . $value . ';'; } eval("class $class extends Enum { $declaration protected static function who() { return __CLASS__; } }"); $class::registerConstants($constants); } } EnumFactory::create('darkSide', array('FOO' => 1, 'BAR' => 2)); EnumFactory::create('aaa', array('FOO' => 1, 'BAR' => 2)); echo (aaa::BAR() instanceof aaa) ? 'Yes' : 'No'; // Yes echo (aaa::BAR() instanceof darkSide) ? 'Yes' : 'No'; // No 

И после этого мы можем использовать «тип намека»:

 function doSomething(darkSide $var) { echo 'Bu!'; } doSomething(darkSide::BAR()); doSomething(aaa::BAR()); 

Q: Простой и компактный. Разрешите простой и компактный синтаксис при использовании в коде. Например, с использованием констант я могу написать условный оператор, например: if ( $my_var === ENUM_Types::TypeA ) {}

Вы можете использовать значения ваших псевдо-констант в такой форме:

 if (darkSide::FOO === 1) {} 

Q: Динамическое перечисление. Я бы хотел, чтобы это перечисление управлялось через интерфейс и хранилось в базе данных (я использую экраны администратора WordPress для этого, если кто-то заботится). Во время выполнения этот «список» следует вытащить из БД и сделать доступным для кода как перечисление (или аналогичную структуру, которая достигает целей выше).

Вы можете инициализировать перечисление, передав массив в EnumFactory::create($class, $constants) :

 EnumFactory::create('darkSide', array('FOO' => 1, 'BAR' => 2)); 

Вы можете сделать что-то вроде Const = $$ constant. Тогда вы можете установить $ contant = что угодно. ИЛИ вы можете использовать защищенное свойство, так как вы хотите, чтобы он был динамическим, а константы – нет. Пример:

 class Foo { protected $test = ''; function set($bar){ $this->test = $bar; } function get($bar){ return $this->test; } } $foobar = new Foo(); $foobar->set('test'); echo $foobar->get('test'); 

Я не рекомендую, но eval () … пожалуйста, не надо.

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