0

i have a problem when i use preg_replace_callback. i have google translator class and i want to translate all matches using it .

the code was .

$code = preg_replace_callback('/_e\(\'(.*?)\'\)/',create_function(
'$matches',
'return $translator->translate($matches);'),
$code);

when i make var dump for the var $code, i found its string"1" !!!

im sure that im using a right way for the class.

Thanks.

3
  • Need to see the translate() method. It should take only one parameter (the $matches array) and return a string. Commented Jul 30, 2011 at 21:39
  • Try adding global $translator; line, just to try... Commented Jul 30, 2011 at 22:12
  • Google Translate is going out of business this year, you shouldn't rely on it. Commented Jul 30, 2011 at 22:22

3 Answers 3

3

The problem here is scope. Something similar to this would work in JavaScript, but JS and PHP handle scope differently. To access $translator from within the anonymous function's scope, you need to declare it as a global.

<?php
$code = preg_replace_callback('/_e\(\'(.*?)\'\)/',
            create_function('$matches',
                'global $translator;'.
                'return $translator->translate($matches);'),
            $code);
?>

If you want to keep the anon as a one-liner, you can use the globals array:

<?php
$code = preg_replace_callback('/_e\(\'(.*?)\'\)/',
            create_function('$matches',
                "return $GLOBALS['translator']->translate($matches);"),
            $code);
?>

If you have PHP 5.3.0 or later, this can be alleviated with closures and use:

<?php
$code = preg_replace_callback('/_e\(\'(.*?)\'\)/',
            function($matches) use ($translator) {
                return $translator->translate($matches);
            }, $code);
?>

This is assuming that $translator was created in the same scope as $code.

Sign up to request clarification or add additional context in comments.

5 Comments

Probably best thing is to make static function so he can access with Translator::tranaslate($matches);, thus avoiding global...
This is to what I just came to.
The alternative is to use a separate callback function instead of the anonymous one.
@webarto In an OOP sense I agree. I guess, though that the class creates an instance for every cURL connection to Google Translate and (since the translate function only has one argument) specifies the to and from languages. If the class were perfect it would store the connection in a static var and let a static translate function use it.
@Programmer4Me No problem. Let us know how it goes.
1

In PHP 5.3 you could use a Closure.

<?php
$code = preg_replace_callback(
    '/_e\(\'(.*?)\'\)/',
    function($matches) use ($translator) {
        return $translator->translate($matches);
    },
    $code
);

1 Comment

And in PHP 5.4 closures will be able to use instance variables again... waiting for it.
1

Try to also pass the $translator as argument.

This could look like:

$code = preg_replace_callback('/_e\(\'(.*?)\'\)/',create_function(
'$translator,$matches',
'return $translator->translate($matches);'),
$code);

UPDATE: This code example does not work. The replace callback is invoked with only one argument while the anonymous function here expects 2 arguments. The working implementation would be:

$code = preg_replace_callback('/_e\(\'(.*?)\'\)/',create_function(
'$matches',
'global $translator; return $translator->translate($matches);'),
$code);

3 Comments

You can't pass an object as a callback. The callback must be a function.
I meant to pass the $translator as argument to the anonymous function. I will update my post to show up the code.
This does address the problem of the scope of $translator but not do so correctly. Since preg_replace_callback calls the callback it passes in the matches array first (and expects only one parameter).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.