一直对symfony的几个配置文件有些疑问,尤其在使用的时候,今天特意记录一下:
Symfony应用程序是通过存储在config/目录下的文件来配置的,该目录的默认结构如下:
your-project/
├─ config/
│ ├─ packages/
│ ├─ bundles.php
│ ├─ routes.yaml
│ └─ services.yaml
routes.yaml文件定义了路由配置;
services.yaml文件配置了服务容器的服务;
bundles.php文件在你的应用程序中启用/禁用包;
config/packages/目录存储了你的应用程序中安装的每个包的配置。
Packages(在Symfony中也称为 "捆绑",在其他项目中称为 "插件/模块")为你的项目添加随时可用的功能
①环境变量
dev用于本地开发、
prod用于生产服务器、
test用于自动测试。
当运行应用程序时,Symfony按照这个顺序加载配置文件(最后一个文件可以覆盖前面的文件中设置的值):
config/packages/*.<extension>中的文件;
config/packages/<environment-name>/*.<extension>中的文件;
config/services.<extension>;
config/services_<environment-name>.<extension>。
如果你需要覆盖一个环境值(例如,在你的本地机器上覆盖一个不同的值),你可以在一个.env.local文件中完成:
# .env.local
DATABASE_URL="mysql://root:@127.0.0.1:3306/my_database_name"
这个文件应该被git忽略,也不应该被提交到你的版本库。其他几个.env文件可以在适当的情况下设置环境变量:
.env:定义了应用程序所需的环境变量的默认值;
.env.local: 覆盖所有环境的默认值,但只在包含该文件的机器上。这个文件不应该被提交到版本库,在测试环境中被忽略(因为测试应该对每个人产生相同的结果);
.env.<environment> (e.g. .env.test): 只在一个环境中覆盖环境变量,但在所有机器上(这些文件被提交);
.env.<environment>.local (e.g. .env.test.local): 只为一个环境定义特定机器的环境变量覆盖。它类似于.env.local,但这些覆盖只适用于一个环境。
在生产中,.env文件也会在每个请求中被解析和加载。因此,定义环境变量的最简单方法是在你的生产服务器上创建一个.env.local文件,其中包含你的生产值,为了提高性能,你可以选择运行dump-env命令事实上:
$ composer dump-env
Successfully dumped .env files in .env.local.php
运行这个命令后,Symfony会加载.env.local.php文件来获取环境变量,不会花时间解析.env文件。
②列出环境变量
$ php bin/console debug:dotenv
Dotenv Variables & Files
========================
Scanned Files (in descending priority)
--------------------------------------
* ⨯ .env.local.php
* ⨯ .env.dev.local
* ⨯ .env.dev
* ✓ .env.local
* ✓ .env
Variables
---------
------------------------- ------------------------------------------------------------------------------ ----------------------------------- -----------------------------------
Variable Value .env.local .env
------------------------- ------------------------------------------------------------------------------ ----------------------------------- -----------------------------------
DUOXAIO_DOMAIN DUOXAIO.web.test DUOXAIO.web.test
DUOXAIO_SCHEME http http
APP_ENV dev dev dev
APP_SECRET ThisTokenIsNotSoSecretChangeIt ThisTokenIsNotSoSecretChangeIt... d6edd2e553f701556efbea65e8d868...
DATABASE_URL mysql://root:123456@127.0.0.1:3306/DUOXAIO?serverVersion=8.0&charset=utf8mb4 mysql://root:123456@127.0.0.1:... mysql://app:!ChangeMe!@127.0.0...
FFMPEG_BINARY_PATH /usr/bin/ffmpeg /usr/bin/ffmpeg
FFPROBE_BINARY_PATH /usr/bin/ffprobe /usr/bin/ffprobe
IDP_SCHEME http http
IDP_URL qinhong.login.test qinhong.login.test
MAILER_DSN smtp://localhost:1025 smtp://localhost:1025 null://null
qinhong_LOGIN_HOST qinhong.login.test qinhong.login.test
MESSENGER_TRANSPORT_DSN redis://localhost:6379/messages redis://localhost:6379/message... doctrine://default?auto_setup=...
SSO_SERVICE DUOXAIO DUOXAIO
USER_LOGIN_AUTHORITY DUOXAIO DUOXAIO DUOXAIO
USER_LOGIN_KEY DUOXAIO DUOXAIO DUOXAIO
------------------------- ------------------------------------------------------------------------------ ----------------------------------- -----------------------------------
// Note real values might be different between web and CLI.
③此外,无论你如何设置环境变量,你都可以看到Symfony的容器配置中引用的所有环境变量及其值
$ php bin/console debug:container --env-vars
Symfony Container Environment Variables
=======================================
------------------------- ------------------ --------------------------------------------------------------------------------
Name Default value Real value
------------------------- ------------------ --------------------------------------------------------------------------------
DUOXAIO_DOMAIN n/a "DUOXAIO.web.test"
DUOXAIO_SCHEME n/a "http"
APP_SECRET n/a "ThisTokenIsNotSoSecretChangeIt"
DATABASE_URL n/a "mysql://root:123456@127.0.0.1:3306/DUOXAIO?serverVersion=8.0&charset=utf8mb4"
FFMPEG_BINARY_PATH n/a "/usr/bin/ffmpeg"
FFPROBE_BINARY_PATH n/a "/usr/bin/ffprobe"
IDP_SCHEME n/a "http"
IDP_URL n/a "qinhong.login.test"
MAILER_DSN n/a "smtp://localhost:1025"
QINGHONG_LOGIN_HOST n/a "qinhong.login.test"
MESSENGER_TRANSPORT_DSN n/a "redis://localhost:6379/messages"
SSO_SERVICE n/a "DUOXAIO"
USER_LOGIN_AUTHORITY n/a "DUOXAIO"
USER_LOGIN_KEY n/a "DUOXAIO"
VAR_DUMPER_SERVER "127.0.0.1:9912" n/a
------------------------- ------------------ --------------------------------------------------------------------------------
// Note real values might be different between web and CLI
④运行下面的命令可以看到你的应用程序中存在的所有参数
$ php bin/console debug:container --parameters
Symfony Container Parameters
============================
----------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
Parameter Value
----------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
DUOXAIO_domain %env(DUOXAIO_DOMAIN)%
DUOXAIO_scheme %env(DUOXAIO_SCHEME)%
asset.request_context.base_path null
asset.request_context.secure null
cache.prefix.seed _/home/qinhong/code/DUOXAIO.App_KernelDevDebugContainer
central_dms_dir /var/www/dms/
console.command.ids []
data_collector.templates {"data_collector.request":["request","@WebProfiler\/Collecto...
debug.container.dump /home/qinhong/code/DUOXAIO/var/cache/dev/App_KernelDevDebugContainer.xml
debug.error_handler.throw_at -1
debug.file_link_format null
doctrine.class Doctrine\Bundle\DoctrineBundle\Registry
doctrine.connections {"default":"doctrine.dbal.default_connection"}
doctrine.data_collector.class Doctrine\Bundle\DoctrineBundle\DataCollector\DoctrineDataCollector
doctrine.dbal.configuration.class Doctrine\DBAL\Configuration
doctrine.dbal.connection.event_manager.class Symfony\Bridge\Doctrine\ContainerAwareEventManager
doctrine.dbal.connection_factory.class Doctrine\Bundle\DoctrineBundle\ConnectionFactory
doctrine.dbal.connection_factory.types []
doctrine.dbal.events.mysql_session_init.class Doctrine\DBAL\Event\Listeners\MysqlSessionInit
doctrine.dbal.events.oracle_session_init.class Doctrine\DBAL\Event\Listeners\OracleSessionInit
doctrine.dbal.logger.chain.class Doctrine\DBAL\Logging\LoggerChain
doctrine.dbal.logger.class Symfony\Bridge\Doctrine\Logger\DbalLogger
doctrine.dbal.logger.profiling.class Doctrine\DBAL\Logging\DebugStack
doctrine.default_connection default
doctrine.default_entity_manager default
doctrine.entity_managers {"default":"doctrine.orm.default_entity_manager"}
doctrine.migrations.preferred_connection null
doctrine.migrations.preferred_em null
doctrine.orm.auto_generate_proxy_classes true
doctrine.orm.cache.apc.class Doctrine\Common\Cache\ApcCache
doctrine.orm.cache.array.class Doctrine\Common\Cache\ArrayCache
doctrine.orm.cache.memcache.class Doctrine\Common\Cache\MemcacheCache
doctrine.orm.cache.memcache_host localhost
doctrine.orm.cache.memcache_instance.class Memcache
doctrine.orm.cache.memcache_port 11211
doctrine.orm.cache.memcached.class Doctrine\Common\Cache\MemcachedCache
doctrine.orm.cache.memcached_host localhost
doctrine.orm.cache.memcached_instance.class Memcached
doctrine.orm.cache.memcached_port 11211
doctrine.orm.cache.redis.class Doctrine\Common\Cache\RedisCache
doctrine.orm.cache.redis_host localhost
doctrine.orm.cache.redis_instance.class Redis
doctrine.orm.cache.redis_port 6379
doctrine.orm.cache.wincache.class Doctrine\Common\Cache\WinCacheCache
doctrine.orm.cache.xcache.class Doctrine\Common\Cache\XcacheCache
doctrine.orm.cache.zenddata.class Doctrine\Common\Cache\ZendDataCache
doctrine.orm.configuration.class Doctrine\ORM\Configuration
doctrine.orm.entity_listener_resolver.class Doctrine\Bundle\DoctrineBundle\Mapping\ContainerEntityListenerResolver
doctrine.orm.entity_manager.class Doctrine\ORM\EntityManager
doctrine.orm.listeners.attach_entity_listeners.class Doctrine\ORM\Tools\AttachEntityListenersListener
doctrine.orm.listeners.resolve_target_entity.class Doctrine\ORM\Tools\ResolveTargetEntityListener
doctrine.orm.manager_configurator.class Doctrine\Bundle\DoctrineBundle\ManagerConfigurator
doctrine.orm.metadata.annotation.class Doctrine\ORM\Mapping\Driver\AnnotationDriver
doctrine.orm.metadata.attribute.class Doctrine\ORM\Mapping\Driver\AttributeDriver
doctrine.orm.metadata.driver_chain.class Doctrine\Persistence\Mapping\Driver\MappingDriverChain
doctrine.orm.metadata.php.class Doctrine\ORM\Mapping\Driver\PHPDriver
doctrine.orm.metadata.staticphp.class Doctrine\ORM\Mapping\Driver\StaticPHPDriver
doctrine.orm.metadata.xml.class Doctrine\ORM\Mapping\Driver\SimplifiedXmlDriver
doctrine.orm.metadata.yml.class Doctrine\ORM\Mapping\Driver\SimplifiedYamlDriver
doctrine.orm.naming_strategy.default.class Doctrine\ORM\Mapping\DefaultNamingStrategy
doctrine.orm.naming_strategy.underscore.class Doctrine\ORM\Mapping\UnderscoreNamingStrategy
doctrine.orm.proxy_cache_warmer.class Symfony\Bridge\Doctrine\CacheWarmer\ProxyCacheWarmer
doctrine.orm.proxy_dir /home/qinhong/code/DUOXAIO/var/cache/dev/doctrine/orm/Proxies
doctrine.orm.proxy_namespace Proxies
doctrine.orm.quote_strategy.ansi.class Doctrine\ORM\Mapping\AnsiQuoteStrategy
doctrine.orm.quote_strategy.default.class Doctrine\ORM\Mapping\DefaultQuoteStrategy
doctrine.orm.second_level_cache.cache_configuration.class Doctrine\ORM\Cache\CacheConfiguration
doctrine.orm.second_level_cache.default_cache_factory.class Doctrine\ORM\Cache\DefaultCacheFactory
doctrine.orm.second_level_cache.default_region.class Doctrine\ORM\Cache\Region\DefaultRegion
doctrine.orm.second_level_cache.filelock_region.class Doctrine\ORM\Cache\Region\FileLockRegion
doctrine.orm.second_level_cache.logger_chain.class Doctrine\ORM\Cache\Logging\CacheLoggerChain
doctrine.orm.second_level_cache.logger_statistics.class Doctrine\ORM\Cache\Logging\StatisticsCacheLogger
doctrine.orm.second_level_cache.regions_configuration.class Doctrine\ORM\Cache\RegionsConfiguration
doctrine.orm.security.user.provider.class Symfony\Bridge\Doctrine\Security\User\EntityUserProvider
doctrine.orm.validator.unique.class Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntityValidator
doctrine.orm.validator_initializer.class Symfony\Bridge\Doctrine\Validator\DoctrineInitializer
env(VAR_DUMPER_SERVER) 127.0.0.1:9912
event_dispatcher.event_aliases {"Symfony\\Component\\Console\\Event\\ConsoleCommandEvent":"...
ffmpeg_binary %env(FFMPEG_BINARY_PATH)%
ffprobe_binary %env(FFPROBE_BINARY_PATH)%
form.type_extension.csrf.enabled true
form.type_extension.csrf.field_name _token
form.type_guesser.doctrine.class Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser
fragment.path /_fragment
fragment.renderer.hinclude.global_template null
idp_scheme %env(IDP_SCHEME)%
idp_url %env(IDP_URL)%
kernel.build_dir /home/qinhong/code/DUOXAIO/var/cache/dev
kernel.bundles {"FrameworkBundle":"Symfony\\Bundle\\FrameworkBundle\\Framew...
kernel.bundles_metadata {"FrameworkBundle":{"path":"\/home\/qinhong\/code\/DUOXAIO\/ven...
kernel.cache_dir /home/qinhong/code/DUOXAIO/var/cache/dev
kernel.charset UTF-8
kernel.container_class App_KernelDevDebugContainer
kernel.debug true
kernel.default_locale en
kernel.enabled_locales []
kernel.environment dev
kernel.error_controller error_controller
kernel.http_method_override false
kernel.logs_dir /home/qinhong/code/DUOXAIO/var/log
kernel.project_dir /home/qinhong/code/DUOXAIO
kernel.runtime_environment %env(default:kernel.environment:APP_RUNTIME_ENV)%
kernel.secret %env(APP_SECRET)%
kernel.trusted_hosts []
knp_paginator.page_limit null
knp_paginator.page_range 5
knp_paginator.template.filtration @KnpPaginator/Pagination/bootstrap_v5_filtration.html.twig
knp_paginator.template.pagination @KnpPaginator/Pagination/bootstrap_v5_pagination.html.twig
knp_paginator.template.sortable @KnpPaginator/Pagination/bootstrap_v5_md_sortable_link.html.twig
krtv_single_sign_on_service_provider.authentication.entry_point.sso.class Krtv\Bundle\SingleSignOnServiceProviderBundle\EntryPoint\SingleSignOnAuthenticationEntryPoint
krtv_single_sign_on_service_provider.authentication.handler.authentication_failure.class Krtv\Bundle\SingleSignOnServiceProviderBundle\Authentication\Handler\AuthenticationFailureHandler
krtv_single_sign_on_service_provider.authentication.provider.otp.class Krtv\Bundle\SingleSignOnServiceProviderBundle\Authentication\Provider\OneTimePasswordAuthenticationProvider
krtv_single_sign_on_service_provider.context_factory.attribute _sso_context
krtv_single_sign_on_service_provider.context_factory.class Krtv\Bundle\SingleSignOnServiceProviderBundle\Context\AuthenticationContextFactory
krtv_single_sign_on_service_provider.context_listener.class Krtv\Bundle\SingleSignOnServiceProviderBundle\EventListener\AuthenticationContextSubscriber
krtv_single_sign_on_service_provider.encoder.otp.class Krtv\SingleSignOn\Encoder\OneTimePasswordEncoder
krtv_single_sign_on_service_provider.factory.class Krtv\Bundle\SingleSignOnServiceProviderBundle\Factory\SingleSignOnFactory
krtv_single_sign_on_service_provider.host %env(qinhong_LOGIN_HOST)%
krtv_single_sign_on_service_provider.host_scheme http
krtv_single_sign_on_service_provider.listener.otp.class Krtv\Bundle\SingleSignOnServiceProviderBundle\Firewall\OneTimePasswordListener
krtv_single_sign_on_service_provider.login_path /sso/login/
krtv_single_sign_on_service_provider.options.main {"require_previous_session":false,"provider":"main","check_p...
krtv_single_sign_on_service_provider.otp_manager {"name":"http","managers":{"http":{"provider":"guzzle","prov...
krtv_single_sign_on_service_provider.otp_parameter _otp
krtv_single_sign_on_service_provider.secret_parameter kernel.secret
krtv_single_sign_on_service_provider.security.authentication.otp_manager.http.class Krtv\SingleSignOn\Manager\Http\OneTimePasswordManager
krtv_single_sign_on_service_provider.security.authentication.otp_manager.http.provider.guzzle.class Krtv\SingleSignOn\Manager\Http\Provider\Guzzle\OneTimePasswordProvider
krtv_single_sign_on_service_provider.twig.extension.url_signer.class Krtv\Bundle\SingleSignOnServiceProviderBundle\Twig\Extension\UrlSignerExtension
liip_imagine.binary.loader.default default
liip_imagine.cache.resolver.default default
liip_imagine.controller.filter_action Liip\ImagineBundle\Controller\ImagineController::filterAction
liip_imagine.controller.filter_runtime_action Liip\ImagineBundle\Controller\ImagineController::filterRuntimeAction
liip_imagine.cwebp.alphaFilter fast
liip_imagine.cwebp.alphaMethod 1
liip_imagine.cwebp.alphaQ 100
liip_imagine.cwebp.binary /usr/bin/cwebp
liip_imagine.cwebp.exact false
liip_imagine.cwebp.m 4
liip_imagine.cwebp.metadata ["none"]
liip_imagine.cwebp.q 75
liip_imagine.cwebp.tempDir null
liip_imagine.default_image null
liip_imagine.driver_service liip_imagine.imagick
liip_imagine.filter_sets {"squared_thumbnail_small":{"quality":100,"jpeg_quality":nul...
liip_imagine.jpegoptim.binary /usr/bin/jpegoptim
liip_imagine.jpegoptim.max null
liip_imagine.jpegoptim.progressive true
liip_imagine.jpegoptim.stripAll true
liip_imagine.jpegoptim.tempDir null
liip_imagine.loaders {"default":{"filesystem":{"data_root":["\/home\/qinhong\/code\/...
liip_imagine.mozjpeg.binary /opt/mozjpeg/bin/cjpeg
liip_imagine.optipng.binary /usr/bin/optipng
liip_imagine.optipng.level 7
liip_imagine.optipng.stripAll true
liip_imagine.optipng.tempDir null
liip_imagine.pngquant.binary /usr/bin/pngquant
liip_imagine.resolvers {"default":{"web_path":{"web_root":"\/home\/qinhong\/code\/acad...
liip_imagine.webp.generate true
liip_imagine.webp.options {"quality":100,"cache":null,"data_loader":null,"post_process...
monolog.handlers_to_channels {"monolog.handler.console":{"type":"exclusive","elements":["...
monolog.swift_mailer.handlers []
monolog.use_microseconds true
profiler.storage.dsn file:/home/qinhong/code/DUOXAIO/var/cache/dev/profiler
profiler_listener.only_exceptions false
profiler_listener.only_main_requests false
request_listener.http_port 80
request_listener.https_port 443
router.request_context.base_url
router.request_context.host localhost
router.request_context.scheme http
router.resource kernel::loadRoutes
security.access.always_authenticate_before_granting false
security.access.denied_url null
security.authentication.hide_user_not_found true
security.authentication.manager.erase_credentials true
security.authentication.session_strategy.strategy migrate
security.firewalls ["dev","main"]
security.main._indexed_authenticators []
security.role_hierarchy.roles []
serializer.mapping.cache.file /home/qinhong/code/DUOXAIO/var/cache/dev/serialization.php
session.metadata.storage_key _sf2_meta
session.metadata.update_threshold 0
session.save_path /home/qinhong/code/DUOXAIO/var/cache/dev/sessions
session.storage.options {"cache_limiter":"0","name":"DUOXAIOSSESSID","cookie_httponl...
sso_service %env(SSO_SERVICE)%
translator.default_path /home/qinhong/code/DUOXAIO/translations
translator.logging false
twig.default_path /home/qinhong/code/DUOXAIO/templates
twig.form.resources ["form_div_layout.html.twig","@LiipImagine\/Form\/form_div_l...
user_login_authority %env(USER_LOGIN_AUTHORITY)%
user_login_key %env(USER_LOGIN_KEY)%
validator.mapping.cache.file /home/qinhong/code/DUOXAIO/var/cache/dev/validation.php
validator.translation_domain validators
web_profiler.debug_toolbar.intercept_redirects false
web_profiler.debug_toolbar.mode 2
----------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------------------
// To search for a specific parameter, re-run this command with a search term. (e.g. debug:container
// --parameter=kernel.debug)
其中我认为最常用的是:kernel.build_dir 这个在很多地方都会有,其实就是项目的根目录
⑤获取/使用环境变量的几种场景(以前总是通过 ParamBagInterface获取,但是这种方法不好,后来用的最多的还是下面的第二种场景)
在从AbstractController延伸出来的控制器中,使用getParameter()辅助工具:
// src/Controller/UserController.php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
class UserController extends AbstractController
{
// ...
public function index(): Response
{
$projectDir = $this->getParameter('kernel.project_dir');
$adminEmail = $this->getParameter('app.admin_email');
// ...
}
}
在服务和不从AbstractController扩展的控制器中,将参数作为构造函数的参数注入。你必须明确地注入它们,因为服务自动布线对参数不起作用:
# config/services.yaml
parameters:
app.contents_dir: '...'
services:
App\Service\MessageGenerator:
arguments:
$contentsDir: '%app.contents_dir%'
如果你反复注入相同的参数,请使用services._defaults.bind选项来代替。该选项中定义的参数会在服务构造函数或控制器动作定义具有该确切名称的参数时自动注入。例如,每当服务/控制器定义$projectDir参数时,要注入kernel.project_dir参数的值,使用这个:
# config/services.yaml
services:
_defaults:
bind:
# pass this value to any $projectDir argument for any service
# that's created in this file (including controller arguments)
$projectDir: '%kernel.project_dir%'
# ...
最后,如果某些服务需要访问很多参数(构造函数注入的太多),你可以通过用ContainerBagInterface对其任何构造参数进行类型提示,一次性注入所有应用参数,而不是单独注入每个参数:
// src/Service/MessageGenerator.php
namespace App\Service;
// ...
use Symfony\Component\DependencyInjection\ParameterBag\ContainerBagInterface;
class MessageGenerator
{
public function __construct(
private ContainerBagInterface $params,
) {
}
public function someMethod()
{
// get any container parameter from $this->params, which stores all of them
$sender = $this->params->get('mailer_sender'); // 可以直接获取到 /config/services.yaml 的 parameters 配置参数
// ...
}
}
