Многобайтовое безопасное преобразование заголовка URL в PHP - PullRequest
1 голос
/ 21 октября 2010

Я пытаюсь создать многобайтовый безопасный конвертер строки title => url, однако я столкнулся с проблемой незнания, как разрешить использование азиатских (и других) символов в URL при удалении других.Эта функция установлена ​​на данный момент.

public static function convertAccentedCharacters($string)
{                            
    $table = array(
            'Œ'=>'CE', 'œ'=>'ce', '¥'=>'Y', 'Ÿ'=>'Y', 'µ'=>'u', 'ü'=>'u', 
            'Š'=>'S', 'š'=>'s', 'Đ'=>'Dj', 'đ'=>'dj', 'Ž'=>'Z', 'ž'=>'z', 'Č'=>'C', 'č'=>'c', 'Ć'=>'C', 'ć'=>'c',
            'À'=>'A', 'Á'=>'A', 'Â'=>'A', 'Ã'=>'A', 'Ä'=>'A', 'Å'=>'A', 'Æ'=>'A', 'Ç'=>'C', 'È'=>'E', 'É'=>'E',
            'Ê'=>'E', 'Ë'=>'E', 'Ì'=>'I', 'Í'=>'I', 'Î'=>'I', 'Ï'=>'I', 'Ñ'=>'N', 'Ò'=>'O', 'Ó'=>'O', 'Ô'=>'O',
            'Õ'=>'O', 'Ö'=>'O', 'Ø'=>'O', 'Ù'=>'U', 'Ú'=>'U', 'Û'=>'U', 'Ü'=>'U', 'Ý'=>'Y', 'Þ'=>'B', 'ß'=>'Ss',
            'à'=>'a', 'á'=>'a', 'â'=>'a', 'ã'=>'a', 'ä'=>'a', 'å'=>'a', 'æ'=>'a', 'ç'=>'c', 'è'=>'e', 'é'=>'e',
            'ê'=>'e', 'ë'=>'e', 'ì'=>'i', 'í'=>'i', 'î'=>'i', 'ï'=>'i', 'ð'=>'o', 'ñ'=>'n', 'ò'=>'o', 'ó'=>'o',
            'ô'=>'o', 'õ'=>'o', 'ö'=>'o', 'ø'=>'o', 'ù'=>'u', 'ú'=>'u', 'û'=>'u', 'ý'=>'y', 'ý'=>'y', 'þ'=>'b',
            'ÿ'=>'y', 'Ŕ'=>'R', 'ŕ'=>'r',
        );

    return str_replace(array_keys($table), array_values($table), $string); 
}

public static function convertStringToSafeCharacters($string)
{                 
    $string = self::convertAccentedCharacters($string);
    if (function_exists('mb_convert_encoding') === true)
    {
        $string = mb_convert_encoding($string, 'UTF-8', 'auto'); 
    }
    else if(function_exists('iconv') === true && ($iconvstr = @iconv('', 'UTF-8', $string)) !== false)
    {
        $string = $iconvstr;
    }
    else
    {
        $string = utf8_decode($string);
    }
    return strip_tags(trim($string));
}

public static function convertToUrlsafe($string, $options=array())
{    
    if(isset($options['separator']) === false || $options['separator'] === false)
    {
        global $_SITE;
        if(strpos($_SITE->urlsafe_format, 'underscore') !== false)
        {
            $options['separator'] = '_';
        }
        else
        {
            $options['separator'] = '-';
        }
    }
    if(isset($options['case']) === false || $options['case'] === false)
    {
        global $_SITE;
        $format = substr($_SITE->urlsafe_format, 0, 5);
        if($format === 'lower')
        {
            $options['case'] = 'lower';
        }
        else if($format === 'upper')  
        {
            $options['case'] = 'upper';
        }
        else
        {
            $options['case'] = 'mixed';
        }
    } 

    $string = self::convertStringToSafeCharacters($string);

    $separator_in_use = $options['separator'];
    $separtor_convert = $options['separator'] == '-' ? '_' : '-';
    $preg_changes = array(
//              convert other seperators into the seperator being used
        '/\\'.$separtor_convert.'/i'            => $separator_in_use, 
//              remove any none legal chars
        '/[^\-\_a-zA-Z0-9&\s]/i'                => '',
        '/\&\#\d+?\;/'                          => '', 
        '/\&\S+?\;/'                            => '',
//              replace spaces with separator
        '/\s+/'                                 => $separator_in_use,
//              replace amersands with and
        '/\&/'                                  => 'and',
//              now finally remove any last chars
        '/[^A-Za-z0-9\/'.$separator_in_use.']/' => '',
//              remove any double paddinging separators, ie ----
        '/'.$separator_in_use.'+/'              => $separator_in_use, 
//              remove separator padding from start and end of string
        '/'.$separator_in_use.'$/'              => '',
        '/^'.$separator_in_use.'/'              => ''
    );
    $string = preg_replace(array_keys($preg_changes), array_values($preg_changes), $string);
    switch($options['case'])
    {
        case 'lower' :
            $string = strtolower($string);
            break;
        case 'upper' :
            $string = strtoupper($string);
            break;
        case 'mixed' :
            // do nothing
    }
    return $string;
}

Пожалуйста, имейте в виду, что там есть некоторые функции, связанные с CMS, и что функции на самом деле являются частью класса.Основной вызов функции будет

convertToUrlsafe($string);

И я почти уверен, что проблема заключается в замене регулярных выражений в самой этой функции, но я не совсем уверен, что изменить, не нарушив некоторые существующие функции.

Я хочу иметь возможность взять следующие заголовки и заставить их возвращать заголовки urlsafe.

"Самый первый блог!"=> «The-Very-First-Blog»

«ス ー ザ ン は 本 本 、 グ グ ス ゴ ゴ ゴ ラ ベ ラ ー ー ス ト ン ン ン の ((((»в тот момент, когда он просто возвращает пустую строку.

1 Ответ

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

В URL-адресах нет «законных азиатских» символов: URL-адреса могут содержать только символы ASCII.

Западные символы, которые можно нормализовать с помощью вашего метода (или, например, iconv(); здесь другая альтернатива).Для всего остального используйте процентное кодирование (т. Е. urlencode ).Современные браузеры будут автоматически отображать правильные символы вместо этого, где это уместно.

Фон: Юникод-символы в URL-адресах

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