requestStartTime = $_SERVER['REQUEST_TIME_FLOAT']; } else { $this->requestStartTime = microtime(true); } parent::__construct($params); } /** * Starts a measure. * * @param string $name Internal name, used to stop the measure * @param string|null $label Public name * @param string|null $collector The source of the collector * * @since 4.0.0 * @return void */ public function startMeasure($name, $label = null, $collector = null) { $start = microtime(true); $this->startedMeasures[$name] = [ 'label' => $label ?: $name, 'start' => $start, 'collector' => $collector, ]; } /** * Check a measure exists * * @param string $name Group name. * * @since 4.0.0 * @return bool */ public function hasStartedMeasure($name): bool { return isset($this->startedMeasures[$name]); } /** * Stops a measure. * * @param string $name Measurement name. * @param array $params Parameters * * @since 4.0.0 * @throws DebugBarException * @return void */ public function stopMeasure($name, array $params = []) { $end = microtime(true); if (!$this->hasStartedMeasure($name)) { throw new DebugBarException("Failed stopping measure '$name' because it hasn't been started"); } $this->addMeasure( $this->startedMeasures[$name]['label'], $this->startedMeasures[$name]['start'], $end, $params, $this->startedMeasures[$name]['collector'] ); unset($this->startedMeasures[$name]); } /** * Adds a measure * * @param string $label A label. * @param float $start Start of request. * @param float $end End of request. * @param array $params Parameters. * @param string|null $collector A collector. * * @since 4.0.0 * @return void */ public function addMeasure($label, $start, $end, array $params = [], $collector = null) { $this->measures[] = [ 'label' => $label, 'start' => $start, 'relative_start' => $start - $this->requestStartTime, 'end' => $end, 'relative_end' => $end - $this->requestEndTime, 'duration' => $end - $start, 'duration_str' => $this->getDataFormatter()->formatDuration($end - $start), 'params' => $params, 'collector' => $collector, ]; } /** * Utility function to measure the execution of a Closure * * @param string $label A label. * @param \Closure $closure A closure. * @param string|null $collector A collector. * * @since 4.0.0 * @return void */ public function measure($label, \Closure $closure, $collector = null) { $name = spl_object_hash($closure); $this->startMeasure($name, $label, $collector); $result = $closure(); $params = \is_array($result) ? $result : []; $this->stopMeasure($name, $params); } /** * Returns an array of all measures * * @since 4.0.0 * @return array */ public function getMeasures(): array { return $this->measures; } /** * Returns the request start time * * @since 4.0.0 * @return float */ public function getRequestStartTime(): float { return $this->requestStartTime; } /** * Returns the request end time * * @since 4.0.0 * @return float */ public function getRequestEndTime(): float { return $this->requestEndTime; } /** * Returns the duration of a request * * @since 4.0.0 * @return float */ public function getRequestDuration(): float { if ($this->requestEndTime !== null) { return $this->requestEndTime - $this->requestStartTime; } return microtime(true) - $this->requestStartTime; } /** * Called by the DebugBar when data needs to be collected * * @since 4.0.0 * @return array Collected data */ public function collect(): array { $this->requestEndTime = microtime(true); $start = $this->requestStartTime; $marks = Profiler::getInstance('Application')->getMarks(); foreach ($marks as $mark) { $mem = $this->getDataFormatter()->formatBytes(abs($mark->memory) * 1048576); $label = $mark->label . " ($mem)"; $end = $start + $mark->time / 1000; $this->addMeasure($label, $start, $end); $start = $end; } foreach (array_keys($this->startedMeasures) as $name) { $this->stopMeasure($name); } usort( $this->measures, function ($a, $b) { if ($a['start'] === $b['start']) { return 0; } return $a['start'] < $b['start'] ? -1 : 1; } ); return [ 'start' => $this->requestStartTime, 'end' => $this->requestEndTime, 'duration' => $this->getRequestDuration(), 'duration_str' => $this->getDataFormatter()->formatDuration($this->getRequestDuration()), 'measures' => array_values($this->measures), 'rawMarks' => $marks, ]; } /** * Returns the unique name of the collector * * @since 4.0.0 * @return string */ public function getName(): string { return 'profile'; } /** * Returns a hash where keys are control names and their values * an array of options as defined in {@see \DebugBar\JavascriptRenderer::addControl()} * * @since 4.0.0 * @return array */ public function getWidgets(): array { return [ 'profileTime' => [ 'icon' => 'clock-o', 'tooltip' => 'Request Duration', 'map' => 'profile.duration_str', 'default' => "'0ms'", ], 'profile' => [ 'icon' => 'clock-o', 'widget' => 'PhpDebugBar.Widgets.TimelineWidget', 'map' => 'profile', 'default' => '{}', ], ]; } }