Setting up an Ubuntu 10.10 laptop for LAMP development

I’m blogging this mostly for my reference as I occasionally reinstall my laptop and always forget the steps to get back to a good state.

Aim:

  • Ubuntu Linux 10.10 desktop
  • Apache 2.2
  • MySQL 5.1
  • PHP 5.2

Firstly, install Ubuntu 10.10. Make sure you opt to encrypt your home directory. While this means it’s difficult to recover contents of your home directory in the event of an OS crash, it’s also means you can sleep at night knowing that if you lose your laptop you haven’t lost your intellectual property. The system overhead for doing this is not really noticable. The down side of this is that you cannot access the files unless you’re logged on (see the bit later about the projects directory and Apache).

Now, let’s install Apache, MySQL and PHP. Note that I’m installing some extra packages that I need for my development purposes.

bob@bob-laptop:~$ sudo apt-get install libapache2-mod-php5 mysql-server php5-mysql
bob@bob-laptop:~$ sudo apt-get install php5-curl php-pear  # some extras I use
bob@bob-laptop:~$ sudo apt-get install openssh-server subversion bzr  # some extras I use

During the installation of those packages you’ll be asked for a password for the MySQL root user. I always use “root” for my convenience. You can use whatever you like. This user does not have root access to the system, but will have full access to the MySQL databases. By default MySQL only listens on the localhost interface so an insecure password like “root” is acceptable for my purposes. You’ll see later that we can shift certain databases to reside on the encrypted home directory if that’s important to you.

Set up the projects directory

I like to keep all my web stuff in a subdirectory of my home directory called projects. The full path to that will be /home/bob/projects. In order to be able to browse these projects with Apache I’ll put a symlink in /var/www (Apache’s default web root directory) to it.

Here’s a terminal session where I create the projects directory.

bob@bob-laptop:~$ mkdir ~/projects
bob@bob-laptop:~$ sudo ln -s ~/projects /var/www/projects
bob@bob-laptop:~$ ls -l /var/www
total 4
-rw-r--r-- 1 root root 177 2011-12-11 15:30 index.html
lrwxrwxrwx 1 root root  18 2011-12-12 21:25 projects -> /home/bob/projects

Great. But now if you try to access http://localhost/projects you’ll get a 403 Forbidden page. This is because Apache isn’t able to see your home directory. A small tweak will fix that.

bob@bob-laptop:~$ chmod o+x ~

Note that this command will allow any other user (of which Apache’s www-data is one) on your system to see the files in your home directory. For me this isn’t an issue as I’m the only user on my system.

Now if you revisit http://localhost/projects you’ll get a directory index instead of a 403 Forbidden page. You can now create files in /home/bob/projects (or whatever your user name is) and Apache will be able to serve them up to your web browser.

Note that because we opted to encrypt the home directory, the /home/bob directory is only mounted when bob logs in. This means that if you boot your system and try to access it over the network without being logged in, you’ll likely get a 403 Forbidden or 404 Page Not Found error for any URL in /projects. Other files can be placed in /var/www/whateveryoulike and will be accessible regardless.

Example:

bob@bob-laptop:~/projects$ cat > phpinfo.php
<?php phpinfo(); ?>

(press Ctrl-D after typing the phpinfo() line to save the file)

Now if you browse to http://localhost/projects/phpinfo.php you will get the standard PHP Information page.

Using an encrypted database

We’re not so much using an encrypted database as we are moving it onto an encrypted file system. We use the same trick that we used for Apache but we’re doing this for MySQL. Note that while it is possible to have all databases encrypted, you will need to make sure you log on first before you start MySQL. Here I will just encrypt one database:

-- Create a mysql directory in my home dir.
bob@bob-laptop:~$ mkdir ~/mysql

-- Create a sample mysql database called 'secure'
bob@bob-laptop:~$ mysqladmin -uroot -proot create secure

-- Stop the mysql service
bob@bob-laptop:~$ sudo stop mysql
mysql stop/waiting

-- Move the newly created 'secure' database to my home dir
bob@bob-laptop:~$ sudo mv /var/lib/mysql/secure ~/mysql

