PageRenderTime 62ms CodeModel.GetById 37ms RepoModel.GetById 1ms app.codeStats 0ms

/contracts.md

https://gitlab.com/roth1002/docs
Markdown | 188 lines | 147 code | 41 blank | 0 comment | 0 complexity | aea6fbf2e095320ff41314793a827344 MD5 | raw file
  1. # Contracts
  2. - [Introduction](#introduction)
  3. - [Why Contracts?](#why-contracts)
  4. - [Contract Reference](#contract-reference)
  5. - [How To Use Contracts](#how-to-use-contracts)
  6. <a name="introduction"></a>
  7. ## Introduction
  8. Laravel's Contracts are a set of interfaces that define the core services provided by the framework. For example, a `Illuminate\Contracts\Queue\Queue` contract defines the methods needed for queueing jobs, while the `Illuminate\Contracts\Mail\Mailer` contract defines the methods needed for sending e-mail.
  9. Each contract has a corresponding implementation provided by the framework. For example, Laravel provides a queue implementation with a variety of drivers, and a mailer implementation that is powered by [SwiftMailer](http://swiftmailer.org/).
  10. All of the Laravel contracts live in [their own GitHub repository](https://github.com/illuminate/contracts). This provides a quick reference point for all available contracts, as well as a single, decoupled package that may be utilized by package developers.
  11. ### Contracts Vs. Facades
  12. Laravel's [facades](/docs/{{version}}/facades) provide a simple way of utilizing Laravel's services without needing to type-hint and resolve contracts out of the service container. However, using contracts allows you to define explicit dependencies for your classes. For most applications, using a facade is just fine. However, if you really need the extra loose coupling that contracts can provide, keep reading!
  13. <a name="why-contracts"></a>
  14. ## Why Contracts?
  15. You may have several questions regarding contracts. Why use interfaces at all? Isn't using interfaces more complicated? Let's distil the reasons for using interfaces to the following headings: loose coupling and simplicity.
  16. ### Loose Coupling
  17. First, let's review some code that is tightly coupled to a cache implementation. Consider the following:
  18. <?php
  19. namespace App\Orders;
  20. class Repository
  21. {
  22. /**
  23. * The cache.
  24. */
  25. protected $cache;
  26. /**
  27. * Create a new repository instance.
  28. *
  29. * @param \SomePackage\Cache\Memcached $cache
  30. * @return void
  31. */
  32. public function __construct(\SomePackage\Cache\Memcached $cache)
  33. {
  34. $this->cache = $cache;
  35. }
  36. /**
  37. * Retrieve an Order by ID.
  38. *
  39. * @param int $id
  40. * @return Order
  41. */
  42. public function find($id)
  43. {
  44. if ($this->cache->has($id)) {
  45. //
  46. }
  47. }
  48. }
  49. In this class, the code is tightly coupled to a given cache implementation. It is tightly coupled because we are depending on a concrete Cache class from a package vendor. If the API of that package changes our code must change as well.
  50. Likewise, if we want to replace our underlying cache technology (Memcached) with another technology (Redis), we again will have to modify our repository. Our repository should not have so much knowledge regarding who is providing them data or how they are providing it.
  51. **Instead of this approach, we can improve our code by depending on a simple, vendor agnostic interface:**
  52. <?php
  53. namespace App\Orders;
  54. use Illuminate\Contracts\Cache\Repository as Cache;
  55. class Repository
  56. {
  57. /**
  58. * Create a new repository instance.
  59. *
  60. * @param Cache $cache
  61. * @return void
  62. */
  63. public function __construct(Cache $cache)
  64. {
  65. $this->cache = $cache;
  66. }
  67. }
  68. Now the code is not coupled to any specific vendor, or even Laravel. Since the contracts package contains no implementation and no dependencies, you may easily write an alternative implementation of any given contract, allowing you to replace your cache implementation without modifying any of your cache consuming code.
  69. ### Simplicity
  70. When all of Laravel's services are neatly defined within simple interfaces, it is very easy to determine the functionality offered by a given service. **The contracts serve as succinct documentation to the framework's features.**
  71. In addition, when you depend on simple interfaces, your code is easier to understand and maintain. Rather than tracking down which methods are available to you within a large, complicated class, you can refer to a simple, clean interface.
  72. <a name="contract-reference"></a>
  73. ## Contract Reference
  74. This is a reference to most Laravel Contracts, as well as their Laravel "facade" counterparts:
  75. Contract | References Facade
  76. ------------- | -------------
  77. [Illuminate\Contracts\Auth\Guard](https://github.com/illuminate/contracts/blob/master/Auth/Guard.php) | Auth
  78. [Illuminate\Contracts\Auth\PasswordBroker](https://github.com/illuminate/contracts/blob/master/Auth/PasswordBroker.php) | Password
  79. [Illuminate\Contracts\Bus\Dispatcher](https://github.com/illuminate/contracts/blob/master/Bus/Dispatcher.php) | Bus
  80. [Illuminate\Contracts\Broadcasting\Broadcaster](https://github.com/illuminate/contracts/blob/master/Broadcasting/Broadcaster.php) | &nbsp;
  81. [Illuminate\Contracts\Cache\Repository](https://github.com/illuminate/contracts/blob/master/Cache/Repository.php) | Cache
  82. [Illuminate\Contracts\Cache\Factory](https://github.com/illuminate/contracts/blob/master/Cache/Factory.php) | Cache::driver()
  83. [Illuminate\Contracts\Config\Repository](https://github.com/illuminate/contracts/blob/master/Config/Repository.php) | Config
  84. [Illuminate\Contracts\Container\Container](https://github.com/illuminate/contracts/blob/master/Container/Container.php) | App
  85. [Illuminate\Contracts\Cookie\Factory](https://github.com/illuminate/contracts/blob/master/Cookie/Factory.php) | Cookie
  86. [Illuminate\Contracts\Cookie\QueueingFactory](https://github.com/illuminate/contracts/blob/master/Cookie/QueueingFactory.php) | Cookie::queue()
  87. [Illuminate\Contracts\Encryption\Encrypter](https://github.com/illuminate/contracts/blob/master/Encryption/Encrypter.php) | Crypt
  88. [Illuminate\Contracts\Events\Dispatcher](https://github.com/illuminate/contracts/blob/master/Events/Dispatcher.php) | Event
  89. [Illuminate\Contracts\Filesystem\Cloud](https://github.com/illuminate/contracts/blob/master/Filesystem/Cloud.php) | &nbsp;
  90. [Illuminate\Contracts\Filesystem\Factory](https://github.com/illuminate/contracts/blob/master/Filesystem/Factory.php) | File
  91. [Illuminate\Contracts\Filesystem\Filesystem](https://github.com/illuminate/contracts/blob/master/Filesystem/Filesystem.php) | File
  92. [Illuminate\Contracts\Foundation\Application](https://github.com/illuminate/contracts/blob/master/Foundation/Application.php) | App
  93. [Illuminate\Contracts\Hashing\Hasher](https://github.com/illuminate/contracts/blob/master/Hashing/Hasher.php) | Hash
  94. [Illuminate\Contracts\Logging\Log](https://github.com/illuminate/contracts/blob/master/Logging/Log.php) | Log
  95. [Illuminate\Contracts\Mail\MailQueue](https://github.com/illuminate/contracts/blob/master/Mail/MailQueue.php) | Mail::queue()
  96. [Illuminate\Contracts\Mail\Mailer](https://github.com/illuminate/contracts/blob/master/Mail/Mailer.php) | Mail
  97. [Illuminate\Contracts\Queue\Factory](https://github.com/illuminate/contracts/blob/master/Queue/Factory.php) | Queue::driver()
  98. [Illuminate\Contracts\Queue\Queue](https://github.com/illuminate/contracts/blob/master/Queue/Queue.php) | Queue
  99. [Illuminate\Contracts\Redis\Database](https://github.com/illuminate/contracts/blob/master/Redis/Database.php) | Redis
  100. [Illuminate\Contracts\Routing\Registrar](https://github.com/illuminate/contracts/blob/master/Routing/Registrar.php) | Route
  101. [Illuminate\Contracts\Routing\ResponseFactory](https://github.com/illuminate/contracts/blob/master/Routing/ResponseFactory.php) | Response
  102. [Illuminate\Contracts\Routing\UrlGenerator](https://github.com/illuminate/contracts/blob/master/Routing/UrlGenerator.php) | URL
  103. [Illuminate\Contracts\Support\Arrayable](https://github.com/illuminate/contracts/blob/master/Support/Arrayable.php) | &nbsp;
  104. [Illuminate\Contracts\Support\Jsonable](https://github.com/illuminate/contracts/blob/master/Support/Jsonable.php) | &nbsp;
  105. [Illuminate\Contracts\Support\Renderable](https://github.com/illuminate/contracts/blob/master/Support/Renderable.php) | &nbsp;
  106. [Illuminate\Contracts\Validation\Factory](https://github.com/illuminate/contracts/blob/master/Validation/Factory.php) | Validator::make()
  107. [Illuminate\Contracts\Validation\Validator](https://github.com/illuminate/contracts/blob/master/Validation/Validator.php) | &nbsp;
  108. [Illuminate\Contracts\View\Factory](https://github.com/illuminate/contracts/blob/master/View/Factory.php) | View::make()
  109. [Illuminate\Contracts\View\View](https://github.com/illuminate/contracts/blob/master/View/View.php) | &nbsp;
  110. <a name="how-to-use-contracts"></a>
  111. ## How To Use Contracts
  112. So, how do you get an implementation of a contract? It's actually quite simple.
  113. Many types of classes in Laravel are resolved through the [service container](/docs/{{version}}/container), including controllers, event listeners, middleware, queued jobs, and even route Closures. So, to get an implementation of a contract, you can just "type-hint" the interface in the constructor of the class being resolved.
  114. For example, take a look at this event listener:
  115. <?php
  116. namespace App\Listeners;
  117. use App\User;
  118. use App\Events\NewUserRegistered;
  119. use Illuminate\Contracts\Redis\Database;
  120. class CacheUserInformation
  121. {
  122. /**
  123. * The Redis database implementation.
  124. */
  125. protected $redis;
  126. /**
  127. * Create a new event handler instance.
  128. *
  129. * @param Database $redis
  130. * @return void
  131. */
  132. public function __construct(Database $redis)
  133. {
  134. $this->redis = $redis;
  135. }
  136. /**
  137. * Handle the event.
  138. *
  139. * @param NewUserRegistered $event
  140. * @return void
  141. */
  142. public function handle(NewUserRegistered $event)
  143. {
  144. //
  145. }
  146. }
  147. When the event listener is resolved, the service container will read the type-hints on the constructor of the class, and inject the appropriate value. To learn more about registering things in the service container, check out [its documentation](/docs/{{version}}/container).