Search code examples
phpregexpreg-replacepreg-replace-callback

Call a function not create one in preg_replace_callback


I'm trying to convert my old preg_replace to preg_replace_callback but struggling quite hard. Wondering if someone could help out a bit.

My old working one:

$pattern = "/\[product\](.+?)\[\/product\]/e";
$text = "Hejsan hoppsan [product]2022|lots of text textext[/product] och sen så händer det lite blandat och så har vi [product]11245| med en jävla massa text[/product]";
echo preg_replace($pattern, "productBox('$1')", $text);

This works quite fine, as long there is no new lines after the | and before [/product].

[product]2022| like
this
dont
work[/product]

But otherwise the code works fine.

The function:

function productBox($text) {

    global $wpdb;

    $test = explode("|",$text);

    $loopProductID = $test[0];
    $desc = $test[1];

    //sql's to get information about the products

    $productHTML = '<div class="flow-item">
                        <div class="flow-product-image"><a href="'.$permalink.'"><img src="'.$thumburl.'" alt="'.$title.'" /></a></div>
                        <div class="flow-product-info">
                            <h3><a href="'.$permalink.'">'.$title.'</a></h3>
                            <div style="padding: 5px 0px 10px;">'.$desc.'</div>
                            <div class="flow-product-facts">Art.nr: '.$artnr.' - Pris: '.$prisinklmoms.' kr</div>
                        </div>
                        <div class="clear"></div>
                    </div>';

    return $productHTML;

}

I also tried to put the whole function inside the preg_replace_callback, like this:

$test = preg_replace_callback($pattern,
                function productBox($matches) {
                global $wpdb;

                $test = explode("|",$matches);

                $loopProductID = $test[0];
                $desc = $test[1];

                //sql's to get information about the products

                $productHTML = '<div class="flow-item">
                                    <div class="flow-product-image"><a href="'.$permalink.'"><img src="'.$thumburl.'" alt="'.$title.'" /></a></div>
                                    <div class="flow-product-info">
                                        <h3><a href="'.$permalink.'">'.$title.'</a></h3>
                                        <div style="padding: 5px 0px 10px;">'.$desc.'</div>
                                        <div class="flow-product-facts">Art.nr: '.$artnr.' - Pris: '.$prisinklmoms.' kr</div>
                                    </div>
                                    <div class="clear"></div>
                                </div>';

                return $productHTML;

            }
            , $text);

Returns a white page.

//sql's to get information about the products contains quite some sql's so I just took it away since it would be a quite long post and the sql is working fine.

Anyone that could help me out?

The best solution would be if I could use it without having the function made inside the preg_replace_callback since the code will be used on more places and creating the function over and over again just seems bad in case I have to change something in it. So I would rather just call the function.

Or is there a way to multi-do it perhaps? Put the whole thing inside a function and just call it like myGoodFunction($text_I_want_fixed);?

[product]productid|Text about the product to show[/product]

This is how it's made now, I've been thinking about trying to change the regex to make it like [product id="productid"]Text[/product] but thats a later fix. Just trying to figure out how to fix the preg_replace_callback.

Thanks in advance for any help!


Solution

  • You need to pass an anonymous function, not a named function:

    preg_replace_callback($pattern, function ($matches) { ... }, $text);
    //                    look ma, no name! ^
    

    Otherwise it's a syntax error.

    The alternative is the define a named function and pass it as callback:

    function productBox($matches) { ... }
    
    preg_replace_callback($pattern, 'productBox', $text);
    //           pass a callback by name ^