Category Archives: PHP

Redirecting in Slim Middleware

I recently ran into a problem with calling redirect() in a Slim framework middleware class, so I thought I'd better document the solution so that I remember in future!

The authentication middleware looks roughly like this:

class Authentication extends \Slim\Middleware
{
    public function call()
    {
        if (!$this->isLoggedIn()) {
            $app = \Slim\Slim::getInstance();
            $app->redirect($app->urlFor('login'));
        }

        $this->next->call();
    }

    // other methods...
}

The problem is that you can't call $app->redirect() in Middleware as redirect() is designed to only run in application route callbacks and Middleware should only act on the request and response objects.

This is because the app's redirect() method calls through to stop() which throws a Stop exception which is intended to be caught by the app's call() method. However, if this exception is thrown in middleware, then it isn't caught by call() and the redirect doesn't work. What's weird is that it works on some (most?) web servers but not all.

The correct way to redirect in middleware, use the Response's redirect() method instead like this:

class Authentication extends \Slim\Middleware
{
    public function call()
    {
        if (!$this->isLoggedIn()) {
            $app = \Slim\Slim::getInstance();
            return $app->response()->redirect($app->urlFor('login'));
        }

        $this->next->call();
    }

    // other methods...
}

Note that we return the result of $response->redirect() so that the next item in the chain isn't called.

Speaking at DPC & OSCON

Two conferences are coming up that I'm speaking at:

I'm speaking at DPC 2014

The Dutch PHP Conference takes place in Amsterdam and this year is between June 26th and 28. I'm giving a tutorial with Matthew Weier O'Phinney on Apigility which will provide you with a full day's teaching on creating web APIs with Apigility. I'm also giving a talk called Creating Models discussing the options available when creating the model layer of a typical MVC PHP application.

DPC is a fantastic conference full of great content and people and if you can get to Amsterdam at the end of June, it's well worth your time to attend.

I'm speaking at OSCON 2014

The following month, I'm coming to the US to speak at OSCON which runs from the 20th to 24th July in Portland. OSCON is a massive conference that covers the entire spectrum of Open Source and I'm excited to be presenting Creating Models in the PHP track. There's a lot on the schedule and I expect to learn a lot and meet lots of people from communities that I haven't interacted with much before. I've never been to Portland before, so it'll be interesting to see what the city has to offer too.

If you attend either of these conferences, please come and say hello!

Immutable entities

I've been thinking recently about using immutable objects for some of my model-layer entities. That is, an object that cannot be changed once it is created.

Immutable objects have a number of benefits including the fact that they are much easier to understand, simple to use and very easy to test. The main motivation for me is that an immutable object is very predictable as it's state doesn't change. This means that any calculated properties can be done once on creation. This is interesting as one application that I'm currently working on has a lot of calculated properties and it's a source of bugs when one property changes and all the dependent calculations aren't always done.
Continue reading

Use statements

I was having a discussion on IRC about use statements and whether they improved code readability or not.

The choices

Consider this hypothetical code:

$cache = new \User\Service\Cache();
$mapper = new \User\Mapper\User($cache)
$form = new \User\Form\Registration($mapper);
$form->process($request->getPost());

vs

use User\Service\Cache;
use User\Mapper\User;
use User\Form\Registration;

// other code

$cache = new Cache();
$db = new User($cache)
$form = new Registration($mapper);
$form->process($request->getPost());

The first snippet is completely unambiguous at the expense of verbosity. Those longer class names make it a little hard to quickly parse what it going on. The second is clearly less cluttered, but is at the expense of ambiguity. Exactly what class is User? I would have to go to the top of the file to find out. Should I use aliases? If so, how should I name them?
Continue reading

Using PHP's NumberFormatter to format currencies

I've been using number_format() for a very long time, but recently discovered that within the intl extension there's a NumberFormatter class available too. This is quite a clever class as it is Locale aware and handles formatting currency, including the correct symbol.

You can check if you have the intl extension installed using php -m | grep intl and if you don't then you can install it with apt-get install php5-intl or yum install php-intl assuming you use your distro's stock PHP. (If you compile your own, then --enable-intl is the switch you need.)

Consider this scenario where I want to display a price in Euros for both the UK and the German markets:

$amount = '12345.67';

$formatter = new NumberFormatter('en_GB',  NumberFormatter::CURRENCY);
echo 'UK: ' . $formatter->formatCurrency($amount, 'EUR') . PHP_EOL;

$formatter = new NumberFormatter('de_DE',  NumberFormatter::CURRENCY);
echo 'DE: ' . $formatter->formatCurrency($amount, 'EUR') . PHP_EOL;

The constructor takes the locale to use along with the type of formatting you want to do, CURRENCY in this case. Then, when you call formatCurrency(), the second parameter is the 3-letter alphabetic ISO 4217 code for the currency you want to display.

The output of the code above is:

UK: €12,345.68
DE: 12.345,68 €

You can see the locale at work here as in the UK we expect to see the currency symbol before the number and use comma to separate thousands, whereas in Germany, the currency symbol is (usually!) at the end of the number and the decimal point is used to separate the thousands.

The ISO 4217 currency code determines which currency symbol is returned. Obviously, for EUR, we get the € symbol. For GBP, we'd get £, etc.

Finally, if you use ZF2, this is all wrapped up into the currencyFormat view helper for you.

Objects in the model layer: Part 2

I previously talked about the terms I use for objects in the model layer and now it's time to put some code on those bones. Note that,as always, all code here is example code and not production-ready.

An entity

My entities are plain old PHP objects:

namespace Book;

class Entity
{
    protected $id;
    protected $author;
    protected $title;
    protected $isbn;

    public function __construct($data = array())
    {
        $this->populate($data);
    }

    // Data transfer methods

    public function populate($data)
    {
        if (array_key_exists('id', $data)) {
            $this->setId($data['id']);
        }
        // repeat for other properties
    }

    public function getArrayCopy()
    {
        return array(
            'id'     => $this->getId(),
            // repeat for other properties
        );
    }

    // Entity-specific methods

    public function isValidIsbn()
    {
        // validate ISBN and return true/false
    }

    // Property getters and setters
    
    public function getId()
    {
        return $this->id;
    }
    
    public function setId($id)
    {
        $this->id = $id;
        return $this;
    }
    
    // Repeat for other properties...

}

There's nothing particularly complicated here. We have an object with a number of properties and some methods. This object represents a book, so we have properties of author, title and isbn. We need to be able to set and retrieve the properties so there is a get and set method for each one (only getId() and setId() are in the code snippet above to save space!)

Generally, I populate an entity from a mapper and use a pair of methods to do this: populate() and getArrayCopy(). These methods transfer the data in the properties to and from an array.

There are also entity-specific methods within the entity. For this object, I have a method called isValidIsbn(); for a user object, I may have a method called getFullName() which concatenates the user's first name and surname.

A mapper

The mapper knows how to load and save entities. This is a hand-rolled one:

namespace Book;

use PDO;
use BookEntity;

class Mapper
{
    protected $pdo;

    public function __construct($dsn, $username, $password)
    {
        $this->pdo = new PDO($dsn, $username,  $password);
    }

    public function loadById($id)
    {
        $sql = 'SELECT * FROM book WHERE id = :id';

        $statement = $this->pdo->prepare($sql);
        $statement->setFetchMode(PDO::FETCH_ASSOC);  
        $statement->execute(array('id' => $id));

        $result = $statement->fetch();
        if ($result) {
            $book = new Entity($result);
            return $book;
        }

        return false;
    }

    public function fetchAll($order)
    {
        // Select all books from database using PDO
        // iterate over each one and create a BookEntity object
    }

    public function save(Entity $book)
    {
        $data = $book->getArrayCopy();
        if ($data['id'] > 0) {
            // Update data in table using PDO and set $result
        } else {
            // Insert data into table using PDO and set $result
        }

        return $result;
    }

    public function delete($id)
    {
        // Delete row in table using PDO
    }
}

In the mapper, I have methods that load with multiple entities and also ones that work on a single one. I like to use the method prefix "find" for methods that will return an array of entities and "load" for methods that return a single entity. This is just a stylistic thing, but I find it makes reading code easier. We then have save and delete methods that allow us to save and remove an entity from the data store.

This is just a skeleton of a specifically written mapper that users PDO. In a ZF2 application I use ZfcBaseMapperAbstractDbMapper and in other applications I tend to abstract the common code into a base class and extend.

Service objects

Lastly, service objects provide the API to the rest of the application:

namespace Book;

use BookMapper;

class Service
{
    protected $mapper;

    public function __construct(Mapper $mapper)
    {
        $this->mapper = $mapper;
    }

    public function fetchAllByTitle()
    {
        $results = $this->events->trigger(__FUNCTION__.'.pre', $this, array(), 
            function ($result) {
                return is_array($result);
            }
        );
        if ($results->stopped()) { 
            return $results->last(); 
        }

        $books = $this->mapper->fetchAll('title');

        $this->getEventManager()->trigger(__FUNCTION__.'.post', $this, 
            array('books' => $books));

        return $books;
    }

    public function loadById($id)
    {
        $results = $this->events->trigger(__FUNCTION__.'.pre', $this, 
            array('id' => $id), 
            function ($result) {
                return ($result instanceof BookEntity);
            }
        );
        if ($results->stopped()) { 
            return $results->last(); 
        }
        
        $book = $this->mapper->loadById($id);
        
        $this->getEventManager()->trigger(__FUNCTION__.'.post', $this, array('book' => $book));

        return $book;
    }

    // etc
}

A simple service object essentially proxies through to the mapper. I generally have more specific methods, such as fetchAllByTitle(), but that's a personal preference. In this example, I have an ZF2 event manager in play and the service object triggers events as required.

