file_get_contents

PHP標準関数による最もシンプルなHTTPクライアント機能。stream contextと組み合わせることで基本的なHTTPリクエストを送信可能。軽量でゼロ依存関係、プロトタイピングや簡単なAPI呼び出しに適している。

HTTPクライアントPHP組み込み関数シンプルストリームコンテキスト

ライブラリ

file_get_contents

概要

file_get_contentsは「PHP組み込みのファイル読み込み関数」として提供され、HTTPリクエスト機能も統合したPHPコアの基本関数です。本来はファイル読み込み用途ですが、URLを指定することでHTTPクライアントとしても機能し、GET/POSTリクエスト、カスタムヘッダー、認証、SSL設定などをストリームコンテキストで制御可能。cURLのような専用ライブラリと比較してシンプルで軽量ながら、一般的なWeb API統合に必要十分な機能を提供し、PHPアプリケーションでの手軽なHTTP通信を実現します。

詳細

file_get_contents 2025年版はPHP 8.x時代においても最もシンプルなHTTP通信手段として重要な位置を占めています。PHP 5.0時代から存在する歴史の長い関数でありながら、ストリームコンテキスト機能により現代的なHTTP通信要件に対応。外部ライブラリのインストールが不要でPHP標準機能のみで動作するため、軽量なスクリプトやクイックプロトタイピングに最適。GET/POSTリクエスト、カスタムヘッダー、HTTPS対応、プロキシ設定、認証、エラーハンドリングなど基本的なHTTP機能を包括的にサポートします。

主な特徴

  • 組み込み関数: PHP標準搭載で追加インストール不要
  • 統一インターフェース: ファイル読み込みとHTTPリクエストの一貫したAPI
  • ストリームコンテキスト: 詳細なHTTPオプション設定が可能
  • HTTPS対応: SSL/TLS通信とカスタム証明書設定をサポート
  • 軽量実装: 最小限のオーバーヘッドで高速動作
  • エラーハンドリング: HTTPステータスコードとレスポンスヘッダーアクセス

メリット・デメリット

メリット

  • PHP標準関数のため追加ライブラリ不要で即座に利用可能
  • シンプルな一行コードでHTTPリクエストが実行可能
  • ストリームコンテキストによる詳細な設定制御
  • ファイル操作とHTTP通信の統一的なインターフェース
  • 軽量で高速、メモリ使用量が少ない
  • 豊富なオンライン情報と学習リソースの存在

デメリット

  • cURLと比較して高度な機能(並列リクエスト、詳細制御)が制限的
  • 非同期処理に対応しておらず同期実行のみ
  • 大容量ファイルのダウンロード時にメモリ使用量が増大
  • リダイレクト処理やクッキー管理が基本的
  • エラーハンドリングが限定的でデバッグ情報が少ない
  • HTTP/2やHTTP/3などの新しいプロトコルに非対応

参考ページ

書き方の例

基本的なHTTPリクエスト(GET/POST)

<?php
// 基本的なGETリクエスト
$content = file_get_contents('https://api.example.com/users');
echo $content;

// JSONレスポンスの処理
$json_response = file_get_contents('https://api.example.com/data');
$data = json_decode($json_response, true);
print_r($data);

// クエリパラメータ付きGETリクエスト
$params = http_build_query([
    'page' => 1,
    'limit' => 10,
    'sort' => 'created_at'
]);
$url = 'https://api.example.com/users?' . $params;
$response = file_get_contents($url);

// POSTリクエスト(フォームデータ)
$post_data = http_build_query([
    'name' => '田中太郎',
    'email' => '[email protected]',
    'age' => 30
]);

$context = stream_context_create([
    'http' => [
        'method' => 'POST',
        'header' => 'Content-Type: application/x-www-form-urlencoded',
        'content' => $post_data
    ]
]);

$result = file_get_contents('https://api.example.com/users', false, $context);
echo $result;

// POSTリクエスト(JSON送信)
$json_data = json_encode([
    'name' => '山田花子',
    'email' => '[email protected]',
    'department' => 'IT'
]);

$context = stream_context_create([
    'http' => [
        'method' => 'POST',
        'header' => 'Content-Type: application/json',
        'content' => $json_data
    ]
]);

$response = file_get_contents('https://api.example.com/users', false, $context);

// PUTリクエスト(データ更新)
$update_data = json_encode(['name' => '田中次郎']);

$context = stream_context_create([
    'http' => [
        'method' => 'PUT',
        'header' => 'Content-Type: application/json',
        'content' => $update_data
    ]
]);

$response = file_get_contents('https://api.example.com/users/123', false, $context);

