Contents
  1. 1. PHP 5.2 earlier
    1. 1.1. autoload
    2. 1.2. PDO and MySQLi
    3. 1.3. Type of constraints
  2. 2. PHP 5.2
    1. 2.1. JSON support
  3. 3. PHP 5.3
    1. 3.1. Abandoned features
      1. 3.1.1. register Globals
      2. 3.1.2. Magic Quotes
      3. 3.1.3. Safe Mode
    2. 3.2. Closure
    3. 3.3. Magic methods: __invoke(), __calltatic()
    4. 3.4. Namespace
    5. 3.5. Late static binding
    6. 3.6. Heredock and Nowdoc
    7. 3.7. Use const define constant
    8. 3.8. Ternary operator
    9. 3.9. Phar
  4. 4. PHP 5.4
    1. 4.1. Short Open Tag
    2. 4.2. New syntax for array
    3. 4.3. Traits
    4. 4.4. Built-in Web server
    5. 4.5. Detail modification
  5. 5. PHP 5.5
    1. 5.1. yield
    2. 5.2. list() in foreach
    3. 5.3. Details in changes
  6. 6. PHP 5.6
    1. 6.1. Improved constant
    2. 6.2. Improved variable function parameters
    3. 6.3. Namespace

I’ve been working on PHP for more than 5 years time. As far as I can find, there are still a lot of companies using PHP with version lower than 5.6. Especially some e-commerce stores like Woocommerce, Magento 1.x. Most of the owners won’t upgrade PHP because the systems are still working fine. There’s no way to spend money on something unnecessary. As a result, developers should keep the PHP version in mind when we need to build new feature or do some bug fixes for the old system.

The current version of PHP is 7.1. But there are more than 50% of users are still using PHP 5.x[1] and some PHP versions are end of officially supported [2].

This article will introduce the new features from PHP 5.2 to PHP 5.6.

  • PHP 5.2 before: autoload, PDO and MySQLi, type of constraints
  • PHP 5.2: JSON support
  • PHP 5.3: Abandoned features, anonymous functions, new magic methods, namespace, late static binding, Heredoc, Nowdoc, const, ternary operator, Phar
  • PHP 5.4: Short Open Tag, new syntax of array, Traits, built-in web server, small features changes
  • PHP 5.5: yield, list() in foreach, feature changes
  • PHP 5.6: constant scalar expressions, Variadic functions and argument unpacking, namespace enhancement

[1] : http://w3techs.com/technologies/details/pl-php/5/all
[2] : http://www.php.net/eol.php

NOTE: The original article is https://www.iamle.com/archives/1530.html

PHP 5.2 earlier

(Before 2006)
Introduce some features which are worth to be mentioned before PHP 5.2.

autoload

Most of the PHP developers may know method __autoload(). If this method has been defined, it will be called when an undefined class is used in the code base. We can load the required class files. For example:

1
2
3
4
function __autoload($classname)
{
require_once("{$classname}.php")
}

But this usage is not recommended. As no duplicate function names in PHP, only one __autoload() is allowed across the whole codebase. When we need to use some other libraries, it’s inevitable to have multiple autoload methods. Therefore, spl_autoload_register() will be used instead:

1
2
3
4
spl_autoload_register(function($classname)
{
require_once("{$classname}.php")
});

spl_autoload_register() will register the classes into the list of autoload method. When unidentified classes appears in the code, SPL[3] will call the registered classes in reversed registered order from autoload method.

[3]: SPL: Standard PHP Library are used for implementing standard features. E.g data structure.

PDO and MySQLi

PHP Data Object: The new PHP database access interface.

In the past, we need to access MySQL database like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// connect to server and select database
$conn = mysql_connect("localhost", "user", "password");
mysql_select_db("database");

// SQL queries
$type = $_POST['type'];
$sql = "SELECT * FROM `table` WHERE `type` = {$type}";
$result = mysql_query($sql);

// print the result
while($row = mysql_fetch_array($result, MYSQL_ASSOC))
{
foreach($row as $k => $v)
print "{$k}: {$v}\n";
}

// release result set and close the connection
mysql_free_result($result);
mysql_close($conn);

In order to use different databases(The above code can only be used with MySQL), PDO is released. In addition, PDO has introduced more features:

  • Object oriented interface
  • SQL prepare, placeholder syntax
  • Better performance.
  • Support most of SQL databases. No code changes by switching databases.

The previous script can be transformed into this with PDO:

1
2
3
4
5
6
7
8
9
10
11
12
13
// Database connection
$conn = new PDO("mysql:host=localhost;dbname=database", "user", "password");

// prepare SQL, bind parameters
$query = $conn->prepare("SELECT * FROM `table` WHERE `type` = :type");
$query->bindParam("type", $_POST['type']);

// Execute and print the results
foreach($query->execute() as $row)
{
foreach($row as $k => $v)
print "{$k}: {$v}\n";
}

PDO is officially recommended and it provide more generic database access. If there are no special requirements, we’d better learn and use PDO. But we need to use MySQLi if we need to use MySQL specific features. PDO won’t include the MySQL specific features because it has to be used with different database system.

MySQLi is the enhanced interface of MySQL. It provides both procedural and object-oriented interfaces. Currently it’s the recommended MySQL driver. The old C style MySQL interface will be removed by default in the future.

There are no big difference to use MySQLi to implement the previous two scripts. For more details, we can visit http://www.php.net/manual/en/mysqli.quickstart.php

Type of constraints

We can use type of constraints in parameters. But this mechanism is not perfect enough. It applies to Class, callable and array except string and int.

1
2
3
4
5
6
7
// Restrict the first parameter with type MyClass, 
// the second parameter is callable,
// the third one is array
function MyFunction(MyClass $a, callable $b, array $c)
{
// ...
}

PHP 5.2

(2006-2011)

JSON support

For example, json_encode(), json_decode(). JSON is widely used for data transfer in web. It’s natively supported by JavaScript. Actually JSON is part of JavaScript syntax.

The JSON methods provided by PHP can convert PHP array to JSON string:

1
2
3
4
5
6
$array = ["key" => "value", "array" => [1, 2, 3, 4]];
$json = json_encode($array);
echo "{$json}\n";

$object = json_decode($json);
print_r($object);

Output:

1
2
3
4
5
6
7
8
9
10
11
12
{"key":"value","array":[1,2,3,4]}
stdClass Object
(
[key] => value
[array] => Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
)
)

Note: json_decode() will return an object by default. We will need to set it’s second parameter to be true if we need it return an associative array.

PHP 5.3

(2009-2012)

PHP 5.3 was a really huge update. A lot of new features have been added and it has some incompatible changes to the old versions.

Abandoned features

The following features will be abandoned. If they are enabled in configuration file, PHP will throw warning in run time.

register Globals

It is an option in php.ini (register_globals). If it’s enabled, all the form variables($_GET and $_POST) will be registered as global variables.

For example:

1
2
3
4
if(isAuth())
$authorized = true;
if($authorized)
include("page.php");

It will set $authorized to true after authorization is succeeded. Then it will show the page determined by $authorized value. But we haven’t initialized $authorized to false. When register_globals is enabled, we can skip the authorization check by visiting page /auth.php?authorized=1 .

It was a history left over. As a result, it’s turned off by default in PHP 4.2 and removed in PHP 5.4.

Magic Quotes

The option magic_quotes_gpc in php.ini. It’s also a history left over and removed in PHP 5.4.

This feature will escape all the user inputs. It sounds great. But PHP has no idea of where the input will go to. SQL? Shell? HTML? Therefore, it will cause confusion in a lot of circumstances.

Safe Mode

Many virtual web hosting provider will use Safe Mode to isolate different users. But Safe Mode has a lot of problems. For instance, some extension won’t follow Safe Mode to implement authorization control.

PHP official recommend use Operating System’s mechanism to implement authorization. It will let web server use different user authorizations to run PHP interpreter.

Closure

It’s usually used for temporarily creating anonymous functions. For example, the callback functions.

1
2
3
4
5
6
$func = function($arg)
{
print $arg;
};

$func("Hello World");

The script above has defined an anonymous function and $func has been assigned. We still use ‘function’ keyword to define anonymous function. But the function name will be ignored.

Anonymous function will capture external arguments by ‘use’ keyword:

1
2
3
4
5
6
function arrayPlus($array, $num)
{
array_walk($array, function(&$v) use($num){
$v += $num;
});
}

The script above has defined an arrayPlus() function (not anonymous function) and it will add a specific number to each element of $array.

We use array_walk() function in arrayPlus(). It will implement the anonymous function, which we have defined, to each array element. We will call use() to let $number be used inside array_walk().

Magic methods: __invoke(), __calltatic()

PHP has provided some “Magic methods” which are used for implementing something like ‘override’ in other programming languages. For example, it will trigger some magic methods when it access undefined properties or methods.

As the anonymous function feature has been developed, PHP has included a new magic method: __invoke().

1
2
3
4
5
6
7
8
9
10
class A
{
public function __invoke($str)
{
print "A::__invoke(): {$str}";
}
}

$a = new A;
$a("Hello World");

The output will be:

1
A::__invoke(): Hello World

__callStatic() will be triggered when a undefined static method is called.

Namespace

