Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Schema Laravel Package

nette/schema

nette/schema is a small PHP library for validating and normalizing structured data. Define schemas for arrays, configuration, and user input with type checks, defaults, required fields, ranges, and clear error messages—ideal for safe config loading.

View on GitHub
Deep Wiki
Context7

Getting Started

Install via Composer:

composer require nette/schema

Start by validating simple configuration arrays — e.g., reading config from config.php or environment variables. Define schemas with Nette\Schema\Expect, then validate with Nette\Schema\Processor:

use Nette\Schema\Expect;
use Nette\Schema\Processor;

$schema = Expect::structure([
    'app_name' => Expect::string()->required(),
    'debug' => Expect::bool()->default(false),
]);

$processor = new Processor();
$config = $processor->process($schema, $rawConfig);

First use case: validating application config (e.g., after loading from a .env-parsed array or JSON file). Check the README and API docs for quick reference — focus on Expect::structure(), Expect::string(), and .required().


Implementation Patterns

Config Validation at Bootstrap

Use in Laravel bootstrapping (e.g., in config/app.php or a custom ConfigLoader) to ensure config integrity before service resolution:

// In a service provider or bootstrap script
$schema = Expect::structure([
    'log' => Expect::structure([
        'level' => Expect::oneOf(['debug', 'info', 'error'])->default('info'),
        'path' => Expect::string()->required(),
    ]),
]);

$raw = config('app.log'); // Or from file
$validated = $processor->process($schema, $raw);
config()->set('app.log', $validated); // Normalize and merge

Request/DTO Sanitization

Parse and validate incoming requests (e.g., JSON payloads for API endpoints) using schemas before domain logic:

$requestData = json_decode($request->getContent(), true);
$schema = Expect::structure([
    'email' => Expect::email()->required(),
    'tags' => Expect::listOf(Expect::string())->minLength(1),
    'metadata' => Expect::arrayOf(Expect::string(), Expect::string()),
]);
$data = $processor->process($schema, $requestData);
// $data is now strongly-typed and safe for use

Composable Schemas with castTo()

Define reusable schemas and map validated data to DTOs/Models:

$addressSchema = Expect::structure([
    'street' => Expect::string()->required(),
    'city' => Expect::string()->required(),
])->castTo(Address::class);

$userSchema = Expect::structure([
    'name' => Expect::string()->required(),
    'address' => $addressSchema,
]);

Environment-Specific Configs via merge() & extend()

Build layered configs (e.g., base → dev → production):

$base = Expect::structure(['timeout' => 30]);
$env = Expect::structure(['timeout' => 5, 'debug' => true])->merge($base);

// Or use extend() for shallow merging of keys
$dev = Expect::structure(['debug' => true])->extend($base);

Gotchas and Tips

  • Expect::array() ≠ associative array only: Passing a numerically indexed array ([1,2,3]) to Expect::array() strips keys → silent data loss. Use Expect::listOf() for lists.

  • Defaults only apply on missing or null keys: If a key exists but is null, default() won’t override it unless explicitly marked nullable() first.

  • AnyOf() must have ≥1 item: AnyOf([]) throws SchemaException. Guard dynamic schema generation (e.g., check if ($conditions) before building branches).

  • Path context is dot-notation: Errors like database.host help debugging. Override Processor::onError to enrich error messages (e.g., localize for frontend).

  • transform() is pure and side-effect-free: Only use it for coercive normalization (e.g., 'TRUE' → true, or string → enum). Avoid logging, DB calls, or mutation.

  • PHP 8.1+ required: Uses typed properties and readonly classes — no fallback. Conflicts with legacy Laravel setups (≤Laravel 8/PHP 8.0).

  • Error codes enable precision: ValidationException::getMessages() returns code (e.g., 'type.string', 'required'). Map codes to UI-friendly messages:

    $messages = $e->getMessages();
    foreach ($messages as $msg) {
        $human = match ($msg->code) {
            'required' => 'This field is required.',
            'type.string' => 'Must be a string.',
            default => $msg->message,
        };
    }
    
  • Structure::skipDefaults() cleans output: Use when caching or diffing configs — avoids bloating output with default values.

  • Static analysis: PHPStan level 9 — run with phpstan.neon to catch schema misuses early (e.g., non-existent keys, type mismatches).

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4