Skip to content

v3: PHP 8.1 - PHP 8.5#3442

Merged
akrabat merged 8 commits intoslimphp:3.xfrom
maksimovic:3.x-php85
Apr 28, 2026
Merged

v3: PHP 8.1 - PHP 8.5#3442
akrabat merged 8 commits intoslimphp:3.xfrom
maksimovic:3.x-php85

Conversation

@maksimovic
Copy link
Copy Markdown

@maksimovic maksimovic commented Apr 22, 2026

Hello!

This is my first contribution to Slim, and it goes to (maybe surprisingly) v3. The reason for that is that the company I work for is relying on v3 a lot in some critical parts, where, at the moment, is a much more safe path to ensure v3 is still doing fine on PHP 8.5 than to swap v3 for v4. This change also cuts ties to anything below PHP 8.1, which is also something that only we need, which may not be something that you consider as an adequate move. For example, making sure it runs on PHP 8.5 bumps the requirement for PHPUnit from the very old v4 to v10 (which is fine for PHP 8.1-8.5).

A brief summary of changes:

  • Stringable guards: method_exists($x, '__toString') to $x instanceof \Stringable fixes the TypeError when non-objects are passed on PHP 8+
  • Explicit ?Type on implicitly-nullable parameters ($x = nulldeprecated since PHP 8.4)
  • Null-to-string casts before vars are passed to some functions (deprecated since PHP 8.1+)
  • Collection PSR interface methods: added #[\ReturnTypeWillChange] on untyped methods is BC-safe for subclasses
  • Container::get passing null as $code to exception also deprecated since 8.1
  • Class-level @phpstan-consistent-constructor docblocks silences phpstan 2.x new.static warnings without runtime change.

None of the above are BC breaks. Tests also got a little revamp to get them aligned with PHPUnit 10, and line coverage is at 99.26% (too hard or impossible to make it 100%). Little bit of updates to GitHub actions, too.

I can re-publish this from the fork, but I first wanted to check if it's something that would get accepted in the official repository as a new minor version. I'm open to discussing the proposed changes and/or elaborating on decisions that have been made.

Source fixes for PHP 8.5:
- Replace method_exists(x, __toString) guards with x instanceof \Stringable
  in Http/Response.php and Http/Uri.php (5 sites). On PHP 8+, method_exists()
  throws TypeError when passed null or an array, so the old guard no longer
  protected the very call sites it was written for.
- Add explicit ?Type to implicitly-nullable parameters (PHP 8.4 deprecation):
  App::subRequest, MiddlewareAwareTrait::seedMiddlewareStack, Router::__construct,
  Response::__construct, RouteGroup::__invoke, DeferredCallable::__construct,
  Request::getParams.
- Collection: add return types to ArrayAccess/Countable/IteratorAggregate
  methods; keep offsetGet mixed via #[\ReturnTypeWillChange].
- Cast potentially-null scalars before strtoupper/ltrim/preg_replace_callback/
  explode in App.php, Http/Request.php, Http/Uri.php.
- Container::get passes 0 (not null) as Exception $code.

Test suite migrated from PHPUnit 4 to PHPUnit 10.5:
- PHPUnit_Framework_TestCase -> PHPUnit\Framework\TestCase across all tests.
- setUp/tearDown/setUpBeforeClass/tearDownAfterClass get : void return types.
- setExpectedException() and @ExpectedException / @expectedExceptionMessage
  docblocks converted to expectException() / expectExceptionMessage() calls.
- assertInternalType(type, x) -> assertIs{Type}(x).
- setMethods() -> onlyMethods() where the method exists, addMethods()
  (PHPUnit 10 MockBuilder idiom) for StdClass stubs of nonexistent methods.
- Legacy getMock(Class, [methods]) rewritten as getMockBuilder()
  ->onlyMethods()->getMock().
- assertAttributeEquals/Contains/Same removed in PHPUnit 9 — rewritten to
  assert against public API where available (getPattern, getMethods,
  getStatusCode, getBody, getUserInfo, etc.) and inline ReflectionProperty
  where private state is the only observable thing.
