CakePHP и JSON c кириллическими данными (версия PHP < 5.4.0)

Добавлено: 03/07/2015 02:17 |  Обновлено: 19/08/2017 11:36 |  Добавил: nick |  Просмотры: 4588 Комментарии: 0
Вводная часть
В этом материале разберемся как использовать JSON в CakePHP. Причем данные в нашем примере будут содержать кириллические символы. Используем стандартную функцию json_encode(). Но проблема в том, что эта функция экранирует русские буквы, если не использовать опцию JSON_UNESCAPED_UNICODE. А раз опция эта появилась в версии 5.4.0, то что делать, тем, у кого версия PHP ниже? Ответ один - использовать свои "костыли".
По поводу использования JSON в CakePHP первым делом можно ознакомиться со статьей на сайте CakePHP.

Итак, перейдем к практике. Первым делом откроем файл www\app\Config\routes.php. В нем добавим такую строку:
Router::parseExtensions('json', 'xml');
XML я оставил, для тех кто хочет использовать и XML-представление данных. Но здесь я его рассматривать не буду.

Далее открываем файл www\app\Controller\AppController.php. В нем добавляем следующую строку:
public $components = array('RequestHandler');
После чего открываем контроллер, из метода которого будем отправлять данные в json-представление. В методе этого контроллера нужно получить массив данных из модели, если нужно, как то его обработать, и передать в виде переменной в представление. Представления у нас пока нет, поэтому этим сейчас и займемся.

В папке www\app\View\Папка ваших представлений создадим папку "json". В ней создадим ctp-файл с именем метода вашего контроллера, из которого передаем данные (пример: getrecords.ctp). Откроем файл.

В нем мы должны получить json-представление данных, полученных из контроллера. Для этого используем функцию json_encode(). Но так как наши данные содержат русские символы, то они будут экранированы. Для того чтобы этого избежать, используем свои "костыли".

Если мы хотим исправить только вид русских символов, то можно использовать следующий код:
$arr_replace_utf = array('\u0410', '\u0430','\u0411','\u0431','\u0412','\u0432',
'\u0413','\u0433','\u0414','\u0434','\u0415','\u0435','\u0401','\u0451','\u0416',
'\u0436','\u0417','\u0437','\u0418','\u0438','\u0419','\u0439','\u041a','\u043a',
'\u041b','\u043b','\u041c','\u043c','\u041d','\u043d','\u041e','\u043e','\u041f',
'\u043f','\u0420','\u0440','\u0421','\u0441','\u0422','\u0442','\u0423','\u0443',
'\u0424','\u0444','\u0425','\u0445','\u0426','\u0446','\u0427','\u0447','\u0428',
'\u0448','\u0429','\u0449','\u042a','\u044a','\u042b','\u044b','\u042c','\u044c',
'\u042d','\u044d','\u042e','\u044e','\u042f','\u044f');
$arr_replace_cyr = array('А', 'а', 'Б', 'б', 'В', 'в', 'Г', 'г', 'Д', 'д', 'Е', 'е',
'Ё', 'ё', 'Ж','ж','З','з','И','и','Й','й','К','к','Л','л','М','м','Н','н','О','о',
'П','п','Р','р','С','с','Т','т','У','у','Ф','ф','Х','х','Ц','ц','Ч','ч','Ш','ш',
'Щ','щ','Ъ','ъ','Ы','ы','Ь','ь','Э','э','Ю','ю','Я','я');
$records = json_encode($records);
$records = str_replace($arr_replace_utf,$arr_replace_cyr,$records);
Согласен, выглядит это не очень приятно, но такой код работает довольно быстро и делает то что нужно. Если вы хотите что-нибудь по короче, и нужно избавиться от экранирования всех символов, то можно использовать следующий код:
$records = json_encode($records);
$records = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($match) {
    return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
}, $records);
Строк кода гораздо меньше, но работает медленнее.

Оставьте свой комментарий

Комментариев нет