この内容は古いバージョンです。最新バージョンを表示するには、戻るボタンを押してください。
バージョン:4
ページ更新者:guest
更新日時:2026-06-11 07:10:02

タイトル: URLパラメータの配列化
SEOタイトル: PHP URL パラメータの配列化完全ガイド($_GET / http_build_query / parse_str)

この記事の要点
  • URL クエリで配列を渡す: ?ids[]=1&ids[]=2&ids[]=3$_GET["ids"] = [1, 2, 3]
  • 連想配列も可: ?user[name]=taro&user[age]=30$_GET["user"] = ["name"=>"taro", ...]
  • 配列 → URL クエリ: http_build_query(["ids" => [1,2,3]])ids%5B0%5D=1&ids%5B1%5D=2&ids%5B2%5D=3
  • URL クエリ文字列 → 配列: parse_str("ids[]=1&ids[]=2", $arr)
  • JS 側: URLSearchParamsFormData で同形式の送信が可
  • Laravel: $request->input("ids") で自動的に配列受取

基本: ?key[]=value で配列受取

PHP は URL クエリ文字列中の []配列要素として解釈します。

// URL: https://example.com/?ids[]=1&ids[]=2&ids[]=3

print_r($_GET);
/*
Array (
    [ids] => Array (
        [0] => 1
        [1] => 2
        [2] => 3
    )
)
*/

// 利用
foreach ($_GET['ids'] as $id) {
    echo $id;
}

連想配列([key] 形式)

// URL: ?user[name]=taro&user[age]=30&user[email]=taro@example.com

print_r($_GET);
/*
Array (
    [user] => Array (
        [name] => taro
        [age] => 30
        [email] => taro@example.com
    )
)
*/

// アクセス
$_GET['user']['name'];  // "taro"
$_GET['user']['age'];   // "30" (文字列)

多次元配列

// URL: ?cart[0][id]=10&cart[0][qty]=2&cart[1][id]=20&cart[1][qty]=1

print_r($_GET);
/*
Array (
    [cart] => Array (
        [0] => Array (
            [id] => 10
            [qty] => 2
        )
        [1] => Array (
            [id] => 20
            [qty] => 1
        )
    )
)
*/

// 利用
foreach ($_GET['cart'] as $item) {
    echo "ID: {$item['id']}, 数量: {$item['qty']}\n";
}

配列から URL クエリ生成: http_build_query()

$params = [
    'ids' => [1, 2, 3],
    'user' => [
        'name' => 'taro',
        'age' => 30,
    ],
    'lang' => 'ja',
];

echo http_build_query($params);
// ids%5B0%5D=1&ids%5B1%5D=2&ids%5B2%5D=3&user%5Bname%5D=taro&user%5Bage%5D=30&lang=ja

// URL デコードして見ると
// ids[0]=1&ids[1]=2&ids[2]=3&user[name]=taro&user[age]=30&lang=ja

// インデックス番号を入れない(連想配列のみ)
echo http_build_query($params, '', '&', PHP_QUERY_RFC3986);

// 区切り文字を変更
echo http_build_query($params, '', '&'); // HTML 中で使う際の安全化

// プレフィックス(インデックスが必要な場合の名前付け)
echo http_build_query(['filter' => [1, 2]], 'arg_');

RFC3986 vs RFC1738

エンコーディングスペース用途
PHP_QUERY_RFC1738(デフォルト)+application/x-www-form-urlencoded(フォーム送信)
PHP_QUERY_RFC3986%20URL 一般(パス / ハッシュ)
http_build_query(['q' => 'hello world']);
// "q=hello+world" (RFC1738)

http_build_query(['q' => 'hello world'], '', '&', PHP_QUERY_RFC3986);
// "q=hello%20world" (RFC3986)

URL クエリ文字列 → 配列: parse_str()

$qs = 'ids[]=1&ids[]=2&user[name]=taro&user[age]=30';

parse_str($qs, $result);

print_r($result);
/*
Array (
    [ids] => Array ( [0] => 1 [1] => 2 )
    [user] => Array ( [name] => taro [age] => 30 )
)
*/

// ❌ 第 2 引数省略は PHP 7.2+ で非推奨(グローバル汚染)
parse_str($qs);
echo $ids[0];  // 動くが非推奨

JavaScript 側で同形式を送る

URLSearchParams

const params = new URLSearchParams();
[1, 2, 3].forEach(id => params.append('ids[]', id));
params.append('user[name]', 'taro');
params.append('user[age]', 30);

console.log(params.toString());
// ids%5B%5D=1&ids%5B%5D=2&ids%5B%5D=3&user%5Bname%5D=taro&user%5Bage%5D=30

fetch('/api?' + params.toString());

jQuery $.param()

const data = {
    ids: [1, 2, 3],
    user: { name: 'taro', age: 30 }
};

console.log($.param(data));
// ids%5B%5D=1&ids%5B%5D=2&ids%5B%5D=3&user%5Bname%5D=taro&user%5Bage%5D=30

$.get('/api', data);

axios

import axios from 'axios';
import qs from 'qs';

// デフォルトでは ids: [1,2,3] が ids[]=1&ids[]=2 にならない
axios.get('/api', {
    params: { ids: [1, 2, 3] },
    paramsSerializer: params => qs.stringify(params, { arrayFormat: 'brackets' })
});
// → /api?ids[]=1&ids[]=2&ids[]=3

// arrayFormat オプション:
// 'indices' → ids[0]=1&ids[1]=2
// 'brackets' → ids[]=1&ids[]=2
// 'repeat'  → ids=1&ids=2
// 'comma'   → ids=1,2

POST フォームでの配列送信

GET と同じ書式が POST でも使えます。

<form action="/process" method="POST">
    <!-- チェックボックスで複数選択 -->
    <input type="checkbox" name="tags[]" value="php">    PHP
    <input type="checkbox" name="tags[]" value="js">     JS
    <input type="checkbox" name="tags[]" value="css">    CSS

    <!-- セレクトボックスの multiple -->
    <select name="langs[]" multiple>
        <option value="ja">日本語</option>
        <option value="en">英語</option>
    </select>

    <!-- 連想配列 -->
    <input type="text" name="user[name]" placeholder="名前">
    <input type="email" name="user[email]" placeholder="メール">

    <button>送信</button>
</form>
// 受信
print_r($_POST);
/*
Array (
    [tags] => Array ( [0] => php [1] => js )
    [langs] => Array ( [0] => ja )
    [user] => Array ( [name] => taro [email] => taro@example.com )
)
*/

Laravel での扱い

use Illuminate\Http\Request;

public function index(Request $request) {
    // GET /search?ids[]=1&ids[]=2&ids[]=3
    $ids = $request->input('ids');           // [1, 2, 3]
    $ids = $request->input('ids', []);       // デフォルト空配列

    // 連想配列
    $userName = $request->input('user.name'); // ドット記法
    $userAge  = $request->input('user.age');

    // バリデーション
    $validated = $request->validate([
        'ids'       => 'array|min:1',
        'ids.*'     => 'integer',         // 各要素のバリデーション
        'user.name' => 'required|string',
        'user.age'  => 'integer|min:0',
    ]);

    // クエリビルダで使う
    $users = User::whereIn('id', $ids)->get();
}

Postman での配列送信

方法記法
Query Params タブキーに ids[]、値に 1。複数行追加
URL に直接?ids[]=1&ids[]=2&ids[]=3
Body (form-data)キー ids[] を複数行
Body (raw JSON){"ids": [1, 2, 3]}(API がこちらを期待する場合)

JSON 形式で送る代替案

API として設計するなら、クエリ配列より JSON が現代的で型情報も明確:

// JS
fetch('/api/users', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
        ids: [1, 2, 3],
        user: { name: 'taro', age: 30 }
    })
});
// PHP 受信
$raw = file_get_contents('php://input');
$data = json_decode($raw, true);

print_r($data);
/*
Array (
    [ids] => Array ( [0] => 1 [1] => 2 [2] => 3 )
    [user] => Array ( [name] => taro [age] => 30 )
)
*/

// Laravel は自動で json デコード
$ids = $request->input('ids');

注意点・ハマりどころ

症状原因対処
配列が文字列で来る?ids=1,2,3 形式explode(',', $_GET['ids'])
URL が長すぎてエラーGET の URL 長制限 (2KB 〜)POST へ変更
max_input_vars 超過php.ini デフォルト 1000php.ini で増やす or 構造変更
ネスト深すぎで取得不能多次元配列の解釈JSON ボディに切替
?ids[]= 空文字空配列ではなく [''] になるarray_filter() で除去

セキュリティの注意

  • 受け取った配列は必ず型バリデーション(int / string / 範囲)
  • SQL に直接使わない → プリペアドステートメント + IN (?, ?, ?)
  • array_map('intval', $ids)整数強制もよくあるテクニック
  • 巨大配列でメモリ枯渇 DoScount() で件数上限チェック
// 安全な受け取り
$ids = $request->input('ids', []);
if (!is_array($ids) || count($ids) > 100) {
    abort(400, 'ids は最大 100 件');
}
$ids = array_values(array_unique(array_map('intval', $ids)));

// IN 句で使う
$users = User::whereIn('id', $ids)->get();

FAQ

Q: ?ids=1&ids=2 ([] 無し)で配列にできる?
A: PHP では後勝ち$_GET['ids'] = "2" になります。配列にするには [] 必須。Java/Spring 等は同名キーで自動配列化。

Q: URL が長くなりすぎる
A: 100 件超えるなら POST + JSON ボディに。またはカンマ区切り ?ids=1,2,3 + サーバ側で explode も実用的。

Q: max_input_vars 警告
A: 1000 個超のフォームフィールドで発生。php.inimax_input_vars = 5000 で緩和、またはJSON 化で根本解決。