Procházet zdrojové kódy

ZF-8200: allow loading PHP 5.3 code containing namespaces

git-svn-id: http://framework.zend.com/svn/framework/standard/trunk@20242 44c647ce-9c0f-0410-b52a-842ac1e357ba
matthew před 16 roky
rodič
revize
72f5c49147

+ 67 - 0
documentation/manual/en/module_specs/Zend_Loader-Autoloader.xml

@@ -126,6 +126,73 @@ $autoloader->suppressNotFoundWarnings(true);
         <programlisting language="php"><![CDATA[
 $autoloader->setFallbackAutoloader(true);
 ]]></programlisting>
+
+        <note>
+            <title>Loading Classes from PHP Namespaces</title>
+
+            <para>
+                Starting in version 1.10.0, Zend Framework now allows loading classes from PHP
+                namespaces. This support follows the same guidelines and implementation as that
+                found in the <link
+                    linkend="http://groups.google.com/group/php-standards/web/psr-0-final-proposal">PHP
+                Framework Interop Group PSR-0</link> reference implementation.
+            </para>
+
+            <para>
+                Under this guideline, the following rules apply:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Each namespace separator is converted to a
+                        <constant>DIRECTORY_SEPARATOR</constant> when loading from the file system.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        Each "_" character in the <emphasis>CLASS NAME</emphasis> is converted to a
+                        <constant>DIRECTORY_SEPARATOR</constant>.  The "_" character has no special
+                        meaning in the namespace.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        The fully-qualified namespace and class is suffixed with ".php" when loading
+                        from the file system.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                As examples:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <classname>\Doctrine\Common\IsolatedClassLoader</classname> =&gt;
+                        <filename>/path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php</filename>
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <classname>\namespace\package\Class_Name</classname> =&gt;
+                        <filename>/path/to/project/lib/vendor/namespace/package/Class/Name.php</filename>
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <classname>\namespace\package_name\Class_Name</classname> =&gt;
+                        <filename>/path/to/project/lib/vendor/namespace/package_name/Class/Name.php</filename>
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </note>
     </sect2>
 
     <sect2 id="zend.loader.autoloader.zf-version">

+ 66 - 0
documentation/manual/en/module_specs/Zend_Loader.xml

@@ -113,6 +113,72 @@ Zend_Loader::loadClass('Container_Tree',
             ('-'), underscore ('_'), and period ('.').
         </para>
 
+        <note>
+            <title>Loading Classes from PHP Namespaces</title>
+
+            <para>
+                Starting in version 1.10.0, Zend Framework now allows loading classes from PHP
+                namespaces. This support follows the same guidelines and implementation as that
+                found in the <link
+                    linkend="http://groups.google.com/group/php-standards/web/psr-0-final-proposal">PHP
+                Framework Interop Group PSR-0</link> reference implementation.
+            </para>
+
+            <para>
+                Under this guideline, the following rules apply:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        Each namespace separator is converted to a
+                        <constant>DIRECTORY_SEPARATOR</constant> when loading from the file system.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        Each "_" character in the <emphasis>CLASS NAME</emphasis> is converted to a
+                        <constant>DIRECTORY_SEPARATOR</constant>.  The "_" character has no special
+                        meaning in the namespace.
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        The fully-qualified namespace and class is suffixed with ".php" when loading
+                        from the file system.
+                    </para>
+                </listitem>
+            </itemizedlist>
+
+            <para>
+                As examples:
+            </para>
+
+            <itemizedlist>
+                <listitem>
+                    <para>
+                        <classname>\Doctrine\Common\IsolatedClassLoader</classname> =&gt;
+                        <filename>/path/to/project/lib/vendor/Doctrine/Common/IsolatedClassLoader.php</filename>
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <classname>\namespace\package\Class_Name</classname> =&gt;
+                        <filename>/path/to/project/lib/vendor/namespace/package/Class/Name.php</filename>
+                    </para>
+                </listitem>
+
+                <listitem>
+                    <para>
+                        <classname>\namespace\package_name\Class_Name</classname> =&gt;
+                        <filename>/path/to/project/lib/vendor/namespace/package_name/Class/Name.php</filename>
+                    </para>
+                </listitem>
+            </itemizedlist>
+        </note>
     </sect2>
 
     <sect2 id="zend.loader.load.isreadable">

+ 14 - 2
library/Zend/Loader.php

@@ -60,8 +60,20 @@ class Zend_Loader
             throw new Zend_Exception('Directory argument must be a string or an array');
         }
 
-        // autodiscover the path from the class name
-        $file = str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php';
+        // Autodiscover the path from the class name
+        // Implementation is PHP namespace-aware, and based on 
+        // Framework Interop Group reference implementation:
+        // http://groups.google.com/group/php-standards/web/psr-0-final-proposal
+        $className = ltrim($class, '\\');
+        $file      = '';
+        $namespace = '';
+        if ($lastNsPos = strripos($className, '\\')) {
+            $namespace = substr($className, 0, $lastNsPos);
+            $className = substr($className, $lastNsPos + 1);
+            $file      = str_replace('\\', DIRECTORY_SEPARATOR, $namespace) . DIRECTORY_SEPARATOR;
+        }
+        $file .= str_replace('_', DIRECTORY_SEPARATOR, $className) . '.php';
+
         if (!empty($dirs)) {
             // use the autodiscovered path
             $dirPath = dirname($file);

+ 11 - 0
tests/Zend/LoaderTest.php

@@ -459,6 +459,17 @@ class Zend_LoaderTest extends PHPUnit_Framework_TestCase
     }
 
     /**
+     * @group ZF-8200
+     */
+    public function testLoadClassShouldAllowLoadingPhpNamespacedClasses()
+    {
+        if (version_compare(PHP_VERSION, '5.3.0') < 0) {
+            $this->markTestSkipped('PHP < 5.3.0 does not support namespaces');
+        }
+        Zend_Loader::loadClass('\Zfns\Foo', array(dirname(__FILE__) . '/Loader/_files'));
+    }
+
+    /**
      * In order to play nice with spl_autoload, an autoload callback should
      * *not* emit errors (exceptions are okay). ZF-2923 requests that this
      * behavior be applied, which counters the previous request in ZF-2463.