Sparkline Creation Using PHP

Sparkline graphs have had a bit of press lately, so I’ve been playing about with generating them on my commutes to and from work.

If you’ve not heard of them before, a Sparkline is a small graph that is often used inline with text.

I’ve been using PHP, so I’ve created a simple class called Spark, with a single static method called line. This returns a simple string as an inline graph from an array of values that have been passed in.

Sparkline Examples

Here’s an example plotting a simple staircase type graph.

require_once('lib/Spark.php');

echo Spark::line(array(1, 2, 3, 4, 5, 6, 7, 8)) . "n";

> ▁▂▃▄▅▆▇█

Here’s an example plotting a cosine wave.

$cos = array();
for($i=0; $i <= 360; $i=$i+20) {
    $cos[] = cos($i * M_PI / 180);
}
echo Spark::line($cos) . "n";

> ██▇▆▅▄▃▂▁▁▁▂▃▄▅▆▇██

Summary

The code is available on GitHub as php-spark, and is free to use. It was inspired by a simple project for Go called Spark, which was inspired from elsewhere.

Data URI’s – Using and Generating

A recent project of mine needed an image embedding into some HTML via JavaScript. Rather than use a separate image, I decided to embed it directly using a data URI.

An image in a data URI is the MIME type of the image and it’s content encoded with base64 into a string. This is great as it cuts down HTTP requests but does cause the initial page weight to increase and be difficult to update as each change means the image needs re-encoding. Modern browsers support data URI’s very well, but older browsers such as IE 7 and below won’t like it.

Examples Using A Data URI Encoded Image

HTML Example

Here’s how I can embed the image of a red cross into an HTML <img> tag.

<img src="data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw==" alt="red cross" width="20" height="20" />

CSS Example

Here’s how I can embed the image of a red cross into background of an HTML element using CSS.

body { 
  background: url(data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw==) no-repeat left center;
}

JavaScript Example

Here’s how I can add an image element with the red cross in to an HTML page using JavaScript.

var imagestring = "data:image/gif;base64,R0lGODlhFAAUAJEAAP/9/fYQEPytrflWViH5BAAAAAAALAAAAAAUABQAQAJKhI+pGe09lnhBnEETfodatVHNh1BR+ZzH9LAOCYrVYpiAfWWJOxrC/5MASbyZT4d6AUIBlUYGoR1FsAXUuTN5YhxAEYbrpKRkQwEAOw==";
var image = new Image();
image.src = imagestring;
image.onload = function() {
  document.body.appendChild(image);  
}

Encoding An Image To A Data URI

It’s easy to create the encoded image string using PHP as it comes with a Base64 encoder as part of the language. Automatically detecting the MIME type of an image is a bit harder, but we can use finfo_file with comes as an extension to PHP 5.3 and above to do this.

So assuming the filename of the image is in the variable $filename we can use the following code to get the mimetype, read the image and encode it to a data URI string.

$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mimetype = finfo_file($finfo, $filename);
finfo_close($finfo);

$contents = file_get_contents($filename);
echo "data:" . $mimetype . ";base64," . base64_encode($contents);

Conclusion

We’ve seen it’s easy to embed encoded images into code. I have wrapped the encoding routine into a command line PHP script and placed it on GitHub as php-base64-encode so it’s easy to quickly generate data URI’s.

DOMElement Content Extraction In PHP

I was using PHP to parse an HTML document using the PHP DOM extension and got stuck on extracting the contents of an element.

The documentation doesn’t make it clear how to do this, until you look and see that a DOMElement inherits from DOMNode. In DOMNode, there is a nodeValue property that holds the content.

DOMElement Content Example

So if I had a HTML document already loaded into a variable $html, and I wanted to extract the value of an element with the ID of “example”, I could do something like this.

$doc = new DOMDocument()
$doc->loadHTML($html);
$element = $doc->getElementById('example');
echo $element->nodeValue;

An Alternative

A DOMNode also has a textContent property that can be used. This will return all the text for the node and descendants, which may not always be what you are hoping for.

Using Disqus On WordPress Behind A Proxy

