我一直在做的mysql_connect
的簡單連接,mysql_pconnect
:更換mysql_ *與PDO和準備語句的功能
$db = mysql_pconnect('*host*', '*user*', '*pass*');
if (!$db) {
echo("<strong>Error:</strong> Could not connect to the database!");
exit;
}
mysql_select_db('*database*');
在使用這個,我一直用簡單的方法來逃避作出之前的任何數據查詢,不管是INSERT
,SELECT
,UPDATE
或DELETE
使用mysql_real_escape_string
$name = $_POST['name'];
$name = mysql_real_escape_string($name);
$sql = mysql_query("SELECT * FROM `users` WHERE (`name` = '$name')") or die(mysql_error());
現在我明白了,這是安全的,在一定程度上!
它逃脫危險字符;然而,它仍然容易受到其他可能包含安全字符的攻擊,但可能會對顯示數據或在某些情況下惡意修改或刪除數據有害。
因此,我搜索了一下,發現了PDO,MySQLi和準備好的語句。是的,我可能會遲到,但我已經閱讀了許多教程(tizag,W3C,博客,谷歌搜索),並沒有一個提到過這些。這似乎很奇怪,爲什麼只是逃避用戶輸入實際上是不安全的,並不是最好的說法。是的,我知道你可以使用正則表達式來解決這個問題,但是我相信這還不夠?
據我的理解,當用戶輸入變量時,使用PDO /準備語句是一種更安全的方式來存儲和檢索數據庫中的數據。唯一的問題是,切換(特別是在被困在我以前的編碼方式/習慣之後)有點困難。
現在我明白,使用PDO連接到我的數據庫,我會用
$hostname = '*host*';
$username = '*user*';
$password = '*pass*';
$database = '*database*'
$dbh = new PDO("mysql:host=$hostname;dbname=$database", $username, $password);
if ($dbh) {
echo 'Connected to database';
} else {
echo 'Could not connect to database';
}
現在,函數名是不同的,因此不再將我mysql_query
,mysql_fetch_array
,mysql_num_rows
等工作。所以我不得不閱讀/記住一大堆新的,但這是我感到困惑的地方。
如果我想從註冊/註冊表單中插入數據,我該如何去做這件事,但主要是我會如何安全地進行操作?我認爲這是準備好的聲明進來的地方,但通過使用它們,這消除了使用諸如mysql_real_escape_string
之類的東西的需要嗎?我知道mysql_real_escape_string
要求你通過mysql_connect
/mysql_pconnect
連接到數據庫,所以現在我們不使用這個函數會不會產生錯誤?
我也見過不同的方法來處理PDO方法,例如,我已經看到:variable
和?
作爲我認爲被稱爲佔位符的對象(抱歉,如果這是錯誤的)。
但我認爲這是大致的應該做什麼從數據庫中提取用戶
$user_id = $_GET['id']; // For example from a URL query string
$stmt = $dbh->prepare("SELECT * FROM `users` WHERE `id` = :user_id");
$stmt->bindParam(':user_id', $user_id, PDO::PARAM_INT);
的想法,但然後我卡上有兩件事情,如果變量是不是數字並且是一串文本,如果我沒有弄錯,你必須在PDO:PARAM_STR
之後給出長度。但是,如果您不確定用戶輸入的數據給出的價值,您如何給定一定的長度,每次都會有所不同?無論哪種方式,據我所知,然後顯示您的數據
$stmt->execute();
$result = $stmt->fetchAll();
// Either
foreach($result as $row) {
echo $row['user_id'].'<br />';
echo $row['user_name'].'<br />';
echo $row['user_email'];
}
// Or
foreach($result as $row) {
$user_id = $row['user_id'];
$user_name = $row['user_name'];
$user_email = $row['user_email'];
}
echo("".$user_id."<br />".$user_name."<br />".$user_email."");
現在,這一切都安全嗎?
如果我是正確的,將插入數據是,例如相同的:
$username = $_POST['username'];
$email = $_POST['email'];
$stmt = $dbh->prepare("INSERT INTO `users` (username, email)
VALUES (:username, :email)");
$stmt->bindParam(':username, $username, PDO::PARAM_STR, ?_LENGTH_?);
$stmt->bindParam(':email, $email, PDO::PARAM_STR, ?_LENGTH_?);
$stmt->execute();
請問
的工作,並且是安全的嗎?如果這是正確的,我會爲?_LENGTH_?
輸入什麼值?我完全錯了嗎?
UPDATE
我已經到目前爲止一直非常有幫助的答覆,不知道怎麼感謝你們夠了!每個人都有一個+1來打開我的眼睛有點不同。選擇最好的答案很困難,但我認爲Col Shrapnel值得擁有,因爲所有內容都被覆蓋了,甚至進入其他具有我不知道的自定義庫的數組!
但由於大家:)
也許「用戶名」和「電子郵件」字段的長度?例如。如果用戶名是varchar(32),那麼長度參數應該是32. – deejayy