99namespace RobiNN \Pca \Dashboards \Memcached ;
1010
1111use function explode ;
12- use function fgets ;
1312use function is_numeric ;
13+ use function preg_match ;
14+ use function preg_replace ;
15+ use function str_contains ;
1416use function str_ends_with ;
17+ use function str_starts_with ;
18+ use function substr_count ;
1519
1620class PHPMem {
1721 public const VERSION = '2.0.1 ' ;
@@ -21,6 +25,8 @@ class PHPMem {
2125 */
2226 private $ stream ;
2327
28+ private ?string $ server_version = null ;
29+
2430 /**
2531 * @param array<string, int|string> $server
2632 */
@@ -206,11 +212,20 @@ public function getKeys(): array {
206212 */
207213 public function parseLine (string $ line ): array {
208214 $ data = [];
209-
210- foreach (explode (' ' , $ line ) as $ part ) {
211- if ($ part !== '' ) {
212- [$ key , $ val ] = explode ('= ' , $ part );
213- $ data [$ key ] = is_numeric ($ val ) ? (int ) $ val : $ val ;
215+ if (preg_match_all ('/(\w+)=(\S+)/ ' , $ line , $ matches , PREG_SET_ORDER )) {
216+ foreach ($ matches as [, $ key , $ val ]) {
217+ switch ($ key ) {
218+ case 'key ' :
219+ $ data ['key ' ] = $ val ;
220+ break ;
221+ case 'exp ' :
222+ $ data ['exp ' ] = ($ val === '-1 ' ) ? -1 : (int ) $ val ;
223+ break ;
224+ case 'la ' :
225+ case 'size ' :
226+ $ data [$ key ] = (int ) $ val ;
227+ break ;
228+ }
214229 }
215230 }
216231
@@ -281,7 +296,13 @@ public function exists(string $key): bool {
281296 * @throws MemcachedException
282297 */
283298 public function version (): string {
284- return str_replace ('VERSION ' , '' , $ this ->runCommand ('version ' ));
299+ if ($ this ->server_version !== null ) {
300+ return $ this ->server_version ;
301+ }
302+
303+ $ this ->server_version = str_replace ('VERSION ' , '' , $ this ->runCommand ('version ' ));
304+
305+ return $ this ->server_version ;
285306 }
286307
287308 /**
@@ -300,6 +321,7 @@ private function connect(): void {
300321 }
301322
302323 stream_set_timeout ($ stream , 1 );
324+ stream_set_blocking ($ stream , false );
303325 $ this ->stream = $ stream ;
304326 }
305327
@@ -377,18 +399,28 @@ private function streamConnection(string $command, string $command_name): string
377399 $ this ->connect ();
378400 }
379401
402+ stream_set_blocking ($ this ->stream , true );
380403 fwrite ($ this ->stream , $ command );
404+ stream_set_blocking ($ this ->stream , false );
381405
382406 $ buffer = '' ;
407+ $ start = microtime (true );
383408
384- while (! feof ( $ this -> stream ) ) {
385- $ line = fgets ($ this ->stream , 4096 );
409+ while (microtime ( true ) - $ start < 5 ) {
410+ $ chunk = fread ($ this ->stream , 65536 );
386411
387- if ($ line === false ) {
388- break ;
412+ if ($ chunk === false ) {
413+ continue ;
414+ }
415+
416+ if ($ chunk === '' ) {
417+ if ($ this ->checkCommandEnd ($ buffer )) {
418+ break ;
419+ }
420+ continue ;
389421 }
390422
391- $ buffer .= $ line ;
423+ $ buffer .= $ chunk ;
392424
393425 // Commands without a specific end string.
394426 if ($ command_name === 'incr ' || $ command_name === 'decr ' || $ command_name === 'version ' ||
0 commit comments