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

使用时

ini_get("upload_max_filesize"); 

它实际上给你在php.ini文件中指定的string。

将此值用作最大上载大小的参考是不好的,因为

  • 有可能使用像1M等所谓的简写字节等,这需要大量额外的parsing
  • 当upload_max_filesize是例如0.25M ,它实际上是零,使得值的parsing更加困难
  • 另外,如果值包含任何空格,如果它被解释为ZERO由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); } } 

上述function在Drupal的任何地方都可用,或者您可以将其复制并在您自己的项目中使用,但须遵守GPL许可证版本2或更高版本的条款。

至于你的问题的第2部分和第3部分,你将需要直接parsingphp.ini文件。 这些本质上是configuration错误,而PHP正在采取后备行为。 看起来你实际上可以在PHP中获取加载的php.ini文件的位置,尽pipe尝试读取它可能无法使用basedir或安全模式启用:

 $max_size = -1; $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; } } 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; 

这是完整的解决scheme。 它处理像速记字节表示法这样的所有陷阱,并考虑post_max_size:

 //This function transforms the php.ini notation for numbers (like '2M') to an integer (2*1024*1024 in this case) function convertPHPSizeToBytes($sSize) { if ( is_numeric( $sSize) ) { return $sSize; } $sSuffix = substr($sSize, -1); $iValue = substr($sSize, 0, -1); switch(strtoupper($sSuffix)){ case 'P': $iValue *= 1024; case 'T': $iValue *= 1024; case 'G': $iValue *= 1024; case 'M': $iValue *= 1024; case 'K': $iValue *= 1024; break; } return $iValue; } function getMaximumFileUploadSize() { return min(convertPHPSizeToBytes(ini_get('post_max_size')), convertPHPSizeToBytes(ini_get('upload_max_filesize'))); } 

这是一个稍微修改版本的来源: http : //www.smokycogs.com/blog/finding-the-maximum-file-upload-size-in-php/ 。

这是我使用的:

 function asBytes($ini_v) { $ini_v = trim($ini_v); $s = [ 'g'=> 1<<30, 'm' => 1<<20, 'k' => 1<<10 ]; return intval($ini_v) * ($s[strtolower(substr($ini_v,-1))] ?: 1); } 

看起来这是不可能的。

因此,我将继续使用此代码:

 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评论。

仍然开放接受更好的答案

我不这么认为,至less不是你所定义的方式。 有很多其他因素会考虑最大的file upload大小,最显着的是用户的连接速度,以及Web服务器的超时设置以及PHP进程。

对于您来说,更有用的度量标准可能是确定对于给定的input,您希望获得的文件types的合理最大文件大小。 根据你的用例做出合理的决定,然后制定一个策略。

那么你总是可以使用这个语法,它会从PHP ini文件中给你正确的数字:

 $maxUpload = (int)(ini_get('upload_max_filesize')); $maxPost = (int)(ini_get('post_max_size')); 

市场