views:

85

answers:

2

So I have a couple of arrays

$array_1 = Array('one','two','three');
$array_2 = Array('red','blue','green');

Is there a dynamic way to create the Setters and Getters for an array with single value entries?

So the class would be something like:

class xFromArray() {

}

So the above if I passed $array_1 it would generate something like this:

private $one;

setOne($x) {
   $one = $x;
}

getOne() {
   return $one;
}

if I passed $array_2 it would generate something like this:

private $red;

setRed($x) {
   $red = $x;
}

getRed() {
   return $red;
}

So I would call it somehow like this? (My best guess but doesn't seem that this would work)

$xFromArray = new xFromArray;
foreach($array_1 as $key=>$data) {
   $xFromArray->create_function(set.ucfirst($data)($data));
   echo $xFromArray->create_function(get.ucfirst($data));
}
+5  A: 

You can use __call() to invoke dynamic methods. So:

class Wrapper {
  private $properties;

  public function __construct(array $names) {
    $this->properties = array_combine(array_keys($names),
      array_fill(0, count($names), null));
  }

  public function __call($name, $args) {
    if (preg_match('!(get|set)(\w+)!', $name, $match)) {
      $prop = lcfirst($match[2]);
      if ($match[1] == 'get') {
        if (count($args) != 0) {
          throw new Exception("Method '$name' expected 0 arguments, got " . count($args));
        }
        return $properties[$prop];
      } else {
        if (count($args) != 1) {
          throw new Exception("Method '$name' expected 1 argument, got " . count($args));
        }
        $properties[$prop] = $args[0];
      }
    } else {
      throw new Exception("Unknown method $name");
    }
  }
}

Personally I wouldn't go the route of using getters and setters in PHP. Use the special methods __get() and __set() instead and treat these dynamic properties as object properties rather than adding a (most likely unnecessary) method wrapper.

Edit: to clarify, __call() is invoked when you call an method in an object that either doesn't exist or is inaccessible. So:

$wrapper = new Wrapper($array_1);
$wrapper->setOne("foo");
echo $wrapper->getOne(); // foo
$wrapper->getAbc(); // exception, property doesn't exist

__call() is used here to decipher the method name. If it fits the pattern of get or set followed by a property name (from the initial array) then it works as expected, otherwise it throws an exception. You can of course change this behaviour any way you wish.

See Overloading from the PHP manual for a more detailed explanation of these "magic" methods.

cletus
This is how I would call it: $wrapper = new Wrapper($array_1); How do I call the individual values from the array in the Set/Get wrapper?
Phill Pafford
would it be $wrapper->__call($name, 'get');
Phill Pafford
It would be as you described: for item 'one' you'd call `$wrapper->setOne('some value');` `
Wrikken
@Phil see update.
cletus
Thanks Cletus!!
Phill Pafford
+2  A: 

You can use __call() (or __set() && __get()), but they have some overhead.

Wrikken