Introducing: the Hive

The world may not feel the need for yet another class library, but after two years with PEAR, I sure do. My attempt to unify PEAR packages with a wrapper package (which I attempted with Yawp) is essentially a dead-end. While I like the mode of operation I have developed with Yawp and DB_Table and Savant, I do not think the PEAR project is open to incorporating such a mode.

With that in mind, I am introducing a new class library for PHP5: the Hive. You can download a PEAR package of it. While this is a 0.0.1 development release, I think you will find the work well fleshed out, with a current PhpDocumentor-generated API reference. End-user documentation will be forthcoming in the next few weeks.

A Bit About My Pear Background

What is it that developers love about PEAR? Look no further than this page, which was the result of a call-for-replies on the PEAR-DEV mailing list last year. Let me add to that list my own reasons why I started using PEAR classes.

In the beginning, there was only one thing that mattered to me: unified error handling. That was it, really. If a foreign object reported an error, I knew exactly how to check for it and what format it would be in; if I needed to report an error, I knew exactly how to format it. Thus, for all its flaws, PEAR_Error was the main reason I started using PEAR classes. Add to that the PEAR DB abstraction package, which was a great labor-saver. Finally, and I have come to love this more than anything else, the PEAR installer has turned into a work of genius under the stewardship of Greg Beaver.

But I have come to believe that PEAR is too much a mishmash; even with coding style standards, the class packages operate according to widely varying styles. In addition, it is far too difficult to add a new package that I find useful but is similar in purpose to an existing package (even if the principles of their operation are widely different). For example, see the acceptance of DB_Table in the face of serious opposition and only after patient months of lobbying, as well the rejection of Savant after a knock-down drag-out (to which rejection I contributed my own fair share).

In short, I find it much too hard to do anything new or different within PEAR that is not already part of PEAR doctrine; while this brings stability, it also brings a certain morbidity. (This is not to say I’m leaving PEAR; I’m not. I am just going to concentrate my new development efforts outside PEAR, not inside it.)

Foundational Principles Of The Hive

There is one essential principle behind the Hive: comprehensibility. Developers exploring the Hive should be able to comprehend the code quickly and easily, so they can see exactly what’s going on and why. In short, I am tired of slogging through uncommented, undocumented, complex, obtuse code and packages, whether mine or someone else’s.

The principle of comprehensibility gives rise to two corollaries:

  • Simplicity of code
  • Obsessive dedication to comments and documentation

These in turn mean that it should be easy to extend and customize code in the Hive, but that has yet to be borne out.

Some Technical Notes

The Hive adheres to PEAR coding style standards and its directory structure is similar to PEAR’s.

Hive can exist with any other library set, including standalone libraries, PEAR, Horde, and so on; using the Hive does not mean you are limited to the Hive.

Hive comes with a shared-object aggregator and convenience method central class and some basic functional classes:

  • Hive_Cache for caching; both file and memcached are currently supported
  • Hive_Error for unified error handling
  • Hive_Sql for identical-operation database abstraction (will migrate to a PDO backend as PDO comes on-line)
  • Hive_Sql_Entity for representing data-type abstracted tables with automated validation and form-hints generation
  • Hive_User for user authentication and roles/groups (preferences and permissions will arrive later)
  • Hive_Valid for data validation

One major goal of the Hive is to provide shared application component backends that are not tied to any particular display mechanism. This is accomplished through Hive_Sql_Entity (the successor to DB_Table) and the Hive.conf.php configuration mechanism, along with the shared object instantiator Hive::shared (which is a successor to the Yawp::getObject technique). The initial set of application component objects will include a comment/trackback tool, a wiki page storage interface, and a blog entry storage interface.

Cliffhanger

(Not a conclusion. 😉 I’ll be writing more about the Hive in weeks to come; with any luck, this will be in the form of documentation, as well as blogging about feedback, issues, ideas, and to-do items.

As always, I’m happy to hear feedback and see trackbacks.

Update (2005-03-08)

Somebody else is using the name “Hive” for a PHP5 project. I have adopted a new name for the project: Solar. You can search this blog for other Solar entries to learn more, or visit the Solar home page.

Are you stuck with a legacy PHP application? You should buy my book because it gives you a step-by-step guide to improving your codebase, all while keeping it running the whole time.
Share This!Share on Google+Share on FacebookTweet about this on TwitterShare on RedditShare on LinkedIn

21 thoughts on “Introducing: the Hive

  1. Sounds very interesting. I tried to download the package with no luck. Unfortunately, the download link doesn’t work.

  2. Err I presume that means yawiki is going to be moving to Hive based classes as you write them then?

  3. Hi, Lukas — YaWiki will stay YaWiki. It will remain PEAR-based, with Yawp and Savant and HTML_QuickForm and all the rest. I am likely to develop a new Hive-based wiki app, though. YaWiki is far too useful to let go. 🙂

  4. Holy shit .. quite a piece of work you got yourself cut out there. Makes me ponder if it wouldnt be less work documenting all the PEAR packages 🙂

    I skimmed some of the code that where I know the PEAR variants. Code looks well commented out, although a bit too much empty lines for my taste and whitespace chars at the end of a line drives me nuts. It also becomes appearent how much work you need to put in to things before they become equally potent. Then again if things are undocumented you may have missed out on all the nice goodys hidden within PEAR packages .. and so have others.

    One thing though that jumped at me as this cant be right is the returning of an error inside the constructor. I think I saw this in the mysql driver. I doubt that PHP5 will like you doing that. Either throw an exception (which is what PHP core objects due on failure inside the constructor), set a class property with the error or simply dont do things that can fail inside the constructor.

  5. Hi, Lukas —

    Makes me ponder if it wouldnt be less work documenting all the PEAR packages 🙂

    You can bet I thought about it. Let’s say the commitment to DocBook was a barrier to me. 😉

    One thing though that jumped at me as this cant be right is the returning of an error inside the constructor.

    Yes, I’m sure you’re right there. I’ll go back and take a look; thanks for the spot-check. 🙂

  6. Seems you’re going the other way, I decided to go. I’m moving most of my development from PAT to PEAR, as long as my packages do not conflict with PEAR (like patTemplate does).

    While I understand your motivation, PEAR has one advantage, that you probably won’t have: if you decide to abandon a package, there’s always someone who’s wlling to commit at least bugfixes, and that’s something that’s important for the users of your packages.

    I downloaded your package and here are some remarks:

    1. Loose those ampersands, this is PHP5, so things like “protected function &error” are not needed anymore

    2. Why aren’t you using exceptions?

    3. You might want to implement Hive_Request_HTTP instead of Hive::get(), as this will bring more flexibility, like accessing the same scripts from the command line or SOAP… Furthermore it allows you to add validating filters (which could also be done using PHP5s filtering hook…)

    You might also be interested in taking a look at patPortal (http://cvs.php-tools.net/horde/chora/cvs.php/patPortal?login=2) which aims to be something similar, but is currently stalled. It’s a lot more abstracted, yo it could be too complex, as you mentioned, you’d like to implement something that’s easy to comprehend. But I’m making use of a lot of the cool new PHP5 features, I currently miss in the Hive. Seems you are using PHP5 only for visibility and static properties, but SPL has a lot of cool features…

    Nevertheless, good luck with your projects.

    Stephan

  7. Hi, Stephan —

    Regarding the ampersands: old habits die hard. 😉 I’ll be sure to drop them when the return is an object.

    As to why I’m not using exceptions: they seem kind of “goto”-ish to me. However, as Lukas notes above, they may be the only reasonable way to report errors in a constructor.

    For filtering GET and POST vars, there is already Hive::scrub, which gets called automatically by Hive::get and Hive::post, and which allows you to pass a set of filter functions to apply to the returned value. One of the things I want to do is to make it so Hive::scrub can use a predefined set of callbacks to apply to data, a la the proposed PHP5 data filtering tools.

    Finally, you say that in PEAR there’s always someone ready to commit a bugfix. Well, I’m always ready to commit a bugifx, too; c.f. my history on the PEAR bug tracker, as well as the mailing list history on Savant.

    Thanks for taking the time to comment, and good luck to you too. =)

  8. Very nice.

    Stephan says:

    if you decide to abandon a package, there’s always someone who’s wlling to commit at least bugfixes, and that’s something that’s important for the users of your packages.

    I wouldn’t be surprised if a community didn’t grow up around Hive. I think many Savant fans could also become fans of Hive.

  9. the Hive
    Interesting that I was just mentioning Paul Jones and his various PHP related efforts, he has just announced a new one centered on PHP5, the Hive. Unfortunetly I’m missing the initial PHP5 wave at the moment, waiting on more widespread deployment (hos…

  10. Hi,

    I wouldn’t be surprised if a community didn’t grow up around Hive. I think many Savant fans could also become fans of Hive.

    patTemplate also has a very large userbase, but it’s hard to find someone willing to actually work on the project, most people use it, but do not know how it works internally. That’s a big difference in PEAR. Still I hope that I’m proven wrong here…

    Stephan

  11. (a bit off-topic)

    While now I understand why some people think exceptions are not in the same street as PHP, I still think that these guys don’t realize the “danger” that lurks when an error that is unhandled (and unexpected) allows the code to continue running “smoothly”. With unhandled exceptions, the termination of the script (or any other custom default behavior) I think is the better way.

    Now, with exceptions you basically can do pretty much any error handling you want: doing nothing (ignoring the error), catching the error, logging the error, letting somebody “up there” handle the error, provide a default exception handler, rethrowing the exception, or any combination of them. While some of them can be done with traditional error handlers, the traditional way does impose more limits than flexibility.

    Considering that I use a custom error handler for handling my errors, so that if any error is thrown, then an error page will be display and the script terminates (this is my way, i.e. I expect my scripts to be “100% bug free” as you guys say).

    The problem is, what if I want to call a function that I *EXPECT* to throw an error in some cases? I can’t check for the returned value, since when an error happens, my custom handler would already be displaying the error page and terminates the script. I can temporarily replace/remove the custom error handler just for the sake of calling that function, but this is just too much work. I can use @ for suppressing the error (assuming my error handler obeys the error_reporting() value), but this only works for native PHP errors or trigger_error() calls, not PEAR errors or any other error objects. If I use PEAR_Error, for example, I can use a special error code (i.e. another way to say E_USER_NOTICE) so it won’t terminate the script and/or display an error code, but this requires the function to specifically say “do not handle this error in normal cases”. Actually we can also use PEAR_Error or any other error object-specific feature to handle this, but this depends on the error handling library we use.

    While with exceptions, I just use a try/catch block for that. Or omit the try/catch block if I expect no error to happen. Or include an empty catch block if I don’t want any exception terminating my script. Isn’t that the better way?

    I still see there’s no equivalent of this exception/try-catch mechanism in the traditional error handling. Since it’s a language construct, I think it’s impossible to simulate this behavior using normal functions, without crpytic and/or inconvenient constructs. Yet, I find exceptions are my way of handling errors.

    I do think traditional error handling and exceptions do complement each other. While I think exceptions should replace traditional errors, I understand that some people prefers traditional errors, i.e. they want to have so many errors displayed at once (or just an empty blank page) rather than one exception thrown then the script terminates. I don’t think a “flag to turn off exceptions” would be a good idea. But I think these guys would just need to develop a habit of wrapping their script with empty catch blocks (assuming they want the empty blank page behavior in case of exceptions).

    Why I think exceptions are such a good thing? More often than not, statements in a block of code are related to each other. When you have a statement that opens a file, the statements below would need to read the file, or write to the file, maybe in a loop, or whatever. Like this:

    $fp = fopen(‘bla.txt’, ‘w’);
    foreach ($bla as $x) {
    fwrite($fp, $x);
    }
    fclose($fp);

    Now, what happens if fopen() fails? fwrite() and fclose() will all be executed, which has no point, since the fopen fails in the first place. With exceptions, these will be a bit more like this:

    try {
    $fp = fopen(‘bla.txt’, ‘w’);
    foreach ($bla as $x) {
    fwrite($fp, $x);
    }
    } catch(…) {
    echo ‘Cannot open file!’;
    }
    if (!empty($fp)) fclose($fp);
    // … other statements

    Here… we expect the fopen will somehow fail someday, and we provide an error handler. Even if we don’t provide an exception handler, it’s “okay” since all the statements that we haven’t explicitly declared as “exception-safe” (i.e. the statements inside catch and after the catch block) will be skipped. And well, usually, your statements are not exception-safe (don’t believe me? do you really have an if ($databaseIsConnected) everytime you perform a database query???)

    Damn… I went too far again this time.

    BTW I also commented about this exception-thingy at http://www.digitalsandwich.com/index.php?url=archives/34-What-did-exceptions-ever-do-to-you.html

  12. Eh!? I posted my comment twice!??? Sorry, didn’t mean that. Something’s wrong that my browser doesn’t update the new page, I thought my comment didn’t get posted.

    And there seems to be no way of deleting my duplicate comment. :-((

  13. Triggered by the strange way my browser behaves (which is Firefox 1.0, I rarely had problems with pages) with this page, which doesn’t reload the page after I posted my comment. I tried to “debug” the page. Here’s what I got:

    GET /blog/index.php?p=105 HTTP/1.1
    Host: paul-m-jones.com

    HTTP/1.0 200 OK
    Date: Sat, 05 Feb 2005 14:43:44 GMT
    Server: Apache/1.3.29
    X-Powered-By: PHP/4.3.10
    Expires: Mon, 26 Jul 1997 05:00:00 GMT
    Last-Modified: Sat, 05 Feb 2005 14:43:44 GMT
    Cache-Control: no-store, no-cache, must-revalidate
    Cache-Control: post-check=0, pre-check=0
    Pragma: no-cache
    X-Pingback: http://paul-m-jones.com/blog/xmlrpc.php
    Content-Type: text/html
    X-Cache: MISS from cache2.jalawave.net
    X-Cache-Lookup: MISS from cache2.jalawave.net:3128
    X-Cache: MISS from proxy3.wahanamultimedia.net
    X-Cache: MISS from proksi.wahanamultimedia.net
    Connection: close

    Nice Expires header, current Last-Modified header, Pragma: no-cache, with all things configured NOT to cache the page. All proxies miss (not hit) the cache. Yet, Firefox caches this page AFTER I posted a comment!?!?!

    Dunno why… I’ll leave this problem to you. 😉 Actually it’s a small glitch… but is a bit inconvenient for me (costs me an F5 touch) 😉

  14. Hendry you are mistaken.
    You can choose to disable PEAR_Error objects. Even selectively per instance (as long as the instance extends PEAR using $foo->expectError(‘*’)) and you can also set a global error handler so that no error will ever remain unnoticed.

    The only difference with Exceptions is that they bubble out directly without having to put an if statement and that you cannot stop this bubbling effect.

  15. You seem to mix up “library” with “framework”. Of course PEAR is kinda mishmash, as many developers are working on many different things. While PEAR is supposed to be a library, it is already framework-ish regarding the installer and its infrastructure.

    But I see nothing new or exciting in Hive, yet… just Yet Another Framework (which is not supposed to be bad, but Paul, you seem to be too much driven by the “I *must* bring my code to the public” thought).


    As long as you’ve got fun! 😉

  16. Hi, Mike —

    You said I am mixing up “library” and “framework” … well, it won’t be the first time. 😉 However, I think the line blurs pretty easily; many frameworks are also libraries, and many libraries turn into frameworks pretty quickly (c.f. your note about PEAR becoming framework-ish).

    As far as Yet Another Framework, well, I must plead guilty. Bringing code to public is in my nature; I figure if it helps me, it may help others, and I live to serve.

    But *nothing* new or exciting? Come on, take a look at Hive_Sql_Entity — you can’t tell me that’s not pretty cool. (Or maybe you can. 😉

  17. Well, it may feel pretty cool writing it 😉
    But ORM is nothing new… 🙂

    Kind Regards,
    Mike

    ps: who does not like publishing ones code? 😉

  18. hi, i couldn`t find author`s email on the site, so i have to write here :]

    i`m author of project called… hive (http://hive.segfault.pl) :] my project is under developement since july last year. in the mean time i got special prize in Zend`s PHP5 Coding Contest for it (http://zend.com/php5/contest/contest.php). i would really appreciate if you added something more descriptive to the name of your project (or even change it, if you don`t feel too attached to it), because i`m afraid we might confuse some users because of two PHP projects with the same name.

    i wish you the very best with your project 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *