diff --git a/composer.json b/composer.json
index 9ae7d43d..5ca727a0 100644
--- a/composer.json
+++ b/composer.json
@@ -34,6 +34,7 @@
"guzzlehttp/psr7": "^1.0 || ^2.0",
"php-http/curl-client": "^2.0",
"php-http/mock-client": "^1.0",
+ "phpcompatibility/php-compatibility": "dev-develop",
"phpstan/phpstan": "~2.1",
"phpunit/phpunit": "^9.5 || ^10.0",
"slevomat/coding-standard": "^8.20",
diff --git a/composer.lock b/composer.lock
index 61d7f347..d6a5af90 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "c71f76f0ed18fb72bfdab0b94774e240",
+ "content-hash": "893f04e6854aa23afd7dcd0cabfe1def",
"packages": [
{
"name": "php-http/discovery",
@@ -1260,6 +1260,193 @@
},
"time": "2024-10-31T10:30:18+00:00"
},
+ {
+ "name": "phpcompatibility/php-compatibility",
+ "version": "dev-develop",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCompatibility/PHPCompatibility.git",
+ "reference": "6e10469b0f3827862b37df2ac2b7ec4580ce888f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/6e10469b0f3827862b37df2ac2b7ec4580ce888f",
+ "reference": "6e10469b0f3827862b37df2ac2b7ec4580ce888f",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.4",
+ "phpcsstandards/phpcsutils": "^1.1.0",
+ "squizlabs/php_codesniffer": "^3.13.0"
+ },
+ "replace": {
+ "wimg/php-compatibility": "*"
+ },
+ "require-dev": {
+ "php-parallel-lint/php-console-highlighter": "^1.0.0",
+ "php-parallel-lint/php-parallel-lint": "^1.4.0",
+ "phpcsstandards/phpcsdevcs": "^1.1.3",
+ "phpcsstandards/phpcsdevtools": "^1.2.0",
+ "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4 || ^10.5.32 || ^11.3.3",
+ "yoast/phpunit-polyfills": "^1.0.5 || ^2.0 || ^3.0"
+ },
+ "suggest": {
+ "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues."
+ },
+ "default-branch": true,
+ "type": "phpcodesniffer-standard",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "9.x-dev",
+ "dev-develop": "10.x-dev"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-3.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Wim Godden",
+ "homepage": "https://github.com/wimg",
+ "role": "lead"
+ },
+ {
+ "name": "Juliette Reinders Folmer",
+ "homepage": "https://github.com/jrfnl",
+ "role": "lead"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors"
+ }
+ ],
+ "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.",
+ "homepage": "https://techblog.wimgodden.be/tag/codesniffer/",
+ "keywords": [
+ "compatibility",
+ "phpcs",
+ "standards",
+ "static analysis"
+ ],
+ "support": {
+ "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues",
+ "security": "https://github.com/PHPCompatibility/PHPCompatibility/security/policy",
+ "source": "https://github.com/PHPCompatibility/PHPCompatibility"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/PHPCompatibility",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/jrfnl",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/php_codesniffer",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/phpcompatibility",
+ "type": "thanks_dev"
+ }
+ ],
+ "time": "2025-08-20T03:33:09+00:00"
+ },
+ {
+ "name": "phpcsstandards/phpcsutils",
+ "version": "1.1.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/PHPCSStandards/PHPCSUtils.git",
+ "reference": "f7eb16f2fa4237d5db9e8fed8050239bee17a9bd"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/f7eb16f2fa4237d5db9e8fed8050239bee17a9bd",
+ "reference": "f7eb16f2fa4237d5db9e8fed8050239bee17a9bd",
+ "shasum": ""
+ },
+ "require": {
+ "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0",
+ "php": ">=5.4",
+ "squizlabs/php_codesniffer": "^3.13.0 || ^4.0"
+ },
+ "require-dev": {
+ "ext-filter": "*",
+ "php-parallel-lint/php-console-highlighter": "^1.0",
+ "php-parallel-lint/php-parallel-lint": "^1.4.0",
+ "phpcsstandards/phpcsdevcs": "^1.1.6",
+ "yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0 || ^3.0.0"
+ },
+ "type": "phpcodesniffer-standard",
+ "extra": {
+ "branch-alias": {
+ "dev-stable": "1.x-dev",
+ "dev-develop": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "classmap": [
+ "PHPCSUtils/"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "LGPL-3.0-or-later"
+ ],
+ "authors": [
+ {
+ "name": "Juliette Reinders Folmer",
+ "homepage": "https://github.com/jrfnl",
+ "role": "lead"
+ },
+ {
+ "name": "Contributors",
+ "homepage": "https://github.com/PHPCSStandards/PHPCSUtils/graphs/contributors"
+ }
+ ],
+ "description": "A suite of utility functions for use with PHP_CodeSniffer",
+ "homepage": "https://phpcsutils.com/",
+ "keywords": [
+ "PHP_CodeSniffer",
+ "phpcbf",
+ "phpcodesniffer-standard",
+ "phpcs",
+ "phpcs3",
+ "phpcs4",
+ "standards",
+ "static analysis",
+ "tokens",
+ "utility"
+ ],
+ "support": {
+ "docs": "https://phpcsutils.com/",
+ "issues": "https://github.com/PHPCSStandards/PHPCSUtils/issues",
+ "security": "https://github.com/PHPCSStandards/PHPCSUtils/security/policy",
+ "source": "https://github.com/PHPCSStandards/PHPCSUtils"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/PHPCSStandards",
+ "type": "github"
+ },
+ {
+ "url": "https://github.com/jrfnl",
+ "type": "github"
+ },
+ {
+ "url": "https://opencollective.com/php_codesniffer",
+ "type": "open_collective"
+ },
+ {
+ "url": "https://thanks.dev/u/gh/phpcsstandards",
+ "type": "thanks_dev"
+ }
+ ],
+ "time": "2025-08-10T01:04:45+00:00"
+ },
{
"name": "phpstan/phpdoc-parser",
"version": "2.2.0",
@@ -3332,7 +3519,9 @@
],
"aliases": [],
"minimum-stability": "dev",
- "stability-flags": {},
+ "stability-flags": {
+ "phpcompatibility/php-compatibility": 20
+ },
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
diff --git a/phpcs.xml.dist b/phpcs.xml.dist
index 45a481c3..2e49db44 100644
--- a/phpcs.xml.dist
+++ b/phpcs.xml.dist
@@ -21,6 +21,15 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/Providers/Http/DTO/Request.php b/src/Providers/Http/DTO/Request.php
index c896d024..bb015fb9 100644
--- a/src/Providers/Http/DTO/Request.php
+++ b/src/Providers/Http/DTO/Request.php
@@ -114,7 +114,7 @@ public function getUri(): string
{
// If GET request with data, append as query parameters
if ($this->method === HttpMethodEnum::GET() && $this->data !== null && !empty($this->data)) {
- $separator = strpos($this->uri, '?') === false ? '?' : '&';
+ $separator = str_contains($this->uri, '?') ? '&' : '?';
return $this->uri . $separator . http_build_query($this->data);
}
diff --git a/src/polyfills.php b/src/polyfills.php
index 51db0bed..dc5d5557 100644
--- a/src/polyfills.php
+++ b/src/polyfills.php
@@ -57,6 +57,26 @@ function str_starts_with(string $haystack, string $needle): bool
}
}
+if (!function_exists('str_contains')) {
+ /**
+ * Checks if a string contains a given substring.
+ *
+ * @since n.e.x.t
+ *
+ * @param string $haystack The string to search in.
+ * @param string $needle The substring to search for.
+ * @return bool True if $haystack contains $needle, false otherwise.
+ */
+ function str_contains(string $haystack, string $needle): bool
+ {
+ if ('' === $needle) {
+ return true;
+ }
+
+ return false !== strpos($haystack, $needle);
+ }
+}
+
if (!function_exists('str_ends_with')) {
/**
* Checks if a string ends with a given substring.