О насБлогКонтакты
Бизнес и продукт22 апреля 2015 г. 4 мин 130Обновлено: 22 июня 2026 г.

Как добавить казахский язык в веб-приложение: полный стек (MySQL, PHP, nginx) - 2015

AunimedaAunimeda
📋 Содержание

Коротко: Казахский требует utf8mb4 в MySQL, charset=UTF-8 в HTTP-заголовках, шрифты Noto Sans с cyrillic-ext подмножеством, и lang="kk" в HTML. Самая частая ошибка - использование utf8 вместо utf8mb4 в MySQL: utf8 в MySQL - это не настоящий UTF-8, он не хранит символы выше U+FFFF.


Казахские буквы и Unicode

Кириллический казахский алфавит (введён в СССР, используется в Казахстане) содержит дополнительные символы:

Буква Unicode Описание
Ә/ә U+04D8/U+04D9 Ae
Ғ/ғ U+0492/U+0493 Ge with stroke
Қ/қ U+049A/U+049B Ka with descender
Ң/ң U+04A2/U+04A3 En with descender
Ө/ө U+04E8/U+04E9 O with stroke
Ұ/ұ U+04B0/U+04B1 Straight U with stroke
Ү/ү U+04AE/U+04AF Straight U
Ҳ/ҳ U+04B2/U+04B3 Ha with descender
І/і U+0406/U+0456 Dotted I

Шаг 1: MySQL - utf8mb4

-- Проверить текущую кодировку
SHOW VARIABLES LIKE 'character_set_%';
SHOW VARIABLES LIKE 'collation_%';

-- Если не utf8mb4 - менять на уровне сервера
-- /etc/mysql/my.cnf:
-- [client]
-- default-character-set = utf8mb4
-- [mysql]
-- default-character-set = utf8mb4
-- [mysqld]
-- character-set-client-handshake = FALSE
-- character-set-server = utf8mb4
-- collation-server = utf8mb4_unicode_ci

-- Создать БД правильно:
CREATE DATABASE myapp_kz 
    CHARACTER SET utf8mb4 
    COLLATE utf8mb4_unicode_ci;

-- Конвертировать существующую таблицу:
ALTER TABLE articles 
    CONVERT TO CHARACTER SET utf8mb4 
    COLLATE utf8mb4_unicode_ci;

-- Проверить конкретный столбец:
ALTER TABLE articles 
    MODIFY COLUMN title VARCHAR(500) 
    CHARACTER SET utf8mb4 
    COLLATE utf8mb4_unicode_ci NOT NULL;

Шаг 2: PHP - подключение с utf8mb4

<?php
// Соединение PDO с правильной кодировкой
$dsn = 'mysql:host=localhost;dbname=myapp_kz;charset=utf8mb4';
$pdo = new PDO($dsn, $user, $password, [
    PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci",
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
]);

// Проверка - вставить и прочитать казахский текст
$stmt = $pdo->prepare("INSERT INTO test_kaz (text) VALUES (?)");
$stmt->execute(['Қазақстан Республикасы - Астана']);

$result = $pdo->query("SELECT text FROM test_kaz LIMIT 1")->fetchColumn();
echo $result;  // Должно быть: Қазақстан Республикасы - Астана
// Если выводятся ??? или ??? - проблема с кодировкой на каком-то уровне

Шаг 3: PHP - правильные заголовки

<?php
// Первое что делает скрипт - установить заголовки
header('Content-Type: text/html; charset=UTF-8');
header('Content-Language: kk');  // kk = казахский ISO 639-1

// Для JSON API:
header('Content-Type: application/json; charset=UTF-8');
; php.ini - глобальная настройка
default_charset = "UTF-8"
mbstring.internal_encoding = UTF-8
mbstring.http_output = UTF-8

Шаг 4: HTML - правильная разметка

<!DOCTYPE html>
<html lang="kk">  <!-- kk = казахский -->
<head>
    <meta charset="UTF-8">
    <!-- Шрифт с поддержкой казахских символов -->
    <link href="https://fonts.googleapis.com/css?family=Noto+Sans:400,700&subset=cyrillic-ext" rel="stylesheet">
    
    <!-- Для многоязычного сайта: hreflang -->
    <link rel="alternate" hreflang="kk" href="https://mysite.kz/kk/article/1">
    <link rel="alternate" hreflang="ru" href="https://mysite.kz/ru/article/1">
    <link rel="alternate" hreflang="x-default" href="https://mysite.kz/article/1">
</head>
<body>

Шаг 5: nginx - charset в заголовках

