63

使用する場合

ini_get("upload_max_filesize");

実際には、php.iniファイルで指定された文字列が提供されます。

この値を最大アップロードサイズの参照として使用するのは適切ではありません。

  • 多くの追加の解析が必要な、などのいわゆるショートハンドバイトを使用することが可能です。1M
  • たとえば0.25M、upload_max_filesizeがの場合、実際にはゼロであるため、値の解析がさらに難しくなります。
  • また、値にスペースが含まれている場合は、phpによってゼロとして解釈されますが、使用時にスペースなしで値が表示されます。ini_get

それで、によって報告されたもの以外に、PHPによって実際に使用されている値を取得する方法はありますかini_get、またはそれを決定するための最良の方法は何ですか?

4

6 に答える 6

72

Drupal はこれをかなりエレガントに実装しています。

// Returns a file size limit in bytes based on the PHP upload_max_filesize
// and post_max_size
function file_upload_max_size() {
  static $max_size = -1;

  if ($max_size < 0) {
    // Start with post_max_size.
    $post_max_size = parse_size(ini_get('post_max_size'));
    if ($post_max_size > 0) {
      $max_size = $post_max_size;
    }

    // If upload_max_size is less, then reduce. Except if upload_max_size is
    // zero, which indicates no limit.
    $upload_max = parse_size(ini_get('upload_max_filesize'));
    if ($upload_max > 0 && $upload_max < $max_size) {
      $max_size = $upload_max;
    }
  }
  return $max_size;
}

function parse_size($size) {
  $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-unit characters from the size.
  $size = preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the size.
  if ($unit) {
    // Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by.
    return round($size * pow(1024, stripos('bkmgtpezy', $unit[0])));
  }
  else {
    return round($size);
  }
}

上記の機能は、Drupal のどこでも利用できます。また、GPL ライセンス バージョン 2 以降の条件に従って、コピーして独自のプロジェクトで使用することもできます。

php.ini質問のパート 2 と 3 については、ファイルを直接解析する必要があります。これらは本質的に構成エラーであり、PHP はフォールバック動作に頼っています。ロードされたファイルの場所を PHP で実際に取得できるようですがphp.ini、それから読み取ろうとすると、basedir またはセーフモードが有効になっていると機能しない場合があります。

$max_size = -1;
$post_overhead = 1024; // POST data contains more than just the file upload; see comment from @jlh
$files = array_merge(array(php_ini_loaded_file()), explode(",\n", php_ini_scanned_files()));
foreach (array_filter($files) as $file) {
  $ini = parse_ini_file($file);
  $regex = '/^([0-9]+)([bkmgtpezy])$/i';
  if (!empty($ini['post_max_size']) && preg_match($regex, $ini['post_max_size'], $match)) {
    $post_max_size = round($match[1] * pow(1024, stripos('bkmgtpezy', strtolower($match[2])));
    if ($post_max_size > 0) {
      $max_size = $post_max_size - $post_overhead;
    }
  }
  if (!empty($ini['upload_max_filesize']) && preg_match($regex, $ini['upload_max_filesize'], $match)) {
    $upload_max_filesize = round($match[1] * pow(1024, stripos('bkmgtpezy', strtolower($match[2])));
    if ($upload_max_filesize > 0 && ($max_size <= 0 || $max_size > $upload_max_filesize) {
      $max_size = $upload_max_filesize;
    }
  }
}

echo $max_size;
于 2014-08-18T19:50:39.337 に答える
42

これが完全な解決策です。省略形のバイト表記のようなすべてのトラップを処理し、post_max_size も考慮します。

/**
* This function returns the maximum files size that can be uploaded 
* in PHP
* @returns int File size in bytes
**/
function getMaximumFileUploadSize()  
{  
    return min(convertPHPSizeToBytes(ini_get('post_max_size')), convertPHPSizeToBytes(ini_get('upload_max_filesize')));  
}  

/**
* This function transforms the php.ini notation for numbers (like '2M') to an integer (2*1024*1024 in this case)
* 
* @param string $sSize
* @return integer The value in bytes
*/
function convertPHPSizeToBytes($sSize)
{
    //
    $sSuffix = strtoupper(substr($sSize, -1));
    if (!in_array($sSuffix,array('P','T','G','M','K'))){
        return (int)$sSize;  
    } 
    $iValue = substr($sSize, 0, -1);
    switch ($sSuffix) {
        case 'P':
            $iValue *= 1024;
            // Fallthrough intended
        case 'T':
            $iValue *= 1024;
            // Fallthrough intended
        case 'G':
            $iValue *= 1024;
            // Fallthrough intended
        case 'M':
            $iValue *= 1024;
            // Fallthrough intended
        case 'K':
            $iValue *= 1024;
            break;
    }
    return (int)$iValue;
}      
于 2014-03-19T08:44:36.310 に答える
5

それは不可能のようです。

このため、このコードを引き続き使用します。

function convertBytes( $value ) {
    if ( is_numeric( $value ) ) {
        return $value;
    } else {
        $value_length = strlen($value);
        $qty = substr( $value, 0, $value_length - 1 );
        $unit = strtolower( substr( $value, $value_length - 1 ) );
        switch ( $unit ) {
            case 'k':
                $qty *= 1024;
                break;
            case 'm':
                $qty *= 1048576;
                break;
            case 'g':
                $qty *= 1073741824;
                break;
        }
        return $qty;
    }
}
$maxFileSize = convertBytes(ini_get('upload_max_filesize'));

もともとこの役立つ php.net コメントから。

より良い回答を受け入れるためにまだ開いています

于 2012-11-04T22:16:37.497 に答える
0

少なくともあなたが定義した方法ではそうではないと思います。最大ファイル アップロード サイズについては、他にも多くの要因が考慮されます。特に、ユーザーの接続速度、Web サーバーと PHP プロセスのタイムアウト設定が最も重要です。

より有用なメトリックは、特定の入力に対して受け取ると予想されるファイルの種類の妥当な最大ファイル サイズを決定することです。ユースケースにとって何が合理的かを決定し、それに関するポリシーを設定します。

于 2012-10-25T20:19:45.777 に答える