norbertkranitz/gophry-dto

此包的最新版本(dev-master)没有可用的许可信息。

dev-master 2017-03-26 00:39 UTC

This package is not auto-updated.

Last update: 2024-09-20 22:18:00 UTC


README

Gophry-dto 是一个简单的库,可以帮助您在 PHP 应用程序的各个层之间传输数据

安装

您可以使用 composer 安装此包(了解更多信息)。

composer require norbertkranitz/gophry-dto "dev-master"

RequestDTOs

大多数 PHP 框架都提供数组形式的请求数据。使用数组工作很好,但如果我们将这个数组包装/适配成简单的对象,我们就可以在上面执行一些操作,比如验证呢?

\Gophry\DTO\RequestDTO 抽象类实现了 bind(array $values) 方法,可以将传入的数组数据绑定到具有相同名称的属性。

class LoginRequestDTO extends \Gophry\DTO\RequestDTO {

    protected $email;
    
    protected $password;
        
    public function getEmail() {
        return $this->email;
    }

    public function getPassword() {
        return $this->password;
    }

}

$data = [
    'email' => 'test@email.app',
    'password' => 'password'
];

$dto = new LoginRequestDTO();
$dto->bind($data);

echo $dto->getEmail(); 
//'test@email.app'

您还可以根据 DTO 和数据数组结构定义对象树。

class NameRequestDTO extends \Gophry\DTO\RequestDTO {

    protected $first_name;
    
    protected $last_name;
        
    public function getFirstName() {
        return $this->first_name;
    }

    public function getLastName() {
        return $this->last_name;
    }

}

class RegisterRequestDTO extends \Gophry\DTO\RequestDTO {

    protected $email;
    
    protected $password;

    protected $name;

    //Important!
    public function __construct() {
        $this->name = new NameRequestDTO();
    }
        
    public function getEmail() {
        return $this->email;
    }

    public function getPassword() {
        return $this->password;
    }

    public function getName() {
        return $this->name->getFirstName() . ' ' . $this->name->getLastName();
    }

}

$data = [
    'name' => [
        'first_name' => 'First',
        'last_name' => 'Last'
    ],
    'email' => 'test@email.app',
    'password' => 'password'
];

$dto = new RegisterRequestDTO();
$dto->bind($data);

echo $dto->getName(); 
//'First Last'

请注意,子请求 DTO 也必须有一个请求 DTO 值才能使其正常工作

ResponeDTOs

大多数 PHP 框架要求将数组结果或基于数组的对象结果作为动作的结果。这就是我们创建 \Gophry\DTO\ResponseDTO 类的原因。

此类的扩展功能几乎与 \Gophry\DTO\RequestDTO 相同。区别在于此类更倾向于使用设置器,并实现了一个名为 toArray 的方法。

class LoginResponseDTO extends \Gophry\DTO\ResponseDTO {

    protected $token;
    
    public function setToken($token) {
        $this->token = $token;
        return $this;
    }

}

$dto = new LoginResponseDTO();
$dto->setToken('theToken');

print_r($dto->getEmail()); 
//['token' => 'theToken']

您还可以使用 ResponseDTO 对象树。

class NameResponseDTO extends \Gophry\DTO\ResponseDTO {

    protected $first_name;
    
    protected $last_name;
        
    public function setFirstName($first_name) {
        $this->first_name = $first_name;
        return $this;
    }

    public function setFirstName($last_name) {
        $this->last_name = $last_name;
        return $this;
    }

}

class LoginResponseDTO extends \Gophry\DTO\ResponseDTO {

    protected $token;

    protected $name;
    
    public function setToken($token) {
        $this->token = $token;
        return $this;
    }

    public function setName(NameResponseDTO $name) {
        $this->name = $name;
        return $this;
    }

}

$name = new NameResponseDTO();
$name->setFirstName('First');
$name->setLastName('Last');

$dto = new LoginResponseDTO();
$dto->setToken('theToken');
$dto->setName($name);

print_r($dto->getEmail()); 
//[
//  'token' => 'theToken'
//  'name' => [
//      'first_name' => 'First',
//      'last_name' => 'Last'
//  ]
//]

在类名中使用请求和响应短语是有意义的

如何使用?

假设您有一个控制器,并且当前正在触发一个动作。控制器提供请求数据作为数组,并需要一个数组结果。

class AuthService {

    public static function login(LoginRequestDTO $dto) {
        //do something with the $dto;
        //communicate with database
        //log something
        //send a welcome mail
        //throw an exception
        //catch the exception
        //etc
        $result = new LoginResponseDTO();
        $result->setToken($token);
        return $result;
    }

}

...

class AuthController extends BaseController {
    
    public function loginAction() {
        $data = $this->request->get();
        $dto = new LoginRequestDTO();
        $dto->bind($data);
        Validator::validate($dto);
        return AuthService::login($dto)->toArray();
    }

}