get server ram with php

后端 未结 9 1614
抹茶落季
抹茶落季 2020-12-05 00:19

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 av

相关标签:
9条回答
  • 2020-12-05 00:55

    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

    0 讨论(0)
  • 2020-12-05 00:56

    // 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');
    }
    
    0 讨论(0)
  • 2020-12-05 01:02

    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.

    0 讨论(0)
提交回复
热议问题