gheb / doctrine-cross-bundle-mapping-bundle
此Bundle提供了跨Bundle的映射
Requires
- php: >=5.4
- doctrine/common: 2.5.*
- doctrine/doctrine-bundle: ~1.2
- doctrine/orm: ~2.4
- knplabs/doctrine-behaviors: 1.0.*@dev
- symfony/symfony: ~2.7
Requires (Dev)
- phpunit/phpunit: 4.4.*
This package is auto-updated.
Last update: 2024-09-28 00:54:44 UTC
README
此Bundle是解决跨Bundle关联映射的解决方案。
此Bundle为您提供一种将属于两个不同Bundle的两个实体关联起来的方法,同时不破坏解耦并独立运行。
用例
假设我们有一个UserBundle和一个ForumBundle。如果一个用户可以是发布者,发布者可以作为独立的实体使用。在这种情况下,我非常希望这两个实体之间不共享任何硬链接。
从User实体到Publisher实体的关联映射创建了一个硬依赖。一旦禁用ForumBundle,Doctrine会抛出错误,指出Publisher不在其注册的任何命名空间中。
由于Doctrine是连接实体和数据库的桥梁,我们可以操纵它理解信息存储的方式,并添加动态映射。
安装
更新您的composer.json
{ ... "require": { ... "gheb/doctrine-cross-bundle-mapping-bundle": "^1.0@dev" } ... }
然后
$ composer update
或者
$ composer require gheb/doctrine-cross-bundle-mapping-bundle
配置
使用此Bundle有两种方式。
第一种称为resolve_target_entities,这是由doctrine提供的。使用示例可以在这里找到。唯一的区别是,如果目标实体不存在,则不创建映射。不会抛出错误。
第二种方式略有不同。您不是在您的整个实体映射配置中设置映射配置,而是在您的config.yml中设置它。您可能希望将额外的配置放在您的app/config.yml中,但将其放在Bundle中更有意义。(Acme/UserBundle/Resources/config/config.yml)
以下是一个配置示例
您有一个UserBundle和一个ForumBundle。它们都可以独立使用。但到目前为止,我想让它们能够通信。我想从User获取Publisher(然后获取他发布的一切),或者从Publisher获取User(然后获取他的邮件或他的名字)
#app/config/config.yml doctrine_cross_bundle_mapping: mapping: Acme\UserBundle\Entity\User: oneToOne: publisher: targetEntity: Acme\ForumBundle\Entity\Publisher mappedBy: user Acme\ForumBundle\Entity\Publisher: oneToOne: user: targetEntity: Acme\UserBundle\Entity\User inversedBy: publisher joinColumn: name: user_id referenceColumnName: id
设置完成后,Doctrine知道映射关联。但您需要更新您的模式。检查一下 ;)
$ php app/console doctrine:schema:update --dump-sql $ php app/console doctrine:schema:update --force
属性访问
到目前为止,我们实际上不需要做任何事情。但我们将进一步扩展。
PHP非常(过于?)灵活,允许我们这样做
$object = new Class(); $object->randomAttribute = 'myValue'; var_dump($object->randomAttribute); // myValue
但到目前为止,我们一直被教导这样做
$object = new Class(); $object->setRandomAttribute('myValue'); var_dump($object->getRandomAttribute()); // myValue
从User可能链接到Publisher的角度来看,没有必要在其中编写任何访问器。
因此,为了保持解耦,只需使用一个Trait。
namespace Acme\UserBundle\Entity; use Gheb\Bundle\DoctrineCrossBundleMappingBundle\Traits\CrossBundleMappingTrait; class User { use CrossBundleMappingTrait; ... }
然后您可以像通常那样做
$object = new Class(); // Scalar and Object var_dump($object->getScalarAttribute()); // null $object->setScalarAttribute('myValue'); var_dump($object->getScalarAttribute()); // myValue // Boolean var_dump($object->getBooleanAttribute()); // false $object->setBooleanAttribute(true); var_dump($object->getBooleanAttribute()); // true var_dump($object->isBooleanAttribute()); // true $object->setBooleanAttribute('test'); var_dump($object->getBooleanAttribute()); // test var_dump($object->isBooleanAttribute()); // false // Array var_dump($object->getArrayAttributes()); // null $object->setArrayAttributes(array(1,2,3)); var_dump($object->getArrayAttributes()); // array(1,2,3) // When using addArrayAttribute, recognize the add and transform ArrayAttribute in arrayAttributes $object->addArrayAttribute('test'); var_dump($object->getArrayAttributes()); // array(1,2,3,'test') $object->addArrayAttribute('test2'); var_dump($object->getArrayAttributes()); // array(1,2,3,'test','test2) $object->addArrayAttribute('test'); var_dump($object->getArrayAttributes()); // array(1,2,3,'test','test2,'test') // When using removeArrayAttribute, recognize the remove and transform ArrayAttribute in arrayAttributes $object->removeArrayAttribute('test'); var_dump($object->getArrayAttributes()); // array(0=>1, 1=>2, 2=>3, 4=>'test2, 5=>'test') $object->removeArrayAttribute('test'); var_dump($object->getArrayAttributes()); // array(0=>1, 1=>2, 2=>3, 4=>'test2) // ArrayCollection (or anything Traversable) var_dump($object->getTraversableAttributes()); // null $object->setTraversableAttributes(new ArrayCollection(array(1,2,3))); var_dump($object->getTraversableAttributes()); // ArrayCollection(array(1,2,3)) // When using addArrayAttribute, recognize the add and transform ArrayAttribute in arrayAttributes $object->addTraversableAttribute('test'); var_dump($object->getTraversableAttributes()); // ArrayCollection(array(1,2,3,'test')) $object->addTraversableAttribute('test2'); var_dump($object->getTraversableAttributes()); // ArrayCollection(array(1,2,3,'test','test2)) $object->addTraversableAttribute('test'); var_dump($object->getTraversableAttributes()); // ArrayCollection(array(1,2,3,'test','test2)) // When using removeArrayAttribute, recognize the remove and transform ArrayAttribute in arrayAttributes $object->removeTraversableAttribute('test'); var_dump($object->getTraversableAttributes()); // ArrayCollection(array(1,2,3,'test2))
警告
力量越大,责任越大... 这可以防止任何未声明的Method的误用。
因此,您可能需要扩展您的基本类并定义这些访问器。
namespace Acme\UserBundle\Entity; use User as BaseUser; class User extends BaseUser { protected $publisher; public function getPublisher(); public function setPublisher(); ... }