PHP Form $ _POST foreach останавливается после первой итерации - PullRequest
0 голосов
/ 05 ноября 2019

У меня есть приведенный ниже PHP-код, который выбирает опубликованные данные формы из другого файла, выполняет запросы SELECT, чтобы найти все связанные данные из различных таблиц (SalesDB, CustDB и ProdDB), а затем выполняет запрос INSERT INTO, чтобы добавитьстрока в таблице «SalesDB». Форма имеет динамически добавленные строки, что дает каждой новой добавленной строке уникальный идентификатор, например:

...<input type="text" id="prodName_1" name="prodName[]" value="">
...<input type="text" id="prodName_2" name="prodName[]" value="">
.  
.  
...<input type="text" id="prodName_Z" name="prodName[]" value="">

Однако, когда скрипт PHP выполняется, например, для 3 строк строк продукта, он выполняет только $ queryinsertзапрос для первой итерации и вставляет первую строку продукта формы. Почему он не перебирает массив? Смотрите скрипт php ниже:

<?php

$db = new SQLite3('../xxx.db');
if(!$db){
  echo $db->lastErrorMsg();
  exit;
}

if (empty($_POST['custID'])) {
  $errorMSG = array("No customer selected");
  echo json_encode($errorMSG, JSON_PRETTY_PRINT);
  exit;
} else {

  $custID = $_POST['custID'];

  $queryInsert = $db->prepare("INSERT INTO 'SalesDB'
  (SalesID,CustID,ProdID,ProdQty,ProdPrice,ProdCurr,ProdVAT,SalesPrice,SalesVAT,SalesSum)
  VALUES (?,?,?,?,?,?,?,?,?,?)");
  $queryInsert->bindParam(1,$salesID);
  $queryInsert->bindParam(2,$custID);
  $queryInsert->bindParam(3,$prodID);
  $queryInsert->bindParam(4,$prodQty);
  $queryInsert->bindParam(5,$prodPrice);
  $queryInsert->bindParam(6,$prodCurr);
  $queryInsert->bindParam(7,$prodVAT);
  $queryInsert->bindParam(8,$salesPrice);
  $queryInsert->bindParam(9,$salesVAT);
  $queryInsert->bindParam(10,$salesSum);

  $querySalesID = "SELECT MAX(SalesID) AS max_SalesID FROM 'SalesDB'";
  $resultSalesID = $db->query($querySalesID);

  while ($row = $resultSalesID->fetchArray()) {
    $salesID = $row['max_SalesID'] + 1;
  }

  foreach($_POST['prodName'] as $prodName => $value) {
    if (!$value) {
      $errorMSG = array("Empty product fields");
      echo json_encode($errorMSG, JSON_PRETTY_PRINT);
      exit;
    } elseif ($value == "Product not found") {
      $errorMSG = array("Invalid products in order form");
      echo json_encode($errorMSG, JSON_PRETTY_PRINT);
      exit;
    }

    $queryProd = "SELECT * FROM `ProdDB` WHERE ProdName LIKE '%$value%'";
    $resultProd = $db->query($queryProd);

    while ($row = $resultProd->fetchArray()) {
      $prodID = $row['ProdID'];
      $prodPrice = $row['ProdPrice'];
      $prodQty = $row['ProdQty'];
      $prodVAT = $row['ProdVAT'];
      $prodCurr = $row['ProdCurr'];
      $salesPrice = $prodQty * $prodPrice;
      $salesVAT = number_format($prodQty * $prodPrice * $prodVAT,2);
      $salesSum = $salesPrice + $salesVAT;
    }
    $result = $queryInsert->execute();
  }
}
?>

Обратите также внимание, что я знаю, что (скорее всего) я делаю много ошибок, когда речь идет о мерах безопасности или стандартах программирования, но в целом (PHPDesktop)> https://github.com/cztomczak/phpdesktop) будет упакован в файл EXE, который будет работать только локально (нет необходимости в онлайн-соединении, так как БД SQLite3 упаковывается вместе с EXE), и я все еще выясняю, как это запрограммировать вВо-первых, эффективное и аккуратное кодирование пока не в моем списке; -)

1 Ответ

1 голос
/ 05 ноября 2019

В скрипте есть некоторые проблемы:

1) Вместо выполнения exit внутри foreach, выполните continue, чтобы пропустить одну фактическую итерацию.

Как и в официальной документации :

continue используется в структурах цикла для пропуска оставшейся части итерации текущего цикла и продолжения выполнения при оценке условия, а затемначало следующей итерации.

Попробуйте этот код:

  foreach($_POST['prodName'] as $prodName => $value) {
    if (!$value) {
      $errorMSG = array("Empty product fields");
      echo json_encode($errorMSG, JSON_PRETTY_PRINT);
      continue;
    } elseif ($value == "Product not found") {
      $errorMSG = array("Invalid products in order form");
      echo json_encode($errorMSG, JSON_PRETTY_PRINT);
      continue;
    }

    $queryProd = "SELECT * FROM `ProdDB` WHERE ProdName LIKE '%$value%'";
    $resultProd = $db->query($queryProd);

    while ($row = $resultProd->fetchArray()) {
      $prodID = $row['ProdID'];
      $prodPrice = $row['ProdPrice'];
      $prodQty = $row['ProdQty'];
      $prodVAT = $row['ProdVAT'];
      $prodCurr = $row['ProdCurr'];
      $salesPrice = $prodQty * $prodPrice;
      $salesVAT = number_format($prodQty * $prodPrice * $prodVAT,2);
      $salesSum = $salesPrice + $salesVAT;
    }
    $result = $queryInsert->execute();
  }

2) ваш запрос использует пользовательские вводы без проверки их содержимого, поэтому ваш скриптможет быть открыт для SQLInjection !

$queryProd = "SELECT * FROM `ProdDB` WHERE ProdName LIKE '%$value%'";

3) , если запрос ничего не возвращает, скрипт не входит в цикл while, так что кажетсячто foreach выполняет только одну итерацию, но вместо этого выполняет все итерации без ввода в while из-за пустого результата этого запроса.

Я предлагаю вам отладить все фрагменты кода, распечатав ихсодержание переменных с использованием var_dump, например:

$a = array(1, 2, array("a", "b", "c"));
var_dump($a);
...