Array PHP MySQL

Опубликовано 2013.06.20

Для хранения данных удобно использовать массивы. В этой статье мы рассмотрим цикл Массив <-> База Данных <-> Массив Примеры будут приведены с использованием библиотеки PDO и устаревшего, но простого mysql_query. Начнём с массива. Предположим что у нас есть массив товаров примерно следующего содержания:
  1. $products = array(
  2. 'title' => 'Яблоки',
  3. 'price' => 17,
  4. 'catalog' => 1,
  5. 'count' => 114,
  6. ),
  7. 'title' => 'Груши',
  8. 'price' => 25,
  9. 'catalog' => 1,
  10. 'count' => 85,
  11. ),
  12. 'title' => 'Молоко',
  13. 'price' => 15,
  14. 'catalog' => 13,
  15. 'count' => 100,
  16. ),
  17. 'title' => 'Канцелярия',
  18. 'price' => 80,
  19. 'catalog' => 17,
  20. 'count' => 56,
  21. ),
  22. 'title' => 'iPhone 4S',
  23. 'price' => 5000,
  24. 'catalog' => 18,
  25. 'count' => 100,
  26. ),
  27. );
Теперь в переменной $products хранится двумерный ассоциативный массив. Массив первого уровня является не ассоциативным, так как в качестве ключей у него цифры, а каждый массив второго уровня уже является ассоциативным, так как по имени ключа разработчик может понять что же в нём хранится. И необходимо поместить этот массив в базу данных. Так как я уже знаю структуру массива, то могу спроектировать соответствующую таблицу. [sql] CREATE TABLE IF NOT EXISTS `my_products` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(255) NOT NULL, `price` int(11) NOT NULL, `catalog` int(11) NOT NULL, `kol` int(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ; [/sql] Данный код можете запустить через PhpMyAdmin. Потом необходимо соединиться с базой данных.
  1. //mysql_query
  2. mysql_connect('localhost', 'user_name', 'user_password');
  3. mysql_select_db('db_name');
  4. mysql_query("SET NAMES 'utf8'");
  5.  
  6. //PDO
  7. $db = new PDO('mysql:dbname=db_name; host=localhost',"user_name","user_password",
  8. array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
Я явно указал кодировку UTF-8, чтобы избежать появления крикозябр в таблице. Запрос можно выполнить двумя способами - по одному запросу на каждый товар, или одним запросом поместить сразу все товары. Вначале реализуем пятью отдельными запросами.
  1. //mysql_query
  2. foreach ($products as $prod) {
  3. $sql = "
  4. INSERT INTO `my_products`
  5. (`id`,`title`,`price`,`catalog`,`kol`)
  6. VALUES
  7. (NULL,'".$prod['title']."','".$prod['price']."','".$prod['catalog']."','".$prod['count']."')
  8. ";
  9. }
  10.  
  11. //PDO
  12. foreach ($products as $prod) {
  13. $sql="insert into `my_products` (`title`,`price`,`catalog`,`kol`) values (:title,:price,:catalog,:kol)";
  14. $sth=$db->prepare($sql);
  15. $sth->bindValue(':title', $prod['title']);
  16. $sth->bindValue(':price', $prod['price']);
  17. $sth->bindValue(':catalog', $prod['catalog']);
  18. $sth->bindValue(':kol', $prod['count']);
  19. $sth->execute();
  20. }
Недостатком такого подходя является то, что запросы к БД исполняются в цикле. Запомните раз и навсегда - никогда не делайте запросов в цикле. Команда INSERT позволяет добавить в таблицу сразу несколько строк. Выглядеть это будет следующим образом.
  1. //mysql_query
  2. $string = array();
  3. foreach ($products as $prod) {
  4. $value = array();
  5. foreach ($prod as $item) {
  6. $value[] = "'" . $item . "'";
  7. }
  8. $string[] = '(' . implode(',', $value) . ')';
  9. // Если этот участок сложен для вас - раскоментите,
  10. // и поймёте как формируется переменная $string
  11. // echo $string . '<br />';
  12. }
  13. $sql = "INSERT INTO `my_products`
  14. (`id`,`title`,`price`,`catalog`,`kol`)
  15. VALUES " . implode(', ', $string);
  16. // Вот и конечный запрос.
  17. // echo $sql . '<br />';
  18.  
  19.  
  20. //PDO
  21. $string = array();
  22. $i = 0;
  23. while ($i < count($products)) {
  24. $value = array();
  25. foreach ($products[0] as $key => $item) {
  26. $value[] = ':' . $key . '_' . $i;
  27. }
  28. $string[] = '(' . implode(',', $value) . ')';
  29. $i++;
  30. }
  31.  
  32. $sql="insert into `my_products` (`title`,`price`,`catalog`,`kol`) values " . implode(',', $string);
  33.  
  34. $sth=$db->prepare($sql);
  35. foreach ($products as $key => $prod) {
  36. $sth->bindValue(':title_' . $key, $prod['title']);
  37. $sth->bindValue(':price_' . $key, $prod['price']);
  38. $sth->bindValue(':catalog_' . $key, $prod['catalog']);
  39. $sth->bindValue(':count_' . $key, $prod['count']);
  40. }
  41. $sth->execute();
  42. </>
Таким образом можно перегнать массив данных в БД. Сам массив может взяться откуда угодно, например распаршен XML файл, получены данные формы, данные из другой БД и т.д. А чтобы получить массив - достаточно сделать 1 единственный запрос на выборку данных.
  1. //mysql_query
  2. $res = mysql_query('SELECT * FROM `my_products`');
  3. while($row = mysql_fetch_assoc($res)){
  4. //print_r($row);
  5. echo $row['title'] . ' стоят ' . $row['price'] . '<br />';
  6. }
  7.  
  8. //PDO
  9. $sql = 'SELECT * FROM `my_products`';
  10. $sth = $db->prepare($sql);
  11. $sth->execute();
  12. $res = $sth->fetchAll(PDO::FETCH_ASSOC);
  13. foreach ($res as $row){
  14. echo $row['title'] . ' стоят ' . $row['price'] . '<br />';
  15. }
Вот собственно и всё. Как видите - ничего сложного, правда пример достаточно примитивный. При работе с БД посредством mysql_query - обязательно оборачивайте переменные в запросе функцией mysql_real_escape_string Вот так:
  1. $sql = "
  2. INSERT INTO `my_products`
  3. (`id`,`title`,`price`,`catalog`,`kol`)
  4. VALUES
  5. (
  6. NULL,
  7. '".mysql_real_escape_string($prod['title'])."',
  8. '".mysql_real_escape_string($prod['price'])."',
  9. '".mysql_real_escape_string($prod['catalog'])."',
  10. '".mysql_real_escape_string($prod['count'])."'
  11. )
  12. ";
Без такой защиты(или аналогичной другой) ваш сайт будет уязвим для SQL-инъекций, и ваш сайт могут тупо взломать и грохнуть.