bestsource

PHP 실제 최대 업로드 크기 가져오기

bestsource 2023. 7. 23. 14:31
반응형

PHP 실제 최대 업로드 크기 가져오기

사용 시

ini_get("upload_max_filesize");

실제로 php.ini 파일에 지정된 문자열을 제공합니다.

다음과 같은 이유로 이 값을 최대 업로드 크기에 대한 참조로 사용하는 것은 좋지 않습니다.

  • 다음과 같이 이른바 단축 바이트를 사용하는 것이 가능합니다.1M추가적인 구문 분석이 많이 필요한 등.
  • upload_max_filesize가 예를 들어 다음과 같은 경우0.25M실제로는 ZERO이며, 값의 구문 분석을 다시 한 번 훨씬 더 어렵게 만듭니다.
  • 또한, 만약 값이 php에 의해 ZERO로 해석되는 것과 같은 공간을 포함한다면, 그것은 사용할 때 공백이 없는 값을 보여줍니다.ini_get

그래서, 보고된 것 외에 PHP에서 실제로 사용되는 값을 얻을 수 있는 방법이 있습니까?ini_get아니면 그것을 결정하는 가장 좋은 방법은 무엇입니까?

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.iniPHP의 파일을 읽으려고 시도하지만 basedir 또는 safe-mode가 활성화된 상태에서는 작동하지 않을 수 있습니다.

$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;

여기 완전한 해결책이 있습니다.이것은 속기 바이트 표기법과 같은 모든 트랩을 처리하고 post_max_size도 고려합니다.

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

다음을 사용합니다.

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 의견에서 왔습니다.

여전히 더 나은 답변을 수용할 수 있습니다.

저는 그렇게 생각하지 않습니다, 적어도 당신이 정의한 방식으로는 아닙니다.최대 파일 업로드 크기를 고려할 수 있는 다른 요소는 매우 많습니다. 특히 사용자의 연결 속도와 PHP 프로세스의 시간 초과 설정이 가장 중요합니다.

더 유용한 메트릭은 지정된 입력에 대해 수신할 것으로 예상되는 파일 유형에 대해 적절한 최대 파일 크기를 결정하는 것입니다.사용 사례에 적합한 것을 결정하고 그에 대한 정책을 설정합니다.

PHP ini 파일의 정확한 숫자를 제공하는 다음 구문을 항상 사용할 수 있습니다.

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

마트

언급URL : https://stackoverflow.com/questions/13076480/php-get-actual-maximum-upload-size

반응형