Как я могу искать странных персонажей в Laravel? - PullRequest
0 голосов
/ 14 сентября 2018

У меня проблема с поиском на моем сайте.У меня есть вход для поиска продуктов по названию.Если я наберу 'leña' (проблема в странных символах).

Это в контроллере

 $termino = $_POST['search']);
 $locale = LaravelLocalization::getCurrentLocale(); //es in this case
 $products = Product::where('title', 'LIKE', "%\"{$locale}\":%{$termino}%");

Это содержимое поля 'title' в базе данных.

{"es":"PAN DE LE\u00d1A"}

Поиск возвращает 0 результатов.

Я уверен, что проблема в кодификации, и я не знаю, как ее решить.

Кодификация utf8mb4.

Спасибо

Ответы [ 2 ]

0 голосов
/ 14 сентября 2018

Проблема на самом деле не в неанглийских символах. Основная проблема заключается в том, что вы храните сложный формат данных (JSON) в одной ячейке базы данных, а не разрабатываете базу данных для хранения отдельных фрагментов данных:

create table product_title (
    product_id int(10) not null,
    locale varchar(2) not null,
    title varchar(200),
    primary key (product_id, locale)
);
insert into product_title (product_id, locale, title) values (1, 'es', 'Leña');
insert into product_title (product_id, locale, title) values (1, 'en', 'Wood');

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

Вы можете исправить дизайн (пожалуйста, сделайте) или применить обходной путь:

  • Если у вас последняя версия MySQL, вы можете сделать столбец JSON типа .
  • Вы можете создать две версии данных JSON и ожидать, что значения базы данных не будут иметь смешанных регистров:

    $locale = 'es';
    $termino = 'Leña';
    $data = [
        $locale => ":%{$termino}%"
    ];
    $ascii = json_encode($data);
    $unicode = json_encode($data, JSON_UNESCAPED_UNICODE);
    
    // Use your framework's syntax instead:
    $sql = 'SELECT * FROM product WHERE title IN (:ascii, :unicode)';
    $params = [$ascii, $unicode];
    

Пожалуйста, обратите внимание, что нет никакого вменяемого обходного пути для использования подстановочных знаков LIKE.

0 голосов
/ 14 сентября 2018

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

// assuming that $termino is a string 
// json_encode should return the unicode representation
$search = json_encode($termino);

// I changed the where condition a bit, 
// but your own condition is also do fine
$products = Product::where('title->'.$locale, 'LIKE', '%'.$search.'%');
...