Обходной путь для базового синтаксиса, который не анализируется
Я хочу иметь свойство класса, которое позволяет выразить выражение в правой части знака равенства. Все версии 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 не допустил бы такой вещи. Может ли кто-нибудь подумать о работе, которая будет поддерживать читаемость и будущую расширяемость следующего кода?
Ответы
Ответ 1
При объявлении константы или свойства класса в 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'));
Ответ 2
Свойство класса PHP не может иметь выражение в объявлении.
[...] Это объявление может включать инициализацию, но эта инициализация должна быть постоянным значением, то есть она должна быть способна быть оценена во время компиляции, а не должна зависеть от информации о времени выполнения для оценки. [...]
Источник: Руководство PHP: Свойства
Следующий код будет работать нормально, поскольку информация может быть установлена во время компиляции и не требует, чтобы компилятор смотрел где-нибудь еще, какие-либо математические или строковые функции получают информацию.
class goodExample
{
// These are OK.
var $Var = 1;
const consts = 'I\'m a 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
может использоваться вне класса, если вы ссылаетесь на имя класса.
Ответ 3
Я думаю, что ваша проблема только со всеми var
, которые у вас есть. Вероятно, они должны быть заменены на const
. var
был необходим в PHP 4 для объявления переменных-членов, но вызывает ошибку в PHP 5. Вместо этого вы должны использовать const
, public
и т.д. вместо PHP 5.
Ответ 4
PHP может выполнить (1 << 0)
, проблема только в том, что вы используете var
, когда вы должны использовать const
. Кроме того, выполнение self::VARIABLE
предназначено для статических переменных, и я считаю, что это должно быть self::$variable
(если вы не определяете их как const