猿问

无法解析基本语法的解决方法

我想要一个类属性,该表达式允许在等号的右侧进行表达式。所有版本的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不允许这样的事情是不可理解的。谁能想到可以保持以下代码的可读性和将来可扩展性的解决方法?


繁华开满天机
浏览 587回答 3
3回答

隔江千里

在PHP中声明类常量或属性时,只能为默认值指定原始值。因此,例如,该类声明将不起作用:class TEST {&nbsp;const ABC = 2 * 4;&nbsp;const DEF = some_function();&nbsp;static $GHI = array(&nbsp; &nbsp;'key'=> 5 * 3,&nbsp;);}但是该类声明将:class TEST {&nbsp;const ABC = 8;&nbsp;static $GHI = 15;}这些规则适用于类常量/属性的默认值 -您始终可以使用表达式的结果初始化其他变量:$a= array(&nbsp;'a'=> 1 * 2,&nbsp;'b'=> 2 * 2,&nbsp;'c'=> 3 * 2,);此类声明行为的原因如下:表达式就像动词。他们做某事。类就像名词:它们声明某些东西。声明性声明绝不应该产生动作声明的副作用。需要原始默认值将强制执行此规则。考虑到这一点,我们可以按以下方式重构原始类:class SDK{&nbsp; &nbsp; static protected $_types= null;&nbsp; &nbsp; static public function getType($type_name) {&nbsp; &nbsp; &nbsp; &nbsp; self::_init_types();&nbsp; &nbsp; &nbsp; &nbsp; if (array_key_exists($type_name, self::$_types)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return self::$_types[$type_name];&nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new Exception("unknown type $type_name");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; static protected function _init_types() {&nbsp; &nbsp; &nbsp; &nbsp; if (!is_array(self::$_types)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; self::$_types= array(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'STRING_NONE'=> 1 << 0,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // ... rest of the "constants" here&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'STRING_HOSTS'=> 1 << 6&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; );&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; function __construct($fString = null) {&nbsp; &nbsp; &nbsp; &nbsp; if (is_null($fString)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; $fString= self::getType('STRING_NONE') & self::getType('STRING_HOSTS');&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; var_dump($fString);&nbsp; &nbsp; }}$SDK &= new SDK(SDK::getType('STRING_HOSTS'));&nbsp;

万千封印

PHP类属性能不能在它的声明中表达。[...]该声明可以包括一个初始化,但是此初始化必须是一个常量值-也就是说,它必须能够在编译时进行评估,并且必须不依赖于运行时信息才能进行评估。[...]资料来源:PHP手册:属性以下代码可以正常工作,因为它的信息可以在编译时确定,并且不需要编译器在其他任何地方查找,执行任何数学或字符串函数来获取信息。class goodExample{&nbsp; &nbsp; // These are OK.&nbsp; &nbsp; var $Var = 1;&nbsp; &nbsp; const consts = 'I\'m a Constant Property of the class goodExample.';&nbsp; &nbsp; static $static = array(FALSE, TRUE);}另一方面,以下内容无效,因为必须解析其值才能获得其真实值。这一点在PHP中根本无效。在var $Var需要数学运算。该const consts要求concations和varable仰望得到它的价值,这样的两个原因一个是行不通的。最后,该static属性还$static需要进行两次数学运算才能获得其真实值。class badExample{&nbsp; &nbsp; // These are NOT OK.&nbsp; &nbsp; var $Var = 1 + 1;&nbsp; &nbsp; const consts = "I'm a constant property of the class " . __CLASS__ . '.';&nbsp; &nbsp; static $static = array((1 << 0), (1 << 2));}Consts和Static关键字声明这些属性后,它们的值将无法更改。const[...]常量与普通变量的不同之处在于,您不使用$符号来声明或使用它们。该值必须是一个常量表达式,而不是(例如)变量,属性,数学运算结果或函数调用。接口也可以具有常量。资料来源:PHP手册:类常量static[...]将类属性或方法声明为静态可以使它们无需类的实例化即可访问。实例化的类对象无法访问声明为static的属性(尽管可以使用static方法)。资料来源:PHP手册:静态关键字Static 可以在类外部使用,只要您引用类名称即可。

凤凰求蛊

PHP之所以能够做到(1 << 0)这一点,仅仅是因为您在使用var时应该使用const。另外,这样做self::VARIABLE是针对静态变量的,我相信应该这样做self::$variable(除非您将它们定义为const
随时随地看视频慕课网APP
我要回答