1
+ <?php
2
+
3
+ /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
4
+
5
+ /**
6
+ * Defines the class InstantAutoloader
7
+ *
8
+ * PHP version 5
9
+ *
10
+ * LICENSE: This program is free software: you can redistribute it and/or modify
11
+ * it under the terms of the GNU General Public License as published by
12
+ * the Free Software Foundation, either version 3 of the License, or
13
+ * (at your option) any later version.
14
+ *
15
+ * This program is distributed in the hope that it will be useful,
16
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
+ * GNU General Public License for more details.
19
+ *
20
+ * You should have received a copy of the GNU General Public License
21
+ * along with this program.
22
+ * If not, see <http://php-autoloader.malkusch.de/en/license/>.
23
+ *
24
+ * @category PHP
25
+ * @package Autoloader
26
+ * @author Markus Malkusch <markus@malkusch.de>
27
+ * @copyright 2009 - 2010 Markus Malkusch
28
+ * @license http://php-autoloader.malkusch.de/en/license/ GPL 3
29
+ * @version SVN: $Id$
30
+ * @link http://php-autoloader.malkusch.de/en/
31
+ */
32
+
33
+ namespace malkusch \autoloader ;
34
+
35
+ /**
36
+ * There might be several InstantAutoloaders deployed in a project.
37
+ * One is enough.
38
+ */
39
+ if (! class_exists ("malkusch\autoloader\InstantAutoloader " , false )) {
40
+
41
+ /**
42
+ * An instant autoloader for shipping with project builds
43
+ *
44
+ * You can build a complete index of your project (by calling
45
+ * Autoloader::buildIndex()). If you use AutoloaderIndex_PHPArrayCode as
46
+ * index you can only use this instant autoloader for your project. This class
47
+ * has no further dependency on any other class. Just copy this class and the
48
+ * generated index anywhere into your project.
49
+ *
50
+ * Consider setting the AutoloaderIndexFilter_RelativePath filter.
51
+ *
52
+ * @category PHP
53
+ * @package Autoloader
54
+ * @author Markus Malkusch <markus@malkusch.de>
55
+ * @license http://php-autoloader.malkusch.de/en/license/ GPL 3
56
+ * @version Release: 1.12
57
+ * @link http://php-autoloader.malkusch.de/en/
58
+ * @see Autoloader::buildIndex()
59
+ * @see AutoloaderIndex_PHPArrayCode()
60
+ * @see AutoloaderIndexFilter_RelativePath()
61
+ */
62
+ class InstantAutoloader
63
+ {
64
+
65
+ const
66
+ /**
67
+ * The name of the class constructor is classConstructor().
68
+ */
69
+ CLASS_CONSTRUCTOR = 'classConstructor ' ;
70
+
71
+ private
72
+ /**
73
+ * @var string
74
+ */
75
+ $ _basePath = "" ,
76
+ /**
77
+ * @var array
78
+ */
79
+ $ _index = array ();
80
+
81
+ /**
82
+ * Loads the generated index array
83
+ *
84
+ * The index must be a generated AutoloaderIndex_PHPArrayCode index.
85
+ *
86
+ * @param string $indexPath Path to the generated index
87
+ */
88
+ public function __construct ($ indexPath )
89
+ {
90
+ $ this ->_index = require $ indexPath ;
91
+ }
92
+
93
+ /**
94
+ * Registers this autoloader at the autoloader stack
95
+ *
96
+ * @return void
97
+ */
98
+ public function register ()
99
+ {
100
+ // spl_autoload_register() disables __autoload(). This might be unwanted.
101
+ if (\function_exists ("__autoload " )) {
102
+ \spl_autoload_register ("__autoload " );
103
+
104
+ }
105
+ \spl_autoload_register (array ($ this , "__autoload " ));
106
+ }
107
+
108
+ /**
109
+ * Includes all class paths
110
+ *
111
+ * You can use this as an alternative to the autoload mechanism. This
112
+ * simply includes all classes without any autoloader.
113
+ *
114
+ * @return void
115
+ */
116
+ public function requireAll ()
117
+ {
118
+ foreach ($ this ->_index as $ classPath ) {
119
+ $ this ->_requirePath ($ classPath );
120
+
121
+ }
122
+ }
123
+
124
+ /**
125
+ * Sets the base path for the class paths in the index
126
+ *
127
+ * @param string $basePath Base path for the class paths in the index
128
+ *
129
+ * @return void
130
+ */
131
+ public function setBasePath ($ basePath )
132
+ {
133
+ $ this ->_basePath = $ basePath ;
134
+ }
135
+
136
+ /**
137
+ * Autoloader callback
138
+ *
139
+ * @param string $class Class name
140
+ *
141
+ * @return void
142
+ */
143
+ public function __autoload ($ class )
144
+ {
145
+ $ this ->_normalizeClass ($ class );
146
+
147
+ /*
148
+ * spl_autoload_call() runs the complete stack,
149
+ * even though the class is already defined by
150
+ * a previously registered method.
151
+ */
152
+ if (
153
+ \class_exists ($ class , false )
154
+ || \interface_exists ($ class , false )
155
+ ) {
156
+ return ;
157
+
158
+ }
159
+ if (
160
+ \version_compare (PHP_VERSION , "5.4 " , '>= ' )
161
+ && \trait_exists ($ class , false )
162
+ ) {
163
+ return ;
164
+
165
+ }
166
+ if (!\array_key_exists ($ class , $ this ->_index )) {
167
+ return ;
168
+
169
+ }
170
+
171
+ $ this ->_requirePath ($ this ->_index [$ class ]);
172
+
173
+ $ this ->_callClassConstructor ($ class , self ::CLASS_CONSTRUCTOR );
174
+ }
175
+
176
+ /**
177
+ * Requires a class path
178
+ *
179
+ * @param string $path Class path
180
+ *
181
+ * @return void
182
+ */
183
+ private function _requirePath ($ path )
184
+ {
185
+ if (!empty ($ this ->_basePath )) {
186
+ $ path = $ this ->_basePath . DIRECTORY_SEPARATOR . $ path ;
187
+
188
+ }
189
+ require_once $ path ;
190
+ }
191
+
192
+ /**
193
+ * Normalizes the reference of a class name with strtolower()
194
+ *
195
+ * Normalizing is needed as PHP is case insensitive.
196
+ *
197
+ * @param String &$class The reference of a class name
198
+ *
199
+ * @see strtolower().
200
+ * @return void
201
+ */
202
+ private function _normalizeClass (&$ class )
203
+ {
204
+ $ class = \strtolower ($ class );
205
+ }
206
+
207
+ /**
208
+ * Calls the class constructor
209
+ *
210
+ * If the class $class has the method public static $constructor, it
211
+ * will be called.
212
+ *
213
+ * @param String $class A class which might have a class constructor
214
+ * @param String $constructorName the method name of the class constructor
215
+ *
216
+ * @return bool true if the class constructor was called
217
+ */
218
+ public static function _callClassConstructor ($ class , $ constructorName )
219
+ {
220
+ $ reflectionClass = new \ReflectionClass ($ class );
221
+ if (!$ reflectionClass ->hasMethod ($ constructorName )) {
222
+ return false ;
223
+
224
+ }
225
+
226
+ $ constructor = $ reflectionClass ->getMethod ($ constructorName );
227
+ if (!$ constructor ->isStatic ()) {
228
+ return false ;
229
+
230
+ }
231
+
232
+ if (\version_compare (PHP_VERSION , "5.4 " , '>= ' ) && $ reflectionClass ->isTrait ()) {
233
+ return false ;
234
+
235
+ }
236
+
237
+ if ($ constructor ->getDeclaringClass ()->getName () != $ reflectionClass ->getName ()) {
238
+ return false ;
239
+
240
+ }
241
+
242
+ $ constructor ->invoke (null );
243
+ return true ;
244
+ }
245
+
246
+ }
247
+
248
+ }
0 commit comments