I had to implement the Disqus Comment System WordPress plugin on a website that will be located behind an outgoing proxy server. By default the Disqus WordPress plugin does not support proxies, so it is unable to run if a proxy is blocking it’s access to the internet.

Since WordPress 2.8, WordPress supports proxy servers using a few defined values, WP_PROXY_HOST and WP_PROXY_PORT. I have now forked the Disqus WordPress plugin on GitHub, and added support that will look to see if these exist, and use them if they do.

To use it, add the following to your wp-config.php file…

define('WP_PROXY_HOST', 'proxy.yourdomain.com');
define('WP_PROXY_PORT', '3128');

Changing the values to match those of your proxy server of course.

Now replace the url.php file in wp-content/plugins/disqus-comment-system/lib/api/disqus/url.php with the url.php found in my github repository.

Visit your WordPress admin panel and you should now be able to activate and configure the Disqus plugin successfully.

I have issued a pull request for my changes to be pulled back into the main plugin, but it’s up to Disqus is they want to implement this or not.

POSTing JSON To A Web Service With PHP

I needed to POST JSON formatted data to a RESTful web service using PHP earlier, so I thought I’d share my solution.

There are a couple of approaches that could be taken, using the CURL extension, or file_get_contents and a http context. I took the later way.

When POSTing JSON to a RESTful web service we don’t send post fields or pretend to be a form, instead we have to send the JSON data in body of the request, and let the web service know it’s JSON data by setting the Content-type header to application/json.

$article = new stdClass();
$article->title = "An example article";
$article->summary = "An example of posting JSON encoded data to a web service";

$json_data = json_encode($article);

$post = file_get_contents('http://localhost/rest/articles',null,stream_context_create(array(
    'http' => array(
        'protocol_version' => 1.1,
        'user_agent'       => 'PHPExample',
        'method'           => 'POST',
        'header'           => "Content-type: application/jsonrn".
                              "Connection: closern" .
                              "Content-length: " . strlen($json_data) . "rn",
        'content'          => $json_data,
    ),
)));

if ($post) {
    echo $post;
} else {
    echo "POST failed";
}

Here I’m first creating an example PHP stdClass object, populating it with some data, then serialising it to a JSON string. The real magic is using file_get_contents to POST it over HTTP to my test web service. If the POST succeeds, then it’s displayed, else an error message is shown.

It’s important to note I send the header, Connection: close . Without this, your script will hang until the web server closes the connection. If we include it, then as soon as the data has POSTed the connection is closed and control returned to the script.

Using SQL Server ntext Columns In PHP

I had to connect to a SQL Server database from a PHP script earlier, and I came across an error I wasn’t expecting.

My SQL was working fine, until I tried to select one particular column, it would then give me a 4004 error. Other columns in this table worked fine, so I investigated more.

The error string returned with the 4004 error code was “Unicode data in a Unicode-only collation or ntext data cannot be sent to clients using DB-Library (such as ISQL) or ODBC version 3.7 or earlier.”

Looking at the table definition, the column I was trying to SELECT was of type ntext. This is used to hold UTF-8 data.

By default the driver I had installed for PHP on Ubuntu Linux using

apt-get install php5-sybase

couldn’t understand this UTF-8 data. The solution is to edit the conf file used by freetds, which is the code used to talk to the SQL Server database by the PDO DBLib library.

So, in /etc/freedts/freetds.conf I added these settings

[global]
tds version = 8.0
client charset = UTF-8

After adding those settings, I was successfully able to SELECT the ntext column from the SQL Server database.

Unit Testing JavaScript With QUnit And Phing

Recently I’ve been using both Phing for my PHP builds, and QUnit for my JavaScript unit tests, so I’ve been looking for a way to run these QUnit tests when Phing builds my application.

By default Phing can run PHPUnit tests, but not QUnit. However Martin Jonsson has come to the rescue with his Qunit Phing Task.

QUnit Phing Tasks lets QUnit tests be run during a build and Phing can either pass or fail based on these results. As QUnit is written in JavaScript, QUnit Phing Task runs PhantomJS to call a JavaScript wrapper that passes the output back to PHP and Phing. PhantomJS is a headless JavaScript browser that can excute on a command line.

Using QUnit Phing Task

To run the QUnit Phing Task you need to install PhantomJS. I downloaded a binary and placed it in /usr/local/bin on my system.

You need to download the QUnit Phing Task. I placed the files in a local ./lib directory in my project.

You will also need to download QUnit. I placed the files in a local ./tests directory in my project.

In the ./tests directory I created an HTML file called runner.html. This is the page we need to call to run our tests.

<!DOCTYPE html>

<html>
        <head>
                <meta chatset="utf-8" />
                <title>Qunit Tests</title>
                <link rel="stylesheet" href="./qunit.css">
                <script src="./qunit.js"></script>
                <script src="./test.js"></script>
        </head>

        <body>
                <div id="qunit"></div>
        </body>
</html>

I also create a JavaScript file called ./test.js in ./tests to hold my JavaScript tests in.

test("testing for true", function() {
        ok(true, "true is true");
});

Finally, I create a build.xml for my Phing build.

<?xml version="1.0" encoding="UTF-8"?>
<project name="qunit example" basedir="." default="qunit">

        <path id="project.class.path">
                <pathelement dir="./lib/" />
        </path>

        <taskdef name="qunit" classname="QunitTask">
                <classpath refid="project.class.path" />
        </taskdef>

        <target name="qunit" description="JavaScript Unit Test">
                <qunit executable="DISPLAY=:0 /usr/local/bin/phantomjs" haltonfailure="true" runner="./lib/run-qunit.js">
                        <fileset dir=".">
                                <include name="tests/runner.html" />
                        </fileset>
                </qunit>
        </target>

</project>

In this I am specifying a path to my ./lib directory as this is where the QUnit Phing Task code is. The path is then used in the taskdeftask which is used to create the <qunit> task. Now when I call <qunit> in my qunit target I just pass in the location of the executable – in this case where PhantomJS is, whether Phing should halt if the QUnit tests fail, and where to find the the JavaScript that runs QUnit. Inside the task, we pass in where our runner pages are, as we only have the one in this example we include it by name tests/runner.html.

Running this gives us the following…

rob@lamp ~/qunitphing> phing
Buildfile: /root/qunitphing/build.xml

qunit example > qunit:

    [qunit] ./tests/runner.html: 1 tests of 1 passed, 0 failed

BUILD FINISHED

Total time: 0.3275 seconds

So we can see our tests have passed. Let’s change our test.js so that it fails.

test("testing for true", function() {
        ok(true, "true is true");
        ok(false, "false is true");
});

This test should fail, as false is not true and will fail the ok assertion.

rob@lamp ~/qunitphing> phing
Buildfile: /root/qunitphing/build.xml

qunit example > qunit:

    [qunit] 1 tests failed on: ./tests/runner.html
    [qunit] Failed test: testing for true (1, 1, 2)
Execution of target "qunit" failed for the following reason: /root/qunitphing/build.xml:13:41: QUnit tests failed

BUILD FAILED
/root/qunitphing/build.xml:13:41: QUnit tests failed
Total time: 0.3258 seconds

So we can see that Phing has failed our build due to the QUnit tests failing, which is what we want.

Summary

Although a very simple and contrived example, I hope this has shown you how to add JavaScript unit tests using QUnit to your Phing build.

Using Phing To Deploy A PHP Project

Deploying a PHP project to a production or even a staging environment isn’t always as simple as copying a directory. One project I have been working on recently has benefited from using Phing as a deployment system. To deploy my code, I just have to call a single build script, and let Phing do all the hard work.

So what is Phing? Well Phing is a tool based on Apache Ant, specifically designed to build PHP projects. It takes an XML file that defines specific tasks and executes them. It is designed to be platform independent so should be at home running on Windows as well as Unix based systems.

Phing is available using PEAR, and can be installed quickly using the following commands…

pear channel-discover pear.phing.info
pear install phing/phing

Hello World! In Phing

It wouldn’t be an overview without a Hello World example. Save the following as build.xml.



    
        
    