// DELETEリクエスト
$context = stream_context_create([
    'http' => [
        'method' => 'DELETE',
        'header' => 'Authorization: Bearer your-token'
    ]
]);

$response = file_get_contents('https://api.example.com/users/123', false, $context);
?>

ストリームコンテキストとカスタムヘッダー

<?php
// カスタムヘッダー付きリクエスト
$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => [
            'User-Agent: MyApp/1.0 (PHP)',
            'Accept: application/json',
            'Accept-Language: ja-JP,en-US',
            'Authorization: Bearer your-jwt-token',
            'X-API-Version: v2',
            'X-Request-ID: req-' . uniqid()
        ]
    ]
]);

$response = file_get_contents('https://api.example.com/data', false, $context);

// 複数ヘッダーの組み合わせ
$headers = [
    'Authorization: Bearer ' . $api_token,
    'Content-Type: application/json',
    'Accept: application/json',
    'User-Agent: MyPHPApp/1.0'
];

$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => implode("\r\n", $headers)
    ]
]);

$data = file_get_contents('https://api.example.com/protected', false, $context);

// Basic認証
$username = 'user';
$password = 'pass';
$auth_header = 'Authorization: Basic ' . base64_encode($username . ':' . $password);

$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => $auth_header
    ]
]);

$content = file_get_contents('https://api.example.com/private', false, $context);

// Cookie付きリクエスト
$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => 'Cookie: session_id=abc123; user_pref=dark_mode'
    ]
]);

$response = file_get_contents('https://api.example.com/user-data', false, $context);

// タイムアウト設定
$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'timeout' => 30,  // 30秒でタイムアウト
        'header' => 'User-Agent: MyApp/1.0'
    ]
]);

try {
    $content = file_get_contents('https://slow-api.example.com/data', false, $context);
    echo "レスポンス取得成功\n";
} catch (Exception $e) {
    echo "タイムアウトまたはエラー: " . $e->getMessage() . "\n";
}

// プロキシ設定
$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'proxy' => 'tcp://proxy.example.com:8080',
        'request_fulluri' => true,
        'header' => 'Proxy-Authorization: Basic ' . base64_encode('proxy_user:proxy_pass')
    ]
]);

$response = file_get_contents('https://api.example.com/data', false, $context);
?>

HTTPS設定とSSL制御

<?php
// 基本的なHTTPS接続
$content = file_get_contents('https://secure-api.example.com/data');

// SSL証明書検証の無効化(開発環境のみ)
$context = stream_context_create([
    'ssl' => [
        'verify_peer' => false,
        'verify_peer_name' => false
    ]
]);

$response = file_get_contents('https://self-signed.example.com/api', false, $context);

// SSL証明書の詳細設定
$context = stream_context_create([
    'ssl' => [
        'verify_peer' => true,
        'verify_peer_name' => true,
        'cafile' => '/path/to/ca-bundle.crt',
        'local_cert' => '/path/to/client.pem',
        'local_pk' => '/path/to/client.key',
        'passphrase' => 'client-key-password'
    ],
    'http' => [
        'method' => 'GET',
        'header' => 'User-Agent: SecureApp/1.0'
    ]
]);

$secure_data = file_get_contents('https://enterprise-api.example.com/data', false, $context);

// 暗号化設定
$context = stream_context_create([
    'ssl' => [
        'crypto_method' => STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT,
        'verify_peer' => true,
        'verify_peer_name' => true,
        'ciphers' => 'HIGH:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK'
    ]
]);

$response = file_get_contents('https://high-security-api.example.com/data', false, $context);

// SNI (Server Name Indication) 対応
$context = stream_context_create([
    'ssl' => [
        'SNI_enabled' => true,
        'SNI_server_name' => 'api.example.com'
    ]
]);

$content = file_get_contents('https://api.example.com/data', false, $context);
?>

エラーハンドリングとレスポンス情報取得

<?php
// エラーを無視してレスポンスを取得
$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'ignore_errors' => true,  // エラーレスポンスも取得
        'header' => 'User-Agent: MyApp/1.0'
    ]
]);

$response = file_get_contents('https://api.example.com/might-fail', false, $context);

// レスポンスヘッダーの確認
if ($response !== false) {
    // グローバル変数 $http_response_header にレスポンスヘッダーが格納される
    echo "レスポンスヘッダー:\n";
    foreach ($http_response_header as $header) {
        echo $header . "\n";
    }
    
    // ステータスコードの抽出
    if (isset($http_response_header[0])) {
        preg_match('/HTTP\/\d\.\d\s+(\d+)/', $http_response_header[0], $matches);
        $status_code = isset($matches[1]) ? (int)$matches[1] : 0;
        echo "ステータスコード: " . $status_code . "\n";
        
        if ($status_code >= 200 && $status_code < 300) {
            echo "成功レスポンス\n";
            $data = json_decode($response, true);
        } elseif ($status_code >= 400) {
            echo "エラーレスポンス: " . $response . "\n";
        }
    }
}

