PHP : http_build_query() et les objets

La fonction PHP http_build_query() sert à générer une chaîne de requête en encodage URL ce qui est notamment utile pour formater les paramètres à envoyer via une méthode post ou get avec curl et pour implémenter une pagination sur des résultats de recherche complexe. La documentation officielle indique qu’elle peut être utilisée aussi bien avec un array qu’avec un objet mais n’indique qu’un example simpliste de cette dernière possibilité. Hors, il est important de noter que la fonction peut exposer des propriétés en private et protected si imprudemment utilisée, exposant ainsi des données censées ne pas être affichées.

class Test
{
	private $private = 1;
	protected $protected = 1;
	public $public = 1;
	const constante = 1;
}
 
$object = new Test();
echo http_build_query($object);

Résultat :

public=1

Le résultat est bien celui attendu, les propriétés private et protected sont bien exclue puisque hors du scope général. Maintenant, imaginons que pour une raison ou une autre vous désiriez que l’objet lui même renvoie la chaîne de requête qui lui correspond :

class Test
{
	private $private = 1;
	protected $protected = 1;
	public $public = 1;
	const constante = 1;
 
	static public $stat = 1;
 
	public function query()
	{
		return http_build_query($this);
	}
}
 
$object = new Test();
echo $object->query();

Résultat :

private=1&protected=1&public=1

La fonction http_build_query() exécutée dans le scope de l’objet a accès à toutes ses propriétés quelque soit leur visibilité. Je ne sais pas s’il s’agit là d’un bug ou du comportement voulu par les développeurs de PHP, mais en pratique ce n’est vraisemblablement pas ce que l’on aurait désiré obtenir. Faisons un dernier test avec une classe parent et un classe enfant :

class TestParent
{
	private $parentPrivate = 1;
	protected $parentProtected = 1;
	public $parentPublic = 1;
}
 
class Test extends TestParent
{
	private $private = 1;
	protected $protected = 1;
	public $public = 1;
	const constante = 1;
 
	static public $stat = 1;
 
	public function query()
	{
		return http_build_query($this);
	}
}
 
class TestChild extends Test
{
	private $childPrivate = 1;
	protected $childProtected = 1;
	public $childPublic = 1;
}
 
$object = new TestChild();
echo $object->query();

Résultat :

childProtected=1&childPublic=1&private=1&protected=1&public=1&parentProtected=1&parentPublic=1

Les propriétés public et protected définies dans les classes parents et enfants sont reprises, ainsi que toutes les propriétés définies dans la classe déclarant la méthode faisant appel à http_build_query. Rien d’étonnant là dedans au vu des résultats précédents, mais ce comportement peut être dangereux si l’on n’en a pas conscience.

Conclusion : Gardez à l’esprit que http_build_query utilise le scope courant et, par mesure de précaution, éviter de l’utiliser avec directement avec des objets. De mon point de vue, implémenter une méthode qui permette à l’objet de retourner un array contenant les propriétés devant être présentes dans la requête est sans doute la meilleure solution vu que cela permettra de réellement profiter des possibilités offerte par la POO.

Ecrire une réponse