views:

40

answers:

4

I want to have a class property that allow for an expression to take place on the right side of the equals sign. All versions of PHP choke on the following code, but it is written in this way to allow for easier extendibility in the future.

/* 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) seems like very basic syntax to me, and is not fathomable why PHP would not allow for such a thing. Can anyone think of a work around that would maintain readability and future expandability of the following code?

A: 

I think your problem is just with all the vars that you have in there. They should probably all be replaced by const. var was necessary in PHP 4 for declaring member variables, but causes an error in PHP 5. You should be using const, public, etc as of PHP 5 instead.

Chad Birch
I understand that statement, and I get where your coming from. I posted this code just as the most basic way to get my point across, so that it would be readable in any version of PHP. And again, `const` is not working for me, as it is throwing the same error as `var`.
Mark Tomlin
And `static` also does not work.
Mark Tomlin
A: 

PHP is able to do (1 << 0) the problem is just because you are using var when you should be using const. Also, doing self::VARIABLE is meant for static variables, and I believe it should be self::$variable (unless you define them as const

webdestroya
The same issue exists with `const`.
Mark Tomlin
And `static` also does not work.
Mark Tomlin
+1  A: 

When declaring a class constant or property in PHP you can only specify a primitive values for default values. So for instance, this class declaration won't work:

class TEST {
 const ABC = 2 * 4;
 const DEF = some_function();
 static $GHI = array(
   'key'=> 5 * 3,
 );
}

But this class declaration will:

class TEST {
 const ABC = 8;
 static $GHI = 15;
}

These rules apply to default values for class constants/properties - you can always initialize other variables with the results of an expression:

$a= array(
 'a'=> 1 * 2,
 'b'=> 2 * 2,
 'c'=> 3 * 2,
);

The reason for this class declaration behavior is as follows: expressions are like verbs. They do something. Classes are like nouns: they declare something. A declarative statement should never produce the side-effects of an action statement. Requiring primitive default values enforces this rule.

With this in mind we can refactor the original class as follows:

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')); 
pygorex1
Primitive types only huh? I feel that my would REALLY suffer from readability, or maybe I'm just being obtuse.
Mark Tomlin
A: 

PHP class property can not have an expression in it's declaration.

[...] This declaration may include an initialization, but this initialization must be a constant value--that is, it must be able to be evaluated at compile time and must not depend on run-time information in order to be evaluated. [...]

Source: PHP Manual: Properties

The following code would work fine, as it's information can be ascertained at compile time and does not require the compiler to look anywhere else, do any mathematical or string functions get the information.

class goodExample
{
    // These are OK.
    var $Var = 1;
    const consts = 'I\'m a Constant Property of the class goodExample.';
    static $static = array(FALSE, TRUE);
}

The following, on the other hand, is not valid as it's value must be parsed to get it's true value. This is not valid in PHP at all. The var $Var requires a mathematical operation. The const consts requires concations and a varable look up to get it's value so that's two reasons why that one would not work. Lastly, the static property $static requires two more mathematical operations to get it's true value.

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));
}

Consts & Static Keywords

Once you declare these properties, their value can not change.

const

[...] Constants differ from normal variables in that you don't use the $ symbol to declare or use them.

The value must be a constant expression, not (for example) a variable, a property, a result of a mathematical operation, or a function call.

Its also possible for interfaces to have constants.

Source: PHP Manual: Class Constants

static

[...] Declaring class properties or methods as static makes them accessible without needing an instantiation of the class. A property declared as static can not be accessed with an instantiated class object (though a static method can).

Source: PHP Manual: Static Keyword

Static can be used outside of the class, so long as you reference the class name.

Mark Tomlin