怎么试也不成功,这一节课多少分钟的内容改成mysqli

查看: 2975|回复: 4
将DISCUZ的数据库扩展改为MYSQLI
Discuz这么多年来数据库类使用的扩展一直是mysql,相比之下mysqli的扩展性能更佳,因此我便动手将Discuz的数据库类修改为mysqli了。
1.下列代码是基于Discuz!X2的数据库类进行修改的,不兼容Discuz!系列,对Discuz!X系列的其他版本也不保证兼容,修改请谨慎。
2.对于mysqli扩展,只有当配合使用其prepared statement或multi query的时候,性能才会有大幅的提升,这需要修改Discuz的大部分源代码,因此不在本文讨论范围之内class db_mysqli
{
& && &&&var $
& && &&&var $version = '';
& && &&&var $querynum = 0;
& && &&&var $slaveid = 0;
& && &&&var $
& && &&&var $link = array();
& && &&&var $config = array();
& && &&&var $sqldebug = array();
& && &&&var $map = array();
& && &&&function db_mysqli($config = array()) {
& && && && && & if(!function_exists('mysqli_connect')) exit('mysqli extension not found!');
& && && && && & if(!empty($config)) {
& && && && && && && && &$this-&set_config($config);
& && && && && & }
& && &&&}
& && &&&function set_config($config) {
& && && && && & $this-&config = &$
& && && && && & $this-&tablepre = $config['1']['tablepre'];
& && && && && & if(!empty($this-&config['map'])) {
& && && && && && && && &$this-&map = $this-&config['map'];
& && && && && & }
& && &&&}
& && &&&function connect($serverid = 1) {
& && && && && & if(empty($this-&config) || empty($this-&config[$serverid])) {
& && && && && && && && &$this-&halt('config_db_not_found');
& && && && && & }
& && && && && & $this-&link[$serverid] = $this-&_dbconnect(
& && && && && && && && &$this-&config[$serverid]['dbhost'],
& && && && && && && && &$this-&config[$serverid]['dbuser'],
& && && && && && && && &$this-&config[$serverid]['dbpw'],
& && && && && && && && &$this-&config[$serverid]['dbcharset'],
& && && && && && && && &$this-&config[$serverid]['dbname'],
& && && && && && && && &$this-&config[$serverid]['pconnect']
& && && && && && && && &);
& && && && && & $this-&curlink = $this-&link[$serverid];
& && &&&function _dbconnect($dbhost, $dbuser, $dbpw, $dbcharset, $dbname, $pconnect) {
& && && && && & $link =
& && && && && & if(!$link = new mysqli($dbhost, $dbuser, $dbpw, $dbname)) {
& && && && && && && && &$this-&halt('notconnect');
& && && && && & } else {
& && && && && && && && &$this-&curlink = $
& && && && && && && && &if($this-&version() & '4.1') {
& && && && && && && && && && &&&$dbcharset = $dbcharset ? $dbcharset : $this-&config[1]['dbcharset'];
& && && && && && && && && && &&&$serverset = $dbcharset ? 'character_set_connection='.$dbcharset.', character_set_results='.$dbcharset.', character_set_client=binary' : '';
& && && && && && && && && && &&&$serverset .= $this-&version() & '5.0.1' ? ((empty($serverset) ? '' : ',').'sql_mode=\'\'') : '';
& && && && && && && && && && &&&$serverset && $link-&query(&SET $serverset&);
& && && && && && && && &}
& && && && && & }
& && && && && & return $
& && &&&}
& && &&&function table_name($tablename) {
& && && && && & if(!empty($this-&map) && !empty($this-&map[$tablename])) {
& && && && && && && && &$id = $this-&map[$tablename];
& && && && && && && && &if(!$this-&link[$id]) {
& && && && && && && && && && &&&$this-&connect($id);
& && && && && && && && &}
& && && && && && && && &$this-&curlink = $this-&link[$id];
& && && && && & } else {
& && && && && && && && &$this-&curlink = $this-&link[1];
& && && && && & }
& && && && && & return $this-&tablepre.$
& && &&&}
& && &&&function select_db($dbname) {
& && && && && & return $this-&curlink-&select_db($dbname);
& && &&&}
& && &&&function fetch_array($query, $result_type = MYSQLI_ASSOC) {
& && && && && & return $query-&fetch_array($result_type);
& && &&&}
& && &&&function fetch_first($sql) {
& && && && && & return $this-&fetch_array($this-&query($sql));
& && &&&}
& && &&&function result_first($sql) {
& && && && && & return $this-&result($this-&query($sql), 0);
& && &&&}
& && &&&function query($sql, $type = '') {
& && && && && & if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {
& && && && && && && && &$starttime = dmicrotime();
& && && && && & }
& && && && && & $func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ?
& && && && && & if(!($query = $this-&curlink-&query($sql))) {
& && && && && && && && &if(in_array($this-&errno(), array()) && substr($type, 0, 5) != 'RETRY') {
& && && && && && && && && && &&&$this-&connect();
& && && && && && && && && && &&&return $this-&query($sql, 'RETRY'.$type);
& && && && && && && && &}
& && && && && && && && &if($type != 'SILENT' && substr($type, 5) != 'SILENT') {
& && && && && && && && && && &&&$this-&halt('query_error', $sql);
& && && && && && && && &}
& && && && && & }
& && && && && & if(defined('DISCUZ_DEBUG') && DISCUZ_DEBUG) {
& && && && && && && && &$this-&sqldebug[] = array($sql, number_format((dmicrotime() - $starttime), 6), debug_backtrace());
& && && && && & }
& && && && && & $this-&querynum++;
& && && && && & return $
& && &&&}
& && &&&function affected_rows() {
& && && && && & return $this-&curlink-&affected_
& && &&&}
& && &&&function error() {
& && && && && & return $this-&curlink-&
& && &&&}
& && &&&function errno() {
& && && && && & return intval($this-&curlink-&errno);
& && &&&}
& && &&&function result($query, $row = 0) {
& && && && && & $query-&data_seek($row);
& && && && && & list($query) = $query-&fetch_row();
& && && && && & return $
& && &&&}
& && &&&function num_rows($query) {
& && && && && & $query = $query-&num_
& && && && && & return $
& && &&&}
& && &&&function num_fields($query) {
& && && && && & return $query-&field_
& && &&&}
& && &&&function free_result($query) {
& && && && && & return $query-&free_result();
& && &&&}
& && &&&function insert_id() {
& && && && && & return ($id = $this-&curlink-&insert_id) &= 0 ? $id : $this-&result($this-&query(&SELECT last_insert_id()&), 0);
& && &&&}
& && &&&function fetch_row($query) {
& && && && && & $query = $query-&fetch_row();
& && && && && & return $
& && &&&}
& && &&&function fetch_fields($query) {
& && && && && & return $query-&fetch_field();
& && &&&}
& && &&&function version() {
& && && && && & if(empty($this-&version)) {
& && && && && && && && &$this-&version = $this-&curlink-&client_
& && && && && & }
& && && && && & return $this-&
& && &&&}
& && &&&function close() {
& && && && && & return $this-&curlink-&close();
& && &&&}
& && &&&function halt($message = '', $sql = '') {
& && && && && & require_once libfile('class/error');
& && && && && & discuz_error::db_error($message, $sql);
& && &&&}
}复制代码使用方法:
将以上代码粘贴至source/class/class_core.php中的class db_mysql复制代码上方
然后查找$class = 'db_mysql';复制代码修改为$class = 'db_mysqli';复制代码保存即可。
占位& && && && && && && &
好高深,都不明!!
虽然不明白&&但还是 长见识了
看不懂 呵呵
Powered by君,已阅读到文档的结尾了呢~~
phpnow下 mysqli加载不了的问题
扫扫二维码,随身浏览文档
手机或平板扫扫即可继续访问
phpnow下 mysqli加载不了的问题
举报该文档为侵权文档。
举报该文档含有违规或不良信息。
反馈该文档无法正常浏览。
举报该文档为重复文档。
推荐理由:
将文档分享至:
分享完整地址
文档地址:
粘贴到BBS或博客
flash地址:
支持嵌入FLASH地址的网站使用
html代码:
&embed src='/DocinViewer-.swf' width='100%' height='600' type=application/x-shockwave-flash ALLOWFULLSCREEN='true' ALLOWSCRIPTACCESS='always'&&/embed&
450px*300px480px*400px650px*490px
支持嵌入HTML代码的网站使用
您的内容已经提交成功
您所提交的内容需要审核后才能发布,请您等待!
3秒自动关闭窗口一言不合就发开车,老司机教你Mysql字符编码利用技巧!
由某CTF题解说起
小密圈里有人提出的问题,大概代码如下:
看了一下,明显考点是这几行:
&?phpif($username==='admin'){if($_SERVER['REMOTE_ADDR']!=='127.0.0.1'){die('Permission denied!');}}$result=$mysqli-&query("SELECT * FROM z_users where username = '{$username}' and password = '{$password}'");
这个if语句嫌疑很大,大概是考我们怎么登陆admin的账号,请先看这一篇文章 /PENETRATION/Mini-XCTF-Writeup.html本文中利用?等latin1字符来绕过php的判断。这个CTF也是用同样的方法来解决:
可见,我传入的username=admin%c2,php的检测if ($username === 'admin')自然就可以绕过的,在mysql中可以正常查出username='admin'的结果。
那么,为什么执行SELECT * FROM user WHERE username='adminxC2' and password='admin'却可以查出用户名是admin的记录?
刚好这段时间有人问我为什么在他的计算机上无法复现,我们来深入研究研究。
编写如下代码:
&?php$mysqli=newmysqli("localhost","root","root","cat");/* check connection */if($mysqli-&connect_errno){printf("Connect failed: %sn",$mysqli-&connect_error);exit();}$mysqli-&query("set names utf8");$username=addslashes($_GET['username']);/* Select queries return a resultset */$sql="SELECT * FROM `table1` WHERE username='{$username}'";if($result=$mysqli-&query($sql)){printf("Select returned %d rows.n",$result-&num_rows);while($row=$result-&fetch_array(MYSQLI_ASSOC)){var_dump($row);}/* free result set */$result-&close();}else{var_dump($mysqli-&error);}$mysqli-&close();
然后在数据库cat中创建表table1:
CREATETABLE`table1`(`id`int(10)unsignedNOTNULLAUTO_INCREMENT,`username`varchar(255)COLLATElatin1_general_ciNOTNULL,`password`varchar(255)COLLATElatin1_general_ciNOTNULL,PRIMARYKEY(`id`))ENGINE=MyISAMAUTO_INCREMENT=1DEFAULTCHARSET=latin1COLLATE=latin1_general_ci;
我特地将字符集设置为latin1,其实默认情况下,Mysql的字符集就是latin1,没必要写明。
插入一个管理员账户:
INSERT`table1`VALUES(1,'admin','admin');
然后,我们访问http://localhost/test.php?username=admin%c2,即可发现%c2被忽略,Mysql查出了username=admin的结果:
假设我们将table1表的字符集换成utf8,就得不到结果了。
Mysql字符集转换
经过第2段中对该Mysql Trick的复现,大概也能猜到原理了。
造成这个Trick的根本原因是,Mysql字段的字符集和php mysqli客户端设置的字符集不相同。
set names utf8 的意思是将客户端的字符集设置为utf8。我们打开mysql控制台,依次执行SHOW VARIABLES LIKE 'character_set_%';、set names utf8;、SHOW VARIABLES LIKE 'character_set_%';,即可得到如下结果:
如上图,在默认情况下,mysql字符集为latin1,而执行了set names utf8;以后,character_set_client、character_set_connection、character_set_results等与客户端相关的配置字符集都变成了utf8,但character_set_database、character_set_server等服务端相关的字符集还是latin1。
这就是该Trick的核心,因为这一条语句,导致客户端、服务端的字符集出现了差别。既然有差别,Mysql在执行查询的时候,就涉及到字符集的转换。
2008年鸟哥曾在博客中讲解了Mysql字符集:
MySQL Server收到请求时将请求数据从character_set_client转换为character_set_connection;
进行内部操作前将请求数据从character_set_connection转换为内部操作字符集
在我们这个案例中,character_set_client和character_set_connection被设置成了utf8,而内部操作字符集其实也就是username字段的字符集还是默认的latin1。于是,整个操作就有如下字符串转换过程:
utf8 --& utf8 --& latin1
最后执行比较username='admin'的时候,'admin'是一个latin1字符串。
那么,字符集转换为什么会导致%c2被忽略呢?
说一下我的想法,虽然我没有深入研究,但我觉得原因应该是,Mysql在转换字符集的时候,将不完整的字符给忽略了。
举个简单的例子,佬这个汉字的UTF-8编码是xE4xBDxAC,我们可以依次尝试访问下面三个URL:
http://localhost:9090/test.php?username=admin%e4
http://localhost:9090/test.php?username=admin%e4%bd
http://localhost:9090/test.php?username=admin%e4%bd%ac
可以发现,前两者都能成功获取到username=admin的结果,而最后一个URL,也就是当我输入佬字完整的编码时,将会被抛出一个错误:
为什么会抛出错误?原因很简单,因为latin1并不支持汉字,所以utf8汉字转换成latin1时就抛出了错误。
那前两次为什么没有抛出错误?因为前两次输入的编码并不完整,Mysql在进行编码转换时,就将其忽略了。
这个特点也导致,我们查询username=admin%e4时,%e4被省略,最后查出了username=admin的结果。
为什么只有部分字符可以使用
我在测试这个Trick的时候发现,username=admin%c2时可以正确得到结果,但username=admin%c1就不行,这是为什么?
我简单fuzz了一下,如果在admin后面加上一个字符,有如下结果:
x00~x7F: 返回空白结果
x80~xC1: 返回错误Illegal mix of collationsxC2~
xEF: 返回admin的结果
xF0~xFF: 返回错误Illegal mix of collations
这就涉及到Mysql编码相关的知识了,先看看维基百科吧。
UTF-8编码是变长编码,可能有1~4个字节表示:
一字节时范围是[00-7F]
两字节时范围是[C0-DF][80-BF]
三字节时范围是[E0-EF][80-BF][80-BF]
四字节时范围是[F0-F7][80-BF][80-BF][80-BF]
然后根据RFC 3629规范,又有一些字节值是不允许出现在UTF-8编码中的:
所以最终,UTF-8第一字节的取值范围是:00-7F、C2-F4,这也是我在admin后面加上80-C1、F5-FF等字符时会抛出错误的原因。
关于所有的UTF-8字符,你可以在这个表中一一看到: http://utf8-chartable.de/unicode-utf8-table.pl
Mysql UTF8 特性
那么,为什么username=admin%F0也不行呢?F0是在C2-F4的范围中呀?
这又涉及到Mysql中另一个特性:Mysql的utf8其实是阉割版utf-8编码,Mysql中的utf8字符集最长只支持三个字节,所以,我们回看前文列出的UTF-8编码第一字节的范围,
三字节时范围是[E0-EF][80-BF][80-BF]
四字节时范围是[F0-F7][80-BF][80-BF][80-BF]
F0-F4是四字节才有的,所以我传入username=admin%F0也将抛出错误。
如果你需要Mysql支持四字节的utf-8,可以使用utf8mb4编码。我将原始代码中的set names改成set names utf8mb4,再看看效果:
已经成功得到结果。
本文深入研究了Mysql编码的数个特性,相信看完本文,对于第一章中的CTF题目也没有疑问了。
通过这次研究,我有几个感想:
研究东西还是需要深入,之前写那篇文章的时候并没有深入研究原理,所以心里总是很迷糊维基百科上涵盖了很多知识,有必要的时候也可以多看看
作者:离别歌
链接:/PENETRATION/mysql-charset-trick.html
炼石信息安全培训班
专注信息安全人才培养
搭建企业人才供需桥梁
咨询QQ群:
责任编辑:
声明:本文由入驻搜狐号的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。
今日搜狐热点正文 phpMyAdmin无法载入 mysqli 扩展,请检查 PHP 配置的解决方法
phpMyAdmin无法载入 mysqli 扩展,请检查 PHP 配置的解决方法
发布时间: & 编辑:
本文分享下,phpMyAdmin无法载入 mysqli 扩展,请检查 PHP 配置问题的处理方法,有遇到类似问题的朋友作个参考。
3、在C:\windows目录下的php.ini文件中,没有将&;extension=php_mysql.dll&中的前面一个&;&去掉,所以不能使用相应功能,解决方法是打开php.ini文件
4、Mysql目录没有读取权限,正确的目录权限如下:
administrator&& 完全控制
system&&& 完全控制
user&&& 读取加运行
其他的用户权限全部删除(也可保留,但安全性不高,建议删除),然后重启MYsql服务和Web服务。
调试环境:xp sp2 +IIS
php版本:PHP 5.2.0
MYsql版本:mysql-5.1.12-beta-win32
phpmyadmin版本:phpMyAdmin-2.8.2.4
网友的解决办法:
1、对于php.ini文件
进入 C:\PHP,将 php.ini-dist 复制一份放到 C:\WINNT( Windows XP/2003 下为 C:\Windows )内,改名为 php.ini,然后用记事本打开,利用记事本的查找功能搜索 extension_dir = &./&,并将其路径指到你的 PHP 目录下的 extensions 目录,比如:extension_dir = &C:\PHP\ext&;再搜索 register_globals = Off,将 Off 改成 On;
查找 ;extension=php_mysql.dll,将前面的引号&;&去掉。
2、手册中关于配置IIS的说明,将其中的&PHP\sapi\php4isapi.dll&改为php目录下的&php5isapi.dll&
3、[b]重要:在按照手册说明复制了php目录、ext([color=red]手册中对于php4x是extension,这里应该是ext)目录下的dll文件到system32的基础上,再复制php目录下的libmysql.dll文件到system32下。
重新启动IIS:
在命令提示符下,逐一执行以下命令:
复制代码 代码示例:
net stop w3svc
net stop iisadmin
net start w3svc
您可能感兴趣的文章:
phpMyAdmin导入和恢复大容量sql文件的方法
wamp打开phpmyadmin提示&缺少 mysqli 扩展。请检查 PHP 配置。&的解决方法
phpmyadmin安装出错,缺少mysqli扩展的几种解决方法
解决:phpmyadmin缺少 mysqli 扩展。请检查 PHP 配置的问题
MySQL与phpMyAdmin中文乱码的解决方法
解决Phpmyadmin导入导出时中文乱码的问题
phpmyadmin偶尔响应慢的问题的解决方法
php导入phpmyadmin导出的sql的实现代码
phpmyadmin 不能导入大SQL文件的解决方法
phpmyadmin导入大数据库文件时问题的解决方法您可能感兴趣的文章:今天升级了php版本,顺便想把php代码中的mysql连接方式改成mysqli,因为官方自php5.3开始一直推荐mysqli 和 pdo 。不多说了,贴代码
if (!function_exists('mysql_result')) {
function mysql_result($result, $number, $field=0) {
mysqli_data_seek($result, $number);
$row = mysqli_fetch_array($result);
return $row[$field];
php官方网址:
本文已收录于以下专栏:
相关文章推荐
&p style=&margin-top: 15 margin-right: 0 margin-bottom: 15 margin-left: 0 padding-top: 0 padding-right: 0 padding-bottom: 0 padding-left: 0 font-w
截至目前(2014.2), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在使用已经不在维护 [注] 的 PHP5.2, 其余的一半用户在使用 PHP5.3 [注].
因为 PHP...
欢迎关注CSDN程序人生公众号
关注程序员生活,汇聚开发轶事。
一、缓存技术:   
&p style=&margin-top: 15 margin-bottom: 15 font-size: 14 text-indent: 2 color: #2a2a2a; line-
看完本篇,你会明白国内的PHP环境和ThinkPHP为啥要采用PHP5.3甚至更高的版本。
截至目前(2014.2), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在使用已经不在...
数组定义: 
&span style=&font-size: 20px
php5.2.x php5.3.x php5.4.x php5.5.x php5.6.x 对比详解
截至目前(2014.2), PHP 的最新稳定版本是 PHP5.5, 但有差不多一半的用户仍在...
PHP生成静态页面 缓存
在速度上,静态页面要比动态页面的比方php快很多,这是毫无疑问的,但是由于静态页面的灵活性较差,如果不借助数据库或其他的设备保存相关信息的
话,整体的管理上比较繁琐,比方修改编辑.比方阅读权限限制等,但是,对应一些我们经常频频使用的文件,比方说,开发的新闻发布系统,我们不希望很多用户
都读取数据库才显示结果,这样一方面消耗了服务器的资源,另一方面占去了浏览者大量可贵的响应时间,所有,有了&静态页面话&的做法,当前很多网站都采用
这种技术,一般都是由管理后台控制,或者生成htm
转载自:/blog/jysperm/3307
PHP 5.2、5.3、5.4、5.5、5.6 对比以
点此查看原文
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)}

我要回帖

更多关于 上节课 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信