<?php
declare (directive=value) {
// 受影響的代碼塊
}
// 或文件級聲明(必須在文件最開頭)
declare (ticks=1);
每執行 N 條**低級語句**(tickable statements)觸發一次 tick 事件,調用已註冊的回調函數。
| 類別 | 示例 | 計數 |
|---|---|---|
| 簡單語句 | echo, return, $a=1, unset($v), break, continue, throw, goto, global, static | 每條 1 |
| 復合語句 | if, while, for, foreach, switch, try/catch, function, class | 整個結構算 1 |
| 語句塊 | { ... } | 整個塊算 1 |
| declare 本身 | declare(...){} | 算 1 |
<?php
declare(encoding='UTF-8'); // 告訴 Zend 引擎源文件編碼,影響字符串字面量解析
// 僅在 PHP 編譯時開啟 --enable-zend-multibyte 時生效(現代 PHP 默認開啟)
<?php
function profiler() {
$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 3);
$caller = $bt[1] ?? ['function' => '?', 'file' => '?', 'line' => '?'];
fprintf(STDERR, "[TICK] %s::%s @ %s:%d\n",
$caller['class'] ?? '', $caller['function'], $caller['file'], $caller['line']);
}
register_tick_function('profiler');
declare(ticks=100) { // 每 100 條低級語句採樣一次
// 你的業務代碼
for ($i = 0; $i < 10000; $i++) {
$x = md5($i);
}
}
unregister_tick_function('profiler');
<?php
$ticks = [];
function sample() {
$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 10);
$key = '';
foreach (array_slice($bt, 1) as $frame) {
$key .= ($frame['class'] ?? '') . ($frame['type'] ?? '') . ($frame['function'] ?? '') . '@' . ($frame['file'] ?? '') . ':' . ($frame['line'] ?? '') . ';';
}
$ticks[$key] = ($ticks[$key] ?? 0) + 1;
}
register_tick_function('sample');
declare(ticks=50) {
runBusinessLogic(); // 你的核心邏輯
}
unregister_tick_function('sample');
arsort($ticks);
echo "Top 10 熱點:\n";
foreach (array_slice($ticks, 0, 10) as $k => $v) {
echo "$v\t$k\n";
}
原理:統計採樣法,開銷極低(<1%),生產環境可用於持續性能監控。
pcntl_async_signals)<?php
declare(ticks=1); // 必須啟用 ticks 才能在非阻塞調用中捕獲信號
pcntl_signal(SIGTERM, function($signo) {
echo "收到 SIGTERM,優雅關閉...\n";
// 關閉連接、刷新緩存、保存狀態
exit(0);
});
while (true) {
// 長時間運行的工作進程
sleep(1);
}
注意:PHP 7.1+ 應使用 pcntl_async_signals(true) 替代 ticks 機制,效率更高、不干擾正常執行。
<?php
function auditLogger() {
$bt = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
$caller = $bt[1] ?? [];
if (isset($caller['function']) && str_starts_with($caller['function'], 'db_')) {
// 記錄所有 db_* 函數調用
syslog(LOG_INFO, "DB_CALL: {$caller['function']} at {$caller['file']}:{$caller['line']}");
}
}
register_tick_function('auditLogger');
declare(ticks=1) {
// 業務代碼中所有 db_query、db_insert 等調用將被自動記錄
db_query('SELECT * FROM users');
}
unregister_tick_function('auditLogger');
| ticks 值 | 採樣頻率 | 開銷 | 適用場景 |
|---|---|---|---|
| 1 | 極高(每語句) | 巨大(100x+ 慢) | 僅極小代碼塊調試 |
| 10~100 | 高 | 明顯(5-20x) | 開發環境詳細分析 |
| 100~1000 | 中 | 低(<5%) | 生產環境持續採樣 |
| 1000+ | 低 | 極低(<1%) | 長期運行監控 |
declare(ticks=N) 是 PHP 獨特的**運行時插桩機制**,適用於:性能統計採樣、信號處理(舊版本)、自動化審計埋點。生產環境建議 ticks >= 100,回調極簡,或直接使用專業 Profiler 工具。