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?
Some of the code will not work with lower versions. Doctrine 2 is an object-relational mapper (ORM) for PHP 5.4+ that provides transparent persistence for PHP objects. It uses the Data Mapper pattern at the heart, aiming for a complete separation of your domain/business logic from the persistence in a relational database management system.
A persistable property is an instance variable of the entity that is saved into and retrieved from the database by Doctrine’s data mapping capabilities. For this Getting Started Guide for Doctrine we will implement the Bug Tracker domain model from the Zend_Db_Table documentation. Reading their documentation we can extract the requirements:
It uses the Data Mapper pattern at the heart, aiming for a complete separation of your domain/business logic from the persistence in a relational database management system. The benefit of Doctrine for the programmer is the ability to focus on the object-oriented business logic and worry about persistence only as a secondary problem.
This doesn’t mean persistence is downplayed by Doctrine 2, however it is our belief that there are considerable benefits for object-oriented programming if persistence and entities are kept separated. Entities are PHP Objects that can be identified over many requests by a unique identifier or primary key.
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.
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:
__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.)empty($entity->field)
will not invoke __get
(and thus it will break proxy behavior if used)If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With