PHP Conference Japan 2024

parse_str

(PHP 4, PHP 5, PHP 7, PHP 8)

parse_str将字符串解析为变量

描述

parse_str(string $string, array &$result): void

string解析为通过 URL 传递的查询字符串,并在当前作用域(如果提供了result,则在数组中)设置变量。

参数

string

输入字符串。

result

如果存在第二个参数result,则变量将作为数组元素存储在此变量中。

警告

从 PHP 7.2 开始,强烈不建议已弃用在没有result参数的情况下使用此函数。从 PHP 8.0.0 开始,result参数是必需的

返回值

不返回任何值。

变更日志

版本 描述
8.0.0 result不再是可选的。
7.2.0 在没有第二个参数的情况下使用parse_str()现在会发出E_DEPRECATED通知。

示例

示例 #1 使用parse_str()

<?php
$str
= "first=value&arr[]=foo+bar&arr[]=baz";

// 建议使用
parse_str($str, $output);
echo
$output['first']; // value
echo $output['arr'][0]; // foo bar
echo $output['arr'][1]; // baz

// 不推荐使用
parse_str($str);
echo
$first; // value
echo $arr[0]; // foo bar
echo $arr[1]; // baz
?>

因为 PHP 中的变量名称不能包含点和空格,所以它们会被转换为下划线。如果使用此函数并带有result参数,则相应的键名也适用相同规则。

示例 #2 parse_str() 名称处理

<?php
parse_str
("My Value=Something");
echo
$My_Value; // Something

parse_str("My Value=Something", $output);
echo
$output['My_Value']; // Something
?>

注释

注意:

所有创建的变量(如果设置了第二个参数,则返回到数组中的值)都已经经过urldecode()解码。

注意:

要获取当前的QUERY_STRING,可以使用变量$_SERVER['QUERY_STRING']。此外,您可能需要阅读关于来自外部来源的变量的部分。

参见

添加注释

用户贡献的注释 31 条注释

121
Evan K
17 年前
值得一提的是,在处理重复字段时,parse_str 内置函数不会以 CGI 标准的方式处理查询字符串。如果查询字符串中存在多个同名的字段,其他任何 Web 处理语言都会将它们读入数组,但 PHP 会默默地覆盖它们。

<?php
# 默默地无法处理多个值
parse_str('foo=1&foo=2&foo=3');

# 以上代码产生:
$foo = array('foo' => '3');
?>

相反,PHP 使用一种不符合标准的做法,在字段名中包含方括号来达到相同的效果。

<?php
# PHP 特有的奇怪行为
parse_str('foo[]=1&foo[]=2&foo[]=3');

# 以上代码产生:
$foo = array('foo' => array('1', '2', '3') );
?>

对于任何习惯使用 CGI 标准的人来说,这可能会令人困惑,所以请记住这一点。作为替代方案,我使用“正确的”查询字符串解析函数。

<?php
function proper_parse_str($str) {
# 结果数组
$arr = array();

# 按外部分隔符分割
$pairs = explode('&', $str);

# 循环处理每一对键值对
foreach ($pairs as $i) {
# 分割名称和值
list($name,$value) = explode('=', $i, 2);

# 如果名称已存在
if( isset($arr[$name]) ) {
# 将多个值放入数组中
if( is_array($arr[$name]) ) {
$arr[$name][] = $value;
}
else {
$arr[$name] = array($arr[$name], $value);
}
}
# 否则,直接放入标量值
else {
$arr[$name] = $value;
}
}

# 返回结果数组
return $arr;
}

$query = proper_parse_str($_SERVER['QUERY_STRING']);
?>
6
Roemer Lievaart
2年前
如果您需要保留键名,并且不希望空格、点或不匹配的“[”或“]”被下划线替换,但又想要`parse_str()`的其他所有优点,例如将匹配的“[]”转换为数组元素,您可以使用此代码作为基础。

<?php
const periodPlaceholder = 'QQleQPunT';
const
spacePlaceholder = 'QQleQSpaTIE';

function
parse_str_clean($querystr): array {
// 不转换空格和点等为下划线。
$qquerystr = str_ireplace(['.','%2E','+',' ','%20'], [periodPlaceholder,periodPlaceholder,spacePlaceholder,spacePlaceholder,spacePlaceholder], $querystr);
$arr = null ; parse_str($qquerystr, $arr);

sanitizeKeys($arr, $querystr);
return
$arr;
}

function
sanitizeKeys(&$arr, $querystr) {
foreach(
$arr as $key=>$val) {
// 将值恢复为原始值
$newval = $val ;
if (
is_string($val)) {
$newval = str_replace([periodPlaceholder,spacePlaceholder], ["."," "], $val);
}

$newkey = str_replace([periodPlaceholder,spacePlaceholder], ["."," "], $key);

if (
str_contains($newkey, '_') ) {

// 点或空格或“[”或“]”转换为下划线。使用查询字符串恢复。
$regex = '/&('.str_replace('_', '[ \.\[\]]', preg_quote($newkey, '/')).')=/';
$matches = null ;
if (
preg_match_all($regex, "&".urldecode($querystr), $matches) ) {

if (
count(array_unique($matches[1])) === 1 && $key != $matches[1][0] ) {
$newkey = $matches[1][0] ;
}
}
}
if (
$newkey != $key ) {
unset(
$arr[$key]);
$arr[$newkey] = $newval ;
} elseif(
$val != $newval )
$arr[$key] = $newval;

if (
is_array($val)) {
sanitizeKeys($arr[$newkey], $querystr);
}
}
}

?>

例如

parse_str_clean("code.1=printr%28hahaha&code 1=448044&test.mijn%5B%5D%5B2%5D=test%20Roemer&test%5Bmijn=test%202e%20Roemer");

输出

array(4) {
["code.1"]=>
string(13) "printr(hahaha"
["code 1"]=>
string(6) "448044"
["test.mijn"]=>
array(1) {
[0]=>
array(1) {
[2]=>
string(11) "test Roemer"
}
}
["test[mijn"]=>
string(14) "test 2e Roemer"
}

而如果您将相同的查询字符串提供给`parse_str`,您将得到

array(2) {
["code_1"]=>
string(6) "448044"
["test_mijn"]=>
string(14) "test 2e Roemer"
}
35
shagshag
12年前
描述中没有说明,但`max_input_vars`指令会影响此函数。如果字符串中的输入变量多于此指令指定的数量,则会发出E_WARNING警告,并且请求中的其他输入变量将被截断。
16
zweibieren at yahoo dot com
9年前
如果提供了`arr`参数,则会移除其所有现有元素。
17
alxcube at gmail dot com
8年前
如果您需要自定义参数分隔符,可以使用此函数。它将解析后的查询作为关联数组返回。

<?php

/**
* 将HTTP查询字符串解析为数组
*
* @author Alxcube <[email protected]>
*
* @param string $queryString 要解析的字符串
* @param string $argSeparator 查询参数分隔符
* @param integer $decType 解码类型
* @return array
*/
function http_parse_query($queryString, $argSeparator = '&', $decType = PHP_QUERY_RFC1738) {
$result = array();
$parts = explode($argSeparator, $queryString);

foreach (
$parts as $part) {
list(
$paramName, $paramValue) = explode('=', $part, 2);

switch (
$decType) {
case
PHP_QUERY_RFC3986:
$paramName = rawurldecode($paramName);
$paramValue = rawurldecode($paramValue);
break;

case
PHP_QUERY_RFC1738:
default:
$paramName = urldecode($paramName);
$paramValue = urldecode($paramValue);
break;
}


if (
preg_match_all('/\[([^\]]*)\]/m', $paramName, $matches)) {
$paramName = substr($paramName, 0, strpos($paramName, '['));
$keys = array_merge(array($paramName), $matches[1]);
} else {
$keys = array($paramName);
}

$target = &$result;

foreach (
$keys as $index) {
if (
$index === '') {
if (isset(
$target)) {
if (
is_array($target)) {
$intKeys = array_filter(array_keys($target), 'is_int');
$index = count($intKeys) ? max($intKeys)+1 : 0;
} else {
$target = array($target);
$index = 1;
}
} else {
$target = array();
$index = 0;
}
} elseif (isset(
$target[$index]) && !is_array($target[$index])) {
$target[$index] = array($target[$index]);
}

$target = &$target[$index];
}

if (
is_array($target)) {
$target[] = $paramValue;
} else {
$target = $paramValue;
}
}

return
$result;
}

