44
55namespace PhpMyAdmin \Server \SysInfo ;
66
7- use COM ;
7+ use com ;
8+ use Throwable ;
89
10+ use function array_merge ;
911use function class_exists ;
10- use function count ;
11- use function in_array ;
12- use function is_string ;
13- use function trim ;
12+ use function intdiv ;
13+ use function intval ;
1414
1515/**
1616 * Windows NT based SysInfo class
1717 */
1818class WindowsNt extends Base
1919{
20- /** @var COM |null */
21- private $ wmi ;
20+ /** @var object |null */
21+ private $ wmiService = null ;
2222
2323 /**
2424 * The OS name
@@ -32,15 +32,18 @@ class WindowsNt extends Base
3232 */
3333 public function __construct ()
3434 {
35- if (! class_exists ('COM ' )) {
36- $ this ->wmi = null ;
37-
35+ if (! class_exists ('com ' )) {
3836 return ;
3937 }
4038
41- // initialize the wmi object
42- $ objLocator = new COM ('WbemScripting.SWbemLocator ' );
43- $ this ->wmi = $ objLocator ->ConnectServer ();
39+ /**
40+ * @see https://www.php.net/manual/en/class.com.php
41+ * @see https://docs.microsoft.com/en-us/windows/win32/wmisdk/swbemlocator
42+ * @see https://docs.microsoft.com/en-us/windows/win32/wmisdk/swbemservices
43+ *
44+ * @psalm-suppress MixedAssignment, UndefinedMagicMethod
45+ */
46+ $ this ->wmiService = (new com ('WbemScripting.SWbemLocator ' ))->ConnectServer ();
4447 }
4548
4649 /**
@@ -50,98 +53,119 @@ public function __construct()
5053 */
5154 public function loadavg ()
5255 {
53- $ sum = 0 ;
54- $ buffer = $ this ->getWMI ('Win32_Processor ' , ['LoadPercentage ' ]);
55-
56- foreach ($ buffer as $ load ) {
57- $ value = $ load ['LoadPercentage ' ];
58- $ sum += $ value ;
59- }
60-
61- return ['loadavg ' => $ sum / count ($ buffer )];
56+ return ['loadavg ' => $ this ->getLoadPercentage ()];
6257 }
6358
6459 /**
6560 * Checks whether class is supported in this environment
6661 */
6762 public function supported (): bool
6863 {
69- return $ this ->wmi !== null ;
64+ return $ this ->wmiService !== null ;
7065 }
7166
7267 /**
73- * Reads data from WMI
74- *
75- * @param string $strClass Class to read
76- * @param array $strValue Values to read
68+ * Gets information about memory usage
7769 *
78- * @return array with results
70+ * @return array with memory usage data
7971 */
80- private function getWMI ( $ strClass , array $ strValue = [] )
72+ public function memory ( )
8173 {
82- $ arrData = [];
83-
84- $ objWEBM = $ this ->wmi ->Get ($ strClass );
85- // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
86- $ arrProp = $ objWEBM ->Properties_ ;
87- $ arrWEBMCol = $ objWEBM ->Instances_ ();
88- foreach ($ arrWEBMCol as $ objItem ) {
89- $ arrInstance = [];
90- foreach ($ arrProp as $ propItem ) {
91- // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
92- $ name = $ propItem ->Name ;
93- if (! empty ($ strValue ) && ! in_array ($ name , $ strValue )) {
94- continue ;
95- }
96-
97- $ value = $ objItem ->$ name ;
98- if (is_string ($ value )) {
99- $ arrInstance [$ name ] = trim ($ value );
100- } else {
101- $ arrInstance [$ name ] = $ value ;
102- }
103- }
104-
105- $ arrData [] = $ arrInstance ;
74+ return array_merge ($ this ->getSystemMemory (), $ this ->getPageFileUsage ());
75+ }
76+
77+ /**
78+ * @return array<string, int>
79+ * @psalm-return array{MemTotal: int, MemFree: int, MemUsed: int}
80+ */
81+ private function getSystemMemory (): array
82+ {
83+ if ($ this ->wmiService === null ) {
84+ return ['MemTotal ' => 0 , 'MemFree ' => 0 , 'MemUsed ' => 0 ];
85+ }
86+
87+ /**
88+ * @see https://docs.microsoft.com/en-us/windows/win32/wmisdk/swbemobject-instances-
89+ * @see https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-operatingsystem
90+ *
91+ * @var object[] $instances
92+ * @psalm-suppress MixedMethodCall
93+ * @phpstan-ignore-next-line
94+ */
95+ $ instances = $ this ->wmiService ->Get ('Win32_OperatingSystem ' )->Instances_ ();
96+ $ totalMemory = 0 ;
97+ $ freeMemory = 0 ;
98+ foreach ($ instances as $ instance ) {
99+ // phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
100+ $ totalMemory += (int ) $ instance ->TotalVisibleMemorySize ; /* @phpstan-ignore-line */
101+ $ freeMemory += (int ) $ instance ->FreePhysicalMemory ; /* @phpstan-ignore-line */
102+ // phpcs:enable
106103 }
107104
108- return $ arrData ;
105+ return [ ' MemTotal ' => $ totalMemory , ' MemFree ' => $ freeMemory , ' MemUsed ' => $ totalMemory - $ freeMemory ] ;
109106 }
110107
111108 /**
112- * Gets information about memory usage
113- *
114- * @return array with memory usage data
109+ * @return array<string, int>
110+ * @psalm-return array{SwapTotal: int, SwapUsed: int, SwapPeak: int, SwapFree: int}
115111 */
116- public function memory ()
112+ private function getPageFileUsage (): array
117113 {
118- $ buffer = $ this ->getWMI (
119- 'Win32_OperatingSystem ' ,
120- [
121- 'TotalVisibleMemorySize ' ,
122- 'FreePhysicalMemory ' ,
123- ]
124- );
125- $ mem = [];
126- $ mem ['MemTotal ' ] = $ buffer [0 ]['TotalVisibleMemorySize ' ];
127- $ mem ['MemFree ' ] = $ buffer [0 ]['FreePhysicalMemory ' ];
128- $ mem ['MemUsed ' ] = $ mem ['MemTotal ' ] - $ mem ['MemFree ' ];
129-
130- $ buffer = $ this ->getWMI ('Win32_PageFileUsage ' );
131-
132- $ mem ['SwapTotal ' ] = 0 ;
133- $ mem ['SwapFree ' ] = 0 ;
134- $ mem ['SwapUsed ' ] = 0 ;
135- $ mem ['SwapPeak ' ] = 0 ;
136-
137- foreach ($ buffer as $ swapdevice ) {
138- $ mem ['SwapTotal ' ] += $ swapdevice ['AllocatedBaseSize ' ] * 1024 ;
139- $ mem ['SwapUsed ' ] += $ swapdevice ['CurrentUsage ' ] * 1024 ;
140- $ mem ['SwapPeak ' ] += $ swapdevice ['PeakUsage ' ] * 1024 ;
114+ if ($ this ->wmiService === null ) {
115+ return ['SwapTotal ' => 0 , 'SwapUsed ' => 0 , 'SwapPeak ' => 0 , 'SwapFree ' => 0 ];
116+ }
117+
118+ /**
119+ * @see https://docs.microsoft.com/en-us/windows/win32/wmisdk/swbemobject-instances-
120+ * @see https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-pagefileusage
121+ *
122+ * @var object[] $instances
123+ * @psalm-suppress MixedMethodCall
124+ * @phpstan-ignore-next-line
125+ */
126+ $ instances = $ this ->wmiService ->Get ('Win32_PageFileUsage ' )->Instances_ ();
127+ $ total = 0 ;
128+ $ used = 0 ;
129+ $ peak = 0 ;
130+ foreach ($ instances as $ instance ) {
131+ // phpcs:disable Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
132+ $ total += intval ($ instance ->AllocatedBaseSize ) * 1024 ; /* @phpstan-ignore-line */
133+ $ used += intval ($ instance ->CurrentUsage ) * 1024 ; /* @phpstan-ignore-line */
134+ $ peak += intval ($ instance ->PeakUsage ) * 1024 ; /* @phpstan-ignore-line */
135+ // phpcs:enable
141136 }
142137
143- $ mem ['SwapFree ' ] = $ mem ['SwapTotal ' ] - $ mem ['SwapUsed ' ];
138+ return ['SwapTotal ' => $ total , 'SwapUsed ' => $ used , 'SwapPeak ' => $ peak , 'SwapFree ' => $ total - $ used ];
139+ }
144140
145- return $ mem ;
141+ private function getLoadPercentage (): int
142+ {
143+ if ($ this ->wmiService === null ) {
144+ return 0 ;
145+ }
146+
147+ /**
148+ * @see https://docs.microsoft.com/en-us/windows/win32/wmisdk/swbemobject-instances-
149+ * @see https://docs.microsoft.com/en-us/windows/win32/cimwin32prov/win32-processor
150+ *
151+ * @var object[] $instances
152+ * @psalm-suppress MixedMethodCall
153+ * @phpstan-ignore-next-line
154+ */
155+ $ instances = $ this ->wmiService ->Get ('Win32_Processor ' )->Instances_ ();
156+ $ i = 0 ;
157+ $ sum = 0 ;
158+ foreach ($ instances as $ instance ) {
159+ // phpcs:ignore Squiz.NamingConventions.ValidVariableName.MemberNotCamelCaps
160+ $ sum += (int ) $ instance ->LoadPercentage ; /* @phpstan-ignore-line */
161+ // Can't use count($instances).
162+ $ i ++;
163+ }
164+
165+ try {
166+ return intdiv ($ sum , $ i );
167+ } catch (Throwable $ throwable ) {
168+ return 0 ;
169+ }
146170 }
147171}
0 commit comments