- カテゴリ: PHP
- 名前空間 / FQCN / コマンド:
explode(string $separator, string $string, int $limit = PHP_INT_MAX): array - 関連: implode / preg_split / str_getcsv / mb_str_split / strtok
- 変更履歴: PHP 8.0 以降、区切り文字が空文字の場合は
ValueErrorを投げる(7系では警告 +false)
要点(TL;DR)
- 区切り文字で文字列を配列へ分割する標準関数。
- 最低限の使い方:
$parts = explode(',', 'a,b,c'); - 罠:
- 区切り文字が空文字
''はValueError $limitが 0 は「1として扱われ分割されない」- 連続区切りや末尾区切りは空文字要素が残る(必要なら
array_filter($a, 'strlen'))
- 区切り文字が空文字
概要
explode は、指定した区切り文字で文字列を分割して配列を返します。CSV のような複雑な形式ではなく、単純な区切りの分割に向きます。ヘッダーや設定値の解析、ログの簡易トークン化など日常的な文字列処理で多用します。
構文 / シグネチャ
array explode(string $separator, string $string, int $limit = PHP_INT_MAX)
- 引数(表) 引数 型 必須 既定値 説明 $separator string はい — 区切り文字。空文字は不可(
ValueError)。 $string string はい — 分割対象の文字列。スカラーは文字列に変換される。 $limit int いいえPHP_INT_MAX正数: 最大要素数(最後の要素に残り全部)。0: 1として扱われ分割されない。負数: 末尾から `- - 戻り値:
array<string>— 分割された文字列の配列。区切りが見つからない場合は元文字列ひとつの配列。 - 例外/副作用:
ValueError:$separator === ''のときTypeError: 文字列化できないオブジェクトを渡した場合- マルチバイトはバイト列として扱う(文字境界は考慮しない)
使用例
最小例
<?php
$parts = explode(',', 'apple,banana,orange');
// ['apple', 'banana', 'orange']
// 連続区切りや末尾区切りは空文字が残る
$tokens = explode(',', 'a,,b,'); // ['a', '', 'b', '']
// 空要素を除外('0' は残したいのでコールバックに 'strlen')
$clean = array_filter($tokens, 'strlen'); // ['a', 'b']
print_r($clean);
実務例:HTTPヘッダー(X-Forwarded-For)の先頭クライアントIPを取得
<?php
$xff = '203.0.113.9, 70.41.3.18, 150.172.238.178';
// カンマ区切り + 空白をトリム
$ips = array_map('trim', explode(',', $xff));
// 先頭(クライアント起点)を取り出す
$clientIp = $ips[0] ?? null;
// 簡易バリデーション(IPv4/IPv6)
if ($clientIp !== null && filter_var($clientIp, FILTER_VALIDATE_IP)) {
// 使う
} else {
// フォールバック
}
$limit の挙動
<?php
// 正の limit: 最大 2 要素、2つ目に残り全部
explode(':', 'a:b:c', 2); // ['a', 'b:c']
// 0 は 1 として扱われる(分割されず丸ごと1要素)
explode(':', 'a:b:c', 0); // ['a:b:c']
// 負の limit: 末尾から N 要素を捨てる
explode(':', 'a:b:c:d', -1); // ['a', 'b', 'c']
explode(':', 'a:b:c:d', -2); // ['a', 'b']
マルチバイト文字の分割(1文字ずつに分けたい場合)
<?php
// explode は区切り「文字列」を探す関数。文字ごとに分割したいなら:
$chars = mb_str_split('あいうえお'); // ['あ','い','う','え','お']
よくある落とし穴・注意
- 空の区切り文字は不可:
explode('', 'abc')はValueError。 - 空要素が残る:
'a,,b,'→['a','','b','']。必要に応じてarray_filter($a, 'strlen')やarray_map('trim', ...)を併用。 - $limit=0 は分割されない:期待と逆になりがち。
- バイト単位:UTF-8 の文字境界は考慮しない。1文字単位分割は
mb_str_split、正規表現条件はpreg_split。 - 巨大文字列はメモリを消費:行単位処理なら
fgets、CSV ならfgetcsvを検討。
代替・関連APIとの比較
preg_split:正規表現で柔軟に分割。空要素除外オプションあり(PREG_SPLIT_NO_EMPTY)。複雑な条件向け。str_getcsv/fgetcsv:CSV 仕様(引用・エスケープ)を考慮。CSV 解析はexplodeではなくこちら。implode:配列を区切り文字で結合(逆方向)。mb_str_split:マルチバイトの文字単位で分割したい場合。strtok:イテレーティブにトークン化。逐次処理でメモリ効率を重視する場合に有効。
テスト例(Pest)
<?php
it('splits by delimiter', function () {
expect(explode(',', 'a,b,c'))->toBe(['a','b','c']);
});
it('keeps empty pieces and handles trailing delimiter', function () {
expect(explode(',', 'a,,b,'))->toBe(['a', '', 'b', '']);
});
it('treats limit 0 as 1', function () {
expect(explode(':', 'a:b:c', 0))->toBe(['a:b:c']);
});
it('drops last N pieces when limit is negative', function () {
expect(explode(':', 'a:b:c:d', -2))->toBe(['a','b']);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
ValueError: explode(): Argument #1 ($separator) cannot be empty | 区切り文字が空文字 | 区切り文字を1文字以上にする |
TypeError: explode(): Argument #1 ($separator) must be of type string, ... | 文字列化できない値(例: __toString を持たないオブジェクト) | 事前に (string)$sep で明示変換または妥当な区切りを渡す |
| 想定外の空要素が混ざる | 連続区切り・末尾区切り | array_filter($a, 'strlen')、rtrim($s, ',')、または preg_split('/,+/', $s) を検討 |
| 日本語が壊れる/1文字ごとに分けたい | explode はバイト基準 | mb_str_split や preg_split('//u', ...) を使う |

