2

With PHP 7.2, each is deprecated. The documentation says:

Warning This function has been DEPRECATED as of PHP 7.2.0. Relying on this function is highly discouraged.

How can I update my code to avoid using it? Here are some examples:

  1. while ($x = each($y) {

  2. while (($x = each($y)) && ($a = each($b))) {

I believe I need to use foreach in these cases, but I am not sure how to properly do it. I already checked many examples on stackoverflow and other sites, but none of the examples is constructed like the above 2.

EDIT I am looking for, if at all possible, a universal drop-in code replacement (one-line or a few lines of code only) for these while one-lines, that will not require a complete script/application rewrite due to the changes of the above.

Thank you

Nikita 웃
  • 2,042
  • 20
  • 45
  • Can you go more in depth what are you trying to accomplish – Frosty Jul 13 '18 at 18:33
  • You could try `foreach ($y as $x) {...}` for your first example. The second example involves iterating over two arrays at once, so you'll need to learn about array pointers. (for example, PHP's `next` function) – RToyo Jul 13 '18 at 18:33
  • 1
    At first glance this seems simple but it's unraveling to be quite challenging. In almost 10 years, never have I needed to loop two arrays at once. I would be interested to hear more about what you are trying to accomplish because it sounds like there should be an easier way; double `each()` seems like a band-aide for something rather than a design decision. However, I am going to assume that this code is not yours and you are simply looking for an identical replacement. – MonkeyZeus Jul 13 '18 at 18:37
  • 1
    If `$y` and `$b` use the same key you could do `foreach ($y as $key => $x) { $b[$key] ..` – user3783243 Jul 13 '18 at 18:38
  • Please clarify, do you need access to both keys and values inside of the loop? – MonkeyZeus Jul 13 '18 at 18:39
  • Thanks guys. @RToyo - Yeah, I thought so too about the first example but `foreach ($y as $x) {...}` didn't work. @MonkeyZeus you are right on the money. The code isn't mine and I am just looking for an identical replacement, but I am sure this can help many others in the very near future. :) – Nikita 웃 Jul 13 '18 at 18:40
  • I've been editing my solution and think I've finally posted some clean code so feel free to check it out. – MonkeyZeus Jul 13 '18 at 19:06
  • I am checking it out, the first scenario, but still no dice. If I edit my question and post here a part of the actual code, would that help? – Nikita 웃 Jul 13 '18 at 19:07
  • @MonkeyZeus Here is the full script: https://pastebin.com/7E8HxN9G – Nikita 웃 Jul 13 '18 at 19:12

2 Answers2

1

Here is one way to approach example #2:

<?php
$y = ['f','g','e'];  // 3 items
$b = ['b'=>'hi', 6]; // 2 items

// Get an indexed array of keys from both arrays
$y_keys = array_keys($y);
$b_keys = array_keys($b);

// Loop one of the keysets
foreach( $y_keys as $k=>$v )
{
    // Check the other keyset to see if it contains as many elements
    if(isset($b_keys[$k]))
    {
        $x = [ $v => $y[$v] ];
        $a = [ $b_keys[$k] => $b[$b_keys[$k]] ];

        // Freely use $x and $a moving forward

        var_dump($x, $a);
    }
    else
    {
        // stop looping because one array has more/less than the other
        break;
    }
}

Example #1 is much simpler:

<?php
$y = ['f','g','e'];  // 3 items

foreach( $y as $k=>$v )
{
    $x = [ $k => $v ];
}
MonkeyZeus
  • 20,375
  • 4
  • 36
  • 77
  • 1
    This is perfect for example 2 in isolation; but don't blindly copy/paste it if you are porting somebody else's code. Some legacy code could rely on the internal array pointer. E.g. it will be somewhere in the middle of the larger array after the `while(each...` loop. However it will not move when you use the replacement. https://3v4l.org/sen9t – jh1711 Jul 13 '18 at 19:14
1

I realize you are looking for a universal equivalent drop-in replacement for those 2 examples that will be PHP 7.2 compatible and I hope someone here will answer this (as this may help many people moving to php 7.2 and higher), but I do have the answer specific to your script example, which will at least help you in this specific case if not universally.

Full disclosure: I know and work with that specific script (on a PHP 7.2 server).

while (($ut = each($user_tracking)) && ($listed++ < CONFIG_USER_TRACKING_SESSION_LIMIT)) {

Should be changed to:

foreach ($user_tracking as $ut['value']) {
if ($listed++ >= CONFIG_USER_TRACKING_SESSION_LIMIT) {
  break;
}

Find:

while (($pu = each($ut['value']['last_page_url']))&&($du = each($ut['value']['page_desc']))) {

And change to:

foreach ($ut['last_page_url'] as $key => $pu) {
          $du = $ut['page_desc'][$key];

This does require a small code rewrite below, as we have changed the arrays to strings, but still get the data we need.

Find:

<tr bgcolor=ffffff> 
    <td class="dataTableContent" valign=top align="right"><?php echo date('H:i:s', $pu['key']); ?></td> 
    <td class="dataTableContent" nowrap valign=top align="left">&nbsp;<a href="<?php echo $pu['value']; ?>" target="_new"><?php if ($du['value']!=''){ echo $du['value'];} ?></a>&nbsp;</td> 
    <td class="dataTableContent" width=100% align="left"><a href="<?php echo $pu['value']; ?>" target="_new"><?php echo chunk_split($pu['value'],40,"<br>"); ?></a></td> 
</tr>

And change to:

<tr bgcolor=ffffff> 
    <td class="dataTableContent" valign=top align="right"><?php echo date('H:i:s', $key); ?></td> 
    <td class="dataTableContent" nowrap valign=top align="left">&nbsp;<a href="<?php echo $pu; ?>" target="_new"><?php if ($du!=''){ echo $du;} ?></a>&nbsp;</td> 
    <td class="dataTableContent" width=100% align="left"><a href="<?php echo $pu; ?>" target="_new"><?php echo chunk_split($pu,40,"<br>"); ?></a></td> 
</tr>

Hope this helps.

Annie Trubak
  • 331
  • 2
  • 5
  • 1
    Thanks a lot! Indeed these changes make the script php 7.2 compatible and working perfectly. Still hoping to get a universal equivalent that won't require script/application rewrites due to the removal of `each`. Thanks again! – Nikita 웃 Jul 14 '18 at 08:50