<?php
class RunTime {
private $startTime = 0.0;
private $stopTime = 0.0;
public function start(): void {
$this->startTime = $this->microtimeFloat();
}
public function stop(): float {
$this->stopTime = $this->microtimeFloat();
return $this->stopTime - $this->startTime;
}
public function getElapsed(): float {
return $this->stopTime - $this->startTime;
}
public function display(int $precision = 6): void {
printf('執行時間:%.%df 秒
', $precision, $this->getElapsed());
}
private function microtimeFloat(): float {
// PHP 7.3+ 可直接用 hrtime(true) / 1e9 取奈秒更精準
[$usec, $sec] = explode(' ', microtime());
return (float)$usec + (float)$sec;
}
}
?>
<?php
require 'RunTime.php';
$timer = new RunTime();
$timer->start();
// ... 業務邏輯、資料庫查詢、API 呼叫 ...
usleep(123456); // 模擬耗時
$timer->stop();
$timer->display(4); // 輸出:執行時間:0.1235 秒
// 或取得浮點數自行處理
$elapsed = $timer->getElapsed();
error_log("API 回應耗時: {$elapsed}s");
| 原版問題 | 優化後 |
|---|---|
| 屬性未型別宣告 | PHP 7.4+ 型別提示:float、void |
display() 內部呼叫 end() 耦合 | 分離 stop()/getElapsed()/display(),單一職責 |
| 硬編碼輸出 HTML | printf 參數化精度,可輸出 JSON/純文字 |
微秒解析用 explode | 保留相容寫法,註釋 hrtime() 現代替代 |
| 無命名空間、無嚴格模式 | 建議加入 declare(strict_types=1); namespace App\Util; |
class SegmentTimer {
private $segments = [];
private $current = null;
private $start = 0;
public function begin(string $name): void {
if ($this->current) $this->end();
$this->current = $name;
$this->start = hrtime(true);
}
public function end(): ?float {
if (!$this->current) return null;
$ns = hrtime(true) - $this->start;
$this->segments[$this->current] = $ns / 1e9;
$this->current = null;
return $this->segments[$this->current];
}
public function report(): array {
if ($this->current) $this->end();
return $this->segments;
}
}
// 使用
$st = new SegmentTimer();
$st->begin('db_query'); $db->query(...); $st->end();
$st->begin('api_call'); $http->get(...); $st->end();
print_r($st->report());
// ['db_query' => 0.045, 'api_call' => 0.123]
auto_prepend_file/auto_append_file 或 RUM(Real User Monitoring)工具。hrtime() 避免系統時間調整影響。