views:

141

answers:

2

I'm building a blog that should parse bbcode tags like this:

Input: <youtube=http://www.youtube.com/watch?v=VIDEO_ID&amp;feature=channel&amp;gt;
Output:

<object width="400" height="245">
<param name="movie" value="http://www.youtube-    nocookie.com/v/VIDEO_ID&hl=en&fs=1&rel=0&showinfo=0"></param>
<param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param>
<embed src="http://www.youtube-nocookie.com/v/VIDEO_ID&amp;hl=en&amp;fs=1&amp;rel=0&amp;showinfo=0" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="400" height="245"></embed>
</object>

My function is incredibly simple so far, because I've gotten stuck on the easiest part! Right now, I have a master process function that calls difference process functions. In this case one of them is processYouTubeVideos(). So I call it like so:

$str = eregi_replace('\<youtube=([^>]*)\>', processYouTubeVideos("\\1"), $str);

processYouTubeVideos() receives the URLs from inside the youtube tag perfectly, but for some reason, when using explode() (or split) the delimeter is never found. Even using test values like "u" or "tube"...

function processYouTubeVideos ($str) {

    $params = explode("?", $str);
    $params = explode("&", $params[1]);

    return $params[0];

}

Thanks in advance for your help!

+3  A: 

Try:

$str = preg_replace('/<youtube=([^>]*)>/e', 'processYouTubeVideos("$1")', $str);

The code that you're attempting to run won't work, because the function on the output string will be called on the target pattern rather than the output. That means that you're sending "\1" literarly to the function. Add var_dump($str); to the beginning of the function and try running your code again, and you'll see this clearly.

preg_replace has a special flag "e" that you can use to execute a function for each time a replacement is made. This works by inserting the subpattern at the marker position ($1) and then running something like eval() or create_function() on the code to execute it and retrieve the result. This then sent back to preg_replace() and the actual replacement is made.

Emil H
Well how about that! It worked. Can you explain what the difference is?
Bloudermilk
See my edit. :)
Emil H
A: 

The processYouTubeVideos("\1") function is being run before the eregi_replace.

The following does what I believe you intend:

$str = eregi_replace('\<youtube=([^>]*)\>', "\\1", $str);
$str = processYouTubeVideos($str);

It performs the replace, and then sends the resulting value to processYouTubeVideos.

Jonathan Fingland