Skip to content

Instantly share code, notes, and snippets.

@SocalNick
Forked from jtai/parser.php
Created March 27, 2012 16:35
Show Gist options
  • Save SocalNick/2217735 to your computer and use it in GitHub Desktop.
Save SocalNick/2217735 to your computer and use it in GitHub Desktop.
Nick's Cache-Control header parser
<?php
function parse($string)
{
$string = trim($string);
$directives = array();
// handle empty string early so we don't need a separate start state
if ($string == '') {
return $directives;
}
$lastMatch = null;
state_directive:
switch (match(array('[a-zA-Z][a-zA-Z_-]*'), $string, $lastMatch)) {
case 0:
$directive = $lastMatch;
goto state_value;
break;
default:
throw new Exception('expected DIRECTIVE');
break;
}
state_value:
switch (match(array('="[^"]*"', '=([^",][^,]*)?'), $string, $lastMatch)) {
case 0:
$directives[$directive] = substr($lastMatch, 2, -1);
goto state_separator;
break;
case 1:
$directives[$directive] = rtrim(substr($lastMatch, 1));
goto state_separator;
break;
default:
$directives[$directive] = true;
goto state_separator;
break;
}
state_separator:
switch (match(array('\s*,\s*', '$'), $string, $lastMatch)) {
case 0:
goto state_directive;
break;
case 1:
return $directives;
break;
default:
throw new Exception('expected SEPARATOR or END');
break;
}
}
function match($tokens, &$string, &$lastMatch)
{
foreach ($tokens as $i => $token) {
if (preg_match('/^'.$token.'/', $string, $matches)) {
$lastMatch = $matches[0];
$string = substr($string, strlen($matches[0]));
return $i;
}
}
return -1;
}
try {
var_dump(parse('no-store& private=test, no-cache="a,b,c"'));
} catch (Exception $e) {
var_dump($e->getMessage());
}
$start = microtime(true);
for ($i=0; $i<10000; $i++) {
parse('no-store, private=test, no-cache="a,b,c"');
}
var_dump(microtime(true) - $start);
@LeMoussel
Copy link

PHP Fatal error: Uncaught Exception: expected SEPARATOR or END when call with parse(' = 31536000')

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