Phil Cross
Phil Cross

Reputation: 9302

PHP unusual bug with debug_print_backtrace

On my site, users can create pages, and assign collaborators. In my Page object, I store the collaborators as User objects in an array.

I also have a method called collaborators which accepts numerous different parameter types in order to manipulate the collaborators. For instance, if null is passed, it returns the existing collaborators. If an array is passed, it adds each user in the array to the array of collaborators.

This is my collaborators method:

public function collaborators($user = null)
{
    if(is_null($this->collaborators) || $user === true){

        if($this->resource_id() === false){
            $this->collaborators = array();
        } else {
            $result = $this->db->query("
                /** This retrieves collaborator user IDs **/
            ", array(
                $this->resource_id()
            ));

            $this->collaborators = array();

            foreach($result->result() as $user){
                $this->collaborators[] = new User($user->global_user_id);
            }
        }
    }

    if(is_null($user)){
        return $this->collaborators;
    } else if(is_string($user)){
        if(User::is_valid_id($user)){
            $this->collaborators[] = new User($user);
        }
    } else if(is_array($user)){
        foreach($user as $u){
            if($u instanceof User){
                $this->collaborators[] = $u;
            } else if(User::is_valid_id($u)){
                $this->collaborators[] = new User($u);
            }
        }
    } else if($user instanceof User){
        $this->collaborators[] = $user;
    } else {

        var_dump($user);
        throw new InvalidParametersException();
    }

    return $this;
}

In my view, I use a foreach loop to loop through collaborators to output them:

foreach($page->collaborators() as $user){ /** do stuff **/ }

As you can see in the collaborator method, if the object collaborator property is null, it retrieves data from the database. All subsequent calls to collaborators() retrieves the array from the collaborators property.

I have 2 problems:

I'm getting the following backtrace in my view:

object(stdClass)#529 (1) { ["global_user_id"]=> string(36) "8c9752fe-40d0-4259-bfe7-a5dcea7cbdfa" } 

Fatal error: Uncaught exception 'InvalidParametersException' with message 'There was an error while trying to process your request. Please try again later.' in application/libraries/objects/MinisiteResource.php:423 

Stack trace: 
#0 application/views/department_site/page.php(153): MinisiteResource->collaborators()
#1 system/core/Loader.php(833): include('/...') 
#2 system/core/Loader.php(419): CI_Loader->_ci_load(Array) 
#3 application/libraries/Pages.php(98): CI_Loader->view('department_site...', Array) 
#4 application/controllers/department/minisite.php(574): Pages->build_page('department_site...', Array) 
#5 [internal function]: Minisite->pages('8', '40') 
#6 system/core/CodeIgniter.php(359): call_user_func_array(Array, Array) 
#7 /v in application/libraries/objects/MinisiteResource.php on line 423

This backtrace does't make sense. You can see #0 is calling MinisiteResource->collaborators(). This defaults to a null parameter, so should return an array from the collaborators() method. However, for some reason its actually being passed an stdClass object from somewhere.

Now I want to know where this stdClass object is coming from, and this is my second problem

I add an extra line of code, to catch stdClass objects:

} else if($user instanceof stdClass) { echo 'Testing'; debug_print_backtrace(); exit; }

However, when I run this code, my page goes blank. I know for a fact that this segment of code IS running, but debug_print_backtrace() is failing. If I remove the debug_print_backtrace() call, I get 'Testing' outputted.

Obviously, if I can find out where the stdClass is being injected into the method, I can work out all my problems. But the main problem is debug_print_backtrace() is outputting nothing, and I can't rely on the Exception trace because for some reason it's not reliable.

Why would debug_print_backtrace() not display anything? There's definately enough method calls up to this point which should output at least something

If you need any further information, please let me know.

Upvotes: 0

Views: 155

Answers (1)

Eternal1
Eternal1

Reputation: 5625

Your problem is here:

foreach($result->result() as $user){
   $this->collaborators[] = new User($user->global_user_id);
}

After foreach is done $user still hangs in memory, and it is a proper stdClass. Just rename it to something else and you're fine.

Upvotes: 2

Related Questions