ファイル転送

【PHP】 アップロード可能な上限ファイルサイズの調べ方と注意点

更新日:2020/01/19

 

php.iniにアップロードに関する設定が保存されている

PHPのファイルアップロードに関する設定は、php.iniというファイルに保存されています。
基本的には黒い画面を開いて直接ファイルを編集するのですが、mixhostやxserverなどの大手のレンタルサーバーなら、管理パネルから設定可能になっているケースが多いです。

ブラウザで確認する方法

php.iniの内容を直接見るのは難しいし、できても面倒なので次の方法で確認してみます。

(1) メモ帳などに次のコードを入力して、「phpinfo.php」という名前で保存してください。

phpinfo.php

<?php phpinfo();

ダウンロード

phpinfo.zip

(2) サーバーにFTPなどで転送してください。

(3) ブラウザでphpinfo.phpを開くと、設定値が一覧で表示されます

phpinfo() 実行結果

PHPプログラムで確認する方法

php.iniの設定値は、次のphpコードで確認できます。

phpinfo.php

echo ini_get(確認したいディレクティブ);

 

ファイルアップロードのサイズ制限に関するディレクティブ

PHPのファイルアップロードに関する設定は、次のディレクティブで確認できます。

1.file_uploads

ファイルアップロードが許可されているかどうか。
「On」ならアップロード可能。

設定できるファイル:php.ini または httpd.conf

2.max_file_uploads

一度にアップロードできるファイル数。

設定できるファイル:php.ini または httpd.conf

3.memory_limit

PHPプログラムを実行するときに使用できる最大メモリ。

設定できるファイル:php.ini または httpd.conf 、 .htaccess(Apache互換Webサーバー) 、.user.ini (CGI/FastCGI SAPI)

4.upload_max_filesize

一度にアップロードできるファイルのサイズ。

設定できるファイル:php.ini または httpd.conf 、 .htaccess(Apache互換Webサーバー) 、.user.ini (CGI/FastCGI SAPI)

5.post_max_size

一度のPOSTに含むことができるデータのサイズ。
ファイルデータはPOSTデータの中に含まれる。

設定できるファイル:php.ini または httpd.conf 、 .htaccess(Apache互換Webサーバー) 、.user.ini (CGI/FastCGI SAPI)

 

設定値に関する注意点

3.memory_limit > 5.post_max_size > 4.upload_max_filesize が望ましい。

理由1)

送信されてきたファイルのデータは一度メモリに取り込まれる。
プログラムの実行に必要なメモリサイズとファイルのサイズの合計がmemory_limitを超えると、アップロードすることができない。

理由2)

POSTデータはファイルデータの他にも追記されることが多い。
post_max_size <= upload_max_filesize とすると、upload_max_filesizeで指定されているサイズを送信したらエラーとなる。

例:

■設定値
upload_max_filesize=1M
post_max_size=1M

■アップロードするデータ
画像ファイル  サイズ1Mバイト
ファイル名   サイズ数10バイト

POSTされるデータサイズが1Mバイト+数10バイトのため、upload_max_filesizeを超えてしまい送信失敗。

 

設定方法

基本はphp.iniで設定すします。
ただし次のディレクティブのみ、他の方法で上書き設定が可能です。

上書き設定可能なディレクティブ

memory_limit
upload_max_filesize
post_max_size

Apache互換Webサーバーでの設定

.htaccessファイルを使用できるWebサーバーの場合、次のように変更します。

.htaccessでの設定

php_value memory_limit 128M
php_value post_max_size 25M
php_value upload_max_filesize 20M

ただしサーバーの設定で.htaccessファイルを使用できるように設定されている場合に限ります。
レンタルサーバーなら、使用できると思います。たぶん…

CGI/FastCGI利用サーバーでの設定

Nginxなど.htaccessファイルを使用できないサーバーは、「.user.ini」というファイルを変更することで設定を上書きできる可能性があります。

.user.iniでの設定

memory_limit=128M
post_max_size=25M
upload_max_filesize=20M

.htaccessと書き方が異なるので注意。

備考:php.iniでの設定

一応、php.iniでの書き方も掲載しておきます。

php.ini

memory_limit=128M
post_max_size=25M
upload_max_filesize=20M

.user.iniと同じです。

Webサーバーで制限されていることもある

PHPの設定を変更してもアップロードでエラーが出る場合は、Webサーバー側でも制限がかかっている可能性があります。
デフォルトではApacheは無制限ですが、Nginxは1Mバイトで制限がかかるようです。

Apacheで制限はphp.confというApacheの設定ファイルでされています。
ですが、.htaccessで上書き設定可能です。
次の例のように、 LimitRequestBody に対して、0(無制限)~ 2147483647 (2Gバイト)で指定します。

.htaccessでの設定

LimitRequestBody 52428800

Nginxは、nginx.confというファイルの client_max_body_size ディレクティブで設定されています。
しかしこの設定値は、上書き設定できないようです。
レンタルサーバーなど設定ファイルを変更できない場合、あきらめるしかないようです…

 

設定値を抜き出しバイトに変換するPHPコード

最後にPHPプログラム上で、サイズ設定を抜き出しバイトに変換するコードを紹介します。

PHPコード


const INIGETBYTE_ARRAY=['K'=>1,'M'=>2,'G'=>3];

function ini_get_byte($directive){
    if(($v = ini_get($directive))===false) return ['text'=>'','byte' => false];

    $retval=false;
    $v = trim($v);
    // 全て数値ならそのままINTへ
    if(ctype_digit($v)) {$retval=intval($v);}
    else {
        $len = strlen($v);
        // 文字数が0か1なら数値ではない
        if($len>1){
           // 最後の一文字以外を取得
            $val = substr($v,0,$len-1);
            if( is_numeric($val) ) {
                // 最後の一文字をキーとして取得
                $key = strtoupper(substr($v,-1));
                  if(array_key_exists($key,INIGETBYTE_ARRAY))
                      $retval = floor(floatval($val) * pow(1024,INIGETBYTE_ARRAY[$key]));
            }
        }
    }
    return  ['text'=>$v,'byte' => $retval];
}

この関数はPHPのディレクティブを渡すと、次の配列を返します。

['text'=>inivalue,'byte'=>bytes]

■inivalue
ini_get()で取得した文字列

■bytes
バイト変換した整数値。
完全な数値か、末尾にMやKなどの単位文字がついている数値をバイト数に変換します。
それ以外はFALSEがセットされます。

実行結果

var_dump( ini_get_byte('memory_limit'));

array (size=2)
  'text' => string '128M' (length=4)
  'byte' => int 134217728

var_dump( ini_get_byte('default_charset'));
array (size=2)
  'text' => string 'UTF-8' (length=5)
  'byte' => boolean false

この関数は設定値と変換後のバイト数を取得したかったので、返り値が配列になっています。
バイト数の変換と逆変換については、こちらでも紹介しています。

【PHP/JavaScript】 バイト数とメガバイトの相互変換するプログラム

お役立てください!

更新日:2020/01/19

書いた人(管理人):けーちゃん

スポンサーリンク

記事の内容について

null

こんにちはけーちゃんです。
説明するのって難しいですね。

「なんか言ってることおかしくない?」
たぶん、こんなご意見あると思います。

裏付けを取りながら記事を作成していますが、僕の勘違いだったり、そもそも情報源の内容が間違えていたりで、正確でないことが多いと思います。
そんなときは、ご意見もらえたら嬉しいです。

掲載コードについては事前に動作確認をしていますが、貼り付け後に体裁を整えるなどをした結果動作しないものになっていることがあります。
生暖かい視線でスルーするか、ご指摘ください。

ご意見、ご指摘はこちら。
https://note.affi-sapo-sv.com/info.php

 

このサイトは、リンクフリーです。大歓迎です。