Обходной путь для основного синтаксиса не анализируется - PullRequest
2 голосов
/ 20 апреля 2010

Я хочу иметь свойство класса, которое позволяет выражению находиться справа от знака равенства. Все версии 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 не допускает такой вещи. Кто-нибудь может придумать обходной путь, который бы поддерживал читабельность и возможность расширения в будущем следующего кода?

Ответы [ 4 ]

2 голосов
/ 20 апреля 2010

При объявлении константы или свойства класса в 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')); 
1 голос
/ 21 апреля 2010

Свойство класса 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 s & Static Ключевые слова

После объявления этих свойств их значение не может измениться.

const

[...] Константы отличаются от обычных переменных тем, что вы не используете символ $ для объявления или их использования.

Значение должно быть константным выражением , а не (например) переменной, свойством, результатом математической операции или вызовом функции.

Также возможно для интерфейсов иметь константы.

Источник: Руководство по PHP: константы класса

static

[...] Объявление свойств или методов класса как статических делает их доступными без необходимости создания экземпляра класса. К свойству, объявленному как статическое, нельзя получить доступ с помощью экземпляра объекта класса (хотя статический метод может).

Источник: Руководство по PHP: статическое ключевое слово

Static можно использовать вне класса, если вы ссылаетесь на имя класса.

0 голосов
/ 20 апреля 2010

PHP может сделать (1 << 0) проблема только в том, что вы используете var, когда вы должны использовать const. Кроме того, выполнение self::VARIABLE предназначено для статических переменных, и я считаю, что это должно быть self::$variable (если вы не определите их как const

0 голосов
/ 20 апреля 2010

Я думаю, что ваша проблема только со всеми var, которые у вас есть. Вероятно, все они должны быть заменены на const. var был необходим в PHP 4 для объявления переменных-членов, но вызывает ошибку в PHP 5. Вместо PHP 5 вы должны использовать const, public и т. Д.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...