[PHP]stream_context_get_default完全解説|デフォルトストリームコンテキストの取得・活用法を実践サンプルで理解する

PHP

stream_context_get_defaultとは?

stream_context_get_default() は、PHPが内部で保持しているデフォルトストリームコンテキストを取得する関数です。

PHPのストリーム関数(file_get_contents()fopen()readfile() など)は、コンテキストを明示的に渡さない場合、このデフォルトコンテキストを暗黙的に使用しています。stream_context_get_default() でそのコンテキストを取得・確認したり、引数にオプション配列を渡すことでデフォルトコンテキストを上書き設定することもできます。

「全ストリーム関数に共通の設定を一括で適用したい」というケースで特に力を発揮します。


基本構文

stream_context_get_default(array $options = []): resource
引数説明
$optionsarray(省略可)デフォルトコンテキストに上書き適用するオプション
戻り値resourceデフォルトストリームコンテキストリソース

stream_context_set_default() との違い

PHP 5.3.0 以降、同じ目的で stream_context_set_default() も利用できます。

関数動作
stream_context_get_default(array $options)取得しつつ、引数があれば上書きも行う
stream_context_set_default(array $options)設定専用(引数は必須)。戻り値は新しいデフォルトコンテキスト

どちらもデフォルトコンテキストを変更できますが、「まず現在の状態を取得したい」なら get_default()「設定のみ行いたい」なら set_default() が意図を明確にします。


基本的な使い方

<?php
// デフォルトコンテキストをそのまま取得(オプション変更なし)
$defaultContext = stream_context_get_default();
var_dump(stream_context_get_options($defaultContext));
// array(0) {} ← 初期状態は空

// オプションを渡してデフォルトコンテキストを上書きしつつ取得
$context = stream_context_get_default([
    'http' => [
        'timeout'    => 10,
        'user_agent' => 'MyApp/1.0',
    ],
]);

// 以降、コンテキストを明示しない file_get_contents() にも上記設定が適用される
$html = file_get_contents('https://www.php.net/');

実践クラスサンプル

サンプル1:アプリケーション起動時にグローバル設定を一括適用するクラス

<?php

class HttpDefaultContextInitializer
{
    private string $userAgent;
    private int    $timeout;
    private bool   $followLocation;

    public function __construct(
        string $userAgent     = 'MyPHPApp/1.0',
        int    $timeout       = 15,
        bool   $followLocation = true
    ) {
        $this->userAgent      = $userAgent;
        $this->timeout        = $timeout;
        $this->followLocation = $followLocation;
    }

    /**
     * アプリ起動時に一度呼び出すことで
     * 全ストリーム関数にデフォルト設定が適用される
     */
    public function initialize(): void
    {
        stream_context_get_default([
            'http' => [
                'user_agent'      => $this->userAgent,
                'timeout'         => $this->timeout,
                'follow_location' => (int)$this->followLocation,
                'max_redirects'   => 5,
                'ignore_errors'   => true,
            ],
            'ssl' => [
                'verify_peer'      => true,
                'verify_peer_name' => true,
            ],
        ]);
    }

    public function getCurrentOptions(): array
    {
        $ctx = stream_context_get_default();
        return stream_context_get_options($ctx);
    }
}

// 使用例:アプリ起動時に1度だけ呼ぶ
$initializer = new HttpDefaultContextInitializer(
    userAgent: 'SampleCrawler/2.0',
    timeout:   20
);
$initializer->initialize();

// 以降はコンテキスト指定なしでもデフォルト設定が適用される
$body = file_get_contents('https://httpbin.org/get');
echo mb_strimwidth($body, 0, 120, '...') . "\n";

// 現在のデフォルト設定を確認
$opts = $initializer->getCurrentOptions();
echo "User-Agent: " . $opts['http']['user_agent'] . "\n";
echo "Timeout: "    . $opts['http']['timeout']    . "\n";

サンプル2:デフォルトコンテキストの現在状態を検査・レポートするクラス

<?php

class StreamContextInspector
{
    public function getDefaultOptions(): array
    {
        $ctx = stream_context_get_default();
        return stream_context_get_options($ctx);
    }

    public function getDefaultParams(): array
    {
        $ctx = stream_context_get_default();
        return stream_context_get_params($ctx);
    }

    public function report(): void
    {
        $options = $this->getDefaultOptions();

        if (empty($options)) {
            echo "デフォルトコンテキストにオプションは設定されていません。\n";
            return;
        }

        echo "=== デフォルトストリームコンテキスト ===\n";
        foreach ($options as $wrapper => $wrapperOptions) {
            echo "\n[{$wrapper}]\n";
            foreach ($wrapperOptions as $key => $value) {
                $display = is_bool($value)
                    ? ($value ? 'true' : 'false')
                    : (string)$value;
                echo "  {$key}: {$display}\n";
            }
        }
    }

    public function hasWrapper(string $wrapper): bool
    {
        return isset($this->getDefaultOptions()[$wrapper]);
    }

    public function getOption(string $wrapper, string $key): mixed
    {
        return $this->getDefaultOptions()[$wrapper][$key] ?? null;
    }
}

// 使用例
stream_context_get_default([
    'http' => ['timeout' => 30, 'user_agent' => 'Inspector/1.0'],
    'ssl'  => ['verify_peer' => true],
]);

$inspector = new StreamContextInspector();
$inspector->report();

echo "\nhttpラッパーあり: " . ($inspector->hasWrapper('http') ? 'Yes' : 'No') . "\n";
echo "timeout設定値: "    . $inspector->getOption('http', 'timeout') . "\n";

サンプル3:環境ごとにデフォルトコンテキストを切り替えるファクトリクラス

本番・ステージング・ローカル開発で異なる設定を適用します。

<?php

class EnvironmentContextFactory
{
    public static function apply(string $env): void
    {
        $options = match ($env) {
            'production' => [
                'http' => [
                    'timeout'         => 10,
                    'user_agent'      => 'ProductionApp/1.0',
                    'follow_location' => 1,
                    'ignore_errors'   => false,
                ],
                'ssl' => [
                    'verify_peer'      => true,
                    'verify_peer_name' => true,
                    'allow_self_signed'=> false,
                ],
            ],
            'staging' => [
                'http' => [
                    'timeout'         => 20,
                    'user_agent'      => 'StagingApp/1.0',
                    'follow_location' => 1,
                    'ignore_errors'   => true,
                ],
                'ssl' => [
                    'verify_peer'      => true,
                    'verify_peer_name' => true,
                    'allow_self_signed'=> true,  // ステージングは自己署名を許可
                ],
            ],
            'local' => [
                'http' => [
                    'timeout'         => 60,
                    'user_agent'      => 'LocalDev/1.0',
                    'follow_location' => 1,
                    'ignore_errors'   => true,
                ],
                'ssl' => [
                    'verify_peer'      => false,  // ローカルのみ検証スキップ
                    'verify_peer_name' => false,
                    'allow_self_signed'=> true,
                ],
            ],
            default => throw new InvalidArgumentException("不明な環境: {$env}"),
        };

        stream_context_get_default($options);
    }
}

// 使用例:環境変数から自動判別
$env = getenv('APP_ENV') ?: 'local';
EnvironmentContextFactory::apply($env);

echo "環境 [{$env}] のデフォルトコンテキストを適用しました\n";

// 以降のすべてのストリーム操作に適用される
$data = file_get_contents('https://jsonplaceholder.typicode.com/todos/1');
echo $data . "\n";

サンプル4:デフォルトコンテキストを一時的に差し替えるスコープガードクラス

処理ブロック内だけ設定を変え、終了後に元に戻します。

<?php

class DefaultContextScope
{
    private array $previous;

    public function __construct(array $options)
    {
        // 現在のデフォルトオプションを退避
        $ctx            = stream_context_get_default();
        $this->previous = stream_context_get_options($ctx);

        // 新しいオプションを適用
        stream_context_get_default($options);
    }

    public function restore(): void
    {
        // 退避しておいたオプションに戻す
        stream_context_get_default($this->previous);
    }
}

// 使用例
echo "=== 通常設定 ===\n";
stream_context_get_default(['http' => ['timeout' => 10, 'user_agent' => 'Default/1.0']]);
$ctx  = stream_context_get_default();
$opts = stream_context_get_options($ctx);
echo "timeout: {$opts['http']['timeout']}, agent: {$opts['http']['user_agent']}\n";

