平常開發中碰到就記一下, 若是有朋友願意分享的 bug 能夠在評論中討論啊
×tamp=1234567890
這樣的字段會被轉義成xtamp=1234567890
這個不只存在於頁面解析當中,當使用 curl 請求時拼接的參數有這種格式的也會發生轉義
解決方法有兩個:javascript
?timestamp=1234567890
這樣避免出現 &time
發生轉義的狀況&
用&
來代替出現這句話一般說明你在用的 php 版本是5.6.並且在php<=5.6
的時候,進行 application/json
格式的 post 提交會把數據放在$HTTP_RAW_POST_DATA
這個系統變量裏面,在php>=7
的時候這個變量被移除了,通通歸總到php://input
這裏
解決方法:php
Although that indeed would be technically impossible (as $HTTP_RAW_POST_DATA is populated in the bootstrapping phase of the PHP process) allow one to override the setting by means of calling ini_set.
要確保本身的系統中沒有使用 `HTTP_RAW_POST_DATA`這個變量,直接在`php.ini`裏面禁掉它的設置,可是容易出現系統中又打開的狀況(在框架中很常見)
application/form-data
或者application/x-www-form-urlencoded
這種格式的提交, 而後在後端接收數據的時候再轉成本身須要的格式(一般是數組)這種狀況出如今平時運行的好好的, 可是忽然換 cli 模式後這個配置就出問題了,緣由在當 host=localhost
時走的是 unix:socket 連接, 當host=127.0.0.1
走的是 tcp 連接,這在php-fpm
和php-cli
中有點區別,尤爲是本地沒有安裝 mysql 的時候
解決方法有三種:html
127.0.0.1
user
表, host=localhost
和host=127.0.0.1
是否是用的同一個帳號密碼php.ini
文件中的pdo_mysql.default_socket=
寫上完整的 socket 路徑以上三種方法均可以試一下
參考資料前端
這個是 phper 不多碰到可是很常見的狀況, 好比用 swoole 啓動了一個常駐進程的服務, 那麼就必定要當心使用靜態變量,在同步模式下會發生變量污染, 還有就是 redis,mysql 這類的連接,你會發現長時間靜置之後就會出現一些摸不着頭腦的問題, 這種狀況不妨想一下是否是 server 端回收了這個 socket,所以在 client 端怎麼都寫入不進去. 還有就是 php 在讀取消息的時候,出現消息過長的狀況,那麼就要考慮EOF終止符的問題了... 單次 http 每一次請求都是全新的代碼, 不用本身考慮 gc 的問題, 可是在常駐內存的時候,這些就是一個個的大坑了java
產生這個錯誤的主要緣由是 mysql server 端斷開了連接, client 端還拿着這個句柄去請求,解決方式有兩種:mysql
show global variables like '%timeout';
查看 wait_timeout 的時長,適當的調長一點, 這種方法治標不治本,並且有隱患mysql> set global wait_timeout=10; mysql> show global variables like 'wait_timeout';
以前碰到了問題是:
在 php 端 urlencode 的值爲:linux
orderid%3D21111111110001954%26pid%3D257742%26reason%3D%E4%B8%AA%E4%BA%BA%E6%96%B9%E9%9D%A2%E5%8E%9F%E5%9B%A0_%E4%BD%BF%E7%94%A8%E7%BA%A2%E5%8C%85%E9%87%8D%E6%96%B0%E4%B8%8B%E5%8D%95%26token%3D041d9e5575f480b7bfd58b09bd14ab1c7ee9e9594f2fcdb9f0e3e39fc634b48f
須要 urldecode 一次redis
而在 js 端的結果是:sql
orderid%3D21111111110002170%26pid%3D257742%26reason%3D%25E4%25B8%25AA%25E4%25BA%25BA%25E6%2596%25B9%25E9%259D%25A2%25E5%258E%259F%25E5%259B%25A0_%25E4%25B8%25AA%25E4%25BA%25BA%25E8%25BA%25AB%25E4%25BD%2593%25E5%258E%259F%25E5%259B%25A0%26token%3D041d9e5575f480b7bfd58b09bd14ab1c7ee9e9594f2fcdb9f0e3e39fc634b48f
須要 urldecode 兩次json
查閱資料後:
在後端是PHP程序的狀況下,保持前端Javascript和PHP之間傳值的統一編碼可使用如下函數進行處理: WEB前端JavaScript 編碼:escape(encodeURI(string)) 解碼:unescape(decodeURI(string)) WEB後端Php 編碼:urlencode(string) 解碼:urldecode(urldecode(string))
rawurlencode遵照是94年國際標準備忘錄RFC 1738
urlencode實現的是傳統作法,和上者的主要區別是對空格的轉義是'+'而不是'%20'
javascript的encodeURL也是94年標準,而javascript的escape是另外一種用"%xxx"標記unicode編碼的方法。
推薦在PHP中使用用rawurlencode。棄用urlencode
樣例
source:
超級無敵的人sadha sajdh數據樣本sdls fhejrthcxzb.file.jpeg
PHP urlencode:
%E8%B6%85%E7%BA%A7%E6%97%A0%E6%95%8C%E7%9A%84%E4%BA%BAsadha+sajdh%E6%95%B0%E6%8D%AE%E6%A0%B7%E6%9C%ACsdls+fhejrthcxzb.file.jpeg
PHP rawurlencode:
%E8%B6%85%E7%BA%A7%E6%97%A0%E6%95%8C%E7%9A%84%E4%BA%BAsadha%20sajdh%E6%95%B0%E6%8D%AE%E6%A0%B7%E6%9C%ACsdls%20fhejrthcxzb.file.jpeg
Javascript encodeURI|encodeURIComponent:
%E8%B6%85%E7%BA%A7%E6%97%A0%E6%95%8C%E7%9A%84%E4%BA%BAsadha%20sajdh%E6%95%B0%E6%8D%AE%E6%A0%B7%E6%9C%ACsdls%20fhejrthcxzb.file.jpeg
Javascript escape:
%u8D85%u7EA7%u65E0%u654C%u7684%u4EBAsadha%20sajdh%u6570%u636E%u6837%u672Csdls%20fhejrthcxzb.file.jpeg
在前端還有個問題就是, js 的 encodeURIComponent
和 encodeURI
都不會轉換 _-.!~*'()#
這些保留字符, 而在後端的rawurlencode
則是會轉換的, 所以須要前端單獨把這幾個給拎出來, 以下:
"*".charCodeAt(0) // 42 String.fromCharCode(42) // *
這裏有張圖說的很明白
圖片來源
若是出現 mb_substr
這類操做的時候, 會出現字數判斷錯誤的問題, 這個有時候很難排查, 由於在 win 上,使用命令行或者 linux 上用cat
命令是看不到字符間是有 <U+200B> 的, 以下:
這玩意兒出現的場景就是: 在前端輸入框中輸入幾個字, 而後複製粘貼. 這樣儘管看起來之間沒有空格, 可是其中仍是插入了這個字符
這玩意就叫 zero-width space 零寬空格, 處理的辦法也很簡單, 前端傳值以前給過濾一下, 好比 https://stackoverflow.com/que... 或 https://codeday.me/bug/201711...
後端 php 處理的話和這個不同, 使用 utf-8 的處理方式, 能夠參考這篇文章 特殊字符<200b><200c><200d>的刪除辦法與原理
替換這種編碼
$value = str_replace("\xe2\x80\x8b", '', $value); $value = str_replace("\xe2\x80\x8c", '', $value); $value = str_replace("\xe2\x80\x8d", '', $value);
編碼對照以下: