DevHouseBerlin aftermath!

Sunday, October 4. 2009
Comments

This year's DevHouseBerlin is almost over, and this is what I managed to do.

Planet-PHP

Planet-PHP's code has been opensourced for a while and when I started setting up a planet for PEAR I wasn't exactly happy with what it did. Aside from the obvious PHP4 vs. PHP5 issues, the unfortunate lack of documentation, I don't understand why anyone wants to transform an XSL with PHP, to generate PHP. And the bottom line, it didn't work always and I didn't want to debug it any longer.

The notable features include:

  • Restructured the code to only expose what is necessary in the document root.
  • Fixed/improved configuration handling.
  • Extended/improved templating.
  • Code cleanup, where possible.
  • Fancy URLs and front controller pattern using Net_URL_Mapper! :-)
  • Webbased admin to add and remove feeds to the planet.

Long story short — the code is on github. It's semi-complete, on the list of things to do are removing the libraries which became obsolete, a (new) submit form, a cache and maybe re-writing the importer/aggregate script.

Also, kudus to Christian Weiske for contributing the admin and generally helping out. :-)

Scr.im

scr.im is a nifty service which allows you to spam protect your email address. So, for example, instead of display name@example.org on your website, you'd provide a link where people enter a captcha to see your email address. I know this is not compliant with the German law and what not, but I wrote a service wrapper for their API anyway. I'll put it online when I find time. The code is on Github, check the README for an example.

Net_URL_Mapper

I never had a chance to explore Net_Url_Mapper before and I must say, this is definitately one of the (many) raw diamonds in PEAR. Raw because its lack of documentation is not exactly helpful when it comes to adoption. Since I spent some time with the package on the Planet-PHP rewrite, I decided to contribute documentation. If you're anxious to check it out, follow this link, or wait until next week when the manual on the official website is updated.

Defined tags for this entry: , , ,

A case for PEAR and PHP4 (Or, why BC is important!)

Tuesday, September 22. 2009
Comments

Every once in someone likes to argue that PEAR is all fugly PHP4 code and why you should not use it, and instead go and use another framework or component library. Most of those people also say that they looked at or used PEAR x years ago and then act all surprised when someone else disagrees.

In related (BC) news, most people probably read my blog because of Zend Framework, and I remember that one of the reasons I sold my clients on Zend Framework was a supposedly backward compatibility and clean API. Well, a couple years later one knows it's not all that and since another BC break was argued today on one of the mailing lists and the project lead said I spread fud, I felt l needed to write something on the topic.

Facts first.

A small history of PEAR.

I don't know how old exactly PEAR is, but the manual is copyrighted since 2001 and none of the other current frameworks have been around eight — almost nine — years.

Because PEAR has been around much longer, we also have more older code than any of those PHP5-only frameworks. In comparison, Zend Framework's first stable was release in June, 2007, almost six years later.

Major versus minor releases.

A package' version consists of x.y.z.

The rules are as follow:

  • A BC break (see below) — increment x, and set y and z to 0.
  • Adding a new feature — keep x, increment y and set z to 0.
  • Fixing a bug — keep x and y, but increment z.

When someone refers to a major release in PEAR's context (and a lot of other projects such as Zend Framework, Solar and ezComponents follow this), it's one with a change in x. :-)

What is backward compatibility?

Backward compatibility, or BC, describes that a component, package or library preserves compatibility with an older versions.

Because programming itself and developers tend to evolve, PEAR tries to keep BC in all minor versions, but allows you to break compatibility to an earlier version with a new major release.

The exception to the rule is that you may break BC during alpha and beta releases before the package reaches a stable 1.0.0. Once a 1.0.0 is reached, BC may not be broken — for whatever reason.

PHP4?

Because PEAR aims to provide BC all the way, BC includes the PHP version when the package was first released. Which in turn means that of course you may make the code compatible to a later PHP release, but not without breaking compatibility to the initial release.

If you followed the above, you understand the reason why for example there is a Mail_Queue and (a soon to be) Mail_Queue2, or more importantly: why the Mail_Queue release in 2009 is still compatible to PHP4. Even though PHP4 EOL'd a while ago.

The first Mail_Queue package was released in September of 2002, the 1.0.0 stable release followed in December of the same year. Because its 1.0.0 was compatible with PHP4, we keep it backwards compatible with PHP4 until we release Mail_Queue2-0.1.0.

