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.