Variable variables

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Variable variables

Post by Jonah Bron »

josh wrote:

Code: Select all

foreach($this as $variableName => $variableValue )
{
    // now what  ?
}
Wouldn't that be this?

Code: Select all

foreach ($this as &$variableValue) {
    $variableValue = 'blah blah blah';
}
I don't want to presume to know something here :?
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Variable variables

Post by josh »

That's assuming you wanted to set every public variable of the class, maybe it was protected, or maybe you didn't want to set every one. Point is, they [variable variables] have a use.... although using them is generally discouraged. Realize too, its not just variable variables - its variable function names, variable class names, in addition to variable variables. Its just a feature of the language that can be useful. It allows you to imitate object oriented design patterns on a procedural code base. I could list an infinite number of potential uses, and you could list an infinite number of ways to solve the problem without the variable variables. There's multiple ways to solve things and different solutions are useful at different times is all. So they are useful ;-)

Code: Select all

function foo() {
echo 'foo';
}

function bar() {
echo 'bar';
}

if(1==rand(1,2))
{
 $command = 'bar';
}
else
{
 $command = 'foo';
}

$command(); // sometimes says foo, sometimes says bar
Really useful for imitating the "strategy" pattern in a procedural code you are extending, just like this ^
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Variable variables

Post by Jonah Bron »

josh wrote:Realize too, its not just variable variables - its variable function names, variable class names, in addition to variable variables.
Yes. In fact, the framework I'm writing depends on that feature for dynamically loading modules. Variable functions/classes are useful.

Oh, there we go... dynamically loading variables; there's a useful case.
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Variable variables

Post by Weirdan »

mtptl11 wrote:A variable is something that changes.
Thank you, Captain Obvious.

Banned for spam.
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Variable variables

Post by alex.barylski »

That's assuming you wanted to set every public variable of the class, maybe it was protected, or maybe you didn't want to set every one. Point is, they [variable variables] have a use....
You can set protected/private variables using variable variables??? Can someone confirm that, as that may be interesting to know. It would serve as a last resort hack if required in some situations.
Realize too, its not just variable variables - its variable function names, variable class names, in addition to variable variables.
This conversation was strictly about variable variables. I had simple never found a good use for them, other than a more obscure way of setting variables or (my understanding at the time of writing) an interesting way to dynamically retreive the name of the variable - which while neat seemed utterly pointless.
Yes. In fact, the framework I'm writing depends on that feature for dynamically loading modules. Variable functions/classes are useful
That is very common, variable function names make the code more elegant, as opposed to using call_user_x() functions, IMO. But variable variables do not look pretty, in fact they look downright encryptic, almost like Pearl code. However if you can indeed set private and protected variables using them...there have been a few times I have been tempted to seek a solution such as this, but I always favored refactoring or extending the class instead, probably for the best.

Perhaps Josh uses proprietary codebase that is Zend encoded or something, in those cases this technique may come in very handy as direct access to code is not possible without reverse compiling the byte code - which is a HUGE PITA. :)

Cheers,
Alex

Cheers,
Alex
User avatar
Weirdan
Moderator
Posts: 5978
Joined: Mon Nov 03, 2003 6:13 pm
Location: Odessa, Ukraine

Re: Variable variables

Post by Weirdan »

PCSpectra wrote:
That's assuming you wanted to set every public variable of the class, maybe it was protected, or maybe you didn't want to set every one. Point is, they [variable variables] have a use....
You can set protected/private variables using variable variables??? Can someone confirm that, as that may be interesting to know. It would serve as a last resort hack if required in some situations.
You can't do that using variable variables as far as I know (you could read privates by casting the object to array in some older php versions). And there's standard and documented way to access privates via reflection: http://us2.php.net/manual/en/reflection ... ssible.php
alex.barylski
DevNet Evangelist
Posts: 6267
Joined: Tue Dec 21, 2004 5:00 pm
Location: Winnipeg

Re: Variable variables

Post by alex.barylski »

I didn't think variable variables let you access/read/write private or protected but until someone says they tried and it works or doesn't I'll remain open minded.

Reflection is the cats meow, I use it quite a bit in variouys parts of my framework, but never tried writing or reading privates or protected, simply because I'm in control of my framework that that kind of hack would scream 'bad design' :)

Cheers,
Alex
User avatar
VladSun
DevNet Master
Posts: 4313
Joined: Wed Jun 27, 2007 9:44 am
Location: Sofia, Bulgaria

Re: Variable variables

Post by VladSun »

I often use variable variables in Proxy pattern:

Code: Select all

class ReadOnlyWrapper
{
	protected $object = null;
 
	public function __construct($object)
	{
		if (!$object)
			throw new Exception('Object instance required.');
 
		$this->object = $object;
	}
 
	public function __set($property, $value)
	{
		throw new ReadOnlyException('Object oproperties have read only access');
	}
 
	public function __get($property)
	{
		if (is_object($this->object->{$property}))
			return new ReadOnlyWrapper($this->object->{$property});
		else
			return $this->object->{$property};
	}
 
	public function __call($method, $arguments)
	{
		if (substr($method, 0, 3) === 'get')
			call_user_func_array(array($this->object, $method), $arguments);
		else
			throw new ReadOnlyException('Method ['.  get_class($this->object).'->'.$method.'] called is not a read only one.');
	}
}
 
class ReadOnlyException extends Exception {}
Usage (in Controller):

Code: Select all

$user = $this->findUser(4);
$this->load->view('user/save/form', new ReadOnlyWrapper($user));
@PCSpectra
The snippet above might be in use in another post of yours - viewtopic.php?f=19&t=119235
;)
There are 10 types of people in this world, those who understand binary and those who don't
User avatar
Benjamin
Site Administrator
Posts: 6935
Joined: Sun May 19, 2002 10:24 pm

Re: Variable variables

Post by Benjamin »

:arrow: Moved to PHP - Theory and Design
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Variable variables

Post by josh »

Too lazy to try it out? Of course you can:

Code: Select all

<?php
class You_Are_Lazy
{
	protected $test;
	
	function test()
	{
		$var = 'test';
		$this->$var = 'you are lazy!';
		echo $this->$var;
	}
}

$test = new You_Are_Lazy();
$test->test();
I don't see how this comes as a surprise, really - or why it would suddenly change your views about the feature.
User avatar
Jonah Bron
DevNet Master
Posts: 2764
Joined: Thu Mar 15, 2007 6:28 pm
Location: Redding, California

Re: Variable variables

Post by Jonah Bron »

josh wrote:Too lazy to try it out? Of course you can:

Code: Select all

<?php
class You_Are_Lazy
{
	protected $test;
	
	function test()
	{
		$var = 'test';
		$this->$var = 'you are lazy!';
		echo $this->$var;
	}
}

$test = new You_Are_Lazy();
$test->test();
I don't see how this comes as a surprise, really - or why it would suddenly change your views about the feature.
A slight miscommunication. I think they meant something more like:

Code: Select all

<?php
class You_Are_Lazy
{
	protected $test = 'you are lazy!';
}

$test = new You_Are_Lazy();
$var = 'test';
echo $test->$var;
That would come as a surprise, and it would probably change their view.

(obviously).
JoeCommodore
Forum Newbie
Posts: 15
Joined: Fri Oct 01, 2010 10:16 pm

Re: Variable variables

Post by JoeCommodore »

Here is my example:

This is the type of stuff I use it for the most - reading in db fields into variables:

Code: Select all

    $things = mysql_fetch_assoc($result); 
    foreach($things as $key => $value) {
        $$key = $value;
    }
Same goes for initializing and reading in filtered POST data into variables (from a an array of POST variable names I specify)
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Variable variables

Post by John Cartwright »

JoeCommodore wrote:Here is my example:

This is the type of stuff I use it for the most - reading in db fields into variables:

Code: Select all

    $things = mysql_fetch_assoc($result); 
    foreach($things as $key => $value) {
        $$key = $value;
    }
Same goes for initializing and reading in filtered POST data into variables (from a an array of POST variable names I specify)
Reminds me of register globals. Why do we hate arrays so much!?
josh
DevNet Master
Posts: 4872
Joined: Wed Feb 11, 2004 3:23 pm
Location: Palm beach, Florida

Re: Variable variables

Post by josh »

I don't understand what variable variables and register global have in common? If you had to use a few variable a lot within a method for really complex logic, its more readable to have the variable instead of the array. And why have multiple lines of variable assignments when all you had to type was one additional '$'
User avatar
John Cartwright
Site Admin
Posts: 11470
Joined: Tue Dec 23, 2003 2:10 am
Location: Toronto
Contact:

Re: Variable variables

Post by John Cartwright »

I don't understand what variable variables and register global have in common?
My comment was directed only to the person I quoted, not the entire thread. However, it reminds me of register globals because there is no clear way to determine exactly where a particular variable came from. Especially if we are using user input to inject variables into our script, exactly as register globals would do, there is the potential for unintended behavior to occur. Similiar to the other example JoeCommodore gave (turning data columns into variables), what happens when we introduce new columns in the future ... again there is potential for unintended behavior. That doesn't go to say something bad will happen, you can of course implement them in a safe manner, but that doesn't mean it's right. We could have used register globals in a safe manner, but the potential for harmful behavior outweighs the utility of it.

Of course this isn't really a problem so much these days with Unit Testing, MVC, etc.. however, I prefer to group related variables together in an array.
If you had to use a few variable a lot within a method for really complex logic, its more readable to have the variable instead of the array. And why have multiple lines of variable assignments when all you had to type was one additional '$'
Of course it is, but that is what parameters are for.

Code: Select all

doSomething($request['foo'], $request['bar']);
function doSomething($somethingMeaningful, $importantToKnowExactlyWhatThisIs) 
{
    //blah
}
I'm not arguing there isn't a place for variable variables. However, the only times I've ever used them was when I was too green.
Post Reply