PHP Tips | 文字列処理:変換系 – camelCase → snake_case

PHP PHP
スポンサーリンク

camelCase と snake_case のイメージをそろえる

まずは形の違いを頭の中でハッキリさせましょう。

camelCase はこういうスタイルです。

userName
createdAt
maxRetryCount

先頭の単語は小文字、2単語目以降の先頭が大文字になります。

snake_case はこうです。

user_name
created_at
max_retry_count

単語をすべて小文字にして、間をアンダースコア _ でつなぎます。

今回やりたいのは、

userName       → user_name
createdAt      → created_at
maxRetryCount  → max_retry_count

のように、camelCase を snake_case に変換するユーティリティです。

PHP のコード(プロパティ名・メソッド名)は camelCase、
DB のカラム名や JSON のキーは snake_case、
という設計にしているときに、めちゃくちゃよく出てきます。


変換の考え方を分解してみる

camelCase → snake_case は、考え方としてはとてもシンプルです。

「大文字が出てきたら、その前に _ を入れて、小文字にする」

これだけです。

例えば maxRetryCount なら、文字を順番に見ていくとこうなります。

  • m a x まではそのまま
  • R が出てきたら、その前に _ を入れて r にする → _retry
  • C が出てきたら、その前に _ を入れて c にする → _count

結果として max_retry_count になります。

この「大文字の前に _ を入れて、小文字にする」というルールを、コードに落とし込めばOKです。


正規表現を使ったシンプルな実装

PHP でこの「大文字の前に _ を入れる」をやるのに、一番スッキリ書けるのが正規表現です。

基本形の関数

まずは動きが分かりやすい形で書いてみます。

/**
 * camelCase を snake_case に変換
 *
 * @param string $camel
 * @return string
 */
function camelToSnake(string $camel): string
{
    // 1. 大文字の前にアンダースコアを入れる
    $withUnderscore = preg_replace('/([A-Z])/', '_$1', $camel);

    // 2. 全部小文字にそろえる
    $snake = mb_strtolower($withUnderscore, 'UTF-8');

    // 3. 先頭にアンダースコアが付いてしまうケースをケア(先頭が大文字だった場合)
    $snake = ltrim($snake, '_');

    return $snake;
}
PHP

やっていることを言葉で追うと、こうなります。

1つ目の preg_replace で、

'maxRetryCount'  'max_Retry_Count'
PHP

のように、「大文字の前に _ を差し込む」変換をしています。

そのあとで mb_strtolower で全部小文字にして、

'max_Retry_Count'  'max_retry_count'
PHP

最後に、もし先頭に _ が付いていたら ltrim で削ります。


実際に動かしてみる

いくつか例を通して、感覚をつかみましょう。

echo camelToSnake('userName');        // user_name
echo camelToSnake('createdAt');       // created_at
echo camelToSnake('maxRetryCount');   // max_retry_count
echo camelToSnake('id');              // id
echo camelToSnake('UserName');        // user_name(先頭が大文字でもケアできる)
PHP

UserName のように、先頭が大文字の camelCase っぽい文字列でも、
ltrim($snake, '_') のおかげで user_name に落ち着きます。


重要なポイントを少し深掘りする

なぜ最後に ltrim(‘_’) が必要なのか

preg_replace('/([A-Z])/', '_$1', $camel); は、
「大文字の前に _ を入れる」ので、先頭が大文字の場合はこうなります。

'UserName'  '_User_Name'
PHP

このまま小文字化すると、

'_user_name'
PHP

となり、先頭に余計な _ が付いてしまいます。

そこで、

$snake = ltrim($snake, '_');
PHP

で、先頭の _ を削っています。

これで、

UserName  user_name
PHP

という、期待どおりの変換になります。

なぜ mb_strtolower を使っているのか

strtolower でも英字だけなら動きますが、
プロジェクト全体を UTF-8 で統一しているなら、
「小文字化は mb_strtolower を使う」と決めておく方が安全です。

  • 英字だけの camelCase を扱う前提なら、どちらでもほぼ同じ
  • でも、将来アクセント付き文字などが混ざる可能性を考えると、最初から mb_* に寄せておく方が安心

という判断です。


もう少しだけきれいに書くバリエーション

正規表現を少し工夫すると、「小文字+大文字」の境目だけを狙う書き方もできます。

function camelToSnake(string $camel): string
{
    $snake = preg_replace('/([a-z0-9])([A-Z])/', '$1_$2', $camel);
    return mb_strtolower($snake, 'UTF-8');
}
PHP

このパターンは、

  • 「小文字 or 数字」のあとに「大文字」が来たところだけ
  • その間に _ を入れる

という動きになります。

maxRetryCount の場合:

  • xRx_R
  • yCy_C

結果 → max_Retry_Count → 小文字化 → max_retry_count

先頭が大文字のケース(UserName)では、

  • ([a-z0-9]) にマッチしないので、先頭には _ が入らない
  • 結果 → User_Name → 小文字化 → user_name

となり、ltrim が不要になります。

こちらの方が「余計な _ を後から削る」必要がないので、
正規表現に慣れてきたら、この書き方の方が好みになるかもしれません。


実務での使いどころ

PHP のプロパティ名 → DB カラム名

よくあるパターンはこれです。

  • PHP のプロパティ:$userName
  • DB のカラム名:user_name

保存するときに、プロパティ名からカラム名を自動で作りたい、というケースです。

$object = new stdClass();
$object->userName  = 'Taro';
$object->createdAt = '2026-01-27 10:00:00';

$data = [];

foreach ($object as $prop => $value) {
    $column = camelToSnake($prop);
    $data[$column] = $value;
}

// $data は ['user_name' => 'Taro', 'created_at' => '2026-01-27 10:00:00']
PHP

こういう「マッピング処理」の中に camelToSnake() を一つ挟むだけで、
DB 側の命名規則(snake_case)と、PHP 側の命名規則(camelCase)をきれいに橋渡しできます。

API のキー変換

自分のアプリ内では camelCase で扱っているけれど、
外部APIには snake_case で送りたい、というケースもよくあります。

$payload = [
    'userName'  => 'Taro',
    'createdAt' => '2026-01-27T10:00:00Z',
];

$converted = [];

foreach ($payload as $key => $value) {
    $converted[camelToSnake($key)] = $value;
}

// ['user_name' => 'Taro', 'created_at' => '2026-01-27T10:00:00Z']
PHP

まとめ:今日からの「camelCase → snake_case」ユーティリティ

押さえておきたいポイントをコンパクトにまとめると、こうなります。

camelCase → snake_case は、

  • 「大文字の前に _ を入れる」
  • 「全体を小文字にする」

という2ステップで考えればよいです。

正規表現を使うと、実装はとてもシンプルになります。

まずは、この関数を一つプロジェクトに置いておけば十分です。

function camelToSnake(string $camel): string
{
    $snake = preg_replace('/([a-z0-9])([A-Z])/', '$1_$2', $camel);
    return mb_strtolower($snake, 'UTF-8');
}
PHP

タイトルとURLをコピーしました