Hostname matching with Zend_Controller_Router_Route_Hostname

Friday, April 2nd, 2010

The Zend Framework offers and handy little tool for hostname matching. This means that you can introduce variables into your application’s URIs. For example, you may want to let users go to a URI like http://chris.yoursite.com or http://neil.yoursite.com and then use the “chris” or “neil” part to determine what content is displayed.

The first thing you have to do in order to use hostname matching, is to setup your server such that *.yoursite.com resolves to wherever your ZF application is running. In most cases this is probably just your domain. For example’s sake, let’s say we setup our server so that *.yoursite.com resolves to the ZF app running at yoursite.com

Once that’s in place, you can start using Zend_Controller_Router_Route_Hostname. Defining a hostname route is pretty straightforward:

 
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
    ':username.yoursite.com',
    array(
        'controller' => 'profile',
        'action'     => 'index'
    )
);

So what is happening here is that you’re telling the router that any time it see’s something like chris.yoursite.com, to take the “chris” part and store it in a variable called username, then route to the index action of the Profile controller. If you’re familiar with ZF and defining routes, this will seem pretty trivial.

Here’s where things get tricky. Our $hostnameRoute is matching the hostname, so this route will match any path since the hostname will be part of any path for your site. This is where route chaining comes into play. If you’re not familiar with route chaining, I suggest you read the Zend_Controller_Router_Route_Chain section of the ZF manual. You can find it here. The point of chaining the routes is so that you can first match the hostname and then match any number of subsequent routes.

Let’s put this all together with a concrete example, craigslist.org. When you go to craigslist.org it gives you the option to go to URIs like toronto.craigslist.org or ottawa.craigslist.org. From there you get URI’s like toronto.craigslist.org/msg and ottawa.craigslist.org/msg. What this means is that we want the hostname matching to be applied to _every_ URI first, then we’ll match the path to a route.

 
// let's load all the routes for the site (i like to use an ini file)
$routerConfig = new Zend_Config_Ini(
    APPLICATION_PATH . '/configs/routes.ini',
    APPLICATION_ENVIRONMENT
);
 
// create a new instance of the router
$router = new Zend_Controller_Router_Rewrite();
 
// add all of our routes into the router
$router->addConfig($routerConfig, 'routes');
 
// create our hostname route for our site
$hostnameRoute = new Zend_Controller_Router_Route_Hostname(
						':city.craigslist.org',
						array(
						      'module' => 'default',
					              'controller' => 'index',
					              'action' => 'index',
					          )
      					);
 
// loop through all the routes in the router and create
// a chain with the hostname route
foreach ($router->getRoutes() as $key => $route) {
 
	// this will overwrite the existing route with our route chain
	$router->addRoute($key, $hostnameRoute->chain($route));
 
}
 
// lastly, set the router on the front controller
$frontController->setRouter($router);

And that’s all there is to it. The trickiest part is getting the hang of the route chaining – once you’ve got that down, you’re good to go.

Book Review — Zend Framework 1.8: Web Application Development by Keith Pope

Monday, March 1st, 2010

I was recently approached by a representative from Packt Publishing to review their newst book on the Zend Framework, Zend Framework 1.8: Web Application Development by Keith Pope. The book is intended to be an introduction to the Zend Framework (ZF), and with the exception of chapters 4 and 5, I tend to agree. Chapters 4 and 5 do have their necessary place in the book, it’s just the nature of the content that leads them outside the realm of the introductory. The early chapters are a clear and concise introduction to the ZF and are even useful for the experienced ZF programmer offering a few tidbits and easier ways to do things in light of the 1.8 release. The later chapters are the most valuable for the experienced programmer and set a benchmark for the beginning programmer, showing them an example of how ZF is deployed in real world situations.

Anyone who has been following the Zend Framework and the speed at which they push out releases, may ask if this book will still be relevant. My answer to that questions is a definite yes. The 1.8 release was a milestone release for the ZF; currently at version 1.10, there haven’t been a number of signifcant changes since version 1.8. However, version 2.0 of the ZF will offer and number of changes and upgrades to a number of the core components. At that point, this book will need to be updated and improved, though just enough to get up to the 2.0 spec.

Before jumping into the review, you may want to check out the table of contents or a sample chapter.

