SitePoint Sponsor

User Tag List

Results 1 to 25 of 29

Hybrid View

  1. #1
    SitePoint Member
    Join Date
    Oct 2007
    Location
    East Sussex
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Hibernate for PHP?

    Ok so first off I know this has been asked before but it does seem to be a few years ago now.

    http://www.sitepoint.com/forums/show...hreadid=228431

    Does anyone know if there is yet something similar to Hibernate available for PHP? I have been told of Doctorine and Propel but I believe these use the Active Record design pattern
    Thanks

  2. #2
    SitePoint Evangelist
    Join Date
    Aug 2005
    Location
    Winnipeg
    Posts
    498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    As far as I can tell from reading quickly about Hibernate there is little difference in what it offers and what PHP OR/M solutions offer.

    Basic mapping between table and class and retreival operations.

    Doctrine seems really complex and bloated. The fact it includes validation at the data access layer scares me, considering I'd prefer to do that in my model layer and possibly even in the controller, this is over kill for me.

    Like wise the inheritence support makes no sense to me in a stateless environment like PHP applications usually run under.

    But I'm curious, what differences do you see in Hibernate and say Doctrine?

    Cheers,
    Alex
    The only constant in software is change itself

  3. #3
    SitePoint Member
    Join Date
    Oct 2007
    Location
    East Sussex
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I may be mistaken but it seems to me looking briefly at the docs that Doctrine uses the Active Record design pattern meaning that the Domain relies directly on the Data Access Layer and so creates dependancy. In contrast Hibernate does not have this restriction so have a far looser coupling between Domain and Data Access.

  4. #4
    SitePoint Evangelist
    Join Date
    Aug 2005
    Location
    Winnipeg
    Posts
    498
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    By domain you mean model?

    If so that is essentially why I'm being cautious about using Doctrine. I basically want a simple data object to just abstract from the database but not neccessarily the schema, which I believe is what ActiveRecord type solutions accomplish.
    The only constant in software is change itself

  5. #5
    SitePoint Member
    Join Date
    Oct 2007
    Location
    East Sussex
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Essentially what im looking for is something that i can do this with;

    PHP Code:
    $userMapper = new UserMapper();
    $user $userMapper ->Get(21);
    // do stuff with $user

    $userMapper ->update($user);
    $userMapper->flush(); 
    However it looks like Doctrine does something similar to the following
    PHP Code:
    $user $userTable->find(21);
    // do stuff with $user

    $user->save(); 

  6. #6
    SitePoint Guru dbevfat's Avatar
    Join Date
    Dec 2004
    Location
    ljubljana, slovenia
    Posts
    684
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Gee Bee View Post
    Essentially what im looking for is something that i can do this with;

    PHP Code:
    $userMapper = new UserMapper();
    $user $userMapper ->Get(21);
    // do stuff with $user

    $userMapper ->update($user);
    $userMapper->flush(); 
    However it looks like Doctrine does something similar to the following
    PHP Code:
    $user $userTable->find(21);
    // do stuff with $user

    $user->save(); 
    In Propel, this is just a convenient shortcut:
    PHP Code:
    $user UserPeer::retrieveByPk(1);
    // do stuff
    $user->save();
    // is the same as:
    UserPeer::doSave($user); 
    User::save() actually only delegates the work to UserPeer::doSave().

    Maybe Doctrine implements this somewhat similarly. The main difference (here, at least, there are others) between Propel and Doctrine is that Propel uses static mappers, which can cause headaches, while you operate with a mapper instance in Doctrine.

    regards

  7. #7
    PHP/Rails Developer Czaries's Avatar
    Join Date
    May 2004
    Location
    Central USA
    Posts
    806
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Gee Bee View Post
    Essentially what im looking for is something that i can do this with;

    PHP Code:
    $userMapper = new UserMapper();
    $user $userMapper ->Get(21);
    // do stuff with $user

    $userMapper ->update($user);
    $userMapper->flush(); 
    If you like that syntax, you will probably really like phpDataMapper. The syntax is almost exactly the same, with the same ideas behind it, like $mapper->save($user) instead of $user->save().

  8. #8
    SitePoint Member
    Join Date
    Oct 2007
    Location
    East Sussex
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    So I suppose the question still stands - does anyone know of an ORM tool like Hibernate/NHibernate which doesn't require the domain model and DAL to be coupled together like both Propel and Doctrine do?

    I suppose leading on from this is that if there is indeed not one, why not?
    Thanks

  9. #9
    SitePoint Member
    Join Date
    Oct 2005
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You could write one by subclassing the Zend_db classes, but there's nothing out of the box which does what you want. It'd be a non-trivial amount of work and it'll likely end up with application specific dependancies.

    Frankly, there are only three ORM layers of anything approaching the level of OO you're looking for (in no order): Zend_db, Propel, Doctrine. Of the three, Doctrine is most Hibernate-like, but I'm doubtful if PHP5 is upto the OO rigor necessary to actually implment a full-on Hibernate-like ORM. That said, I haven't been following the latest Doctrine development, so maybe ask the same question over there....

    That said, there's no doubt that ActiveRecord is the center of gravity in PHP-land...

    Andrew

  10. #10
    SitePoint Enthusiast
    Join Date
    Jun 2007
    Posts
    27
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    It may not be what you are looking for, but it's for sure an interesting and different approach: http://www.ezpdo.net/blog/?p=840

  11. #11
    SitePoint Member romanb's Avatar
    Join Date
    May 2006
    Location
    Berlin
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    No, there is currently nothing similar to Hibernate in PHP. Doctrine 2.0 is heading in that direction, so you might want to check it out again in the 3rd quarter of '09 at the earliest.

    There are 2 main reasons why something like that does not exist yet:

    1) Its still unclear whether PHP is up to the task in terms of the "heaviness" of such an ORM. People already love to complain about "performance" of almost all larger PHP libraries, "lightweight" seems to be the new cool buzzword.

    "WTF, i only get 15 requests/sec" with a hello world-app in symfony/cakephp/whatever?? Screw it!" Then they go on, build their "leightweight" homegrown solutions and at the end the site can be happy if it gets 10 hits a minute. Seriously, come on.

    2) Language "deficits" of PHP. One of the main things needed for "transparent persistence" is a transparent way to get data in and out of the domain objects. Java ORM solutions mostly use reflection, in PHP its only now, with 5.3 ALPHA, possible to get/set private/protected properties through reflection.

    There are other problems that make such a "transparent persistence" solution more difficult and potentially more "heavy" than ActiveRecord, like:

    - Change tracking. Hibernate/TopLink/whatever usually keep clones of all objects read from the database so they can compare them with the originals at commit time to determine the changes in the objects.

    - Lazy loading is also much more difficult without an ActiveRecord-style base class. There are many possible solutions here (virutal proxy, ghost, ...) but its nevertheless more difficult than just to intercept all calls in an ActiveRecord class ala __get/__set.

    The list of reasons goes on and on. Considering these things it should be no surprise that ActiveRecord dominates the PHP scene.

    We will see how Doctrine 2 works out, whether it will succeed or not, its nevertheless an interesting challenge. The significant speed bump of PHP 5.3 helps larger php libraries a lot, while "lightweight" libraries might not even notice the difference.

  12. #12
    SitePoint Member simensen's Avatar
    Join Date
    Jan 2009
    Posts
    1
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    There are two newish PHP projects that both aim to feel a lot like Hibernate for PHP. Outlet ORM and Repose PHP ORM.

    Outlet is older and more mature, Repose is newer with slightly different design goals (mainly that it does not rely on having getters and setters to retrieve objects, at the cost of loading more of the object graph at the same time).

    Both have similar usage and neither currently require the model classes to extend any base classes or inherit any interfaces.

    Example Outlet code.

    PHP Code:
    <?php
    $outlet 
    Outlet::getInstance();
     
    $client = new Client;
    $client->Name 'Test Client';
     
    $project = new Project;
    $project->Name 'Cool Project';
    $project->setClient$client );
     
    $bug = new Bug;
    $bug->Title "Button doesn't work";
     
    $project->addBug$bug );
     
    // inserts the project 
    // and all of the related entities
    // in one transaction
    $outlet->save$project );
    ?>
    Example Repose code.

    PHP Code:
    $session MyProjectReposeUtil::getSession();
    $userBeau = new sample_User('beau');
    $userJosh = new sample_User('josh');

    $project = new sample_Project('Sample Project'$userBeau);

    $bug = new sample_Bug(
        
    $project,
        
    'Something is broken',
        
    'Click example.com to test!',
        
    $userJosh// Reporter
        
    $userBeau // Owner
    );

    $session->save($bug); 
    2) Language "deficits" of PHP. One of the main things needed for "transparent persistence" is a transparent way to get data in and out of the domain objects. Java ORM solutions mostly use reflection, in PHP its only now, with 5.3 ALPHA, possible to get/set private/protected properties through reflection.
    Repose has a workaround for dealing with protected properties and has planned support for private properties with PHP >= 5.3. The hope is that people using PHP < 5.3 will continue to be able to use protected properties and anyone who has access to PHP >= 5.3 will be able to use private properties if they need to.

    I'll have to take a look at Doctrine 2.
    Last edited by simensen; Jan 14, 2009 at 14:25. Reason: New info.

  13. #13
    SitePoint Guru dagfinn's Avatar
    Join Date
    Jan 2004
    Location
    Oslo, Norway
    Posts
    894
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by romanb View Post
    One of the main things needed for "transparent persistence" is a transparent way to get data in and out of the domain objects. Java ORM solutions mostly use reflection, in PHP its only now, with 5.3 ALPHA, possible to get/set private/protected properties through reflection.
    I wonder, though, how PHPers became religious about visibility restrictions. In PHP 4, everything was public, and I never saw a problem in keeping the discipline of not using them except through accessors. Transparent persistence is a far more important issue with much wider implications. As is testing.
    Dagfinn Reiersøl
    PHP in Action / Blog / Twitter
    "Making the impossible possible, the possible easy,
    and the easy elegant"
    -- Moshe Feldenkrais

  14. #14
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by romanb View Post
    1) Its still unclear whether PHP is up to the task in terms of the "heaviness" of such an ORM. People already love to complain about "performance" of almost all larger PHP libraries, "lightweight" seems to be the new cool buzzword.
    That sounds more like a coder preference than anything specifically to do with php.

    Quote Originally Posted by romanb View Post
    2) Language "deficits" of PHP. One of the main things needed for "transparent persistence" is a transparent way to get data in and out of the domain objects. Java ORM solutions mostly use reflection, in PHP its only now, with 5.3 ALPHA, possible to get/set private/protected properties through reflection.
    As dagfinn mentioned, you don't have to set your properties as private. You could also set up the ORM to use getters/setters.

    Quote Originally Posted by romanb View Post
    - Change tracking. Hibernate/TopLink/whatever usually keep clones of all objects read from the database so they can compare them with the originals at commit time to determine the changes in the objects.
    There are a couple of ways to do this, storing a clone is only one of them. Any decent UoW implementation should be able to keep track of dirty/clean objects.

    Quote Originally Posted by romanb View Post
    - Lazy loading is also much more difficult without an ActiveRecord-style base class. There are many possible solutions here (virutal proxy, ghost, ...) but its nevertheless more difficult than just to intercept all calls in an ActiveRecord class ala __get/__set.
    Is lazy loading really that difficult? I've already implemented wrappers that lazy load and lazy batch load objects/collections... the classes weren't that complex, they just stored a callback to a DataMapper and executed the callback on first access. __get/__set/__call delegates to the returned value. If you really wanted to get fancy, you could implement some runtime subclassing so the wrapper would satisfy type hints.

    Quote Originally Posted by romanb View Post
    The list of reasons goes on and on. Considering these things it should be no surprise that ActiveRecord dominates the PHP scene.
    I would like to hear more of these reasons. So far I'm not sold.

  15. #15
    We're from teh basements.
    Join Date
    Apr 2007
    Posts
    1,205
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by myc View Post
    It may not be what you are looking for, but it's for sure an interesting and different approach: http://www.ezpdo.net/blog/?p=840
    Thanks for posting this. Interesting indeed. And it would complement a project I'm working on perfectly. It's refreshing to see this kind of out-of-the-box thinking on occasion.

  16. #16
    SitePoint Enthusiast
    Join Date
    Jan 2006
    Posts
    46
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Gee Bee View Post
    So I suppose the question still stands - does anyone know of an ORM tool like Hibernate/NHibernate which doesn't require the domain model and DAL to be coupled together like both Propel and Doctrine do?

    I suppose leading on from this is that if there is indeed not one, why not?
    Thanks
    Can someone educate me as to the pros/cons of the domain model and DAL being tightly/loosely coupled?

  17. #17
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by hutchic View Post
    Can someone educate me as to the pros/cons of the domain model and DAL being tightly/loosely coupled?
    In a nutshell, having a domain layer means your code is 1. testable and 2. reusable. If your domain objects don't rely on the application layer or persistence layer, then they should work equally well in a test framework as in a web application. They should also be simple to reuse in other applications, since they have minimal dependencies and only have single responsibilities.

  18. #18
    SitePoint Enthusiast
    Join Date
    Feb 2004
    Location
    Montreal
    Posts
    77
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I have come up with something that can, in no way, be compared to Doctrine or Propel. It does, however seem to work pretty well for me. It was built with ease of use in mind. I feel that things in PHP should take a minimum of lines or the interface may be cumbersome. I will show a couple of its paradigms and you may possibly find it interesting.

    PHP Code:
    // Initialize using the built-in DBA layer (I needed to run this in a non-PDO environment)
    // AFAIK, you could just as easily use FAPersistence::connect(new PDO('...'));
    $orm FAPersistence::init('mysql://user:pass@host/database');

    // Find a user the suggested way
    $user $orm->User(4);

    // Otherwise, the long way
    $user = new User(array('id' => 4));
    $user->find();

    // Note that if both ways were used on the same page request, they would nevertheless contain references to a common record object.

    // Find all users
    $users $orm->findAll('User');

    // Find users who joined in the last day
    $users $orm->findAll('User')->where('User.joined > CURDATE()-1'); // I'm not sure about the SQL, but that's not the point

    // Find all users ordered by their full name
    $users $orm->findAll('User')->orderBy('User.fullname');

    // Method chaining for simple updates
    $orm->User(4)->set('fullname''Real Name')->save(); 
    The entities returned through these queries all implement __get and __set magic methods (not shown above).

    Thoughts?

  19. #19
    SitePoint Member
    Join Date
    Mar 2009
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've been working in a project like hibernate for PHP. Been 3 years since i began and right now im having some problems with the language.
    Since it cant "runtime extend" a class, its kinda hard to implement lazy fetch proxying if you are using type hinting. Unless your server suports runkit allowing best AoP in PHP. There are other issues as well but it runs fine and after it became stable (documented in my home language Brazillian Portuguese, tho) never needed to declare SQL statements anymore, but i realize that it cant do complex reports yet. If you are interested i can provide the code and later on translated docs.

  20. #20
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by seelaz View Post
    Since it cant "runtime extend" a class, its kinda hard to implement lazy fetch proxying if you are using type hinting.
    Interfaces?

  21. #21
    SitePoint Member
    Join Date
    Mar 2009
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    even using interfaces... i assume you'll hint your parameter with the class it expects. if its a interface you'll need a proxy implementing it or make your classes implement an fw interface. I do the trick using annotations (phpDocComment parsed with regex and extending the reflection classes to suport them) and i tried hard to not force inheritance or interface implementations... seems that i have to face it cant be done like i want right now. Dont want to ask for hinting removal also....

  22. #22
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by seelaz View Post
    even using interfaces... i assume you'll hint your parameter with the class it expects.
    The point of interfaces is pretty much that you typehint to the interface, not the concrete class. You would be forcing the user to write code this way, yes, but that wouldn't be too bad.

  23. #23
    SitePoint Member
    Join Date
    Mar 2009
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I was used to do it using the concrete class since its a "bean". Thanks for your advice.
    Right now im implementing inheritance using interface (for multiple subclass support) and im thinking about using the discriminator like hibernate. it already supports one table per class and single table for entire object (no discriminator yet). Next is the basic validation using annotations like Size, NotNull etc...


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •