Skip to content

JSON Conversion

Convert between HCL and JSON formats for interoperability.

Use case: Integrating with tools that expect JSON, generating HCL from code, or migrating configurations.

use Cline\Hcl\Hcl;
$hcl = <<<'HCL'
name = "my-app"
version = "1.0.0"
enabled = true
ports = [80, 443]
HCL;
// Pretty-printed JSON (default)
$json = Hcl::toJson($hcl);
// {
// "name": "my-app",
// "version": "1.0.0",
// "enabled": true,
// "ports": [80, 443]
// }
// Compact JSON
$json = Hcl::toJson($hcl, pretty: false);
// {"name":"my-app","version":"1.0.0","enabled":true,"ports":[80,443]}
use Cline\Hcl\Hcl;
$hcl = 'name = "my-app"';
$data = Hcl::parse($hcl);
// ['name' => 'my-app']
// Then encode as JSON yourself if needed
$json = json_encode($data, JSON_PRETTY_PRINT);
use Cline\Hcl\Hcl;
$json = '{"name": "my-app", "port": 8080, "enabled": true}';
$hcl = Hcl::fromJson($json);
// name = "my-app"
// port = 8080
// enabled = true
use Cline\Hcl\Hcl;
$data = [
'name' => 'my-app',
'version' => '1.0.0',
'settings' => [
'timeout' => 30,
'retries' => 3,
],
];
$hcl = Hcl::arrayToHcl($data);
// name = "my-app"
// version = "1.0.0"
// settings = {
// timeout = 30
// retries = 3
// }

Nested structures are intelligently converted to HCL blocks:

$hcl = <<<'HCL'
resource "aws_instance" "web" {
ami = "ami-12345"
instance_type = "t2.micro"
tags = {
Name = "WebServer"
}
}
HCL;
$json = Hcl::toJson($hcl);
{
"resource": {
"aws_instance": {
"web": {
"ami": "ami-12345",
"instance_type": "t2.micro",
"tags": {
"Name": "WebServer"
}
}
}
}
}
$data = [
'resource' => [
'aws_instance' => [
'web' => [
'ami' => 'ami-12345',
'instance_type' => 't2.micro',
],
],
],
];
$hcl = Hcl::arrayToHcl($data);
resource "aws_instance" "web" {
ami = "ami-12345"
instance_type = "t2.micro"
}
HCLJSON
"string""string"
4242
3.143.14
truetrue
falsefalse
nullnull
// Arrays
$hcl = 'ports = [80, 443, 8080]';
$json = Hcl::toJson($hcl);
// {"ports": [80, 443, 8080]}
// Objects
$hcl = 'config = { host = "localhost", port = 8080 }';
$json = Hcl::toJson($hcl);
// {"config": {"host": "localhost", "port": 8080}}

Functions are preserved as special structures:

$hcl = <<<'HCL'
password = sensitive("secret123")
config = file("settings.json")
HCL;
$json = Hcl::toJson($hcl);
{
"password": {
"__function__": "sensitive",
"__args__": ["secret123"]
},
"config": {
"__function__": "file",
"__args__": ["settings.json"]
}
}

Data is preserved when converting HCL -> JSON -> HCL:

use Cline\Hcl\Hcl;
$original = <<<'HCL'
name = "roundtrip-test"
version = 42
enabled = true
tags = ["a", "b", "c"]
HCL;
// HCL -> JSON
$json = Hcl::toJson($original);
// JSON -> HCL
$backToHcl = Hcl::fromJson($json);
// Verify data integrity
$reparsed = Hcl::parse($backToHcl);
assert($reparsed['name'] === 'roundtrip-test');
assert($reparsed['version'] === 42);
assert($reparsed['enabled'] === true);
assert($reparsed['tags'] === ['a', 'b', 'c']);

The arrayToHcl method produces formatted output:

$data = [
'server' => [
'web' => [
'host' => 'localhost',
'port' => 8080,
],
],
];
$hcl = Hcl::arrayToHcl($data);

Output:

server "web" {
host = "localhost"
port = 8080
}

Arrays exceeding 80 characters are formatted on multiple lines:

$data = [
'items' => [
'this is a very long string',
'another very long string that exceeds the threshold',
],
];
$hcl = Hcl::arrayToHcl($data);

Output:

items = [
"this is a very long string",
"another very long string that exceeds the threshold",
]
$variables = [
'region' => 'us-west-2',
'instance_type' => 't2.micro',
'instance_count' => 3,
];
$hcl = '';
foreach ($variables as $name => $default) {
$hcl .= Hcl::arrayToHcl([
'variable' => [
$name => ['default' => $default],
],
]);
}
file_put_contents('variables.tf', $hcl);
// Read existing config
$data = Hcl::parseFile('config.hcl');
// Transform
$data['version'] = '2.0.0';
$data['updated_at'] = date('Y-m-d');
// Write back
$hcl = Hcl::arrayToHcl($data);
file_put_contents('config.hcl', $hcl);
// Parse HCL config
$config = Hcl::parseFile('app.hcl');
// Send as JSON to API
$response = Http::post('https://api.example.com/config', $config);
// Or explicitly convert
$json = Hcl::toJson(file_get_contents('app.hcl'));
$response = Http::withBody($json, 'application/json')
->post('https://api.example.com/config');