Skip to content

Instantly share code, notes, and snippets.

@svenk
Created November 3, 2017 17:53
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save svenk/11f13c577bc4f6d284ae5f979514808e to your computer and use it in GitHub Desktop.
Save svenk/11f13c577bc4f6d284ae5f979514808e to your computer and use it in GitHub Desktop.
Multi document YAML reader for PHP
<?php
/*
* There is currently no pure PHP yaml parser capable of reading
* multi documents (--- separated). I have tested both spyc and Symfony's YAML.
*
* Therefore I parse YAML with Python, encode it to json and read the json in
* PHP. The json is cached on disk.
*
* Public Domain by http://github.com/svenk
*/
function read_yamlfile($filename) {
$cache_dir = dirname(__FILE__).'/cache';
//global $cache_dir;
// check if json file exists
$cache_filename = $cache_dir . '/' . md5($filename) . ".yaml2json";
#print "YAML: $cache_filename <br>".filemtime($cache_filename)."<br>";
#print "FILE: $filename <br>".filemtime($filename)."<br>";
#exit;
/* Check for existence and validity of the cache file by comparing modification times */
if(file_exists($cache_filename) and filemtime($cache_filename) >= filemtime($filename)) {
return json_decode(file_get_contents($cache_filename), /* assoc: */ TRUE);
}
// create json file by creating a Python program that creates it.
$python_prog = <<<PYTHON
#!/usr/bin/python
import yaml # pip install PyYAML / python-yaml
import json # included
from io import open # python 2/3 unicode
import sys
def slurp(filename):
# read file in string
with open(filename, 'r', encoding='utf-8') as file:
return file.read()
def yamlfile(filename):
# load yaml markup into python structures
try:
talks = list(yaml.load_all(slurp(filename)))
except yaml.composer.ComposerError as e:
print "Compilation error in %s: %s" % (filename,str(e))
sys.exit(1)
return talks
json.dump(yamlfile(sys.argv[1]), sys.stdout)
sys.exit(0)
PYTHON;
$python_command = $cache_dir . "/yaml2json.py";
file_put_contents($python_command, $python_prog);
$exec = "python $python_command $filename 2>&1";
exec($exec, $output, $retval);
$output = implode("\n",$output);
if($retval != 0) {
print "Error evaluating Yaml2Json when executing Python (<em>$exec</em>, Retval: $retval): <pre>$output</pre>";
return null;
}
file_put_contents($cache_filename, $output);
return json_decode($output, /* assoc: */ TRUE);
}
@svenk
Copy link
Author

svenk commented Nov 3, 2017

This is a python-workaround for reading in YAML files in PHP. Due to the file cache, it is not even slow.

Known limitations: Serialization of python data structures may fail if the python yaml parser detected something special, for instance date objects (i.e. a string 2017-11-03 which is parsed as a date). But it is easy to implement a fix for that.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment