Передача массива через форму

Статус
В этой теме нельзя размещать новые ответы.
так так и ввыводит.
может для ТС передача массива и строки Array одно и тоже :eek:
 
Для того, чтобы вывести куда-нибудь массив, его надо сначала преобразовать в строку.

Можно воспользоваться стандартным преобразованием типов php - но оно для любого массива возвращает 'Array'. Т.е. не зависимо от того, что там у тебя в массиве были за элементы и сколько их было - после перевода будет получаться одна и та же строка 'Array'. Некруто.

Можно самому составить строку, содержащую подряд все элементы массива:

PHP:
$a = array(1,2,3,'txt',6);
$s = '';
foreach($a as $element) $s .= '|' . $element;
echo $s;

Получим строку '|1|2|3|txt|6' - уже лучше. Если массив одномерный, а ключи массива не нужны, то этот вариант в принципе имеет право на жизнь. В php есть даже пара специальных функций - explode и implode - для преобразования массива в строку и обратно по такому вот алгоритму. Читай php.net/implode - там подробно и с примерами. И еще есть пара похожих функций - split / join. Там же.


Если же массив многомерный, или имеет вложенные масивы, или нам важно сохранить не только значения, но и ключи - тогда вместо explode / implode нам следует использовать serialize / unserialize. Эти функции тоже перегоняют массив в строку и обратно, но делают это намного качественней. Правда и строка получается менее читабельная, но зато обратно в массив превращается без проблем. Читай php.net/serialize


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

Код:
<input type=hidden name='postval' 
value="<?=serialize($_POST)?>"

то при сабмите этой формы тебе придет переменная $_REQUEST['postval'] содержащая строку в которой зашифрован весь прошлый массив $_POST. Достать его оттуда можно очень просто:

PHP:
$arr = unserialize($_POST['postval']);
$_POST=array_merge($_POST, $arr);

этим мы вытащили старый массив $_POST, и присоединили его к текущему массиву $_POST. Если я правильно тебя понял, задача состояла именно в этом.


Важная ремарка:
Строка, которая получается после serialize(массив) может содержать непечатаемые символы. Которые после отправки в форму и последующего сабмита могут исчезнуть. В результате ты получишь не ту строку, что отправлял, и она у тебя обратно в массив не рассериализуется. Чтобы этого избежать, перед отправкой строки мы преобразуем ее в печатный вид командой base64_encode, а получив обратно - вернем в исходную перед тем, как начать доставать из нее массив. См здесь: php.net/base64_encode

Получаем нечто такое:

PHP:
<input type=hidden name='prevpost' value =
"<?=base64_encode(gzcompress(serialize($_POST)))?>"

....
<?
$str = $_POST['prevpost'];
$str = base64_decode($str);
$str = gzuncompress($str);
$arr = unserialize($str);
unset($_POST['prevpost']);
$_POST = array_merge($arr, $_POST);


Здесь используется еще gzcompress для уменьшения размера передаваемой строки (этого делать не обязательно), а также удаляется старое значение 'prevpost' из массива $_POST, чтоб оно там не накапливалось. Иначе если ты много раз будешь этот $_POST отправлять в форму, он у тебя с каждым разом будет содержать весь предыдущий массив + еще новые поля, т.е. фактически будет распухать в два раза после каждого сабмита.

To Lonely Wolf: Извини, что я фактически твой же пост просто еще раз написал, но просто мне показалось что лучше объяснить, что там и откуда берется..
 
Да если есть свободное время и желание расписывать миллион первый раз для тех кто не может зайти в гугл то я ничего против не имею :)

