Doctrine 2 Whats the Recommended Way to Access Pro

2020-02-08 18:01发布

I remember reading that in Doctrine 2 models, I should not set properties/fields public. How then would you expose these fields? The sandbox used get*() & set*() methods. Is that the best idea? Its very cumbersome. Using magic methods __get() __set() will make things similar to setting fields public?

Whats your recommendation?

6条回答
淡お忘
2楼-- · 2020-02-08 18:16

Yes getter and setter methods are the way to access your data. They are a little cumbersome which is why some people do not like doctrine2 or hibernate. But you only need to do it once for each entity and then they are very flexible to produce the output formatting you are hoping for. You can use the cli to do some of this for you. But when you get them rolling I don't find it to big a deal. Especially since you only do this to the properties you need.

Cheers

查看更多
我想做一个坏孩纸
3楼-- · 2020-02-08 18:17

Rather than having seperate getter and setters, or even using the magic functions.. Is there problem with having something like this in the class

public function Set($attrib, $value)
{
    $this->$attrib = $value;    
}

public function Get($attrib)
{
    return $this->$attrib;
}   

It makes it much easy to access the attributes and means they be dynamically set from key-pair arrays.. any comments? or alternative suggestions?

查看更多
ら.Afraid
4楼-- · 2020-02-08 18:23

Doctine 2 provides a [command line tool][1] to generate basic entity classes

use the following to get a basic Entity class definition from your mapping, complete with getter/setter functions for each property:

path/to/doctrine_cli orm:generate-entities --generate-methods=true path/to/entities/

You're still responsible for modifying each getter/setter to ensure that they are the proper datatype, as the getter/setter methods generated for the Entity don't do any type casting/converting.

查看更多
We Are One
5楼-- · 2020-02-08 18:31

If some info should be made public, define a getter for it. If it's modifiable, add a setter (even better, add a fluent setter!).

API's are cleaner this way, with no magic involved. I don't like magic in my code.

Just my two cents :)


By "fluent setter" I meant one implementing the fluent interface pattern.

查看更多
唯我独甜
6楼-- · 2020-02-08 18:33

Here's why you can't use public properties: How can public fields “break lazy loading” in Doctrine 2?

You are correct that __get() and __set() can make accessing the protected/private fields easier.

Here's a simple example:

public function __get($name)
{
  if(property_exists($this, $name)){
    return $this->$name;
  }
}

Of course that gives access to all the properties. You could put that in a class that all your entities extended, then define non-assessable fields as private. Or you could use an array to determine which properties should be accessible:$this->accessable = array('name', 'age')

There are plenty of ways to keep all properties protected and still have a reasonably easy way to get/set them.

查看更多
Melony?
7楼-- · 2020-02-08 18:35

Personally, I don't like boilerplate code with trivial purpose - it makes the code ugly and tiresome to read. Therefore, I strongly prefer __get/__set. That said, they do have a few drawbacks:

  • they are significantly slower than normal function calls, though not so much that it should make a difference in practice, as database access is several orders of magnitude slower
  • __get/__set only gets called when the field is not visible; if you access properties in the code of the entity class, they do not get called, and the proxy has no chance to load itself. (Doctrine tries to avoid this by instantly loading the proxy as soon as one of its public methods are called, but there are some exceptions such as __construct or __wake where that would not make sense, so you can get into trouble by e.g. reading a field in the constructor.)
  • PHP has some confusing behaviors related to magic methods - e. g. empty($entity->field) will not invoke __get (and thus it will break proxy behavior if used)
查看更多
登录 后发表回答