Chris Hope's LAMP Blog - The Electric ToolboxChris Hope's LAMP Blog - The Electric Toolbox

Linux Apache MySQL and PHP articles by Chris Hope

This is Chris Hope's blog for Linux, Apache, MySQL and PHP (known as LAMP) and Javascript/jQuery. I started this website several years ago with articles about web programming, Linux and Windows tips and tricks, howtos etc.

The ten most recent articles can be found below in their entirety. Navigating the sections in the right navigation (under Categories) will bring up all the other posts, and you can also use the search box at the top of the page to find what you might be looking for.

Promo codes, discount vouchers, etcPromo codes, discount vouchers, etc

Posted October 29th, 2014 in Miscellaneous Postings

This post has promo codes and discount voucher codes that I come across that I find useful and may need in the near future.

Name.com

GOFISH will get you a $9.25 .com or .net registration or renewal until November 4th 2014 at name.com

Convert StudlyCaps to words with PHPConvert StudlyCaps to words with PHP

Posted October 23rd, 2014 in PHP

I needed to convert a bunch of database fieldnames in PHP from StudlyCaps to regular words, preserving the capitalization of words (e.g. from StudlyCaps to Studly Caps), and found a useful function on StackOverflow.

The solution

I'm almost certainly going to need this function again in the future, hence posting it here on my blog as a bookmark. The solution, posted here at StackOverflow, looks like this:

function StudlyCapsToWords($StudlyCaps) {
    return implode(' ', preg_split('/(?<=[a-z])(?=[A-Z])|(?=[A-Z][a-z])/', $StudlyCaps, -1, PREG_SPLIT_NO_EMPTY));
}

Note that I've put the code into a function and changed the variable name from the original example.

This works even better than what I was after, because it preserves capitals that follow one another as a word, but then splits it on the next capital. Make sure you go to the StackOverflow page for a full description of how it works.

Some examples

echo StudlyCapsToWords('DatabaseFieldName');
echo StudlyCapsToWords('ThisIsATest');
echo StudlyCapsToWords('TextWithCAPSInIt');

The above examples output:
- Database Field Name
- This Is A Test
- Text With CAPS In It

Copy OS X Yosemite installer to prevent multiple downloadsCopy OS X Yosemite installer to prevent multiple downloads

Posted October 17th, 2014 in OSX

Apple's OS X Yosemite upgrade is available today from the App Store for free, and weighs in at about 5.1GB. After downloading it via the App Store it's possible to make a copy of the installer so you don't need to download it again for each Mac you want to run it on.

Note, do this before installing the update

After downloading the update, the App Store saves the installer to the Applications directory and starts it, as shown in the screenshot below.

Do not click "Continue" until you have copied the installer. The reason? It gets deleted after the update has finished running.

os x yosemite installer

How to copy the installer

When the screen above appears, go and find the installer and copy it before clicking "Continue".

You can navigate to the installer in Finder from the menu selecting "Go" then "Applications" or by using the Cmd+Shift+A Finder shortcut keyboard combo.

Scroll down until you find "Install OS X Yosemite" and then copy it to some other location, such as a USB stick or external hard drive.

Now go back to the installer and click the continue button.

Run the installer on a second, third, fourth, etc... machine

You can now use the same application to install Mac OS X Yosemite on another machine. This afternoon I installed it onto my MacBookPro via the App Store, copied it to an external hard drive and then installed onto my MacMini from the external hard drive.

Is this legal?

Aside from the fact the upgrade is free, a single copy of Yosemite can be installed on each Apple-branded computer that you own or control. So yes, it's legal.

Why bother?

If you have super fast bandwidth and/or low or no data caps then maybe you don't want to bother going to the fuss of copying the installer, but if your bandwidth isn't so fast or you have a low data cap and/or bandwidth is expensive, then you might want to avoid having to download this 5.1GB update more than once.

MySQL queries to get the local part and domain from an email addressMySQL queries to get the local part and domain from an email address

Posted October 16th, 2014 in MySql

This post shows how to extract the local part and domain name from an email address using MySQL. The local part is the part before the @, for example "chris" in chris@example.com.

Get the local part of the email address

Let's assume the email address column is called "email" and is in the "users" table, and that all email addresses in the database are valid with an @ in them.

SELECT SUBSTRING(email, 1, LOCATE('@', email) - 1) AS localpart FROM users;

This gets the first part of the email address up to the @ symbol, so the resulting data for "chris@example.com" would look like this:

+-------------+
| localpart   |
+-------------+
| chris       |
+-------------+
1 row in set (0.00 sec)

Get the domain part of the email address

SELECT SUBSTRING(email, LOCATE('@', email) + 1) AS domain FROM users;

This gets everything after the @ symbol, so the resulting data for "chris@example.com" would look like this:

+-------------+
| domain      |
+-------------+
| example.com |
+-------------+
1 row in set (0.00 sec)

Getting both at the same time

There's no reason why you shouldn't put both into the same query:

SELECT SUBSTRING(email, 1, LOCATE('@', email) - 1) AS localpart,
       SUBSTRING(email, LOCATE('@', email) + 1) AS domain
FROM   users

And the resulting data:

+-----------+-------------+
| localpart | domain      |
+-----------+-------------+
| chris     | example.com |
+-----------+-------------+
1 row in set (0.00 sec)

Debian releases and namesDebian releases and names

Posted October 13th, 2014 in Linux/Unix/BSD (Updated October 14th, 2014)

Debian releases are named after characters from Toy Story and are frequently referred to with the name rather than the version. This post is for my own quick reference for the version-to-name of each Debian release.

Debian version names

I've added the Toy Story character name into each row as well, because sometimes they're not completely obvious. For example, even though I've seen all the movies, it took looking up the name behind "Squeeze" to know it was the alien toys who first appeared in Toy Story 2.

Version Code name Release date Toy Story character
1.1 Buzz 1996-06-17 Buzz Lightyear
1.2 Rex 1996-12-12 Rex (the T-Rex)
1.3 Bo 1997-06-05 Bo Peep
2.0 Hamm 1998-07-24 Hamm (the pig)
2.1 Slink 1999-03-09 Slinky Dog
2.2 Potato 2000-08-15 Mr Potato Head
3.0 Woody 2002-07-19 Woody the cowboy
3.1 Sarge 2005-06-06 Sarge from the Bucket O' Soldiers
4.0 Etch 2007-04-08 Etch, the Etch-A-Sketch
5.0 Lenny 2009-02-14 Lenny, the binoculars
6.0 Squeeze 2011-02-06 Squeeze toy aliens
7 Wheezy 2013-05-04 Wheezy the penguin
8 Jessie not yet released Jessie the cowgirl
  Sid "unstable" The next door neighbour

Debian always has at least three releases in active maintenance: stable (currently Wheezy), testing (currently Jessie) and unstable, which is permanently named Sid after the boy next door in Toy Story 1 who liked to destroy toys.

Updating bash for shellshock on Debian 5 LennyUpdating bash for shellshock on Debian 5 Lenny

Posted September 30th, 2014 in Linux/Unix/BSD

If you are running Debian 5 Lenny and upgrading the distro to Debian 6 or 7 is not an option, you will need to compile bash from source, applying patches in order to secure your server against the bash shellshock vulnerability.

Patching bash on Debian 5 Lenny

Follow the instructions on this page under the "Patching older and unsupported systems" section. The page is kept up to date as new vulnerabilities are found, and shows the tests you need to run.

You will need to continue to monitor the page and apply updates as and when they become available by manually patching and compiling from source each time.

Note that the compiler may stall on "checking for working mktime..." for some time, but it will continue and finish compiling eventually.

An alternative option is to remove bash from your install and use another shell instead, obviously first making sure any shell scripts you have running will continue to function.

Warning: Skipping the data of table mysql.eventWarning: Skipping the data of table mysql.event

Posted September 29th, 2014 in MySql (Updated September 30th, 2014)

The events table was introduced to MySQL in 5.1.6 and when upgrading you will start to see the warning "Warning: Skipping the data of table mysql.event" when using mysqldump. This is not an error as such, but more to make it clear to you that something has changed.

How to include the event table with mysqldump

Use the --events flag when using mysqldump to include the events table:

mysqldump -u[username] -p --events mysql > mysql.sql

This will then suppress the warning message from the output.

How to exclude the event table with mysqldump

Use the --ignore-table flag when using mysqldump to exclude the events table like so:

mysqldump -u[username] -p --ignore-table=mysql.event mysql > mysql.sql

This will then suppress the warning message from the output.

Output when using -T / --tab flag

This is an update the day after originally writing this post. Using the above flags suppresses output when doing a straight SQL dump to file. When using the -T / --tab flag to write the data out to tabbed data files, you will still get this output when dumping events:

--
-- Dumping events for database 'mysql'
--

and this when attempting to ignore the table (which is the original message addressed by this post):

