Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 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
15-1427097672
кгшзх
2015-03-23 11:01
2015.11.08
квест


15-1426683289
Piter
2015-03-18 15:54
2015.11.08
Delphi как инструмент для зарабатывания денег


2-1401695334
lewka_s
2014-06-02 11:48
2015.11.08
Проблема соединения с SQL Server


15-1427039153
AndrewAndrey
2015-03-22 18:45
2015.11.08
digital signage решения


15-1426973404
Юрий
2015-03-22 00:30
2015.11.08
С днем рождения ! 22 марта 2015 воскресенье





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский