Laravel Contracts Conceptual Analysis and Code Samples

Introduction to Contracts

Laravel's Contract Contracts are a set of interfaces and a specification for code implementation.The Laravel Framework Core Service provides many Contracts, such as IlluminateContracts\Logging\LoggingLogging, which defines the method required to log. The framework itself has corresponding implementations for Contracts, such as IlluminateContracts\Cache\Factory and IlluminateContracts\Cache\Repository Laravel Cache Services, which provide access to the cache service, while FactoryContract provides access to all cache drivers for your application, and Repository contract is a typical cache-driven implementation that changes depending on your cache profile.

Definition

Just now we said that Contracts is an interface, so we first define the USB interface, then define both Flash and Print to implement this interface (in order to facilitate the implementation of the internal interface specification).

  • Define an interface

    namespace App\Contracts;
    
    interface USB{
    
        public function start();
    
        public function stop();
    
    }
    
  • Implement this interface

    namespace App\Contracts\Support;
    
    use App\Contracts\USB;
    
    class Flash implements USB{
    
        public function start()
        {
            return 'U Disk Open Work';
        }
        public function stop()
        {
            return 'U Disk End Work';
        }
    }
    
    namespace App\Contracts\Support;
    
    use App\Contracts\USB;
    
    class Printer implements USB{
    
        public function start()
        {
            return 'Printer on';
        }
        public function stop()
        {
            return 'Printer End of Work';
        }
    }
    

Use

  • Instead of Facades, use type prompts and resolve Contracts within the service container.

    Many classes in Laravel are resolved through service containers, including controllers, event listeners, middleware, queue tasks, and even routing closures.Contracts also need to be bound to service containers for resolution.

    Automatically parse and inject services through type hints (Type Hint,php official translated as type constraints) of interfaces, as needed:

    $this->app->bind(\App\Contracts\Support\USB::class,\App\Contracts\Support\Flash::class);
    

    Note: PHP 5 can use type constraints, function parameters can specify that they must be objects (specify the name of the class inside the function prototype), interfaces, arrays (starting with PHP 5.1).

    As above, binding an interface to an instance automatically resolves to only one instance, that is, the instance you bind to. Now we have two implementation classes (Flash and Printer) that want to bind to the USB interface, that is, different classes, the constructor constrains the same interface by type, injects different instances, which can be used at this time (Context Binding, Context Binding)Binding).

    Files in the App\Providers directory can only be injected into containers in the register method of the file. AppServiceProvider is used here, but you can also create a service provider separately (inherit the ServiceProvider and write the file into the config/app.php configuration array providers)

    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    
    class AppServiceProvider extends ServiceProvider
    {
        /**
         * Bootstrap any application services.
         *
         * @return void
         */
        public function boot()
        {
            //
        }
    
        /**
         * Register any application services.
         *
         * @return void
         */
        public function register()
        {
            $this->app->when(\App\Http\Controllers\TestFlashController::class)
                ->needs(\App\Contracts\USB::class)
                ->give(\App\Contracts\Support\Flash::class);
            $this->app->when(\App\Http\Controllers\TestPrinterController::class)
                ->needs(\App\Contracts\USB::class)
                ->give(\App\Contracts\Support\Printer::class);
        }
    
    }
    
  • Instead of Facades, we use Type Constraints to resolve classes in the class constructor.

    Flash implementation test class:

    namespace App\Http\Controllers;
    
    use App\Contracts\USB;
    
    class TestFlashController extends Controller
    {
    
        public function __construct(USB $flash){
            $this->flash = $flash;
        }
    
        public function flash(){
            return $this->flash->start();
        }
    
    }
    

    Printer implements the test class:

    namespace App\Http\Controllers;
    
    use App\Contracts\USB;
    
    class TestPrinterController extends Controller
    {
    
        public function __construct(USB $printer){
            $this->printer = $printer;
        }
    
        public function printer(){
            return $this->printer->start();
        }
    
    }
    

    Bind our routes

    Route::get('test/flash', 'TestFlashController@flash');
    Route::get('test/printer', 'TestPrinterController@printer');
    
  • test result

    • index.php/test/flash

      U disk open operation

    • index.php/test/printer

      Printer on

Keywords: Programming PHP Laravel

Added by andychurchill on Sat, 11 Apr 2020 04:52:21 +0300