PSR-4 實例

Aug 08, 2016 am 09:28 AM
bar class this

以下是一个实现PSR-4规范的例子:

Closure Example

<code><span><?php</span><span>/**
 * 一个具体项目实现的例子.
 * 使用SPL注册了autoload函数之后,以下代码将触发autoload函数从
 * /path/to/project/src/Baz/Qux.php 文件加载
 * \Foo\Bar\Baz\Qux 类
 *      new \Foo\Bar\Baz\Qux;
 *      
 *<span> @param</span> string $class The fully-qualified class name.
 *<span> @return</span> void
 */</span>
spl_autoload_register(<span><span>function</span><span>(<span>$class</span>)</span> {</span><span>// 项目约定的命名空间前缀</span><span>$prefix</span> = <span>'Foo\\Bar\\'</span>;

    <span>// 命名空间前缀的基础目录</span><span>$base_dir</span> = <span>__DIR__</span> . <span>'/src/'</span>;

    <span>// 这个类是否使用了命名空间前缀?</span><span>$len</span> = strlen(<span>$prefix</span>);
    <span>if</span> (strncmp(<span>$prefix</span>, <span>$class</span>, <span>$len</span>) !== <span>0</span>) {
        <span>// 没有,尝试下个已注册的 autoloader</span><span>return</span>;
    }

    <span>// 获取相对类名(截取命名空间前缀后剩下的部分)</span><span>$relative_class</span> = substr(<span>$class</span>, <span>$len</span>);

    <span>// 用base目录替换命名空间前缀;</span><span>// 用目录分隔符替换命名空间分隔符;</span><span>// 坠上 .php</span><span>$file</span> = <span>$base_dir</span> . str_replace(<span>'\\'</span>, <span>'/'</span>, <span>$relative_class</span>) . <span>'.php'</span>;

    <span>// 如果文件存在,加载文件。</span><span>if</span> (file_exists(<span>$file</span>)) {
        <span>require</span><span>$file</span>;
    }
});</code>
登入後複製

Class Example

以下是一个处理多命名空间的类的例子。

<code><span><?php</span><span>namespace</span><span>Example</span>;

