- カテゴリ: PHP
- 掲載バージョン: PHP 8.4
- 名前空間 / FQCN / コマンド:
range(グローバル関数) - 関連: array_fill / array_map / array_filter / array_keys / DatePeriod
- 変更履歴: PHP 8系で引数検証が厳格化。
stepが0の場合はValueError例外に(従来は警告)。
要点(TL;DR)
- 目的:開始値から終了値まで、一定刻みの値を配列で生成する
- 最小コード:
$xs = range(1, 5); // [1,2,3,4,5] - 罠:
- 巨大レンジはメモリ圧迫(配列は全要素を保持)
- 浮動小数の刻みは誤差で終端が合わないことがある
- 文字レンジは単一バイト前提(
'A'..'Z'はOK、マルチバイト不可)
概要
range() は数値や英字のシーケンスをまとめて作る関数です。ループを書かずに「1〜100」や「A〜Z」を生成でき、テストデータ作成・ページネーション・ID分割などで便利です。一方で返り値が配列のため大きな範囲生成はメモリを消費します。
構文 / シグネチャ
array range(int|float|string $start, int|float|string $end, int|float $step = 1)
- 引数(表)
| 引数 | 型 | 必須 | 既定値 | 説明 |
|---|---|---|---|---|
| $start | int|float|string | ✓ | — | 開始値。文字の場合は単一バイト文字として扱う |
| $end | int|float|string | ✓ | — | 終了値(両端含む) |
| $step | int|float | 1 | 刻み幅。負数で降順可。0は不可 |
- 戻り値:
array(0始まりの数値キー、要素は$startから$endまでの値) - 例外/副作用:
ValueError:$step === 0の場合- 浮動小数の刻みでは丸め誤差に注意
- 文字列レンジは ASCII 的挙動、マルチバイト非対応
使用例
最小例
<?php
$ints = range(1, 5); // [1,2,3,4,5]
$desc = range(5, 1, -2); // [5,3,1]
$alph = range('A', 'F'); // ['A','B','C','D','E','F']
var_dump($ints, $desc, $alph);
実務例:バルク処理を固定件数で分割
<?php
/**
* 大量レコードを1,000件ずつ処理する例
*/
$total = 125_000;
$chunk = 1_000;
foreach (range(0, $total - 1, $chunk) as $offset) {
// ここで DB から $chunk 件を取得して処理
// SELECT ... LIMIT $chunk OFFSET $offset
processChunk($offset, $chunk);
}
function processChunk(int $offset, int $limit): void
{
// 実処理(例外処理は省略)
// ...
}
実務例:日付配列を生成(小規模)
<?php
$start = new DateTimeImmutable('2024-01-01');
$days = array_map(
fn($i) => $start->modify("+$i day")->format('Y-m-d'),
range(0, 6) // 7日分
);
// ['2024-01-01','2024-01-02', ... '2024-01-07']
日付の大レンジは
DatePeriodの利用を検討。
よくある落とし穴・注意
- メモリ使用:
range(1, 10_000_000)のような大きな範囲は一括配列で保持され、メモリ不足の原因に。 - 浮動小数の誤差:
range(0, 1, 0.1)などは誤差で終端が合わないことがある。厳密さが必要なら整数で管理し、必要時にスケーリング。 - 文字列レンジの制約:
range('あ','お')は意図通り動かない(単一バイト前提)。英数字のみを想定。 step=0は例外:ValueErrorが投げられる。降順は負のstepを使う。
代替・関連APIとの比較
- for ループ:超大きい範囲は
forで逐次処理(メモリ節約)。 - Generator(
yield):必要なときだけ値を生成でき、遅延評価でメモリ効率が良い。 - DatePeriod:日付レンジは専用クラスが安全・高速。
- array_fill / array_map:
range()の結果に対して値を変換・埋める用途で組み合わせる。
Generator 例(メモリ効率)
<?php
function xrange(int $start, int $end, int $step = 1): Generator
{
if ($step === 0) {
throw new ValueError('step must not be 0');
}
if (($start <= $end && $step < 0) || ($start >= $end && $step > 0)) {
return; // 空(方向が合わない)
}
for ($i = $start; ($step > 0) ? $i <= $end : $i >= $end; $i += $step) {
yield $i;
}
}
// 例: 巨大範囲でも低メモリ
foreach (xrange(1, 10_000_000) as $i) {
// 逐次処理
}
テスト例(Pest)
<?php
it('generates inclusive integer ranges', function () {
expect(range(1, 3))->toBe([1, 2, 3]);
});
it('supports descending with negative step', function () {
expect(range(5, 1, -2))->toBe([5, 3, 1]);
});
it('generates alphabet ranges', function () {
expect(range('A', 'C'))->toBe(['A', 'B', 'C']);
});
it('throws on step zero', function () {
$fn = fn() => range(1, 5, 0);
expect($fn)->toThrow(ValueError::class);
});
トラブルシュート(エラー別)
| 症状/エラー | 原因 | 対処 |
|---|---|---|
| Allowed memory size exhausted | 範囲が大きすぎ配列が巨大化 | 分割処理に切替、Generator/for を使用 |
| 期待した終端にならない(小数) | 浮動小数誤差 | 整数でスケールして管理(例:小数第1位なら×10) |
| 日本語文字レンジが変 | 単一バイト前提の挙動 | マルチバイトは不可。必要なら独自ロジック |
ValueError: step must not be 0 | step=0 | 1 以上(または負値で降順)を指定 |
参考リンク
- PHP Manual — range
https://www.php.net/manual/en/function.range.php - PHP Manual — Generators
https://www.php.net/manual/en/language.generators.overview.php - PHP Manual — DatePeriod
https://www.php.net/manual/en/class.dateperiod.php - PHP Manual — foreach
https://www.php.net/manual/en/control-structures.foreach.php

