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里配置了默认的连接编码,谁知道告诉我一声,我还是先把这个坑记录一下。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/427797.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

bzoj3203: [Sdoi2013]保护出题人

我三分这么好吗居然1A啦???提交的时候只是想着先WA一次的。。。。 这题真的很妙啊 首先第一步,就是把僵尸的生命值取一个前缀和,这样造成伤害的时候,可以视为同时对所有僵尸造成伤害。 那么就可以得到一个柿…

ad19原理图标注_AD19中原理图的模板如何进行编辑?

我们在进行原理图设计的时候,有时候不想去用软件自带默认的模板,想要用自己设计的模板,就涉及到我们的模板怎么去编辑的呢?我们应该如何去编辑原理图自己设计的模板?操作步骤是怎么的呢?我们今天就以AD19为…

mysql+秘密_mysql不被人知的秘密

http://blog.csdn.net/yueguanghaidao/article/details/69333872011先建立两张表。1.student表2.grade表一:mysql的复制技术1.表与数据的复制->>实现表结构和数据的同步create table desttable select * from srctable;(desttable:目标表,srctable…

项目管理中风险评价的必要性

摘要:在项目管理实践中,风险是时时存在的。 因此,如何评价、度量风险的大小,确定可接受风险和不可接受风险,对不可接受风险作进一步分析,制定补偿措施,将风险减至最小或可以接受的水平&#xff…

mysql一个表几亿数据_如何在mysql 造1亿条记录的大容量数据表?

背景及目标:现有数据1000w单表,为压力测试准备1亿条数据。步骤:1.将1000w条记录,除id外都导入到多个文件中://DELIMITERDROP PROCEDURE if EXISTS createManyTable;create PROCEDURE createManyTable()BEGINDECLARE i …

windows键盘在mac上怎么识别_Mac电脑怎么使用pc键盘?

苹果电脑一般需要使用配套的mac键盘,毕竟按键和普通pc键盘不一样。但是总会遇到一些情况,比如配套的mac键盘坏了,而刚好有一个pc键盘,那么这时候苹果电脑要怎么用pc键盘呢?这边小编跟大家介绍mac电脑连接pc键盘以及设置…

LOJ#6002. 「网络流 24 题」最小路径覆盖

模板。 1 #include<iostream>2 #include<cstring>3 #include<cstdio>4 //#include<time.h>5 //#include<complex>6 //#include<set>7 //#include<queue>8 #include<algorithm>9 #include<stdlib.h>10 using namespace s…

zabbix mysql设置中文乱码_解决zabbix监控因php问题导致图形界面中文乱码方法

解决因编译php中添加了-enable-gd-jis-conv选项导致Zabbix监控系统图形界面中文乱码问题现象&#xff1a;php编译参数&#xff1a;说明&#xff1a;如果PHP编译时启用–enable-gd-jis-conv选项的话&#xff0c;那么非ASCII字符(例如汉字、拼音、希腊文和箭头) 会被当成EUC-JP编…

熟悉常用的HDFS操作

一、Hadoop提供的Shell命令完成相同任务&#xff1a; 在本地Linux文件系统的“/home/hadoop/”目录下创建一个文件txt&#xff0c;里面可以随意输入一些单词.在本地查看文件位置&#xff08;ls&#xff09;在本地显示文件内容使用命令把本地文件系统中的“txt”上传到HDFS中的当…

mysql 低端_mysql入门

相关了解(重点内容从标题一开始)目前主流数据库有:sqlserver, mysql, Qracle, SQLite, Access, MS SQL Server等, 我主要说的是mysql;以下几点需要记住!!!SQL包括了所有对数据库的操作, 主要由4个部分组1. 数据库定义语言(DDL): 用于定义和管理数据库对象, 包括数据库, 基本表,…

阿里云服务器由于被检测到对外攻击,已阻断该服务器对其它服务器端口的访问...

问题&#xff1a; (系统&#xff1a;CentOS 7.2 ) 前几天在阿里云服务器安装了Redis, 刚开始没有设置redis密码, 后台阿里云发送多次邮件提示如下&#xff1a; 经过几次波折才发现并彻底解决了问题&#xff1a; 原因&#xff1a; 估计是因为 Redis服务开启时没有设置密码 &…

opencv rect画旋转矩形_在opencv c中绘制旋转的矩形

既然你想要一个填充的矩形,你应该使用fillConvexPoly&#xff1a;// Include center point of your rectangle, size of your rectangle and the degrees of rotationvoid DrawRotatedRectangle(cv::Mat& image, cv::Point centerPoint, cv::Size rectangleSize, double ro…

批量找注入 python3+sqlmap结合

注入一直都是用sqlmap 导致本来就不怎么精通的手工注入现在就忘的一干二净 想实战练习 却一时又找不到有注入的网站 于是便有了这篇文章 想找个批量获取域名链接的工具 但都是只是获取域名而已 都没获取后面的参数 于是自己写了个只获取bing前10页的结果 输入q 结束循环…

python collections模块_Python 的collections模块

前言&#xff1a;collections是实现了特定目标的容器&#xff0c;以提供python标准内建容器dict,list,set和tuple的替代选择。CounterCounter是一个dict子类&#xff0c;主要是用来对你访问的对象的频率进行计数import collections#统计字符出现的次数test1 collections.Count…

C# VS2017 winForm 使tableLayoutPanel 不闪烁

//设置tablelayoutpanel控件的DoubleBuffered 属性为true&#xff0c;这样可以减少或消除由于不断重绘所显示图面的某些部分而导致的闪烁 private void Form_PrintPreview_Load(object sender, EventArgs e){//开启双缓冲&#xff0c;改善TableLayoutPanel闪烁问题TableLayoutP…

java 继承调用_【JAVA学习】继承中函数调用机制

类(类的对象)在调用函数时&#xff0c;究竟哪一个函数被调用&#xff0c;是存在特定的机制的&#xff0c;现在我们来梳理下其步骤。步骤一&#xff1a;当其调用一个函数的时候&#xff0c;编译器根据其声明的变量类型和调用的函数名字找到所有此“类”和其父类中具有同名的函数…

golang 反射

参考&#xff1a;|--http://blog.51cto.com/speakingbaicai/1707637 |--https://studygolang.com/articles/6324 反射是在golang程序运行时检查变量所具有类型的一种机制。由于反射可以得出关于变量结构的数据&#xff08;即“关于数据的数据”&#xff09;&#xff0c;所以这也…

java硬件编程_关于JAVA并发编程你需要知道的——硬件篇

无论程序语言如何千变万化&#xff0c;他们都深深地根植于目前的计算机体系结构。左图是intel CPU的三级高速缓存设计&#xff0c;由于高速缓存对程序员基本不可见&#xff0c;因此可以抽象为右图。缓存的设计首先还是先谈谈左图。L1-cache分为两部分&#xff0c;i-cache存储指…

ELF 动态链接 so的动态符号表(.dynsym)

静态链接中有一个专门的段叫符号表 -- “.symtab”(Symbol Table)&#xff0c; 里面保存了所有关于该目标文件的符号的定义和引用。 动态链接中同样有一个段叫 动态符号表 -- “.dynsym”(Dynamic Symbol) &#xff0c; 但.dynsym 相对于 .symtab 只保存了与动态链接相关的导入…

java线程池怎么创建_java中的线程池,如何创建?

Java中的线程池它是线程的容器&#xff0c;或者(换句话说&#xff0c;它是具有执行任务能力的线程的集合)。我们可以使用ThreadPool框架来定位(或实现)线程池。线程池可以包含多个线程。每当我们执行任何任务时&#xff0c;线程就会从线程池中出来并完成该任务&#xff0c;然后…