Troubleshooting of PHP errors

From LemonWiki共筆
Jump to navigation Jump to search

PHP 問題的排除與解決

檔案操作有關

可否讀取或寫入:例如 imagejpeg($canvas, $filename, 100); 沒有顯示錯誤訊息,則需要

使用者操作/使用者輸入的內容

使用者輸入內容,內容可能是

  • 空值 ex: 空白、全形空白、NULL、0000-00-00
  • 文字字串間夾雜空白
  • 包含特殊符號 ex: 單引號 ', 雙引號 ", > < <== 對策: PHP: htmlentities - Manual
  • 內容的前後有空白 <== 對策: PHP: trim 或 jQuery $.trim('string')
  • 超出預期的內容長度
  • 資料數量從少量變成多量時
  • 重複的內容 ex: Excel 欄位重複
  • (可勾選多個項目的狀況下) 指勾選了單一項目或者沒有勾選項目,就送出(submit)表單資料
  • (如果允許輸入多行文字) 包含換行符號
  • 嘗試進行 SQL injection

使用者操作

  • 重複點選按鈕
  • 在輸入框按 Enter

操作順序

  • 使用者的操作順序,可能不按照功能設計的順序
  • 沒有選取任何項目,就提交(submit)或操作表格

錯誤訊息

執行PHP時顯示原始碼的錯誤

錯誤訊息: 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 Os linux.png
    • php -i 變數 --info 或 -i ,用途顯示PHP資訊或設定值。(PHP information and configuration 摘錄自man php)
    • | 管線命令 (pipe),詳 鳥哥的 Linux 私房菜 -- 學習 bash shell
    • grep -i 變數 -i 代表忽略搜尋關鍵字或搜尋條件 (pattern) 的大小寫
  • /path/to/bin/php -m 列出載入的模組[2]

錯誤訊息: 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 Os linux.png

預期結果:

OpenSSL support => enabled
  • 是否可以連線到 SMTP 主機nslookup smtp.gmail.comtelnet 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

  • 訊息: PHP Fatal error: Allowed memory size of XXX bytes exhausted (tried to allocate XX bytes)
  • 原因: 一次讀取13萬行的資料,發生錯誤
  • 解決方法: 限制每次讀取的資料行數,例如每次只讀取 50 行的資料筆數來做處理。

移除非預期的空白(全形空白)

需要額外移除 'IDEOGRAPHIC SPACE' (U+3000) 全形空白

$string = str_replace(json_decode('"\u3000"'), "", $string);
$string = trim($string);

unified coding style

variable: $var

  • PHP: starts with dollar symbol $var[3]
  • javascript: the first character can be a letter or _ or $, and the other characters can be letters or _ or $ or numbers.[4]

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.

references

  1. php - Create a folder if it doesn't already exist - Stack Overflow code snippet: mkdir('path/to/directory', 0755, true);
  2. PHP: extension_loaded - Manual
  3. PHP: Basics - Manual
  4. , and the other characters can be letters or _ or $ or numbers.