วิธีการตั้งค่า Facades ใน Laravel 5.2 (นอก /app)

ฉันถาม/ตอบเพราะฉันมีปัญหาอย่างมากในการทำงานนี้ และฉันต้องการแสดงการใช้งาน ทีละขั้นตอน

อ้างอิง:


person Martin    schedule 25.02.2016    source แหล่งที่มา


คำตอบ (1)


นี่อาจไม่ใช่วิธี เดียว ในการใช้งานส่วนหน้าใน Laravel 5 แต่นี่คือ วิธีที่ฉันทำ

เราจะสร้างส่วนหน้า Foo ที่กำหนดเองซึ่งมีอยู่ในเนมสเปซ Foobar

1. สร้างคลาสที่กำหนดเอง

ก่อนอื่น สำหรับตัวอย่างนี้ ฉันจะสร้างโฟลเดอร์ใหม่ในโครงการของฉัน โดยจะมี เนมสเปซ ของตัวเอง ซึ่งจะทำให้ค้นหาได้ง่ายขึ้น

ในกรณีของฉัน ไดเร็กทอรีชื่อ Foobar:

ป้อนคำอธิบายรูปภาพที่นี่

ในที่นี้ เราจะสร้างไฟล์ PHP ใหม่พร้อมคำจำกัดความของคลาสของเรา ในกรณีของฉัน ฉันเรียกมันว่า Foo.php

<?php
// %LARAVEL_ROOT%/Foobar/Foo.php

namespace Foobar;


class Foo
{
    public function Bar()
    {
        return 'got it!';
    }
}

2. สร้างคลาสส่วนหน้า

ในโฟลเดอร์ใหม่ของเรา เราสามารถเพิ่มไฟล์ PHP ใหม่สำหรับส่วนหน้าของเราได้ ฉันจะเรียกมันว่า FooFacade.php และฉันจะวางมันไว้ในเนมสเปซอื่นที่เรียกว่า Foobar\Facades โปรดจำไว้ว่าเนมสเปซในกรณีนี้ไม่ได้สะท้อนถึงโครงสร้างโฟลเดอร์!

<?php
// %LARAVEL_ROO%/Foobar/FooFacade.php

namespace Foobar\Facades;


use Illuminate\Support\Facades\Facade;

class Foo extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'foo'; // Keep this in mind
    }
}
  • โปรดจำไว้ว่าสิ่งที่คุณส่งคืนใน getFacadeAccessor เนื่องจากคุณจะต้องการสิ่งนั้นในอีกสักครู่

โปรดทราบว่าคุณกำลังขยายคลาส Facade ที่มีอยู่ที่นี่

3. สร้างผู้ให้บริการใหม่โดยใช้ php artisan

ตอนนี้เราต้องการผู้ให้บริการรายใหม่ที่หรูหรา โชคดีที่เรามีเครื่องมือ artisan ที่ยอดเยี่ยม ในกรณีของฉัน ฉันจะเรียกมันว่า FooProvider

php artisan make:provider FooProvider

แบม! เรามีผู้ให้บริการแล้ว อ่านเพิ่มเติมเกี่ยวกับผู้ให้บริการที่นี่ สำหรับตอนนี้ โปรดทราบว่ามีสองฟังก์ชัน (boot และ register ) และเราจะเพิ่มโค้ดบางส่วนไปที่ register เราจะผูก ผู้ให้บริการรายใหม่ของเรา แอปของเรา:

$this->app->bind('foo', function () {
    return new Foo; //Add the proper namespace at the top
});

ดังนั้นส่วน bind('foo' นี้จะตรงกับสิ่งที่คุณใส่ไว้ในโค้ด FooFacade.php ของคุณ ที่ฉันพูดว่า return 'foo'; ก่อนหน้านี้ ฉันต้องการให้การเชื่อมโยงนี้ตรงกับสิ่งนั้น (ถ้าฉันจะบอกว่า return 'wtv'; ฉันจะบอกว่า bind('wtv', ที่นี่)

นอกจากนี้ เราต้องบอก Laravel ว่าจะหา Foo ได้ที่ไหน!

ที่ด้านบนเราเพิ่มเนมสเปซ

use \Foobar\Foo;

ตรวจสอบไฟล์ทั้งหมดทันที:

<?php
// %LARAVEL_ROOT%/app/Providers/FooProvider.php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Foobar\Foo;

class FooProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('foo', function () {
            return new Foo;
        });
    }
}
  • ตรวจสอบให้แน่ใจว่าคุณใช้ Foobar\Foo และไม่ใช่ Foobar\Facades\Foo - IDE ของคุณอาจแนะนำให้กรอกผิด