-- Warning: Skipping the data of table mysql.event. Specify the --events option explicitly.

This happens for me on two different servers which run MySQL 5.1.73. If anyone has any suggestions about how to suppress this output, while allowing other errors/warnings to be displayed, it would be greatly appreciated to prevent output from being emailed from automated backup processes.

Signature verification error when running apt-get update on Debian 6Signature verification error when running apt-get update on Debian 6

Posted September 28th, 2014 in Linux/Unix/BSD

When updating a Debian 6 server for the bash shellshock bug, I got a signature verification error message when running apt-get update. This post shows how to fix it; it may also solve the issue for other versions of Debian, but this post was specifically written when updating Debian 6 Squeeze.

Error message

After running "sudo apt-get update" this was the error message:

W: A error occurred during the signature verification. The repository is not updated and the previous index files will be used. GPG error: http://ftp.nz.debian.org squeeze-updates Release: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8B48AD6246925553

W: Failed to fetch http://ftp.nz.debian.org/debian/dists/squeeze-updates/Release  

W: Some index files failed to download, they have been ignored, or old ones used instead.

The fix

Run this to fix it:

sudo apt-get install debian-archive-keyring

Updating bash for shellshock on Debian 6 SqueezeUpdating bash for shellshock on Debian 6 Squeeze

Posted September 28th, 2014 in Linux/Unix/BSD (Updated September 30th, 2014)

An update has been made for the bash shellshock bug on Debian 6 Squeeze but it isn't available unless you update your apt sources to include the LTS repository.

Add the LTS repository

If you haven't already, add this to /etc/apt/sources.list:

deb http://http.debian.net/debian/ squeeze-lts main contrib non-free
deb-src http://http.debian.net/debian/ squeeze-lts main contrib non-free

Then run

sudo apt-get update
sudo apt-get upgrade

Check for vulnerabilities

The current checks I have found to ensure bash is not affected are as follows:

This test this will echo "vulnerable" if vulnerable:

env 'x=() { :;}; echo vulnerable' 'BASH_FUNC_x()=() { :;}; echo vulnerable' bash -c "echo test"

This test will create a file at /tmp/echo and echo the date if vulnerable:

cd /tmp; rm -f /tmp/echo; env 'x=() { (a)=>\' bash -c "echo date"; cat /tmp/echo

This one will output "CVE-2014-7186 vulnerable, redir_stack" and possibly a segmentation fault if vulnerable:

bash -c 'true <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF <<EOF' || echo "CVE-2014-7186 vulnerable, redir_stack"

A gotcha with PHP's PDO::FETCH_CLASSA gotcha with PHP's PDO::FETCH_CLASS

Posted September 26th, 2014 in PHP

PHP's PDO has a nifty way of fetching database records into an object, but there's a slight gotcha when also using a constructor which initializes the class properties.

tl;dr

Data is populated before the constructor is called. To populate data after the constructor use PDO::FETCH_PROPS_LATE i.e.:

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'className');

Longer answer

PDO's setFetchMode() allows you to specify the way data is retrieved, e.g. as an associative array, indexed array, etc or into an object.

In the following examples:
- $pdo is a connected PDO database object
- $sql is the query to run, with ? placeholders
- $data is an array of data for those placeholders
- $class is the name of the class to fetch the data into

Run a query using PDO and then fetch the result into an object like this:

$stmt = $pdo->prepare($sql);
$stmt->execute($data);
$stmt->setFetchMode(PDO::FETCH_CLASS, $class);
$object = $stmt->fetch();

This is really useful if you are implementing some sort of data object with a bunch of functions attached to it; the object returned is populated from the database and you can then call those functions.

The gotcha

In the above example, the data is populated into the object first, and then the constructor is called (if there is one). If the constructor does some sort of initialization, then values from the database may be overwritten with the same values every time.

Using the following trivial example, no matter what the value of "id" is in the database, the object will always set it to 1 after the record is loaded:

class foo {
    public $id;
    function __construct()
    {
        $this->id = 1;
    }
}

Again, this is a trivial example which you probably wouldn't do, but it illustrates the point. You might have a data object that sets default values in the constructor, which clobbers the values loaded from the database after they are set into the object.

The solution

This may not be an issue for you, and you may indeed want the constructor to run after the data is populated into the object. But if you don't, simply add PDO::FETCH_PROPS_LATE when calling setFetchMode() and the constructor will be called first:

$stmt->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'foo');

Done! I hope this was useful :)