Thelonias
Thelonias

Reputation: 2935

Is there another way than passing by reference to do what I want

I have the following data structure:

A Contract has an array projects, which can have X number of projects. Each Project has an array, subProjects, which contain the same Project type, so theoretically you could have an infinite tree of Project-SubProjects-Project...

Anyway, each project has a unique ID, and I need to search for a given project AND make a modification to that project, starting at the top level, and then store the changed contract back to my session. Currently, I'm doing it via a recursive function that returns a reference to the project it finds, but the more I'm searching, the more it seems people don't like PHP references. I'm not sure why, could someone explain the problems? Is there a better way to do what I want?

Some code:

// Get the associative array version of the contract (it's stored as JSON)
$contract = json_decode($contract, true);

if(array_key_exists('projects', $contract))
{
    $resultProject = &$this->findProject($contract['projects'], $projectId);

    if($resultProject)
    {
        $resultProject[$inputData['propertyName']] = $inputData['value'];

         \Session::put('workingContract', json_encode($contract));

        // return 200
    }
}

// Return 404

/**
 * Performs a depth-first search to find a project.
 *
 * @param array $projects
 * @param $projectId
 * @return null
 */
private function &findProject(array &$projects, $projectId)
{
    foreach($projects as &$project)
    {
        if($project['_id']['$id'] == $projectId)
        {
            return $project;
        }

        if(array_key_exists('subProjects', $project))
        {
            $result = &$this->findProject($project['subProjects'], $projectId);
            return $result;
        }
    }

    $null = null; // TODO: shitty hack for inability to return null when function returns a reference. Need to rethink use of references in general. Is there another way???
    return $null;
}

Upvotes: 4

Views: 68

Answers (1)

silkfire
silkfire

Reputation: 25935

Why not just create an array with all your projects (a flat array), indexed by ID. Let each Project object have an ->id property that you can refer to. Problem solved?

Also, if the Project doesn't exist in the flat array, I see absolutely no problem in returning null.

class Contract {
   private $projects_flat = array();

   ....

   private function get_project($id) {
      return (isset($this->projects_flat[$id]) ? $this->projects_flat[$id] : null)
   }
}

Upvotes: 1

Related Questions