A principal

A lot of people argue that with the official end of life of PHP4, one should break BC anyway. But here is why you should not.

  • Even though we all love to use PHP5, there is still a lot of PHP4 in the enterprise. And like it or not, many of those apps use PEAR, and not your funky PHP5 framework.

  • How do you keep so-called necessary and unnecessary BC breaks apart? From another point of you (which is not your own), there is always a necessary BC break to fix implement something else.

  • Because there is no such thing as small or acceptable BC breaks. There are BC breaks or there are none, it's one of those things that is black and white.

BC in other frameworks

I know for a fact that ezComponents is very strict on BC. I cannot comment on Solar or Symfony, but at least in Solar's case, I'm assuming that adhere to BC as well since a some former PEAR developers are active and they also follow the PEAR Coding Standard in many respects.

Zend Framework?

A friend of mine said that if Zend Framework really kept BC, we would at 10.0.0 and not on 1.9.3.

Reasons why Zend Framework likes to break BC, even though it advertises full BC:

  • No versioning per components but per framework.

  • Missing peer review and QA leads to unstable code in a so-called stable release. (Which in turn also fakes the stability of the entire framework since it suggests that a component that was added a couple weeks ago is as stable as a component added in 2007.)

  • Because it fixes an "issue". (Biggest WTF of them all.)

The issue in question, I'm not even sure what they were trying to fix. Supposedly some developers found it too hard or did not understand how to write an adapter for Zend_Db and someone committed a fix in the 1.9 tree/branch and apparently it was OK to break BC because it was the easier way out.

I haven't updated some projects since late 1.8.x because of these BC breaks because no one can tell me what the issue is and I don't have a day to debug my application to figure out where and how it breaks. This is annoying as hell, especially since they are supposed to be tailored to the business.

On a side-note, I know of a couple components (e.g. Zend_Session) which really deserve (!) a BC break and don't get one until 2.0. And I totally get why, but why is it OK in some cases? All BC breaks fix issues!

(Btw, as I finish this post, I see an email to zf-contributor@ in my inbox where someone considers pulling the 1.9.3 release (because it obviously breaks BC). Guess I didn't spread that much FUD after all.)

Defined tags for this entry: , , , , ,

Mail_Queue: 1.2.3

Friday, September 4. 2009
Comments

Despite Mail_Queue being a PHP4-compatible package, I still like to use it on current projects because it is so easy to implement and because it gets the job done. So, over the last weeks (and especially since PHP moved from CVS to SVN :-)), I put in a little time, and especially with the help of Ken, we managed to push out the 1.2.3 release today.

What's new?

changed license from PHP to the (New) BSD license

This is good news for two reasons. Numero uno, GPL-licensed (open source) projects may bundle Mail_Queue now since the (new) BSD license is compatible with the GPL. And secondly, because (re-)releasing the code using this well-known license also gets rid off another entry barrier for commercial entities and also provides them with enough flexibility to use this code inside commercial applications.

bug #7850

This one is a tough one, and only bites you if you really adhere to backwards compatibility (aka BC) and work with an older code base. ;-)

So the story is, that with PHP4, a constructor cannot return a PEAR_Error object. PHP4 also did not have exceptions. So what we implemented as a work around it, and of course to keep BC, was to introduce a new "factory" method (which can return a PEAR_Error object). In addition to the factory, we added helper methods (Mail_Queue::getErrors() and Mail_Queue::hasErrors()) so you can check the state of the class at any time.

bug #14626

This one's self-explanatory — and the only real bugfix in this release.

minor CS fixes

To make the PEAR test suite happy. :-)

request #15049

We added a method to count emails in queue. This is currently only implemented when you use the MDB2-based backend. (Side-note: DB, MDB and creole backends are deprecated!)

request #14921

Implemented optional support to sleep() in between the sending process — to not hammer mail servers.

request #6456

Additional parameter validation to deal with PHP's loosely typed variables.

requests #16064, #16068

These are Ken's contributions to the Mail_Queue release — callback support to run a custom function whenever an email was send (or queued on the SMTP side). This could be used to provide extended monitoring and metrics on the sending process. Yay!

Installation, or upgrading

Existing install:

pear upgrade Mail_Queue

New install:

pear install Mail_Queue

