Remove index.php from your URL

17th January 2011

One thing you may have noticed with Zend Framework projects that use the baseUrl() view helper to reference CSS and other static files is that it doesn't work if the URL contains contains index.php.

Let's explain, by using code from the tutorial.

In the layout.phtml file, we link to a CSS file like this:

<?php echo $this->headLink()->prependStylesheet($this->baseUrl().'/css/site.css'); ?> 

This code uses a baseUrl() view helper that looks like this

<?php 
class Zend_View_Helper_BaseUrl 
{ 
    function baseUrl() 
    { 
        $fc Zend_Controller_Front::getInstance(); 
        return $fc->getBaseUrl(); 
    } 
}

When you go to http://localhost/zf-tutorial/ you get an page that looks like this:

Screen short of Zend Framework tutorial

However, if you go to http://localhost/zf-tutorial/index.php, you get this:

zf-tutorial_no_css.jpg

This happens because the baseURL used in the href of the CSS link in the second case is /zf-tutorial/public/index.php/css/site.css rather than the correct /zf-tutorial/public/css/site.css.

Solution using mod_rewrite

One way to fix this is to use a mod_rewrite rule in your .htaccess file:


RewriteCond %{THE_REQUEST} ^[A-Z]{3,9} /([^/]+/)*index.php 
RewriteRule ^index.php(.*)$ /zf-tutorial/public$[R=301,L]

I did have to put the full subdirectory into the rewrite rule to get it to work.

The quick and dirty solution

At the top of your index.php file take out the index.php from the REQUEST_URI:


$_SERVER["REQUEST_URI"] = str_replace('index.php','',$_SERVER["REQUEST_URI"]);

This obviously works, but feels a bit "hacky"! There's probably other ways to solve it too, but once I found the rewrite rule, I stuck with it.

PHPUK 11 Conference in London

10th January 2011

PHPUKConference2011.png

PHPUK, the conference organised by the PHP London usergroup is being held on Friday 25th February 2011. If you haven't bought your ticket yet, then you should!

I'll be there talking about optimising a Zend Framework application, which should be interesting. I'm going to be looking at what's slow in the ZF code itself and have been profiling using xhprof which is the first time I've used it. It's quite good, once you have it set up :)

There are a lot of good talks at PHPUK this year and I'm particularly looking forward to Thijs Feryn's Varnish in Action and Jonathan Weiss' Running on Amazon EC2. Check out the full list of talks.

If you are going, then come and say hello.

Displaying an RSS feed in WordPress

3rd January 2011

My wife decided that she wanted to display a list of her latest AudioBoos in the sidebar of her blog. She looked at the AudioBoo JavaScript widget but decided it wasn't subtle enough and so she enlisted me to solve her problem.

It turns out that AudioBoo has an RSS feed, so a simple plugin was required. I had a quick look on the extension site, but most are now "widgets" which her theme isn't set up for or didn't provide an unsigned list. Hence, I whipped up a small extension for her.

It turns out that WordPress ships with MagpieRSS baked in, so the work to get the feed is trivial:

include_once(ABSPATH WPINC '/rss.php');
$messages fetch_rss($url);

The rest of the work is simply formatting the output. The key requirement that she had was that it should provide an unsigned list with title, date and optionally the summary. Along with providing some customisation for her, this is what I came up with:

function akrabat_simple_rss($options = array()) 
{
    $defaults = array(
        'url' => '', 
        'number_of_items' => 5,
        'display_date' => true,
        'date_format' => 'd M Y at H:i', 
        'display_summary' => true,
        'number_of_summary_chars' => 100,
        'link_on_title' => true,
        'link_on_date' => false,
        'css_class' => 'akrabat-simple-rss',
    );
    
    extract (array_merge($defaults$options));
    
    $output '';
    if (!empty($url)) {
        include_once(ABSPATH WPINC '/rss.php');
        $messages fetch_rss($url);
        if(count($messages->items) == 0){
            return '';
        }
        
        if($number_of_items count($messages->items)) {
            $number_of_items count($messages->items);
        }
    
        $output '<ul class="'.$css_class.'">';
        for($i 0$i $number_of_items$i++){
            $message $messages->items[$i];
        
            $link $message['link'];
            $title $message['title'];
            $date null;
            if (isset($message['published'])) {
                $date $message['published'];
            }
            if (!$date && isset($message['pubdate'])) {
                $date $message['pubdate'];
            }
            $summary null;
            if (isset($message['summary'])) {
                $summary $message['summary'];
            }
            if (!$summary && isset($message['description'])) {
                $summary $message['description'];
            }
            
            $output .= "<li>";
            $title_string htmlspecialchars($title_string);
            if ($link_on_title) {
                $output .= '<a href="'.$link.'">'.$title_string.'</a>';
            }
            $output .= '<div class="akrabat-rss-title">'.$title_string.'</div>';
            
            if ($date && $display_date) {
                $dateString date($date_formatstrtotime($date));
                if ($link_on_date) {
                    $dateString '<a href="'.$link.'">'.$dateString.'</a>';
                }
                $output .= '<div class="date">'.$dateString.'</div>';
            }
            if ($summary && $display_summary) {
                $summary_string substr($summary0$number_of_summary_chars);
                if (count(summary) > $number_of_summary_chars) {
                    $summary_string substr(summary_string0, -3) . '...';
                }
                $summary_string htmlspecialchars($summary_string);
                $output .= '<div class="summary">'.$summary_string.'</div>';
            }
            $output .= "</li>";
        }
        $output .= "</ul>";
    }
        
    return $output;
}

Maybe it's useful to someone else too, and I've documented it somewhere!

2010 Wrap up

31st December 2010

Another year is over, and as is becoming a tradition, I like to show off some photos that recap my year!

January

We started the year with a visit to the zoo!

Lion

There was also snowy weather last January and on the last day of the month, we put our house on the market. We would be accepting an offer on it in late October.

For sale

February

In February, I took pictures of canal boats.

The PHPUK conference was also in February, where I presented a session about Windows Azure and PHP.

Presenting on PHP & Azure

March

I took my best picture yet of Worcester cathedral.

Worcester Cathedral

April

April was all about my wife! She had her first tatoo done.

Tiger tattoo

and spent some time in hospital having her appendix removed

Flowers and cards

May

The big event in May was php|tek. I struggled to find a single picture that captured the conference for me, but went for this one.

php|tek 2010 conference

June

June saw another conference: DPC in Amsterdam.

Cal presentating

This photo of Chris Shiflett was also popular:

I cannot even begin to think of a caption

July

Photographically, the main source of all my photos was my aunt and uncle's 40th wedding anniversary, of which I haven't published any of the photos :)

Camera

August

I took the kids to the Severn Valley Railway in August, but the main event was our friends' wedding!

Bride and groom

September

September saw the inaugural PHPSW meeting in Bristol.

The audience!

I also tried to take a photo of a glass of red wine with a white background. This proved to be much harder than I expected

A glass of red wine

October

The Severn Valley Railway's autumn gala was held in October

City of Truro approaches Highley

October also saw the fantastic PHPNW conference come back to Manchester.

Rowan uses an example we can understand!

November

I tried my hand at photographing fireworks

Fireworks

December

The snow really fell in December. So much so that we had to abandon a trip to London having travelled 13 miles in 6 hours.

It's a bit snowy...

Handling exceptions in a Front Controller plugin

20th December 2010

If you have a Zend Framework Front Controller plugin which throws an exception, then the action is still executed and then the error action is then called, so that the displayed output shows two actions rendered, with two layouts also rendered. This is almost certainly not what you want or what you expected.

This is how to handle errors in a Front Controller plugin:

  1. Prefer preDispatch() over dispatchLoopStartup() as it is called from within the dispatch loop
  2. Catch the exception and the modify the request so that the error controller's error action is dispatched.
  3. Create an error handler object so that the error action works as expected.

This is the code:

<?php

class Application_Plugin_Foo extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    { 
        try {

            // do something that throws an exception

        } catch (Exception $e) {
            // Repoint the request to the default error handler
            $request->setModuleName('default');
            $request->setControllerName('error');
            $request->setActionName('error');

            // Set up the error handler
            $error = new Zend_Controller_Plugin_ErrorHandler();
            $error->type Zend_Controller_Plugin_ErrorHandler::EXCEPTION_OTHER;
            $error->request = clone($request);
            $error->exception $e;
            $request->setParam('error_handler'$error);
        }
    }

}

That's it.