str_replace не заменяет правильно - PullRequest
0 голосов
/ 02 февраля 2012

У меня есть следующий простой код:

$text = str_replace($f,'<a href="'.$f.'" target="_blank">'.$u.'</a>',$text);

, где $ f - это URL, например http://google.ca, а $ u - это имя URL (моя функция называет его «Google»).

Моя проблема в том, если я дам своей функции строку типа

http://google.ca http://google.ca

возвращает

<a href="<a href="http://google.ca" target="_blank">Google</a>" target="_blank">Google</a> <a href="<a href="http://google.ca" target="_blank">Google</a>" target="_blank">Google</a>

Что, очевидно, не то, что я хочу. Я хочу, чтобы моя функция отображала две отдельные кликабельные ссылки. Но str_replace заменяет первое вхождение (оно находится в цикле для прохождения всех найденных URL-адресов), и это первое вхождение уже заменено.

Как я могу сказать str_replace игнорировать этот конкретный и перейти к следующему? Данная строка является пользовательским вводом, поэтому я не могу просто дать ей статическое смещение или что-то еще с substr, что я пробовал.

Спасибо!

Ответы [ 4 ]

1 голос
/ 02 февраля 2012

С одной стороны, хотя это немного клудж: вы можете использовать временный маркер, который (надеюсь) не появится в строке:

$text = str_replace ($f, '<a href="XYZZYPLUGH" target="_blank">' . $u . '</a>',
                     $text);

Таким образом, первая замена не будет найдена снова. Затем в конце (после того, как вы обработали всю строку), просто поменяйте маркеры обратно:

$text = str_replace ('XYZZYPLUGH', $f, $text);
0 голосов
/ 02 февраля 2012

Я предлагаю вам использовать preg_replace вместо str_replace здесь, как этот код:

$f = 'http://google.ca';
$u = 'Google';
$text='http://google.ca http://google.ca';
$regex = '~(?<!<a href=")' . preg_quote($f) . '~'; // negative lookbehind
$text = preg_replace($regex, '<a href="'.$f.'" target="_blank">'.$u.'</a>', $text);
echo $text . "\n";
$text = preg_replace($regex, '<a href="'.$f.'" target="_blank">'.$u.'</a>', $text);
echo $text . "\n";

ВЫХОД:

<a href="http://google.ca" target="_blank">Google</a> <a href="http://google.ca" target="_blank">Google</a>
<a href="http://google.ca" target="_blank">Google</a> <a href="http://google.ca" target="_blank">Google</a>
0 голосов
/ 02 февраля 2012

Если я правильно понимаю вашу проблему, вы можете просто использовать функцию sprintf.Я думаю, что-то вроде этого должно работать:

function urlize($name, $url)
{
    // Make sure the url is formatted ok
    if (!filter_var($url, FILTER_VALIDATE_URL))
        return '';

    $name = htmlspecialchars($name, ENT_QUOTES);
    $url  = htmlspecialchars($url, ENT_QUOTES);

    return sprintf('<a href="%s">%s</a>', $url, $name);
}

echo urlize('my name', 'http://www.domain.com'); 
// <a href="http://www.domain.com">my name</a>

Хотя я не проверял это.

0 голосов
/ 02 февраля 2012

Почему бы не передать вашей функции массив URL, вместо этого?

function makeLinks(array $urls) {
    $links = array();

    foreach ($urls as $url) {
        list($desc, $href) = $url;
        // If $href is based on user input, watch out for "javascript: foo;" and other XSS attacks here.
        $links[] = '<a href="' . htmlentities($href) . '" target="_blank">'
                 . htmlentities($desc)
                 . '</a>';
    }

    return $links; // or implode('', $links) if you want a string instead
}

$urls = array(
    array('Google', 'http://google.ca'),
    array('Google', 'http://google.ca')
);

var_dump(makeLinks($urls));
...