// 一時的に別設定へ切り替え
$scope = new DefaultContextScope([
    'http' => ['timeout' => 60, 'user_agent' => 'HeavyTask/1.0'],
]);

echo "\n=== 一時設定(スコープ内)===\n";
$ctx  = stream_context_get_default();
$opts = stream_context_get_options($ctx);
echo "timeout: {$opts['http']['timeout']}, agent: {$opts['http']['user_agent']}\n";

// スコープ終了、元の設定に戻す
$scope->restore();

echo "\n=== 元の設定に復元 ===\n";
$ctx  = stream_context_get_default();
$opts = stream_context_get_options($ctx);
echo "timeout: {$opts['http']['timeout']}, agent: {$opts['http']['user_agent']}\n";

サンプル5:デフォルトコンテキストに認証ヘッダーを注入するクラス

内部システムへのリクエストで、全呼び出しに共通トークンを付与します。

<?php

class DefaultContextAuthInjector
{
    private string $token;

    public function __construct(string $token)
    {
        $this->token = $token;
    }

    public function inject(): void
    {
        // 既存のhttpオプションを取得して、ヘッダーだけ追記する
        $ctx     = stream_context_get_default();
        $current = stream_context_get_options($ctx)['http'] ?? [];

        $existingHeader = $current['header'] ?? '';
        $authHeader     = "Authorization: Bearer {$this->token}\r\n"
                        . "X-App-Token: {$this->token}\r\n";

        $current['header'] = $existingHeader . $authHeader;

        stream_context_get_default(['http' => $current]);
    }

    public function revoke(): void
    {
        $ctx     = stream_context_get_default();
        $current = stream_context_get_options($ctx)['http'] ?? [];

        // Authorizationヘッダーを除去
        if (isset($current['header'])) {
            $lines = explode("\r\n", trim($current['header']));
            $lines = array_filter($lines, function (string $line): bool {
                return !str_starts_with($line, 'Authorization:')
                    && !str_starts_with($line, 'X-App-Token:');
            });
            $current['header'] = implode("\r\n", $lines) . "\r\n";
        }

        stream_context_get_default(['http' => $current]);
    }
}

