Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP pass by reference in recursive function not working

I have two functions that I'm using to add or remove slashes from a deeply nested object/array combo. The first "level" of the array is always an object, but some of its properties may be arrays or objects.

Here are my two functions:

function objSlash( &$obj, $add=true )
{
    foreach ( $obj as $key=>$field )
    {
        if ( is_object( $field ) )
            objSlash( $field, $add );
        else if ( is_array( $field ) )
            arrSlash( $field, $add );
        else if ( $add )
            $obj->$key = addslashes( $field );
        else
            $obj->$key = stripslashes( $field );
    }

    return;
}

function arrSlash( &$arr, $add=true )
{
    foreach ( $arr as $key=>$field )
    {
        if ( is_object( $field ) )
            objSlash( $field, $add );
        else if ( is_array( $field ) )
            arrSlash( $field, $add );
        else if ( $add )
            $arr[$key] = addslashes( $field );
        else
            $arr[$key] = stripslashes( $field );
    }

    return;
}

Being called like so:

objSlash( $obj, false );

However, the function does not strip the slashes from the nested array. The object passed into the function is like this:

stdClass Object
(
    [id] => 3
    [lines] => Array
        (
            [0] => Array
                (
                    [character] => Name
                    [dialogue] => Something including \"quotes\"
                )
        )
)

What have I done wrong? Somewhere along the line a reference is going missing...

like image 439
DisgruntledGoat Avatar asked Aug 01 '09 13:08

DisgruntledGoat


2 Answers

foreach uses a copy of the array/object and not the array/object itself:

Note: Unless the array is referenced, foreach operates on a copy of the specified array and not the array itself. foreach has some side effects on the array pointer. Don't rely on the array pointer during or after the foreach without resetting it.

So use either a reference:

foreach ($arr as $key => &$field) {
    // …
}

Or use the array element/object property itself like Kuroki Kaze suggested by using $arr[$key] instead of its copied value $field.

like image 59
Gumbo Avatar answered Sep 20 '22 15:09

Gumbo


foreach makes a copy of value, i suppose.

Try using objSlash( $arr[$key], $add ) intead of objSlash( $field, $add ) inside foreach.

like image 22
Kuroki Kaze Avatar answered Sep 24 '22 15:09

Kuroki Kaze