- Prophecy removed from PHPUnit 10 — two prophesize() tests rewritten to use
  PHPUnit MockBuilder.
- Renamed assertions: assertRegExp -> assertMatchesRegularExpression,
  assertNotRegExp -> assertDoesNotMatchRegularExpression,
  assertFileNotExists -> assertFileDoesNotExist,
  assertContains(string, string) -> assertStringContainsString.
- Data provider methods made static (PHPUnit 10 requirement).
- Removed no-op ReflectionProperty/Method::setAccessible(true) calls
  (deprecated in 8.5, no effect since 8.1).

phpunit.xml.dist modernized to PHPUnit 10 schema: dropped removed
attributes (backupStaticAttributes, convertErrorsToExceptions, etc.),
added <exclude>tests/Mocks</exclude> so helper classes with Test suffix
don't get picked up as test cases, replaced <filter>/<whitelist> with
<source>/<include>.

composer.json bumps: php ^8.1, psr/http-message ^1.1, psr/container ^1.1,
phpunit/phpunit ^10.5.

Notes on tests still skipped:
testPhpError5, testPhpErrorDisplayDetails5, testNotFoundContentType5
(PhpErrorTest), and testHandlePhpError (AppTest) use a skipIfPhp70() helper
that marks the test skipped when PHP >= 7.0. With the PHP 8.1 floor these
are dead code on every supported runtime; left in place here to keep the
diff scoped to the migration, not behavioral cleanup.

Suite result on PHP 8.5.3: 625 tests, 1025 assertions, 14 skipped, no
errors, no failures, no deprecations, no warnings.
- @phpstan-consistent-constructor on Collection, Uri, UploadedFile, Request
- Move two inner named functions (handle, testCallable) to namespace scope
- Group closure uses $app instead of $this rebinding in one test
- Drop unused $res from three closure use-lists
- Wrap intentional undefined-function call via call_user_func
- phpcbf auto-fixes from the migration sweep
- Require phpstan/phpstan ^2.1, add paths to phpstan.neon.dist
  - CI: drop Travis, matrix PHP 8.1-8.5, bump action versions,
    coverage on 8.5 leg
  - composer scripts: add test:coverage and analyse (stan)
  - Tests: remove dead tests, improve code coverage
@maksimovic
Copy link
Copy Markdown
Author

P.S. Looks like there are branch protection rules preventing the updated workflow to kick in. There's a PR with these changes here, where tests can be seen in action: maksimovic#1

@coveralls
Copy link
Copy Markdown

coveralls commented Apr 27, 2026

Coverage Status

Coverage is 99.262%maksimovic:3.x-php85 into slimphp:3.x. No base build found for slimphp:3.x.

@akrabat
Copy link
Copy Markdown
Member

akrabat commented Apr 28, 2026

Thanks for you work on this.

When I run the tests locally on PHP 8.5.5 after doing a composer install, I get errors:

rob@leviathan Slim (3.x-php85 *%) $ ./vendor/bin/phpunit --version
PHPUnit 10.5.63 by Sebastian Bergmann and contributors.

rob@leviathan Slim (3.x-php85 *%) $ ./vendor/bin/phpunit
PHPUnit 10.5.63 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.5.5
Configuration: /Users/rob/Projects/slim/slimphp/Slim/phpunit.xml
Random Seed:   1777363455

........................Slim Application Error:
Type: Exception
File: /Users/rob/Projects/slim/slimphp/Slim/tests/Handlers/PhpErrorTest.php
Line: 40
Trace: #0 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(1548): Slim\Tests\Handlers\PhpErrorTest->testPhpError('text/html', 'text/html', '<html>')
#1 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(686): PHPUnit\Framework\TestCase->runTest()
#2 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestRunner.php(106): PHPUnit\Framework\TestCase->runBare()
#3 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(516): PHPUnit\Framework\TestRunner->run(Object(Slim\Tests\Handlers\PhpErrorTest))
#4 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestCase->run()
#5 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#6 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#7 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#8 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(64): PHPUnit\Framework\TestSuite->run()
#9 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/Application.php(204): PHPUnit\TextUI\TestRunner->run(Object(PHPUnit\TextUI\Configuration\Configuration), Object(PHPUnit\Runner\ResultCache\DefaultResultCache), Object(PHPUnit\Framework\TestSuite))
#10 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/phpunit(104): PHPUnit\TextUI\Application->run(Array)
#11 /Users/rob/Projects/slim/slimphp/Slim/vendor/bin/phpunit(122): include('/Users/rob/Proj...')
#12 {main}
View in rendered output by enabling the "displayErrorDetails" setting.

.Slim Application Error:
Type: Exception
File: /Users/rob/Projects/slim/slimphp/Slim/tests/Handlers/PhpErrorTest.php
Line: 40
Trace: #0 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(1548): Slim\Tests\Handlers\PhpErrorTest->testPhpError('text/xml', 'text/xml', '<error>')
#1 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(686): PHPUnit\Framework\TestCase->runTest()
#2 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestRunner.php(106): PHPUnit\Framework\TestCase->runBare()
#3 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(516): PHPUnit\Framework\TestRunner->run(Object(Slim\Tests\Handlers\PhpErrorTest))
#4 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestCase->run()
#5 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#6 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#7 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#8 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(64): PHPUnit\Framework\TestSuite->run()
#9 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/Application.php(204): PHPUnit\TextUI\TestRunner->run(Object(PHPUnit\TextUI\Configuration\Configuration), Object(PHPUnit\Runner\ResultCache\DefaultResultCache), Object(PHPUnit\Framework\TestSuite))
#10 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/phpunit(104): PHPUnit\TextUI\Application->run(Array)
#11 /Users/rob/Projects/slim/slimphp/Slim/vendor/bin/phpunit(122): include('/Users/rob/Proj...')
#12 {main}
View in rendered output by enabling the "displayErrorDetails" setting.

.Slim Application Error:
Type: Exception
File: /Users/rob/Projects/slim/slimphp/Slim/tests/Handlers/PhpErrorTest.php
Line: 40
Trace: #0 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(1548): Slim\Tests\Handlers\PhpErrorTest->testPhpError('application/jso...', 'application/jso...', '{')
#1 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(686): PHPUnit\Framework\TestCase->runTest()
#2 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestRunner.php(106): PHPUnit\Framework\TestCase->runBare()
#3 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(516): PHPUnit\Framework\TestRunner->run(Object(Slim\Tests\Handlers\PhpErrorTest))
#4 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestCase->run()
#5 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#6 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#7 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#8 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(64): PHPUnit\Framework\TestSuite->run()
#9 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/Application.php(204): PHPUnit\TextUI\TestRunner->run(Object(PHPUnit\TextUI\Configuration\Configuration), Object(PHPUnit\Runner\ResultCache\DefaultResultCache), Object(PHPUnit\Framework\TestSuite))
#10 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/phpunit(104): PHPUnit\TextUI\Application->run(Array)
#11 /Users/rob/Projects/slim/slimphp/Slim/vendor/bin/phpunit(122): include('/Users/rob/Proj...')
#12 {main}
View in rendered output by enabling the "displayErrorDetails" setting.

.Slim Application Error:
Type: Exception
File: /Users/rob/Projects/slim/slimphp/Slim/tests/Handlers/PhpErrorTest.php
Line: 40
Trace: #0 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(1548): Slim\Tests\Handlers\PhpErrorTest->testPhpError('application/hal...', 'application/xml', '<error>')
#1 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(686): PHPUnit\Framework\TestCase->runTest()
#2 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestRunner.php(106): PHPUnit\Framework\TestCase->runBare()
#3 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(516): PHPUnit\Framework\TestRunner->run(Object(Slim\Tests\Handlers\PhpErrorTest))
#4 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestCase->run()
#5 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#6 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#7 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#8 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(64): PHPUnit\Framework\TestSuite->run()
#9 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/Application.php(204): PHPUnit\TextUI\TestRunner->run(Object(PHPUnit\TextUI\Configuration\Configuration), Object(PHPUnit\Runner\ResultCache\DefaultResultCache), Object(PHPUnit\Framework\TestSuite))
#10 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/phpunit(104): PHPUnit\TextUI\Application->run(Array)
#11 /Users/rob/Projects/slim/slimphp/Slim/vendor/bin/phpunit(122): include('/Users/rob/Proj...')
#12 {main}
View in rendered output by enabling the "displayErrorDetails" setting.

.Slim Application Error:
Type: Exception
File: /Users/rob/Projects/slim/slimphp/Slim/tests/Handlers/PhpErrorTest.php
Line: 40
Trace: #0 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(1548): Slim\Tests\Handlers\PhpErrorTest->testPhpError('application/xml', 'application/xml', '<error>')
#1 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(686): PHPUnit\Framework\TestCase->runTest()
#2 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestRunner.php(106): PHPUnit\Framework\TestCase->runBare()
#3 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(516): PHPUnit\Framework\TestRunner->run(Object(Slim\Tests\Handlers\PhpErrorTest))
#4 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestCase->run()
#5 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#6 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#7 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#8 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(64): PHPUnit\Framework\TestSuite->run()
#9 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/Application.php(204): PHPUnit\TextUI\TestRunner->run(Object(PHPUnit\TextUI\Configuration\Configuration), Object(PHPUnit\Runner\ResultCache\DefaultResultCache), Object(PHPUnit\Framework\TestSuite))
#10 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/phpunit(104): PHPUnit\TextUI\Application->run(Array)
#11 /Users/rob/Projects/slim/slimphp/Slim/vendor/bin/phpunit(122): include('/Users/rob/Proj...')
#12 {main}
View in rendered output by enabling the "displayErrorDetails" setting.

.Slim Application Error:
Type: Exception
File: /Users/rob/Projects/slim/slimphp/Slim/tests/Handlers/PhpErrorTest.php
Line: 40
Trace: #0 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(1548): Slim\Tests\Handlers\PhpErrorTest->testPhpError('application/vnd...', 'application/jso...', '{')
#1 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(686): PHPUnit\Framework\TestCase->runTest()
#2 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestRunner.php(106): PHPUnit\Framework\TestCase->runBare()
#3 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestCase.php(516): PHPUnit\Framework\TestRunner->run(Object(Slim\Tests\Handlers\PhpErrorTest))
#4 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestCase->run()
#5 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#6 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#7 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/Framework/TestSuite.php(374): PHPUnit\Framework\TestSuite->run()
#8 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(64): PHPUnit\Framework\TestSuite->run()
#9 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/src/TextUI/Application.php(204): PHPUnit\TextUI\TestRunner->run(Object(PHPUnit\TextUI\Configuration\Configuration), Object(PHPUnit\Runner\ResultCache\DefaultResultCache), Object(PHPUnit\Framework\TestSuite))
#10 /Users/rob/Projects/slim/slimphp/Slim/vendor/phpunit/phpunit/phpunit(104): PHPUnit\TextUI\Application->run(Array)
#11 /Users/rob/Projects/slim/slimphp/Slim/vendor/bin/phpunit(122): include('/Users/rob/Proj...')
#12 {main}
View in rendered output by enabling the "displayErrorDetails" setting.

..................................  63 / 616 ( 10%)
............................................................... 126 / 616 ( 20%)
............................................................... 189 / 616 ( 30%)
............................................................... 252 / 616 ( 40%)
............................................................... 315 / 616 ( 51%)
............................................................... 378 / 616 ( 61%)
.............................................................F. 441 / 616 ( 71%)
...............................................FE.............. 504 / 616 ( 81%)
............................................................... 567 / 616 ( 92%)
.................................................               616 / 616 (100%)

Time: 00:00.094, Memory: 18.00 MB

There were 3 PHPUnit test runner warnings:

1) Class Slim\Tests\Mocks\CallableTest declared in /Users/rob/Projects/slim/slimphp/Slim/tests/Mocks/CallableTest.php does not extend PHPUnit\Framework\TestCase

2) Class Slim\Tests\Mocks\InvocationStrategyTest declared in /Users/rob/Projects/slim/slimphp/Slim/tests/Mocks/InvocationStrategyTest.php does not extend PHPUnit\Framework\TestCase

