PHP获取实际最大上传大小

标签 php

使用时

ini_get("upload_max_filesize");

它实际上为您提供了 php.ini 文件中指定的字符串。

不宜将此值用作最大上传大小的引用,因为

  • 可以使用所谓的 shorthandbytes比如 1M 等等需要大量额外的解析
  • 当upload_max_filesize例如0.25M时,实际上是零,使得解析值再次变得更加困难
  • 另外,如果该值包含任何空格,例如它被 php 解释为零,而在使用 ini_get
  • 时它显示没有空格的值

那么,除了 ini_get 报告的那个之外,还有什么方法可以获取 PHP 实际使用的值,或者确定它的最佳方法是什么?

最佳答案

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 或更高版本的条款。

至于问题的第 2 部分和第 3 部分,您需要直接解析 php.ini 文件。这些本质上是配置错误,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;

关于PHP获取实际最大上传大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13076480/

相关文章:

php - 获取下拉菜单

php - Regex/DOMDocument - 匹配和替换不在链接中的文本

php - 如何找到图像位置

php - 是否有一个 PHP 沙箱,比如 JSFiddle 之类的 JS?

PHP artisan 数据库:seed is not working Laravel 5

php - 无法从数据库中获取要显示的正确字符

php - 无法在 php 中回显 jquery(使用 ajax)变量

php - 提交按钮上的 JavaScript

php - 如何在 YII 中更改 GridView 列的大小?

php - 将太少的参数传递给函数时,PHP 7 是否会引发错误?