Tag: PHP

Anonymous Code of Conduct Reporting With Twilio

August 29, 2016 » Geek

I’m lucky to be one of the organizers of NEJS Conf, a great little JavaScript & frontend conference here in Omaha, NE.

One of the core values we’ve held since the beginning of our conference was for it to be diverse, respectful and safe. To that end we adopted a Code of Conduct from the very beginning, based on the excellent JSConf example.

Our first year, we identified specific volunteers as our CoC points of contact. It seemed like a good plan, but our only report that year came via a circuitous route, which may have been a result of the face-to-face reporting we had defaulted to.

This spring I got to attend Twilio’s SIGNAL conference, and one neat thing they had in their Code of Conduct was an anonymous reporting phone line. Sounds like a good idea, and something fun to build!

The plan is simple: add a Twilio backed phone number which anonymizes incoming SMS and calls, then forwards them to the code of conduct reporting volunteer. Twilio makes this easy. At it’s core it’s just two TwiML files, one for SMS and one for Voice.

The SMS response contains the original message, a destination number to send it to (i.e. the CoC volunteer), a unique ID per reporter, and a link to the web interface. Behind the scenes we are doing a little but of work to assign the ID, match up numbers to destinations, etc, but not a lot of work total.

<?xml version="1.0" encoding="UTF-8" ?>
  <Message to="{{ destination_number }}">[{{ reporter_id }}] {{ message_body }}

{{ link }}</Message>

Voice is even simpler. Here we just connect the call to the CoC volunteer, and spoof the caller ID with the hotline’s number.

<?xml version="1.0" encoding="UTF-8"?>
  <Say>Connecting, one moment.</Say>
  <Dial record="true" callerId="{{ caller_id }}">{{ number.destination }}</Dial>

That’s the core of it, only took an evening to get things running. As I hinted above, I added a web interface for replying to reporters, as well as seeing the entire interaction in one place.

SMS Reporting Web Interface Voice Reporting

If you’d like to run this for your event, the source is all on github. https://github.com/jmhobbs/simple-coc

Tags: , , ,

Impromptu logging from a socket.io connection

October 27, 2012 » Geek

I recently participated in a live streamed event that provided a “watching now” counter usin socket.io. Basically it was a super simple node.js script which incremented or decremented a variable when users joined and left the channel, and broadcasted the count to it’s subscribers. What I didn’t realize until right before the event that we might want to have a record for users on page at a given point in the broadcast. With so little time before the broadcast, I didn’t want to tinker with the server and break it, so I did the next best thing, I logged from the subscriber side.

I put up a quick PHP script on my laptop that allowed cross-domain access from the origin server and logged the incoming counter.

Then, in Chrome's JavaScript console, I just hooked updates from socket.io into an XHR to provide the values to my PHP.

socket.on('update', function ( data ) { $.get('http://localhost/logger.php', { count: data.count } ); } );

It worked like a charm, I didn't have to mess with the server at a crucial point, and we got the data we needed.

Xoket: The Learning Framework

February 16, 2012 » Geek

If you are new to it, frameworks are confusing, and just hard. Books and tutorials help, but there’s still a lot of “magic” going on in the background. This is good if you can treat it as a black box, but it’s better if you can find out what’s going on in there.

To this end, I have decided to write a framework, piece by piece, from scratch.

This framework does not have delusions of grandeur. I don’t expect anyone to actually use it in production, that is not what it’s for.

This framework is about learning and sharing. I’m going to blog my way through every component, as I build it, and keep a full history in github. I’m not going to lie, there will be mis-steps, but you’ll be able to see it all evolve commit by commit.


Principles are a good place to start – here are some for Xoket (zah-ket)

1. Documentation

As stated above, documentation is essential. PHPDoc formatting will be used.

2. MVC

Xoket will be a single request, MVC framework. HMVC is popular, but in the interest of complexity, we will not be implementing multiple request.

3. Explicit is better than Implicit

Taking a queue from The Zen of Python I will try to write explicitly, instead of using implicit magic. Unusual technique will be commented and discussed.

4. Modular

As much functionality that can be moved out of the core, should be kept out of the core. Auto-loading will be PSR-0 compatible, but also include some cascading functionality similar to Kohana.

5. Modern

Xoket will be designed for PHP 5.3 and higher. If you aren’t running modern PHP you should, there really isn’t a good excuse.

Getting Started

That’s the outline of Xoket – my next post will be about the early implementation of, well, whatever I decide to write first.

Cache Control With Kohana 3

January 11, 2012 » Geek

I recently did some work with cache control in Kohana and found the documentation a little thin out there, so I thought I would share what I learned.

Kohana has nice built in functionality for ETag validations, so you don’t really need to roll your own cache headers.

If you need to brush up on web caching in general, I would recommend a quick read of Caching Tutorial for Web Authors and Webmasters, an excellent and concise reference.


For the purposes of this example, I’m creating a small controller which will use a short string as it’s response body. The implementation here is trivial.

response->body( 'Hello, world!' );

  } // Controller_Example

Let’s look at the headers that are returned by default. Your headers may vary, so adjust accordingly.

If you look at the response headers from this request, you will note that there no Cache-Control, Last-Modified or ETag headers are returned. That gives us a blank slate to work with.


An ETag is a unique identifier string describing your content for cache validation. ETags have an advantage over Last-Modified headers in that there is no need to worry about clock synchronization. The server can determine how to generate ETags in any manner it desires.

The Response object in Kohana provides two methods useful for ETag based caching. The first is Response::generate_etag(), the second is Response::check_cache().


This method uses the sha1 hash to create a unique ETag based on the content of the rendered response. Because it renders and hashes the response before returning a result, there is a memory and CPU time hit, which increases with the size of your response.


This method is the one we will use directly, as it compares the ETag of the response to request headers and takes the appropriate action.

It’s signature is ($etag = NULL, Request $request = NULL). This is a bit odd, because although both are NULL by default, and the Request parameter is second, it is not optional while $etag is.

If you provide NULL for $etag the method will use Response::generate_etag() to get a valid ETag. As mentioned above, this is not always the optimal choice, so if you have a unique identifier that you can provide, you should.

Since this is a simplistic example, I will let Response::generate_etag() create my ETag value.

response->check_cache( null, $this->request );

    public function action_index () {
      $this->response->body( 'Hello, world!' );

  } // Controller_Example

Let’s see the response headers for this version. We now have an ETag header, at the very bottom.

If we refresh the page again, we see that the browser sends an “If-None-Match” request header, which Response::check_cache() compares to the ETag. Finding that they match, the method returns a 304 response and immediately exits the script, causing the browser to use the cached version and saving the time it would take to send those bytes.

To demonstate how the ETag is generated let’s modify our response body so that it returns new content for every request (well, every second at least).

response->check_cache( null, $this->request );

    public function action_index () {
      $this->response->body( 'Hello, world at ' . date( DATE_RSS ) . '!' );

  } // Controller_Example

After refreshing we get a new body, and a new ETag, breaking the cache and re-sending the entire page.

Remember, if you implement this, you should try to use an alternate ETag value if you can.

Cache Control

ETags aren’t useful without a Cache-Control header, but you can set that yourself with Response::headers(), just be aware that Response::check_cache() will append must-revalidate to your header value, so don’t add that part yourself.

response->headers( 'cache-control', 'private' );
      $this->response->check_cache( null, $this->request );

    public function action_index () {
      $this->response->body( 'Hello, world at ' . date( DATE_RSS ) . '!' );

  } // Controller_Example

Hopefully that clears up how to use the built in browser cache handling in Kohana 3, please leave your own tips or experiences in the comments!

Thinking Functionally In PHP

November 22, 2011 » Geek

I’ve noticed a trend in PHP code to shy away from function application and closures. I understand to some extent. Useful, inline anonymous functions were not available until 5.3.0, which is relatively new. And create_function is an abomination.

Still, I think that PHP programmers just don’t think in this mindset, but it can be very useful.

Here is a rather contrived example, but one I’ve honestly seen an analogue of before.

$accumulator = array();
foreach( $this->tags->all() as $tags ) {
  $accumulator[] = htmlspecialchars( $tag->name );
return implode( ', ',  $accumulator );

Easy to understand, simple, does the job, but it is far more verbose than it needs to be.

Here is a version using array_map.

$tags = array_map( 'htmlspecialchars', $this->tags->all() );
return implode( ', ', $tags );

The array_map function is doing all the work of the loop, but you don’t have to write it and you don’t have to manage the accumulator.

Doesn’t that feel better?

Next time you mangle an array, first think if array_map or it’s friends array_filter or array_reduce could do it better.

Tags: , ,