我试图从数据库中加载它们,而不是在parameters.yml
中对参数进行硬编码。并非所有parameters.yml中的参数都需要从数据库中加载,例如paypal的api详细信息
在config.yml
我已导入parameters.php
imports:
- { resource: parameters.php }
如果我在parameters.php
中添加静态信息,就像下面那样,那就可以了。
$demoName = 'First Last';
$container->setParameter('demoName', $demoName);
但是我无法从数据库表中获取信息。我以为我应该创建课程并使用$em = this->getDoctrine()->getManager();
它应该可以工作,但它没有,我得到的错误
Notice: Undefined variable: paypal_data in /opt/lampp/htdocs/services/app/config/parameters.php (which is being imported from "/opt/lampp/htdocs/services/app/config/config.yml").
这是我的尝试如下,但代码似乎没有进入__construct()
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\ORM\Mapping as ORM;
class parameters extends Controller
{
public $paypal_data;
function __construct() {
$this->indexAction();
}
public function indexAction(){
$em = $this->getDoctrine()->getManager();
$this->paypal_data = $em->getRepository('featureBundle:paymentGateways')->findAll();
}
}
$demoName = 'First Last';
$container->setParameter('demoName', $demoName);
$container->setParameter('paypal_data', $this->paypal_data);
非常感谢任何帮助。
答案 0 :(得分:13)
你做错了事。您需要声明CompilerPass并将其添加到容器中。整个容器将被加载...在编译时,您将可以访问其中的所有服务。
获取实体管理器服务并查询所需参数并将其注册到容器中。
分步说明:
定义编译器传递:
# src/Acme/YourBundle/DependencyInjection/Compiler/ParametersCompilerPass.php
class ParametersCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$em = $container->get('doctrine.orm.default_entity_manager');
$paypal_params = $em->getRepository('featureBundle:paymentGateways')->findAll();
$container->setParameter('paypal_data', $paypal_params);
}
}
在包定义类中,您需要将编译器传递添加到容器
# src/Acme/YourBundle/AcmeYourBundle.php
class AcmeYourBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new ParametersCompilerPass(), PassConfig::TYPE_AFTER_REMOVING);
}
}
答案 1 :(得分:1)
在我的情况下,使用CompilerPass
的解决方案在Symfony 4中不起作用,它只能在控制器上起作用,而在twig.yaml文件中使用时无效:
param_name: '%param_name%'
由于我需要在侧栏中使用此参数,因此在所有页面中,从控制器传递它都是不可行的。
这就是我所做的,这要感谢您可以reference services作为全局Twig变量。
我有一个名为“设置”的服务,该服务直接从数据库中加载设置,简化了:
class Settings
{
/** @var \PDO */
private $db;
public function __construct(EntityManagerInterface $em)
{
$this->db = $this->em->getConnection();
}
/**
* Gets a setting value.
* If the setting doesn't exist, returns the default value specified as second param
*/
public function get(string $name, $default=''): string
{
$stmt = $this->db->prepare("SELECT `value` FROM `settings` WHERE `key`=?;");
$stmt->execute([$name]);
return $stmt->fetchColumn() ?: $default;
}
/**
* Sets a setting value.
* If the setting doesn't exists, it creates it. Otherwise, it replaces the db value
*/
public function set(string $name, string $value, string $description = '')
{
$this->db->prepare("INSERT INTO settings (`key`, `value`, `description`) VALUES (?,?,?) ON DUPLICATE KEY UPDATE `value`=?;")
->execute([$name, $value, $description, $value]);
}
现在,我只是添加了config/packages/twig.yaml
:
twig:
# ...
globals:
# ...
settings: '@App\Service\Settings'
这太神奇了,因为现在我可以从任何模板读取任何数据库设置:
{{ dump(settings.get('setting_name')) }}
我发布的Settings类得到了简化,例如,如果您多次请求相同的设置,避免再次进行相同的查询,仍然可以进行改进,但这很简单(将获取的密钥存储在{{1 }}数组)