Una biblioteca PHP simple que contiene afirmaciones y métodos de protección para la validación de entradas (¡sin filtrado!) en modelos de negocios, bibliotecas y código de bajo nivel de aplicaciones. La biblioteca se puede utilizar para implementar condiciones previas y posteriores en los datos de entrada.
La idea es reducir la cantidad de código para implementar aserciones en su modelo y también simplificar las rutas de código para implementar aserciones. Cuando las aserciones fallan, se lanza una excepción, lo que elimina la necesidad de cláusulas if en su código.
La biblioteca no utiliza Symfony o Zend Validators por una razón: las comprobaciones deben ser códigos de bajo nivel, rápidos y no orientados a objetos para usarse en todos los lugares necesarios. El uso de cualquiera de las dos bibliotecas requiere la creación de instancias de varios objetos, utilizando un componente local, traducciones, lo que sea. Es demasiada hinchazón.
Usando el compositor:
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 );
}
}
Uso en tiempo real con 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 );
}
Se proporciona un método auxiliar ( Assertion::nullOr*
) para comprobar si un valor es nulo O se cumple para la afirmación:
<?php
Assertion :: nullOrMax ( null , 42 ); // success
Assertion :: nullOrMax ( 1 , 42 ); // success
Assertion :: nullOrMax ( 1337 , 42 ); // exception
El método Assertion::all*
comprueba si todos los valores proporcionados son válidos para la afirmación. Lanzará una excepción de la afirmación que no es válida para uno de los valores:
<?php
Assertion :: allIsInstanceOf ( array ( new stdClass, new stdClass), ' stdClass ' ); // success
Assertion :: allIsInstanceOf ( array ( new stdClass, new stdClass), ' PDO ' ); // exception
El uso de la API estática en valores es muy detallado cuando se comparan valores con múltiples afirmaciones. A partir de 2.6.7 de Assert, la clase Assert
proporciona una API fluida mucho mejor para aserciones, comenzando con Assert::that($value)
y luego recibiendo las aserciones que desea invocar en la interfaz fluida. Sólo tienes que especificar el $value
una vez.
<?php
Assert :: that ( $ value )-> notEmpty ()-> integer ();
Assert :: that ( $ value )-> nullOr ()-> string ()-> startsWith ( " Foo " );
Assert :: that ( $ values )-> all ()-> float ();
También hay dos funciones de acceso directo Assert::thatNullOr()
y Assert::thatAll()
que habilitan el ayudante "nullOr" o "all" respectivamente.
Hay muchos casos en el desarrollo web, especialmente cuando se trata de formularios, en los que se desea recopilar varios errores en lugar de abortar directamente en el primer error. Para eso están las afirmaciones perezosas. Su API funciona exactamente igual que la fluida Assert::that()
, pero en lugar de generar una excepción directamente, recopilan todos los errores y solo activan la excepción cuando se llama al método verifyNow()
en el objeto AssertSoftAssertion
.
<?php
Assert :: lazy ()
-> that ( 10 , ' foo ' )-> string ()
-> that ( null , ' bar ' )-> notEmpty ()
-> that ( ' string ' , ' baz ' )-> isArray ()
-> verifyNow ();
El método that($value, $propertyPath)
requiere una ruta de propiedad (nombre), para que luego sepas diferenciar los errores.
En caso de error, verifyNow()
generará una excepción Assert\LazyAssertionException
con un mensaje combinado:
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.
También puede recuperar todas las AssertionFailedException
llamando getErrorExceptions()
. Esto puede resultar útil, por ejemplo, para crear una respuesta ante fallos para el usuario.
Para aquellos que buscan capturar múltiples errores en un solo valor cuando usan una cadena de aserciones tryAll
that
ejecutar todas las aserciones contra el valor y capturar todos los mensajes de error de aserción fallidos resultantes. He aquí un ejemplo:
Assert :: lazy ()
-> that ( 10 , ' foo ' )-> tryAll ()-> integer ()-> between ( 5 , 15 )
-> that ( null , ' foo ' )-> tryAll ()-> notEmpty ()-> string ()
-> verifyNow ();
Lo anterior muestra cómo utilizar esta funcionalidad para ajustar con precisión el comportamiento de los informes de fallas, pero para facilitar aún más la detección de todas las fallas, también puede llamar tryAll
antes de realizar cualquier afirmación como se muestra a continuación. Esto ayuda a reducir las llamadas a métodos y tiene el mismo comportamiento que el anterior.
Assert :: lazy ()-> tryAll ()
-> that ( 10 , ' foo ' )-> integer ()-> between ( 5 , 15 )
-> that ( null , ' foo ' )-> notEmpty ()-> string ()
-> verifyNow ();
Las siguientes funciones existen como alias para Assert
constructores estáticos:
Assertthat()
AssertthatAll()
AssertthatNullOr()
Assertlazy()
El uso de constructores funcionales o estáticos es una preferencia totalmente personal.
Nota: Los constructores funcionales no funcionarán con una extensión Assertion
. Sin embargo, es trivial recrear estas funciones de manera que apunten a la clase extendida.
<?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 );
Recuerde: cuando es necesario un parámetro de configuración, siempre se pasa DESPUÉS del valor. El valor es siempre el primer parámetro.
Si alguna de las afirmaciones falla, se lanza una AssertAssertionFailedException
. Puede pasar un argumento llamado $message
a cualquier aserción para controlar el mensaje de excepción. Cada excepción contiene un mensaje predeterminado y un código de mensaje único de forma predeterminada.
<?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
es solo una interfaz y la implementación predeterminada es AssertInvalidArgumentException
que extiende SPL InvalidArgumentException
. Puede cambiar la excepción que se utiliza a nivel de paquete.
Puede pasar una devolución de llamada como parámetro de mensaje, lo que le permitirá crear su propio mensaje solo si falla una aserción, en lugar de cada vez que ejecute la prueba.
La devolución de llamada se proporcionará con una serie de parámetros que son para la afirmación.
Como algunas aserciones llaman a otras aserciones, su devolución de llamada deberá utilizar un ejemplo de la matriz para determinar qué aserción falló.
La matriz contendrá una clave llamada ::assertion
que indica qué aserción falló.
La devolución de llamada debe devolver la cadena que se utilizará como mensaje de excepción.
Para proteger su biblioteca de posibles errores, malas interpretaciones o interrupciones de BC dentro de Assert, debe introducir una subclase de aserción basada en biblioteca/proyecto, donde también puede anular la excepción lanzada.
Además, puede anular el método AssertAssertion::stringify()
para proporcionar sus propias interpretaciones de los tipos durante el manejo de errores.
<?php
namespace MyProject ;
use Assert Assertion as BaseAssertion ;
class Assertion extends BaseAssertion
{
protected static $ exceptionClass = ' MyProjectAssertionFailedException ' ;
}
A partir de V2.9.2, las aserciones diferidas ahora tienen acceso a cualquier aserción adicional presente en sus propias clases de aserción.
Consulte CONTRIBUCIÓN para obtener más detalles.