PHP 5.4 which is set to be released in late 2011 has several changes and enhancements from PHP 5.3. Roughly, these changes are:
- Array dereferencing and notation
- Traits
- New and Deprecated Functionality
- Closure changes
- Upload Progress, Built-in HTTP server
- Miscellaneous Changes
A very useful addition to PHP 5.4 is array dereferencing and an alternate JSON-like notation.
Arrays
Dereferencing
You can now call a function which returns an array and immediately access values from it.
in PHP 5.3 and below you had to assign an array to a variable before using values from it.
$result = foobar();
print $result[0];
in PHP 5.4 you can access values without assigning the variable
print foobar()[0];
Notation
PHP arrays can now be created similarly to JSON arrays with square brackets []
$array_1 = ['a', 'b', 'c', 8, 9, 10];
$array_2 = ['a', 'dog' => 'snoopy', 'c', 'cat' => 'garfield', 7 => 12];
Of course, the PHP '=>' operator is not used in JSON.
The older PHP notation is still legal, namely:
$array_1 = array('a', 'b', 'c', 8, 9, 10);
$array_2 = array('a', 'dog' => 'snoopy', 'c', 'cat' => 'garfield', 7 => 12);
Traits
Although used in many other programming languages, I must admit that traits are new to me.
Traits are designed as a method for ("horizontal") code reuse that does not require inheritence. This allows for more reused functionality while still enforcing single inheritence in PHP. Heirarchy remains flatter than if multiple inheritance where allowed. Traits help eliminate code duplication.
In PHP 5.4, trait is a reserved keyword. The best way to learn about traits is to see them in action. Example:
<?php
class A extends B {
function e() {
echo "foo";
}
function f() {
echo "bar";
}
}
class C extends D {
function e() {
echo "foo";
}
function f() {
echo "bar";
}
}
?>
In this scenario, classes A and C extend different parent classes (assume B and D are not related). They both implement two identical functions, e and f.
With traits, you can change the above example into:
<?php
trait g{
function e() {
echo "foo";
}
function f() {
echo "bar";
}
}
class A extends B {
use g;
}
class C extends D {
use g;
}
?>
Now we have a trait, g, which has both the e and f function. In our classes we can "use g;". From this simple example, you can see that we have eliminated duplicate code.
To invoke method e or f, you would do so as if they were methods defined within our class:
$a = new A();
$a->e(); //foo
$a->f(); //bar
Now you are probably asking, why would I use a trait over say a static class? One reason is that with a trait you can use the parent:: operator.
<?php
trait g{
function e() {
parent::e();
echo "foo";
}
}
class A extends B {
use g;
}
class B {
function e(){
echo "baz";
}
}
?>
$a = new A();
$a->e(); //bazfoo
Invoking function e, calls the trait function e, which then calls the parent class of A, B. So B->e() is invoked. Followed by the remainder of g->e()
What if you override a trait method?
<?php
trait g{
function e() {
parent::e();
echo "bar";
}
}
class A extends B {
use g;
function e(){
echo "meow meow";
}
}
class B {
function e(){
echo "baz";
}
}
?>
$a = new A();
$a->e(); //meow meow
In this example, A->e() is implemented and invoked instead of g->e().
Multiple traits:
<?php
trait g{
function e() {
echo "bar";
}
}
trait h{
function i() {
echo "king";
}
}
class A{
use g, h;
}
?>
$a = new A();
$a->e().$a->i(); //barking
We are using both traits g and h.
What we have conflicting method names? Imagine that you have a situation like that below:
<?php
trait g{
function e() {
echo "bar";
}
}
trait h{
function e() {
echo "king";
}
}
class A{
use g, h;
}
?>
In this situation, PHP will not try to guess which version of e you want to use. This will be a fatal error!
The solution to this dilemna is to explicitly tell PHP which method you want to use. To use trait g's version of e, you would define:
class A{
use g, h{
g::e insteadof h;
}
}
$a->e(); //bar
To use trait h's version instead:
class A{
use g, h{
h::e insteadof g;
}
}
$a->e(); //king
Ok, great. But what if you want to use both? Then you choose one and pick
an alias for the other.
class A{
use g, h{
g::e insteadof h;
h::e as e2;
}
}
$a->e(); //bar
$a->e2(); //king
Traits can get more complex. Without going into further depth, traits can also:
- use other traits (nesting)
- have abstract methods
- use static variables and methods
- have their visibility set (public, protected, private, final) on a per class basis
New and Deprecated Functionality
New Functionality
int http_response_code([int $response_code])
//get current HTTP response code
//if parameter passed, than set HTTP response code
header_register_callback()
php.ini
New Functionality
int http_response_code([int $response_code])
//get current HTTP response code
//if parameter passed, than set HTTP response code
header_register_callback()
php.ini
default_charset is now UTF-8
Deprecated Functionality
session_register()
session_unregister()
session_is_registered()
import_request_variables()
//variable break and continue statements
break $var;
continue $var;
//however fixed values still work
//example: break 2; continue 3;
php.ini
deprecated
register_globals
register_long_arrays
safe_mode
allow_call_time_pass_reference
define_syslog_variables
highlight.bg
session.bug_compat42
session.bug_compat_warn
y2k_compliance
magic_quotes
Closure $this support
The simplest explanation I have found is on stackoverflow
In PHP 5.3 if you tried the following:
<?php
class A {
private $value = 1;
public function getClosure()
{
return function() { return $this->value; };
}
}
$a = new A;
$fn = $a->getClosure();
echo $fn(); //Fatal error: Using $this when not in object context
You would receive a fatal error. This is not the case in PHP 5.4.
<?php
class A {
private $value = 1;
public function getClosure()
{
return function() { return $this->value; };
}
}
$a = new A;
$fn = $a->getClosure();
echo $fn(); //1
Upload Progress and Built-in Server
Built in webserver
The CLI (Command Line Interface) will have a built-in webserver for use with development only.
//example
$ cd ~/public_html
$ php -S localhost:8000
Upload Progress
<form action="upload.php" method="POST" enctype="multipart/form-data">
<input type="hidden" name="<?php echo ini_get(" session.upload_progress.name");="" ?="">" value="foobar" />
<input type="file" name="file1">
<input type="submit">
</form>
With the hidden form element, you can poll the server multiple times
for file progress. In the example about, you would check
$_SESSION["upload_progress_foobar"]
Miscellaneous Changes
E_ALL now includes E_STRICT
//PHP 5.3
error_reporting(E_ALL ^ E_STRICT);
//PHP 5.4 equivalent
error_reporting(E_ALL);
This is a nice change.
Indirect method call through array
An array of form `array('class_name', 'method_name') can now be used to call a function.
class Foo {
public function bar($name) {
echo $name;
}
}
$f = array('Foo','bar');
echo $f('Bertrand'); //Bertrand
I am not crazy about this addition, but then again I have never used is_callable. Too much magic for my liking.
More Information
There are other subtle improvements in PHP 5.4. The full list is available at http://www.php.net/releases/NEWS_5_4_0_alpha1.txt. Another interesting link shows the full list of nominated changes for PHP 5.4 and the voting results.
Let me know of any upcoming PHP features that you think are great and that I may have missed.

All Articles
Add new comment