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

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

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

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

Q&A

解決済

6回答

6920閲覧

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

Kuriaki

総合スコア85

PHP

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

0グッド

3クリップ

投稿2017/01/18 01:57

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

html

1<!DOCTYPE html> 2<html> 3<head> 4 5 <meta charset="utf-8"> 6 <title>php</title> 7</head> 8<body> 9<form action="resize.php" method="post" name="form" enctype="multipart/form-data"> 10 11 12<input type="hidden" name="MAX_FILE_SIZE" value="524288"> 13<p> 14<input type="file" name="upfile" size="30" id="upload"> 15</p> 16 17<p> 18<input type="submit" value="送信する"> 19</p> 20</form> 21</body> 22 </html>

php

1<?php 2ini_set('display_errors', '1'); 3error_reporting(E_ALL); 4 5if (!isset($_FILES['upfile'])) { 6 echo '<FONT COLOR="RED">恐らくアップロードページのHTMLに記述ミス有り!</FONT>'; 7 return; 8} 9 10$file = $_FILES['upfile']; 11$tmp_name = $file['tmp_name']; // 一時ファイルのパス 12 13echo $_FILES['upfile']['size']; 14 15 16switch ($file['error']) { 17 case UPLOAD_ERR_OK: 18 break; 19 case UPLOAD_ERR_INI_SIZE: 20 echo '<FONT COLOR="RED">アップロードされたファイルは、php.ini の upload_max_filesize ディレクティブの値を超えています。</FONT>'; 21 return; 22 case UPLOAD_ERR_FORM_SIZE: 23 echo '<FONT COLOR="RED">アップロードされたファイルは、HTML フォームで指定された MAX_FILE_SIZE を超えています。</FONT>'; 24 return; 25 case UPLOAD_ERR_PARTIAL: 26 echo '<FONT COLOR="RED">もう一度実行してみてください!</FONT>'; 27 return; 28 case UPLOAD_ERR_NO_FILE: 29 echo '<FONT COLOR="RED">ファイルを選択して下さい!</FONT>'; 30 return; 31 case UPLOAD_ERR_NO_TMP_DIR: 32 case UPLOAD_ERR_CANT_WRITE: 33 case UPLOAD_ERR_EXTENSION: 34 echo '<FONT COLOR="RED">サーバ内部で発生したエラー!</FONT>'; 35 return; 36 default: 37 echo '<FONT COLOR="RED">何が起きたか分からない!</FONT>'; 38 return; 39} 40 41$finfo = new finfo(FILEINFO_MIME_TYPE); 42if (!preg_match('/\.jpg$|\.jpeg$/i', $file['name']) 43 || $finfo->file($tmp_name) !== 'image/jpeg') { 44 echo '<FONT COLOR="RED">JPEGファイルを選択してください!</FONT>'; 45 return; 46} 47 48$result = true; 49$get = getimagesize($tmp_name); 50 51if ($get["0"]>1000) { 52 $result = false; 53 echo '<FONT COLOR="RED">横幅を小さくしてください!</FONT>'; 54} 55if ($get["1"]>1000) { 56 $result = false; 57 echo '<FONT COLOR="RED">縦幅を小さくしてください!</FONT>'; 58} 59 60if ($result) { 61 echo '送信完了'; 62 63} 64 65?>

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

クリップした質問は、後からいつでもMYページで確認できます。

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答6

0

ベストアンサー

#検証用コード

php

1<?php 2ini_set('display_errors', true); 3error_reporting(E_ALL); 4 5define('UP_DIR', 'updir'); 6 7function h($string) 8{ 9 return htmlspecialchars($string, ENT_QUOTES, 'utf-8'); 10} 11 12/** 13 * ファイルアップロードエラーを判定する 14 * @param type $upfile 15 * @return bool 16 * @throws Exception 17 */ 18function check_error($upfile) 19{ 20 switch ($upfile['error']) { 21 case UPLOAD_ERR_OK: 22 return true; 23 case UPLOAD_ERR_INI_SIZE: 24 $err = 'アップロードされたファイルは、php.ini の upload_max_filesize ディレクティブの値を超えています。'; 25 break; 26 case UPLOAD_ERR_FORM_SIZE: 27 $err = 'アップロードされたファイルは、HTML フォームで指定された MAX_FILE_SIZE を超えています。'; 28 break; 29 case UPLOAD_ERR_PARTIAL: 30 $err = 'アップロードされたファイルは一部のみしかアップロードされていません。'; 31 break; 32 case UPLOAD_ERR_NO_FILE: 33 $err = 'ファイルはアップロードされませんでした。'; 34 break; 35 case UPLOAD_ERR_NO_TMP_DIR: 36 $err = 'テンポラリフォルダがありません。'; 37 break; 38 case UPLOAD_ERR_CANT_WRITE: 39 $err = 'ディスクへの書き込みに失敗しました。'; 40 break; 41 case UPLOAD_ERR_EXTENSION: 42 $err = 'PHP の拡張モジュールがファイルのアップロードを中止しました。'; 43 break; 44 } 45 46 if (!empty($err)) { 47 throw new Exception($err); 48 } 49} 50 51/** 52 * ファイルタイプをチェックし、拡張子を返す 53 * @param type $upfile 54 * @return bool 55 */ 56function check_extension($upfile) 57{ 58 $arr_accept_mimes = [ 59 'jpg' => 'image/jpeg' 60 , 'png' => 'image/png' 61 , 'gif' => 'image/gif' 62 ]; 63 64 $finfo = finfo_open(FILEINFO_MIME_TYPE); 65 $mime_type = finfo_file($finfo, $upfile['tmp_name']); 66 67 if (in_array($mime_type, $arr_accept_mimes)) { 68 return array_search($mime_type, $arr_accept_mimes); 69 } 70 71 $msg = '許可されていないファイルタイプです。'; 72 throw new Exception($msg); 73} 74 75if (filter_input(INPUT_SERVER, 'REQUEST_METHOD') === 'POST') { 76 77 try { 78 79 var_dump($_FILES); 80 81 $upfile = $_FILES['upfile']; 82 83 // エラーチェック 84 check_error($upfile); 85 86 // ファイルタイプチェック 87 $extension = check_extension($upfile); 88 89 $tmp_name = $upfile['tmp_name']; 90 91 // ファイル保存先 + ファイル名 92 $base_name = sha1_file($tmp_name) . '.' . $extension; 93 94 if (!file_exists(UP_DIR)) { 95 $msg = sprintf('%s ディレクトリが存在しません。', UP_DIR); 96 throw new Exception($msg); 97 } 98 if (!is_writable(UP_DIR)) { 99 $msg = sprintf('%s に書き込み権限がありません。', UP_DIR); 100 throw new Exception($msg); 101 } 102 103 $destination = UP_DIR . DIRECTORY_SEPARATOR . $base_name; 104 if (file_exists($destination)) { 105 $msg = sprintf('同一のファイルがすでにアップロードされています。', UP_DIR); 106 throw new Exception($msg); 107 } 108 109 move_uploaded_file($tmp_name, $destination); 110 } catch (Exception $e) { 111 $err = $e->getMessage(); 112 } 113} 114?><!DOCTYPE HTML> 115<html lang="ja"> 116 <head> 117 <meta charset="UTF-8"> 118 <title></title> 119 <style type="text/css"> 120 .error { 121 color: red; 122 } 123 </style> 124 </head> 125 <body> 126 <form action="" enctype="multipart/form-data" method="post"> 127 <?php if (isset($err)) : ?> 128 <p class="error">エラー: <?= h($err); ?></p> 129 <?php endif; ?> 130 131 <p> 132 post_max_size: <?= ini_get('post_max_size'); ?> 133 </p> 134 <p> 135 upload_max_filesize: <?= ini_get('upload_max_filesize'); ?> 136 </p> 137 138 <p> 139 <label for="upfile">画像ファイル</label> 140 <input type="file" name="upfile" id="upfile" /> 141 </p> 142 <p> 143 <button type="submit">アップロード</button> 144 </p> 145 </form> 146 </body> 147</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 05:14

編集2017/01/18 05:15
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

一つ確認したいのだが

HTML

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

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

投稿2017/01/18 02:44

date

総合スコア1820

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/01/18 02:57 編集

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

2017/01/18 02:48

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

2017/01/18 03:09

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

0

既に他の方の回答にもありますが、
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 02:10

編集2017/01/18 03:03
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

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

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

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

投稿2017/01/18 02:07

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kuriaki

2017/01/18 02:12

今はpost_max_sizeが8になっていて、upload_max_filesizeがもともと2で5に変えただけです。ほかはいじってないですが
退会済みユーザー

退会済みユーザー

2017/01/18 02:21

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

2017/01/18 02:45

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

退会済みユーザー

2017/01/18 02:55

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

2017/01/18 03:02

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

2017/01/18 03:07

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

2017/01/18 03:15

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

0

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

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

投稿2017/01/18 02:03

masaya_ohashi

総合スコア9206

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kuriaki

2017/01/18 02:10

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

0

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

投稿2017/01/18 02:45

yambejp

総合スコア114771

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Kuriaki

2017/01/18 02:49

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

2017/01/18 02:59

そうですか・・・ 個人的な話で一般的にみな同じとはいえませんが 以前PHP側にデバッガをいれて運用していたところ 大きなファイルが送れなくなる現象に遭遇したことがあります。 そのときは何をやっても無駄だったので、結局phpを強制的に 一から入れ直したところ治りました。 もしかしたら残念ながらご利用の環境がなにかおかしくなっているのかもしれないです
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問