iconv utf-8 для транслитерации ascii в mod_php / apache2 - PullRequest
1 голос
/ 24 августа 2010

Мне нужно сравнить строки и сопоставить имена друг с другом, даже если они написаны не одинаково.Например, DÉSIRÉ-Smith должно соответствовать Desireesmith, а также Desiree или Desi'ree Smith

Поэтому у меня был следующий подход, который отлично работал в командной строке с использованием PHP-CLI:

    <?
    class Alike {
      static function convertAlike($string) {
        // in case the first and last name or two first names are mixed up
        $parts = preg_split('/[\s\-\.\_]/', $string, -1, PREG_SPLIT_NO_EMPTY);
        sort($parts);
        $string = implode($parts);

        $string = iconv('UTF-8', 'ASCII//TRANSLIT', $string); // transliterate
        $string = strtolower($string); // lowercase
        $string = preg_replace('/[^a-z]/','',$string); // remove everything but a-z
        $string = preg_replace('{(.)\1+}','$1',$string); // remove duplicate chars
        return $string;
      }
      static function compareAlike($string1,$string2) {
        return (strcmp(Alike::convertAlike($string1),Alike::convertAlike($string2)) === 0) ? true : false;
      }
    }
    echo Alike::convertAlike("DÉSIRÉ-Smith").PHP_EOL; // desiresmith
    echo Alike::convertAlike("Desireesmith").PHP_EOL; // desiresmith
    echo Alike::convertAlike("Desi'ree Smith").PHP_EOL; // desiresmith
    echo Alike::convertAlike("René Röyßeå likes special characters ½ € in ©").PHP_EOL; // reneroysealikespecialcharacterseurinc

    var_dump(Alike::compareAlike("DÉSIRÉ-Smith","Desireesmith")); // true
    var_dump(Alike::compareAlike("Desireesmith","Desi'ree Smith")); // true
    var_dump(Alike::compareAlike("summer","winter")); // false
    ?>

Однако на моем сайте под управлением Server version: Apache/2.2.14 (Ubuntu) под управлением PHP Version 5.3.2-1ubuntu4.2 в качестве модуля я всегда получаю только знаки вопроса.Самое смешное, что ошибка должна возникать в этой строке

$string = iconv('UTF-8', 'ASCII//TRANSLIT', $string); // transliterate

, потому что после этого я вижу все символы, которые не были транслитерированы, но те, которые должны были быть заменены на символы ascii, становятся знаками вопроса.*

Я перепробовал все возможные комбинации кодирования строки ввода / вывода и внутренних настроек iconv, настроек кодировки ввода и вывода, а также настроек локали.я даже выполнил команду chmod -R 777 / usr / lib / gconv и переместил ее в мой рабочий каталог.

однако я увидел сообщение об ошибке в списке рассылки: http://bugs.php.net/bug.php?id=44096

[2010-06-07 21:22 UTC] icovt at yahoo dot com
mod_php iconv() is not working properly if your apache is chrooted and you do not 
have the content of /usr/lib/gconv/ folder into your relative chroot path (i.e. 
/your/chroot/path/usr/lib/gconv/). 
You can simply do: 
cp /usr/lib/gconv/* /your/chroot/path/usr/lib/gconv/
... and re-try.

This was a fix for me, hope this could save time for somebody else.

P.S. Btw, initially iconv() called from command line (using php cli) was OK.

Я попробовал, чтобы мой пользователь www-данных находился дома в / var / www /, и у меня появилась папка / var / www / usr / lib / gconv /, а также / var / www / myproject / usr /lib / gconv /

К вашему сведению: у меня были функции обнаружения и транскодирования кодирования для обеспечения правильной передачи кодов, но я удалил их для ясности, поскольку они не нужны в любом случае, если вы вводите строки utf8, все должно бытьхорошо ...

Есть идеи?

1 Ответ

2 голосов
/ 25 августа 2010

выяснил, что языковой стандарт не был настроен правильно, и мои попытки установить его не увенчались успехом, поскольку доступные в системе языковые стандарты фактически были названы иначе, чем примеры из man-страницы (в соответствии с их кодировкой!), Простой locale -a показал, что; O)

setlocale(LC_ALL, "en_US.utf8");

это действительно сделало свою работу!

хорошо, теперь эта функция работает отлично.

хорошо, теперь понятно, почему она работала и с консоли, потому чтолокаль была импортирована из текущих настроек оболочки пользователя;) она фактически нуждается в любой локали.на самом деле не имеет значения, какой из них, когда мы конвертируем в ascii, где все равны, только некоторые из них более равны, чем другие:)

Будьте внимательны, чтобы установить языковой стандарт, который фактически установлен в вашей системе, и проверить результат setlocale,потому что вы ничего не измените, если языковой стандарт не установлен или имя написано с ошибкой.

...