4. เพิ่มข้อมูลอ้างอิงของเราไปที่ config/app.php

ตอนนี้เราต้องบอก Laravel ว่าเราสนใจที่จะใช้ไฟล์สุ่มเหล่านี้ที่เราเพิ่งสร้างขึ้น และเราสามารถทำได้ในไฟล์ config/app.php ของเรา

  1. เพิ่มการอ้างอิงคลาสผู้ให้บริการของคุณไปที่ 'providers': App\Providers\FooProvider::class

  2. เพิ่มการอ้างอิงคลาสส่วนหน้าของคุณไปที่ 'aliases': 'Foo' => Foobar\Facades\Foo::class

โปรดจำไว้ว่า ใน นามแฝง ที่ฉันเขียน 'Foo' คุณจะต้องใส่ชื่อที่คุณต้องการอ้างอิงส่วนหน้าของคุณที่นั่น ดังนั้นหากคุณต้องการใช้ MyBigOlFacade::helloWorld() รอบๆ แอปของคุณ คุณจะต้องขึ้นต้นบรรทัดนั้นด้วย 'MyBigOlFacade' => MyApp\WhereEverMyFacadesAre\MyBigOlFacade::class

5. อัปเดต composer.json ของคุณ

การเปลี่ยนแปลงโค้ดครั้งสุดท้ายที่คุณควรต้องมีคือการอัปเดตช่องว่าง psr-4 ของ composer.json . คุณจะต้องเพิ่มสิ่งนี้:

    "psr-4": {
        "Foobar\\" : "Foobar/",
        // Whatever you had already can stay
    }

การย้ายครั้งสุดท้าย

เอาล่ะ ตอนนี้คุณได้เปลี่ยนแปลงทุกอย่างแล้ว สิ่งสุดท้ายที่คุณต้องมีคือการรีเฟรชแคชทั้งในผู้แต่งและช่างฝีมือ ลองสิ่งนี้:

composer dumpautoload
php artisan cache:clear

การใช้งานและการทดสอบอย่างรวดเร็ว:

สร้างเส้นทางใน app/routes.php:

Route::get('/foobar', 'FooBarController@testFoo');

จากนั้นจึงวิ่ง

php artisan make:controller FooBarController

และเพิ่มโค้ดบางส่วนเพื่อให้มีลักษณะดังนี้:

<?php

namespace App\Http\Controllers;

use Foobar\Facades\Foo;

use App\Http\Requests;

class FooBarController extends Controller
{
    public function testFoo()
    {
        dd(Foo::Bar());
    }
}

คุณควรลงท้ายด้วยสตริงต่อไปนี้:

ป้อนคำอธิบายรูปภาพที่นี่


การแก้ไขปัญหา

  • หากคุณพบข้อผิดพลาดและแจ้งว่าไม่พบคลาส Foobar\Facades\Foo ให้ลองเรียกใช้ php artisan optimize
person Martin    schedule 25.02.2016
comment
ได้โปรด! หากคุณใช้คู่มือนี้และมีบางอย่างใช้งานไม่ได้ โปรดแจ้งให้เราทราบเพื่อเราจะได้แก้ไข! - person Martin; 26.02.2016
comment
อีกประการหนึ่ง ฉันละเว้นการล้างแคชและ Laravel ส่งข้อผิดพลาด Class not found ให้ฉัน ดังนั้นฉันจึงรันคำสั่ง php artisan Optimize และทุกอย่างทำงานได้ - person IlGala; 01.03.2016
comment
ขอบคุณ @IlGala ฉันได้ทำการแก้ไขบางอย่าง รวมถึงตัวชี้เกี่ยวกับการใช้คำสั่ง artisan optimize - person Martin; 02.03.2016
comment
การใช้ Foobar\Join; คืออะไร? และน่าเสียดายที่ทั้งหมดที่ฉันได้รับเมื่อผลลัพธ์สุดท้ายคือ Class 'Foobar\Facades\Foo' not found ทำตามคำแนะนำในจดหมาย - person Jiho Kang; 23.08.2016
comment
ฉันเปลี่ยนชื่อชั้นเรียนของฉันก่อนที่จะใส่ไว้ใน SO สงสัยลืมเปลี่ยนชื่อคลาสซะล่ะ! ฉันคิดว่ามันควรอ่านว่า Foobar\Foo - person Martin; 23.08.2016