Troubleshooting of PHP errors
Jump to navigation
Jump to search
PHP 問題的排除與解決
檔案操作有關
可否讀取或寫入:例如 imagejpeg($canvas, $filename, 100); 沒有顯示錯誤訊息,則需要
- 檢查檔案是否存在 file_exists
- 檢查暫存目錄是否可以寫入 upload - PHP way to find the web server's temp path? - Stack Overflow
- 檢查該檔案所在該目錄是否已經建立,若未建立則需要建立 mkdir,並設定可以寫入。如果是巢狀的多層目錄,則需要啟用 $recursive [1]
- 檢查該檔案是否可以寫入 is_writable: 如果要刪除檔案,需要檢查是否可以寫入
使用者操作/使用者輸入的內容
使用者輸入內容,內容可能是
- 空值 ex: 空白、全形空白、NULL、0000-00-00
- PHP: 陣列元素中的空白值,可用 array_filter 函數移除。
- 文字字串間夾雜空白
- 輸入文字內容的前後有額外的空白。處理方式:
- PHP: 可用 rim 函數處理。陣列元素值則搭配 array_map 函數處理。ex: $trimmed_array = array_map('trim' ,$array);[2]
- jQuery: $.trim('string')
- 包含特殊符號 ex: 單引號 ', 雙引號 ", 反斜線 \, 大於小於符號 > < <== 對策: PHP: htmlentities - Manual
- 超出預期的內容長度、超出預期的資料數量
- 資料數量從少量變成多量時
- 重複的內容 ex: Excel 欄位重複
- (可勾選多個項目的狀況下) 只勾選了單一項目或者沒有勾選項目,就送出(submit)表單資料
- (如果允許輸入多行文字) 包含換行符號
- 嘗試進行 SQL injection
使用者操作
- 重複點選按鈕
- 在輸入框內,輸入完文字後,按一次或多次的 Enter 鍵
- 使用 Tab 鍵,將游標移到下一個輸入框
使用者環境
- 各種瀏覽器 + 擴充套件 ex: AdBlock
- 各種設備
- 不同網路環境:連線快或慢
操作順序
- 使用者的操作順序,可能不按照功能設計的順序
- 沒有選取任何項目,就提交(submit)或操作表格
網頁 UI 元件回饋訊息
- 操作錯誤時的回饋訊息,例如輸入錯誤帳號密碼的回饋
- 資料儲存變動的回饋訊息,例如資料順利儲存時顯示「儲存成功」
- 搜尋結果的回饋訊息,例如搜尋結果顯示結果筆數
PHP 技術問題處理
不知道載入哪一個 php.ini 設定檔
使用 console command
- php --ini
> php --ini Configuration File (php.ini) Path: C:\Windows Loaded Configuration File: C:\xampp\php\php.ini Scan for additional .ini files in: (none) Additional .ini files parsed: (none)
執行PHP時顯示原始碼的錯誤
- 確認伺服器是否能執行 PHP。驗證: phpinfo/ phpinfo from the command line | commandlinefu.com
- 如果 PHP 使用 short tag語法撰寫,則 php.ini 檔案 需要開啟 short_open_tag = Off -> On
錯誤訊息: ERROR: 00000::
- 原因: 想要刪除的資料不在 MySQL 資料庫內,進行刪除時,會發生的錯誤。
- 解決方法: 先檢查該資料是否存在,再進行刪除。
錯誤訊息: phpinfo() has been disabled
PHP Warning: phpinfo() has been disabled for security reasons in /path/to/phpinfo.php on line xx
- 原因: 網管關閉使用 phpinfo
替代解決方法: 使用 console command
- php -i | grep -i "變數名稱" 或 /path/to/bin/php -i | grep -i "變數名稱" for Linux
- php -i 變數 --info 、 -i 或 -ini,用途顯示PHP資訊或設定值。(PHP information and configuration 摘錄自man php)
- | 管線命令 (pipe),詳 鳥哥的 Linux 私房菜 -- 學習 bash shell
- grep -i 變數 -i 代表忽略搜尋關鍵字或搜尋條件 (pattern) 的大小寫
- /path/to/bin/php -m 列出載入的模組[3]
錯誤訊息: PHP syntax error “unexpected $end”
解決方法
- 檢查括弧是否封閉: 使用 Notepad++ctrl + b 檢查括弧是否封閉 或 使用 Sublime Textctrl + m 檢查括弧是否封閉
- <?php 是否簡寫為 shorttag <?
錯誤訊息: SMTP Error: Could not connect to SMTP host.
錯誤訊息: Invalid address: SMTP -> ERROR: Failed to connect to server: Permission denied (13) SMTP Error: Could not connect to SMTP host. Mailer Error: SMTP Error: Could not connect to SMTP host.
解決方法
- 檢查 PHP 模組是否安裝 OpenSSL php -r "phpinfo();" | grep -i "OpenSSL support" 或 php -i | grep -i OpenSSL for Linux
預期結果:
OpenSSL support => enabled
- 是否可以連線到 SMTP 主機nslookup smtp.gmail.com 或 telnet smtp.gmail.com port (例子中以 gmail 作為 smtp 伺服器)
telnet smtp.gmail.com 465 預期結果:
Trying 74.125.129.109... Connected to smtp.gmail.com. Escape character is '^]'. ^] //註:(Windows) 輸入 ctrl + ] 兩個按鍵,(Mac) 輸入 control + ] 兩個按鍵 telnet> quit Connection closed.
非預期結果:請調整防火牆設定
Trying x.x.x.x... telnet: connect to address x.x.x.x: Connection refused
預期結果:
# getsebool httpd_can_sendmail httpd_can_sendmail --> on # getsebool httpd_can_network_connect httpd_can_network_connect --> on
非預期結果:
# getsebool httpd_can_sendmail httpd_can_sendmail --> off # getsebool httpd_can_network_connect httpd_can_network_connect --> off
需要輸入指令:
# setsebool -P httpd_can_sendmail 1 # setsebool -P httpd_can_network_connect 1
錯誤訊息: Allowed memory size of XXX bytes exhausted (out of memory)
- 訊息: PHP Fatal error: Allowed memory size of XXX bytes exhausted (tried to allocate XX bytes)
- 原因: 一次讀取13萬行的資料,發生錯誤
- 解決方法:
- 減少每次讀取的資料行數,例如每次只讀取 50 行的資料筆數來做處理。
- foreach 時,與其寫入整個陣列到記憶體,可以改用 Generators 寫法,節省記憶體的使用。詳見: PHP: Generators overview - Manual
錯誤訊息: It is not safe to rely on the system's timezone settings
- 訊息: Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone.
- 原因: 沒有設定時區
- 解決方法: 使用 date() 或 strtotime() 等時間相關函數之前,先設定時區,例 date_default_timezone_set("Asia/Taipei")
移除非預期的空白(全形空白)
需要額外移除 'IDEOGRAPHIC SPACE' (U+3000) 全形空白
$string = str_replace(json_decode('"\u3000"'), "", $string);
$string = trim($string);
PHPExcel 產生的 Excel 檔案,開啟後看到一堆亂碼
狀況1: 開啟 Excel 檔案,看到最前面有 NOTICE 的錯誤訊息,例如 <b>Notice</b>: Constant CONST_XXX already defined in <b>path\to\script.php</b> on line xx
- 解法: 關閉錯誤訊息輸出 ex: error_reporting(0); 以及修正 NOTICE 訊息指涉的問題,例如例子中常數重複宣告的問題。
狀況2: 開啟 Excel 檔案,看到最前面有 Fatal error 之類的錯誤訊息
- 解法: 關閉錯誤訊息輸出 ex: error_reporting(0); ,以及修正 Fatal error 訊息指涉的問題。
狀況3: 開啟 Excel 檔案,看到有儲存格位址之類的錯誤訊息
- 解法: 該儲存格內容以等號 (=) 開始,卻不是函數。解決方式是將儲存格內容的最前面加一個單引號 (') 或者是加個空白。
unified coding style
variable: $var
- PHP: starts with dollar symbol $var[4]
- javascript: the first character can be a letter or _ or $, and the other characters can be letters or _ or $ or numbers.[5]
tools
tester
- $ PHP Code Tester for macOS
documentation
- Dash 3 for macOS
- API Docs & Snippets. Integrates with Xcode, Alfred, TextWrangler and many more. on the Mac App Store - DevDocs API Documentation
troubleshooting steps of function
simply the question
- Is the function_exists?
- Extension dependency? Install the extension you need.
- If not, looking for the alternative functions.
- Was the function really executed? Maybe using the __LINE__ to examin the logic.
- Disable the logical judgement and just print text using var_dump or print_r functions.
- Check the if-else condition was satisfied or not cf: Java: String Comparison It's logical (compiler will not show the warning) but wrong.
- logging: ex: PHP: error_log - Manual, monolog
references
- ↑ php - Create a folder if it doesn't already exist - Stack Overflow code snippet: mkdir('path/to/directory', 0755, true);
- ↑ How to trim white spaces of array values in php - Stack Overflow
- ↑ PHP: extension_loaded - Manual
- ↑ PHP: Basics - Manual
- ↑ , and the other characters can be letters or _ or $ or numbers.