Янв 25 2013

Определить максимальный размер загружаемого файла в PHP

Категория: PHPgugglegum @ 16:09

Возникла необходимость определять автоматически какого размера файл может быть загружен при текущих настройках PHP. Однако, беглый поиск по интернету не привёл ни к одному достойному результату. Известно, что этот размер зависит от трёх параметров php.ini (”upload_max_filesize”, “post_max_size”, “memory_limit”) и не может быть больше каждого из них. Однако значения этих параметров не всегда указываются в мегабайтах, а могут указываться также в килобайтах, гигайбайтах или просто в байтах. В основном все лежащие в сети примеры срезаются уже на этом. Также они не учитывают, что размеры могут быть дробными. Поэтому я написал свою функцию, которая учитывает эти нюансы. Я просто положу её здесь, пусть кому-нибудь когда-нибудь пригодится.


/**
 * Detects max size of file can be uploaded to server
 *
 * Based on php.ini parameters "upload_max_filesize", "post_max_size" &
 * "memory_limit". Valid for single file upload form. Respects floating point
 * values like "1.5G and special values of memory_limit = -1 and
 * post_max_size = 0 that treats as unlimited.
 *
 * @throws Exception
 * @return int|float	Max file size in bytes
 */
function detectMaxUploadFileSize()
{
	/**
	 * Converts shorthands like "2M" or "512K" to bytes
	 *
	 * @param int $size
	 * @return int|float
	 * @throws Exception
	 */
	$normalize = function($size) {
		if (preg_match('/^(-?[\d\.]+)(|[KMG])$/i', $size, $match)) {
			$pos = array_search($match[2], array("", "K", "M", "G"));
			$size = $match[1] * pow(1024, $pos);
		} else {
			throw new Exception("Failed to normalize memory size '{$size}' (unknown format)");
		}
		return $size;
	};
	$limits = array();
	$limits[] = $normalize(ini_get('upload_max_filesize'));
	if (($max_post = $normalize(ini_get('post_max_size'))) != 0) {
		$limits[] = $max_post;
	}
	if (($memory_limit = $normalize(ini_get('memory_limit'))) != -1) {
		$limits[] = $memory_limit;
	}
	$maxFileSize = min($limits);
	return $maxFileSize;
}

Ну и в довесок ещё функция форматирования возвращаемого значения в человеко-читабельный формат в мегабайтах:


/**
 * Converts size in bytes into human-friendly format in megabytes (MiB)
 * and trims redundant zero decimals
 *
 * @param int|float $size		Size of file or memory in bytes
 * @param int $maxDecimals		OPTIONAL	Amount of max decimal digits
 * @param string $mbSuffix		OPTIONAL	MB-suffix (may be used for i18n)
 * @return string
 */
function formatSizeInMb($size, $maxDecimals = 3, $mbSuffix = " MB")
{
	$mbSize = round($size / 1024 / 1024, $maxDecimals);
	return preg_replace("/\\.?0+$/", "", $mbSize) . $mbSuffix;
}

В ней можно задать максимальное кол-во десятичных знаков после запятой, лишние нули автоматически обрежутся.