|
|
|
| Всем доброго времени суток.
Есть массив, в нем сто строк с [0] по [99] ключ, нужно записать в БД каждый пятый ключ..
Не могу сообразить как это сделать?
Представляется как-то так:
<?
$num = 0;
$array[$num];
// записали в БД
$num = 0 + 4;
$array[$num];
//записали в БД
итд
?>
|
но как это зациклить в одном цикле..? Или еще как-то проще все можно сделать? | |
|
|
|
|
|
|
|
для: *m*
(16.07.2010 в 11:25)
| | т.е нужно записать 4, 9, 14, 19, 24 и тд? | |
|
|
|
|
|
|
|
для: *m*
(16.07.2010 в 11:25)
| |
<?php
for ($i = -1; $i < 95; $i = $i + 5)
echo $array[$i];
|
Че-то такое.. | |
|
|
|
|
|
|
|
для: neadekvat
(16.07.2010 в 11:45)
| |
for($i = 0, $n = count($array); $i < $n; $i +=5)
...
|
| |
|
|
|
|
|
|
|
для: Trianon
(16.07.2010 в 11:51)
| | Хм..но по идее, допустим, в массиве 11 элементов. После второй итерации условие ($i < $n) выполнится, затем увеличение переменной, но индекса 15 в массиве нет.
К тому же, элемент с индексом 5 является уже шестым элементом в массиве | |
|
|
|
|
|
|
|
для: neadekvat
(16.07.2010 в 13:00)
| | > по идее, допустим, в массиве 11 элементов
1. $i = 0, $n = count($array) // => $n = 11
2. ($i < $n) => (0 < 11) => true
3. // первая итерация
4. ($i +=5) => ($i = 0+5) => ($i = 5)
5. ($i < $n) => (5 < 11) => true
6. // вторая итерация
7. ($i +=5) => ($i = 5+5) => ($i = 10)
8. ($i < $n) => (10 < 11) => true
9. // третья итерация, элемент с индексом 10 существует
10. ($i +=5) => ($i = 10+5) => ($i = 15)
11. ($i < $n) => (15 < 11) => false
12. // завершение цикла
> затем увеличение переменной
Увеличение происходит после очередной итерации, перед проверкой условия выполнения цикла.
> элемент с индексом 5 является уже шестым элементом в массиве
не факт :)
После элемента с индексом 0, следующий должен быть с индексом 5, это если "каждый пятый" начиная с первого.
Но у автора пример какой то противоречивый условию. Толи каждый пятый нужен, толи каждый четвёртый. Не ясно. | |
|
|
|
|
|
|
|
для: sms-send
(16.07.2010 в 13:41)
| | И правда, тупанул, признаю :) | |
|
|
|
|
|
|
|
для: neadekvat
(16.07.2010 в 14:44)
| | А как быть если нужно записать каждый пятый и каждый 7ой?
пардон, сразу не написал | |
|
|
|
|
|
|
|
для: *m*
(16.07.2010 в 15:02)
| | прежде всего нужно научиться думать головой, что бы в последствии не творить геморрой на свою (и не только) голову (и не только).
Обьясните как так получилось, что перед Вами встали подобного рода задачи. Проблему легче решить в корне, чем бороться с её многочисленными последствиями. | |
|
|
|
|
|
|
|
для: Valick
(16.07.2010 в 15:07)
| | ОК, смотрите я получаю контент из html страницы, далее полученный массив я разбираю регулярным выражением, нахожу текст внутри определенных тегов, например <td>. У меня получается уже другой массив, массив строк, который мне нужно записать в БД. Поскольку массив строк имеет определенную последовательность, я подумал, что можно ее правильно зациклить для записи в БД.
То есть я правильно понимаю под каждую последовательность нужно отдельный цикл создавать или можно как-то в одном сделать? | |
|
|
|
|
|
|
|
для: *m*
(16.07.2010 в 15:25)
| | Если бы тот массив который Вы собираетесь писать в БД был бы ассоциативным и имел четкую структуру то проблемы и небыло бы.
А так да, проще отдельный цикл под каждую последовательность (в ущерб универсальности). | |
|
|
|
|
|
|
|
для: *m*
(16.07.2010 в 15:25)
| | А при записи в базу вам что важна последовательность этих записей в базе? | |
|
|
|
|
|
|
|
для: sim5
(16.07.2010 в 16:56)
| | смысл такой:
пусть [0] [10] [20] ключ, например - (цвет)
пусть [1] [11] [21] ключ, например - (размер)
|
мне нужно записать в таблицу так:
id цвет размер
1 [0] [1]
2 [10] [11]
2 [20] [21]
|
| |
|
|
|
|
|
|
|
для: *m*
(16.07.2010 в 17:55)
| | ну если так то можно и одним циклом, и даже одним запростом | |
|
|
|
|
|
|
|
для: Valick
(16.07.2010 в 17:58)
| | подскажите, пожалуйста, что-то никак сообразить не могу..) как зациклить? | |
|
|
|
|
|
|
|
для: *m*
(16.07.2010 в 18:01)
| | 1) дайте четкую структуру массива с описанием ключей одного набора данных которые будут циклически повторяться, если массив каждый раз разный или цикличность не совсем циклическая, то забудте... и начинайте смотреть в сторону формирования ассоциативного многомерного массива, а то и запроса в базу без промежуточного массива.
2) речь может пойти о оказании платной услуги. | |
|
|
|
|
|
|
|
для: Valick
(16.07.2010 в 18:07)
| | ну смотрите вот масив:
Array
(
[0] => Array
(
[0] => Зеленый
[1] => 20м
[2] =>
[3] =>
[4] => Красный
[5] => 20м
[6] =>
[7] =>
[8] =>
[9] => Синий
[10] => 20м
[11] =>
[12] =>
[13] =>
[14] => Зеленый
[15] => 20м
[16] =>
[17] =>
[18] =>
[19] => Синий
[20] => 20м
)
|
массив всегда будет одинаковым, разница только в колличестве строк.. | |
|
|
|
|
|
|
|
для: *m*
(17.07.2010 в 12:14)
| | А как вы умудряетесь с помощью рег. выражений получить массив с пустыми значениями? К тому же на выходе можно получить уже так:
Array
(
[0] => Array
(
[0] => Зеленый
[1] => 20м
)
[1] => Array
(
[4] => Красный
[5] => 20м
)
и т.д..
)
|
| |
|
|
|
|
|
|
|
для: sim5
(17.07.2010 в 12:18)
| | я прост для примера написал) ключи все заполнены у меня.. | |
|
|
|
|
|
|
|
для: *m*
(17.07.2010 в 12:19)
| | И у массива может быть второй вложенный массив, где опять будут повторяться Зеленый=>20м и т.д.?
Причем значения повторяются, так и нужно, или дублирующие значения нужно удалить? | |
|
|
|
|
|
|
|
для: sim5
(17.07.2010 в 12:25)
| | ну у меня массив одномерный, хотя в нем есть [0] и [1] ключ оба они идентичны, я беру array[0] и его собираюсь обходить в цикле | |
|
|
|
|
|
|
|
для: *m*
(17.07.2010 в 12:30)
| | Повторяю вопрос еще раз. У вас первый вложенный массив содержит повторяющиеся значения:
[0] => Зеленый
[1] => 20м
[4] => Красный
[5] => 20м
[9] => Синий
[10] => 20м
[14] => Зеленый
[15] => 20м
[19] => Синий
[20] => 20м
|
второй вложенный массив, надо полагать, может содеражать также повторяющиеся значения, причем и значений из первого вложенного массива. Вопрос, что с ними делать - удалить дубликаты или оставить? Запись в базу должна происходить парами как: Зеленый, 20м; Красный, 20м; и т.д.? | |
|
|
|
|
|
|
|
для: sim5
(17.07.2010 в 12:38)
| | значения иногда повторяются... (но все значения должны быть записаны в БД) то есть если представить таблицу со строками, то каждая строка таблицы должна быть записаны в БД.
>>>Запись в базу должна происходить парами как: Зеленый, 20м; Красный, 20м; и т.д.?
ну наверно можно и парами, но смысл тот.. да, должно быть соответствие. | |
|
|
|
|
|
|
|
для: *m*
(17.07.2010 в 12:52)
| | Вы русский язык понимаете? Я вам задаю конкретный вопрос - "Что делать с дубликатами (повторяющимися значениями)?". И что вы отвечате:
"значения иногда повторяются... (но все значения должны быть записаны в БД) то есть если представить таблицу со строками, то каждая строка таблицы должна быть записаны в БД."
Вот как ваш ответ понять - ДА (удалить дубликаты) или НЕТ (оставить дубликаты)?
PS. Немного подправлю вопрос, ибо вижу вы не поняли о чем я спрашиваю - у вас два вложенных массива, они также могут иметь дубликаты. Вам надо эти два массива, не взирая на дубликаты записать в базу? Я правильно понимаю? | |
|
|
|
|
|
|
|
для: *m*
(16.07.2010 в 17:55)
| | Вам таки необходимо самому формировать id записей? Может лучше подойдет автоинкремент их?
Проходите в цикле массив и формируете стоку запроса для многострочного оператора INSERT, затем делаете всего один запрос к базе. ID будут сформированы автоматом при автоинкременте, а их порядок в базе, как и самих записей, это непринципиально. | |
|
|
|
|
|
|
|
для: sim5
(16.07.2010 в 18:10)
| | так я и хотел запись организовать с автоинкрементом, какой id будет у какой строки это действительно не принципиально. Я как себе это представлял, что я буду обходить массив и выбранные ключи записывать построчно в базу в цикле. Вот с зацикливанием у меня и трабла, не могу сообразить как. | |
|
|
|
|
|
|
|
для: *m*
(17.07.2010 в 12:18)
| | Не надо циклов. Если ваш массив, это строгое повторение Зеленый, 20м, Синий 20м и т.д., нет пустых значений, то:
<?
//это ваш массив
$arr = array(
array('Зеленый', '20м',
'Красный', '20м',
'Синий', '20м',
'Зеленый', '20м',
'Синий', '20м'),
array('Зеленый', '20м',
'Красный', '20м',
'Синий', '20м',
'Зеленый', '20м',
'Синий', '20м')
);
//если нужно записать оба вложенных массива,
//и если не удалять дубликаты,
//то просто соеденяем эти вложенные массивы
$arr = array_merge($arr[0],$arr[1]);
//если же надо записать только первый вложенный массив,
//то просто работаем далее с массивом $arr[0], как:
//$arr = $arr[0];
//разбиваем массив на массивы по два значения в каждом
$arr = array_chunk($arr, 2);
//преобразуем каждый вложенный массив в строку
//содержащую его значения через запятую,
//предварительно мнемонизуруя их,
//и заключенную в скобки
array_walk($arr, create_function('&$s','$s = "(" . implode(",", array_map(mysql_real_escape_string, $s)) . ")";'));
//вот что получится в результате
print "<pre>";
print_r($arr);
//остается сформировать из массива строку для многострочного оператора INSERT
$arr = implode(',',$arr);
//и сделать запрос на запись
mysql_query("INSERT INTO `table` (`fieldName1`, `fieldName2`) values " . $arr );
|
PS. Виноват, я же о кавычках для строковых значений забыл. Вот так должно выглядеть преобразование элементов массива в строку:
<?
array_walk($arr, create_function('&$s','$s = "(\'" . implode("\',\'", array_map(mysql_real_escape_string, $s)) . "\')";'));
|
| |
|
|
|
|
|
|
|
для: sim5
(17.07.2010 в 13:25)
| | Да нет же, уважаемый sim5, мой массив это не строгое повторение, то есть есть канешно и повторяющиеся строки, но еще есть и описания, где текст всегда отличающийся..
спасибо, что потратили время и на этот пример (такова решения я еще не видел). | |
|
|
|
|
|
|
|
для: *m*
(18.07.2010 в 11:58)
| | Повторения, это означает, что вы будете писать в базу два значения: цвет => параметр. То есть, они у вас в массиве так и чередуются: Зеленый 20м Синий 20м...., а не Зеленый 20м 20м Синий....
Если у вас "беспорядок" в массиве, а писать нужно пары вышеуказанные, то сперва нужно подготовить массив (ваши данные) перед его преобразованием/записью.
Что же касается кода выше, то это в любом случае нужно будет делать, а уж так или проходом в цикле, уже вопрос другой. Если у вас путаница в данных, то вполне возможно, что выгоднее пройтись по ним в цикле, сравнивая, преобразовывая, подготоваливая к записи....
PS. но еще есть и описания, где текст всегда отличающийся..
Какие данные и сколько их имеет каждая запись, это не важно, главное, что вы должны знать, это размерность полей записываемых данных. Другими словами, массивы, данные которых надо записать, могут быть любого размера, но одинаковыми у всех. То есть это не обязательно два поля для записи (Зеленый, 20м), а это может быть "Зеленый", "20м", "Провод", "Производитель", и т.д..., и например, это будет 6 полей. И все вложенные массивы должны иметь 6 полей. А их последовательное чередование, это либо ваша забота при получении из документа, либо сортировка после получения. | |
|
|
|
|
|
|
|
для: sim5
(18.07.2010 в 12:06)
| | да чередуются одинаково Зеленый 20м Синий 20м итд..
только вот один момент в моем массиве, все данные идут от нулевого до n-го ключа вот так:
вот как я приводил:
Array
(
[0] => Array
(
[0] => Зеленый
[1] => 20м
[2] =>
[3] =>
[4] => Красный
[5] => 20м
[6] =>
[7] =>
[8] =>
[9] => Синий
[10] => 20м
[11] =>
[12] =>
[13] =>
[14] => Зеленый
[15] => 20м
[16] =>
[17] =>
[18] =>
[19] => Синий
[20] => 20м
)
и у меня есть пустые ключи, немного выше я оговорился что все ключи у меня заполнены.
а получилось это так :
<?
preg_match_all('|<td>(.*)</td>|Uis', $data, $out);
?>
|
а в вашем примере строки имеют уже разные ключи(0,1,2,3 итд):
Array
(
[0] => Array
(
[0] => Зеленый
[1] => 20м
)
[1] => Array
(
[0] => Красный
[1] => 20м
)
[2] => Array
(
[0] => Синий
[1] => 20м
)
[3] => Array
(
[0] => Зеленый
[1] => 20м
)
...
|
нужно как-то приводить мой массив к виду как вы привели в примере? | |
|
|
|
|
|
|
|
для: *m*
(18.07.2010 в 12:31)
| | >нужно как-то приводить мой массив к виду как вы привели в примере?
Нужно, и удалить пустые значения из массива, плевое дело, и также без использования цикла. Попробуйте сначала сами найти такой инструмент в РНР среди функций работы с массивами. Это первое.
Второе, я еще ранее вас спрашивал о ID записях, которые можно формировать автоматически при записи в базу. Теперь вы пишите: "а в вашем примере строки имеют уже разные ключи(0,1,2,3 итд):" - вам что нужно сохранять ключи исходного массива, для записи их в базу? | |
|
|
|
|
|
|
|
для: sim5
(18.07.2010 в 12:37)
| | пересмотрел с десяток функций отсюда http://www.php.ru/manual/ref.array.html логически подходящих по описанию, не могу найти..(
нет ключи масива при записи в БД сохранять не нужно, не важно какой id будет у записавшейся строки.
я про ключи говорил к тому что ваш массив отличается от моего.) | |
|
|
|
|
|
|
|
для: *m*
(18.07.2010 в 13:13)
| | Если не нашли, значит вы воспринимаете описание функций "в лоб" - понимаете вроде бы для чего они, но не стараетесь представить как их можно использовать.
<?
//это первый индекс вашего массива
$arr = array(array('Зеленый', '20м', '', '', 'Красный', '20м', '', '', '',
'Синий', '20м', '', '', '', 'Зеленый', '20м', '', '', '', 'Синий', '20м')
);
//и если нужен только он, то избавтесь сразу от лишнего:
$arr = $arr[0];
|
В наборе функций работы с массивами, имеются функции пересечения массивов, которые при сравнении возвращают массив соответствующий логике работы той или иной функции. То есть, мы можем сравнить ваш массив, с массивом со значением "пусто", с условием, чтобы нам вернулся массив не содержащий значений "пусто". Для вашего массива подойдет функция array_diff(). Но не обязательно может быть "пусто", возможно массив может содержать в значении пробел(ы), поэтому предварительно нужно такие элементы массива превратить в "пусто". Это делается функцией trim(), а чтобы обойти этой функцией все элементы массива, можно воспользоваться функцией array_map(). В итоге все выглядит так:
<?
$arr = array_diff(array_map('trim', $arr), array(''));
//проверьте, теперь ваш массив не содержит пустых значений
|
Но как уже ранее замечалось, еще при разборе рег. выражениями можно задать условия, при котором не будут возвращаться пустые значения или пробелы. Это в другой раздел форума с объяснением того "что", и почему "не так как надо" получается. | |
|
|
|
|
|
|
|
для: sim5
(18.07.2010 в 13:37)
| | странно, почему то не работает ваш пример, делаю так:
<?
$arr = array_diff(array_map('trim', $arr), array(''));
//проверьте, теперь ваш массив не содержит пустых значений
$out = $out[0];
$out = array_diff(array_map('trim', $out), array(''));
//пробелы остаются..
?>
|
А как мне привести массив к виду как в вашем примере? | |
|
|
|
|
|
|
|
для: *m*
(18.07.2010 в 15:30)
| | Это ваш массив с двумя вложенными массивами (заметьте, что я сам добавил в некоторые значения пробелы и перевод строки):
<?
$out = array(
0 => array (
0 => 'Зеленый',
1 => '20м',
2 => '
',
3 => '',
4 => 'Красный',
5 => '20м',
6 => '',
7 => ' ',
8 => '',
9 => 'Синий',
10 => '20м',
11 => '',
12 => '',
13 => '',
14 => 'Зеленый',
15 => '20м',
16 => '',
17 => '',
18 => ' ',
19 => 'Синий',
20 => '20м'),
2 => array (
0 => 'Зеленый',
1 => '20м',
2 => ' ',
3 => '',
4 => 'Красный',
5 => '20м',
6 => '',
7 => ' ',
8 => '',
9 => 'Синий',
10 => '20м',
11 => '',
12 => '',
13 => '',
14 => 'Зеленый',
15 => '20м',
16 => '',
17 => '',
18 => ' ',
19 => 'Синий',
20 => '20м')
);
//удаляем второй вложенный массив
$out = $out[0];
//смотрим, что получилось
print "<pre>";
print_r($out);
?>
Array
(
[0] => Зеленый
[1] => 20м
[2] =>
[3] =>
[4] => Красный
[5] => 20м
[6] =>
[7] =>
[8] =>
[9] => Синий
[10] => 20м
[11] =>
[12] =>
[13] =>
[14] => Зеленый
[15] => 20м
[16] =>
[17] =>
[18] =>
[19] => Синий
[20] => 20м
)
<?
//удаляем из него пустые элементы
$out = array_diff(array_map('trim', $out), array(''));
//смотрим, что получилось
print "<pre>";
print_r($out);
?>
Array
(
[0] => Зеленый
[1] => 20м
[4] => Красный
[5] => 20м
[9] => Синий
[10] => 20м
[14] => Зеленый
[15] => 20м
[19] => Синий
[20] => 20м
)
|
Что у вас не работает? | |
|
|
|
|
|
|
|
для: sim5
(18.07.2010 в 16:10)
| | если скопировать ваш пример все работает, как нужно, но я пробую использовать ваш пример в своем скрипте - не работает. Решил по другому просто поменял рег выражение. и убрал все пробелы. но осталось несколько ключей просто пустых. | |
|
|
|
|
|
|
|
для: *m*
(18.07.2010 в 16:59)
| | Вы не копируйте мой пример слепо, а смотрите для какого массива он применим. У вас скорее всего массив, это некая "каша", а тут вы представляете не реальное содержимое его, на которое я ориентируюсь, а то, что вы хотели бы видеть. Иначе объяснить почему у вас не работает трудно.
Ваш разбор документа рег. выражением не отвечает нужным условиям, выдает лишнее, и что там у вас творится только вам известно. Сперва разберитесь с парсером документа в разделе рег. выражений, а уж потом применяйте то, что я вам писал. При паттерне учтывающем все "и", вы не будете получать ни грязи, не пустот...
Главное о чем нужно будет после этого позаботиться, это то, что исходный массив должен не только строго чередоваться группами данных для записи, но и быть кратен числу элементов в этой группе. Все остальное можно сделать уже просто, так как я и писал. | |
|
|
|
|
|
|
|
для: sim5
(18.07.2010 в 17:09)
| | так все теперь пустых ключей нет, все заполнены нужной информацией, как теперь привести массив к нужному виду? | |
|
|
|
|
|
|
|
для: *m*
(18.07.2010 в 17:53)
| | К какому виду? | |
|
|
|
|
|
|
|
для: 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м
)
...
|
| |
|
|
|
|
|
|
|
для: *m*
(18.07.2010 в 19:16)
| | Вы не должны просто "хлямзить" мой пример и вставлять его в свою подходящую задачу. Этот путь написания кода пагубный. Чуть изменяться условия вашей задачи, а смыл кода примера вы не понимаете, вот и застопорится все... А ведь то, что я привел в качестве примера, можно применить во многих ситуациях, и ни количество записываемых в базу данных, ни их тип не накладывает на этот пример никаких ограничений.
Подобным образом я могу обрабатывать массивы данных от формы возвращаемой пользователем, при этом в зависимости от полей формы будут автоматически формироваться как число/имена полей в MySQL запросе, так и сами данные. И проверку допустимых данных от пользователя я тоже могу не производить по принципу "for if OK else echo юзерамать туды сюды не то…", а опять по максимуму использовать стандартные РНР функции для работы с массивами.
Вам не слепо надо копировать то, что пишут вам, а понимать, что и для чего. В коде есть строка, которая "приводит" массив к нужному виду:
<?
$arr = array_chunk($arr, 2);
|
Вы должны понимать, для чего это сделано.
Какая перед вами стоит задача - записать массив данных в базу. Это можно сделать простым способом - пройтись по массиву циклом, получать необходимые данные, делаяя запрос к базе, вставляя их. Но этот способ нерационален, и чем больше будет "строк" данных для записи, тем более этот подход нерационален, ибо этот путь будет изобиловать лишними запросами к базе.
Задавшись вопросом – "возможно ли произвести запись в базу всех данных массива одним запросом", легко получить ответ – да. Достигается это с помощью многострочного оператора 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($a, create_function('&$s','$s = "(\'" .
implode("\',\'", array_map(mysql_real_escape_string, $s)) .
"\')";'));
$a = implode(',',$a);
}
?>
|
Теперь вся ваша задача записи массива в базу сводится к простому:
<?php
getStringForMySQL(&$out, 2);
mysql_query("INSERT INTO `table` (`name1`, `name2`) values " . $out);
?>
|
Заметьте, что в вызове функции указывается ссылка на массив, а не передается копия его в функцию, и функция не возвращает обработанный результат, а преобразует массив исходник. Если требуется сохранять исходный массив для дальнейших с ним действий, то следует передавать в функцию копию его и возвращать значение. Хотя не составляет труда сделать в функции два режима работы, то есть универсальной. Ну и как говорилось ранее, число полей формы, например, их имена (или имена могут служить ключами для реальных имен таблицы), могут позволить автоматически сформировать и (`name1`, `name2`) для запроса. Вот вам и универсальность.
Если нужно будет записать, например, по 10 полей данных, то просто передаем в функцию массив значений исходного массива, а вторым аргументом указываем 10, и получим небоходимоую строку для записи.
Вот это все вы должны понимать, а не только такую мелочь, как найти и понять, что делает строка кода $arr = array_chunk($arr, 2) в примере, чтобы вопросов "как привести массив к виду" у вас не возникало. | |
|
|
|
|
|
|
|
для: *m*
(16.07.2010 в 11:25)
| | В ответ на письмо
Я редко отвечаю на письма, но не потому, что я такой нехорший, считающий всех остальных снобами. ) Просто не всем даю свой адрес, и в этом нет ничего предосудительного. Не стоит благодарностей, правда. На то он и форум, и вы еще от многих участников этого форума познаете много полезного для себя. Я так полагаю. Чтобы не быть невежливым, отвечу так:
Что касается предложенного мною, так в этом ничего необычного нет, все получается естественно - коли ваши данные это массив, то почему бы не решать задачу с помощью инструментов предназначенных для этого. Если таковые имеются, то задача зачастую упрощается.
Коли вам что-то из вышеизложенного пригодилось, да и слава богу, можете развить далее. К примеру, подумайте, как вы решите следующее, использовав по максимуму уже готовые инструменты РНР. Для начала, измените функцию, ну например, так:
<?
function getStringForMySQL($a, $n, $r = false) {
$a = array_chunk($a, $n);
array_walk($a, create_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
(22.07.2010 в 00:49)
| | > Кроме этого, вы должны ответь еще на один вопрос, явно неуказанный - что обязательно нужно проверять при приеме такой формы?
В сессию можно записать это случайное имя формы, по приходе формы проверить, есть ли в сессии такая строка, если есть - вытягиваем для этой строки другие параметры(имя поля таблицы; является ли поле обязательным для заполнения и т.д. Т.е. каждое случайное имя надо писать в тот же самый массив, где другие параметры.
Или у вас была другая задумка? | |
|
|
|
|
|
|
|
для: Лена
(22.07.2010 в 22:22)
| | Если вы о "что обязательно нужно проверять при приеме такой формы?", то нет. Случайное имя поля формы и должно заноситься в массив описывающий эту форму.
Я имею ввиду иное - в данном случае вы возлагаете все на "скрипт-автомат", ему дано количество параметров, имена полей, а все остальное, это производное от них, и он должен во всем разобраться. Так что он должен проверить обязательно? | |
|
|
|
|
|
|
|
для: sim5
(22.07.2010 в 23:21)
| | Чтобы количество пришедших значений от формы совпадало с количеством массивов, которые описывают поведение поля формы, в сессии.
Если неправильно, уже как-то намекните. Я все-таки эту тему со второго захода осилила, длинная сильно :) | |
|
|
|
|
|
|
|
для: Лена
(22.07.2010 в 23:38)
| | Еще раз - в сессии описываются реальные имена полей и условия приема по ним данных. Какое количество данных должно прийти может быть и не указано (пользователю дан выбор). Ну и количество данных, это совсем еще не означает, что пришли ожидаемые данные (можете считать это намеком). | |
|
|
|
|
|
|
|
для: sim5
(22.07.2010 в 23:44)
| | Пользователь может же и не выбрать? И тогда придет пустое значение.Тогда по приходе формы надо сравнить, что выбрал пользователь и то, что описано в сессии, т.е определить значения, которые выбрал пользователь. | |
|
|
|
|
|
|
|
для: Лена
(22.07.2010 в 23:59)
| | Это проверки ошибок, они естественны, и вытекают из условия приема формы, которые описаны в сессии.
Нет, не это. ) | |
|
|
|
|