The theme function uses the func_get_args function. In php5 this gets the arguments by reference. In php4 this gets a copy of the arguments. So if I want to pass a variable by reference to a theme function and I'm using php4... I can't, because it gets a copy of the original variable.

e.g. calling theme('my_theme_func',$variable)

and defining function theme_my_theme_func(&$passed) {

will mean that changes which are made to $passed will affect $variable in php5 but won't in php4.

Not sure what the design is supposed to be. My guess is that you don't want to be able to alter original variables in theme functions. But it seems unsatisfactory that the functions behave differently in php4 and php5.

Comments

pwolanin’s picture

Yes, I just stumbled upon the same behavior. I've been looking into the way the organic groups module themes nodes and have been perplexed by the fact that passing the node object by reference does not work as I expect.

This version works to modify the node body:

function og_view_group(&$node, $teaser = FALSE, $page = FALSE) {	
  $node=theme('og_view', &$node, $teaser, $page);
  return;
}

function theme_og_view(&$node, $teaser, $page){
  $node->body .= '<p>helllo world</p>';
  return node;
}

This version doesn't:

function og_view_group(&$node, $teaser = FALSE, $page = FALSE) {	
  theme('og_view', &$node, $teaser, $page);
  return;
}

function theme_og_view(&$node, $teaser, $page){
  $node->body .= '<p>helllo world</p>';
  return;
}

In the first case, passing in the pointer to $node is enough that all the contents of $node are present in theme_og_view() and can be modified and returned. It's very odd if different versions of PHP are so divergent. It should work. The webserver is running PHP Version 4.3.10.

Looking at the theme() function documentation: http://drupaldocs.org/api/head/function/theme
doesn't suggest anything to me.

pwolanin’s picture

some comments about this issue are posted here:

http://us3.php.net/manual/en/function.func-get-arg.php
http://us3.php.net/manual/en/function.func-get-args.php

It also seems the same value/reference problem applies to call-user-func-array():

http://us3.php.net/manual/en/function.call-user-func-array.php
http://us3.php.net/manual/en/function.call-user-func.php

It seems there may be ways around this problem, though I haven't gotten anything to work yet. At the least, I'd think this should be mentioned in the theme() function documentation.

heine’s picture

I don't think theme functions should go about and modify the data that's passed to them. IMO they should only generate output.

Crell’s picture

Status: Active » Closed (works as designed)

Agreed. If your theme function needs to modify something, then you're doing something wrong. The only reason why you'd want to then would be for performance reasons if you're passing in a particularly large data structure. It's too bad PHP doesn't have a const keyword for such things. :-)

You are correct about there being by-ref issues in PHP 4's call_user_func() family of functions. That's not a Drupal issue, though, but a PHP 4 issue. The fix is to upgrade to PHP 5, where objects are always passed by reference, period. That's one of the reasons why PHP 5 does that.

Marking this by design, since Drupal is behaving exactly as a PHP app is expected to behave under PHP 4. That the rules changed for PHP 5 is PHP's problem, not Drupal's. :-)

pwolanin’s picture

Project: Drupal core » Documentation
Component: theme system » Developer Guide
Status: Closed (works as designed) » Active

I certainly agree that it's not a Drupal problem, except that the theme function documentation should mention it. I came across this when looking at a theme function in organic groups that is called under og_nodeapi (hook_nodeapi). The API for hook_nodeapi does specify passing by reference, and so I was trying to carry this pass-by-reference down to the function that actually made a change to the node.

Crell’s picture

Is this still an issue? Sounds like it's just a docs question at this point, if it's still an issue at all...

pwolanin’s picture

Yes, this is really a documentation issue.

anschinsan’s picture

Project: Documentation » Drupal core
Version: x.y.z » 7.x-dev
Component: Developer Guide » documentation
drewish’s picture

Version: 7.x-dev » 6.x-dev

well 7.x is going going to be PHP5 only so if this needs to be fixed it needs to happen on the D6 side.

jhodgdon’s picture

Status: Active » Closed (works as designed)

I don't see what needs to be documented really. theme() doesn't say anything about passing args by reference. Maybe it should be in the Handbook somewhere, but it can't be a very good practice to modify an object in a theme() function?