php - 在 Symfony2 中使用 Doctrine 和静态 YAML 数据库

标签 php database symfony doctrine-orm yaml

我熟悉PHP,但只是学习Symfony2和Doctrine。我想知道静态数据的最佳做法是什么,因为只有在将新版本的 Web 应用程序部署到生产环境时才会更新数据。

我更愿意在 YAML 中指定静态数据(而不是模式),因为这样修改该数据对每个人来说都很容易,无论他们是否了解任何 PHP/Doctrine。我希望非开发人员能够通过修改 .yml 文件来添加成就。我想维护的静态 YAML 数据库的示例是:

Achievements:
  Conservative:
    Difficulty: 2
    Description: >
      Description of Conservative Achievement.
  Dedicated:
    Difficulty: 3
    Description: >
      Description of Dedicated Achievement.
  Persistent:
    Difficulty: 2
    Description: > 
      Description of Persistent Achievement.

现在假设我有一个代表用户的实体

// src/Paulpro/ExperimentingBundle/Entity/User.php
namespace Paulpro\ExperimentingBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;

class User {

    protected $name;
    protected $achievements;

    public function __construct(){
        // Collection of achievements as defined by achievements.yml
        // $this->achievements = new ArrayCollection();
    }

}

我想为用户正常使用 Doctrine,以便将它们存储在数据库中,并且我希望用户能够获得成就。用户可以拥有多项成就,因此在我的用户实体中,我需要某种方式来表示具有数量的成就集合。我不希望将成就难度和描述存储在数据库中,仅存储在 .yml 文件中,除非有充分的理由将成就本身存储在数据库中以及将静态数据导入数据库的好方法自动部署的一部分。

我有三个与此问题相关的主要问题:

  • 请记住,我希望非开发人员能够轻松添加成就,并且我可能希望为不同的语言环境覆盖 achievements.yml 文件,是否有更好的方法来做到这一点?

  • 我应该将 achievements.yml 文件放在我的 Symfony2 包中的什么地方?

  • 我应该如何修改用户实体,以便生成的数据库可以维护每个用户的成就数量?

最佳答案

I do not want the achievements difficulties and descriptions to be stored in the database, only in the .yml file, unless there is a good reason to store the achievements themselves in the database and a good way to import the static data into the database as part of automatic deployment.

一个很好的理由:管理用户成就之间的关系会更容易。
一种将静态数据导入数据库的方法:DoctrineFixturesBundle

1。定义静态配置

这样做的最好方法是 expose a semantic configuration .

在您的情况下,您将拥有以下 2 个文件:

// src/Paulpro/ExperimentingBundle/DependencyExtension/Configuration.php

<?php

namespace Paulpro\ExperimentingBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
    /**
     * Defines the configuration tree for the bundle
     * 
     * @return \Symfony\Component\Config\Definition\Builder\TreeBuilder
     */
    public function getConfigTreeBuilder()
    {
        $treeBuilder = new TreeBuilder();
        $rootNode = $treeBuilder->root('paulpro_experimenting');

        $rootNode
            ->children()
                ->arrayNode('Achievements')->addDefaultsIfNotSet()
                    ->children()
                        ->arrayNode('Conservative')->addDefaultsIfNotSet()
                            ->children()
                                ->integerNode('Difficulty')->defaultValue(2)->end()
                                ->scalarNode('Description')->defaultValue('Description of Conservative Achievement.')->end()
                            ->end()
                        ->end()
                        ->arrayNode('Dedicated')->addDefaultsIfNotSet()
                            ->children()
                                ->integerNode('Difficulty')->defaultValue(3)->end()
                                ->scalarNode('Description')->defaultValue('Description of Dedicated Achievement.')->end()
                            ->end()
                        ->end()
                        ->arrayNode('Persistent')->addDefaultsIfNotSet()
                            ->children()
                                ->integerNode('Difficulty')->defaultValue(2)->end()
                                ->scalarNode('Description')->defaultValue('Description of Persistent Achievement.')->end()
                            ->end()
                        ->end();

        return $treeBuilder;
    }
}

和:

<?php

namespace Paulpro\ExperimentingBundle\DependencyInjection;

use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;

