Форум: "Прочее";
Текущий архив: 2015.11.08;
Скачать: [xml.tar.bz2];
Внизjson буферизация отдачи (как) Найти похожие ветки
← →
кгшзх © (2015-03-25 14:18) [0]сейчас веб-сервер отдает результаты запроса в xml
формирует заголовочно-служебную часть, открывает рутовый узел для строк выборки и затем входит в цикл фетча данных
зафетчив необходимую порцию, он выводит эту порцию в виде чайлд узлов
и в конце цикла закрывает все теги.
Это так было.
сейчас необходимо отдавать все тоже самое, но в json
на ум приходит пока такой костыль:
в начале отдаем служебную часть:
{"success":true,"rows":[
затем такой же цикл фетча с накоплением $buff .=json_encode($datasetrow);
и в конце отдаем хвостик ]}
зачем надо?
выборка может быть многомегабайтной и fetchAll() делать нифига не хочется.
может кто решал буферизацию вывода json более гламурно чем описано здесь?
← →
megavoid © (2015-03-25 14:30) [1]смотря насколько многомегабайтнее
чуть гламурнее вот так:
$json = array("success" => true);
$json["rows"][] = $datasetrow;
echo json_encode( $json );
← →
кгшзх © (2015-03-25 14:44) [2]ну так здесь чтобы заполнить "rows" мне и требуется сделать fetchAll, от которого я хочу избавиться
← →
ухты © (2015-03-25 15:02) [3]зачем хвостики, отдавайте пустой объект а потом кусками ровы, в конце all=yes
както так
← →
кгшзх © (2015-03-25 15:12) [4]и как я этому безобразию сделаю декоде в браузере?
← →
кгшзх © (2015-03-25 15:20) [5]Схематично выглядит вот так:
результат содержит поле success + строки.
в качестве строк (здесь) массив из трех элементов.
Буферизация эмулируется построчным echo одной строки (в реале будут "пачки" строк фиксированной длины).
первое что категорически здесь не нравится - слежка за запятой внутри цикла (последняя порция или нет).
второе что совсем нафик не нравится : здесь у меня полный массив строк и количество строк мне известно.
но в реале когда я зафетчу скажем десяток строк и начну их выводить, то я нифига не знаю, есть там на сервере БД еще строки в выборке или нет.
Пока не начну фетчить новую порцию, я этого не узнаю.
это значит что подготовив очередной буфер, мне нельзя будет его выводить тут же, не выяснив есть еще данные или нет.function echo_glamourless($res, $rows){
echo "{"success":true,"rows":[";
$n = 0;
foreach($rows as $row){
echo json_encode($row).$b;
$n +=1;
if ($n < (count($rows))) {
echo ",";
}
}
echo "]}";
}
$res = array("success"=>true);
$rows = array( array("id"=>1, "name"=>"name1"),array("id"=>2, "name"=>"name2"),array("id"=>3, "name"=>"name3"));
echo_glamourless($res, $rows);
← →
DVM © (2015-03-25 15:23) [6]
> кгшзх ©
По-моему твой вариант с буфером с накоплением сериализованных в JSON строк вполне нормальное решение. Только я не понял, ты в буфер хочешь собрать все строки а потом отдать? Или отдаешь порциями?
← →
DVM © (2015-03-25 15:25) [7]
> Пока не начну фетчить новую порцию, я этого не узнаю.
>
> это значит что подготовив очередной буфер, мне нельзя будет
> его выводить тут же, не выяснив есть еще данные или нет.
>
Почему нельзя выводить?
← →
кгшзх © (2015-03-25 15:34) [8]Или отдаешь порциями?
Именно порциями.
фетчим скажем первую сотню записей.
енкодим их в буфер и выводим.
затем пробуем фетчить вторую сотню и так далее пока есть данные.
в итоге если у нас в выборке окажется лимон строк,
то сервер будет тратить память максимум на сто строк.
в общем если все делать через xmlwriter, (которому не нужен целиковый дом) - то все так и происходит. работаем только через райтер без костылей со строками.
вот и ищется некий аналог джейсон-класса, который работал бы в потоковом режиме.
Почему нельзя выводить?
Да можно выводить, это работает.
Но надо вручную проверять окончание выборки чтобы после последней порции не вставить лишнюю запятую.
← →
ухты © (2015-03-25 15:39) [9]выдаете массивы, никаких запятых, просто куски в браузере вставляете в объект, не строки
← →
кгшзх © (2015-03-25 15:44) [10]хорошо.
на пальцах:
если сделать вот так:
есhо json_encode($res);
есhо json_encode($rows);
то в браузере этот респонстекст не отдекодится в объект.
потому что ему на вход будет подано вот такое:
"success":true"rows:[........]
даже если я вставлю запятую:
"success":true,"rows:[........]
то все равно фик он его проглотит, потому что нет "охватывающего" объекта этим двум сущностям
то есть вместо возни на сервере будет возня с респонсом на клиенте.
← →
DVM © (2015-03-25 15:46) [11]
> Но надо вручную проверять окончание выборки чтобы после
> последней порции не вставить лишнюю запятую.
Тоже мне проблема, прямо корень зла :) В любом случае кто-то где-то проверять такое должен.
Выводи запятую всегда, просто если очередной fetch вернет EOF то вставь вместо последнего объекта null :{
"firstName": "Иван",
"lastName": "Иванов",
"addresses": [
{
"streetAddress": "Московское ш., 101, кв.101",
"city": "Ленинград",
"postalCode": 101101
},
null
]
}
← →
megavoid © (2015-03-25 15:56) [12]
function echo_g( $res, $rows )
{
if ($res)
{
$json = array( "success" => true );
foreach( $rows as $row )
$json["rows"][] = $row;
}
else
{
$json = array( "success" => false );
}
echo json_encode( $json );
}
echo_g( true, array("bla" => "bla") );
← →
кгшзх © (2015-03-25 16:04) [13]мега, ты несомненно хороший человек.
но не надо меня учить как напихать в один массив много других массивов.
все что ты написал, заменяется на одну единственную строку:echo json_encode(array("success"=>true, "rows"=>$dbStatement->fetchAll()));
проблема не в этом.
← →
ухты © (2015-03-25 16:19) [14]
> потому что ему на вход будет подано вот такое:
> "success":true"rows:[........]
>
> даже если я вставлю запятую:
> "success":true,"rows:[........]
так и не понял в чем проблема
не надо отдавать так, надо так
{..., rows:[]}
потом примерно так
{rows:[........]} или просто [....]
опять не про то?
просто наваждение какое то, все не так :)
← →
кгшзх © (2015-03-25 16:33) [15]проблема в том, что в джейсон можно сериализовать когда имеешь объект целиком.
имеем массив, добавляем в него полную выборку, енкодим и отдаем в браузер
в браузере делается обратный decode
и в результате внутри js имеем готовый объект.
для описанного случая вот такой:{success: true,
rows: [{...первая строка...},{вторая....},... {последняя}
]
}
проблема в том, что выборка может содержать много строк и если их всех зафетчить в массив, то памяти на сервере шибко сильно поубавится.
хочу не фетчить все сразу, а фетчить по сто строк.
и хочу отдать это в браузер как джейсон строку.
и чтобы в браузере одним вызовом сделать ей декоде и получить данные.
код из [5] делает это.
но в коде костыль.
костыль в том, что работая через json_encode мне еще приходится лепить костыли в виде рукопашно отсериализованного начала и конца респонса.
в приведенном выше случае это легко, так как в ответе кроме строк всего одно поле сукцесс.
но структура ответа может быть сложнее.
← →
Mystic © (2015-03-25 18:48) [16]
> код из [5] делает это.
> но в коде костыль.
> костыль в том, что работая через json_encode мне еще приходится
> лепить костыли в виде рукопашно отсериализованного начала
> и конца респонса.
Т. е. 10 строчек кода, которые решают твою конкретную проблему, тебя не устраивают, и ты желаешь иметь специальную библиотечную функцию для этого?
← →
ухты © (2015-03-25 19:08) [17]на клиенте не охота собирать объект, на сервере запятая мешает, ну есть вариант еще, собирать не просто джийсон, а скрипт, который евалом соберёт объект на клиенте
← →
Eraser © (2015-03-25 19:13) [18]
> кгшзх © (25.03.15 14:18)
выкинуть эти велосипеды и отдавать сразу и все с грамотно настроенными модулями кэша и сжатия.
что MS, что EMBC отдают свои дистрибутивы по http, и ничего, никто не жалуется )
в общем протестируй разные подходы. уверен все эти сложности окажутся лишними.
← →
кгшзх © (2015-03-25 19:27) [19]что MS, что EMBC отдают свои дистрибутивы по http, и ничего, никто не жалуется )
Не надо путать жопу с пальцем.
Дистрибутивы там на диске.
Отдать два гига с диска из похпапе не напрягая себя и память сервера - два пальца об асфальт.
А в вопросе выборка, которую либо тянуть в память либо костылями пользоваться.
тебя не устраивают, и ты желаешь иметь
Именно что не устраивают и не устраивают категорически.
И не по причине запятой.
Причина идеологическая.
Если я вывожу джейсон, и попутно мудохаюсь со строками (колхозя ручной джейсон) то это косяк.
Несмотря на то что все будет работать без запинки.
← →
megavoid © (2015-03-25 21:14) [20]А, я понял теперь, что требуется. Кстати, ничего, что после селекта строки всё равно уже находятся в памяти? И как относится браузерный клиент к миллиону записей? Имхо, идеологически правильно было бы не выдавать в клиент столько инфы, все равно человек не осилит, да и extjs (это ведь он на стороне клиента?) будет грустно, там есть прекрасные встроенные инструменты для пагинации.
← →
кгшзх © (2015-03-25 21:54) [21]Кстати, ничего, что после селекта строки всё равно уже находятся в памяти?
они не находятся в памяти все.
если только не вызван fetchAll, или если выборка меньше чем размер префетча самой дб-библиотеки
Страницы: 1 вся ветка
Форум: "Прочее";
Текущий архив: 2015.11.08;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.002 c