From 21605128f26e770eef5a2c996c6a429a9e94a282 Mon Sep 17 00:00:00 2001 From: Rowan Merewood Date: Fri, 20 Mar 2026 13:06:51 +0000 Subject: [PATCH 1/3] feat: default to CurlPost when cURL is available (#253) Updates the `ReCaptcha` constructor to automatically use `RequestMethod\CurlPost` if the cURL extension is installed (`function_exists('curl_version')`) and the user has not explicitly provided a request method. This provides better reliability out of the box while gracefully falling back to `file_get_contents()` via `RequestMethod\Post` when cURL is not available. --- src/ReCaptcha/ReCaptcha.php | 9 ++++++++- tests/ReCaptcha/ReCaptchaTest.php | 14 ++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/ReCaptcha/ReCaptcha.php b/src/ReCaptcha/ReCaptcha.php index a7d0f2e..a6da30e 100644 --- a/src/ReCaptcha/ReCaptcha.php +++ b/src/ReCaptcha/ReCaptcha.php @@ -172,7 +172,14 @@ public function __construct($secret, ?RequestMethod $requestMethod = null) } $this->secret = $secret; - $this->requestMethod = (is_null($requestMethod)) ? new RequestMethod\Post() : $requestMethod; + + if (!is_null($requestMethod)) { + $this->requestMethod = $requestMethod; + } elseif (function_exists('curl_version')) { + $this->requestMethod = new RequestMethod\CurlPost(); + } else { + $this->requestMethod = new RequestMethod\Post(); + } } /** diff --git a/tests/ReCaptcha/ReCaptchaTest.php b/tests/ReCaptcha/ReCaptchaTest.php index 5b1fa4e..7aa6453 100644 --- a/tests/ReCaptcha/ReCaptchaTest.php +++ b/tests/ReCaptcha/ReCaptchaTest.php @@ -73,6 +73,20 @@ public function testVerifyReturnsErrorOnMissingResponse() $this->assertEquals([Recaptcha::E_MISSING_INPUT_RESPONSE], $response->getErrorCodes()); } + public function testDefaultRequestMethod() + { + $rc = new ReCaptcha('secret'); + $reflection = new \ReflectionClass($rc); + $property = $reflection->getProperty('requestMethod'); + $requestMethod = $property->getValue($rc); + + if (function_exists('curl_version')) { + $this->assertInstanceOf(RequestMethod\CurlPost::class, $requestMethod); + } else { + $this->assertInstanceOf(RequestMethod\Post::class, $requestMethod); + } + } + public function testVerifyReturnsResponse() { $method = $this->getMockRequestMethod('{"success": true}'); From 82cd182b0f468ca1a9bc710661e7ef8a3000f13d Mon Sep 17 00:00:00 2001 From: Rowan Merewood Date: Fri, 20 Mar 2026 13:10:09 +0000 Subject: [PATCH 2/3] docs: update request methods documentation Moves the documentation about alternate request methods from ARCHITECTURE.md to README.md and updates it to reflect the new default behavior of attempting to use cURL. --- ARCHITECTURE.md | 29 ++++------------------------- README.md | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 25 deletions(-) diff --git a/ARCHITECTURE.md b/ARCHITECTURE.md index 13add26..4e0dfa2 100644 --- a/ARCHITECTURE.md +++ b/ARCHITECTURE.md @@ -16,31 +16,10 @@ if ($resp->isSuccess()) { } ``` -By default, this will use the -[`stream_context_create()`](https://secure.php.net/stream_context_create) and -[`file_get_contents()`](https://secure.php.net/file_get_contents) to make a POST -request to the reCAPTCHA service. This is handled by the -[`RequestMethod\Post`](./src/ReCaptcha/RequestMethod/Post.php) class. - -## Alternate request methods - -You may need to use other methods for making requests in your environment. The -[`ReCaptcha`](./src/ReCaptcha/ReCaptcha.php) class allows an optional -[`RequestMethod`](./src/ReCaptcha/RequestMethod.php) instance to configure this. -For example, if you want to use [cURL](https://secure.php.net/curl) instead you -can do this: - -```php -isSuccess()) { You can find the constants for the libraries error codes in the `ReCaptcha` class constants, e.g. `ReCaptcha::E_HOSTNAME_MISMATCH` +### Alternate request methods + +By default, the library will attempt to use [cURL](https://secure.php.net/curl) to make the +POST request to the reCAPTCHA service. This is handled by the +[`RequestMethod\CurlPost`](./src/ReCaptcha/RequestMethod/CurlPost.php) class. +If cURL is not available, it will fall back to using +[`stream_context_create()`](https://secure.php.net/stream_context_create) and +[`file_get_contents()`](https://secure.php.net/file_get_contents) via the +[`RequestMethod\Post`](./src/ReCaptcha/RequestMethod/Post.php) class. + +You may need to use other methods for making requests in your environment. The +[`ReCaptcha`](./src/ReCaptcha/ReCaptcha.php) class allows an optional +[`RequestMethod`](./src/ReCaptcha/RequestMethod.php) instance to configure this. +For example, if you want to force the use of [cURL](https://secure.php.net/curl) you +can do this: + +```php + Date: Fri, 20 Mar 2026 13:18:13 +0000 Subject: [PATCH 3/3] docs: explain 1.4.2 behavior change and fallback Adds a note about the change in the default request method as of 1.4.2 and provides an example of how to maintain the previous behavior by manually injecting RequestMethod\Post. --- README.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/README.md b/README.md index ad22f76..e37e514 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,8 @@ class constants, e.g. `ReCaptcha::E_HOSTNAME_MISMATCH` ### Alternate request methods +**Note:** As of version 1.4.2, the default behavior has changed. + By default, the library will attempt to use [cURL](https://secure.php.net/curl) to make the POST request to the reCAPTCHA service. This is handled by the [`RequestMethod\CurlPost`](./src/ReCaptcha/RequestMethod/CurlPost.php) class. @@ -132,6 +134,13 @@ If cURL is not available, it will fall back to using [`file_get_contents()`](https://secure.php.net/file_get_contents) via the [`RequestMethod\Post`](./src/ReCaptcha/RequestMethod/Post.php) class. +To keep the previous behavior of always using `file_get_contents()` regardless of cURL's availability, you can explicitly configure it: + +```php +