The preface and first chapter of the book really highlight how easy it is to get a simple application up and running using the ZF. Within 3 pages of the first chapter, you’ve already got a functioning application (provided you’re following along with the examples). An important part of the first chapter, not only for programmers new to ZF but also those who are just new to the 1.8 release, is the new application configuration and the introduction of the Bootstrap classes. The way of bootstrapping applications changed pretty drastically in ZF 1.8 and you’ll see the important role is plays in development throughout chapters 1 – 4.

Chapter 2 covers all the basics of the ZF Model-View-Controller (MVC) architecture. You’ll probably need a little bit of background information about MVC architecture in order to get a full grasp of what’s going on here, but even without any knowledge of MVC, you should be able to continue following along. Really only the View and Controller ascpects are covered in any detail in Chapter 2. The Model aspect comes to light in chapter 3 and finds fruition in chapters 4 and 5. Chapters 4 and 5 start to delve outside of an introduction to the ZF and get into some of the more complex aspects of application development. In these chapters you start to see more of a picture of how Keith Pope builds a web application, which is understandable, an authors background is going to influence their writing. However I don’t think that the Service Layer pattern is strictly necessary for an introduction application development. I think that someone new to the ZF should probably re-read these chapters after reading the entire book and building at least one application. I think the importance of these chapters will come to light in retrospect.

Chapter 6 is a brief but very useful introduction to the Zend_Form component, which is arguably one of the more powerful aspects of the ZF when building web applications. While chapter 7 brings together the View aspect of the MVC showing the role that the forms play within views and really emphasising how ZF can speed up your application development. Chapters 8 and 9 cover some of the more complex parts of any web application: Authentication and Authorization. Authentication and authorization are two concepts that are often confused or conflated. Pope defines them very succintly by asking a couple simple questions to the requesting user. Authorization asks: “Can they do this?”, while Authentication asks: “Are they who they say they are?”. It’s important to keep these two concepts straight. The ZF’s concept of modules is introduced in chapter 10. Modules are a way for you to compartmentalize your application and can be reused between different applications. If your application is setup properly, modifications are only required to the application’s bootstrapping.

I found chapters 11 and 12 to be particularly useful, especially for the experienced ZF programmer. Chapter 11 covers the powerful caching that the ZF is capable of. ZF offers a number of different caching strategies, each suited to a particular purpose. Chapter 12 gets into the nitty gritty of testing. Testing is one of the most important aspects of web application development, especially when your application is live and used regularily. Pope gives a quick and handy introduction to PHPUnit (one of the most widely used testing frameworks for PHP) and then shows how ZF extends the functionality of PHPUnit. Ultimately at the end of chapter 12, you have all the tools necessary to test your entire application.

After getting through this book, you will have more than the tools necessary to build out a powerful web application using the Zend Framework. If you would like more information about the book or are interested in purachasing it, you can check it out on the Packt Publishing website

Using Zend_Soap_Client with the Campaign Monitor API

Wednesday, February 3rd, 2010

I recently needed to write a PHP client to integrate with the SOAP side of the Campaign Monitor API. The code was pretty simple and straight-forward, but I was getting a weird error: 101 Invalid ListID. I checked and re-checked my ListID in our Campaign Monitor account and verified that I was using the correct ListID. Why then was I getting this Invalid ListID error?

After reading the Campaign Monitor API documentation a couple times, I realized that there was a specific header that I wasn’t using:

SOAPAction: "http://api.createsend.com/api/Subscriber.AddWithCustomFields"

Due to the Invalid ListID error, I wasn’t even thinking about headers! To fix the problem, all I needed to add was one line of code:

$client->addSoapInputHeader(
        new SoapHeader($soapUri, 'SOAPAction', $soapUri . $action)
    );

Then everything worked! Awesome.

Here’s a full code snippet:

 
$wsdl = 'http://api.createsend.com/api/api.asmx?wsdl';
$soapUri = 'http://api.createsend.com/api/';
$apiUri = 'http://api.createsend.com/api/api.asmx';
 
$apiKey = 'xxxxxxxxxxxxxxxxx'; // replace with your API key!
$listId = 'xxxxxxxxxxxxxxxxx'; // replace with a valid ListID! ;)
 
$action = 'Subscriber.Add';
		$method = 'AddSubscriber';
 
$client = new Zend_Soap_Client($wsdl);
$client->addSoapInputHeader(
        new SoapHeader($soapUri, 'SOAPAction', $soapUri . $action)
    );
 
$params = array ('ApiKey' => $apiKey,
		 'ListID' => $listId,
		 'Email' => 'test@offshootinc.com',
		 'Name' => 'Test Testford');
 
$response = $client->$method($params);
 
$resultName = $action . 'Result';
 
print_r($response->$resultName);

Zend Framework: Amazon S3 Component

Monday, May 11th, 2009

With the 1.8 release, the Zend Framework has pushed out a number of really awesome components. One that I got to work with recently, was Zend_Service_Amazon_S3. At the time that I started using the S3 component, it was still in the incubator. Since it has been released, the official documentation can be found here. Although the documentation is pretty thorough, there are a couple points-of-interest that I think are worth mentioning.

1. Global namespace. Amazon S3 is set up such that all accounts share the same namespace. So this means that if you create a bucket in your S3 account, that bucket name can’t already exist. I suggest picking a unique bucket name and then using that as a root “directory” for all your S3 files.

2. Sub-Buckets. In S3, there’s no way to create a bucket within a bucket. But there is an easy way to mimic that kind of functionality. All you have to do is name your objects as though they are part of a bucket path. E.g. if your bucket name is ‘offshoot’, and you’d like to create a sub-bucket called ‘uploads’ and put an object called ‘file.jpg’ in your ‘uploads’ bucket, you would just name your object ‘uploads/file.jpg’. The code would look something like this:

$s3 = new Zend_Service_Amazon_S3($myAwsKey, $myAwsSecret);
$s3->putObject(‘offshoot/uploads/file.jpg’, ‘imagedata…’);

This will give the appearances of having a sub-bucket called ‘uploads’ within your root bucket. This should help you keep your objects nicely organized, as you would expect from any file system.

3. Pay attention to the ACL Headers. Amazon S3 has a pretty solid ACL for controlling who can do what with the files that you upload.

(Taken from the Zend Framework documentation):
S3_ACL_PRIVATE: Only the owner has access to the item.
S3_ACL_PUBLIC_READ: Anybody can read the object, but only owner can write. This is setting may be used to store publicly accessible content.
S3_ACL_PUBLIC_WRITE: Anybody can read or write the object. This policy is rarely useful.
S3_ACL_AUTH_READ: Only the owner has write access to the item, and other authenticated S3 users have read access. This is useful for sharing data between S3 accounts without exposing them to the public.

Make sure to use these to your advantage!

————————-

Overall, I’m really impressed with the quality of the components that ZF has been pushing out in the last little while. I’m looking forward to digging into the the Amazon EC2 component next!

Using PHP’s Imagick class to convert a CMYK jpeg to RGB

Friday, October 24th, 2008

We’ve recently converted all of our image processing from using GD to using ImageMagick and one of the biggest stumbling blocks in doing that has been the lack of documentation for PHP’s Imagick class. I ran into a problem when I realized that I needed to convert a jpeg from CMYK to RGB. After some googling, I was only able to find a solution that used imagemagick on the command line. This just isn’t a viable solution for my current needs, I need a solution in PHP, preferably using the Imagick class. Back to google. I finally find what appears to be exactly what I’m looking for, but it’s on one of those question/answer sites where you have to pay to see the answer. Forget that! So I read through the little Imagick documentation that exists and trial-and-errored my way to a working solution.

Here’s a simple script that gives a run through of converting a CMYK jpeg to RGB using ImageMagick’s Imagic class:

<?php

$filePath = '/path/to/your/file.jpg';
$i = new Imagick($filePath);

$cs = $i->getImageColorspace();

if ($cs == Imagick::COLORSPACE_CMYK) {

    print "Image is CMYK<br/>\n";

    ?>
    CMYK Image:<br/>
    <img src="<?=$filePath ?>"/>
    <br/><br/>
    <?php

    $i->setImageColorspace(Imagick::COLORSPACE_SRGB);
    $i->setImageFormat('jpeg');

    $cs = $i->getImageColorspace();

    if ($cs != Imagick::COLORSPACE_CMYK) {

        print "Image is no longer CMYK<br/>\n";

        // write it to a temp file
        $filePath = '/path/to/temp/file.jpg';
        $i->writeImage($filePath);

    }

} else {
    print "Image is not CMYK<br/>\n";
}

if ($cs == Imagick::COLORSPACE_SRGB ||
    $cs == Imagick::COLORSPACE_RGB){
    print "Image is RGB<br/>\n";
}

?>
RGB Image:<br/>
<img src="<?=$filePath ?>"/>
<?php

$i->clear();
$i->destroy();
$i = null;

Hopefully this will help some of you out! I know there are a lot of people out there looking for the same (or at least a similar) solution.

Zend Framework 1.6RC

Friday, July 25th, 2008

If you don’t frequent the zend framework website you might not have realized that they already have a release candidate for version 1.6 of the zend framework. What’s interesting about version 1.6 (other than the additions to my new friend Zend_Form) is that it comes bundled with the Dojo javascript framework. On the surface this seems like a good idea: a php framework and a rich integration with a javascript framework. Your basic all-in-one package. Looking deeper, I feel like this has the business equivalent to “code smell” to it. Why did Zend select Dojo out of all the javascript frameworks out there? The community doesn’t seem to think Dojo is the right way to go. All the blogs I’ve been reading seem to be really pushing jQuery. But then again programmers (yes, myself included) are a fickle sort and tend to always jump on whatever bandwagon seems to have the most hype. So now Zend has taken it upon themselves to make it easier for programmers already using the Zend Framework to start using Dojo. Did Dojo start loosing the popular vote and figure their best bet for the future is attempting to piggy back on the Zend Framework’s hype? The relationship between the Zend Framework and Dojo is clearly beneficial to both parties and the integration of the two will only become easier and more seemless over time. I suspect it will get to the point where the ease of using Dojo far out weighs the hassle at attempting to use another javascript framework. I figure the result can go one of two ways, developers using ZF will either: convert to using Dojo or come together and extend the Zend Framework to have a rich integration with other javascript frameworks.

In a perfect world, business wouldn’t determine the choice of programming language or tools that we use. As part of an open source community, we have the tools required to make our own decisions and to branch off when business begins to constrict our choices.

What do you think?

Free App: PHP Simple Gallery

Friday, July 25th, 2008

Here at the office, when we’ve run into a bottleneck design wise, we’ve used a collection of images to inspire us, mostly in the form of large, slow to open, and hard to share layered PSD resource files.

To fix this problem I slapped together this simple php image gallery. No database required, no extensive configuration. Just upload files and folders and you’re done.

The gallery seeks through up to 2 levels of folders and generates thumbnails* of png, jpg or gif images on the fly. The left hand navigation lists all the main folders and sub folders so you can get to what you need to look at quickly.

Installation is simple:
1. Un-Rar all the files.
2. Upload to your server
3. Create the directory ‘files’ in the same folder as index.php
4. Upload your files and folders to the ‘files directory’

thats it.

Feel free to give it a shot, modify it to your heart’s content. If you come up with a wicked awesome mod let me know and I’ll add it to any modifications that I do in the future.

Download Here

*Thumbnails are generated by WV4, modified by me to work with png, jpg and gif

Favour Composition over Inheritance

Wednesday, June 4th, 2008

I was just reading through the current issue of php|architect (April 2008) and I noticed a particular piece of code that irked me to the point that I need to write about it. If you’re interested, the article is Exceptional Error Handling. Don’t get me wrong, it’s a well written and informative article, however, one of the listings (Listing 9) has some really hacky code in it. The hack is only in the constructor, but the flaw is in the design. A flaw that can easily be overcome with a piece of sage advice from the Gang of Four: “Favour object composition over class inheritance” [GoF20]

The intention of the code is to have a singleton class that extends PHP’s ArrayObject class. Here’s the code snippet:

class LogService extends ArrayObject
{

    private static $instance;

    public function __construct(Array $loggers = array())
    {
        // examine backtrace to see how the constructor was called
        $backtrace = debug_backtrace();

        // throw exception if we were not called from the
        // getInstance() method of this class
        if ($backtrace[1]['class'] !- __CLASS__ ||
            $backtrace[1]['function'] != 'getInstance'){
            throw new SingletonException('...');
        }

        parent::__construct($loggers);
    }

    public function getInstance(Array $loggers = array())
    {
        if (!self::$instance){
            self::$instance = new LogService($loggers);
        }
        return self::$instance;
    }

    ...
}

NB: i left out the rest of the class and the content of
the exception message because it's not really relevant
to the point at hand.

Can you spot the problem here?

The problem is that this breaks one of the main rules of the singleton pattern — that new instance of the class cannot be created from outside of the class — and then attempts to reconcile it by checking the backtrace and throwing an exception. Since the constructor of the ArrayObject class is defined as public, any child classes of ArrayObject must also have their constructor defined as public. This is because access to a method of a child class cannot be more restrictive than that method in the parent class. The final solution ended up being a hacky mimic of the singleton pattern.

Ockham’s razor (or at least a paraphrased version): “the simplest solution is the best”

Checking the backtrace and throwing an exception is not the simplest solution. The simplest solution is to favour composition over inheritance.

Let’s look a little deeper at the ArrayObject class

ArrayObject

You’ll see that the ArrayObject implements 3 interfaces: IteratorAggregate, ArrayAccess, and Countable. These interfaces are what allow php to treat instances of the ArrayObject as native array, i.e. using it in a foreach loop, accessing elements of the ArrayObject, finding out how many elements are in the ArrayObject, etc.

Let’s see how we can use composition and interfaces to write an equivalent singleton class without the need for the hacky constructor


class LogService implements IteratorAggregate, ArrayAccess, Countable
{

    // the only available instance of this class
    private static $_instance;

    // an instance of ArrayObject. using composition rather than
    // inheritance
    private $_array;

    // private constructor as an optimal solution for the singleton
    // pattern
    private function __construct(Array $loggers = array())
    {
        $this->_array = new ArrayObject($loggers);
    }

    // method required by the IteratorAggregate interface
    public function getIterator()
    {
        return $this->_array->getIterator();
    }

    // method require by the ArrayAccess interface
    public function offsetExists($index)
    {
        return $this->_array->offsetExists($index);
    }

    // method require by the ArrayAccess interface
    public function offsetGet($index)
    {
        return $this->_array->offsetGet($index);
    }

    // method require by the ArrayAccess interface
    public function offsetSet($index, $newval)
    {
        return $this->_array->offsetSet($index, $newval);
    }

    // method require by the ArrayAccess interface
    public function offsetUnset($index)
    {
        return $this->_array->offsetUnset($index);
    }

    // method require by the Countable interface
    public function offsetCount()
    {
        return $this->_array->count();
    }

    public function getInstance(Array $loggers = array())
    {
        if (!self::$_instance){
            self::$_instance = new LogService($loggers);
        }
        return self::$_instance;
    }

    ....

}

In my opinion this is a much more elegant solution, even if it does require a little bit more coding (and very trivial code at that). There’s no way to call the constructor outside of the class and thus no need to manage the possibility of an exception thrown by the constructor. It serves the same purpose as the original code (you could even implement the php’s magic method __call() in the LogService class to essentially proxy method calls to the instance of the ArrayObject) and is more inline with the intention of the Singleton pattern.

What do you think? Which solution would you prefer? What do you think is more important: good design practices or less lines of code?

Oh CRUD… (Part 3)

Tuesday, May 6th, 2008

Well, somewhat unfortunately, there won’t be a part 3 to this blog post. I ended up pitching the idea to php|architect magazine (http://www.phparch.com) and they will be publishing it in their july 2008 issue. I’ll post any links and relevant data sometime in july. So keep your eyes peeled for that.

In the mean time, check out the current issue of php|architect here

Zend Framework Extensions

Tuesday, May 6th, 2008

Recently we made the decision to move from our custom php framework to the zend framework. With the recent 1.5 release, the zend framework has shown that it’s truly a force to be reckoned with. However, I quickly found that there were certain bits and pieces that I’ve become accustomed to using that weren’t (or at least weren’t readily) available within the framework. Here’s where the power of the zend framework comes in. I was easily able to extend the certain classes in order to incorporate elements of our old custom framework.

Over the next little while I’ll be creating some tutorials which will outline the various extensions to the zend framework that we’ve built.

Tutorial 1: Application Controller