Я хочу иметь свойство класса, которое позволяет выразить выражение в правой части знака равенства. Все версии PHP дросселируются по следующему коду, но они написаны таким образом, чтобы обеспечить более удобную расширяемость в будущем.
/* Example SDK Class */ class SDK { /* Runtime Option Flags */ // Strings # 0: Makes no change to the strings. var $STRING_NONE = (1 << 0); # 1: Removes color codes from the string. var $STRING_STRIP_COLOR = (1 << 1); # 2: Removes language codes from the string. var $STRING_STRIP_LANG = (1 << 2); # 3: Removes all formatting from the string. var $STRING_STRIP = SELF::STRING_STRIP_COLOR & SELF::STRING_STRIP_LANG; # 4: Converts color codes to HTML & UTF-8. var $STRING_HTML = (1 << 3); # 8: Converts color codes to ECMA-48 escape color codes & UTF-8. var $STRING_CONSOLE = (1 << 4); # 16: Changes player names only. var $STRING_NAMES = (1 << 5); # 32: Changes host names only. var $STRING_HOSTS = (1 << 6); function SDK($fString = SELF::STRING_HTML & SELF::STRING_NAMES & SELF_HOST) { // constructor code. } } $SDK &= new SDK(SDK::STRING_NONE);
(1 << 0)
кажется мне очень сильным синтаксисом, и не понятно, почему PHP не допустил бы такой вещи. Может ли кто-нибудь подумать о работе вокруг, которая будет поддерживать читаемость и будущую расширяемость следующего кода?
При объявлении константы или свойства класса в PHP вы можете указать только примитивные значения для значений по умолчанию. Так, например, это объявление класса не будет работать:
class TEST { const ABC = 2 * 4; const DEF = some_function(); static $GHI = array( 'key'=> 5 * 3, ); }
Но это объявление класса:
class TEST { const ABC = 8; static $GHI = 15; }
Эти правила применяются к значениям по умолчанию для констант / свойств класса – вы всегда можете инициализировать другие переменные с результатами выражения:
$a= array( 'a'=> 1 * 2, 'b'=> 2 * 2, 'c'=> 3 * 2, );
Причина этого поведения объявления класса такова: выражения похожи на глаголы. Они что-то делают . Классы похожи на существительные: они что-то объявляют . В декларативном заявлении никогда не должно возникать побочных эффектов заявления о действии. Требование примитивных значений по умолчанию принудительно применяет это правило.
Имея это в виду, мы можем реорганизовать исходный класс следующим образом:
class SDK { static protected $_types= null; static public function getType($type_name) { self::_init_types(); if (array_key_exists($type_name, self::$_types)) { return self::$_types[$type_name]; } else { throw new Exception("unknown type $type_name"); } } static protected function _init_types() { if (!is_array(self::$_types)) { self::$_types= array( 'STRING_NONE'=> 1 << 0, // ... rest of the "constants" here 'STRING_HOSTS'=> 1 << 6 ); } } function __construct($fString = null) { if (is_null($fString)) { $fString= self::getType('STRING_NONE') & self::getType('STRING_HOSTS'); } var_dump($fString); } } $SDK &= new SDK(SDK::getType('STRING_HOSTS'));
У свойства PHP-класса не может быть выражения в его объявлении.
[…] Это объявление может включать инициализацию, но эта инициализация должна быть постоянным значением, то есть она должна быть способна быть оценена во время компиляции и не должна зависеть от информации о времени выполнения для оценки . […]
Источник: Руководство PHP: Свойства
Следующий код будет работать нормально, так как информация может быть установлена во время компиляции и не требует, чтобы компилятор смотрел где-нибудь еще, какие-либо математические или строковые функции получают информацию.
class goodExample { // These are OK. var $Var = 1; const consts = 'I\'ma Constant Property of the class goodExample.'; static $static = array(FALSE, TRUE); }
С другой стороны, нижеследующее недействительно, так как его значение должно анализироваться, чтобы получить его истинное значение. Это вообще недействительно в PHP. var $Var
требует математической операции. Константа const consts
требует консигнований и переменного поиска, чтобы получить его значение, поэтому две причины, почему это не сработает. Наконец, static
свойство $static
требует еще двух математических операций, чтобы получить истинное значение.
class badExample { // These are NOT OK. var $Var = 1 + 1; const consts = "I'm a constant property of the class " . __CLASS__ . '.'; static $static = array((1 << 0), (1 << 2)); }
Const
и Static
ключевые слова После объявления этих свойств их значение не может измениться.
const
[…] Константы отличаются от обычных переменных тем, что вы не используете символ $ для объявления или использования.
Значение должно быть константным выражением , а не (например) переменной, свойством, результатом математической операции или вызовом функции.
Его также возможно, чтобы интерфейсы имели константы.
Источник: руководство PHP: константы классов
static
[…] Объявление свойств класса или методов как статических делает их доступными без необходимости создания экземпляра класса. Свойство, объявленное как статическое, не может быть доступно с помощью экземпляра объекта класса (хотя может использоваться статический метод).
Источник: Руководство PHP: статическое ключевое слово
Static
можно использовать вне класса, если вы ссылаетесь на имя класса.
Я думаю, что ваша проблема заключается только в том, что у вас есть все var
s. Вероятно, они должны быть заменены на const
. var
был необходим в PHP 4 для объявления переменных-членов, но вызывает ошибку в PHP 5. Вместо этого вы должны использовать const
, public
и т. д. вместо PHP 5.
PHP может делать (1 << 0)
проблема заключается только в том, что вы используете var
когда вы должны использовать const
. Кроме того, выполнение self::VARIABLE
предназначено для статических переменных, и я считаю, что это должна быть self::$variable
(если вы не определяете их как const