PHP で文字列の大文字・小文字を変換したいとき、よく使うのが strtoupper() / strtolower() / ucfirst() / ucwords() の4つの関数です。「すべて大文字にする」「すべて小文字にする」「先頭の1文字だけ大文字にする」「単語ごとに先頭を大文字にする」と、変換したい範囲によって使う関数が変わります。この記事では、それぞれの違いを対応表とコードで整理し、名前の整形や表記ゆれの正規化といった実用例、そして日本語など ASCII 以外の文字には効かないという注意点まで解説します。先頭を小文字にする lcfirst() にも触れます。
目次
4つの関数の違いを整理する
大文字・小文字を変換する関数は、どの範囲を変換するかで使い分けます。文字列全体を変換するのが strtoupper()(すべて大文字)と strtolower()(すべて小文字)、一部だけ変換するのが ucfirst()(先頭1文字を大文字)と ucwords()(各単語の先頭を大文字)です。いずれも引数の文字列を変換した新しい文字列を返す関数で、元の変数を書き換えるわけではありません。まずは対応関係を表で確認しておきましょう。
| 関数 | 変換する範囲 | 例(入力 → 出力) |
|---|---|---|
strtoupper() | すべての文字を大文字に | hello world → HELLO WORLD |
strtolower() | すべての文字を小文字に | Hello World → hello world |
ucfirst() | 先頭の1文字だけ大文字に | hello world → Hello world |
ucwords() | 各単語の先頭を大文字に | hello world → Hello World |
lcfirst() | 先頭の1文字だけ小文字に | Hello World → hello World |
共通しているのは、引数に文字列を1つ受け取り、変換後の文字列を戻り値として返すという点です。$result = strtoupper($text); のように、戻り値を別の変数で受け取るか、その場で使います。元の $text はそのまま残ります。
strtoupper と strtolower で全体を変換する
文字列に含まれる英字をすべて大文字にするのが strtoupper()、すべて小文字にするのが strtolower() です。アルファベット以外の文字(数字・記号・空白など)はそのまま残ります。
<?php
$text = 'Hello, PHP 8!';
echo strtoupper($text); // すべて大文字に
// HELLO, PHP 8!
echo "\n";
echo strtolower($text); // すべて小文字に
// hello, php 8!
数字の 8 やカンマ・感嘆符はそのままで、英字部分だけが変換されています。すべて大文字の見出しを作りたいときや、後述する表記ゆれの正規化のために文字列をそろえたいときに使います。
ucfirst で先頭の1文字を大文字にする
ucfirst() は、文字列の先頭の1文字だけを大文字にします。2文字目以降には手を付けません。文章の書き出しや、英単語の頭文字をそろえたいときに使います。
<?php
echo ucfirst('hello world');
// Hello world ← 先頭の h だけ大文字。world はそのまま
echo "\n";
// 2文字目以降は変換されない点に注意
echo ucfirst('hELLO');
// HELLO ← 先頭は元から大文字相当、ELLO はそのまま残る
echo "\n";
// 先頭を小文字にしたいときは lcfirst()
echo lcfirst('Hello World');
// hello World ← 先頭の H だけ小文字に
注意したいのは、ucfirst() は先頭以外の文字には一切触れないという点です。'hELLO' を渡すと先頭の h が H になるだけで、続く ELLO はそのまま残ります。「先頭だけ大文字、残りは小文字」というきれいな整形をしたい場合は、いったん strtolower() で全体を小文字にしてから ucfirst() を掛けると確実です。先頭を逆に小文字へ変えたいときは lcfirst() を使います。
ucwords で単語ごとに先頭を大文字にする
ucwords() は、文字列に含まれる各単語の先頭を大文字にします。人名や見出しのように、複数の単語の頭文字をそろえて大文字にしたいときに便利です。
<?php
echo ucwords('hello world from php');
// Hello World From Php ← 各単語の先頭が大文字に
echo "\n";
// ucwords は2文字目以降を変換しない
echo ucwords('hELLO wORLD');
// HELLO WORLD ← 各単語の先頭だけ大文字、残りはそのまま
ここでも変換されるのは各単語の先頭1文字だけで、それ以降の文字は変わりません。'hELLO wORLD' のように2文字目以降が大文字混じりだと残ってしまうため、「先頭だけ大文字で残りは小文字」にしたいなら、ucwords(strtolower($text)) のように先に小文字化してから掛けるのが定番です。
ucwords の区切り文字を指定する(第2引数)
ucwords() が「単語の区切り」と見なす文字は、既定では半角スペース・タブ・改行・キャリッジリターン・水平タブ・垂直タブ(" \t\r\n\f\v")です。つまり標準ではスペースなどで区切られた語の先頭だけが大文字になります。ハイフンやアンダースコアなど別の区切り文字でも大文字にしたい場合は、第2引数 $separators(区切り文字)に、区切りとして扱いたい文字をまとめた文字列を渡します。
<?php
// 既定ではスペースだけが区切り。ハイフンは区切りとみなされない
echo ucwords('hello-world example');
// Hello-world Example
echo "\n";
// 第2引数でハイフンも区切り文字として指定する
echo ucwords('hello-world example', " -");
// Hello-World Example ← ハイフンの後ろも大文字に
echo "\n";
// 第2引数を指定すると、既定の区切り文字(スペース等)は
// 上書きされる。スペースも区切りたいなら一緒に含める
echo ucwords('a-b c-d', "-");
// A-B c-d ← スペースを含めなかったので c は大文字にならない
ここで気をつけたいのは、第2引数を指定すると既定の区切り文字がすべて置き換わることです。たとえば "-" だけを渡すと、ハイフンは区切りとして扱われる一方で、スペースは区切りと見なされなくなります。スペースとハイフンの両方で区切りたいなら、" -" のように両方を含めた文字列を渡す必要があります。区切り文字は「この文字の直後の1文字を大文字にする」という意味で働く、と覚えておくと理解しやすいです。
表記ゆれをそろえて比較する
これらの関数が実務で役立つ場面のひとつが、大文字・小文字の違いを無視した比較です。ユーザーが入力したメールアドレスやタグ名は Example・EXAMPLE・example のように表記がばらつきます。そのまま === で比較すると別物として扱われてしまうため、両方を strtolower() でそろえてから比較すると、見た目の大文字小文字に左右されずに判定できます。
<?php
$input = 'Taro.Yamada@Example.com';
$expected = 'taro.yamada@example.com';
// そのままだと大文字小文字の違いで一致しない
var_dump($input === $expected);
// bool(false)
// 両方を小文字にそろえてから比較すると一致する
var_dump(strtolower($input) === strtolower($expected));
// bool(true)
このように、保存・比較するキーは小文字にそろえておくと表記ゆれによる重複や取りこぼしを防げます。なお、大文字小文字を区別せずに文字列を比較するだけなら、専用の strcasecmp() 関数を使う方法もあります。表示用には ucwords(strtolower($name)) で名前を整形し、内部の比較には strtolower() でそろえた値を使う、といった使い分けが定番です。
日本語など ASCII 以外の文字は変換されない
つまずきやすいのが、これらの関数が「英字(ASCII の a〜z / A〜Z)」だけを対象にしている点です。strtoupper() などは1バイトずつ処理するため、日本語(ひらがな・カタカナ・漢字)のようなマルチバイト文字は変換されません。全角の英字も対象外です。
<?php
// 半角英字は変換されるが、日本語や全角英字はそのまま
echo strtoupper('php と php');
// PHP と php ← 半角の php だけが PHP に
echo "\n";
// マルチバイト文字も含めて変換したいときは mb_ 系を使う
echo mb_strtoupper('php と php', 'UTF-8');
// PHP と PHP ← 全角英字も大文字になる
上の例のように、半角の php は PHP になりますが、全角の php はそのまま残ります。全角英字やアクセント付き文字なども含めて大文字小文字を変換したいときは、マルチバイト対応の mb_strtoupper() / mb_strtolower() を、文字エンコーディング(通常は 'UTF-8')を指定して使います。ただし ucfirst() や ucwords() に相当する mb_ 関数は標準には用意されていないため、日本語混じりの文字列で頭文字だけを大文字にしたいような場合は、変換したい部分を切り出して処理するなどの工夫が必要です。
まとめ
大文字・小文字の変換は、変換したい範囲で関数を選ぶのが基本です。要点を振り返ります。
strtoupper()/strtolower()は文字列全体を大文字・小文字に変換するucfirst()は先頭1文字、ucwords()は各単語の先頭を大文字にする(lcfirst()は先頭を小文字に)ucfirst()・ucwords()は先頭以外を変えないので、整形にはstrtolower()と組み合わせるucwords()の第2引数で区切り文字を指定でき、指定すると既定の区切り(スペース等)は上書きされる- 対象は ASCII の英字のみ。日本語や全角英字には効かないので、必要なら
mb_strtoupper()系を使う - 表記ゆれの比較は、両方を
strtolower()でそろえてから行う
「全体か、先頭か、単語ごとか」という変換範囲と、「ASCII 英字しか対象にならない」という性質さえ押さえておけば、4つの関数を迷わず使い分けられます。日本語を含む文字列を扱うときは mb_ 系の存在も思い出してください。