3
\$\begingroup\$

I have been reading this thread on Stack Overflow about simulating enums in PHP and it seems that the most common approach is to use class constants. My problem with that is I can't use it for type hints, so I have added a static function that checks if a value is defined as one of the constants.

class DataType
{
    const BIT = 'BIT';
    const TINYINT = 'TINYINT';
    const SMALLINT = 'SMALLINT';
    const MEDIUMINT = 'MEDIUMINT';
    const INT = 'INT';
    const INTEGER = 'INTEGER';
    const BIGINT = 'BIGINT';
    const FLOAT = 'FLOAT';
    const DECIMAL = 'DECIMAL';
    const NUMERIC = 'NUMERIC';
    const DATE = 'DATE';
    const TIME = 'TIME';
    const TIMESTAMP = 'TIMESTAMP';
    const DATETIME = 'DATETIME';
    const YEAR = 'YEAR';
    const CHAR = 'CHAR';
    const VARCHAR = 'VARCHAR';

    static public function Defines($const)
    {
        $cls = new ReflectionClass(__CLASS__);
        foreach($cls->getConstants() as $key=>$value)
        {
            if($value == $const)
            {
                return true;
            }
        }

        return false;
    }
}

Any thoughts on improving the code are welcome.

\$\endgroup\$
  • \$\begingroup\$ I'm not really sure I understand what you are trying to accomplish here... Maybe this will help? \$\endgroup\$ – mseancole Jul 2 '12 at 16:25
  • \$\begingroup\$ Thank you for the comment. The class is supposed to be used for other class property values. For example MySqlColumn::Type property should be one of the above constants. It would be ideal if I could use a type hint for MySqlColumn::Type getter method, but I think this is not possible without without having class instancess passed to it. My workaround is to use the static method (Defines) to check if a value passed to a property getter is valid, which is not ideal. \$\endgroup\$ – Anonimista Jul 3 '12 at 18:16
  • \$\begingroup\$ Alright... I think I'm beginning to understand, though I still feel like I'm holding a match in a dark room. Anyways, have you tried mysql_field_type()? This seems like it accomplishes what you are trying to do. Which, if I understand you correctly, is simply to retrieve the data type from a MySQL result. If you are trying to limit these types to the list that you provided, I think the easiest way would be to check it while fetching it and throw an error or return FALSE if not of the right type, rather than try to filter it after already being set. \$\endgroup\$ – mseancole Jul 3 '12 at 18:43
  • \$\begingroup\$ Sorry for not being clear. I have a PHP class that represents a MySql column that would help me (along with a class that represents a table) dynamically generate and execute MySql DDL statements, like CREATE TABLE, ALTER TABLE etc. One of my column class property is Type which value should be limited to one of MySql data types. Having an enum (like in JAVA or C#) would be ideal for this because if a wrong value is passed to Column::get_Type() it would simply throw an exception. But according to the SO discussion I linked in my post you can't really have enums in PHP so the above class is my... \$\endgroup\$ – Anonimista Jul 3 '12 at 18:55
  • \$\begingroup\$ ...replacement. It works but it is not ideal because I can't use it for a type hint (function get_Type(DataType $value) will not work because I don't create DataType instances, I just use class constants) This is why I added a static function DataType::Defines(), I use it in my getter to check if a value is one of the DataType constants. This works, but I'm not really happy with it, this is why I posted the code for review. Thanks. \$\endgroup\$ – Anonimista Jul 3 '12 at 18:59
2
\$\begingroup\$

Why not just pass the data type you are looking for as a second argument to get_Type() then call the Defines() or similar method inside to verify it is the correct type? You can even provide a default data type should you use one more frequently.

function get_Type( $value, $DataType = VARCHAR ) {
    if( ! $this->Defines( $DataType ) ) { return FALSE; }

    //rest of method
}

Since you only want to test a given "DataType", I'd rewrite Defines() to use in_array() rather than loop through all the constants manually. Which BTW, you don't need to declare the $key=> bit in a foreach loop unless you are actually going to use the key.

function Defines( $const ) { return in_array( $const, $this->getConstants() ); }

I wrote this non-static, don't know if it needs to be static or not, but I tend to avoid static if at all possible.

I'd also like to point out that your method names conflict with PHP functions or aren't very descriptive. With the former you run the chance of your code conflicting with something else, or confusing people as to its purpose. With the latter you just confuse people. define() is a PHP function, so Defines() is close enough that it might cause issues or become confusing. get_Type() looks too much like you are fetching the data type rather than comparing it.

I hope this answer helps, if not then I'd add those last two comments to your actual question so more people might be able to help. That's what helped me to understand what you were trying to accomplish a lot better than the original explanation. If I actually understood it. Anyways, it seems much clearer now. Good Luck!

\$\endgroup\$
  • \$\begingroup\$ Thank you for the answer. Both points taken, choosing function names and not iterating the constants array manually. I'm still learning PHP so I tend to overlook common functions. \$\endgroup\$ – Anonimista Jul 4 '12 at 17:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.