The top 10 most-used PHP features

Carl Glaysher of Ecce Media rounds up his top 10 most useful PHP functions, classes and features

At Ecce Media, we use PHP as part of our daily coding ritual. We all love to use many of the open source frameworks and code snippets to make our lives easier. However, we also feel it’s important that every developer has a full understanding of the core base PHP functions, classes and methods. Without knowledge of these, how can you begin to understand how all the frameworks out there operate?

We have compiled a selection of our top 10 native functions, classes and features that we use on a daily basis. We know first-hand how invaluable these features are, so we hope you find them to be useful too.

1. PDO Class

We use the PDO (PHP Data Object) exclusively for connecting to our MySQL databases. PDO provides a nice abstraction layer around a set of database drivers such as MySQL, PostgreSQL and MS SQL. This means that whichever database you are using, as long as PDO supports it, you can use the same functions to perform the same actions on the database. This makes your code more portable for your web application to be used on a whole range of databases with no extra development time.

The PDO Class provides many standardised functions such as creating transactions, creating prepared statements and allowing you to escape your variables if you need to. Used in the correct way, PDO can help protect your web application from SQL injection attacks.

The PDO class can be used directly, but we like to use our own layer over the top to give us more control over things like data entry formatting and validation, which the PDO class does not provide. RedBeanPHP ORM is a good open source solution that provides some nice functionality that's built on top of PDO.

The example below shows a connection to a MySQL database that selects the name, colour and calories from each row in fruit table. By using a prepared statement, PDO converts the placeholders to match the array that is parsed in the execute function. By using the prepared statement, all the values are escaped to protect from SQL injection. The whole piece of code has been added to a try block, which can be used to catch any exceptions.

<?phptry{ /* Connect to Database */ $dsn = 'mysql:dbname=test;host=localhost'; $dbh = new PDO($dsn,'username','password'); /* Create SQL String with parameters */ $sql = 'SELECT name, colour, calories FROM fruit WHERE calories < :calories AND colour = :colour'; $sth = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY)); /* add values and execute request on database */ $sth->execute(array(':calories' => 150, ':colour' => 'red')); /* Get the returned Data */ $dataSet = $sth->fetchAll(); /* Print Results */ print_r($dataSet);}catch (PDOException $e){ echo 'PDO Error: '.$e->getMessage();}catch(Exception $e){ echo 'A Unknown Error Occurred: '.$e->getMessage();}

2. json_encode & json_decode

With the rollout of PHP5.2 came two very useful functions that allow you to parse JSON (JavaScript Object Notation) strings. JSON is a text-based standard that is generally used to send and receive data with a simple structure that was designed to be easily read, both by a computer and by a human.

PHP provides two functions that allow you to manipulate your data both to and from JSON. json_encode is utilised by setting the first argument as your data. Be that a simple string or a multi dimensional array, PHP will try to return a string of your data that has been converted to a JSON formatted string. This string can then be used to output on an API or included in your HTML template to be read by your JavaScript code on the front end.

There are some caveats to using json_encode. For example, only basic data types can be used. Strings, numbers and Booleans are the main types along with associative and non-associative arrays. PHP will also try to convert class objects but will only encode public properties. UTF8 is also used to encode the resulting string of JSON.

The example below shows an array of animals that is converted to a JSON string then sent to the user. You could call this script from an Ajax request via a JavaScript framework which will then return a JavaScript object ready for you to iterate over.

<?php/* Set Content Encoding Header */header('Content-type: application/json; charset=utf-8');/* Array of animals*/$myArray = array( array('type'=>'cat','name'=>'Alfie','age'=>2), array('type'=>'dog','name'=>'Bella','age'=>6));/* Encode to JSON */$jsonString = json_encode($myArray);echo $jsonString;

json_decode is the opposite of json_encode. The function takes the JSON string as the first argument and tries to parse the string into a PHP variable. There is an optional second argument to convert the string to an object or an associative array. By parsing ‘true’ as the second argument (as shown below) you can return an array.

<?php/* Set Content Encoding Header */$json = '[{"type":"cat","name":"Alfie","age":2},{"type":"dog","name":"Bella","age":6}]';/* Parse JSON to Object */$object = json_decode($json);/* Parse JSON to Array */$array = json_decode($json,true);/* Print Object */var_dump($object);/* Print Array */var_dump($array);

The advantage of using JSON over XML is its simplicity; with only a few data types PHP makes it very easy to parse simple data. JSON may not be as fast as the XML parsing in the majority of cases, but json_decode provides you with direct access to your data in an array or object format. This is unlike simpleXML, which returns a simpleXML object which you then have to process further to gain access to your data. Consequently, json_decode can be considered to be just as fast.

3. DateTime Class

The DateTime class allows you to manage time and dates in a more object-ordinated way, which is impossible using the standard core functions such as mktime and strtotime. By utilising the DateInterval and DateTimeZone classes, we are able to perform standard functionality like adding or subtracting time intervals on a date or changing the current time zone. The DateTime class can also be extended so we can provide extra functionality whilst making code cleaner and easier to read.

An important reason to use the DateTime class is that it stores all the dates as a 64-bit integer, which provides a workaround for the 32-bit 2038 bug where the dates will cease it increase any further.

The code example below demonstrates how the DateTime Class can be used to add a day to the current server time then convert the time zone to UTC.

<?php/* Get server time*/$date = new DateTime();echo $date->format('Y-m-d H:i:s');/* Add 1 Day */$date->add(new DateInterval('P1D'));echo '<br>'.$date->format('Y-m-d H:i:s');/* Change Timezone to UTC */$date->setTimezone(new DateTimeZone('etc/UTC'));echo '<br>'.$date->format('Y-m-d H:i:s');

4. Exceptions

With PHP5 came the implementation of exceptions. Like other programming languages such as Java and C#, exceptions are used to 'throw' errors that can be caught at any point by bubbling up through your code stack. An exception can be created easily using the throw keyword followed by an Exception object.

Catching exceptions is implemented by wrapping the code you want to test in try block. You will then need to create a catch block to 'catch' any exception that the code in the try block throws.

The PHP interpreter will try and parse everything in the block as usual. If no exception is thrown, then the interpreter will continue down the script ignoring anything in the catch block. However, if an exception is thrown, the rest of the code in the try block is ignored and will execute everything in the catch block.

The beauty of exceptions is that they can be extended as they are just classes. By extending the standard Exception class you can give extra functionality to your exception. Another advantage of extending Exceptions is that it allows you to have multiple catch blocks that can refer to each exception class by utilising type hinting.

With PHP5.5, we are now given a third block called finally. Any code in this area will be run regardless of whether there has been an exception thrown or not.

Like in the PDO example, the example below is contained in a try block. If the script fails to connect for any reason then we are able to capture that by introducing a catch block to capture any PDOExceptions or Exceptions. In the case below any errors will be printed to the screen and the script will still be executed to the end.

<?phptry{ $dsn = 'mysql:dbname=test;host=localhost'; $dbh = new PDO($dsn,'username','password'); echo 'Connected to Database';}catch (PDOException $e){ echo 'Connection Failed: '.$e->getMessage();}catch(Exception $e){ echo 'A Unknown Error Occurred: '.$e->getMessage();}echo 'I am still parsed, even if there was an error';

5. Namespaces

In the times before namespaces, PHP put every variable, function and class under the global namespace. This limited developers to ensure that their applications only had unique function and class names. Developers got round this issue by prefixing class and function names to provide a pseudo effect of namespaces, but the problem with this was that class names could end up being huge, making it sometime hard to read and write them without the use of an intelligent IDE.

Thankfully, with the introduction of namespaces, this problem was resolved. By using the namespace keyword followed by the namespace name at the top of a PHP file, it puts all the code below into that reflective namespace that cannot be accessed by any other namespaces unless explicitly instructed to. With the use of namespaces, we are now able to create well-structured and readable code that's easier to read and manage.

The example below shows how we can implement our own myNamespace namespace and create a new DateTime Class that is completely independent from the standard one provided in the global namespace. Notably, we are able to still use the default standard DateTime class in the namespace by adding a backslash to the front of the name when creating a new instance.

<?phpnamespace myNamespace;class DateTime{ public function customMethod(){ return 'Fun Times'; }}/* * Create a new DateTime object that's in this current namespace * If we are outside this namespace we can create it by: * $customDate = new \myNamespace\DateTime(); */$customDate = new DateTime();echo $customDate->customMethod();/* We can still create the default DateTime object */$standardDate = new \DateTime();echo $standardDate->format('Y-m-d H:i:s');

6. Usort

usort allows the developer to sort an array based on a compare function that's configurable by the developer. This allows you to create more complex sorting algorithms that are not provided by the standard core array sort functions.

The callback/closure function has two parameters, which are two items in the array you have asked to sort on. It's then for you to decide if the first argument is greater, smaller or equal to the second argument. This is done by returning an integer value. Anything smaller than zero will assume the first argument is smaller than the second. Zero means the arguments are equal. Greater than zero means the first argument is larger than the second.

