diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a12e827b..0755cde8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,6 +11,7 @@ jobs: strategy: matrix: php: + - 8.3 - 8.2 - 8.1 - 8.0 @@ -24,7 +25,7 @@ jobs: - 5.4 - 5.3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} @@ -47,6 +48,10 @@ jobs: strategy: matrix: php: + - 8.3 + - 8.2 + - 8.1 + - 8.0 - 7.4 - 7.3 - 7.2 @@ -57,19 +62,19 @@ jobs: - 5.4 - 5.3 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} coverage: xdebug ini-file: development extensions: sockets, pcntl - - name: Install ext-uv on PHP 7.x + - name: Install ext-uv on PHP 7+ run: | - sudo add-apt-repository ppa:ondrej/php -y && sudo apt-get update -q && sudo apt-get install libuv1-dev - echo "yes" | sudo pecl install uv-beta - echo "extension=uv.so" >> "$(php -r 'echo php_ini_loaded_file();')" - if: ${{ matrix.php >= 7.0 && matrix.php < 8.0 }} + sudo apt-get update -q && sudo apt-get install libuv1-dev + echo "yes" | sudo pecl install ${{ matrix.php >= 8.0 && 'uv-0.3.0' || 'uv-0.2.4' }} + php -m | grep -q uv || echo "extension=uv.so" >> "$(php -r 'echo php_ini_loaded_file();')" + if: ${{ matrix.php >= 7.0 }} - name: Install legacy ext-libevent on PHP < 7.0 run: | sudo apt-get update && sudo apt-get install libevent-dev @@ -106,6 +111,7 @@ jobs: strategy: matrix: php: + - 8.3 - 8.2 - 8.1 - 8.0 @@ -114,7 +120,7 @@ jobs: - 7.2 - 7.1 steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: shivammathur/setup-php@v2 with: php-version: ${{ matrix.php }} @@ -132,7 +138,7 @@ jobs: runs-on: ubuntu-22.04 continue-on-error: true steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - run: cp "$(which composer)" composer.phar && ./composer.phar self-update --2.2 # downgrade Composer for HHVM - name: Run hhvm composer.phar install uses: docker://hhvm/hhvm:3.30-lts-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 1647dbe3..e634b12e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,16 @@ # Changelog +## 1.5.0 (2023-11-13) + +* Feature: Improve performance by using `spl_object_id()` on PHP 7.2+. + (#267 by @samsonasik) + +* Feature: Full PHP 8.3 compatibility. + (#269 by @clue) + +* Update tests for `ext-uv` on PHP 8+ and legacy PHP. + (#270 by @clue and #268 by @SimonFrings) + ## 1.4.0 (2023-05-05) * Feature: Improve performance of `Loop` by avoiding unneeded method calls. diff --git a/README.md b/README.md index 8ec9621a..88a3e18b 100644 --- a/README.md +++ b/README.md @@ -419,7 +419,7 @@ This loop uses the [`uv` PECL extension](https://pecl.php.net/package/uv), that provides an interface to `libuv` library. `libuv` itself supports a number of system-specific backends (epoll, kqueue). -This loop is known to work with PHP 7.x. +This loop is known to work with PHP 7+. #### ~~ExtLibeventLoop~~ @@ -889,7 +889,7 @@ This project follows [SemVer](https://semver.org/). This will install the latest supported version: ```bash -composer require react/event-loop:^1.4 +composer require react/event-loop:^1.5 ``` See also the [CHANGELOG](CHANGELOG.md) for details about version upgrades. diff --git a/src/ExtUvLoop.php b/src/ExtUvLoop.php index 631a4593..4434720d 100644 --- a/src/ExtUvLoop.php +++ b/src/ExtUvLoop.php @@ -13,7 +13,7 @@ * that provides an interface to `libuv` library. * `libuv` itself supports a number of system-specific backends (epoll, kqueue). * - * This loop is known to work with PHP 7.x. + * This loop is known to work with PHP 7+. * * @see https://github.com/bwoebi/php-uv */ diff --git a/src/Timer/Timers.php b/src/Timer/Timers.php index 3a33b8ce..53c46d03 100644 --- a/src/Timer/Timers.php +++ b/src/Timer/Timers.php @@ -38,7 +38,7 @@ public function getTime() public function add(TimerInterface $timer) { - $id = \spl_object_hash($timer); + $id = \PHP_VERSION_ID < 70200 ? \spl_object_hash($timer) : \spl_object_id($timer); $this->timers[$id] = $timer; $this->schedule[$id] = $timer->getInterval() + $this->updateTime(); $this->sorted = false; @@ -46,12 +46,13 @@ public function add(TimerInterface $timer) public function contains(TimerInterface $timer) { - return isset($this->timers[\spl_object_hash($timer)]); + $id = \PHP_VERSION_ID < 70200 ? \spl_object_hash($timer) : \spl_object_id($timer); + return isset($this->timers[$id]); } public function cancel(TimerInterface $timer) { - $id = \spl_object_hash($timer); + $id = \PHP_VERSION_ID < 70200 ? \spl_object_hash($timer) : \spl_object_id($timer); unset($this->timers[$id], $this->schedule[$id]); } diff --git a/tests/LoopTest.php b/tests/LoopTest.php index 833539ef..42f85244 100644 --- a/tests/LoopTest.php +++ b/tests/LoopTest.php @@ -4,7 +4,6 @@ use React\EventLoop\Factory; use React\EventLoop\Loop; -use ReflectionClass; final class LoopTest extends TestCase { @@ -66,7 +65,7 @@ public function testStaticAddReadStreamWithNoDefaultLoopCallsAddReadStreamOnNewL { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $stream = stream_socket_server('127.0.0.1:0'); $listener = function () { }; @@ -92,7 +91,7 @@ public function testStaticAddWriteStreamWithNoDefaultLoopCallsAddWriteStreamOnNe { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $stream = stream_socket_server('127.0.0.1:0'); $listener = function () { }; @@ -117,7 +116,7 @@ public function testStaticRemoveReadStreamWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $stream = tmpfile(); Loop::removeReadStream($stream); @@ -141,7 +140,7 @@ public function testStaticRemoveWriteStreamWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $stream = tmpfile(); Loop::removeWriteStream($stream); @@ -169,7 +168,7 @@ public function testStaticAddTimerWithNoDefaultLoopCallsAddTimerOnNewLoopInstanc { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $interval = 1.0; $callback = function () { }; @@ -199,7 +198,7 @@ public function testStaticAddPeriodicTimerWithNoDefaultLoopCallsAddPeriodicTimer { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $interval = 1.0; $callback = function () { }; @@ -226,7 +225,7 @@ public function testStaticCancelTimerWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $timer = $this->getMockBuilder('React\EventLoop\TimerInterface')->getMock(); Loop::cancelTimer($timer); @@ -250,7 +249,7 @@ public function testStaticFutureTickWithNoDefaultLoopCallsFutureTickOnNewLoopIns { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $listener = function () { }; Loop::futureTick($listener); @@ -279,7 +278,7 @@ public function testStaticAddSignalWithNoDefaultLoopCallsAddSignalOnNewLoopInsta $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $signal = 1; $listener = function () { }; @@ -309,7 +308,7 @@ public function testStaticRemoveSignalWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); $signal = 1; $listener = function () { }; @@ -332,7 +331,7 @@ public function testStaticRunWithNoDefaultLoopCallsRunsOnNewLoopInstance() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); Loop::run(); @@ -353,7 +352,7 @@ public function testStaticStopCallWithNoDefaultLoopIsNoOp() { $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); $ref->setAccessible(true); - $ref->setValue(null); + $ref->setValue(null, null); Loop::stop(); @@ -366,10 +365,8 @@ public function testStaticStopCallWithNoDefaultLoopIsNoOp() */ public function unsetLoopFromLoopAccessor() { - $ref = new ReflectionClass('\React\EventLoop\Loop'); - $prop = $ref->getProperty('instance'); - $prop->setAccessible(true); - $prop->setValue(null); - $prop->setAccessible(false); + $ref = new \ReflectionProperty('React\EventLoop\Loop', 'instance'); + $ref->setAccessible(true); + $ref->setValue(null, null); } }
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: