2015-09-16 5 views
0

Я пытаюсь получить 2 столбцов из моей базы данных со следующим утверждением: приготовленногоPHP Mysqli выбор несколько столбцов, возвращающегося нуль

$statement = $conn->prepare("SELECT script, work_instruction FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."' AND issue='".$issue."'"); 

Всякий раз, когда я использую этот запрос, PHP возвращает null к моей странице, даже хотя данные присутствуют в БД. Однако следующее утверждение делает работу (то же самое для work_instruction):

$statement = $conn->prepare("SELECT script FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."' AND issue='".$issue."'"); 

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

$statement->execute(); 
$statement->bind_result($results); 

while($statement->fetch()){ 
    array_push($myArr, $results); 
} 

$statement->free_result(); 
echo json_encode($myArr); 


Вот пример того, что моя таблица выглядит следующим образом: enter image description here


Вот целая функция, только в случае, если вам нужно, чтобы увидеть больше:

// Responsible for generating queries to the database 
// and returning the data collected 
function query($conn, $column) {  
    $myArr = array(); 
    $table = $_POST['table']; 
    $category = $_POST['category']; 
    $sub_category = $_POST['sub_category']; 
    $issue = $_POST['issue']; 

    switch ($column) { 
     case 'category': 
      $statement = $conn->prepare("SELECT DISTINCT category FROM ".$table); 
      break; 

     case 'sub_category': 
      $statement = $conn->prepare("SELECT DISTINCT sub_category FROM ".$table." WHERE category='".$category."'"); 
      break; 

     case 'issue': 
      $statement = $conn->prepare("SELECT DISTINCT issue FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."'"); 
      break; 

     //This does not work 
     case 'script': 
     $statement = $conn->prepare("SELECT script, work_instruction FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."' AND issue='".$issue."'"); 
     break; 

     //This does work 
     case 'work_instruction': 
     $statement = $conn->prepare("SELECT work_instruction FROM ".$table." WHERE category='".$category."' AND sub_category='".$sub_category."' AND issue='".$issue."'"); 
     break; 

     case 'doc_link': 
      //$statement = $conn->prepare($query); 
      break; 

     default: 
      break; 
    } 
    $statement->execute(); 
    $statement->bind_result($results); 

    while($statement->fetch()){ 
     array_push($myArr, $results); 
    } 

    $statement->free_result(); 
    echo json_encode($myArr); 

} 

ответ

1

В попытке упростить функцию запроса и добавить отчет об ошибках.

function query($conn, $column) {  
    $myArr = array(); 
    $table = '`' . trim($_POST['table']) . '`'; 
    $category = $_POST['category']; 
    $sub_category = $_POST['sub_category']; 
    $issue = $_POST['issue']; 
    $selects = array(
     'category' => 'SELECT DISTINCT `category` FROM ' . $table, 
     'sub_category' => 'SELECT DISTINCT `sub_category` FROM ' . $table . ' WHERE category = ?', 
     'issue' => 'SELECT DISTINCT `issue` FROM ' . $table . ' WHERE category = ? AND sub_category = ?', 
     'script' => 'SELECT `script`, `work_instruction` FROM ' . $table . ' WHERE category = ? AND sub_category = ? AND issue = ?', 
     'work_instruction' => 'SELECT `work_instruction` FROM ' . $table . ' WHERE category = ? AND sub_category = ? AND issue = ?' 
    ); 
    if (true === isset($selects[$column])) { 
     $statement = $conn->prepare($selects[$column]); 
     switch ($column) { 
      case 'sub_category': 
      $statement->bind_param('s', $category); 
      break; 
      case 'issue': 
      $statement->bind_param('ss', $category, $sub_category); 
      break; 
      case 'work_instruction': 
      case 'script': 
      $statement->bind_param('sss', $category, $sub_category, $issue); 
      break; 
     } 
     if (!$statement->execute()) { 
      trigger_error('Error executing MySQL query: ' . $statement->error); 
     } 
     $results = $statement->get_result(); 
     while ($row = $results->fetch_array(MYSQLI_ASSOC)) { 
      $myArr[] = $row; 
     } 
     $results->free(); 
     $statement->close(); 
    } else { 
     trigger_error('Unknown column specified. Expected one of: "' . implode('", "', array_keys($selects)) . '" received "' . $column . '"'); 
    } 
    echo json_encode($myArr); 
} 

Вне вашего использования bind_result Проверка запроса я возвращать данные тонкие, так что если вы все еще возникают проблемы после изменения этого, я считаю, что это будет что-то делать с переменными значениями. http://sqlfiddle.com/#!9/0bfb79/2

Для идентификации проблемы нам понадобится пример структуры таблицы (столбцы и значения) как можно ближе к фактическим значениям, например, в связанной скрипте SQL.

Наряду со значениями переменных, отправляемыми в запрос для заполнения таблицы, категории, подкатегории и выпуска.Снова, как скрипт SQL, я связал.

Если вы не используете $statement->store_result() вам не нужно вызывать $statement->free_result()http://php.net/manual/en/mysqli-stmt.free-result.php В отличие от освобождения памяти, выделенной с помощью $statement->get_resulthttp://php.net/manual/en/mysqli-result.free.php

+0

Спасибо за отличный пост. Я пытаюсь внести эти изменения в свой код, пока не повезло :) Вот пример вашего скрипача, который соответствует моей схеме: http://sqlfiddle.com/#!9/0c4b3/1/0 Я также обновил мой пост с IMG моей таблицы. –

+0

Когда я запускаю ваш код, я получаю код ответа «500», который возникает при вызове функции «get_results()». Любые идеи почему? –

+0

Хорошо, с некоторой незначительной настройкой мне удалось получить этот сниппет! Спасибо за внимание и за отличный ответ. По какой-то причине функция get_result() не работала. Я закончил использование bind_result() вместо –

2

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

Попробуйте следующий код и посмотрите, если проблема решена. Я думаю, что это должно работать, если нет проблемы со значениями, которые вы передаете. Здесь я предположил, что все ваши параметры являются строками. Если это целое число, вы можете изменить 's' в bind_param на 'i'.

<?php 
$statement = $conn->prepare("SELECT script, work_instruction FROM {$table} WHERE category = ? AND sub_category = ? AND issue= ?"); 
$statement->bind_param('sss', $category, $sub_category, $issue); // s = string 
$statement->execute(); 

$results = $statement->get_result(); 
while($row = $results->fetch_array(MYSQLI_ASSOC)) { 
    array_push($myArr, $row); 
} 

echo json_encode($myArr); 
+0

ли эта работа дается следующий сценарий: необходимо выбрать пользователя инструмент, когда инструмент выбран DB запрашивается для категорий для этого инструмента, когда категория выбрана на веб-странице, БД - запросы для sub_category и т. д. и т. д. Другими словами, база данных запрашивается в определенном порядке и не запрашивает все в то же время обязательно –

+0

@EvanBechtol Параметры защищают вас от попыток SQL-инъекций. Вам нужно будет добавить 'bind_param' для каждого из ваших условий случая, если это необходимо. – fyrye

+0

@fyrye Awesome, спасибо большое! SO в принципе, каждый случай должен иметь ту же базовую структуру, что и код, который n00b выложил, а затем в конце выполнить и пропустить результаты? –

2

Есть несколько вопросов с кодом

  1. Это широко открыты для инъекций SQL
  2. В нем нет надлежащего сообщения об ошибках.
  3. Незначительная проблема синтаксиса (о чем следует было сообщить, если вы обратили внимание на вариант 2).

Как вы думаете, первые два не важны вообще, здесь идет решение для третьего: с bind_result() вам нужно привязать переменные для всех выбранных полей.

В качестве примечания, если вам нужно динамически менять имя таблицы, это БОЛЬШОЙ КРАСНЫЙ ЗНАК, мигающий «Плохой дизайн базы данных».

+0

Спасибо за ответ! Это мой первый опыт использования PHP для подключения к базам данных, поэтому у меня пока нет опыта с SQL-инъекциями. Но, зная это сейчас, я настрою свой код. –

Смежные вопросы