Poznajemy bardzo ciekawy patent na odfiltrowanie niechcianych pól z tablicy asocjacyjnej na ciekawym przykładzie. Do dzieła!
Wyobraźmy sobie, że piszemy middleware do obsługi wyjątków związanych z walidacją:
try {
next();
} catch (ValidationException $e) {
$data = $_POST;
//(...)
}
W przypadku gdy wyrzucony zostanie ValidationException (nie jest to wbudowany Error PHP) pobieramy dane z tablicy $_POST.
Poudajemy, że tak się właśnie dzieje:
// try {
// next();
// } catch (ValidationException $e) {
// $data = $_POST;
$data = [
'user' => 'John',
'password' => md5('helloworld'),
'confirmPassword' => md5('helloworld'),
'email' => 'john.doe@wp.pl'
];
Chcemy teraz te dane umieścić w jakimś „old” jak w Laravelu, ale najpierw musimy je odfiltrować z niechcianych pól.
Na pewno nie chcemy, aby hasło zostało przekazane dalej:
$data = [
'user' => 'John',
'password' => md5('helloworld'),
'confirmPassword' => md5('helloworld'),
'email' => 'john.doe@wp.pl'
];
$excluded_fields = ['password', 'confirmPassword'];
Trzymanie pól do wyrzucenia w tablicy ma swoje zalety, zawsze możemy dodać kolejne pole.
Teraz zobaczmy coś takiego:
$excluded_fields = ['password', 'confirmPassword'];
print_r($excluded_fields);
//Array (
// [0] => password
// [1] => confirmPassword
// )
print_r(array_flip($excluded_fields));
// Array (
// [password] => 0
// [confirmPassword] => 1
// )
Flip zamienia wartości z kluczami (w tym przypadku indeksami). Mamy do czynienia z tablicą asocjacyjną data oraz tablicą-listą excluded_fields.
I jesteśmy tylko o krok od odfiltrowania niechcianych pól:
<?php
// try {
// next();
// } catch (ValidationException $e) {
// $data = $_POST;
$data = [
'user' => 'John',
'password' => md5('helloworld'),
'confirmPassword' => md5('helloworld'),
'email' => 'john.doe@wp.pl'
];
$excluded_fields = ['password', 'confirmPassword'];
$oldFormData = array_diff_key($data, array_flip($excluded_fields));
print_r($oldFormData);
//Array ( [user] => John [email] => john.doe@wp.pl )
W normalnym przypadku nasze middleware zabrałoby errory z ValidationException, wpisało je do sesji, podobnie odfiltrowane dane „old”, sprawdziło referera i na niego przekierowało następny ruch:
<?php
// try {
// next();
// } catch (ValidationException $e) {
// $data = $_POST;
$data = [
'user' => 'John',
'password' => md5('helloworld'),
'confirmPassword' => md5('helloworld'),
'email' => 'john.doe@wp.pl'
];
$excluded_fields = ['password', 'confirmPassword'];
$oldFormData = array_diff_key($data, array_flip($excluded_fields));
//print_r($oldFormData);
//Array ( [user] => John [email] => john.doe@wp.pl )
//$_SESSION['errors'] = $e->errors;
$_SESSION['oldFormData'] = $oldFormData;
//$referer = $_SERVER['HTTP_REFERER'];
//redirectTo($referer);
//}
Ten referer to jest strona formularza, skąd wysyłaliśmy request i na której nam ValidationException wyskoczył. I nie pójdziemy pod „action” naszego forma, kiedy wyskoczy, tylko na tego referera wrócimy.
Wrócimy bez hasła i powtórzonego hasła, za to z wypełnionymi innymi polami (poprzez old) oraz wyświetlonymi errorami tam, gdzie walidacja padła.
To oczywiście tylko przykład, w ćwiczeniu chodziło o array_diff_key i array_flip, ale tak to wygląda.