PHP namespace has the most ridiculous syntax:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
// The separator should be forward slash and namespace should be put in the first line of file.
// Namespace can include any script. Only Class, Function, Constant will be affected by namespace.
namespace XXOO\Test;

// This class full namespace is \XXOO\Test\A. The first forward slash states it's global namespace.
class A{}

// You can even define a second namespace in current file. The following script will be in \Other\Test2 .
namespace Other\Test2;

// Initialized the object from other namespace
$a = new \XXOO\Test\A;
class B{}

// You can use braces to define a third namespace
namespace Other {
// Initialized the object from child namesapce.
$b = new Test2\B;

// Include other namesapce and rename it.
// NOTE: It can include Class only. Can include functions and constants
use \XXOO\Test\A as ClassA
}

For more namespace syntax, we can visit http://www.php.net/manual/zh/language.namespaces.php.

Namespace is often used by autoload:

1
2
3
4
5
spl_autoload_register(
function ($class) {
spl_autoload(str_replace("\\", "/", $class));
}
);

When we initialize \XXOO\Test\A, its full namespace will be passed to autoload(). autoload() will replace forward slashes with backslash in the namespace. As a result, we can put class files to different layers and load files on required.

Late static binding

The OPP mechanism of PHP has inheritance and something like virtual function. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class A
{
public function callFuncXXOO()
{
print $this->funcXXOO();
}

public function funcXXOO()
{
return "A::funcXXOO()";
}
}

class B extends A
{
public function funcXXOO()
{
return "B::funcXXOO";
}
}

$b = new B;
$b->callFuncXXOO();

The result would be:

1
B::funcXXOO

The virtual function can be reflected when $this->funcXXOO() was called in class A. Actually it’s calling B::funcXXOO().

If we change all functions to static functions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

class A
{
static public function callFuncXXOO()
{
print self::funcXXOO();
}

static public function funcXXOO()
{
return "A::funcXXOO()";
}
}

class B extends A
{
static public function funcXXOO()
{
return "B::funcXXOO";
}
}

$b = new B;
$b->callFuncXXOO();

The output will be:

1
A::funcXXOO()

It’s because self will be treated as “Current class”. PHP 5.3 will give static keyword a new feature: late static binding.

1
2
3
4
5
6
7
8
9
10
11
class A
{
static public function callFuncXXOO()
{
print static::funcXXOO();
}

// ...
}

// ...

The result will be expected:

1
B::funcXXOO

Heredock and Nowdoc

PHP 5.3 will bring some improvement to Heredoc and Nowdoc.

Heredoc will act as double quote string:

1
2
3
4
$name = "MyName";
echo <<< TEXT
My name is "{$name}".
TEXT;

Heredoc starts with three open angles and followed by an identifier(TEXT). It ends with another identifier(no retract). It can also include variables:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
var_dump(<<<EOD
Hello World
EOD
);

class A
{
const xx = <<< EOD
Hello World
EOD;

public $oo = <<< EOD
Hello World
EOD;
}

Nowdoc acts like a single quote string and it can’t include variables. It requires single quotes in the first identifier followed by three open angles:

1
2
3
4
$name = "MyName";
echo <<< 'TEXT'
My name is "{$name}".
TEXT;

It will output:

1
My name is "{$name}".

Use const define constant

Constant can be defined in full namespace and Classes.

1
2
3
4
5
//old syntax
define("XOOO", "Value");

//new syntax
const XXOO = "Value";

Only constant can be defined in const. Expression is not allowed.

1
2
3
4
// Correct use
const XXOO = 1234;
// Wrong use
const XXOO = 2 * 617;

Ternary operator

1
2
3
4
5
//old syntax
echo $a ? $a : "No Value";

//new syntax
echo $a ?: "No Value";

Phar

It’s short for PHP Archive. It’s a library of Pear at first. But it has been rewritten as C extension and integrated into PHP from PHP 5.3. Phar can be used for packing multiple PHP files (or other type of files) into a single .phar compress file(zip format by default). It makes PHP applications easier to be published. Also it provides digital signature authorization feature.

.phar files can be executed by PHP engine(same as .php). What’s more, it can be included as follows:

1
2
require("xxoo.phar");
require("phar://xxoo.phar/xo/ox.php");

PHP 5.4

(2012-2013)

Short Open Tag

Normally, PHP tags will be like this:

1
2
3
<?php
// Code...
?>

It can be rewritten as:

1
<? /* Code... */ ?>

Also, we can rewrite

1
<?php echo $xxoo;?>

into

1
<?= $xxoo;?>

This is Short Open Tag. It’s enabled by default in PHP 5.3 and always enabled in PHP 5.4. This syntax makes PHP variables much easier to be integrated in HTML. For pure PHP files(e.g class files), PHP Official recommends file starts with PHP open tag and ignore close tag. It will make sure the whole PHP file won’t contain any extra output. Otherwise there might be some issues in setting Header and Cookie when the file is included. Because Header and Cookie must be sent before any content.

