懒惰的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存储库,我正在其中研究一种数据库设计方法,该方法包括在同时设计示例假数据的情况下为开发数据库注入种子。

From: https://hackernoon.com/a-tip-for-lazy-symfony-developers-9j1b36e4

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值