// 包括的なエラーハンドリング関数
function safe_http_request($url, $options = []) {
    $default_options = [
        'http' => [
            'method' => 'GET',
            'timeout' => 30,
            'ignore_errors' => true,
            'header' => 'User-Agent: SafeHTTPClient/1.0'
        ]
    ];
    
    // オプションをマージ
    $context_options = array_merge_recursive($default_options, $options);
    $context = stream_context_create($context_options);
    
    // リクエスト実行
    $response = @file_get_contents($url, false, $context);
    
    if ($response === false) {
        $error = error_get_last();
        throw new Exception("HTTPリクエストに失敗しました: " . ($error['message'] ?? 'Unknown error'));
    }
    
    // レスポンス情報を解析
    global $http_response_header;
    $status_code = 0;
    $response_headers = [];
    
    if (isset($http_response_header)) {
        foreach ($http_response_header as $header) {
            if (preg_match('/HTTP\/\d\.\d\s+(\d+)/', $header, $matches)) {
                $status_code = (int)$matches[1];
            }
            $response_headers[] = $header;
        }
    }
    
    return [
        'status_code' => $status_code,
        'headers' => $response_headers,
        'body' => $response,
        'success' => $status_code >= 200 && $status_code < 300
    ];
}

// 使用例
try {
    $result = safe_http_request('https://api.example.com/data', [
        'http' => [
            'method' => 'POST',
            'header' => 'Content-Type: application/json',
            'content' => json_encode(['key' => 'value'])
        ]
    ]);
    
    if ($result['success']) {
        echo "成功: " . $result['body'] . "\n";
    } else {
        echo "エラー (Status: {$result['status_code']}): " . $result['body'] . "\n";
    }
    
} catch (Exception $e) {
    echo "例外: " . $e->getMessage() . "\n";
}

// ファイル保存とHTTPダウンロード
function download_file($url, $local_path, $headers = []) {
    $context_options = [
        'http' => [
            'method' => 'GET',
            'timeout' => 300,  // 5分でタイムアウト
            'header' => array_merge([
                'User-Agent: FileDownloader/1.0'
            ], $headers)
        ]
    ];
    
    $context = stream_context_create($context_options);
    $content = file_get_contents($url, false, $context);
    
    if ($content === false) {
        throw new Exception("ファイルのダウンロードに失敗しました");
    }
    
    $bytes_written = file_put_contents($local_path, $content);
    
    if ($bytes_written === false) {
        throw new Exception("ファイルの保存に失敗しました");
    }
    
    return $bytes_written;
}

// 使用例
try {
    $bytes = download_file(
        'https://example.com/large-file.zip',
        '/tmp/downloaded.zip',
        ['Authorization: Bearer your-token']
    );
    echo "ダウンロード完了: {$bytes} バイト\n";
} catch (Exception $e) {
    echo "ダウンロードエラー: " . $e->getMessage() . "\n";
}
?>

実用的なAPIクライアント実装

<?php
// 再利用可能なAPIクライアントクラス
class SimpleAPIClient {
    private $base_url;
    private $default_headers;
    private $timeout;
    
    public function __construct($base_url, $headers = [], $timeout = 30) {
        $this->base_url = rtrim($base_url, '/');
        $this->default_headers = $headers;
        $this->timeout = $timeout;
    }
    
    public function get($endpoint, $params = [], $headers = []) {
        $url = $this->base_url . '/' . ltrim($endpoint, '/');
        
        if (!empty($params)) {
            $url .= '?' . http_build_query($params);
        }
        
        return $this->request('GET', $url, null, $headers);
    }
    
    public function post($endpoint, $data = null, $headers = []) {
        $url = $this->base_url . '/' . ltrim($endpoint, '/');
        return $this->request('POST', $url, $data, $headers);
    }
    
    public function put($endpoint, $data = null, $headers = []) {
        $url = $this->base_url . '/' . ltrim($endpoint, '/');
        return $this->request('PUT', $url, $data, $headers);
    }
    
    public function delete($endpoint, $headers = []) {
        $url = $this->base_url . '/' . ltrim($endpoint, '/');
        return $this->request('DELETE', $url, null, $headers);
    }
    
