Unsolved Need to handle parsing these strings in PHP
-
So, a sometimes project I am working on for FreePBX systems needs to rip apart a string to put the values into columns.
Current GitHub on this: https://github.com/sorvani/freepbx-helper-scripts/tree/extensions_status/Extension_StatusInitial testing was only done with a couple Yealink phones. Now I want to make this actually a bit intelligent.
Here is a sample of the data going into the array. This was output with
var_dump
// The user agent contains information about the device. // Break it into pieces as Brand/Model/Firmware // TODO turn this into function to handle various formats /********** Examples ["UserAgent"]=> string(31) "Yealink SIP VP-T49G 51.80.0.100" ["UserAgent"]=> string(26) "Yealink SIP-T54W 96.85.0.5" ["UserAgent"]=> string(17) "Zoiper rv2.10.8.2" ["UserAgent"]=> string(26) "Grandstream HT802 1.0.17.5" ["UserAgent"]=> string(16) "snomPA1/8.7.3.19" ["UserAgent"]=> string(54) "LinphoneiOS/4.3.0 (Bob's iPhone) LinphoneSDK/4.4.0" ["UserAgent"]=> string(24) "OBIHAI/OBi202-3.2.2.5921" ["UserAgent"]=> string(15) "MicroSIP/3.20.5" **********/
Here is the initial quick code I used
$useragent = explode(' ',$data['UserAgent']); echo ' <td>' . $useragent[0] . '</td>' . "\n"; echo ' <td>' . $useragent[1] . '</td>' . "\n"; echo ' <td>' . $useragent[2] . ' ' . $useragent[3] . ' ' . $useragent[4] . ' ' . $useragent[5] . '</td>' . "\n";
It looks like this.
I think I should send
$useragent
to a function and have the function return the three pieces; Brand, Model, and Firmware.So far, the Brand is either split on a space or forward slash. This leads me to thinking I need to use
preg_split
. Wondering if there is a another choice I am unaware of.Once I have the brand, I was thinking to go into a
switch
based on brand and then break apart as needed per brand. Wondering about any opinions on that process as well. -
@JaredBusch said in Need to handle parsing these strings in PHP:
thinking I need to use
preg_split
So that idea seems like it will work.
<?php echo get_device_info("Yealink SIP VP-T49G 51.80.0.100") . "\n"; echo get_device_info("Yealink SIP-T54W 96.85.0.5") . "\n"; echo get_device_info("Zoiper rv2.10.8.2") . "\n"; echo get_device_info("Grandstream HT802 1.0.17.5") . "\n"; echo get_device_info("snomPA1/8.7.3.19") . "\n"; echo get_device_info("LinphoneiOS/4.3.0 (Bob's iPhone) LinphoneSDK/4.4.0") . "\n"; echo get_device_info("OBIHAI/OBi202-3.2.2.5921") . "\n"; echo get_device_info("MicroSIP/3.20.5") . "\n"; echo get_device_info("Fanvil X4U 1.0.0 0c383e42480e") . "\n"; // echo get_device_info("") . "\n"; function get_device_info($ua) { $ua_brand = preg_split("/[\s\/]/",$ua)[0]; $device_info = $ua_brand; return $device_info; // next step this becomes an array } ?>
-
And here is what it outputs now.
I think this is pretty solid. so if anyone has a better idea for how I could handle it better, I am wide open to suggestion.
<?php $ret_info = get_device_info("Yealink W52P 25.81.0.10"); print "Brand: {$ret_info['brand']} | Model: {$ret_info['model']} | Firmware: {$ret_info['firmware']}\n"; function get_device_info($ua) { $ua_arr = preg_split("/[\s\/]/", $ua, 2); switch ($ua_arr[0]) { case "Yealink": $mod_firm_arr = preg_split("/[\s]/", preg_replace("/^SIP[\s-]/","",$ua_arr[1])); $device_info = ["brand" => $ua_arr[0], "model" => $mod_firm_arr[0], "firmware" => $mod_firm_arr[1]]; break; case "Grandstream": case "OBIHAI": case "Fanvil": $mod_firm_arr = preg_split("/[\s-]/", $ua_arr[1]); $device_info = ["brand" => $ua_arr[0], "model" => $mod_firm_arr[0], "firmware" => $mod_firm_arr[1]]; break; case "Zoiper": case "MicroSIP": $device_info = ["brand" => $ua_arr[0], "model" => "", "firmware" => $ua_arr[1]]; break; case "snomPA1": $device_info = ["brand" => "Snom", "model" => "PA1", "firmware" => $ua_arr[1]]; break; case "LinphoneiOS": $mod_firm_arr = preg_split("/[\s]/", $ua_arr[1]); $device_info = ["brand" => $ua_arr[0], "model" => "", "firmware" => $mod_firm_arr[0]]; break; default: $device_info = ["brand" => "Unknown", "model" => "", "firmware" => ""]; } return $device_info; } ?>
-
Current version looks like this. Much improved.
-
If you're good with regular expressions you could use a loop of preg_replace instead and not hardcode the parsing in php. It would be more flexible and you could even put the regexp definitions in it's own file.
For instance with the expression | substitution: ^(Yealink)[^T]+(T[[0-9A-Z]*) ([0-9\.]+)$ | $1,$2,$3 ^snom(.*)\/([0-9\.]+)$ | Snom,$1,$2 etc User agent is reformatted into: Yealink SIP-T54W 96.85.0.5 => Yealink,T54W,96.85.0.5 Yealink SIP VP-T49G 51.80.0.100 => Yealink,T49G,51.80.0.100 snomPA1/8.7.3.19 => Snom,PA1,8.7.3.19"
It's just easier to keep the result in a string and then separate it when you need it. You could use
/
or tab or whatever as a separator. Then you useexplode
if you want an array. In many cases it better to put the result into variables instead:// User agent has been formatted into $s $s='Snom,PA1,8.7.3.19'; // we put the result in variables list($brand, $model, $firmware) = explode(',', $s); // print the results print "Brand: $brand | Model: $model | Firmware: $firmware\n";
Also be very careful when you're programming php and do not use
"
for strings unless you have variables or escaped characters inside the string that needs to be interpreted. Use'
as your go to for strings. For instance'test\r'
is not at all the same string as as"test\r"
. You got lucky in your sample script because"\s"
is an escape sequence in php but it's not a valid one so php didn't interpret it for you. But it's easy to run into conflicts between php and regular expressions when you encapsulate the strings with"
. -
@pete-s said in Need to handle parsing these strings in PHP:
If you're good with regular expressions
I'm adequate. Definitely not good.
-
@pete-s I've never claimed to be a real PHP dev. So this is good feedback.