如何构造一个合适的foreach()

时间:2019-03-16 17:36:40

标签: pdo foreach

一开始我必须注意到...我是一个菜鸟:)

我尝试在本地Windows计算机(IIS,PHP 5.2,MSSQL)上运行脚本,但出现错误:

PHP Notice:  Undefined variable: table in C:\Inetpub\wwwroot\XX.php on line 38
PHP Warning:  Invalid argument supplied for foreach() in C:\Inetpub\wwwroot\XX.php on line 12

脚本:

<?php
$user = 'xx';
$pass = 'xx';
$host = '10.0.2.15';
$dbname = 'Game3G';
try{
$dbh = new PDO ("mssql:host=$host;dbname=$dbname", "$user", "$pass");
$n=0;  
function sorting($next,$table) {
$temp=0;

foreach($table as $entry) if($entry['position']==0) if($entry['level']>=$temp['level'] && $entry['exp']>=$temp['exp']) $temp=$entry;
if($temp) {
$table[$temp['id']]['position']=$next;
echo '<tr>
     <td width="20px" style="font-size: 10px;">'.$next.'</td><td width="80px" style="font-size: 10px;">'.$temp['character'].'</td><td style="font-size: 10px;">'.$temp['level'].'</td> <td  width="30px" style="font-size: 10px; text-align: right;">'.$temp['exp'].'%</td>
     </tr>
   ';
sorting($next+1,$table);
}
}


echo '<br> <table width="170"  border=0  >';
$i=0;
foreach ($dbh->query('SELECT TBL_CHARACTER.FLD_LEVEL, TBL_CHARACTER.FLD_jOB, TBL_CHARACTER.FLD_CHARACTER, TBL_ABILITY.FLD_MAXEXP, TBL_ABILITY.FLD_EXP from TBL_CHARACTER LEFT JOIN TBL_ABILITY ON(TBL_CHARACTER.FLD_CHARACTER = TBL_ABILITY.FLD_CHARACTER) where TBL_CHARACTER.FLD_LEVEL < 69 and TBL_CHARACTER.FLD_jOB = 2 and TBL_CHARACTER.FLD_DELETED = 0 order by TBL_ABILITY.FLD_EXP + TBL_ABILITY.FLD_LEVEL * TBL_ABILITY.FLD_MAXEXP desc') as $row)
{
$i++;
$table[$i-1]['level']=$row['FLD_LEVEL'];
$table[$i-1]['character']=$row['FLD_CHARACTER'];
$table[$i-1]['exp']=round(($row['FLD_EXP']/$row['FLD_MAXEXP'])*100);
$table[$i-1]['id']=$i-1;
$table[$i-1]['position']=0;

$n++;
 if($n>=10) break;
};
sorting(1,$table);
echo '</table><br>';
$dbh = null;    
 }
 catch(PDOException $e){
     echo 'Statystyki niedostępne.';
 }  
/*end*/            
?>

脚本应生成带有角色统计信息的表格(游戏服务器)。我确定它可以在其他机器上工作,最好是不同的php版本。 你们中有人可以为php v5.2.1调整此代码吗?

THX

1 个答案:

答案 0 :(得分:0)

您收到的错误消息中清楚地突出显示了您的问题。当您调用sorting(1,$table);时,尚未定义变量$ table(如错误消息所示,这是第38行),因此,当您的函数尝试运行第12行时:foreach($table as $entry) for循环失败因为for循环只需要一个数组,而您要它进行循环的是一个未设置或空值。

但是我在另一个循环中设置了$table变量,听说您说过!好吧,您可以尝试,但是正如PHPStorm有用地强调:enter image description here

因为您假设查询已成功运行,并且在这里还返回了至少一行:foreach ($dbh->query('SELECT TBL_CHARACTER.FLD_LEVEL, TBL_C ....但从不检查是否存在传递未实例化变量的风险。

那你该怎么办?在您尝试向其中添加任何内容之前,请在任何地方声明您的$table变量,以便始终至少是一个有效的结果。

更明智的是,尽管我会将您的查询从foreach中取出,并将结果存储在某个地方,然后您可以检查是否有任何数据,如果没有任何数据,则可以适当地处理这种情况。

$result = $dbh->query('SELECT TBL_CHARACTER.FLD_LEVEL, TBL_CHARAC....fetchAll()....

then say 
if(sizeof($result) > 0) {

     foreach($result as $row){
     \\\do all your stuff here
     }
} else {
      //output something useful 
}

您的代码中似乎还有其他一些异常之处

$i++;
$table[$i-1]['level']=$row['FLD_LEVEL'];

为什么要递增$ i,然后每次减去1?仅在最后增加增量是否更有意义?但是无论如何,如果您可以这样做,则根本不需要进行增量操作:

$array = ['level' =>$row['FLD_LEVEL'],['character' => $row['FLD_CHARACTER'] ....];

 $table[] = $array;

,然后它将自动正确索引。进行此增量的唯一原因是,如果您需要在项目上指定索引,但我看不到您正在这样做

我也看不到使用它的任何要点:

$n++;
if($n>=10) break;

您要递增$ i而您要递增$ n它们都是相同的值,所以只需选择其中之一,或者不作任何增加就说(假设结果在索引数组中,并且不获取密钥或其他任何内容)

foreach($result as $key => $row){

  if($key > 9) break;//because it starts at zero, key 9 = 10 iterations, so > 9 is our limit
  //sensibly building your array

}

简而言之,我不认为这与PHP版本有关。但是无论如何,您应该升级到php7,尽管我知道这可能超出您的控制范围