The service object is also useful when there are multiple related objects. For instance, if books had tags that were loaded separately, then I would have a method such as loadTagsIntoBook($book) on this service object. Of course, others prefer to use an ORM, such as Doctrine for these things.

Summary

This overview shows the type of methods that I have in each type of core object in my model layer. My controllers and view helpers only ever deal with service objects and entities, so I can change my mapper at any time.

You also need to think carefully where the business logic lives. I'm a fan of putting the logic in the entities as well as in service objects. Others tend to like their entities to be quite "dumb", though.

Missing fields in $_POST

I recently updated to OS X 10.8 (Mountain Lion) which has PHP 5.3.13 installed by default.

When testing something today, I discovered that a very very large form wasn't submitting all fields. It seemed that $_POST was being truncated. After a little bit of searching around I discovered the max_input_vars php.ini setting. This is new since PHP 5.3.9 and defaults to 1000.

As OS X also comes with suhosin installed, if you want to increase the number of fields for _POST you need to set the following in php.ini:

max_input_vars = 2000
suhosin.post.max_vars = 2000
suhosin.request.max_vars = 2000

Also, ensure that suhosin.post.max_value_length and suhosin.request.max_value_length are large enough.

Update: I was pointed to Supercolliding a PHP array which explains why this setting was introduced.

A primer on PHP namespaces

I know that there are a lot of posts now about namespaces in PHP 5.3. This is mine which is how I learnt how they work.

What are namespaces?

From the PHP manual:

namespaces are a way of encapsulating items

Hardly the most useful of definitions, but it's a starting point! A namespace is a way of grouping code that exists across multiple files without having a naming collision. That is, you can have the same named class in two different places if they are encapsulated within namespaces.

Of course the way that ZF1 solves this problem is with Extra_Long_Classnames which are obviously unique. Namespaces allow us to reference the classname by the important bit (the last section and not have to carry the meta data (where it lives) in every use of the class.

That is, namespaces allow us to:

  • combine libraries with the same classnames
  • avoid very long classnames
  • organise our code easily

Note that namespaces do not just affect classes. They also affect functions and constants.

Defining a namespace

There is a new keyword called namespace which is used to declare a namespace for a file. This is file-wide:

    namespace MyDbStatement;
    
    class Sqlsrv extends AbstractStatement
    {
    }

Note that we can have multiple sub-namespaces, separated by the backslash. When we extend the Sqlsrv class the extended class is within the namespace too, but not in the same file.

We can then use the class like this:

    $stmt = new MyDbStatementSqlsrv(); 

You can have multiple namespaces in a file, but the first namespace must be the first line of code in the file (except comments and declare statements).

Working within the same namespace

When you are working within the same namespace, then any unqualified functions and classes will be resolved to the current namespace. i.e:

    namespace MyDbStatement;
    
    function testSqlsrv()
    {
        $stmt = new Sqlsrv();
    }

In this case, the SqlSrv class is in the namespace MyDbStatement.

Namespace importing: the use keyword

We can import a namespace into a different file using the use keyword.

    namespace MyApplication;

    use MyDbStatement;

    $stmt = new StatementSqlsrv();

Note that we don't use a leading in the new statement as we are using a qualified namespace, not a fully-qualified one.

or you can import a specific class from a namespace;

    namespace MyApplication;

    use MyDbStatementSqlsrv;
    $stmt = new Sqlsrv();

It follows you can use multiple use statements:

    use MyDbStatement;
    use MyDbAdapter;
    
    $stmt = new StatementSqlsrv();
    $adapter = new AdapterSqlsrv();

You cannot do this though:

    use MyDbStatementSqlsrv;
    use MyDbAdapterSqlsrv;
    
    $stmt = new Sqlsrv();
    $adapter = new Sqlsrv();

as clearly PHP cannot resolve which Sqlsrv class to instantiate.

You can also alias namespaces. This allows us to reference a long namespace with a shorter name or to import two namespaces having the same name and give them different names.

    use MyDbStatementSqlsrv as DbStatement;
    use MyDbAdapterSqlsrv as DbAdapter;
    
    $stmt = new DbStatement();
    $adapter = new DbAdapter();

This also allows you to write code the focusses on the functionality of the class rather than the specific type. For example, we could start using the Mysqli versions of the statement and adapter by just changing the use statements.

The __NAMESPACE__ constant

The constant __NAMESPACE__ provides the current namespace name. In the global space it will be an empty string.

Namespace resolution

This bit is really important!

An unqualified class name is resolved in this order:

  1. If there is an import statement that aliases another name to this class name, then the alias is applied.
  2. Otherwise the current namespace is applied.

An unqualified function name has different rules:

  1. The current namespace is prepended to the function name.
  2. If the function names doesn't exists in the current namespace, then a global function name is used if it exists.

This means that within a namespace'd file, you can do:

    $date = date('Y-m-d');

but not:

    $datetime = new DateTime();

Instead, you have to use:

    $datetime = new DateTime();

Conclusion

That's really all you need to know to use namespaces in a PHP application. They aren't so hard really.