簡體   English   中英

htmlentities設置為“ UTF-8”時,圖片未上傳

[英]Images not uploading when htmlentities has 'UTF-8' set

我有一個表單,其中包括接受要上傳的圖像並將其粘貼到數據庫中。 以前,我有一個過濾POSTed數據的函數,該函數基本上是:

function processInput($stuff) {
    $formdata = $stuff;
    $formdata = htmlentities($formdata, ENT_QUOTES);
    return "'" . mysql_real_escape_string(stripslashes($formdata)) . "'";
}

為了修復某些未正確轉換的怪異實體時,我將功能更改為(更改的只是我在htmlentities中添加了“ UTF-8”位):

function processInput($stuff) {
        $formdata = $stuff;
        $formdata = htmlentities($formdata, ENT_QUOTES, 'UTF-8'); //added UTF-8
        return "'" . mysql_real_escape_string(stripslashes($formdata)) . "'";
    }

現在,圖像將不會上傳。

是什么原因造成的? 只需刪除“ UTF-8”位,即可正確上傳圖像,但隨后,用戶放入系統中的某些MS Word實體就會顯示為亂碼。 到底是怎么回事?

**編輯:由於我不能做太多更改此野獸上的代碼,因此我可以使用htmlspecialchars()而不是htmlentities()來貼上創可貼,這似乎至少使圖像數據保持不變,同時轉換了引號等內容,尖括號等。bobince的建議非常好,但是在這種情況下,我現在無法花費時間來修復該項目中的混亂舊版代碼。 我處理的大多數內容都是面向對象的和基於框架的,但是現在我親眼看到了人們談論PHP中的“意大利面條式代碼”時的意思。

function processInput($stuff) {
    $formdata = $stuff;
    $formdata = htmlentities($formdata, ENT_QUOTES);
    return "'" . mysql_real_escape_string(stripslashes($formdata)) . "'";
}

此函數表示字符串處理的基本誤解,這是PHP程序員常見的一種。

SQL轉義,HTML轉義和輸入驗證是三個獨立的函數,將在腳本的不同階段使用。 一口氣嘗試全部完成是沒有意義的。 當在腳本的其他部分中使用時,只會導致對任何一個進程“特殊”的字符變得混亂。 您可以嘗試修改此功能,以嘗試修復應用程序一部分中的錯誤,但會破壞其他功能。

為什么圖像被扭曲? 好吧,目前還不清楚通過什么路徑將圖像數據從$_FILES臨時上傳文件傳輸到數據庫。 如果在任何時候都涉及到此功能,它將完全破壞圖像文件的二進制內容。 刪除了反斜杠並轉義了HTML……沒有圖像可以幸免。

  1. mysql_real_escape_string用於轉義一些包含在MySQL字符串文字中的文本。 當使用插入的文本制作SQL字符串文字時,應始終僅將其使用, 而不應將其全局應用於輸入。 因為輸入中包含的某些內容不會立即或僅進入數據庫。 例如,如果您echo輸入值到HTML頁面中的一個,你會發現你得到了一堆不必要的反斜線在它時,它包含了諸如字符' 這就是您最終得到充滿反斜杠的頁面的方式。

    (即使那樣,參數化查詢通常也比手動字符串黑客攻擊和mysql_real_escape_string更好。它們會向您隱藏字符串轉義的詳細信息,以免您被它們混淆。)

  2. htmlentities用於轉義包含在HTML頁面中的文本。 應該在PHP的輸出模板位中始終使用它。 在所有輸入上全局運行它是不合適的,因為並非所有內容都將最終顯示在HTML頁面中或僅在HTML頁面中顯示,並且很可能首先將其轉到您絕對不希望加載的數據庫中的< & 垃圾使您的文本無法可靠搜索或子字符串化。

    (即使那樣, htmlspecialchars通常也比htmlentities更可取,因為它只編碼真正需要它的字符htmlentities將添加不必要的轉義,除非您告訴它正確的編碼,否則它也將完全弄亂您所有的非ASCII字符htmlentities幾乎不應該使用。)

  3. 至於stripslashes ……好吧, 有時您需要將其應用到輸入中,但是僅當啟用了慣用的magic_quotes_gpc選項時。 當然,只有當您檢測到magic_quotes_gpc處於打開狀態時,您才應該一直應用它。 長期以來,它已被棄用,並且很容易消亡,因此,如果檢測到錯誤消息已被打開,則可能同樣有用。 然后,你可以扔掉整個processInput事情了。

總結一下:

  • 在啟動時,做沒有全球性的輸入處理。 如果需要,您可以在此處進行特定於應用程序的驗證,例如檢查電話號碼只是數字,還是從文本或其他內容中刪除控制字符,但此處不應進行轉義。

  • 當在其中使用字符串文字的SQL查詢時,對字符串中的值使用SQL轉義: $query= "SELECT * FROM t WHERE name='".mysql_real_escape_string($name)."'"; 您可以使用較短的名稱定義一個函數,以進行轉義以節省一些鍵入內容。 或者更可讀地是參數化。

  • 使用來自輸入或數據庫或其他地方的字符串進行HTML輸出時,請使用HTML轉義,例如: <p>Hello, <?php echo htmlspecialchars($name); ?>!</p> <p>Hello, <?php echo htmlspecialchars($name); ?>!</p> 同樣,您可以定義一個帶有短名稱的函數以echo htmlspecialchars以節省鍵入內容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM