En route vers PHP 5.5 : empty() peut maintenant être utilisé sur une fonction

16 octobre 2012php, php-5.5
 Cet article a été rédigé il y a plusieurs années et peut ne plus être tout à fait à jour…

Avec PHP <= 5.4, empty() ne pouvait être utilisé que sur une variable.

Avec la version actuelle de la branche master de PHP (et donc, probablement, avec PHP 5.5), il devient possible de l’appeler directement sur une fonction, sans avoir à stocker le retour de celle-ci dans une variable temporaire sur laquelle serait ensuite appelée empty().

empty() peut être utilisé sur une fonction

Par exemple, si nous prenons la portion de code reproduite ci-dessous :

<?php

function test_empty() {
    return array();
}

function test_not_empty() {
    return "Hello, World!";
}


$emptyVar = array();
if (empty($emptyVar)) {
    echo "\$emptyVar => empty\n";
}

if (empty(test_empty())) {
    echo "test_empty() => empty\n";
}

if (!empty(test_not_empty())) {
    echo "test_not_empty() => not empty\n";
}

Avec PHP 5.3 (le résultat serait le même en 5.4), cette portion de code ne fonctionne pas, et donnerait une sortie de ce type :

$ php ./empty/empty-1.php
PHP Fatal error:  Can't use function return value in write context 
    in /.../php-5.5/tests/empty/empty-1.php on line 17

Alors qu’avec la version actuelle de la branche master de PHP (et donc probablement avec PHP 5.5), nous obtiendrions :

$ $HOME/bin/php-5.5/bin/php ./empty/empty-1.php 
$emptyVar => empty
test_empty() => empty
test_not_empty() => not empty

Autrement dit, empty() peut maintenant être utilisé directement sur une fonction, et analysera la valeur retournée par celle-ci.

Il en va bien entendu de même avec un appel de méthode.
A titre d’illustration, la portion de code suivante :

<?php
class MaClasse {
    protected $emptyVar = 0;
    protected $notEmptyVar = 'plop';
    public function testEmpty() {
        return $this->emptyVar;
    }
    public function testNotEmpty() {
        return $this->notEmptyVar;
    }
}

$obj = new MaClasse();

if (empty($obj->testEmpty())) {
    echo "\$obj->testEmpty() => empty\n";
}

if (!empty($obj->testNotEmpty())) {
    echo "\$obj->testNotEmpty() => not empty\n";
}

Donnerait la sortie que je reproduis ci-dessous :

$obj->testEmpty() => empty
$obj->testNotEmpty() => not empty

Ici encore, il ne s’agit pas d’une fonctionnalité révolutionnaire, mais plutôt d’un petit raccourci qui peut être sympathique.

isset() n’a pas changé

Notez que isset(), par contre, n’a pas été modifiée : la portion de code suivante :

<?php
// /!\ Ceci ne fonctionne pas : seul empty() a été modifié

function test_isset() {
    return 123;
}

echo "test_isset() => ";
if (isset(test_isset())) {
    echo "set\n";
}
else {
    echo "not set\n";
}

Mène toujours à une Fatal Error – avec tout de même un message qui a évolué, lui, pour devenir nettement plus explicite :

PHP Fatal error:  Cannot use isset() on the result of a function call (you can use "null !== func()" instead) 
    in /.../php-5.5/tests/empty/isset-1.php on line 9

Pour rappel, en PHP 5.3, nous aurions obtenu quelque chose de ce type, avec un message moins clair (qui était le même pour empty() appelée sur une non-variable, d’ailleurs) :

PHP Fatal error:  Can't use function return value in write context 
    in /.../php-5.5/tests/empty/isset-1.php on line 9

isset() permettant de déterminer si une variable existe, il ne semble pas vraiment cohérent de l’appeler sur une fonction ; ce qui explique que cette construction n’ait pas été modifée – contrairement à empty().

Voir aussi

  • RFC: Allow arbitrary expression arguments to empty() and isset() : le résultat du vote, en bas de la page de la RFC, montre que la majorité des votants étaient pour la modification qui a été apportée à empty(), et contre une éventuelle modification de isset() (ce qui explique que cette seconde n’ait pas été implémentée).