質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

92.00%

  • PHP

    12042questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

画像をアップロードする時、画像のサイズをエコしたが0と表示。

解決済

回答 6

投稿 2017/01/18 10:57

  • 評価
  • クリップ 3
  • VIEW 322

k3n1

score 38

実は画像をアップロードして、小さいデータならうまく表示しますが、4Mや5M以上のデータですと、自分が書いたエラーチェックが出てきます。確認のためecho $_FILES['upfile']['size']で画像のサイズをエコしてみました。
小さい画像はまだバイト数が普通にでてくるですが、4Mや5Mの画像ですと、0と出てきました。それとともに自分が書いたエラーチェックのUPLOAD_ERR_FORM_SIZE:が通れなくなってエラー文が出ます。画像の容量が0と表示しているのにサイズがオーバーするのはどういうことですか?
何故小さいデータならうまくいって、大きいデータだとこうなるでしょうか?
php.iniの方も5Mに変えています。
理解ができなくて何回も質問して申し訳ないですが、よろしくお願いいたします。

<!DOCTYPE html>
<html>
<head>

  <meta charset="utf-8">
  <title>php</title>
</head>
<body>
<form action="resize.php" method="post" name="form" enctype="multipart/form-data">


<input type="hidden" name="MAX_FILE_SIZE" value="524288">
<p>
<input type="file" name="upfile" size="30" id="upload">
</p>

<p>
<input type="submit" value="送信する">
</p>
</form>
</body>
  </html>
<?php
ini_set('display_errors', '1');
error_reporting(E_ALL);

if (!isset($_FILES['upfile'])) {
    echo '<FONT COLOR="RED">恐らくアップロードページのHTMLに記述ミス有り!</FONT>';
    return;
}

$file = $_FILES['upfile'];
$tmp_name = $file['tmp_name']; // 一時ファイルのパス

echo $_FILES['upfile']['size'];


switch ($file['error']) {
    case UPLOAD_ERR_OK:
        break;
    case UPLOAD_ERR_INI_SIZE:
           echo '<FONT COLOR="RED">アップロードされたファイルは、php.ini の upload_max_filesize ディレクティブの値を超えています。</FONT>';
            return;
        case UPLOAD_ERR_FORM_SIZE:
           echo '<FONT COLOR="RED">アップロードされたファイルは、HTML フォームで指定された MAX_FILE_SIZE を超えています。</FONT>';
            return;
    case UPLOAD_ERR_PARTIAL:
        echo '<FONT COLOR="RED">もう一度実行してみてください!</FONT>';
        return;
    case UPLOAD_ERR_NO_FILE:
       echo '<FONT COLOR="RED">ファイルを選択して下さい!</FONT>';
        return;
    case UPLOAD_ERR_NO_TMP_DIR:
    case UPLOAD_ERR_CANT_WRITE:
    case UPLOAD_ERR_EXTENSION:
        echo '<FONT COLOR="RED">サーバ内部で発生したエラー!</FONT>';
        return;
    default:
        echo '<FONT COLOR="RED">何が起きたか分からない!</FONT>';
        return;
}

$finfo = new finfo(FILEINFO_MIME_TYPE);
if (!preg_match('/\.jpg$|\.jpeg$/i', $file['name'])
        || $finfo->file($tmp_name) !== 'image/jpeg') {
    echo '<FONT COLOR="RED">JPEGファイルを選択してください!</FONT>';
    return;
}

$result = true;
$get = getimagesize($tmp_name);

if ($get["0"]>1000) {
    $result = false;
    echo '<FONT COLOR="RED">横幅を小さくしてください!</FONT>';
}
if ($get["1"]>1000) {
    $result = false;
    echo '<FONT COLOR="RED">縦幅を小さくしてください!</FONT>';
}

if ($result) {
    echo '送信完了';

}

?>
  • 気になる質問をクリップする

    クリップした質問に回答があった場合に通知・メールを受け取ることができます。

    クリップした質問はマイページの「クリップ」タブからいつでも見ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 6

checkベストアンサー

+5

検証用コード

<?php
ini_set('display_errors', true);
error_reporting(E_ALL);

define('UP_DIR', 'updir');

function h($string)
{
    return htmlspecialchars($string, ENT_QUOTES, 'utf-8');
}

/**
 * ファイルアップロードエラーを判定する
 * @param type $upfile
 * @return bool
 * @throws Exception
 */
function check_error($upfile)
{
    switch ($upfile['error']) {
        case UPLOAD_ERR_OK:
            return true;
        case UPLOAD_ERR_INI_SIZE:
            $err = 'アップロードされたファイルは、php.ini の upload_max_filesize ディレクティブの値を超えています。';
            break;
        case UPLOAD_ERR_FORM_SIZE:
            $err = 'アップロードされたファイルは、HTML フォームで指定された MAX_FILE_SIZE を超えています。';
            break;
        case UPLOAD_ERR_PARTIAL:
            $err = 'アップロードされたファイルは一部のみしかアップロードされていません。';
            break;
        case UPLOAD_ERR_NO_FILE:
            $err = 'ファイルはアップロードされませんでした。';
            break;
        case UPLOAD_ERR_NO_TMP_DIR:
            $err = 'テンポラリフォルダがありません。';
            break;
        case UPLOAD_ERR_CANT_WRITE:
            $err = 'ディスクへの書き込みに失敗しました。';
            break;
        case UPLOAD_ERR_EXTENSION:
            $err = 'PHP の拡張モジュールがファイルのアップロードを中止しました。';
            break;
    }

    if (!empty($err)) {
        throw new Exception($err);
    }
}

/**
 * ファイルタイプをチェックし、拡張子を返す
 * @param type $upfile
 * @return bool
 */
function check_extension($upfile)
{
    $arr_accept_mimes = [
        'jpg' => 'image/jpeg'
        , 'png' => 'image/png'
        , 'gif' => 'image/gif'
    ];

    $finfo = finfo_open(FILEINFO_MIME_TYPE);
    $mime_type = finfo_file($finfo, $upfile['tmp_name']);

    if (in_array($mime_type, $arr_accept_mimes)) {
        return array_search($mime_type, $arr_accept_mimes);
    }

    $msg = '許可されていないファイルタイプです。';
    throw new Exception($msg);
}

if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') === 'POST') {

    try {

        var_dump($_FILES);

        $upfile = $_FILES['upfile'];

        // エラーチェック
        check_error($upfile);

        // ファイルタイプチェック
        $extension = check_extension($upfile);

        $tmp_name = $upfile['tmp_name'];

        // ファイル保存先 + ファイル名
        $base_name = sha1_file($tmp_name) . '.' . $extension;

        if (!file_exists(UP_DIR)) {
            $msg = sprintf('%s ディレクトリが存在しません。', UP_DIR);
            throw new Exception($msg);
        }
        if (!is_writable(UP_DIR)) {
            $msg = sprintf('%s に書き込み権限がありません。', UP_DIR);
            throw new Exception($msg);
        }

        $destination = UP_DIR . DIRECTORY_SEPARATOR . $base_name;
        if (file_exists($destination)) {
            $msg = sprintf('同一のファイルがすでにアップロードされています。', UP_DIR);
            throw new Exception($msg);
        }

        move_uploaded_file($tmp_name, $destination);
    } catch (Exception $e) {
        $err = $e->getMessage();
    }
}
?><!DOCTYPE HTML>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <style type="text/css">
            .error {
                color: red;
            }
        </style>
    </head>
    <body>
        <form action="" enctype="multipart/form-data" method="post">
            <?php if (isset($err)) : ?>
                <p class="error">エラー: <?= h($err); ?></p>
            <?php endif; ?>

            <p>
                post_max_size: <?= ini_get('post_max_size'); ?>
            </p>
            <p>
                upload_max_filesize: <?= ini_get('upload_max_filesize'); ?>
            </p>

            <p>
                <label for="upfile">画像ファイル</label>
                <input type="file" name="upfile" id="upfile" />
            </p>
            <p>
                <button type="submit">アップロード</button>
            </p>
        </form>
    </body>
</html>

スクリーンショット

ini の設定はデフォルト

イメージ説明

アップロード・ファイル

巨大な画像ファイルのサンプルといえば、ここかなということで、気象衛星ひまわりの画像
http://www.jma-net.go.jp/sat/data/web89/himawari8_first_image.html

実験、検証

ブラウザは、Firefox50.1.0

  • 1.8Mの画像をアップロードしたとき

イメージ説明

  • 2.4Mの画像をアップロードしたとき

イメージ説明

アップロードに失敗しているのだし、処理を中断しているので、size が 0。

  • 8Mを超える画像をアップロードしたとき

そもそも $_FILES に値が入ってこない ブラウザが送信自体を中断していると考えるのが無難。

イメージ説明

投稿 2017/01/18 14:14

編集 2017/01/18 14:15

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

+4

一つ確認したいのだが

<input type="hidden" name="MAX_FILE_SIZE" value="524288">


これだと512Kb 約0.5Mbなんだけど正しいの
5Mだと 5*1024*1024 = 5242880

投稿 2017/01/18 11:44

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/01/18 11:57 編集

    アップロードファイルを受信するphpでwebサーバープロセスが処理できてphpが処理できたあとに、MAX_FILE_SIZEのチェックをするものだと思います。524288は小さすぎます。

    キャンセル

  • 2017/01/18 11:48

    間違ってすみません。
    でもここの数値とは関係ないみたいです。
    9999999999にしてみたが、変わらなかったです。

    キャンセル

  • 2017/01/18 11:56

    MAX_FILE_SIZEは、PHP本体で処理されます(http://php.net/manual/ja/features.file-upload.post-method.php)。

    キャンセル

  • 2017/01/18 12:09

    このMAX_FILE_SIZE以上のファイルを送ると
    print_r($_FILES);
    Array ( [upfile] => Array ( [name] => dummy5M.img [type] => [tmp_name] => [error] => 2 [size] => 0 ) )
    のようになります。sizeの表示も0になります。なので関係はあります。


    キャンセル

+3

http://www.php-factory.net/trivia/05.php

ここをチェックしてみてください。phpinfoを使って情報を表示して、そのphp.iniに書いた情報が正しく反映されているか確認して見てください。必要な3項目に漏れがある、全然関係ない位置にあるphp.iniをいじっている可能性があるかもしれません。

投稿 2017/01/18 11:03

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/01/18 11:10

    回答ありがとうございます。
    確認したところ、ちゃんと反映しています。
    post_max_sizeが8Mでupload_max_filesizeも5Mになっています。

    キャンセル

+3

PHPでファイルをアップロードする際、upload_max_filesizeだけではなく、他にも容量に制約がかかるところがあります。

  • Webサーバ自体のPOST容量制限(デフォルト: Apacheは無制限、nginxは1MB)
  • PHPのPOSTサイズ制限(post_max_size、デフォルト:8MB)

これらの設定に1つでも引っかかると、POSTデータは正常でなくなります。

投稿 2017/01/18 11:07

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/01/18 11:12

    今はpost_max_sizeが8になっていて、upload_max_filesizeがもともと2で5に変えただけです。ほかはいじってないですが

    キャンセル

  • 2017/01/18 11:21

    php.iniファイルを書き換えた後、webサーバープロセス(Apacheなど)の再起動が必要です。やっていますか? また、レンタルサーバーの場合など特に、許容可能な数字以上を与えるとユーザーが与えた設定値を無視されることもあります。

    キャンセル

  • 2017/01/18 11:45

    はい、書き換えたあと再起動しましたが、特にかわらなかったです。
    一つお聞きしたいですが、もしupload_max_filesizeとかpost_max_sizeの問題でしたら、エラーとして出てくるのはUPLOAD_ERR_INI_SIZE:の方ではないですか?何故UPLOAD_ERR_FORM_SIZEの方からエラーがでるのでしょうか?一応htmlのほうでvalueを上げても変わらなかったです。

    キャンセル

  • 2017/01/18 11:55

    hiddenパラメータで与えているMAX_FILE_SIZEを超えるサイズのファイルを送信したから、そういうエラーになっています。バイト数で与える必要があるので、5MB→5*1024*1024=5242880である必要があります。もしもphp側やwebサーバープロセス側の制約を取り払っても、この数字が小さい場合には、このエラーが発生します。

    キャンセル

  • 2017/01/18 12:02

    k3n1さん「書き換えたあと再起動しましたが」とありますが、ブラウザキャッシュも削除しました?

    キャンセル

  • 2017/01/18 12:07

    @Y.H.さん はい、そうです。普通は画像サイズがFROMで指定したバイト数より多きくてもサイズをエコした限りでは0にならないですよね?
    それともその指定した値を超えると0になるものでしょうか?

    キャンセル

  • 2017/01/18 12:15

    アップロードエラーが発生した場合(UPLOAD_ERR_OK以外の場合)tmp_nameのファイルサイズは0バイトになるかもしれません。
    でないと、2TByteなどのファイルを送りつけてサーバーのディスクを枯渇させる攻撃が成り立つので。

    キャンセル

+3

既に他の方の回答にもありますが、
php側の設定でのファイルサイズ制限
→php.ini上のupload_max_filesizeやpost_max_sizeの拡大、
webサーバープロセス側(Apache,nginx)のPOSTサイズ制限、
→Apacheならhttpd.confでのLimitRequestBodyの拡大、
が考えられ、まったく出力されない場合には
アップロード処理自体に時間がかかりすぎてphp実行が強制終了
→php.iniでのmax_execution_timeの拡大、
→Apacheならhttpd.confでのtimeoutを伸ばすとか、
ということまで考慮する必要があります。

どこをいじればいいかは、
webサーバーのエラーログをチェックして判断します。
(エラー出力レベルを調整してエラー情報をわかりやすくする必要があるかもしれません。)

点検項目まで解説してある記事:
PHPのファイルアップロードサイズの上限値を変更する - Qiita

あと、いろいろいじっているとやってしまいがちな話として、
phpファイルをローカルで書き換えてサーバーにアップロードするのを忘れているとか、
php.iniやhttpd.confなどの定義ファイルの場所を間違って別のファイルを書き換えているとか、
少しでも変更を加えたら適切に反映されているか、phpinfo()とか使って再確認しましょう。

投稿 2017/01/18 11:10

編集 2017/01/18 12:03

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

+1

エンコードの絡みで必ずしも許可したファイルサイズが実際の
ファイルサイズとぴったり一致するわけではないようです。
post上限とファイルサイズ上限は多少余裕をもって設定しておき
受け取ったファイルサイズをみてオーバーフローの処理をいれてください

投稿 2017/01/18 11:45

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    以下のような回答は評価を下げられます

    • 間違っている回答
    • 質問の回答になっていない投稿
    • 不快な投稿

    評価を下げる際はその理由をコメントに書き込んでください。

  • 2017/01/18 11:49

    回答ありがとうございます。
    一応upload_max_filesizeとpost_max_sizeを20まで上げてみたですが、ダメでした。

    キャンセル

  • 2017/01/18 11:59

    そうですか・・・
    個人的な話で一般的にみな同じとはいえませんが
    以前PHP側にデバッガをいれて運用していたところ
    大きなファイルが送れなくなる現象に遭遇したことがあります。

    そのときは何をやっても無駄だったので、結局phpを強制的に
    一から入れ直したところ治りました。
    もしかしたら残念ながらご利用の環境がなにかおかしくなっているのかもしれないです

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

ただいまの回答率

92.00%

関連した質問

同じタグがついた質問を見る

  • PHP

    12042questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

閲覧数の多いPHPの質問