title |
---|
Dependency Container |
The RawPHP service container is a powerful tool for managing class dependencies and performing dependency injection. Dependency injection is a fancy phrase that essentially means this: class dependencies are "injected" into the class via the constructor or, in some cases, "setter" methods.
In the example below, the UserController
needs to retrieve users from a data source
, probably the database. So, we will inject a service that is able to retrieve users. In this context, our UserRepository most likely uses Eloquent to retrieve user information from the database. However, since the repository is injected, we are able to easily swap it out with another implementation. We are also able to easily "mock", or create a dummy implementation of the UserRepository when testing our application.
A deep understanding of the RawPHP service container is essential to building a powerful, large application, as well as for contributing to the Laravel core itself.
<?php
namespace App\Http\Controllers;
use App\User;
use App\Repositories\UserRepository;
use App\Http\Controllers\Controller;
class UserController extends Controller
{
/**
* The user repository implementation.
*
* @var UserRepository
*/
protected $users;
/**
* Create a new controller instance.
*
* @param UserRepository $users
* @return void
*/
public function __construct(UserRepository $users)
{
$this->users = $users;
}
/**
* Show the profile for the given user.
*
* @param int $id
* @return Response
*/
public function show($id)
{
$user = $this->users->find($id);
return view('user.profile', ['user' => $user]);
}
}
RawPHP uses a dependency container to prepare, manage, and inject application dependencies. RawPHP supports containers that implement the Container-Interop interface. You can use RawPHP's built-in container (based on Pimple) or third-party containers like Acclimate or PHP-DI.
You don't have to provide a dependency container. If you do, however, you must inject the container instance into the Slim application's constructor.
$container = new \Slim\Container;
$app = new \Slim\App($container);
Add a service to RawPHP container:
$container = $app->getContainer();
$container['myService'] = function ($container) {
$myService = new MyService();
return $myService;
};
You can fetch services from your container explicitly or implicitly. You can fetch an explicit reference to the container instance from inside a Slim application route like this:
/**
* Example GET route
*
* @param \Psr\Http\Message\ServerRequestInterface $req PSR7 request
* @param \Psr\Http\Message\ResponseInterface $res PSR7 response
* @param array $args Route parameters
*
* @return \Psr\Http\Message\ResponseInterface
*/
$app->get('/foo', function ($req, $res, $args) {
$myService = $this->get('myService');
return $res;
});
You can implicitly fetch services from the container like this:
/**
* Example GET route
*
* @param \Psr\Http\Message\ServerRequestInterface $req PSR7 request
* @param \Psr\Http\Message\ResponseInterface $res PSR7 response
* @param array $args Route parameters
*
* @return \Psr\Http\Message\ResponseInterface
*/
$app->get('/foo', function ($req, $res, $args) {
$myService = $this->myService;
return $res;
});
To test if a service exists in the container before using it, use the has()
method, like this:
/**
* Example GET route
*
* @param \Psr\Http\Message\ServerRequestInterface $req PSR7 request
* @param \Psr\Http\Message\ResponseInterface $res PSR7 response
* @param array $args Route parameters
*
* @return \Psr\Http\Message\ResponseInterface
*/
$app->get('/foo', function ($req, $res, $args) {
if($this->has('myService')) {
$myService = $this->myService;
}
return $res;
});
Slim uses __get()
and __isset()
magic methods that defer to the application's
container for all properties that do not already exist on the application instance.
Your container MUST implement these required services. If you use Slim's built-in container, these are provided for you. If you choose a third-party container, you must define these required services on your own.
settings : Associative array of application settings, including keys:
* `httpVersion`
* `responseChunkSize`
* `outputBuffering`
* `determineRouteBeforeAppMiddleware`.
* `displayErrorDetails`.
* `addContentLengthHeader`.
* `routerCacheFile`.
environment
: Instance of \Slim\Interfaces\Http\EnvironmentInterface
.
request
: Instance of \Psr\Http\Message\ServerRequestInterface
.
response
: Instance of \Psr\Http\Message\ResponseInterface
.
router
: Instance of \Slim\Interfaces\RouterInterface
.
foundHandler
: Instance of \Slim\Interfaces\InvocationStrategyInterface
.
phpErrorHandler
: Callable invoked if a PHP 7 Error is thrown. The callable MUST return an instance of \Psr\Http\Message\ResponseInterface
and accept three arguments:
\Psr\Http\Message\ServerRequestInterface
\Psr\Http\Message\ResponseInterface
\Error
errorHandler
: Callable invoked if an Exception is thrown. The callable MUST return an instance of \Psr\Http\Message\ResponseInterface
and accept three arguments:
\Psr\Http\Message\ServerRequestInterface
\Psr\Http\Message\ResponseInterface
\Exception
notFoundHandler
: Callable invoked if the current HTTP request URI does not match an application route. The callable MUST return an instance of \Psr\Http\Message\ResponseInterface
and accept two arguments:
\Psr\Http\Message\ServerRequestInterface
\Psr\Http\Message\ResponseInterface
notAllowedHandler
: Callable invoked if an application route matches the current HTTP request path but not its method. The callable MUST return an instance of \Psr\Http\Message\ResponseInterface
and accept three arguments:
\Psr\Http\Message\ServerRequestInterface
\Psr\Http\Message\ResponseInterface
- Array of allowed HTTP methods
callableResolver
: Instance of \Slim\Interfaces\CallableResolverInterface
.