Flag This Hub

Doctrine 2 + Zend Framework CRUD example (pt 1)

By


Warning:

I’m not going to explain how to install Doctrine 2 to work along with Zend Framework, there are already tons of tutorials that talk about how to do that, if you want to check how I did it, it’s all in my git repository link at the end of the article.

Regardless where you decide to store your models, if you’re using Doctrine 2, you’re probably end up having a Entity (or Entities) folder, which contains your Entities (dough!) and a folder called Proxy (or Proxies) with the proxies generated by doctrine for internal use.

A basic example would be having a User entity that is related to a Languages entity in a OneToMany relationship where each user can speak more than one language. Let’s see how you’d define this User Entity and its properties first:

namespace Federico\Entity;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Description of User
 * @Table(name="users")
 * @Entity(repositoryClass="Federico\Entity\Repository\UserRepository")
 * @author Federico Mendez
 */
class User {

    /**
     * @var integer
     * @Id @Column (name="id", type="integer", nullable=false)
     * @GeneratedValue(strategy="AUTO")
     *
     */
    private $id;
    /**
     * @Column(type="string",length=60,nullable=true, unique=true)
     * @var string
     */
    private $email;
    /**
     *
     * @param \Doctring\Common\Collections\ArrayCollection $property
     * @OneToMany(targetEntity="Languages",mappedBy="user", cascade={"persist", "remove"})
     */
    protected $languages;

    public function __construct () {
        $this->languages = new \Doctrine\Common\Collections\ArrayCollection();
    }

    //... here you would have all your getters and setters (DO NOT USE MAGIC METHODS)

   /* Languages methods */
    public function setLanguages ($languages) {
        $this->languages = $languages;
        return $this->languages;
    }

    public function getLanguages () {
        return $this->languages;
    }

    public function hasLanguage (Languages $language) {
	$languages = array();
	foreach ($this->getLanguages() as $arrMember) {
		$languages[] = $arrMember->getLanguageName();
	}
	if (in_array($language->getLanguageName(), $languages))    //check if the supplied language is to be removed or not
	    return true;
    }

    public function removeLanguage (Languages $language) {
        $this->languages->removeElement($language);
        $language->unsetUser();
    }

    public function addLanguage (Languages $language) {
		$language->setUser($this);
		$this->languages[] = $language;
    }
    /* end Languages methods */
}
Source: Doctrine 2

There are already a couple of gotchas in here so let’s try to keep this organized. The first thing you’ll notice are all those weird comments in the code. This is the way in which you tell Doctrine that you’re working on such and such table and that this field is of this or this type, however, there’s one property in particular which you won’t be able to figure out at first glance:

Array Collections:

If you pay closer attention to the definition of $languages you’ll see it’s defined as an ArrayCollection. An ArrayCollection is a Collection implementation that wraps a regular PHP array and Doctrine always uses them for many-valued associations. In this case $languages is defined as a @OneToMany which leads me to…

@OneToMany:

In Doctrine, when you’re doing association mapping, both sides are declared… in the User entity you define $languages as mapped by the $user property in its target entity “Languages” (which will be the class name for that entity). In this second entity, the relationship is going to be set backwards:

    @ManyToOne(targetEntity="User", inversedBy="languages")

The rest of the language methods contained within the User entity, will be used later on in the UserService, which I will proceed to detail in the second part of this tutorial.

Another thing to bear in mind is the __construct method. Doctrine recommends that you initialize any properties that you’ve set as such as an empty ArrayCollection in the construct method, otherwise getLanguages() would only return an instance of Doctrine\Common\Collections\Collection.

I’ll be talking about entity services in the second part of this tutorial… in the mean time check my github repository for the rest of the code.

Did you find this article helpful?

  • yes
  • no
  • enlightening
See results without voting

Comments

No comments yet.

Submit a Comment
Members and Guests

Sign in or sign up and post using a hubpages account.



    Like this Hub?
    Please wait working