Now let’s run this, we just call phing on the command line, and we get something like this back.

rob@lamp /tmp/helloworld> phing
Buildfile: /tmp/helloworld/build.xml

helloworld > helloworld:

     [echo] Hello World!

BUILD FINISHED

Total time: 0.0487 seconds

rob@lamp /tmp/helloworld>

So what is going on? Well in the project element we have a default setting of “helloworld”. This tells Phing the target to call by default. We can call this on the command line as well, phing helloworld, so if we have multiple tasks we can create a target for each of those. As you can see we only have a target of “helloworld” in our example. Inside the target we have tasks. In this example, we have a single EchoTask that just prints out the message “Hello World!”.

Adding A Clean Up

There is so much more Phing can do that just print Hello World!. One of the common tasks you may have is to cleanup a deployment directory. Let’s assume you have a build directory, when you call phing clean you want this to be removed. We can add a simple task to do this to our build.xml.



    
            

As you can see, as well as adding a target called “clean”, I’ve also added a property called “builddir” with the value “./build”. I can access this later as variable, so when I call the DeleteTask, I can reference this value using ${builddir}, and Phing will delete the directory ./build.

Create an empty directory called build and run this using phing clean.

rob@lamp /tmp/helloworld> phing clean
Buildfile: /tmp/helloworld/build.xml

helloworld > clean:

     [echo] Clean...

BUILD FINISHED

Total time: 0.0493 seconds

rob@lamp /tmp/helloworld>

When you check the contents of your working directory you should have found the build directory has been deleted.

Adding A Deployment Target

Deployment is the area where Phing really comes into it’s own. Let’s create a target that creates a build directory then uploads the contents of that via FTP to a remote server.


    
    
    
    
        
            
            
            
            
            
        
    

    
    
        
            
        
    

    

We’re doing a few things here, first we are deleting the ${builddir}, and creating it from scratch to ensure it is clean. Then we are copying all the files in the current directory across, except for the build directory, any build file with any extension, the docs directory and the tests directory. Then we are FTP’ing up the contents of the ${builddir} using a FTPDeployTask. Assume I have already set a selection of FTP variables earlier using the same syntax as earlier when I defined ${builddir}.

OK, so that is useful, but there are other useful things that could be done as part of the process. We may want our JavaScript minified on production, but not when we are developing. We can add a task to do this as part of the deploy using the JSMinTask.

There are plenty of other tasks that can be usefully integrated, such as running phpcs to ensure your code is meeting coding standards, building your documentation using phpdocumentor, running your phpunit unit tests. If anything fails you can prevent the deployment and stop your site breaking unnecessarily.

Summary

This has just been a quick overview of how to use Phing. We’ve seen various simple tasks take place, and we’ve seen we can easily add more tasks to increase functionality and usefulness. In the real world adding tests to check your code before it gets deployed is essential and prevents silly errors hitting your production environment. Taking the time to write a build script will also save you time in the future when you come to make changes to your site and you can’t quite remember how your production environment was setup. Using Phing, you just have to run your build script.

Recursive Functions In PHP

Recursive functions can be very useful when developing in PHP.

A recursive function is simply a function that calls itself, but why would you want your function to be able to call itself?

They are best used when a problem needs to be solved by breaking it up into a smaller instance of itself. Examples of this would be calculation a factorial or the Fibonacci Series.

Let’s take a look at the Fibonacci Series as an example. The series looks like this…

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, …

It can be described using the following formula,

Fn = Fn-1 + Fn-2

with the seed values,

F0 = 0, F1 = 1

As you can see in the formula’s definition, it has to call itself for n-1 and n-2 to work out the current value for n.

So how would we write this in PHP?

A simple function like this should do the trick.

function fib($n) {
	if ($n < 0) {
		return NULL;
	} elseif ($n === 0) {
		return 0;
	} elseif ($n === 1 || $n === 2) {
		return 1;
	} else {
		return fib($n-1) + fib($n-2);
	}	 
}

As you can see I have added some guard statements, so if $n is 0, we return NULL (as the Fibonacci series starts at 0 and works up from there), for 0 we know the seed value is 0 and for 1 and 2 we know the seed values are 1. As we now know the start of the series, we can call our function to work out any part of the series.

For very large values of $n, there will be a lot of recursion, and this could use a lot of computer resources. Each call to fib (apart from to values 0, 1 & 2) costs us at least two more calls to fib, and these calls could be making more calls as it recurses. For example, when $n is 19, there would be 8361 calls made to the fib function to calculate the result, and when $n is 29, there would be 1028457 calls. It’s easy to see that although this is a very simple formula, it can end up being very expensive to use.

However, we can optimise the code and make things easier. We are constantly calculating the same values multiple times, so this should be telling you that this is an ideal candidate for caching.

Let’s modify our function to keep already calculated values of $n in an array and return those if possible rather than recalculating each call.

function fib($n) {
	static $cache;

	if ($n < 0) {
		return NULL;
	} elseif ($n === 0) {
		return 0;
	} elseif ($n === 1 || $n === 2) {
		return 1;
	} else {
		if (!(!is_null($cache) && array_key_exists($n, $cache))) {
			$cache[$n] = fib($n-1) + fib($n-2);
		}
		return $cache[$n]; 
	} 	
}

Here we are using a static variable to persist the $cache between calls. Then before recursively calling the fib function we check if the $cache isn’t null and if the $cache has data stored with the key value of $n. If it doesn’t we calculate the can cache the data. Finally we return the value from the cache.

Now when we call the function for when $n = 19, our function is only called 35 times, and for $n = 29, our function is only called 55 times. That’s saved us 1028402 calls!

I hope this has been a useful quick look at recursive functions using PHP.

JSON Config Files In Zend Framework

During a recent code review it was suggested that we should move from using an ini file to a JSON file for our Zend Framework application config file. The reason was to reduce duplication of data that can occur and instead move to a nicely nested file.

I wasn’t aware that JSON format config files were supported, but sure enough after a quick look at the Zend Framework documentation, there was the relevant class, Zend_Config_Json. It has only appeared in recent versions of the Zend Framework so that could be why I had missed it.

It’s easy to use in code, being almost a complete drop in for a the usual ini config.

$config = new Zend_Config_Json(
  './example_config.json',
  'production'
);

The first parameter is the location of the config file, the second is the section of the config file to use.

There is an optional third paramter that allows some addition configuration options to be specified such as changing the immutability of the config object once loaded, changing the behaviour of _extends, and the ability to ignore constants. More details can be found in options section of the Zend_Config_Json manual.

Here’s a quick example. Firstly the JSON configuration file.

{
  "production" : {
    "username" : "Robert Price",
    "beer" : [
      "Harveys Sussex Best",
      "Spitfire",
      "Asahi"
    ]
  },
  "testing" : {
    "_extends" : "production",
    "beer" : [
      "Harveys Star Of Eastbourne",
      "Schwaben Brau - Das Helle",
      "Brauhaus J.Albrect - Dunkel"
    ]
  }
}

OK, it’s a good real life example, but it has two sections, production and testing. Testing inherits from production by using the _extends parameter.
We can load and extract details using the following code.

$config = new Zend_Config_Json(
  './example_config.json',
  'production'
);
echo "Username is " . $config->username . "n";
echo "Favourite beers are...n";
foreach ($config->beer as $beer) {
  echo "* " . $beer . "n";
}

When you run this code you get the following results, assuming you saved the json config file from earlier as example_config.json

Username is Robert Price
Favourite beers are...
* Harveys Sussex Best
* Spitfire
* Asahi

Now change the code so instead of production when we load the config file, we use testing. Run the code and you’ll get the following…

Username is Robert Price
Favourite beers are...
* Harveys Star Of Eastbourne
* Schwaben Brau - Das Helle
* Brauhaus J.Albrect - Dunkel

As you can see my username has been inherited from the production block, but the list of beers has changed. This is a very powerful feature that lets you change a small section of data between environments in real code without having to repeat yourself and reduces the risk introducing errors in duplicated config options.