Время между запросами в Zend 2

У меня есть вопрос о Zend Framework 2. Я хочу узнать, сколько времени занимает выполнение запроса, и я знаю, что это возможно с помощью Zend MVCEvent, но я не знаю, как это сделать.


person Serban Alexandru    schedule 19.08.2014    source источник


Ответы (3)


лучшее решение, на мой взгляд, - заменить специальную переменную внутри ваших файлов шаблонов, как это

{{ renderTime }}

так что вы можете свободно контролировать положение текста и не путать модели ответов json в своем приложении zf.

позвольте мне объяснить, почему я не подключаюсь к событию \Zend\View\ViewEvent::EVENT_RENDERER и не заменяю свою переменную непосредственно в Response на событии FINISH.

в основном вы не можете использовать другие события, потому что страница не отображается в любое время, и все функции/вьюхелперы в вашем шаблоне в настоящее время не выполняются, и поэтому время будет меньше, чем реальное время рендеринга.

Событие \Zend\View\ViewEvent::EVENT_RENDERER_POST нехорошо, потому что ваше представление отображается правильно, но приложение еще не выполнено, и, возможно, все зарегистрированные события и т. д., которые следуют, еще не выполнены.

если вам нравится моя идея, то ваш index.php будет выглядеть так

<?php
/**
 * This makes our life easier when dealing with paths. Everything is relative
 * to the application root now.
 */
chdir(dirname(__DIR__));
define('STARTTIME', microtime(true));

// Decline static file requests back to the PHP built-in webserver
if (php_sapi_name() === 'cli-server' && is_file(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH))) {
    return false;
}

// Setup autoloading
require 'init_autoloader.php';

// Run the application!
Zend\Mvc\Application::init(require 'config/application.config.php')->run();

и ваш метод module.php onBootstrap станет таким

$e->getApplication()->getEventManager()->attach(\Zend\Mvc\MvcEvent::EVENT_FINISH, function($e){
    /** @var $e \Zend\Mvc\MvcEvent */
    if( $e->getResult() instanceof \Zend\View\Model\ViewModel )
    {
        $renderText = sprintf('page render time - %s seconds', number_format(microtime(true) - STARTTIME, 5));

        /** @var \Zend\Http\PhpEnvironment\Response $response */
        $response = $e->getResponse();
        $response->setContent(
            str_replace('{{ renderTime }}', $renderText, $response->getContent())
        );
    }
}, 100000);

и в вашем наборе файлов шаблона/макета, где вы хотите ввести время рендеринга с помощью {{ renderTime }}

<h1>Hello Friends!</h1>
<div>some content</div>
<div class="footer">
    {{ renderTime }}
</div>

что теперь дает вам page render time - 0.67307 seconds

person ins0    schedule 20.08.2014
comment
Вы говорите, что если я инициализирую время начала в событии DISPATCH и время окончания в событии FINISH, возможно, что не все запросы будут выполнены? И я вижу, что вы инициализируете время окончания в событии FINIS, но время начала прямо в методе начальной загрузки, поэтому Вы говорите, что, поскольку мое время начала указано в методе DISPATCH, а ваше в методе начальной загрузки, я теряю некоторое время запроса? Я сделал это, потому что я понимаю из документации Zend, что запрос начинается с триггера DISPATCH Event и заканчивается, когда триггер FINISH Event. Не могли бы вы объясните мне, каков именно поток запросов в вашем видении? Спасибо! - person Serban Alexandru; 20.08.2014
comment
это верно, даже когда вы устанавливаете время запуска в методе onBootstrap, вы упускаете некоторое время, когда zend должен загрузить ваше приложение/маршрутизацию и т. д. ваш ответ в порядке, но не очень хорош, потому что вы захватываете класс request, чтобы доставить время рендеринга, и у вас нет времени. controll, где ваше время рендеринга будет отображаться на клиенте (внизу — без контроля), также вы испортите модели просмотра json, потому что каждый раз, когда ваш ответ добавляется к прямому выводу клиента. я редактирую свой ответ - person ins0; 20.08.2014
comment
Я понимаю, что вы говорите о позиции на странице, но я не принял это во внимание, моя первая цель состояла в том, чтобы каким-то образом определить время запроса с помощью MVC Event, тогда я могу делать какие-то трюки, чтобы поместить время туда, где я хочу, например тот, который вы сделали с setContent, и, возможно, есть другие возможности, но я еще не думал о них, я просто хотел посмотреть, как поток запросов со стороны MVC Event и как использовать event-›attach для выполнения действий в определенный момент приложение, например, до начала запроса и после завершения, это было целью приложения, чтобы привыкнуть к запросу - person Serban Alexandru; 20.08.2014
comment
Flow и MVC Event, потому что я только начал изучать Zend 2 несколько дней назад и хотел лучше понять, как идут дела. - person Serban Alexandru; 20.08.2014
comment
Я добавил ваше решение, и вы правы, это разница во времени, у меня 0,014517068862915 секунд, а у вас 0,07570 секунд. Но я был бы очень признателен, если бы вы могли рассказать мне несколько о том, в каком именно порядке Zend делает что-то по запросу, поэтому я можно увидеть, где я теряю это время. Спасибо! - person Serban Alexandru; 20.08.2014
comment
лучше всего посмотреть исходный код репозитория zf2 (Zend\Mvc\Application) и понять, где и почему события запускаются из zend. это сложно объяснить здесь, но основы написаны здесь framework.zend.com/manual/2.1/en/modules/ - person ins0; 20.08.2014
comment
Спасибо, кажется, что время между index.php и DISPATCH EVENT потеряно, я попытаюсь посмотреть в Application и надеюсь, что смогу увидеть поток вещей, даже если код сейчас немного сложен для меня. - person Serban Alexandru; 20.08.2014
comment
да в первый раз zf2 кажется таким DAFUQ но через некоторое время попадаешь в точку ;) - person ins0; 20.08.2014

Это не совсем отвечает на ваш вопрос, но я думаю, вы могли бы сделать это, используя REQUEST_TIME, который вы можете получить с сервера запросов. Что-то вроде этого :

 $startTime = $mvcEvent->getRequest()->getServer()->get('REQUEST_TIME');

И затем в конце запроса:

 $endTime = microtime(true);

Я не уверен, но думаю, что этот модуль ZendDeveloperTools позволяет отображать время выполнения.

person blackbishop    schedule 19.08.2014
comment
Спасибо за ваш ответ, на самом деле это не то, что я хочу, я тоже сначала пришел с этим подходом: $eventManager-›attach(MvcEvent::EVENT_FINISH,function($e){ $p=$e-›getParams(); Время:'.(микровремя(ИСТИНА)-$p['запрос']›getServer('REQUEST_TIME')).' секунды'; }); - person Serban Alexandru; 19.08.2014
comment
Но этого недостаточно, потому что я не хочу зависеть от сервера apache, мне нужно что-то, что могло бы работать на любом сервере. Теперь я пытаюсь сделать что-то вроде получения микровремени (true) в MvcEvent::EVENT_DISPATCH и в MvcEvent:: EVENT_FINISH и имеет значение, но я не знаю, как получить значение микровремени из обратного вызова EVENT_DISPATCH, который я прикрепляю. - person Serban Alexandru; 19.08.2014
comment
@SerbanAlexandru Вы можете добавлять произвольные значения в экземпляр события. $mvcEvent->setParam('startTime', $value) и $mvcEvent->getParam('startTime') в более позднем слушателе. - person AlexP; 19.08.2014
comment
Я знаю, но для MvcEvent::Event_DISPATCH требуется экземпляр MvcEvent, когда вы хотите его запустить, а не экземпляр MvcEvent\Event, если я понимаю, что вы хотели сделать. - person Serban Alexandru; 19.08.2014
comment
В любом случае, я нашел другой способ, наконец, я отвечу на него. - person Serban Alexandru; 19.08.2014

Это решение, которое я придумал, код написан в Module.php в модуле, который я хочу отображать на каждой странице:

 public function onBootstrap(MvcEvent $e)
{
    $eventManager        = $e->getApplication()->getEventManager();
    $moduleRouteListener = new ModuleRouteListener();
    $checklistener=new CheckListener();
    $checklistener->attach($eventManager);
    $addyearlistener=new AddyearListener();
    $addyearlistener->attach($eventManager);
    $moduleRouteListener->attach($eventManager);
    //request time
    $eventManager->attach(MvcEvent::EVENT_DISPATCH,function($e){
        $param=new Parameters(array('time' => microtime(TRUE)));
        $e->getApplication()->getRequest()->setPost($param);
        $e->getApplication()->getEventManager()->attach(MvcEvent::EVENT_FINISH, function($e){
           echo 'Time:'. (microtime(TRUE)-$e->getRequest()->getPost('time')).' seconds'; 
        });

    });

}
person Serban Alexandru    schedule 19.08.2014