支付宝扫一扫付款
微信扫一扫付款
(微信为保护隐私,不显示你的昵称)
你的程序 全部是 各有用途的对象: 一个 "Mailer" 对象可以帮助你发送邮件,而另一个对象可以帮你把数据入库。 你程序中的几乎 所有 事都是由这些对象中的某一个来完成的。每当你安装一个新bundle,你就拥有了更多的对象!
在Symfony中,这些有用的对象被称为 services(服务),每一个服务都被存放于一个特殊的名为 service container(服务容器)之中。如果你有服务容器,那么你可以使用服务的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];
}
} |
本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。