时间:2021-07-01 10:21:17 帮助过:13人阅读
可是我在mysql版本的函数,上面的sql都不能执行。是不是不支持多重查询了?
这篇文章 http://www.runoob.com/php/php-mysql-connect.html 对mysqli, PDO的方式有一些介绍,不详细。
主要用的这篇文章:http://blog.csdn.net/yipiankongbai/article/details/17277477
三种连接方式:
- <span style="color: #008000">//</span><span style="color: #008000"> PDO </span>
- $pdo = <span style="color: #0000ff">new</span> PDO("mysql:host=localhost;dbname=database", ‘username‘, ‘password‘<span style="color: #000000">);
- </span><span style="color: #008000">//</span><span style="color: #008000"> mysqli, procedural way </span>
- $mysqli = mysqli_connect(‘localhost‘,‘username‘,‘password‘,‘database‘<span style="color: #000000">);
- </span><span style="color: #008000">//</span><span style="color: #008000"> mysqli, object oriented way </span>
- $mysqli = <span style="color: #0000ff">new</span> mysqli(‘localhost‘,‘username‘,‘password‘,‘database‘);
先看mysqli过程型:
- <?<span style="color: #000000">php
- header(</span>‘Content-Type: text/html; charset=utf-8‘<span style="color: #000000">);
- echo </span>"PHP version:" . PHP_VERSION . "<br/>"<span style="color: #000000">;
- $con </span>= mysqli_connect(‘10.117.146.21:8306‘, ‘root‘, ‘[password]‘<span style="color: #000000">);
- mysqli_select_db($con, </span>‘springdemo‘<span style="color: #000000">);
- $input_id </span>= trim($_GET[‘id‘<span style="color: #000000">]);
- $sql </span>= ‘select nickname from user where id = ‘<span style="color: #000000"> . $input_id;
- print_r(</span>‘SQL is:‘ . $sql . ‘<br/>‘<span style="color: #000000">);
- $result </span>=<span style="color: #000000"> mysqli_query($con, $sql);
- </span><span style="color: #0000ff">if</span> ($result != <span style="color: #0000ff">null</span><span style="color: #000000">) {
- print_r(</span>‘rows:‘ . mysqli_num_rows($result) . ‘<br/>‘<span style="color: #000000">);
- </span><span style="color: #0000ff">while</span> ($row =<span style="color: #000000"> mysqli_fetch_array($result)) {
- print_r($row[</span>‘nickname‘] . ‘<br/>‘<span style="color: #000000">);
- }
- }
- mysqli_close($con);
- </span>?>
测试:
- http:<span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- SQL is:select nickname from user where id </span>= 3<span style="color: #000000">
- rows:</span>1<span style="color: #000000">
- micro
- http:</span><span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3%20or%201=1</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- SQL is:select nickname from user where id </span>= 3 or 1=1<span style="color: #000000">
- rows:</span>4<span style="color: #000000">
- abc
- micro
- helloworld
- 你好</span>
加上real_escape函数:
- ?<span style="color: #000000">php
- header(</span>‘Content-Type: text/html; charset=utf-8‘<span style="color: #000000">);
- echo </span>"PHP version:" . PHP_VERSION . "<br/>"<span style="color: #000000">;
- $con </span>= mysqli_connect(‘10.117.146.21:8306‘, ‘root‘, ‘[password]‘<span style="color: #000000">);
- mysqli_select_db($con, </span>‘springdemo‘<span style="color: #000000">);
- $input_id </span>= mysqli_real_escape_string($con, $_GET[‘id‘<span style="color: #000000">]);
- $sql </span>= ‘select nickname from user where id = ‘<span style="color: #000000"> . $input_id;
- print_r(</span>‘SQL is:‘ . $sql . ‘<br/>‘<span style="color: #000000">);
- $result </span>=<span style="color: #000000"> mysqli_query($con, $sql);
- </span><span style="color: #0000ff">if</span> ($result != <span style="color: #0000ff">null</span><span style="color: #000000">) {
- print_r(</span>‘rows:‘ . mysqli_num_rows($result) . ‘<br/>‘<span style="color: #000000">);
- </span><span style="color: #0000ff">while</span> ($row =<span style="color: #000000"> mysqli_fetch_array($result)) {
- print_r($row[</span>‘nickname‘] . ‘<br/>‘<span style="color: #000000">);
- }
- }
- mysqli_close($con);
- </span>?>
测试:
- http:<span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3%20or%201=1</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- SQL is:select nickname from user where id </span>= 3 or 1=1<span style="color: #000000">
- rows:</span>4<span style="color: #000000">
- abc
- micro
- helloworld
- 你好
- <span style="color: #ff0000">注:仍然有问题,因为没有在url里面加引号!</span></span>
采用推荐的mysqli的PreparedStatement方式:
- ?<span style="color: #000000">php
- header(</span>‘Content-Type: text/html; charset=utf-8‘<span style="color: #000000">);
- echo </span>"PHP version:" . PHP_VERSION . "<br/>"<span style="color: #000000">;
- $con </span>= <span style="color: #0000ff">new</span> mysqli(‘10.117.146.21:8306‘, ‘root‘, ‘[password]‘, ‘springdemo‘<span style="color: #000000">);
- </span><span style="color: #008000">//</span><span style="color: #008000">mysqli_select_db($con, ‘springdemo‘);</span>
- <span style="color: #000000">
- $query </span>= $con->prepare(‘SELECT nickname FROM user WHERE id = ?‘<span style="color: #000000">);
- <span style="color: #ff0000">$query</span></span><span style="color: #ff0000">->bind_param(‘s‘, $_GET[‘id‘</span><span style="color: #000000"><span style="color: #ff0000">]);</span>
- $query</span>-><span style="color: #000000">execute();
- <span style="color: #ff0000">$result </span></span><span style="color: #ff0000">= $query->get_result();
- </span><span style="color: #0000ff">if</span> ($result != <span style="color: #0000ff">null</span><span style="color: #000000">) {
- print_r(</span>‘rows:‘ . mysqli_num_rows($result) . ‘<br/>‘<span style="color: #000000">);
- </span><span style="color: #0000ff">while</span> ($row =<span style="color: #000000"> mysqli_fetch_array($result)) {
- print_r($row[</span>‘nickname‘] . ‘<br/>‘<span style="color: #000000">);
- }
- }
- mysqli_close($con);
- </span>?>
测试:
- http:<span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- rows:</span>1<span style="color: #000000">
- micro
- http:</span><span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3%20or%201=1</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- rows:</span>1<span style="color: #000000">
- micro</span>
PDO与mysqli的对比:
- <span style="color: #000000">性能
- PDO和MySQLi都有非常好的性能。在非prepared statements的基准测试下,MySQLi略快2.</span>5%,而prepared statements下是6.5%,可以说对于性能无关紧要。
PDO | MySQLi | |
Database support | 12 different drivers | MySQL only |
API | OOP | OOP + procedural |
Connection | Easy | Easy |
Named parameters | Yes | No |
Object mapping | Yes | Yes |
Prepared statements (client side) |
Yes | No |
Performance | Fast | Fast |
Stored procedures | Yes | Yes |
PDO方式:
- <?<span style="color: #000000">php
- header(</span>‘Content-Type: text/html; charset=utf-8‘<span style="color: #000000">);
- echo </span>"PHP version:" . PHP_VERSION . "<br/>"<span style="color: #000000">;
- $pdo </span>= <span style="color: #0000ff">new</span> PDO("mysql:host=10.117.146.21:8306;dbname=springdemo", ‘root‘, ‘[password]‘<span style="color: #000000">);
- </span><span style="color: #0000ff">class</span><span style="color: #000000"> Name {
- </span><span style="color: #0000ff">public</span><span style="color: #000000"> $nickname;
- </span><span style="color: #0000ff">public</span><span style="color: #000000"> function info()
- {
- </span><span style="color: #0000ff">return</span> ‘#‘.$<span style="color: #0000ff">this</span>-><span style="color: #000000">nickname;
- }
- }
- $input_id </span>= $_GET[‘id‘<span style="color: #000000">];
- $sql </span>= ‘select nickname from user where id = ‘<span style="color: #000000"> . $input_id;
- print_r(</span>‘SQL is:‘ . $sql . ‘<br/>‘<span style="color: #000000">);
- $result </span>= $pdo-><span style="color: #000000">query($sql);
- $result</span>->setFetchMode(PDO::FETCH_CLASS, ‘Name‘<span style="color: #000000">);
- </span><span style="color: #0000ff">if</span> ($result != <span style="color: #0000ff">null</span><span style="color: #000000">) {
- </span><span style="color: #0000ff">while</span> ($row = $result-><span style="color: #000000">fetch()) {
- print_r($row</span>->info() . ‘<br/>‘<span style="color: #000000">);
- }
- }
- $pdo</span>=<span style="color: #0000ff">null</span><span style="color: #000000">;
- </span>?>
测试:
- http:<span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- SQL is:select nickname from user where id </span>= 3<span style="color: #000000">
- #micro
- http:</span><span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3%20or%201=1</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- SQL is:select nickname from user where id </span>= 3 or 1=1<span style="color: #000000">
- #abc
- #micro
- #helloworld
- #你好</span>
加上转码:
- <span style="color: #ff0000">$input_id = $pdo->quote($_GET[‘id‘]);</span>
测试:
- http:<span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- SQL is:select nickname from user where id </span>= ‘3‘<span style="color: #000000">
- #micro
- http:</span><span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3%20or%201=1</span>
- <span style="color: #ff0000">
- PHP version:5.5.30
- SQL is:select nickname from user where id = ‘3 or 1=1‘
- #micro</span>
注意,pdo的quote自动加了引号,解决了这个问题。
- http:<span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3%27%20or%201=%271</span>
- <span style="color: #ff0000">
- PHP version:5.5.30
- SQL is:select nickname from user where id = ‘3\‘ or 1=\‘1‘
- #micro</span>
并且,尝试自己加引号去做侵入也没有用的。引号被转码了,所以成功防住攻击。
PDO的prepared statement:
- <?<span style="color: #000000">php
- header(</span>‘Content-Type: text/html; charset=utf-8‘<span style="color: #000000">);
- echo </span>"PHP version:" . PHP_VERSION . "<br/>"<span style="color: #000000">;
- $pdo </span>= <span style="color: #0000ff">new</span> PDO("mysql:host=10.117.146.21:8306;dbname=springdemo", ‘root‘, ‘[password]‘<span style="color: #000000">);
- </span><span style="color: #ff0000">
- $prepared = $pdo->prepare(‘select nickname from user where id = :id‘);
- $prepared->execute(array(‘:id‘ => $_GET[‘id‘]));
- while ($results = $prepared-></span><span style="color: #000000"><span style="color: #ff0000">fetch(PDO::FETCH_ASSOC)) {</span>
- print_r($results[</span>‘nickname‘] . ‘<br/>‘<span style="color: #000000">);
- }
- $pdo</span>=<span style="color: #0000ff">null</span><span style="color: #000000">;
- </span>?>
实验:
- http:<span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- micro
- http:</span><span style="color: #008000">//</span><span style="color: #008000">localhost:8080/test.php?id=3%20or%201=1</span>
- <span style="color: #000000">
- PHP version:</span>5.5.30<span style="color: #000000">
- micro</span>
都不再出现sql注入的威胁。
PDO里面多次用到fetch:
值 | 说明 |
---|---|
PDO::FETCH_ASSOC | 关联数组形式。 |
PDO::FETCH_NUM | 数字索引数组形式。 |
PDO::FETCH_BOTH | 两者数组形式都有,这是默认的。 |
PDO::FETCH_OBJ | 按照对象的形式,类似于以前的mysql_fetch_object()函数。 |
PDO::FETCH_BOUND | 以布尔值的形式返回结果,同时将获取的列值赋给bindParam()方法中指定的变量。 |
PDO::FETCH_LAZY | 以关联数组、数字索引数组和对象3种形式返回结果。 |
把上面程序给prepared statement传参数的过程改了一下:
- <?<span style="color: #000000">php
- header(</span>‘Content-Type: text/html; charset=utf-8‘<span style="color: #000000">);
- echo </span>"PHP version:" . PHP_VERSION . "<br/>"<span style="color: #000000">;
- $pdo </span>= <span style="color: #0000ff">new</span> PDO("mysql:host=10.117.146.21:8306;dbname=springdemo", ‘root‘, ‘[password]‘<span style="color: #000000">);
- <span style="color: #ff0000">$prepared </span></span><span style="color: #ff0000">= $pdo->prepare(‘select nickname from user where id = :id‘);
- $prepared->bindParam(‘:id‘, $_GET[‘id‘]);
- $prepared->execute();
- </span><span style="color: #0000ff">while</span> ($results = $prepared-><span style="color: #000000">fetch(PDO::FETCH_ASSOC)) {
- print_r($results[</span>‘nickname‘] . ‘<br/>‘<span style="color: #000000">);
- }
- $pdo</span>=<span style="color: #0000ff">null</span><span style="color: #000000">;
- </span>?>
实验之后,结果对于上面哪些url,都能得到正确的结果。
性能方面:
- PDO和MySQLi都有非常好的性能。在非prepared statements的基准测试下,MySQLi略快2.5%,而prepared statements下是6.5%,可以说对于性能无关紧要。<br>如果你真的非常介意这一点点性能的话,而自带的MySQL扩展比两者都快,你可以考虑下它。
上面部分来自这篇:http://blog.csdn.net/yipiankongbai/article/details/17277477 《PDO vs. MySQLi 选择哪一个?》
PDO(PHP Data Object),Mysqli,以及对sql注入等问题的解决
标签:函数 state 版本 自动 mode string color ble 对象