2009-09-21 17 views
24

¿Hay alguna manera de conocer el RAM disponible en un servidor (Linux distro) con php (widthout usando comandos linux)?obtener el servidor ram con php

editar: lo siento, el objetivo es ser consciente de la memoria RAM disponible en el servidor/máquina virtual, para el servidor en particular (incluso si esa memoria se comparte).

+2

para Windows hay una extensión PECL: http://php.net/manual/en/function.win32-ps-stat- mem.php – Gordon

+2

Cosas geniales para chicos geniales: https://github.com/BitOne/php-meminfo – Sliq

Respuesta

30

Si sabe que este código solo se ejecutará en Linux, puede usar el archivo especial /proc/meminfo para obtener información sobre el subsistema de memoria virtual del sistema. El archivo tiene una forma como esta:

MemTotal:  255908 kB 
MemFree:   69936 kB 
Buffers:   15812 kB 
Cached:   115124 kB 
SwapCached:   0 kB 
Active:   92700 kB 
Inactive:  63792 kB 
... 

Esa primera línea, MemTotal: ..., contiene la cantidad de RAM física en la máquina, menos el espacio reservado por el núcleo para su propio uso. Es la mejor forma que conozco de obtener un informe simple de la memoria utilizable en un sistema Linux. Usted debe ser capaz de extraerlo a través de algo como el siguiente código:

<?php 
    $fh = fopen('/proc/meminfo','r'); 
    $mem = 0; 
    while ($line = fgets($fh)) { 
    $pieces = array(); 
    if (preg_match('/^MemTotal:\s+(\d+)\skB$/', $line, $pieces)) { 
     $mem = $pieces[1]; 
     break; 
    } 
    } 
    fclose($fh); 

    echo "$mem kB RAM found"; ?> 

(Tenga en cuenta:. Este código puede requerir algunos ajustes para su entorno)

+4

upvoted para el meminfo, con 3 errores: - NO es '/proc/meminfo.txt', pero '/ proc/meminfo ' - debe coincidir con' MemFree 'y no con' MemTotal '. - y olvidaste fclose();) –

+0

Tienes razón en que el sufijo '.txt' es incorrecto, pero quise utilizar' MemTotal', no 'MemFree' - sin embargo, tal vez entendí mal la pregunta original. Volviéndolo a leer, veo la palabra "disponible", aunque sinceramente no estoy seguro de cómo conocer la RAM * disponible * en un servidor ayuda mucho, dada la naturaleza de los modernos subsistemas de caché y VM. Además, la omisión de 'fclose()' no debería ser realmente un factor para los scripts de PHP de corta vida, ¿correcto? Es difícil filtrar descriptores de archivos cuando su GC puede finalizar manipuladores abiertos ... – rcoder

+0

No creo que el análisis de archivos de sistema con un script sea una buena idea cuando podemos ejecutar comandos de shell simples para obtener el mismo resultado. – fotuzlab

-1

No recuerdo haber visto alguna vez una función de este tipo: está fuera del alcance de lo que PHP está hecho, en realidad.

Incluso si existiera tal funcionalidad, probablemente se implementaría de forma específica para el sistema operativo subyacente, y probablemente no funcionaría tanto en Linux como en Windows (vea sys_getloadavg para ver un ejemplo de eso) tipo de cosa)

32

El uso de '/ proc/meminfo' y conseguir todo en una matriz es simple:

<?php 

function getSystemMemInfo() 
{  
    $data = explode("\n", file_get_contents("/proc/meminfo")); 
    $meminfo = array(); 
    foreach ($data as $line) { 
     list($key, $val) = explode(":", $line); 
     $meminfo[$key] = trim($val); 
    } 
    return $meminfo; 
} 

?> 

var_dump (getSystemMemInfo());

array(43) { 
    ["MemTotal"]=> 
    string(10) "2060700 kB" 
    ["MemFree"]=> 
    string(9) "277344 kB" 
    ["Buffers"]=> 
    string(8) "92200 kB" 
    ["Cached"]=> 
    string(9) "650544 kB" 
    ["SwapCached"]=> 
    string(8) "73592 kB" 
    ["Active"]=> 
    string(9) "995988 kB" 
    ... 
+3

Es posible que desee agregar un trim() en el resultado de file_get_contents. Estaba obteniendo un final de línea final, lo que resulta en una matriz vacía, que a su vez genera una advertencia de PHP –

+1

Supongo que esta es la mejor opción, porque la pregunta no ha preguntado sobre ram libre, solo valores de RAM, que pueden ser, gratis , total, etc. – erm3nda

+0

Hola .. los valores anteriores que se están obteniendo están en kb .. qué se debe hacer para recuperarlo en GB. – pihu

5

comandos de Linux se puede ejecutar mediante la función exec en PHP. Esto es eficiente y hará el trabajo (si el objetivo es obtener la memoria).

Prueba el siguiente código:

<?php 
    exec("free -mtl", $output); 
    print_r($output); 
?> 
1

Vale la pena señalar que en Windows esta información (y mucho más) pueden ser adquiridos mediante la ejecución y analizar el resultado del comando shell: systeminfo

+0

Aunque el comando es muy lento, puedo confirmar que se puede invocar con éxito desde PHP. –

1

I no creo que pueda acceder a la información de la memoria del servidor host sin una extensión especial PHP escrita. La biblioteca principal de PHP no permite (tal vez por razones de seguridad) acceder a la información de la memoria extendida.

Sin embargo, si su script tiene acceso al /proc/meminfo, entonces puede consultar ese archivo especial y obtener la información que necesita. En Windows (aunque no lo haya solicitado) podemos usar la extensión PHP com_dotnet para consultar el marco de trabajo de Windows a través de COM.

A continuación puede encontrar mi getSystemMemoryInfo que devuelve esa información para usted, sin importar si ejecuta la secuencia de comandos en un servidor Linux/Windows. El wmiWBemLocatorQuery es solo una función de ayuda.

function wmiWBemLocatorQuery($query) { 
    if (class_exists('\\COM')) { 
     try { 
      $WbemLocator = new \COM("WbemScripting.SWbemLocator"); 
      $WbemServices = $WbemLocator->ConnectServer('127.0.0.1', 'root\CIMV2'); 
      $WbemServices->Security_->ImpersonationLevel = 3; 
      // use wbemtest tool to query all classes for namespace root\cimv2 
      return $WbemServices->ExecQuery($query); 
     } catch (\com_exception $e) { 
      echo $e->getMessage(); 
     } 
    } elseif (! extension_loaded('com_dotnet')) 
     trigger_error('It seems that the COM is not enabled in your php.ini', E_USER_WARNING); 
    else { 
     $err = error_get_last(); 
     trigger_error($err['message'], E_USER_WARNING); 
    } 

    return false; 
} 

// _dir_in_allowed_path this is your function to detect if a file is withing the allowed path (see the open_basedir PHP directive) 
function getSystemMemoryInfo($output_key = '') { 
    $keys = array('MemTotal', 'MemFree', 'MemAvailable', 'SwapTotal', 'SwapFree'); 
    $result = array(); 

    try { 
     // LINUX 
     if (! isWin()) { 
      $proc_dir = '/proc/'; 
      $data = _dir_in_allowed_path($proc_dir) ? @file($proc_dir . 'meminfo') : false; 
      if (is_array($data)) 
       foreach ($data as $d) { 
        if (0 == strlen(trim($d))) 
         continue; 
        $d = preg_split('/:/', $d); 
        $key = trim($d[0]); 
        if (! in_array($key, $keys)) 
         continue; 
        $value = 1000 * floatval(trim(str_replace(' kB', '', $d[1]))); 
        $result[$key] = $value; 
       } 
     } else  // WINDOWS 
     { 
      $wmi_found = false; 
      if ($wmi_query = wmiWBemLocatorQuery( 
       "SELECT FreePhysicalMemory,FreeVirtualMemory,TotalSwapSpaceSize,TotalVirtualMemorySize,TotalVisibleMemorySize FROM Win32_OperatingSystem")) { 
       foreach ($wmi_query as $r) { 
        $result['MemFree'] = $r->FreePhysicalMemory * 1024; 
        $result['MemAvailable'] = $r->FreeVirtualMemory * 1024; 
        $result['SwapFree'] = $r->TotalSwapSpaceSize * 1024; 
        $result['SwapTotal'] = $r->TotalVirtualMemorySize * 1024; 
        $result['MemTotal'] = $r->TotalVisibleMemorySize * 1024; 
        $wmi_found = true; 
       } 
      } 
      // TODO a backup implementation using the $_SERVER array 
     } 
    } catch (Exception $e) { 
     echo $e->getMessage(); 
    } 
    return empty($output_key) || ! isset($result[$output_key]) ? $result : $result[$output_key]; 
} 

ejemplo en un sistema de 8 GB de RAM

print_r(getSystemMemoryInfo()); 

salida

Array 
(
    [MemTotal] => 8102684000 
    [MemFree] => 2894508000 
    [MemAvailable] => 4569396000 
    [SwapTotal] => 4194300000 
    [SwapFree] => 4194300000 
) 

Si se quiere entender lo que cada campo representa a continuación read more.

1

// ayudantes

/** 
* @return array|null 
*/ 
protected function getSystemMemInfo() 
{ 
    $meminfo = @file_get_contents("/proc/meminfo"); 
    if ($meminfo) { 
     $data = explode("\n", $meminfo); 
     $meminfo = []; 
     foreach ($data as $line) { 
      if(strpos($line, ':') !== false) { 
       list($key, $val) = explode(":", $line); 
       $val = trim($val); 
       $val = preg_replace('/ kB$/', '', $val); 
       if (is_numeric($val)) { 
        $val = intval($val); 
       } 
       $meminfo[$key] = $val; 
      } 
     } 
     return $meminfo; 
    } 
    return null; 
} 

// example call to check health 
public function check() { 
    $memInfo = $this->getSystemMemInfo(); 
    if ($memInfo) { 
     $totalMemory = $memInfo['MemTotal']; 
     $freeMemory = $memInfo['MemFree']; 
     $swapTotalMemory = $memInfo['SwapTotal']; 
     $swapFreeMemory = $memInfo['SwapFree']; 
     if (($totalMemory/100.0) * 30.0 > $freeMemory) { 
      if (($swapTotalMemory/100.0) * 50.0 > $swapFreeMemory) { 
       return new Failure('Less than 30% free memory and less than 50% free swap space'); 
      } 
      return new Warning('Less than 30% free memory'); 
     } 
    } 
    return new Success('ok'); 
} 
+3

¡Bienvenido a Stack Overflow! Gracias por este fragmento de código, que puede brindar alguna ayuda inmediata. Una explicación adecuada [mejoraría en gran medida] (// meta.stackexchange.com/q/114762) su valor educativo al mostrar * por qué * esta es una buena solución al problema, y ​​lo haría más útil para lectores futuros con similares, pero no idénticas, preguntas. Por favor [edite] su respuesta para agregar una explicación y dar una indicación de qué limitaciones y suposiciones se aplican. –

0

más corta versión

preg_match('#MemFree:[\s\t]+([\d]+)\s+kB#', file_get_contents('/proc/meminfo'), $matches); 
var_dump($matches[1]); // Free abount in KB 
Cuestiones relacionadas