При использовании функции PHP, которая требует обратного вызова, как мы передаем пользовательский параметр в обратный вызов? - PullRequest
1 голос
/ 01 октября 2009

Например,

http://www.php.net/manual/en/function.preg-replace-callback.php

<?php
// this text was used in 2002
// we want to get this up to date for 2003
$text = "April fools day is 04/01/2002\n";
$text.= "Last christmas was 12/24/2001\n";
// the callback function
function next_year($matches)
{
// as usual: $matches[0] is the complete match
// $matches[1] the match for the first subpattern
// enclosed in '(...)' and so on
return $matches[1].($matches[2]+1);
}
echo preg_replace_callback(
"|(\d{2}/\d{2}/)(\d{4})|",
"next_year",
$text);

?>

Если мы хотим передать пользовательский параметр в функцию обратного вызова next_year, как мы можем сделать это без использования create_function ()?

Большое спасибо всем вам.

Ответы [ 4 ]

2 голосов
/ 01 октября 2009

Я не знаю, является ли это самым простым решением, но я бы пошел для обратного вызова метода объекта, где объект несет необходимые параметры в своем состоянии:

class Callback
{
    public $parameter;

    public function handle($matches)
    {
        return $matches[1] . ($matches[2] + $this->parameter);
    }
}

$instance = new Callback();
$instance->parameter = 99;
echo preg_replace_callback("|(\d{2}/\d{2}/)(\d{4})|", array($instance, 'handle'), $text);

Второй вариант - прибегнуть к глобальным переменным:

$parameter = 99;

function next_year($matches)
{
    global $parameter;
    return $matches[1] . ($matches[2] + $parameter);
}
echo preg_replace_callback("|(\d{2}/\d{2}/)(\d{4})|", "next_year", $text);
1 голос
/ 01 октября 2009

Я взял идею С. Геригса и пошел дальше, почему бы не поместить все функциональные возможности замены в класс?

<?php
class Replacer {

    private $additional = 'X';

    private function next_year($matches)
    {
        // as usual: $matches[0] is the complete match
        // $matches[1] the match for the first subpattern
        // enclosed in '(...)' and so on
        return $this->additional . $matches[1].($matches[2]+1);
    }

    public function replace_years($text)
    {
        return preg_replace_callback( "|(\d{2}/\d{2}/)(\d{4})|", array($this, 'next_year'), $text);
    }
}


$text = "April fools day is 04/01/2002\n";
$text.= "Last christmas was 12/24/2001\n";

$Replacer = new Replacer();
echo $Replacer->replace_years($text);

И результат:

[~]> php test.php
April fools day is X04/01/2003
Last christmas was X12/24/2002
0 голосов
/ 01 октября 2009

Обратный вызов псевдотипа - это просто строка с именем функции. Таким образом, вы можете объявить функцию как любую другую функцию и использовать это имя так же, как и вы. Или вы используете create_function для объявления функции при исполнении. create_function вернет имя вновь созданной функции lambda_x. (Начиная с PHP 5.3 вы также можете использовать синтаксис анонимной функции .)

Но поскольку callback - это просто имя функции, вы можете использовать функцию, чтобы создать эту функцию на лету и вернуть имя этой новой созданной функции, например:

function shift_years($years) {
    return create_function('$matches', 'return $matches[1].($matches[2]+'.((int)$years).');');
}
$func = shift_years(123);
echo preg_replace_callback("|(\d{2}/\d{2}/)(\d{4})|", $func, $text);

Теперь shift_years создает пользовательскую функцию callback , как указано.

0 голосов
/ 01 октября 2009

Посмотрите на callback псевдотип , вы можете передать любой вариант этого в preg_replace_callback.

Вот ответ, который я дал вчера, в котором дан обзор типа: Можно ли сохранить функцию в массиве PHP?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...