New syntax for array

1
2
3
4
5
//old syntax
$arr = array("key" => "value", "key2" => "value2");

//new syntax
$arr = ["key" => "value", "key2" => "value2"];

Traits

It’s a new mechanism to replace inheritance. PHP doesn’t support override but multiple Traits can be used in a single class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// Traits can't be initialized. It can only be included in Class.
trait SayWorld
{
public function sayHello()
{
echo 'World!';
}
}

class MyHelloWorld
{
// Include trait
use SayWorld;
}

$xxoo = new MyHelloWorld();
$xxoo->sayHello();

Traits has a lot of magic features, such as multiple Traits, conflict resolution, changing access right, setting alias name for function, a Traits can include other Traits. For more details, visit http://www.php.net/manual/zh/language.oop5.traits.php.

Built-in Web server

A lightweight Web server has been built-in since PHP 5.4. But it doesn’t support concurrency. It targets development and debug environment. It’s quite convenient for development.

1
php -S localhost:8000

A web server will start and the current path will be a web server directory. It can be accessed by http://localhost:8000/.

We need URL rewrite in most of the web applications. PHP provides a feature to set routing script:

1
php -S localhost:8000 index.php

All the requests will be processed by index.php and we can use XDebug to run breakpoint debugging.

Detail modification

PHP 5.4 provides a new way to access static methods:

1
2
$func = "funcXXOO";
A::{$func}();

Access new initialized class method:

1
(new MyClass)->xxoo();

Access element from function returned array(It will throw exception error in previous versions).

1
print func()[0];

PHP 5.5

(From 2013)

yield

yield is used by functions which require returning an iterator:

1
2
3
4
5
function number10()
{
for($i = 1; $i <= 10; $i += 1)
yield $i;
}

This function will return an array

1
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

list() in foreach

list() is used for accessing nested arrays inside foreach loop:

1
2
3
4
5
6
7
$array = [
[1, 2, 3],
[4, 5, 6],
];

foreach ($array as list($a, $b, $c))
echo "{$a} {$b} {$c}\n";

The result would be:

1
2
1 2 3
4 5 6

Details in changes

  • mysql methods are deprecated. PDO and MySQLi will be recommended. Windows XP is not supported anymore.

  • MyClass::class will return a full class name(Included full namespace).

  • empty() support

  • finally block is included in try-catch.

PHP 5.6

Improved constant

Previous constants can be used for constant computation in definition:

1
2
3
4
5
6
7
8
const A = 2;
const B = A + 1;

class C
{
const STR = "hello";
const STR2 = self::STR + ", world";
}

Constant can be used for default argument value in function:

1
function func($arg = C::STR2)

Improved variable function parameters

It’s used for replacing func_get_args():

1
2
3
4
5
6
7
8
9
10
11
function add(...$args)
{
$result = 0;
foreach($args as $arg)
$result += $arg;
return $result;
}

$arr = [2, 3];
add(1, ...$arr);
// The output is 6

Namespace

Namespace support constants and functions:

1
2
3
4
5
6
7
8
9
10
11
12
namespace Name\Space {
const FOO = 42;
function f() { echo __FUNCTION__."\n"; }
}

namespace {
use const Name\Space\FOO;
use function Name\Space\f;

echo FOO."\n";
f();
}
Contents
  1. 1. PHP 5.2 earlier
    1. 1.1. autoload
    2. 1.2. PDO and MySQLi
    3. 1.3. Type of constraints
  2. 2. PHP 5.2
    1. 2.1. JSON support
  3. 3. PHP 5.3
    1. 3.1. Abandoned features
      1. 3.1.1. register Globals
      2. 3.1.2. Magic Quotes
      3. 3.1.3. Safe Mode
    2. 3.2. Closure
    3. 3.3. Magic methods: __invoke(), __calltatic()
    4. 3.4. Namespace
    5. 3.5. Late static binding
    6. 3.6. Heredock and Nowdoc
    7. 3.7. Use const define constant
    8. 3.8. Ternary operator
    9. 3.9. Phar
  4. 4. PHP 5.4
    1. 4.1. Short Open Tag
    2. 4.2. New syntax for array
    3. 4.3. Traits
    4. 4.4. Built-in Web server
    5. 4.5. Detail modification
  5. 5. PHP 5.5
    1. 5.1. yield
    2. 5.2. list() in foreach
    3. 5.3. Details in changes
  6. 6. PHP 5.6
    1. 6.1. Improved constant
    2. 6.2. Improved variable function parameters
    3. 6.3. Namespace