Multibyte strings7 min readExamples run on PHP 8.5.10

mb_convert_kana()

Learn how mb_convert_kana() converts between half-width and full-width Japanese characters, with mode flags, UTF-8 examples, error cases and common mistakes.

Signature

mb_convert_kana(string $string, string $mode = "KV", ?string $encoding = null): string
Available since PHP 4.0.67.48.08.18.28.38.48.5All versions →

Purpose

mb_convert_kana() converts Japanese text between the "han-kaku" (half-width) and "zen-kaku" (full-width) forms. It can also switch between katakana and hiragana. It is typically used to normalize user input before searching, comparing or storing it. Examples are full-width digits typed with a Japanese input method, or half-width katakana pasted from an old system. The manual notes that the function is only useful for Japanese text.

Signature

Parameters and defaults

  • $string: the text to convert.
  • $mode: a string of single-letter options. Each letter turns on one conversion, and you combine letters in one string. The default is "KV".
  • $encoding: the character encoding of the input. If you omit it or pass null, PHP uses the internal encoding. Passing 'UTF-8' explicitly keeps results independent of configuration.

The mode letters come in lowercase and uppercase pairs. Lowercase usually means "to half-width" and uppercase "to full-width".

  • r / R: alphabet, full-width to half-width / half-width to full-width.
  • n / N: the same for digits.
  • a / A: the same for alphabet and digits together. These cover U+0021 to U+007E, except U+0022, U+0027, U+005C and U+007E.
  • s / S: space, U+3000 to U+0020 / U+0020 to U+3000.
  • k / K: full-width katakana to half-width / half-width katakana to full-width.
  • h / H: full-width hiragana to half-width katakana / half-width katakana to full-width hiragana.
  • c / C: full-width katakana to full-width hiragana / full-width hiragana to full-width katakana.
  • V: collapse voiced sound marks into a single character. Use it together with K or H.

Return value and failure cases

The function returns the converted string. In PHP 8 it does not return false.

  • It throws a ValueError if the combination of modes is invalid. The manual gives "sS" as an example, because it asks for both directions at once. The changelog lists this behavior as new in PHP 8.2.0.
  • It throws a ValueError if $encoding is not a valid encoding. This has been the case since PHP 8.0.0, and earlier versions emitted a warning instead.

Example 1: half-width katakana to hiragana and full-width

Half-width katakana writes a voiced sound such as "da" as two code points: the base character and a separate voice mark. The V flag joins them into one character. Without V the mark stays separate.

Example
<?php
echo mb_convert_kana('ヤマダ ハナコ', 'HV', 'UTF-8') . "\n";
echo mb_convert_kana('コウザバンゴウ 0123456', 'KVa', 'UTF-8') . "\n";
Output
やまだ はなこ
コウザバンゴウ 0123456

The first call turns half-width katakana into full-width hiragana. The second turns it into full-width katakana and also turns full-width digits into ASCII digits.

Example 2: normalizing alphanumerics and spaces

The a option handles letters and digits, but it does not touch the ideographic space. Add s for that.

Example
<?php
$text = 'ABC xyz 123';
echo json_encode(mb_convert_kana($text, 'as', 'UTF-8'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
Output
"ABC xyz 123"

The result is plain ASCII, which is easier to compare, validate or index.

Example 3: invalid mode combinations

Asking for opposite space conversions in the same call is rejected, so you can catch the error when the mode comes from configuration.

Example
<?php
try {
    mb_convert_kana('A B', 'sS', 'UTF-8');
} catch (ValueError $e) {
    echo get_class($e), "\n";
}
Output
ValueError

Edge cases

  • Characters that a mode does not cover pass through unchanged, so kanji and unrelated symbols are left alone.
  • The a and A ranges leave out the double quote, apostrophe, backslash and tilde. Those characters are never converted by these options.
  • Plain ASCII space is not part of the a or A range. Use s or S for spaces.
  • V only matters when combined with K or H. On its own it has no useful effect.
  • Some conversions cannot be undone exactly. Several half-width forms map to the same full-width form, so converting back may not recover the original text.
  • An empty string returns an empty string.

Common mistakes

  1. Relying on the default mode. "KV" converts half-width katakana only. It will not touch full-width digits, so add a or n when you need them.
  2. Mixing opposite directions. Combining s and S, or similar pairs, is an invalid combination and throws.
  3. Forgetting the encoding. If the internal encoding is not UTF-8, UTF-8 input is misread. Pass the encoding explicitly.
  4. Expecting it to convert other scripts. The function is for Japanese kana, ASCII and spaces. It does not transliterate in general.
  5. Confusing h with k. k produces half-width katakana from full-width katakana. h produces half-width katakana from hiragana.
  • mb_convert_encoding() changes the character encoding of a string.
  • mb_strwidth() measures display width, where full-width characters count as two columns.
  • mb_strtolower() and mb_strtoupper() change case in a multibyte-aware way.
  • mb_internal_encoding() reads or sets the default encoding used when $encoding is null.

Recap

mb_convert_kana() takes a string, a mode string of option letters and an optional encoding. It returns the converted string. Choose each letter deliberately, pass 'UTF-8' explicitly, and avoid contradictory mode combinations, which throw a ValueError.

Tested examples

Half-width katakana to hiragana and full-width katakana
<?php
echo mb_convert_kana('ヤマダ ハナコ', 'HV', 'UTF-8') . "\n";
echo mb_convert_kana('コウザバンゴウ 0123456', 'KVa', 'UTF-8') . "\n";
Output
やまだ はなこ
コウザバンゴウ 0123456
Normalizing full-width alphanumerics and spaces
<?php
$text = 'ABC xyz 123';
echo json_encode(mb_convert_kana($text, 'as', 'UTF-8'), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) . "\n";
Output
"ABC xyz 123"
Invalid mode combination throws ValueError
<?php
try {
    mb_convert_kana('A B', 'sS', 'UTF-8');
} catch (ValueError $e) {
    echo get_class($e), "\n";
}
Output
ValueError