在PHP中,與許多其他編程語言一樣,右側操作數的值與左側操作數變量的值相同。也就是說,在執行這樣的命令後,=
符號左側的變量將包含=
符號右側的表達式值。
您的右側操作數是一個double-quoted string literal,其中PHP使用它們的值擴展(替換)變量;然而,結果(分配給左側操作數)僅僅是一個字符序列。
PHP的echo
構造將其參數(s)轉換爲字符串(s),按順序連接它們並將結果發送到輸出緩衝區。
在你的情況下,唯一的參數是另一雙引號字符串字面"$requete"
,其中PHP再次展開變量與他們的價值觀:這一次的文字的內容完全是可變$requete
,從而引述它只是造成多餘解析高架;並且由於該變量被分配了以前的字符串文字,所以得到的字符串(由echo
輸出)等於原始字符串文字。因此,您的兩個語句具有相同的效果:
echo "SELECT login, pass FROM membres WHERE login='$login' AND pass='$pass'";
PHP沒有被告知,RDBMS存在,這是您希望通過RDBMS進行評估,或者您希望爲所產生的結果集,以SQL被輸出。
更糟的是,除非你是絕對一定是$login
和$pass
不包含轉義字符'
,解析該字符串SQL可能會導致意外的行爲。攻擊者經常利用這個疏忽執行SQL injection attacks,這可能會危及整個數據庫。 最安全的方法來避免這是從來沒有來評估變量爲SQL,而不是使用prepared statements你將變量作爲參數傳遞到其中。
我建議你看看PHP Data Objects,使安全數據庫的訪問非常容易:
$dbh = new PDO("mysql:dbname=$dbname;charset=utf8", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$qry = $dbh->prepare('
SELECT login, pass
FROM membres
WHERE login = ? AND pass = ?
');
$qry->execute(array($login, $pass));
while ($row = $qry->fetch(PDO::FETCH_ASSOC)) print_r($row);
然而,需要注意以下幾點:
你只是從你的數據庫中的字段選擇該匹配常量值,這是毫無意義的:從這樣的查詢中唯一可以獲得的信息是數據庫中匹配記錄的數量,但是資源浪費在返回多餘的數據上。
您可以改爲SELECT COUNT(*) FROM membres WHERE ...
來獲得相同的信息,而不會浪費任何開銷;或者如果您只希望發現是否有一個或多個匹配記錄,則SELECT EXISTS (SELECT * FROM membres WHERE ...)
會更有效。
您似乎在創建一個登錄腳本,這對於以安全的方式完成是非常重要的:如果您想了解更多信息,請參閱The Definitive Guide To Forms based Website Authentication。在那裏有一些庫和工具,您可以將它們放入項目中,以免浪費重新發明輪子的資源(以及其他人苦苦學習的許多痛苦錯誤)。
+1這個,但我不認爲他現在可以理解這個 –
@MinaGabriel:是的,我也很擔心。請隨時就如何讓PHP新手更易於接受答案提出編輯/建議。 – eggyal