Jeff Meyers
Jeff Meyers

Reputation: 144

PHP preg_replace 'e' modifier dilemma

I've been fighting with this for a few days now and it looks like I really have to ask someone else.

For the purposes of this thread, here is the problem: I am trying to manipulate a string using PHP's preg_replace and the 'e' modifier to execute a function within it. I want to change any instance of [pdf]somefilename[/pdf] to <a href="somefilename.pdf">PDF</a> size('somefilename.pdf');

So, for example maybe [pdf]somefilename[/pdf] would output a link to the file followed by (137MB).

For some reason, however, the (137MB) part is being put at the beginning of the entire string, instead of where it's supposed to be. It seems like preg_replace is evaluating everything, then going back and executing the function and just throwing the result in the beginning of the string.

So if I had Some text blah, blah. Download the document: [pdf]somefilename[/pdf] the regular expression outputs (137MB) Some text blah, blah. Download the document: [link to document] when it should output Some text blah, blah. Download the document [link to document] (137MB).

I'm lost. Google can't save me. Someone please help!

Thanks in advance, Jeff

Here's the code:

$bbcode_pdf_tag = '/\[pdf\](.*?)\[\/pdf\]/ie';
$html_pdf_tag = '"<a href=\"$1.pdf\">PDF</a>" .size("\\1.pdf")';
$decoded_data = preg_replace($bbcode_pdf_tag, $html_pdf_tag, $data);

EDIT: It's worth mentioning that size() is defined in a completely different file and this doesn't seem to happen when I use a built-in function such as strtolower(). Defining the size() function internally and using preg_replace_callback does not solve the problem.

Upvotes: 0

Views: 1488

Answers (1)

Vincent Savard
Vincent Savard

Reputation: 35947

Use preg_replace_callback instead! 'e' option can be dangerous. Example with preg_replace_callback :

preg_replace_callback('`\[pdf\]([^\[]+)\[/pdf\]`i', function ($matches) { return "<a href=\"{$matches[1]}\">PDF</a> " . filesize($matches[1]); }, $string);

You can obviously make a more elaborate function that checks if the file exists or whatever. This code uses PHP 5.3 anonymous function, so if you don't run on PHP 5.3, you have to use the older syntax.

Edit: I wrote this answer before seeing the comments and OP's edited post, so I may have missed something.

Edit2: What is your size function? It looks like it prints the value instead of returning it.

function test() {
    echo "world";
}

echo "hello " . test(); // worldhello

Upvotes: 2

Related Questions