yurihbss yurihbss - 1 month ago 10
PHP Question

symfony doctrine using setters and getters dynamically

I'm using symfony and doctrine.

The server gets a HTTP PATCH request for the URL /company/{id} containing the property of a model and its value like

{"name": "My new name"}
The new value needs to be persisted into the DB.

$request = Request::createFromGlobals();
$requestContentJSON = $request->getContent();
$requestContentObj = json_decode($requestContentJSON);

$repository = $this->getDoctrine()->getRepository('MyBundle:Company');
$company = $repository->find($id);


Now I could just enter
$company->setName($requestContentObj[0]);
but the property being received will vary. Right now I'm using the following code to be able to handle every property:

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;
}
}


But this doesn't look very smart especially because I know that I will have other entities like news, products, users, etc that will have their properties updated in the same manner. I'd like to do something like this:

$company->set("property", "value");


First thought that crossed my mind was to put this switch statement inside the company class inside this set function and also inside all the other entity classes I have. But is there a better way? Maybe symfony/doctrine has the solution already built-in, but I didn't find anything that would suit me.

I still want to use setters and getters as a long-term investment.

Thank you.

Answer

Assuming you'll have the property names similar to method names.

You can do something like this. To set multiple properties.

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));
    }

}

Now you can simply do this:

$array = array('email' => 'abc.@gmail.com');
$customer = new Customer($array);
echo $customer->getEmail();