9

私はPHPの初心者で、現在「ファイルアップロードの検証」の部分を学んでいます。

次のコードを含むtest.phpページを作成しました。

var_dump(@$_FILES['file']['type']);

まず、画像「img.gif」をアップロードすると、次のように返されました。

string 'image/gif' (length=9)

次に、画像の拡張子を「.jpg」に変更すると、次のように返されます。

string 'image/jpeg' (length=10)

そのため、$ _ FILES ["file"] ["type"]はアップロードされたファイル拡張子のみを返すが、実際にはどのファイルであるかを確認しなかったことに気付きました。

このページhttp://www.w3schools.com/php/php_file_upload.aspには、次のコードがあります。

$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

上記のコードがファイル拡張子を2回チェックするのはなぜですか?上記のコードからいくつかを削除しました。これが私の新しいコードです。

$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if (($_FILES["file"]["size"] < 20000) && in_array($extension, $allowedExts))

私のコードは正しいですか?または、アップロードファイルが画像であることを検証するためのより良い方法はありますか?

ありがとう!

4

3 に答える 3

19

file* の tmp_name をgetimagesizeに渡す必要があります。これにより、イメージのサイズとタイプが得られます (イメージの場合)。渡された引数がファイルで画像ではない場合、false が返され、検証が可能になります。

編集: イメージ検証の唯一の信頼できる方法は、GD または Imagick を使用してイメージのコピーを作成することです。getimagesize は簡単にハッキングできます

*: つまり、アップロード後に作成される一時ファイルです。

例えば:

if ($_SERVER['REQUEST_METHOD'] === 'POST')
{
    $file = $_FILES['file']['tmp_name'];
    if (file_exists($file))
    {
        $imagesizedata = getimagesize($file);
        if ($imagesizedata === FALSE)
        {
            //not image
        }
        else
        {
            //image
            //use $imagesizedata to get extra info
        }
    }
    else
    {
        //not file
    }
}

このコードでは、一般的な目的でfile_existsを使用しています。ファイルがアップロードされていない場合は$_FILES['file']['size'] = 0$_FILES['file']['tmp_name'] = ''$_FILES['file']['error'] = 4. is_readableも参照してください。エラー値については、 php.netで説明されているファイル アップロード エラーを参照してください。

于 2013-03-24T05:49:53.543 に答える
4
$allowedExts = array("gif", "jpeg", "jpg", "png");
$extension = end(explode(".", $_FILES["file"]["name"]));
if ((($_FILES["file"]["type"] == "image/gif")
|| ($_FILES["file"]["type"] == "image/jpeg")
|| ($_FILES["file"]["type"] == "image/jpg")
|| ($_FILES["file"]["type"] == "image/png"))
&& ($_FILES["file"]["size"] < 20000)
&& in_array($extension, $allowedExts))

ファイルの拡張子と「ファイルタイプ」が異なる可能性があるため、これは2回チェックされます。そのため、誰かが.png拡張子の実行可能ファイルをアップロードすることはできません。

変更したコードでは、拡張子が変更された別の種類のファイルをアップロードできます。拡張子が「.png」のWord文書をアップロードできるように。

新しいコードは拡張子をチェックしているだけで、ダブルチェックはありません。

于 2013-03-24T05:47:45.897 に答える
0

新しいコードは、ファイルの拡張子とファイルのサイズのみをチェックします。ファイルの種類はチェックしません。

古いコードを使用することを強くお勧めします。古いコードではファイルタイプもチェックされるからです。

于 2013-03-24T05:48:11.697 に答える