views:

308

answers:

4

For example,

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);

?>

If we want to pass a custom parameter to the next_year callback function, how can we do that without using create_function()?

Many thanks to you all.

+2  A: 

I don't know if it's the easiest solution, but I'd go for a object-method callback, where the object carries the required parameters in its state:

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);

Second option would be to resort to global variables:

$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);
Stefan Gehrig
using a global variable is easier, but if I put that in a class as a static variable, is this thread safe?
bobo
PHP doesn't have threads. Each PHP script runs in its own process. I would use the object instance method as in Gehrigs first example.
troelskn
Thank you so much. I will go for your object instance method.
bobo
A: 

Take a look at the callback pseudo-type, you can pass any variant of that to preg_replace_callback.

Here is an answer I gave yesterday, giving an overview of the type: Can you store a function in a PHP array?

Alex Barrett
Thank you so much for your reply.
bobo
A: 

I took S. Gehrigs idea and went a bit further with it, why not not put all the replacement functionality inside the class?

<?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);

And the result is:

[~]> php test.php
April fools day is X04/01/2003
Last christmas was X12/24/2002
Anti Veeranna
This replacer class is a great one.
bobo
A: 

The callback pseudo-type is just a string with the name of a function. So you can either declare the function like any other function and use that name just like you did. Or you use the create_function to declare a function on execution. create_function will then return the name of the newly created function lambda_x. (Since PHP 5.3 you can also use the anonymouse function syntax.)

But since callback is just the name of a function, you could use a function to create that function on the fly and return the name of that newley created function like this:

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);

Now shift_years creates your custom callback function as specified.

Gumbo
is create_function very slow that we should try to avoid it?
bobo
@bobo: Sorry, I have no data on that. But I think if you create that function just once and then use the anonymous function’s name to reference it, there will be no considerable performance loss.
Gumbo
i see, your curried function is also a nice one.
bobo