views:

20

answers:

3

How can I dynamically pass "items" to class function?

For example here it is a piece of some class and its function where I declare an element of object (items) as $b:

//..........
     public function __add2SomeObj($b) {    

        $namespc = $this -> __someObj();  // __someObj() returns object
        $namespc -> cats = $b;

            }
//...................

Can I pass any other name instead cats dynamically so it won't be declared as a string? i.e. something like:

    //..........
         public function __add2SomeObj($a,$b) { 

            $namespc = $this -> __someObj();  // __someObj() returns object
            $namespc -> $a = $b;

                }
    //...................
} //end of class started above

$t=new aboveClass()
$t->__add2SomeObj("cats", array(1=>"PussyCat",2=>"Scratchy"));
$t->__add2SomeObj("dogs", array(1=>"Waffy",2=>"Sharik")); // once again but dogs...

Should I define a constant or what to make this or should i declare this protected varibale as object like (object) $vaaar? Sorry I'm a little bit infamiliar with PHP OOP...

A: 

You syntax is correct:

$obj->cats = $b;

and

$a = 'cats';
$obj->$a = $b;

will do the same thing.

As for whether or not to make "cats" a constant, that's up to you. I would suggest putting the error reporting up:

error_reporting(E_ALL | E_STRICT);

That way if you accidentally put in "cast" and that's not a valid member you'll get an error thrown.

Lastly, PHP is a dynamic language. I get the feeling your background might be with more static languages. This is just something you need to get comfortable with and you need to find a balance between readability and verbosity. But whatever you do, don't try and recreate non-PHP idioms in PHP, which is a common mistake for people coming from one language to another.

cletus
+1  A: 

Yes you can do this. Read about variable variables:

Class properties may also be accessed using variable property names. The variable property name will be resolved within the scope from which the call is made. For instance, if you have an expression such as $foo->$bar, then the local scope will be examined for $bar and its value will be used as the name of the property of $foo. This is also true if $bar is an array access.


However you must be carful when dealing with arrays:

$namespc->$a[0]

will get the first element from the array that gets returned by $namespc->$a.

Whereas

$namespc->{$a[0]}

will first resolve $a[0], i.e. get the first value of the array $a, and use this as property name.

Felix Kling
Thank you! That is exactly what I looked for and it worked! Ah, that's why in some SQL statements I meet these carved brackets!
moogeek
@moogeek: Yep, it is called *complex syntax* and mostly use if you have variables in strings. You can read about it here: http://www.php.net/manual/de/language.types.string.php#language.types.string.parsing
Felix Kling
+1  A: 

What you're asking is whether you can decide at runtime which property to change inside __add2SomeObj as you in the second listing. You can, and you did is correct.

However, properties must be strings __add2SomeObj, so you should ensure that the $a parameter is a string (it will be automatically converted to a string, but this may give unexpected results if $a is an object or an array).

Second, you're allowing the caller too change an arbitrary property. This may or may not violate the encapsulation of your class depending on the class __someObj returns and on the class of __add2SomeObj. It will also create a dynamic property on the object $namespce (i.e., one that does not exist in all the objects of that class), which you may not want.

Finally, and has a consequence of the point before, __add2SomeObj may generate a fatal error. So I'd say you'd better validate the $a paramater against a set of permitted property names.

Artefacto
Thanks for the useful criticism! Of course, I would reckon for these things in production, but the examples above are just the scratch to point responsers into the plot of question!
moogeek