?>
2
[email protected]
17 年前
这可能比下面的解决方案更好。第一行确保文件不存在,然后第二行将所有请求定向到一个脚本。这种方法也不需要输出200头。

RewriteEngine On

RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [L]
5
[email protected]
19年前
您可能需要将查询字符串解析为数组。

<?php
/**
* 功能类似于 parse_str。如果查询字符串或URL为空,则返回false。因为我们不是解析到
* 变量而是数组键值对,所以此函数将能“正确”处理 ?[]=1&[]=2。
*
* @return array 类似于PHP自动生成的 $_GET 格式。
* @param string $url 查询字符串或URL
* @param boolean $qmark 查找并去除字符串中问号之前的全部内容
*/
function parse_query_string($url, $qmark=true)
{
if (
$qmark) {
$pos = strpos($url, "?");
if (
$pos !== false) {
$url = substr($url, $pos + 1);
}
}
if (empty(
$url))
return
false;
$tokens = explode("&", $url);
$urlVars = array();
foreach (
$tokens as $token) {
$value = string_pair($token, "=", "");
if (
preg_match('/^([^\[]*)(\[.*\])$/', $token, $matches)) {
parse_query_string_array($urlVars, $matches[1], $matches[2], $value);
} else {
$urlVars[urldecode($token)] = urldecode($value);
}
}
return
$urlVars;
}

/**
* parse_query_string 的辅助函数。给定一个结果数组、一个起始键和一组类似于“[a][b][c]”的键
* 以及最终值,使用正确的PHP数组键更新结果数组。
*
* @return void
* @param array $result 用于从查询字符串填充的结果数组
* @param string $k 要在 $result 中填充的起始键
* @param string $arrayKeys 要解析的键列表,格式为 "[][a][what%20ever]"
* @param string $value 要放置在目标数组键的值
*/
function parse_query_string_array(&$result, $k, $arrayKeys, $value)
{
if (!
preg_match_all('/\[([^\]]*)\]/', $arrayKeys, $matches))
return
$value;
if (!isset(
$result[$k])) {
$result[urldecode($k)] = array();
}
$temp =& $result[$k];
$last = urldecode(array_pop($matches[1]));
foreach (
$matches[1] as $k) {
$k = urldecode($k);
if (
$k === "") {
$temp[] = array();
$temp =& $temp[count($temp)-1];
} else if (!isset(
$temp[$k])) {
$temp[$k] = array();
$temp =& $temp[$k];
}
}
if (
$last === "") {
$temp[] = $value;
} else {
$temp[urldecode($last)] = $value;
}
}

/**
* 将字符串分解成一对,用于通用解析函数。
*
* 如果存在任何字符串对,则传入的字符串将被截断为字符串对的左半部分,如果存在任何右半部分,则返回。
*
* 使用示例:
* <code>
* $path = "Account.Balance";
* $field = string_pair($path);
*
* $path 为 "Account"
* $field 为 "Balance"
*
* $path = "Account";
* $field = string_pair($path);
*
* $path 为 "Account"
* $field 为 false
* </code>
*
* @return string 如果找到分隔符,则返回字符串的“右”部分。
* @param string $a 要分解成一对的字符串。如果找到分隔符,则在此返回字符串的“左”部分。
* @param string $delim 用于分隔字符串对的字符
* @param mixed $default 如果在字符串中找不到分隔符,则返回的值
* @desc
*/
function string_pair(&$a, $delim='.', $default=false)
{
$n = strpos($a, $delim);
if (
$n === false)
return
$default;
$result = substr($a, $n+strlen($delim));
$a = substr($a, 0, $n);
return
$result;
}

?>
13
Olivier Mengué
18年前
Vladimir:此函数在处理 &amp; 方面没问题。
&amp; 仅应在 HTML/XML 数据中输出 URL 时使用。
你应该问问自己,为什么在将 URL 传递给 parse_str 时,URL 中会有 &amp;。
8
Tore Bj?lseth
19年前
从 PHP 5 开始,你可以使用 http_build_query() 做完全相反的操作。只需记住使用可选的数组输出参数。

如果你想重新使用搜索字符串 URL,但又想稍微修改它,这是一个非常有用的组合。

示例
<?
$url1 = "action=search&interest[]=sports&interest[]=music&sort=id";
$str = parse_str($url1, $output);

// 修改条件
$output['sort'] = "interest";

$url2 = http_build_query($output);

echo "<br>url1: ".$url1;
echo "<br>url2: ".$url2;
?>

结果为
url1: action=search&interest[]=sports&interest[]=music&sort=id
url2: action=search&interest[0]=sports&interest[1]=music&sort=interest

(数组索引会自动创建。)
4
tobsn at php dot net
16年前
关于上面示例的一个提示
?var[]=123 - [] 必须进行 URL 编码。
变量名和变量值 - 都必须进行 URL 编码!
3
avi at amarcus dot com
19年前
如果你尝试保留一个复杂的数组,则序列化函数可能比 http_build_query 或其他创建查询字符串的方法更好。
4
helpmepro1 at gmail dot com
16年前
<?
// 作者:shimon doodkin

$url_form=url_to_form($url);
echo '<form action="'.$url_form['action'].'" method="get">';
echo $url_form['hidden'];
echo '<input name="otherfiled" type="text">';
echo '<input type="submit">';
echo '</form>';

function url_to_form($url)
{
$url=split('\?',$url,2);
$action=$url[0];
$hidden="";
if(isset($url[1]))
{
$pairs=split('&',$url[1]);
foreach($pairs as $pair)
{
$pair=split('=',$pair,2);
$name=$pair[0];
if(isset($pair[1]))
$value=$pair[1];
else
$value='';
$name=$name;
$value=htmlspecialchars($value);
if($name!='')
$hidden.='<hidden name="'.$name.'" value="'.$value.'">';
}
}
return array('action'=>$action,'hidden'=>$hidden);
}

?>
2
jgbreezer at gmail dot com
17 年前
Vladimir Kornea 于 2006年9月8日撰写
“此函数被编码为HTML实体(&amp;)的与号 (&) 弄混了”

嗯,确实会这样 - 它不应该传递HTML实体,那是不同的编码方案。不过,此函数确实可以正确地为您解码URL编码的参数(使用rawurlencode而不是urlencode,即'+'被转换为空格)。
5
jrgns at jadeit dot co dot za
12年前
无需在调用函数之前定义要填充的数组。

<?php
error_reporting
(E_ALL | E_STRICT);
parse_str('var=value', $array);
?>

这不会产生通知。
3
PEPE_RIVAS at repixel dot net
18年前
将任何格式化的字符串转换为变量

我使用一个商家开发了一个信用卡在线支付解决方案,这个商家会返回给我交易状态的答案,如下所示:

estado=1,txnid=5555444-8454445-4455554,monto=100.00

为了将所有这些数据放入变量中,这对我来说很好!所以我使用了str_replace(),问题是这个函数使用&字符识别每一组变量……而我用逗号分隔了值……所以我用&替换了逗号。

<?php
$string
= "estado=1,txnid=5555444-8454445-4455554,monto=100.00";
$string = str_replace(",","&",$string);
parse_str($string);
echo
$monto; // 输出 100.00
?>
2
StanE
9年前
请注意,字符“.”和“ ”(空格)将被转换为“_”。字符“[”和“]”具有特殊含义:它们表示数组,但似乎存在一些奇怪的行为,我不太理解。

<?php
// 注意: "[" = %5B, "]" = %5D

/*
"v][=a" 产生 ( "[" 被替换为 "_" ):
Array
(
[v]_] => a
)
*/
parse_str("v%5D%5B=a", $r);
print_r($r);

/*
"v][[=a" 产生 (第一个 "[" 被替换为 "_" ,但后续的不是):
Array
(
[v]_[] => a
)
*/
parse_str("v%5D%5B%5B=a", $r);
print_r($r);

?>
2
mike dot coley at inbox dot com
17 年前
这是一个与parse_str函数相反的小函数。它将接收一个数组并从中构建一个查询字符串。

<?php

/* 将参数数组转换为要附加到URL的查询字符串。
*
* @return string : 要附加到URL的查询字符串。
* @param array $array : 要附加到查询字符串的参数数组。
* @param string $parent : 这应该留空(函数内部使用)。
*/
function append_params($array, $parent='')
{
$params = array();
foreach (
$array as $k => $v)
{
if (
is_array($v))
$params[] = append_params($v, (empty($parent) ? urlencode($k) : $parent . '[' . urlencode($k) . ']'));
else
$params[] = (!empty($parent) ? $parent . '[' . urlencode($k) . ']' : urlencode($k)) . '=' . urlencode($v);
}

$sessid = session_id();
if (!empty(
$parent) || empty($sessid))
return
implode('&', $params);

// 如果需要,将会话ID附加到查询字符串。
$sessname = session_name();
if (
ini_get('session.use_cookies'))
{
if (!
ini_get('session.use_only_cookies') && (!isset($_COOKIE[$sessname]) || ($_COOKIE[$sessname] != $sessid)))
$params[] = $sessname . '=' . urlencode($sessid);
}
elseif (!
ini_get('session.use_only_cookies'))
$params[] = $sessname . '=' . urlencode($sessid);

return
implode('&', $params);
}

?>

请注意,如果需要,该函数还会将会话ID附加到查询字符串。
2
chris at mcfadyen dot ca
17 年前
我不应该发布原始版本,因为它只适用于最基本的查询字符串。

此函数将解析一个HTML安全的类似查询的URL字符串以获取变量和类似PHP的有序和关联数组。它将它们放置到全局作用域中,就像parse_str一样,并为数据库插入添加最少的反斜杠,而不会出现magic quotes可能产生的三重反斜杠问题(我必须编写它的原因)。如果您不需要反斜杠,则很容易将其删除。

<?php
function parse_query($str) {

// 分隔所有名称-值对
$pairs = explode('&', $str);

foreach(
$pairs as $pair) {

// 提取名称和值
list($name, $value) = explode('=', $pair, 2);

// 解码变量名称并查找数组
list($name, $index) = split('[][]', urldecode($name));

// 数组
if(isset($index)) {

// 声明或添加到由 $name 定义的全局数组
global $$name;
if(!isset($
$name)) $$name = array();

// 关联数组
if($index != "") {
${
$name}[$index] = addslashes(urldecode($value));

// 有序数组
} else {
array_push($$name, addslashes(urldecode($value)));
}

// 变量
} else {

// 声明或覆盖由 $name 定义的全局变量
global $$name;
$
$name = addslashes(urldecode($value));
}
}
}
?>
1
chris at mcfadyen dot ca
17 年前
如果您想要一个没有magic quotes的parse_str版本,以下代码可以解决这个问题。

<?php
function parse_query($str) {
$pairs = explode('&', $str);

foreach(
$pairs as $pair) {
list(
$name, $value) = explode('=', $pair, 2);
global $
$name;
$
$name = $value;
}
}
?>
1
mortoray at ecircle-ag dot com
19年前
在Kent的解决方案中,如果您想摆脱将[烦人的]加号'+'转换为空格' '的转换,您可能希望将“urldecode”切换为“rawurldecode”。
0
kawewong at gmail dot com
3年前
警告:`parse_str()`可能会导致“输入变量超过1000”错误(1000是`max_input_vars`的默认php.ini设置)。

测试代码。

<?php

$inputString
= 'first=firstvalue';

for (
$i = 1; $i <= 1100; $i++) {
$inputString .= '&arrLoopNumber[]=' . $i;
}
unset(
$i);

echo
'输入字符串: <code>' . $inputString . '</code><br>' . PHP_EOL;
echo
'<h5>正在执行 <code>parse_str()</code></h5>' . PHP_EOL;

$output = [];
parse_str($inputString, $output);
// 错误!!
?>
1
twiddly
6年前
proper_parse_str 函数运行良好,我喜欢它不会用下划线替换空格,但是应该对 $value 进行 urldecode 解码。
-1
Will Voelcker
14年前
如果您需要一个类似于 parse_str 的函数,但不会将空格和点转换为下划线,请尝试以下方法:

<?php
function parseQueryString($str) {
$op = array();
$pairs = explode("&", $str);
foreach (
$pairs as $pair) {
list(
$k, $v) = array_map("urldecode", explode("=", $pair));
$op[$k] = $v;
}
return
$op;
}
?>

它可能需要调整以处理各种边缘情况。
-1
motin at demomusic dot nu
18年前
当您通过命令行运行脚本(例如通过 cron 在本地运行)时,您可能希望能够使用 _GET 和 _POST 变量。将此代码放在您的计划任务文件的顶部

<?
parse_str ($_SERVER['argv'][1], $GLOBALS['_GET']);
parse_str ($_SERVER['argv'][2], $GLOBALS['_POST']);
?>

并通过以下方式调用您的脚本:

/usr/local/bin/php /path/to/script.php "id=45&action=delete" "formsubmitted=true"

干杯!
-1
Michal Zalewski
17 年前
Vladimir Kornea
尝试使用 html_entity_decode()

$str = 'first=value&amp;arr[]=foo+bar&amp;arr[]=baz';
parse_str(html_entity_decode($str), $output);
print_r($output);

数组
(
[first] => value
[arr] => 数组
(
[0] => foo bar
[1] => baz
)

)
-1
lenix.de
17 年前
如果您希望使用 php/apache 获得一个良好的 URL 方案,并且想要在一个中心 php 脚本中处理所有请求,则有一个简单的解决方案/技巧

在您的“basedir”(您拥有主脚本(在此示例中为 index.php)的位置)中创建一个 .htaccess 文件,其中包含一些类似这样的行:

"ErrorDocument 404 /index.php"

在 index.php 中,您现在可以执行以下操作:

<?php
$virtual_path
= substr(
$_SERVER['REQUEST_URI'],
strlen( dirname( $_SERVER['PHP_SELF'] ) ) + 1
);
if( (
$pos = strpos( $virtual_path, '?' )) !== false ) {
parse_str( substr( $virtual_path, $pos + 1 ), $_GET );
$_REQUEST = array_merge( $_REQUEST, $_GET );
$virtual_path = substr( $virtual_path, 0, $pos );
}

// 检查有效位置的某些代码等...
header( 'HTTP/1.1 200 OK' );
header( 'Content-Type: text/plain' );

echo
$virtual_path."\n\n";
print_r( $_REQUEST );
?>

// guido 'lenix' boehm
-1
kerosuppi
19年前
这不能按预期工作。

<?php
class someclass
{
var
$query_string;
function
someclass($a_query_string)
{
$this->query_string = $a_query_string;
parse_str($this->query_string);
}
function
output()
{
echo
$this->action;
}
}

$a_class = new someclass("action=go");
$a_class->output();
?>

请改用这个。

<?php
class someclass
{
var
$arr;
function
someclass($a_query_string)
{
parse_str($a_query_string, $this->arr);
}
function
output()
{
echo
$this->arr['action'];
}
}

$a_class = new someclass("action=go");
$a_class->output();
?>
-1
markc
11年前
注意在使用引用传递变量的函数中使用 parse_str。似乎 parse_str 实际上会创建新的变量,即使存在相同名称的变量也是如此。如果您通过引用传递与正在解析的查询字符串中相同的名称的变量,则将创建新的局部变量,并且您不会将任何值传递回调用方(与 Maikel 在下面提到的内容相关)。

一个不切实际的示例(与我发现这个问题时正在做的事情大致相关)……

function get_title($query,&$title)
{
parse_str($query);
$title=str_replace("_"," ",$title);
}

$title="foo";
$query = "context=something&title=Title_of_Something";
get_title($query,$title);

echo $title .... "foo"
-3
Vladimir Kornea
17 年前
parse_str() 对作为 HTML 实体 (&amp;) 编码的 & 符号感到困惑。如果您从 HTML 页面(抓取)中提取查询字符串,则这与之相关。解决方案是在通过 parse_str() 运行之前,先通过 html_entity_decode() 运行该字符串。

(编辑者:我的原始评论是一个警告,其解决方案显而易见,但它导致了三个回复(“那又怎样?”、“按预期那样”、“这就是解决方法”)。请删除之前处理此问题的四个帖子(69529、70234、72745、74818),只留下上面的摘要。这个问题太琐碎了,不值得发表这么多的评论。)
-2
anatilmizun at gmail dot com
20年前
我编写了一对使用 parse_str() 的函数,它们将数组中的值写入文本文件,反之亦然,并将这些值从文本文件读回数组。如果您需要存储大量数据但无法访问 SQL,则非常有用。

通过调用 cfg_save($filename,$array) 保存数组,并使用 $array=cfg_load($filename) 加载它。

<?php
$newline
="?";

function
cfg_load($cfgfile){
global
$newline;
$setting="";
if(
file_exists($cfgfile)){
$setting=fopen($cfgfile, "r");
$ookk="";
while(
$ook=fgets($setting)){
//去除注释
$commt=strpos($ook,"##");
if(
$commt!==false) $ook=substr($ook,0,$commt);
//追加
if($ook!="") $ookk=$ookk."&".str_replace($newline,"\n",str_replace("&","%26",trim($ook)));
}
fclose($setting);
parse_str($ookk, $setting);
}
return
$setting;
}

function
cfg_save($cfgfile,$setting){
global
$intArray;
$intArray="";
for(
$i=0;$i<2000;$i++)
$intArray[]=$i;
if(
is_array($setting)){
$allkeys=array_keys($setting);
foreach(
$allkeys as $aKey)
cfg_recurse($setting[$aKey], $aKey, $outArray);
}
$cfgf=fopen($cfgfile,"w");
foreach(
$outArray as $aLine)
fputs($cfgf,stripslashes($aLine)."\r\n");
fclose($cfgf);
}

function
cfg_recurse($stuffIn, $keysofar, &$toAppend){
global
$intArray, $newline;
if(
is_array($stuffIn)){
$allkeys=array_keys($stuffIn);
if(
array_slice($intArray,0,sizeof($allkeys))==$allkeys)
$nokey=true;
else
$nokey=false;
foreach(
$allkeys as $aKey){
if(!
$nokey) $toKey=$aKey;
cfg_recurse($stuffIn[$aKey], $keysofar."[".$toKey."]", $toAppend);
}
}else
$toAppend[]=$keysofar."=".str_replace("\n",$newline,$stuffIn);
}
?>

注意,这些函数支持无限层级的嵌套数组;)
-4
Benjamin Garcia
12年前
类似 parse_str 的函数,但在 $_GET 和 $_POST 中不会将空格和点转换为下划线

/**
* 包含点等字符的 GET 和 POST 输入
*/
function getRealREQUEST() {
$vars = array();

$input = $_SERVER['REDIRECT_QUERY_STRING'];
if(!empty($input)){
$pairs = explode("&", $input);
foreach ($pairs as $pair) {
$nv = explode("=", $pair);

$name = urldecode($nv[0]);
$nameSanitize = preg_replace('/([^\[]*)\[.*$/','$1',$name);

$nameMatched = str_replace('.','_',$nameSanitize);
$nameMatched = str_replace(' ','_',$nameMatched);

$vars[$nameSanitize] = $_REQUEST[$nameMatched];
}
}

$input = file_get_contents("php://input");
if(!empty($input)){
$pairs = explode("&", $input);
foreach ($pairs as $pair) {
$nv = explode("=", $pair);

$name = urldecode($nv[0]);
$nameSanitize = preg_replace('/([^\[]*)\[.*$/','$1',$name);

$nameMatched = str_replace('.','_',$nameSanitize);
$nameMatched = str_replace(' ','_',$nameMatched);

$vars[$nameSanitize] = $_REQUEST[$nameMatched];
}
}

return $vars;
}
To Top