PHP获取实际最大上载大小
使用时PHP获取实际最大上载大小,php,Php,使用时 ini_get("upload_max_filesize"); 它实际上提供了php.ini文件中指定的字符串 使用此值作为最大上载大小的参考是不好的,因为 可以使用所谓的like1M等,这需要大量额外的解析 例如,当upload_max_filesize为0.25M时,它实际上为零,这使得解析值再次变得困难 此外,如果该值包含任何空格,则php会将其解释为零,而在使用ini\u get 那么,除了ini\u get报告的值之外,还有什么方法可以获得PHP实际使用的值,或者确定它的
ini_get("upload_max_filesize");
它实际上提供了php.ini文件中指定的字符串
使用此值作为最大上载大小的参考是不好的,因为
- 可以使用所谓的like
等,这需要大量额外的解析1M
- 例如,当upload_max_filesize为
时,它实际上为零,这使得解析值再次变得困难0.25M
- 此外,如果该值包含任何空格,则php会将其解释为零,而在使用
ini\u get
那么,除了
ini\u get
报告的值之外,还有什么方法可以获得PHP实际使用的值,或者确定它的最佳方法是什么?我不这么认为,至少不是以您定义它的方式。最大文件上载大小还需要考虑许多其他因素,最显著的是用户的连接速度以及web服务器和PHP进程的超时设置
对于您来说,一个更有用的指标可能是确定对于给定输入,您希望接收的文件类型的合理最大文件大小。决定什么对您的用例是合理的,并围绕它设置一个策略。看起来这是不可能的 因此,我将继续使用以下代码:
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注释
仍然可以接受更好的答案您可以始终使用此语法,它将从PHP ini文件中为您提供正确的数字:
$maxUpload = (int)(ini_get('upload_max_filesize'));
$maxPost = (int)(ini_get('post_max_size'));
Mart这是我使用的:
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);
}
函数为字节($ini\u v){
$ini_v=修剪($ini_v);
$s=['g'=>1这是完整的解决方案。它考虑了所有陷阱,如简写字节表示法,还考虑了post_max_大小:
/**
* 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;
}
这是此源代码的一个无错误版本:。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);
}
}
当然,这就是我正在做的。但我仍然绝对需要知道php.ini中允许的大小是否低于我建议的最大大小。你看过开场白了吗?echo ini_get('post_max_size');->8M
echo(int)(ini_get('post_max_size'));->8
我不知道这到底是怎么回事(特别是switch语句)直到我最终意识到switch语句中只有一个“break”语句,“case”行的顺序很重要。它工作得很好,但我害怕一些初级程序员回头尝试修改代码。也许是“更标准化”版本会是一个更好的长期解决方案吗?嗯,这并不能真正解决我在问题中提到的问题,因为它只使用ini_get()-)我们已经有了很多这样的答案。@GavinG我现在按照PSR-2的要求添加了正确的注释,因此错误是显而易见的。pow
行非常优雅,但这只解决了问题中列出的3个问题中的一个。另外两个问题实际上是配置错误,而不是有效的情况不需要考虑。但是为了检查配置错误,只有在php尝试解析无效条目之前直接读取php.ini文件才能完成。而且由于php.ini可能在任何地方,这不是检查活动配置的稳定或跨平台的方法。那么$ini=parse\u ini\u文件呢('/etc/php.ini');$ini['upload_max_filesize']
?我只是想澄清一下,自从我之前的评论以来,我已经用一些代码更新了帖子,以找到活动的php.ini
文件并直接对其进行解析。这似乎是我目前最好的选择。如果php.ini不可读,请回到ini_get()非常好。如果这个限制真的被强制执行了,我想是的,它是由允许php运行的Apache或CGI控制器处理的吗?他们是如何处理的?说我们应该找到将其转换为字节的内部机制,而不是膨胀我们自己的代码(假设我们还没有运行Drupal)。可能重复(int)ini_get(“upload_max_filesize”)*1024将其转换为kbs。例如,2M->2048在2020年,我们可以使用kbs
$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;