背景概述:游戲接口是使用PHP cURL擴(kuò)展進(jìn)行請(qǐng)求操作,但是,被請(qǐng)求的服務(wù)器經(jīng)常會(huì)無故的不響應(yīng)或者超時(shí),總之,就是請(qǐng)求之后收不到響應(yīng)回來的數(shù)據(jù),這時(shí)候可不能說對(duì)方API接口有問題,或者服務(wù)器有故障,總之,可能出現(xiàn)的問題是非常之多,不能一概而論。
一、給出一段常用的PHP cURL代碼:
經(jīng)常使用PHP cURL函數(shù)的人,一定不會(huì)陌生吧,同時(shí),我也相信大部分PHPer也是這樣寫代碼的。至少核心部分就是這樣,根本沒有判斷這個(gè)請(qǐng)求失敗了,是什么情況產(chǎn)生的。
誠(chéng)然,通過嚴(yán)重的安全事故導(dǎo)致我必須重新審核這個(gè)cURL庫,該怎樣保證我的請(qǐng)求是穩(wěn)定可靠的。當(dāng)出現(xiàn)失敗之后,我要知道是什么原因?qū)е碌摹5谝粫r(shí)間知道并反饋到人,進(jìn)行及時(shí)的溝通協(xié)調(diào)與修復(fù)。
現(xiàn)在我們?yōu)榱吮WC每次請(qǐng)求的穩(wěn)定可靠性,必須加入日志功能,即把失敗時(shí)請(qǐng)求的相關(guān)參數(shù)狀態(tài)和錯(cuò)誤碼一起記錄到日志中,方便,我們失敗之后去檢查,看代碼:
現(xiàn)在調(diào)用 sendRequestGame 函數(shù)的時(shí)候,會(huì)將每次請(qǐng)求的信息給json_encode之后保存到日志文件 curl_log.txt中。這樣,我們就可以清楚地知道,每次請(qǐng)求到底發(fā)生了什么情況,改進(jìn)之后,增加了兩個(gè)函數(shù):
這兩個(gè)函數(shù)非常的關(guān)鍵,第一個(gè) curl_errno是返回當(dāng)前請(qǐng)求的錯(cuò)誤碼,0代表沒有錯(cuò)誤,是一個(gè)Ok正常的請(qǐng)求。非0代碼請(qǐng)求出現(xiàn)了錯(cuò)誤。但是,大部分錯(cuò)誤發(fā)生時(shí),請(qǐng)求都沒有正確到達(dá)URL所指定的服務(wù)器。如:主機(jī)打不到、網(wǎng)址錯(cuò)誤、404,當(dāng)然,不排除有500這種內(nèi)部服務(wù)器錯(cuò)誤的存在。
第二個(gè)是函數(shù)非常重要,curl_getinfo函數(shù)會(huì)獲取當(dāng)前請(qǐng)求的相關(guān)信息:
我相信大家人字面意思就能看懂7788.不明白的話,自己去看PHP官方手冊(cè)吧,以下,我再附上 curl error code,即 curl_errno函數(shù)返回的數(shù)字說明:
CURLE_UNSUPPORTED_PROTOCOL (1) – 您傳送給 libcurl 的網(wǎng)址使用了此 libcurl 不支持的協(xié)議。 可能是您沒有使用的編譯時(shí)選項(xiàng)造成了這種情況(可能是協(xié)議字符串拼寫有誤,或沒有指定協(xié)議 libcurl 代碼)。
CURLE_FAILED_INIT (2) – 非常早期的初始化代碼失敗。 可能是內(nèi)部錯(cuò)誤或問題。
CURLE_URL_MALFORMAT (3) – 網(wǎng)址格式不正確。
CURLE_COULDNT_RESOLVE_PROXY (5) – 無法解析代理服務(wù)器。 指定的代理服務(wù)器主機(jī)無法解析。
CURLE_COULDNT_RESOLVE_HOST (6) – 無法解析主機(jī)。 指定的遠(yuǎn)程主機(jī)無法解析。
CURLE_COULDNT_CONNECT (7) – 無法通過 connect() 連接至主機(jī)或代理服務(wù)器。
CURLE_FTP_WEIRD_SERVER_REPLY (8) – 在連接到 FTP 服務(wù)器后,libcurl 需要收到特定的回復(fù)。 此錯(cuò)誤代碼表示收到了不正常或不正確的回復(fù)。 指定的遠(yuǎn)程服務(wù)器可能不是正確的 FTP 服務(wù)器。
CURLE_REMOTE_ACCESS_DENIED (9) – 我們無法訪問網(wǎng)址中指定的資源。 對(duì)于 FTP,如果嘗試更改為遠(yuǎn)程目錄,就會(huì)發(fā)生這種情況。
CURLE_FTP_WEIRD_PASS_REPLY (11) – 在將 FTP 密碼發(fā)送到服務(wù)器后,libcurl 需要收到正確的回復(fù)。 此錯(cuò)誤代碼表示返回的是意外的代碼。
CURLE_FTP_WEIRD_PASV_REPLY (13) – libcurl 無法從服務(wù)器端收到有用的結(jié)果,作為對(duì) PASV 或 EPSV 命令的響應(yīng)。 服務(wù)器有問題。
CURLE_FTP_WEIRD_227_FORMAT (14) – FTP 服務(wù)器返回 227 行作為對(duì) PASV 命令的響應(yīng)。如果 libcurl 無法解析此行,就會(huì)返回此代碼。
CURLE_FTP_CANT_GET_HOST (15) – 在查找用于新連接的主機(jī)時(shí)出現(xiàn)內(nèi)部錯(cuò)誤。
CURLE_FTP_COULDNT_SET_TYPE (17) – 在嘗試將傳輸模式設(shè)置為二進(jìn)制或 ascii 時(shí)發(fā)生錯(cuò)誤。
CURLE_PARTIAL_FILE (18) – 文件傳輸尺寸小于或大于預(yù)期。當(dāng)服務(wù)器先報(bào)告了一個(gè)預(yù)期的傳輸尺寸,然后所傳送的數(shù)據(jù)與先前指定尺寸不相符時(shí),就會(huì)發(fā)生此錯(cuò)誤。
CURLE_FTP_COULDNT_RETR_FILE (19) – ‘RETR’ 命令收到了不正常的回復(fù),或完成的傳輸尺寸為零字節(jié)。
CURLE_QUOTE_ERROR (21) – 在向遠(yuǎn)程服務(wù)器發(fā)送自定義 “QUOTE” 命令時(shí),其中一個(gè)命令返回的錯(cuò)誤代碼為 400 或更大的數(shù)字(對(duì)于 FTP),或以其他方式表明命令無法成功完成。
CURLE_HTTP_RETURNED_ERROR (22) – 如果 CURLOPT_FAILONERROR 設(shè)置為 TRUE,且 HTTP 服務(wù)器返回 >= 400 的錯(cuò)誤代碼,就會(huì)返回此代碼。 (此錯(cuò)誤代碼以前又稱為 CURLE_HTTP_NOT_FOUND。)
CURLE_WRITE_ERROR (23) – 在向本地文件寫入所收到的數(shù)據(jù)時(shí)發(fā)生錯(cuò)誤,或由寫入回調(diào) (write callback) 向 libcurl 返回了一個(gè)錯(cuò)誤。
CURLE_UPLOAD_FAILED (25) – 無法開始上傳。 對(duì)于 FTP,服務(wù)器通常會(huì)拒絕執(zhí)行 STOR 命令。錯(cuò)誤緩沖區(qū)通常會(huì)提供服務(wù)器對(duì)此問題的說明。 (此錯(cuò)誤代碼以前又稱為 CURLE_FTP_COULDNT_STOR_FILE。)
CURLE_READ_ERROR (26) – 讀取本地文件時(shí)遇到問題,或由讀取回調(diào) (read callback) 返回了一個(gè)錯(cuò)誤。
CURLE_OUT_OF_MEMORY (27) – 內(nèi)存分配請(qǐng)求失敗。此錯(cuò)誤比較嚴(yán)重,若發(fā)生此錯(cuò)誤,則表明出現(xiàn)了非常嚴(yán)重的問題。
CURLE_OPERATION_TIMEDOUT (28) – 操作超時(shí)。 已達(dá)到根據(jù)相應(yīng)情況指定的超時(shí)時(shí)間。 請(qǐng)注意: 自 Urchin 6.6.0.2 開始,超時(shí)時(shí)間可以自行更改。 要指定遠(yuǎn)程日志下載超時(shí),請(qǐng)打開 urchin.conf 文件,取消以下行的注釋標(biāo)記:
#DownloadTimeout: 30
CURLE_FTP_PORT_FAILED (30) – FTP PORT 命令返回錯(cuò)誤。 在沒有為 libcurl 指定適當(dāng)?shù)牡刂肥褂脮r(shí),最有可能發(fā)生此問題。 請(qǐng)參閱 CURLOPT_FTPPORT。
CURLE_FTP_COULDNT_USE_REST (31) – FTP REST 命令返回錯(cuò)誤。如果服務(wù)器正常,則應(yīng)當(dāng)不會(huì)發(fā)生這種情況。
CURLE_RANGE_ERROR (33) – 服務(wù)器不支持或不接受范圍請(qǐng)求。
CURLE_HTTP_POST_ERROR (34) – 此問題比較少見,主要由內(nèi)部混亂引發(fā)。
CURLE_SSL_CONNECT_ERROR (35) – 同時(shí)使用 SSL/TLS 時(shí)可能會(huì)發(fā)生此錯(cuò)誤。您可以訪問錯(cuò)誤緩沖區(qū)查看相應(yīng)信息,其中會(huì)對(duì)此問題進(jìn)行更詳細(xì)的介紹。可能是證書(文件格式、路徑、許可)、密碼及其他因素導(dǎo)致了此問題。
CURLE_FTP_BAD_DOWNLOAD_RESUME (36) – 嘗試恢復(fù)超過文件大小限制的 FTP 連接。
CURLE_FILE_COULDNT_READ_FILE (37) – 無法打開 FILE:// 路徑下的文件。原因很可能是文件路徑無法識(shí)別現(xiàn)有文件。 建議您檢查文件的訪問權(quán)限。
CURLE_LDAP_CANNOT_BIND (38) – LDAP 無法綁定。LDAP 綁定操作失敗。
CURLE_LDAP_SEARCH_FAILED (39) – LDAP 搜索無法進(jìn)行。
CURLE_FUNCTION_NOT_FOUND (41) – 找不到函數(shù)。 找不到必要的 zlib 函數(shù)。
CURLE_ABORTED_BY_CALLBACK (42) – 由回調(diào)中止。 回調(diào)向 libcurl 返回了 “abort”。
CURLE_BAD_FUNCTION_ARGUMENT (43) – 內(nèi)部錯(cuò)誤。 使用了不正確的參數(shù)調(diào)用函數(shù)。
CURLE_INTERFACE_FAILED (45) – 界面錯(cuò)誤。 指定的外部界面無法使用。 請(qǐng)通過 CURLOPT_INTERFACE 設(shè)置要使用哪個(gè)界面來處理外部連接的來源 IP 地址。 (此錯(cuò)誤代碼以前又稱為 CURLE_HTTP_PORT_FAILED。)
CURLE_TOO_MANY_REDIRECTS (47) – 重定向過多。 進(jìn)行重定向時(shí),libcurl 達(dá)到了網(wǎng)頁點(diǎn)擊上限。請(qǐng)使用 CURLOPT_MAXREDIRS 設(shè)置上限。
CURLE_UNKNOWN_TELNET_OPTION (48) – 無法識(shí)別以 CURLOPT_TELNETOPTIONS 設(shè)置的選項(xiàng)。 請(qǐng)參閱相關(guān)文檔。
CURLE_TELNET_OPTION_SYNTAX (49) – telnet 選項(xiàng)字符串的格式不正確。
CURLE_PEER_FAILED_VERIFICATION (51) – 遠(yuǎn)程服務(wù)器的 SSL 證書或 SSH md5 指紋不正確。
CURLE_GOT_NOTHING (52) – 服務(wù)器未返回任何數(shù)據(jù),在相應(yīng)情況下,未返回任何數(shù)據(jù)就屬于出現(xiàn)錯(cuò)誤。
CURLE_SSL_ENGINE_NOTFOUND (53) – 找不到指定的加密引擎。
CURLE_SSL_ENGINE_SETFAILED (54) – 無法將選定的 SSL 加密引擎設(shè)為默認(rèn)選項(xiàng)。
CURLE_SEND_ERROR (55) – 無法發(fā)送網(wǎng)絡(luò)數(shù)據(jù)。
CURLE_RECV_ERROR (56) – 接收網(wǎng)絡(luò)數(shù)據(jù)失敗。
CURLE_SSL_CERTPROBLEM (58) – 本地客戶端證書有問題
CURLE_SSL_CIPHER (59) – 無法使用指定的密鑰
CURLE_SSL_CACERT (60) – 無法使用已知的 CA 證書驗(yàn)證對(duì)等證書
CURLE_BAD_CONTENT_ENCODING (61) – 無法識(shí)別傳輸編碼
CURLE_LDAP_INVALID_URL (62) – LDAP 網(wǎng)址無效
CURLE_FILESIZE_EXCEEDED (63) – 超過了文件大小上限
CURLE_USE_SSL_FAILED (64) – 請(qǐng)求的 FTP SSL 級(jí)別失敗
CURLE_SEND_FAIL_REWIND (65) – 進(jìn)行發(fā)送操作時(shí),curl 必須回轉(zhuǎn)數(shù)據(jù)以便重新傳輸,但回轉(zhuǎn)操作未能成功
CURLE_SSL_ENGINE_INITFAILED (66) – SSL 引擎初始化失敗
CURLE_LOGIN_DENIED (67) – 遠(yuǎn)程服務(wù)器拒絕 curl 登錄(7.13.1 新增功能)
CURLE_TFTP_NOTFOUND (68) – 在 TFTP 服務(wù)器上找不到文件
CURLE_TFTP_PERM (69) – 在 TFTP 服務(wù)器上遇到權(quán)限問題
CURLE_REMOTE_DISK_FULL (70) – 服務(wù)器磁盤空間不足
CURLE_TFTP_ILLEGAL (71) – TFTP 操作非法
CURLE_TFTP_UNKNOWNID (72) – TFTP 傳輸 ID 未知
CURLE_REMOTE_FILE_EXISTS (73) – 文件已存在,無法覆蓋
CURLE_TFTP_NOSUCHUSER (74) – 運(yùn)行正常的 TFTP 服務(wù)器不會(huì)返回此錯(cuò)誤
CURLE_CONV_FAILED (75) – 字符轉(zhuǎn)換失敗
CURLE_CONV_REQD (76) – 調(diào)用方必須注冊(cè)轉(zhuǎn)換回調(diào)
CURLE_SSL_CACERT_BADFILE (77) – 讀取 SSL CA 證書時(shí)遇到問題(可能是路徑錯(cuò)誤或訪問權(quán)限問題)
CURLE_REMOTE_FILE_NOT_FOUND (78) – 網(wǎng)址中引用的資源不存在
CURLE_SSH (79) – SSH 會(huì)話中發(fā)生無法識(shí)別的錯(cuò)誤
CURLE_SSL_SHUTDOWN_FAILED (80) – 無法終止 SSL 連接