PHP开发中遇到的问题
1. 数据库连接
问题:在执行sql语句的函数中,因为strsql用单引号引住,所以里面的变量值无法获得,
方法一:
通过字符串连接的方式完成(.):‘字符串’+.变量来构成一条完整的sql语句。如下面代码所示:
//这个函数的作用是,如果输入框的数据发生改变,则更新到服务器中 public function UpdateProjInfo($uPid = 0) { $uPid = intval($uPid); if ($uPid <= 0) { echo '{"success":0,"error":"未指定项目"}'; return; } //从前端获取两个数据:column和changed_value $column = $_POST['col']; $changed_value = $_POST['changed_value']; $oDBConn = $this->_createMysqlConn(); $oResult = $this->_execSql($oDBConn,'UPDATE `tbl_project` SET '.$column.'='. $changed_value); if ($oResult) $strRsp = '{"success":1,"messg":"Update Success"}'; else $strRsp = '{"success":0,"error":"数据更改失败"}'; mysqli_close($oDBConn); echo $strRsp; } };
方法二:预处理语句
在网上还找到一种方式——预处理语句,绑定参数及绑定结果。因为我们项目中封装的是mysqli接口,blabla我也不太清楚,一直没成功,所以只是先贴在这里,供以后参考。
预处理语句对于防止 MySQL 注入是非常有用的。使用预准备语句可提高重复使用语句的性能,在PHP中,使用prepare()方法来进行预准备语句查询,使用execute()方法来执行预准备语句。PHP有两种预准备语句:一种是绑定结果,另一种是绑定参数。
1. 工作原理
1)预处理:创建SQL语句模板并发送到数据库。预留的值用参数“?”来标记,例如:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)";
2)数据库解析,编译,对SQL语句模板执行查询优化,并存储结果不输出。
3)执行:最后,将应用绑定的值传递给参数(”?” 标记),数据库执行语句。应用可以多次执行语句,如果参数的值不一样。
2. 优点
相比于直接执行SQL语句,预处理语句有两个主要优点:
- 预处理语句大大减少了分析时间,只做了一次查询(虽然语句多次执行)。
- 绑定参数减少了服务器带宽,你只需要发送查询的参数,而不是整个语句。
- 预处理语句针对SQL注入是非常有用的,因为参数值发送后使用不同的协议,保证了数据的合法性。
3. 具体实现——MySQLi 预处理语句及绑定参数
<?php $servername = "localhost"; $username = "username"; $password = "password"; $dbname = "ikeepstudying"; // 创建连接 $conn = new mysqli($servername, $username, $password, $dbname); // 检测连接 if ($conn->connect_error) { die("连接失败: " . $conn->connect_error); } // 预处理及绑定 $stmt = $conn->prepare("INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)"); $stmt->bind_param("sss", $firstname, $lastname, $email); // 设置参数并执行 $firstname = "John"; $lastname = "Doe"; $email = "john@example.com"; $stmt->execute(); $firstname = "Mary"; $lastname = "Moe"; $email = "mary@example.com"; $stmt->execute(); $firstname = "Julie"; $lastname = "Dooley"; $email = "julie@example.com"; $stmt->execute(); echo "新记录插入成功"; $stmt->close(); $conn->close(); ?>
解析以下实例的每行代码:
"INSERT INTO MyGuests (firstname, lastname, email) VALUES(?, ?, ?)"
在 SQL 语句中,我们使用了问号 (?),在此我们可以将问号替换为整型,字符串,双精度浮点型和布尔值。
接下来,让我们来看下 bind_param() 函数:
$stmt->bind_param("sss", $firstname, $lastname, $email);
该函数绑定了 SQL 的参数,且告诉数据库参数的值。 “sss” 参数列处理其余参数的数据类型。s 字符告诉数据库该参数为字符串。
types:绑定的变量的数据类型,它接受的字符种类包括4个,如表所示。
参数types接受的字符的种类和绑定的变量需要一一对应。通过告诉数据库参数的数据类型,可以降低 SQL 注入的风险。
4. MySQLi 预处理语句及绑定结果
所谓绑定结果就是把PHP脚本中的自定义变量绑定到结果集中的相应字段上,这些变量就代表着所查询的记录,绑定结果的示例代码如下:
<?php $mysqli = new mysqli("localhost","root","root","ikeepstudying"); //实例化mysqli $query = "select * from MyGuests"; $result = $mysqli->prepare($query); //进行预准备语句查询 $result->execute(); //执行预准备语句 $result->bind_result($id,$firstname,$lastname,$email); //绑定结果 while ($result->fetch()) { echo $id; echo $firstname; echo $lastname; echo $email; } $result->close(); //关闭预准备语句 ?>
在绑定结果的时候,脚本中的变量要与结果集中的字段一一对应,绑定完以后,通过fetch()方法将绑定在结果集中的变量一一取出来,最后将预准备语句和数据库连接分别关闭。
5. MySQLi 同时绑定参数和绑定结果
在一个脚本中还可以同时绑定参数和绑定结果,示例代码如下:
<?php $conn = new mysqli("localhost","root","root","ikeepstudying"); //实例化mysqli $query = "select * from MyGuests where id < ?"; $result = $conn->prepare($query); $result->bind_param("i",$id); //绑定参数 $id=4; $result->execute(); $result->bind_result($id,$number,$name,$age); //绑定结果 while ($result->fetch()) { echo $id; echo $firstname; echo $lastname; echo $email; } $result->close(); $conn->close(); ?>
详情请看:网页链接