    private function request($method, $url, $data = null, $headers = []) {
        $all_headers = array_merge($this->default_headers, $headers);
        
        $context_options = [
            'http' => [
                'method' => $method,
                'timeout' => $this->timeout,
                'ignore_errors' => true,
                'header' => implode("\r\n", $all_headers)
            ]
        ];
        
        if ($data !== null) {
            if (is_array($data) || is_object($data)) {
                $context_options['http']['content'] = json_encode($data);
                $context_options['http']['header'] .= "\r\nContent-Type: application/json";
            } else {
                $context_options['http']['content'] = $data;
            }
        }
        
        $context = stream_context_create($context_options);
        $response = @file_get_contents($url, false, $context);
        
        if ($response === false) {
            throw new Exception("HTTP request failed for: $url");
        }
        
        global $http_response_header;
        $status_code = 0;
        
        if (isset($http_response_header[0])) {
            preg_match('/HTTP\/\d\.\d\s+(\d+)/', $http_response_header[0], $matches);
            $status_code = isset($matches[1]) ? (int)$matches[1] : 0;
        }
        
        return [
            'status_code' => $status_code,
            'headers' => $http_response_header ?? [],
            'body' => $response,
            'data' => json_decode($response, true)
        ];
    }
}

// APIクライアント使用例
$client = new SimpleAPIClient('https://api.example.com/v1', [
    'Authorization: Bearer your-api-token',
    'User-Agent: MyApp/1.0'
]);

try {
    // ユーザー一覧取得
    $users = $client->get('users', ['page' => 1, 'limit' => 10]);
    
    if ($users['status_code'] == 200) {
        echo "ユーザー数: " . count($users['data']) . "\n";
    }
    
    // 新しいユーザー作成
    $new_user = $client->post('users', [
        'name' => '佐藤太郎',
        'email' => '[email protected]',
        'role' => 'user'
    ]);
    
    if ($new_user['status_code'] == 201) {
        echo "ユーザー作成成功: ID=" . $new_user['data']['id'] . "\n";
        
        // ユーザー情報更新
        $updated = $client->put("users/{$new_user['data']['id']}", [
            'name' => '佐藤次郎'
        ]);
        
        if ($updated['status_code'] == 200) {
            echo "ユーザー更新成功\n";
        }
    }
    
} catch (Exception $e) {
    echo "APIエラー: " . $e->getMessage() . "\n";
}

// Webhook受信処理
function handle_webhook($payload, $signature, $secret) {
    // 署名検証
    $expected_signature = 'sha256=' . hash_hmac('sha256', $payload, $secret);
    
    if (!hash_equals($expected_signature, $signature)) {
        throw new Exception('Invalid webhook signature');
    }
    
    $data = json_decode($payload, true);
    
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new Exception('Invalid JSON payload');
    }
    
    // 外部APIに通知
    $notification_context = stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => "Content-Type: application/json\r\nAuthorization: Bearer internal-token",
            'content' => json_encode([
                'event' => $data['event'] ?? 'unknown',
                'timestamp' => date('c'),
                'data' => $data
            ]),
            'timeout' => 10
        ]
    ]);
    
    $result = file_get_contents('https://internal-api.example.com/webhooks', false, $notification_context);
    
    return $result !== false;
}

// フォームデータ送信例
function submit_form($url, $form_data, $files = []) {
    $boundary = 'boundary' . uniqid();
    $content = '';
    
    // フォームフィールド
    foreach ($form_data as $name => $value) {
        $content .= "--{$boundary}\r\n";
        $content .= "Content-Disposition: form-data; name=\"{$name}\"\r\n\r\n";
        $content .= "{$value}\r\n";
    }
    
    // ファイル
    foreach ($files as $field_name => $file_path) {
        if (file_exists($file_path)) {
            $filename = basename($file_path);
            $file_content = file_get_contents($file_path);
            $mime_type = mime_content_type($file_path) ?: 'application/octet-stream';
            
            $content .= "--{$boundary}\r\n";
            $content .= "Content-Disposition: form-data; name=\"{$field_name}\"; filename=\"{$filename}\"\r\n";
            $content .= "Content-Type: {$mime_type}\r\n\r\n";
            $content .= "{$file_content}\r\n";
        }
    }
    
    $content .= "--{$boundary}--\r\n";
    
    $context = stream_context_create([
        'http' => [
            'method' => 'POST',
            'header' => "Content-Type: multipart/form-data; boundary={$boundary}",
            'content' => $content
        ]
    ]);
    
    return file_get_contents($url, false, $context);
}

// 使用例
$response = submit_form('https://upload.example.com/submit', [
    'title' => 'ドキュメント',
    'category' => 'report'
], [
    'document' => '/path/to/document.pdf'
]);

echo "フォーム送信完了\n";
?>