Skip to content
This repository has been archived by the owner on Dec 19, 2022. It is now read-only.
/ struct-array Public archive

Make PHP 7 array data validation easier and clearer by defining array structures.

License

Notifications You must be signed in to change notification settings

seifkamal/struct-array

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PHP Structured Arrays

Make PHP array data validation easier and clearer by defining array structures.

Why

We often need to receive, validate, and process data objects. Sometimes, an array might be too dumb for the task at hand, requiring several unpleasant control structures to validate and setup. Moreover, creating a dedicated DTO class (or more) might be overkill, requiring a lot of boilerplate code, whilst making things like error messaging and future refactoring more difficult.

In cases like this I find myself itching for a Go/Rust like struct instead.

See doc for a more in depth discussion.

Installation

composer require seifkamal/struct-array

Usage

To define and validate an array data structure, first create a Struct - this requires a name, used for error messaging, and an interface - then use the provided Validator function to validate the data against the defined Struct.

A Struct's interface ia an array consisting of string keys (matching the expected property names) and callable values. These values can be any callable PHP entity, and is expected to accept a single mixed type $value, and return a bool. Some valid examples are:

  • is_* variable handling functions (is_string, is_int, is_callable etc.)
  • A Closure (function ($value): bool {})
  • A class with an __invoke($value): bool method

Example

Here's an example written using the provided convenient helper functions:

<?php

use SK\StructArray\Exception\StructValidationException;

use function SK\StructArray\{
    arrayOf, optional, not, struct, validate
};

$directory = [
    'path' => __DIR__,
    'content' => [
        [
            'header' => 'Greeting',
            'line' => 'Hello',
        ],
    ]
];

try {
    validate($directory, struct('Directory', [
         'path' => 'is_dir',
         'file' => optional('is_file', __DIR__ . '/README.md'),
         'content' => arrayOf(struct('Paragraph', [
             'header' => 'is_string',
             'line' => not('is_null'),
         ])),
     ]));
} catch (StructValidationException $e) {
    echo $e->getMessage() . PHP_EOL;
    return;
}

echo "Path: {$directory['path']}" . PHP_EOL;
echo "File: {$directory['file']}" . PHP_EOL;
// Prints:
// Path: /Users/seifkamal/src/struct-array
// File: /Users/seifkamal/src/struct-array/README.md

You can also just use an array directly, without creating a Struct:

<?php

use function SK\StructArray\{
    arrayOf, optional, not, validate
};

$directory = [...];

validate($directory, [
    'path' => 'is_dir',
    'file' => optional('is_file', __DIR__ . '/README.md'),
    'content' => arrayOf([
        'header' => 'is_string',
        'line' => not('is_null'),
    ]),
]);

This is tailored for quick usage, and therefore assumes the defined interface is non-exhaustive (ie. the array submitted for validation is allowed to have keys that aren't defined here). It also means error messages will be more generic, ie you'll see:

Struct failed validation. ...

instead of:

Directory failed validation. ...

Here's another example directly using the static class methods:

<?php

use SK\StructArray\Exception\StructValidationException;
use SK\StructArray\Property\Type;
use SK\StructArray\Struct;
use SK\StructArray\Validator;

$directory = [
    'path' => __DIR__,
    'content' => [
        [
            'header' => 'Greeting',
            'line' => 'Hello',
        ],
    ]
];

$paragraphStruct = Struct::of('Paragraph', [
     'header' => 'is_string',
     'line' => Type::not('is_null'),
]);
$directoryStruct = Struct::of('Directory', [
     'path' => 'is_dir',
     'file' => Type::optional('is_file', __DIR__ . '/README.md'),
     'content' => Type::arrayOf($paragraphStruct),
]);

try {
    Validator::validate($directory, $directoryStruct);
} catch (StructValidationException $e) {
    echo $e->getMessage() . PHP_EOL;
    return;
}

echo "Path: {$directory['path']}" . PHP_EOL;
echo "File: {$directory['file']}" . PHP_EOL;
// Prints:
// Path: /Users/seifkamal/src/struct-array
// File: /Users/seifkamal/src/struct-array/README.md

For more, see the examples directory.

About

Make PHP 7 array data validation easier and clearer by defining array structures.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages