2015-11-03 2 views
2

Я использую этот код, чтобы заменить шорткоды в CMS с ссылкой, включая изображение, но он заменяет только первый SHORTCODEнайти и заменить все вхождения строки [PHP] Шорткоды

$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; 
} 

строка содержит несколько абзацев и 2 шорткоды

[gal=36] and [gal=37] 

результат замены только первый шорткод со ссылками и изображениями, но второй шорткод отображается следующим образом: «37» только номер. Итак, как проложить все короткие коды, чтобы заменить их ссылками не только первым коротким кодом

+0

Это должно быть сделано с заменой регулярного выражения так, чтобы оно заменяло все экземпляры, а не только первые. Я вернусь немного позже и попытаюсь написать это для вас, если никто не поможет. –

+1

Я бы предложил использовать регулярное выражение для соответствия коротким кодам. Лично я бы preg_match все существующие коды, объединить их в один запрос, запустить и форматировать его в массив. Затем preg_replace_callback, чтобы заменить короткие коды на поиск массива результатов. Вы получаете два вызова шаблонов регулярных выражений, но только один запрос, который будет самой медленной частью. –

+0

'$ q = $ db-> prepare (" select * from images where Gal_ID = '$ gal' ");' warning: injection immanent. Дело не в том, что вы используете 'PDO :: prepare', вы можете как-то безопасно вставлять значения в запрос. Вы должны использовать 'SELECT * FROM images WHERE Gal_ID =: id' и' $ q-> execute ([': id' => $ gal]); ' –

ответ

1

Вот полный пример того, как я описал выше.

//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; 
} 

Я тестировал его как можно больше, но у меня нет PDO и/или ваших таблиц. Это должно сработать в значительной степени за счет замены того, что у вас есть выше.

+0

Большое вам спасибо, что я очень ценю это. –

Смежные вопросы