【问题标题】:Is there a way to pass another parameter in the preg_replace_callback callback function?有没有办法在 preg_replace_callback 回调函数中传递另一个参数?
【发布时间】:2011-02-10 11:30:16
【问题描述】:

嗯,伙计们,我真的希望我的英语足够好来解释我需要什么。

让我们来看看这个例子(这只是一个例子!)的代码:

class Something(){
    public function Lower($string){
        return strtolower($string);
    }
}
class Foo{
    public $something;
    public $reg;
    public $string;
    public function __construct($reg, $string, $something){
        $this->something = $something;
        $this->reg = $reg;
        $this->string = $string;
    }
    public function Replace(){
        return preg_replace_callback($this->reg, 'Foo::Bar', $this->string);
    }
    public static function Bar($matches){
        /*
        * [...]
        * do something with $matches and create the $output variable
        * [...]
        */

        /*
        * I know is really useless in this example, but i need to have an istance to an object here
        * (in this example, the Something object, but can be something else!)
        */
        return $this->something->Lower($output);
    }
}
$s = new Something();
$foo = new Foo($myregexp, $mystring, $s);
$content = $foo->Replace();

所以,php手册说要在preg_replace_callback()中使用类方法作为回调,方法必须是抽象的。

我需要在回调函数中传递一个先前初始化的对象的实例(在示例中,Something 类的实例)。

我尝试使用call_user_func(),但不起作用(因为这样我错过了matches 参数)。

有没有办法做到这一点,或者让 i 分离进程(在preg_match_all 之前执行,为每个匹配项检索替换值,然后是一个简单的preg_replace)?

编辑: 作为旁注,在汤姆·海格回答之前,我使用了这个解决方法(在示例中,这是替换方法):

$has_dynamic = preg_match_all($this->reg, $this->string, $dynamic);
if($has_dynamic){
    /*
    * The 'usefull' subset of my regexp is the third, so $dynamic[2]
    */
    foreach($dynamic[2] AS $key => $value){
        $dynamic['replaces'][$key] = $this->Bar($value);
    }
    /*
    * ..but i need to replace the complete subset, so $dynamic[0]
    */
    return str_replace($dynamic[0], $dynamic['replaces'], $this->string);
}else{
    return $this->string;
}

希望可以帮助别人。

【问题讨论】:

    标签: php preg-replace preg-match preg-match-all preg-replace-callback


    【解决方案1】:

    很难将参数传递给回调,但不是这样:

    return preg_replace_callback($this->reg, 'Foo::Bar', $this->string);
    

    您可以使Bar() 不是静态的,并使用它:

    return preg_replace_callback($this->reg, array($this, 'Bar'), $this->string);
    

    然后回调函数就能看到$this

    参见Pseudo-types and variables中的“回调”

    同样在 PHP >=5.3 中,您可以使用 anonymous functions/closures 将其他数据传递给回调函数。

    【讨论】:

    • 这行得通!我认为类方法必须是静态的,不记得我在哪里读过它..也许我根本没有,我把一些句子弄乱了。谢谢
    【解决方案2】:

    我在尝试将参数(额外参数)传递给回调时卡住了 使用 create_function() 和 call_user_function() 方法。

    仅供参考:

    <?php
    $pattern = "/([MmT][a-z]*)/";
    $string = "Mary is a naughty girl because she took all my animals.";
    $kill = "Mary";
    
    echo preg_replace_callback($pattern, function($ma) use ($kill) {
    
        foreach ($ma as $m){
            if ($m == $kill){
                return "Jenny";
            }
            return "($m)";
        }
    }, $string);
    
    echo "\n";
    ?>
    

    $ php preg_replace_callback.php 
    Jenny is a naughty girl because she took all (my) ani(mals).
    

    【讨论】:

    • 应该注意 use 关键字是在 PHP 5.4 中添加的。大多数服务器仍在运行 5.3 :(
    • @Mark use 关键字在 PHP5.3 中添加
    • 这就是解决方案。谢谢!真的需要知道这一点。
    【解决方案3】:

    是的,我使用类似这样的东西来设置和取消设置一个变化的变量,以便回调函数可以使用它,并且您不需要更新的 php 来执行它:

    foreach ($array as $key) {
        $this->_current_key = $key;
        preg_replace_callback($regex, array($this, '_callback'), $content);
        unset($this->_current_key);
    }
    

    那么在回调函数中 $this->_current_key 是可用的:

    function _callback ($match) {    
        //use the key to do something
        new_array[$key] = $match[0];
    
        //and still remove found string
        return '';
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-06-10
      • 2021-08-15
      • 1970-01-01
      • 2013-12-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-23
      • 1970-01-01
      相关资源
      最近更新 更多