Запрос PDO возвращает пустые записи, когда ни одна не должна быть возвращена - PullRequest
0 голосов
/ 16 октября 2019

При загрузке HTML-страницы я также выполняю запросы к базе данных, чтобы заполнить несколько выпадающих списков. Я обнаружил, что 1 запрос возвращает 23 пустых записи (по крайней мере, именно это он и делает) и добавляет 23 пустых «опции» в выпадающий список. Поскольку таблица для этого запроса (# 2) еще не существует, я ожидаю, что никакие записи не будут возвращены запросом, и никакие записи не будут добавлены в раскрывающийся список. 23 записи совпадают с количеством записей, возвращаемых запросом № 1. В журнале ошибок PHP не сообщается об ошибках, кроме недействительных индексных сообщений об именах столбцов (2 из них).

Я написал класс Database много лет назад, когда изучал PHP. Я просмотрел код класса, но ничего плохого не вижу. Я создаю объект базы данных в верхней части страницы и использую этот объект 1 для всех запросов.

Я разместил оба запроса и все используемые функции класса. Поскольку я не вижу проблемы, я надеюсь, что кто-то может.

Спасибо за любую помощь,

Чарльз

Запрос 1, работает как ожидалось:

<div class="container" title="Please select your name suffix.">
 <label for="suffix">Suffix:</label><br>
 <select id="suffix" name="suffix" onchange="">
  <option value="0"<?php if(isset($_POST["suffix"]) && (($_POST["suffix"] == "0") || ($_POST["suffix"] == "1"))) echo(' selected="selected"');?>>&nbsp;</option>
  <option value="1"><?php echo("S" == "P" ? "Add New/Edit Prefix" : "Add New/Edit Suffix");?></option>
<?php
$sql = "SELECT `id`, `abbrev`, `description` FROM `{$pdo->db_name}`.`name_pre-suf` WHERE `type` = :type ORDER BY `abbrev` ASC;";
$pdo->query($sql);
$pdo->bind(":type", str_ToUpper("S"));
$results = $pdo->resultSet();
if($pdo->rowCount())
{
 foreach($results as $row)
 {
  echo("      <option value=\"" . SafeDisplay($row["id"]) . "\"");
  if(isset($_POST["suffix"]))
  {
   if(SafeDisplay($row["id"]) == SafeDisplay($_POST["suffix"]))
   {
    echo(" selected=\"selected\"");
   } // Closing brace for if(SafeDisplay($row["id"]) == SafeDisplay($_POST["suffix"]))
  } // Closing brace for if(isset($_POST["suffix"]))
  echo(">" . SafeDisplay($row["abbrev"]) . " - " . SafeDisplay($row["description"]) . "</option>" . PHP_EOL);
 } // Closing brace for foreach($results as $row)
} // Closing brace for if($pdo->rowCount())
?>
 </select>
 <span id="cefiform_suffix_errorloc" class="error"><?php if(isset($validator) && array_key_exists('suffix', $validator->errors)) echo(implode('<br>', $validator->errors['suffix']));?></span>
</div>

Запрос 2, не должен работать, поскольку таблица «страны» еще не существует. Я не ожидаю добавления записей. Однако возвращается 23 записи и добавляются 23 пустых «опции». 23 число записей, полученных по запросу 1.

<div class="container" title="Please select your country.">
 <label for="ctry">Country:</label><br>
 <select id="ctry" name="ctry">
  <option value="0"<?php if(isset($_POST["ctry"]) && (($_POST["ctry"] == "0") || ($_POST["ctry"] == "1"))) echo(' selected="selected"');?>>&nbsp;</option>
  <option value="1">Add New/Edit Country</option>
<?php
$sql = "SELECT `alpha2_id`, `common_name` FROM `{$pdo->db_name}`.`countries` ORDER BY `common_name` ASC;";
$pdo->query($sql);
$results = $pdo->resultSet();
if($pdo->rowCount())
{
 foreach($results as $row)
 {
  echo("      <option value=\"" . SafeDisplay($row["alpha2_id"]) . "\"");
  if(isset($_POST["ctry"]))
  {
   if(SafeDisplay($row["alpha2_id"]) == SafeDisplay($_POST["ctry"]))
   {
    echo(" selected=\"selected\"");
   } // Closing brace for if(SafeDisplay($row["alpha2_id"]) == SafeDisplay($_POST['ctry']))
  } // Closing brace for if(isset($_POST['ctry']))
  echo(">" . SafeDisplay($row["common_name"]) . "</option>" . PHP_EOL);
 } // Closing brace for foreach($results as $row)
} // Closing brace for if($pdo->rowCount())
?>
 </select>
 <span id="cefiform_ctry_errorloc" class="error"><?php if(isset($validator) && array_key_exists('ctry', $validator->errors)) echo(implode('<br>', $validator->errors['ctry']));?></span>
</div>

class Database
{
 // Set database handler and database name variables
 private $pdo;
 public $db_name;

 // Set errors variable
 public $errors = array();

 public function bind($param, $value = null, $type = null)
 {
  if(is_array($param) && is_null($value) && is_null($type))
  {
   foreach($param as $key => $value)
   {
    $this->bind($key, $value);
   } // Closing brace for foreach($param as $key => $value)
  } // Closing brace for if(is_array($param) && is_null($value) && is_null($type))
  else
  {
   if(is_null($type))
   {
    switch(true)
    {
     case is_int($value):
      $type = PDO::PARAM_INT;
      break;
     case is_bool($value):
      $type = PDO::PARAM_BOOL;
      break;
     case is_null($value):
      $type = PDO::PARAM_NULL;
      break;
     default:
      $type = PDO::PARAM_STR;
      break;
    }
   }
   $this->stmt->bindValue($param, $value, $type);
  } // Closing brace for if(is_array($param) && is_null($value) && is_null($type)) else
 }

 public function query($query)
 {
  try
  {
   $this->stmt = $this->pdo->prepare($query);
  }
  catch(PDOException $e)
  {
   $this->addError("pdo", $e->getMessage());
  }
 }

 public function resultSet()
 {
  $this->execute();
  return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
 }

 public function rowCount()
 {
  return $this->stmt->rowCount();
 }
}

1 Ответ

0 голосов
/ 17 октября 2019

Вашему классу Database необходимо очистить $this->stmt, если вызов prepare() завершится неудачей.

 public function query($query)
 {
  try
  {
   $this->stmt = $this->pdo->prepare($query);
  }
  catch(PDOException $e)
  {
   $this->addError("pdo", $e->getMessage());
   $this->stmt = null;
  }

И все другие методы, использующие $this->stmt, должны сначала проверить, является ли он нулевым. Например:

 public function resultSet()
 {
  if (!$this->stmt) {
    return [];
  }
  $this->execute();
  return $this->stmt->fetchAll(PDO::FETCH_ASSOC);
 }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...