Encoding
PHP Toml encodes PHP arrays to TOML and supports explicit value wrappers for TOML local date/time/datetime literals.
Basic Encoding
use PhpCollective\Toml\Toml;
$toml = Toml::encode([
'title' => 'My App',
'database' => [
'host' => 'localhost',
'port' => 5432,
],
]);Output:
title = "My App"
[database]
host = "localhost"
port = 5432Supported Input Types
| PHP Type | TOML Output |
|---|---|
string | Basic string "value" |
int | Integer 42 |
float | Float 3.14 |
bool | Boolean true / false |
array (list) | Array [1, 2, 3] |
array (assoc) | Table or inline table depending on position |
DateTimeInterface | Offset datetime |
PhpCollective\Toml\Value\LocalDate | Local date |
PhpCollective\Toml\Value\LocalTime | Local time |
PhpCollective\Toml\Value\LocalDateTime | Local datetime |
null is not supported and throws EncodeException.
Encoder Options
use PhpCollective\Toml\Encoder\EncoderOptions;
use PhpCollective\Toml\Encoder\ArrayStyle;
$options = new EncoderOptions(
sortKeys: true,
arrayStyle: ArrayStyle::Multiline,
);
$toml = Toml::encode($data, $options);See API Reference for the full options list.
Diff-Friendly Preset
For files under version control, use the diffFriendly() preset to minimize diffs when making changes:
$toml = Toml::encode($data, EncoderOptions::diffFriendly());This preset enables:
- Trailing commas in arrays (adding items doesn't modify the previous line)
- Auto multiline arrays (arrays with more than 3 items use one item per line)
Example output:
small = [1, 2,]
large = [
1,
2,
3,
4,
]Sort Keys
$toml = Toml::encode([
'zebra' => 1,
'apple' => 2,
'mango' => 3,
], new EncoderOptions(sortKeys: true));Output:
apple = 2
mango = 3
zebra = 1Custom Newlines
$toml = Toml::encode([
'name' => 'test',
'count' => 42,
], new EncoderOptions(newline: "\r\n"));Skip Null Values
By default, null values throw EncodeException. Use skipNulls to silently omit them:
$toml = Toml::encode([
'name' => 'Alice',
'email' => null, // Will be omitted
'age' => 30,
], new EncoderOptions(skipNulls: true));Output:
name = "Alice"
age = 30This also filters nulls from arrays and inline tables.
Integer Grouping
Add underscores to large integers for readability:
$toml = Toml::encode([
'population' => 1000000,
], new EncoderOptions(integerGrouping: true));Output:
population = 1_000_000Trailing Commas
Add trailing commas to inline arrays:
$toml = Toml::encode([
'items' => [1, 2, 3],
], new EncoderOptions(trailingComma: true));Output:
items = [1, 2, 3,]Dotted Keys
Use dotted keys instead of table sections:
$toml = Toml::encode([
'database' => [
'host' => 'localhost',
'port' => 5432,
],
], new EncoderOptions(dottedKeys: true));Output:
database.host = "localhost"
database.port = 5432Array Style
Control array formatting with ArrayStyle:
use PhpCollective\Toml\Encoder\ArrayStyle;
// Multiline arrays (one item per line)
$toml = Toml::encode([
'ports' => [8080, 8081, 8082],
], new EncoderOptions(arrayStyle: ArrayStyle::Multiline));Output:
ports = [
8080,
8081,
8082,
]Use ArrayStyle::Auto to automatically switch to multiline when arrays exceed a threshold:
$toml = Toml::encode([
'few' => [1, 2],
'many' => [1, 2, 3, 4, 5],
], new EncoderOptions(
arrayStyle: ArrayStyle::Auto,
arrayAutoThreshold: 3,
));Output:
few = [1, 2]
many = [
1,
2,
3,
4,
5,
]Customize indentation with indent:
$toml = Toml::encode([
'items' => [1, 2, 3],
], new EncoderOptions(
arrayStyle: ArrayStyle::Multiline,
indent: ' ', // 2 spaces
));Date and Time Encoding
Offset Datetime
Use DateTimeInterface for TOML offset datetimes:
$toml = Toml::encode([
'created' => new DateTimeImmutable('2024-01-15T10:30:00Z'),
]);Output:
created = 2024-01-15T10:30:00.000000+00:00Local Date, Time, and DateTime
Use explicit wrappers for TOML local temporal values:
use PhpCollective\Toml\Value\LocalDate;
use PhpCollective\Toml\Value\LocalDateTime;
use PhpCollective\Toml\Value\LocalTime;
$toml = Toml::encode([
'date' => new LocalDate('2024-03-15'),
'time' => new LocalTime('10:30:45'),
'timestamp' => new LocalDateTime('2024-03-15T10:30:45'),
]);Output:
date = 2024-03-15
time = 10:30:45
timestamp = 2024-03-15T10:30:45Plain PHP strings are always encoded as TOML strings, not temporal literals.
Array of Tables
Sequential arrays of associative arrays become array-of-tables:
$toml = Toml::encode([
'servers' => [
['name' => 'alpha', 'ip' => '10.0.0.1'],
['name' => 'beta', 'ip' => '10.0.0.2'],
],
]);Output:
[[servers]]
name = "alpha"
ip = "10.0.0.1"
[[servers]]
name = "beta"
ip = "10.0.0.2"Special Float Values
$toml = Toml::encode([
'infinity' => INF,
'negative_infinity' => -INF,
'not_a_number' => NAN,
]);Output:
infinity = inf
negative_infinity = -inf
not_a_number = nanString Escaping
Strings are emitted as basic strings with escapes:
$toml = Toml::encode([
'message' => "Hello\nWorld",
'path' => 'C:\Users\name',
]);Output:
message = "Hello\nWorld"
path = "C:\\Users\\name"Re-encoding from AST
$document = Toml::parse($originalToml, true);
// Modify the AST...
$toml = Toml::encodeDocument(
$document,
new EncoderOptions(documentFormatting: DocumentFormattingMode::SourceAware),
);WARNING
encodeDocument() defaults to normalized output. Use DocumentFormattingMode::SourceAware when you want minimal-diff, source-aware behavior for trivia-preserving ASTs.
In SourceAware mode, unchanged parsed regions can round-trip losslessly and edited regions follow local fallback rules. Compatible key, value, dotted-key, and table-header edits can often keep their original separator spacing, and single-line collections preserve local delimiter style when the AST has consistent local formatting evidence. If not, the encoder canonicalizes locally.
For the full editing contract and compatibility boundary, see Compatibility.
Error Handling
Encoding throws EncodeException for unsupported values:
use PhpCollective\Toml\Exception\EncodeException;
try {
$toml = Toml::encode([
'callback' => fn() => 'hello',
]);
} catch (EncodeException $e) {
echo $e->getMessage();
}Common unsupported values:
null- closures
- resources
- arbitrary objects that do not implement the TOML value contract
- circular references