ヘルパー関数
Laravel が用意している便利なヘルパー関数(配列・数値・パス・URL・そのほか)を分類ごとに全部並べ、使い方の例と、時間の計測や遅延実行などの便利な道具も説明します。
ヘルパー関数は、どこからでも呼べる、Laravel の便利な PHP の関数です。Laravel の内部でもたくさん使われていますが、便利だと思えば、自分のアプリでも自由に使えます。道具箱の中の、よく使う工具のようなものです。このページでは、関数を「配列とオブジェクト」「数値」「パス」「URL」「そのほか」に分けて、全部を表に並べます。そのあとに、時間の計測や遅延実行などの「そのほかの便利な道具」を説明します。
以降の例では、ふつうの関数は名前だけで呼びます。Arr:: や Number:: で始まるものは、それぞれ Illuminate\Support\Arr と Illuminate\Support\Number というクラスのメソッド(クラスの中の関数)です。使うときは、先に読みこみます。
use Illuminate\Support\Arr;
use Illuminate\Support\Number;
配列とオブジェクト#
配列やオブジェクトを扱う関数です。「ドット記法」は、'products.desk.price' のように、深い所にある値を、名前を「.」でつないで指す書き方です。「多次元の配列」は、配列の中に配列が入ったものです。表の「例外を投げる」は、エラーの知らせを出して、そこで処理を止めることです。
配列の関数の一覧#
| 名前 | 説明 |
|---|---|
Arr::accessible |
値が、配列のように使えるかを調べる |
Arr::add |
キーが無い(または null の)ときだけ、キーと値を足す |
Arr::array |
ドット記法で値を取り出す。配列でなければ例外を投げる |
Arr::boolean |
ドット記法で値を取り出す。真偽値でなければ例外を投げる |
Arr::collapse |
配列の配列を、1つの配列にまとめる |
Arr::crossJoin |
配列どうしの、すべての組み合わせを作る |
Arr::divide |
キーの配列と値の配列の、2つに分ける |
Arr::dot |
多次元の配列を、ドット記法のキーの1段の配列にする |
Arr::every |
すべての値が、条件に合うかを調べる |
Arr::except |
指定したキーを取り除く |
Arr::exceptValues |
指定した値を取り除く |
Arr::exists |
キーが配列にあるかを調べる |
Arr::first |
条件に合う、最初の要素を返す |
Arr::flatten |
多次元の配列を、1段の配列にする |
Arr::float |
ドット記法で値を取り出す。小数でなければ例外を投げる |
Arr::forget |
ドット記法で指した値を取り除く |
Arr::from |
いろいろな入力を、ふつうの配列に変える |
Arr::get |
ドット記法で値を取り出す |
Arr::has |
ドット記法で、キーがあるかを調べる |
Arr::hasAll |
ドット記法で、すべてのキーがあるかを調べる |
Arr::hasAny |
ドット記法で、どれか1つでもキーがあるかを調べる |
Arr::integer |
ドット記法で値を取り出す。整数でなければ例外を投げる |
Arr::isAssoc |
連想配列(名前と値の組の並び)かを調べる |
Arr::isList |
キーが 0 から順の整数の配列かを調べる |
Arr::join |
要素を文字でつなぐ。最後の要素だけ別の文字でつなげる |
Arr::keyBy |
指定した項目をキーにした配列にする |
Arr::last |
条件に合う、最後の要素を返す |
Arr::map |
各要素を関数で変えた、新しい配列を作る |
Arr::mapSpread |
入れ子の要素を、関数の引数に展開して変える |
Arr::mapWithKeys |
関数が返した「キーと値」で、新しい配列を作る |
Arr::only |
指定したキーだけを残す |
Arr::onlyValues |
指定した値だけを残す |
Arr::partition |
条件に合うものと合わないものの、2つに分ける |
Arr::pluck |
指定したキーの値だけを集める |
Arr::prepend |
配列の先頭に足す |
Arr::prependKeysWith |
すべてのキーの前に、同じ文字を付ける |
Arr::pull |
値を取り出して、配列からは取り除く |
Arr::push |
ドット記法で指した配列に、値を足す |
Arr::query |
配列を、URL のクエリ文字列にする |
Arr::random |
配列から、ランダムに値を返す |
Arr::reject |
条件に合うものを取り除く |
Arr::select |
配列の配列から、指定した項目だけを取り出す |
Arr::set |
ドット記法で指した所に、値を入れる |
Arr::shuffle |
要素をランダムに並べかえる |
Arr::sole |
条件に合う値が1つだけのときに、それを返す |
Arr::some |
1つでも条件に合う値があるかを調べる |
Arr::sort |
値で並べかえる |
Arr::sortDesc |
値で、大きい順に並べかえる |
Arr::sortRecursive |
入れ子の配列も、まとめて並べかえる |
Arr::string |
ドット記法で値を取り出す。文字列でなければ例外を投げる |
Arr::take |
先頭(または後ろ)から、指定した数だけ取る |
Arr::toCssClasses |
条件に合う CSS のクラスだけを、文字列にする |
Arr::toCssStyles |
条件に合う CSS のスタイルだけを、文字列にする |
Arr::undot |
ドット記法の1段の配列を、多次元の配列に戻す |
Arr::where |
条件に合うものだけを残す |
Arr::whereNotNull |
null の値を取り除く |
Arr::wrap |
値を配列で包む(すでに配列ならそのまま) |
data_fill |
配列やオブジェクトの、まだ無い値だけを入れる |
data_get |
配列やオブジェクトから、ドット記法で値を取り出す |
data_set |
配列やオブジェクトに、ドット記法で値を入れる |
data_forget |
配列やオブジェクトから、ドット記法で値を取り除く |
head |
配列の最初の要素を返す(空なら false) |
last |
配列の最後の要素を返す(空なら false) |
調べる・取り出す#
// 配列のように使えるか調べる
Arr::accessible(['a' => 1, 'b' => 2]); // true
Arr::accessible(new Collection); // true
Arr::accessible('abc'); // false
Arr::accessible(new stdClass); // false
// キーがあるか調べる
Arr::exists(['name' => 'John Doe', 'age' => 17], 'name'); // true
Arr::exists(['name' => 'John Doe', 'age' => 17], 'salary'); // false
// ドット記法で値を取り出す
$array = ['products' => ['desk' => ['price' => 100]]];
Arr::get($array, 'products.desk.price'); // 100
Arr::get($array, 'products.desk.discount', 0); // 0(3つ目は、無いときの既定値)
// ドット記法で、キーがあるか調べる
$array = ['product' => ['name' => 'Desk', 'price' => 100]];
Arr::has($array, 'product.name'); // true
Arr::has($array, ['product.price', 'product.discount']); // false(1つでも無ければ false)
Arr::hasAny($array, ['product.name', 'product.discount']); // true
Arr::hasAny($array, ['category', 'product.discount']); // false
$array = ['name' => 'Taylor', 'language' => 'PHP'];
Arr::hasAll($array, ['name', 'language']); // true
Arr::hasAll($array, ['name', 'IDE']); // false
// 連想配列か・リストか
Arr::isAssoc(['product' => ['name' => 'Desk', 'price' => 100]]); // true
Arr::isAssoc([1, 2, 3]); // false
Arr::isList(['foo', 'bar', 'baz']); // true
Arr::isList(['product' => ['name' => 'Desk', 'price' => 100]]); // false
型を決めて取り出す関数は、Arr::get と同じように、ドット記法で値を取り出します。ちがうのは、値が決めた型でないときです。そのときは、InvalidArgumentException という例外を投げます。
$array = ['name' => 'Joe', 'languages' => ['PHP', 'Ruby'], 'available' => true, 'balance' => 123.45, 'age' => 42];
Arr::array($array, 'languages'); // ['PHP', 'Ruby']
Arr::array($array, 'name'); // 例外を投げる
Arr::boolean($array, 'available'); // true
Arr::boolean($array, 'name'); // 例外を投げる
Arr::float($array, 'balance'); // 123.45
Arr::float($array, 'name'); // 例外を投げる
Arr::integer($array, 'age'); // 42
Arr::integer($array, 'name'); // 例外を投げる
Arr::string($array, 'name'); // Joe
Arr::string($array, 'languages'); // 例外を投げる
条件に合う要素を取り出す関数です。関数(クロージャ)には、値とキーが渡されます。
$array = [100, 200, 300];
Arr::first($array, function (int $value, int $key) {
return $value >= 150;
}); // 200
Arr::first($array, $callback, $default); // 3つ目は、合うものが無いときの既定値
$array = [100, 200, 300, 110];
Arr::last($array, function (int $value, int $key) {
return $value >= 150;
}); // 300
Arr::last($array, $callback, $default); // 3つ目は、合うものが無いときの既定値
// 合うものがちょうど1つのときだけ取り出す
// 2つ以上なら MultipleItemsFoundException、1つも無ければ ItemNotFoundException を投げる
$array = ['Desk', 'Table', 'Chair'];
Arr::sole($array, fn (string $value) => $value === 'Desk'); // 'Desk'
// すべてが条件に合うか、1つでも合うか
Arr::every([1, 2, 3], fn ($i) => $i > 0); // true
Arr::every([1, 2, 3], fn ($i) => $i > 2); // false
Arr::some([1, 2, 3], fn ($i) => $i > 2); // true
// 先頭と最後の要素(空の配列なら false)
head([100, 200, 300]); // 100
last([100, 200, 300]); // 300
足す・入れる・取り除く#
// キーが無い(または null の)ときだけ足す
Arr::add(['name' => 'Desk'], 'price', 100); // ['name' => 'Desk', 'price' => 100]
Arr::add(['name' => 'Desk', 'price' => null], 'price', 100); // ['name' => 'Desk', 'price' => 100]
// 先頭に足す
Arr::prepend(['one', 'two', 'three', 'four'], 'zero'); // ['zero', 'one', 'two', 'three', 'four']
Arr::prepend(['price' => 100], 'Desk', 'name'); // ['name' => 'Desk', 'price' => 100]
// ドット記法で、配列に値を足す(無ければ作る)
$array = [];
Arr::push($array, 'office.furniture', 'Desk');
// $array: ['office' => ['furniture' => ['Desk']]]
// ドット記法で値を入れる
$array = ['products' => ['desk' => ['price' => 100]]];
Arr::set($array, 'products.desk.price', 200);
// ['products' => ['desk' => ['price' => 200]]]
// ドット記法で値を取り除く
$array = ['products' => ['desk' => ['price' => 100]]];
Arr::forget($array, 'products.desk');
// ['products' => []]
// 値を取り出して、配列からは取り除く
$array = ['name' => 'Desk', 'price' => 100];
$name = Arr::pull($array, 'name');
// $name: Desk、$array: ['price' => 100]
Arr::pull($array, $key, $default); // 3つ目は、キーが無いときの既定値
// 指定したキーを取り除く・残す
$array = ['name' => 'Desk', 'price' => 100, 'orders' => 10];
Arr::except($array, ['price']); // ['name' => 'Desk', 'orders' => 10]
Arr::only($array, ['name', 'price']); // ['name' => 'Desk', 'price' => 100]
// 指定した値を取り除く・残す(strict: true で、型まで同じものだけを対象にする)
$array = ['foo', 'bar', 'baz', 'qux'];
Arr::exceptValues($array, ['foo', 'baz']); // ['bar', 'qux']
Arr::onlyValues($array, ['foo', 'baz']); // ['foo', 'baz']
$array = [1, '1', 2, '2'];
Arr::exceptValues($array, [1, 2], strict: true); // ['1', '2']
Arr::onlyValues($array, [1, 2], strict: true); // [1, 2]
// 条件で取り除く・残す
$array = [100, '200', 300, '400', 500];
Arr::reject($array, function (string|int $value, int $key) {
return is_string($value);
}); // [0 => 100, 2 => 300, 4 => 500]
Arr::where($array, function (string|int $value, int $key) {
return is_string($value);
}); // [1 => '200', 3 => '400']
// null を取り除く
Arr::whereNotNull([0, null]); // [0 => 0]
data_fill・data_set・data_forget は、配列だけでなくオブジェクトにも使えます。*(ワイルドカード)で、すべての要素をまとめて指せます。
// まだ無い値だけを入れる
$data = ['products' => ['desk' => ['price' => 100]]];
data_fill($data, 'products.desk.price', 200);
// ['products' => ['desk' => ['price' => 100]]](すでにあるので変わらない)
data_fill($data, 'products.desk.discount', 10);
// ['products' => ['desk' => ['price' => 100, 'discount' => 10]]]
$data = [
'products' => [
['name' => 'Desk 1', 'price' => 100],
['name' => 'Desk 2'],
],
];
data_fill($data, 'products.*.price', 200);
// 2つ目の price だけが 200 で入る
// 値を入れる(既定では、あるものも上書きする)
$data = ['products' => ['desk' => ['price' => 100]]];
data_set($data, 'products.desk.price', 200);
// ['products' => ['desk' => ['price' => 200]]]
$data = [
'products' => [
['name' => 'Desk 1', 'price' => 100],
['name' => 'Desk 2', 'price' => 150],
],
];
data_set($data, 'products.*.price', 200);
// どちらの price も 200 になる
// 上書きしたくないときは overwrite: false
$data = ['products' => ['desk' => ['price' => 100]]];
data_set($data, 'products.desk.price', 200, overwrite: false);
// ['products' => ['desk' => ['price' => 100]]]
// 値を取り除く
$data = ['products' => ['desk' => ['price' => 100]]];
data_forget($data, 'products.desk.price');
// ['products' => ['desk' => []]]
$data = [
'products' => [
['name' => 'Desk 1', 'price' => 100],
['name' => 'Desk 2', 'price' => 150],
],
];
data_forget($data, 'products.*.price');
// どちらの price も取り除かれる
data_get は、配列やオブジェクトから値を取り出します。無いときの既定値、* のワイルドカード、最初と最後を指す {first} と {last} が使えます。
$data = ['products' => ['desk' => ['price' => 100]]];
data_get($data, 'products.desk.price'); // 100
data_get($data, 'products.desk.discount', 0); // 0
$data = [
'product-one' => ['name' => 'Desk 1', 'price' => 100],
'product-two' => ['name' => 'Desk 2', 'price' => 150],
];
data_get($data, '*.name'); // ['Desk 1', 'Desk 2']
$flight = [
'segments' => [
['from' => 'LHR', 'departure' => '9:00', 'to' => 'IST', 'arrival' => '15:00'],
['from' => 'IST', 'departure' => '16:00', 'to' => 'PKX', 'arrival' => '20:00'],
],
];
data_get($flight, 'segments.{first}.arrival'); // 15:00
変える・まとめる・並べかえる#
// 配列の配列を、1つにまとめる
Arr::collapse([[1, 2, 3], [4, 5, 6], [7, 8, 9]]); // [1, 2, 3, 4, 5, 6, 7, 8, 9]
// すべての組み合わせ
Arr::crossJoin([1, 2], ['a', 'b']);
// [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
Arr::crossJoin([1, 2], ['a', 'b'], ['I', 'II']);
// 3つの配列でも使える(2 × 2 × 2 で8通りの組み合わせ)
// キーと値に分ける
[$keys, $values] = Arr::divide(['name' => 'Desk']);
// $keys: ['name']、$values: ['Desk']
// 多次元の配列を、ドット記法の1段にする・戻す
Arr::dot(['products' => ['desk' => ['price' => 100]]]);
// ['products.desk.price' => 100]
Arr::undot([
'user.name' => 'Kevin Malone',
'user.occupation' => 'Accountant',
]);
// ['user' => ['name' => 'Kevin Malone', 'occupation' => 'Accountant']]
// 1段の配列にする
Arr::flatten(['name' => 'Joe', 'languages' => ['PHP', 'Ruby']]); // ['Joe', 'PHP', 'Ruby']
// 配列に変える(オブジェクト、Arrayable、Enumerable、Jsonable、JsonSerializable、
// Traversable、WeakMap などに対応)
Arr::from((object) ['foo' => 'bar']); // ['foo' => 'bar']
// つなぐ(3つ目は、最後の要素の前につなぐ文字)
$array = ['Tailwind', 'Alpine', 'Laravel', 'Livewire'];
Arr::join($array, ', '); // Tailwind, Alpine, Laravel, Livewire
Arr::join($array, ', ', ', and '); // Tailwind, Alpine, Laravel, and Livewire
// 指定した項目をキーにする(同じキーは、最後の1つだけが残る)
$array = [
['product_id' => 'prod-100', 'name' => 'Desk'],
['product_id' => 'prod-200', 'name' => 'Chair'],
];
Arr::keyBy($array, 'product_id');
// ['prod-100' => [...], 'prod-200' => [...]]
// 各要素を関数で変える
Arr::map(['first' => 'james', 'last' => 'kirk'], function (string $value, string $key) {
return ucfirst($value);
}); // ['first' => 'James', 'last' => 'Kirk']
// 入れ子の要素を、引数に展開して変える
Arr::mapSpread([[0, 1], [2, 3], [4, 5], [6, 7], [8, 9]], function (int $even, int $odd) {
return $even + $odd;
}); // [1, 5, 9, 13, 17]
// 関数が返した「キーと値」で新しい配列を作る
$array = [
['name' => 'John', 'department' => 'Sales', 'email' => 'john@example.com'],
['name' => 'Jane', 'department' => 'Marketing', 'email' => 'jane@example.com'],
];
Arr::mapWithKeys($array, function (array $item, int $key) {
return [$item['email'] => $item['name']];
}); // ['john@example.com' => 'John', 'jane@example.com' => 'Jane']
// 2つに分ける(配列の分割代入と組み合わせる)
$numbers = [1, 2, 3, 4, 5, 6];
[$underThree, $equalOrAboveThree] = Arr::partition($numbers, function (int $i) {
return $i < 3;
});
// $underThree: [1, 2]、$equalOrAboveThree: [3, 4, 5, 6]
// 指定したキーの値だけを集める(3つ目は、結果のキーにする項目)
$array = [
['developer' => ['id' => 1, 'name' => 'Taylor']],
['developer' => ['id' => 2, 'name' => 'Abigail']],
];
Arr::pluck($array, 'developer.name'); // ['Taylor', 'Abigail']
Arr::pluck($array, 'developer.name', 'developer.id'); // [1 => 'Taylor', 2 => 'Abigail']
// キーの前に文字を付ける
Arr::prependKeysWith(['name' => 'Desk', 'price' => 100], 'product.');
// ['product.name' => 'Desk', 'product.price' => 100]
// クエリ文字列にする
Arr::query([
'name' => 'Taylor',
'order' => ['column' => 'created_at', 'direction' => 'desc'],
]);
// name=Taylor&order%5Bcolumn%5D=created_at&order%5Bdirection%5D=desc
// ランダムに取り出す(個数を渡すと、1つでも配列で返る)
Arr::random([1, 2, 3, 4, 5]); // 4(ランダム)
Arr::random([1, 2, 3, 4, 5], 2); // [2, 5](ランダム)
// ランダムに並べかえる
Arr::shuffle([1, 2, 3, 4, 5]); // [3, 2, 5, 1, 4](ランダム)
// 必要な項目だけを取り出す
$array = [
['id' => 1, 'name' => 'Desk', 'price' => 200],
['id' => 2, 'name' => 'Table', 'price' => 150],
['id' => 3, 'name' => 'Chair', 'price' => 300],
];
Arr::select($array, ['name', 'price']);
// [['name' => 'Desk', 'price' => 200], ['name' => 'Table', 'price' => 150], ['name' => 'Chair', 'price' => 300]]
// 先頭から(負の数なら後ろから)取る
Arr::take([0, 1, 2, 3, 4, 5], 3); // [0, 1, 2]
Arr::take([0, 1, 2, 3, 4, 5], -2); // [4, 5]
// 値で並べかえる(関数の結果で並べかえることもできる)
$array = ['Desk', 'Table', 'Chair'];
Arr::sort($array); // ['Chair', 'Desk', 'Table']
Arr::sortDesc($array); // ['Table', 'Desk', 'Chair']
$array = [
['name' => 'Desk'],
['name' => 'Table'],
['name' => 'Chair'],
];
$sorted = array_values(Arr::sort($array, function (array $value) {
return $value['name'];
})); // Chair、Desk、Table の順
// 入れ子の配列も並べかえる。数字のキーの配列は sort、連想配列は ksort
$array = [
['Roman', 'Taylor', 'Li'],
['PHP', 'Ruby', 'JavaScript'],
['one' => 1, 'two' => 2, 'three' => 3],
];
Arr::sortRecursive($array);
// [['JavaScript', 'PHP', 'Ruby'], ['one' => 1, 'three' => 3, 'two' => 2], ['Li', 'Roman', 'Taylor']]
Arr::sortRecursiveDesc($array); // 大きい順にしたいときはこちら
// 配列で包む
Arr::wrap('Laravel'); // ['Laravel']
Arr::wrap(null); // []
CSS のクラスとスタイルを作る#
Arr::toCssClasses は、条件に合うクラスだけを、文字列にまとめます。キーに足したいクラス、値に条件を書きます。キーが数字の要素は、いつでも入ります。
$isActive = false;
$hasError = true;
$array = ['p-4', 'font-bold' => $isActive, 'bg-red' => $hasError];
Arr::toCssClasses($array); // 'p-4 bg-red'
Arr::toCssStyles も同じ形で、CSS のスタイルを文字列にまとめます。
$hasColor = true;
$array = ['background-color: blue', 'color: blue' => $hasColor];
Arr::toCssStyles($array); // 'background-color: blue; color: blue;'
補足
この2つは、Blade コンポーネントの属性にクラスを足す機能と、Blade の @class ディレクティブ(@ で始まる Blade の命令)の裏で使われています。
数値#
数値を、読みやすい形の文字列にしたり、読みとったりする Number クラスのメソッドです。
数値のメソッドの一覧#
| 名前 | 説明 |
|---|---|
Number::abbreviate |
1K・1.23M のように、単位を短くした形にする |
Number::clamp |
数が、決めた範囲の中に収まるようにする |
Number::currency |
通貨の形の文字列にする |
Number::defaultCurrency |
Number クラスが使っている、既定の通貨を返す |
Number::defaultLocale |
Number クラスが使っている、既定のロケール(言語・地域の設定)を返す |
Number::fileSize |
バイト数を、ファイルの大きさの形(KB・MB など)にする |
Number::forHumans |
1 thousand のように、言葉を使った読みやすい形にする |
Number::format |
ロケールに合わせた形の文字列にする |
Number::ordinal |
1st・2nd のような、順番の形にする |
Number::pairs |
範囲を、決めた幅ごとの組(小さな範囲)に分ける |
Number::parse |
ロケールに合わせた数の文字列を、数として読みとる |
Number::parseInt |
文字列を、整数として読みとる |
Number::parseFloat |
文字列を、小数として読みとる |
Number::percentage |
パーセントの形の文字列にする |
Number::spell |
数を、英語などの言葉の文字列にする |
Number::spellOrdinal |
順番を、言葉の文字列にする |
Number::trim |
小数点より後ろの、終わりの 0 を取り除く |
Number::useLocale |
既定のロケールを、全体で決める |
Number::withLocale |
一時的に、指定したロケールで関数を動かす |
Number::useCurrency |
既定の通貨を、全体で決める |
Number::withCurrency |
一時的に、指定した通貨で関数を動かす |
使い方の例#
// 単位を短くする
Number::abbreviate(1000); // 1K
Number::abbreviate(489939); // 490K
Number::abbreviate(1230000, precision: 2); // 1.23M
// 範囲に収める
Number::clamp(105, min: 10, max: 100); // 100
Number::clamp(5, min: 10, max: 100); // 10
Number::clamp(10, min: 10, max: 100); // 10
Number::clamp(20, min: 10, max: 100); // 20
// 通貨の形にする
Number::currency(1000); // $1,000.00
Number::currency(1000, in: 'EUR'); // €1,000.00
Number::currency(1000, in: 'EUR', locale: 'de'); // 1.000,00 €
Number::currency(1000, in: 'EUR', locale: 'de', precision: 0); // 1.000 €
// 既定の通貨・ロケール
Number::defaultCurrency(); // USD
Number::defaultLocale(); // en
// ファイルの大きさの形にする
Number::fileSize(1024); // 1 KB
Number::fileSize(1024 * 1024); // 1 MB
Number::fileSize(1024, precision: 2); // 1.00 KB
// 言葉を使った形にする
Number::forHumans(1000); // 1 thousand
Number::forHumans(489939); // 490 thousand
Number::forHumans(1230000, precision: 2); // 1.23 million
// ロケールに合わせた形にする
Number::format(100000); // 100,000
Number::format(100000, precision: 2); // 100,000.00
Number::format(100000.123, maxPrecision: 2); // 100,000.12
Number::format(100000, locale: 'de'); // 100.000
// 順番の形にする
Number::ordinal(1); // 1st
Number::ordinal(2); // 2nd
Number::ordinal(21); // 21st
// 範囲を組に分ける。ページ送りや、仕事を小分けにするときに使える
Number::pairs(25, 10); // [[0, 9], [10, 19], [20, 25]]
Number::pairs(25, 10, offset: 0); // [[0, 10], [10, 20], [20, 25]]
// 文字列を数として読みとる(PHP の NumberFormatter を使う)
Number::parse('10,123', locale: 'en'); // 10123.0
Number::parse('10,123', locale: 'fr'); // 10.123
Number::parseInt('10.123'); // (int) 10
Number::parseInt('10,123', locale: 'fr'); // (int) 10
Number::parseFloat('10'); // (float) 10.0
Number::parseFloat('10', locale: 'fr'); // (float) 10.0
// パーセントの形にする
Number::percentage(10); // 10%
Number::percentage(10, precision: 2); // 10.00%
Number::percentage(10.123, maxPrecision: 2); // 10.12%
Number::percentage(10, precision: 2, locale: 'de'); // 10,00%
// 言葉の文字列にする
Number::spell(102); // one hundred and two
Number::spell(88, locale: 'fr'); // quatre-vingt-huit
// after の値より大きい数だけを、言葉にする
Number::spell(10, after: 10); // 10
Number::spell(11, after: 10); // eleven
// until の値より小さい数だけを、言葉にする
Number::spell(5, until: 10); // five
Number::spell(10, until: 10); // 10
Number::spellOrdinal(1); // first
Number::spellOrdinal(2); // second
Number::spellOrdinal(21); // twenty-first
// 終わりの 0 を取り除く
Number::trim(12.0); // 12
Number::trim(12.30); // 12.3
useLocale と useCurrency は、アプリ全体の既定のロケールと通貨を決めます。そのあとの Number のメソッドは、この既定に合わせた形で文字列を作ります。ふつうは、サービスプロバイダ(アプリの起動のときに道具を登録する場所)の boot メソッドに書きます。
/**
* Bootstrap any application services.
*/
public function boot(): void
{
Number::useLocale('de');
Number::useCurrency('GBP');
}
withLocale と withCurrency は、渡した関数が動いているあいだだけ、指定したロケールや通貨を使います。関数が終わると、元に戻ります。
$number = Number::withLocale('de', function () {
return Number::format(1500);
});
$number = Number::withCurrency('GBP', function () {
// ...
});
パス#
アプリのフォルダの、完全なパス(場所)を返す関数です。引数にファイルの名前を渡すと、そのフォルダの中のファイルの完全なパスを作れます。
| 名前 | 説明 |
|---|---|
app_path |
app フォルダの完全なパス |
base_path |
アプリの一番上のフォルダの完全なパス |
config_path |
config フォルダの完全なパス |
database_path |
database フォルダの完全なパス |
lang_path |
lang フォルダの完全なパス |
public_path |
public フォルダの完全なパス |
resource_path |
resources フォルダの完全なパス |
storage_path |
storage フォルダの完全なパス |
$path = app_path();
$path = app_path('Http/Controllers/Controller.php');
$path = base_path();
$path = base_path('vendor/bin');
$path = config_path();
$path = config_path('app.php');
$path = database_path();
$path = database_path('factories/UserFactory.php');
$path = lang_path();
$path = lang_path('en/messages.php');
$path = public_path();
$path = public_path('css/app.css');
$path = resource_path();
$path = resource_path('sass/app.scss');
$path = storage_path();
$path = storage_path('app/file.txt');
補足
作りたてのアプリには、lang フォルダがありません。Laravel の言語ファイルを自分向けに直したいときは、lang:publish という Artisan コマンドで取り出します。
URL#
URL を作ったり、別の URL に移したりする関数です。
| 名前 | 説明 |
|---|---|
action |
コントローラーのメソッドへの URL を作る |
asset |
画像や CSS などのファイルへの URL を作る(リクエストと同じ HTTP か HTTPS) |
route |
名前を付けたルートへの URL を作る |
secure_asset |
HTTPS で、ファイルへの URL を作る |
secure_url |
指定したパスへの、HTTPS の完全な URL を作る |
to_action |
コントローラーのメソッドへの、リダイレクト(別の URL へ移すこと)のレスポンスを作る |
to_route |
名前を付けたルートへの、リダイレクトのレスポンスを作る |
uri |
URI を組み立てて扱える Uri のインスタンスを作る |
url |
指定したパスへの、完全な URL を作る |
use App\Http\Controllers\HomeController;
// コントローラーのメソッドへの URL
$url = action([HomeController::class, 'index']);
// ルートのパラメーターは、2つ目の引数で渡す
$url = action([UserController::class, 'profile'], ['id' => 1]);
// ファイルへの URL
$url = asset('img/photo.jpg');
// ファイルを S3 や CDN のような外のサービスに置くなら、.env の ASSET_URL で、ホストを決められる
// ASSET_URL=http://example.com/assets
$url = asset('img/photo.jpg'); // http://example.com/assets/img/photo.jpg
// 名前を付けたルートへの URL
$url = route('route.name');
$url = route('route.name', ['id' => 1]);
// 既定は、完全な URL。相対の URL にしたいときは、3つ目に false を渡す
$url = route('route.name', ['id' => 1], false);
// HTTPS で作る
$url = secure_asset('img/photo.jpg');
$url = secure_url('user/profile');
$url = secure_url('user/profile', [1]); // 2つ目で、URL の部品を足せる
// 指定したパスへの完全な URL
$url = url('user/profile');
$url = url('user/profile', [1]);
// パスを渡さないと、UrlGenerator が返る
$current = url()->current();
$full = url()->full();
$previous = url()->previous();
to_action と to_route は、リダイレクトのレスポンスを作ります。3つ目にステータスコード、4つ目に追加のヘッダーを渡せます。
use App\Http\Controllers\UserController;
return to_action([UserController::class, 'show'], ['user' => 1]);
return to_action(
[UserController::class, 'show'],
['user' => 1],
302,
['X-Framework' => 'Laravel']
);
return to_route('users.show', ['user' => 1]);
return to_route('users.show', ['user' => 1], 302, ['X-Framework' => 'Laravel']);
uri は、後ろの「URI」の節で説明する Uri のインスタンスを作ります。コントローラーとメソッドの組、1つの処理だけを持つコントローラー、ルートの名前も渡せます。
$uri = uri('https://example.com')
->withPath('/users')
->withQuery(['page' => 1]);
// コントローラーとメソッドの組を渡すと、そのルートのパスの Uri ができる
$uri = uri([UserController::class, 'show'], ['user' => $user]);
// 1つの処理だけを持つコントローラーなら、クラス名だけでよい
$uri = uri(UserIndexController::class);
// ルートの名前に合えば、そのルートのパスの Uri ができる
$uri = uri('users.show', ['user' => $user]);
url のくわしい使い方は、URL を作るのページにあります。
そのほか#
エラー・ログ・キャッシュ・リダイレクトなど、いろいろな場面で使う関数です。
そのほかの関数の一覧#
| 名前 | 説明 |
|---|---|
abort |
HTTP の例外を投げて、エラーの画面を出す |
abort_if |
条件が true のとき、HTTP の例外を投げる |
abort_unless |
条件が false のとき、HTTP の例外を投げる |
app |
サービスコンテナを返す。クラス名を渡せば、そのクラスを取り出す |
auth |
認証(ログイン)を扱うものを返す |
back |
前にいた場所へ戻す、リダイレクトのレスポンスを作る |
bcrypt |
Bcrypt で、値をハッシュにする |
blank |
値が「空」かを調べる |
broadcast |
イベントを、ブロードキャスト(リアルタイムに知らせる)する |
broadcast_if |
条件が true のとき、ブロードキャストする |
broadcast_unless |
条件が false のとき、ブロードキャストする |
cache |
キャッシュから値を取り出す、またはキャッシュに入れる |
class_uses_recursive |
クラスと、その親が使っているトレイト(クラスに機能を足す部品)を、すべて返す |
collect |
値から、コレクションを作る |
config |
設定値を取り出す、または動いている間だけ変える |
context |
コンテキストの値を取り出す、または入れる |
cookie |
新しい Cookie を作る |
csrf_field |
CSRF トークンを入れた、隠し入力欄の HTML を作る |
csrf_token |
いまの CSRF トークンの値を返す |
decrypt |
値を復号する(暗号を元に戻す) |
dd |
値を表示して、そこで処理を止める |
dispatch |
ジョブを、キューに入れる |
dispatch_sync |
ジョブを、すぐ動かす(sync のキューに入れる) |
dump |
値を表示する(処理は続ける) |
encrypt |
値を暗号化する |
env |
環境変数の値を返す |
event |
イベントを出して、リスナーに知らせる |
fake |
ためしのデータを作る Faker を返す |
filled |
値が「空ではない」かを調べる |
info |
情報のログを書く |
literal |
名前つきの引数を、プロパティに持つオブジェクトを作る |
logger |
デバッグのログを書く。引数が無ければ、ロガー(ログを書く道具)を返す |
method_field |
フォームの HTTP メソッドを装う、隠し入力欄の HTML を作る |
now |
いまの時刻の Carbon(日時を扱うもの)を作る |
old |
直前の入力の値を取り出す |
once |
関数の結果を、リクエストの間だけ覚えておく |
optional |
null かもしれない値のプロパティやメソッドを、安全に呼ぶ |
policy |
クラスに対応する、ポリシーを取り出す |
redirect |
リダイレクトのレスポンスを返す |
report |
例外を、例外のハンドラーに報告する |
report_if |
条件が true のとき、例外を報告する |
report_unless |
条件が false のとき、例外を報告する |
request |
いまのリクエストを返す。キーを渡せば、その入力の値を返す |
rescue |
関数を動かし、例外が出ても処理を続ける |
resolve |
サービスコンテナから、クラスを取り出す |
response |
レスポンスを作る。引数が無ければ、レスポンスを作るものを返す |
retry |
例外が出たら、決めた回数まで、やり直す |
session |
セッションの値を、取り出す・入れる |
tap |
値を関数に渡して、そのあとで元の値を返す |
throw_if |
条件が true のとき、例外を投げる |
throw_unless |
条件が false のとき、例外を投げる |
today |
きょうの日付の Carbon を作る |
trait_uses_recursive |
トレイトが使っているトレイトを、すべて返す |
transform |
値が空でなければ、関数で変えて返す |
validator |
バリデーション(入力のチェック)をするものを作る |
value |
値をそのまま返す。関数なら、動かした結果を返す |
view |
ビューを返す |
with |
値をそのまま返す。関数があれば、動かした結果を返す |
when |
条件が true のとき値を返し、そうでなければ null を返す |
エラーとして止める#
abort は、HTTP の例外を投げます。投げた例外は、例外のハンドラー(例外を受け取って処理する係)が、エラーの画面にして返します。メッセージと、ブラウザに送るヘッダーも渡せます。abort_if は条件が true のとき、abort_unless は条件が false のときに、例外を投げます。3つ目にメッセージ、4つ目にヘッダーの配列を渡せます。
abort(403);
abort(403, 'Unauthorized.', $headers);
abort_if(! Auth::user()->isAdmin(), 403);
abort_unless(Auth::user()->isAdmin(), 403);
throw_if と throw_unless は、条件に合ったとき、渡した例外を投げます。
throw_if(! Auth::user()->isAdmin(), AuthorizationException::class);
throw_if(
! Auth::user()->isAdmin(),
AuthorizationException::class,
'You are not allowed to access this page.'
);
throw_unless(Auth::user()->isAdmin(), AuthorizationException::class);
throw_unless(
Auth::user()->isAdmin(),
AuthorizationException::class,
'You are not allowed to access this page.'
);
report は、例外を、例外のハンドラーに報告します(処理は止めません)。文字列を渡すと、その文字をメッセージにした例外を作ります。report_if と report_unless は、条件で決まります。
report($e);
report('Something went wrong.');
report_if($shouldReport, $e);
report_if($shouldReport, 'Something went wrong.');
report_unless($reportingDisabled, $e);
report_unless($reportingDisabled, 'Something went wrong.');
rescue は、関数を動かし、途中で出た例外を受け止めます。受け止めた例外は例外のハンドラーに送られますが、リクエストの処理は止まらずに続きます。2つ目の引数には、例外が出たときに返す「既定の値」を渡せます。値の代わりに関数を渡すこともできます。また、report という名前の引数に関数を渡せば、その例外をハンドラーに報告するかどうかを決められます。
return rescue(function () {
return $this->method();
});
return rescue(function () {
return $this->method();
}, false);
return rescue(function () {
return $this->method();
}, function () {
return $this->failure();
});
return rescue(function () {
return $this->method();
}, report: function (Throwable $throwable) {
return $throwable instanceof InvalidArgumentException;
});
retry は、関数を、決めた回数まで、やり直しながら動かします。例外が出なければ、その結果を返します。例外が出たら、自動でやり直し、回数を使い切ったら、例外を投げます。
return retry(5, function () {
// 5回ためす。ためすたびに、100ミリ秒休む...
}, 100);
休む長さには、CarbonInterval(時間の長さを表すもの)も渡せます。
use function Illuminate\Support\seconds;
return retry(5, function () {
// 5回ためす。ためすたびに、5秒休む...
}, seconds(5));
休むミリ秒を自分で計算したいときは、3つ目に関数を渡します。
use Exception;
return retry(5, function () {
// ...
}, function (int $attempt, Exception $exception) {
return $attempt * 100;
});
1つ目の引数に配列を渡すと、やり直すたびに休むミリ秒が、配列で決まります。
return retry([100, 200], function () {
// 1回目のやり直しの前に100ミリ秒、2回目の前に200ミリ秒休む...
});
特定の条件のときだけやり直したいときは、4つ目に関数を渡します。
use App\Exceptions\TemporaryException;
use Exception;
return retry(5, function () {
// ...
}, 100, function (Exception $exception) {
return $exception instanceof TemporaryException;
});
アプリの中の道具を取り出す#
// サービスコンテナ
$container = app();
$api = app('HelpSpot\API'); // クラス名を渡すと、取り出せる
$api = resolve('HelpSpot\API'); // resolve でも同じ
// 認証。Auth ファサードの代わりに使える
$user = auth()->user();
$user = auth('admin')->user(); // ガード(ログインを確かめる係)も選べる
// 設定値
$value = config('app.timezone');
$value = config('app.timezone', $default);
// 動いている間だけ変える(本当の設定は変わらない)
config(['app.debug' => true]);
// コンテキスト
$value = context('trace_id');
$value = context('trace_id', $default);
context(['trace_id' => Str::uuid()->toString()]);
// 環境変数
$env = env('APP_ENV');
$env = env('APP_ENV', 'production');
// ポリシー
$policy = policy(App\Models\User::class);
// バリデーション
$validator = validator($data, $rules, $messages);
// リクエスト
$request = request();
$value = request('key', $default);
// セッション
$value = session('key');
session(['chairs' => 7, 'instruments' => 3]);
// 引数が無ければ、セッションを返す
$value = session()->get('key');
session()->put('key', $value);
注意
公開の手順で config:cache を動かすなら、env 関数は設定ファイルの中でだけ呼びます。キャッシュしたあとは .env が読まれないので、env は、サーバーや OS の環境変数か、null しか返しません。
キャッシュ・ハッシュ・暗号化#
// キャッシュから取り出す(無ければ、2つ目の既定値)
$value = cache('key');
$value = cache('key', 'default');
// キャッシュに入れる(2つ目に、有効な秒数か長さを渡す)
cache(['key' => 'value'], 300);
cache(['key' => 'value'], now()->plus(seconds: 10));
// Bcrypt でハッシュにする。Hash ファサードの代わりに使える
$password = bcrypt('my-secret-password');
// 暗号化と復号。Crypt ファサードの代わりに使える
$secret = encrypt('my-secret-value');
$password = decrypt($value);
リダイレクトとレスポンス#
// 前にいた場所へ戻す(ステータス、ヘッダー、戻れないときの行き先)
return back($status = 302, $headers = [], $fallback = '/');
return back();
// リダイレクトのレスポンス。引数が無ければ、リダイレクトを作るものが返る
return redirect($to = null, $status = 302, $headers = [], $secure = null);
return redirect('/home');
return redirect()->route('route.name');
// レスポンス。引数が無ければ、レスポンスを作るものが返る
return response('Hello World', 200, $headers);
return response()->json(['foo' => 'bar'], 200, $headers);
// ビュー
return view('auth.login');
// Cookie を作る
$cookie = cookie('name', 'value', $minutes);
フォームのための関数#
{{-- CSRF トークンを入れた隠し入力欄 --}}
{{ csrf_field() }}
{{-- フォームの HTTP メソッドを装う隠し入力欄 --}}
<form method="POST">
{{ method_field('DELETE') }}
</form>
// CSRF トークンの値
$token = csrf_token();
// 直前の入力の値(無ければ、2つ目の既定値)
$value = old('value');
$value = old('value', 'default');
old の2つ目の既定値は、Eloquent のモデルの属性のことが多いので、モデルそのものを渡せます。そのとき、1つ目の引数が、モデルの属性の名前になります。
{{ old('name', $user->name) }}
{{-- 上と同じ --}}
{{ old('name', $user) }}
キューとイベント#
// ジョブをキューに入れる
dispatch(new App\Jobs\SendEmails);
// ジョブをすぐ動かす
dispatch_sync(new App\Jobs\SendEmails);
// イベントを出して、リスナーに知らせる
event(new UserRegistered($user));
// ブロードキャストする(toOthers() で、自分以外にだけ送る)
broadcast(new UserRegistered($user));
broadcast(new UserRegistered($user))->toOthers();
broadcast_if($user->isActive(), new UserRegistered($user));
broadcast_if($user->isActive(), new UserRegistered($user))->toOthers();
broadcast_unless($user->isBanned(), new UserRegistered($user));
broadcast_unless($user->isBanned(), new UserRegistered($user))->toOthers();
値の表示とログ#
dd は、値を表示して、そこで処理を止めます。処理を止めたくないときは、dump を使います。
dd($value);
dd($value1, $value2, $value3, ...);
dump($value);
dump($value1, $value2, $value3, ...);
ログを書く関数です。info は情報のログ、logger はデバッグのログを書きます。連想配列で、補足の情報も渡せます。logger は、引数が無ければ、ロガーを返します。
info('Some helpful information!');
info('User login attempt failed.', ['id' => $user->id]);
logger('Debug message');
logger('User has logged in.', ['id' => $user->id]);
logger()->error('You are not allowed here.');
空かどうかを調べる#
blank は、値が「空」かを調べます。filled は、その逆で、「空ではない」かを調べます。0・true・false は、空ではありません。
blank('');
blank(' ');
blank(null);
blank(collect());
// true
blank(0);
blank(true);
blank(false);
// false
filled(0);
filled(true);
filled(false);
// true
filled('');
filled(' ');
filled(null);
filled(collect());
// false
値を扱う便利な関数#
// コレクションを作る
$collection = collect(['Taylor', 'Abigail']);
// 名前つきの引数をプロパティに持つオブジェクト(stdClass)を作る
$obj = literal(
name: 'Joe',
languages: ['PHP', 'Ruby'],
);
$obj->name; // 'Joe'
$obj->languages; // ['PHP', 'Ruby']
// いまの時刻・きょうの日付
$now = now();
$today = today();
// クラスやトレイトが使っているトレイトを、すべて返す
$traits = class_uses_recursive(App\Models\User::class);
$traits = trait_uses_recursive(\Illuminate\Notifications\Notifiable::class);
tap は、値と関数を受け取ります。値が関数に渡され、そのあとで、tap が元の値を返します。関数の戻り値は使われません。
$user = tap(User::first(), function (User $user) {
$user->name = 'Taylor';
$user->save();
});
関数を渡さなければ、値のどんなメソッドも呼べます。呼んだメソッドが何を返すかにかかわらず、返るのは、いつも元の値です。たとえば、Eloquent の update はふつう整数を返しますが、tap を通すと、モデルそのものが返ります。
$user = tap($user)->update([
'name' => $name,
'email' => $email,
]);
クラスに tap メソッドを足したいときは、Illuminate\Support\Traits\Tappable トレイトを使います。足した tap メソッドは、関数だけを受け取ります。その関数にオブジェクト自身が渡され、そのあとでオブジェクト自身が返ります。
return $user->tap(function (User $user) {
// ...
});
optional は、どんな値でも受け取り、そのプロパティやメソッドを呼べます。値が null のとき、エラーにならずに null を返します。2つ目に関数を渡すと、1つ目が null でなければ、その関数が動きます。
return optional($user->address)->street;
{!! old('name', optional($user)->name) !!}
return optional(User::find($id), function (User $user) {
return $user->name;
});
transform は、値が空でなければ、関数を動かして、その結果を返します。3つ目に、値が空のときに返す値(または関数)を渡せます。
$callback = function (int $value) {
return $value * 2;
};
$result = transform(5, $callback);
// 10
$result = transform(null, $callback, 'The value is blank');
// The value is blank
value は、渡された値をそのまま返します。関数を渡すと、動かして、その結果を返します。2つ目より後ろにも引数を渡せます。1つ目が関数なら、それらはその関数に渡されます。1つ目が関数でなければ、無視されます。
$result = value(true);
// true
$result = value(function () {
return false;
});
// false
$result = value(function (string $name) {
return $name;
}, 'Taylor');
// 'Taylor'
with も、値をそのまま返します。2つ目に関数を渡すと、動かして、その結果を返します。
$callback = function (mixed $value) {
return is_numeric($value) ? $value * 2 : 0;
};
$result = with(5, $callback);
// 10
$result = with(null, $callback);
// 0
$result = with(5, null);
// 5
when は、条件が true のとき、渡した値を返します。そうでなければ null です。2つ目に関数を渡すと、動かして、その結果を返します。HTML の属性を、条件によって出すときに便利です。
$value = when(true, 'Hello World');
$value = when(true, fn () => 'Hello World');
<div {!! when($condition, 'wire:poll="calculate"') !!}>
...
</div>
once は、関数を動かして、その結果を、リクエストが終わるまで、メモリに覚えておきます。同じ関数でもう一度 once を呼ぶと、覚えておいた結果が返ります。
function random(): int
{
return once(function () {
return random_int(1, 1000);
});
}
random(); // 123
random(); // 123(覚えておいた結果)
random(); // 123(覚えておいた結果)
オブジェクトの中から once を呼ぶと、覚えた結果は、そのオブジェクトごとに別になります。
<?php
class NumberService
{
public function all(): array
{
return once(fn () => [1, 2, 3]);
}
}
$service = new NumberService;
$service->all();
$service->all(); // (覚えておいた結果)
$secondService = new NumberService;
$secondService->all();
$secondService->all(); // (覚えておいた結果)
ためしのデータを作る(fake)#
fake は、ためしのデータを作る Faker を、サービスコンテナから取り出します。モデルのファクトリ、シーダー、テスト、ビューの試作などで、ためしのデータを作るのに便利です。
@for ($i = 0; $i < 10; $i++)
<dl>
<dt>Name</dt>
<dd>{{ fake()->name() }}</dd>
<dt>Email</dt>
<dd>{{ fake()->unique()->safeEmail() }}</dd>
</dl>
@endfor
既定では、config/app.php の app.faker_locale の設定を使います。この設定は、ふつう、環境変数の APP_FAKER_LOCALE で決めます。fake にロケールを渡して選ぶこともできます。ロケールごとに、別のシングルトン(1つだけ作られるもの)が取り出されます。
fake('nl_NL')->name();
そのほかの便利な道具#
関数ではなくクラスですが、ヘルパーと同じように、アプリのどこからでも使える道具です。
| 道具 | 説明 |
|---|---|
Benchmark |
処理にかかった時間を、ミリ秒で測る |
Carbon と間隔の関数 |
日付と時刻を扱う。minutes(10) のような時間の長さを作る |
defer |
レスポンスを返したあとに、処理を動かす |
Lottery |
決めた確率で、処理を動かす |
Pipeline |
値を、いくつかの処理に順に通す |
Sleep |
処理を休ませる。テストしやすい |
Timebox |
処理にかかる時間を、いつも一定にそろえる |
Uri |
URI を組み立てたり、調べたり、書きかえたりする |
時間を測る(Benchmark)#
アプリのある部分の速さを、手早く試したいときがあります。そんなときは、Benchmark クラスで、関数が終わるまでにかかったミリ秒を測れます。
<?php
use App\Models\User;
use Illuminate\Support\Benchmark;
Benchmark::dd(fn () => User::find(1)); // 0.1 ms
Benchmark::dd([
'Scenario 1' => fn () => User::count(), // 0.5 ms
'Scenario 2' => fn () => User::all()->count(), // 20.0 ms
]);
既定では、関数は1回だけ動き、かかった時間がブラウザやコンソールに表示されます。
何回も動かしたいときは、2つ目の引数に、回数を渡します。何回も動かしたときは、全部の平均のミリ秒が返ります。
Benchmark::dd(fn () => User::count(), iterations: 10); // 0.5 ms
関数が返した値も、いっしょに受け取りたいときは、value メソッドを使います。関数が返した値と、かかったミリ秒の、2つの組が返ります。
[$count, $duration] = Benchmark::value(fn () => User::count());
日付と時刻#
Laravel には、日付と時刻を扱う強力なライブラリ Carbon が入っています。新しい Carbon のインスタンス(実際に作ったもの)は、now 関数で作れます。この関数は、アプリのどこからでも使えます。
$now = now();
Illuminate\Support\Carbon クラスで作ることもできます。
use Illuminate\Support\Carbon;
$now = Carbon::now();
Laravel は、Carbon に、日時を足し引きする plus と minus のメソッドも足しています。
return now()->plus(minutes: 5);
return now()->plus(hours: 8);
return now()->plus(weeks: 4);
return now()->minus(minutes: 5);
return now()->minus(hours: 8);
return now()->minus(weeks: 4);
間隔の関数#
milliseconds・seconds・minutes・hours・days・weeks・months・years の関数もあります。これらは、PHP の DateInterval クラスを受け継いだ CarbonInterval を返します。Laravel が DateInterval を受け取る所なら、どこでも使えます。
| 関数 | 説明 |
|---|---|
milliseconds |
ミリ秒の長さ |
seconds |
秒の長さ |
minutes |
分の長さ |
hours |
時間の長さ |
days |
日の長さ |
weeks |
週の長さ |
months |
月の長さ |
years |
年の長さ |
use Illuminate\Support\Facades\Cache;
use function Illuminate\Support\{minutes};
Cache::put('metrics', $metrics, minutes(10));
あとで動かす(遅延関数)#
Laravel のキューのジョブを使うと、仕事を裏で動かせます。ただ、そのためには、動き続けるワーカー(列から仕事を取り出して動かすプログラム)を用意して管理する必要があります。かんたんな仕事のために、そこまでしたくないこともあります。
遅延関数(deferred functions)は、利用者にレスポンスを送り終えたあとで、関数を動かします。利用者に、アプリが速く、よく反応すると感じてもらえます。Illuminate\Support\defer に、関数を渡します。
use App\Services\Metrics;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
use function Illuminate\Support\defer;
Route::post('/orders', function (Request $request) {
// 注文を作る...
defer(fn () => Metrics::reportOrder($order));
return $order;
});
遅延関数が動くのは、ふつうは、defer を呼んだ処理(HTTP のレスポンス・Artisan コマンド・キューのジョブ)がうまく終わったときだけです。つまり、4xx や 5xx(エラーを表す番号)のレスポンスになったときは動きません。いつでも動かしたいときは、always メソッドをつなげます。
defer(fn () => Metrics::reportOrder($order))->always();
注意
Swoole という PHP の拡張機能を入れていると、Laravel の defer が、Swoole のグローバルな defer 関数とぶつかって、Web サーバーのエラーになることがあります。名前空間をはっきり書いて、use function Illuminate\Support\defer; と読みこんでから使ってください。
遅延関数を取り消す#
動く前に取り消したいときは、forget メソッドを使い、名前で取り消します。遅延関数に名前を付けるには、defer の2つ目の引数に渡します。
defer(fn () => Metrics::report(), 'reportMetrics');
defer()->forget('reportMetrics');
テストで遅延関数を止める#
テストを書くときは、遅延関数を止めておくと便利なことがあります。テストの中で withoutDefer を呼ぶと、遅延関数が、すぐに動くようになります。
Pest の場合です。
test('without defer', function () {
$this->withoutDefer();
// ...
});
PHPUnit の場合です。
use Tests\TestCase;
class ExampleTest extends TestCase
{
public function test_without_defer(): void
{
$this->withoutDefer();
// ...
}
}
テストケースのすべてのテストで止めたいときは、基本の TestCase クラスの setUp メソッドで、withoutDefer を呼びます。
<?php
namespace Tests;
use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
abstract class TestCase extends BaseTestCase
{
protected function setUp(): void
{
parent::setUp();
$this->withoutDefer();
}
}
くじで動かす(Lottery)#
Lottery クラスは、決めた確率で、関数を動かします。たとえば、リクエストの何パーセントかだけ、処理を動かしたいときに便利です。
use Illuminate\Support\Lottery;
Lottery::odds(1, 20)
->winner(fn () => $user->won())
->loser(fn () => $user->lost())
->choose();
Laravel のほかの機能と組み合わせられます。たとえば、遅いクエリ(データベースへの問い合わせ)のうち、ほんの一部だけを、例外のハンドラーに報告したいときです。Lottery のインスタンスは、関数のように呼び出せるもの(callable)です。だから、呼び出せるものを受け取るメソッドなら、どこにでも渡せます。
use Carbon\CarbonInterval;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Lottery;
DB::whenQueryingForLongerThan(
CarbonInterval::seconds(2),
Lottery::odds(1, 100)->winner(fn () => report('Querying > 2 seconds.')),
);
くじのテスト#
くじを使ったコードを、かんたんにテストするためのメソッドがあります。
| メソッド | 説明 |
|---|---|
Lottery::alwaysWin() |
いつも当たる |
Lottery::alwaysLose() |
いつもはずれる |
Lottery::fix([true, false]) |
当たり、はずれの順にして、そのあとは、ふつうに戻る |
Lottery::determineResultsNormally() |
ふつうの動きに戻す |
// いつも当たる...
Lottery::alwaysWin();
// いつもはずれる...
Lottery::alwaysLose();
// 当たり、はずれの順になって、最後に、ふつうの動きに戻る...
Lottery::fix([true, false]);
// ふつうの動きに戻る...
Lottery::determineResultsNormally();
順に通す(Pipeline)#
Pipeline ファサードを使うと、入力を、いくつかの呼べるクラスや関数に、順に「通せ」ます。それぞれが、入力を調べたり変えたりしてから、次に渡せます。
use Closure;
use App\Models\User;
use Illuminate\Support\Facades\Pipeline;
$user = Pipeline::send($user)
->through([
function (User $user, Closure $next) {
// ...
return $next($user);
},
function (User $user, Closure $next) {
// ...
return $next($user);
},
])
->then(fn (User $user) => $user);
通す順の中の、それぞれのクラスや関数には、入力と、$next という関数が渡されます。$next を呼ぶと、次の処理が動きます。ミドルウェアによく似ています。
最後の処理が $next を呼ぶと、then に渡した関数が動きます。ふつうは、渡された入力をそのまま返す関数です。処理した入力をそのまま返したいだけなら、thenReturn メソッドが使えます。
関数だけでなく、呼べるクラスも渡せます。クラスの名前を渡すと、Laravel のサービスコンテナが作るので、そのクラスに、必要な道具を自動で渡せます。
$user = Pipeline::send($user)
->through([
GenerateProfilePhoto::class,
ActivateSubscription::class,
SendWelcomeEmail::class,
])
->thenReturn();
withinTransaction メソッドを呼ぶと、通す順の全部を、1つのデータベースのトランザクション(まとめて成功か失敗かにする処理)で包めます。
$user = Pipeline::send($user)
->withinTransaction()
->through([
ProcessOrder::class,
TransferFunds::class,
UpdateInventory::class,
])
->thenReturn();
休む(Sleep)#
Sleep クラスは、PHP の sleep と usleep を軽く包んだものです。テストしやすく、時間を扱いやすい書き方もできます。
use Illuminate\Support\Sleep;
$waiting = true;
while ($waiting) {
Sleep::for(1)->second();
$waiting = /* ... */;
}
いろいろな時間の単位で、休ませられます。
| メソッド | 説明 |
|---|---|
Sleep::for(...)->second() / seconds() |
秒で休む |
Sleep::for(...)->minutes() |
分で休む |
Sleep::for(...)->milliseconds() |
ミリ秒で休む |
Sleep::for(...)->microseconds() |
マイクロ秒で休む |
->then(...) |
休んだあとに、値を返す |
->while(...) |
関数が true を返すあいだ、休む |
->and(...) |
時間の単位を、つなげる |
Sleep::until(...) |
決めた時刻まで休む |
Sleep::sleep(2) |
PHP の sleep の別名 |
Sleep::usleep(5000) |
PHP の usleep の別名 |
// 休んだあとに、値を返す...
$result = Sleep::for(1)->second()->then(fn () => 1 + 1);
// 値が true のあいだ、休む...
Sleep::for(1)->second()->while(fn () => shouldKeepSleeping());
// 90秒、処理を止める...
Sleep::for(1.5)->minutes();
// 2秒、処理を止める...
Sleep::for(2)->seconds();
// 500ミリ秒、処理を止める...
Sleep::for(500)->milliseconds();
// 5,000マイクロ秒、処理を止める...
Sleep::for(5000)->microseconds();
// 決めた時刻まで、処理を止める...
Sleep::until(now()->plus(minutes: 1));
// PHP の「sleep」関数の別名...
Sleep::sleep(2);
// PHP の「usleep」関数の別名...
Sleep::usleep(5000);
時間の単位は、and メソッドでつなげられます。
Sleep::for(1)->second()->and(10)->milliseconds();
休みのテスト#
Sleep や PHP の休む関数を使ったコードをテストすると、テストの処理が止まります。そのため、テスト全体が、とても遅くなります。たとえば、次のコードをテストするとします。
$waiting = /* ... */;
$seconds = 1;
while ($waiting) {
Sleep::for($seconds++)->seconds();
$waiting = /* ... */;
}
ふつうにテストすると、少なくとも 1秒かかります。Sleep クラスには、休んだふりをする「フェイク」があるので、テストを速いままにできます。
Pest の場合です。
it('waits until ready', function () {
Sleep::fake();
// ...
});
PHPUnit の場合です。
public function test_it_waits_until_ready()
{
Sleep::fake();
// ...
}
Sleep をフェイクにすると、本当の処理の停止は飛ばされるので、テストがぐっと速くなります。
フェイクにしたあとは、起きるはずだった「休み」を、アサーション(「こうなっているはず」を確かめる命令)で確かめられます。たとえば、1秒ずつ長くなる休みを、3回とるコードをテストするとします。assertSequence を使うと、テストを速いままにして、正しい長さで休んだかを確かめられます。
Pest の場合です。
it('checks if ready three times', function () {
Sleep::fake();
// ...
Sleep::assertSequence([
Sleep::for(1)->second(),
Sleep::for(2)->seconds(),
Sleep::for(3)->seconds(),
]);
});
PHPUnit の場合です。
public function test_it_checks_if_ready_three_times()
{
Sleep::fake();
// ...
Sleep::assertSequence([
Sleep::for(1)->second(),
Sleep::for(2)->seconds(),
Sleep::for(3)->seconds(),
]);
}
テストで使えるアサーションは、ほかにもあります。
| メソッド | 説明 |
|---|---|
Sleep::assertSequence |
休みが、決めた順に起きたか確かめる |
Sleep::assertSleptTimes |
休みが、決めた回数だけ起きたか確かめる |
Sleep::assertSlept |
休みの長さが、条件に合うか確かめる |
Sleep::assertNeverSlept |
Sleep が、一度も呼ばれなかったか確かめる |
Sleep::assertInsomniac |
Sleep が呼ばれても、処理が止まることはなかったか確かめる |
use Carbon\CarbonInterval as Duration;
use Illuminate\Support\Sleep;
// 休みが3回呼ばれたことを確かめる...
Sleep::assertSleptTimes(3);
// 休みの長さを確かめる...
Sleep::assertSlept(function (Duration $duration): bool {
return /* ... */;
}, times: 1);
// Sleep クラスが、一度も呼ばれなかったことを確かめる...
Sleep::assertNeverSlept();
// Sleep が呼ばれても、処理が止まることはなかったことを確かめる...
Sleep::assertInsomniac();
フェイクの休みが起きるたびに、何かをしたいときもあります。whenFakingSleep メソッドに、関数を渡します。次の例では、Laravel の時間を動かすヘルパーを使って、休みの長さのぶん、時間をすぐに進めています。
use Carbon\CarbonInterval as Duration;
$this->freezeTime();
Sleep::fake();
Sleep::whenFakingSleep(function (Duration $duration) {
// 休みをフェイクにしたとき、時間を進める...
$this->travel($duration->totalMilliseconds)->milliseconds();
});
時間を進めたいことは多いので、fake メソッドには、syncWithCarbon という引数があります。テストの中で休んだときに、Carbon の時間もいっしょに進めます。
Sleep::fake(syncWithCarbon: true);
$start = now();
Sleep::for(1)->second();
$start->diffForHumans(); // 1 second ago
Laravel は、内部でも、処理を休ませるときに Sleep クラスを使っています。たとえば、前のほうの retry ヘルパーも、休むときに Sleep を使うので、テストしやすくなっています。
時間を一定にそろえる(Timebox)#
Timebox クラスは、関数が早く終わっても、いつも決まった長さの時間がかかるようにします。暗号の処理や、ユーザーの認証の確認のような場面で、とくに役に立ちます。攻撃する人が、処理にかかった時間のちがいから、秘密の情報を推測してしまうことがあるからです。
実際の処理が、決めた長さを超えたときは、Timebox は何もしません。最悪の場合でも足りる、十分に長い時間を決めるのは、開発する人の仕事です。
call メソッドは、関数と、時間の上限を受け取ります。上限はマイクロ秒(100万分の1秒)で決めます。関数を動かしたあと、上限の時間になるまで待ちます。
use Illuminate\Support\Timebox;
(new Timebox)->call(function ($timebox) {
// ...
}, microseconds: 10000);
関数の中で例外が投げられたときも、決めた待ち時間は守られ、待ったあとに、例外がもう一度投げられます。
URI を扱う(Uri)#
Uri クラスは、URI を作ったり変えたりするための、メソッドをつないで書ける便利な道具です。League URI という部品を包んだもので、Laravel のルーティングともうまくつながっています。
静的メソッドで、Uri のインスタンスを作れます。
| メソッド | 説明 |
|---|---|
Uri::of |
文字列から作る |
Uri::to |
パスから作る |
Uri::route |
名前を付けたルートから作る |
Uri::signedRoute |
署名つきのルートから作る |
Uri::temporarySignedRoute |
期限つきで、署名つきのルートから作る |
Uri::action |
コントローラーのメソッドから作る |
$request->uri() |
いまのリクエストの URL から作る |
use App\Http\Controllers\UserController;
use App\Http\Controllers\InvokableController;
use Illuminate\Support\Uri;
// 文字列から作る...
$uri = Uri::of('https://example.com/path');
// パス・名前を付けたルート・コントローラーのメソッドから作る...
$uri = Uri::to('/dashboard');
$uri = Uri::route('users.show', ['user' => 1]);
$uri = Uri::signedRoute('users.show', ['user' => 1]);
$uri = Uri::temporarySignedRoute('user.index', now()->plus(minutes: 5));
$uri = Uri::action([UserController::class, 'index']);
$uri = Uri::action(InvokableController::class);
// いまのリクエストの URL から作る...
$uri = $request->uri();
作ったあとは、メソッドをつないで書きかえられます。
| メソッド | 説明 |
|---|---|
withScheme |
スキーム(http や https)を変える |
withHost |
ホスト(サイトの名前)を変える |
withPort |
ポートの番号を変える |
withPath |
パスを変える |
withQuery |
クエリ(? の後ろ)を足す |
withFragment |
フラグメント(# の後ろ)を変える |
$uri = Uri::of('https://example.com')
->withScheme('http')
->withHost('test.com')
->withPort(8000)
->withPath('/users')
->withQuery(['page' => 2])
->withFragment('section-1');
URI の部品を調べる#
URI の部品を、1つずつ調べられます。
| メソッド | 説明 |
|---|---|
scheme |
スキーム |
authority |
ユーザー名・ホスト・ポートをまとめた部分 |
host |
ホスト |
port |
ポート |
path |
パス |
pathSegments |
パスを / で区切った各部分(コレクション) |
query |
クエリ |
fragment |
フラグメント |
$scheme = $uri->scheme();
$authority = $uri->authority();
$host = $uri->host();
$port = $uri->port();
$path = $uri->path();
$segments = $uri->pathSegments();
$query = $uri->query();
$fragment = $uri->fragment();
クエリ文字列を変える#
Uri には、クエリ文字列(? の後ろ)を変える方法がいくつかあります。
| メソッド | 説明 |
|---|---|
withQuery |
いまのクエリに、新しい値を足す(同じ名前は上書き) |
withQueryIfMissing |
同じ名前がまだ無いときだけ、足す |
replaceQuery |
いまのクエリを、新しいものに、まるごと入れかえる |
pushOntoQuery |
配列の値を持つ名前に、値を足す |
withoutQuery |
指定した名前を、クエリから取り除く |
$uri = $uri->withQuery(['sort' => 'name']);
$uri = $uri->withQueryIfMissing(['page' => 1]);
$uri = $uri->replaceQuery(['page' => 1]);
$uri = $uri->pushOntoQuery('filter', ['active', 'pending']);
$uri = $uri->withoutQuery(['page']);
URI からレスポンスを作る#
redirect メソッドは、その URI への RedirectResponse(別の URL へ移すレスポンス)を作ります。
$uri = Uri::of('https://example.com');
return $uri->redirect();
ルートやコントローラーから、Uri のインスタンスをそのまま返してもかまいません。その URI へのリダイレクトのレスポンスが、自動で作られます。
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Uri;
Route::get('/redirect', function () {
return Uri::to('/index')
->withQuery(['sort' => 'name']);
});
関連するページ#
公式ドキュメント(英語)
2026年10月5日時点の内容をもとに、日本語でまとめています。