// 使用例
$injector = new DefaultContextAuthInjector(token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9');
$injector->inject();

// この file_get_contents にも自動的にAuthorizationヘッダーが付く
// $data = file_get_contents('https://api.internal.example.com/data');

$ctx  = stream_context_get_default();
$opts = stream_context_get_options($ctx);
echo "現在のヘッダー:\n" . ($opts['http']['header'] ?? '(なし)') . "\n";

// トークン無効化
$injector->revoke();
echo "\n認証ヘッダー削除後:\n";
$opts = stream_context_get_options(stream_context_get_default());
echo $opts['http']['header'] ?? '(ヘッダーなし)';
echo "\n";

サンプル6:デフォルトコンテキストを使ったシンプルなHTTPラッパー関数群

<?php

class DefaultContextHttpHelper
{
    /**
     * デフォルトコンテキストをベースに、追加オプションだけ上書きして取得
     */
    public static function fetchWithOverride(string $url, array $override = []): string|false
    {
        // 現在のデフォルトを取得
        $ctx     = stream_context_get_default();
        $current = stream_context_get_options($ctx);

        // httpオプションだけ上書きマージ
        $merged = array_merge_recursive($current, $override);

        // 一時的なコンテキストを作成(デフォルトは変更しない)
        $tempCtx = stream_context_create($merged);

        return file_get_contents($url, false, $tempCtx);
    }

    /**
     * 現在のデフォルト設定のサマリーを返す
     */
    public static function summary(): string
    {
        $opts  = stream_context_get_options(stream_context_get_default());
        $lines = [];

        foreach ($opts as $wrapper => $settings) {
            foreach ($settings as $key => $val) {
                $lines[] = "{$wrapper}.{$key} = " . (is_bool($val) ? ($val ? 'true' : 'false') : $val);
            }
        }

        return empty($lines) ? '(設定なし)' : implode("\n", $lines);
    }
}

// 使用例
stream_context_get_default([
    'http' => ['timeout' => 10, 'user_agent' => 'Base/1.0'],
]);

// デフォルトは timeout=10 だが、このリクエストだけ timeout=30 で実行
$body = DefaultContextHttpHelper::fetchWithOverride(
    'https://jsonplaceholder.typicode.com/posts/1',
    ['http' => ['timeout' => 30]]
);

echo json_decode($body, true)['title'] . "\n";

echo "\n現在のデフォルト設定:\n";
echo DefaultContextHttpHelper::summary() . "\n";

サンプル7:テスト用にデフォルトコンテキストをモック設定するクラス

ユニットテストやスタブ処理でデフォルトコンテキストを差し替えます。

<?php

class StreamContextTestHelper
{
    private static array $originalOptions = [];

    /**
     * テスト前にデフォルトコンテキストを保存して差し替え
     */
    public static function setUp(array $mockOptions): void
    {
        $ctx                   = stream_context_get_default();
        self::$originalOptions = stream_context_get_options($ctx);
        stream_context_get_default($mockOptions);
    }

    /**
     * テスト後に元の設定に復元
     */
    public static function tearDown(): void
    {
        stream_context_get_default(self::$originalOptions);
        self::$originalOptions = [];
    }

    /**
     * 現在のデフォルトオプションが期待値を含むか検証
     */
    public static function assertOption(string $wrapper, string $key, mixed $expected): bool
    {
        $ctx     = stream_context_get_default();
        $options = stream_context_get_options($ctx);
        $actual  = $options[$wrapper][$key] ?? null;

        $result = $actual === $expected;
        $status = $result ? 'PASS' : 'FAIL';
        echo "[{$status}] {$wrapper}.{$key}: 期待={$expected}, 実際=" . var_export($actual, true) . "\n";

        return $result;
    }
}

// テスト例
echo "=== テスト開始 ===\n";

StreamContextTestHelper::setUp([
    'http' => ['timeout' => 5, 'user_agent' => 'TestBot/1.0', 'ignore_errors' => true],
]);

StreamContextTestHelper::assertOption('http', 'timeout',       5);
StreamContextTestHelper::assertOption('http', 'user_agent',    'TestBot/1.0');
StreamContextTestHelper::assertOption('http', 'ignore_errors', true);
StreamContextTestHelper::assertOption('http', 'method',        'GET'); // 設定していないのでFAIL

StreamContextTestHelper::tearDown();
echo "\nテスト後にデフォルトコンテキストを復元しました\n";

関連関数との比較

関数用途
stream_context_get_default()デフォルトコンテキストを取得(引数付きで上書きも可)
stream_context_set_default()デフォルトコンテキストを設定(引数は必須)
stream_context_create()新規のコンテキストリソースを作成
stream_context_get_options()コンテキストのオプションを取得
stream_context_get_params()コンテキストのパラメータを取得
stream_context_set_option()既存コンテキストにオプションを追加・変更

注意点

  • デフォルトコンテキストへの変更はプロセス全体・スクリプト全体に影響します。意図しない箇所の動作変更に注意してください。
  • stream_context_get_default() に配列を渡すと、指定したオプションがマージではなく上書きされます。既存設定を維持したい場合は、一度 stream_context_get_options() で取得してからマージしてください(サンプル5・6参照)。
  • SSL検証を無効化するオプション(verify_peer: false)は、ローカル開発環境専用です。本番では必ず有効にしてください。

まとめ

項目内容
関数名stream_context_get_default()
分類ストリームコンテキスト関数
PHP バージョンPHP 5.1.0以上
戻り値デフォルトストリームコンテキストリソース
主な用途全ストリーム関数への共通設定の一括適用・取得

stream_context_get_default() は、アプリケーション全体のストリーム通信設定を一か所で管理するための関数です。タイムアウト・User-Agent・SSL設定などをアプリ起動時に一度設定するだけで、個別にコンテキストを渡す手間がなくなります。環境ごとの設定切り替えや、テスト時の一時的な差し替えにも活用でき、ストリームを多用するアプリケーションの可読性と保守性を大きく向上させます。

タイトルとURLをコピーしました