Форум: Форум PHPФорум ApacheФорум Регулярные ВыраженияФорум MySQLHTML+CSS+JavaScriptФорум FlashРазное
Новые темы: 0000000
PHP 5. На примерах. Авторы: Кузнецов М.В., Симдянов И.В., Голышев С.В. Самоучитель PHP 5 / 6 (3 издание). Авторы: Кузнецов М.В., Симдянов И.В. MySQL 5. В подлиннике. Авторы: Кузнецов М.В., Симдянов И.В. Самоучитель MySQL 5. Авторы: Кузнецов М.В., Симдянов И.В. PHP. Практика создания Web-сайтов (второе издание). Авторы: Кузнецов М.В., Симдянов И.В.
ВСЕ НАШИ КНИГИ
Консультационный центр SoftTime

Форум PHP

Выбрать другой форум

 

Здравствуйте, Посетитель!

вид форума:
Линейный форум (новые сообщения вниз) Структурный форум

тема: Записать массив в БД

Сообщения:  [1-10]    [11-20]   [21-30]   [31-40]  [41-48] 

 
 автор: sim5   (23.07.2010 в 00:03)   письмо автору
 
   для: Лена   (22.07.2010 в 23:59)
 

Это проверки ошибок, они естественны, и вытекают из условия приема формы, которые описаны в сессии.
Нет, не это. )

  Ответить  
 
 автор: Лена   (22.07.2010 в 23:59)   письмо автору
 
   для: sim5   (22.07.2010 в 23:44)
 

Пользователь может же и не выбрать? И тогда придет пустое значение.Тогда по приходе формы надо сравнить, что выбрал пользователь и то, что описано в сессии, т.е определить значения, которые выбрал пользователь.

  Ответить  
 
 автор: sim5   (22.07.2010 в 23:44)   письмо автору
 
   для: Лена   (22.07.2010 в 23:38)
 

Еще раз - в сессии описываются реальные имена полей и условия приема по ним данных. Какое количество данных должно прийти может быть и не указано (пользователю дан выбор). Ну и количество данных, это совсем еще не означает, что пришли ожидаемые данные (можете считать это намеком).

  Ответить  
 
 автор: Лена   (22.07.2010 в 23:38)   письмо автору
 
   для: sim5   (22.07.2010 в 23:21)
 

Чтобы количество пришедших значений от формы совпадало с количеством массивов, которые описывают поведение поля формы, в сессии.

Если неправильно, уже как-то намекните. Я все-таки эту тему со второго захода осилила, длинная сильно :)

  Ответить  
 
 автор: sim5   (22.07.2010 в 23:21)   письмо автору
 
   для: Лена   (22.07.2010 в 22:22)
 

Если вы о "что обязательно нужно проверять при приеме такой формы?", то нет. Случайное имя поля формы и должно заноситься в массив описывающий эту форму.
Я имею ввиду иное - в данном случае вы возлагаете все на "скрипт-автомат", ему дано количество параметров, имена полей, а все остальное, это производное от них, и он должен во всем разобраться. Так что он должен проверить обязательно?

  Ответить  
 
 автор: Лена   (22.07.2010 в 22:22)   письмо автору
 
   для: sim5   (22.07.2010 в 00:49)
 

> Кроме этого, вы должны ответь еще на один вопрос, явно неуказанный - что обязательно нужно проверять при приеме такой формы?

