# WordPress/Requests: the PHP HTTP client that hides cURL and fsockopen behind one API

> Requests for PHP is a dependency-free HTTP library for PHP 5.6.20 and newer, maintained under the WordPress organisation. It wraps cURL and fsockopen behind a single interface, and this article covers what it does, how to install it, where it stops, and when a PSR-18 client is the better choice.

**WordPress/Requests** — Requests for PHP is a humble HTTP request library. It simplifies how you interact with other sites and takes away all your worries.

- Repository: https://github.com/WordPress/Requests
- Website: https://requests.ryanmccue.info/
- Stars: 3,575 · Forks: 500
- Language: PHP
- License: NOASSERTION
- Published: 2026-09-23 · Updated: 2026-09-23 · Language: en
- Canonical page: https://hysenlabs.com/projects/wordpress-requests

## The problem Requests solves for PHP developers

Sending an HTTP request in PHP has historically meant choosing between two awkward paths. The cURL extension exposes its behaviour through curl_setopt, an option-setting API the README itself calls "interesting, to say the least". Raw sockets give you even less: the README notes they "provide only low level access, and require you to build most of the HTTP response parsing yourself". Neither path is portable, because cURL is not guaranteed to be installed on the machine running your code.

The audience is therefore PHP developers who ship code into environments they do not control: plugins, libraries, small services on shared hosting, CLI scripts. The README frames the goal plainly, saying Requests is "a HTTP library written in PHP, for human beings" and that it is "roughly based on the API from the excellent Requests Python library". If you have written Python's requests, the shape of the PHP call will look familiar: a static method, an array of headers, an array of options, and a response object with status_code, headers and body.

The cost of that convenience is a smaller surface than a modern PSR-18 client. Requests is not a framework component and does not try to be one.

## How the cURL and fsockopen transports are chosen

Requests does not pick a transport at install time. The README states it "uses cURL and fsockopen, depending on what your system has available, but abstracts all the nasty stuff out of your way, providing a consistent API". That abstraction is the core design decision: your calling code does not branch on extension availability, and the library resolves the transport underneath.

The response object is the other half of the contract. The README example calls WpOrg\Requests\Requests::get() and then reads three properties: status_code as an int, headers as an array keyed by lower-case header name (the example reads headers['content-type']), and body as a string. Options and headers are passed as plain PHP arrays rather than builder objects, which keeps the call site short but means the option names are string keys you have to look up.

The feature list is modest and specific: international domains and URLs, browser-style SSL verification, basic and digest authentication, automatic decompression, and connection timeouts. Methods supported are HEAD, GET, POST, PUT, DELETE and PATCH. The repository layout backs this up with a src/ directory, a library/ directory, a certificates/ directory for the SSL material, and an examples/ directory containing one file per scenario: basic-auth.php, cookie.php, cookie_jar.php, get.php, multiple.php, post.php, preload-aliases.php, proxy.php, session.php and timeout.php.

## Installing Requests with Composer or from source

The README gives Composer as the first installation route. Run this in your project root, and Composer will add the package to your vendor directory and update composer.json and composer.lock:

```bash
composer require rmccue/requests
```

If you prefer to pin the constraint by hand, the README shows the equivalent composer.json entry. The caret constraint allows any 2.x release, so you will get v2.0.20 or later within that major line:

```json
{
    "require": {
        "rmccue/requests": "^2.0"
    }
}
```

Without Composer, the README documents cloning the repository and including the bundled autoloader. The require_once line loads the class file, and the static register() call wires it into PHP's autoload stack so that WpOrg\Requests\* classes resolve on demand:

```php
require_once '/path/to/Requests/src/Autoload.php';
WpOrg\Requests\Autoload::register();
```

The README also lists a tarball or zipball download using curl or wget, and a PSR-4 route for projects that already run a class loader such as Symfony ClassLoader, mapping the prefix WpOrg\\Requests\\ to the src directory.

For a first real call, the README's own example is the shortest path to a working request. It fetches a GitHub API endpoint with an Accept header and basic auth, then dumps the three response properties. Expect an int status code, a content-type header string, and the raw body:

```php
$headers = array('Accept' => 'application/json');
$options = array('auth' => array('user', 'pass'));
$request = WpOrg\Requests\Requests::get('https://api.github.com/gists', $headers, $options);

var_dump($request->status_code);
var_dump($request->headers['content-type']);
var_dump($request->body);
```

The examples/ directory is the next place to look, with dedicated files for POST, cookies, proxies, sessions and timeouts. The README points to docs/README.md for prose documentation and to the request() method reference for full parameter detail.

## Where Requests stops: no PSR-7 or PSR-18, and a thin README on details

The most consequential limitation is stated by the project itself. PSR-7 and PSR-18 were created after Requests, and the README says: "At this time, there is no intention to add a native PSR-7/PSR-18 implementation to the Requests library." If your application is built around PSR-18 client interfaces, or you want to swap HTTP clients behind a shared interface, Requests will not slot in directly. The README points to art4/requests-psr18-adapter as the bridge, which means an extra dependency and an adapter layer rather than first-class support.

