1#!/usr/bin/env php
2<?php
3//////////
4// Gron //
5//////////
6
7// Take valid JSON on stdin, or read it from a file or URL,
8// then output it as discrete assignments to make it grep-able.
9
10// Exit codes:
11//   0 - Success
12//   1 - Failed to decode JSON
13//   2 - Argument is not valid file or URL
14//   3 - Failed to fetch data from URL
15
16// Tom Hudson - 2012
17// https://github.com/TomNomNom/gron
18
19// Decide on stdin, a local file or URL
20if ($argc == 1){
21  $buffer = file_get_contents('php://stdin');
22
23} else {
24  $source = $argv[1];
25
26  // Check for a readable file or URL
27  if (is_readable($source)){
28    $buffer = file_get_contents($source);
29
30  } else if (filter_var($source, FILTER_VALIDATE_URL)){
31    $c = curl_init($source);
32    curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
33    curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);
34    curl_setopt($c, CURLOPT_TIMEOUT, 20);
35    curl_setopt($c, CURLOPT_HTTPHEADER, array(
36      'Accept: application/json'
37    ));
38
39    $buffer = curl_exec($c);
40    $err    = curl_errno($c);
41    curl_close($c);
42
43    if ($err != CURLE_OK){
44      fputs(STDERR, "Data could not be fetched from [{$source}]\n");
45      exit(3);
46    }
47
48  } else {
49    fputs(STDERR, "[{$source}] is not a valid file or URL.\n");
50    exit(2);
51  }
52}
53
54// Meat
55$struct = json_decode($buffer);
56$err = json_last_error();
57
58if ($err != JSON_ERROR_NONE){
59  // Attempt to read as multiple lines of JSON (sometimes found in streaming APIs etc)
60  $lines = explode("\n", trim($buffer));
61  for ($i = 0; $i < sizeOf($lines); $i++){
62
63    $line = $lines[$i];
64    $struct = json_decode($line);
65    $err = json_last_error();
66
67    // No dice; time to die
68    if ($err != JSON_ERROR_NONE){
69      fputs(STDERR, "Failed to decode JSON\n");
70      exit(1);
71    }
72
73    printSruct($struct, "json{$i}");
74    echo PHP_EOL;
75  }
76} else {
77  // Buffer is all one JSON blob
78  printSruct($struct);
79}
80
81function printSruct($struct, $prefix = 'json'){
82  if (is_object($struct)){
83    echo "{$prefix} = {};\n";
84  } elseif (is_array($struct)){
85    echo "{$prefix} = [];\n";
86  } else {
87    echo "{$prefix} = ". json_encode($struct) .";\n";
88
89    // No need to iterate if we already have a scalar
90    return;
91  }
92
93  foreach ($struct as $k => $v){
94    $k = json_encode($k);
95    printSruct($v, "{$prefix}[{$k}]");
96  }
97}
98
99exit(0);
100