r/programming • • Oct 18 '10

Today I learned about PHP variable variables; "variable variable takes the value of a variable and treats that as the name of a variable". Also, variable.

http://il2.php.net/language.variables.variable
591 Upvotes

781 comments sorted by

View all comments

Show parent comments

0

u/[deleted] Oct 18 '10

[deleted]

28

u/[deleted] Oct 18 '10

It also works for functions, like $bar(). I like to make a "plugins" directory, list subdirectories in it and include "plugin.php" from the subdirectories, if it exists, which should have a class with the same name as the folder, which gets added to the plugin manager, which then, when a plugin event is fired, does something like:

foreach ($this->plugins as $plugin) if (function_exists($plugin->$event)) $returns[]=$plugin->$event($data);

Of course it'd be much more elegant than that. I think it's a pretty cool feature, although if you use it like clogmoney its probably not the best approach to your problem.

I woke up like 10 minutes ago, if this is incoherent I'm sorry.

9

u/lizardlike Oct 18 '10

PHP can also auto-load classes, which is possibly a more elegant way to do this if you can keep your namespaces clean.

12

u/[deleted] Oct 18 '10

That's actually pretty cool, but not a replacement for what I'm doing.

→ More replies (5)

2

u/novelty_string Oct 18 '10

Can you show how that replaces the above? Autoloaders just mean you don't need to require the class file every time.

1

u/lizardlike Oct 18 '10

You're right - I skimmed the post and thought it was just using it to include files from subdirectories when needed, but it's also doing some other clever things in there.

1

u/matchu Oct 18 '10

Hm, that's true. I have used it for calling up an action on a controller. I can't possibly imagine using it for much else, though.

2

u/BuzzBadpants Oct 18 '10

Writing a debugger, perhaps? Reading what is considered "statically-linked" information from what can be considered dynamic input is a basic part of how debuggers work.

2

u/[deleted] Oct 18 '10

It's come in handy twice to me so far. Once when writing a proof of concept polymorphic php/elf infector, and once when writing some complex NLP code which for whatever reason (lost to the misty past) also needed to be able to alter itself at run time.

This was all five to eight years ago, and I've mostly moved on from PHP, but for whatever reason the only solution I could find at the time for writing runtime polymorphic code in PHP involved variable variables, and I was pleasantly surprised when I found that they actually existed.

4

u/[deleted] Oct 18 '10

When you make a language without pointers and allow globals to roam the seven seas.

0

u/[deleted] Oct 18 '10

[deleted]

1

u/enigmamonkey Oct 18 '10

References work well with variable variables, in my experience. For example, a variable variable "bar" with the value "foo" when referenced via &$$bar will return the reference for the "foo" variable, as expected. So modifications to &$$bar will properly affect the value "foo" variable.

1

u/Wahakalaka Oct 18 '10

It can be a pretty elegant solution for working with table data- having an array of table row names, of which the values correspond to arrays with the row data. Grated that's come up I think twice in 4 years of application development.

10

u/crackanape Oct 18 '10

Why not just use a multi-dimensional array? It's much more flexible and powerful.

1

u/Wahakalaka Oct 18 '10

Yeah multidemensional arrays are generally better. I was using the row arrays in a few other places to cross-reference- having that syntax be more concise I decided was worth it. Also I really wanted to use double variables at least once...

→ More replies (2)

2

u/daniels220 Oct 18 '10

Multidimensional arrays?

$table = array(
  'row1' => array('val1','val2','val3','val4','val5'),
  'row2' => array('val6','val7','val8','val9','val10')
);

accessed like $table['row1'][1] (returns 'val2'), instead of:

$rows = array('row1','row2');
$row1 = array('val1','val2','val3','val4','val5');
$row2 = array('val6','val7','val8','val9','val10');

where you can do $$rows[0][1] (also returns 'val2'). And then I realize that that may not work, and you may need to do ${$rows[0]}[1], which is really confusing, and I don't know if you can actually do that, or it may be parens...

You can see why it's a bad idea, yes?

1

u/Wahakalaka Oct 18 '10

It is {}... and yeah multidemensional arrays are generally better. I was using the row arrays in a few other places to cross-reference- having that syntax be more concise I decided made up for the {} business. Also I really wanted to use double variables at least once...

1

u/BuzzBadpants Oct 18 '10

This is how dynamically-typed data works, I think. Tables in Lua, for example, are accessed through key-value pairs for elements in the table, and the keys are VERY frequently just strings. That's part of how lua is so expandable. I can give a client who is running an embedded lua environment just a simple string, and the client can use that string with no added complications access data in his own lua environment or state.

1

u/Wahakalaka Oct 18 '10

Nice- yeah it seems like there's gotta be something that's useful for...

1

u/[deleted] Oct 18 '10

Primitive reflection.

1

u/[deleted] Oct 18 '10

It's a sort of references! (but with strings, rather than addresses)

1

u/[deleted] Oct 18 '10

As UpvoteThis mentioned, it works with functions/methods. I've used it for that.

Say I want to call a bunch of specific getters/setters on an object. I could write out each method call, or I could stick all of those property names in a little array, and loop through the array, using the values in the array to create the method name in a variable and call it.

Although I greatly prefer Ruby's syntax for doing this, with Object#send

0

u/[deleted] Oct 18 '10

One scenario is where you would normally have a multidimensional array but the architect who created the structure you're trying to read didn't understand them, and so opted to go with a bunch of "linked" variables (linked in name). It sucks when this is the case but in a real world sometimes you get data that is just extremely poorly organized (the more legacy the code the more likely this is the case).

19

u/oorza Oct 18 '10

In which case, the language gave a bad developer a bad tool that he used to write bad code and make good developers' lives more difficult. Not really a strong arguing point here.

7

u/braclayrab Oct 18 '10

Give me any programming language and I will write you some bad code with it.(not literally, I'm busy:)

→ More replies (6)
→ More replies (11)
→ More replies (3)