PHP Notice: Undefined variable: _SERVER in ..

I upgraded Linux on this server a while back and in the course of that upgrade PHP was upgraded too, to version 5.5.9.

Since I had a modified php.ini it asked me to check over any new options. There were a few but I fixed anything that looked like it might break things. I saved the php.ini and let the upgrade go on.

Clearing up bugs

Some time later I saw odd notices in the PHP error log. Usually it referred to wp-comments-post.php but files outside of WordPress raised the warning too:

PHP Notice: Undefined variable: _SERVER in ..

It turns out the fix is rather easy. Jacques Marneweck on his blog posted a solution. Simply switch off “auto_globals_jit” in your php.ini and restart Apache (if required).

From the PHP manual entry for auto_globals_jit:

When enabled, the SERVER and ENV variables are created when they’re first used (Just In Time) instead of when the script starts. If these variables are not used within a script, having this directive on will result in a performance gain.

The PHP directives register_globals, register_long_arrays, and register_argc_argv must be disabled for this directive to have any affect. Since PHP 5.1.3 it is not necessary to have register_argc_argv disabled.

A bug

It looks like the bug is ancient although I’m not using APC, and the JIT compiler can be fooled if you access the super globals like _SERVER through variable variables. Sneaky!

The default for auto_globals_jit is “On” so next time you upgrade PHP keep an eye on the error log.

PHP is_numeric() vs is_int()

Some lessons you don’t forget, but this one I did because it doesn’t come up very often.

Don’t use is_int() because, as Jeremy says, it’ll lie to you. Use is_numeric() instead.

Copy the following chunk of code into a php file and run it. You’ll be surprised at the outcome:

$t = "12345";
if( is_int($t ) ) {
    echo $t . " is an int!";
} else {
    echo $t . " is not an int!";

The problem is that is_int() thinks a string of numbers is a string, not an integer. The is_int() man page has an example illustrating that but it’s easy to miss. That function should carry a public health warning!

There’s also the ctype_digit() function too but it has it’s own gotcha:

Note: This function require a string to be useful, so for example passing in an integer will always return FALSE. However, also note that HTML Forms will result in numeric strings and not integers. See also the types section of the manual.

No activity within 1800 seconds; please log in again

1800 seconds is such a long time, right?

  1. It’s 30 minutes.
  2. It’s 0.5 hours.
  3. It’s 0.0208333333 days.
  4. It’s also 5.70397764 × 10-5 years.

And it’s not long enough for me. phpMyAdmin logs you out after 1800 seconds, obviously for security reasons. That’s fine if there are other people about, if I was in an office with people coming and going, but I work from home. All I see for most of the day is my family, the radio, my messy desk, computers, and the view out the window. Time to figure out how to make that 1800 second limit a little longer or remove it altogether.

After a little digging, I discovered that extending the time limit to a day is actually quite easy. Open your phpMyAdmin’s and search for or add the following line:

$cfg['LoginCookieValidity'] = 86400;

Refresh your logged out phpMyAdmin and presuming you haven’t left it idle for 24 hours, you’ll be logged in again!

If the time limit really bugs you, you need http authentication. Look for the “auth_type” line in the and change that to “http”. phpMyAdmin won’t log you out as long as your browser is open. Perfect!

If you’re concerned about sending your MySQL username and password in the clear each time you make a request to phpMyAdmin you can either use SSL or try the “config” auth_type. Make sure you fill in the username and password fields in the config file, and secure the phpMyAdmin directory with a htpasswd file.

Is your eAccelerator cache dir still there?

While looking through this WordPress performance post I realised that eAccelerator might not be running properly on this blog. For some time I’ve noticed this site hasn’t been as quick off the mark as it used to be. Dare I say it, but it was even a little sluggish!

If you’re not familiar with it, eAccelerator is a PHP accelerator. It caches PHP bytecode and performs optimizations to make your PHP site run a lot faster.

I verified that eAccelerator was loaded and then checked my php.ini configuration. Sure enough, the eaccelerator.cache_dir directive was set to “/tmp/eacc/” and that directory was deleted the last time my server rebooted.

A permanent fix is to change the location of the cache dir. Put it anywhere the webserver can read, but don’t put it in /tmp/.

While you’re looking at eAccelerator, upgrade to the latest version, especially if you’re running PHP5.

Notes when upgrading to PHP5

I upgraded one of my servers to PHP5 this morning. Two things to watch out for:

  • The location of your php.ini may have changed. It’s probably now in /etc/php5/apache2/. You need to copy over any changes from your old one.
  • Update your libraries too such as the mysql client and the gd library. Don’t forget you can delete the old ones. apt-get install php5-mysql php5-gd will do the job of installing, the old packages have a php4 prefix.
  • WP-Cache doesn’t like PHP5 much. If you see a blank page after upgrading to PHP5, then hit reload and it loads, then WP-Cache needs to be modified. Leroy has the fix, open wp-cache-phase2.php in your wp-cache folder and change ob_end_clean() to ob_end_flush(). SImple as that!

The reason for the upgrade? I wanted to install the gd extension, but after lots of fun upgrading everything my browser tried to download every page, complaining that it was a phtml file. I chose the upgrade to PHP5 to fix it!

And finally, the reason for gd, was to get the heatmap in this wordpress click tracking plugin working. It’s like Crazy Egg and it works well, but I couldn’t get it to display a heatmap for any page other than the front page. Some of the comments on Daily Blog Tips where I found it are hilarious. They completely miss the point of using a heatmap!

Cannot load mysql extension. Please check your PHP configuration.

A friend recently had a problem configuring a new server. He installed PHP, Apache, MySQL and phpMyAdmin but when he launched it he got the following error:

phpMyAdmin – Error
Cannot load mysql extension. Please check your PHP configuration.

If you’ve installed all of the above more than once you’ll know what is more than likely wrong. The MySQL PHP module isn’t loaded. First of all, you must find your php.ini. It could be anywhere but if you create a small php file with the phpinfo(); command it will tell you where it is. Common places include /etc/apache/, /etc/php4/apache2/php.ini, /etc/php5/apache2/php.ini or even /usr/local/lib/php.ini

Edit your server’s php.ini and look for the following line. Remove the ‘;’ from the start of the line and restart Apache. Things should work fine now!


should become

Killing off PHP

Do you know why Apache processes get stuck and stop responding when serving pages on a WordPress site?

I’ve seen this happen here and on my previous host on a regular basis. I don’t know what happens. It can’t be a PHP script gone into an infinite loop because the normal Apache timeout should kill it. It’s not MySQL as a quick inspection of the process list usually shows it’s empty.

It could be plugins, some of them haven’t been written to the high standards that is expected in WordPress core. It could be some strange interaction between plugins and core code and memory limits and PHP extensions.

Whatever causes it, this will fix it. It’s brutal, it’s crude, but it’ll stop the load average going up on your box and it will ensure that every Apache child process is listening and responding. Add this to the crontab of your nobody or www-data user. Pick whichever user runs the webserver because you want to limit the damage in case something bad happens and the command malfunctions!
*/10 * * * * ps auxw|grep apache2| awk '$10 !~ /0:00/ {print $2":"$10}'|awk -F ':' '$2 !~ 0 {print $1}'|xargs kill -9 2> /dev/null
What this does is it uses the ps, grep, and awk tools to find processes that are using anything more than the minimum CPU time. It is very crude, but it works.

If you use Litespeed, then replace “apache2” with “lsphp”. I have found that this is very necessary as those processes get stuck quite often, especially in low memory situations.