How to fetch data from yaml file in php
- Create your YAML file (e.g. data.yaml)
database:
host: localhost
port: 3306
credentials:
username: root
password: secret
settings:
debug: true
cache: false
rates: [1.0, 2.0, 3.0]
servers:
- name: server1
ip: 192.168.1.1
- name: server2
ip: 192.168.1.2
2. Create Class
class SimpleYamlParser {
3. Create the object of class and pass yaml file name
$parser = new SimpleYamlParser();
$data = $parser->parseFile('data.yaml');
4. Access your data with object
if ($data !== false) {
// Access your data
echo $data['database']['host']; // outputs: localhost
echo $data['settings']['debug']; // outputs: 1 (true)
echo $data['servers'][0]['name']; // outputs: server1
print_r($data['settings']['rates']); // outputs array of numbers
}
Complete code:
<?php
class SimpleYamlParser {
private $indentSpaces = 2;
public function parseFile($filePath) {
try {
// Check if file exists
if (!file_exists($filePath)) {
throw new Exception('File not found: ' . $filePath);
}
// Read file content
$content = file_get_contents($filePath);
if ($content === false) {
throw new Exception('Unable to read file: ' . $filePath);
}
return $this->parse($content);
} catch (Exception $e) {
error_log('YAML Parser Error: ' . $e->getMessage());
return false;
}
}
public function parse($yamlString) {
// Remove comments and empty lines
$lines = array_filter(explode("\n", $yamlString), function($line) {
$trimmedLine = trim($line);
return $trimmedLine !== '' && !str_starts_with($trimmedLine, '#');
});
$result = [];
$currentPath = [];
$previousIndent = -1;
foreach ($lines as $line) {
// Count leading spaces for indentation level
$indent = strlen($line) - strlen(ltrim($line));
$indent = floor($indent / $this->indentSpaces);
// Remove leading/trailing whitespace
$line = trim($line);
// Skip empty lines and comments
if (empty($line) || $line[0] === '#') {
continue;
}
// Parse key and value
if (strpos($line, ':') !== false) {
list($key, $value) = array_pad(explode(':', $line, 2), 2, '');
$key = trim($key);
$value = trim($value);
// Adjust current path based on indentation
while (count($currentPath) > $indent) {
array_pop($currentPath);
}
if (empty($value)) {
// This is a new nested level
$currentPath[$indent] = $key;
} else {
// This is a key-value pair
// Handle different value types
$value = $this->parseValue($value);
// Build the complete path and set the value
$target = &$result;
for ($i = 0; $i < $indent; $i++) {
if (isset($currentPath[$i])) {
if (!isset($target[$currentPath[$i]])) {
$target[$currentPath[$i]] = [];
}
$target = &$target[$currentPath[$i]];
}
}
$target[$key] = $value;
}
} else if (str_starts_with($line, '-')) {
// Handle array items
$value = trim(substr($line, 1));
$value = $this->parseValue($value);
$target = &$result;
for ($i = 0; $i < $indent; $i++) {
if (isset($currentPath[$i])) {
if (!isset($target[$currentPath[$i]])) {
$target[$currentPath[$i]] = [];
}
$target = &$target[$currentPath[$i]];
}
}
$lastKey = end($currentPath);
if ($lastKey) {
if (!is_array($target[$lastKey])) {
$target[$lastKey] = [];
}
$target[$lastKey][] = $value;
}
}
$previousIndent = $indent;
}
return $result;
}
private function parseValue($value) {
$value = trim($value);
// Handle null
if ($value === '~' || strtolower($value) === 'null') {
return null;
}
// Handle booleans
if (strtolower($value) === 'true') {
return true;
}
if (strtolower($value) === 'false') {
return false;
}
// Handle numbers
if (is_numeric($value)) {
return strpos($value, '.') !== false ? (float)$value : (int)$value;
}
// Handle quoted strings
if (preg_match('/^([\'"])(.*)\1$/', $value, $matches)) {
return $matches[2];
}
return $value;
}
}
// Example usage:
$parser = new SimpleYamlParser();
$data = $parser->parseFile('data.yaml');
if ($data !== false) {
// Access your data
echo $data['database']['host']; // outputs: localhost
echo $data['settings']['debug']; // outputs: 1 (true)
echo $data['servers'][0]['name']; // outputs: server1
print_r($data['settings']['rates']); // outputs array of numbers
}
Keep Learning 🙂