1

I want to print in every page of my site, which is in ZF2, the request execution time.

I have already defined a constant within the index.php (which is the first file the request access) with the request initial microtime(true).
Now, where should I get the request final microtime(true)?

My plan is to have something like this:

$executionTime = ($finalTime - $initialTime) / 1000000; // in seconds
$executionTime = number_format($executionTime, 2);
Edson Horacio Junior
  • 3,033
  • 2
  • 29
  • 50
  • The exactly answer on your question http://stackoverflow.com/a/32646823/949273 – tasmaniski Jun 09 '16 at 21:58
  • @tasmaniski That doesn't clarify what is the `end` place I should use microtime. – Edson Horacio Junior Jun 10 '16 at 12:33
  • The end is the end of a index.php file. So add that line at the end of file. – tasmaniski Jun 10 '16 at 12:49
  • @tasmaniski I need to get the microtime as closest as possible to the end of the execution but still inside the ZF2's run, so I can print that in my views. If i do it at the end of index.php file, it's out of ZF2 run and it's no use to me because I can't show it inside the application. – Edson Horacio Junior Jun 10 '16 at 13:03

5 Answers5

3

The problem is that you probably want to add this information to the view (so the user can see it) which would mean adding the time before you render the view (before MvcEvent::EVENT_RENDER). The problem is though that the view is rendered way before MvcEvent::EVENT_FINISH is triggered so the time would not be accurate. This won't be easy to solve...


You could consider adding some time related header inside your response. Here an interesting related question about adding your custom headers.

  • There is for example a $request_time variable for NGinx which you could use out-of-the-box:

    $request_time
    request processing time in seconds with a milliseconds resolution (1.3.9, 1.2.6); time elapsed since the first bytes were read from the client

    add_header X-Request-Time $request_time always;
    
  • There is also an Age response header field. You can find it here in the Header Field Definitions section 14.6 in RFC2616.

    The Age response-header field conveys the sender's estimate of the amount of time since the response (or its revalidation) was generated at the origin server. A cached response is "fresh" if its age does not exceed its freshness lifetime. Age values are calculated as specified in section 13.2.3.

    Maybe you could use it to calculate the time it took to process the request on the server.

You could also add a custom header in your ZF2 application by adding some code to your Module.php like this:

function onBootstrap(MvcEvent $event) {
    $application = $event->getApplication();
    $eventManager = $application->getEventManager();
    $eventManager->attach(MvcEvent::EVENT_FINISH, [$this, 'addTimeHeader']);

    //...
}

function addTimeHeader(MvcEvent $event) {
    $time = // get your time value
    $response = $event->getResponse();
    $response->getHeaders()->addHeaderLine('X-Request-Time', $time);
}

The issue will still be to get this data inside your view. If you use an AJAX request it will be easy to get the header from the response, but if you don't use AJAX it is a whole different story. Read more here in this answer.

Community
  • 1
  • 1
Wilt
  • 41,477
  • 12
  • 152
  • 203
2

To achieve what you ask, and some more, in a development environment, you could use the Zend Developer Tools modules, which will automatically give you some informations regarding your application.

In a production environment, you could instead listen to the MvcEvent::EVENT_FINISH, that is the last event emitted by the Zend framework MVC

marcosh
  • 8,780
  • 5
  • 44
  • 74
  • I want to do that in production environment to show in every page, as kind of a proof to users that the system is not slow. – Edson Horacio Junior Jun 10 '16 at 12:35
  • 1
    ok, so my solution is definitely not what you're looking for. Then I would suggest you to attach to the MvcEvent::EVENT_FINISH (http://framework.zend.com/manual/current/en/modules/zend.mvc.mvc-event.html#order-of-events) – marcosh Jun 10 '16 at 14:34
  • Awesome! If you edit your answer for that I'll accept it, I'd apreciate an example too (: – Edson Horacio Junior Jun 10 '16 at 14:42
  • edited the answer... I'm sorry but at the moment I'm short of time for the example... – marcosh Jun 10 '16 at 14:58
  • The problem is that you probably want to add this information to the view (so the user can see it) which would mean adding the time before you render the view (before `MvcEvent::EVENT_RENDER`). The problem is though that the view is rendered way before `MvcEvent::EVENT_FINISH` is triggered. This won't be an easy fix... – Wilt Jun 11 '16 at 11:09
0

If you want to be a really dirty, add in your index.php file at beginning:

$_GET['the_time'] = round(microtime(true) * 1000);

Wherever you want in the view or layout print:

echo round(microtime(true) * 1000) - $_GET['the_time'];
// Use $_GET as global variable 

Note: The rest of developers will probably hate you.

tasmaniski
  • 4,767
  • 3
  • 33
  • 65
0

My solution is based on this answer.

Every view of mine has a footer.phtml attached to it, so if I print it there, there will be no need to change many files.

To print the time there, first I wrote something specific to that footer.phtml, for example Execution time:

Than in module/Application/Module.php I added this code to onBootstrap()

$eventManager->attach(\Zend\Mvc\MvcEvent::EVENT_FINISH, function($e) {
    $time = microtime(true) - REQUEST_MICROTIME;

    // formatting time to be more friendly
    if ($time <= 60) {
        $timeF = number_format($time, 2, ',', '.').'s'; // conversion to seconds

    } else {
        $resto  = fmod($time, 60);
        $minuto = number_format($time / 60, 0);
        $timeF = sprintf('%dm%02ds', $minuto, $resto); // conversion to minutes and seconds
    }

    // Search static content and replace for execution time
    $response = $e->getResponse();
    $response->setContent(str_replace(
        'Execution time:', 'Execution time: '.$timeF, $response->getContent()));

}, 100000);
Community
  • 1
  • 1
Edson Horacio Junior
  • 3,033
  • 2
  • 29
  • 50
0

You can capture time to variable in index.php and then use register_shutdown_function to print time difference between:

index.php

define('APP_START_TIME', microtime(true));

register_shutdown_function(function(){
 echo 'Request time(sec): ' . number_format(microtime(true) - APP_START_TIME, 3);
});
Alexander Goncharov
  • 1,572
  • 17
  • 20