<span>/**
 * 这个例子是一个针对 一个命名空间前缀对应多个base谬的通用实现。
 * 
 * foo-bar 类的包分别在以下路径下...
 * 
 *     /path/to/packages/foo-bar/
 *         src/
 *             Baz.php             # Foo\Bar\Baz
 *             Qux/
 *                 Quux.php        # Foo\Bar\Qux\Quux
 *         tests/
 *             BazTest.php         # Foo\Bar\BazTest
 *             Qux/
 *                 QuuxTest.php    # Foo\Bar\Qux\QuuxTest
 * 
 * ... 以下代码将类文件的路径添加到 \Foo\Bar\命名空间前缀下。
 * 
 *      <span><?php</span>
 *      // 初始化 loader
 *      $loader = new \Example\Psr4AutoloaderClass;
 *      
 *      // 注册 autoloader
 *      $loader->register();
 *      
 *      // 为命名空间前缀注册base目录。
 *      $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/src');
 *      $loader->addNamespace('Foo\Bar', '/path/to/packages/foo-bar/tests');
 * 
 * 下面的代码将触发 autoloader 尝试从
 * /path/to/packages/foo-bar/src/Qux/Quux.php 加载
 * \Foo\Bar\Qux\Quux 类:
 * 
 *      <span><?php</span>
 *      new \Foo\Bar\Qux\Quux;
 * 
 * 以下代码触发autoloader尝试从
 *  /path/to/packages/foo-bar/tests/Qux/QuuxTest.php
 * 加载\Foo\Bar\Qux\QuuxTest类 :
 * 
 *      <span><?php</span>
 *      new \Foo\Bar\Qux\QuuxTest;
 */</span><span><span>class</span><span>Psr4AutoloaderClass</span>
{</span><span>/**
     * An associative array where the key is a namespace prefix and the value
     * is an array of base directories for classes in that namespace.
     *
     *<span> @var</span> array
     */</span><span>protected</span><span>$prefixes</span> = <span>array</span>();

    <span>/**
     * Register loader with SPL autoloader stack.
     * 
     *<span> @return</span> void
     */</span><span>public</span><span><span>function</span><span>register</span><span>()</span>
    {</span>
        spl_autoload_register(<span>array</span>(<span>$this</span>, <span>'loadClass'</span>));
    }

    <span>/**
     * Adds a base directory for a namespace prefix.
     *
     *<span> @param</span> string $prefix The namespace prefix.
     *<span> @param</span> string $base_dir A base directory for class files in the
     * namespace.
     *<span> @param</span> bool $prepend If true, prepend the base directory to the stack
     * instead of appending it; this causes it to be searched first rather
     * than last.
     *<span> @return</span> void
     */</span><span>public</span><span><span>function</span><span>addNamespace</span><span>(<span>$prefix</span>, <span>$base_dir</span>, <span>$prepend</span> = false)</span>
    {</span><span>// normalize namespace prefix</span><span>$prefix</span> = trim(<span>$prefix</span>, <span>'\\'</span>) . <span>'\\'</span>;

        <span>// normalize the base directory with a trailing separator</span><span>$base_dir</span> = rtrim(<span>$base_dir</span>, DIRECTORY_SEPARATOR) . <span>'/'</span>;

        <span>// initialize the namespace prefix array</span><span>if</span> (<span>isset</span>(<span>$this</span>->prefixes[<span>$prefix</span>]) === <span>false</span>) {
            <span>$this</span>->prefixes[<span>$prefix</span>] = <span>array</span>();
        }

        <span>// retain the base directory for the namespace prefix</span><span>if</span> (<span>$prepend</span>) {
            array_unshift(<span>$this</span>->prefixes[<span>$prefix</span>], <span>$base_dir</span>);
        } <span>else</span> {
            array_push(<span>$this</span>->prefixes[<span>$prefix</span>], <span>$base_dir</span>);
        }
    }

    <span>/**
     * Loads the class file for a given class name.
     *
     *<span> @param</span> string $class The fully-qualified class name.
     *<span> @return</span> mixed The mapped file name on success, or boolean false on
     * failure.
     */</span><span>public</span><span><span>function</span><span>loadClass</span><span>(<span>$class</span>)</span>
    {</span><span>// the current namespace prefix</span><span>$prefix</span> = <span>$class</span>;

        <span>// work backwards through the namespace names of the fully-qualified</span><span>// class name to find a mapped file name</span><span>while</span> (<span>false</span> !== <span>$pos</span> = strrpos(<span>$prefix</span>, <span>'\\'</span>)) {

            <span>// retain the trailing namespace separator in the prefix</span><span>$prefix</span> = substr(<span>$class</span>, <span>0</span>, <span>$pos</span> + <span>1</span>);

            <span>// the rest is the relative class name</span><span>$relative_class</span> = substr(<span>$class</span>, <span>$pos</span> + <span>1</span>);

            <span>// try to load a mapped file for the prefix and relative class</span><span>$mapped_file</span> = <span>$this</span>->loadMappedFile(<span>$prefix</span>, <span>$relative_class</span>);
            <span>if</span> (<span>$mapped_file</span>) {
                <span>return</span><span>$mapped_file</span>;
            }

            <span>// remove the trailing namespace separator for the next iteration</span><span>// of strrpos()</span><span>$prefix</span> = rtrim(<span>$prefix</span>, <span>'\\'</span>);   
        }

        <span>// never found a mapped file</span><span>return</span><span>false</span>;
    }

    <span>/**
     * Load the mapped file for a namespace prefix and relative class.
     * 
     *<span> @param</span> string $prefix The namespace prefix.
     *<span> @param</span> string $relative_class The relative class name.
     *<span> @return</span> mixed Boolean false if no mapped file can be loaded, or the
     * name of the mapped file that was loaded.
     */</span><span>protected</span><span><span>function</span><span>loadMappedFile</span><span>(<span>$prefix</span>, <span>$relative_class</span>)</span>
    {</span><span>// are there any base directories for this namespace prefix?</span><span>if</span> (<span>isset</span>(<span>$this</span>->prefixes[<span>$prefix</span>]) === <span>false</span>) {
            <span>return</span><span>false</span>;
        }

        <span>// look through base directories for this namespace prefix</span><span>foreach</span> (<span>$this</span>->prefixes[<span>$prefix</span>] <span>as</span><span>$base_dir</span>) {

            <span>// replace the namespace prefix with the base directory,</span><span>// replace namespace separators with directory separators</span><span>// in the relative class name, append with .php</span><span>$file</span> = <span>$base_dir</span>
                  . str_replace(<span>'\\'</span>, <span>'/'</span>, <span>$relative_class</span>)
                  . <span>'.php'</span>;

            <span>// if the mapped file exists, require it</span><span>if</span> (<span>$this</span>->requireFile(<span>$file</span>)) {
                <span>// yes, we're done</span><span>return</span><span>$file</span>;
            }
        }

        <span>// never found it</span><span>return</span><span>false</span>;
    }

    <span>/**
     * If a file exists, require it from the file system.
     * 
     *<span> @param</span> string $file The file to require.
     *<span> @return</span> bool True if the file exists, false if not.
     */</span><span>protected</span><span><span>function</span><span>requireFile</span><span>(<span>$file</span>)</span>
    {</span><span>if</span> (file_exists(<span>$file</span>)) {
            <span>require</span><span>$file</span>;
            <span>return</span><span>true</span>;
        }
        <span>return</span><span>false</span>;
    }
}</span></span></code>
登入後複製

Unit Tests

The following example is one way of unit testing the above class loader:

<code><span><?php</span><span>namespace</span><span>Example</span>\<span>Tests</span>;

<span><span>class</span><span>MockPsr4AutoloaderClass</span><span>extends</span><span>Psr4AutoloaderClass</span>
{</span><span>protected</span><span>$files</span> = <span>array</span>();

    <span>public</span><span><span>function</span><span>setFiles</span><span>(array <span>$files</span>)</span>
    {</span><span>$this</span>->files = <span>$files</span>;
    }

    <span>protected</span><span><span>function</span><span>requireFile</span><span>(<span>$file</span>)</span>
    {</span><span>return</span> in_array(<span>$file</span>, <span>$this</span>->files);
    }
}

<span><span>class</span><span>Psr4AutoloaderClassTest</span><span>extends</span> \<span>PHPUnit_Framework_TestCase</span>
{</span><span>protected</span><span>$loader</span>;

    <span>protected</span><span><span>function</span><span>setUp</span><span>()</span>
    {</span><span>$this</span>->loader = <span>new</span> MockPsr4AutoloaderClass;

        <span>$this</span>->loader->setFiles(<span>array</span>(
            <span>'/vendor/foo.bar/src/ClassName.php'</span>,
            <span>'/vendor/foo.bar/src/DoomClassName.php'</span>,
            <span>'/vendor/foo.bar/tests/ClassNameTest.php'</span>,
            <span>'/vendor/foo.bardoom/src/ClassName.php'</span>,
            <span>'/vendor/foo.bar.baz.dib/src/ClassName.php'</span>,
            <span>'/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php'</span>,
        ));

        <span>$this</span>->loader->addNamespace(
            <span>'Foo\Bar'</span>,
            <span>'/vendor/foo.bar/src'</span>
        );

        <span>$this</span>->loader->addNamespace(
            <span>'Foo\Bar'</span>,
            <span>'/vendor/foo.bar/tests'</span>
        );

        <span>$this</span>->loader->addNamespace(
            <span>'Foo\BarDoom'</span>,
            <span>'/vendor/foo.bardoom/src'</span>
        );

        <span>$this</span>->loader->addNamespace(
            <span>'Foo\Bar\Baz\Dib'</span>,
            <span>'/vendor/foo.bar.baz.dib/src'</span>
        );

        <span>$this</span>->loader->addNamespace(
            <span>'Foo\Bar\Baz\Dib\Zim\Gir'</span>,
            <span>'/vendor/foo.bar.baz.dib.zim.gir/src'</span>
        );
    }

    <span>public</span><span><span>function</span><span>testExistingFile</span><span>()</span>
    {</span><span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\Bar\ClassName'</span>);
        <span>$expect</span> = <span>'/vendor/foo.bar/src/ClassName.php'</span>;
        <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>);

        <span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\Bar\ClassNameTest'</span>);
        <span>$expect</span> = <span>'/vendor/foo.bar/tests/ClassNameTest.php'</span>;
        <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>);
    }

    <span>public</span><span><span>function</span><span>testMissingFile</span><span>()</span>
    {</span><span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'No_Vendor\No_Package\NoClass'</span>);
        <span>$this</span>->assertFalse(<span>$actual</span>);
    }

    <span>public</span><span><span>function</span><span>testDeepFile</span><span>()</span>
    {</span><span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\Bar\Baz\Dib\Zim\Gir\ClassName'</span>);
        <span>$expect</span> = <span>'/vendor/foo.bar.baz.dib.zim.gir/src/ClassName.php'</span>;
        <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>);
    }

    <span>public</span><span><span>function</span><span>testConfusion</span><span>()</span>
    {</span><span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\Bar\DoomClassName'</span>);
        <span>$expect</span> = <span>'/vendor/foo.bar/src/DoomClassName.php'</span>;
        <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>);

        <span>$actual</span> = <span>$this</span>->loader->loadClass(<span>'Foo\BarDoom\ClassName'</span>);
        <span>$expect</span> = <span>'/vendor/foo.bardoom/src/ClassName.php'</span>;
        <span>$this</span>->assertSame(<span>$expect</span>, <span>$actual</span>);
    }
}</span></code>
登入後複製

以上就介绍了PSR-4 实例,包括了方面的内容,希望对PHP教程有兴趣的朋友有所帮助。

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Win11 Xbox Game Bar怎麼會徹底卸載?分享Xbox Game Bar卸載方法 Win11 Xbox Game Bar怎麼會徹底卸載?分享Xbox Game Bar卸載方法 Feb 10, 2024 am 09:21 AM

