解析基本语法的解决方法

时间:2010-04-20 01:12:14

标签: php class variables arguments bit-manipulation

我希望有一个类属性,允许表达式发生在等号的右侧。所有版本的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 个答案:

答案 0 :(得分:2)

在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 :(得分:1)

PHP类属性可以 在其声明中有一个表达式。

  

[...]此声明可能包含初始化,但此初始化必须是常量值 - 也就是说,它必须能够在编译时进行评估,并且必须不依赖于运行时信息为了进行评估。 [...]

来源:PHP Manual: Properties

以下代码可以正常工作,因为它的信息可以在编译时确定,并且不需要编译器查看其他任何地方,任何数学或字符串函数都可以获取信息。

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&amp; Static关键字

声明这些属性后,其值无法更改。

const

  

[...]常量与正常变量的不同之处在于您不使用$符号来声明或使用它们。

     

必须是常量表达式,而不是(例如)变量,属性,数学运算的结果或函数调用。

     

接口也可以有常量。

来源:PHP Manual: Class Constants

static

  

[...]将类属性或方法声明为静态使得它们可以访问而无需实例化类。声明为static的属性无法使用实例化的类对象访问(尽管静态方法可以)。

来源:PHP Manual: Static Keyword

只要您引用类名,就可以在类之外使用

Static

答案 2 :(得分:0)

我认为你的问题只与你在那里的所有var有关。它们应该全部由const取代。在PHP 4中需要var来声明成员变量,但在PHP 5中会导致错误。您应该使用PHP {5}中的constpublic等。

答案 3 :(得分:0)

PHP能够(1 << 0)问题只是因为您在使用var时使用的是const。此外,执行self::VARIABLE是针对静态变量的,我认为它应该是self::$variable(除非您将它们定义为const