ip — IPアドレス形式を検証するバリデーションルール

validation
  • カテゴリ: validation
  • 掲載バージョン: Laravel 12・PHP 8.4
  • 名前空間 / FQCN / コマンド: (バリデーションルール名)ip
  • 関連: ipv4 / ipv6 / active_url / url
  • 変更履歴: Laravel 5 以降で利用可能(Laravel 10〜12 では仕様に大きな変更なし)

要点(TL;DR)

  • 何に使うか:入力値が有効な IP アドレスかどうかをチェックする。
  • 最低限の使い方'ip_address' => ['required', 'ip']
  • よくある罠
    • 「IPv4 だけ/IPv6 だけ」を制限したいのに ip だけを使ってしまう
    • プライベートIPやローカルIPを許可してよいかを仕様で決めていない
    • 文字列前後の空白やポート番号付き(192.168.0.1:80 など)は通らないことに気づかない

概要

ip ルールは、フォーム入力やAPIリクエストで受け取った値が有効な IP アドレス形式かどうかを検証します。
IPv4・IPv6 のどちらも許可したいときの「ざっくり IP アドレスチェック」として使うのが基本です。

構文 / シグネチャ

$request->validate([
    'ip_address' => ['nullable', 'ip'],
]);

引数(ルールとしての指定)

引数必須既定値説明
ipstringはいなし入力値が IPv4 または IPv6 のいずれかの正しい形式であることを検証

ip ルール自体には追加パラメータはありません。
※ Laravel の内部では PHP の filter_var($value, FILTER_VALIDATE_IP) が利用されます。

  • 戻り値
    • バリデーションとしては、成功/失敗(true/false)
    • コントローラの validate() 使用時は、失敗すると ValidationException をスローし、元のページへリダイレクト+エラーメッセージを付与
  • 例外/副作用
    • Illuminate\Validation\ValidationException が投げられる可能性
    • セッションにエラーメッセージが保存される(通常のフォームバリデーション時)

使用例

最小例

<?php

use Illuminate\Http\Request;

Route::post('/submit-ip', function (Request $request) {
    $validated = $request->validate([
        'ip_address' => ['required', 'ip'],
    ]);

    // ここまで来れば $validated['ip_address'] は有効なIP形式
    return 'IP: ' . $validated['ip_address'];
});

実務例:アクセスログ登録API

<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\AccessLog;
use Illuminate\Http\Request;

class AccessLogController extends Controller
{
    public function store(Request $request)
    {
        $validated = $request->validate([
            'ip'        => ['required', 'ip'],
            'path'      => ['required', 'string', 'max:255'],
            'user_agent'=> ['nullable', 'string', 'max:1024'],
        ]);

        $log = AccessLog::create([
            'ip'         => $validated['ip'],
            'path'       => $validated['path'],
            'user_agent' => $validated['user_agent'] ?? $request->userAgent(),
        ]);

        return response()->json([
            'id'  => $log->id,
            'msg' => 'logged',
        ]);
    }
}

よくある落とし穴・注意

  • IPv4/IPv6 を分けたいときは専用ルールを使う
    • ip は IPv4/IPv6 の両方を受け付けます。
    • IPv4 だけにしたい場合は ipv4、IPv6 だけは ipv6 を使います。
  • ポート番号付きは無効
    • 192.168.0.1:80 のような形式は IP アドレスとしては不正扱いです。
    • 必要なら IP とポートを別フィールドに分けて受け取る設計にしましょう。
  • 前後の空白・改行
    • trim() されないまま ip ルールに渡すと、前後に空白があるだけで不正と判定されます。
    • 基本的には HTML 側や FormRequestprepareForValidation()trim() しておくと安全です。
  • プライベートIPを許可してよいか要検討
    • 127.0.0.1192.168.x.x なども有効な IP として通ります。
    • 「グローバルIPのみ許可したい」といった要件がある場合は、ip だけでは不足で、追加のカスタムルールが必要です。

代替・関連APIとの比較

  • ip
    • IPv4 / IPv6 どちらも許可。
    • 「とりあえず IP 形式ならOK」という用途向き。
  • ipv4 / ipv6
    • それぞれのバージョンに限定して検証したいときに使用。
    • ネットワーク機器の設定画面や、バージョン別に処理を変えたいときに便利。
  • active_url / url
    • これらは URL 用であり、IP アドレス単体ではなく「http(s)://〜」形式を前提とします。
    • IP アドレス+ポートなどを検証したい場合、url に頼るのではなく、別途設計・ルールを分けたほうが明瞭です。

選定基準としては、「IP形式だけ見たいなら ip、バージョンを固定したいなら ipv4 / ipv6 と覚えると十分です。

テスト例(Pest)

<?php

use Illuminate\Support\Facades\Validator;

it('accepts valid ip address', function () {
    $validator = Validator::make(
        ['ip_address' => '192.168.0.1'],
        ['ip_address' => ['required', 'ip']]
    );

    expect($validator->passes())->toBeTrue();
});

it('rejects invalid ip address', function () {
    $validator = Validator::make(
        ['ip_address' => '999.999.999.999'],
        ['ip_address' => ['required', 'ip']]
    );

    expect($validator->fails())->toBeTrue();
});

トラブルシュート(エラー別)

症状/エラー原因対処
「The ip address must be a valid IP address.」ip ルールに不正な文字列(ポート付き、空白付き、完全に別形式)が渡されている実際の値を dd($request->all()) などで確認し、trim や項目分割を検討する
IPv4 のつもりが IPv6 も通ってしまうip ルールは IPv4/IPv6 両方を許可するipv4 / ipv6 ルールを明示的に使う
ローカルIPも通ってしまうip はグローバル/プライベートを区別しない追加のカスタムルール(CIDRチェックなど)を実装する

参考リンク

レン (Wren)

こんにちは。レンです。

Laravelのコードの森に住んでいる、小さな案内役です。
ルーティングの枝やクラスの影を歩きながら、コードの流れや仕組みを眺めています。

このサイトでは、Laravelの基本から実装のコツまで、開発で役立つポイントを静かに整理しています。
難しいことを増やすのではなく、コードの見通しが少し良くなるヒントを届けるのが役目です。

「この処理はどこに書くのがいいのか」
「Laravelではどう考えると整理できるのか」

そんな疑問に、小さなメモを残すような気持ちで記事を書いています。

コードを書いている途中で迷ったとき、
このサイトが少し立ち止まって整理できる場所になればうれしいです。

レン (Wren)をフォローする