1

I have this Deprecated warning after switching my php to 5.5.8,

Deprecated: preg_replace(): The /e modifier is deprecated, use preg_replace_callback instead in C:\wamp\www...Curly.php on line 28

This is the function in my class of Curly,

public function replace ($input, $options = array()) {

        return preg_replace("/\{{2}(([a-z\_]+\|.+)|([a-z\_]+))\}{2}/Ue",'$this->_replace("\\1",$options)',$input);
    }

so if I use preg_replace_callback instead,

return preg_replace_callback("/\{{2}(([a-z\_]+\|.+)|([a-z\_]+))\}{2}/Ue",'$this->_replace("\\1",$options)',$input);

Then I get this error,

Warning: preg_replace_callback(): Requires argument 2, '$this->_replace("\1",$options)', to be a valid callback in C:\wamp\www...Curly.php on line 28

Any ideas how can I fix this?

EDIT:

class Curly extends CoreModel
{
    // Set the property/ variable of this class
    public $constant = null;

    /**
     * Extend the parent class property.
     */ 
    public function __construct($connection){

       // Extend parent's.
       parent::__construct($connection);
       $this->constant = new Constant($connection);
    }

    /**
     * Replace the curly in an input string
     * @param string $input
     * @return string
     */
    public function replace ($input, $options = array()) {

        //return preg_replace("/\{{2}([a-z]+\|.+)\}{2}/Ue",'$this->_replace("\\1")',$input);
        //return preg_replace("/\{{2}(([a-z\_]+\|.+)|([a-z\_]+))\}{2}/Ue",'$this->_replace("\\1",$options)',$input);
        return preg_replace_callback(
            "/\{\{([a-z_]+(?:\|.+)?)\}\}/U",
            function($m) { return $this->_replace($m[1], $options); }, 
            $input
        );
    }

    /**
     * Run the replacement code on a given macro string
     * @param string $input
     * @return string
     */
    private function _replace ($input,$options) {

        // Set local vars.
        $defaults = array();

        // Call internal method to process the array.
        $array = parent::arrayMergeValues($defaults,$options);
        //print_r($array);

        // Convert array to object.
        $property = parent::arrayToObject($array);

        // type-checking comparison operator is necessary.
        if (strpos($input, '|') !== false) { 

            //VERTICAL SIGN FOUND
            list ($name,$params) = explode("|",$input);

            if (method_exists($this,$name)) {
                return $this->$name($params);
            }
            throw new Exception ("Unrecognised macro: {$name}.",500);

        } else {

            // Get the input string and request the data from constant table.
            $value = $this->constant->getRow($input)->value;

            // If there is a value returned from the contstant table.
            if($value !== null) { 

                // Return the what is returned from the the constant table.
                return $value;

            } else if(isset($property->$input)) { // If there is a customised value from the developer.

                // Return what is customised by the developer.
                return $property->$input;

            } else { // Nothing is found.

                // Return what is from the input.
                return "{{{$input}}}"; 

            }

        }   
    }

    /**
     * Replaces a YouTube curly
     * @param string $params
     * @return string
     */
    private function youtube ($params) {

        parse_str($params);

        // set defaults
        if (!isset($id)) { $id = "ykwqXuMPsoc"; }
        if (!isset($width)) { $width = 560; }
        if (!isset($height)) { $height = 315; }

        // output the final HTML
        return "<iframe width=\"{$width}\" height=\"{$height}\" src=\"http://www.youtube.com/embed/{$id}\" frameborder=\"0\" allowfullscreen></iframe>";
    }
}
hakre
  • 193,403
  • 52
  • 435
  • 836
Run
  • 54,938
  • 169
  • 450
  • 748
  • 4
    Look at the examples in the [documentation](http://uk3.php.net/preg_replace_callback) the second argument has to be a function, not a string. – Quentin Mar 22 '14 at 10:36
  • 1
    My explanation in this previous answer might also be useful: http://stackoverflow.com/questions/15454220/replace-preg-replace-e-modifier-with-preg-replace-callback/15454454#15454454 – IMSoP Mar 22 '14 at 10:41
  • In fact I think this is effectively a duplicate of that question, since the basic usage remains the same. – IMSoP Mar 22 '14 at 11:04
  • THanks IMSop, I tried that answer already, but I get error and the replacement does not happen at all. – Run Mar 22 '14 at 11:48
  • @tealou Then please show the code you wrote based on that answer, and the error you got – IMSoP Mar 22 '14 at 12:06
  • Hi IMSoP, please see my entire code in my edit above. Thanks. – Run Mar 22 '14 at 19:21

2 Answers2

4

How about:

public function replace ($input, $options = array()) {
    return preg_replace_callback(
        "/\{\{([a-z_]+(?:\|.+)?)\}\}/U",
        function($m) use($options) { return $this->_replace($m[1], $options); }, 
        $input
    );
}
Toto
  • 89,455
  • 62
  • 89
  • 125
  • I like Anonymous functions :) – bansi Mar 22 '14 at 10:47
  • Your anonymous function doesn't actually execute the replacement, it will just insert some PHP code into the middle of the string. – IMSoP Mar 22 '14 at 10:49
  • @IMSoP: Yes it will. May be I'm wrong but I guess it is what the OP wants. – Toto Mar 22 '14 at 10:52
  • The deprecated `/e` modifier makes preg_replace `eval()` its argument. See my answer to a similar question linked above (probably similar enough to consider duplicate). – IMSoP Mar 22 '14 at 10:55
  • @IMSoP: OK, I see. I've added an alternative in my answer. – Toto Mar 22 '14 at 11:08
  • There's no ambiguity in the question, the old code will execute `$this->_replace`. Your first suggestion is wrong, and wouldn't need a callback at all anyway. Your second suggestion is right, except that you've missed the _callback from the function name. – IMSoP Mar 22 '14 at 11:13
  • thanks M42 but it doesn't actually execute the replacement... :( – Run Mar 22 '14 at 11:35
  • I get this error, `preg_replace_callback(): Modifier /e cannot be used with replacement callback in...` – Run Mar 22 '14 at 11:47
  • @tealou: Remove the `/e` as in my answer. – Toto Mar 22 '14 at 12:02
  • Hi M42, I removed /e from the answer then I get a new error, `Notice: Undefined variable: options in C:\wamp\www\...Curly.php on line 33
    `
    – Run Mar 22 '14 at 19:15
  • 1
    @tealou: You have to add `use($options)` when calling the callback. See my edit. – Toto Mar 23 '14 at 08:55
-2

Otherwise with call_user_func_array:

return preg_replace_callback(
    // RegExpr
    "/\{{2}(([a-z\_]+\|.+)|([a-z\_]+))\}{2}/Ue",

    // Callback
    array($this, '_replace'),

    // Data
    $input
);
Adrian Preuss
  • 3,228
  • 1
  • 23
  • 43
  • I'm not sure what call_user_func_array has to do with anything. This code will also fail unless the _replace function is modified, as it is expecting a single string, but will be given all the matches from the regex as an array. – IMSoP Mar 22 '14 at 10:47
  • `call_user_func_array` will be called at this point. – Adrian Preuss Mar 22 '14 at 10:48
  • No, it won't. That's just the standard way of representing an object callback in PHP. The "array" in call_user_func_array refers not to the type of callback but the arguments it's given, which are pulled from an array you provide as though you had listed them as separate parameters. Nothing like that is happening here. – IMSoP Mar 22 '14 at 11:00