Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix pass by reference in php after upgrading to 5.6.x

I recently upgraded fom php 5.2 to 5.6 and there is some code I could not fix yet:

//Finds users with the same ip- or email-address
function find_related_users($user_id) {
    global $pdo;

    //print_R($pdo);

    //Let SQL do the magic!
    $sth = $pdo->prepare('CALL find_related_users(?)');
    $sth->execute(array($user_id));
    //print_R($sth);
    //Contains references to all users by id, to check if a user has already been processed
    $users_by_id = array(); 

    //Contains arrays of references to users by depth
    $users_by_depth = array();

    while ($row = $sth->fetchObject()) {
        //Create array for current depth, if not present
        if (!isset($users_by_depth[$row->depth])) 
            $users_by_depth[$row->depth] = array();

        //If the user is new
        if (!isset($users_by_id[$row->id])) {
            //Create user array
            $user = array(
                'id' => $row->id,
                'name' => $row->name,
                'email' => $row->email,
                'depth' => $row->depth,
                'adverts' => array()
            );

            //Add all users to depth array
            @array_push($users_by_depth[$row->depth], &$user);

            //Add references to all users to id array (necessary to check if the id has already been processed)
            $users_by_id[$row->id] = &$user;
        }
        //If user already exists
        else 
            $user = &$users_by_id[$row->id];

        //Add advert to user
        if ($row->advert_id != null)
            array_push($user['adverts'], array(
                'id' => $row->advert_id,
                'title' => $row->advert_title,
                'msgs' => $row->msgs,
                'url' => $row->url
            ));
        #print_r($user);
        //Unset $user variable !!! 
        //If this is missing, all references in the array point to the same user
        unset($user);
    }

    //Return users, grouped by depth
    return $users_by_depth;
}

If I simply remove the ampersand before the dollar sign, the function stops to work as intended. From other questions on stackoverflow I found that this is a call by reference and will brake for new php versions. However I could not find a solution yet.

Thank you for any help on how to update this code for php 5.6.x

like image 740
merlin Avatar asked Dec 04 '25 10:12

merlin


1 Answers

Your code was probably never working as you thought it was as you are suppressing the errors on your array_push() call. Note that only the first parameter of array_push() is passed by reference, the other values are always passed by value.

You should remove the error suppressor @ (never use that in your own code) and in this case you can also do:

$users_by_depth[$row->depth][] = &$user;
                            ^^ add an element just like `array_push`

Now your new value in your $users_by_depth will contain a reference to the $user variable.

like image 65
jeroen Avatar answered Dec 08 '25 14:12

jeroen



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!