PHP-код для создания безопасного URL? - PullRequest
5 голосов
/ 21 октября 2010

Нам нужно создать уникальный URL-адрес из заголовка книги, где заголовок может содержать любой символ.Как мы можем найти и заменить все «недопустимые» символы, чтобы сгенерировать правильный и аккуратный URL-адрес?

Например:

"The Great Book of PHP"

www.mysite.com/book/12345/the-great-book-of-php

"The Greatest !@#$ Book of PHP"

www.mysite.com/book/12345/the-greatest-book-of-php

"Funny title     "

www.mysite.com/book/12345/funny-title

Ответы [ 9 ]

15 голосов
/ 21 октября 2010

А, слизи

// This function expects the input to be UTF-8 encoded.
function slugify($text)
{
    // Swap out Non "Letters" with a -
    $text = preg_replace('/[^\\pL\d]+/u', '-', $text); 

    // Trim out extra -'s
    $text = trim($text, '-');

    // Convert letters that we have left to the closest ASCII representation
    $text = iconv('utf-8', 'us-ascii//TRANSLIT', $text);

    // Make text lowercase
    $text = strtolower($text);

    // Strip out anything we haven't been able to convert
    $text = preg_replace('/[^-\w]+/', '', $text);

    return $text;
}

Это работает довольно хорошо, так как сначала он использует свойства юникода каждого символа, чтобы определить, является ли он буквой (или \ d против числа), - затем он преобразует те, которые не в «-», а затем транслитерируется в ASCII, делает другую замену для чего-либо еще, а затем убирает за собой. (тест Фабрика возвращает "arvizturo-tukorfurogep")

Я также склоняюсь к добавлению в список стоп-слов, чтобы они были удалены из слага. "the" of "" или "" a "и т. д. (но не делайте этого по длине, или вы удалите такие вещи, как" php ")

7 голосов
/ 21 октября 2010

Если «недействительный» означает не алфавитно-цифровой, вы можете сделать это:

function foo($str) {
    return trim(preg_replace('/[^a-z0-9]+/', '-', strtolower($str)), '-');
}

Это превратит $str в строчные буквы, заменит любую последовательность из одного или нескольких не алфавитно-цифровых символов одним дефисом, а затем удалит начальные и конечные дефисы.

var_dump(foo("The Great Book of PHP") === 'the-great-book-of-php');
var_dump(foo("The Greatest !@#$ Book of PHP") === 'the-greatest-book-of-php');
var_dump(foo("Funny title     ") === 'funny-title');
2 голосов
/ 21 октября 2010

Для этой цели вы можете использовать простое регулярное выражение:

<?php
    function safeurl( $v )
    {
        $v = strtolower( $v );
        $v = preg_replace( "/[^a-z0-9]+/", "-", $v );
        $v = trim( $v, "-" );
        return $v;
    }
    echo "<br>www.mysite.com/book/12345/" . safeurl( "The Great Book of PHP" );
    echo "<br>www.mysite.com/book/12345/" . safeurl( "The Greatest !@#$ Book of PHP" );
    echo "<br>www.mysite.com/book/12345/" . safeurl( "  Funny title  " );
    echo "<br>www.mysite.com/book/12345/" . safeurl( "!!Even Funnier title!!" );
?>
1 голос
/ 21 октября 2010

Этот код получен от помощника по URL CodeIgniter .Это должно сделать трюк.

function url_title($str, $separator = 'dash', $lowercase = FALSE)
    {
        if ($separator == 'dash')
        {
            $search     = '_';
            $replace    = '-';
        }
        else
        {
            $search     = '-';
            $replace    = '_';
        }

        $trans = array(
                        '&\#\d+?;'              => '',
                        '&\S+?;'                => '',
                        '\s+'                   => $replace,
                        '[^a-z0-9\-\._]'        => '',
                        $replace.'+'            => $replace,
                        $replace.'$'            => $replace,
                        '^'.$replace            => $replace,
                        '\.+$'                  => ''
                      );

        $str = strip_tags($str);

        foreach ($trans as $key => $val)
        {
            $str = preg_replace("#".$key."#i", $val, $str);
        }

        if ($lowercase === TRUE)
        {
            $str = strtolower($str);
        }

        return trim(stripslashes($str));
    }
1 голос
/ 21 октября 2010

Если вы хотите разрешить только буквы, цифры и подчеркивание (обычные символы слова), вы можете сделать:

$str = strtolower(preg_replace(array('/\W/','/-+/','/^-|-$/'),array('-','-',''),$str));

Сначала он заменяет любой несловесный символ (\W) на -,
Далее он заменяет любой последовательный - на один -
Затем он удаляет любой начальный или конечный -.

Рабочая ссылка

0 голосов
/ 21 октября 2010

Санитарная обработка спецсимволов не легкая задача imho. Взгляните на удивительную функцию WordPress sanitize_title , также посмотрите, что это source .

Обновление: Извините, ребята, я должен понизить каждый ответ, который не касается акцентированных символов. Вы понимаете, что "заголовок может содержать любой символ" означает?

Обновление 2: Иди, ребята, иди! Пожалуйста, уменьшите меня как можно больше!

Примечание: и, пожалуйста, не удивляйтесь, когда встретите специального персонажа. Просто устраните это с помощью str_replace!

0 голосов
/ 21 октября 2010
<?php
$input = "  The Great Book's of PHP  ";
$output = trim(preg_replace(array("`'`", "`[^a-z]+`"),  array("", "-"), strtolower($input)), "-");
echo $output; // the-great-books-of-php

Это обрезает конечные тире и не делает такие вещи, как "it's raining" -> "it-s-raining", как это делает большинство решений.

0 голосов
/ 21 октября 2010

Используйте регулярное выражение замены, чтобы удалить все несловарные символы.Например:

str_replace ('[^ a-zA-Z] +', '-', $ input)

0 голосов
/ 21 октября 2010

Замените специальные символы для пробелов, а затем замените пробелы на "-". str_replace

...