PHP 5.3: Why We’re All Late to the Party

Posted by Nessa | Posted in uncategorized | Posted on 27-05-2010


It’s been almost a year since the PHP 5.3 branch was released to the PHP community, and yet we’re all still in the shadow of PHP 5.2.  If you’re just a faithful customer wondering why your host isn’t getting with the times, I’ll tell you exactly why: We don’t stock enough diapers to keep up with that ish.

Let me talk about you, the common website owner, that runs a simple Drupal or WordPress site.  You didn’t sign up with your host to go around in circles over compatibility problems that could have been avoided by your host doing a little research. As a programmer, I would hold it to any site owner to check their site’s requirements and the offerings of their host before they unnecessarily waste a lot of time and money, but as a system administrator I frown upon shared hosting providers offering software with known compatibility issues just to be able to advertise as the “latest and greatest”. The latest isn’t always the greatest, and it won’t be until the community catches up with what the greatest has to offer.

I’ve had numerous discussions with my superiors about whether to upgrade to PHP 5.3, and the end result is pretty much the same – we’re just not ready. And neither are our customers, or the developers of the applications they use.  And trust me – this is normal. We all went through the same thing when PHP 4.2 came out, and again with PHP 5, and again with PHP 5.2.  That being said, this is why all the good hosts are now also holding off jumping on the PHP 5.3 bandwagon:

  • Lack of compatibility:  Many open source applications and frameworks (such as Drupal, Joomla, Magento, and even parts of WordPress) are not fully compatible with PHP 5.3 yet
  • No Zend Optimizer or Zend Guard support
  • It’s not required for PCI compliance yet, which is one of the main reasons why hosts upgrade PHP on their servers

PHP 5.3 does have a lot of new features and functions to offer, and it will eventually wiggle its way into mainstream hosting -  it’s just not ready for the shared hosting population yet until everyone else catches up.  Most hosts (including IMH) will still offer PHP 5.3 as an optional upgrade for customers on VPS or Dedicated servers, or as an optional move to a server that has that version. In the meantime, start upgrading your applications and keep tabs on your softwares’ developers to find out when php 5.3 support will be available.  PHP 5.2 will likely become obscure near the end of 2010 or early 2011 in favor of 5.3, and you should be ready when it is.

Command Line PHP: Part 3

Posted by Nessa | Posted in uncategorized | Posted on 25-05-2010


This is part third and final part in my PHP command line tutorial series. If you didn’t see parts 1 and 2:

Command Line PHP: Part 1

Command Line PHP: Part 2

Command Line PHP: Part 2

Posted by Nessa | Posted in uncategorized | Posted on 21-05-2010


This post is continuing on my three-part series on command line PHP programming. Missed part one? It’s right behind you. This part will go over command execution and processes.

Command Line PHP – Part 1

Posted by Nessa | Posted in uncategorized | Posted on 18-05-2010


PHP isn’t just for websites anymore. In fact, almost every script I’ve written to perform server-side functions is either written in bash or PHP, rather than Perl or Python as preferred by my colleagues. It’s a common belief that PHP isn’t suited for CLI programming since it’s mainly used in web applications, but PHP has over a hundred functions specifically intended for system management.

These kinds of posts can be rather lengthy, so I’m making this into a series with three parts.  Part 1 will go over the basic filesystem functions. You can find a complete listing here, but I’ll just go over a few of the more important and common ones.

Simple API Writing, Part I

Posted by Nessa | Posted in uncategorized | Posted on 09-02-2009


A lot of people don’t realize how easy it is to write an API with PHP. It really is as easy as having a simple PHP script accepting GET variables, and when you add in some security, you can pretty much do anything you want with a single script that accepts variables from any authenticated source.  So a little while ago I posted about the new cPanel XML API and how to integrate that with your own scripts – well now, I’ll use that as an example to show you how to write an API for their API, a.k.a, an API connector.   Though in real applications you wouldn’t need an API, all you’d need is a PHP script that accepts GET or POST input to perform some kind of action. In this example, we’ll have a script that automatically adds DNS zones to a nameserver that runs cPanel as well.

Most APIs do the same thing – you have a script, then that script accepts post/get variables, then does something.

The Interface (addzone.php):

You guy remember the one I posted a while back – well, we’ll use the same one only a tad different.  This is the script that runs statically on the server, which accepts the variables passed through the URL:

// API for adding a DNS zone to ns cluster
$isinclude = “1″; // specifies $isinclude for xmlapi.php
// GET & POST definitions

$key = “098f6bcd4621d373cade4e832627b4f6″;
$domain = $_GET['domain'];
$ip = $_GET['ip'];

// Validation – make sure that we have the right information

if($_POST['key'] != $key){ echo “Invalid key!!”; die(); }
if(empty($domain)){ echo “Domain value missing!!”; die(); }
if(empty($ip)){ echo “IP Value missing!!”; die(); }

$theServer = “”; // the server to connect to
$apiPath = “/xml-api/adddns?domain=$domain&ip=$ip”; // the xml api path

$user = “root”; // use to connect to whm as

// ns1 hash (whm > remote access)

$rhash = “e9917f16b3fda69137192725a06b68e7
–edited out for sake of length–

// Include the API connector

// Output XML Result

echo $xmlObject->result->statusmsg . “\n”;


The file that is called via include() is the basic xml function file which constructs all of the variables from the outser script (shown above).  You can get a copy of of xmlapi.php from here, but for this example you need to comment out the output.

Now all we need to do is pass the variables that the script needs in order to know what information to process, which is $ip and $domain.  Therefore, in order to successfully call this API, you would enter the following in a browser:

This will pass the ‘domain’ and ‘ip’ variables to addzone.php, which uses the XML API to connect to WHM and add a dns zone on the nameserver  This is a problem though – what’s to keep outsiders from finding this and abusing it?  Well, there are several forms of non-interactive authentication you can use, such as:

  • Have an allow list of ips that can access the script (look up environmental variables at
  • Requiring a key or token

I generally use a key, though there are better ways to do this.  The way I’m about to show you is simple and secure, but slightly limits the way your API can be called.

First, I generated an md5 hash and defined it in the scipt (remember $key = “098f6bcd4621d373cade4e832627b4f6″; ?).  Then all I need to do is make sure that key is used whenever I call the API. Notice that in addzone.php it’s defined as a POST variable?  That is mainly for preference but you can just as easily make it a GET variable and just add it to your URL line.  Here I want it to be posted, so I can call the API through cURL as follows:

curl -k -d key = “098f6bcd4621d373cade4e832627b4f6

And there you have it! A very simple way to write an API using POST and GET.

Alternative PHP Caching FTW

Posted by Nessa | Posted in uncategorized | Posted on 27-06-2008



We get a TON of requests for the PHP APC pecl module because after having adopted suPHP into our configuration, eAccelerator is worthless. It’s quick to install, and especially if you’re running suPHP or phpsuexec, each user can maintain their own settings within their local php.ini without me having to do anything — basically the best thing that a lazy system admin can ask for.

Soooo, here’s how you install it:

tar -xvzf APC-3.0.17.tgz

./configure && make && make install

Then just add “extension=/” to your php.ini and you’re done. With PHP under Apache this will load the APC module for everyone, but for suPHP users you’ll need to add it to their php.ini which will also allow them to modify their own APC settings. These are the ones I recommend using:

apc.enabled = 1
apc.shm_segments = 1
apc.shm_size = 30
apc.optimization = 0
apc.ttl = 7200
apc.user_ttl = 7200
apc.num_files_hint = 1000
apc.mmap_file_mask = /tmp/apc.XXXXXX

Now, if you want to get even sexier with it I came across this little tool that monitors the performance of APC on your server.

Sexifying WHM with XML API

Posted by Nessa | Posted in uncategorized | Posted on 07-06-2008



I don’t know about you other cPanel system admins out there, but I find WHM to be very useful for the more advanced and time-consuming tasks, such as installing SSL certificates. However, the easy stuff like changing an account’s package and resetting passwords is a royal pain in the ass as far as convenience is concerned when you have to log into WHM, list accounts, and make whatever change.

I recently became favorable towards the WHM XML API functionality which will let me do a majority of the everyday account-related tasks from command line without ever opening my browser, which is a lot easier when managing thousands of users across multiple servers. Below are a couple scripts I’ve put together using the XML API from a base script in the cPanel forums:

Change account password

Change account package

Both are run via command line, and the arguments passed to the PHP script as variables. For example, to change an account’s password:

./chacctpass myuser mypass1234

Customizing these scripts to perform different functions is easy via the following steps:

- change if ($argc != 3) to the number of command line arguments you wish to pass to the script plus one. In the above example there are two arguments and since the script name counts, add one and that makes 3.

- in the section where the arguments are assigned to variables (like $cpuser, etc), name your variables. The first one should have an array value of 0, then 1, 2, etc.

- edit the usage example, which will come up if the required number of arguments is not provided…you can add any text you like

- if you’re using a hash (which is more secure than user/pass authentication), go fetch your remote access key from WHM and put it in the $hash value within quotes, format intact. Otherwise, put in your WHM user’s username and password

- change the $server variable to your server’s hostname

- change $apipath to the WHM path for the function you are using. You can find a whole list of them here, and most will give you the path to use in the examples sections. In the API path, insert your variable names where the values are suppose to be. For instance:

$apiPath = “/xml-api/passwd?user=myuser&pass=mypass1234″;

Would be:

$apiPath = “/xml-api/passwd?user=$cpuser&pass=$newpass”;

In the header section, uncomment whichever $header .= “Authorization: line that matches your authentication method (user/pass or hash)

Once you’ve configured your API script, chmod to 700 and run from the command line as show in my example. It’s better to lock down the script by changing its ownership only to the user that will be using it, and not giving read, write, or execute permissions to anyone else.

Note: for these scripts to work you have to have PHP compiled with OpenSSL support, otherwise change the socket variables to http over port 2086.

Moving Towards PCI Compliance with cPanel

Posted by Nessa | Posted in uncategorized | Posted on 14-04-2008


See also:

Those of you who are server admins or use certain merchant services know what I’m taking about — it’s that dreaded security scan that picks apart your server to tell you everything that it thinks is wrong, assuming you have the knowledge or access to fix it: yes, the PCI scan. PCI compliancy is a somewhat new procedure used by security companies and financial institutions to measure the security of a webserver that collects and stores sensitive information. The reasons for getting a scan vary, but are most commonly for legal reasons or just the assurance that your server is subject to certain vulnerabilities.

After dealing with 2-3 PCI scans a week for the last year, I’ve put together a common procedure for how to make your server compliant to current PCI standards. Note that each scan company is different and may report other issues, and if you’re using ControlScan then, well, I feel sorry for you. I’m also assuming that you are on a Linux server running cPanel and LAMP.

Step 1: Make sure you have a firewall

PCI scans are nazis about unjustified open ports, so only open the ones that you need in order for services to run effectively. Manually configuring iptables is a pain in the ass, so I recommend using APF or CSF (if you have cPanel) and then configuring the allow rules to only allow ports for active services.

Note that both indicate the opening of cPanel ports 2082, 2095, and 2086, but some scans will complain about these being nonsecure. If that is the case you can configure within WHM to only use the secure ports, then remove the nonsecure ones from the firewall so they can’t be accessed. You should also close MySQL port 3306 for external hosts and allow them on a per-IP basis to anyone other than localhost has to be allowed.

Step 2: Update your system

This is an obvious one, but you’d be surprised how many people still have old packages installed on the server. With cPanel, running /scripts/upcp will usually update the vital system software as long as you have your update configuration in WHM set to allow it, but otherwise I would recommend doing a yum update, up2date, or whatever else you use to manage packages to make sure everything is up to date.

Nowadays old versions of MySQL, PHP, and Apache are no longer squeezing through either, so you need to upgrade to at least MySQL 4.1.22, PHP 5.2.5, and Apache 1.3.39 (some scans will want Apache 2.0.x).

Step 3: FIx OpenSSL

If you did a package update this was probably already taken care of, but if you installed via source you need to make sure you’re using at least 0.9.7j, which is the oldest version that most PCI scans allow. You can get your sources from here, and it may require a recompile of Apache and other services that use it. To check your OpenSSL version, type ‘openssl‘ from your SSH prompt and then type ‘version‘.

Note to Redhat/Fedora/CentOS users: If you’re running a somewhat recent version of your OS your openSSL version probably is something like 0.9.7a, but due to Redhat backporting this may be a false-positive. If you’re on any Redhat-based distribution, just tell your scan company and they’ll bypass OpenSSL checks.

Step 4: Check your SSL certificates

In order to pass a PCI scan your server must have at least one SSL certificate signed by a recognized certificate authority, and any services using SSL need to be using a certificate as well. Go cough up $30-$100 and buy a decent 264-bit SSL certificate and install it not just for Apache, but also for all of your active services. WebHost Manager has a section for installing service SSL certificates to make this process easier.

Step 5: Disable SSLv2 and other weak encryption methods

This one always gets me, because there is no way to disable SSLv2 for everything at once, at least not one that I know of. What makes this part the worse is that not all services support the choosing of SSL protocols and ciphers, but luckily unless you are using ControlScan the ones that don’t are probably not going to show up. Here’s how you do it for common services that are reported:


Add these lines to your httpd.conf (you may to add them to each secure vhost as well):

SSLProtocol -ALL +SSLv3 +TLSv1

POP3 and IMAP:

Edit the following files:


Comment out the existing TLS_CIPHER_LIST line and replace it with the following and restart courier-imap:



Add the following to exim.conf:

tls_require_ciphers = ALL:!aNULL:!ADH:!eNULL:!LOW:!EXP:RC4+RSA:+HIGH:+MEDIUM:!SSLv2

For other services that might be on your system, take a look at this guide.

Step 6: Disable mod_userdir (or whatever cPanel is calling it nowadays)

If you are able to go to http://yourserverip/~yourusername, then you have mod_userdir enabled and the scan will probably complain. You can disable this in WHM under Security Center > Apache mod_userdir Tweak, or in httpd.conf add “userdir disabled user1 user2 user3 …etc”

Step 7: Put Apache in incognito mode and disable the bad stuff

If you try to get an Apache error (like a 404 error), the footer of that page probably contains more information that you may want to share about your Apache setup. You can disable this in your httpd.conf by adding these lines:

ServerSignature Off
ServerTokens Prod
FileETag None

You can read more about these here.

Another thing that some scans report is the use of 413 errors. You should add this line to httpd.conf as a workaround:

ErrorDocument 413 /index.php (or any other file)

Just about all scans will complain if the ‘trace’ and ‘track’ apache methods are enabled on your server. You can fix this by adding these lines to your Virtualhost entries or .htaccess files:

RewriteRule ^.*$ - [F]

You should also disable directory indexes, which can be done most easily in your cPanel’s index manager. Directory indexes allow the listing of files inside folders that do not have an index page. You can also disable these in your .htaccess files:

Options All -Indexes

Ending notes

Really, it doesn’t matter how secure your server is if your web application scan is poorly programmed, so your server should not be the ending point in security. Some PCI scan companies are able to detect common vulnerabilities in web applications, but you should take the extra steps to stay ahead of the game and update your site software on a regular basis.

The [pretty much] Complete Guide to Installing ffMPEG and Audio Binaries

Posted by Nessa | Posted in uncategorized | Posted on 07-01-2008


I know you’ve provably seen a lot of guides on how to install ffMPEG, but I’ve noticed that most of them are incomplete and don’t cover the possible issues that can arise during installation. I’ve installed ffMPEG on dozens of servers and have devised a standardized procedure on what I feel is the best way to perform this installation.

This walkthrough has been tested on systems running Redhat 9, RHEL 4, and CentOS 4.5 and it may also work on other distributions and versions. Our servers also run cPanel 11, but this is in no way required in order to install ffMPEG. I assume at this point that you have root access and that yum (or another similar package manager) is installed.

ffMPEG commonly consists of and includes the following software:

- Essential / MPlayer
- FLVtool2 (Requires a Ruby Core)
- LAME MP3 Encoder
- php-ffMPEG
- ffMPEG
- libOgg
- libvorbis

To start out, enter into a temporary source directory and download all the binaries:

cd /usr/src

*These are the latest stable versions at the time this article was written. If you are unable to download any of the above, you’ll need to visit the distributor’s site and download the latest stable version available.

Now extract everything:

bunzip2 essential-20061022.tar.bz2; tar xvf essential-20061022.tar
tar zxvf flvtool2-1.0.6.tgz
tar zxvf lame-3.97.tar.gz
bunzip2 ffmpeg-php-0.5.0.tbz2; tar xvf ffmpeg-php-0.5.0.tar
bunzip2 MPlayer-1.0rc2.tar.bz2 ; tar -xvf MPlayer-1.0rc2.tar

Create and import the Codecs directory:

mkdir /usr/local/lib/codecs/
mv essential-20061022/* /usr/local/lib/codecs/
chmod -Rf 755 /usr/local/lib/codecs/

Install Subversion and Ruby

yum install subversion
yum install ruby  (If you're on cPanel you can alternatively use /scripts/installruby)
yum install ncurses-devel

Get ffMPEG and MPlayer from SVN:

svn checkout svn:// ffmpeg
svn checkout svn:// mplayer

Install LAME:

cd /usr/src/lame-3.97
./configure && make && make install

Install libOgg and libVorbis:

yum install libogg.i386
yum install libvorbis.i386
yum install libvorbis-devel.i386

Install flvtool2

cd /usr/src/flvtool2-1.0.6/
ruby setup.rb config
ruby setup.rb setup
ruby setup.rb install

Install MPlayer:

cd /usr/src/MPlayer-1.0rc2
./configure && make && make install

HTML Email Template Pack - PC Version

Install ffMPEG:

cd /usr/src/ffmpeg/
./configure --enable-libmp3lame --enable-libvorbis --disable-mmx --enable-shared
make && make install

This is the typical configure line that I use, but you can customize this to what you need. For available configure options, type ./configure –help. Your custom configuration may require the installation of additional software on the server.

ln -s /usr/local/lib/ /usr/lib/
ln -s /usr/local/lib/ /usr/lib/
ln -s /usr/local/lib/ /usr/lib/
ln -s /usr/local/lib/ /usr/lib/
ln -s /usr/local/lib/ /usr/lib/

You may get an error about a library path not being found, if so, run

export LD_LIBRARY_PATH=/usr/local/lib

If this is being installed on a dedicated server, you might also get an error about the /tmp directory not be executable, which is common when installing on a dedicated server with a separate /tmp partition mounted noexec. In this case, you will need to create a tmp dir in the ffmpeg folder and use that as the tmp disk for now:

mkdir tmp
chmod 777 tmp
export TMPDIR=./tmp

Then run the configure command and set the TMPDIR variable back.

export TMPDIR=/tmp

Install ffMPEG-php

cd /usr/src/ffmpeg-php-0.5.0/
./configure && make && make install
ln -s /usr/local/bin/ffmpeg /usr/bin/ffmpeg
ln -s /usr/local/bin/mplayer /usr/bin/mplayer

When the installation is complete, it will give you a long path to the shared libraries. This needs to be copied to the php.ini as so:


or in most cases where the extension_dir variable is set, just do:


The ‘no-debug-non-zts-xxxxxxxx’ directory will be the one provided during installation. When this is done, restart Apache and check that the module is loaded in PHP:

/etc/init.d/httpd restart
php -r 'phpinfo();' | grep ffmpeg

Look for this:

fmpeg support (ffmpeg-php) => enabled
ffmpeg-php version => 0.5.0
ffmpeg.allow_persistent => 0 => 0

If you only get output for the ‘PWD’ variables, make sure that the extension_dir path is correct in the phpinfo file. Sometimes there are two specified, and if that is the case then the incorrect one should be commented out.

Test out ffmpeg for errors just by typing ffmpeg at the command line. The most common error is:

ffmpeg: error while loading shared libraries: cannot open...

To correct this, edit /etc/ and add the line


then save and exit.

Now run this command to reload the library cache:

ldconfig -v

You’re all done…enjoy!

Whitespace is Evil

Posted by Nessa | Posted in uncategorized | Posted on 19-12-2007


I have this recurring nightmare of PHP apps that don’t trim whitespace when entering info. As a habitual copy and paster, it would be nice if some programmers could tend to my laziness and reluctance to type. Yes, Tony, I’m talking about you. Ever hear of the trim() function? Yea, it’s the Brazilian wax of PHP you inconsiderate bastard.

$text = "some text with extra spaces ";
$trimmed = trim($text);
echo $trimmed;