There is nothing else to do. All new features are optional, and nothing requires you to touch your code base. The beauty of BC!

What's next?

I added a roadmap for 1.2.4 last night, but I'm not sure if we will really get to it. I'm trying to channel all efforts to Mail_Queue2 (which is a PHP5-only port of Mail_Queue and already contains most (if not all) the features included in Mail_Queue's 1.2.3 release. If you would like to contribute, please check out the project on Google Code and let me know your thoughts.

Defined tags for this entry: , , , ,

PEAR & Plesk

Tuesday, December 9. 2008
Comments

We frequently get users on #pear (@efnet) who happen to run Plesk and need help setting up PEAR. Now running any config interface is a blog entry by itself and when I say Plesk, I should also mention confixx and cpanel. And while I have a strong dislike for all them, let me focus on Plesk for now.

This is not a copy'n'paste howto, so make sure you double-check all steps involved. With little knowledge, you should be able to to apply all instructions to any other control panel, all you need is SSH access to the server.

I installed PEAR, but it's not working

The number one reason here is that even though the include_path is setup correctly, you also run with open_basedir. For pseudo security reasons, Plesk typically restricts open_basedir to your "document root", for example:

/srv/www/vhosts/domain.com/httpdocs
/srv/www/vhosts/domain.com/subdomains/test/httpdocs

(httpdocs is the document root.)

To verify the above, create a file called phpinfo.php in httpdocs, with the following content:

<?php phpinfo(); ?>

Look for include_path, it should contain something like /usr/share/php/pear and the open_basedir, which should contain this setting as well -- but doesn't.

Plesk internals

To understand the issue entirely, let's look at how plesk builds virtual hosts.

  • Each domain name has its own virtualhost include file, called http.include
  • The http.include is located in:

/srv/www/vhosts/domain.com/conf

  • The settings (e.g. open_basedir) are set using php_admin_flag/_value which makes overriding through ini_set() or .htaccess unsuccessful.

Solutions

  • The Annoying: Hack http.include and lose changes each time Plesk rebuilds your hosts (with each update). :-)
  • The high road: Find and edit Plesk's default template to add your PEAR installation to the open_basedir directive, or to turn off open_basedir completely. In this, case, what you're looking for is called "domain template" in Plesk, but because I'm not a Plesk user, I don't know much about it -- feel free to correct me.
  • The intermediate fix: Run your own local PEAR installation for each domain name.

Running your own PEAR installation

Running your own PEAR installation per domain name is a pretty solution, even if you managed to rid yourself of open_basedir, there are a couple strong points.

Adantages

  • Dependencies, local and trackable -- vs. global (one installation per server).
  • This allows you to use different versions of packages when required by the software you use/run.
  • You can't really have enough PEAR. :-)

Disadvantage(s)

  • More management.

Note: you may need to adjust the paths, my examples are from a Plesk install on SuSE.

Installation

This is assuming that you already installed one copy of PEAR through your system's package manager -- for example, aptitude on Debian and Ubuntu, yast on SuSE, rpm on RedHat(e) and CentOS or ports/pkg on all BSDs.

Go into your domains document root and create a pear-directory:

cd /srv/www/vhosts/domain.com/httpdocs/
mkdir my_pear
pear config-create /srv/www/vhosts/domain.com/httpdocs/my_pear .pearrc

This should create a .pearrc file in the current directory, which holds the local installations' settings.

How do we use it?

Per User

If your website user has ssh, you move the .pearrc to the users home directory, which is the directory you end up in when you login via ssh.

mv /srv/www/vhosts/domain.com/httpdocs/.pearrc /srv/www/vhosts/domain.com/

To test if the .pearrc file is being read, issue the following:

pear config-show

The screen should show paths which contain /srv/www/vhosts/domain.com.

If that is not the case, try the following:

pear -c /srv/www/vhosts/domain.com/.pearrc config-show

If it's working, continue to install the packages you need. Since this is a new installation, the first should be PEAR itself:

pear install PEAR

Or:

pear -c /srv/www/vhosts/domain.com/.pearrc install PEAR

Conclusion?

If you followed this guide, I hope it enabled you to have a different -- yet maintainable -- PEAR setup per directory. All you need is to use a different PEAR config file using the -c switch.

Further information is available on the PEAR manual.

Defined tags for this entry: , , , , ,