當前位置:首頁 » 編程語言 » php參數綁定

php參數綁定

發布時間: 2022-07-24 23:33:52

A. php 開發中有效防禦 sql 注入攻擊有哪些好方法

使用PDO或者MySQLi,有很多封裝好的方便的Class。
例如使用PHP-PDO-MySQL-Class · GitHub(這個Class使用上比較類似Python的MySQLdb)的話,這樣就是安全的:
<?php
$DB->query("SELECT * FROM fruit WHERE name IN (?)",array($_GET['pm1'],$_GET['pm2']));
$DB->query("SELECT * FROM users WHERE name=? and password=?",array($_GET['name'],$_GET['pw']));
?>

直接拼接字元串則是危險的:
<?php
$DB->query("SELECT * FROM fruit WHERE name IN ('".$_GET['pm1']."','".$_GET['pm2']."')");
$DB->query("SELECT * FROM users WHERE name='".$_GET['name']."' and password='".$_GET['pw']."'");
?>

PDO參數綁定的原理是將命令與參數分兩次發送到MySQL,MySQL就能識別參數與命令,從而避免SQL注入(在參數上構造命令)。
mysql在新版本PHP中已經預廢棄,使用的話會拋出錯誤,現在建議使用MySQLi或者MySQL_PDO。

B. php函數參數中的&符號是什麼意思

在PHP中&符號即傳的是變數的引用而不是拷貝,引用意味著用不同的名字訪問同一個變數內容。這並不像 C 的指針,它們是符號表別名。注意在 PHP 中,變數名和變數內容是不一樣的,因此同樣的內容可以有不同的名字。最接近的比喻是 Unix 的文件名和文件本身 - 變數名是目錄條目,而變數內容則是文件本身。引用可以被看作是 Unix 文件系統中的緊密連接。

PHP 的引用允許你用兩個變數來指向同一個內容。意思是,當你這樣做時:
<?php
$a =&$b
?>
這意味著 $a 和 $b 指向了同一個變數。
注: $a 和 $b 在這里是完全相同的,這並不是 $a 指向了 $b 或者相反,而是 $a 和 $b 指向了同一個地方。
同樣的語法可以用在函數中,它返回引用,以及用在 new 運算符中(PHP 4.0.4 以及以後版本):
<?php
$bar =& new fooclass();
$foo =& find_var ($bar);
?>
注: 不用 & 運算符導致對象生成了一個拷貝。如果你在類中用 $this,它將作用於該類當前的實例。沒有用 & 的賦值將拷貝這個實例(例如對象)並且 $this 將作用於這個拷貝上,這並不總是想要的結果。由於性能和內存消耗的問題,通常你只想工作在一個實例上面。
盡管你可以用 @ 運算符來關閉構造函數中的任何錯誤信息,例如用 @new,但用 &new 語句時這不起效果。這是 Zend 引擎的一個限制並且會導致一個解析錯誤。
引用做的第二件事是用引用傳遞變數。這是通過在函數內建立一個本地變數並且該變數在呼叫范圍內引用了同一個內容來實現的。例如:
<?php
function foo (&$var) {
$var++;
}
$a=5;
foo ($a);
?>
將使 $a 變成 6。這是因為在 foo 函數中變數 $var 指向了和 $a 指向的同一個內容。更多詳細解釋見引用傳遞。
引用做的第三件事是引用返回。
引用不是什麼
如前所述,引用不是指針。這意味著下面的結構不會產生你預期的效果:
<?php
function foo (&$var){
$var =& $GLOBALS["baz"];
}
foo($bar);
?>
這將使 foo 函數中的 $var 變數在函數調用時和 $bar 綁定在一起,但接著又被重新綁定到了 $GLOBALS["baz"] 上面。不可能通過引用機制將 $bar 在函數調用范圍內綁定到別的變數上面,因為在函數 foo 中並沒有變數 $bar(它被表示為 $var,但是 $var 只有變數內容而沒有調用符號表中的名字到值的綁定)。
引用傳遞
你可以將一個變數通過引用傳遞給函數,這樣該函數就可以修改其參數的值。語法如下:
<?php
function foo (&$var) {
$var++;
}
$a=5;
foo ($a);
// $a is 6 here
?>
注意在函數調用時沒有引用符號 - 只有函數定義中有。光是函數定義就足夠使參數通過引用來正確傳遞了。
以下內容可以通過引用傳遞:
變數,例如 foo($a)
New 語句,例如 foo(new foobar())
從函數中返回的引用,例如:
<?php
function &bar() {
$a = 5;
return $a;
}
foo(bar());
?>
詳細解釋見引用返回。
任何其它表達式都不能通過引用傳遞,結果未定義。例如下面引用傳遞的例子是無效的:
<?php
function bar(){ // Note the missing &
$a = 5;
return $a;
}
foo(bar());
foo($a = 5) // 表達式,不是變數
foo(5) // 常量,不是變數
?>
這些條件是 PHP 4.0.4 以及以後版本有的。
引用返回
引用返回用在當你想用函數找到引用應該被綁定在哪一個變數上面時。當返回引用時,使用此語法:
<?php
function &find_var ($param){
/* ...code... */
return $found_var;
}
$foo =& find_var ($bar);
$foo->x = 2;
?>
本例中 find_var 函數所返回的對象的屬性將被設定(譯者:指的是 $foo->x = 2; 語句),而不是拷貝,就和沒有用引用語法一樣。
注: 和參數傳遞不同,這里必須在兩個地方都用 & 符號 - 來指出返回的是一個引用,而不是通常的一個拷貝,同樣也指出 $foo 是作為引用的綁定,而不是通常的賦值。
取消引用
當你 unset 一個引用,只是斷開了變數名和變數內容之間的綁定。這並不意味著變數內容被銷毀了。例如:
<?php
$a = 1;
$b =& $a;
unset ($a);
?>
不會 unset $b,只是 $a。
再拿這個和 Unix 的 unlink 調用來類比一下可能有助於理解。
引用定位
許多 PHP 的語法結構是通過引用機制實現的,所以上述有關引用綁定的一切也都適用於這些結構。一些結構,例如引用傳遞和返回,已經在上面提到了。其它使用引用的結構有:
global 引用
當用 global $var 聲明一個變數時實際上建立了一個到全局變數的引用。也就是說和這樣做是相同的:
<?php
$var =& $GLOBALS["var"];
?>
這意味著,例如,unset $var 不會 unset 全局變數。
$this
在一個對象的方法中,$this 永遠是調用它的對象的引用。

C. php mysqli 預處理 怎麼綁定參數

預處理:創建 SQL 語句模板並發送到資料庫。預留的值使用參數 "?" 標記 。
資料庫解析,編譯,對SQL語句模板執行查詢優化,並存儲結果不輸出
執行:最後,將應用綁定的值傳遞給參數("?" 標記),資料庫執行語句。應用可以多次執行語句,如果參數的值不一樣。如果你有時間的話,可以多去後盾人學習學習,應該有更多的體驗

D. php中用參數傳遞的pdo查詢語句怎麼寫

方法 bindParam() 和 bindValue() 非常相似。
唯一的區別就是前者使用一個PHP變數綁定參數,而後者使用一個值。
所以使用bindParam是第二個參數只能用變數名,而不能用變數值,而bindValue至可以使用具體值。
復制代碼 代碼如下:

$stm = $pdo->prepare("select * from users where user = :user");
$user = "jack";
//正確
$stm->bindParam(":user",$user);
//錯誤
//$stm->bindParam(":user","jack");
//正確
$stm->bindValue(":user",$user);
//正確
$stm->bindValue(":user","jack");

另外在存儲過程中,bindParam可以綁定為input/output變數,如下面:
復制代碼 代碼如下:

$stm = $pdo->prepare("call func(:param1)");
$param1 = "abcd";
$stm->bindParam(":param1",$param1); //正確
$stm->execute();

存儲過程執行過後的結果可以直接反應到變數上。
對於那些內存中的大數據塊參數,處於性能的考慮,應優先使用前者。
--------------------------------------------------
http://zh.wikipedia.org/wiki/%E5%8F%83%E6%95%B8%E5%8C%96%E6%9F%A5%E8%A9%A2
參數化查詢
參數化查詢(Parameterized Query 或 Parameterized Statement)是指在設計與資料庫連結並訪問數據時,在需要填入數值或數據的地方,使用參數 (Parameter) 來給值,這個方法目前已被視為最有效可預防SQL注入攻擊 (SQL Injection) 的攻擊手法的防禦方式。有部份的開發人員可能會認為使用參數化查詢,會讓程序更不好維護,或者在實現部份功能上會非常不便[來源請求],然而,使用參數化查詢造成的額外開發成本,通常都遠低於因為SQL注入攻擊漏洞被發現而遭受攻擊,所造成的重大損失。
除了安全因素,相比起拼接字元串的 SQL 語句,參數化的查詢往往有性能優勢。因為參數化的查詢能讓不同的數據通過參數到達資料庫,從而公用同一條 SQL 語句。大多數資料庫會緩存解釋 SQL 語句產生的位元組碼而省下重復解析的開銷。如果採取拼接字元串的 SQL 語句,則會由於操作數據是 SQL 語句的一部分而非參數的一部分,而反復大量解釋 SQL 語句產生不必要的開銷。
目錄
* 1 原理
* 2 SQL 指令撰寫方法
o 2.1 Microsoft SQL Server
o 2.2 Microsoft Access
o 2.3 MySQL
o 2.4 PostgreSQL/SQLite
* 3 客戶端程序撰寫方法
o 3.1 ADO.NET
o 3.2 PDO
o 3.3 JDBC
o 3.4 Cold Fusion
[編輯] 原理
在使用參數化查詢的情況下,資料庫伺服器不會將參數的內容視為SQL指令的一部份來處理,而是在資料庫完成 SQL 指令的編譯後,才套用參數運行,因此就算參數中含有具破壞性的指令,也不會被資料庫所運行。
[編輯] SQL 指令撰寫方法
在撰寫 SQL 指令時,利用參數來代表需要填入的數值,例如:
[編輯] Microsoft SQL Server
Microsoft SQL Server 的參數格式是以 "@" 字元加上參數名稱而成,SQL Server 亦支持匿名參數 "?"。
SELECT * FROM myTable WHERE myID = @myID
INSERT INTO myTable (c1, c2, c3, c4) VALUES (@c1, @c2, @c3, @c4)
[編輯] Microsoft Access
Microsoft Access 不支持具名參數,只支持匿名參數 "?"。
UPDATE myTable SET c1 = ?, c2 = ?, c3 = ? WHERE c4 = ?
[編輯] MySQL
MySQL 的參數格式是以 "?" 字元加上參數名稱而成。
UPDATE myTable SET c1 = ?c1, c2 = ?c2, c3 = ?c3 WHERE c4 = ?c4
[編輯] PostgreSQL/SQLite
PostgreSQL 和 SQLite 的參數格式是以 「:」 加上參數名而成。當然,也支持類似 Access 的匿名參數。
UPDATE "myTable" SET "c1" = :c1, "c2" = :c2, "c3" = :c3 WHERE "c4" = :c4
[編輯] 客戶端程序撰寫方法
在客戶端代碼中撰寫使用參數的代碼,例如:
[編輯] ADO.NET
ADO.NET用於ASP.NET之內。
SqlCommand sqlcmd = new SqlCommand("INSERT INTO myTable (c1, c2, c3, c4) VALUES (@c1, @c2, @c3, @c4)", sqlconn);
sqlcmd.Parameters.AddWithValue("@c1", 1); // 設定參數 @c1 的值。
sqlcmd.Parameters.AddWithValue("@c2", 2); // 設定參數 @c2 的值。
sqlcmd.Parameters.AddWithValue("@c3", 3); // 設定參數 @c3 的值。
sqlcmd.Parameters.AddWithValue("@c4", 4); // 設定參數 @c4 的值。
sqlconn.Open();
sqlcmd.ExecuteNonQuery();
sqlconn.Close();
[編輯] PDO
PDO用於PHP之內。 在使用 PDO 驅動時,參數查詢的使用方法一般為:
復制代碼 代碼如下:

// 實例化數據抽象層對象
$db = new PDO('pgsql:host=127.0.0.1;port=5432;dbname=testdb');
// 對 SQL 語句執行 prepare,得到 PDOStatement 對象
$stmt = $db->prepare('SELECT * FROM "myTable" WHERE "id" = :id AND "is_valid" = :is_valid');
// 綁定參數
$stmt->bindValue(':id', $id);
$stmt->bindValue(':is_valid', true);
// 查詢
$stmt->execute();
// 獲取數據
foreach($stmt as $row) {
var_mp($row);
}
[code]
對於 MySQL 的特定驅動,也可以這樣使用:
$db = new mysqli("localhost", "user", "pass", "database");
$stmt = $mysqli -> prepare("SELECT priv FROM testUsers WHERE username=? AND password=?");
$stmt -> bind_param("ss", $user, $pass);
$stmt -> execute();
值得注意的是,以下方式雖然能有效防止 SQL注入 (歸功於 mysql_real_escape_string 函數的轉義),但並不是真正的參數化查詢。其本質仍然是拼接字元串的 SQL 語句。
[code]
$query = sprintf("SELECT * FROM Users where UserName='%s' and Password='%s'",
mysql_real_escape_string($Username),
mysql_real_escape_string($Password));
mysql_query($query);

[編輯] JDBC
JDBC用於java之內。
java.sql.PreparedStatement prep = connection.prepareStatement(
"SELECT * FROM `users` WHERE USERNAME = ? AND PASSWORD = ?");
prep.setString(1, username);
prep.setString(2, password);
prep.executeQuery();
[編輯] Cold Fusion
<cfquery name="Recordset1" datasource="cafetownsend">
SELECT *
FROM COMMENTS
WHERE COMMENT_ID =<cfqueryparam value="#URL.COMMENT_ID#" cfsqltype="cf_sql_numeric">
</cfquery>

E. thinkphp3.2 參數綁定是什麼意思

這是防止thinkPHP框架里的I方法過濾不全而設置的。
以下是我對於bind的理解:
例如:
$bind[':name']="abc \' or 1 =1 '";//這是注入輸入的信息;
$where['name']=": name";
$User=M('user');
$User->where($where)->bind($bind)->select();
mysql語句輸出為 :select * from user where name="abc or 1 =1 '";
bind會用戶傳過來的特殊非法字元給再次過濾。
現在Tp框架里只要設置了

'DB_BIND_PARAM' => true
引用TP例子
然後,我們在使用
$Model = M('User');
$Model->name = 'thinkphp';
$Model->email = '[email protected]';
$Model->add();

會自動對寫入的數據進行參數綁定操作。其操作等效於:
$Model = M('User');
$Model->name = ':name';
$Model->email = ':email';
$bind[':name'] = 'thinkphp';
$bind[':email'] = '[email protected]';
$Model->bind($bind)->add();

F. php中用bind參數綁定有什麼作用

你說的是php中mysqli或pdo綁定參數嗎?使用bind_param或bindValue來給mysql傳參的時候可以防止mysql注入,這樣相對於mysql自己拼接完整的sql語句更安全。
另外通過處理語句(prepared statement)可以提高mysql的查詢效率,推薦使用pdo方式哦。

熱點內容
cad配置低可以安裝什麼版本 發布:2025-03-04 12:59:36 瀏覽:977
寶可夢日月什麼配置能玩 發布:2025-03-04 12:46:18 瀏覽:919
oraclesql動態 發布:2025-03-04 12:44:19 瀏覽:233
MPLAB能否編譯pic32 發布:2025-03-04 12:42:50 瀏覽:290
如何分辨一輛車是什麼配置 發布:2025-03-04 12:41:10 瀏覽:350
配置很低的電腦玩csgo怎麼調 發布:2025-03-04 12:40:29 瀏覽:26
視頻解析網站源碼 發布:2025-03-04 12:40:25 瀏覽:319
哪個軟體可以直接重啟安卓手機 發布:2025-03-04 12:22:42 瀏覽:610
c語言scanf的意思 發布:2025-03-04 12:08:31 瀏覽:469
兩端存儲器 發布:2025-03-04 12:07:49 瀏覽:87