Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2015.11.08;
Скачать: CL | DM;

Вниз

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;
Скачать: CL | DM;

Наверх




Память: 0.53 MB
Время: 0.006 c
2-1402078384
0w1
2014-06-06 22:13
2015.11.08
создание бд аэропорта


2-1401973992
Дмитрий
2014-06-05 17:13
2015.11.08
как создавать столбцы в excel- при его отсутствии на ПК


15-1427097672
кгшзх
2015-03-23 11:01
2015.11.08
квест


2-1401924262
Sakipiel
2014-06-05 03:24
2015.11.08
Зацикливается Чтение свойстсва функцией


15-1426696739
Pavelnk
2015-03-18 19:38
2015.11.08
DWD-RW