Created
January 27, 2017 15:48
-
-
Save FLamparski/104407d41322e47f766d4aba7bf2a20e to your computer and use it in GitHub Desktop.
Hacky way to use shlex.split in PHP
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Hacks around the fact that there isn't a good shell-style argument lexer | |
* for PHP by using the Python one. | |
* One argument: the line to parse as a shell line. | |
* Returns: An array such that: | |
* 'foo --bar baz\ foo "/bar/foo man/quux"' → ['foo', '--bar', 'baz foo', '/bar/foo man/quux'] | |
* Caveat: no error handling. Depends on /usr/bin/python3 being python. It's horrible. | |
*/ | |
function hack_shlex($str) { | |
// Set up file descriptors for the python program | |
$dspec = [ | |
0 => ['pipe', 'r'], | |
1 => ['pipe', 'w'], | |
2 => ['file', '/dev/null', 'a'] | |
]; | |
// Opens Python, it runs the following program: | |
// | |
// from shlex import split | |
// from json import dumps | |
// print(dumps(split(input()))) | |
// | |
// It does exactly 4 things: | |
// 1. Reads a line from the standard input | |
// 2. Uses the Python shlex module to parse the line into shell arguments | |
// 3. Encodes the resulting array of strings into JSON | |
// 4. Prints that JSON to stdout, to be read from the PHP side. | |
$ph = proc_open("/usr/bin/python3 -c 'from shlex import split; from json import dumps; print(dumps(split(input())));'", $dspec, $pipes); | |
// Writes the string to lex to the python program | |
fwrite($pipes[0], $str); | |
// Close the write stream as we've written what we needed | |
fclose($pipes[0]); | |
// Read the result from the Python program | |
$result = stream_get_contents($pipes[1]); | |
// No need for this now | |
fclose($pipes[1]); | |
// Python's done its job now | |
proc_close($ph); | |
// Decode json and return the parsed shell line | |
return json_decode(trim($result)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment