Iconv возвращает неверную строку в phpunit

У меня есть проект в SF4, и я использую phpunit 6.5.8. Я тестировал сервис, использующий iconv:

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

Когда я использую эту службу в приложении и когда $ string имеет значение: «ąbć», возвращается «abc», но когда та же служба запускается в phpunit, возвращается «? B?».

Не понимаю, почему не работает ... Конечно, тест отрицательный, но в приложении работает хорошо.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
1
0
398
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Хорошо, я решил проблему. Php в CLI не устанавливает языковой стандарт. Так что надо ставить перед тестами.

1. Проверьте местоположение, которое у вас есть в системе:

locale -a

Например:

$ locale -a
C
C.UTF-8
en_US.utf8

2. В тестах добавить:

setlocale(LC_CTYPE, 'en_US.utf8');

3. Пример:

    public static function setUpBeforeClass()
    {
        setlocale(LC_CTYPE, 'en_US.utf8');
    }

источник:

Я сделал один класс для работы со строками, а один из методов использует iconv.

При использовании phpunit в Windows iconv не может транслитерировать из-за проблем с языковым стандартом. Даже использование setlocale () в коде всегда приводит к провалу теста с использованием кода ниже.

/**
 * @param $str Convert string to lowercase and replace special chars to equivalents ou remove its
 * @return string
 */
public static function slugify($str)
{
    $str = self::toUtf8($str); // Convert from any encoding to UTF-8
    $str = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $str); // transliterate
    $str = strtolower($str); // lowercase
    return $str;
}

Модульный тест

public function testSlugfy()
{
    // Basic String
    $str = StringUtils::slugify($this->basicstring);
    $this->assertEquals(strtolower($this->basicstring), $str, 'Basic String cannot be slugfied');

    // Latin String
    $str = StringUtils::slugify($this->latinstring);
    $this->assertEquals(strtolower($this->basicstring), $str, 'Latin1 String cannot be slugfied');

    // UTF-8 String
    $str = StringUtils::slugify($str);
    $this->assertEquals(strtolower($this->basicstring), $str, 'UTF8 String cannot be slugfied');

}

У меня нет проблем с моим приложением, но тест PHPUnit не работает с приведенным выше кодом.

Итак, чтобы пройти тест, я меняю функцию на

/**
 * @param $str Convert string to lowercase and replace special chars to equivalents ou remove its
 * @return string
 */
public static function slugify($str)
{
    $string = self::toUtf8($str);
    $string = iconv('UTF-8', 'ASCII//TRANSLIT', $string);

    if ($string != htmlentities($str, ENT_QUOTES, 'UTF-8')) { // iconv fails
        $string = htmlentities($str, ENT_QUOTES, 'UTF-8');
        $string = preg_replace('#&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);#i', '$1', $string);
// If need to leave only 0-9, a-z and A-Z
//            $string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');
//            $string = preg_replace(array('#[^0-9a-z]#i', '#[ -]+#'), ' ', $string);
        $string = trim($string, ' -');
    }

    // lowercase
    $str = strtolower($string);

    return $str;
}

А в конструкторе класса Unit Test я создаю строки с другим подходом, чтобы избежать проблем с кодировкой файлов и проблемами языкового стандарта.

private $basicstring;
private $latinstring;
private $utf8string;

public function __construct()
{
    // ASCII string
    $this->basicstring = 'aeioucAEIOUC';

    // To avoid troubles using command line in different locales
    // the string used to create different charset is a plain HTML entities
    // Using html_entity_decode to convert the
    // string ãéìôüçÃÉìÔÜÇ
    // into ãéìôüçÃÉìÔÜÇ in different charsets
    $html_chars = 'ãéìôüçÃÉìÔÜÇ';
    $this->utf8string = html_entity_decode($html_chars, ENT_HTML5, 'UTF-8');
    $this->latinstring = html_entity_decode($html_chars, ENT_HTML5, 'ISO-8859-1');
    parent::__construct();
}

Я также использую Symfony 4

Другие вопросы по теме