服务容器
你的程序 全部是 各有用途的对象: 一个 "Mailer" 对象可以帮助你发送邮件,而另一个对象可以帮你把数据入库。 你程序中的几乎 所有 事都是由这些对象中的某一个来完成的。每当你安装一个新bundle,你就拥有了更多的对象!
In Symfony, these useful objects are called services and each service lives inside a very special object called the service container. If you have the service container, then you can fetch a service by using that service's id:
1 2 |
$logger = $container->get('logger');
$entityManager = $container->get('doctrine.orm.entity_manager'); |
The container allows you to centralize the way objects are constructed. It makes your life easier, promotes a strong architecture and is super fast!
取得并使用服务 ¶
The moment you start a Symfony app, your container already contains many services. These are like tools: waiting for you to take advAntage of them. In your controller, you can "ask" for a service from the container by type-hinting an argument with the service's class or interface name. Want to log something? No problem:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// src/AppBundle/Controller/ProductController.php
// ...
use Psr\Log\LoggerInterface;
/**
* @Route("/products")
*/
public function listAction(LoggerInterface $logger)
{
$logger->info('Look! I just used a service');
// ...
} |
3.3 New in version 3.3: The ability to type-hint a service in order to receive it was added in Symfony 3.3. See the controller chapter for more details.
What other services are available? Find out by running:
1 |
php bin/console debug:container |
This is just a small sample of the output:
Service ID | Class name |
---|---|
doctrine | Doctrine\Bundle\DoctrineBundle\Registry |
filesystem | Symfony\Component\Filesystem\Filesystem |
form.factory | Symfony\Component\Form\FormFactory |
logger | Symfony\Bridge\Monolog\Logger |
request_stack | Symfony\Component\Httpfoundation\RequestStack |
router | Symfony\Bundle\FrameworkBundle\Routing\Router |
security.authorization_checker | Symfony\Component\Security\Core\Authorization\AuthorizationChecker |
security.password_encoder | Symfony\Component\Security\Core\Encoder\UserPasswordEncoder |
session | Symfony\Component\HttpFoundation\Session\Session |
translator | Symfony\Component\Translation\DataCollectorTranslator |
twig | Twig_Environment |
validator | Symfony\Component\Validator\Validator\ValidatorInterface |
You can also use the unique "Service ID" to access a service directly:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// src/AppBundle/Controller/ProductController.php
namespace AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ProductController extends Controller
{
/**
* @Route("/products")
*/
public function listAction()
{
$logger = $this->container->get('logger');
$logger->info('Look! I just used a service');
// ...
}
} |
Fetching a service directly from the container
like this only works if you extend the Controller
class.
Throughout the docs, you'll see how to use the many different services that live in the container.
在容器中创建/配置服务 ¶
Tip
The recommended way of configuring services changed in Symfony 3.3. For a deep explanation, see The Symfony 3.3 DI Container Changes Explained (autowiring, _defaults, etc).
You can also organize your own code into services. For example, suppose you need to show your users a ranDOM, happy message. If you put this code in your controller, it can't be re-used. Instead, you decide to create a new class:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
// src/AppBundle/Service/MessageGenerator.php
namespace AppBundle\Service;
class MessageGenerator
{
public function getHappyMessage()
{
$messages = [
'You did it! You updated the system! Amazing!',
'That was one of the coolest updates I\'ve seen all day!',
'Great work! Keep going!',
];
$index = array_rand($messages);
return $messages[$index];
}
} |