何をしたいユーティリティなのか
「文字種判定(英字/数字/記号)」は、 ある文字列の中に「英字」「数字」「記号」がどれくらい含まれているか、 あるいは「この文字列は英字だけか?数字だけか?記号を含んでいるか?」を判定するためのユーティリティです。
パスワードチェック、ユーザー名のバリデーション、 入力制限(英数字のみ/記号禁止/記号必須など)で、ほぼ必ず出番があります。
基本方針:1 文字ずつ「何者か」を調べる
「文字列全体」ではなく「1 文字単位」で見る
文字種判定の考え方はシンプルで、
- 文字列を 1 文字ずつ見る
- その文字が「英字か」「数字か」「記号か」を判定する
- 必要に応じてカウントしたり、フラグを立てたりする
という流れになります。
PHP には「文字種判定」に向いた関数群(ctype 系)が用意されていて、 これを使うと初心者でも読みやすいコードで書けます。
ctype 系関数で文字種を判定する
よく使う 3 種類
代表的なものはこのあたりです。
ctype_alpha($ch); // 英字かどうか
ctype_digit($ch); // 数字かどうか
ctype_punct($ch); // 記号(英数字・空白以外の印字可能文字)かどうか
PHPこれらは「引数が 1 文字の文字列」であるとき、 その文字がそのカテゴリに属しているかどうかを true/false で返してくれます。
ポイントは、「ASCII ベースの判定」であることです。 英字は A〜Z / a〜z、数字は 0〜9、記号は一般的な記号類が対象になります。
1 文字を分類する小さな関数
まずは「1 文字を英字/数字/記号のどれかに分類する」関数を作ってみます。
/**
* 1 文字を「英字」「数字」「記号」「その他」に分類する
*/
function classify_char(string $ch): string
{
// 1 文字でない場合は「その他」
if (strlen($ch) !== 1) {
return 'other';
}
if (ctype_alpha($ch)) {
return 'alpha'; // 英字
}
if (ctype_digit($ch)) {
return 'digit'; // 数字
}
if (ctype_punct($ch)) {
return 'symbol'; // 記号
}
return 'other'; // 空白や日本語など
}
PHPここでの重要ポイントは、「その他」をちゃんと用意していることです。
- 英字でも数字でも記号でもないもの(空白、日本語、絵文字など)は
other - 判定対象外のものを無理にどれかにねじ込まない
という方針にしておくと、後の処理が分かりやすくなります。
文字列全体の「文字種」を集計する
英字・数字・記号の個数を数える
次に、「文字列全体で何文字が英字/数字/記号なのか」を数えるユーティリティを作ります。
/**
* 文字列中の「英字」「数字」「記号」「その他」の個数を数える
*/
function count_char_types(string $text): array
{
$alpha = 0;
$digit = 0;
$symbol = 0;
$other = 0;
$len = strlen($text);
for ($i = 0; $i < $len; $i++) {
$ch = $text[$i];
if (ctype_alpha($ch)) {
$alpha++;
} elseif (ctype_digit($ch)) {
$digit++;
} elseif (ctype_punct($ch)) {
$symbol++;
} else {
$other++;
}
}
return [
'alpha' => $alpha,
'digit' => $digit,
'symbol' => $symbol,
'other' => $other,
];
}
PHPここでの重要ポイントは、「1 文字ずつループして、分類しながらカウントしている」ことです。 この形にしておくと、あとで「英字が 1 文字以上あるか」「記号が 2 文字以上あるか」などの条件を簡単に書けます。
例題で挙動を確認する
$text = 'Abc123!@';
$result = count_char_types($text);
var_dump($result);
PHP出力イメージはこうなります。
array(4) {
["alpha"] => int(3) // A, b, c
["digit"] => int(3) // 1, 2, 3
["symbol"] => int(2) // !, @
["other"] => int(0)
}
PHPこの結果を見れば、「英字も数字も記号も含まれている」ことが一目で分かります。
実務での使いどころ
パスワード強度チェック
よくある要件として、「英字・数字・記号をそれぞれ少なくとも 1 文字含める」というものがあります。
さっきの count_char_types を使うと、こう書けます。
$password = $_POST['password'] ?? '';
$types = count_char_types($password);
$hasAlpha = $types['alpha'] > 0;
$hasDigit = $types['digit'] > 0;
$hasSymbol = $types['symbol'] > 0;
if (!($hasAlpha && $hasDigit && $hasSymbol)) {
$error = '英字・数字・記号をそれぞれ 1 文字以上含めてください。';
}
PHP「何文字あるか」を数えているので、 「最低 2 文字以上」などの条件にも簡単に拡張できます。
ユーザー名のバリデーション(英数字のみ/記号禁止)
ユーザー名を「英数字だけにしたい」「記号は禁止したい」というケースもよくあります。
$username = $_POST['username'] ?? '';
$types = count_char_types($username);
if ($types['symbol'] > 0) {
$error = 'ユーザー名に記号は使用できません。';
}
if ($types['other'] > 0) {
$error = 'ユーザー名は英字と数字のみ使用できます。';
}
PHP「記号が 1 文字でも含まれていたら NG」「その他(日本語など)が含まれていたら NG」といったルールを、素直なコードで書けます。
正規表現で「文字種をまとめて判定する」パターン
「全部英数字か?」を一発で見る
「この文字列は全部英数字か?」だけを見たい場合は、正規表現で一発判定する方法もあります。
/**
* 文字列が「英字と数字だけ」で構成されているかを判定する
*/
function is_alnum_string(string $text): bool
{
// 空文字を許すかどうかは要件次第
if ($text === '') {
return false;
}
return (bool)preg_match('/^[A-Za-z0-9]+$/', $text);
}
PHP^[A-Za-z0-9]+$ は、
- 先頭から末尾まで
- 英字(A〜Z, a〜z)と数字(0〜9)だけ
- 1 文字以上
という意味になります。
例:
var_dump(is_alnum_string('Abc123')); // true
var_dump(is_alnum_string('Abc123!')); // false(! が入っている)
var_dump(is_alnum_string('山田123')); // false(日本語が入っている)
PHP「文字列全体が英数字だけか」を見るには、この形が分かりやすいです。
まとめ:今日からの「文字種判定(英字/数字/記号)」ユーティリティ
文字種判定の本質は、「文字列の中身を“何者か”で分類して、ルールに沿って扱えるようにする」ことです。
そのために、
- ctype_alpha / ctype_digit / ctype_punct で 1 文字ずつ分類する
- 文字列全体をループして、英字・数字・記号・その他の個数を数える
- その結果を使って「英字を含むか」「数字を含むか」「記号を禁止するか」などの条件を書く
- 必要に応じて、正規表現で「全体が英数字だけか」を一発判定する
という形のユーティリティを用意しておくと、 入力チェックやパスワード強度判定、ユーザー名バリデーションなどが、ぐっと書きやすくなります。
最後に、いちばん汎用的な集計関数をもう一度載せておきます。
function count_char_types(string $text): array
{
$alpha = 0;
$digit = 0;
$symbol = 0;
$other = 0;
$len = strlen($text);
for ($i = 0; $i < $len; $i++) {
$ch = $text[$i];
if (ctype_alpha($ch)) {
$alpha++;
} elseif (ctype_digit($ch)) {
$digit++;
} elseif (ctype_punct($ch)) {
$symbol++;
} else {
$other++;
}
}
return [
'alpha' => $alpha,
'digit' => $digit,
'symbol' => $symbol,
'other' => $other,
];
}
PHPここから先は、「あなたのシステムでどんな文字を許したいか/禁止したいか」に合わせて、 条件を足していくだけです。

