minnis/neon-tools

NEON tools. A handy (and super fast) NEON fileloader class for PHP.

1.1.01 2019-09-28 13:44 UTC

This package is auto-updated.

Last update: 2024-04-29 00:37:08 UTC


README

NEON tools. A handy (and super fast) NEON fileloader class for PHP.

Jump to:

Install

The package can be installed using composer:

composer require minnis/neon-tools

Usage

We really like YAML but we are in love with NEON.

You probably know Symfony's Yaml component and its parseFile function.

$array = Yaml::parseFile('/path/to/file.yaml');

We don't know why but the nette/neon package is not shipped with a fileloader. So we created our own.

Quick Start

Simply swap Yaml::parseFile() with NeonLoader::parseFile()

Example using the static function:

<?php

use MINNIS\NeonTools\NeonLoader;

require_once __DIR__ . '/../vendor/autoload.php';

$array = NeonLoader::parseFile('/path/to/file.neon');

And for those who prefer the Object Oriented approach:

<?php

use MINNIS\NeonTools\NeonLoader;

require_once __DIR__ . '/../vendor/autoload.php';

$NeonLoader = new NeonLoader();
$array = $NeonLoader->fromFile('/path/to/file.neon');

Cache

When NEON/YAML is used as a way to manage settings/configuration performance becomes important. Especially if it is parsed on every request.

If you are using symfony/yaml, mustangostang/spyc or nette/neon as stand-alone package (without a framework) your need to manage caching yourself. And who has time for that.

We created a simple but fast caching system within the fileloader. It requires no config and is enabled by default. It just works.

If you are using git on your environment we recommend adding *.cache to your .gitignore file.

When the cache file is used the modification timestamp of the original file (and all files it imports) is checked. Simply edit the original files and all changes are detected automaticly.

You can still use fileloader without the caching, like this:

//static
$array = NeonLoader::parseFileWithoutCache('/path/to/file.neon');

//object oriented
$NeonLoader = new NeonLoader(false); //the false parameter disables caching

Performance

NEON has a very good balance between ease of use, features and performance.

It must be said YAML has some cool advanced features. However, that comes at a price when it comes to perfomance.

We did some benchmarking and the results are spectaculair! Not only is NEON (the neon parser) twice as fast YAML (symfony's yaml parser). The caching functionality we created is about 7.5 times faster as runtime parsing.

1000 runs

PHP 5.6PHP 7.1PHP 7.3
NEON (cached)0.5 sec0.2 sec0.18 sec
NEON (uncached)2.9 sec1.5 sec1.03 sec
YAML (symfony)5.9 sec3.1 sec2.22 sec

Want to do benchmarking of your own? We added a benchmarking script and test neon files in the ./tests/ folder.

Imports

A very nice feature of YAML is to link files using the imports array. Since nette/neon has no fileloader this behaviour was not available to NEON. So, we added it to neon-tools.

We made the YAML notation available so no need to alter your files:

imports:
  - { resource: second_file.neon }
  - { resource: third_file.neon }

And since we like things simple, this just works:

imports:
  - second_file.neon
  - third_file.neon

The import workds recursive. So you can import a file that imports a file that imports a file that .... well, you get the point.

Options

NEON is, like YAML, often used as a configurations file. In some occasions you do not want (or need) the full contents of the file.

Lets take this example configuration file: example.neon

database:
    host: localhost
    port: 3306
    user: someuser
    pass: somepass
    charset: utf8mb4

third_party_api:
    bearer: abc123abc123abc
    userid: 238473

nsa_supersecret_api:
    api_key: root
    api_token: root 

Include

The (optional) second parameter can be used to include only selected root keys. This can either be a string or an array.

$array = NeonLoader::parseFile('/path/to/example.neon', 'database');

//result:
array(1) {
  ['database']=>
  array(5) {
     ...
  }
}

Exclude

The (optional) third parameter can be used to exclude selected root keys. This can either be a string or an array.

$array = NeonLoader::parseFile('/path/to/example.neon', null, ['nsa_supersecret_api', 'cia_alsosecret_api']);

//result:
array(2) {
  ['database']=>
  array(5) {
    ...
  }
  ['third_party_api']=>
  array(2) {
    ...
  }
}

Parameters

Not part of Symfony's Yaml parser but a feature of the Symfony framework itself is the possibility to use placeholders(variables) in config files. When used with imports it keeps your config nice, tidy and seperated. Since we like nice and tidy we added this feature to neon-tools as well.

A placeholder is defined by surrounding it with %, like this: %i_am_a_placeholder%. The actual value is retrieved from the parameters array.

#application.neon
imports:
  - environment.neon

database:
    user: %db_username%
    pass: %db_password%
    host: %db_host%
    options: %db_options%
#environment.neon
parameters:
  db_username: ROOT
  db_password: SECRET
  db_host: localhost
  db_options: 
    char_set: utf8mb4
    backup: false

When parsed the result will look like this:

['database' => [ 
    'user' => "ROOT",
    'pass' => "SECRET",
    'host' => "localhost",
    'options' => [
        'charset' => "utf8mb4",
        'backup'  => false
    ]
]

The parameters array is merged with every import. So you can use the parameters array in every imported file you want. Just make sure the key is unique. The placeholder itself can be used as often as you like.

Because imports are parsed before parameters you cannot use placeholders within the imports array to create dynamic paths/filenames.

Neon

NEON is very similar to YAML.The main difference is that the NEON supports entities (so can be used e.g. to parse phpDoc annotations, DI services, …) and both spaces and tabs for indentation. NEON syntax is a little simpler and the parsing is faster.

Try NEON in sandbox!