PHP функция для создания ссылок для пользователей, которые не знают HTML, приводящий к фатальной ошибке - PullRequest
0 голосов
/ 04 мая 2011

У меня проблемы с парой функций, которые позволяют пользователю создавать ссылки без предварительного знания HTML, используя набор [link] и [/ link].Все было хорошо, пока я не начал тестировать его на случайности, такие как пробелы до и после ссылки.Теперь на моем сервере истекло время ожидания, для которого установлено максимальное время обработки 30 секунд.

Пользователь может ввести в общей сложности 5000 символов, что представляет собой полезный текст на странице, который должны просмотреть эти функции.Однако, когда пользователь правильно вводит код (без пробелов), он не облагается налогом на сервер, и моя страница выскакивает за доли секунды, как и должно быть.Если один из [link] [/ link] отсутствует, цикл while завершается - ничего не происходит.Только когда ссылка набирается с такими пробелами, как это:

[ссылка] www.google.com [/ link] - или-- [ссылка] www.google.com [/ link]

оба тайм-аута сервера с этой ошибкой (слегка измененный путь):

Неустранимая ошибка: максимальное время выполнения 30 секунд превышено в /home/example/thiscode.php в строке 18

[ссылка] www.google.com [/ link] не истекает и не делает: [ссылка] www.google.com [/ link], который просто не распознается как действительная ссылка html, но получает ли якорный тег с ним правильно.

Есть мысли?Код hoy!

function my_link($snip)
{

    // Locate '[link]'
    $pos = stripos($snip, '[link]');

    // Strips off everything before [link]
    $str = substr($snip, $pos);

    // Removes [link] from $str
    $str = substr($str, 6);

    // Trim off any accidental whitespace BEFORE the link
    $str = ltrim($str);

    // Locate the end delimiter '[/link]'
    $pos_2 = stripos($str, '[/link]');

    // Cut off everything after and including '[/link]'
    $str = substr($str, 0, $pos_2);

    // Trim any accidental whitespace AFTER the link
    $str = rtrim($str);

    // Construct valid HTML link using content given
    if(strpos($str, 'http://') === FALSE) {
        $link = '<a href="http://'.$str.'">'.$str.'</a>';
    }else{
        $link = '<a href="'.$str.'">'.$str.'</a>';
    }

    // Replace the old [link]content[/link] with our newly constructed link
    $new_input = str_replace('[link]'.$str.'[/link]', $link, $snip);

    return $new_input;

}

function making_links($input)
{

    // Loop through $input as many times as [link] & [/link] pairs occur
    while(strpos($input, '[link]') && strpos($input, '[/link]')) {

        $input = my_link($input);

    }

    return $input;

}

Заранее спасибо всем, кто может мне помочь!

Ответы [ 3 ]

1 голос
/ 04 мая 2011

В вашем коде есть несколько логических ошибок.Например, весь ваш код вплоть до (но не включая) str_replace допускает следующие варианты:

  • [LINK] http: // ... [/ LINK]
  • [ссылка]www.example.com [/ link]
  • [LiNk] example.com [/ LINk]

Но ваш str_replace не допускает другой регистр тегов, и он не позволяетначальные / конечные пробелы, поскольку они удаляются из $ str.Во всех вышеперечисленных случаях str_replace ничего не заменит.Во втором из этих примеров ваш код застрянет в бесконечном цикле.

Используйте регулярное выражение, как показано Филом.Это, безусловно, самое простое решение вашей проблемы.

1 голос
/ 04 мая 2011

PECL BBCode может быть вариантом для вас.За исключением этого, проблема с вашим кодом, очевидно, связана с циклом.В частности, ни [link], ни [/ link] не удаляются из строки, если есть начальный или конечный пробел.

Ваша конкретная проблема вызвана этой строкой: $new_input = str_replace('[link]'.$str.'[/link]', $link, $snip);

Поскольку вы обновляете строку для удаления пробелов, [link]'.$str.'[/link] не существует в исходном фрагменте, существует только форма с пробелами.Таким образом, он никогда не найден.Чтобы обойти это, было бы лучше поработать с исходной строкой.

Еще одно предложение: измените strpos($input, '[link]') на strpos($input, '[link]') === FALSE.В противном случае он все равно будет иметь значение false, если ввод начинается с [link]

1 голос
/ 04 мая 2011

Вы можете попробовать что-то вроде этого, однако, это может привести к проблемам с производительностью, учитывая достаточно большой блок текста. Не может быть хуже того, что у тебя есть

$input = preg_replace('@\[link\]\s*(https?://)?(.+?)\s*\[/link\]@i', '<a href="http://$2">$2</a>', $input);

Для более надежного решения вы должны изучить лексический анализ .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...