21 March 2017

Why is it important to understand how PHP matches a catch block?

Image: Pixabay
PHP allows you to have multiple catch blocks.  The manual says that when an exception occurs PHP will try to find the first matching exception block, but it isn't entirely clear on exactly how  PHP matches "catch" blocks when handling exceptions.

Why is it important to understand how PHP matches a catch block?

It really relates to the fact that you are able to extend the base "Exception" class in PHP to make your own classes.  Throwing exceptions that are specific is good practice because it allows you to write catch blocks that are focused on solving just one sort of problem at a time.  The SPL exceptions are a good example of hierarchical exception inheritance in case you're wanting to see some practical usage.

In PHP a catch block is a match for an exception if the exception class is either the same as or inherits from the class in the catch clause.

Here's a trivial example:

In this example I've set up an exception class that extends the base exception class.  I'm throwing an instance of this child exception.  If I didn't know that PHP will match it's parent class I would expect the message "Child exception" to be output.

In actual fact if you run this code (here) you will see that the message "Parent exception" is output because PHP has matched MyException with its parent class.

The PHP manual doesn't make this explicit or obvious when discussing catch blocks or exception inheritance but it's one of those things that's always handy to know.

This implies that when we're coding multiple catch blocks we should place the more general parent classes at the bottom of the list.  This prevents them from catching exceptions that are meant for their children.

I discuss this and other gotchas  in my study guide for the Zend certification exam.


23 January 2017

Complying with PCI database requirements in Laravel on AWS

Image: pexels.com
I'm busy with the self assessment questionnaire for PCI compliance.  Part of the database requirements are that cardholder data are encrypted at rest as well as in transit.

I host with Amazon RDS and use Laravel so my life is made pretty easy.

Amazon RDS natively supports encrypted connections and also lets you create a database that is stored on an encrypted backing instance.  If you've enabled this option then all that you need to do is make sure that you connect to the database using an encrypted connection.

I'm not getting paid anything for saying that I really enjoy using RDS, but today is another occasion when I'm really happy that I didn't have to sit and install certificates and fiddle with a cluster configuration to enable SSL connections.  The "zero config" that comes with RDS saves time and money.

Laravel was really easy to configure to use SSL.  All that you need to do is download the RDS certificate chain from https://s3.amazonaws.com/rds-downloads/rds-combined-ca-bundle.pem and amend your database configuration to use it when connecting.

I saved the pem file into storage/app/mysql_ssl_certificate and then amended my app/database.php to look like this:

Now I can use a command like var_dump(DB::select(DB::raw("SHOW STATUS LIKE 'SSL_CIPHER'"))); to check that I'm connected with SSL.

I also decided that although PCI compliance doesn't actually demand that you encrypt the data in the database I would rather take the performance hit and protect my user details.  I don't use them terribly often so the overhead of decrypting them when I do seems worth the effort to avoid the reputational damage my company would suffer if it leaked user details.

Again this is very easy to accomplish with Laravel.  I just implemented a trait which I can selectively apply to any of my entities that I want to protect.  So now if the application is breached and nasty people run off with my database at least they'll need to have the application key if they hope to read my users details.


20 January 2017

Email injection attacks in PHP

Image: Pixabay
Email injection is one of the topics I cover in my Zend certification guide.  You can grab a copy on Leanpub - https://leanpub.com/phpforprogrammers/

It is possible for a user to supply hexadecimal control characters that allow them to change the message body or recipient list.

For example, if your form allows the person to enter their email address as a “from” field for the email then the following string will cause additional recipients to be included as cc and blind carbon copy recipients of the message:


It is also possible for the attacker to provide their own body, and even to change the MIME type of the message being sent.  This means that your form could be used by spammers to send mail from.

You can protect against this in a couple of ways.

Make sure that you properly filter input that you use when sending mails.  The `filter_var()` function provides a number of flags that you can use to make sure that your input data conforms to a desired pattern.

$from = $_POST["sender"];
$from = filter_var($from, FILTER_SANITIZE_EMAIL);
// send the email

You could also install and use the Suhosin PHP extension.  It provides the `suhosin.mail.protect` directive that will guard against this.

You could implement a tarpit to slow bots down or trap them indefinitely.  Take a look at msigley/PHP-HTTP-Tarpit on Github  as an example of a tarpit.

Just be careful that when setting up your mail server you must make sure it is not configured as an open relay that allows anybody on the Internet to use it to send mail.  You should also consider closing port 25 (SMTP) on your firewall so that outside hosts are unable to reach your server.


12 January 2017

Traits in PHP

What are traits?

Image: Pixabay
Let's start by understanding what traits are and how they're useful.  We'll move on to code examples straight after that.

Traits are not unique to PHP and are available in other languages too.  They provide a way to extend the functionality of a class.  A trait will have methods to implement this functionality and make these available as if they had been defined in the class itself.

In other words traits are flattened into a class and it doesn’t matter if a method is defined in the trait or in the class that uses the trait. You could copy and paste the code from the trait into the class and it would be used in the same manner.

The code that is included into a trait is intended to encapsulate reusable properties and methods that
can be applied to multiple classes.  Traits group functionality in a fine-grained and consistent way and allow you to reuse this functionality without requiring inheritance.

I mentioned before in the lecture on inheritance that PHP does not support inheriting from multiple classes.  Traits offer a way to provide similar functionality and offer a way to avoid the so-called "diamond problem" that is introduced with multiple inheritance.

Defining and using traits

Traits are very easy to use and there are lots of places that they can be useful.  I'm going to run through an example that defines a trait that implements singleton functionality.

We define the trait using the `trait` keyword followed by the name we want to use.  We can declare variables in the trait as well as functions.  

If you look at the code example you'll see that my Singleton trait has got all of the implementation requirements for the singleton pattern.

I've defined a private static variable called $instance in the trait.  Although it's private in the trait remember that the code gets flattened when a class uses the trait and so the class would be able to access it.  If that's not clear just imagine copying and pasting the code in the trait straight into your class.

The trait also includes a static function called getInstance that returns a singleton instance of the class.

I'm using the trait in the class called MyClass.  The `use` keyword indicates that we're using the trait.  You might already be familiar with the `use` keyword as a way to import namespaces.  When we import a namespace the `use` keyword is outside of the class, if it's inside the class it indicates that we're using a trait.

Now we're able to call the `getInstance()` static method on the class.  This method is defined in the trait but we're using the trait in the class so it's available to be used as part of the class.

We're able to overwrite the constructor method in the trait.  In this example I've set the constructor to private so that you are not able to instantiate the class but rather have to use the singleton method to get an instance.  Trying to create a new instance of MyClass generates a fatal error because `__construct()` is public.

Now we're able to easily give a class all of the functionality it needs to be turned into a singleton without interfering with the inheritance hierarchy.

Namespacing Traits

So far we've seen how to declare and use a trait.  What happens if we want to use a name for our trait that has already been using elsewhere in our code?  It might happen for example that one of the libraries we use has already defined a trait named Singleton.

Traits, just like classes, can be namespaced.  The name of a trait must be unique within its namespace otherwise PHP will throw a fatal error.

Just as with classes if you're wanting to use a trait in a namespace other than your own then you'll need to provide a full reference to it.

Inheritance and Method precedence

Traits may not inherit from other traits or classes but you can nest one trait inside another.

Okay so inheritance is simple, but what about situations where a class and trait have a method with the same name?  Which method will take precedence and be run when we try to call it?

Methods declared in a class using a trait take precedence over methods declared in the trait. However, methods in a trait will override methods inherited by a class.

Expressed more simply, precedence in traits and classes is as follows:


Conflict resolution in traits

What happens if your class is using two traits and they both declare a method with the same name?  

PHP requires you to explicitly resolve these sort of conflicts and will throw a fatal error if you try to use two traits that each define a method of the same name.

There are two approaches to resolving name conflicts between traits.  You can either tell PHP not to use a method that is defined in one of the traits or you can tell PHP to use an alias for a method in one of the traits.  Put shorter, you can exclude a method or alias a method.

In order to exclude a method you use the `insteadof` operator which tells PHP to use a method from one trait instead of the method from the other.

In order to alias a method you use the `as` operator to provide an alias to use.  The only trick here is that it's not enough to just specify an alias, you must *also* exclude the original method from being used.

Right, so we've got that we can either exclude or alias a method to resolve naming conflicts between traits.  Lets look at some code to see how it works.

First we're going to create two traits.  We're going to define two methods in each trait and name them such that they'll create naming conflicts.

We're going to use the traits in a class which we're calling DomesticPet.  Because the methods in the traits have conflicting names we're going to have to resolve these conflicts.

We resolve the conflicts in a code block that follows the `use` keyword.  We have to resolve every conflict so lets step through this now.

Replacing methods with "insteadof"

For the first method, `makeNoise()`, we're going to simply exclude the method from the Dog class.  We would do this if we only ever want to use the Cat method and expect never to use the Dog method.

In order to do this we're going to tell the class to use the makeNoise function declared in the Cat trait instead of the one in the Dog trait.  

We use the `insteadof` keyword to tell PHP to use the method declared in the Cat trait instead of the one in the dog class.

Whenever the `makeNoise()` function is called PHP will know that you mean the one defined in the Cat trait and you won't be able to access the one from the Dog trait.

Aliasing methods with "as"

For the second method, `wantWalkies()`, we're going to rather alias the method in Cat.  We would do this when we want to be able to use both methods in our class.

You may have already noticed in the code sample that there are three statements in the conflict resolution block but only two functions that need to be resolved.  

Remember that earlier I said the trick with aliasing methods is that it's not enough to alias by itself and that you must also exclude the method you're aliasing?  

We're going to need two statements to alias our method.

First we're going to tell PHP to give the method an alias that we can use to reference it.  Then we're going to tell PHP to exclude the original method.

In order to alias the method we use the `as` keyword.   We're going to give the `wantWalkies()` method an alias of `kittyWalk()`.  By doing this you will be able to call the `kittyWalk()` function in your class.  This isn't a new function, it's just an alias for the function in the Cat trait.

Right after we alias the function we go ahead and tell PHP to use the Dog `wantWalkies()` method instead of the Cat trait.  If we left out this step we would still have a naming conflict.

The end result

We used the Cat `makeNoise()` function instead of the Dog one.  When we call the `makeNoise()` method on the object we are referencing the cat function and so the output is "Purr".

We aliased the Cat `wantWalkies()` method as `kittyWalk()` and so when we call the `kittyWalk()` method on the object we are referencing the aliased Cat method and the output is "No Thanks".

Because we are aliasing the Cat `wantWalkies` method we also had to use the Dog method instead of the Cat method.  Therefore when we call the `wantWalkies` method on the object we are referencing the Dog method and the output is "Yes Please".


You might want to change the visibility of a method that you're using from a trait.  This is done by using the `as` keyword.  

Lets look at a simple example before we take a look at the complications.

We can set an aliased method as protected by inserting the keyword `protected` between `as` and the name we're aliasing it as.  For example we can say,

Dog::wantWalkies as protected doggyWalk;

Changing the visibility of a replaced method is slightly more complicated.

In order to change the visibility of a replaced method we need to use two steps.  First we use `insteadof` to replace the method and then in the next statement we stipulate that it must be protected.

Lets look at this in code.  

In the first line inside the trait use block I'm aliasing a function and also changing its visibility.  The keyword `protected` appears between `as` and the aliased name.  If I were to try and call `doggyWalk()` from outside the class I would receive an error because it is protected.

I've commented out the second line because it's an example of what doesn't work.  The rule of thumb seems to be that you can't use both `as` and `insteadof` in one single statement.  You need to split them into separate statements as I do in the last two lines of the use block.


24 September 2016

Connecting to Elixir web channels from the Angular 2 quickstart application

I am busy learning Elixir, a language that adds syntactic sugar to the awesomely scalable and concurrent Erlang language.  The "go to" framework in Elixir is Phoenix and I'm busy writing my "hello world" application which will serve up data across a web channel.

I followed the Typescript version of the Quickstart guide for Angular 2 (here).  I really like what I've seen of Typescript so far.  Dependencies are easy to manage and the ability to define interfaces is a good sign of how well structured the language is.  I think Satya Nadella should be made an open source hero, if such an award exists.

Anyway, what I wanted to do was get my Angular 2 application to be able to connect to the Elixir server channel and send a request to listen to a particular stream.  The idea is to use the Actor concurrency model (explained brilliantly in "The Little Elixir & OTP Book") to start up a new process whenever a request for a stream arrives.  This article focuses on setting up the Angular 2 connection.

The official Phoenix javascript client is packaged up and can be installed with "npm install --save phoenix".  Once it's installed we need to tell SystemJS where to find it so we amend systemjs.config.js and include it in our map array.

Now we'll be able to import the Phoenix class from it wherever we need to. We'll need it in the service that we're going to use to wrap the Phoenix channel support. Lets take a look…

We import the library using the map name that we set up in our systemjs config to make it available to our class.  We then copy the code that Phoenix shows on the channels manual page to actually handle the connection.

This gives us a channel service that we'll be able to inject into components.

Angular 2 uses constructor injection so we'll be passing a channel service into the constructor function. Before we do that though we need to let the component know that our channel service is a provider so that we can properly typecast the injected variable. Once all this is saved run your app with 'npm start' and if you pop over to your browser window you should see error messages in your console log saying that the channel connection was refused, unless of course you're already running your Phoenix server.

06 September 2016

Laravel refusing to start up

I'm very much a fan of the clean implementation of Laravel but really dislike the fact that if there is something wrong with the .env file it refuses to give any meaningful information.

Laravel uses the vlucas/phpdotenv package to manage its environment.

It's pretty well known that if you have a space on either side the = sign in a key value pair then the .env file is invalid, but I had checked for this (and checked again).

Laravel will try to use its standard logging methods before they have actually had a chance to be booted up with the result that you're left with a "reflection error" exception message on the CLI rather than the actual cause of the problem in the dotenv package.

Debugging this is not trivial and I resorted to using strace to try and determine exactly what was going on.  Don't do this at home kids!  The easier solution is at the end of the article.

I used the following command to generate a trace of the system calls being made by PHP while trying (and failing) to run artisan optimize.

 strace php artisan optimize &> /tmp/strace.txt  

That let me walk through the calls and eventually confirm that the first PHP exception was thrown in the package that deals with reading the environment file.

 access("/var/www/raffle.bhf.org.uk.new/vendor/vlucas/phpdotenv/src/Dotenv.php", F_OK) = 0  
 ... more lines loading up more of the package and showing us processing it ....  
 access("/var/www/raffle.bhf.org.uk.new/vendor/vlucas/phpdotenv/src/Exception/InvalidFileException.php", F_OK) = 0  

But sadly there was no indication of exactly what the problem is with the file!

I decided that creating a minimal project dedicated to debugging my .env file was going to be faster than anything else.

I created a temporary directory and ran "composer require vlucas/phpdotenv".  Then I placed my faulty .env file into the directory and ran the following PHP file:

 $dotenv = new Dotenv\Dotenv(__DIR__);  

This gave me the actual exception in DotEnv which was that "Dotenv values containing spaces must be surrounded by quotes".  So it wasn't a space around the = sign but rather a space in one of my values, which made my life a lot easier!  As an extra bonus the first line in the stack showed exactly which key was problematic.

21 August 2016

Solving a Docker in VirtualBox DNS issue

I've recently been playing with Docker on Windows in conjunction with Linux on Windows.  I'm really amazed at how cool the stuff coming out of Microsoft is under Satya Nadella.  

When I was using Docker Toolbox on Windows my Dockerfiles would build correctly but as soon as I tried to run them in a Virtualbox host they would fail with the error "Something wicked happened resolving 'archive.ubuntu.com:http' (-5 - No address associated with hostname)"

Of course this error wasn't distribution specific and none of the distros I tried were working.

The stack that I am using is Windows Home hosting Ubuntu on VirtualBox which is running Docker.  I'm using bash on Linux for Windows because it's easier to do stuff like ssh but it's not relevant to this setup.

I tried setting the DNS in the Docker setup by using RUN steps to update /etc/resolv.  This felt a bit hacky and didn't work anyway.

In the end the fix was to go to my Windows shell and run ipconfig to get its DNS servers.  I then went and edited /etc/default/docker in my VirtualBox guest server and set the Docker options to use this DNS.  After restarting the docker service it was able to resolve DNS properly.

# Use DOCKER_OPTS to modify the daemon startup options.

I had installed Docker with the package but I think if you install with binary you would set the DNS when you start up the daemon.

Ironically Docker was easier to use with the Windows toolkit but I'll be deploying to Linux machines so I wanted to get this working under Ubuntu.