Une simple bibliothèque PHP qui contient des assertions et des méthodes de garde pour la validation des entrées (pas de filtrage !) dans le modèle économique, les bibliothèques et le code de bas niveau de l'application. La bibliothèque peut être utilisée pour implémenter des conditions pré/post sur les données d'entrée.
L'idée est de réduire la quantité de code pour implémenter les assertions dans votre modèle et également de simplifier les chemins de code pour implémenter les assertions. Lorsque les assertions échouent, une exception est levée, supprimant ainsi la nécessité de clauses if dans votre code.
La bibliothèque n'utilise pas Symfony ou Zend Validators pour une raison : les vérifications doivent être du code de bas niveau, rapide et non orienté objet pour être utilisé partout où cela est nécessaire. L'utilisation de l'une des deux bibliothèques nécessite l'instanciation de plusieurs objets, à l'aide d'un composant local, des traductions, vous le nommez. C'est trop de ballonnement.
Utiliser Composer :
composer require beberlei/assert
<?php
use Assert Assertion ;
function duplicateFile ( $ file , $ times )
{
Assertion :: file ( $ file );
Assertion :: digit ( $ times );
for ( $ i = 0 ; $ i < $ times ; $ i ++) {
copy ( $ file , $ file . $ i );
}
}
Utilisation en temps réel avec Azure Blob Storage :
<?php
public function putBlob ( $ containerName = '' , $ blobName = '' , $ localFileName = '' , $ metadata = array (), $ leaseId = null , $ additionalHeaders = array ())
{
Assertion :: notEmpty ( $ containerName , ' Container name is not specified ' );
self :: assertValidContainerName ( $ containerName );
Assertion :: notEmpty ( $ blobName , ' Blob name is not specified. ' );
Assertion :: notEmpty ( $ localFileName , ' Local file name is not specified. ' );
Assertion :: file ( $ localFileName , ' Local file name is not specified. ' );
self :: assertValidRootContainerBlobName ( $ containerName , $ blobName );
// Check file size
if ( filesize ( $ localFileName ) >= self :: MAX_BLOB_SIZE ) {
return $ this -> putLargeBlob ( $ containerName , $ blobName , $ localFileName , $ metadata , $ leaseId , $ additionalHeaders );
}
// Put the data to Windows Azure Storage
return $ this -> putBlobData ( $ containerName , $ blobName , file_get_contents ( $ localFileName ), $ metadata , $ leaseId , $ additionalHeaders );
}
Une méthode d'assistance ( Assertion::nullOr*
) est fournie pour vérifier si une valeur est nulle OU est valable pour l'assertion :
<?php
Assertion :: nullOrMax ( null , 42 ); // success
Assertion :: nullOrMax ( 1 , 42 ); // success
Assertion :: nullOrMax ( 1337 , 42 ); // exception
La méthode Assertion::all*
vérifie si toutes les valeurs fournies sont valables pour l'assertion. Il lèvera une exception si l'assertion n'est pas valable pour l'une des valeurs :
<?php
Assertion :: allIsInstanceOf ( array ( new stdClass, new stdClass), ' stdClass ' ); // success
Assertion :: allIsInstanceOf ( array ( new stdClass, new stdClass), ' PDO ' ); // exception
L'utilisation de l'API statique sur les valeurs est très détaillée lors de la vérification des valeurs par rapport à plusieurs assertions. À partir de la version 2.6.7 d'Assert, la classe Assert
fournit une API fluide beaucoup plus agréable pour les assertions, en commençant par Assert::that($value)
, puis en recevant les assertions que vous souhaitez appeler sur l'interface fluide. Vous ne devez spécifier la $value
qu'une seule fois.
<?php
Assert :: that ( $ value )-> notEmpty ()-> integer ();
Assert :: that ( $ value )-> nullOr ()-> string ()-> startsWith ( " Foo " );
Assert :: that ( $ values )-> all ()-> float ();
Il existe également deux fonctions de raccourci Assert::thatNullOr()
et Assert::thatAll()
activant respectivement l'assistant "nullOr" ou "all".
Il existe de nombreux cas dans le développement Web, notamment lorsqu'il s'agit de formulaires, où vous souhaitez collecter plusieurs erreurs au lieu d'abandonner directement à la première erreur. C’est à cela que servent les affirmations paresseuses. Leur API fonctionne exactement comme l'API fluide Assert::that()
, mais au lieu de lancer une exception directement, ils collectent toutes les erreurs et ne déclenchent l'exception que lorsque la méthode verifyNow()
est appelée sur l'objet AssertSoftAssertion
.
<?php
Assert :: lazy ()
-> that ( 10 , ' foo ' )-> string ()
-> that ( null , ' bar ' )-> notEmpty ()
-> that ( ' string ' , ' baz ' )-> isArray ()
-> verifyNow ();
La méthode that($value, $propertyPath)
nécessite un chemin de propriété (nom), afin que vous sachiez comment différencier les erreurs par la suite.
En cas d'échec, verifyNow()
lèvera une exception Assert\LazyAssertionException
avec un message combiné :
The following 3 assertions failed:
1) foo: Value "10" expected to be string, type integer given.
2) bar: Value "<NULL>" is empty, but non empty value was expected.
3) baz: Value "string" is not an array.
Vous pouvez également récupérer toutes les AssertionFailedException
en appelant getErrorExceptions()
. Cela peut être utile par exemple pour créer une réponse à l'échec pour l'utilisateur.
Pour ceux qui cherchent à capturer plusieurs erreurs sur une seule valeur lors de l'utilisation d'une chaîne d'assertions paresseuses, vous pouvez suivre votre appel avec that
pour exécuter toutes les assertions sur la valeur et capturer tous les messages d' tryAll
d'assertion ayant échoué. Voici un exemple :
Assert :: lazy ()
-> that ( 10 , ' foo ' )-> tryAll ()-> integer ()-> between ( 5 , 15 )
-> that ( null , ' foo ' )-> tryAll ()-> notEmpty ()-> string ()
-> verifyNow ();
Ce qui précède montre comment utiliser cette fonctionnalité pour affiner le comportement des échecs de rapport, mais pour faciliter encore plus la détection de tous les échecs, vous pouvez également appeler tryAll
avant de faire des assertions comme ci-dessous. Cela permet de réduire les appels de méthode et a le même comportement que ci-dessus.
Assert :: lazy ()-> tryAll ()
-> that ( 10 , ' foo ' )-> integer ()-> between ( 5 , 15 )
-> that ( null , ' foo ' )-> notEmpty ()-> string ()
-> verifyNow ();
Les fonctions suivantes existent en tant qu'alias pour les constructeurs statiques Assert
:
Assertthat()
AssertthatAll()
AssertthatNullOr()
Assertlazy()
L’utilisation des constructeurs fonctionnels ou statiques est une préférence entièrement personnelle.
Remarque : Les constructeurs fonctionnels ne fonctionneront pas avec une extension Assertion
. Cependant, il est trivial de recréer ces fonctions de manière à pointer vers la classe étendue.
<?php
use Assert Assertion ;
Assertion :: alnum (mixed $ value );
Assertion :: base64 (string $ value );
Assertion :: between (mixed $ value , mixed $ lowerLimit , mixed $ upperLimit );
Assertion :: betweenExclusive (mixed $ value , mixed $ lowerLimit , mixed $ upperLimit );
Assertion :: betweenLength (mixed $ value , int $ minLength , int $ maxLength );
Assertion :: boolean (mixed $ value );
Assertion :: choice (mixed $ value , array $ choices );
Assertion :: choicesNotEmpty (array $ values , array $ choices );
Assertion :: classExists (mixed $ value );
Assertion :: contains (mixed $ string , string $ needle );
Assertion ::count(array| Countable | ResourceBundle | SimpleXMLElement $ countable , int $ count );
Assertion :: date (string $ value , string $ format );
Assertion :: defined (mixed $ constant );
Assertion :: digit (mixed $ value );
Assertion :: directory (string $ value );
Assertion :: e164 (string $ value );
Assertion :: email (mixed $ value );
Assertion :: endsWith (mixed $ string , string $ needle );
Assertion :: eq (mixed $ value , mixed $ value2 );
Assertion :: eqArraySubset (mixed $ value , mixed $ value2 );
Assertion :: extensionLoaded (mixed $ value );
Assertion :: extensionVersion (string $ extension , string $ operator , mixed $ version );
Assertion :: false (mixed $ value );
Assertion :: file (string $ value );
Assertion :: float (mixed $ value );
Assertion :: greaterOrEqualThan (mixed $ value , mixed $ limit );
Assertion :: greaterThan (mixed $ value , mixed $ limit );
Assertion :: implementsInterface (mixed $ class , string $ interfaceName );
Assertion :: inArray (mixed $ value , array $ choices );
Assertion :: integer (mixed $ value );
Assertion :: integerish (mixed $ value );
Assertion :: interfaceExists (mixed $ value );
Assertion :: ip (string $ value , int $ flag = null );
Assertion :: ipv4 (string $ value , int $ flag = null );
Assertion :: ipv6 (string $ value , int $ flag = null );
Assertion :: isArray (mixed $ value );
Assertion :: isArrayAccessible (mixed $ value );
Assertion :: isCallable (mixed $ value );
Assertion ::isCountable(array| Countable | ResourceBundle | SimpleXMLElement $ value );
Assertion :: isInstanceOf (mixed $ value , string $ className );
Assertion :: isJsonString (mixed $ value );
Assertion :: isObject (mixed $ value );
Assertion :: isResource (mixed $ value );
Assertion :: isTraversable (mixed $ value );
Assertion :: keyExists (mixed $ value , string|int $ key );
Assertion :: keyIsset (mixed $ value , string|int $ key );
Assertion :: keyNotExists (mixed $ value , string|int $ key );
Assertion :: length (mixed $ value , int $ length );
Assertion :: lessOrEqualThan (mixed $ value , mixed $ limit );
Assertion :: lessThan (mixed $ value , mixed $ limit );
Assertion :: max (mixed $ value , mixed $ maxValue );
Assertion ::maxCount(array| Countable | ResourceBundle | SimpleXMLElement $ countable , int $ count );
Assertion :: maxLength (mixed $ value , int $ maxLength );
Assertion :: methodExists (string $ value , mixed $ object );
Assertion :: min (mixed $ value , mixed $ minValue );
Assertion ::minCount(array| Countable | ResourceBundle | SimpleXMLElement $ countable , int $ count );
Assertion :: minLength (mixed $ value , int $ minLength );
Assertion :: noContent (mixed $ value );
Assertion :: notBlank (mixed $ value );
Assertion :: notContains (mixed $ string , string $ needle );
Assertion :: notEmpty (mixed $ value );
Assertion :: notEmptyKey (mixed $ value , string|int $ key );
Assertion :: notEq (mixed $ value1 , mixed $ value2 );
Assertion :: notInArray (mixed $ value , array $ choices );
Assertion :: notIsInstanceOf (mixed $ value , string $ className );
Assertion :: notNull (mixed $ value );
Assertion :: notRegex (mixed $ value , string $ pattern );
Assertion :: notSame (mixed $ value1 , mixed $ value2 );
Assertion :: null (mixed $ value );
Assertion :: numeric (mixed $ value );
Assertion :: objectOrClass (mixed $ value );
Assertion :: phpVersion (string $ operator , mixed $ version );
Assertion :: propertiesExist (mixed $ value , array $ properties );
Assertion :: propertyExists (mixed $ value , string $ property );
Assertion :: range (mixed $ value , mixed $ minValue , mixed $ maxValue );
Assertion :: readable (string $ value );
Assertion :: regex (mixed $ value , string $ pattern );
Assertion :: same (mixed $ value , mixed $ value2 );
Assertion :: satisfy (mixed $ value , callable $ callback );
Assertion :: scalar (mixed $ value );
Assertion :: startsWith (mixed $ string , string $ needle );
Assertion :: string (mixed $ value );
Assertion :: subclassOf (mixed $ value , string $ className );
Assertion :: true (mixed $ value );
Assertion :: uniqueValues (array $ values );
Assertion :: url (mixed $ value );
Assertion :: uuid (string $ value );
Assertion :: version (string $ version1 , string $ operator , string $ version2 );
Assertion :: writeable (string $ value );
Rappel : Lorsqu'un paramètre de configuration est nécessaire, il est toujours passé APRÈS la valeur. La valeur est toujours le premier paramètre.
Si l’une des assertions échoue, une AssertAssertionFailedException
est levée. Vous pouvez transmettre un argument appelé $message
à n'importe quelle assertion pour contrôler le message d'exception. Chaque exception contient un message par défaut et un code de message unique par défaut.
<?php
use Assert Assertion ;
use Assert AssertionFailedException ;
try {
Assertion :: integer ( $ value , " The pressure of gas is measured in integers. " );
} catch ( AssertionFailedException $ e ) {
// error handling
$ e -> getValue (); // the value that caused the failure
$ e -> getConstraints (); // the additional constraints of the assertion.
}
AssertAssertionFailedException
n'est qu'une interface et l'implémentation par défaut est AssertInvalidArgumentException
qui étend le SPL InvalidArgumentException
. Vous pouvez modifier l’exception utilisée au niveau du package.
Vous pouvez transmettre un rappel en tant que paramètre de message, ce qui vous permet de construire votre propre message uniquement si une assertion échoue, plutôt qu'à chaque fois que vous exécutez le test.
Le rappel sera fourni avec un tableau de paramètres destinés à l'assertion.
Comme certaines assertions appellent d’autres assertions, votre rappel devra donner un exemple du tableau pour déterminer quelle assertion a échoué.
Le tableau contiendra une clé appelée ::assertion
qui indique quelle assertion a échoué.
Le rappel doit renvoyer la chaîne qui sera utilisée comme message d'exception.
Pour protéger votre bibliothèque contre d'éventuels bugs, interprétations erronées ou ruptures BC dans Assert, vous devez introduire une sous-classe d'assertion basée sur la bibliothèque/le projet, dans laquelle vous pouvez également remplacer l'exception levée.
De plus, vous pouvez remplacer la méthode AssertAssertion::stringify()
pour fournir vos propres interprétations des types lors de la gestion des erreurs.
<?php
namespace MyProject ;
use Assert Assertion as BaseAssertion ;
class Assertion extends BaseAssertion
{
protected static $ exceptionClass = ' MyProjectAssertionFailedException ' ;
}
Depuis la version 2.9.2, les assertions paresseuses ont désormais accès à toutes les assertions supplémentaires présentes dans vos propres classes d'assertions.
Veuillez consulter CONTRIBUER pour plus de détails.