Tag: PHP

Skunk: A stinky PHP microframework

November 18, 2011 » Geek

Six months ago I wrote a little PHP framework as an exercise. I’d been down this path before with the now abandoned Xoket – but this time I decided to go small, and throw away.

Hence Skunk was born.

Skunk is a single file, very lightweight API. Really, it’s just a borrowed router with some sugar wrapped around it.

I was after a Sinatra or Bottle feel, and I think I got something rather nice out of it.

Skunk uses anonymous functions extensively, so use PHP 5.3+ to save yourself the pain of create_function.


Here is a super simple Skunk application:

// Initialize
$s = new Skunk();

// Add a route
  function ( &$s, $name = null ) {
    $s->body = 'Hello' . ( ( is_null( $name ) ) ? '' : " $name" ) . '!';

// Run it!

Let’s tear that apart.

$s = new Skunk();

Everything in Skunk revolves around the Skunk object, so we need to set one up.

While it is possible to have multiple Skunk objects, there really isn’t a good use case I can think of. But we won’t restrict your cleverness with a singleton.


The two most important functions for Skunk are get and post.

These functions take a route and a function to apply when that route is matched, in a GET request and a POST request respectively.


In this chunk we are setting up a GET request, with the route /hi(/<name>), so that will match /hi, /hi/John, etc.

Note the identifier <name> in the route. This named match will be captured and sent as an argument to the function.

  function ( &$s, $name = null ) {
    $s->body = 'Hello' . ( ( is_null( $name ) ) ? '' : " $name" ) . '!';

Skunk route functions always need to take a reference to the Skunk object as their first argument. Following that are any other arguments that might be pulled from the route itself.

In this case we are just setting the body of the Skunk response.


This kicks off the request process and also renders the response.

Other Tricks

Skunk has some other features too.

You can raise a variety of errors inside of a request:

  function ( &$s ) {
    return $s->HTTP_500();

You can set headers:

  function ( &$s ) {
    $s->header( 'Content-Type', 'application/json' );
    $s->body = json_encode( array( "Example" => TRUE ) );

There is even a little hook system, so you can do middleware-ish stuff:

  function ( &$s ) { 
    $s->header( 'X-Stinky-By', 'Skunk' );


So that is Skunk.

It could use some love, but it’s workable. We’ve run Number Laundry on it with no problems for four months with no problems yet.

For an example of Skunk in action, check out Number Laundry’s source at github.

A Walk Through Swiftmailer Transport AWS SES

October 26, 2011 » Geek

A Problem

“@jmhobbs thanks for your amazonses swiftmailer integration. it works. can’t understand your code tho. way over my head.”


“@rrcatto no problem! Neither can I sometimes. :-)”


After this exchange, I thought I would dig back into this project and outline how it works.

Three Core Classes

There are really only two classes in play with this project. The first is Swift_AWSInputByteStream, the second is the transport itself, Swift_AWSTransport. The third, and possibly the most confusing, is ChunkedTransferSocket.

So let’s got over each of them.


The purpose of this class is to write out the contents of the message to the provided socket. We have this special class for AWS because the documentation specifies that the message data should be Base64 encoded. One side effect of Base64 is padding on encoding. Because of this, we buffer any excess bytes and encode only on multiples of 3 bytes received.

Here is a documented version of the core function, write:

public function write($bytes) {

  // Get the buffer size + new chunk size
  $total_size = strlen( $this->buffer ) + strlen( $bytes );
  // Size of the remainder we will need to buffer
  $excess = $total_size % 3;

  // Nothing to write? Return early.
  if( $total_size - $excess == 0 ) { return ++$this->counter; }

  // Encode and write bytes to the socket
          $this->buffer . $bytes, // Source is buffer + new chunk
          0,                      // Begin at the beginning
          $total_size - $excess   // Write up to the new buffer 

  // If there was excess, store it in the buffer
  if( $excess != 0 ) {
    $this->buffer = substr( $this->buffer . $bytes, -1 * $excess );
  else {
    $this->buffer = '';

  return ++$this->counter;


This class provides the transport for Swiftmailer. It sets up the socket, takes a message, and sends it off to AWS. The core functionality is in _doSend. This function is documented below. I’m not detailing much here, because it’s mostly glue code.

protected function _doSend( 
  Swift_Mime_Message $message, 
  &$failedRecipients = null
) {
  // Use secret key to generate HMAC used to 
  // authorize the message to AWS
  $date = date( 'D, j F Y H:i:s O' );
  // Use the native extension if available
    function_exists( 'hash_hmac' ) and 
    in_array( 'sha1', hash_algos() )
  ) {
    $hmac = base64_encode( 
      hash_hmac( 'sha1', $date, $this->AWSSecretKey, true ) 
  // Otherwise, fallback to a PHP implementation
  else {
    $hmac = $this->calculate_RFC2104HMAC( $date, $this->AWSSecretKey );

  // Now we use that to create the authorization header
  $auth = "AWS3-HTTPS AWSAccessKeyId=" . 
          $this->AWSAccessKeyId . 
          ", Algorithm=HmacSHA1, Signature=" . 

  $host = parse_url( $this->endpoint, PHP_URL_HOST );
  $path = parse_url( $this->endpoint, PHP_URL_PATH );

  // Open up a raw SSL socket to the host 
  $fp = fsockopen( 'ssl://' . $host , 443, $errno, $errstr, 30 );

  if( ! $fp ) {
    throw new AWSConnectionError( "$errstr ($errno)" );

  // Convert that into a chunked "socket"
  $socket = new ChunkedTransferSocket( $fp, $host, $path );

  // Add our date and auth headers (generated above)
  $socket->header("Date", $date);
  $socket->header("X-Amzn-Authorization", $auth);

  // Write the initial post parameters

  // Hand it off to an Swift_AWSInputByteStream to write the message
  $ais = new Swift_AWSInputByteStream($socket);

  $result = $socket->read();

  return $result;

Okay, not simple, but fairly straightforward.


This class makes an HTTP request direct on the socket. Since we don’t know the message size before encoding, and it’s memory intensive to encode, buffer, and then send, we do a chunked transfer encoding POST.

It’s actually pretty easy. You send some headers, and then every time you have a chunk to write, you preface it with the number of bytes you are sending before you send them.

Here’s the code for the write function:

public function write ( $chunk ) {
  if( $this->write_finished ) { throw new InvalidOperationException( "Can not write, reading has started." ); }

  if( ! $this->write_started ) {
    fwrite( $this->socket, "\r\n" ); // Start message body
    $this->write_started = true;

  // Write the length of the chunk, carriage return and new line
  fwrite( $this->socket, sprintf( "%x\r\n", strlen( $chunk ) ) );
  // Write the chunk
  fwrite( $this->socket, $chunk . "\r\n" );
  // Flush the socket to send the data now, not later
  fflush( $this->socket );

Pretty simple once you understand how chunked transfer works. The rest of the class is just state keeping.


So, that’s that. Nothing really deep in there, just a collection of fairly simple methods that, glued together, send email to AWS SES.

Hit me up with any questions in the comments section if you have them.

Regex Fun – Get a substring by length, breaking on word boundary.

June 7, 2011 » Geek

Yesterday I had a discussion wherein Regular Expression’s were (sort of) jokingly referred to as “magic”. Well, today I had cause to write a clever(ish) one, and I thought I would lay it out real quick.

What I needed to do was break a string at between 200 and 250 characters, but it had to be on a word boundry. So, it could run over if needed, but it had to break on a word boundary.

Now, I know you could do this with a couple of other functions mixed together, but I’m going to do it with preg_replace. No idea how this compares on performance. Poorly for large strings, I would guess.

I’ll ruin the surprise and show you the answer first:

preg_replace( "/(.{200,}?\b).*/s", '\1', $string );

So let’s break this down.


Starting from the left. ( this signifies that I am opening a subpattern. What comes inside of these parentheses are the content I want to save.

The dot, ., is a wildcard that matches any character.

The string {200,} is a repetition marker, allowing for the previous character (the dot, so, anything, remember) to repeat 200 or more times.

The question mark, ? here is really important. By default repetition is “greedy”, or, it will suck up as many characters as it is allowed, with precedence being given out left to right. By putting the ? here we make {200,} un-greedy, so it only grabs as much as required for the match to work.

The \b is an escape sequence for a word boundary. Handy!

After that we close the subpattern, )

Next we have .* which is a greedy repetition matching any character. Since this is greedy and {200,} is not, it will pick up any of the slack.

The last little bit is the s after the pattern delimiter. This is a modifier that tells the dot character to match anything, including newlines.


So, to recap, we say…

Give me any character, 200 or more times, ungreedily, followed by a line break, and then collect any following characters greedily.


//  T  h  i  s     i  s     a     t  e  s  t     s  t  r  i  n  g  .
// 00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21
$string = "This is a test string.";
echo preg_replace( "/(.{5,}?\b).*/s", '\1', $string );
// This 
echo preg_replace( "/(.{7,}?\b).*/s", '\1', $string );
// This is
echo preg_replace( "/(.{9,}?\b).*/s", '\1', $string );
// This is a
echo preg_replace( "/(.{11,}?\b).*/s", '\1', $string );
// This is a test
echo preg_replace( "/(.{25,}?\b).*/s", '\1', $string );
// This is a test string.

// I'm removing that ? here, see what it does to it...
echo preg_replace( "/(.{3,}\b).*/s", '\1', $string );
// This is a test string
// It made {3,} gobble everything up to the last word boundary. Greedy bugger!

Got it?

Swiftmailer Transport for Amazon Simple Email Service

January 25, 2011 » Geek

Updated (2011-02-03)

On the suggestions of Chris Corbyn I re-wrote my class to use direct access and the Swiftmailer byte stream interface, no cURL anymore. It’s way faster, and way cooler, if I do say so myself. You can get the latest at https://github.com/jmhobbs/Swiftmailer-Transport–AWS-SES

So, today Amazon debuted Simple Email Service. The gist of it is, send mail with them instead of your own servers. Like a feature reduced SendGrid or Postmark.

Not a lot of stuff out there for it so I thought I’d jump the gun a bit and write a transport for PHP’s Swiftmailer. If you have to send e-mail from your sever and from PHP, Swiftmailer is your best friend.

Never dug into Swiftmailer’s guts before, but it’s pretty well laid out. All you have to do for a new transport is implement the send method of the Transport interface and you are done.

I knocked mine together pretty quick, and the only code I cribbed was the HMAC code from php-aws, because AWS was rejecting the output from hash_hmac. (Which I literally just figured out while I wrote that paragraph. Works now.)

So how hard is it to use? Easy as any other transport in Swiftmailer.

setSubject("What up?")
  ->setFrom(array('[email protected]'))
  ->setTo(array('[email protected]'))

Dude, I'm totally sending you email via AWS.

", 'text/html'); $mailer->send( $message );

So, yeah, it works.

I know there is a ton of stuff I didn’t implement that I need to before this could be “production” ready, but it was a very satisfying little project.

You can grab it here: https://github.com/jmhobbs/Swiftmailer-Transport–AWS-SES

Flip WordPress Plugin

December 28, 2010 » Geek

So I took a few minutes and slapped together a plugin for WordPress that lets you “flip” your website upside down. I basically just packaged up the code from the last post.

Grab a copy here: https://github.com/jmhobbs/Flip. It works for me in Firefox and Chrome.