server {
    # Добавить charset для text/html
    charset utf-8;
    charset_types text/html text/css application/json application/javascript;
    
    # Для PHP-FPM убедиться что fastcgi передаёт правильную кодировку
    location ~ \.php$ {
        fastcgi_pass unix:/var/run/php5-fpm.sock;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        # Не переопределять charset если PHP устанавливает сам через header()
    }
}

Работа с казахским текстом в PHP

<?php
// Используйте mb_* функции вместо строковых для казахского текста

// НЕПРАВИЛЬНО:
$length  = strlen("Қазақстан");       // 17 (байты, не символы!)
$upper   = strtoupper("қазақстан");   // Не работает для нелатинских

// ПРАВИЛЬНО:
$length  = mb_strlen("Қазақстан", 'UTF-8');         // 9 (символы)
$upper   = mb_strtoupper("қазақстан", 'UTF-8');     // ҚАЗАҚСТАН
$lower   = mb_strtolower("ҚАЗАҚСТАН", 'UTF-8');     // қазақстан
$substr  = mb_substr("Астана қаласы", 0, 6, 'UTF-8'); // Астана

// Поиск по казахскому тексту
$pos = mb_strpos("Қазақстан", "зақ", 0, 'UTF-8');  // 2

// Транслитерация для URL-slug
function kazakhSlug(string $text): string {
    $translit = [
        'Ә' => 'ae', 'ә' => 'ae',
        'Ғ' => 'gh', 'ғ' => 'gh',
        'Қ' => 'q',  'қ' => 'q',
        'Ң' => 'ng', 'ң' => 'ng',
        'Ө' => 'oe', 'ө' => 'oe',
        'Ұ' => 'u',  'ұ' => 'u',
        'Ү' => 'u',  'ү' => 'u',
        'Ҳ' => 'h',  'ҳ' => 'h',
        'І' => 'i',  'і' => 'i',
    ];

    $text = strtr($text, $translit);
    $text = mb_strtolower($text, 'UTF-8');
    // Кириллица → транслит (Iconv)
    $text = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $text);
    $text = preg_replace('/[^a-z0-9\-]/', '-', $text);
    $text = preg_replace('/-+/', '-', $text);
    return trim($text, '-');
}

echo kazakhSlug("Қазақстан Республикасы");  // qazaqstan-respublikasy

Полнотекстовый поиск по казахскому

-- MySQL 5.6+ поддерживает полнотекстовый поиск для utf8mb4
-- Но казахский стеммер не встроен - используем LIKE для 2015 года

CREATE TABLE articles (
    id      INT AUTO_INCREMENT PRIMARY KEY,
    title   VARCHAR(500),
    body    TEXT,
    lang    CHAR(2) DEFAULT 'kk',
    FULLTEXT INDEX ft_title_body (title, body)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

-- Поиск через LIKE (медленнее но надёжнее для казахского в 2015)
SELECT * FROM articles 
WHERE lang = 'kk' 
  AND (title LIKE '%қазақ%' OR body LIKE '%қазақ%')
ORDER BY created_at DESC
LIMIT 20;

Типичная ошибка: кириллица отображается, казахские буквы - нет

Причина: шрифт загружается без cyrillic-ext подмножества.

<!-- НЕПРАВИЛЬНО - нет cyrillic-ext -->
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700" rel="stylesheet">

<!-- ПРАВИЛЬНО - с расширенной кириллицей -->
<link href="https://fonts.googleapis.com/css?family=Roboto:400,700&subset=cyrillic,cyrillic-ext" rel="stylesheet">

После этого Ә, Ғ, Қ, Ң, Ө, Ұ, Ү, Ҳ, І отображаются корректно.

Читайте также

AI в e-commerce Казахстана: персонализация, рекомендации и как не отстать от Kaspi в 2026aunimeda
Бизнес и продукт

AI в e-commerce Казахстана: персонализация, рекомендации и как не отстать от Kaspi в 2026

Kaspi.kz использует AI-персонализацию уже несколько лет. Как независимые интернет-магазины Казахстана могут применить те же принципы без бюджета tech-гиганта? Разбираем доступные AI-инструменты для казахстанского e-commerce.

Как запустить интернет-магазин в Алматы с нуля - пошаговый гайдaunimeda
Бизнес и продукт

Как запустить интернет-магазин в Алматы с нуля - пошаговый гайд

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

IT аутсорсинг в Казахстане - почему компании выбирают Алматыaunimeda
Бизнес и продукт

IT аутсорсинг в Казахстане - почему компании выбирают Алматы

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

Нужна IT-разработка для вашего бизнеса?

Разрабатываем сайты, мобильные приложения и AI-решения для бизнеса в Казахстане. Бесплатная консультация.

Получить консультацию Все статьи