~ubuntu-branches/ubuntu/wily/php-doctrine-common/wily-proposed

« back to all changes in this revision

Viewing changes to DoctrineCommon-2.3.0/Doctrine/Common/ClassLoader.php

  • Committer: Package Import Robot
  • Author(s): David Prévot
  • Date: 2014-06-15 11:26:00 UTC
  • mfrom: (2.1.1 experimental)
  • Revision ID: package-import@ubuntu.com-20140615112600-sg4mgpwq9sfg4mre
Tags: 2.4.2-2
* Upload to unstable
* No tests if DEB_BUILD_OPTIONS contains nocheck

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
<?php
2
 
/*
3
 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4
 
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5
 
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6
 
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7
 
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8
 
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9
 
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10
 
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11
 
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12
 
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13
 
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
14
 
 *
15
 
 * This software consists of voluntary contributions made by many individuals
16
 
 * and is licensed under the MIT license. For more information, see
17
 
 * <http://www.doctrine-project.org>.
18
 
 */
19
 
 
20
 
namespace Doctrine\Common;
21
 
 
22
 
/**
23
 
 * A <tt>ClassLoader</tt> is an autoloader for class files that can be
24
 
 * installed on the SPL autoload stack. It is a class loader that either loads only classes
25
 
 * of a specific namespace or all namespaces and it is suitable for working together
26
 
 * with other autoloaders in the SPL autoload stack.
27
 
 *
28
 
 * If no include path is configured through the constructor or {@link setIncludePath}, a ClassLoader
29
 
 * relies on the PHP <code>include_path</code>.
30
 
 *
31
 
 * @author Roman Borschel <roman@code-factory.org>
32
 
 * @since 2.0
33
 
 */
34
 
class ClassLoader
35
 
{
36
 
    /**
37
 
     * @var string PHP file extension
38
 
     */
39
 
    protected $fileExtension = '.php';
40
 
 
41
 
    /**
42
 
     * @var string Current namespace
43
 
     */
44
 
    protected $namespace;
45
 
 
46
 
    /**
47
 
     * @var string Current include path
48
 
     */
49
 
    protected $includePath;
50
 
 
51
 
    /**
52
 
     * @var string PHP namespace separator
53
 
     */
54
 
    protected $namespaceSeparator = '\\';
55
 
 
56
 
    /**
57
 
     * Creates a new <tt>ClassLoader</tt> that loads classes of the
58
 
     * specified namespace from the specified include path.
59
 
     *
60
 
     * If no include path is given, the ClassLoader relies on the PHP include_path.
61
 
     * If neither a namespace nor an include path is given, the ClassLoader will
62
 
     * be responsible for loading all classes, thereby relying on the PHP include_path.
63
 
     *
64
 
     * @param string $ns The namespace of the classes to load.
65
 
     * @param string $includePath The base include path to use.
66
 
     */
67
 
    public function __construct($ns = null, $includePath = null)
68
 
    {
69
 
        $this->namespace = $ns;
70
 
        $this->includePath = $includePath;
71
 
    }
72
 
 
73
 
    /**
74
 
     * Sets the namespace separator used by classes in the namespace of this ClassLoader.
75
 
     *
76
 
     * @param string $sep The separator to use.
77
 
     */
78
 
    public function setNamespaceSeparator($sep)
79
 
    {
80
 
        $this->namespaceSeparator = $sep;
81
 
    }
82
 
 
83
 
    /**
84
 
     * Gets the namespace separator used by classes in the namespace of this ClassLoader.
85
 
     *
86
 
     * @return string
87
 
     */
88
 
    public function getNamespaceSeparator()
89
 
    {
90
 
        return $this->namespaceSeparator;
91
 
    }
92
 
 
93
 
    /**
94
 
     * Sets the base include path for all class files in the namespace of this ClassLoader.
95
 
     *
96
 
     * @param string $includePath
97
 
     */
98
 
    public function setIncludePath($includePath)
99
 
    {
100
 
        $this->includePath = $includePath;
101
 
    }
102
 
 
103
 
    /**
104
 
     * Gets the base include path for all class files in the namespace of this ClassLoader.
105
 
     *
106
 
     * @return string
107
 
     */
108
 
    public function getIncludePath()
109
 
    {
110
 
        return $this->includePath;
111
 
    }
112
 
 
113
 
    /**
114
 
     * Sets the file extension of class files in the namespace of this ClassLoader.
115
 
     *
116
 
     * @param string $fileExtension
117
 
     */
118
 
    public function setFileExtension($fileExtension)
119
 
    {
120
 
        $this->fileExtension = $fileExtension;
121
 
    }
122
 
 
123
 
    /**
124
 
     * Gets the file extension of class files in the namespace of this ClassLoader.
125
 
     *
126
 
     * @return string
127
 
     */
128
 
    public function getFileExtension()
129
 
    {
130
 
        return $this->fileExtension;
131
 
    }
132
 
 
133
 
    /**
134
 
     * Registers this ClassLoader on the SPL autoload stack.
135
 
     */
136
 
    public function register()
137
 
    {
138
 
        spl_autoload_register(array($this, 'loadClass'));
139
 
    }
140
 
 
141
 
    /**
142
 
     * Removes this ClassLoader from the SPL autoload stack.
143
 
     */
144
 
    public function unregister()
145
 
    {
146
 
        spl_autoload_unregister(array($this, 'loadClass'));
147
 
    }
148
 
 
149
 
    /**
150
 
     * Loads the given class or interface.
151
 
     *
152
 
     * @param string $className The name of the class to load.
153
 
 
154
 
     * @return boolean TRUE if the class has been successfully loaded, FALSE otherwise.
155
 
     */
156
 
    public function loadClass($className)
157
 
    {
158
 
        if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) {
159
 
            return false;
160
 
        }
161
 
 
162
 
        require ($this->includePath !== null ? $this->includePath . DIRECTORY_SEPARATOR : '')
163
 
               . str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className)
