Skip to content

Commit b6684e6

Browse files
authored
Merge pull request #8005 from kenjis/perf-autoloader
perf: autoloader
2 parents 6f63602 + 9a9a5ed commit b6684e6

File tree

13 files changed

+83
-48
lines changed

13 files changed

+83
-48
lines changed

admin/starter/composer.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
"phpunit/phpunit": "^9.1"
2020
},
2121
"autoload": {
22+
"psr-4": {
23+
"App\\": "app/"
24+
},
2225
"exclude-from-classmap": [
2326
"**/Database/Migrations/**"
2427
]

app/Config/Autoload.php

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,23 +30,18 @@ class Autoload extends AutoloadConfig
3030
* their location on the file system. These are used by the autoloader
3131
* to locate files the first time they have been instantiated.
3232
*
33-
* The '/app' and '/system' directories are already mapped for you.
34-
* you may change the name of the 'App' namespace if you wish,
33+
* The 'Config' (APPPATH . 'Config') and 'CodeIgniter' (SYSTEMPATH) are
34+
* already mapped for you.
35+
*
36+
* You may change the name of the 'App' namespace if you wish,
3537
* but this should be done prior to creating any namespaced classes,
3638
* else you will need to modify all of those classes for this to work.
3739
*
38-
* Prototype:
39-
* $psr4 = [
40-
* 'CodeIgniter' => SYSTEMPATH,
41-
* 'App' => APPPATH
42-
* ];
43-
*
4440
* @var array<string, array<int, string>|string>
4541
* @phpstan-var array<string, string|list<string>>
4642
*/
4743
public $psr4 = [
48-
APP_NAMESPACE => APPPATH, // For custom app namespace
49-
'Config' => APPPATH . 'Config',
44+
APP_NAMESPACE => APPPATH,
5045
];
5146

5247
/**

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@
5858
},
5959
"autoload": {
6060
"psr-4": {
61-
"CodeIgniter\\": "system/"
61+
"CodeIgniter\\": "system/",
62+
"Config\\": "app/Config/"
6263
},
6364
"exclude-from-classmap": [
6465
"**/Database/Migrations/**"

system/Autoloader/Autoloader.php

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,6 @@ private function loadComposerAutoloader(Modules $modules): void
141141
/** @var ClassLoader $composer */
142142
$composer = include COMPOSER_PATH;
143143

144-
$this->loadComposerClassmap($composer);
145-
146144
// Should we load through Composer's namespaces, also?
147145
if ($modules->discoverInComposer) {
148146
// @phpstan-ignore-next-line
@@ -159,11 +157,11 @@ private function loadComposerAutoloader(Modules $modules): void
159157
*/
160158
public function register()
161159
{
162-
// Prepend the PSR4 autoloader for maximum performance.
163-
spl_autoload_register([$this, 'loadClass'], true, true);
160+
// Register classmap loader for the files in our class map.
161+
spl_autoload_register([$this, 'loadClassmap'], true);
164162

165-
// Now prepend another loader for the files in our class map.
166-
spl_autoload_register([$this, 'loadClassmap'], true, true);
163+
// Register the PSR-4 autoloader.
164+
spl_autoload_register([$this, 'loadClass'], true);
167165

168166
// Load our non-class files
169167
foreach ($this->files as $file) {
@@ -366,9 +364,13 @@ private function loadComposerNamespaces(ClassLoader $composer, array $composerPa
366364
{
367365
$namespacePaths = $composer->getPrefixesPsr4();
368366

369-
// Get rid of CodeIgniter so we don't have duplicates
370-
if (isset($namespacePaths['CodeIgniter\\'])) {
371-
unset($namespacePaths['CodeIgniter\\']);
367+
// Get rid of duplicated namespaces.
368+
$duplicatedNamespaces = ['CodeIgniter', APP_NAMESPACE, 'Config'];
369+
370+
foreach ($duplicatedNamespaces as $ns) {
371+
if (isset($namespacePaths[$ns . '\\'])) {
372+
unset($namespacePaths[$ns . '\\']);
373+
}
372374
}
373375

374376
if (! method_exists(InstalledVersions::class, 'getAllRawData')) {
@@ -432,13 +434,6 @@ private function loadComposerNamespaces(ClassLoader $composer, array $composerPa
432434
$this->addNamespace($newPaths);
433435
}
434436

435-
private function loadComposerClassmap(ClassLoader $composer): void
436-
{
437-
$classes = $composer->getClassMap();
438-
439-
$this->classmap = array_merge($this->classmap, $classes);
440-
}
441-
442437
/**
443438
* Locates autoload information from Composer, if available.
444439
*

system/Config/AutoloadConfig.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ class AutoloadConfig
9292
*/
9393
protected $corePsr4 = [
9494
'CodeIgniter' => SYSTEMPATH,
95-
'App' => APPPATH, // To ensure filters, etc still found,
95+
'Config' => APPPATH . 'Config',
9696
];
9797

9898
/**

tests/system/Commands/Utilities/NamespacesTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ public function testNamespacesCommandCodeIgniterOnly(): void
5656
| Namespace | Path | Found? |
5757
+---------------+-------------------------+--------+
5858
| CodeIgniter | ROOTPATH/system | Yes |
59-
| App | ROOTPATH/app | Yes |
6059
| Config | APPPATH/Config | Yes |
60+
| App | ROOTPATH/app | Yes |
6161
| Tests\Support | ROOTPATH/tests/_support | Yes |
6262
+---------------+-------------------------+--------+
6363
EOL;

tests/system/Config/ConfigTest.php

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,6 @@ public function testCreateSharedInstance(): void
4646
$this->assertSame($Config2, $Config);
4747
}
4848

49-
public function testCreateNonConfig(): void
50-
{
51-
$Config = Config::get('Constants', false);
52-
53-
$this->assertNull($Config);
54-
}
55-
5649
/**
5750
* @runInSeparateProcess
5851
* @preserveGlobalState disabled

user_guide_src/source/changelogs/v4.5.0.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,10 @@ Helpers and Functions
116116
Others
117117
======
118118

119+
- **Autoloader:** Autoloading performance when using Composer has been improved.
120+
Adding the ``App`` namespace in the ``autoload.psr4`` setting in **composer.json**
121+
may also improve the performance of your app. See :ref:`autoloader-application-namespace`.
122+
119123
Message Changes
120124
***************
121125

user_guide_src/source/concepts/autoloader.rst

Lines changed: 50 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ classes that your project is using. Keeping track of where every single file is,
1313
hard-coding that location into your files in a series of ``requires()`` is a massive
1414
headache and very error-prone. That's where autoloaders come in.
1515

16+
***********************
1617
CodeIgniter4 Autoloader
1718
***********************
1819

@@ -36,12 +37,14 @@ beginning of the framework's execution.
3637
file name case is incorrect, the autoloader cannot find the file on the
3738
server.
3839

40+
*************
3941
Configuration
4042
*************
4143

4244
Initial configuration is done in **app/Config/Autoload.php**. This file contains two primary
4345
arrays: one for the classmap, and one for PSR-4 compatible namespaces.
4446

47+
**********
4548
Namespaces
4649
**********
4750

@@ -61,21 +64,53 @@ The value is the location to the directory the classes can be found in.
6164
6265
php spark namespaces
6366
67+
.. _autoloader-application-namespace:
68+
69+
Application Namespace
70+
=====================
71+
6472
By default, the application directory is namespace to the ``App`` namespace. You must namespace the controllers,
6573
libraries, or models in the application directory, and they will be found under the ``App`` namespace.
6674

75+
Config Namespace
76+
----------------
77+
78+
Config files are namespaced in the ``Config`` namespace, not in ``App\Config`` as you might
79+
expect. This allows the core system files to always be able to locate them, even when the application
80+
namespace has changed.
81+
82+
Changing App Namespace
83+
----------------------
84+
6785
You may change this namespace by editing the **app/Config/Constants.php** file and setting the
6886
new namespace value under the ``APP_NAMESPACE`` setting:
6987

7088
.. literalinclude:: autoloader/002.php
7189
:lines: 2-
7290

73-
You will need to modify any existing files that are referencing the current namespace.
91+
And if you use Composer autoloader, you also need to change the ``App`` namespace
92+
in your **composer.json**, and run ``composer dump-autoload``.
7493

75-
.. important:: Config files are namespaced in the ``Config`` namespace, not in ``App\Config`` as you might
76-
expect. This allows the core system files to always be able to locate them, even when the application
77-
namespace has changed.
94+
.. code-block:: text
7895
96+
{
97+
...
98+
"autoload": {
99+
"psr-4": {
100+
"App\\": "app/" <-- Change
101+
},
102+
...
103+
},
104+
...
105+
}
106+
107+
.. note:: Since v4.5.0 appstarter, the ``App\\`` namespace has been added to
108+
**composer.json**'s ``autoload.psr-4``. If your **composer.json** does not
109+
have it, adding it may improve your app's autoloading performance.
110+
111+
You will need to modify any existing files that are referencing the current namespace.
112+
113+
********
79114
Classmap
80115
********
81116

@@ -87,12 +122,21 @@ third-party libraries that are not namespaced:
87122

88123
The key of each row is the name of the class that you want to locate. The value is the path to locate it at.
89124

125+
****************
90126
Composer Support
91127
****************
92128

93-
Composer support is automatically initialized by default. By default, it looks for Composer's autoload file at
129+
Composer support is automatically initialized by default.
130+
131+
By default, it looks for Composer's autoload file at
94132
``ROOTPATH . 'vendor/autoload.php'``. If you need to change the location of that file for any reason, you can modify
95133
the value defined in **app/Config/Constants.php**.
96134

97-
.. note:: If the same namespace is defined in both CodeIgniter and Composer, CodeIgniter's autoloader will be
135+
Priority of Autoloaders
136+
=======================
137+
138+
If the same namespace is defined in both CodeIgniter and Composer, Composer's
139+
autoloader will be the first one to get a chance to locate the file.
140+
141+
.. note:: Prior to v4.5.0, if the same namespace was defined in both CodeIgniter and Composer, CodeIgniter's autoloader was
98142
the first one to get a chance to locate the file.

user_guide_src/source/concepts/autoloader/001.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ class Autoload extends AutoloadConfig
88
{
99
// ...
1010
public $psr4 = [
11-
APP_NAMESPACE => APPPATH, // For custom app namespace
12-
'Config' => APPPATH . 'Config',
11+
APP_NAMESPACE => APPPATH,
1312
];
1413

1514
// ...

user_guide_src/source/dbmgmt/migration.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ For example, assume that we have the following namespaces defined in our Autoloa
9393
configuration file:
9494

9595
.. literalinclude:: migration/004.php
96+
:lines: 2-
9697

9798
This will look for any migrations located at both **APPPATH/Database/Migrations** and
9899
**ROOTPATH/MyCompany/Database/Migrations**. This makes it simple to include migrations in your
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?php
22

33
$psr4 = [
4-
'App' => APPPATH,
5-
'MyCompany' => ROOTPATH . 'MyCompany',
4+
APP_NAMESPACE => APPPATH,
5+
'MyCompany' => ROOTPATH . 'MyCompany',
66
];

user_guide_src/source/general/modules/001.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@
66

77
class Autoload extends AutoloadConfig
88
{
9+
// ...
910
public $psr4 = [
10-
APP_NAMESPACE => APPPATH, // For custom namespace
11-
'Config' => APPPATH . 'Config',
11+
APP_NAMESPACE => APPPATH,
1212
'Acme\Blog' => ROOTPATH . 'acme/Blog',
1313
];
1414

0 commit comments

Comments
 (0)