SHOW COLUMNS. In that case decode_list_json would be the most appropiate since, generally, elements from an enum and a set do not contain quotes.

" /> SHOW COLUMNS. In that case decode_list_json would be the most appropiate since, generally, elements from an enum and a set do not contain quotes.

" />

PHP: Unpacking a string with a list of substrings

PHP: Desempaquetar una cadena con un listado de subcadenas

13 Aug 2010

This can be useful for example to extract the elements from an enum in PHP using a SHOW COLUMNS. In that case decode_list_json would be the most appropiate since, generally, elements from an enum and a set do not contain quotes.

// Slow but safe and without side-effects.  
function decode_list_preg($list_string) {  
    preg_match_all("@(?:,|^)('|\")((?:\\\\'|\\\\\\\\|[^'])*)\\1@Umsi", $list_string, $matches);  
    return array_map('stripslashes', $matches[2]);  
}  
// Fast but unsafe with the possibility of code injection with an invalid input.  
function decode_list_eval($list_string) {  
    eval('$list = array(' . $list_string . ');');  
    return $list;  
}  
// Fast but with side-effects: it changes single quotes with double quotes so it is a valid JSON.  
function decode_list_json($list_string) {  
    return json_decode('[' . str_replace("'", '"', $list_string) . ']');  
}  
// Slow and safe using PHP's tokenizer.  
function decode_list_php($list_string) {  
    $tokens = array_slice(token_get_all('<?php ' . $list_string), 1);  
    $expect_comma = false;  
    $list = array();  
    //print_r($tokens);  
    foreach ($tokens as $token) {  
        if (!is_array($token)) $token = array(0, $token, -1);  
        if ($expect_comma) {  
            if ($token[1] !== ',') throw(new Exception("Invalid input (" . token_name($token[0]) . ")"));  
        } else {  
            if ($token[0] !== T_CONSTANT_ENCAPSED_STRING) throw(new Exception("Invalid input (" . token_name($token[0]) . ")"));  
            $list[] = stripslashes(substr($token[1], 1, -1));  
        }  
        $expect_comma = !$expect_comma;  
    }  
    return $list;  
}  
function util_rand_string($len) {  
    $str = '';  
    while ($len-- > 0) $str .= chr(mt_rand(0x20, 0x7e));  
    return $str;  
}  

$str_list = array();  
for ($n = 0, $len = mt_rand(1000, 2000); $n < $len; $n++) $str_list[] = var_export(util_rand_string(mt_rand(40, 80)), true);  
$list_string = implode(',', $str_list);  

//echo $list_string; exit;  

//$list_string = "'ho\'la',\"esto\",'es','una','prueba'";  

//print_r(decode_list_preg($list_string));  
//print_r(decode_list_eval($list_string));  
//print_r(decode_list_json($list_string));  
print_r(decode_list_php($list_string));  

Spanish

Esto puede ser útil por ejemplo para extraer los elementos de un enum en PHP usando un SHOW COLUMNS. En ese caso el decode_list_json podría ser el más apropiado ya que, generalmente, los elementos de un enum o un set no contendrán comillas.

// Lenta pero segura y sin efectos colaterales (en principio).  
function decode_list_preg($list_string) {  
    preg_match_all("@(?:,|^)('|\")((?:\\\\'|\\\\\\\\|[^'])*)\\1@Umsi", $list_string, $matches);  
    return array_map('stripslashes', $matches[2]);  
}  
// Rápida pero insegura con posibilidad de inyección de código con una entrada inválida.  
function decode_list_eval($list_string) {  
    eval('$list = array(' . $list_string . ');');  
    return $list;  
}  
// Rápida pero con efectos colaterales: cambia comillas simples por dobles para que sea un json válido.  
function decode_list_json($list_string) {  
    return json_decode('[' . str_replace("'", '"', $list_string) . ']');  
}  
// Lenta y segura usando el tokenizer de php.  
function decode_list_php($list_string) {  
    $tokens = array_slice(token_get_all('<?php ' . $list_string), 1);  
    $expect_comma = false;  
    $list = array();  
    //print_r($tokens);  
    foreach ($tokens as $token) {  
        if (!is_array($token)) $token = array(0, $token, -1);  
        if ($expect_comma) {  
            if ($token[1] !== ',') throw(new Exception("Invalid input (" . token_name($token[0]) . ")"));  
        } else {  
            if ($token[0] !== T_CONSTANT_ENCAPSED_STRING) throw(new Exception("Invalid input (" . token_name($token[0]) . ")"));  
            $list[] = stripslashes(substr($token[1], 1, -1));  
        }  
        $expect_comma = !$expect_comma;  
    }  
    return $list;  
}  
function util_rand_string($len) {  
    $str = '';  
    while ($len-- > 0) $str .= chr(mt_rand(0x20, 0x7e));  
    return $str;  
}  

$str_list = array();  
for ($n = 0, $len = mt_rand(1000, 2000); $n < $len; $n++) $str_list[] = var_export(util_rand_string(mt_rand(40, 80)), true);  
$list_string = implode(',', $str_list);  

//echo $list_string; exit;  

//$list_string = "'ho\'la',\"esto\",'es','una','prueba'";  

//print_r(decode_list_preg($list_string));  
//print_r(decode_list_eval($list_string));  
//print_r(decode_list_json($list_string));  
print_r(decode_list_php($list_string));