3) Class Slim\Tests\Mocks\InvokableTest declared in /Users/rob/Projects/slim/slimphp/Slim/tests/Mocks/InvokableTest.php does not extend PHPUnit\Framework\TestCase

--

There was 1 error:

1) Slim\Tests\Http\UploadedFilesTest::testGetStream
RuntimeException: Uploaded file my-avatar.txt has already been moved

/Users/rob/Projects/slim/slimphp/Slim/Slim/Http/UploadedFile.php:188
/Users/rob/Projects/slim/slimphp/Slim/tests/Http/UploadedFilesTest.php:134

--

There were 2 failures:

1) Slim\Tests\DeferredCallableTest::testItResolvesCallable
Failed asserting that 2 matches expected 1.

/Users/rob/Projects/slim/slimphp/Slim/tests/DeferredCallableTest.php:25

2) Slim\Tests\Http\UploadedFilesTest::testMoveToNotWritable
Failed asserting that exception of type "RuntimeException" matches expected exception "\InvalidArgumentException". Message was: "Uploaded file already moved" at
/Users/rob/Projects/slim/slimphp/Slim/Slim/Http/UploadedFile.php:233
/Users/rob/Projects/slim/slimphp/Slim/tests/Http/UploadedFilesTest.php:151
.

ERRORS!
Tests: 616, Assertions: 1033, Errors: 1, Failures: 2, PHPUnit Warnings: 3.
rob@leviathan Slim (3.x-php85 *%) $

I see that composer install has installed PHPUnit 10.5.63, whereas the CI seems to be using 10.1.16, so that may be related?

@maksimovic
Copy link
Copy Markdown
Author

My local setup is nearly identical to yours, but all good:

| /System/Volumes/Data/Users/oliver/www/Slim   (3.x-php85)
| => ./vendor/bin/phpunit
PHPUnit 10.5.63 by Sebastian Bergmann and contributors.

Runtime:       PHP 8.5.3
Configuration: /Users/oliver/www/Slim/phpunit.xml.dist

...............................................................  63 / 616 ( 10%)
............................................................... 126 / 616 ( 20%)
............................................................... 189 / 616 ( 30%)
............................................................... 252 / 616 ( 40%)
............................................................... 315 / 616 ( 51%)
............................................................... 378 / 616 ( 61%)
............................................................... 441 / 616 ( 71%)
............................................................... 504 / 616 ( 81%)
............................................................... 567 / 616 ( 92%)
.................................................               616 / 616 (100%)

Time: 00:00.362, Memory: 18.00 MB

OK (616 tests, 1034 assertions)

I'll try finding out why things are blowing up on your end.

@maksimovic
Copy link
Copy Markdown
Author

wait... that output shows PHPUnit picking up your local phpunit.xml, not the phpunit.xml.dist shipped in the PR. PHPUnit itself is 10.5.63 on both sides. Could you rm phpunit.xml (or copy the new .dist over it) and re-run? The three failures and three warnings all match settings that are present in the updated .dist

@maksimovic
Copy link
Copy Markdown
Author

I've also renamed those "Test" classes that aren't really tests, and that were excluded in the .dist file so PHPUnit doesn't pick them up. Those annoyed me so I just excluded them while working on other things, but I forgot to get back to that little bit later.

@akrabat
Copy link
Copy Markdown
Member

akrabat commented Apr 28, 2026

wait... that output shows PHPUnit picking up your local phpunit.xml, not the phpunit.xml.dist shipped in the PR. PHPUnit itself is 10.5.63 on both sides. Could you rm phpunit.xml (or copy the new .dist over it) and re-run? The three failures and three warnings all match settings that are present in the updated .dist

Aha! I had forgotten that I had a custom phpunit.xml - which was no doubt related to 4x.

Removing it and it's all good.

@akrabat
Copy link
Copy Markdown
Member

akrabat commented Apr 28, 2026

I have pushed a README change. I think it's good to go.

Copy link
Copy Markdown
Member

@akrabat akrabat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👍

Thank you for this work @maksimovic.

@akrabat akrabat merged commit f899a6e into slimphp:3.x Apr 28, 2026
6 checks passed
@akrabat akrabat added this to the 3.13.0 milestone Apr 28, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants