obtenir la ram du serveur avec php

Existe-t-il un moyen de connaître la ram disponible dans un serveur (distribution linux) avec php (widthout utilisant les commandes linux)?

Edit: désolé, l'objectif est d'être conscient de la ram disponible dans le serveur / machine virtuelle, pour le serveur particulier (même si cette mémoire est partagée).

27
demandé sur yoda 2009-09-21 20:17:12

8 réponses

Si vous savez que ce code ne fonctionnera que sous Linux, vous pouvez utiliser le fichier spécial /proc/meminfo pour obtenir des informations sur le sous-système de mémoire virtuelle du système. Le fichier a une forme comme ceci:

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

Cette première ligne, MemTotal: ..., contient la quantité de RAM physique à la machine, moins l'espace réservé par le noyau pour son propre usage. C'est le meilleur moyen que je connaisse pour obtenir un rapport simple de la mémoire utilisable sur un système Linux. Vous devriez être en mesure de l'extraire via quelque chose comme le code suivant:

<?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"; ?>

(Veuillez noter que ce code peut nécessiter quelques modifications pour votre environnement.)

33
répondu rcoder 2014-06-25 03:13:07

Utiliser /proc/meminfo et tout mettre dans un tableau est 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"
  ...
34
répondu J.C. Inacio 2018-04-22 15:30:41

Les commandes Linux peuvent être exécutées en utilisant la fonction exec en PHP. C'est efficace et fera le travail (si l'objectif est d'obtenir la mémoire).

Essayez le code suivant:

<?php
  exec("free -mtl", $output);
  print_r($output);
?>
5
répondu fotuzlab 2013-11-22 11:52:03

Il convient de noter que dans Windows, ces informations (et bien plus encore) peuvent être acquises en exécutant et en analysant la sortie de la commande shell: systeminfo

1
répondu xendi 2014-05-31 06:25:35

Je ne pense pas que vous puissiez accéder aux informations de mémoire du serveur hôte sans une extension PHP écrite spéciale. La bibliothèque PHP core ne permet pas (peut-être pour des raisons de sécurité) d'accéder aux informations de mémoire étendue.

Cependant, si votre script a accès au /proc/meminfo, vous pouvez interroger ce fichier spécial et récupérer les informations dont vous avez besoin. Sous Windows (bien que vous ne l'ayez pas demandé), nous pouvons utiliser l'extension com_dotnet PHP pour interroger le framework Windows via COM.

Ci-dessous vous pouvez trouver mon getSystemMemoryInfo que renvoie cette information pour vous, peu importe si vous exécutez le script sur un serveur Linux/Windows. Le wmiWBemLocatorQuery est juste une fonction d'aide.

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];
}

Exemple sur un système de 8 Go de RAM

print_r(getSystemMemoryInfo());

Sortie

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

Si vous voulez comprendre ce que chaque champ représente alors lire la suite .

1
répondu Eugen Mihailescu 2016-03-04 10:25:24

// helpers

/**
 * @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');
}
1
répondu Helmut Hoffer von Ankershoffen 2017-07-31 11:49:13

Version plus Courte

preg_match('#MemFree:[\s\t]+([\d]+)\s+kB#', file_get_contents('/proc/meminfo'), $matches); 
var_dump($matches[1]); // Free abount in KB
0
répondu Elvis Ciotti 2018-02-08 16:07:31

Je ne me souviens pas avoir jamais vu une telle fonction - c'est un peu la portée de ce que PHP est fait pour, en fait.

Même s'il y avait une telle fonctionnalité, elle serait probablement implémentée d'une manière spécifique au système d'exploitation sous-jacent, et ne fonctionnerait probablement pas à la fois sur Linux et windows (Voir sys_getloadavg pour un exemple de ce genre de chose)

-1
répondu Pascal MARTIN 2009-09-21 16:23:26