首页 电脑 电脑学堂 查看内容

查询mysql总结和预处理

2011-10-17 21:09 553 0

摘要:   任务:进一步深入mysqli_multi_query()用法。  一、连接到mysql:  $dbc = mysqli_connect(host,user,password,databasenam...
关键词: mysqli mysql result nbsp query 查询 select insert dbc rows

  任务:进一步深入mysqli_multi_query()用法。  一、连接到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'])));  七、统计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 . "] &nbsp;&nbsp;";  echo "价格:".  $rs->price . "&nbsp;&nbsp;";  echo "入库时间:".$rs->addTime . "&nbsp;&nbsp;";  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 . "] &nbsp;&nbsp;";  echo "价格:".  $rs->price . "&nbsp;&nbsp;";  echo "入库时间:".$rs->addTime . "&nbsp;&nbsp;";  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 ", 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>
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部