我正在寻找一种将数组转换为条令实体的方法。我使用的是教义2。
我有一个实体类,比如:
class User
{
/**
* @Id
* @Column(type="integer", nullable=false)
* @GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
* @Column(type="string", length=255, unique=true, nullable=false)
*/
protected $email;
/**
* @Column(type="string", length=64, nullable=false)
*/
protected $password;
/**
* @var DateTime
* @Column(type="datetime", nullable=false)
*/
protected $dob;
//getter and setters
}
当我从html表单发布数据时,我想将post数组转换为User实体。所以我有一个类似的阵列
$userAsArray = array("email"=>"abc@xyz.com","password"=>"hello","dob"=>"10'20'1990");
$user = new User();
covert($userAsArray,$user) // I am looking for something like this
我正在寻找一种通用的方法来实现这一点。我试过这样的东西:
function fromArray(array $array,$class){
$user = new $class();
foreach($array as $key => $field){
$keyUp = ucfirst($key);
if(method_exists($user,'set'.$keyUp)){
call_user_func(array($user,'set'.$keyUp),$field);
}
}
return $user;
}
但问题是,它将所有内容都设置为字符串。但对于日期,我希望将其作为DateTime对象。有什么帮助吗?
如果您的数组元素之一是外键怎么办?在设置实体属性之前,您可能需要准备外键属性。这就是我完成类似任务的方式:
扩展存储库
<?php
namespace My'Doctrine;
use Doctrine'ORM'EntityRepository;
class Repository extends EntityRepository
{
/**
* Prepare attributes for entity
* replace foreign keys with entity instances
*
* @param array $attributes entity attributes
* @return array modified attributes values
*/
public function prepareAttributes(array $attributes)
{
foreach ($attributes as $fieldName => &$fieldValue) {
if (!$this->getClassMetadata()->hasAssociation($fieldName)) {
continue;
}
$association = $this->getClassMetadata()
->getAssociationMapping($fieldName);
if (is_null($fieldValue)) {
continue;
}
$fieldValue = $this->getEntityManager()
->getReference($association['targetEntity'], $fieldValue);
unset($fieldValue);
}
return $attributes;
}
}
创建父Entity
类:
namespace My'Doctrine;
class Entity
{
/**
* Assign entity properties using an array
*
* @param array $attributes assoc array of values to assign
* @return null
*/
public function fromArray(array $attributes)
{
foreach ($attributes as $name => $value) {
if (property_exists($this, $name)) {
$methodName = $this->_getSetterName($name);
if ($methodName) {
$this->{$methodName}($value);
} else {
$this->$name = $value;
}
}
}
}
/**
* Get property setter method name (if exists)
*
* @param string $propertyName entity property name
* @return false|string
*/
protected function _getSetterName($propertyName)
{
$prefixes = array('add', 'set');
foreach ($prefixes as $prefix) {
$methodName = sprintf('%s%s', $prefix, ucfirst(strtolower($propertyName)));
if (method_exists($this, $methodName)) {
return $methodName;
}
}
return false;
}
}
用途,回购中的一种方法:
$entity = new User();
$attributes = array(
"email" =>"abc@xyz.com",
"password" =>"hello",
"dob" =>"10'20'1990"));
$entity->fromArray($this->prepareAttributes($attributes));
$this->getEntityManager()->persist($entity);
$this->getEntityManager()->flush();
为什么不编写setDob()
方法来检测字符串,并在必要时进行转换
public function setDob($dob) {
if (!$dob instanceof DateTime) {
$dob = new DateTime((string) $dob); // or however you want to do the conversion
}
$this->dob = $dob;
}
您正在尝试反序列化
我将查看Zend Framework 2 Stdlib组件。您不需要使用整个框架。
水合物,特别是DoctrineModule''Stdlib''Hydrator''DoctrineObject,按照您的要求执行。