164
 
               . $this->fileExtension;
165
 
 
166
 
        return true;
167
 
    }
168
 
 
169
 
    /**
170
 
     * Asks this ClassLoader whether it can potentially load the class (file) with
171
 
     * the given name.
172
 
     *
173
 
     * @param string $className The fully-qualified name of the class.
174
 
     * @return boolean TRUE if this ClassLoader can load the class, FALSE otherwise.
175
 
     */
176
 
    public function canLoadClass($className)
177
 
    {
178
 
        if ($this->namespace !== null && strpos($className, $this->namespace.$this->namespaceSeparator) !== 0) {
179
 
            return false;
180
 
        }
181
 
 
182
 
        $file = str_replace($this->namespaceSeparator, DIRECTORY_SEPARATOR, $className) . $this->fileExtension;
183
 
 
184
 
        if ($this->includePath !== null) {
185
 
            return file_exists($this->includePath . DIRECTORY_SEPARATOR . $file);
186
 
        }
187
 
 
188
 
        return (false !== stream_resolve_include_path($file));
189
 
    }
190
 
 
191
 
    /**
192
 
     * Checks whether a class with a given name exists. A class "exists" if it is either
193
 
     * already defined in the current request or if there is an autoloader on the SPL
194
 
     * autoload stack that is a) responsible for the class in question and b) is able to
195
 
     * load a class file in which the class definition resides.
196
 
     *
197
 
     * If the class is not already defined, each autoloader in the SPL autoload stack
198
 
     * is asked whether it is able to tell if the class exists. If the autoloader is
199
 
     * a <tt>ClassLoader</tt>, {@link canLoadClass} is used, otherwise the autoload
200
 
     * function of the autoloader is invoked and expected to return a value that
201
 
     * evaluates to TRUE if the class (file) exists. As soon as one autoloader reports
202
 
     * that the class exists, TRUE is returned.
203
 
     *
204
 
     * Note that, depending on what kinds of autoloaders are installed on the SPL
205
 
     * autoload stack, the class (file) might already be loaded as a result of checking
206
 
     * for its existence. This is not the case with a <tt>ClassLoader</tt>, who separates
207
 
     * these responsibilities.
208
 
     *
209
 
     * @param string $className The fully-qualified name of the class.
210
 
     * @return boolean TRUE if the class exists as per the definition given above, FALSE otherwise.
211
 
     */
212
 
    public static function classExists($className)
213
 
    {
214
 
        if (class_exists($className, false) || interface_exists($className, false)) {
215
 
            return true;
216
 
        }
217
 
 
218
 
        foreach (spl_autoload_functions() as $loader) {
219
 
            if (is_array($loader)) { // array(???, ???)
220
 
                if (is_object($loader[0])) {
221
 
                    if ($loader[0] instanceof ClassLoader) { // array($obj, 'methodName')
222
 
                        if ($loader[0]->canLoadClass($className)) {
223
 
                            return true;
224
 
                        }
225
 
                    } else if ($loader[0]->{$loader[1]}($className)) {
226
 
                        return true;
227
 
                    }
228
 
                } else if ($loader[0]::$loader[1]($className)) { // array('ClassName', 'methodName')
229
 
                    return true;
230
 
                }
231
 
            } else if ($loader instanceof \Closure) { // function($className) {..}
232
 
                if ($loader($className)) {
233
 
                    return true;
234
 
                }
235
 
            } else if (is_string($loader) && $loader($className)) { // "MyClass::loadClass"
236
 
                return true;
237
 
            }
238
 
        }
239
 
 
240
 
        return class_exists($className, false) || interface_exists($className, false);
241
 
    }
242
 
 
243
 
    /**
244
 
     * Gets the <tt>ClassLoader</tt> from the SPL autoload stack that is responsible
245
 
     * for (and is able to load) the class with the given name.
246
 
     *
247
 
     * @param string $className The name of the class.
248
 
     * @return ClassLoader The <tt>ClassLoader</tt> for the class or NULL if no such <tt>ClassLoader</tt> exists.
249
 
     */
250
 
    public static function getClassLoader($className)
251
 
    {
252
 
         foreach (spl_autoload_functions() as $loader) {
253
 
            if (is_array($loader)
254
 
                && $loader[0] instanceof ClassLoader
255
 
                && $loader[0]->canLoadClass($className)
256
 
            ) {
257
 
                return $loader[0];
258
 
            }
259
 
        }
260
 
 
261
 
        return null;
262
 
    }
263
 
}