简体   繁体   中英

My PHP foreach commands only act on the last item of the array!

I'm taking the input from a text field, turning each line into a value in an array, and then using a foreach loop to run a search and replace on each value. Code is as follows:

$countryinp = trim($_POST['country']);
$countryinp = explode("\n", $countryinp);
$countryinp = array_filter($countryinp, 'trim');
foreach($countryinp as $code)
{
$country = '';
if( $code == 'Afghanistan' ) $country = 'AF';
if( $code == 'Aland Islands' ) $country = 'AX';
if( $code == 'Albania' ) $country = 'AL';
if( $code == 'Algeria' ) $country = 'DZ';
...
if( $country == '') $country = $code;
echo "$country";
echo "<br />";
unset($code);
}

The code will loop and output a list of all the inputs, but it only sets $country to a two letter code for the last line of the input! I'm going crazy, anyone seen this before?

Try something like this...

foreach($countryinp as $code)
{
$code = trim($code);
    switch($code){
        case "Afganistan": $country = "AF"; break;
        case "Alanad Islands": $country = "AX"; break;
        default: $country = $code;
    }

    echo $country."<br />";
}

And make sure your data exists...

What problem are you having exactly? You say that it only sets $country to a two-letter code for the last line, but is it printing out all of the codes before that?

This should be obvious, but if you're only having problems with the value of $country after the loop finishes, then you should realize that the $country variable is overwritten on each iteration of the loop, and would therefore only hold the value from the last iteration when the loop finishes.

If the problem is that your loop isn't printing each code, then that sounds like it's a data problem, and you would need to show us the values in your array in order to determine the problem.

One possible data problem you may have is this line:

$countryinp = array_filter($countryinp, 'trim');

I think your intent with this line is to apply the trim function to each element in the array, but that's not what array_filter does. The function of array_filter is to pass each element in an array to a callback function. That function examines the contents of the element, then returns true if the contents should be kept, or false if that element should be filtered out of the array.

When you pass trim to array_filter , the only thing that happens is that any array element which is empty, or only contains whitespace, will be removed. This is because after such elements are trimmed, they are empty. PHP interprets an empty string as false and removes it from the array.

This could cause issues with your if statements, because if $code contains, for example, "Afghanistan " (note the trailing space), then it wouldn't get caught by the if statement as the strings wouldn't match.

You would be much better off simply running the line $code = trim($code); at the beginning of your foreach loop.

Also, your code is a little bit ugly to me. If you're just going to check the same variable over and over (ie repeated if ($code == 'Value') statements), then you should really be using a switch statement instead:

switch ($code) {
    case "Afghanistan":
        $country = 'AF';
        break;
    case "Aland Islands":
        $country ='AX';
        break;
    // repeat for other cases
    default:
        $country = $code;
}

You can too many logical issues with this piece of code

foreach($countryinp as $code) // #1
{
$country = ''; // #2
if( $code == 'Afghanistan' ) $country = 'AF'; // #3
if( $code == 'Aland Islands' ) $country = 'AX';
if( $code == 'Albania' ) $country = 'AL';
if( $code == 'Algeria' ) $country = 'DZ';
...
if( $country == '') $country = $code; #4
echo "$country";
echo "<br />";
unset($code); // #5
}
  1. $code is variable visible in foreach scope, assigned with value of next($countryinp) (pointer to next element in array)

  2. $country is reset to '' (empty value) on each iteration (you are resetting $country value)

  3. $code == 'xxxx' - here you can use switch() statement, two benefits: 1) expression is evaluated only once then matched against 'case' and 2) maintainability (if you have to change something in your code... Better solution would be to simply have array with country name as key and country code as value, then you can directly access the country code like this $countryCodes[$countryName];

  4. Here you assign current country $code to $country only if $country is empty but as mantioned in #2 you are resetting $country value on each iteraction

  5. Here you unset the value of $code and this is not necessary, $code is only visible inside foreach() and automatically unset when your code exists the foreach loop.

Hope that helps. :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM