This is not just about Smarty, but I guess most template engines that have variables assigned. It’s more a theoretical question, than a practical. I have no use case.
What happens in PHP when you assign a big array $a to another variable $b? PHP copies the array? Maybe, just maybe, internally it creates a pointer. Then what happens when you alter $a slightly? $b shouldn’t be changed, because no & was used to create $b. Did PHP just double the memory usage??
More specifically: What happens when you assign a big array from you Controller ($a) to your template engine ($tpl->vars['a']) and to use in the view (extract to $a)? Did PHP’s memory just triple??
Now what happens if I assign all my variables by reference? I’m cool with my view being able to alter the array back into the Controller (I won’t be coming back there anyway). It’s also fine if the variable changes within the templat engine ($tpl->vars['a']).
Is assigning all vars by reference better for memory? Better for performance? If so: any chances of strange, unwanted side effects?
Because people like code and not stories:
// copies
$a = array( ... );
$tpl->assign('a', $a); // creates a copy (?) in $tpl->vars['a']
// pointer / by ref
$a = array( ... );
$tpl->assign_by_ref('a', $a); // creates a pointer in $tpl->vars['a'] because:
function assign_by_ref( $name, &$var ) {
$this->vars[$name] = $var; // voila pointer?
}
I’m pretty sure PHP doesn’t mind big arrays and copies and clones, but performance and memory wise: which’s ‘better’?
edit
For objects, all of this doesn’t matter. Objects are always, automatically assigned by reference. And since objects are hot, maybe this is an outdated question, but I am very curious.
UPDATE
So PHP uses copy on write… Love it. And objects are always pointers. What happens when you:
$a = new BigObject;
$b = $a; // pointer, right?
$b->updateSomethingInternally(); // $b is now changed > what about $a?
Did this trigger the copy-on-write? Or are $a and $b still identical (like in ===)?
edit
Could I conclude that assigning by ref is really not worth it just to spare memory? PHP in itself is smart enough?
edit
Interesting visualization of copy, clone, by-ref etc: http://www.phpinsider.com/download/PHP5RefsExplained.pdf
PHP uses a concept called copy on write. I.e. if you just do a
$a = $bPHP will not copy the whole value of$bto$a. It will just create some kind of a pointer. (To be more precise both$aand$bwill point to the same zval and it’srefcountwill be increased.)Now, if either
$aor$bwere modified the value obviously can’t be shared anymore and must be copied.So, unless you aren’t modifying the array in your template code, no copying will be done.
Some further notes:
Beware of trying to optimize your code by blindly inserting references. Often they will have an effect contrary to what you expect. Example to explain why:
So the contrary to what you wanted actually happened. Instead of saving memory you are actually allocating additional. It’s often hard to judge whether adding a reference will make it better or worse because it’s often hard to trace all different variables pointing to one zval (it’s often not as easy as it looks, just have a look at the examples of the
debug_zval_dumpfunction. So, really, the only safe way to know, whether a reference is good for performance or not, is to actually profile both variants.This was just a short introduction to the topic. You can find a more in-depth analysis of the topic in a blog post by Sara Golemon with the porvoking title “You’re being lied to”.