Уроки PHP - урок 3.2 - Работа с БД MySQL. Вставка данных INSERT INTO. Выборка данных SELECT
В прошлом уроке мы создали таблицу для нашего сайта. В этом уроке мы улучшим нашу таблицу и уже начнем работать с БД: вносить туда данные и брать эти данные из таблицы. Я думаю ничего сложного не ожидается, поэтому давайте начнем.
Для начала я предлагаю улучшить нашу таблицу messages. Сейчас есть в ней есть поля для данных, но нужно еще одно поле для нумерации записей. Если вы откроете БД друпала, то там в таблице node будет поле nid, по которому мы нумеруем наши ноды. Также нужно будет сделать и с нашей таблицей messages.
Давайте зайдем в phpMyAdmin (http://localhost/tools/phpmyadmin для денвера) и подредактируем нашу таблицу. Добавим еще одну колонку в начало таблице, как это показано на рисунке:
Назовем колонку mid (message id), тип данных INT (целочисленный) длина 11 символов. Также поставим галочку напротив AUTO_INCREMENT, что означает автоматическую нумерацию в этом столбце. И еще поставим в поле Index значение primary, это будет значить, что это первичный ключ нашей таблицы.
Если вы помните, то мы создавали отдельный метод для класса simpleCMS, чтобы создавать таблицу. Думаю нам нужно теперь изменить работу этого метода, чтобы он добалял еще и поле mid. Зайдите в таблицу messages и нажмите на export:
Мы попадем на страницу экспорта таблицы. Экспорт производится в виде SQL запросов, на создание и редактирование таблиц. Если мы изменяем таблицу в phpmyadmin, то мы можем потом скопировать SQL запрос на ее создание, это очень удобно.
На странице экспорта оставьте все по умолчанию и нажмите ОК. PhpMyAdmin выдаст вам sql-запрос либо прямо в браузере, либо в виде файла. И то и другое нас устраивает. Нам нужно будет скопировать вот этот код:
Заметьте какие там стоят косые кавычки, такие используются в phpMyAdmin. В php мы можем использовать простые одинарные кавычки. Копируем текст в наш метод buildDB():
public function buildDB(){ $sql = "CREATE TABLE IF NOT EXISTS 'messages' ( 'mid' int(11) NOT NULL AUTO_INCREMENT, 'title' varchar(150) DEFAULT NULL, 'bodytext' text, 'created' varchar(100) DEFAULT NULL, PRIMARY KEY ('mid') ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"; return mysql_query($sql); }
Теперь давайте проверим как это будет работать. Давайте удалим таблицу messages.
Потвердите удаление. Теперь когда мы запустим на нашем сайте index.php, то запустится метод buildDB() и наша таблица должна быть заново создана.
public function buildDB(){ $sql = "CREATE TABLE Messages ( mid int NOT NULL AUTO_INCREMENT, PRIMARY KEY(mid), title varchar(15), bodytext text, created int(11) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 AUTO_INCREMENT=1"; $result = mysql_query($sql); print_r($result); }
Теперь запускаем index.php и у нас появляется таблица Messages, как и была прежде.
Запросы вставки INSERT INTO
База данных создана, все готово к тому чтобы реализовать наши методы записи и вывода сообщений с использованием БД. Давайте начнем с записи в БД. Итак открывайте метод write(), будем его менять.
Запись в таблицы осуществляется с помощью оператора INSERT INTO, следующим образом:
public function write($p) { // метод записи сообщения $sql = 'INSERT INTO Messages (title, bodytext, created) VALUES ("'. $p["title"] . '", "' . $p["bodytext"] . '", ' . time() . ')'; return mysql_query($sql); }
Давайте теперь разберемся как же именно вставляются значения. Как я и говорил раньше SQL-запрос вставки начинается с оператора INSERT INTO, дальше идет имя таблицы Messages. После имени таблицы мы пишем в какие колонки вставлять значения, заметьте что мы не пишем mid, потому что его значение будет автоматически поставлено MySQL, так как мы поставили автоматический инкремент (приращение на единицу) каждой новой записи. Дальше идет оператор VALUES (значения) после которого мы пишем значения для каждой колонки в таблице. Причем порядок колонок и порядок значений должен совпадать, как и количество значений и колонок.
Если в значениях нужно вставить строчное выражение, тогда мы используем кавычки. Причем нужно следить чтобы эти кавычки отличались от тех ковычек в которые обернут весь SQL-запрос. И еще не путайтесь когда вставляете переменную в SQL запрос, текстовую часть sql-запроса мы оборачиваем в одинарные кавычки, тогда мы должны строку выводимую из переменной обернуть в двойные кавычки, например здесь:
"'. $p["title"] . '"
следующий порядок ковычек: двойный, одинарные, точка, переменная, точка, одинарные, двойные.
Я думаю одного примера пока достаточно, дальше будут еще примеры, так что не расстраивайтесь если я вам плохо объяснил и вы не сразу поняли. Давайте лучше теперь создадим пару записей в таблице, для этого замените код метода write(), на тот который я вам дал выше.
Запросы выборки SELECT
Создали несколько строк, посмотрели через phpmyadmin:
Теперь мы можем выводить эти записи с помощью метода display_public(), который мы тоже изменим. Делать выборку из таблицы мы будем с помощью оператора SELECT, давайте начнем с простого выбора:
public function display_public() { // метод вывода сообщений $content = ''; $sql = 'SELECT * FROM Messages'; //запрос выборки $result = mysql_query($sql); // результат выполнения запроса выборки мы сохраняем в переменную while($row = mysql_fetch_array($result)){ // переменную запроса выборки необходимо обработать специальной функцией mysql_fetch_array() print '<div class="post">'; // div оборачивающий запись print '<span class="time">#' . $row['mid'] . ' от ' . date('d-m-Y', $row['created']) . '</span><h2>' . $row['title'] . '</h2>'; // выводим время и заголовок print '<p>' . $row['bodytext'] . '</p>'; // выводим текст сообщения print '</div>'; // конец оборачивающего div'a } $content .= '<p><a href="/index.php?admin=1">Добавить сообщение</a></p>'; return $content; }
Я уже заменил полностью реализацию метода display_public(), теперь все записи выводятся из БД. Давайте теперь разберем этот пример. Запрос выборки начинается с оператора SELECT дальше идет знак * (звездочка) это значит, что мы хотим выбрать все поля каждой строки из таблицы. Если бы мы написали так:
$sql = 'SELECT mid,title FROM Messages'; //запрос выборки $result = mysql_query($sql);
То это бы означало, что мы будем выбирать только mid и title из каждой строки, а bodytext и created нам не нужны.
Дальше после * идет оператор FROM, который указывает из какой таблицы мы будем выбирать.
Результат выполнения функции mysql_query() для запроса выборки нужно записывать в переменную (у нас это переменная $result), потому что позже эту переменную нужно будет обработать функцией mysql_fetch_array().
Представьте, что мы сделали запрос выборки и получили 3 записи, так вот функция mysql_fetch_array(), позволяет формировать поочередно по одному массиву после каждого вызова. То есть при первом вызове, мы получим массив первой строки, при втором вызове массив второй строки и т.д. Когда строки закончатся функция mysql_fetch_array() вернет не массив, а значение false. Поэтому в этом случае можно использовать цикл while (пока условие выполняется мы производим действия). Он позволяет выполнить одинаковые действия для всех записей из таблицы. Таким образом мы перебираем каждую запись пока условие выполняется.
Я думаю это может быть сложно для понимания с первого раза, но со временем втягиваешься в написания запросов на SQL. Операторов не так уж много поэтому быстро их запоминаешь.
Запросы выборки, сортировка ORDER BY
Так же можно задавать порядок выборки с помощью оператора ORDER BY, по умолчанию порядок устанавливается по возрастанию, ну например:
$sql = 'SELECT * FROM Messages ORDER BY mid';
Так мы отсортируем запрос выборки по возрастаю mid. Можно также сортировать по убыванию, для этого нужно использовать еще один дополнительный оператор DESC.
$sql = 'SELECT * FROM Messages ORDER BY mid DESC';
Как вы видите все очень просто, если для убывания мы используем DESC, то для возрастания нужно использовать ACS:
$sql = 'SELECT * FROM Messages ORDER BY mid ASC';
Хотя сортировка по возрастанию используется по умолчанию.
Запросы выборки, условия WHERE
Кроме сортировки, можно фильтровать запросы выборки, устанавливая условия на выбоку с помощью оператора WHERE:
$sql = 'SELECT * FROM Messages WHERE mid<3 ORDER BY mid DESC';
Таким образом мы выведем первые две записи ( с mid=1 и mid=2 ), если конечно такие записи есть в таблице. Можно также использовать операторы AND (и) и OR (или), для связки нескольких условий. Если мы ставим AND, то оба условия должны выполняться, если ставим OR, то достаточно выполнения только одного из условий.
$limit_time = time() - 3600; // время час назад $sql = 'SELECT * FROM Messages WHERE mid<3 AND created>' . $limit_time . ' ORDER BY mid DESC'; //запрос выборки
Таким образом мы еще наложим дополнительное условия, что запись создана не раньше, чем час назад. Думаю для запросов выборки пока достаточно, поэтому давайте перейдем к следующему уроку.