Logan Bailey

Adventures In Web Development

Blog, About, GitHub, and LinkedIn

For most programmers who have looked at Laravel, they're pretty familiar with Auth::user() It's an easy way to retrieve the logged in user's object. The issue here is I'm now using an evil facade. To avoid this catastrophe, I started injecting the facade's corresponding class into the constructor and assigning the user as a property of the controller.

<?php 
class MyController {

    /** @var Acme\User\User; */ 
    protected $user; 

    function __construct(Illuminate\Auth\AuthManager $auth)
    {
        $this->user = $auth->user();
    }
    function myMethod()
    {
        // do something with $this->user
    }
}

If you're ever curious what the corresponding class is for a Facade, there's a [http://laravel.com/docs/facades#facade-class-reference](list on the Laravel website)

This works, but my controller shouldn't have AuthManager as a dependency when it really only needs User. But how can I inject the logged in user? I was able to use Laravel's container bindings. First, I created an interface for the session user.

<?php namespace Acme\User; interface SessionUser { }

I then updated the User model to implement this interface.

<?php namespace Acme\User;

class User extends \Eloquent implements SessionUser
{
	// your code here
}

Then created a provider which bound Acme\User\SessionUser to the result of Auth::user().

<?php namespace Acme\User;

class SessionUserServiceProvider extends \Illuminate\Support\ServiceProvider {
	protected $defer = true;
	
	public function provides()
	{
		return ['Acme\User\SessionUser'];
	}
	
	public function register()
	{
		$this->app->bind('Acme\User\SessionUser', function() { 
			$auth = $this->app->make('auth'); 
			if (!$user = $auth->user()) { 
				throw new \Exception; 
			}
			
			return $user;
		}); 
	}
}

Finally, I was able to inject the logged in User object.

<?php 
class MyController
{
	/** @var Acme\User\User; */
	protected $user;
	
	function __construct(Acme\User\SessionUser $user)
	{
		$this->user = $user;
	}

	function myMethod()
	{
		// do something with $this->user
	}
}

The drawback to this method is now all routes that correspond to methods in this controller must require the user to be logged in. You should either add the auth filter to any of these routes or rework the service provider to throw a custom exception. Then add an exception handler for the service provider's exception. If you're interested in trying this out, you can find it on packagist.

Posted In:
php Web Development