symfony开发
搜索关于懒惰的精明语录,您会发现其中有很多话说的不太好,但是您知道成为一个懒惰的程序员实际上是一件好事吗?
归根结底,在解决问题时,您可能想采用惰性方法的原因可能是因为您想节省大脑的能量。
现在让我提醒您,PHP被认为是一种松散类型的编程语言,既不错也不是很好,而是一种特殊的功能,可以灵活地处理变量类型。
可以根据需要使用PHP变量,而无需先声明它们,而函数中的类型提示是可选的。
话虽如此,另一方面, Doctrine是PHP和Symfony的流行ORM,它鼓励您使用所谓的实体,如下所示。
// src/DataFixtures/AddressFixtures.php
namespace App \ DataFixtures ;
use App \ Entity \ Address ;
use Doctrine \ Bundle \ FixturesBundle \ Fixture ;
use Doctrine \ Common \ DataFixtures \ DependentFixtureInterface ;
use Doctrine \ Common \ Persistence \ ObjectManager ;
use Faker \ Factory ;
class AddressFixtures extends Fixture implements DependentFixtureInterface
{
const N = 50 ;
private $faker;
public function __construct ()
{
$this ->faker = Factory::create();
$this ->faker->addProvider( new \Faker\Provider\en_US\Address( $this ->faker));
}
public function load (ObjectManager $manager)
{
for ($i = 0 ; $i < self ::N; $i++) {
$address = ( new Address())
->setAddress( $this ->faker->address)
->setPostcode( $this ->faker->postcode)
->setCity( $this ->faker->city)
->setUser( $this ->getReference( 'user-' .rand( 0 ,UserFixtures::N -1 )));
$manager->persist($address);
}
$manager->flush();
}
public function getDependencies ()
{
return [
UserFixtures::class,
];
}
}
如您所见,此示例大约要加载50
地址夹具 ,必须调用Adress
实体中的每个setter方法才能创建$address
对象。
$address = (new Address())
->setAddress( $this ->faker->address)
->setPostcode( $this ->faker->postcode)
->setCity( $this ->faker->city)
->setUser( $this ->getReference( 'user-' .rand( 0 ,UserFixtures::N -1 )));
有人可能会认为这是不必要的冗长,在这种情况下,我将利用PHP的灵活特性亲自提出以下名为VerbosityTrait
自定义实体行为。
// src/Entity/Behaviour/VerbosityTrait.php
namespace App \ Entity \ Behaviour ;
trait VerbosityTrait
{
/**
* Sets the entity's properties.
*
* @param array $props
* @return $this
*/
public function setProps (array $props)
{
foreach ($props as $key => $val) {
$method = 'set' . $this ->camelize($key);
if (method_exists( $this , $method)) {
$this ->{$method}( $this ->filter($key, $val));
}
}
return $this ;
}
/**
* Camelizes a string.
*
* @param string $string
* @param string $separator
* @return $this
*/
private function camelize (string $string, string $separator = '_' )
{
return str_replace($separator, '' , ucwords($string, $separator));
}
/**
* Applies a filter.
*
* @param string $key
* @param mixed $val
*/
private function filter (string $key, $val)
{
switch ( true ) {
case empty ($val):
return null ;
case substr($key, 0 , 3 ) === 'is_' :
return filter_var($val, FILTER_VALIDATE_BOOLEAN);
case is_string($val) && preg_match( "/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/" , $val):
return new \DateTime($val);
default :
return $val;
}
}
}
// src/Entity/Address.php
namespace App \ Entity ;
use App \ Entity \ Behaviour \ VerbosityTrait ;
use Doctrine \ ORM \ Mapping as ORM ;
/**
* @ORM \Entity(repositoryClass="App\Repository\AddressRepository")
*/
class Address
{
use VerbosityTrait ;
/**
* @ORM \Id()
* @ORM \GeneratedValue()
* @ORM \Column(type="integer")
*/
private $id;
/**
* @ORM \Column(type="string", length=255)
*/
private $address;
/**
* @ORM \Column(type="string", length=15)
*/
private $postcode;
/**
* @ORM \ManyToOne(targetEntity="App\Entity\User", inversedBy="addresses")
*/
private $user;
/**
* @ORM \Column(type="string", length=255)
*/
private $city;
public function getId () : ? int
{
return $this ->id;
}
public function getAddress () : ? string
{
return $this ->address;
}
public function setAddress (string $address) : self
{
$this ->address = $address;
return $this ;
}
public function getPostcode () : ? string
{
return $this ->postcode;
}
public function setPostcode (string $postcode) : self
{
$this ->postcode = $postcode;
return $this ;
}
public function getCity () : ? string
{
return $this ->city;
}
public function setCity (string $city) : self
{
$this ->city = $city;
return $this ;
}
public function getUser () : ? User
{
return $this ->user;
}
public function setUser (?User $user) : self
{
$this ->user = $user;
return $this ;
}
}
这样,固定装置的装载就变成了不同的,简洁的口味或版本。
// src/DataFixtures/AddressFixtures.php
namespace App \ DataFixtures ;
use App \ Entity \ Address ;
use Doctrine \ Bundle \ FixturesBundle \ Fixture ;
use Doctrine \ Common \ DataFixtures \ DependentFixtureInterface ;
use Doctrine \ Common \ Persistence \ ObjectManager ;
use Faker \ Factory ;
class AddressFixtures extends Fixture implements DependentFixtureInterface
{
const N = 50 ;
private $faker;
public function __construct ()
{
$this ->faker = Factory::create();
$this ->faker->addProvider( new \Faker\Provider\en_US\Address( $this ->faker));
}
public function load (ObjectManager $manager)
{
for ($i = 0 ; $i < self ::N; $i++) {
$address = ( new Address())->setProps([
'address' => $this ->faker->address,
'postcode' => $this ->faker->postcode,
'city' => $this ->faker->city,
'user' => $this ->getReference( 'user-' .rand( 0 ,UserFixtures::N -1 )),
]);
$manager->persist($address);
}
$manager->flush();
}
public function getDependencies ()
{
return [
UserFixtures::class,
];
}
}
通过使用我们自定义的VerbosityTrait
行为的Address
实体,创建的$address
对象的详细程度要低得多。
$address = (new Address())->setProps([
'address' => $this ->faker->address,
'postcode' => $this ->faker->postcode,
'city' => $this ->faker->city,
'user' => $this ->getReference( 'user-' .rand( 0 ,UserFixtures::N -1 )),
]);
实体属性是通过setProps()
方法设置的,该方法接受一个关联的属性数组,每个属性在执行时都可以具有未知类型。
有关此实现的更多详细信息,请访问programarivm / zebra ,这是一个GitHub存储库,我正在其中研究一种数据库设计方法,该方法包括在同时设计示例假数据的同时为开发数据库播种。
翻译自: https://hackernoon.com/a-tip-for-lazy-symfony-developers-9j1b36e4
symfony开发