Advanced PHP: 7 useful techniques that are rarely used

May 31, 2016
Advanced PHP: 7 useful techniques that are rarely used | Ivo Petkov
In human languages, not all words are equally used, but they all have a purpose and unique power. The same is true for programming languages. A big part of the code we write is just variables, functions, classes, and loops. They are part of the basics you need to know to get your application done. Today I am not going to talk about them. Instead, I'll show you some of the PHP techniques I rarely use but have great impact.

Let's get started.

Anonymous functions and classes

Sometimes in your code, you must provide a callback function (in usort for example). Instead of defining a global function, you can create one dynamically, use it once or twice and remove it (if you want). It can also save you some time thinking about the right name (because naming things is important).
In the following example an anonymous function is used as a callback to help sort people by age.
$list = [ ['name' => 'John', 'age' => 31], ['name' => 'Mike', 'age' => 25], ['name' => 'Ben', 'age' => 27] ]; usort($list, function($a, $b) { if ($a['age'] == $b['age']) { return 0; } return ($a['age'] < $b['age']) ? -1 : 1; });
Next, a function is dynamically created and saved into a variable, then called and finally destroyed.
$sqrt = function($a) { return $a * $a; }; echo $sqrt(2); unset($sqrt);
PHP 7 adds support for anonymous classes, so you can get creative with that too.

Autoloading classes

It's a best practice to create one file per class when writing object-oriented applications in PHP. That way the classes are easier to develop and maintain and the application can load only the classes needed to complete the request. This can be achieved by registering a class autoload function that will include the class file when needed. So instead of writing:
include "some/dir/Class1.php" include "some/dir/Class2.php" include "some/dir/Class3.php"
you can write
spl_autoload_register(function ($class) { include "some/dir/" . $class . ".php"; });
And then the following code will work just fine.
$object1 = new Class1(); $object2 = new Class2(); // Class3 will not be loaded because it's not needed

Convert errors to exceptions

Prior PHP 7 error reporting in PHP was a bit messy. In PHP 7 there are some improvements. Converting errors to exceptions technique has served me well for years, so would like to show it to you. It's a couple of lines and will improve the way you manage errors.
set_error_handler(function($errorNumber, $errorMessage, $errorFile, $errorLine) { throw new \ErrorException($errorMessage, 0, $errorNumber, $errorFile, $errorLine); });
So now the only thing you have to worry about is catching exceptions. That's a lot easier than suppressing errors, registering custom handlers and taking care of different error handling configurations (in php.ini, runtime, custom handlers and so on). Here is an example:
try { echo 5 / 0; } catch (Exception $e) { print_r($e); }

Magic methods

Object-oriented programming is very popular these days, and PHP provides a great way to bring it to the next level. Magic methods allow you to tweak calls to methods or properties of a class and update the object state when particular operation occur.

Imagine you have to create the following class:
class Person { public $age = null; public $eyesColor = null; public $hairColor = null; }
You can provide the magic method __construct to set the default values for the object created.
class Person { public $age = null; public $eyesColor = null; public $hairColor = null; function __construct(){ $this->age = 20; $this->eyesColor = 'blue'; $this->hairColor = 'brown'; } }
You can validate properties using __set and retrieve them using __get.
class Person { private $data = []; public $eyesColor = null; public $hairColor = null; function __set($name, $value) { if ($name === 'age') { if (is_int($value) && $value >= 18) { $this->data[$name] = $value; } else { throw new InvalidArgumentException('Age is invalid. Must be at least 18.'); } } } function __get($name) { return isset($this->data[$name]) ? $this->data[$name] : null; } function __isset($name) { return isset($this->data[$name]); } function __unset($name) { if (isset($this->data[$name])) { unset($this->data[$name]); } } }
See the full list of magic methods at php.net.

Xdebug

Debugging and profiling are a requirement when working on large applications and for years, there has been a tool called Xdebug that does this in a wonderful way. So now you can easily find the slow places in your code and fix them. Head over to xdebug.org for more information.

register_shutdown_function()

As the name implies this function registers a function that will be called when the execution of the request is about to finish. I often use it to check for fatal errors and print friendly output.
register_shutdown_function(function() { $errorData = error_get_last(); if (is_array($errorData)) { ob_end_clean(); echo 'Error occured! - ' . $errorData['message']; } });
Another great use case is to log something.

Command line

PHP is mostly known as one the popular server languages that power our web pages. But it's not just for web pages. You can write useful script and programs that can be called from the command line. Here is an example:
php hello-world.php -name John
And this is the code of the program. The variable $argv contains all the arguments passed. Index 0 is the filename.
if (isset($argv[1]) && $argv[1] === '-help') { echo 'Enter -name <your-name> so I can greet you properly.'; exit(); } if (isset($argv[1], $argv[2]) && $argv[1] === '-name') { echo 'Hello, ' . $argv[2]; exit(); } echo 'Invalid command. Type -help for help.'; exit();

Thanks

I hope these techniques will be useful for you too.
All the code from the examples is available at my GitHub repo.

Comments

Send