简体   繁体   中英

find and replace all occurrences of string [php shortcodes]

i'm using this code to replace shortcodes in a CMS with links including images but it replaces only the first shortcode

$string = $row['Content'];
  if(stristr($string,'[gal=')){
    $startTag = "[gal=";
    $endTag = "]";
    $pos1 = strpos($string, $startTag) + strlen($startTag);
    $pos2 = strpos($string, $endTag);
    $gal = substr($string, $pos1, $pos2-$pos1);
    $q=$db->prepare("select * from images where Gal_ID = :gal");
    $q->execute(["gal"=>$gal]);
    $imgs='';
    while($r=$q->fetch(PDO::FETCH_ASSOC)){
        $images[] = $r['Image'];
    }
    foreach($images as $val){
        $imgs .= "<a href='gallery/large/$val' class='fancybox-thumbs' rel='gallery'><img src='gallery/thumb/$val'></a>";
    }
    $result = substr_replace($string, $imgs, $pos1, $pos2-$pos1);
    $result = str_replace($startTag,'',$result);
    $result = str_replace($endTag,'',$result);
    echo $result;
 }
 else{
    echo $string;
 }

string contains some paragraphs and 2 shortcodes

[gal=36] and [gal=37]

the result is replacing only the first shortcode with links and images but the second shortcode is displayed like this: "37" just the number. So how to loop through all shortcodes to replace them with links not only the first shortcode

Here is a full example how I described above.

//get matches
if(preg_match_all('/\[gal=(\d+)\]/i', $string, $matches) > 0){
    //query for all images. You could/should bind this, but since the expression
    //matches only numbers, it is technically not possible to inject anything.
    //However best practices are going to be "always bind".
    $q=$db->prepare("select Gal_ID, Image from images where Gal_ID in (".implode(',', $matches[1]).")");
    $q->execute();

    //format the images into an array
    $images = array();
    while($r=$q->fetch(PDO::FETCH_ASSOC)){
        $images[$r['Gal_ID']][] = "<a href='gallery/large/{$r['Image']}' class='fancybox-thumbs' rel='gallery'><img src='gallery/thumb/{$r['Image']}'></a>";
    }

    //replace shortcode with images
    $result = preg_replace_callback('/\[gal=(\d+)\]/i', function($match) use ($images){
        if(isset($images[$match[1]])){
            return implode('', $images[$match[1]]);
        } else {
            return $match[0];
        }
    }, $string);

    echo $result;
}

I tested it as much as I could, but I don't have PDO and/or your tables. This should work as a pretty much drop in replacement for what you have above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM