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

タイトル: GET通信
SEOタイトル: PHP GET 通信完全ガイド(curl / Laravel HTTP / Guzzle / fetch / Postman)

この記事の要点
  • GET 通信は URL にクエリ文字列を付けて取得する HTTP メソッド。冪等で副作用なし
  • PHP 側で受け取り: $_GET["param"]、Laravel は $request->query() / $request->input()
  • 送信は curl (CURLOPT_URL) / Laravel Http::get() / Guzzle / file_get_contents
  • 配列パラメータは ?ids[]=1&ids[]=2、URL エンコードは http_build_query() が安全
  • CORS / Origin ヘッダの理解、Postman / curl での再現確認、fetch / axios でのフロント連携

GET 通信とは

HTTP の代表的なメソッドの一つで、サーバから情報を取得するのが本来の用途です。URL に ?key=value&key2=value2 形式でクエリ文字列を付与して送信し、サーバ側で読み取ります。

性質説明
冪等性何度同じリクエストを送っても結果が変わらない(基本)
キャッシュ可能ブラウザ / CDN がキャッシュする
ボディ無し(実質)パラメータは URL に乗せる
URL 長制限サーバ・ブラウザによるが約 2000〜8000 文字
機密データ不向きURL がブラウザ履歴 / アクセスログに残る

PHP 側で受け取る

<?php
// http://example.com/search.php?q=php&page=2

// シンプルな取得
$q    = $_GET['q'] ?? '';
$page = (int)($_GET['page'] ?? 1);

// バリデーション
$q = mb_substr(trim($q), 0, 100);
if ($page < 1) $page = 1;

// 配列パラメータ ?ids[]=1&ids[]=2&ids[]=3
$ids = $_GET['ids'] ?? [];
$ids = array_filter($ids, fn($v) => ctype_digit((string)$v));

// 全クエリを連想配列で
print_r($_GET);
// Array ( [q] => php [page] => 2 [ids] => Array ( [0] => 1 [1] => 2 ) )

// REQUEST_URI から自前パース
$urlParts = parse_url($_SERVER['REQUEST_URI']);
parse_str($urlParts['query'] ?? '', $params);

Laravel での受け取り

use Illuminate\Http\Request;

Route::get('/search', function (Request $request) {
    // query() はクエリ文字列のみ、input() は POST/GET 両対応
    $q    = $request->query('q', '');
    $page = (int) $request->query('page', 1);

    // 検証付き
    $validated = $request->validate([
        'q'    => 'nullable|string|max:100',
        'page' => 'integer|min:1|max:1000',
        'ids'  => 'array',
        'ids.*'=> 'integer',
    ]);

    return view('search.index', compact('q', 'page'));
});

// FormRequest 化
class SearchRequest extends FormRequest {
    public function rules(): array {
        return [
            'q'    => 'nullable|string|max:100',
            'page' => 'integer|min:1',
        ];
    }
}

curl で GET 送信(PHP 内から)

<?php
function httpGet(string $url, array $params = [], array $headers = []): array {
    if ($params) {
        $url .= (str_contains($url, '?') ? '&' : '?') . http_build_query($params);
    }

    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => 10,
        CURLOPT_FOLLOWLOCATION => true,
        CURLOPT_MAXREDIRS      => 3,
        CURLOPT_SSL_VERIFYPEER => true,
        CURLOPT_HTTPHEADER     => array_merge([
            'Accept: application/json',
            'User-Agent: MyApp/1.0',
        ], $headers),
    ]);

    $body   = curl_exec($ch);
    $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $err    = curl_error($ch);
    curl_close($ch);

    if ($body === false) {
        throw new RuntimeException("curl error: $err");
    }
    return ['status' => $status, 'body' => $body];
}

// 利用
$resp = httpGet('https://api.example.com/users', ['page' => 1, 'per_page' => 20]);
$data = json_decode($resp['body'], true);

Laravel HTTP Client

Laravel 7+ には Guzzle ベースの Http ファサードが入っています。最も読みやすい書き方です:

use Illuminate\Support\Facades\Http;

// 基本
$response = Http::get('https://api.example.com/users', [
    'page' => 1,
    'per_page' => 20,
]);

if ($response->successful()) {
    $data = $response->json();
}

// ヘッダ / タイムアウト / リトライ / 認証
$response = Http::withHeaders([
        'Accept-Language' => 'ja',
    ])
    ->withToken($token)            // Authorization: Bearer
    ->timeout(10)
    ->retry(3, 200)                // 3 回、200ms 間隔
    ->get('https://api.example.com/users', ['q' => 'php']);

// マクロ / プール(並列)
$responses = Http::pool(fn ($pool) => [
    $pool->get('https://api.example.com/a'),
    $pool->get('https://api.example.com/b'),
]);

Guzzle 直接利用

use GuzzleHttp\Client;
use GuzzleHttp\Exception\GuzzleException;

$client = new Client([
    'base_uri' => 'https://api.example.com',
    'timeout'  => 10,
    'http_errors' => false,           // 4xx/5xx で例外を投げない
]);

try {
    $response = $client->get('/users', [
        'query' => [
            'page' => 1,
            'ids'  => [10, 20, 30],     // ?ids[0]=10&ids[1]=20&ids[2]=30
        ],
        'headers' => ['Accept' => 'application/json'],
    ]);
    $data = json_decode((string)$response->getBody(), true);
} catch (GuzzleException $e) {
    error_log($e->getMessage());
}

配列・ネストの送信

<?php
// http_build_query が PHP 5.1.3+ で標準
$params = [
    'q'       => 'php',
    'ids'     => [1, 2, 3],
    'filter'  => [
        'category' => 'book',
        'price'    => ['min' => 100, 'max' => 5000],
    ],
];

$qs = http_build_query($params);
// q=php
// &ids%5B0%5D=1&ids%5B1%5D=2&ids%5B2%5D=3
// &filter%5Bcategory%5D=book
// &filter%5Bprice%5D%5Bmin%5D=100&filter%5Bprice%5D%5Bmax%5D=5000

// 区切りを「&amp;」「&」のどちらにするか
http_build_query($params, '', '&', PHP_QUERY_RFC3986);

URL エンコードの違い

関数挙動用途
urlencode()スペース → +application/x-www-form-urlencoded
rawurlencode()スペース → %20RFC 3986 準拠(パスや一般的な URL)
http_build_query()連想配列を一括変換(既定 PHP_QUERY_RFC1738)クエリ文字列生成

CORS(クロスオリジン)の理解

ブラウザの JS から別オリジンの API を GET する場合、サーバ側でCORS ヘッダを返す必要があります:

<?php
// シンプル GET の場合
header('Access-Control-Allow-Origin: https://app.example.com');
header('Vary: Origin');

// 認証情報付き(Cookie)
header('Access-Control-Allow-Credentials: true');
// → JS 側は fetch(url, { credentials: 'include' })

// Preflight (OPTIONS) が来るのは
// - 独自ヘッダがある
// - PUT/DELETE/PATCH
// - Content-Type が application/json

JS との連携(fetch / axios)

// fetch API
const params = new URLSearchParams({ q: 'php', page: 2 });
fetch(`/api/search?${params}`, {
  headers: { Accept: 'application/json' },
})
  .then(r => r.json())
  .then(data => console.log(data));

// axios
import axios from 'axios';
const { data } = await axios.get('/api/search', {
  params: { q: 'php', page: 2, ids: [1, 2, 3] },
  paramsSerializer: { indexes: false },  // ?ids=1&ids=2 形式
});

Postman / curl での検証

# curl で GET
curl -G https://api.example.com/users \
  -H &quot;Accept: application/json&quot; \
  -H &quot;Authorization: Bearer $TOKEN&quot; \
  --data-urlencode &quot;q=php&quot; \
  --data-urlencode &quot;page=2&quot;

# ヘッダも表示
curl -i 'https://api.example.com/users?q=php'

# 詳細トレース
curl -v 'https://api.example.com/users?q=php'

# レスポンスを保存
curl -o out.json 'https://api.example.com/users'

Postman では Params タブにキー / バリューを追加すれば自動で URL にクエリが反映されます。Auth タブで Bearer Token、Headers タブでカスタムヘッダを設定。

注意点とアンチパターン

  • パスワード / トークンを GET で送らない → アクセスログに残る
  • 長い URL は 414 URI Too Long を引き起こす
  • GET で副作用(DB 更新)を起こすとブラウザ プリフェッチで意図せず実行される
  • $_GET['param']直接 SQL に埋め込まない → プリペアド文に渡す
  • XSS 防止のため、出力時は htmlspecialchars() + ホワイトリスト検証

FAQ

Q: GET の上限文字数は?
A: ブラウザは 2000〜8000 程度を保証、サーバは Nginx の large_client_header_buffers で調整。大きいデータは POST + body を使う。

Q: GET と POST どちらを使うべき?
A: 取得のみ → GET状態変更 → POST/PUT/DELETE。RESTful 設計が API のキャッシュ性能を上げます。

Q: 同じパラメータ名を複数回送ると?
A: ?id=1&amp;id=2$_GET['id'] に最後の値「2」だけが入ります。配列にするには ?id[]=1&amp;id[]=2