飛機的 PHP 學習筆記之應用技術篇

飛機飛過天空發表於2020-01-31

前言

最近在系統的學習 PHP ,參考的資料是《PHP程式設計》+ 官方文件(如果你有好的學習資料,歡迎推薦給我)。雖然這本《PHP程式設計》是基於 PHP5 的,但我筆記裡的程式碼,全部在 PHP 7.2 的環境裡測試過,是能夠執行的。另,本筆記中只記錄我模糊不清的知識。

輸出快取

輸出緩衝區

把輸出的內容先放進記憶體,而不先顯示。最根本的作用是,協調高速 CPU 和相對緩慢的 IO 裝置(磁碟等)的運作。

函式

  • ob_start([callback]) : 開啟輸出緩衝。callback 引數是後處理輸出的函式名。
  • ob_get_length():int : 獲取當前緩衝區長度。緩衝沒有開啟返回 false 。
  • ob_get_contents():string : 獲取當前緩衝區長度。緩衝沒有開啟返回 false 。
  • ob_clean() : 清理輸出緩衝區但是不會關閉輸出緩衝。
  • ob_end_clean() : 清理輸出緩衝區並且結束輸出緩衝
  • ob_flush() : 傳送資料到網頁伺服器並且清理輸出,但是不關閉輸出緩衝。
  • flush() : 除了重新整理和清理輸出緩衝區,也會嘗試讓網頁伺服器立即傳送資料到瀏覽器
  • ob_end_flush() : 傳送資料到網頁伺服器並且清理輸出,並且關閉輸出緩衝。

錯誤處理

錯誤報告

PHP 中錯誤有三種等級:

  • 提示: notice ,發生在執行指令碼可能出現錯誤時,但正常執行時也遇到(例如,嘗試訪問一個不存在的變數)。
  • 警告: warning ,表明一個非致命錯誤,典型的,警告在函式呼叫無效引數時就會顯示。
  • 錯誤: error ,表明致命狀態,無法從指令碼中恢復,解析錯誤是一個特殊的錯誤型別,在指令碼中有語法錯誤時發生。除了解析錯誤外的所有錯誤都叫執行時錯誤

在 PHP 中可以在 php.ini 檔案中用 error_reporting 選項全域性修改這個特性。也可以在指令碼中使用 error_reporting() 函式在本地變數錯誤報告行為。

錯誤抑制

可以通過在獨立表示式前放置一個錯誤抑制符 @ 來禁用它的錯誤資訊.

$value = @(2 / 0);

錯誤抑制符不能抑制解析錯誤,只能抑制執行時錯誤的不同型別。

觸發錯誤

可以在 PHP 中用 trigger_error() 函式丟擲一個錯誤:

trigger_error(message [, tyep="E_SUER_NOTICE"]);

type 引數:
* E_USER_ERROR : 錯誤
* E_USER_WARNING : 警告
* E_USER_NOTICE : 提示

定義錯誤處理器

如果你想格式化錯誤資訊,可以向 PHP 提供錯誤處理器。基本方法是建立一個錯誤處理函式並用 set_error_handler() 來註冊。

宣告的函式可以接受 2 到 5 個引數。前兩個引數是錯誤程式碼和錯誤描述。後面三個引數分別是:錯誤發生的檔名、錯誤發生的行號和錯誤發生的符號表複製。

function displayError($error, $errorString, $filename, $line, $symbols)
{
    echo "<p>Error '<b>{$errorString}</b>' occurred.<br />";
    echo "-- in file '<i>{$filename}</i>', line $line.";
}

set_error_handler('displayError');
$value = 4 / 0; 

//輸出
/*
Error 'Division by zero' occurred.
-- in file 'C:\Git\php\text1.php', line 8.
*/

錯誤處理器中的日誌

PHP 提供內建函式 error_log() ,把錯誤記錄到管理員放錯誤日誌的地方。

error_log(message, type [, destination [, extra_haders ]]);

type引數:
* 0 : 用 PHP 標準錯誤日誌
* 1 : 把錯誤郵件給 destination 地址
* 3 : 附加錯誤到 destination 檔案

當型別為 0 來呼叫 error_log() 。通過改變 php.ini 檔案中 error_log 的值,可以修改要往那個檔案中寫日誌。如果將其設定為 syslog ,系統日誌將被使用。

效能調優

一旦你的程式碼可以工作,就可以優化程式碼。優化程式碼的目標通常為縮短執行時間減少記憶體佔用

分析

使用 microtime() 來準確的標識消逝的時間。

例如,下面程式碼可以的得到 phpinfo() 輸出花費了多少時間:

ob_start();
$start = microtime();

phpinfo();

$end = microtime();
ob_end_clean();

echo "phpinfo() took" . ($end - $start) . "seconds to run.\n";

優化執行時間

  • 避免使用 printf() ,只用 echo

  • 避免在迴圈中重新計算值,因為 PHP 解析器不會移除迴圈不變數

    // 如果 $array 大小不變
    
    for($i = 0; $i < count($array); $i++) // bad
    
    $num = count($array);
    for($i = 0; $i < $num; $i++) // good
  • 只包含必要的檔案。分離出包含檔案中確定要用的函式,將他們放在一起。

  • 如果用了資料庫,要使用持久化資料庫連線——啟動和關閉資料庫連線時比較慢的。

  • 當可以用簡單字串操作函式時就不要用正規表示式。

優化記憶體佔用

  • 用數字代替字串

    for($i = "0", $i < "10"; $i++) // bad
    for($i = 0; $i < 10; $i++) // good
  • 當你處理完了一個大字串,把儲存字串的變數設定為空,這會釋放記憶體以便重用。

  • 只包含必需的檔案,用 include_oncerequire_once 來替代 includerequire

  • 處理完 MySQL 和其他資料庫的結果集後立即釋放。在記憶體中儲存使用後的結果集沒有任何好處。

擴充套件流量的三種方式:

反向代理快取

反向代理伺服器位於使用者與目標伺服器之間,但是對於使用者而言,反向代理伺服器就相當於目標伺服器,即使用者直接訪問反向代理伺服器就可以獲得目標伺服器的資源。代理用來更快的提供靜態檔案。

負載均衡

負載均衡是分攤負載到幾臺機器上。一個“負載均衡系統”通過均衡分佈負載或轉發請求到較少負載的機器上實現。

資料庫複製

有時資料庫伺服器會成為瓶頸——很多併發查詢可能會拖垮一個伺服器。複製是一個很好的解決方案。把發生在一個資料庫上的所有同步帶到其他一個或多個資料庫上,這可以讓你查詢分散到不同的資料庫伺服器而不是自從一臺伺服器載入。

最有效的模型是單向複製,就是你只有一個主資料庫要複製到幾個從資料庫上。寫資料庫到主資料庫,讀資料庫是負載均衡地跨多個從庫。這個技術的目標架構是多讀小寫。

感謝你看到了這裡。如果文章有錯誤,請評論指正,謝謝!

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章