Mb strwidth: примеры (PHP)

Определение ширины строки с помощью mb_strwidth
Раздел: Многобайтовые строки
mb_strwidth(string $string, ?string $encoding = null): int

Функция mb_strwidth в PHP

Функция mb_strwidth вычисляет ширину строки в символах, учитывая особенности многобайтовых кодировок и ширину символов в моноширинных шрифтах. Она полезна при форматировании текста для терминалов или в случаях, где требуется выравнивание с учетом полной и половинной ширины символов.

Область применения

Функция применяется при работе с текстами на азиатских языках (китайский, японский, корейский), где часть символов имеет полную ширину, а часть - половинную. Также используется для точного подсчета места, которое займет строка в моноширинном отображении.

Аргументы функции
int mb_strwidth(string $string, string|null $encoding = null)

$string - анализируемая строка. Обязательный параметр.

$encoding - кодировка входной строки. Если не указана, используется внутренняя кодировка. Необязательный параметр.

Примеры использования mb_strwidth

Базовый пример с разной шириной символов
echo mb_strwidth("Hello"); // 5
echo mb_strwidth("Привет"); // 6 (кириллица имеет полную ширину)
echo mb_strwidth("こんにちは"); // 10 (хирагана - полная ширина)
echo mb_strwidth("abc123"); // 6
5
6
10
6
Пример с указанием кодировки
$str = "Пример";
echo mb_strwidth($str, 'UTF-8'); // 6
6
Смешанный контент
$text = "Hello 世界!"; // Латиница + иероглифы
$width = mb_strwidth($text);
echo "Ширина строки: $width";
Ширина строки: 13

Похожие функции в PHP

Подсчитывает количество символов в строке. Отличие от mb_strwidth в том, что каждый символ считается как 1, независимо от его визуальной ширины.

echo mb_strlen("Hello"); // 5
echo mb_strwidth("Hello"); // 5 (одинаково для латиницы)
echo mb_strlen("世界"); // 2
echo mb_strwidth("世界"); // 4 (иероглифы имеют полную ширину)
strlen

Подсчитывает количество байт в строке. Не учитывает многобайтовые кодировки, поэтому для UTF-8 может давать неверные результаты для подсчета символов.

iconv_strlen

Аналог mb_strlen из расширения iconv. Работает с различными кодировками, но не учитывает ширину символов.

mb_strwidth предпочтительнее при работе с восточными языками и в задачах визуального форматирования. mb_strlen лучше подходит для подсчета реального количества символов.

Типичные ошибки

Некорректная кодировка
// Если передать строку в неверной кодировке
$str = mb_convert_encoding("Пример", 'Windows-1251', 'UTF-8');
echo mb_strwidth($str, 'UTF-8'); // Может вернуть неожиданный результат
6 (но может варьироваться в зависимости от окружения)
Специальные символы
// Управляющие символы и эмодзи
$str = "Line1\nLine2"; // Символ новой строки
$str2 = "Hello ????"; // Эмодзи
echo mb_strwidth($str); // 10
echo mb_strwidth($str2); // 7 (эмодзи считается как 2 символа ширины)
10
7
Неправильные ожидания

Ожидание, что результат mb_strwidth всегда будет равен количеству символов для европейских языков. Для символов с комбинирующими диакритическими знаками это не так.

Изменения в версиях PHP

PHP 8.0.0

Параметр encoding стал опциональным и по умолчанию равен null. В предыдущих версиях рекомендовалось явно указывать кодировку.

PHP 7.1.0

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

Ранние версии

В PHP 4 и ранних версиях PHP 5 функция была доступна только при включенном расширении mbstring. Сейчас расширение обычно включено по умолчанию.

Расширенные примеры

Форматирование таблицы
Пример php
function formatTableRow($name, $value) {
    $width = 30;
    $nameWidth = mb_strwidth($name);
    $dots = str_repeat('.', $width - $nameWidth);
    return $name . $dots . ' ' . $value;
}

echo formatTableRow('Продукт', '150 руб.') . "\n";
echo formatTableRow('Доставка', '300 руб.') . "\n";
echo formatTableRow('Сумма', '450 руб.');
Продукт........................ 150 руб.
Доставка...................... 300 руб.
Сумма......................... 450 руб.
Обрезка строки с учетом ширины
Пример php
function truncateByWidth($string, $maxWidth, $suffix = '...') {
    if (mb_strwidth($string) <= $maxWidth) {
        return $string;
    }
    
    $result = '';
    $currentWidth = 0;
    $suffixWidth = mb_strwidth($suffix);
    
    for ($i = 0; $i < mb_strlen($string); $i++) {
        $char = mb_substr($string, $i, 1);
        $charWidth = mb_strwidth($char);
        
        if ($currentWidth + $charWidth + $suffixWidth > $maxWidth) {
            break;
        }
        
        $result .= $char;
        $currentWidth += $charWidth;
    }
    
    return $result . $suffix;
}

echo truncateByWidth('Очень длинная строка с разными символами: 你好', 20);
Очень длинная строка...
Подсчет ширины с игнорированием управляющих последовательностей
Пример php
function visualWidth($string) {
    // Удаляем ANSI escape-последовательности
    $cleaned = preg_replace('/\x1b\[[0-9;]*m/', '', $string);
    return mb_strwidth($cleaned);
}

$colored = "\033[31mКрасный текст\033[0m";
echo visualWidth($colored);
12

Аналоги в других языках

Python

Модуль wcwidth предоставляет функцию wcswidth, которая работает аналогично.

import wcwidth
print(wcwidth.wcswidth('Hello 世界!'))
13

Mb strwidth в Javascript

Нативный аналог отсутствует. Можно использовать библиотеку string-width из npm.

const stringWidth = require('string-width');
console.log(stringWidth('Hello 世界!'));
13

Mb strwidth в MySQL

Функция CHAR_LENGTH подсчитывает символы, но не учитывает их ширину. Специальной функции для определения ширины нет.

SELECT CHAR_LENGTH('Hello 世界!');
8
Основные отличия

В отличие от PHP, Python требует установки дополнительного модуля. JavaScript не имеет встроенного решения. MySQL вообще не предоставляет такой функциональности.

PHP mb_strwidth function comments

En
Mb strwidth Return width of string