日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

thinkphp mysql 中文_耗时5天解决thinkphp连接mysql中文乱码的问题

發布時間:2023/12/10 数据库 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 thinkphp mysql 中文_耗时5天解决thinkphp连接mysql中文乱码的问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

坑大,或者不大,它就在那里,等著你進。

先前修改成熟的一個基于thinkphp3.1.2的后臺框架,里面有我的autoCode,本來在新項目上不想再用這么落后的版本,但考慮到后臺項目不對外使用,重點是autoCode是我的進度保證,于是繼續使用了這個版本。

本地開發環境是windows + phpstudy(apache,php5.4),數據庫直接用線上的mariadb10.2,一切在本地就緒,可當我把這個后臺項目放進線上容器(centos7 + apache + php5.4)里,滿心歡喜的打開在線地址觀看時,竟然發現網頁中的一部分中文變成了英文問號,經過短暫的分析即刻得出:數據庫里讀出來的中文亂碼了,而模板輸出的中文是正常的。

這首先排除了頁面編碼的問題,而且代碼在本地運行時一切正常,與線上用的是同一個數據庫,因此數據庫也不存在問題。

需要強調的是:

1、我給所有人要求過代碼文件必須使用utf8無bom

2、每個html文件都有這段

3、數據庫,表及字段全是utf8,且數據庫里的中文內容是正常的

4、thinkphp的config.php里面已經加入了'DB_CHARSET' => 'utf8'

我檢查了許許多多的配置文件,php的和apache的,連無辜的mariadb也沒有放過。顯式的配置了各種與編碼相關的配置項,但問題并沒有解決。

深深的疑惑使我嘗試過許許多多的做法,我懷疑了很多不該懷疑的東西,除了人生。

我在php入口文件里加了header("Content-type: text/html; charset=utf-8");

我還把thinkphp3.1.2的/Lib/Driver/Db/DbMysql.class.php中的

mysql_query("SET NAMES '".C('DB_CHARSET')."'", $this->linkID[$linkNum]);

改為了

mysql_query("SET NAMES 'utf8'", $this->linkID[$linkNum]);

然而這都是無用功。

其實非常明顯,這就是php連接mariadb時的編碼有問題,我一次又一次的把目光投向了apache、php和mariadb的配置文件,特別是mariadb的/etc/my.cnf.d/server.cnf,[mysqld]加入了:

character_set_server=utf8

init_connect = 'SET collation_connection = utf8_general_ci'

init_connect = 'SET NAMES utf8'

其他幾個配置文件該加default-character-set = utf8的也都加了。

亂碼依舊。

痛定思痛,我冷靜下來,經驗告訴我,也許問題就在某個被自己認為沒有問題而忽視掉的地方。

于是我把以上每項又檢查了一遍。

是該做點別的嘗試了,于是我檢查了centos7的語言環境,并安裝了中文語言包。

我的期待并沒有得到滿足,亂碼還在。

對了我剛開始還讓另一個php工程師在相同環境下的另一個項目里去讀同一個數據庫里的中文,結果并沒有亂碼。

而且我直覺一定是哪個地方使得這個后臺項目中php使用了latin1或者別的編碼去連接mysql。

第N次的痛定思痛,我一直都很確定這就是php使用了非utf8編碼去連接mysql,但我在config.php里配置了呀,甚至還在DbMysql.class.php里寫死了。

于是我用php做了一個驗證:

dump(M()->query("SHOW VARIABLES LIKE '%char%'"));

dump(M()->query("SET NAMES 'utf8'"));

dump(M()->query("SHOW VARIABLES LIKE '%char%'"));

die;

這段代碼在我本地毫無意外的,與mysql連接的編碼都是utf8,而在線上的結果正如我所想,第一行打出來的結果里,character_set_connection、character_set_client、character_set_results這三個都是latin1,而在執行第二行后,第三行打印的結果就變成utf8了。

這表明我最后的結論是正確的,可是在哪里產生的這個問題呢?

于是我再一次打開thinkphp3.1.2框架的/Lib/Driver/Db/DbMysql.class.php文件,

把其中數據庫版本大于4.1的if段注釋掉,改成了判斷mysql_set_charset函數是否存在的if段,如下:

$dbVersion = mysql_get_server_info($this->linkID[$linkNum]);

/*

if ($dbVersion >= '4.1') {

//使用UTF8存取數據庫 需要mysql 4.1.0以上支持

mysql_query("SET NAMES '".C('DB_CHARSET')."'", $this->linkID[$linkNum]);

mysql_query("SET character_set_client = ".C('DB_CHARSET'), $this->linkID[$linkNum]);

mysql_query("SET character_set_results = ".C('DB_CHARSET'), $this->linkID[$linkNum]);

}*/

if (function_exists('mysql_set_charset') === false) {

mysql_query("SET NAMES '".C('DB_CHARSET')."'", $this->linkID[$linkNum]);

}else{

mysql_set_charset(C('DB_CHARSET'), $this->linkID[$linkNum]);

}

問題到此解決。

我先是震驚,問題居然這么簡單,就是$dbVersion >= '4.1'這個判斷沒進去,于是我想起了我用的是mariadb10.2,確實按照字符串來對比版本的話,這盤算我輸。

線上把$dbVersion這個變量打出來看了下,確實是 string(19) "10.2.12-MariaDB-log"

我又疑惑了,那我本地也是用的這同一個庫啊,難道?

我在本地也打印了下$dbVersion,結果竟然是?string(25) "5.5.5-10.2.12-MariaDB-log"

這個疑問先留著,還有就是前面我明明在mariadb的server.cnf里配置了默認的連接編碼,誰知道告訴我一聲,我還是先把這個坑記錄一下。

總結

以上是生活随笔為你收集整理的thinkphp mysql 中文_耗时5天解决thinkphp连接mysql中文乱码的问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。