PHP: Unpacking a string with a list of substrings

PHP: Desempaquetar una cadena con un listado de subcadenas

Published at Fri, 13 Aug 2010 00:00:00 UTC by soywiz

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. ```php // 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]); } ``` ```php // 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; } ``` ```php // 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) . ']'); } ``` ```php // Slow and safe using PHP's tokenizer. function decode_list_php($list_string) { $tokens = array_slice(token_get_all(' 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)); ```
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. ```php // 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]); } ``` ```php // 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; } ``` ```php // 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) . ']'); } ``` ```php // Lenta y segura usando el tokenizer de php. function decode_list_php($list_string) { $tokens = array_slice(token_get_all(' 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)); ```