One great application for usort that we tend to use on a daily basis is to sort a simple multi-dimensional array. For example, let's say we have an array of students that consists of an associative array of name and age. By using the usort function along with a callback/closure function, we are able to pick the age and sort by ascending or descending.

For example, the code below is sorting by the age variable for each student in the students array. The callback/closure function provides the algorithm that compares the two ages and decides if the first age is greater than the second.

<?php$successful = usort($students, function ($a, $b) { return $a['age'] - $b['age'];});

7. Hashing API

There was an issue not too long ago with big-name sites getting hacked and insecure hashed passwords getting stolen. Back in the day, using the MD5 function was sufficient to hash a password, so it was secure. The problem with MD5 and SHA1 is that they are fast to perform the hashing algorithm. Along with the invention of faster processors and the utilisation of GPUs, people have the ability to process many hundreds of thousands of hashes per second, even on a standard desktop computer or laptop.

The new hashing API introduced in PHP5.5 provides an easy-to-use layer on top of bcrypt to create secure (for now) hashes that are a lot harder to solve by hackers. The example below shows how any string variable can be hashed. A salt will be created automatically and the hashing routing will have a cost of 15. The cost will make the hashing more secure but slower to complete.

<?php$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 20]);

8. SimpleXML Class

When we have to deal with XML files we tend to use the SimpleXML class. This easy-to-use class gives you the ability to read and edit XML files via objects. Using these objects gives you the ability to return values and iterate over arrays in the usual ways, as well as a set of simple methods to modify the XML’s structure. If you just need to grab something specific in the XML then using the built-in method of XPath, you can return a set of SimpleXML Element objects for just the path that you provided.

As well as reading XML, SimpleXML also provides the methods to create new documents and/or inject elements back into the imported XML. This can then be saved all in a few lines of code.

The SimpleXML class is provided as a standard extension for PHP. Although it’s not in the core of PHP, it is enabled by default.

The example below shows a very simple example to get a list of public photos from Flickr and display the content html of each photo.

<?php/* Load flickr Public Feed */$xml = simplexml_load_file('http://api.flickr.com/services/feeds/photos_public.gne');if(is_object($xml)){ /* Get each entry and echo the content tag */ foreach($xml->entry as $photo) echo $photo->content;}

9. glob

The glob function provides an easy one-line solution for creating an array of path names using a pattern you provide. glob may not be as fast as using the opendir and readdir combination, but if you just want to iterate over a directory, or you’re searching for a specific file type such as an image, then using glob could be a good solution to your problem.

The first argument is a glob pattern string that's similar to a regular expression in the way that it functions, but the syntax to create the pattern has some differences. This allows you to search for a varied subset of files and folders that are contained in a directory.

One big disadvantage of using glob is that all the results are stored into memory in one go. If you have a very large folder full of files you can soon run out of memory, and in this instance, it would be better to use opendir and readdir as it creates a read stream buffer.

Using the example below we are able to return all the image files in the $imagePath directory. An array will be returned to the $images variable.

<?php/* Find all image files in image folder */$images = glob($imagePath.'*.{gif,jpeg,jpg,png}',GLOB_BRACE);

10. array_map

The standard core functions that PHP provide tend to perform faster, than creating your own similar functions using PHP code. A great example of this is utilising array_map instead of creating a for or which loop. array_map allows you to create a function called a callback that will be applied to every item in an array you supply.

For example, if you had an array of lowercase letters, a callback function can be created to uppercase all the characters in the array. On a small-sized array, the speed increase would be quite small, but once you start using larger arrays, you can really see a significant difference in speed.

In the example below we are converting the alphabet from lowercase to uppercase. We have provided the array_map function with a string of the name of the function we want to process. In this case we are using strtoupper to convert each letter in the array.

If there’s a need for more complex functionality, we can also provide the array_map function, a closure like in the usort example above.

<?php$alphabet=array();/* Create lower Case Alphabet */for($i=97;$i<123;$i++) $alphabet[]=chr($i);/* Convert to Uppercase */$upperCaseAlphabet = array_map('strtoupper',$alphabet);

Expert badge

There are endless possibilities with PHP, but it’s not until you fully grasp the base features covered in this article that you fully begin to earn your PHP expert badge. It can be a long and steep learning curve but it’s a worthwhile one. PHP forms the foundations of so much of our work at Ecce Media, from building bespoke platforms and ecommerce systems, to content management systems and so much more. In the world of web development, every day brings a new challenge and armed with PHP and our top tips, you’ll be in prime position to tackle them.