проблема с памятью preg_replace_callback()
-
22-08-2019 - |
Вопрос
у меня возникла проблема с памятью при тестировании функции поиска / замены.
Допустим, предметом поиска является:
$subject = "Я написал статью в журнал "А +".Это очень длинно и полно слов.Я хочу заменить каждый экземпляр A + в этом тексте ссылкой на страницу, посвященную A+.
";
строка, которую нужно найти :
$find='A+'; $find = preg_quote($find,'/');
обратный вызов функции замены:
function replaceCallback($match) { if (is_array($match)) { return '<a class="tag" rel="tag-definition" title="Click to know more about ' .stripslashes($match[0]) . '" href="?tag=' . $match[0]. '">' . stripslashes($match[0]) . '</a>'; } }
и этот звонок:
$result = preg_replace_callback($find, 'replaceCallback', $subject);
теперь полный найденный шаблон извлекается из базы данных.На данный момент это:
$find = '/(?![^<]+>)\b(voice recognition|test project reference|test|synesthesia|Superflux 2007|Suhjung Hur|scripts|Salvino a. Salvaggio|Professional Lighting Design Magazine|PLDChina|Nicolas Schöffer|Naziha Mestaoui|Nabi Art Center|Markos Novak|Mapping|Manuel Abendroth|liquid architecture|LAb[au] laboratory for Architecture and Urbanism|l'Arca Edizioni|l' ARCA n° 176 _ December 2002|Jérôme Decock|imagineering|hypertext|hypermedia|Game of Life|galerie Roger Tator|eversion|El Lissitzky|Bernhard Tschumi|Alexandre Plennevaux|A+)\b/s';
Этот шаблон $find затем ищется (и заменяется, если найден) в 23 столбцах в 7 таблицах mysql.
Использование предложенного preg_replace() вместо preg_replace_callback(), похоже, решило проблему с памятью, но у меня возникают новые проблемы в будущем:в теме, возвращаемой preg_replace(), отсутствует много содержимого...
Обновить:
потеря содержимого происходит из-за использования preg_quote($find,'/');Теперь это работает, за исключением...'A +', который становится 'A ' после завершения процесса.
Решение
Хорошо - теперь я понимаю, почему вы используете обратный вызов
Прежде всего, я бы изменил ваш обратный вызов на этот
function replaceCallback( $match )
{
if ( is_array( $match ) )
{
$htmlVersion = htmlspecialchars( $match[1], ENT_COMPAT, 'UTF-8' );
$urlVersion = urlencode( $match[1] );
return '<a class="tag" rel="tag-definition" title="Click to know more about ' . $htmlVersion . '" href="?tag=' . $urlVersion. '">' . $htmlVersion . '</a>';
}
return $match;
}
Команды stripslashes не принесут вам никакой пользы.
Что касается решения проблемы с памятью, вы можете разбить свой шаблон на несколько шаблонов и выполнить их в цикле.Я думаю, что ваше совпадение просто слишком большое / сложное для PHP, чтобы обработать его за один цикл вызова.
Другие советы
Я пытаюсь воспроизвести вашу ошибку, но есть ошибка синтаксического анализа, которую сначала необходимо исправить.Либо этого кода недостаточно, чтобы стать хорошим образцом, либо здесь действительно ошибка.
Во-первых, значение, которое вы храните в $find, не является шаблоном извлечения, поэтому мне пришлось добавить разделители шаблонов.
Во-вторых, ваша строка замены не включает закрывающий элемент для тегов привязки.
$subject = "
I wrote an article in the A+ magazine. It'\s very long and full of words. I want to replace every A+ instance in this text by a link to a page dedicated to A+.
";
$find='A+';
$find = preg_quote($find,'/');
function replaceCallback($match)
{
if (is_array($match)) {
return '<a class="tag" rel="tag-definition" title="Click to know more about ' .stripslashes($match[0]) . '" href="?tag=' . $match[0]. '">' . stripslashes($match[0]) . '</a>';
}
}
$result = preg_replace_callback( "/$find/", 'replaceCallback', $subject);
echo $result;
Этот код работает, но я не уверен, что это то, чего вы хотите.Кроме того, у меня есть сильное подозрение, что вам вообще не нужна функция preg_replace_callback().
Это здесь работает для меня, мне пришлось немного изменить соответствие preg, но это превращает каждый A + для меня в ссылку.Вам также не хватает </a>
в конце.
$subject = "I wrote an article in the A+ magazine. It'\s very long and full of words. I want to replace every A+ instance in this text by a link to a page dedicated to A+.";
function replaceCallback($match)
{
if (is_array($match))
{
return '<a class="tag" rel="tag-definition" title="Click to know more about ' .stripslashes($match[0]) . '" href="?tag=' . $match[0]. '">' . stripslashes($match[0]) . '</a>';
}
}
$result = preg_replace_callback("/A\+/", "replaceCallback", $subject);
echo $result;