A second boundary is documentation depth. The README is short by design and defers parameter documentation to docs/README.md and the PHPDoc site. That is fine for the common GET and POST cases, but if you need to reason about redirect policy, proxy configuration or cookie jar behaviour, you will be reading source and example files rather than a single reference page. The examples directory is helpful here, but it is examples, not specification.

Finally, the version floor of PHP 5.6.20 is a compatibility choice, not a modern one. It buys you reach into old hosting, and it also means the library cannot lean on newer language features. If you are on PHP 8 and want an HTTP client written against current PHP, this is not the library pushing that direction.

## Requests versus Guzzle and other PSR-18 clients

The honest comparison is Guzzle, the client most PHP frameworks reach for. The difference in approach is architectural rather than cosmetic. Guzzle is built around PSR-7 message objects and a PSR-18 client interface, with middleware and handler stacks you can compose. Requests is built around static methods and plain arrays, with no PSR interfaces in the core library. That makes Requests shorter to call and easier to drop into a plugin, and it makes Guzzle the better fit when you need to inject a client, swap handlers, or share HTTP behaviour across packages that already speak PSR-18.

The dependency story differs too. The README states Requests "has no dependencies, except for PHP 5.6.20+", so it will not pull a tree of packages into a WordPress plugin. A PSR-18 client typically arrives with its own interface packages and handler dependencies, which matters when you are shipping into an environment where you do not control the full dependency set.

If you want Requests semantics with PSR-7/PSR-18 compatibility, the README's recommended route is the art4/requests-psr18-adapter package. That is a legitimate middle path, but it is an adapter, and adapters add a layer you will have to maintain.

## Licence, maintenance and the upgrade cost of the 2.x line

Requests is released under the ISC licence, which the README describes as "similar to the new BSD license". The repository's LICENSE file is the authoritative text; the GitHub metadata reports the licence as NOASSERTION, so if licence terms matter to your legal review, read the LICENSE file directly rather than relying on the repository label. This is a description of what the project states, not legal advice.

The maintenance picture is active by the available signals. The repository is not archived, the last push was on 2026-09-16, and the release history shows v2.0.20 on 2026-08-31, v2.0.19 on 2026-07-22 and v2.0.18 on 2026-04-30. Patch releases at that cadence suggest bug fixes rather than a stalled project, though the README does not publish a support window or an end-of-life policy for the 1.x line, so plan your own pinning.

Upgrade cost is driven by the namespace. Current code uses WpOrg\Requests\Requests and the WpOrg\Requests\Autoload class, as shown in the README examples. If you carry older code that references the previous namespace, the CHANGELOG.md at the repository root is where the migration detail lives. The README itself does not document rollback, so treat the CHANGELOG as the source of truth before you move a production dependency across a major version.

## Conclusion

Adopt Requests if you are writing PHP that must run on shared hosting where cURL may be missing, or if you maintain WordPress-adjacent code and want one API across GET, POST, PUT, DELETE, PATCH and HEAD. Do not adopt it if your framework already consumes PSR-18 clients and you need interchangeable middleware; the README states there is no intention to add a native PSR-7/PSR-18 implementation, so you would go through the art4/requests-psr18-adapter package instead. Before committing, check that your minimum PHP is 5.6.20 or newer, confirm the transport your host actually provides, and read docs/README.md plus the request() method reference at requests.ryanmccue.info/api-2.x, because the README defers parameter detail there rather than listing it.

## FAQ

### How do I install WordPress/Requests?

The README's first route is Composer: run composer require rmccue/requests, or add "rmccue/requests": "^2.0" to the require block of composer.json. Without Composer you can clone the repository, require src/Autoload.php and call WpOrg\Requests\Autoload::register().

### Does WordPress/Requests support PSR-7 or PSR-18?

No. The README states there is no intention to add a native PSR-7/PSR-18 implementation to the library, because both specifications were created after Requests. It recommends the art4/requests-psr18-adapter package if you need a PSR-7 compatible PSR-18 client.

### Which HTTP methods and authentication types does WordPress/Requests support?

The README lists HEAD, GET, POST, PUT, DELETE and PATCH, along with basic and digest authentication, browser-style SSL verification, automatic decompression and connection timeouts.

### What PHP version does WordPress/Requests require?

The README states the library has no dependencies except for PHP 5.6.20 or newer, and that it is ISC licensed.

### How does WordPress/Requests send a request when cURL is not installed?

The README says Requests uses cURL and fsockopen depending on what the system has available, and abstracts that choice behind a consistent API. Your calling code does not select the transport.

### Where are the WordPress/Requests examples?

The repository has an examples/ directory with one file per scenario, including basic-auth.php, cookie.php, cookie_jar.php, get.php, multiple.php, post.php, proxy.php, session.php and timeout.php. The README also points to docs/README.md for prose documentation.

## Sources

- [Issues](https://github.com/WordPress/Requests/issues)
- [Project website](https://requests.ryanmccue.info/)
- [README](https://github.com/WordPress/Requests/blob/develop/README.md)
- [Releases](https://github.com/WordPress/Requests/releases)
- [WordPress/Requests on GitHub](https://github.com/WordPress/Requests)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/wordpress-requests
