как построить правильный foreach () - PullRequest
1 голос
/ 16 марта 2019

ребята при запуске я должен заметить ... я вообще нуб:)

я пытаюсь запустить скрипт на локальной машине 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 голосов
/ 16 марта 2019

Ваша проблема четко обозначена в полученном вами сообщении об ошибке.Когда вы вызываете 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 .... butНикогда не проверяйте, рискуете ли вы передать необоснованную переменную.

Так что вы можете сделать?либо объявите переменную $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, хотя я понимаю, что это может быть вне вашего контроля

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...