<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Oliver Smith</title>
	<atom:link href="http://chemicaloliver.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://chemicaloliver.net</link>
	<description>experimentation and geekiness</description>
	<lastBuildDate>Fri, 11 May 2012 20:44:08 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Using PHP &#8211; Resque with Silex and the Symfony2 Classloader</title>
		<link>http://chemicaloliver.net/programming/using-php-resque-with-silex-and-the-symfony2-classloader/</link>
		<comments>http://chemicaloliver.net/programming/using-php-resque-with-silex-and-the-symfony2-classloader/#comments</comments>
		<pubDate>Fri, 11 May 2012 20:43:59 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[silex]]></category>
		<category><![CDATA[synfony2]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1360</guid>
		<description><![CDATA[Resque is a popular Redis-backed Ruby library for creating and processing background jobs, this is all well and good if you&#8217;re building applications in Ruby but fortunately for those, like me, who prefer PHP there is also a PHP port - PHP-Resque. This post will describe how to use php-resque in conjunction with the Silex micro framework to queue jobs, initially this [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://github.com/defunkt/resque">Resque</a> is a popular Redis-backed Ruby library for creating and processing background jobs, this is all well and good if you&#8217;re building applications in Ruby but fortunately for those, like me, who prefer PHP there is also a PHP port -<a href="https://github.com/chrisboulton/php-resque"> PHP-Resque</a>. This post will describe how to use php-resque in conjunction with the Silex micro framework to queue jobs, initially this was not immediately obvious to me as php-resque is not namespaced so wouldn&#8217;t work using the default autoloading configuration but fortunately the class naming seems to follow the PEAR convention where the path to the class is defined by the classname (i.e. Resque_Event would be found in Resque/Event.php). The method described here should work for any similar libraries.</p>
<p>One point to note, there is a Symfony2 bundle that could be easily integrated with Silex which aims to integrate php-resque but it&#8217;s a lot more complicated than I require and in most cases is just not necessary.</p>
<p>The key to using php-resque is to use the registerPrefix method of the symfony classloader (included with Silex) which uses PEAR naming conventions load libraries.</p>
<p>To configure php-resque first clone a copy of the library from github into the vendors folder (or wherever you like to store your external libraries):</p>
<pre class="brush: bash; title: ; notranslate">
git clone https://github.com/chrisboulton/php-resque.git vendors/php-resque
</pre>
<p>Now we have the library in place where ever you configure your application, in my case /src/bootstrap.php which is included in the main application file point the Synfony class loader to the place for classes beginning with the prefix Resque, all the relevant php-resque files are in the lib subdirectory:</p>
<pre class="brush: php; title: ; notranslate">
$app['autoloader']-&gt;registerPrefix('Resque', __DIR__ . '/../vendor/php-resque/lib');
$app['autoloader']-&gt;register();
</pre>
<p>It does need to be before the <code>$app['autoloader']-&gt;register();</code></p>
<p>The library can then be used in your application at will without requiring or manually including it:</p>
<pre class="brush: php; title: ; notranslate">
Resque::setBackend('localhost:6379');

$args = array();

Resque::enqueue('default', 'My_Job', $args);
</pre>
<p>Once you get your head around the different options the synfony2 classloader (and the rest of the components) are wonderful.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/using-php-resque-with-silex-and-the-symfony2-classloader/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTP Basic Auth in Silex</title>
		<link>http://chemicaloliver.net/programming/http-basic-auth-in-silex/</link>
		<comments>http://chemicaloliver.net/programming/http-basic-auth-in-silex/#comments</comments>
		<pubDate>Mon, 07 May 2012 15:08:37 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[silex]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1345</guid>
		<description><![CDATA[Silex is a great platform for building small web applications and APIs, recently I&#8217;ve been using it to build an API with only a couple of routes. As this API will only be used by a couple of users it made sense to use use HTTP basic auth (over SSL of course). HTTP auth could be [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://silex.sensiolabs.org/">Silex</a> is a great platform for building small web applications and APIs, recently I&#8217;ve been using it to build an API with only a couple of routes. As this API will only be used by a couple of users it made sense to use use HTTP basic auth (over SSL of course). HTTP auth could be left to apache/nginx etc. but that wouldn&#8217;t give me the control I&#8217;d like over the output and authentication so I implemented it in Silex, I hope someone finds this useful:</p>
<p>HTTP basic authentication is very simple and just passes a username and password in the headers, PHP has built in functionality to extract these values which can be used in the Silex before hook to ensure it happens before every request is fulfilled, my example is for an API which returns JSON but it would work equally well for a conventional website:</p>
<pre class="brush: php; title: ; notranslate">
$app-&gt;before(function() use ($app)
{
    if (!isset($_SERVER['PHP_AUTH_USER']))
    {
        header('WWW-Authenticate: Basic realm=&quot;&lt;website name&gt;&quot;');
        return $app-&gt;json(array('Message' =&gt; 'Not Authorised'), 401);
    }
    else
    {
        //once the user has provided some details, check them
        $users = array(
            'workflow' =&gt; 'password'
            );

        if($users[$_SERVER['PHP_AUTH_USER']] !== $_SERVER['PHP_AUTH_PW'])
        {
            //If the password for this user is not correct then resond as such
            return $app-&gt;json(array('Message' =&gt; 'Forbidden'), 403);
        }

        //If everything is fine then the application will carry on as normal
    }
});
</pre>
<p>Full details of implementing HTTP auth in PHP can be found in the <a href="http://php.net/manual/en/features.http-auth.php">PHP manual</a>, this includes how to implement HTTP digest auth.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/http-basic-auth-in-silex/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JSON Error / Exception Messages in Codeigniter 2.0+</title>
		<link>http://chemicaloliver.net/programming/json-error-exception-messages-in-codeigniter-2-0/</link>
		<comments>http://chemicaloliver.net/programming/json-error-exception-messages-in-codeigniter-2-0/#comments</comments>
		<pubDate>Mon, 09 Apr 2012 18:39:23 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1325</guid>
		<description><![CDATA[The Problem One of my recent projects required me to build a quick JSON only API to abstract interaction with multiple databases for multiple web applications, as I&#8217;d already got some of the logic in Codeigniter I just added Phil Sturgeon&#8217;s Codeigniter REST Library. However while this handles all method not found errors when URL routing gets as [...]]]></description>
			<content:encoded><![CDATA[<h2>The Problem</h2>
<p>One of my recent projects required me to build a quick JSON only API to abstract interaction with multiple databases for multiple web applications, as I&#8217;d already got some of the logic in Codeigniter I just added <a href="http://philsturgeon.co.uk/blog/2009/06/REST-implementation-for-CodeIgniter">Phil Sturgeon&#8217;s Codeigniter REST Library</a>. However while this handles all method not found errors when URL routing gets as far as the controller all other errors still appear as HTML, when using curl and attempting to parse as JSON this isn&#8217;t helpful.</p>
<h2>The Solution</h2>
<p>My solution was to extend the core Exceptions class which normally deals with these errors. This is done by creating MY_Exceptions.php in application/core and using something similar to the code below:<br />
<span id="more-1325"></span></p>
<pre class="brush: php; title: ; notranslate">
&lt;?php defined('BASEPATH') OR exit('No direct script access allowed');

/**
 * Extending the default errors to always give JSON errors
 *
 * @author Oliver Smith
 */

class MY_Exceptions extends CI_Exceptions
{
	function __construct()
	{
		parent::__construct();
	}

	/**
	 * 404 Page Not Found Handler
	 *
	 * @param	string	the page
	 * @param 	bool	log error yes/no
	 * @return	string
	 */
	function show_404($page = '', $log_error = TRUE)
	{
		// By default we log this, but allow a dev to skip it
		if ($log_error)
		{
			log_message('error', '404 Page Not Found --&gt; '.$page);
		}

		header('Cache-Control: no-cache, must-revalidate');
		header('Content-type: application/json');
		header(&quot;HTTP/1.1 404 Not Found&quot;);

		echo json_encode(
			array(
				'status' =&gt; FALSE,
				'error' =&gt; 'Unknown method',
			)
		);

		exit;
	}

	/**
	 * General Error Page
	 *
	 * This function takes an error message as input
	 * (either as a string or an array) and displays
	 * it using the specified template.
	 *
	 * @access	private
	 * @param	string	the heading
	 * @param	string	the message
	 * @param	string	the template name
	 * @param 	int		the status code
	 * @return	string
	 */
	function show_error($heading, $message, $template = 'error_general', $status_code = 500)
	{
		header('Cache-Control: no-cache, must-revalidate');
		header('Content-type: application/json');
		header(&quot;HTTP/1.1 500 Internal Server Error&quot;);

		echo json_encode(
			array(
				'status' =&gt; FALSE,
				'error' =&gt; 'Internal Server Error',
			)
		);

		exit;
	}

	/**
	 * Native PHP error handler
	 *
	 * @access	private
	 * @param	string	the error severity
	 * @param	string	the error string
	 * @param	string	the error filepath
	 * @param	string	the error line number
	 * @return	string
	 */
	function show_php_error($severity, $message, $filepath, $line)
	{
		header('Cache-Control: no-cache, must-revalidate');
		header('Content-type: application/json');
		header(&quot;HTTP/1.1 500 Internal Server Error&quot;);

		echo json_encode(
			array(
				'status' =&gt; FALSE,
				'error' =&gt; 'Internal Server Error',
			)
		);

		exit;
	}
}

?&gt;
</pre>
<h2>Limitations</h2>
<p>This code will only output a basic JSON formatted message, it will not vary the http error codes based on conditions, nor will it take into account accepts headers or similar. Right now this class meets my needs but features such as other formats could easily be added.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/json-error-exception-messages-in-codeigniter-2-0/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Codeigniter Conference 2012 &#8211; Post Conference Thoughts</title>
		<link>http://chemicaloliver.net/events-2/codeigniter-conference-2012-post-conference-thoughts/</link>
		<comments>http://chemicaloliver.net/events-2/codeigniter-conference-2012-post-conference-thoughts/#comments</comments>
		<pubDate>Sun, 19 Feb 2012 21:38:11 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[ciconf]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1299</guid>
		<description><![CDATA[Having not even got back home yet after the 2012 Codeigniter Conference I thought I&#8217;d write up some of my highlights of a very enjoyable weekend: Testing - John Crepizzi Testing is something I&#8217;ve been working on recently using Simpletest, Jenkins and Codeigniter with moderate success, it was great to see that PHPUnit can be [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: center;"><img class="size-medium wp-image-1305 aligncenter" title="CIConf 2012 Logo" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2012/02/Screenshot-at-2012-02-19-2130531-300x100.png" alt="" width="300" height="100" /></p>
<p>Having not even got back home yet after the 2012 Codeigniter Conference I thought I&#8217;d write up some of my highlights of a very enjoyable weekend:</p>
<p><span id="more-1299"></span></p>
<h3>Testing -<a href="http://twitter.com/seejohnrun" target="_blank"> John Crepizzi</a></h3>
<p>Testing is something I&#8217;ve been working on recently using Simpletest, Jenkins and Codeigniter with moderate success, it was great to see that PHPUnit can be used quite simply, however as full PHPUnit support is planned to be integrated into the core of Codeigniter in v3.0 I think I&#8217;ll wait before transitioning away from Simpletest.</p>
<h3>API Driven Development &#8211; <a href="http://nickjackson.me/" target="_blank">Nick Jackson</a></h3>
<p>Nick did a great job of reassuring me I&#8217;m doing things right. I&#8217;ve just started a project where I&#8217;m essentially building the API first as I know there are going to be multiple apps on top of it. I&#8217;ll definitely be refining my existing API based on some of the tips given regarding response format.</p>
<h3>MongoDB &#8211; <a href="http://www.httpster.org/" target="_blank">Alex Bilbie</a></h3>
<p>MongoDB is something I&#8217;ve played with but not used in anger yet, I&#8217;m not sure I have a use case for it yet but this talk did demonstrate some very cool edge case functions for searching using latitude and longitude where MongoDB will do all the heavy lifting when trying to do box searches on a 3d spherical earth model.</p>
<h3>Who needs Ruby when you&#8217;ve got CodeIgniter? &#8211; <a href="http://twitter.com/jamierumbelow">Jamie Rumbelow</a></h3>
<p>Jamie Rumberlow&#8217;s talk was very practical and showed some very good ideas of how Codeigniter could be improved but demonstrated some really hacky ways to make it work the way he wanted (putting non POST data for validation into $_POST anyone&#8230;.). Really I&#8217;d have preferred to see him talk about how the framework could be improved to fit in with the best practice. That&#8217;s the kind of thing that gives Codeigniter a bad reputation amongst many PHP developers.</p>
<h3>Live coding  - <a href="http://twitter.com/philsturgeon" target="_blank">Phil Sturgeon</a></h3>
<p>Phil demoed setting up a pyrocms site on pagodabox, while I didn&#8217;t find the actual demo very relevant to me, I do like is looking into others coding setups, this lead me to spend half of the next talk configuring my bash prompt and colour scheme to show mercurial or git branch names!</p>
<h3>Other Talks</h3>
<p>All of the talks were very engaging but some not as interesting to me personally, in particular <a href="http://twitter.com/WanWizard" target="_blank">Harro Verton </a>was a great speaker on ORMs but it just further confirmed my views that I&#8217;m not a fan.</p>
<h3>General Thoughts</h3>
<p>Generally the conference went well, the venue was pretty good (apart from the food) and the wifi nothing short of amazing. Oh and the best bit &#8211; a FREE t shirt!</p>
<p>I&#8217;m always in a bit of a love hate relationship with Codeigniter, it&#8217;s very quick and easy but its slightly old fashioned way of doing things and lack of modern features like auto-loading, namespacing and dependency injection make it annoy me and cause me to look at things like Symfony2 or Silex.</p>
<p>Still a great weekend away and thanks to all who were responsible for the planning and organisation. I&#8217;ll hopefully be back next time.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/events-2/codeigniter-conference-2012-post-conference-thoughts/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Streaming audio from Ubuntu Linux to a DLNA player (Blu Ray or PS3) using Rygel</title>
		<link>http://chemicaloliver.net/linux/streaming-audio-from-ubuntu-linux-to-a-dlna-player-blu-ray-or-ps3/</link>
		<comments>http://chemicaloliver.net/linux/streaming-audio-from-ubuntu-linux-to-a-dlna-player-blu-ray-or-ps3/#comments</comments>
		<pubDate>Tue, 10 Jan 2012 20:15:43 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[linux]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1277</guid>
		<description><![CDATA[This project started out of researching how to play sound from spotify or rhythmbox from my laptop running ubuntu 11.10 through my hifi. Initially I set out to see if an airport express would work using raop and pulseaudio but it seems that support for the new 802.11 version is flakey so I didn&#8217;t wish to invest £80 [...]]]></description>
			<content:encoded><![CDATA[<p>This project started out of researching how to play sound from spotify or rhythmbox from my laptop running ubuntu 11.10 through my hifi. Initially I set out to see if an airport express would work using raop and pulseaudio but it seems that support for the new 802.11 version is flakey so I didn&#8217;t wish to invest £80 in a device that might not work. During my research I found that DLNA supported streaming, DLNA is a protocol commonly used for sharing media files with devices such as networked dvd players, internet tvs and consoles like the ps3 so I explored further.</p>
<p>DLNA is supported in Ubuntu (and other modern linux distros) by <a href="http://live.gnome.org/Rygel">Rygel</a>, part of the Gnome project. Rygel provides a DLNA server which also has the capability to capture a pulseaudio sink (an input or output stream) and stream it to a DLNA enabled device.</p>
<p>Below are the steps I took to enable me to stream audio from my computer to my Sony BDP-S370, they should be applicable to any similar device:<br />
<span id="more-1277"></span></p>
<ol>
<li>Install required packages:
<pre class="brush: bash; title: ; notranslate">sudo apt-get install rygel rygel-gst-launch wavpack</pre>
</li>
<li>Find the name of the pulseaudio sink which you wish to capture:<br />
To list the choices, use:
<pre class="brush: bash; title: ; notranslate">pacmd list-sinks</pre>
<p>Then make a note of the name attribute (minus surrounding brackets), in my case it was:</p>
<pre class="brush: bash; title: ; notranslate">alsa_output.usb-C-Media_INC._USB_Sound_Device-00-Device.analog-stereo</pre>
<p>I found that adding .monitor to this was required for the next stage, this can be achieved in one command:</p>
<pre class="brush: bash; title: ; notranslate">pactl list | egrep -A2 '^(\*\*\* )?Source #' | grep 'Name: .*\.monitor$' | awk '{print $NF}' | tail -n1</pre>
</li>
<li>Edit /etc/rygel.conf:<br />
Replace (or comment out)</p>
<pre class="brush: bash; title: ; notranslate">
[GstLaunch]
enabled=true
launch-items=audiotestsrc;videotestsrc;videotestoverlay
audiotestsrc-title=Audiotestsrc
audiotestsrc-mime=audio/x-wav
audiotestsrc-launch=audiotestsrc ! wavenc
videotestsrc-title=Videotestsrc
videotestsrc-mime=video/mpeg
videotestsrc-launch=videotestsrc ! ffenc_mpeg2video ! mpegtsmux
videotestoverlay-title=Videotestsrc with timeoverlay 2
videotestoverlay-mime=video/mpeg
videotestoverlay-launch=videotestsrc ! timeoverlay ! ffenc_mpeg2video ! mpegtsmux
</pre>
<p>with</p>
<pre class="brush: bash; title: ; notranslate">[GstLaunch]
enabled=true
launch-items=mypulseaudiosink
mypulseaudiosink-title=Audio on @HOSTNAME@
mypulseaudiosink-mime=audio/x-wav
mypulseaudiosink-launch=pulsesrc device=alsa_output.usb-C-Media_INC._USB_Sound_Device-00-Device.analog-stereo.monitor ! wavpackenc
</pre>
<p>replacing the device on the last line with the output from the previous stage.</li>
<li>Start Rygel (type rygel in the terminal)</li>
<li>Connect your player to the DLNA device which should have appeared (probably as GstLaunch) and you should hear any audio played on your computer through your DLNA device.</li>
<li>If you wish (I don&#8217;t) add rygel to run at startup.</li>
</ol>
<div><em>This worked perfectly for my desktop but for my laptop I had to fiddle with which hardware output of the soundcard was being used under the standard gnome sound settings, changing the profile for the selected device to an option with no output (ie input only or disabled).</em></div>
<h2>Alternatives</h2>
<ul>
<li>If you just wish to share audio and video files then something like <a href="http://mediatomb.cc/">mediatomb</a> with be much more simple (although rygel also shares files).</li>
<li>There is meant to be a simpler way to link rygel and pulseaudio where everything works out of the box and rygel appears as a separate audio out but it&#8217;s currently broken with the supplied pulseaudio/rygel combination in ubuntu.</li>
</ul>
<h2>Acknowledgements</h2>
<p>I figured all this out with the help of these guys:</p>
<ul>
<li><a href="http://ubuntuforums.org/showpost.php?p=11010331&amp;postcount=4">http://ubuntuforums.org/showpost.php?p=11010331&amp;postcount=4</a></li>
<li><a href="http://www.outflux.net/blog/archives/2009/04/19/recording-from-pulseaudio/">http://www.outflux.net/blog/archives/2009/04/19/recording-from-pulseaudio/</a></li>
<li><a href="http://mpd.wikia.com/wiki/PulseAudio">http://mpd.wikia.com/wiki/PulseAudio</a></li>
</ul>
<p>Thanks.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/linux/streaming-audio-from-ubuntu-linux-to-a-dlna-player-blu-ray-or-ps3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>PHP 5.4 File Upload Progress and HTML5 Progress Bars</title>
		<link>http://chemicaloliver.net/programming/php-5-4-file-upload-progress-and-html5-progress-bars/</link>
		<comments>http://chemicaloliver.net/programming/php-5-4-file-upload-progress-and-html5-progress-bars/#comments</comments>
		<pubDate>Sun, 04 Dec 2011 00:35:07 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1221</guid>
		<description><![CDATA[This posts was originally written for using pre release versions of php5.4, now PHP5.4 has been release everything should work as before I haven&#8217;t tested it. There is probably more choice in ways to install it now. There was a live demo of this but I couldn&#8217;t justify the cost of a whole ec2 instance just for this! The [...]]]></description>
			<content:encoded><![CDATA[<p><em>This posts was originally written for using pre release versions of php5.4, now PHP5.4 has been release everything should work as before I haven&#8217;t tested it. There is probably more choice in ways to install it now.</em></p>
<p><em>There was a live demo of this but I couldn&#8217;t justify the cost of a whole ec2 instance just for this!</em></p>
<p><em>The way I have implemented this may be problematic in Chrome/Safari due to Webkit <a href="https://bugs.webkit.org/show_bug.cgi?id=23933">Bug 23933</a>,  &#8221;XMLHttpRequest doesn&#8217;t work while submitting a form (useful for progress tracking)&#8221; I tested this in firefox (the latest version at the time) and it worked fine. Chrome may or may not work. Let me know how you get on.</em></p>
<p>Full details of the upload progress implementation can be found the official RFC: <a href="https://wiki.php.net/rfc/session_upload_progress">https://wiki.php.net/rfc/session_upload_progress</a></p>
<p>Developers who work with PHP applications that upload files commonly struggle with providing user feedback on the upload progress, usually using flash and javascript solutions like uploadify. In PHP 5.4 there is now integrated functionality to allow file upload progress to be passed back to the browser.</p>
<p>In this post I&#8217;ll describe the basic operation of this feature and describe a quick example of its use.</p>
<p style="text-align: center;"><a href="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/12/Screenshot-at-2011-12-03-234816.png"><img class="size-medium wp-image-1234 aligncenter" title="PHP 5.4 Upload Progress" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/12/Screenshot-at-2011-12-03-234816-300x156.png" alt="" width="300" height="156" /></a></p>
<h2>How it Works</h2>
<p>The upload progress functionality stores the current progress in a session variable which can then be queried as required to give the current progress, it requires the use of PHP native sessions. The $_SESSION key is set by the form name and a prefix defined in php.ini</p>
<p><span id="more-1221"></span></p>
<p>An example of the data stored is shown below:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php $_SESSION[&quot;upload_progress_123&quot;] = array(  &quot;start_time&quot; = 1234567890,  &quot;content_length&quot; = 57343257,
 &quot;bytes_processed&quot; =&gt; 453489,
 &quot;done&quot; =&gt; false,
 &quot;files&quot; =&gt; array(
  0 =&gt; array(
   &quot;field_name&quot; =&gt; &quot;file1&quot;,
   // The following 3 elements equals those in $_FILES
   &quot;name&quot; =&gt; &quot;foo.avi&quot;,
   &quot;tmp_name&quot; =&gt; &quot;/tmp/phpxxxxxx&quot;,
   &quot;error&quot; =&gt; 0,
   &quot;done&quot; =&gt; true,
   &quot;start_time&quot; =&gt; 1234567890,
   &quot;bytes_processed&quot; =&gt; 57343250,
  ),
  // An other file, not finished uploading, in the same request
  1 =&gt; array(
   &quot;field_name&quot; =&gt; &quot;file2&quot;,
   &quot;name&quot; =&gt; &quot;bar.avi&quot;,
   &quot;tmp_name&quot; =&gt; NULL,
   &quot;error&quot; =&gt; 0,
   &quot;done&quot; =&gt; false,
   &quot;start_time&quot; =&gt; 1234567899,
   &quot;bytes_processed&quot; =&gt; 54554,
  ),
 )
);
</pre>
<p>It is up to the developer how they wish to present this data to the user.</p>
<h2>Setup</h2>
<p>This functionality is included as standard in PHP 5.4 which can be simply installed from an ubuntu package as discussed in my previous post: <a href="http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/">http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/</a></p>
<p>This feature should be enabled by default.</p>
<h2>Example</h2>
<p>Complete code can be found on <a href="https://github.com/chemicaloliver/PHP-5.4-Upload-Progress-Example">github</a>.</p>
<h3>Upload Form</h3>
<p>The upload form is standard html file upload form apart from an additional hidden value defining the progress name attribute so the upload can be identified in the session variables later:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;form id=&quot;upload&quot; action=&quot;/progress/upload.php&quot; method=&quot;POST&quot; enctype=&quot;multipart/form-data&quot;&gt;&lt;input type=&quot;hidden&quot; name=&quot;&quot; value=&quot;upload&quot; /&gt;

 &lt;input id=&quot;file1&quot; type=&quot;file&quot; name=&quot;file1&quot; /&gt;
 &lt;input id=&quot;file2&quot; type=&quot;file&quot; name=&quot;file2&quot; /&gt;

 &lt;input class=&quot;btn primary&quot; type=&quot;submit&quot; value=&quot;Upload&quot; /&gt;&lt;/form&gt;
</pre>
<p>In my example I&#8217;ve used the <a href="http://jquery.malsup.com/form/">jquery form plugin</a> to make submitting the form using AJAX more simple.</p>
<h3>Recieving Script</h3>
<p>In this example the receiving script needs to do nothing except start a session, I added a var_dump for debugging initially:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php session_start(); var_dump($_SESSION); var_dump($_FILES);?&gt;
</pre>
<h3>Monitoring Progress</h3>
<p>This is performed through a combination of javascript and PHP, the client polls a server page which echos the current progress as JSON:</p>
<h4>Client:</h4>
<p>The client uses an interval time to get the progress every 200ms and pass it to an HTML5 progress bar.</p>
<pre class="brush: jscript; title: ; notranslate">
interval_id = setInterval(function() {
$.getJSON('/progress/progress.php', function(data){
    //if there is some progress then update
    if(data)
    {
        $('#progress').val(data.bytes_processed / data.content_length);
        $('#progress-txt').html('Uploading '+ Math.round((data.bytes_processed / data.content_length)*100) + '%');
    }

    //When there is no data the upload is complete
    else
    {
        $('#progress').val('1');
        $('#progress-txt').html('Complete');
        stopProgress();
    }
})
}, 200);
</pre>
<h4>Server Side:</h4>
<p>The server side just echos a json encoded version of the session variable:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php session_start(); echo json_encode( $_SESSION['upload_progress_upload']); ?&gt;
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/php-5-4-file-upload-progress-and-html5-progress-bars/feed/</wfw:commentRss>
		<slash:comments>13</slash:comments>
		</item>
		<item>
		<title>Installing PHP 5.4 in Ubuntu</title>
		<link>http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/</link>
		<comments>http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/#comments</comments>
		<pubDate>Sat, 03 Dec 2011 23:46:02 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1223</guid>
		<description><![CDATA[I&#8217;ve been excitedly awaiting some of the new features found in PHP 5.4, in particular array notation and file upload progress monitoring so I decided to try and install PHP 5.4 on Ubuntu. Fortunately there is a repository of prebuilt packages for Ubuntu. I recommend using a VM so you don&#8217;t mess up any stable PHP install. Update [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been excitedly awaiting some of the new features found in PHP 5.4, in particular array notation and file upload progress monitoring so I decided to try and install PHP 5.4 on Ubuntu. Fortunately there is a repository of prebuilt packages for Ubuntu.</p>
<p>I recommend using a VM so you don&#8217;t mess up any stable PHP install.</p>
<h2><em>Update</em></h2>
<p>Since writing this post php 5.4 stable has been released and a more up to date package is available in this ppa: <a href="https://launchpad.net/~ondrej/+archive/php5">https://launchpad.net/~ondrej/+archive/php5</a> I haven&#8217;t tested this personally but should work as described below.</p>
<h2>Installation</h2>
<p>The ppa can be simply added to ubuntu:</p>
<pre class="brush: bash; title: ; notranslate">
sudo add-apt-repository ppa:ondrej/php5
</pre>
<p>Then installing as normal</p>
<pre class="brush: bash; title: ; notranslate">
sudo apt-get update
sudo apt-get install php5 libapache2-mod-php5
</pre>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/internet/installing-php-5-4-in-ubuntu/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Codeigniter Unit Testing with Simpletest and PHP 5.3</title>
		<link>http://chemicaloliver.net/internet/codeigniter-unit-testing-with-simpletest-and-php-5-3/</link>
		<comments>http://chemicaloliver.net/internet/codeigniter-unit-testing-with-simpletest-and-php-5-3/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 22:03:04 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Internet]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[simpletest]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1212</guid>
		<description><![CDATA[I&#8217;m a regular user of codeigniter-simpletest developed by Eric Barnes however I ran into a number of issues when attempting to run some features under PHP5.3, this was due to using an old version of Simpletest. I have now updated this and had my pull request accepted and merged into the main repo so that [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a regular user of <a title="Github: Codeigniter-Simpletest" href="http://github.com/ericbarnes/codeigniter-simpletest">codeigniter-simpletest</a> developed by Eric Barnes however I ran into a number of issues when attempting to run some features under PHP5.3, this was due to using an old version of Simpletest. I have now updated this and had my pull request accepted and merged into the main repo so that it now uses the most recent versions (1.1alpha3).</p>
<p>There is however one important change to note which will stop old tests working, that is the way that test classes define a label, these are optional so this only applies if you use them in your project. The name of the test is now passed through the simpletest constructor otherwise the default is to use the classname of the test.</p>
<h3>Before</h3>
<pre class="brush: php; title: ; notranslate">
class test_users_model extends CodeIgniterUnitTestCase
{
	public function __construct()
	{
		parent::__construct();

		$this-&gt;UnitTestCase('Users Model');

		$this-&gt;load-&gt;model('users/users_model');
	}

etc...
</pre>
<h3>After</h3>
<pre class="brush: php; title: ; notranslate">
class test_users_model extends CodeIgniterUnitTestCase
{
	public function __construct()
	{
		parent::__construct('Users Model');

		$this-&gt;load-&gt;model('users/users_model');
	}
etc...
</pre>
<p>I&#8217;m also working on integration with CI systems, Jenkins in particular based on this rather cool presentation: <a href="http://www.cs.northwestern.edu/academics/courses/394/ci-server-setup/orange-ci-setup-2011.pdf" target="_blank">Setting up a Continuous Integration Server for Ubuntu with Codeigniter and Github</a></p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/internet/codeigniter-unit-testing-with-simpletest-and-php-5-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHP North West 2011</title>
		<link>http://chemicaloliver.net/programming/php-north-west-2011/</link>
		<comments>http://chemicaloliver.net/programming/php-north-west-2011/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 13:23:41 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Events]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[manchester]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[phpnw]]></category>
		<category><![CDATA[scripting]]></category>
		<category><![CDATA[web development]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1202</guid>
		<description><![CDATA[This was my first PHPNW conference but after hearing so many good things about the conference in previous years I thought I&#8217;d give it a go. In this post I&#8217;ll summarise some of my highlights. Talks (Selected) PHP Tester&#8217;s Toolbox &#8211; Sebastian Bergmann A quick run through different testing frameworks for use with PHP, as Sebastian is [...]]]></description>
			<content:encoded><![CDATA[<p>This was my first PHPNW conference but after hearing so many good things about the conference in previous years I thought I&#8217;d give it a go. In this post I&#8217;ll summarise some of my highlights.</p>
<p style="text-align: center;"><img class="size-full wp-image-1203 aligncenter" title="PHPNW11 Logo" src="http://chemicaloliver.net/wordpress/wp-content/uploads/2011/10/phpnw11-logo.png" alt="" width="200" height="68" /></p>
<p><span id="more-1202"></span></p>
<h2>Talks (Selected)</h2>
<h3>PHP Tester&#8217;s Toolbox &#8211; Sebastian Bergmann</h3>
<p>A quick run through different testing frameworks for use with PHP, as Sebastian is the creator of PHPUnit this talk had an obvious bias but I didn&#8217;t feel this overwhelmed the talk. For me who has used phpunit and simpletest for unit testing there was nothing ground breaking here but gave me an introduction to BDD and reassured me I was doing the existing bits right.</p>
<h3>Deploying PHP Applications with Phing &#8211; Michiel Rook</h3>
<p>Phing is one of those things I keep meaning to get around to, I&#8217;ve used various methods for deployment from mercurial to FTP and ant (when using html5 boilerplate) but Phing seems like a logical thing to use for PHP deployment, as with the previous talk this just provided reassurance that I&#8217;d understood it correctly and didn&#8217;t really provide anything new. It also only half filled the slot which felt like a bit of a waste.</p>
<h3>Estimation or &#8216;How to dig your own grave&#8217; &#8211; Rowan Merewood</h3>
<p>Without a doubt this was the most entertaining talk of the day, plagued by early technical issues Rowan breezed through it all with a casual air of confidence and a good measure of humour. The content of the talk was also pretty spot on discussing common sense ways to improve estimating how long your projects will take, much of it rang true for me and will be bearing it in mind in the future, if only my boss got to watch it he might understand that actually my estimations are not so long after all.</p>
<h3>Are your tests really helping &#8211; Laura Beth Denker</h3>
<p>Another entertaining talk centring on best practice when testing with anecdotes from LB&#8217;s experience at Google and Etsy liberally mixed in. For me this was a talk which described a way of working to aspire to; Etsy have over 100 developers and can deploy new code up to every 20 minutes due to the efficiency of the test and deployment process. The approach LB presented was a nice common sense approach of testing what needs to be tested rather than every little thing.</p>
<h3>Introducing Pyri the new aggregator for Pear &#8211; Jeremy Coates</h3>
<p>The only talk I&#8217;m going to mention here that I watched from the unconference track given by the organiser of the event (or at least one of them). It described an aggregator and search engine for the PEAR PHP package system which is notoriously fragmented. The system, which is only in its early stages of development at the moment  (humorously described as Conference Driven Development), crawls submitted PEAR repos and grabs the XML data on the packages and indexes it. The data is then accessed via an API. The eventual aim is to have a one stop reference site for all PEAR packages available. Development is set to continue on the project over the coming months.</p>
<h2>Organisation</h2>
<p>In general the organisation of the conference seemed great pretty much everything ran smoothly and there were no real frustrations.</p>
<p>I&#8217;m still not sure in my mind if three tracks + an unconference track are too much, there were odd things in the unconference track I would liked to have seen but clashed with one or more things on the schedule. However I did appreciate the unconference track as it filled in a few gaps when other talks finished early. It&#8217;s probably better this way than having times when there was nothing I wished to see.</p>
<h2>Venue</h2>
<p>The physical location for the conference was great, the Ramada Hotel in Manchester is about 10 minutes walk from the station, however the hotel itself wasn&#8217;t amazing; the chairs were the most uncomfortable I&#8217;ve ever sat on at a conference and some of the hotel looked a bit tired.When it came to lunchtime for some (me included) the queue was unbearable and lack of space to be seated was a disappointment so I retreated to the local Pret a Manger which also allowed me to get some welcome fresh air.</p>
<h2>Overall</h2>
<p>All in all I had an enjoyable day and will probably return next year, however I didn&#8217;t leave inspired to go home an instantly start a new exciting project to make use of something I&#8217;d learnt, more a host of useful little things to integrate into existing projects and ways to improve what I&#8217;m already doing, so still good but not mind blowing.</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/php-north-west-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Speeding up PHP &#8211; Using process forking to accelerate image resizing</title>
		<link>http://chemicaloliver.net/programming/speeding-up-php-using-process-forking-for-image-resizing/</link>
		<comments>http://chemicaloliver.net/programming/speeding-up-php-using-process-forking-for-image-resizing/#comments</comments>
		<pubDate>Fri, 07 Oct 2011 13:42:23 +0000</pubDate>
		<dc:creator>Oliver</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://chemicaloliver.net/?p=1182</guid>
		<description><![CDATA[Most of my projects at work involve resizing images in PHP applications, usually the result is loaded via AJAX so it needs to be generated as fast as possible for optimum user experience. Recently I discovered the ability to fork processes in PHP, this gives the ability to run multiple functions at the same time. [...]]]></description>
			<content:encoded><![CDATA[<p>Most of my projects at work involve resizing images in PHP applications, usually the result is loaded via AJAX so it needs to be generated as fast as possible for optimum user experience. Recently I discovered the ability to fork processes in PHP, this gives the ability to run multiple functions at the same time. In the example below I&#8217;ll demonstrate how parallel processing can be used in PHP to speed the generation of several different sizes of preview images from a large uploaded image.</p>
<p>This code uses the <a href="http://www.php.net/manual/en/book.pcntl.php">PCNTL</a> extension which was installed as standard on my Ubuntu 11.04 PHP 5.3 install.</p>
<p><span id="more-1182"></span></p>
<p>Conventionally to generate a couple of different sizes of images from a large JPEG image one might use something like this:</p>
<pre class="brush: php; title: ; notranslate">
&lt;?php

/**
 * Create a thumbnail image from the specified file
 *
 * @param int $height output image height
 * @param int $width  output image width
 */

function create_preview($height, $width)
{
    //Input image
    $img = 'test.jpg';

    //Output image
    $new_img = 'test -'.$width.'x'.$height.'.jpg';

    //get the current image size
    list($full_width, $full_height) = getimagesize($img) ;

    //Create a blank image to load in the new resized image
    $tn = imagecreatetruecolor($width, $height) ;

    //Load the original file
    $image = imagecreatefromjpeg($img) ;

    //Do the crop
    imagecopyresampled($tn, $image, 0, 0, 0, 0, $width, $height, $full_width, $full_height) ;

    //Save the file
    imagejpeg($tn, $new_img, 100);
}        

// The thumbnail sizes to be generated
$image_sizes = array(
    array(100,100),
    array(200, 200),
    array(300, 300),
    array(400, 400),
    array(500, 500),
    array(1000, 1000)
);

// Loop through the images sequentially
foreach($image_sizes as $image_size)
{
    create_preview($image_size[0], $image_size[1]);
}

?&gt;
</pre>
<p>To get an idea of the speed of this script we can run it from the command line:</p>
<pre class="brush: bash; title: ; notranslate">
time php single_process.php
</pre>
<p>This takes couple of seconds, as you might expect, in my case:</p>
<pre class="brush: bash; title: ; notranslate">
real	0m2.325s
user	0m2.210s
sys	0m0.100s
</pre>
<p>However rather than performing the resizing sequentially it can be performed in parallel using the same <code>create_preview()</code> function as before:</p>
<pre class="brush: php; title: ; notranslate">
// The thumbnail sizes to be generated
$image_sizes = array(
    array(100,100),
    array(200, 200),
    array(300, 300),
    array(400, 400),
    array(500, 500),
    array(1000, 1000)
);

//Counter for number of processes
$i = 1;

//Loop through the image sizes but this time fork a process for each size.
foreach($image_sizes as $image_size)
{
    //Fork a process
    $pid = pcntl_fork();

    //if we're in a child thread then grab an image size and process it.
    if (!$pid)
    {
        echo 'starting child ', $i, PHP_EOL;
        create_preview($image_size[0], $image_size[1]);

        //Die otherwise the process will continue to loop and each process will create all the thumbnails
        die();
    }

    $i++;
}

//Wait for all the subprocesses to complete to avoid zombie processes
foreach($image_sizes as $image_size)
{
    pcntl_wait($status);
}
</pre>
<p>Now running the script using the same command line again the advantage is instantly noticeable:</p>
<pre class="brush: bash; title: ; notranslate">
time php multi_process.php

starting child 1
starting child 2
starting child 3
starting child 4
starting child 5
starting child 6

real	0m0.693s
user	0m3.030s
sys	0m0.140s
</pre>
<p>As you can see from this very unscientific test running the processes in parallel increases the speed by over 3.5x. As long as you&#8217;re careful to watch for threads terminating and not just leaving them unattended this seems like a great way to speed up simple repetitive tasks, <del>I&#8217;d certainly hope to find a place for it in some of my applications in the future</del> I&#8217;ll probably not use this in a production web application due to the warning that Paul kindly posted below, I guess should read the manual before getting excited&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://chemicaloliver.net/programming/speeding-up-php-using-process-forking-for-image-resizing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