В сессию можно записать это случайное имя формы, по приходе формы проверить, есть ли в сессии такая строка, если есть - вытягиваем для этой строки другие параметры(имя поля таблицы; является ли поле обязательным для заполнения и т.д. Т.е. каждое случайное имя надо писать в тот же самый массив, где другие параметры.

Или у вас была другая задумка?

  Ответить  
 
 автор: sim5   (22.07.2010 в 00:49)   письмо автору
 
   для: *m*   (16.07.2010 в 11:25)
 

В ответ на письмо

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

Что касается предложенного мною, так в этом ничего необычного нет, все получается естественно - коли ваши данные это массив, то почему бы не решать задачу с помощью инструментов предназначенных для этого. Если таковые имеются, то задача зачастую упрощается.
Коли вам что-то из вышеизложенного пригодилось, да и слава богу, можете развить далее. К примеру, подумайте, как вы решите следующее, использовав по максимуму уже готовые инструменты РНР. Для начала, измените функцию, ну например, так:
<?
function getStringForMySQL($a$n$r false) {
  
$a array_chunk($a$n);
  
array_walk($acreate_function('&$s','$s = "(\'" . 
                 implode("\',\'", array_map(mysql_real_escape_string, $s)) . 
                 "\')";'
));
  
$a implode(',',$a);
  if(
$r$a str_replace("'""`"$a);
}

Если теперь передать в нее ссылку на массив содержащий имена полей таблицы, указав ее размер, и третим аргументом true, то она подготовит список имен полей таблицы для многострочного оператора INSERT:
(`name1`, name2`, .... , `nameN`)

По умолчанию (без третьего аргумента) вызов функции будет готовить строку для этого запроса, но уже с данными.
А теперь задача.

У вас есть таблица содержащая поля `id` (автоинкремент), `desc` (varchar 120, анонс), `doc` (текст), `rang` (TINYINT) и `status` (TINYINT, по умолчанию 0, статус записи). Вы будете принимать от пользователя форму как массив полей типа text (для `desc`, не обязательное для заполнения), textarea (для `doc`, обязательное для заполнения) и text (для `rang`, обязательное для заполнения). Количество таких полей (вложенность) вы можете устанавливать сами, либо эти поля может добавлять пользователь, то есть число их может быть произвольным.

Форма необычная, она "анонимная", правда анонимная для скрипта обработчика этой формы. В чем заключается анонимность:

1) Поля формы не могут содержать имен "членораздельных", их имена, это набор случайных символов, причем при каждой выдаче формы пользователю, эти случайные имена обновляются.

2) Вы задаете в сессии "описание требований" к этой форме в виде массива: имя поля таблицы (выше указанные); является ли поле обязательным для заполнения; какой проверке данное поле должно подвергаться; сообщения об ошибках выдаваемых пользователю.

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

То есть, получив форму, вы не можете поступать так - if(isset/empty($_POST[имя поля])).... и т.д., проходя это циклом. Считайте, что ваш обработчик должен работать автоматом, получая данные из сессионного массива как руководство к выполнению подпрограммы - от получения необходимых данных из массива описания, до вывода ошибок пользователю при возврате формы, от обработки данных, до записи их в базу. Попробуйте здесь и использовать (найти) уже готовые инструменты РНР для решения, если не для всей задачи в целом, то многих ее составляющих.
Вы должны описать логическую последовательность всех этапов проверки формы. Кроме этого, вы должны ответь еще на один вопрос, явно неуказанный - что обязательно нужно проверять при приеме такой формы?

Попробуйте подумать над этим, и пусть не решить задачу целиком, но представив ее в общем, решить некоторые ее "законченные" области, по максимуму используя функции работы с массивами, ибо их вы и будете обрабатывать в задаче этой. Цель все та же - запись массива в базу.

  Ответить  
 
 автор: sim5   (18.07.2010 в 21:39)   письмо автору
 
   для: *m*   (18.07.2010 в 19:16)
 

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

Подобным образом я могу обрабатывать массивы данных от формы возвращаемой пользователем, при этом в зависимости от полей формы будут автоматически формироваться как число/имена полей в MySQL запросе, так и сами данные. И проверку допустимых данных от пользователя я тоже могу не производить по принципу "for if OK else echo юзерамать туды сюды не то…", а опять по максимуму использовать стандартные РНР функции для работы с массивами.

Вам не слепо надо копировать то, что пишут вам, а понимать, что и для чего. В коде есть строка, которая "приводит" массив к нужному виду:
<?
$arr 
array_chunk($arr2);

Вы должны понимать, для чего это сделано.

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

Задавшись вопросом – "возможно ли произвести запись в базу всех данных массива одним запросом", легко получить ответ – да. Достигается это с помощью многострочного оператора INSERT, запрос для которого в общем виде выглядит так:
INSERT INTO имя таблицы (имя поля 1, имя поля 2, …, имя поля N) 
VALUES 
(значение 1, значение 2, …, значение N), 
(значение 1, значение 2, …, значение N), 
(…), 
(значение 1, значение 2, …, значение N)

Вот из этого и возникает необходимость разделить массив на срезы равные числу записываемых полей данных. Зачем резать массив? Затем, что я так захотел решить задачу записи данных массива в базу, которые перед записью надо привести к виду согласно синтаксиса многострочного оператора INSERT. Кроме этого учесть и другие требования к "оформлению" данных перед запросом. Но вы ведь вольны и не поступать так, а пройтись по массиву циклом, и формировать строку запроса из этих данных в нем.

Если опустить все предварительные подготовки массива (пустоты, пробелы и т.п.), то главное, что должно быть, это то, что ваш массив должен удовлетворять трем важным моментам:
1. Данные массива должны строго чередоваться согласно полям для записи, иначе данные могут попасть в поле не им предназначенное, или вызвать ошибку при запросе, например, несоответствие ожидаемых типов данных.
2. Данные должны чередоваться группами, по числу данных в группе равному числу записываемых полей, иначе пункт 1.
3. Общее число элементов массива должно быть кратным числу записываемых полей. Если не так, то неполный остаток из массива либо удалить, либо дополнить до кратности, иначе это приведет к ошибке при запросе.

Считаем, что ваш массив удовлетворяет трем вышеизложенным требованиям, и мы решили отказаться от прохода массива в цикле, и воспользоваться стандартными РНР функциями для этого. И помним, что мы работаем с индексным одномерным массивом. Что нам для этого надо:
а) разбить массив на группы по числу записываемых полей, у нас эта величина равна 2, то есть разбить массив на подмассивы (вложенные массивы в исходном массиве);
б) найти среди стандартных функций функцию, которая бы позволила стандартными функциями обойти полученный на шаге а) многомерный массив, обработав его значения и сформировав строки для запроса.

Найти функцию для первого просто - это array_chunk(). Для второго этапа нам подойдет функция array_walk(), но… Эта функция накладывает ограничение – нельзя использовать в ней вызов стандартных функций РНР, вызываемые функции должны быть пользовательскими. Можно конечно написать такую функцию и обратиться к ней, но нам-то ведь надо всего с десяток букв написать, а тут придется писать лишнее, в общем, жаба давит. Но если не огорчаться, и поискать, то, оказывается, есть способ обойти это ограничение, для этого можно создать анонимную функцию - create_function(), в которой и опишем все наши действия, плюс свободно сможем вызывать стандартные функции РНР.

Что у нас происходит в array_walk – первым аргументом функции мы указываем массив, который нужно обойти. Вторым аргументом мы объявили анонимную функцию, которая передает по ссылке (&$s) значение каждого элемента массива (у нас это вложенные массивы по два элемента в каждом), значения которых:
1. мнемонизируются специальные символы в строке для использования в операторе SQL функцией mysql_real_escape_string, а обход всех значений для мнемонизации, в переданном по ссылке (&$s) массиве, нам позволяет сделать стандартная функция РНР - array_map;
2. соединяем обработанные значения массива через запятую (стандартная функция implode), добавляя по бокам запятой кавычки, а по краям соединенных значений добавляем кавычки и скобки, как требует синтаксис запроса и условия обрамления текстовых значений в запросе.
Вот собственно и вся идея и ее инструменты. Осталось вложенные массивы, значения которых теперь являются подготвленными для запроса строками, соединить через запятую, то есть уже к исходному массиву применить функцию implode.

Надо только отметить, что в массиве наряду со строковыми значениями, могут быть и числовые значения. А для них нет необходимости обрамлять их в кавычки, но это никак не повлияет на запись данных в базу – поле типа INT примет такое значение как положено, более того, ваше, например, значение "20м" в поле INT будет помещено как 20, и только значение, например, "м20" вызовет ошибку. Другими словами можно сказать, что этот подход в некой мере универсальный, потому, что нам всего и всегда нужны некие сгруппированные отсортированные значения и величина на которую эти значения нужно разбить на массив (группы). А раз так, то можно оформить эти действия в функцию и вызывать ее по мере необходимости. Какой исходный массив при этом у нас (индексный или ассоциативный), роли не играет, так как всегда можно отсортировать/сгруппировать массив, а значения из ассоциативного массива всегда можно получить функцией array_values(). Оформляем функцию:
<?php
function getStringForMySQL($a$n) {
  
$a array_chunk($a$n);
  
array_walk($acreate_function('&$s','$s = "(\'" . 
                 implode("\',\'", array_map(mysql_real_escape_string, $s)) . 
                 "\')";'
));
  
$a implode(',',$a);
}
?>

Теперь вся ваша задача записи массива в базу сводится к простому:
<?php
getStringForMySQL
(&$out2);
mysql_query("INSERT INTO `table` (`name1`, `name2`) values " $out);
?>

Заметьте, что в вызове функции указывается ссылка на массив, а не передается копия его в функцию, и функция не возвращает обработанный результат, а преобразует массив исходник. Если требуется сохранять исходный массив для дальнейших с ним действий, то следует передавать в функцию копию его и возвращать значение. Хотя не составляет труда сделать в функции два режима работы, то есть универсальной. Ну и как говорилось ранее, число полей формы, например, их имена (или имена могут служить ключами для реальных имен таблицы), могут позволить автоматически сформировать и (`name1`, `name2`) для запроса. Вот вам и универсальность.

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

Вот это все вы должны понимать, а не только такую мелочь, как найти и понять, что делает строка кода $arr = array_chunk($arr, 2) в примере, чтобы вопросов "как привести массив к виду" у вас не возникало.

  Ответить  
 
 автор: *m*   (18.07.2010 в 19:16)   письмо автору
 
   для: sim5   (18.07.2010 в 17:56)
 

ну как у вас в примере



Array
(
    [0] => Array
        (
            [0] => Зеленый
            [1] => 20м
        )

    [1] => Array
        (
            [0] => Красный
            [1] => 20м
        )

    [2] => Array
        (
            [0] => Синий
            [1] => 20м
        )

    [3] => Array
        (
            [0] => Зеленый
            [1] => 20м
        )
...

  Ответить  
 
 автор: sim5   (18.07.2010 в 17:56)   письмо автору
 
   для: *m*   (18.07.2010 в 17:53)
 

К какому виду?

  Ответить  

Сообщения:  [1-10]    [11-20]   [21-30]   [31-40]  [41-48] 

Форум разработан IT-студией SoftTime
Rambler's Top100
вверх

Rambler's Top100 Яндекс.Метрика Яндекс цитирования