Obmerk Kronen Obmerk Kronen - 1 month ago 12
PHP Question

PHP Understanding callbacks - difference between preg_replace_callback() and preg_match_all()

I am a bit confused on the use of

preg_replace_callback()


I have a
$content
with some URLs inside .

Previously I used

$content = preg_match_all( '/(http[s]?:[^\s]*)/i', $content, $links );


foreach ($links[1] as $link ) {
// we have the link. find image , download, replace the content with image
// echo '</br>LINK : '. $link;
$url = esc_url_raw( $link );
$url_name = parse_url($url);
$url_name = $description = $url_name['host'];// get rid of http://..
$url = 'http://somescriptonsite/v1/' . urlencode($url) . '?w=' . $width ;
}

return $url;


But what I really need is to REPLACE the original URL with my parsed URL...

So I tried the preg_replace_callback:

function o99_simple_parse($content){

$content = preg_replace_callback( '/(http[s]?:[^\s]*)/i', 'o99_simple_callback', $content );


return $content;
}


and :

function o99_simple_callback($url){
// how to get the URL which is actually the match? and width ??
$url = esc_url_raw( $link );
$url_name = parse_url($url);
$url_name = $description = $url_name['host'];// get rid of http://..
$url = 'http://something' . urlencode($url) . '?w=' . $width ;
return $url; // what i really need to replace
}


I assumed that the callback will work in a way that EVERY match will call the callback (recursively ?) and get back results , thus allowing for to replace on-the-fly the URLS in $content with the parsed
$url
from
o99_simple_callbac()
.

But another question here (and especially this comment) triggered my doubts .

If the
preg_replace_callback()
actually pass the whole array of matches , then what is actually the difference between what I used previously (
preg_match_all()
in first example ) and the callback example ?

What am I missing / misunderstanding ??
What would be the correct way of replacing the URLS found in
$content
with the parsed urls ?

Answer

It does not pass all matches, but invokes the callback for each match. The callback won't receive a single string parameter, but a list of strings. $match[0] is the whole match, and $match[1] the first capture group (what's in your regex between the first parens).

So this is how your callback should look:

function o99_simple_callback($match){
    $url = $match[1];
    //$url = esc_url_raw( $link );
    $url_name = parse_url($url); 
    $url_name = $description = $url_name['host'];// get rid of http://..
    $url = 'http://something' .  urlencode($url)   . '?w=' . $width ; 
    return $url; // what i really need to replace 
}

Please also see the manual examples on preg_replace_callback