2014-09-03 2 views
-1

Прежде всего, отвечая, пожалуйста, попробуйте объяснить, насколько это возможно, поскольку я довольно новичок в php. В любом случае, моя проблема в том, что я не понимаю, почему мой ассоциативный массив для преобразования строк не работает. В основном я использую ту же модель, что описана здесь: PHP 5 arrays Прокрутите вниз, чтобы увидеть пример для ассоциативных массивов. Во всяком случае, выход я всегда получаю это когда я представляю "Адам" в текстовое поле:ассоциативный массив для преобразования строки

Notice: Undefined индекс: queryStr в C: \ XAMPP \ HTDOCS \ практика \ SRC \ fetchigndatausingpdo.php на линии 24 PID = 80 = 8 AND FirstName = adam AND 1 = adam AND LastName = preston AND 2 = preston AND Возраст = 17 AND 3 = 17 AND

Ниже приведен код, если у вас есть предложения, пожалуйста, сообщите мне, thankyou :). Кроме того, пользовательские и $ pass были намеренно закрыты по соображениям безопасности.

<form action="fetchigndatausingpdo.php" method="post"> 
<input type="text" name="name"> 
<input type="submit" name="submit" value="submit"> 
</form> 

<?php 

$user = "adam"; 
$pass = "**********"; 


if(isset($_POST['name'])){ 
    try{ 
     $dbh = new PDO('mysql:host=localhost;dbname=my_db', $user, $pass, array(PDO::ATTR_PERSISTENT=>true)); 

     $stmt = $dbh->prepare("SELECT * FROM persons WHERE FirstName LIKE ?"); 
     $stmt->execute(array($_POST['name'])); 
     if($stmt->rowCount() > 0){ 
      $result = $stmt->fetchAll(); 
      $terms = count($result);  
      foreach($result as $person){ 
       foreach ($person AS $field => $value){ 
       $terms--; 
       $GLOBALS['queryStr'].= $field.' = '.$value; 
       if($terms){ 
        $GLOBALS['queryStr'].=' AND '; 
       } 
       }   
      } 
      echo $queryStr; 
     } 

    }catch(PDOException $e){ 
    echo $e->getMessage(); 
} 
} 

?> 
+1

Вы можете использовать http_build_query() для этого. Создает строку запроса с кодировкой URL из предоставленного ассоциативного (или проиндексированного) массива. http://php.net/manual/en/function.http-build-query.php – deadman

ответ

0

Если вы будете только получать ровно одну строку из вашего запроса, вы можете изменить свой $result = $stmt->fetchAll(); строку использовать fetch() метод обработчика базы данных вместо. Это даст вам ровно один массив для вашей переменной $result. Таким образом, вам не нужно будет делать никаких дальнейших изменений.

Изменения обязательны, так как fetchAll() будет помещать массивы в вашу переменную $result (даже если есть только один результат). Если вы не измените fetchAll() на fetch(), то вы можете попробовать изменить ваш foreach($result as $field => $value){ и ниже части к чему-то вроде этого:

.. 
foreach($result as $person){ 
    foreach ($person AS $field => $value){ 
     $terms--; 
     $GLOBALS['queryStr'].= $field.' = '.$value; 
     if($terms){ 
      $GLOBALS['queryStr'].=' AND '; 
     } 
     echo $queryStr; 
    }   
} 
.. 

Просьба уточнить, если это желаемый эффект.

Некоторые дополнительные замечания по коду:

Вы уже используете библиотеку PDO и его метод prepare для эффективного и безопасного использования запросов. Поскольку вы используете привязку параметров, нет необходимости выполнять ручную дезинфекцию полученных данных, поскольку PDO будет обрабатывать это для вас. Говоря об этой линии здесь:

$name = mysql_real_escape_string($_POST['name']); 

и этот:

$stmt->execute(array($name)) 

Вы можете изменить выполнить часть в

$stmt->execute(array($_POST['name'])) 

вместо этого. Кроме того, регулярный способ проверки того, были ли возвращены какие-либо результаты при использовании PDO, будет метод оператора, который вы выполняете. PDO вернет true, даже если в вашем запросе не было совпадений. Прежде всего в сочетании, вы бы ту часть кода выглядит следующим образом:

.. 

if(isset($_POST['name'])){ 
    try{ 
     $dbh = new PDO('mysql:host=localhost;dbname=my_db', $user, $pass, array(PDO::ATTR_PERSISTENT=>true)); 

     $stmt = $dbh->prepare("SELECT * FROM persons WHERE FirstName LIKE ?"); 
     $stmt->execute(array($_POST['name'])); 
     $resultsSize = $stmt->rowCount(); 
     if($resultsSize > 0){ 
      $queryStr = ''; 

      $result = $stmt->fetchAll(); 
      foreach($result as $person){ 
       $terms = sizeof(array_keys($person));  
       foreach ($person AS $field => $value){ 
        $terms--; 
        $queryStr .= $field.' = '.$value; 
        if($terms){ 
         $queryStr .=' AND '; 
        } 
       $queryStr .= '<br/>'; // easier HTML visual evaluation 
       }   
      } 
      echo $queryStr; 
     } 

    }catch(PDOException $e){ 
     echo $e->getMessage(); 
    } 
} 

С выше рефакторинга (вы первый проверки, если $_POST['name'] установлен) вы избегаете дополнительных ресурсов, выделяемых на соединение с базой данных (даже если вы его не используете). Включение вашего инициализации соединения вместе с другим исполняемым кодом не является проблемой в этом случае, вам хорошо с одним блоком catch, обрабатывающим ваши ошибки (так как в этом случае они были бы аналогичного характера, либо проблемное подключение к базе данных.

Изменения, внесенные в запрос: при сравнении строковых значений знак равенства (=) приведет к побайтовому сравнению для точного значения, тогда как оператор LIKE даст преимущество, не наткнувшись на какую-либо причудливость кодирования - и использование LIKE является общепринятым способом сравнения строковых значений (также с LIKE вы можете использовать подстановочные знаки (% символов и т. д.)).

** Edit:

Я обновил приведенный выше код на основе вашего комментария - я также переместил вывод строки после внешней foreach цикла (так он будет печатать, когда все возвращенные строки были обработаны). Я изменил вашу переменную из переопределенной переменной 2 на локальную (текущий контекст не означает, что вам нужен доступ к ней за пределами этого файла или генерации страницы, если да, посмотрите на возможность использования переменной $ _SESSION).

+0

Привет, Ладно, я изменил свой код, который находится в моей исходной области кода. Его в значительной степени точно так же, как ваш, однако «echo $ queryStr» находится за пределами скобок foreach. Это связано с тем, что цель, которую я собираюсь сделать, - это строка результата, которая может быть легко проанализирована для отображения значений для имени, имени и возраста. Я почти достиг этого, но результат по-прежнему остается немного неудобным. Я отредактировал свой основной пост, чтобы отобразить текущий результат. Я думаю, что мы почти взломали его, просто нужно немного «убирать» – user3918443

+0

Внесены некоторые изменения в код на основе вашего комментария, проверьте редактирование. – Gabor

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