Flynn February 2016

Trying to make string output an array in php

I'm running into an issue where I get a rather irregular string output from an RCON script on a server. When I send a command for returning players on a server, I get a string that looks like this:

rcon->get_players();

Players on server: [#] [IP Address]:[Port] [Ping] [GUID] [Name] -------------------------------------------------- 0 1.1.1.1:2 46 654321(OK) Player Name1 1 2.2.2.2:2 47 123456(OK) Player Name2 (2 players in total)

Here's what it looks like formatted if that helps:

Players on server: 
[#] [IP Address]:[Port] [Ping] [GUID] [Name] 
-------------------------------------------------- 
0 1.1.1.1:2 46 654321(OK) Player Name1 
1 2.2.2.2:2 47 123456(OK) Player Name2 
(2 players in total)

So the first 0 is their key id on the server (0-however many players), the second is their IP and PORT, the 47 is the ping, playerguid is their battleye guid, then their name inthe game, and then a total of the players returned.

However, it returns as one big string. I'm trying to figure out how to feed this into an array. So I get something like this:

array("id"=>"0", "Connection"=>"1.1.1.1:2", "ping"=>"46", "guid"=>"654321", "name"=>"Player Name1");

Any way I can achieve this, considering how irregular the output is? Having the headers in the string is throwing me off.

I followed Don't Panic's advice and it's close: UPDATED

echo "Player List:<br />";
$raw_players = $rcon->get_players();
$lines = explode("\n", $raw_players);
$end = count($lines)-1;
$keys = array('id','connection','ping','guid','name');
$regex = '/(\d+)\s+([\d\.\:]+)\s+(\d+)\s+(\d+)\(OK\)\s+(.+)/';
for ($i=3; $i < $end; $i++) {
    echo($lines[$i]);
    preg_match($regex, $lines[$i], $matches);
    unset($matches[0]);
    echo(var_dump($matches));
    $players[] = array_combine($keys, $matches);
}

And I get:


      

Answers


jstrieb February 2016

You could easily use the explode() function on the string using the spaces as delimiters. From there just only use the second half of the array.

Alternatively use explode(), but set a limit such that the final element in the array can then be broken up into a second array.


migg February 2016

I would use a regular expression on that, that looks like this:

(\d+) ([\d.:]+) (\d+) (\d+)\([^)]+\) (.*)

combined with preg_match_all in PHP like that:

preg_match_all('#(\d+) ([\d.:]+) (\d+) (\d+)\([^)]+\) (.*)#', $players, $matches);


Don't Panic February 2016

First, explode based on newlines to get an array of each line.

$lines = explode("\n", $string);

then you can construct a for loop excluding the header and footer like this:

$end = count($lines) - 1; // this will exclude the last line
for ($i=3; $i < $end; $i++) { // this will start at the fourth line

inside the loop, you can use explode again, with space as the delimiter, to get an array for every line.

$players[] = explode(' ', $lines[$i], 5);

This should work, because it looks like all the values at the beginning of each line do not have spaces. The third argument (5) will prevent the player name from being split on space (if it contains a space) because it restricts the size of the array generated by explode to 5 elements.

If you want the resulting array to have string keys, you can define an array of keys (before your loop):

$keys = array('id', 'connection', 'ping', 'guid', 'name');

And then use array_combine in your loop to create each player array.

$players[] = array_combine($keys, explode(' ', $lines[$i], 5));

With some new info about this string, it seems that some of the columns are separated by more than one space (and not the same number of spaces), so explode will not work for this. You can use a regular expression match in your loop instead.

$keys = array('id', 'connection', 'ping', 'guid', 'name');
$regex = '/(\d+)\s+([\d\.\:]+)\s+(\d+)\s+(\w+)\(OK\)\s+(.+)/';
for ($i=3; $i < $end; $i++) {
    preg_match($regex, $lines[$i], $matches);
    unset($matches[0]);
    $players[] = array_combine($keys, $matches);
}

The unset($matches[0]); is because the first element in the preg_match matches will be the entire string. Each of the subsequent values in $matches will be the

Post Status

Asked in February 2016
Viewed 2,819 times
Voted 11
Answered 3 times

Search




Leave an answer