更新 PHP 后功能损坏
function broke after updating PHP
我的一个功能有点问题,它似乎在新 php 版本中不能完全工作,我收到了
Notice: String offset cast occurred in D:\xampp\htdocs\decode\bencoded.php on line 266
Notice: String offset cast occurred in D:\xampp\htdocs\decode\bencoded.php on line 270
这是我的函数:
function bdecode($s, &$pos=0) {
if($pos>=strlen($s)) {
return null;
}
switch($s[$pos]){
case 'd':
$pos++;
$retval=array();
while ($s[$pos]!='e'){
$key=bdecode($s, $pos);
$val=bdecode($s, $pos);
if ($key===null || $val===null)
break;
$retval[$key]=$val;
}
$retval["isDct"]=true;
$pos++;
return $retval;
case 'l':
$pos++;
$retval=array();
while ($s[$pos]!='e'){
$val=bdecode($s, $pos);
if ($val===null)
break;
$retval[]=$val;
}
$pos++;
return $retval;
case 'i':
$pos++;
$digits=strpos($s, 'e', $pos)-$pos;
// Proger_XP: changed (int) -> (float) to avoid trimming of values exceeding
// signed int's max value (2147483647).
$val=(float)substr($s, $pos, $digits);
$pos+=$digits+1;
return $val;
// case "0": case "1": case "2": case "3": case "4":
// case "5": case "6": case "7": case "8": case "9":
default:
$digits=strpos($s, ':', $pos)-$pos;
if ($digits<0 || $digits >20)
return null;
$len=(float)substr($s, $pos, $digits);
$pos+=$digits+1;
$str=substr($s, $pos, $len);
$pos+=$len;
//echo "pos: $pos str: [$str] len: $len digits: $digits\n";
return (string)$str;
}
return null;
}
我知道我在新 php 中收到警告,但我不知道如何解决它。
第 266 行(在 case 'd' 之前):switch($s[$pos]){
第 270 行(在案例“1”之后):while ($s[$pos]!='e'){
我认为解决这个问题的最简单方法应该是使用以下代码禁用通知:
// Report all errors except E_NOTICE
error_reporting(E_ALL ^ E_NOTICE);
如果您确定代码总是 returns 正确的结果并且通知无关紧要,您可能想要这样做。
为什么显示通知?
据我所知,显示通知是因为您尝试访问字符串偏移量而不是整数,而是浮点值。
代码的关键行是:
$len=(float)substr($s, $pos, $digits);
$pos+=$digits+1;
$str=substr($s, $pos, $len);
$pos+=$len;
$len
转换为浮动并添加到 $pos
。这样做的结果是 $pos
被转换为 float 。没问题。但是如果您稍后使用 $pos
访问字符串的偏移量,您会收到通知,因为它不再是整数:
//line 266 (before case 'd'):
switch($s[$pos]){
//line 270 (after case '1'):
while ($s[$pos]!='e'){
也许您想通过像这样将 $pos
转换为 int explecit 来解决它:
//line 266 (before case 'd'):
switch($s[(int)$pos]){
//line 270 (after case '1'):
while ($s[(int)$pos]!='e'){
你的函数的结果应该是一样的,通知应该已经消失了。
我的一个功能有点问题,它似乎在新 php 版本中不能完全工作,我收到了
Notice: String offset cast occurred in D:\xampp\htdocs\decode\bencoded.php on line 266
Notice: String offset cast occurred in D:\xampp\htdocs\decode\bencoded.php on line 270
这是我的函数:
function bdecode($s, &$pos=0) {
if($pos>=strlen($s)) {
return null;
}
switch($s[$pos]){
case 'd':
$pos++;
$retval=array();
while ($s[$pos]!='e'){
$key=bdecode($s, $pos);
$val=bdecode($s, $pos);
if ($key===null || $val===null)
break;
$retval[$key]=$val;
}
$retval["isDct"]=true;
$pos++;
return $retval;
case 'l':
$pos++;
$retval=array();
while ($s[$pos]!='e'){
$val=bdecode($s, $pos);
if ($val===null)
break;
$retval[]=$val;
}
$pos++;
return $retval;
case 'i':
$pos++;
$digits=strpos($s, 'e', $pos)-$pos;
// Proger_XP: changed (int) -> (float) to avoid trimming of values exceeding
// signed int's max value (2147483647).
$val=(float)substr($s, $pos, $digits);
$pos+=$digits+1;
return $val;
// case "0": case "1": case "2": case "3": case "4":
// case "5": case "6": case "7": case "8": case "9":
default:
$digits=strpos($s, ':', $pos)-$pos;
if ($digits<0 || $digits >20)
return null;
$len=(float)substr($s, $pos, $digits);
$pos+=$digits+1;
$str=substr($s, $pos, $len);
$pos+=$len;
//echo "pos: $pos str: [$str] len: $len digits: $digits\n";
return (string)$str;
}
return null;
}
我知道我在新 php 中收到警告,但我不知道如何解决它。
第 266 行(在 case 'd' 之前):switch($s[$pos]){
第 270 行(在案例“1”之后):while ($s[$pos]!='e'){
我认为解决这个问题的最简单方法应该是使用以下代码禁用通知:
// Report all errors except E_NOTICE
error_reporting(E_ALL ^ E_NOTICE);
如果您确定代码总是 returns 正确的结果并且通知无关紧要,您可能想要这样做。
为什么显示通知?
据我所知,显示通知是因为您尝试访问字符串偏移量而不是整数,而是浮点值。
代码的关键行是:
$len=(float)substr($s, $pos, $digits);
$pos+=$digits+1;
$str=substr($s, $pos, $len);
$pos+=$len;
$len
转换为浮动并添加到 $pos
。这样做的结果是 $pos
被转换为 float 。没问题。但是如果您稍后使用 $pos
访问字符串的偏移量,您会收到通知,因为它不再是整数:
//line 266 (before case 'd'):
switch($s[$pos]){
//line 270 (after case '1'):
while ($s[$pos]!='e'){
也许您想通过像这样将 $pos
转换为 int explecit 来解决它:
//line 266 (before case 'd'):
switch($s[(int)$pos]){
//line 270 (after case '1'):
while ($s[(int)$pos]!='e'){
你的函数的结果应该是一样的,通知应该已经消失了。