2012-02-24 2 views
0

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

$leadstory = "-1"; 
if (isset($_GET['leadstory'])) { 
    $leadstory = $_GET['leadstory']; 
} 

$query_News = "SELECT * FROM news WHERE lead_story = $leadstory"; 
$News = mysql_query($query_News, $HDAdave) or die(mysql_error()); 
$row_News = mysql_fetch_assoc($News); 
$totalRows_News = mysql_num_rows($News); 

В предыдущем посте я спросил, если эти ЗЕЬЕСТ были уязвимы для атак SQL вставки. Ответ был да, как вы, наверное, знаете. Я сделал некоторое чтение и понять, что мне нужно использовать MySQLi и что-то вроде следующего:

$statement = $db_connection->prepare("SELECT * FROM news WHERE lead_story = ?;';"); 
$statement->bind_param("s", $leadstory); 
$statement->execute(); 
$row_News = $statement->fetchAll(); 

У меня есть несколько вопросов.

  1. мне нужен тип линии «или умереть», если не удается установить соединение ли?

  2. Как назначить $ totalRows_News?

  3. мне нужно «чистых» $leadstory переменной с mysql_real_escape_string ли?

+0

Переключиться на PDO, это, безусловно, лучшая библиотека базы данных PHP – Phil

+0

Возможный дубликат [Если вы всегда заканчиваете mysql-запросы с помощью «или умираете?»] (Http://stackoverflow.com/q/2130105/), [ Count with PDO] (http://stackoverflow.com/q/883365/), [Когда указано в подготовленных операциях pdo в PHP?] (Http: // stackoverflow. com/q/2212097 /) – outis

ответ

1

Использование PDO сделает вашу жизнь намного проще

$pdo = new PDO(...); 
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 

$stmt = $pdo->prepare('SELECT * FROM news WHERE lead_story = ?'); 
$stmt->bindParam(1, $leadStory); 
$stmt->execute(); 

$allRows_News = $stmt->fetchAll(); 
$totalRows_News = count($allRows_News); 
+0

Большое спасибо Филу, теперь, когда я вижу правильный синтаксис, я могу начать изучать, как он работает. С наилучшими пожеланиями, Dave – user1028866

1
  1. Не используйте or die при выводе HTML. Вы получите недопустимый HTML. Часто ошибки обнаруживаются на низком уровне, но могут обрабатываться только на более высоком уровне. Правильная обработка ошибок включает передачу ошибки до тех пор, пока она не будет обработана надлежащим образом. Вы можете использовать возвращаемые значения для удержания ошибок (если могут быть разные типы ошибок и ошибок без ошибок) или использовать exceptions.
  2. Вы можете получить количество строк результатов, используя mysqli_result->num_rows или PDOStatement->rowCount. Обратите внимание, что последнее не доступно для всех баз данных, поддерживаемых PDO, но для MySQL. Тем не менее, оба требуют буферизованные запросы, которые менее эффективны как из-за того, что запрос должен завершиться до того, как программа может продолжить (т. Е. execute является синхронной по отношению к запросу), и весь набор результатов должен быть сохранен в памяти. Метод Phil показывает работу с другими базами данных, хотя он страдает теми же затратами на производительность, что и буферизованные запросы. Альтернативные, небуферизованные запросы (execute асинхронны по отношению к запросу) - это работать со строками по мере их появления, игнорируя общее количество строк до конца. PDOStatement поддерживает Traversable, что означает, что вы можете перебрать его с помощью цикла foreach, так что вам не нужно знать общее количество строк для перебора.

    ... 
    $query->execute(array(':after' => $date)); 
    foreach ($query as $row) { 
        ... 
    } 
    

    Это делает результаты обработки в других модулях особенно хорошо, так как они не должны быть осведомлены о том, что они итерации. Вы даже можете вернуть результаты как экземпляры данного класса.

    $query->execute(...); 
    /* assign properties after calling constructor, so default property 
        values set in constructor don't overwrite the values from the DB */ 
    $query->setFetchMode(PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE, 'Article'); 
    
    # elsewhere, $articles has been set to the value of $query 
    foreach ($articles as $article) { 
        # $article is an Article; do with it what you will. 
        ... 
    } 
    

    Один недостаток к использованию PDOStatement непосредственно является то, что результаты запроса, как правило, используют одноразовый; если вы не используете курсор, вы можете прокручивать их только один раз.

  3. Этот вопрос был задан (вероятно, много раз) перед: When is quoting necessary in prepared statements of pdo in PHP?

Вы можете думать о подготовленных заявлений как аналогично функциям. С помощью функции вы берете блок кода, параметризуете его часть и упаковываете. Функция может быть вызвана несколько раз, но ее необходимо определить только один раз. То же самое относится к подготовленным заявлениям. Поскольку значения сохраняются отдельно от кода, инъекция невозможна в параметрах подготовленного оператора (инъекция является результатом confusing data with code).

Как и в случае с функциями, вы не можете произвольно заменить части инструкции параметром. Во-первых, вам нужно уважать синтаксис. Другим ограничением может быть параметризация только определенного типа вещей. Обе функции и параметры обычно позволяют вам параметризовать значения, хотя на некоторых языках значение считается довольно широким. В SQL то, что считается значением, довольно узкое. Идентификаторы (имена для баз данных, таблиц, столбцов, хранимых процедур, & c) не являются значениями. Списки значений (такие как правый аргумент оператора IN) сами по себе не являются значениями.

Развернувшись на одном из пунктов в 1. немного, в хорошо спроектированном проекте код разделен на несколько модулей на основе того, какие функции он реализует. Это называется «separation of concerns» и приводит к таким вещам, как MVC и многоуровневые архитектуры. «single responsibility principle относится к нему (его можно считать под-принципом). Применяя их к делу, у вас должен быть отдельный data access layer, который отвечает за доступ к базе данных. Существуют различные patterns, которые вы можете применить для реализации этого, но Аспект - это ничего, кроме того, что DAL должен обращаться к базе данных или быть затронутым изменением того, как данные сохраняются. DAL может обрабатывать определенные ошибки (частично или полностью), но это не должно касаться взаимодействия пользователя или отображения данных.

+0

Спасибо за богатство информации outis. Это было настоящее образование. Дейв – user1028866