Question
Is there a way to know the avaliable ram in a server (linux distro) with php (widthout using linux commands)?
edit: sorry, the objective is to be aware of the ram available in the server / virtual machine, for the particular server (even if that memory is shared).
Solution
If you know this code will only be running under Linux, you can use the special /proc/meminfo
file to get information about the system's virtual memory subsystem. The file has a form like this:
MemTotal: 255908 kB
MemFree: 69936 kB
Buffers: 15812 kB
Cached: 115124 kB
SwapCached: 0 kB
Active: 92700 kB
Inactive: 63792 kB
...
That first line, MemTotal: ...
, contains the amount of physical RAM in the machine, minus the space reserved by the kernel for its own use. It's the best way I know of to get a simple report of the usable memory on a Linux system. You should be able to extract it via something like the following code:
<?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"; ?>
(Please note: this code may require some tweaking for your environment.)
OTHER TIPS
Using /proc/meminfo
and getting everything into an array is 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"
...
Linux commands can be run using the exec function in PHP. This is efficient and will do the job(if objective is to get the memory).
Try the following code:
<?php
exec("free -mtl", $output);
print_r($output);
?>
It is worth noting that in Windows this information (and much more) can be acquired by executing and parsing the output of the shell command: systeminfo
I don't think you can access the host server memory info without a special written PHP extension. The PHP core library does not allow (perhaps for security reasons) to access the extended memory info.
However, if your script has access to the /proc/meminfo
then you can query that special file and grab the info you need. On Windows (although you've not asked for it) we can use the com_dotnet
PHP extension to query the Windows framework via COM.
Below you can find my getSystemMemoryInfo
that returns that info for you no matter if you run the script on a Linux/Windows server. The wmiWBemLocatorQuery
is just a helper function.
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];
}
Example on a 8GB RAM system
print_r(getSystemMemoryInfo());
Output
Array
(
[MemTotal] => 8102684000
[MemFree] => 2894508000
[MemAvailable] => 4569396000
[SwapTotal] => 4194300000
[SwapFree] => 4194300000
)
If you want to understand what each field represent then read more.
// 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');
}
shorter version
preg_match('#MemFree:[\s\t]+([\d]+)\s+kB#', file_get_contents('/proc/meminfo'), $matches);
var_dump($matches[1]); // Free abount in KB
I don't remember having ever seen such a function -- its kind of out the scope of what PHP is made for, actually.
Even if there was such a functionnality, it would probably be implemented in a way that would be specific to the underlying operating system, and wouldn't probably work on both Linux and windows (see sys_getloadavg
for an example of that kind of thing)