Простая библиотека PHP, которая содержит утверждения и методы защиты для проверки ввода (не фильтрации!) в бизнес-модели, библиотеках и низкоуровневом коде приложения. Библиотеку можно использовать для реализации пред-/пост-условий для входных данных.
Идея состоит в том, чтобы уменьшить объем кода для реализации утверждений в вашей модели, а также упростить пути кода для реализации утверждений. Когда утверждения терпят неудачу, генерируется исключение, устраняющее необходимость в предложениях if в вашем коде.
Библиотека не использует валидаторы Symfony или Zend по одной причине: проверки должны представлять собой низкоуровневый, быстрый, необъектно-ориентированный код, который можно использовать везде, где это необходимо. Использование любой из двух библиотек требует создания экземпляров нескольких объектов с использованием компонента локали, переводов и т. д. Это слишком раздуто.
Использование Композитора:
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 );
}
}
Использование в реальном времени с помощью хранилища BLOB-объектов Azure:
<?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 );
}
Вспомогательный метод ( Assertion::nullOr*
) предоставляется для проверки того, является ли значение нулевым ИЛИ сохраняется для утверждения:
<?php
Assertion :: nullOrMax ( null , 42 ); // success
Assertion :: nullOrMax ( 1 , 42 ); // success
Assertion :: nullOrMax ( 1337 , 42 ); // exception
Метод Assertion::all*
проверяет, все ли предоставленные значения соответствуют утверждению. Будет выдано исключение, если утверждение не выполняется для одного из значений:
<?php
Assertion :: allIsInstanceOf ( array ( new stdClass, new stdClass), ' stdClass ' ); // success
Assertion :: allIsInstanceOf ( array ( new stdClass, new stdClass), ' PDO ' ); // exception
Использование статического API для значений очень многословно при проверке значений по нескольким утверждениям. Начиная с версии 2.6.7 Assert, класс Assert
предоставляет гораздо более удобный API-интерфейс для утверждений, начиная с Assert::that($value)
и затем получая утверждения, которые вы хотите вызвать, через интерфейс Fluent. Вам нужно указать $value
только один раз.
<?php
Assert :: that ( $ value )-> notEmpty ()-> integer ();
Assert :: that ( $ value )-> nullOr ()-> string ()-> startsWith ( " Foo " );
Assert :: that ( $ values )-> all ()-> float ();
Есть также две функции быстрого доступа Assert::thatNullOr()
и Assert::thatAll()
включающие помощник «nullOr» или «all» соответственно.
В веб-разработке существует множество случаев, особенно при использовании форм, когда вы хотите собрать несколько ошибок вместо того, чтобы прерывать работу сразу после первой ошибки. Вот для чего нужны ленивые утверждения. Их API работает точно так же, как API-интерфейс Fluent Assert::that()
, но вместо того, чтобы напрямую генерировать исключение, они собирают все ошибки и запускают исключение только тогда, когда verifyNow()
вызывается для объекта AssertSoftAssertion
.
<?php
Assert :: lazy ()
-> that ( 10 , ' foo ' )-> string ()
-> that ( null , ' bar ' )-> notEmpty ()
-> that ( ' string ' , ' baz ' )-> isArray ()
-> verifyNow ();
Метод that($value, $propertyPath)
требует пути к свойству (имени), чтобы вы знали, как впоследствии различать ошибки.
В случае сбоя verifyNow()
выдаст исключение Assert\LazyAssertionException
с комбинированным сообщением:
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.
Вы также можете получить все AssertionFailedException
, вызвав getErrorExceptions()
. Это может быть полезно, например, для создания реакции пользователя на ошибку.
Для тех, кто хочет зафиксировать несколько ошибок для одного значения при использовании ленивой цепочки утверждений, вы можете выполнить свой вызов с that
tryAll
чтобы выполнить все утверждения для этого значения и перехватить все полученные сообщения об ошибках неудачного утверждения. Вот пример:
Assert :: lazy ()
-> that ( 10 , ' foo ' )-> tryAll ()-> integer ()-> between ( 5 , 15 )
-> that ( null , ' foo ' )-> tryAll ()-> notEmpty ()-> string ()
-> verifyNow ();
Выше показано, как использовать эту функцию для точной настройки поведения отчетов об ошибках, но чтобы еще больше упростить обнаружение всех ошибок, вы также можете вызвать tryAll
прежде чем делать какие-либо утверждения, как показано ниже. Это помогает сократить количество вызовов методов и ведет себя так же, как указано выше.
Assert :: lazy ()-> tryAll ()
-> that ( 10 , ' foo ' )-> integer ()-> between ( 5 , 15 )
-> that ( null , ' foo ' )-> notEmpty ()-> string ()
-> verifyNow ();
Следующие функции существуют как псевдонимы статических конструкторов Assert
:
Assertthat()
AssertthatAll()
AssertthatNullOr()
Assertlazy()
Использование функциональных или статических конструкторов является исключительно личным предпочтением.
Примечание. Функциональные конструкторы не будут работать с расширением Assertion
. Однако воссоздать эти функции так, чтобы они указывали на расширенный класс, тривиально.
<?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 );
Помните: если параметр конфигурации необходим, он всегда передается ПОСЛЕ значения. Значение всегда является первым параметром.
Если какое-либо из утверждений не выполняется, создается исключение AssertAssertionFailedException
. Вы можете передать аргумент $message
в любое утверждение, чтобы управлять сообщением об исключении. Каждое исключение по умолчанию содержит сообщение по умолчанию и уникальный код сообщения.
<?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
— это просто интерфейс, а реализация по умолчанию — AssertInvalidArgumentException
, которая расширяет SPL InvalidArgumentException
. Вы можете изменить используемое исключение на уровне пакета.
Вы можете передать обратный вызов в качестве параметра сообщения, что позволит вам создавать собственное сообщение только в случае сбоя утверждения, а не при каждом запуске теста.
Обратный вызов будет снабжен массивом параметров, предназначенных для утверждения.
Поскольку некоторые утверждения вызывают другие утверждения, вашему обратному вызову потребуется пример массива, чтобы определить, какое утверждение не удалось.
Массив будет содержать ключ с именем ::assertion
, который указывает, какое утверждение не выполнено.
Обратный вызов должен возвращать строку, которая будет использоваться в качестве сообщения об исключении.
Чтобы защитить вашу библиотеку от возможных ошибок, неверных интерпретаций или сбоев BC внутри Assert, вам следует ввести подкласс утверждения на основе библиотеки/проекта, где вы также можете переопределить выдаваемое исключение.
Кроме того, вы можете переопределить метод AssertAssertion::stringify()
чтобы обеспечить собственную интерпретацию типов во время обработки ошибок.
<?php
namespace MyProject ;
use Assert Assertion as BaseAssertion ;
class Assertion extends BaseAssertion
{
protected static $ exceptionClass = ' MyProjectAssertionFailedException ' ;
}
Начиная с версии 2.9.2, ленивые утверждения теперь имеют доступ к любым дополнительным утверждениям, присутствующим в ваших собственных классах утверждений.
Пожалуйста, смотрите ВКЛАД для более подробной информации.