php runtime and server environment

Context Options

PHP streams can read from files, URLs, sockets, compressed data, and other wrappers. Context options let you change how those streams behave. You will most often see them with functions such as file_get_contents(), fopen(), and copy().

For junior PHP work, the practical use is understanding small integrations and legacy code. Modern applications often use a dedicated HTTP client such as Guzzle or Symfony HttpClient, but stream contexts still appear in older projects, simple scripts, package code, and small diagnostics.

Creating a context

A stream context is created with stream_context_create(). The options are grouped by wrapper name, such as http, ssl, or ftp.

PHP example
<?php

declare(strict_types=1);

$context = stream_context_create([
    'http' => [
        'method' => 'GET',
        'header' => "Accept: application/json\r\n",
        'timeout' => 5,
    ],
]);

echo get_resource_type($context) . PHP_EOL;

// Prints:
// stream-context

The context itself does not make a request. It is passed to a stream function that uses it.

HTTP options

The http wrapper can set request methods, headers, content, timeouts, and whether PHP should still return a response body for error status codes.

PHP example
<?php

declare(strict_types=1);

$payload = json_encode(['email' => 'ada@example.com'], JSON_THROW_ON_ERROR);

$context = stream_context_create([
    'http' => [
        'method' => 'POST',
        'header' => implode("\r\n", [
            'Content-Type: application/json',
            'Accept: application/json',
        ]),
        'content' => $payload,
        'timeout' => 3,
        'ignore_errors' => true,
    ],
]);

echo strlen($payload) . PHP_EOL;
echo get_resource_type($context) . PHP_EOL;

// Prints:
// 27
// stream-context

ignore_errors is badly named. It does not ignore network failures. It allows PHP to return the response body even when the server replies with an HTTP error status such as 400 or 500. That can be useful when an API sends validation details in the response body.

Reading response headers

After using the HTTP wrapper, PHP exposes response headers in $http_response_header in the local scope.

PHP example
<?php

declare(strict_types=1);

function firstStatusLine(array $headers): string
{
    return $headers[0] ?? 'No response headers';
}

echo firstStatusLine(['HTTP/1.1 404 Not Found', 'Content-Type: application/json']) . PHP_EOL;

// Prints:
// HTTP/1.1 404 Not Found

In production code, handle the case where no response was received. DNS failures, timeouts, blocked outbound network access, and TLS problems can all prevent an HTTP response from existing.

SSL options

The ssl context controls TLS behaviour for secure connections.

PHP example
<?php

declare(strict_types=1);

$context = stream_context_create([
    'ssl' => [
        'verify_peer' => true,
        'verify_peer_name' => true,
        'cafile' => '/etc/ssl/certs/ca-certificates.crt',
    ],
]);

echo get_resource_type($context) . PHP_EOL;

// Prints:
// stream-context

Do not disable verify_peer or verify_peer_name to "fix" HTTPS in production. That removes certificate verification and can make the connection vulnerable to interception. If certificates fail, fix the CA bundle, hostname, certificate chain, system clock, or environment configuration.

Error handling

Many stream functions return false on failure and may also emit warnings. Treat the return value as untrusted.

PHP example
<?php

declare(strict_types=1);

function requireString(string|false $value, string $message): string
{
    if ($value === false) {
        throw new RuntimeException($message);
    }

    return $value;
}

$body = requireString('{"ok":true}', 'Request failed.');

echo $body . PHP_EOL;

// Prints:
// {"ok":true}

The helper above is deliberately small. In real HTTP code, you would also inspect status codes, parse JSON safely, log failures, and avoid leaking secrets in error messages.

When to use a real HTTP client

Stream contexts are fine for small scripts and simple integrations. For application-level HTTP work, a proper client usually gives you clearer APIs for retries, redirects, JSON, authentication, connection pooling, testing, middleware, and structured exceptions.

Use stream contexts when the dependency cost is not worth it or when you are maintaining existing code. Use a real client when HTTP behaviour is central to the application.

What you should be able to do

After this lesson, you should be able to create a stream context, set HTTP headers and timeouts, understand ignore_errors, recognise dangerous TLS shortcuts, and know when a dedicated HTTP client is a better choice.

Practice

Task: Build An HTTP Stream Context

Create a PHP script that prepares a JSON POST request using stream context options.

Requirements

  • Build a JSON payload from an array.
  • Create an http context with method, header, content, timeout, and ignore_errors.
  • Keep the script runnable without making a real network request.
  • Print the payload length and the context resource type.
  • Add a short note explaining what ignore_errors does and why TLS verification should not be disabled in production.

Check your work

The script should show that the context is configured correctly without depending on an external API being available.

Show solution

One possible solution is to prepare the payload and context without calling file_get_contents() against a real URL.

PHP example
<?php

declare(strict_types=1);

$payload = json_encode([
    'email' => 'ada@example.com',
    'active' => true,
], JSON_THROW_ON_ERROR);

$context = stream_context_create([
    'http' => [
        'method' => 'POST',
        'header' => implode("\r\n", [
            'Content-Type: application/json',
            'Accept: application/json',
        ]),
        'content' => $payload,
        'timeout' => 3,
        'ignore_errors' => true,
    ],
    'ssl' => [
        'verify_peer' => true,
        'verify_peer_name' => true,
    ],
]);

echo 'payload_bytes: ' . strlen($payload) . PHP_EOL;
echo 'context_type: ' . get_resource_type($context) . PHP_EOL;

// Prints:
// payload_bytes: 41
// context_type: stream-context

ignore_errors allows PHP to return an HTTP response body for error statuses such as 400 or 500; it does not make network failures safe to ignore. TLS verification should stay enabled in production because disabling it means PHP no longer proves it is connected to the intended HTTPS server.