-- Create a symbolic link for mysql to use
bob@bob-laptop:~$ sudo ln -s ~/mysql/secure /var/lib/mysql/secure

-- Start mysql again
bob@bob-laptop:~$ sudo start mysql
mysql start/running, process 2778

-- Now access the database in the new place
bob@bob-laptop:~$ mysql -uroot -proot
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 34
Server version: 5.1.49-1ubuntu8.1 (Ubuntu)

Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> use secure;
Database changed

No errors – the connection was successful. Again the same thing applies in that you can only access this database while you are logged on.

.htaccess files (optional, but recommended)
Out of the box, Apache won’t read .htaccess files. To enable these permanently for all directories under your /var/www directory (including the project directory), edit the /etc/apache2/sites-enabled/000-default file (as root) and change line 11 to say “AllowOverride All” (instead of None).

mod_rewrite (optional, but recommended)

Also, you may want to enable mod_rewrite as many web applications use this to generate nice looking URL’s.

bob@bob-laptop:~$ sudo a2enmod rewrite
bob@bob-laptop:~$ sudo apache2ctl restart

xdebug plugin for PHP

The xdebug plugin gives you nice stack traces and formatted var_dump()s which makes it easier to develop. It also comes with breakpoints, remote debugging and a range of other things. Check out the whole shebang at http://xdebug.org/.

Installation is simple:

bob@bob-laptop:~$ sudo apt-get install php5-xdebug

Restart Apache for the change to take effect (sudo apache2ctl restart).

Enabling display of errors in your browser

By default PHP ships with display_errors = Off. This is a requirement for a production system but it will drive you nuts on a development box. When off, any errors are logged to Apache’s error_log file in /var/log/apache.

To turn it on, edit the file /etc/php5/apache2/php.ini and look for the lines like this:

display_errors = Off
display_startup_errors = Off
html_errors = Off

And change them all to “On”. Again, restart Apache for the change to take effect (sudo apache2ctl restart).

Happy developing!

Consistency

Warning: this may be the most valuable blog post you ever read.

I’ve been developing for a long time – the first programs that I first wrote that other people were using was back in 1992. At the time, I was the only one working on the code and there was no reason for others to get involved. In fact back then it seemed that we were driven by one-upmanship and sharing code was almost unheard of, unless you had to get an assignment in the next day and you had some stupid reason for not being able to complete it, then someone might take pity on your ass and bail you out. Back then, consistency wasn’t important – what mattered was whether the code ran or not. Even better if it ran and you got paid.

If there’s one thing I could share with you about my experiences over the last twenty years, I would have to say that it’s this. Be consistent.

Consider the following code:

<?php
  $query = 'select * from customer where id = 123';
  $result = mysql_query($query);
  $row = mysql_fetch_assoc($result);
  $identifier = $row['id'];
  echo $identifier;
?>

We’re fetching a row from a table and echoing out the id field. The code above doesn’t really matter, but what does matter is the inconsistency. Can you spot it?

The inconsistency is that the field in the database is called “id” and we put it into a variable called $identifier. This does not break the code, but it does mean that you have just introduced an inconsistency that will bite you.

That’s a pretty simple example, but imagine those kind of differences across an entire application, a database schema or even your whole organisation. It happens, and all too frequently.

The consistency issue isn’t a coding style issue – let me be very clear on that – it’s more a culture issue. You need to work hard to spot these inconsistencies in your organisation and nip them in the bud really early. And they may not appear in code either. You can find them anywhere from code, to documentation, to common usage in discussions in the workplace.

If you let these inconsistencies propagate you’re going to have to deal with them time and time again. Here’s a real world example: I am dealing with a system at the moment where products are identified by their SKU number (Stock Keeping Unit). This number has been referred to as the following in various places (code, documentation, wiki pages, emails etc):

  • ItemCode
  • ItemId
  • Item_Id
  • ItemID (yes, case makes a difference!)
  • ItemSKU
  • Identifier
  • Identifer (yes, misspelling of Identifier)
  • ProductId
  • ProductSku
  • SKU

The boat has sailed on that one – there is no way that this situation could be wrestled under control, you’ll have to do what you can if you come across this. But if you have the luxury of a fresh project then it’s time to gather your troops and spell it out on the board – CONSISTENCY. Drum it into your processes and procedures, your code reviews and commit messages. There’s no excuse for any inconsistency at all – especially when it will cost you in time chasing bugs because the value isn’t turning up like it should or the record isn’t saving.

If you haven’t already I highly recommend putting together some coding standards for your company – or even for yourself. And follow them to the letter. It doesn’t really matter what style of indenting you use (K&R, Allman, BSD KNF, Whitesmiths etc) – what matters is that you’re … you know what I’m going to say don’t you.

Feel free to borrow from the Turboweb Coding Standards (which in turn were based on the Drupal Coding Standards). Make sure that your new starts read your coding standards and understand them. And take time to teach them well.

Addendum: Ironically I managed to misspell the title of this blog post, I’ve now corrected it but as the link is out and about on various social media sites I can’t change that, therefore if you’re viewing this post by itself you’ll see that the URL says “consitency” :)

Installing Debian Testing from USB Key

I’ve been on the hunt for a new Linux Distribution for a while – Ubuntu 11.10 – while impressive – is too much for my seven year old laptop. I’m a bit disgusted really that with 704MB of available RAM that it doesn’t really work as snappily as a plain TTY ;) But, to be fair to Ubuntu I am running it on my work PC now as of yesterday and while there are some obvious annoyances (e.g. no panels in Unity, sometimes losing applications from the task switcher) it’s certainly a promising start. They tell me 12.04 is going to be well polished – ps. Good luck Thomi with the new job!

I’ve tried Linux Mint and again, the standard of this distribution is exceptional, but again the seven-year-old super-laptop grimaces a little too much under the weight.

This blog post is about installing Debian Testing from a USB key. I hunted around for how to do it and the answer wasn’t immediately apparent. There are tutorials that help you out by getting you to zcat a boot.img.gz onto your USB key, then copy the Debian ISO etc but this didn’t work for me. I think this was because the method was outdated and not compatible with the latest ISO.

By the way – don’t be put off by the term “testing” when it comes to Debian. The stable release may seem to be the likely choice and it is very stable – it hardly changes and is deliberately out of date. Only security updates are applied to it. This is suitable for a server environment, or for your mum if having slightly out of date applications isn’t an issue and you don’t want things changing on her. If you want a more up to date distribution that keeps pace with the latest applications, go for Debian Testing. If you want the bleeding edge latest developer release, go for Debian Unstable. You probably don’t want this though.

Anyway, back to the installation – fortunately the solution is very simple. Over here they say that the latest Debian ISO’s can be directly dd’d to a USB drive. This means that you can simply:

  1. Download the Debian Testing ISO (I chose the netinst ISO which will bootstrap me onto the network during the install process and then drag the rest off the internet as required)
  2. Plug in your USB key to your linux box
  3. Unmount it if it got automatically mounted (e.g. right click it on the desktop and choose unmount)
  4. Install it onto your USB key with the following command: dd if=/path/to/debian-testing-i386-netinst.iso of=/dev/sdd bs=1M
  5. When that has finished, boot your computer from your USB key and the Debian installer will lead you through the installation process (I’m at 87% currently)
Note that the of=/dev/sdd in bold above has to be the correct name of your USB key. You can find this out by plugging in your key and using the command “sudo fdisk -l” which will list all disk devices plugged into your computer. Look for the one that has just appeared and is the correct size.
Also note that when you issue the dd command that all information on your USB key will be overwritten. If you don’t know, the dd command can be used to take a file (generally) and write the contents of that file to a physical media (e.g. a hard drive, or a USB key) in such a way that it overwrites the entire filesystem on that device.

Meta keywords for OpenCart

OpenCart out of the box does not support meta keywords throughout the system. This is relatively easy to add, but you will need to edit each controller to enable this.

In this particular post we’ll take a look at adding support for meta keywords on the OpenCart home page. There is support already for a meta description and this can be configured in the back end of OpenCart under System » Settings » Store » Meta Tag Description.

Our aim will be to add another field beneath that called “Meta Tag Keywords” and have this reflect in the source of the homepage.

There are two parts to this: adding support for editing and storing the meta keywords in the admin, and adding the code to the front of the website so that the value will be used.

