1. 程式人生 > >【PHP】使用引數繫結防止SQL注入

【PHP】使用引數繫結防止SQL注入

<html>
<head>
<title>Sql注入演示</title>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
</head>

<body >
<form action="" method="post">
    <fieldset>
        <legend>Sql注入演示</legend>
        <table>
            <tr>
                <td>使用者名稱:</td>
                <td><input type="text" name="username"></td>
            </tr>
            <tr>
                <td>密  碼:</td>
                <td><input type="text" name="password"></td>
            </tr>
            <tr>
                <td><input type="submit" value="提交"></td>
                <td><input type="reset" value="重置"></td>
            </tr>
        </table>
    </fieldset>
</form>
</body>
</html>

<?php

    if($_POST['username']){

        try{
            $pdo = new PDO('mysql:host=localhost;dbname=mydb', 'root', 'root');
            $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
        }catch(PDOException $e){
            die($e->getMessage());
        }


        try{
            /**
            * MySQL預處理和繫結
            * 當一條SQL被提交到MySQL的時候並不是立即執行,而是要先被編譯為資料庫可識別的指令然後再執行
            * 預處理的原理是先編譯SQL,然後等待資料的傳入,這樣,當用戶輸入例如' or 1=1 #'的資料的時候
            * 該資料就僅僅作為資料被傳入,而不再是SQL語句的一部分,從而達到預防注入的作用
            */
            $sql = "select * from users where user=:user and password=:password";
            $stmt = $pdo->prepare($sql);//對SQL進行預處理(編譯)

            //繫結引數
            $stmt->bindParam(':user', $_POST['username']);
            $stmt->bindParam(':password', $_POST['password']);

            //執行命令
            $stmt->execute();

            if($stmt->rowCount()){
                echo "登陸成功!";  
            }else{  
                echo "您的使用者名稱或密碼輸入有誤,請重新登入!";  
            }

        }catch(PDOException $e){
            die($e->getMessage());
        }

    }

?>

關於預處理提升SQL效率

過去天真的以為使用PDO的預處理,因為SQL語句編譯一次,相對於多條SQL語句,在連續的插入的情況下會提升效率。但在最近的試驗中發現並非如此

兩套複雜度相同的程式碼,連續插入5W條資料,在最後的執行結果並未有太大差異

 未使用預處理的程式碼片段

        $i=0;
        while($i < 50000){
            $user = $password = $email = mt_rand();
            $sql = "insert into users(user, password, email)values('{$user}', '{$password}', '{$email}')";
            $pdo->query($sql);
            $i++;
        }

使用預處理程式碼片段
        $i=0;
        $sql = "insert into users(user, password, email)values(:user, :password, :email)";
        $stmt = $pdo->prepare($sql);
        while ($i < 50000) {
            $param['user'] = $param['password'] = $param['email'] = mt_rand();
            $stmt->execute($param);
            $i++;
        }

最終執行時間對比
未使用預處理 使用預處理
[[email protected] pdo]# time php test3.php 
real0m49.901s
user0m0.118s
sys0m6.046s
[[email protected] pdo]# time php test4.php 
real0m49.101s
user0m0.140s
sys0m6.111s

相關推薦

PHP使用引數防止SQL注入

<html> <head> <title>Sql注入演示</title> <meta http-equiv="content-type" content="text/html;charset=utf-8"> <

javaFX屬性

         在引入屬性繫結之前,先來看個簡單的例子: import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.layout.

PHP使用PDO簡單實現防止SQL注入的方法

方法一:execute代入引數  <?php if(count($_POST)!= 0) { $host = 'aaa'; $database = 'bbb'; $username = 'ccc'; $password = '***'; $num

mysqlmysql concat函式與SQL注入

     例如:原本查詢語句是 select username,email,content from test_table where user_id=uid;其中uid,是使用者輸入的。正常顯示結果會出現使用者名稱,使用者郵箱,使用者留言內容。但是如果uid過濾不嚴,我們可以構造如下SQL語句來獲得任意資

Hibernate實戰原始碼解析Hibernate引數及PreparedStatement防SQL注入原理

    本文采用mysql驅動是5.1.38版本。    本篇文章涉及內容比較多,單就Hibernate來講就很大,再加上資料庫驅動和資料庫相關,非一篇文章或一篇專題就能說得完。本文從使用入手在【Spring實戰】----Spring4.3.2整合Hibernate5.2

SpringMVC自定義引數日期型別

前提:由於日期型別有很多種格式,springmvc無法將字串轉換成日期型別,所以需要我們根據業務需求自定義引數繫結! 第一步:自定義引數繫結器---根據介面卡引數繫結器的編碼要求規範開發bean package com.cyn.ssm.converter; impor

玩轉JDBC打造資料庫操作萬能工具類JDBCUtil,加入了高效的資料庫連線池,利用了引數有效防止SQL注入

SELECT * FROM emp_test 成功查詢到了14行資料 第1行:{DEPT_TEST_ID=10, EMP_ID=1001, SALARY=10000, HIRE_DATE=2010-01-12, BONUS=2000, MANAGER=1005, JOB=Manager, NAME=張無忌}

Revit二次開發之獲取引數的類別比目魚原創

專案引數儲存在Revit 裡,所以刪除共享引數或者共享引數檔案,都不會對專案引數產生影響,哪怕專案引數是通過共享引數建立的。專案引數在建立的時候,就已經和類別綁定了。也就是說和類別對應的元素都加上了新的引數。  在“專案引數”裡看到的引數,實際上是一系列的繫結(Bindin

SpringMVC引數學習總結前後端資料引數傳遞

目錄 1. 繫結機制 2. 支援的資料型別 3. 引數請求中文亂碼解決 4.自定義型別轉換器 5、最後引數繫結學習小結 SpringMVC作為Controller

####jquery click點選一次執行兩次解決方法遇到解決(先接觸,再):$('#addImg').unbind('click').click(function () {})

====專案例項: <%--$("body").on("click", "#toggle-button${activityDTO.id}", function (e) {--%> // 一次點選兩次觸發事件 <%--$("body").on("click", "#switc

SQLSQL注入是什麼?如何防止SQL注入

今天在優化一個查詢的時候,關於一個SQL語句的問題,發現引數傳進去是空的,導致條件查詢失敗了,查出來的是所有的資料。 剛開始是這樣寫的 <select id="selectPictureList" parameterType="map" resultMap="BaseRes

phpPDO資料庫防sql注入

安全的方式: $pdo = new PDO('mysql:host=localhost;dbname=phptry','username','passwd'); $pdo->query("SET

Asp.net之旅--資料控制元件之Repeater

引言         前幾篇的文章在說AJAX的內容,利用AJAX技術能夠開發出高效執行的網站應用程式,不過在進行B/S專案開發時只擁有AJAX技術是遠遠不夠的,踏入到B/S要學的東西會更多,但相較C/S的複雜邏輯結構來說B/S在開發時還是很簡單的。         在開

錯誤處理Mybatis錯誤 Invalid bound statement (not found)

        隔了好久重新搭建SSM框架,出現了好多BUG,但排查,解決BUG的同時也讓我更加深入地瞭解到Tomcat SSM框架等技術的執行原理。        【錯誤原因簡述】                相信大家出現這個問題的時候都會很驚訝,自己的Dao層,Mapp

web學習如何自己的Lofter獨立域名——域名解析篇

每天學習一點,成功更近一些。—— 蔣陳偉 前言        幾個月前,那時萬網搞活動,一個域名19 元(原價 39 元,有 20 元優惠券),腦袋一熱,買了。沒有考慮如何用,沒有考慮伺服器怎麼辦,沒有考慮作為一個什麼站點,總之,就是什麼都沒有考慮

Asp.net之旅--資料控制元件之DataList

       上篇部落格討論了Repeater控制元件的基本用法,它是最基本的資料繫結控制元件,只提供了資料繫結的功能,熟練運用Repeater控制元件後,其它類似的資料繫結控制元件就很簡單了。接著我們上篇部落格的內容繼續,今天來討論下DataList的基本使用方法。

分享防止重複提交表單php

表單重複提交是在多使用者Web應用中最常見、帶來很多麻煩的一個問題。有很多的應用場景都會遇到重複提交問題,比如: 點選提交按鈕兩次。點選重新整理按鈕。使用瀏覽器後退按鈕重複之前的操作,導致重複提交表單。使用瀏覽器歷史記錄重複提交表單。瀏覽器重複的HTTP請求。   幾種防止

Hexo搭建GitPage部落格系列06.獨立域名

前言 因為Hexo個人部落格是託管在github之上,每次訪問都要使用githubname.github.io這麼一個長串的域名來訪問,會顯得非常繁瑣。這個時候我們可以購買一個域名,設定DNS跳轉,以達到通過域名即可訪問我們的個人部落格。通過查閱文件發現,github

Javaweb後臺的字串轉義,入庫之前記得先對字串轉義防止sql注入問題

在《【JavaScript】某些字元不轉義可以導致網頁崩潰與涉及轉義字元的顯示方法》(點選開啟連結)提及到一種表單之前,必須把表單的輸入框的內容轉義的方法,但是,其實這種字串的轉義更加應該放在後臺中進行。這樣同時能夠有效地防止sql注入的問題。 所謂的sql注入是什麼呢?比

JQuery-02事件多次造成多次執行

問題描述:必現。先刪除A記錄,再新增A記錄,再刪除B記錄時,會連同AB一起刪除。 原因: 在彈出確認是否刪除的對話方塊中,註冊的事件{記錄id,如果點選確定則刪除該id對應的記錄;},該modaldialog一直在dom中,每刪除一次就會繫結一次。 A已經被