A simple example

Table of Contents

A simple example

The following is a simple example that shows you how to use EZPDO to persist and retrieve your objects.

You may want to check out the tutorial that showcases more advanced features that EZPDO has after following this simple example.

Mapping

Suppose you have a class Book and you want to store it into database. You only need to insert a few lines of comments.

Annotated code

<?php
 
/**
 * Class of a book
 * @orm mysql://dbuser:secret@localhost/ezpdo
 */
class Book {
 
  /**
   * @orm char(64)
   */
  public $title;
 
  /**
   * @orm char(32)
   */
  public $author;
 
  /**
   * @orm integer
   */
  public $pages;
 
  /**
   * @orm boolean
   */
  public $is_easy_to_read;
 
  /**
   * Your regular code for the class here.
   * ......
   */
}
 
?>

See the highlighted comment lines starting with @orm? @orm is a custom tag in the comment block (DocBlock in phpDocumentor terms). This simple tag does the ORM magic!

A little explanation follows.

The @orm tag

In the class comment block, we have a line

@orm mysql://dbuser:secret@localhost/ezpdo

The orm tag associates the class Book to a Data Source Name (DSN) of the database. The tag simply means that we want the class to be mapped to a table in the database ezpdo. The name of the table is the same as the name of the class. If you want the table name to be different, you can simply write:

@orm my_book_table mysql://dbuser:secret@localhost/ezpdo

For class variable $title, we use

@orm char(64)

to map the variable to a column, which is a 64-char string column. Again if you want the variable to be mapped to a column name different than the variable name, you can write the comment like this:

@orm my_title_col char(64)

Type mapping

Databases of any breed usually support numerous column types. Experience tells us that, because of this, mapping variables into database columns is not a small task. In a deep contrast, EZPDO lets you use only a small set of data types that only has a very few types, but is considered sufficient for most of our tasks. We bet you know each of them well. Take a look at Supported data types.

Easy enough? Next we show how to make your objects into database.

Persisting

The following code snippets show you how to use EZPDO persistence manager to persist your objects to database without writing a single line of SQL code.

Get the manager

Persistence, in EZPDO, is managed by the persistence manager. So let’s get the manager and let it do the work.

// include ezpdo runtime api
include_once('/path/to/ezpdo/ezpdo_runtime.php');
 
// load config.xml (optional: not needed if it is in currrent dir)
epLoadConfig('/path/to/your/config.xml');
 
// get ezpdo persistence manager
$m = epManager::instance();

Create an object

Time to call the manger ($m) to create objects for you.

// create a Book
$b = $m->create('Book');
$b->author = "ezpdo4php";
$b->title = "The life of a bug";
$b->pages = 21;

Save object to DB

// persist the object
$m->commit($b);

And this is it! Your first object has been persisted into your database.


Note that if you enable auto_flush in your configuration, you don’t need to commit the object explicitly for it to be saved to the database. This is automatically done at the end of your script.


Retrieval

Want to find all books by the author and update their info?

Find by example

You can use an example object to find all books by author ezpdo4php.

// use an example object to find object in db
$book2find = $m->create('Book');
$book2find->author = "ezpdo4php";
 
// find all books by ezpdo4php
$books = $m->find($book2find);



You can now also use EZOQL to query objects with more flexibility.



Delete and update

Say we want to delete all books that have more than 500 pages by author ezpdo4php and mark the rest of books is_easy_to_read.

// for each book
foreach($books as $book) {
 
  if ($book->pages > 500) {
 
    // delete the thick book (> pages)
    $m->delete($book);
 
  } else {
 
    // otherwise, mark the book thin
    $book->is_easy_to_read = true;
 
    // update it in storage
    $m->commit($book);
  }
 
}

Wanna do more?

Start from here.

27 user comments

  1. EZPDO » Blog Archive » EZPDO in the last week on March 19th, 2005:

    […] ou strengthened our belief in simplicity. Many like the way to use the @orm tag to specify O/R mapping and are impressed by the ease in handling complex object relationships. Many find it easy to […]

  2. Paul H on April 16th, 2005:

    In your example:

    // use an example object to find object in db
    $book2find = $m->create('Book');
    $book2find = 'ezpdo4php'; // ***

    // find all books by ezpdo4php
    $books = $m->find($book2find);

    I think the line marked *** should really be

    $book2find->author = 'ezpdo4php';

  3. ezpdo4php on April 16th, 2005:

    Paul, thanks for pointing out the typo. It’s been corrected now. Thanks for trying EZPDO. -oak

  4. AJG on May 7th, 2005:

    Hello there,

    Many thanks for the great work on EZPDO. I worked thru the tutorial and got everything to work properly. However, I ran into a wall trying to change the Base class. I can’t find a way to specify an incremental uuid (MySQL: AUTO_INCREMENT) instead of the random one (PHP: uniqid()) provided by default. Is there an elegant way to accomplish this, perhaps thru orm tags?

    Thank you,
    –AJG.

  5. ezpdo4php on May 7th, 2005:

    Hi AJG, Thanks for trying EZPDO.

    If you create objects through the EZPDO runtime API, you don’t need to assign object id. It is auto incremented by the EZPDO core. The following snippet shows how you can get it in case you need to use it in your application.


    // create an object
    $o = epManager::instance()->create("MyClass");
    // commit object (save it to db)
    $o->commit();
    // oid is available only after object is committed
    echo $1->epGetObjectId() . "\n";

    Keep in mind that, because of object deletion, the largest object id may not be the total number of objects actually in datastore. To get the total number, use

    epManager::instance()->count('MyClass') . "\n";

    Hope this helps.

    -oak

  6. AJG on May 8th, 2005:

    Hi there!

    Wow, thanks for the prompt reply. In short, you read my mind. Those were exactly the two things I wanted to accomplish. So, since this ID is handled internally (which is great):

    1) How large can it be? I suppose this depends on the database. In MySQL, can it reach BIGINT?

    2) Is it possible to override this ID for specific objects?

    Finally, somewhat off-topic:

    3) How can I change (specify) the filename or at least location of config.xml?

    Thank you,
    –AJG.

  7. ezpdo4php on May 8th, 2005:

    EZPDO uses INT(11) for oid in MySQL. So the max oid is 10^11 - 1. It is not suggested to alter object id because doing so may make object relationships inconsistent. (You can of course have your own data member in your class to identify your objects.)

    By default, EZPDO checks if config.xml is under the current directory (where your main script is run). EZPDO is pretty flexible in this regard: you can actually place config.xml anywhere you want. If this is the case, after including ezpdo_runtime.php, don’t forget to load your own configuration.

    include_once(dirname(__FILE__) . '/../../ezpdo_runtime.php');
    epLoadConfig('/path/to/your/own/config.xml');

    By the way, you can also throw your questions into the forums for quicker (and maybe more responses) from all users.

  8. Matt B on June 17th, 2005:

    I’m loving EZPDO so far but the documentation appears to have a few typos. For example, shouldn’t the Book class at the top of the page have the extends keyword? And a constructor? Many thanks, Matt :)

  9. ezpdo4php on June 17th, 2005:

    Thanks for trying EZPDO. Agreed that we should have better docs for EZPDO. Please help us by letting us know typos you spot. We’d love more people proofread them.

    The Book class here is a simplified example (which is different from the class in Tutorial and the book-author example distributed). It’s okay not to have a constructor though.

  10. mingkit on October 4th, 2005:

    $child = $m->create(’Child’);
    $child->childName = ‘child’;
    // $child->commit();

    $toy = $m->create(’Toy’);
    $toy->toyName = ‘toyName’;
    $toy->childX = $child;
    $child->toy = $toy;
    // $toy->commit();

    $child->delete();
    I create that 2 objects do not commit and wait terminate flush
    The result is two object also record on the db
    do you feel that is problem? I observer that you call delete when it do not have oids then you only remove the object cached in epManager but do not remember to set epSetDeleted………

  11. mingkit on October 4th, 2005:

    $child = $m->create(’Child’);
    $child->childName = ‘child’;
    $child->commit();

    $toy = $m->create(’Toy’);
    $toy->toyName = ‘toyName’;
    $toy->childX = $child;
    $child->toy = $toy;
    $toy->commit();

    $child->delete();

    Why I still can get the child from “echo $toy->childX;” ?

  12. ezpdo4php on October 4th, 2005:

    mingkit, thanks for reporting the problem. we have entered a bug report. will fix it soon.

  13. ezpdo4php on October 4th, 2005:

    p.s. el (elnayaf) has fixed bug #97. please download the latest nightly.

  14. dbg on December 8th, 2005:

    typo
    # // for each boook

  15. ezpdo4php on December 8th, 2005:

    thanks for spotting the typo. fixed.

  16. Vishwanath on January 9th, 2006:

    How to test ezpdo ?

    I have installed Symfony and EZPDO , now i want to test for EZPDO how should i test it ? Please help me out.

    Thanks,
    Vishwanath

  17. Mark Meves on February 3rd, 2006:

    Having some experience with java’s Hibernate and Ruby’s ActiveRecord, from what I have seen on this page I am turned off from this solution in light of the use of the connection dsn (”url”) in the @orm tag near the class declaration.

    I see the utility of having both the table name hear and a (preferably abstract) way of representing which connection to use (useful for apps w/ multiple databases), but could you please justify the use of the full DSN here?

    This is problematic for the following reasons:
    1. From a security perspective it is a high-risk for those of you that keep your class files under DocumentRoot (”public_html”) — you risk exposing your password to the world if php rendering breaks, which it often does for example when you are trying to install new apache modules.

    2. Redundant data — you are supposed to put this DSN atop *every* class file? What about when the password (or anything else) changes in the DSN? In dozens (hundreds) of class files?

    3. What about the common scenario where you have multiple databases e.g. for testing, staging and live? You want to have the same codebase as much as possible through all these environments.

    Thanks,

    mark d0t meves at gmail d0t com

  18. ezpdo4php on February 3rd, 2006:

    great questions. in fact, you can use “default_dsn” option in the ezpdo config file (example here), which i am not sure you have gone that far to realize. the config file can be placed anywhere you’d like. this option will affect all classes that do not have their own dsn set (i.e. no dsn specified in the class level @orm tag). you change this option to target different dbs in one shot. that said, there are certainly ways to improve the security by allowing configuring complex class to db mapping in the configuration file. you can do so by injecting database config info at runtime through the class map interface. what you see in this simple example is only one way of doing the mapping. no offense, but i am turned off as well by comments based on an incomplete view. :)

  19. Gougou’s world » Blog Archive » 一个phpçš„ORM工具 on March 22nd, 2006:

    […] http://www.ezpdo.net/blog/?p=840 […]

  20. Hubert on February 1st, 2007:

    Am I wrong, or is documentation not up to date and/or doesn’t cover all features of this interesting project? For example, the only place where I found information about possibility to use unique index with orm tag is forum ( http://www.ezpdo.net/forum/viewtopic.php?pid=1698 ). I don’t see it in doc. I wonder how many other features, tricks etc is not even mentioned in doc. I must say it discourages from using ezpdo.

    And I have a question. Is it possible to edit class definition (for example add some property) and have db modified without the need to drop all tables and define all objects from the very start?

  21. Frank Topel on April 1st, 2007:

    Hmm, at first glance this looks like all attributes of my classes have to be public in order to be able to use EZPDO. Can that be true?

  22. Richard on May 9th, 2007:

    Am I wrong, or is documentation not up to date and/or doesn’t cover all features

    I noticed this too. While releases are being made quite nice and regular (well, March this year) the manual remains more than 2 years out of date! it really isn’t very encouraging. (I do love ezpdo, it would just be nice to see some more activity)

  23. ezpdo4php on May 9th, 2007:

    Ah.. that’s a bug in dwBliki, which we use to convert the manual pages from DokuWiki. For some reason, the timestamp is stuck to the first time we did the conversion. Will fix it. We do update the manual pages on a regular basis.

  24. Richard on May 9th, 2007:

    Oh cool, good to know it’s not drying up. So does that mean there is documentation on unique() and index() somewhere then? ;)

  25. QBert on June 21st, 2007:

    How about if I configure a global DSN to use on my application on it’s ezpdo config file and also I wrote a different DSN on a class, for example:

    Now, imagine you already have another application (using ezpdo or not) and you want to ’share’ the table ‘User’ to allow session integration.

    Having as a restriction to have both different databases on the same host, then would be nice if EZPDO generates a sql query using those two databases.

    Something like:


    SELECT ... FROM ezpdo_database.Book as b ... anotherDatabase.User as u ... where ...

  26. QBert on June 21st, 2007:

    How about if I configure a global DSN to use on my application on it’s ezpdo config file and also I wrote a different DSN on a class, for example:


    /**
    * @orm mysql://dbuser:secret@localhost/anotherDatabase
    */
    class User {

    /**
    * @orm char(64)
    */
    public $login;

    /**
    * @orm char(64)
    */
    public $password;

    /**
    * Your regular code for the class here.
    * ......
    */
    }

    Now, imagine you already have another application (using ezpdo or not) and you want to ’share’ the table ‘User’ to allow session integration.

    Having as a restriction to have both different databases on the same host, then would be nice if EZPDO generates a sql query using those two databases.

    Something like:


    SELECT ... FROM ezpdo_database.Book as b ... anotherDatabase.User as u ... where ...

  27. ezpdo4php on June 22nd, 2007:

    @QBert, please take a look at this post, which may be what you want.

Post your comments

XHTML: tags you can use <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>

Couldn't find your convert utility. Check that you have ImageMagick installed.