Preg replace image src using callback

1.4k views Asked by At

I have an article with HTML tags. It's a long article with 3/5 images. Now I want to update every image src attributes. Example:

Image html tag looks like:

<img class="aligncenter" style="display: block;margin-left:auto;margin-right:auto;" src="http://img.zszywka.com/0/0269/w_0980/moj-swiat/muza-2013-najnowsze-eska-hity-2013-.jpg" width="642" />

I want to take this URL, make some changes and next update src. Then go to next image and do it again (so script must change all images src)

Final img tag looks like:

<img class="aligncenter" style="display: block;margin-left:auto;margin-right:auto;" src="http://EXMAPLE.COM/0/0269/w_0980/moj-swiat/muza-2013-najnowsze-eska-hity-2013-.jpg" width="642" />

So I need to manipulate with changes. I try using preg_replace_callback but I have a problem with it:

// change image src


$finalContent = preg_replace_callback('/' . preg_quote('src="(*.?)"') . '/', 
function() use ($variable_with_changes){ return $variable_with_changes; }, $variable_with_article_content);

echo $finalContent;

This doesn't works, I don't have an idea how I can update image domain and keep path.

3

There are 3 answers

0
miken32 On BEST ANSWER

You should be parsing HTML as HTML, not using regular expressions.

$doc = new DOMDocument();
$doc->loadHTML('<html><body><img class="aligncenter" style="display: block;margin-left:auto;margin-right:auto;" src="http://img.zszywka.com/0/0269/w_0980/moj-swiat/muza-2013-najnowsze-eska-hity-2013-.jpg" width="642" /></body></html>');
$images = $doc->getElementsByTagName('img');
foreach ($images as $img) {
    $url = $img->getAttribute('src');
    // do whatever you need to with $url
    $url = str_replace('img.zszywka.com', 'example.com', $url);
    $img->setAttribute('src', $url);
}
echo $doc->saveHTML();
1
chris85 On

The parsing answer is better but to answer your question of why your regex/preg_replace_callback fails...

  1. preg_quote escapes all special regex characters, so don't use the on your regex. If you were passing variables or unknown characters to your regex you'd use that.

  2. *. is invalid the * is a quantifier, meaning 0 or more of the previous character/group are allowed. .* is what you wanted, it means zero or more of any character excluding new lines.

  3. You are not doing anything with your found matches, you need to pass them into the function. function($match).

  4. You never make a swap of domain names in your function. You can use str_replace for that.

PHP Example:

$variable_with_article_content = '<img class="aligncenter" style="display: block;margin-left:auto;margin-right:auto;" src="http://img.zszywka.com/0/0269/w_0980/moj-swiat/muza-2013-najnowsze-eska-hity-2013-.jpg" width="642" />';
$finalContent = preg_replace_callback('/' . 'src="(.*?)"' . '/', 
function($match) { return 'src="' . str_replace('img.zszywka.com', 'EXMAPLE.COM', $match[1]) . '"'; }, $variable_with_article_content);

echo $finalContent;

Demo: https://eval.in/699201

Note also your regex has no requirement that you are replacing an image's domain.

0
Michak Firas On

I found solution, and works great. :)

function getURL($matches) {
  global $rootURL;
  return $matches[1] . $rootURL . "?type=image&URL=" . base64_encode($matches['2']);
}

$contents = preg_replace_callback("/(<img[^>]*src *= *[\"']?)([^\"']*)/i", getURL, $contents);

Thank's all for reply to me!