internal/toml
PHP 8.1+ TOML 1.0/1.1 parser and encoder. Parse TOML into PHP arrays or an AST, modify and round-trip back to TOML. Simple static API (Toml::parse/parseToArray/encode) for config files and tooling.
Installation:
composer require internal/toml
Requires PHP 8.1+.
First Use Case - Parsing:
use Internal\Toml\Toml;
$tomlString = file_get_contents('config.toml');
$configArray = Toml::parseToArray($tomlString);
Use this for loading configuration files (e.g., config/toml/) into PHP arrays.
First Use Case - Encoding:
$phpData = ['database' => ['host' => 'localhost']];
$tomlString = (string) Toml::encode($phpData);
Use this for generating TOML output (e.g., for API responses or config exports).
First Use Case - AST Access:
$document = Toml::parse($tomlString);
$array = $document->toArray(); // Convert to array
$modifiedToml = (string) $document; // Re-encode with original formatting
Use this for advanced workflows like validation or schema enforcement.
Toml::parseToArray(), Toml::encode(), and Toml::parse().// config/toml/database.toml
[mysql]
host = "localhost"
port = 3306
// In Laravel service provider
public function register()
{
$config = Toml::parseToArray(file_get_contents(base_path('config/toml/database.toml')));
$this->app->singleton('db.config', fn() => $config);
}
// Generate TOML for a feature flag
$featureFlags = [
'new_ui' => ['enabled' => true, 'environments' => ['production', 'staging']],
];
$toml = (string) Toml::encode($featureFlags);
file_put_contents(storage_path('toml/feature-flags.toml'), $toml);
// Parse → Modify → Encode
$document = Toml::parse(file_get_contents('config.toml'));
$data = $document->toArray();
$data['new_key'] = 'new_value';
// Preserve original formatting (e.g., hex numbers, comments)
$document->nodes = ...; // Manipulate AST if needed
file_put_contents('config.toml', (string) $document);
$document = Toml::parse($tomlString);
foreach ($document->nodes as $node) {
if ($node instanceof \Internal\Toml\Node\Table) {
// Validate table structure
if (!array_key_exists('required_key', $node->entries)) {
throw new \InvalidArgumentException("Missing required key in table");
}
}
}
// In a custom config loader (e.g., app/Providers/ConfigServiceProvider)
public function boot()
{
$tomlFiles = glob(app_path('config/toml/*.toml'));
foreach ($tomlFiles as $file) {
$configKey = str_replace('.toml', '', basename($file));
config([$configKey => Toml::parseToArray(file_get_contents($file))]);
}
}
files helper or a package like spatie/laravel-file-watcher to reload TOML configs when files change (e.g., for development).Toml::parse() in a try-catch to handle malformed TOML gracefully:
try {
$data = Toml::parseToArray($tomlString);
} catch (\Internal\Toml\Exception\ParseException $e) {
report($e);
$data = []; // Fallback
}
Toml::encode() to generate test TOML files or validate round-trip conversions:
$originalToml = 'key = "value"';
$data = Toml::parseToArray($originalToml);
$roundTripToml = (string) Toml::encode($data);
$this->assertEquals($originalToml, $roundTripToml);
TOML 1.1 vs. 1.0:
Toml::encode() to generate TOML 1.0-compatible output if needed (it defaults to 1.0 for maximum interoperability).Bare Keys and Dotted Keys:
key = "value") and dotted keys (e.g., [table.key]). If your TOML uses these, ensure you’re on 1.1.2+.AST Manipulation:
$document->nodes) can break formatting or validation.toArray() and encode() for safer round-trip edits:
$data = $document->toArray();
$data['new_key'] = 'new_value';
$document = Toml::parse((string) Toml::encode($data));
DateTime Handling:
DateTimeImmutable objects, but parsing relies on the input TOML’s format.created = 1979-05-27, the output array will use a DateTime object, but re-encoding may not preserve the exact string format.DateTimeImmutable objects for consistent encoding:
$data = ['created' => new DateTimeImmutable('1979-05-27')];
$toml = (string) Toml::encode($data); // Output: created = 1979-05-27T00:00:00Z
Comments Preservation:
Document object).parseToArray() + encode() may strip comments.$document = Toml::parse($tomlString);
// Modify AST (e.g., add comments)
$document->addComment('New comment');
file_put_contents('output.toml', (string) $document);
Hex/Octal/Binary Numbers:
0xDEADBEEF stays as hex), but parsing may convert these to integers.$document = Toml::parse('magic = 0xDEADBEEF');
$toml = (string) $document; // Output: magic = 0xDEADBEEF
JsonSerializable Support:
JsonSerializable objects, but nested structures may not serializeHow can I help you explore Laravel packages today?