Search code examples
phparraysfunctionreference

Array.prototype.find() in PHP that returns reference


I'm trying to make a function that works like Array.prototype.find() in javascript but for PHP.

My array have that structure :

$array = [
     ["id" => 54, "type" => 5, "content" => [
          ["id" => 99, "type" => 516],
          ["id" => 88, "type" => 464],
          ["id" => 41, "type" => 845]]
     ],
     ["id" => 54, "type" => 55, "content"=> [
          ["id" => 54, "type" => 578],
          ["id" => 54, "type" => 354],
          ["id" => 75, "type" => 458]]
     ],
     ["id" => 65, "type" => 59, "content" => [
          ["id" => 87, "type" => 5454],
          ["id" => 65, "type" => 245],
          ["id" => 65, "type" => 24525]]
     ]
];

Then I created my function to search like in javascript :

function array_find($array, $function){
    foreach($array as $value){
        if($function($value)){
            return $value;
        }
    }
}
$id=54;
$type=55;
$mycontent = array_find(
    $array,
    function($foo) {
        global $id;
        global $type;
        return $foo["id"] == $id && $foo["type"] == $type;
    }
)["content"];

It's working. However i want the returned result to be a reference and not a value, so i can later add/remove elements inside of the returned array.

How can i do this?


Solution

  • I'll try to answer this question without completely abandoning your original code.

    If you want to be able return the reference for a qualifying row, then the only way that I can think of is to

    1. Convert your array of arrays to an array of objects,
    2. Add & to the function name declaration, and
    3. Use = & to declare the reference variable in the global scope.

    Adjusted Code: (Demo)

    function &getRowReference($array, $fn) {
        foreach ($array as $row) {
            if ($fn($row)) {
                return $row->content;
            }
        }
    }
    
    function qualifyingRow($row) {
        global $id;
        global $type;
        return $row->id == $id && $row->type == $type;
    }
    
    $id = 54;
    $type = 55;
    
    $array = [
        (object)[
            "id" => 54,
            "type" => 5,
            "content" => [
                ["id" => 99, "type" => 516],
                ["id" => 88, "type" => 464],
                ["id" => 41, "type" => 845]
            ]
        ],
        (object)[
            "id" => 54,
            "type" => 55,
            "content" => [
                ["id" => 54, "type" => 578],
                ["id" => 54, "type" => 354],
                ["id" => 75, "type" => 458]
            ]
        ],
        (object)[
            "id" => 65,
            "type" => 59,
            "content" => [
                ["id" => 87, "type" => 5454],
                ["id" => 65, "type" => 245],
                ["id" => 65, "type" => 24525]
            ]
        ]
    ];
    
    $ref = &getRowReference($array, 'qualifyingRow');
    
    $ref = 'this has been changed';
    
    var_export($array);
    

    I don't think that I would bother going to all this effort myself. I would probably leave the data structure in its original state, return the index of the qualifying row, then access, mutate, and store the data using the index.

    Here is a relevant page to offer some additional commentary and warning about returning references: Return by reference in PHP