Attempt to assign property of non-object - Laravel 5.2

scrfix picture scrfix · Jan 28, 2016 · Viewed 8.3k times · Source

Issue: Converting my Laravel 4 code to Laravel 5.2. I'm at the point of moving and converting my views and cannot get past the following error.

Error: ErrorException in IndexController.php line 27: Attempt to assign property of non-object

Debug Information:

  1. in IndexController.php line 27
  2. at HandleExceptions->handleError('2', 'Attempt to assign property of non-object', 'C:\Apache24\B2B_Contracts\app\Http\Controllers\IndexController.php', '27', array('numberofpcs' => object(additionalPCs), 'addtpcs' => array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23', '24', '25', '26', '27', '28', '29', '30', '31', '32', '33', '34', '35', '36', '37', '38', '39', '40', '41', '42', '43', '44', '45', '46', '47', '48', '49', '50', '51', '52', '53', '54', '55', '56', '57', '58', '59', '60', '61', '62', '63', '64', '65', '66', '67', '68', '69', '70', '71', '72', '73', '74', '75', '76', '77', '78', '79', '80', '81', '82', '83', '84', '85', '86', '87', '88', '89', '90', '91', '92', '93', '94', '95', '96', '97', '98', '99', '100'))) in IndexController.php line 27
  3. at IndexController->index()

Request: Please assist in figuring out why the error comes up and please explain in detail how to prevent it and what I am doing wrong with example, if possible.

Notes: I used to receive a similar error on Laravel 4 after I would seed the database but I was able to refresh the migrations and reseed the database and everything would start working again. This does not work with this error in Laravel 5. This code works on L4.

Attempts: I have been reading a lot on Google and have tried various items such as php artisan clear-compiled, composer dump-autoload, php artisan optimize to no avail. I believe the error is coming from $numberofpcs = new additionalPCs(); however I have not been able to confirm that. I have also removed all of the variables I am sending to the view and the error still persisted so it looked like $this->layout->content = View::make('index');

IndexController.php

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Library\additionalPCs;
use App\Http\Requests;
use App\Http\Controllers\Controller;
use View;
use App\Models\businesstype;
use App\Models\contractterm;


class IndexController extends BaseController
{
    Protected $layout = 'master';
    /**
     * Display a listing of the resource.
     *
     * @return Response
     */
    public function index()
    {
        /** Wayne - 03-02-2014 - Moved for loop to a method within its own class. */
        $numberofpcs = new additionalPCs();
        $addtpcs=$numberofpcs->display();
        $this->layout->content = View::make('index')->with('addtpcs', $addtpcs)->with('businesstypelist', businesstype::dropdown())->with('contracttermlist',ContractTerm::dropdown());
    }
}

additionalPCs.php

<?php
namespace App\Library;

use App\Library\additionalComputer;

class additionalPCs extends additionalComputer {
    public function display() {
        return $this->displayMenu();    
    }
}

additionalComputer.php

<?php
namespace App\Library;
/** Counts up the Number of Additional PC Options
* and stores them into an array then sends them to the view.
*/
    class additionalComputer {
        protected function displayMenu() {
            $addtpcs= [];
            for ($i=0; $i <= 100; $i++) {
            $addtpcs[$i] = $i;
            }
        return $addtpcs;
        }

    }

BaseController.php - (This is only here to show that I do have a BaseController.php file for the IndexController. I'm aware that L5 doesn't come with one by default.)

<?php
namespace App\Http\Controllers;

class BaseController extends Controller {

    /**
     * Setup the layout used by the controller.
     *
     * @return void
     */
    protected function setupLayout()
    {
        if ( ! is_null($this->layout))
        {
            $this->layout = View::make($this->layout);
        }
    }

}

Answer

patricus picture patricus · Jan 28, 2016

The controller layout functionality was removed in Laravel 5. Because of this, the setupLayout() method is not getting called, meaning your layout property is staying as just the string 'master'. Since it is just a string, when you do $this->layout->content = ..., you're attempting to assign a property of a non-object.

I believe you should be able to add this back in if you want. In your BaseController, you will need to override the callAction method to the way it used to be:

public function callAction($method, $parameters)
{
    $this->setupLayout();

    $response = call_user_func_array(array($this, $method), $parameters);

    // If no response is returned from the controller action and a layout is being
    // used we will assume we want to just return the layout view as any nested
    // views were probably bound on this view during this controller actions.

    if (is_null($response) && ! is_null($this->layout)) {
        $response = $this->layout;
    }

    return $response;
}