我会解析以下字符串:
$str = 'ProceduresCustomer.tipi_id=10&ProceduresCustomer.id=1';
parse_str($str,$f);
我希望将$ f解析为:
array(
'ProceduresCustomer.tipi_id' => '10',
'ProceduresCustomer.id' => '1'
)
实际上,parse_str
会返回
array(
'ProceduresCustomer_tipi_id' => '10',
'ProceduresCustomer_id' => '1'
)
除了编写我自己的函数之外,还有人知道是否有php函数吗?
答案 0 :(得分:8)
来自PHP Manual:
变量名中的点和空格将转换为下划线。例如,
<input name="a.b" />
变为$_REQUEST["a_b"]
。
所以,这是不可能的。 parse_str()
会将所有期间转换为下划线。如果您确实无法避免在查询变量名中使用句点,则必须编写自定义函数来实现此目的。
以下函数(取自this answer)将查询字符串中每个键值对的名称转换为相应的十六进制形式,然后对其执行parse_str()
。然后,他们又恢复原状。这样,不会触及期间:
function parse_qs($data)
{
$data = preg_replace_callback('/(?:^|(?<=&))[^=[]+/', function($match) {
return bin2hex(urldecode($match[0]));
}, $data);
parse_str($data, $values);
return array_combine(array_map('hex2bin', array_keys($values)), $values);
}
使用示例:
$data = parse_qs($_SERVER['QUERY_STRING']);
答案 1 :(得分:2)
快点'肮脏。
$str = "ProceduresCustomer.tipi_id=10&ProceduresCustomer.id=1";
function my_func($str){
$expl = explode("&", $str);
foreach($expl as $r){
$tmp = explode("=", $r);
$out[$tmp[0]] = $tmp[1];
}
return $out;
}
var_dump(my_func($str));
array(2) {
["ProceduresCustomer.tipi_id"]=> string(2) "10"
["ProceduresCustomer.id"]=>string(1) "1"
}
答案 2 :(得分:0)
这个快速生成的函数尝试正确解析查询字符串并返回一个数组。
第二个(可选)参数$break_dots
告诉解析器在遇到点时创建一个子数组(这超出了问题范围,但无论如何我都包含它)。
/**
* parse_name -- Parses a string and returns an array of the key path
* if the string is malformed, only return the original string as a key
*
* $str The string to parse
* $break_dot Whether or not to break on dots (default: false)
*
* Examples :
* + parse_name("var[hello][world]") = array("var", "hello", "world")
* + parse_name("var[hello[world]]") = array("var[hello[world]]") // Malformed
* + parse_name("var.hello.world", true) = array("var", "hello", "world")
* + parse_name("var.hello.world") = array("var.hello.world")
* + parse_name("var[hello][world") = array("var[hello][world") // Malformed
*/
function parse_name ($str, $break_dot = false) {
// Output array
$out = array();
// Name buffer
$buf = '';
// Array counter
$acount = 0;
// Whether or not was a closing bracket, in order to avoid empty indexes
$lastbroke = false;
// Loop on chars
foreach (str_split($str) as $c) {
switch ($c) {
// Encountering '[' flushes the buffer to $out and increments the
// array counter
case '[':
if ($acount == 0) {
if (!$lastbroke) $out[] = $buf;
$buf = "";
$acount++;
$lastbroke = false;
// In this case, the name is malformed. Return it as-is
} else return array($str);
break;
// Encountering ']' flushes rge buffer to $out and decrements the
// array counter
case ']':
if ($acount == 1) {
if (!$lastbroke) $out[] = $buf;
$buf = '';
$acount--;
$lastbroke = true;
// In this case, the name is malformed. Return it as-is
} else return array($str);
break;
// If $break_dot is set to true, flush the buffer to $out.
// Otherwise, treat it as a normal char.
case '.':
if ($break_dot) {
if (!$lastbroke) $out[] = $buf;
$buf = '';
$lastbroke = false;
break;
}
// Add every other char to the buffer
default:
$buf .= $c;
$lastbroke = false;
}
}
// If the counter isn't back to 0 then the string is malformed. Return it as-is
if ($acount > 0) return array($str);
// Otherwise, flush the buffer to $out and return it.
if (!$lastbroke) $out[] = $buf;
return $out;
}
/**
* decode_qstr -- Take a query string and decode it to an array
*
* $str The query string
* $break_dot Whether or not to break field names on dots (default: false)
*/
function decode_qstr ($str, $break_dots = false) {
$out = array();
// '&' is the field separator
$a = explode('&', $str);
// For each field=value pair:
foreach ($a as $param) {
// Break on the first equal sign.
$param = explode('=', $param, 2);
// Parse the field name
$key = parse_name($param[0], $break_dots);
// This piece of code creates the array structure according to th
// decomposition given by parse_name()
$array = &$out; // Reference to the last object. Starts to $out
$append = false; // If an empty key is given, treat it like $array[] = 'value'
foreach ($key as $k) {
// If the current ref isn't an array, make it one
if (!is_array($array)) $array = array();
// If the current key is empty, break the loop and append to current ref
if (empty($k)) {
$append = true;
break;
}
// If the key isn't set, set it :)
if (!isset($array[$k])) $array[$k] = NULL;
// In order to walk down the array, we need to first save the ref in
// $array to $tmp
$tmp = &$array;
// Deletes the ref from $array
unset($array);
// Create a new ref to the next item
$array =& $tmp[$k];
// Delete the save
unset($tmp);
}
// If instructed to append, do that
if ($append) $array[] = $param[1];
// Otherwise, just set the value
else $array = $param[1];
// Destroy the ref for good
unset($array);
}
// Return the result
return $out;
}
我试图正确处理多级密钥。代码有点hacky,但它应该工作。我试图评论代码,如果你有任何问题请评论。
测试用例:
var_dump(decode_qstr("ProceduresCustomer.tipi_id=10&ProceduresCustomer.id=1"));
// array(2) {
// ["ProceduresCustomer.tipi_id"]=>
// string(2) "10"
// ["ProceduresCustomer.id"]=>
// string(1) "1"
// }
var_dump(decode_qstr("ProceduresCustomer.tipi_id=10&ProceduresCustomer.id=1", true));
// array(1) {
// ["ProceduresCustomer"]=>
// array(2) {
// ["tipi_id"]=>
// string(2) "10"
// ["id"]=>
// string(1) "1"
// }
// }