Basics On Doctrine CRUD Operations


 Basics On Doctrine CRUD Operations  
 


Some developers don’t start using doctrine in their application, just because, they find it a little difficult to get started(I listened so from some of my own friends too). And unluckily, I also faced some similar issue as well. I tried to start it at very early time when I am new in LAMP(Linux, Apache,MySQL And PHP Environment) and found it a little difficult to understand from the official documentation for installation and getting started smoothly. I had to take help of several online tutorials as well. On an earlier post, I have already discussed about basic usage and integration of Doctrine ORM with Codeigniter framework. Today, in this tutorial, I am going to give some php code examples and show how we can perform the doctrine CRUD operations.

Important Note: I will be using same contact entity used on the earlier tutorial. So, if you haven’t read the previous tutorial, at least get an idea of the entity structure from there.

Select/Read Operation:

To select a single entity by its identifier: This is a common need and thus doctrine made the work easy for us with its integrated function. You can pass the entity name and the identifier value to the “find” function of doctrine entity manager and it will return you a single entity object. Code is as follows:

function get_single($id)
    {
        try
        {     
            $city = $this->em->find("PdContact",$id);
            return $city;
        }
        catch(Exception $err)
        {
            return NULL;
        }
    }

Another thing, that need to be remembered here is that, the identifier value must be the value of primary key column. Suppose, you have two columns in your database table named ‘id’ and ‘email’ and you made the ‘email’ column as primary key(may be used the ‘id’ for auto increment). In this case, doctrine will search for the entity via email column in database table with the given identifier value, not the id column.

To records in a specified range and with/without constraint: This often required in case, where data are shown on a data grid and have paging like system to show only certain number of data. You may have some conditions as well, like retrieve only active members,approved messages, join more than one table etc. The example code for such cases is as follows:

 /**
     * Return list of records according to given start index and length
     * @param Int $start the start index number for the result entity list
     * @param Int $length Determines how many records to fetch
     * @param Array $criteria specify where conditions
     * @param String $orderby specify columns, in which data should be ordered
     * @return type 
     */
    function get_by_range($start=0,$length=10,$criteria = NULL,$orderby=NULL)
    {
        try
        {
            return $this->em->getRepository("PdContact")->findBy($criteria, $orderby, $length, $start);
        }
        catch(Exception $err)
        {
            return NULL;
        }
    }

Retrieve total row count for an entity in database: I didn’t find any built-in function for this purpose in doctrine(please correct me if I am wrong :) ) and thus we have to create a query for this purpose, which can be as follows(You can use DQL as an alternative as well):

    /**
     * Return the number of records
     * @return integer 
     */
    function get_count()
    {
        try
        {
            $query = $this->em->createQueryBuilder()
                            ->select("count(a)")
                            ->from("PdContact", "a")
                            ->getQuery();
            return $query->getSingleScalarResult();
        }
        catch(Exception $err)
        {
            return 0;
        }
    }

Here, I will like to clarify for your better understanding that, there are some similar function named ‘getSingle’ and ‘getScalarResult’ also. As their name implies, ‘getSingleResult’ will retrieve a single record, which have a list of properties and ‘getScalar’ will retrieve a list of records with a single property for each. So, for a single value(as like count), we should use ‘getSingleScalerResult’ method.

Insert/Create operation:

I already shared code snippet for this operation on my previous tutorial on using doctrine with codeigniter. However, that was in codeigniter format(taking the post input), so I am sharing it here again in regular format. Also, I will be writing the function in a little different way, you will know the reason very soon. Here we go:

/**
     * Save contact message to database
     * @param array $contact_form
     * @return bool 
     */
    function save_message($data,$id=NULL)
    {    
        /**
         * @var PdContact $contact
         */
        if(empty($id)){
            $contact = new PdContact();
        }
        else{
            $contact = $this->get_single($id);
        }
        $contact->setName($data["name"]);
        $contact->setEmail($data["email"]);
        $contact->setSubject($data["subject"]);
        $contact->setMessage($data["message"]);
        
        try {
            //save to database
            $this->em->persist($contact);
            $this->em->flush();
            return TRUE;
        }
        catch(Exception $err){
            return FALSE;
        }
        return true;        
    }

Here I am assuming that, you already have validate the submitted data(in either post or get method) and passing them in a $data named associative array. For insert purpose, use this as follows:

$classname->save_message($data);

class name is where these codes you are integrating. It need to be remembered, second value is not supposed to pass in this case. Then, it will assume it as null and create new entity, which will result a new insertion in database.

Update Operation:

here, actually, we won’t have to write anything new :D . The previous function will do our work by nature. to use that function for update purpose, follow this example:

$classname->save_message($data,$id);

Also, for update purpose, the above described function definition requires that, the previous ‘get_single’ method is also in the same class. When the function is called with an id parameter, it will retrieve the corresponding record from database, update the fields with new data and save it to database.

Delete Operation:

To delete an entity is some how straight cut way. Specify the entity and call ‘remove’ method on entity manager. And flush the operation. Following is the code example for such need, which I have generalized to accept either a single parameter or an array of parameter to ease deletion of single/multiple entitie(s) in the same function:

     /**
     * Delete an Entity according to given (list of) id(s)
     * @param type $ids array/single
     */
    function delete_entities($ids){
        try
        {
            if(!is_array($ids))
            {
                $ids = array($ids);
            }
            foreach($ids as $id)
            {
                $entity = $this->em->getPartialReference("PdContact", $id);
                $this->em->remove($entity);
            }
            $this->em->flush();
            return TRUE;
        }
        catch(Exception $err)
        {
            return FALSE;
        }
    }

Note the method call of “getPartialReference” . You could use simply “$this->get_single($id)” instead. However, in that case, it would retrieve the record from database and then you would perform the delete operation. And now, with getting partial reference, it won’t query the database at all. Thus, saving some query cost and optimize the performance(it would be noticeably slow if try to delete a lot of data at once).

Hope this doctrine crud tutorial will be helpful for you. Very soon, I am planning to write few more tutorials on doctrine covering other features of it. So, be in touch. Ask me if you have any questions as well. Happy coding :) .

Comments

  1. says

    God bless you dude. You saved my life. I looked from videos to official docs of the Doctrine, they all suck. But this saved me. Really great tutorial. Hope you can do same for PHPUnit too ;)

Trackbacks

Leave a Reply