2010-04-07 69 views
1

我最近遇到的一個問題是,當試圖更新我的數據庫中的字段時,使用此代碼將無法工作。我將它追溯到正在更新的文本中有一個%符號($ note,然後是$ note_escaped)......雖然使用sprintf插入它效果不錯。sprintf和文本中的%符號

我不應該使用sprintf進行更新,還是應該以不同的方式形成?

我做了一些搜索,但不能拿出任何東西。

$id = mysql_real_escape_string($id); 
$note_escaped = mysql_real_escape_string($note); 
$editedby = mysql_real_escape_string($author); 
$editdate = mysql_real_escape_string($date); 
//insert info from form into database 
$query= sprintf("UPDATE notes_$suffix SET note='$note_escaped', editedby='$editedby', editdate='$editdate' WHERE id='$id' LIMIT 1"); 

非常感謝!

+0

謝謝大家:真正我絆倒當我把實際的查詢放在Sequel Pro中並運行它時,它正確地更新了數據庫。 – 2010-04-07 18:02:01

回答

5

您正在使用sprintf完全錯誤。在您的代碼中刪除函數調用仍然會執行相同的操作。它應該是:

sprintf("UPDATE notes_%s SET note='%s', editedby='%s', editdate='%s' WHERE id=%d LIMIT 1", $suffix, $note_escaped, $editedby, $editdate, $id); 

您應該閱讀手冊。

+0

刪除函數調用?你的意思是mysql_real_escape_string?這是一個愚蠢的建議給 – knittl 2010-04-07 17:03:28

+0

@ knittl - 不,刪除sprintf會給出相同的代碼。到底在哪裏,我甚至提到了mysql_real_escape_string? – 2010-04-07 17:04:59

+0

從你的答案聽起來像是這樣,你談論的是刪除一個函數調用 - 什麼函數調用? - 你正在談論sprintf - 並且不會在代碼中顯示轉義函數調用。它可能有點誤導 – knittl 2010-04-07 17:08:50

1

你可以通過在mysql中用\%來代替原文中的%

+0

在mysql中正確轉義的方法是\% - http://dev.mysql.com/doc/refman/5.0/en/string-syntax.html – 2010-04-07 16:21:01

+1

我的,很糟糕。糾正。 – vfilby 2010-04-07 16:29:57

-1

http://php.net/manual/en/function.mysql-real-escape-string.php

注:mysql_real_escape_string()不逃避%和_。如果與LIKE,GRANT或REVOKE結合使用,這些是MySQL中的通配符。

您需要用\%和_手動轉義%和_(如果有的話)。我不推薦使用sprintf,但只是改善你的逃生功能。

1

sprintf()在PHP中用處不大,除非您需要以某種方式格式化數據。這兩句話在PHP相同方式工作:

$num = 42; 
$char = 'q'; 

$text = sprintf('The number is %d and the character is %s', $num, $char); 
$text = "The number is $num and the character is $char"; 

的sprintf的使用更下「打印」可變數據轉換爲字符串。但是PHP可以用雙引號字符串來實現,所以除非需要使用sprintf的特殊格式化函數(例如%0.2f用於2位小數位浮點數),否則使用常規字符串方法會更容易。

+1

如果您在雙引號字符串中使用變量替換創建sql字符串,地獄將凍結 – knittl 2010-04-07 17:04:51

+0

如果您不瞭解SQL注入和/或不在乎,手動構建查詢只會非常危險。尖叫從屋頂手動查詢是危險的並不有助於教育初學者。 – 2010-04-07 22:22:22

+0

看來,我讀了一些地方,sprintf()是一個更快的方式來執行mysql查詢比正常的變量字符串。 – 2010-04-09 14:20:43

2

首先你應該使用prepared statements代替的sprintf調用所有的

,但如果你非得做這種方式,您必須使用:

$id = mysql_real_escape_string($id); 
$note_escaped = mysql_real_escape_string($note); 
$editedby = mysql_real_escape_string($author); 
$editdate = mysql_real_escape_string($date); 
//insert info from form into database 
$query= sprintf(" 
    UPDATE notes_%s /* this is still open for injection, and cannot be properly escaped with mysql_real_escape_string */ 
    SET note='%s', 
    editedby='%s', 
    editdate='%s' 
    WHERE id='%d' 
    LIMIT 1", 
$suffix, 
$note_escaped, $editedby, $editdate, $id);