2012-04-18 22 views
18

Necesito comprobar si memory_limit es al menos 64M en el instalador de mi script. Esto es solo una parte del código PHP que debería funcionar, pero probablemente debido a esta "M" no está leyendo correctamente el valor. Cómo arreglar esto ?comprobando memory_limit en PHP

//memory_limit 
    echo "<phpmem>"; 
    if(key_exists('PHP Core', $phpinfo)) 
    { 
     if(key_exists('memory_limit', $phpinfo['PHP Core'])) 
     { 
      $t=explode(".", $phpinfo['PHP Core']['memory_limit']); 
      if($t[0]>=64) 
       $ok=1; 
      else 
       $ok=0; 
      echo "<val>{$phpinfo['PHP Core']['memory_limit']}</val><ok>$ok</ok>"; 
     } 
     else 
      echo "<val></val><ok>0</ok>"; 
    } 
    else 
     echo "<val></val><ok>0</ok>"; 
    echo "</phpmem>\n"; 
+0

Estoy usando el código XML, por lo que no es posible. – Spacedust

+0

¿Puedes mostrar 'var_dump ($ phpinfo);', o al menos 'var_dump ($ phpinfo ['PHP Core']);', para que podamos ver con qué estás empezando? – DaveRandom

Respuesta

19

Intente convertir primero el valor (p. Ej .: 64M -> 64 * 1024 * 1024). Después de eso, haga una comparación e imprima el resultado.

<?php 
$memory_limit = ini_get('memory_limit'); 
if (preg_match('/^(\d+)(.)$/', $memory_limit, $matches)) { 
    if ($matches[2] == 'M') { 
     $memory_limit = $matches[1] * 1024 * 1024; // nnnM -> nnn MB 
    } else if ($matches[2] == 'K') { 
     $memory_limit = $matches[1] * 1024; // nnnK -> nnn KB 
    } 
} 

$ok = ($memory_limit >= 640 * 1024 * 1024); // at least 64M? 

echo '<phpmem>'; 
echo '<val>' . $memory_limit . '</val>'; 
echo '<ok>' . ($ok ? 1 : 0) . '</ok>'; 
echo '</phpmem>'; 
+4

La expresión regular proporcionada es incompleta, precisa y dará lugar a resultados incorrectos en varias instalaciones. – hakre

+0

ini_get() función arroja una excepción en algunos servidores ¿tiene algún ajuste en esto? – Sahan

+0

Recuerde manejar memory_limit de -1 – Kieran

4

Mientras que incluía la matriz $phpinfo['PHP Core']['memory_limit'] contiene el valor de memory_limit, funciona lo siguiente:

  • El último carácter de ese valor se puede señalar la notación abreviada. Si es inválido, se ignora.
  • El comienzo de la cadena se convierte a un número en la forma específica de PHP: espacio en blanco ignorado, etc.
  • Se ignora el texto entre el número y la notación abreviada (si lo hay).

Ejemplo:

# Memory Limit equal or higher than 64M? 
$ok = (int) (bool) setting_to_bytes($phpinfo['PHP Core']['memory_limit']) >= 0x4000000; 

/** 
* @param string $setting 
* 
* @return NULL|number 
*/ 
function setting_to_bytes($setting) 
{ 
    static $short = array('k' => 0x400, 
          'm' => 0x100000, 
          'g' => 0x40000000); 

    $setting = (string)$setting; 
    if (!($len = strlen($setting))) return NULL; 
    $last = strtolower($setting[$len - 1]); 
    $numeric = (int) $setting; 
    $numeric *= isset($short[$last]) ? $short[$last] : 1; 
    return $numeric; 
} 

Los detalles de la notación abreviada son contorno en a PHP manual's FAQ entry extrema y detalles son parte de Protocol of some PHP Memory Stretching Fun.

Tenga cuidado si la configuración es -1 PHP no se limita aquí, pero el sistema sí. Por lo tanto, debe decidir cómo trata el instalador ese valor.

+0

Este es un código compacto, pero se rompe en PHP 7.1+: '$ numérico = 0 + $ configuración;' arroja una excepción porque $ configuración no es un valor numérico debido al sufijo (el mensaje es "Un valor numérico no bien formado encontrado en [...]"). en (al menos) 7.2, en su lugar funciona lo siguiente: '$ numeric = (int) $ setting;' –

+0

@GabrielMagana: Buen punto, hace bastante tiempo escribí eso, y usar (int) cast es preferible sobre 0 + de todos modos para convertir el número. Editado la respuesta. – hakre

10

Aquí hay otra forma más sencilla de comprobarlo.

$memory_limit = return_bytes(ini_get('memory_limit')); 
if ($memory_limit < (64 * 1024 * 1024)) { 
    // Memory insufficient  
} 

/** 
* Converts shorthand memory notation value to bytes 
* From http://php.net/manual/en/function.ini-get.php 
* 
* @param $val Memory size shorthand notation string 
*/ 
function return_bytes($val) { 
    $val = trim($val); 
    $last = strtolower($val[strlen($val)-1]); 
    switch($last) { 
     // The 'G' modifier is available since PHP 5.1.0 
     case 'g': 
      $val *= 1024; 
     case 'm': 
      $val *= 1024; 
     case 'k': 
      $val *= 1024; 
    } 
    return $val; 
} 
2

No es tan exacto pero más simple solución:

$limit = str_replace(array('G', 'M', 'K'), array('000000000', '000000', '000'), ini_get('memory_limit')); 
if($limit < 500000000) ini_set('memory_limit', '500M');      
0

muy antiguo puesto. pero voy a dejar esto aquí:

/* converts a number with byte unit (B/K/M/G) into an integer */ 
function unitToInt($s) 
{ 
    (int)preg_replace_callback('/(\-?\d+)(.?)/', function ($m) { 
     return $m[1] * pow(1024, strpos('BKMG', $m[2])); 
    }, strtoupper($s)); 
} 

$mem_limit = unitToInt(ini_get('memory_limit')); 
+2

¿Qué es esto? No solo publique código por favor. Explica cómo y por qué este código tuyo resolverá el problema. – UmarZaii

+0

siento eso. código editado. – Gibz

Cuestiones relacionadas