preg_split to unknown number of list() elements

959 views Asked by At

I have a PHP script that I wrote probably 10 years ago. I don't remember what version PHP was on at the time but my script worked just fine without complaint from the interpreter. Now, I've had to move my scripts to a new web host and, under PHP 7.x, the interpreter complains loudly about a certain line of this script and I'm looking for an elegant way to get it to shut up.

The offending line is:-

list($degrees, $minutes, $seconds) = preg_split("/ /", $coord);

The $coord variable contains a GPS coordinate in one of three forms: "degrees minutes seconds", "degrees decimal-minutes", or "decimal-degrees". So, the preg_split() may return 1, 2, or 3 elements. If it returns only 1 or 2 elements, the interpreter complains loudly about the undefined references to $seconds and/or $minutes. I see that there is a LIMIT parameter that I could specify for preg_split() that gives it a maximum number of elements to return but there doesn't seem to be a complimentary parameter to tell it the MINIMUM number of elements to return. Any suggestions welcome.

Sample coords: '-97.74019' or '-97 44.411' or '-97 44 24.7'

4

There are 4 answers

0
cn007b On BEST ANSWER

Totally agree with Anant, but you can do it in bit more elegant way:

<?php

$coordArray = preg_split('/ /', $coord);
$degrees = $coordArray[0] ?? 0;
$minutes = $coordArray[1] ?? 0;
$seconds = $coordArray[2] ?? 0;
3
spinkus On

The line gives a E_NOTICE ("Notice: Undefined offset: X in Command line code on line 1"). You can either change the error reporting level to not include E_NOTICE or just hide disable the error reporting for this particular line with the @ operator. There is no harm in using @ here. Unmatched variables will be assigned NULL (in 5 and 7):

$coord = "x y";
@list($degrees, $minutes, $seconds) = preg_split("/ /", $coord);
var_dump($degrees, $minutes, $seconds);

Gives:

string(1) "x"
string(1) "y"
NULL

I wouldn't generally recommend it, but to suppress all E_NOTICE error notices, you can unset it in the error_reporting setting:

ini_set("error_reporting", E_ALL&~E_NOTICE);
0
Death-is-the-real-truth On

You can convert that code like below:-

$d_m_s_array = preg_split("/ /", $coord); 
$degrees = (!empty($d_m_s[0]) ? $d_m_s[0] :0;
$minutes = (!empty($d_m_s[1]) ? $d_m_s[1] :0;
$seconds = (!empty($d_m_s[2]) ? $d_m_s[2] :0;

Note:-

Also your original code will generate a notice only (if error reporting is on for that too). Look here:- https://eval.in/707979

It will not stop the program execution, but you can+have-to resolve this notice by the above code

0
Design.Garden On

Wrap the variably-sized array with array_pad as demonstrated below:

list($degrees, $minutes, $seconds) = array_pad( preg_split("/ /", $coord), 3, null);

Your intuition is right that you need a MINIMUM number of elements to return, and that is exactly what array_pad will do for you.