How to install phpBB from Subversion (svn)

It’s pretty simple to install phpBB from subversion, but I couldn’t find any instructions online, so I decided to write some.

Firstly, checkout the phpBB 3.0.x branch directory which always contains the latest stable code. You can do this with the following command:

svn checkout http://code.phpbb.com/svn/phpbb/branches/phpBB-3_0_0/phpBB forum

Where forum is the directory you want to install the forum into. Once all the code has been checked out, visit the the forum url in your web browser.

E.g. http://www.yoursite.co.uk/forum/

This will take you to an install wizard, which will guide you through the remaining steps. It’s as simple as that!

Getting Apache, PHP and MySQL to work on Leopard

Enabling PHP

If you have upgraded from Tiger, you may need to complete this step to get Leopard’s version of Apache to work with UserDir (otherwise ignore this bit):

  • Copy your old userdir configurations from /etc/httpd/users/ to /etc/apache2/users/

PHP is normally disabled by the default Apache configuration, so you will need to load up a text editor and then:

  • Uncomment LoadModule php5_module libexec/apache2/libphp5.so in /etc/apache2/httpd.conf

Once you’ve saved this, you’ll need to restart apache. The easiest way to do this is to go to System Preferences > Sharing and to turn Web sharing off then on again.

Installing MySQL

To install MySQL, just follow these steps:

  • Download the MySQL OS X disk image from a MySQL mirror
  • Mount the image, and install the main package, the startup item package, and then the preferences pane
  • Add the mysql bin folder to your path:
    sudo echo 'export PATH=$PATH:/usr/local/mysql/bin' >> ~/.bash_profile
  • If no /private/etc/php.ini exists, make a copy of php.ini.default
  • Update php.ini to point at the new MySQL socket mysql.default_socket = /private/tmp/mysql.sock – do this for both mysql and mysqli.
    mysql.default_socket = /private/tmp/mysql.sock
    mysqli.default_socket = /private/tmp/mysql.sock

Other tips if you having problems with .htaccess

Ensure the following directives are enabled (e.g. look in /etc/apache2/users/username.conf) :

Options FollowSymLinks
AllowOverride All

Installing Zend Framework on Ubuntu (Hardy)

As of the 8.04 Hardy release of Ubuntu, Zend Framework has been added to the repositories, so you can install it by simply running:

sudo apt-get install zend-framework

The package installs 17M of files into /usr/share/php/libzend-framework-php/.

Once that has finished, you then need to ensure that the framework is in your PHP include path. The best way to do this is to add the include to your PHP scripts directly, or better still via a global include file. The line you would need to add is:

set_include_path(get_include_path().PATH_SEPARATOR.'/usr/share/php/libzend-framework-php');

An example project would then look like:

set_include_path(get_include_path().PATH_SEPARATOR.'/usr/share/php/libzend-framework-php');
require_once 'Zend/Mail.php';
$mail = new Zend_Mail();
$mail->setBodyText('My Nice Test Text');
$mail->setBodyHtml('My Nice Test Text');
$mail->setFrom('test@example.com', 'Mr Example');
$mail->addTo('test@test.com', 'Mr Test');
$mail->setSubject('TestSubject');
$mail->send();

As Andy pointed out in a comment, Zend Framework is evolving quite rapidly, so if the Ubuntu repository version fails to meet your needs, then you could easily install and switch to a newer version for certain projects if you modify the include path this way.

Hosting multiple blogs on a single WordPress installation

As you can probably tell from this blog, WordPress is my favourite blogging tool. I’ve been using it for a couple of years now, and during that time I’ve been really impressed by it. So when I was recently asked if a single copy of WordPress could be used to power several blogs, I was optimistic that it would be up to the job.

And it didn’t disappoint me…

There are a number of ways you can host multiple blogs with WordPress:

  • WordPress MU (multi-user) – This is system that powers all blogs at wordpress.com, Le Monde, Harvard Univeristy etc…
  • Batch management of blogs with WP-Create and WP-Upgrade – These scripts let you install multiple blogs in parallel, however each one would get it’s own installation.
  • Modifying wp-config.php to choose a different database per hostname. This uses the standard wordpress scripts.

Since I wanted to use a standard wordpress installation, and I didn’t want to install it multiple times, I chose the 3rd option. WordPress stores most of it’s configuration in it’s database, so all you need to do is modify wp-config.php to point at a different database depending on the hostname of the site being accessed:

// Ignore the www. part of a hostname
$host = eregi_replace('^www\.', '', $_SERVER['HTTP_HOST']);

switch ($host) {
        case 'site1.co.uk';
                $db = 'site1';
                break;
        case 'site2.co.uk';
                $db = 'site2';
                break;
        default:
                header("HTTP/1.0 404 Not Found");
                exit();
                break;
}

// ** MySQL settings ** //
define('DB_NAME', $db);    // The name of the database
define('DB_USER', 'user');     
define('DB_PASSWORD', 'password'); 
define('DB_HOST', 'hostname'); 

Simply add the existing database settings code with the code above, and then create a new empty database for each blog you want to host. You will need to run the install scripts for each blog, e.g. http://www.site1.co.uk/blog/wp-admin/install.php

References:

Multi-process CLI scripts with PHP

I’ve been wanting to write a multi-process command line script in PHP for a while now, and tonight I finally got round to it. Proc_open() is really useful if you want to run a batch of commands simultaneously, such as querying the A records for multiple domain names, or running a bunch of whois commands.

Anyway, in the following example I’ll show you how to lookup the A records of a number of Google’s domain names in parallel:

You’ll notice there are two foreach loops. In the first we simply “launch” our commands, without waiting for any response from them. In the second, we iterate though and grab the output of each command in sequence until an end of file character is received.

PHP Array to Text Table Function

Have you ever wanted to display the contents of an array as a table in a command line script? If so, you will have no doubt realised that it takes somewhat longer than it’s html equivalent.

I needed to output some data in a tabular format from a PHP CLI script this week. MySQL does a good job of this with it’s own command line interface, so my first hope was that someone may have replicated this in a PHP function. After a fair bit of searching on Google, I still couldn’t find a suitable tool, so I decided to write my own.

Please note that it is not perfect; e.g. it will break with unpredictable results if the array you pass to it is not correctly formed. However, if you want a quick function that converts an array to a table, then this will certainly help:


<style type="text/css">

* {font-family:courier new;}
</style>

<?

/*
//////////////////////////////////////////////////////
// FUNCTION: draw_text_table ($table)
// Accepts an array ($table) and returns a text table
// Array must be of the form:

$table[1]['id']       = '1';
$table[1]['make']     = 'Citroen';
$table[1]['model']    = 'Saxo';
$table[1]['version']  = '1.4 West Coast';

$table[2]['id']       = '2';
$table[2]['make']     = 'Honda';
$table[2]['model']    = 'Civic';
$table[2]['version']  = '1.6 VTi';

$table[3]['id']       = '3';
$table[3]['make']     = 'BMW';
$table[3]['model']    = '3 Series';
$table[3]['version']  = '328 Ci';

//////////////////////////////////////////////////////
*/

function draw_text_table ($table) {
    
    
// Work out max lengths of each cell
    
foreach ($table AS $row) {
        
$cell_count = 0;
        foreach (
$row AS $key=>$cell) {
            
$cell_length = strlen($cell);
            
$cell_count++;
            if (!isset(
$cell_lengths[$key]) || $cell_length > $cell_lengths[$key]) $cell_lengths[$key] = $cell_length;
        }    
    }

    
// Build header bar

    
$bar = '+';
    
$header = '|';
    
$i=0;

    foreach (
$cell_lengths AS $fieldname => $length) {
        
$i++;
        
$bar .= str_pad('', $length+2, '-')."+";
        
$name = $i.") ".$fieldname;
        if (
strlen($name) > $length) {
            
// crop long headings
            
$name = substr($name, 0, $length-1);
        }
        
$header .= ' '.str_pad($name, $length, ' ', STR_PAD_RIGHT) . " |";
    }

    
$output = '';

    
$output .= $bar."\n";
    
$output .= $header."\n";
    
$output .= $bar."\n";

    
// Draw rows

    
foreach ($table AS $row) {
        
$output .= "|";
        foreach (
$row AS $key=>$cell) {
            
$output .= ' '.str_pad($cell, $cell_lengths[$key], ' ', STR_PAD_RIGHT) . " |";
        }
        
$output .= "\n";
    }

    
$output .= $bar."\n";

    return
$output;

}

$table[1]['id']       = '1';
$table[1]['make']     = 'Citroen';
$table[1]['model']    = 'Saxo';
$table[1]['version']  = '1.4 West Coast';

$table[2]['id']          = '2';
$table[2]['make']     = 'Honda';
$table[2]['model']    = 'Civic';
$table[2]['version']  = '1.6 VTi';

$table[3]['id']          = '3';
$table[3]['make']     = 'BMW';
$table[3]['model']    = '3 Series';
$table[3]['version']  = '328 Ci';


echo
'This function takes an array like this:<br /><pre>';

var_dump($table);

echo
'</pre>And converts it into a text table like this:<br /><pre>';

echo
draw_text_table ($table);

echo
'</pre>Handy for command line output!';

?>