Skip to content

Commit fdd935d

Browse files
authored
Merge pull request #7747 from paulbalandan/autoloader-loader
Return signatures of Autoloader's loaders should be void
2 parents a5378a7 + f075b7c commit fdd935d

4 files changed

Lines changed: 48 additions & 40 deletions

File tree

phpstan-baseline.php

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,6 @@
11
<?php declare(strict_types = 1);
22

33
$ignoreErrors = [];
4-
$ignoreErrors[] = [
5-
'message' => '#^Parameter \\#1 \\$callback of function spl_autoload_register expects \\(callable\\(string\\)\\: void\\)\\|null, array\\{\\$this\\(CodeIgniter\\\\Autoloader\\\\Autoloader\\), \'loadClass\'\\} given\\.$#',
6-
'count' => 1,
7-
'path' => __DIR__ . '/system/Autoloader/Autoloader.php',
8-
];
9-
$ignoreErrors[] = [
10-
'message' => '#^Parameter \\#1 \\$callback of function spl_autoload_register expects \\(callable\\(string\\)\\: void\\)\\|null, array\\{\\$this\\(CodeIgniter\\\\Autoloader\\\\Autoloader\\), \'loadClassmap\'\\} given\\.$#',
11-
'count' => 1,
12-
'path' => __DIR__ . '/system/Autoloader/Autoloader.php',
13-
];
144
$ignoreErrors[] = [
155
'message' => '#^Method CodeIgniter\\\\BaseModel\\:\\:chunk\\(\\) has parameter \\$userFunc with no signature specified for Closure\\.$#',
166
'count' => 1,

system/Autoloader/Autoloader.php

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -240,33 +240,30 @@ public function removeNamespace(string $namespace)
240240
/**
241241
* Load a class using available class mapping.
242242
*
243-
* @return false|string
243+
* @internal For `spl_autoload_register` use.
244244
*/
245-
public function loadClassmap(string $class)
245+
public function loadClassmap(string $class): void
246246
{
247247
$file = $this->classmap[$class] ?? '';
248248

249249
if (is_string($file) && $file !== '') {
250-
return $this->includeFile($file);
250+
$this->includeFile($file);
251251
}
252-
253-
return false;
254252
}
255253

256254
/**
257255
* Loads the class file for a given class name.
258256
*
259-
* @param string $class The fully qualified class name.
257+
* @internal For `spl_autoload_register` use.
260258
*
261-
* @return false|string The mapped file on success, or boolean false
262-
* on failure.
259+
* @param string $class The fully qualified class name.
263260
*/
264-
public function loadClass(string $class)
261+
public function loadClass(string $class): void
265262
{
266263
$class = trim($class, '\\');
267264
$class = str_ireplace('.php', '', $class);
268265

269-
return $this->loadInNamespace($class);
266+
$this->loadInNamespace($class);
270267
}
271268

272269
/**

tests/system/Autoloader/AutoloaderTest.php

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
namespace CodeIgniter\Autoloader;
1313

1414
use App\Controllers\Home;
15+
use Closure;
1516
use CodeIgniter\Exceptions\ConfigException;
1617
use CodeIgniter\Test\CIUnitTestCase;
18+
use CodeIgniter\Test\ReflectionHelper;
1719
use Config\Autoload;
1820
use Config\Modules;
1921
use Config\Services;
2022
use InvalidArgumentException;
23+
use PHPUnit\Framework\MockObject\MockObject;
2124
use RuntimeException;
2225
use UnnamespacedClass;
2326

@@ -28,7 +31,10 @@
2831
*/
2932
final class AutoloaderTest extends CIUnitTestCase
3033
{
34+
use ReflectionHelper;
35+
3136
private Autoloader $loader;
37+
private Closure $classLoader;
3238

3339
protected function setUp(): void
3440
{
@@ -50,13 +56,15 @@ protected function setUp(): void
5056

5157
$this->loader = new Autoloader();
5258
$this->loader->initialize($config, $modules)->register();
59+
60+
$this->classLoader = $this->getPrivateMethodInvoker($this->loader, 'loadInNamespace');
5361
}
5462

5563
protected function tearDown(): void
5664
{
57-
$this->loader->unregister();
58-
5965
parent::tearDown();
66+
67+
$this->loader->unregister();
6068
}
6169

6270
public function testLoadStoredClass(): void
@@ -96,9 +104,10 @@ public function testInitializeTwice(): void
96104

97105
public function testServiceAutoLoaderFromShareInstances(): void
98106
{
99-
$autoloader = Services::autoloader();
107+
$classLoader = $this->getPrivateMethodInvoker(Services::autoloader(), 'loadInNamespace');
108+
100109
// look for Home controller, as that should be in base repo
101-
$actual = $autoloader->loadClass(Home::class);
110+
$actual = $classLoader(Home::class);
102111
$expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
103112
$this->assertSame($expected, realpath($actual) ?: $actual);
104113
}
@@ -109,8 +118,10 @@ public function testServiceAutoLoader(): void
109118
$autoloader->initialize(new Autoload(), new Modules());
110119
$autoloader->register();
111120

121+
$classLoader = $this->getPrivateMethodInvoker($autoloader, 'loadInNamespace');
122+
112123
// look for Home controller, as that should be in base repo
113-
$actual = $autoloader->loadClass(Home::class);
124+
$actual = $classLoader(Home::class);
114125
$expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
115126
$this->assertSame($expected, realpath($actual) ?: $actual);
116127

@@ -119,41 +130,43 @@ public function testServiceAutoLoader(): void
119130

120131
public function testExistingFile(): void
121132
{
122-
$actual = $this->loader->loadClass(Home::class);
133+
$actual = ($this->classLoader)(Home::class);
123134
$expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
124135
$this->assertSame($expected, $actual);
125136

126-
$actual = $this->loader->loadClass('CodeIgniter\Helpers\array_helper');
137+
$actual = ($this->classLoader)('CodeIgniter\Helpers\array_helper');
127138
$expected = SYSTEMPATH . 'Helpers' . DIRECTORY_SEPARATOR . 'array_helper.php';
128139
$this->assertSame($expected, $actual);
129140
}
130141

131142
public function testMatchesWithPrecedingSlash(): void
132143
{
133-
$actual = $this->loader->loadClass(Home::class);
144+
$actual = ($this->classLoader)(Home::class);
134145
$expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
135146
$this->assertSame($expected, $actual);
136147
}
137148

138149
public function testMatchesWithFileExtension(): void
139150
{
140-
$actual = $this->loader->loadClass('\App\Controllers\Home.php');
141-
$expected = APPPATH . 'Controllers' . DIRECTORY_SEPARATOR . 'Home.php';
142-
$this->assertSame($expected, $actual);
151+
/** @var Autoloader&MockObject $classLoader */
152+
$classLoader = $this->getMockBuilder(Autoloader::class)->onlyMethods(['loadInNamespace'])->getMock();
153+
$classLoader->expects($this->once())->method('loadInNamespace')->with(Home::class);
154+
155+
$classLoader->loadClass('\App\Controllers\Home.php');
143156
}
144157

145158
public function testMissingFile(): void
146159
{
147-
$this->assertFalse($this->loader->loadClass('\App\Missing\Classname'));
160+
$this->assertFalse(($this->classLoader)('\App\Missing\Classname'));
148161
}
149162

150163
public function testAddNamespaceWorks(): void
151164
{
152-
$this->assertFalse($this->loader->loadClass('My\App\Class'));
165+
$this->assertFalse(($this->classLoader)('My\App\Class'));
153166

154167
$this->loader->addNamespace('My\App', __DIR__);
155168

156-
$actual = $this->loader->loadClass('My\App\AutoloaderTest');
169+
$actual = ($this->classLoader)('My\App\AutoloaderTest');
157170
$expected = __FILE__;
158171

159172
$this->assertSame($expected, $actual);
@@ -168,11 +181,11 @@ public function testAddNamespaceMultiplePathsWorks(): void
168181
],
169182
]);
170183

