tags:

views:

84

answers:

6

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.

A: 

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.

powtac
that is possible
Ikke
the page you mentioned, talks about class constants, not clas members.
Ikke
+3  A: 

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.

Ivan Nevostruev
A: 

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

Ikke
A: 

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;
    }
}
?>
Allyn
Then, obviously, you use this method to validate your input and save it accordingly.
Allyn
+2  A: 

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.
Jon Benedicto
A: 

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!
}
StasM