0

I have looking around for too long with no luck. My situation is that i have a bit large table +60 columns which is represented in Doctrine Entity. Working on FosREST and what i want to achieve is that i want to send a JSON with specific data let's say for example

[phone] => new_phone
[name] => new_name
[id] => 1

while like i said the entity contains over 60 columns like address, picture, category, etc...

and the phone, name and id are not what I want to change every time but i want to change some columns each time. So at some time i might want to update phone and name other time i want to change the category third time i want to change category and photo and address so is there anything like this ?

$entity->update($parameters);

where the $parameters are dynamically changed as explained before. ps. i know that i can build a very long function with something like

if(isset($parameters['name']){
     $entity->setName($parameters['name']);
}

but with 60 ifs this just sounds idiotic anyone have any other approach ? Thanks

2
  • Sometimes the ORM component is more trouble that it's worth. If you frequently need to just update a few fields then consider dropping down to the DBAL connection and using sql. On the other hand, 60 columns is a bit of a code smell so perhaps a different design should be considered. Commented Mar 13, 2017 at 13:00
  • @Cerad yeah i know its a bit smell but there is no way to do another design anyway the accepted answer solved the issue :) Commented Mar 13, 2017 at 13:07

1 Answer 1

5

1) If the parameters are named after the attributes (here with underscore annotations), you can do this

use Doctrine\Common\Util\Inflector;
// ...

public function setParameters($params) {
    foreach ($params as $k => $p) {
        $key = Inflector::camelize($k);
        if (property_exists($this, $key)) {
            $this->$key = $p;
        }
    }
    return $this;
}

2) Same thing with the setters

use Doctrine\Common\Util\Inflector;
// ...

public function setParameters($params) {
    foreach ($params as $k => $p) {
        $key = Inflector::camelize($k);
        if (property_exists($this, $key)) {
            $this->{'set'.ucfirst($key)}($p); // ucfirst() is not required but I think it's cleaner
        }
    }
    return $this;
}

3) If its not the same name, you can do this :

public function setParameters($params) {
    foreach ($params as $k => $p) {
        switch $k {
            case 'phone':
                $this->phoneNumber = $p;
                break;
            // ...
        }
    }
    return $this;
}

EDIT : Best approach is number two but you should define a white-list or a black-list in order to avoid the user updating something you don't want him to.

Sign up to request clarification or add additional context in comments.

3 Comments

its not because there is the _ and camelCase problem with them like phone_number and phoneNumber so the first one wont work as for the second one its just like building 60 ifs :/
and its not gonna work either ways cuz i will end up using $entity->setParam($param) not $entity->param = $param
For your first comment, I made an edit to camelize the key. For the second one, I don't understand what you mean. You want to use the setters and getters ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.