Есть тока вопросы по ману,
во-первых: зачем использовать gzcompress()/gzuncompress()?
во-вторых: объеденение массива и строковой переменной не понятно $_POST = array_merge($arr, $_POST);
ну и как обычно в-третьих:
Код:
[COLOR=#000000][COLOR=#0000bb]$a [/COLOR][COLOR=#007700]= array([/COLOR][COLOR=#0000bb]1[/COLOR][COLOR=#007700],[/COLOR][COLOR=#0000bb]2[/COLOR][COLOR=#007700],[/COLOR][COLOR=#0000bb]3[/COLOR][COLOR=#007700],[/COLOR][COLOR=#dd0000]'txt'[/COLOR][COLOR=#007700],[/COLOR][COLOR=#0000bb]6[/COLOR][COLOR=#007700]); 
[/COLOR][COLOR=#0000bb]$s [/COLOR][COLOR=#007700]= [/COLOR][COLOR=#dd0000]''[/COLOR][COLOR=#007700]; 
foreach([/COLOR][COLOR=#0000bb]$a [/COLOR][COLOR=#007700]as [/COLOR][COLOR=#0000bb]$element[/COLOR][COLOR=#007700]) [/COLOR][COLOR=#0000bb]$s [/COLOR][COLOR=#007700].= [/COLOR][COLOR=#dd0000]'|' [/COLOR][COLOR=#007700]. [/COLOR][COLOR=#0000bb]$element[/COLOR][COLOR=#007700]; 
echo [/COLOR][COLOR=#0000bb]$s[/COLOR][COLOR=#007700];  [/COLOR][/COLOR]
это делается проще так:
Код:
[COLOR=#000000][COLOR=#0000bb]$a [/COLOR][COLOR=#007700]= array([/COLOR][COLOR=#0000bb]1[/COLOR][COLOR=#007700],[/COLOR][COLOR=#0000bb]2[/COLOR][COLOR=#007700],[/COLOR][COLOR=#0000bb]3[/COLOR][COLOR=#007700],[/COLOR][COLOR=#dd0000]'txt'[/COLOR][COLOR=#007700],[/COLOR][COLOR=#0000bb]6[/COLOR][COLOR=#007700]); 
[/COLOR][COLOR=#007700]echo implode('|',[/COLOR][COLOR=#0000bb]$a)[/COLOR][COLOR=#007700];  [/COLOR][/COLOR]
и так же просто обратно:
Код:
[COLOR=#000000][COLOR=#007700]$a = explode('|',[/COLOR][COLOR=#0000bb]$_POST['a'])[/COLOR][COLOR=#007700];[/COLOR][/COLOR]
:)
 
Lonely Wolf написал(а):
во-первых: зачем использовать gzcompress()/gzuncompress()?

venetu написал(а):
Здесь используется еще gzcompress для уменьшения размера передаваемой строки (этого делать не обязательно)


Lonely Wolf написал(а):
во-вторых: объеденение массива и строковой переменной не понятно


venetu написал(а):
$arr = unserialize($_POST['postval']);
$_POST=array_merge($_POST, $arr);
unserialize возвращает array, он мерджится с другим array


Lonely Wolf написал(а):
ну и как обычно в-третьих:
....
это делается проще так:
....

venetu написал(а):
В php есть даже пара специальных функций - explode и implode - для преобразования массива в строку и обратно по такому вот алгоритму.


Надеюсь ответил на твои вопросы!
ay.gif
 
Блин по второму вопросу извиняюсь не обратил внимание, что в результате мы в post всё складываем, думал нафик это всё объединять, хотя и на самом деле всё равно же разбирать этот массив зачем его увеличивать :)
 
echo не применимо к массивам.
Блин, действительно же... Туплю

а также удаляется старое значение 'prevpost' из массива $_POST, чтоб оно там не накапливалось. Иначе если ты много раз будешь этот $_POST отправлять в форму, он у тебя с каждым разом будет содержать весь предыдущий массив + еще новые поля, т.е. фактически будет распухать в два раза после каждого сабмита.
А после выполнения скрипта $_POST не обнуляется?
 
А после выполнения скрипта $_POST не обнуляется?

Ну смотри, возьмем простой пример: в $_POST у тебя один элемент: "id" => 1.

После первого сабмита тебе передастся в $_POST уже два значения: "id" => 1 и "prevpost" => "{id:1}".

Если prevpost сейчас не убрать из массива $_POST, то в форму отправится уже и prevpost тоже, в результате после второго сабмита ты получишь такое:

"id" => 1,
"prevpost" => "{id:1;prevpost:{id:1}}"


После третьего сабмита будет уже так:

"id" => 1,
"prevpost" => "{id:1;prevpost:{id:1;prevpost:{id:1}}}"


ну и так далее.

При serialize($_POST) у тебя в строку отправятся все значения из этого $_POST, включая и prevpost, который содержит все предыдущие значения $_POST, а также прошлый prevpost, в котором есть позапрошлый prevpost и т.д. Вот о чем я говорю.
 
А есть еще какойнить способ передачи массива не применяя serialize с сохранением структуры
Так как передаеться ассоциативный многомерный массив примерно 100к строк, чет не вариант его использовать
 
в $_SESSION пишешь, там храниться в файле в темпе, дальше вытаскиваешь. В форме передаёшь id сессии.
 
Статус
В этой теме нельзя размещать новые ответы.
Назад
Сверху