Win11XboxGameBar怎麼徹底卸載? XboxGameBar是系統中自帶的遊戲平台,它提供了用於遊戲錄製、截圖和社交功能的工具,不過很是佔用內存,也不好卸載,一些小伙伴想要將它卸載掉,但是不這道怎麼徹底卸載,下面就來為大家介紹一下。方法一、使用Windows終端機1、按【Win+X】組合鍵,或【右鍵】點選工作列上的【Windows開始功能表】,在開啟的的選單項目中,選擇【終端機管理員】。 2.用戶帳戶控制窗口,你要允許此應用程式對你的設備進行更改嗎?點選【是】。 3、執行以下指令:Get-AppxP

Python中的class類別和method方法的使用方法 Python中的class類別和method方法的使用方法 Apr 21, 2023 pm 02:28 PM

類別和方法的概念和實例類別(Class):用來描述具有相同的屬性和方法的物件的集合。它定義了該集合中每個物件所共有的屬性和方法。物件是類別的實例。方法:類別中定義的函數。類別的建構方法__init__():類別有一個名為init()的特殊方法(建構方法),該方法在類別實例化時會自動呼叫。實例變數:在類別的宣告中,屬性是用變數來表示的,這種變數就稱為實例變量,實例變數就是用self修飾的變數。實例化:建立一個類別的實例,類別的具體物件。繼承:即一個派生類別(derivedclass)繼承基底類別(baseclass)的

python中class是什麼意思 python中class是什麼意思 May 21, 2019 pm 05:10 PM

class是python中的一個關鍵字,用來定義一個類,定義類別的方法:class後面加一個空格然後加類名;類名規則:首字母大寫,如果多個單字用駝峰命名法,如【class Dog()】。

使用jQuery替換元素的class名稱 使用jQuery替換元素的class名稱 Feb 24, 2024 pm 11:03 PM

jQuery是一種經典的JavaScript庫,被廣泛應用於網頁開發中,它簡化了在網頁上處理事件、操作DOM元素和執行動畫等操作。在使用jQuery時,常會遇到需要取代元素的class名稱的情況,本文將介紹一些實用的方法,以及具體的程式碼範例。 1.使用removeClass()和addClass()方法jQuery提供了removeClass()方法來刪除

PHP Class用法詳解:讓你的程式碼更清楚易讀 PHP Class用法詳解:讓你的程式碼更清楚易讀 Mar 10, 2024 pm 12:03 PM

在編寫PHP程式碼時,使用類別(Class)是一個非常常見的做法。透過使用類,我們可以將相關的功能和資料封裝在一個單獨的單元中,使程式碼更加清晰、易於閱讀和易於維護。本文將詳細介紹PHPClass的用法,並提供具體的程式碼範例,幫助讀者更好地理解如何在實際專案中應用類別來優化程式碼。 1.建立和使用類別在PHP中,可以使用關鍵字class來定義一個類,並在類別中定義屬性和方法。

「Touch ID 登入」卡在 Mac Touch Bar 上?這是修復 「Touch ID 登入」卡在 Mac Touch Bar 上?這是修復 Apr 15, 2023 pm 12:04 PM

使用Safari圖示修復MacTouchBar上的「TouchID登入」問題強制觸控列重新啟動將解決此問題:在Mac上開啟ActivityMonitor,它位於/Applications/Utilities資料夾中,或者您可以使用Spotlight透過按Command+空白鍵並鍵入ActivityMonitor並返回來啟動它使用活動監視器的搜尋功能並蒐索“觸摸”選擇“TouchBarServer”,然後單擊活動監視器工具列中的(X)退出按鈕選擇“強制退出”以強制

Vue報錯:無法正確使用v-bind綁定class和style,怎麼解決? Vue報錯:無法正確使用v-bind綁定class和style,怎麼解決? Aug 26, 2023 pm 10:58 PM

Vue報錯:無法正確使用v-bind綁定class和style,怎麼解決?在Vue開發中,我們常常會用到v-bind指令來動態綁定class和style,但是有時候我們可能會遇到一些問題,如無法正確使用v-bind綁定class和style。在本篇文章中,我將為你解釋這個問題的原因,並提供解決方案。首先,讓我們先來了解v-bind指令。 v-bind用於將V

jquery怎麼判斷元素是否有class jquery怎麼判斷元素是否有class Mar 21, 2023 am 10:47 AM

jquery判斷元素是否有class的方法:1、透過「hasClass('classname')」方法判斷元素是否具有某個class;2、透過「is('.classname')」方法判斷元素是否具有某個class。

See all articles