class PaulproExperimentingExtension extends Extension
{
    /**
     * Load the configuration for the bundle
     * 
     * @param array $configs
     * @param \Symfony\Component\DependencyInjection\ContainerBuilder $container
     */
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        foreach($config as $key => $value)
        {
            $container->setParameter('paulpro_experimenting.'.$key, $value);
        }
    }
}

这样做,您将能够更好地管理用户使用配置的方式。要查看默认配置结果的示例,您可以使用以下命令:

php app/console config:dump-reference PaulProExperimentingBundle

结果应该如下:

Default configuration for "PaulProExperimentingBundle"
paulpro_experimenting:
    Achievements:
        Conservative:
            Difficulty:           2
            Description:          Description of Conservative Achievement.
        Dedicated:
            Difficulty:           3
            Description:          Description of Dedicated Achievement.
        Persistent:
            Difficulty:           2
            Description:          Description of Persistent Achievement.

这意味着您的用户可以将此示例放在 app\config 文件夹下的 config.yml 中,并根据需要进行更改。唯一的条件是,他们放入此文件的任何信息都必须通过您定义的 Configuration 树进行验证。

2。定义您的实体

定义Achievement 实体,因为它最适合您的需要。例如,您可以使用:

// src/Paulpro/ExperimentingBundle/Entity/Achievement.php
namespace Paulpro\ExperimentingBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;

class Achievement{

    protected $name;
    protected $difficulty;
    protected $description;    
    /**
     * @ManyToMany(targetEntity="User", mappedBy="achievements")
     * @JoinTable(name="users_achievements")
     **/
    private $users;

    public function __construct() {
        $this->users = new ArrayCollection();
    }

}

除了必须添加与 Achievement 的关系外,您将保持 User 实体的原样:

// src/Paulpro/ExperimentingBundle/Entity/User.php
namespace Paulpro\ExperimentingBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;

class User {

    protected $name;
    /**
     * @ManyToMany(targetEntity="Achivement", mappedBy="users")
     **/
    protected $achievements;

    public function __construct(){
        $this->achievements = new ArrayCollection();
    }

}

3。部署应用时填写数据库

这是最后一步,它专门使用 DoctrineFixturesBundle .

您必须为您的 Achivement 实体创建夹具:

// src/Paulpro/ExperimentingBundle/DataFixtures/ORM/LoadAchivementData.php

<?php

namespace Paulpro\ExperimentingBundle\DataFixtures\ORM;

use Doctrine\Common\DataFixtures\FixtureInterface;
use Doctrine\Common\Persistence\ObjectManager;
use Paulpro\ExperimentingBundle\Entity\Achivement;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

class LoadTypesData implements FixtureInterface, ContainerAwareInterface
{
    private $container;

    public function setContainer(ContainerInterface $container = null)
    {
        $this->container = $container;
    }

    public function load(ObjectManager $manager)
    {
        foreach($this->container->getParameter('paulpro_experimenting.Achievements') as $key => $value)
        {
            $achivement = new Achivement();
            $achivement->setName($key);
            $achivement->setDifficulty($value['Difficulty']);
            $achivement->setDescription($value['Description']);

            $manager->persist($achivement);
        }
        $manager->flush();
    }
}

此装置将通过 paulpro_experimenting.Achievements 的配置并从此处加载定义的 Achievements
最后,要将数据加载到数据库中,您必须运行以下命令:

php app/console doctrine:fixtures:load

Et voila,您现在应该能够从您的 users 添加/删除 achievements

关于php - 在 Symfony2 中使用 Doctrine 和静态 YAML 数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17222887/

相关文章:

不显示 PHP 错误

php - Sed 和 PHP 关联数组

java - 更新某一行中的多个列 SQLITE

mysql - 将 MySQL 数据库转换为 UTF8

forms - 模板渲染过程中抛出异常一个表单只能提交一次

php - 将 php 结果与 jQuery 接口(interface)

php - YouTube API videoEntry计数评论

sql - 影响在数据库上运行 SQL 所需时间的因素有哪些?

macos - ErrorException JMS\SerializerBundle\JMSSerializerBundle

php - 从未导入属性中的注释 "@OneToMany"(Doctrine2)