0

I'm not really sure how to do this. I have an object and I want to set a 'type' property on it, but before doing that I want to check to make sure it's a valid type.

I was thinking this is a good time to use constants since the type names won't change (nor do I want them to be).

// this is just a sample of what I was thinking:
class Foobar
{
    const TYPE_1 = 'type 1';
    protected $_types = array(
        self::TYPE_1
    );

    public function setType($value)
    {
        // check to make sure value is a valid type
        // I'm thinking it should be able to accept
        // Foobar::TYPE_1, 'TYPE_1', or 'type 1'
        // for flexibility sake. But I don't know
    }
}

$foobar = new Foobar();
$foobar->setType('TYPE_1'); //what should go here? (best practice)

Update: I decided I didn't really need to use constants in the first place, but I've accepted an answer that I think could have gotten the job done.

6 Answers 6

3

If you have an array with all types $_types, then you can directly check if value presents in it:

class Foobar
{
    const TYPE_1 = 'type 1';
    ## declare all available types as static variable
    ## don't forget to change it when new type will be added
    protected static $_types = array(
        self::TYPE_1
    );
    public function setType($value) {
         if (in_array($value, self::$_types)) {
              // type is valid, we can use it
         }
         else {
              // type is wrong, reporting error
              throw new Exception("wrong type [".$value."]");
         }
    }
}

But it require additional work to support this array to make sure that all posible types are in array. Also it should be static. So the only copy of data will be used for all instances.

Sign up to request clarification or add additional context in comments.

Comments

2

To get the available constants in a class, you're going to have to use Reflection.

For example:

$ref = new ReflectionClass( $this );
$constants = $ref->getConstants();

// Constants now contains an associative array with the keys being
// the constant name, and the value the constant value.

Comments

0

if you would print the array. You would see the string values. So you can just check if $value is in $_values.

Comments

0

You could do something like this. The actual code is a bit of code I pulled from a production app, but you get the idea.

<?php
class Example {
    protected $SEARCH_TYPES = array('keyword', 'title', 'subject');

    function getSearchType($val) {
        if (in_array($val, $this->SEARCH_TYPES)) {
            return $val;
        }
        return FALSE;
    }
}
?>

1 Comment

Then, obviously, you use this method to validate your input and save it accordingly.
0

in_array would help you, but note that in_array has to scan all the array to find the value. So it may be something like:

class Foobar
{
const TYPE_1 = 'type 1';
protected $_types = array(
    self::TYPE_1 => true
);

public function setType($value)
{
    $value = strtolower($value); // case-insensitive
    if(isset($this->_types[$value])     // check "type 1"
        || isset($this->_types[str_replace($value, '_', ' ')]))     // check "type_1"
    {
        // OK!
    } else {
        throw new Exception("Invalid type: $value");
    }

}
}

If you also want to check Foobar::TYPE_1, use constant($value) - it allows checking class constants. Or if you want exact class name use reflection like:

list($class, $const) = explode('::', $value);
$refclass = new ReflectionClass($this);
if(get_class($this) == $class && $refclass->getConstant($value)) {
// OK!
}

Comments

-1

You can't set an array as value to a class variable!

See http://php.net/manual/en/language.oop5.constants.php

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

You could reach the the functionality by using a setter and getter method for your variable but not for a constant.

1 Comment

the page you mentioned, talks about class constants, not clas members.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.