I have a question about Zend Framework 2.I want to find out how much time take to complete a request and I know that it should be possible using Zend MVCEvent but I don't know how.
问题:
回答1:
a better solution in my mind is to replace a special variable inside your template files like this
{{ renderTime }}
so you are free to controll the text position and don't mess up json response models in your zf application.
let me explain why i don't hook up into the \Zend\View\ViewEvent::EVENT_RENDERER
event and replace my variable directly in the Response
at the FINISH
event.
basically you can't use the other events, because the page is not rendered at any time and all the functions/viewhelper into your template are currently not done and so the time would be less then the real render time.
The \Zend\View\ViewEvent::EVENT_RENDERER_POST
Event is not good because - your view is rendered thats true - but the application is not done and maybee all the registered events etc that follow are not executed yet.
if you like my idea than your index.php
would look like this
<?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();
and your module.php
onBootstrap
method would become this
$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);
and in your template/layout file set where you wish to inject the rendertime with {{ renderTime }}
<h1>Hello Friends!</h1>
<div>some content</div>
<div class="footer">
{{ renderTime }}
</div>
that now gives you page render time - 0.67307 seconds
回答2:
This don't exactly answer your question but I think you could do such a thing using the REQUEST_TIME
that you can get from the request server. Something like this :
$startTime = $mvcEvent->getRequest()->getServer()->get('REQUEST_TIME');
And then at the end of the request :
$endTime = microtime(true);
I'm not sure but I think this module ZendDeveloperTools permits to show the execution time.
回答3:
This is the solution I've came up with,the code is write in Module.php on the Module that I want to display request time on every page:
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';
});
});
}