171-
$actual = $this->loader->loadClass('My\App\App');
184+
$actual = ($this->classLoader)('My\App\App');
172185
$expected = APPPATH . 'Config' . DIRECTORY_SEPARATOR . 'App.php';
173186
$this->assertSame($expected, $actual);
174187

175-
$actual = $this->loader->loadClass('My\App\AutoloaderTest');
188+
$actual = ($this->classLoader)('My\App\AutoloaderTest');
176189
$expected = __FILE__;
177190
$this->assertSame($expected, $actual);
178191
}
@@ -183,7 +196,7 @@ public function testAddNamespaceStringToArray(): void
183196

184197
$this->assertSame(
185198
__FILE__,
186-
$this->loader->loadClass('App\Controllers\AutoloaderTest')
199+
($this->classLoader)('App\Controllers\AutoloaderTest')
187200
);
188201
}
189202

@@ -201,15 +214,15 @@ public function testGetNamespaceGivesArray(): void
201214
public function testRemoveNamespace(): void
202215
{
203216
$this->loader->addNamespace('My\App', __DIR__);
204-
$this->assertSame(__FILE__, $this->loader->loadClass('My\App\AutoloaderTest'));
217+
$this->assertSame(__FILE__, ($this->classLoader)('My\App\AutoloaderTest'));
205218

206219
$this->loader->removeNamespace('My\App');
207-
$this->assertFalse((bool) $this->loader->loadClass('My\App\AutoloaderTest'));
220+
$this->assertFalse(($this->classLoader)('My\App\AutoloaderTest'));
208221
}
209222

210223
public function testloadClassNonNamespaced(): void
211224
{
212-
$this->assertFalse($this->loader->loadClass('Modules'));
225+
$this->assertFalse(($this->classLoader)('Modules'));
213226
}
214227

215228
public function testSanitizationContailsSpecialChars(): void

user_guide_src/source/changelogs/v4.4.0.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,12 @@ Added Parameters
109109
- **Routing:** The third parameter ``Routing $routing`` has been added to
110110
``RouteCollection::__construct()``.
111111

112+
Return Type Changes
113+
-------------------
114+
115+
- **Autoloader:** The return signatures of the `loadClass` and `loadClassmap` methods are made `void`
116+
to be compatible as callbacks in `spl_autoload_register` and `spl_autoload_unregister` functions.
117+
112118
Enhancements
113119
************
114120

@@ -225,6 +231,8 @@ Changes
225231
``Config\App::$forceGlobalSecureRequests = true`` sets the HTTP status code 307,
226232
which allows the HTTP request method to be preserved after the redirect.
227233
In previous versions, it was 302.
234+
- The methods `Autoloader::loadClass()` and `Autoloader::loadClassmap()` are now both
235+
marked `@internal`.
228236

229237
Deprecations
230238
************

0 commit comments

Comments
 (0)