- 浏览: 88638 次
- 性别:
- 来自: 深圳
文章分类
最新评论
一、连接到mysql:
$dbc = mysqli_connect(host,user,password,databasename);
等价于:
$dbc = mysqli_connect(host,user,pwd);
mysqli_select_db($dbc,db_name);
如果发生错误,可以调用:mysqli_connect_error()
返回错误信息,不带参数。
$dbc = @mysqli_connect(host,user,pwd,db) or die('无法连接到mysql:'.mysqli_connect_error());
@是错误控制运算符,防止在web浏览器显示php错误。此外,@也可以放在mysqli_query前面。上面是一种首选做法,因为错误将由or die处理。die()会终止脚本执行。
可以将连接文件放在路径外。
设置编码:mysqli_query("set names gb2312");
二、执行查询:
不管是select, delete, update,insert 查询都是用:
$result=mysqli_query($dbc,SQL);
对于insert ,delete,update等查询不会返回结果,$result将返回true或false,因此可以用这个来判断下一步:
$result = mysqli_query($dbc,sql);
if($result) {//susses}
如果查询没有成功,必定发生某种mysql错误,可能调用
mysqli_error($dbc)
//注意和mysqli_connect_error()区别
三、关闭连接:
mysqli_close($dbc)
这不是必需要的,php会在脚本最后自动关闭,但最好写上。
四、多条查询:
mysqli_multi_query()
允许同时执行多条查询。但语法更复杂一点。特别是当返回结果时。
五、检索select查询结果:
mysqli_fetch_array($result [, type])
是最常用的,以数组格式一次返回一行数据。由它来配合while()
来遍历返回数据。带有一个可选参数type,用于指定返回的数组类型:关联的还是索引的,或二者均可。参数类型如下:
MYSQLI_ASSOC
示例:$rows['columnName']
MYSQLI_NUM
示例:$rows[0] ,这一种效率较高一点。
MYSQLI_BOTH
示例:$rows[0]或$rows['columnName']
当使用mysqli_fetch_array($result [, type])
后,可以采取一个可选步聚的是:一旦查询结果完成了工作,即可释放这些信息,来消除$result占用的系统内存开销。这一步是可选的,PHP同样也在会结果时自动清理:
mysqli_free_result($result)
//注意参数是不是$rows!
流程如下:
while($rows=mysqli_fetch_array($result)) //或while($rows=mysqli_fetch_array($result,MYSQLI_ASSOC))
{//遍历
.......code do something.......
echo $rows[0]
mysqli_free_result($result)
}
注意:
mysqli_fetch_array()和mysqli_fetch_array($result,MYSQLI_NUM)等价。
mysqli_fetch_assoc()和mysqli_fetch_array($result,MYSQLI_ASSOC)等价。
六、确保sql安全,使用转义函数:
mysqli_real_escape_string($dbc,para)
该函数接收字符串作为参数,用于检验用户提交的并将组合到sql查询语句的变量值,它将转义那些有可能无意或带恶意的字符。如单引号,在外国人的姓名有可能会包含该符号(如O'Toole),这时就需要用它。
案例:
$name = $_POST['name'];
$name = mysqli_real_escape_string($dbc,$name);
$query = "Select ... From tb where name='$name'";
//这样可以确保带入sql 时参数的安全。
注意:如果在使用php6之前的版本,若启用MAGIC QUOTES魔法引用时,那么在使用mysqli_real_escape_string前,需要用stripslashes(para)删除魔法引用添加的任何斜杠,如下:
$fn = mysqli_real_escape_string($dbc,trim(stripslashes($_POST['firstName'])));
备注:
在PHP5.3版本之前, mysqli_real_escape_string()函数存在路径泄漏问题,远程攻击者可以利用漏洞获得服务器端脚本的实际路径。即如果传递的参数值为数组而不是字符串的情况下会发出警告,警告消息中会包含有当前服务端运行脚本的完整路径信息。
测试方法:
http://localhost/cms/sqlfilter/sqlsanatizer.php?params
[]=
Warning: mysqli_real_escape_string() expects parameter 1 to be string,
array given in /var/www/vhosts/cms/sqlfilter/sqlsanatizer.php
七、统计select返回的记录数:
使用mysqli_num_rows($result)统计select 返回的结果行数。$num=mysqli_num_rows($r),对于上面所说的while流程,可以更改成以下更严谨的写法,而不只是分析查询是否成功,因为如果数据库为空的话,就不会出错。
$sql = "select * from tb where id=$id";
$r = @mysqli_query($dbc,$sql);
$num = mysqli_num_rows($r);
if($num>0){ //这样比if($r)更准确。不是仅仅分析是否成功运行。
// Do something;
mysqli_free_result($r)
}
mysqli_close($dbc);
八、返回insert ,update,delete受影响行数:
和上面不同的是,如果查询不是select则用mysqli_affected_rows()函数返回受影响行数。用法如下:
$num = mysqli_affected_rows($dbc);
//注意参数是$dbc;
如:
$q = "update tb set pass=SHA1('$newpassword') where id=$row[0]";
$r = @myslqi_query($dbc,$q);
if(mysqli_affected_rows($dbc)==1){
//Do something
}else{
echo mysqli_error($dbc);
exit(); //终止脚本。
}
注意:
1、如果使用truncate tb清空表时,则mysqli_affected_rows()会返回0,即使查询成功执行并且删除了每一行。
2、如果用update查询时,但实质上没有更改任何列的值,比如用相同的密码代替一个旧密码,则也会返回0。
九、批量查询:预处理语句(第12章第4节:P311)
版本:MYSQL 4.1开始添加预处理。php5可以使用。
预处理的好处:
1、更大安全性。2、更好性能。3、批量查询。
对于预处理语句,只会把查询本身发送给mysql,并且只会解析一次,然后单独把值发送给mysql。
$q = 'Insert into tb(num) values (?)';
$stmt = mysqli_prepare($dbc,$q);
mysqli_stmt_bind_param($stmt,'i',$n);
for($n=1;$n<=100;$n++)
{
mysqli_stmt_execute($stmt);
}
可以通过insert , update , delete , select 查询创建预处理,步骤:
1、定义查询:
$q = "select firstname,lastname from users where uid = ?";
//(正常则是uid=$id)
2、将查询传给mysql预处理:
$stmt = mysqli_prepare($dbc,$q);
//此时mysql会解析查询,但不会执行。
3、将变量绑定到查询占位符"?",如下:
mysqli_stmt_bind_param($stmt,'i',$id);
其中'i'的含义是mysql_stmt_bind_param函数期望接收到的值为int类型,共有以下几种:
--------------------------------------------------------------------------------
字母 表示绑定的值类型
d Decimal
i Integer
b Blob (二进制类型)
s 所有其它类型
----------------------------------------------------------------------------------
如果查询语句有多个变量,如:
$q = "select uid,firstname from users where email=? AND pass=SHA1(?)";
//注意这里都没有对?问号加单引号,即使是字符型。这是和标准查询的区别。
多个变量直接在绑定时按顺序在引号内列出即可。如下:
$stmt = mysqli_prepare($dbc,$q);
mysqli_stmt_bind_param($stmt,'ss',$e,$p);
还需要注意的时,在调用绑定函数前,可以不需要先对变量定义设置,如上面的$e,$p在下面才设置,这不会出错。
4、完成绑定后,可以给php变量赋值(如果还没有值的话)。然后执行语句。
$id=15;
mysqli_stmt_execute($stmt);
5、关闭预处理:
mysqli_stmt_close($stmt);
6、关闭连接
mysqli_close($dbc);
执行预处理时,如有出错则用mysqli_stmt_error($stmt)调用。
示例:
$dbc =mysqli_connect('localhost','username','pwd','forum');
$q = 'insert into messages(forumid,parentid,userid,subject,body,forumdate) values(?,?,?,?,?,NOW())';
$stmt = mysqli_prepare($dbc,$q);
mysqli_stmt_bind_param($stmt,'iiiss',$forumid,$parentid,$userid,$subject,$body);
$forumid = (int)$_POST['forumid'];
$parentid=(int) $_POST['parentid'];
$user_id =3;
$subject = strip_tags($_POST['subject']); //strip_tags
$body = strip_tags($_POST['body']);
mysqli_stmt_execute($stmt);
if(mysqli_stmt_affected_rows($stmt)==1)
{
//do ....
}else{
echo mysqli_stmt_error($stmt);
}
mysqli_stmt_close($stmt);
mysqli_close($dbc);
以上演示了预处理的一种语句,实际上预处理有两种语句:
1、绑定参数(bound parameter):如上面的示例
2、绑定结果(bound result):将查询结果绑定到php变量。
十、阻止sql注入:(第12章第4节:P311)
1、验证在查询中要使用的数据,如果有可能,就可执行类型强制转换。如:
$forumid = (int)$_POST['forumid'];
if($forumid>0) .... //如果强制转换成int完=0时,则不符数据型要求。
2、使用mysqli_real_escape_string($dbc,para)
3、使用mysqli_real_escape_string($dbc,para)替代办法:预处理,参上面。
十一、早先的php和mysql连接方式:
mysql_connect,在写法上只差上面一个字母i,但用法差不多。以下简单示例:
$conn = mysql_connect("127.0.0.1","mysqltest","123456");
mysql_select_db("shop"); //如果用$selectdb = mysql_select_db("shop");则$selectdb=1
mysql_query("set names gb2312"); //mysql_query("set names utf8");
$exec="select * from product";
$result=mysql_query($exec,$conn); //或:$result=mysql_query($exec);
while($rs=mysql_fetch_object($result))
{
echo "品名:[".$rs->pname . "] ";
echo "价格:".
$rs->price . " ";
echo "入库时间:".$rs->addTime . " ";
echo "<br />";
}
echo $result;
如果要进行结果判断有无再输出,则可以用:
$conn = mysql_connect("127.0.0.1","mysqltest","123456");
mysql_select_db("shop");
mysql_query("set names gb2312"); //mysql_query("set names utf8");
$exec="select * from product";
if($result=mysql_query($exec,$conn)){
while($rs=mysql_fetch_object($result))
{
echo "品名:[".$rs->pname . "] ";
echo "价格:".
$rs->price . " ";
echo "入库时间:".$rs->addTime . " ";
echo "<br />";
}
}
附:
A、在insert后取得最后一条记录:2种方法:
1、使用mysql的:last_insert_id() 函数。“insert into ....;select last_insert_id()”
2、使用php 的 mysql_insert_id() 或mysqli_insert_id() 返回同样的值:
PHP的 mysql_insert_id ( [resource $link_identifier] ) 函数可以返回你需要的ID。 可选参数是php连接mysql的句柄。 每个连接都有不同的句柄。如:
mysql_query("INSERT INTO mytable (product) values ('kossu')");
printf ("Last inserted record has id %d\n", mysql_insert_id());
B、几个函数:
trim() , ltrim(), rtrim()
exit(),
strip_tags()去掉字符串中包含的任何 HTML 及 PHP 的标记字符串。若是字符串的 HTML 及 PHP 标签原来就有错,例如少了大于的符号,则也会返回错误。而本函数和 fgetss() 有着相同的功能。
$text = '<p>Test paragraph.</p><!-- Comment --> <a href="#fragment">Other text</a>';
echo strip_tags($text); //结果:Test paragraph. Other text
// 许可用 <p> and <a>
echo strip_tags($text, '<p><a>'); //结果:<p>Test paragraph.</p> <a href="#fragment">Other text</a>
发表评论
-
RedHat下安装并开启PHP GD库的方法
2014-10-13 15:25 2070GD库是PHP进行图文操作时一个重要的库。红帽系统适合用编译安 ... -
PHP获得真实客户端的真实IP
2014-09-25 10:19 1762REMOTE_ADDR 是你的客户端跟你的服务器“握手”时候的 ... -
xxtea加密解密算法的PHP实现
2012-11-29 10:35 1589Class Xxtea { pu ... -
PHP:字符串变量中大括号(花括号{})的作用
2012-11-29 09:50 1574PHP 变量后面加上一个大括号{},里面填上数字,就是指 PH ... -
Linux下的 ZipArchive 配置
2012-08-22 13:25 3492今天在Linux底下上传Excel文件时,抛出“Z ... -
解决PHP不能上传、拷贝含有中文路径文件的问题
2012-08-01 16:29 4311在使用copy()、 move_uploaded_file ... -
empty(), is_null(), isset() 的真值表
2012-06-25 16:22 893比较全面,以便不时之需。 -
PHP获取当前时间的毫秒数
2012-06-25 16:04 238221 second = 1000 millisecond = 1 ... -
PHP之引用
2012-06-07 16:01 982所谓PHP的引用,就是不同的名字访问同一个变量内容。可 ... -
解决PHP之 Allowed memory size of xxx bytes exhausted
2012-05-25 10:30 4852今天写了个死循环 ... -
CI框架与widget(页面布局)
2012-02-10 11:24 1634在WEB开发过程中,我们免不了要输出视图文件,而 ... -
解决url传输的中文字符乱码
2011-12-31 18:16 1106今天在做接口的时候,遇到在url里带参数时,当传入中文字符 ... -
关于obstart()
2011-12-13 09:54 915最近在开发一系列 ... -
PHP开发编码规范
2011-11-29 10:20 1233在PHP的编写过程中,越 ... -
sprintf用法小记
2011-11-14 11:06 1083sprintf()函数非常适合生成数据库查询,从而避免我们手工 ... -
Apache服务器解析shtml
2011-09-16 11:27 1140首先要配置apache服务器,让apache支持shtml的解 ... -
WindowsXP下Wamp5集成安装memcached
2011-09-16 10:01 1359随着各种公司业务的发展,memcache缓存在为各公司的数 ... -
php中header的用法【转载】
2011-07-25 15:30 864header的用法 header()函数 ... -
php调用远程url的四种方法
2011-03-31 15:57 9541、 用file_get_contents 以get方式获取内 ... -
图片表单提交
2011-01-11 14:52 777很多情况下为了美化表单都会把提交按钮改成用一个图片来代替。 图 ...
相关推荐
MYSQL C API预处理语句
python3对mysql的预处理支持并不是很好,网上很多人说python并不支持mysql预处理,其实mysql官方是有提供支持的,但是依然不友好,所以本人修改源码提供了补丁,以期python3能像php那样支持mysql预处理
关于mysql知识点的xmind总结,包含mysql的基础介绍,普通用法以及高级用法
PHP MySQL 预处理语句.rar
Mysql百万级以上查询优化总结,,对mysql表优化、索引优化
mysql 树形结构查询,使用存储过程,实现mysql的树形结构查询
Mysql 时间模糊查询,不同场景的查询方式,根据条件查询
候选界面包括MySQL C API客户端库(用于C程序)、MySQL Connector/J(用于Java程序)和MySQL Connector/NET。例如,C API可以提供一套能组成预制语句API的函数调用。其它语言界面可以对使用了二进制协议(通过在C...
MySQL总结和课程大纲.xmind
代码如下: DELIMITER $$ set @stmt = ... 用这种形式写的查询,可以随意替换参数,给出代码的人称之为预处理,我想这个应该就是MySQL中的变量绑定吧……但是,在查资料的过程中我却听到了两种声音,一种是,MySQL中有
mysql多表查询和EXISTS查询性能对比
多线程(线程数可调节),处理千万级mysql数据表,预处理+数据迁移到新表 执行脚本(参数20000 为每一个线程执行的数据量,代码默认30线程)
预处理语句对于防止 MySQL 注入是非常有用的。 预处理语句及绑定参数 预处理语句用于执行多个相同的 SQL 语句,并且执行效率更高。 预处理语句的工作原理如下: 预处理:创建 SQL 语句模板并发送到数据库。预留的值...
自己封装的PDO类,可以处理mysql增删改查等基础操作,也可以实现执行原装的sql语句,支持预处理。
对Mysql基础进行的总结,加深记忆和理解。
从实践看,MySQL的子查询优化技术的内容和范围,明确掌握子查询优化手段 预计时间2小时,每小时一个课程段(子查询是SQL查询优化的重点内容,务必掌握好) 第5课 查询优化技术理论与MySQL实践(三)------视图重写...
MySQL官方将prepare、execute、deallocate统称为PREPARE STATEMENT,我习惯称其为【预处理语句】,其用法十分简单,下面话不多说,来一起看看详细的介绍吧。 示例代码 PREPARE stmt_name FROM preparable_stmt ...
用了将近一周的时间对mysql进行了初步的学习,总结成思维导图,主要内容包括有基本使用,查询,与python的交互,事务,视图,索引,账户管理,主从同步配置等内容。
25.3.1. 使用MySQL和PHP的常见问题 25.4. MySQL Perl API 25.5. MySQL C++ API 25.5.1. Borland C++ 25.6. MySQL Python API 25.7. MySQL Tcl API 25.8. MySQL Eiffel Wrapper 25.9. MySQL程序开发实用工具 25.9.1. ...