preg_replace_callback回调函数中是否有一种方法可以传递另一个参数?

9

大家好,我希望我的英语足够好,能够解释清楚我的需求。

让我们来看这个代码示例(仅为示例):

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参数)。

是否有一种方法可以做到这一点,或者我必须分开处理(在进行preg_match_all之前,对于每个匹配检索替换值,然后使用简单的preg_replace)?

编辑:在Tom Haigh的答案之前,我使用了这个解决方法(在示例中,这是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;
}

希望能帮助到某些人。

3个回答

14

传递参数到回调函数比较麻烦,但是可以使用以下方法替代:

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

您可以将Bar()改为非静态方法,并使用this关键字:

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

那么回调函数将能够看到$this

请参阅伪类型和变量中的'callback'

另外,在PHP> = 5.3中,您可以使用匿名函数/闭包将其他数据传递给回调函数。


这个可行!我以为类方法必须是静态的,不记得在哪里读过了..也许根本没读过,只是把一些句子搞混了。 - Strae

12

我在尝试使用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 :( - mpen
1
在PHP5.3中添加了“use”关键字。 - Wouter J
这就是解决方案。谢谢!真的很需要知道这个。 - Jamie Carl

0

是的,我使用类似这样的东西来设置和取消一个变化的变量,以便它可以在回调函数中使用,而不需要更新的 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 '';
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接