2012-04-01 88 views
-1

在PHP中你經常包含其他PHP串那樣的SQL查詢:美化在PHP代碼SQL字符串

$sql = "SELECT * 
FROM `mytable` 
". (isset($a) ? $a : "") . " 
LIMIT " . ($page - 1) * 10 . ",10"; 

如果查詢是更大然後是與PHP的毛絨,它有時會難以閱讀。

是否有任何可以格式化PHP包含(我的)SQL的美化工?

+0

我見過很多,比這更糟糕。無論如何,你想如何讓它變得光明?你是什​​麼意思,解析SQL字符串爲它的關鍵字着色? – 2012-04-01 11:02:25

+0

這就是爲什麼發明變量的原因。那麼,不完全是,但他們也在這裏幫助。 – JJJ 2012-04-01 11:03:29

+7

請看,看在上帝的份上......不要通過字符串concat來建立你的SQL!至少逃避參數。更好:使用PDO和準備好的語句。 – Malax 2012-04-01 11:08:21

回答

3

讓我採取不同的方法,以你的問題:

如果你有一個看起來像SQL查詢,你這樣做是錯誤的。

Prepared statements是你的朋友。 SQL注入不是你的朋友。引述the PDO documentation

預處理語句是非常有用,所以他們是唯一的功能, PDO將模擬對於不支持它們的驅動程序。

也許你覺得你很好,你使用mysql_real_escape_string()無處不在,你需要(而不是偶然使用mysql_escape_string()代替)。也許你認爲magic_quotesstripslashes會救你。也許你會很幸運並且做對了。但是,爲了解釋Ms. Schmich:如果我只能提供給您未來的一個建議,那就是「使用準備好的陳述」。

Here is a nice StackOverflow answer illustrating them in more detail,以下是我的(不含不管它是你與$a做)你的例子來使用預處理語句部分轉換:

$statement = $dbh->prepare("SELECT * FROM `mytable` LIMIT :offset , 10"); 
$statement->bindValue(":offset", ($page - 1) * 10)); 
$statement->execute(); 

當然,也許你已經繼承了一些遺留代碼和這就是爲什麼你問,所以我的立場變得有點沒有意義。我仍然認爲,您最好是重構準備好的語句,無論是爲了安全/功能優勢,還是因爲如果可能更詳細,它們可能會更容易閱讀。

+0

我對此有一個小問題。綁定值/ param比將它們放入數組慢一點? (我認爲它是相同的,但通過yiis框架文檔,它說執行時引用速度更快) – itachi 2012-04-01 11:39:08

+0

我似乎記得可能是這種情況,但我會非常驚訝地聽到這是你的瓶頸剖析... – 2012-04-01 11:40:11

+0

Lol no。已經完成基準。微不足道。幾乎沒有。 – itachi 2012-04-01 11:43:00

1

也許嘗試確定您的查詢字符串以外的值。一旦他們通過了任何想要應用的過濾/驗證檢查,就添加它們。

$param = (isset($a) ? $a : ""); 
$param2 = ($page - 1) * 10; 

$sql = "SELECT * FROM mytable " . $param . " LIMIT " . $param2 . ",10"; 
+0

另外,要小心你放入該字符串的內容,確保它不是來自客戶端的任何內容(get/post/server等)。 – 2012-04-01 11:08:50

+0

更合適,在放入查詢之前,變量應該進行清理/轉義/過濾(不同的人使用不同的單詞)。如果我們禁止來自客戶的變量來源,那麼主流網站的用途是什麼? – itachi 2012-04-01 11:33:27

+0

我會重新修改,確保它不是直接從客戶端獲得。適用的衛生條件已經適用。 – 2012-04-01 12:14:15

0

您可以計算查詢

$a = isset($a) ? $a : ""; 
$page = ($page - 1) * 10; 

$sql = "SELECT * FROM `mytable` $a LIMIT $page,10"; 
3

之外有沒有美化,將調整你的代碼,以便它更易於閱讀。這是你的作爲程序員的工作;有人認爲這是程序員的主要工作。所以,不要編寫難看的代碼,並試圖讓計算機爲您清理它,而是首先要養成編寫可讀代碼的習慣。在這種情況下,比可讀性更好(例如轉義和驗證變量)。

$conditions = (isset($a) ? $a : ""); 
$lowerLimit = ($page - 1) * 10; 

$sql = "SELECT * 
    FROM `mytable` 
    $conditions 
    LIMIT $lowerLimit, 10"; 
0

你可以嘗試找一些數據庫代理,但在我的經驗,我可以告訴你,或者他們缺乏能力,或者他們很難去適應它。

儘管如此,你可以嘗試自己做一個更清晰的查詢,聲明瓦爾分開。 你甚至可以做出簡單的幫手功能。

0

如果可能,請使用準備好的語句。

PDO例如:

$PDO = new PDO('host=localhost;dbname=test', 'foo', 'bar'); 

$query = $PDO->prepare(' 
    SELECT 
     * 
    FROM 
     foobar 
    WHERE 
     id = :user_id 
    LIMIT 
     :limit 
'); 

$query->execute(array(
    ':user_id' => $user_id, 
    ':limit' => $limit 
)); 
$query->fetchAll(); 
/*...*/ 

預處理語句是易於維護,你可以避免手工串逃跑。

0

你可以改變你寫你的SQL代碼的方式,以使其更易於粘貼複製/到一個基於Web的美化,像這樣

$param = (isset($a) ? $a : ""); 
$param2 = ($page - 1) * 10; 

$sql = " 
SELECT * FROM mytable $param LIMIT $param2,10 
"; 

然後你複製的中間線,並粘貼到一個基於Web的美化(see here)和它吐出

SELECT * 
FROM mytable $param 
LIMIT $param2, 10 

如果您正在使用vim/emacs的,那麼這整個事情可以通過傳遞到一個基於SQL殼美化簡化,但對我的生活我不能找到一個。