Php 细枝函数和传递引用变量

Php 细枝函数和传递引用变量,php,function,templates,pass-by-reference,twig,Php,Function,Templates,Pass By Reference,Twig,情况如下: {% for entry in entries %} {{ action('entry_modify', entry) }} {{ entry.title }} {% endfor %} action($action,$params)方法是为某个操作注册自己的插件的某种触发器。在本例中,我调用了“entry\u modify”操作,插件用“entry”参数响应该操作,该参数是一个数组 function plugin(&$params) { $params['titl

情况如下:

{% for entry in entries %}
{{ action('entry_modify', entry) }}
{{ entry.title }}
{% endfor %}
action($action,$params)方法是为某个操作注册自己的插件的某种触发器。在本例中,我调用了“entry\u modify”操作,插件用“entry”参数响应该操作,该参数是一个数组

function plugin(&$params)
{
    $params['title'] = 'changed to ...'; 
}
但据我所知,细枝不是通过引用传递变量的,有什么方法可以做到这一点吗

我只想修改传递给action函数的变量


谢谢…

细枝函数总是通过引用传递给对象。您可以考虑使用对象而不是数组来表示每个条目。 我可能有办法解决你的问题。我正在用Twig开发一个Wordpress主题,我想通过引用传递变量并向它们添加一些数据。 我的目标是做这样的东西

{{ load_data('all_posts',foo) }}
我想执行一个名为
load\u all\u posts
的函数,并将该函数的结果分配给
foo
(作为第二个参数传递的细枝变量)。 我还希望以下方法也能起作用:

{% set foo = {'bar':'bar'} %}

{#foo is#}
array(1) {
  ["bar"]=>
  string(3) "bar"
}

{{load_data('all_posts',foo.posts)}}

{#foo is#}
array(2) {
  ["bar"]=>
  string(3) "bar"
  ["posts"]=>
  array(3) {
    [0]=>
    string(5) "post1"
    [1]=>
    string(5) "post2"
    [2]=>
    string(5) "post3"
  }
}
因为不是所有变量都通过引用传递给函数。我们不能将函数用于此目的。相反,我创建了自己的标记,并像这样使用它:

{% set foo = {'bar':'bar'} %}
{% load all_pots in foo.posts %}
要做到以下几点,我们必须做两件事:

  • 创建“加载”标记
  • 调用正确的函数并在正确的位置加载数据
创建令牌解析器: 令牌的创建很容易。我们只需要告诉twig如何使用以下类解析此令牌:

class Load_Data_TokenParser  extends Twig_TokenParser
{
    public function parse(Twig_Token $token)
    {
        $stream = $this->parser->getStream();
        $variable_array = array(); //an array where we'll store the destination variable, as it can be just foo or foo.post, or foo.bar.foo.bar.posts

        $function_name = $stream->expect(Twig_Token::NAME_TYPE)->getValue();  //here we say that we expect a name. In our case it'll be 'all_posts' (the name of the function we will execute)
        $in = $stream->expect(Twig_Token::OPERATOR_TYPE)->getValue();   //here we say that the next thing should be the operator 'in'
        while(Twig_Token::typeToEnglish($stream->getCurrent()->getType()) === 'name'){ //and with this while, we get all the variable names that are separated with '.'
            array_push($variable_array,$stream->getCurrent()->getValue());

            $stream->next();
            $new  = $stream->getCurrent();

            if(Twig_Token::typeToEnglish($new->getType()) === 'punctuation'){
                $stream->next();
            } else {
                break;
            }
        }
        //in our case $variable_array here will be ['foo','posts']

        $stream->expect(Twig_Token::BLOCK_END_TYPE);

        return new Load_Node($variable_array, $function_name, $token->getLine(), $this->getTag());
    }

    public function getTag()
    {
        return 'load';
    }
}
最后,我们返回一个新的“加载节点”,并将
$variable\u array、$function\u name
行和当前标记传递给它

加载数据 目前它仅适用于阵列。如果试图在对象内部加载数据,它会引发异常。稍后我将对其进行编辑并添加对对象的支持。 我希望这能帮助你和其他人。
祝你今天愉快:)

你想实现什么?我只想修改插件函数中的输入变量。你看过过滤器了吗?可能更适合您的问题。过滤器确实会修改变量,但真正的目的是用给定的变量回答事件。它可以修改变量,也可以不修改。
class Load_Node extends Twig_Node
{
    public function __construct($variable_array, $function_name, $line, $tag = null)
    {
        $value = new Twig_Node();
        parent::__construct(array('value'=>$value),array(
            'variable_array'=>$variable_array,
            'function_name'=>$function_name
        ),$line,$tag);
    }

    public function compile(Twig_Compiler $compiler)
    {
        $variable_access_string = '';
        $variable_array = $this->getAttribute('variable_array');
        foreach ($variable_array as $single_variable) {
            $variable_access_string.= '[\''.$single_variable.'\']';
        } //here we prepare the string that will be used to access the correct variables. In our case here $variable_access_string will be "['foo']['posts']"

        $compiler
            ->addDebugInfo($this)
            ->write('$context'.$variable_access_string.' = load_'.$this->getAttribute('function_name').'()')
            ->raw(";\n"); //and the here we call load_{function_name} and assign the result to the correct variable
    }
}