In the admin:

There are three things you’ll need to do to provide support for this in the admin.

  1. Edit the setting controller to get the value from the database.
  2. Edit the setting language file to provide labels for the form.
  3. Edit the settings template to provide the HTML for the form.

The Controller

The admin controller we want is found in the admin/controller/setting/setting.php file. Depending on which version of OpenCart you have, at about line 47 you’ll find a reference to the entry_meta_description. Simply copy that line and replace the text entry_meta_description with entry_meta_keywords.
$this->data['entry_meta_keywords'] = $this->language->get('entry_meta_keywords');
Also, a bit later in the file (search for config_meta_description) we want to add a section which will take care of collecting up the posted results of the form. Use the other sections as a guide:
if (isset($this->request->post['config_meta_keywords'])) {
	$this->data['config_meta_keywords'] = $this->request->post['config_meta_keywords'];
} else {
	$this->data['config_meta_keywords'] = $this->config->get('config_meta_keywords');
}

The language file

The language file changes are very simple. Open the file admin/language/english/setting/setting.php and add a line beneath the entry_meta_description line that says:

$_['entry_meta_keywords']     = 'Meta Tag Keywords:';

The settings template (view)

Oopen the file admin/view/template/setting/setting.tpl, find the config_meta_description and paste this after it. Note that it’s a HTML table so you’ll paste this after the closing </tr> tag of the table row for the meta description:

<tr>
  <td><?php echo $entry_meta_keywords; ?></td>
  <td><input type="text" name="config_meta_keywords" value="<?php echo $config_meta_keywords; ?>" />
    <?php if ($error_entry_meta_keywords) { ?>
    <span class="error"><?php echo $error_entry_meta_keywords; ?></span>
    <?php } ?></td>
</tr>

In the front end:

The front end changes are very straightforward. We need to make changes to the header template and the home controller.

The header template

Open the file catalog/view/theme/default/template/common/header.tpl and add the following code after the definition of the description meta tag:

<?php if ($keywords) { ?>
<meta name="keywords" content="<?php echo $keywords; ?>" />
<?php } ?>

The home controller

Finally, open the home controller (catalog/controller/common/home.php) and find the reference to the config_meta_description. Simply copy that line and change it for the keywords:

$this->document->keywords = $this->config->get('config_meta_keywords');

Complete

Now you’re done – you should be able to update the keywords in the System » Settings » Store » Meta Tag Keywords and see these in the HTML source.

In addition to this, you’ve also made a key change to the template so that in any controller you can set $this->document->keywords to whatever you like and those keywords will show in the HTML source.

 

 

PHP’s DateTime built-in class vs. Zend_Date

If you ever wanted a reason not to use PHP’s built-in DateTime class or to lie awake wondering about your code that uses it, here’s a good one. I’ve not looked into why this happens but 31st October minus one month gives 1st October. It should give 30th September. Zend_Date works in this respect:

Here’s a session showing this in action:

bob@desktop:~$ php -a
Interactive shell

php > $m = new DateTime();
php > echo $m->format( 'r' );
Mon, 31 Oct 2011 09:39:12 +1300
php > echo $m->modify('-1 month')->format( 'r' );
Sat, 01 Oct 2011 09:39:12 +1300

*cries*

bob@desktop:~$ php -a
Interactive shell

php > $m = new Zend_Date();
php > echo $m;
Oct 31, 2011 9:47:50 AM
php > echo $m->sub( 1, Zend_Date::MONTH );
Sep 30, 2011 9:48:25 AM

*correct*

 

Adjusting the screen DPI in Ubuntu

My laptop has a screen resolution of 1280×800 (it’s a 16:10 ratio widescreen). Sometimes it seems that the screen is a little crowded. Fortunately on most operating systems there’s a solution – adjust the screen DPI to get more pixels per inch.

The simplest way to do this in Gnome (the default window manager for Ubuntu) is to go into the following:

  1. System, Preferences, Appearance
  2. Click on the Fonts tab
  3. Click on the Details button in the bottom right
  4. Adjust the “Resolution” value.
The default value is 96 – I find that 84 is a good number for me, but even down at 70 the text is still very readable.

WordPress Themes