Skip to content

A little pain^H^H^H^H^Java never hurt anybody

While I personally agree with some of what Luke Welling wrote in his article "PHP is not Java" for PHP Advent 2008, I also disagree with the general tone of the article and the examples he provides. The example Luke provides might be true in some respects (that it looks like Java code), but the solution offered is the best example why PHP and PHP developers are looked down on most time.

PHP is the red-headed step child (no offense to redheads, I love you all) when it comes to programming, or wait, scripting languages. Because PHP is not even a programming language. ;-) For example, when I started at this co-working place most of the people did not talk to me at all. Besides Jan, who I share the room with most of the time, there are only Ruby (and Java) people on this floor. Horror, right? (Just kidding!)

And even though my crap PHP code handles much more traffic than their fancy rails, and even though I'm open to other languages as well, most people stop taking me serious when I admit to doing PHP.

The truth is out there, Mulder.

The notion of the last years has been that a lot of PHP-based open source projects worked hard to improve the quality of their code by defining coding standards, by improving the documentation and sometimes even by adding a dedicated QA team. Even though any PR is good PR, no one wants to make those headlines. The (by no means complete) list of examples include (of course) PEAR, Joomla (where this is an ongoing effort :-)), and also rather notorious projects such as phpBB and Wordpress.

PEAR & Plesk

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.

ZendFramework version requirements

As some people noticed, with the release of ZendFramework 1.7, the version requirement was bumped up from 5.1.6 to 5.2.4.

If you really care which ancient version of PHP you should install (vs. 5.2.6, 5.2.7 or 5.2.8 next week ;-)) -- here is a breakdown per component:

Zend_Acl: 5.0.0 
Zend_Amf: 5.0.0 
Zend_Auth: 5.0.0 
Zend_Cache: 5.0.0 
Zend_Captcha: 5.1.0 
Zend_Config: 5.0.0 
Zend_Console: 5.0.0 
Zend_Controller: 5.0.0 
Zend_Currency: 5.0.0 
Zend_Date: 5.1.0 
Zend_Db: 5.1.0 
Zend_Debug: 5.0.0 
Zend_Dojo: 5.0.0 
Zend_Dom: 5.0.0 
Zend_Exception: 4.0.0 
Zend_Feed: 5.1.1 
Zend_File: 5.2.1 
Zend_Filter: 5.1.0 
Zend_Form: 5.0.0 
Zend_Gdata: 5.1.0 
Zend_Http: 5.1.0 
Zend_InfoCard: 5.0.0 
Zend_Json: 5.0.0 
Zend_Layout: 5.0.0 
Zend_Ldap: 5.1.0 
Zend_Loader: 5.1.2 
Zend_Locale: 5.0.0 
Zend_Log: 5.0.0 
Zend_Mail: 5.1.0 
Zend_Measure: 5.0.0 
Zend_Memory: 5.0.0 
Zend_Mime: 5.0.0 
Zend_OpenId: 5.2.0 
Zend_Paginator: 5.0.0 
Zend_Pdf: 5.0.0 
Zend_ProgressBar: 5.0.0 
Zend_Registry: 5.0.0 
Zend_Request: 5.0.0 
Zend_Rest: 5.0.0 
Zend_Search: 5.0.0 
Zend_Server: 5.0.0 
Zend_Service: 5.0.0 
Zend_Session: 5.0.0 
Zend_Soap: 5.0.0 
Zend_Test: 5.0.0 
Zend_Text: 5.0.0 
Zend_TimeSync: 5.0.0 
Zend_Translate: 5.0.0 
Zend_Uri: 5.0.0 
Zend_Validate: 5.1.0 
Zend_Version: 5.0.0 
Zend_View: 5.0.0 
Zend_Wildfire: 5.0.0 
Zend_XmlRpc: 5.0.0

Zend_File is leading the list with 5.2.1 -- according to the mailinglist, the requirement is due to some tests (and essentially PHPUnit) which require 5.2.4. I generated the list using PHP_CompatInfo. I'll share the code later, since it'll go into a bigger project.