nette/neon
NEON is Nette’s human-friendly data serialization format and parser for PHP. It offers a clean syntax for configuration files, supports comments, multiline strings and typed values, and converts NEON to/from PHP arrays and objects with reliable error reporting.
Install via Composer:
composer require nette/neon
First use case: Load a NEON config file in Laravel’s config() helper.
use Nette\Neon\Neon;
// Load NEON file into PHP array
$config = Neon::decodeFile(app_path('config/custom.neon'));
// Merge with Laravel’s config (e.g., in a service provider)
config(['custom' => $config]);
Where to look first:
decode(), encode(), decodeFile()).Workflow: Replace Laravel’s YAML/JSON configs with NEON for Nette-compatible projects.
// config/app.php
return [
'custom' => Neon::decodeFile(__DIR__ . '/custom.neon'),
];
Tip: Use Neon::decodeFile() in a custom config loader (e.g., NeonConfigLoader) to integrate with Laravel’s config() helper.
Use case: Generate NEON configs dynamically (e.g., for feature flags).
$flags = [
'experimental' => true,
'beta' => ['users' => ['admin', 'dev']],
];
$neon = Neon::encode($flags, 4); // Indent with 4 spaces
file_put_contents(storage_path('app/flags.neon'), $neon);
Use case: Validate NEON syntax or enforce schema rules.
use Nette\Neon\Ast\Traverser;
$ast = Neon::decode($neonString, Neon::STRICT);
$traverser = new Traverser();
$traverser->onEnterNode(function ($node) {
if ($node instanceof \Nette\Neon\Ast\ScalarNode && $node->value === 'debug') {
throw new \RuntimeException("'debug' is reserved!");
}
});
$traverser->traverse($ast);
Pattern: Merge NEON configs with Laravel’s native arrays.
$neonConfig = Neon::decodeFile(config_path('neon_config.neon'));
config(['neon' => array_merge(
config('neon.defaults', []),
$neonConfig
)]);
Use case: Parse NEON in Artisan commands.
// In a custom Artisan command
$neonData = Neon::decodeFile($this->argument('neon_file'));
$this->info('Loaded NEON: ' . Neon::encode($neonData));
PHP Version Mismatch:
composer require nette/neon:^3.3 for PHP 7.4+.composer.json constraints or use composer why-not nette/neon:^3.3.UTF-8 Strictness:
mb_detect_encoding() or use Neon::decode($content, Neon::FORGIVING).BC Breaks in v3.x:
Neon::decode() no longer strips BOM (v3.3.1).DateTimeImmutable is used instead of DateTime (v2.4.0).Large Integers:
PHP_INT_MAX are decoded as strings (v3.4.3).(int) $neonData['big_number'].Special Values:
INF, NAN, and null in keys throw exceptions (v3.4.1).Neon::encode($value, Neon::FORGIVING) to skip problematic values.AST Traversal Quirks:
Traverser::traverse() modifies the AST in-place.Neon::decode($neon, Neon::STRICT) if immutability is needed.try {
$data = Neon::decode($neonString, Neon::STRICT);
} catch (\Nette\Neon\Exception $e) {
report($e); // Log via Laravel’s error handler
throw new \RuntimeException("Invalid NEON: " . $e->getMessage());
}
$neon = Neon::encode($data, 4); // 4-space indent
file_put_contents('debug.neon', $neon);
$content = file_get_contents('config.neon');
if (!mb_check_encoding($content, 'UTF-8')) {
throw new \RuntimeException("NEON file must be UTF-8 encoded!");
}
Custom Encoder/Decoder:
Override Neon\Encoder or Neon\Decoder for domain-specific types (e.g., UUIDs).
class CustomEncoder extends \Nette\Neon\Encoder {
public function encode($value) {
if ($value instanceof \Ramsey\Uuid\Uuid) {
return $value->toString();
}
return parent::encode($value);
}
}
Neon Linter:
Use the built-in neon-lint CLI tool or integrate it into Laravel’s testing:
composer require --dev nette/neon
./vendor/bin/neon-lint config.neon
Neon Config Caching: Cache decoded NEON configs in Laravel’s cache:
$cacheKey = 'neon:config';
$config = cache()->remember($cacheKey, now()->addHours(1), function () {
return Neon::decodeFile(config_path('custom.neon'));
});
IDE Support: Enable PHPStan or Psalm with the updated phpDoc (v3.4.8+):
# phpstan.neon
includes:
- vendor/nette/neon/src
decodeFile() is atomic (v3.3.4) but slower than file_get_contents() + decode().Traverser::DontTraverseChildren to optimize.Neon::encode($data, 0) for compact output (no indentation).How can I help you explore Laravel packages today?