目前我们正在为德国经营一家网店。现在,我们还希望在英国提供具有自己域名的产品。
根据域的不同,它们应该加载几个设置:
在之前的项目中,我们通过将此设置放在数据库的域表中来解决它。但我认为整个支付服务信息和密钥和和......并不是最好的解决方案。
答案 0 :(得分:5)
您可以编写一个包Extension class来加载您的配置,具体取决于主机。
捆绑扩展:
// src/AcmeBundle/DependencyInjection/AcmeExtension.php
<?php
namespace AcmeBundle\DependencyInjection;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
class AcmeExtension extends Extension
{
public function load(array $configs, ContainerBuilder $container)
{
$configuration = new Configuration();
$config = $this->processConfiguration($configuration, $configs);
$rootdir = $container->getParameter('kernel.root_dir');
// Load the bundle's services.yml
$loader = new Loader\YamlFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('services.yml');
// Load parameters depending on current host
$paramLoader = new Loader\YamlFileLoader($container, new FileLocator($rootdir.'/config')); // Access the root config directory
$parameters = sprintf('parameters_%s.yml', $container->getParameter('router.request_context.host'));
if (!file_exists($rootdir.'/config/'.$parameters)) {
$parameters = 'parameters.yml'; // Default
}
$paramLoader->load($parameters);
}
}
相应的捆绑配置:
// src/AcmeBundle/DependencyInjection/Configuration.php
<?php
namespace AcmeBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
class Configuration implements ConfigurationInterface
{
public function getConfigTreeBuilder()
{
$treeBuilder = new TreeBuilder();
$rootNode = $treeBuilder->root('acme');
return $treeBuilder;
}
}
像这样,您可以创建一个名为parameters_localhost.yml
的文件,它将自动加载。
如果找不到该文件,将使用默认的parameters.yml
。
您可以根据所需的每个参数应用此逻辑(例如_locale
用于您的翻译)。
希望得到这个帮助。
答案 1 :(得分:2)
如果您的每个商店都是不同的应用安装,那么为什么不将您的配置保存在parameters.yml
文件中?您还可以查看ParameterHandler脚本,它将帮助您管理所有参数。
如果你使用单一代码库,也许你应该完全重新考虑你的实现,因为例如,如果将来你需要从英国商店独立于DE商店等产品制作产品呢? (有更多这样的用例)
我认为您当前的解决方案是一个短期解决方案,如果您计划扩展到不同的国家/地区,您应该投入一些时间来寻求长期解决方案。当然,这完全取决于您的要求和用例。
一个选项是将您的应用程序拆分为多个渠道,其中每个渠道将成为英国和德国的商店等等。
然后,您还可以使用不同的设置,产品,付款,每个频道的货币等。
您可以在GitHub上查看Sylius项目。他们开发了这个不错的ChannelBundle,您可以看到它是如何工作的。
答案 2 :(得分:1)
我知道已经选择了最佳答案,但我找到了parameters.php
的其他方法:
<?php
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Loader;
$hostArray = explode('.', $_SERVER['HTTP_HOST']);
$hostArrayCount = count($hostArray);
$host = $hostArray[$hostArrayCount - 2] . '.' . $hostArray[$hostArrayCount - 1];
$hostDir = $container->getParameter('kernel.root_dir') . '/config/domains/';
$parameters = sprintf('%s.yml', $host);
if (file_exists($hostDir . $parameters)) {
$hostParamLoader = new Loader\YamlFileLoader($container, new FileLocator($hostDir));
$hostParamLoader->load($parameters);
}
并在config.yml
之后:
imports:
- { resource: parameters.yml }
添加字符串:
- { resource: parameters.php }
答案 3 :(得分:0)
您可以在(apache?)配置中使用SetEnv作为数据库变量和每个域的其他变量(ref)
# /etc/apache2/sites-available/one-domain.conf
<VirtualHost *:80>
ServerName onedomain.uk
DocumentRoot "/path/to/onedomain/web"
DirectoryIndex index.php index.html
SetEnv SYMFONY__GOOGLE__ANALYTICSID mygoogleanalyticsid
SetEnv SYMFONY__PAYMENT__APISECRET mysecret
# ...
<Directory "/path/to/onedomain/web">
AllowOverride All
Allow from All
</Directory>
</VirtualHost>
然后使用常见的parameters.yml设置变量:
# app/config/parameters.yml
parameters:
analytics_id: "google.analyticsid"
payment_secret: "payment.apisecret"
# ...
它们都有自己的数据库设置和您想为每个设置的任何变量。
您还可以通过设置标识每个域的变量(ref)来分隔缓存和日志文件夹:
# app/AppKernel.php
public function getCacheDir()
{
if(getenv("SYMFONY__DOMAIN__NAME")){
return dirname(__DIR__).'/var/cache/'.$this->getEnvironment().'/'.getenv("SYMFONY__DOMAIN__NAME");
} else {
return dirname(__DIR__).'/var/cache/'.$this->getEnvironment();
}
}
public function getLogDir()
{
if(getenv("SYMFONY__DOMAIN__NAME")){
return dirname(__DIR__).'/var/logs/'.getenv("SYMFONY__DOMAIN__NAME");
} else {
return dirname(__DIR__).'/var/logs/';
}
}
如果您将会话存储在文件中,您也可以对sessions文件夹执行此操作:
# app/config/config.yml
framework:
# ...
session:
handler_id: session.handler.native_file
save_path: "%kernel.root_dir%/../var/sessions/%kernel.environment%/%domain.name%"