我使用symfony和doctrine。
服务器获取包含模型属性的URL / company / {id}的HTTP PATCH请求,其值如{"name": "My new name"}
。新值需要保留在数据库中。
$request = Request::createFromGlobals();
$requestContentJSON = $request->getContent();
$requestContentObj = json_decode($requestContentJSON);
$repository = $this->getDoctrine()->getRepository('MyBundle:Company');
$company = $repository->find($id);
现在我可以输入$company->setName($requestContentObj[0]);
,但收到的财产会有所不同。现在我使用以下代码来处理每个属性:
foreach($requestContentObj as $key => $value){
switch($key){
case 'name':
$company->setName($value);
break;
case 'department':
$company->setDepartment($value);
break;
case 'origin':
$company->setOrigin($value);
break;
case 'headquarters':
$company->setHeadquarters($value);
break;
case 'email':
$company->setEmail($value);
break;
case 'twitterid':
$company->setTwitterId($value);
break;
case 'description':
$company->setDescription($value);
break;
}
}
但这看起来并不聪明,特别是因为我知道我将拥有其他实体,如新闻,产品,用户等,这些实体将以相同的方式更新其属性。我想做这样的事情:
$company->set("property", "value");
首先想到的是,我想到的是将这个switch语句放在这个set函数中的公司类中,也放在我拥有的所有其他实体类中。但有更好的方法吗?也许symfony / doctrine已经内置了解决方案,但我找不到任何适合我的方法。
我仍然希望使用setter和getter作为长期投资。
谢谢。
答案 0 :(得分:9)
假设您的属性名称与方法名称类似。
你可以这样做。设置多个属性。
Class customer {
protected $_email;
public function __construct(array $config = array()){
$this->setOptions($config);
}
public function getEmail(){
return $this->_email;
}
public function setEmail($email){
$this->_email = $email;
}
public function setOptions(array $options)
{
$_classMethods = get_class_methods($this);
foreach ($options as $key => $value) {
$method = 'set' . ucfirst($key);
if (in_array($method, $_classMethods)) {
$this->$method($value);
} else {
throw new Exception('Invalid method name');
}
}
return $this;
}
public function setOption($key, $value){
return $this->setOptions(array($key, $value));
}
}
现在你可以这样做:
$array = array('email' => 'abc.@gmail.com');
$customer = new Customer($array);
echo $customer->getEmail();
答案 1 :(得分:4)
我的初衷是将merge
方法添加到您的班级,如下:
<?php
// example Company entity
class Company
{
private $name;
function setName($name)
{
$this->name = $name;
}
function getName()
{
return $this->name;
}
function merge(\stdClass $obj)
{
// get the object vars of the passed object
// iterate, and replace matching properties
foreach (get_object_vars($obj) as $prop => $val) {
if (property_exists($this, $prop)) {
$this->$prop = $val;
}
}
}
}
$company = new Company();
// mocking your request object
$requestContentObj = new stdClass();
$requestContentObj->name = 'acme';
$company->merge($requestContentObj);
var_dump($company);
收率:
class Company#1 (1) {
private $name =>
string(4) "acme"
}
这会以静默方式转储任何与Company
类中的任何属性都不匹配的传递值,这些属性可能是您想要的,也可能不是。希望这会有所帮助:)
答案 2 :(得分:2)
我可以建议的不是使用setter,但它似乎非常适合你的问题。 在doctrine 1.2.4中,您可以使用DQL:
$q = Doctrine_Core::getTable("myTable")->createQuery("q")
->update()
->where("id = ?", $id);
foreach($requestContentObj as $key => $value)
{
$q->set($key, "?", $value);
}
$q->execute();