PHP + Yii2 + output_buffering

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Ответить
guest_guest
Сообщения: 4
Зарегистрирован: 2018.05.24, 07:53

PHP + Yii2 + output_buffering

Сообщение guest_guest »

Привет всем.
Пытаюсь заюзать Yii2, но что-то безуспешно.
Суть. При открытии страницы, отрабатывается JS, который ajax'ом вытягивает данные из СУБД. И вот, когда количество разом выгружаемых данных перевалило за 4096 знаков, данные из БД перестали приходить. Долго гуглил и не нагуглил. Думал, что проблема в БД, JS, где угодно, но не в php. Оказалось, в php есть такой параметр output_buffering который разработчики настоятельно рекомендуют не трогать по причине работает-не_лезь. Вот и думаю. Сейчас около 37 объектов, по которым выгружается 4102 байта инфы. Объектов планируется около 2200, т.е. 256Кб было бы шикарно, а лучше 512КБ, но это все рискует сдохнуть.

Как быть?

Спасибо.
Nex-Otaku
Сообщения: 831
Зарегистрирован: 2016.07.09, 21:07

Re: PHP + Yii2 + output_buffering

Сообщение Nex-Otaku »

При чём тут "output_buffering"?

Размер данных значения не имеет, может иметь значение только время выполнения скрипта, так как оно ограничено. Может, SQL-запрос просто медленный и скрипт умирает, не дождавшись его выполнения? Также ограничено количество данных, которые вы можете отправить на сервер, но получаемые с сервера данные могут быть сколько угодно большими.
guest_guest
Сообщения: 4
Зарегистрирован: 2018.05.24, 07:53

Re: PHP + Yii2 + output_buffering

Сообщение guest_guest »

Nex-Otaku писал(а): 2018.05.24, 09:43 При чём тут "output_buffering"?
Я же говорю, что в php.ini параметр output_buffering выставлен в 4096 по дефолту и ппц как не рекомендуется его трогать. Т.е. суть вот какая.
Страница отправляет на ajax-документ данные, по данным происходит выборка, данные из БД препарируются в json_encode и как дело доходит до echo - если размер до 4096 - все норм. Больше - тишина. Дока к пхп говорит, что данные пилиться должны, кратно 4096. Пришло у тебя 4102, значит передача пойдет в 2 этапа. Сначала 4096, затем еще 6 байт. Тут такого не происходит, мне система просто пишет в лог строку в которой ошибка, а в консоль.лог падает инфа, что url корявая.

Как заставить её ходить в 2 блока мне и интересно. Я могу бесконечно долго задирать параметр output_buffering. На данный момент - 8192. Если дело дойдет до продакшна, то там это значение будет около мегабайта, что приведет к паникам самого процесса и сбоям в работе. Никому это не нужно, естественно.
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: PHP + Yii2 + output_buffering

Сообщение skynin »

guest_guest писал(а): 2018.05.24, 18:10 как дело доходит до echo - если размер до 4096 - все норм. Больше - тишина. Дока к пхп говорит, что данные пилиться должны, кратно 4096.
сброс=отдача содержимого буфера происходит при закрытии соединения или по внутреннему таймеру. то есть работает все давно надежно.
никакой там тонкости нет, если сами не вмешиваетесь в его работу функциями ob_*

тогда разберитесь с ob_implicit_flush()
guest_guest писал(а): 2018.05.24, 18:10 Как заставить её ходить в 2 блока мне и интересно.
разобраться в своем коде, а не коде php движка

может еще с настройками веб-сервера быть что-то нетипичное.

но точно проблема не в размере output_buffering
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
guest_guest
Сообщения: 4
Зарегистрирован: 2018.05.24, 07:53

Re: PHP + Yii2 + output_buffering

Сообщение guest_guest »

skynin писал(а): 2018.05.24, 18:34 разобраться в своем коде, а не коде php движка
Мой код.
По клику на кнопку выполняется функция JS:

Код: Выделить всё

	function getAllEventsInRange(start, end) {
		
		$.ajax({
			url: 'index.php?r=calendar/get-events-day',
			dataType: 'json',
			type: 'post',
			async: false,
			data: { 
				'start' : start, 'end' : end	
			},
		}).done(function ( callback ) {
			returnCallback(callback);
		}).fail(function ( error, error_txt ) {
			console.log(error);
		});
	};
В контроллере это

Код: Выделить всё

 public function actionGetEventsDay() {
        //$query3 = "SELECT id, eventname AS title, eventtext as description, CONCAT(eventdate, 'T', eventtime) AS start, eventcolor AS color FROM addevent_form WHERE eventdate BETWEEN '" . $_POST["start"] .  "' AND '"  . $_POST["end"] ."'" ;   //All events

        $query3 = "SELECT *  FROM addevent_form " ;   

        $allEventsOnDays = ActiveRecord::findBySql($query3)->asArray()->all();

        $myjson = json_encode($allEventsOnDays);

        if ($myjson)
            //echo strlen($myjson);
            echo $myjson;
        else
            echo json_last_error_msg();
    }
Как-то так. Запрос я привел крайне упрощенный, в реальности там 2 JOIN'а и выборка по времени.
В логи падает ругань именно на echo $myjson;
skynin писал(а): 2018.05.24, 18:34 если сами не вмешиваетесь в его работу функциями ob_*
Не вмешиваюсь
skynin писал(а): 2018.05.24, 18:34 может еще с настройками веб-сервера быть что-то нетипичное.
Именно. Установил из коробки и правлю output_buffering
skynin
Сообщения: 400
Зарегистрирован: 2017.12.12, 10:09

Re: PHP + Yii2 + output_buffering

Сообщение skynin »

теперь понятней.
actionGetEventsDay() написан неправильно. не по Yii2.

надо, для вашей задачи

1. наследовать контроллер от \yii\rest\Controller
2. прописать в конфиг
'components' => 'request' => [
...
'parsers' => [
'application/json' => 'yii\web\JsonParser',
],
],
...
3.
contentType : 'application/json',

4.
и тогда

Код: Выделить всё

public function actionGetEventsDay() {
        //$query3 = "SELECT id, eventname AS title, eventtext as description, CONCAT(eventdate, 'T', eventtime) AS start, eventcolor AS color FROM addevent_form WHERE eventdate BETWEEN '" . $_POST["start"] .  "' AND '"  . $_POST["end"] ."'" ;   //All events

        $query3 = "SELECT *  FROM addevent_form " ;   

        $allEventsOnDays = ActiveRecord::findBySql($query3)->asArray()->all();
		
	return $allEventsOnDays;
    }
то есть output_buffering вообще ни при чем, вы не разобрались с Yii2, и он потому генерирует неправильный ответ.

в контроллерах не должно быть никакого echo.

Для отдачи json написал выше

Для ручной работы с запросом и ответом в web контроллере надо использовать yii\base\Request yii\base\Response
Или использовать предствления, которые формируют правильный Response:
return $this->render(...

-- Не вмешиваюсь
а вмешались :)
Вы не даете движку Yii2 формировать ответ, неожиданным для него echo

я бы конечно и это
url: 'index.php?r=calendar/get-events-day',
заменил на
url: '/calendar/get-events-day',

Код: Выделить всё

'components' => [
    // ...
    'urlManager' => [
        'class' => 'yii\web\UrlManager',
        // Hide index.php
        'showScriptName' => false,
        // Use pretty URLs
        'enablePrettyUrl' => true,
        'rules' => [
        ],
    ],
    // ...
],
вобщем - изучайте Yii2. или не используйте его вообще, если хотите просто писать echo и все делать самостоятельно.

например вы и с базой данных работаете сами, не по Yii2:

Код: Выделить всё

$query3 = "SELECT *  FROM addevent_form " ; 
ActiveRecord::findBySql($query3)->asArray()->all();
зачем вам Yii2?
Не желайте странного, и не будет у вас головной боли чтобы достичь этого странного.
Тем более что окажется что оно вам и не нужно было, странное это.
someweb
Сообщения: 552
Зарегистрирован: 2017.03.09, 10:12

Re: PHP + Yii2 + output_buffering

Сообщение someweb »

Да в принципе и этот код будет работать, только некрасиво: echo на return заменить и все.
Чтобы правильно задать вопрос, нужно знать бо́льшую часть ответа. Роберт Шекли.
urichalex
Сообщения: 994
Зарегистрирован: 2015.08.07, 11:03

Re: PHP + Yii2 + output_buffering

Сообщение urichalex »

return $this->asJson($myData);
guest_guest
Сообщения: 4
Зарегистрирован: 2018.05.24, 07:53

Re: PHP + Yii2 + output_buffering

Сообщение guest_guest »

someweb писал(а): 2018.05.25, 09:27 Да в принципе и этот код будет работать, только некрасиво: echo на return заменить и все.
Ну.. да. Помогло. Спасибо.
skynin писал(а): 2018.05.25, 09:04 теперь понятней.
actionGetEventsDay() написан неправильно. не по Yii2.
Понял. Исправлю немного позже.

Всем спасибо за ответы. Думаю, что тема решена.
Ответить