You are currently viewing PHP empty : guide complet pour tester vos variables

PHP empty : guide complet pour tester vos variables

Dans cet article

  • empty() retourne true pour 8 valeurs précises : "", 0, 0.0, "0", null, false, [] et une variable non déclarée
  • Depuis PHP 5.5, empty() accepte les expressions et plus seulement les variables, ce qui simplifie les tests
  • La différence entre isset() et empty() tient en une règle : isset() vérifie l’existence, empty() vérifie l’existence ET la vacuité
  • Utiliser empty() sur un entier valant 0 renvoie true, un piège classique qui provoque des bugs en production
  • Les comparaisons strictes (===) sont souvent préférables à empty() dans du code typé moderne
  • Un tableau vide ([]) est considéré comme empty, ce qui est pratique pour valider des résultats de requête

En PHP, tester si une variable est « vide » semble simple. Pourtant, php empty est l’une des fonctions qui génère le plus de bugs silencieux dans les projets que je corrige avec mes étudiants en BTS SIO. La raison : son comportement est plus large que ce que la plupart des développeurs imaginent. Dans ce guide, je vous explique précisément comment fonctionne empty(), quand l’utiliser, et surtout quand l’éviter.

Comprendre empty() en PHP : définition et fonctionnement

La fonction empty() est un constructeur de langage (et non une fonction classique) qui détermine si une variable est considérée comme vide. Concrètement, empty($var) retourne true si la variable n’existe pas ou si sa valeur est évaluée comme « falsy » par PHP.

Sa signature est simple :

empty(mixed $var): bool

Ce qui rend empty en php particulier, c’est qu’il ne génère aucun warning si la variable n’est pas définie. Contrairement à un simple test if (!$var), qui déclenchera un E_WARNING sur une variable non déclarée, empty() gère ce cas silencieusement. C’est à la fois sa force et sa faiblesse.

<?php
// Pas de warning, retourne true
if (empty($variableInexistante)) {
    echo 'La variable est vide ou non définie';
}

// Génère un E_WARNING en PHP 8+
if (!$variableInexistante) {
    echo 'Warning ici';
}

Depuis PHP 5.5, empty() accepte aussi les expressions, pas uniquement les variables. Vous pouvez donc écrire empty(trim($input)) ou empty($obj->getResult()), ce qui n’était pas possible dans les versions antérieures. Ce point est important si vous maintenez du code legacy, comme je le vois régulièrement dans les projets de stage de mes étudiants.

Tester correctement les variables PHP évite de nombreux bugs en production
Tester correctement les variables PHP évite de nombreux bugs en production

Les 8 valeurs considérées comme empty en PHP

Voici la liste exhaustive des valeurs pour lesquelles empty() retourne true. Je vous recommande de la mémoriser, car elle est à l’origine de la majorité des surprises :

Valeur Type empty() retourne Remarque
"" string true Chaîne vide classique
0 int true Piège fréquent avec les identifiants
0.0 float true Zéro flottant inclus
"0" string true La chaîne « 0 » est vide, attention aux formulaires
null null true Variable non initialisée ou explicitement nulle
false bool true Résultat de comparaison échouée
[] array true PHP empty array retourne true
Variable non déclarée true Aucun warning généré

Le cas le plus trompeur est celui de la chaîne « 0 ». Quand un utilisateur saisit le chiffre zéro dans un formulaire, la valeur transmise est la chaîne "0". Si vous testez cette valeur avec empty(), elle sera considérée comme vide, et votre validation rejettera une saisie parfaitement légitime. C’est un bug que je rencontre au moins une fois par semestre dans les projets de mes étudiants.

De même, un PHP empty array (tableau vide []) est considéré comme empty. Ce comportement est en revanche très utile pour vérifier si une requête SQL a retourné des résultats :

<?php
$resultats = $pdo->query('SELECT * FROM utilisateurs WHERE actif = 1')->fetchAll();

if (empty($resultats)) {
    echo 'Aucun utilisateur actif trouvé.';
}

PHP empty vs isset vs is_null : le comparatif

La confusion entre empty(), isset() et is_null() est probablement la question que l’on me pose le plus en cours. Voici un comparatif clair pour trancher définitivement le débat PHP empty vs isset.

Expression empty() isset() is_null()
$x non déclarée true false true (+ warning)
$x = null true false true
$x = "" true true false
$x = 0 true true false
$x = "0" true true false
$x = false true true false
$x = [] true true false
$x = "hello" false true false
$x = 42 false true false

La règle que je donne à mes étudiants est la suivante :

  • isset() répond à la question : « Cette variable existe-t-elle et n’est-elle pas null ? »
  • empty() répond à : « Cette variable est-elle absente ou a-t-elle une valeur falsy ? »
  • is_null() répond à : « Cette variable vaut-elle exactement null ? »

En termes logiques, empty($var) est équivalent à !isset($var) || $var == false. C’est pour cela que PHP empty null retourne true : null n’est pas « set », donc la première condition suffit.

Pour traiter les données de formulaires, je combine souvent les deux. Par exemple, pour vérifier qu’un champ existe et contient une valeur exploitable, la logique avec les fonctions de manipulation de chaînes comme substr() devient plus fiable quand on sait exactement ce qu’on teste :

<?php
// Approche robuste pour un champ de formulaire
if (isset($_POST['email']) && !empty(trim($_POST['email']))) {
    $email = filter_var($_POST['email'], FILTER_VALIDATE_EMAIL);
}
Comparer empty, isset et is_null est essentiel pour choisir la bonne fonction
Comparer empty, isset et is_null est essentiel pour choisir la bonne fonction

Cas d’usage pratiques de empty() dans vos projets

Malgré ses pièges, empty() reste un outil très utile dans certains contextes précis. Voici les situations où je le recommande sans hésitation.

Vérifier les paramètres d’entrée d’une requête

Quand vous récupérez des données depuis $_GET, $_POST ou $_REQUEST, empty() est parfait car il gère à la fois le cas où la clé n’existe pas et le cas où elle est vide :

<?php
if (empty($_GET['page'])) {
    $page = 1; // Valeur par défaut
} else {
    $page = (int) $_GET['page'];
}

Tester le résultat d’une requête de base de données

Comme mentionné plus haut, vérifier si un tableau de résultats est vide est un cas d’usage parfaitement adapté. Cela fonctionne aussi bien avec PDO qu’avec les ORMs comme Eloquent ou Doctrine. Pour aller plus loin dans le comptage de résultats avec COUNT DISTINCT en SQL, combiner les deux approches renforce la robustesse de votre code.

Valider une configuration optionnelle

<?php
$config = require 'config.php';

$dbHost = !empty($config['db_host']) ? $config['db_host'] : 'localhost';
$dbPort = !empty($config['db_port']) ? $config['db_port'] : 3306;

Notez qu’en PHP 7+, l’opérateur null coalescing (??) remplace avantageusement ce pattern pour les cas simples. Mais empty() reste pertinent quand vous voulez aussi exclure les PHP empty string (chaînes vides).

Contrôler un flux conditionnel avec switch

Dans les structures conditionnelles complexes, empty() s’intègre bien avec un switch PHP pour gérer plusieurs cas de validation. On peut par exemple tester plusieurs champs d’un formulaire et router vers le bon case statement selon le premier champ vide détecté.

Les pièges classiques de empty() et comment les éviter

Après des années d’enseignement et de développement, voici les pièges que je vois revenir le plus souvent avec empty php.

Piège n°1 : le zéro est « vide »

C’est LE piège numéro un. Is 0 empty in PHP ? Oui, et c’est souvent problématique :

<?php
$quantite = 0; // L'utilisateur veut zéro article

if (empty($quantite)) {
    echo 'Veuillez saisir une quantité'; // Affiché à tort !
}

// Solution : comparaison stricte
if ($quantite === null || $quantite === '') {
    echo 'Veuillez saisir une quantité';
}

Ce piège se manifeste particulièrement dans les formulaires de e-commerce, les systèmes de notation (une note de 0 est valide), et les calculs financiers. Si vous travaillez avec des données numériques, préférez toujours la comparaison stricte.

Piège n°2 : la chaîne « 0 »

Un champ de formulaire contenant le caractère « 0 » sera considéré comme vide. C’est surprenant mais cohérent avec le tableau de comparaison des types de la documentation officielle PHP. Le jonglage de types (type juggling) transforme "0" en 0, puis en false.

<?php
$codePostal = '01000'; // Bourg-en-Bresse
var_dump(empty($codePostal)); // false, OK

$code = '0';
var_dump(empty($code)); // true, problème !

Piège n°3 : masquer les erreurs de logique

Puisque empty() ne génère pas de warning sur une variable non déclarée, il peut masquer des fautes de frappe dans vos noms de variables :

<?php
$userName = 'Alice';

// Typo : userNmae au lieu de userName
if (empty($userNmae)) {
    echo 'Utilisateur non défini'; // Toujours affiché !
}

Avec isset() ou un accès direct, vous auriez eu un warning qui vous aurait alerté de la faute de frappe. C’est l’un des arguments avancés par les développeurs qui recommandent d’éviter empty() selon le manuel PHP.

Piège n°4 : empty() et les propriétés magiques

Quand vous utilisez empty() sur une propriété d’objet qui utilise __get(), PHP appelle en réalité __isset(). Si votre classe ne définit pas __isset(), empty() retournera toujours true, même si la propriété existe et a une valeur. C’est un cas que l’on retrouve avec certains patterns d’énumérations en PHP ou avec des objets de type Value Object.

<?php
class Config {
    private array $data = ['debug' => true];
    
    public function __get(string $name): mixed {
        return $this->data[$name] ?? null;
    }
    
    // Sans __isset(), empty($config->debug) retourne true !
    public function __isset(string $name): bool {
        return isset($this->data[$name]);
    }
}
Le PHP moderne offre des alternatives plus explicites à empty()
Le PHP moderne offre des alternatives plus explicites à empty()

Empty dans le PHP moderne : bonnes pratiques 2026

Avec l’évolution de PHP vers un typage de plus en plus strict (PHP 8.0 à 8.4), la place de empty() dans le code moderne se réduit. Voici comment j’enseigne son utilisation dans le contexte actuel.

Typage strict et empty()

En activant declare(strict_types=1), vous réduisez déjà considérablement le besoin de tester les types au runtime. Quand une fonction attend un string, vous savez que vous recevrez un string, pas un null ni un int. Le besoin de empty() se limite alors aux frontières du système : entrées utilisateur, réponses d’API, données de base de données.

<?php
declare(strict_types=1);

function processName(string $name): string {
    // Pas besoin de empty() : $name est garanti string
    // On teste juste si la chaîne est vide
    if ($name === '') {
        throw new \InvalidArgumentException('Le nom ne peut pas être vide');
    }
    return ucfirst(strtolower($name));
}

Types nullable et null coalescing

Les types nullable (?string) combinés avec l’opérateur ?? couvrent la majorité des cas où l’on utilisait empty() :

<?php
// Ancien style avec empty()
$displayName = !empty($user['nickname']) ? $user['nickname'] : 'Anonyme';

// Style moderne PHP 7+
$displayName = $user['nickname'] ?? 'Anonyme';

// Avec nullsafe operator PHP 8.0+
$displayName = $user?->getProfile()?->getNickname() ?? 'Anonyme';

PHP empty interface : un concept différent

Ne confondez pas la fonction empty() avec le concept de PHP empty interface (interface vide ou « marker interface »). Une interface vide est une interface sans méthode, utilisée uniquement pour marquer une classe. Par exemple, Serializable dans certains frameworks. C’est un pattern de conception, pas une fonction de test. Vous en trouverez des exemples dans les patterns liés aux enums PHP où les interfaces servent de contrats de type.

Alternatives à empty() pour un code plus explicite

Dans la communauté PHP, le débat sur l’utilisation de empty() est vif. Voici les alternatives que je privilégie selon le contexte, et que je recommande à mes étudiants pour écrire du code plus lisible.

Comparaisons strictes

C’est l’alternative la plus fiable. Vous testez exactement ce que vous attendez :

<?php
// Au lieu de empty($name)
if ($name === '' || $name === null) { ... }

// Au lieu de empty($count)
if ($count === null) { ... } // 0 n'est plus considéré comme vide

// Au lieu de empty($items)
if ($items === []) { ... } // Explicite : on teste un tableau vide

Fonctions de validation dédiées

Pour la validation de formulaires, les fonctions filter_var() et filter_input() sont bien plus appropriées :

<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);

if ($email === false || $email === null) {
    echo 'Email invalide ou manquant';
}

Le pattern « guard clause »

Plutôt que de tester si une variable est vide pour continuer, testez l’inverse et sortez tôt :

<?php
function traiterCommande(?array $articles): void {
    if ($articles === null || $articles === []) {
        throw new \DomainException('La commande doit contenir au moins un article');
    }
    
    // Suite du traitement, $articles est garanti non vide
    foreach ($articles as $article) {
        // ...
    }
}

Cette approche est particulièrement utile quand on manipule des structures de données complexes. Si vous comptez les éléments d’un tableau, la différence entre sizeof et count en PHP est un point connexe à maîtriser pour éviter les confusions.

Match expression (PHP 8.0+)

La nouvelle expression match peut remplacer certains patterns complexes impliquant empty() et des switch imbriqués :

<?php
$message = match(true) {
    $valeur === null => 'Non défini',
    $valeur === ''   => 'Chaîne vide',
    $valeur === 0    => 'Zéro (valide)',
    $valeur === []   => 'Tableau vide',
    default          => 'Valeur présente : ' . $valeur,
};

Ce style est bien plus explicite que empty() car il documente chaque cas traité. En bonus, match utilise des comparaisons strictes par défaut, ce qui élimine les surprises du type juggling. Pour aller plus loin, le manuel PHP sur l’expression match détaille tous les cas d’utilisation.

Quand vous documentez ces choix dans votre code, pensez à utiliser des commentaires clairs, même si c’est du SQL plutôt que du PHP : le principe reste le même.

À retenir

  • Utilisez empty() uniquement aux frontières du système : formulaires, paramètres GET/POST, données externes
  • Préférez les comparaisons strictes (===) dès que vous connaissez le type attendu de la variable
  • N’oubliez jamais que 0, « 0 » et 0.0 sont considérés comme empty : testez vos cas limites
  • Implémentez __isset() dans toute classe qui utilise __get() pour éviter les faux positifs
  • En PHP 8+, combinez types stricts, opérateur ?? et nullsafe pour remplacer la plupart des appels à empty()

Questions fréquentes


What is empty() in PHP ?

empty() est un constructeur de langage PHP qui teste si une variable est considérée comme vide. Il retourne true si la variable n’existe pas ou si sa valeur fait partie des 8 valeurs « falsy » : chaîne vide "", entier 0, flottant 0.0, chaîne "0", null, false, tableau vide [], et toute variable non déclarée. Contrairement à un test direct, empty() ne génère aucun warning sur une variable inexistante.

Is null or is empty en PHP ?

null et « empty » ne sont pas interchangeables. null signifie qu’une variable n’a aucune valeur assignée ou a été explicitement définie à null. « Empty » est un concept plus large : une variable null est toujours empty, mais une variable empty n’est pas forcément null. Par exemple, "" (chaîne vide) et 0 sont empty mais pas null. is_null() teste uniquement la nullité, tandis que empty() couvre les 8 valeurs falsy.

Is 0 empty in PHP ?

Oui, empty(0) retourne true en PHP. Le zéro, qu’il soit entier (0), flottant (0.0) ou même sous forme de chaîne ("0"), est considéré comme une valeur vide. C’est l’un des pièges les plus courants : si vous validez un champ numérique où zéro est une valeur légitime (quantité, note, index), utilisez plutôt $var === null || $var === '' pour ne pas rejeter le zéro à tort.

Is null the same as empty in PHP ?

Non, null et empty ne sont pas identiques. null est un type et une valeur spécifique en PHP : il représente l’absence de valeur. empty() est une fonction de test qui retourne true pour null ET 7 autres valeurs (0, 0.0, « 0 », «  », false, []). Donc empty(null) retourne true, mais is_null("") retourne false. Si vous devez distinguer null des autres valeurs falsy, utilisez is_null() ou la comparaison stricte === null.

Quelle différence entre empty() et isset() en PHP ?

isset() vérifie qu’une variable existe et n’est pas null. empty() vérifie qu’une variable n’existe pas OU contient une valeur falsy. En pratique, empty($x) équivaut à !isset($x) || $x == false. La différence clé : isset(0) retourne true (la variable existe et n’est pas null) tandis que empty(0) retourne true (zéro est falsy). Pour les formulaires, combinez les deux : isset() pour vérifier la présence, puis une validation spécifique pour le contenu.

Comment tester si un tableau est vide en PHP ?

Trois méthodes fonctionnent : empty($array) retourne true si le tableau est vide ou non défini ; $array === [] teste strictement un tableau vide (plus explicite) ; count($array) === 0 compte les éléments. La méthode la plus performante est empty() ou la comparaison directe === [], car count() parcourt le tableau pour compter. Pour un code moderne et lisible, je recommande $array === [] quand vous êtes certain que la variable est bien un tableau.


Lucie Moreau
Lucie Moreau

Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.

Lucie Moreau

Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.