Repository: ccxt/ccxt
Pull request: fix(php8) - promise interface & react update
reactphp-promise is now of v3.0.0 version, where `then()` has signature of: https://github.com/reactphp/promise/blob/3.x/src/PromiseInterface.php#L40

while we had older signature:
https://github.com/ccxt/ccxt/blob/master/php/pro/Future.php#L15

which caused an issue ( fix #19087 fix #19310 ).

Problem statement:
Composer v2.6.1 install fatal error
### Operating System

Ubuntu 20.04.6 LTS

### Programming Languages

PHP

### CCXT Version

4.0.80

### Description

When I run `composer install --verbose --prefer-dist --no-progress --no-interaction --no-dev --optimize-autoloader` on my production server I get a PHP fatal error. I did not have this error before and I've run composer many times on production. Looks like the issue started with version 4.0.75 or 4.0.77. But now even if I lower the version still get the error 

 I don't get this error on my local environment when I run composer install (using docker)

`"require": {
        "ccxt/ccxt": "^4.0.80",
  }`

### Code

```
  PHP Fatal error:  Declaration of ccxt\pro\Future::then($onFulfilled = null,  
   $onRejected = null, $onProgress = null) must be compatible with React\Prom  
  ise\PromiseInterface::then(?callable $onFulfilled = null, ?callable $onReje  
  cted = null): React\Promise\PromiseInterface in /var/www/.../vendor/ccxt/ccxt/php/pro/Future.php on line 15 

```


Cannot Update or Install CCXT on php v8.2.10
### Operating System

Ubuntu 22.04

### Programming Languages

PHP

### CCXT Version

4.0.99

### Description

Cannot update or install ccxt on php v8.2.10
Fatal error: Declaration of ccxt\pro\Future::then($onFulfilled = null, $onRejected = null, $onProgress = null) must be compatible with React\Promise\PromiseInterface::then(?callable $onFulfilled = null, ?callable $onRejected = null): React\Promise\PromiseInterface in /var/www/sleep.finance/vendor/ccxt/ccxt/php/pro/Future.php on line 15

### Code

```
  lock file operations: 0 installs, 1 update, 0 removals
  - Upgrading ccxt/ccxt (4.0.98 => 4.0.99)
Writing lock file
Installing dependencies from lock file (including require-dev)
Package operations: 0 installs, 1 update, 0 removals
  - Downloading ccxt/ccxt (4.0.99)
  - Upgrading ccxt/ccxt (4.0.98 => 4.0.99): Extracting archive
Package fgrosse/phpasn1 is abandoned, you should avoid using it. No replacement was suggested.
Package laravelcollective/html is abandoned, you should avoid using it. Use spatie/laravel-html instead.
Package php-http/message-factory is abandoned, you should avoid using it. Use psr/http-factory instead.
Generating optimized autoload files
Class ccxt\async\Throttler located in ./vendor/ccxt/ccxt/php/async/Throttle.php does not comply with psr-4 autoloading standard. Skipping.
Class ccxt\baseMainTestClass located in ./vendor/ccxt/ccxt/php/test/test_sync.php does not comply with psr-4 autoloading standard. Skipping.
Class ccxt\testMainClass located in ./vendor/ccxt/ccxt/php/test/test_sync.php does not comply with psr-4 autoloading standard. Skipping.
Class ccxt\baseMainTestClass located in ./vendor/ccxt/ccxt/php/test/test_async.php does not comply with psr-4 autoloading standard. Skipping.
Class ccxt\testMainClass located in ./vendor/ccxt/ccxt/php/test/test_async.php does not comply with psr-4 autoloading standard. Skipping.
Class ccxt\async\Throttler located in ./vendor/ccxt/ccxt/php/async/Throttle.php does not comply with psr-4 autoloading standard. Skipping.
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
PHP Fatal error:  Declaration of ccxt\pro\Future::then($onFulfilled = null, $onRejected = null, $onProgress = null) must be compatible with React\Promise\PromiseInterface::then(?callable $onFulfilled = null, ?callable $onRejected = null): React\Promise\PromiseInterface in /var/www/sleep.finance/vendor/ccxt/ccxt/php/pro/Future.php on line 15

Fatal error: Declaration of ccxt\pro\Future::then($onFulfilled = null, $onRejected = null, $onProgress = null) must be compatible with React\Promise\PromiseInterface::then(?callable $onFulfilled = null, ?callable $onRejected = null): React\Promise\PromiseInterface in /var/www/sleep.finance/vendor/ccxt/ccxt/php/pro/Future.php on line 15

```

Hints from issue discussion:
i'll get to this soon, thanks for the report
can you please share your composer.json (just other dependencies excluded and sensitive details hidden) and also which PHP version do you use specifically
I've reproduced the issue, working on a fix.

Commit message: -

Patch to review:
diff --git a/composer.json b/composer.json
index 6d5831307edea..cb28a50b96ef2 100644
--- a/composer.json
+++ b/composer.json
@@ -240,7 +240,7 @@
         "ratchet/pawl": ">=0.4.1",
         "react/http": ">=1.6.0",
         "react/async": "^4.0.0",
-        "react/promise": "^2.9.0",
+        "react/promise": ">=3.0.0",
         "react/promise-timer": "^1.10"
     },
     "suggest": {
diff --git a/composer.lock b/composer.lock
index 66c4fada28825..5c228402a9e30 100644
--- a/composer.lock
+++ b/composer.lock
@@ -943,7 +943,7 @@
         },
         {
             "name": "react/promise",
-            "version": "v2.10.0",
+            "version": "v3.0.0",
             "source": {
                 "type": "git",
                 "url": "https://github.com/reactphp/promise.git",
diff --git a/php/pro/Future.php b/php/pro/Future.php
index fa3dc0973ab3d..3385299ab806e 100644
--- a/php/pro/Future.php
+++ b/php/pro/Future.php
@@ -12,7 +12,7 @@ public function __construct() {
         parent::__construct();
     }
 
-    public function then($onFulfilled = null, $onRejected = null, $onProgress = null) {
+    public function then(?callable $onFulfilled = null, ?callable $onRejected = null): PromiseInterface {
         return $this->promise()->then($onFulfilled, $onRejected);
     }
 


Code review comments:
diff_hunk: @@ -240,7 +240,7 @@
         "ratchet/pawl": ">=0.4.1",
         "react/http": ">=1.6.0",
         "react/async": "^4.0.0",
-        "react/promise": "^2.9.0",
+        "react/promise": ">=3.0.0",
path: composer.json
text: @user1:
Why not this?

```suggestion
        "react/promise": "^3.0.0",
```

>= is unbounded and dangerous

@author:
right, i've had `^` initially, just PR build didn't install v3 and I've just switched to that to test. however, switched back now as you pointed out.