0

I have a set of variables that i need for multiple other classes. I extended a 'nice' getter function (that guesses for the var name and produces 'set'/'get' functions on the fly) to work with setters to.

Example:

In interface/parent/whatever: public $name;

In some other class that loads the 'mySetterGetter' class: $set_get = new mySetterGetter(); $set_get->get_name();.

Sadly I can't use variables in an interface and can't extend a class with multiple parent classes. Is there some other way to load these "interfaces"/extend the Set/Get class?

What I need to do is the following:

// This should be my "interface" one
class myIntegerInterface
{
public $one;
public $two;
public $three;
}
// This should be my "interface" two
class myStringInterface
{
public $foo;
public $bar;
public $whatever;
}

// This is my setter/getter class/function, that needs to extend/implement different variable classes
class mySetterGetter implements myIntegerInterface, myStringInterface
{
/**
 * Magic getter/setter method
 * Guesses for a class variable & calls/fills it or throws an exception.
 * Note: Already defined methods override this method.
 * 
 * Original @author Miles Keaton <[email protected]> 
 * on {@link http://www.php.net/manual/de/language.oop5.overloading.php#48440}
 * The function was extended to also allow 'set' tasks/calls.
 * 
 * @param (string) $val | Name of the property
 * @param unknown_type $x | arguments the function can take
 */
function __call( $val, $x )
{
    $_get = false;

    // See if we're calling a getter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == 'get_' )
    {
        $_get = true;
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == 'get' )
    {
        $_get = true;
        $varname = substr( $val, 3 );
    }

    // See if we're calling a setter method & try to guess the variable requested
    if( substr( $val, 0, 4 ) == 'set_' )
    {
        $varname = substr( $val, 4 );
    }
    elseif( substr( $val, 0, 3 ) == 'set' )
    {
        $varname = substr( $val, 3 );
    }

    if ( ! isset( $varname ) )
        return new Exception( "The method {$val} doesn't exist" );

    // Now see if that variable exists:
    foreach( $this as $class_var => $class_var_value )
    {
        if ( strtolower( $class_var ) == strtolower( $varname ) )
        {
            // GET
            if ( $_get )
            {
                return $this->class_var_value;
            }
            // SET
            else 
            {
                return $this->class_var_value = $x;
            }
        }
    }

    return false;
}
}
2
  • I wonder, why do you need that kind of magic? Why not work via the properties directly and introduce __get and __set at a later stage if you need to have custom setters and getters? Commented Jun 21, 2011 at 19:41
  • The whole construct is implemented in a much larger one. I got a loader/extender class, database handling, and much more. The whole construct currently is set to handle different scenarios (creating a page, a dragable box, a table and form fields. The only difference is a) the basic values i need and b) the constructor classes i call for the different scenarios. Therefore it would make my life a lot easier to not write set_/get_ functions for the different szenarios, but let this be handled by the __call method and only define the variables in a single encapsuled file/class. Commented Jun 21, 2011 at 20:01

1 Answer 1

2

It sounds like you want something like this:

// An abstract class that can't be instantiated but which provides a __call method to other classes that extend this one.
abstract class mySetterGetter
{
  function __call($val, $x)
  {
    $_get = false;

    // See if we're calling a getter method & try to guess the variable requested
    if( substr($val, 0, 4) == 'get_' )
    {
      $_get = true;
      $varname = substr($val, 4);
    }
    elseif( substr($val, 0, 3) == 'get' )
    {
      $_get = true;
      $varname = substr($val, 3);
    }

    // See if we're calling a setter method & try to guess the variable requested
    if( substr($val, 0, 4) == 'set_' )
      $varname = substr($val, 4);
    elseif( substr($val, 0, 3) == 'set' )
      $varname = substr($val, 3);

    if ( ! isset($varname) )
      throw new Exception("The method {$val} doesn't exist");

    // Now see if that variable exists:
    foreach( $this as $class_var => $class_var_value )
    {
      if ( strtolower($class_var) == strtolower($varname) )
      {
        // GET
        if ( $_get )
          return $this->class_var_value;
        // SET
        else
        {
          $this->class_var_value = $x[0];

          return;
        }
      }
    }

    return false;
  }
}

// myString
class myString extends mySetterGetter
{
  public $foo;
  public $bar;
  public $whatever;
}

// myInteger
class myInteger extends mySetterGetter
{
  public $one;
  public $two;
  public $three;
}

You can also "fake" inheriting by multiple classes as in this previous Stack Overflow question: Can I extend a class using more than 1 class in PHP?.

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

11 Comments

+1, I was confused by how he presented the question, but I think you're right in that this is all he needs. Of course, unfortunately, you can still run into the similar problem where you don't really want to "waste" the inheritance on something like a getter/setter class.
@konforce - I agree with you but I think given the currently available option in PHP, the only option is inheritance. Thanks for the +1.
I doubt he wants that, since he explicitly states "can't extend a class with multiple parent classes" he probably ins't looking for inheritance.
@phant0m - His example doesn't show that. He could always consider making the parent class extend the abstract getter/setter class.
@phant0m, yes, but the OP's code is nonsensical. If he is importing the same variables into a single gettersetter class (thus making it non-reusuable), then he might as well just hardcode them all and forget about extending or implementing anything.
|

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.