dongmaoluan5719 2012-10-25 20:11 采纳率: 100%
浏览 104
已采纳

PHP获得实际的最大上传大小

When using

ini_get("upload_max_filesize");

it actually gives you the string specified in the php.ini file.

It is not good to use this value as a reference for the maximum upload size because

  • it is possible to use so-called shorthandbytes like 1M and so on which needs alot of additional parsing
  • when upload_max_filesize is for example 0.25M, it actually is ZERO, making the parsing of the value much harder once again
  • also, if the value contains any spaces like it is interpreted as ZERO by php, while it shows the value without spaces when using ini_get

So, is there any way to get the value actually being used by PHP, besides the one reported by ini_get, or what is the best way to determinate it?

  • 写回答

6条回答 默认 最新

  • drghhp8706 2014-08-18 19:50
    关注

    Drupal has this implemented fairly elegantly:

    // 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);
      }
    }
    

    The above functions are available anywhere in Drupal, or you can copy it and use it in your own project subject to the terms of the GPL license version 2 or later.

    As for parts 2 and 3 of your question, you will need to parse the php.ini file directly. These are essentially configuration errors, and PHP is resorting to fallback behaviors. It appears you can actually get the location of the loaded php.ini file in PHP, although trying to read from it may not work with basedir or safe-mode enabled:

    $max_size = -1;
    $files = array_merge(array(php_ini_loaded_file()), explode(",
    ", 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;
        }
      }
      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;
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看