유형-안전 입력 처리 용 소형 PHP 라이브러리.
일부 엔티티를 나열하는 조치가 있다고 가정 해 봅시다. 여기에는 엔티티가 생성 될 때까지 페이징, 오름차순 또는 내림차순 주문 및 선택적 필터링이 포함됩니다. 이 조치는 어떤 종류의 입력 구문 분석이있을 것입니다.
public function index ()
{
$ page = $ this -> request -> query -> get ( ' page ' );
if ( $ page === null || ! is_integer ( $ page )) {
throw new Exception ( " Parameter page not found " );
}
$ order = $ this -> request -> query -> get ( ' order ' );
if ( $ order === null || ! in_array ( $ order , [ ' asc ' , ' desc ' ])) {
throw new Exception ( " Parameter order not found " );
}
// Optional parameter
$ createdAt = $ this -> query -> query -> get ( ' createdAt ' );
if ( is_string ( $ createdAt )) {
$ createdAt = new DateTime ( $ createdAt );
} else {
$ createdAt = null ;
}
}분명히이 코드는 설명이 좋지 않기 때문에 읽는 것이 좋지 않습니다. 또한 그것이하는 일에 대해서도 꽤 말입니다. 그리고 당신이 세심한주의를 기울이지 않으면 당신은 아마도 널 수표 나 유형 수표를 놓칠 것입니다.
이제 위의 코드를이 버전과 비교하십시오.
public function index ()
{
$ page = $ this -> queryParameter ( ' page ' )-> int ()-> required ();
$ order = $ this -> queryParameter ( ' order ' )-> oneOf ([ ' asc ' , ' desc ' ])-> required ();
$ createdAt = $ this -> queryParameter ( ' createdAt ' )-> dateTime ()-> defaultsTo ( null );
}그것이이 도서관이 제공하는 것입니다. " 이 작업은 유형 int의 페이지 매개 변수가 필요합니다 "또는 " 이 작업에는 DateTime 유형의 선택적 매개 변수가 있으며 결석하면 기본값으로 설정됩니다 "를 표현할 수 있습니다.
지금 코드로 바로 가려면 예제를 가지고 놀 수 있습니다.
cd /tmpgit clone [email protected]:mpscholten/request-parser.gitcd request-parsercomposer installcd examplesphp -S localhost:8080예제 디렉토리에는 여러 다른 PHP 파일도 있습니다. 손을 더럽 히려면 예제를 조금 수정하는 것이 좋습니다.
작곡가를 통해 설치하십시오
composer require mpscholten/request-parser
symfony/http-foundation 사용하는 경우 여기를 클릭하십시오.ServerRequestInterface 구현을 사용하는 경우 여기를 클릭하십시오.Request 추상화를 사용하는 경우 (또는 아마도 일반 $_GET 및 친구)이 예제를 확인하십시오. 다음 예는 Symfony Request 사용한다고 가정합니다.
class MyController
{
use MPScholten RequestParser Symfony ControllerHelperTrait;
public function __construct ( Request $ request )
{
$ this -> initRequestParser ( $ request );
}
}그런 다음 다음과 같은 라이브러리를 사용할 수 있습니다.
class MyController
{
use MPScholten RequestParser Symfony ControllerHelperTrait;
public function __construct ( Request $ request )
{
$ this -> initRequestParser ( $ request );
}
public function myAction ()
{
$ someParameter = $ this -> queryParameter ( ' someParameter ' )-> string ()-> required ();
}
} GET /MyController/myAction?someParameter=example 수행 할 때 $someParameter 변수에는 문자열 "example" 포함됩니다.
GET /MyController/myAction 과 같은 ?someParameter 부분을 제거 할 때 어떤 일이 발생하는지 궁금 할 것입니다. 이 경우 $this->queryParameter('someParameter')->string()->required() NotFoundException 던집니다. 이 예외는 응용 프로그램에서 처리하여 오류 메시지를 표시 할 수 있습니다.
예제를 살펴보십시오.
다음 예는 PSR7 ServerRequestInterface 사용하고 있다고 가정합니다.
class MyController
{
use MPScholten RequestParser Psr7 ControllerHelperTrait;
public function __construct ( ServerRequestInterface $ request )
{
$ this -> initRequestParser ( $ request );
}
}그런 다음 다음과 같은 라이브러리를 사용할 수 있습니다.
class MyController
{
use MPScholten RequestParser Psr7 ControllerHelperTrait;
public function __construct ( ServerRequestInterface $ request )
{
$ this -> initRequestParser ( $ request );
}
public function myAction ()
{
$ someParameter = $ this -> queryParameter ( ' someParameter ' )-> string ()-> required ();
}
} GET /MyController/myAction?someParameter=example 수행 할 때 $someParameter 변수에는 문자열 "example" 포함됩니다.
GET /MyController/myAction 과 같은 ?someParameter 부분을 제거 할 때 어떤 일이 발생하는지 궁금 할 것입니다. 이 경우 $this->queryParameter('someParameter')->string()->required() NotFoundException 던집니다. 이 예외는 응용 프로그램에서 처리하여 오류 메시지를 표시 할 수 있습니다.
예제를 살펴보십시오.
someParameter 선택적으로 만들려면 required() defaultsTo($someDefaultValue) 로 바꿀 수 있습니다.
class MyController
{
use MPScholten RequestParser Symfony ControllerHelperTrait;
public function __construct ( Request $ request )
{
$ this -> initRequestParser ( $ request );
}
public function myAction ()
{
$ someParameter = $ this -> queryParameter ( ' someParameter ' )-> string ()-> defaultsTo ( ' no value given ' );
}
} GET /MyController/myAction 수행 할 때 $someParameter 변수에는 이제 "no value given" 이 포함됩니다. 기본값을 지정했기 때문에 예외는 발생하지 않습니다.
일반적으로 먼저 매개 변수 이름을 지정한 다음 유형을 지정한 다음 매개 변수가 필요한지 또는 기본값으로 선택 사항인지 지정합니다.
더 많은 예를 보려면이 저장소의 examples/ 디렉토리를 확인하십시오. 몇 가지 런닝 가능한 예제가 포함되어 있습니다.
종종 우리는 단순한 줄 이상이 필요합니다. RequestParser는 또한 다른 데이터 유형에 대한 방법을 제공합니다.
class DashboardController
{
public function show ()
{
$ dashboardId = $ this -> queryParameter ( ' id ' )-> int ()-> required ();
// GET /dashboard?name=Hello => $dashboardName == "Hello"
$ dashboardName = $ this -> queryParameter ( ' name ' )-> string ()-> required ();
// Get /dashboard?name= => $dashboardName == "default value"
$ dashboardName = $ this -> queryParameter ( ' name ' )-> string ()-> defaultsToIfEmpty ( " default value " );
// GET /dashboard?status=private => $dashboardStatus == "private"
// GET /dashboard?status=public => $dashboardStatus == "public"
// GET /dashboard?status=invalid => A NotFoundException will be thrown
$ dashboardStatus = $ this -> queryParameter ( ' status ' )-> oneOf ([ ' private ' , ' public ' ])-> required ();
// GET /dashboard?createdAt=01.01.2016 => $dateTime == new DateTime("01.01.2016")
// GET /dashboard?createdAt=invalid_date => A NotFoundException will be thrown
$ dateTime = $ this -> queryParameter ( ' createdAt ' )-> dateTime ()-> required ();
// GET /dashboard?config={"a":true} => $json == ['a' => true]
$ json = $ this -> queryParameter ( ' config ' )-> json ()-> required ();
// GET /dashboard?includeWidgets=true => $includeWidgets == true
// GET /dashboard?includeWidgets=false => $includeWidgets == false
// GET /dashboard?includeWidgets=0 => $includeWidgets == false
// GET /dashboard?includeWidgets=abcde => A NotFoundException will be thrown
$ includeWidgets = $ this -> queryParameter ( ' includeWidgets ' )-> boolean ()-> required ();
// GET /dashboard?includeWidgets=yes => $includeWidgets == true
// GET /dashboard?includeWidgets=no => $includeWidgets == false
$ includeWidgets = $ this -> queryParameter ( ' includeWidgets ' )-> yesNoBoolean ()-> required ();
// GET /image?scale=2.5 => $scale == 2.5
$ scale = $ this -> queryParameter ( ' scale ' )-> float ()-> required ();
}
} 이러한 모든 유형은 또한 defaultsTo 변형을 제공합니다.
| 유형 | 코드 예제 | 입력 예제 |
|---|---|---|
| 끈 | $this->queryParameter('name')->string()->required(); | 'John Doe' |
| 쉼표로 구분 된 문자열 | $this->queryParameter('names')->commaSeparated()->string()->required(); | 'John Doe,John Oliver' |
| 정수 | $this->queryParameter('id')->int()->required(); | '5' |
| 쉼표로 분리 된 정수 | $this->queryParameter('groupIds')->commaSeparated()->int()->required(); | '5,6,7,8' |
| 뜨다 | $this->queryParameter('ratio')->float()->required(); | '0.98' |
| 쉼표로 분리 된 플로트 | $this->queryParameter('precipitation')->commaSeparated()->float()->required(); | '0.98,1.24,5.21' |
| DateTime | $this->queryParameter('timestamp')->dateTime()->required(); | '2016-07-20' |
| 쉼표로 분리 된 DateTime | $this->queryParameter('eventTimes')->commaSeparated()->dateTime()->required(); | '2016-07-20 13:10:50,2016-07-21 12:01:07' |
| 부울 | $this->queryParameter('success')->boolean()->required(); | 'true' |
| 쉼표로 구분 된 부울 | $this->queryParameter('answers')->commaSeparated()->boolean()->required(); | '1,0,0,1' |
| 예/아니요 부울 | $this->queryParameter('success')->yesNoBoolean()->required(); | 'yes' |
| 쉼표로 구분 된 예/아니오 부울 | $this->queryParameter('answers')->commaSeparated()->yesNoBoolean()->required(); | 'y,n,n,y,n' |
| JSON | $this->queryParameter('payload')->json()->required(); | '{"event":"click","timestamp":"2016-07-20 13:10:50"}' |
| 쉼표로 구분 된 JSON | $this->queryParameter('events')->commaSeparated()->json()->required(); | '{"event":"click","timestamp":"2016-07-20 13:10:50"},{"event":"add_to_basket","timestamp":"2016-07-20 13:11:01"}' |
$this->queryParameter($name) 컨트롤러에 쿼리 매개 변수를 원한다고 말합니다 ( "?"를 쿼리 문자열이라고합니다). 이것은 일반적으로 GET 요청을 처리 할 때 원하는 것입니다.
게시물 요청을 처리 할 때는 양식 필드 또는 Ajax 페이로드에 액세스하기 위해 $this->bodyParameter($name) 사용해야합니다.
라이브러리를 사용하면 IDE의 자동 완성 기능을 광범위하게 사용할 수 있습니다. 예를 들어 $this->queryParameter('someParameter)-> IDE를 입력 한 후 IDE는 가능한 모든 입력 유형 (예 : string() 또는 int() 제공합니다. 유형 (예 : string() 선택한 후 IDE는 required() 또는 defaultsTo(defaultValue) 제공하여 매개 변수가 설정되지 않은 경우 동작을 지정합니다.



라이브러리는 IDE의 정적 분석을 지원합니다. 예를 들어 $createdAt = $this->queryParameter('createdAt')->dateTime()->required(); , 당신의 IDE는 $createdAt 가 DateTime 객체라는 것을 알게 될 것입니다. 이를 통해 편집하는 동안 유형 오류를 감지 할 수 있으며 유형이 가독성을 향상시키기 때문에 작업의 유지 보수 비용을 줄입니다.
라이브러리는 또한 매개 변수가 항상 명시적인 기본값을 가지거나 필요하기 때문에 예상치 못한 널 값의 위험을 줄입니다.
매개 변수가 필요하지만 찾을 수 없거나 유효성 검사가 실패한 경우 라이브러리는 예외를 던집니다. 기본 예외는 MPScholtenRequestParserNotFoundException 및 MPScholtenRequestParserInvalidValueException 입니다. 라이브러리가 던진 오류를 처리하는 제안 된 방법은 전면 컨트롤러 내부를 잡는 것입니다.
try {
$ controller -> $ action ();
} catch ( NotFoundException $ e ) {
echo $ e -> getMessage ();
} catch ( InvalidValueException $ e ) {
echo $ e -> getMessage ();
} class MyController
{
use MPScholten RequestParser Symfony ControllerHelperTrait;
public function __construct ( Request $ request )
{
$ exceptionFactory = new ExceptionFactory (CustomNotFoundException::class, CustomInvalidValueException::class));
$ config = new MPScholten RequestParser Config ();
$ config -> setExceptionFactory ( $ exceptionFactory );
$ this -> initRequestParser ( $ request , $ config );
}
} 도서관에서 한두 번 방해하는 예외 메시지를 무시 해야하는 경우, 예외 메시지를 첫 번째 및 두 번째 인수로 ->required() 로 전달하여이를 수행 할 수 있습니다.
class DashboardController
{
public function show ()
{
$ dashboardId = $ this -> queryParameter ( ' id ' )-> int ()-> required ( " The dashboard id has to be a valid number " , " No dashboard id given " );
}
}모든 작업에 대한 사용자 정의 예외 메시지를 지정하고 싶지 않지만 내장 예외 메시지를 사용하고 싶지 않더라도 자신의 예외 메시지 생성기를 제공 할 수 있습니다.
class FriendlyExceptionMessageFactory extends MPScholten RequestParser ExceptionMessageFactory
{
protected function createNotFoundMessage ( $ parameterName )
{
return " Looks like $ parameterName is missing :) " ;
}
protected function createInvalidValueMessage ( $ parameterName , $ parameterValue , $ expected )
{
return " Whoops :) $ parameterName seems to be invalid. We're looking for $ expected but you provided ' $ parameterValue ' " ;
}
}
class MyController
{
use MPScholten RequestParser Symfony ControllerHelperTrait;
public function __construct ( Request $ request )
{
$ config = new MPScholten RequestParser Config ();
$ config -> setExceptionMessageFactory ( new FriendlyExceptionMessageFactory ());
$ this -> initRequestParser ( $ request , $ config );
}
}사용자 정의 예외에 대해이 예제를 확인하십시오.
전적으로. 이 라이브러리는 처음에 Quintly에서 개발되었으며 2015 년 4 월부터 생산에 광범위하게 사용됩니다. 생산에서 규모로 사용하면 거꾸로 호환성과 물건을 깨뜨리지 않는 데 큰 초점이 맞습니다.
composer tests
composer tests-coverage
풀 요청을 보내 주시기 바랍니다!