Helper doesn't work with Controllers

Published 2 months ago by JJK

I've created myself a helper class called Perm that is meant to return user of current session (I know, I could use default auth/user, but that wouldn't be as much of a fun as creating one from scratch!)

..sadly, the created helper class only works inside a view, but doesn't work at all in controllers.. which kinda misses the point.

Whenever I'm trying to use it inside a controller, it pops:

"Class 'App\Http\Controllers\Perm' not found"

I would most appreciate any help.

HelperServiceProvider.php:

namespace App\Providers;

use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;

class HelperServiceProvider extends ServiceProvider
{
    public function boot()
    {
        //
    }

    public function register()
    {
        foreach( glob (app_path().'/Helpers/*.php' ) as $filename ) // register all helpers
        {
            require_once($filename);
        }
    }
}

Helpers/PermHelper.php:

use App\User;

class Perm
{
    public static function user()
    {
        if(!session('user_id')) return null;
        return User::find(session('user_id'));
    }
}

Portion of config/app.php, the 'providers' array:

// Custom
App\Providers\HelperServiceProvider::class,
Best Answer (As Selected By JJK)
Jaytee

You essentially have three options:

  1. Create a view composer. You will basically share a variable to all views that you define.

  2. Setup a Blade directive. Then you would use it such as @user @enduser

  3. Setup a Facade. But you'll still need to call it like MyFacade::user()

Dry7
Dry7
2 months ago (134,770 XP)

@JJK rename

class Perm

to

class PermHelper
Cronix
Cronix
2 months ago (168,860 XP)

Just add the directory to your composer.json file for PS4 autoloading. Not sure why you're doing this in code.

JJK

@Dry7 "Class 'App\Http\Controllers\PermHelper' not found"

JJK

@Cronix I did previously add it to autoload inside a 'file' array to no avail.

Dry7
Dry7
2 months ago (134,770 XP)

@JJK in PermHelper

namespace App\Helpers;

in controller

use App\Helpers\PermHelper;
JJK

@Dry7 That's kinda missing the point, considering I defined a helper so I don't have to 'use' it every time.

JJK

@Dry7 when I did what you said, it broke for views. What you are basically telling me to do is create a control inside 'Helpers' folder that works like a controller becasue it is a controller.

That's not what I'm aiming for.

Jaytee
Jaytee
2 months ago (101,055 XP)

You're best off making this a global function, rather than a class method. It means you don't need to import the class and/or instantiate it.

But to solve this case, you need to use the correct namespace. Your class should have a namespace equal to the directory structure of your app. So something like: namespace App\Helpers. Then to use the class, you do use App\Helpers\MyClassName.

Now, to create a global function, create a helpers.php file (or whatever you wish to call it) where ever you like.

Then you can do something like:

if (! function_exists('myFunctionName')) {
    function myFunctionName()
    {
         // logic here
     }
}

Then in your composer.json file, you will add it to be autoloaded:

"autoload": {
    "files": [
          "path/to/helpers.php" // "app/helpers.php" etc
     ]
}

Then run composer dump-autoload

Now you can use it like this, anywhere you want:

public function someRandomControllerMethod()
{
     $user = myFunctionName();
}
JJK

@Jaytee It's urgent for me to have a class helper rather than a single function. What is surprising to me is that as soon as I add 'namespace App\Helpers' to PermHelper.php, it stops working for the view - which I assume is because it's 'added' to a specific namespace - so using App\Helpers\PermHelper::user() rather than PermHelper fixes the issue.

So, maybe a different approach would solve this issue considering I can now use it fine in Controller (as long as I do the 'use' thing) and I can use it in a view using 'App\Helpers\Perm::user()'.

By different approach I mean - how can I force 'use App\Helpers' on all views, so I don't have to pass it as an instance in a variable?

Jaytee
Jaytee
2 months ago (101,055 XP)

Well to be completely honest, there is no point of having the helper that you have.

The point of Laravel is to provide all of this stuff for you, now based on your helper, you're just wanting the currently signed in user, so use Laravel's built in methods.

You're just making things harder for yourself, and making your code messier, which is never a good thing.

But if you still insist on creating your own methods because it's fun, then setup a view composer and bind it to a variable for your views.

JJK

@Jaytee It's more of a 'damn-I-removed-something-I-could-use-but-now-the-project-has-over-90k-lines-of-code' rather than 'it's fun' haha.

I'll definitely use the built in auth/user when I'll be remaking the website during winter break.

Anyways - how would I go about binding the class to all views so it's accessible via PermHelper::user()? Or perhaps should I create a facade?

Jaytee
Jaytee
2 months ago (101,055 XP)

You essentially have three options:

  1. Create a view composer. You will basically share a variable to all views that you define.

  2. Setup a Blade directive. Then you would use it such as @user @enduser

  3. Setup a Facade. But you'll still need to call it like MyFacade::user()

JJK

@Jaytee Yeah, but MyFacade::user() (ergo PermHelper::user()) was the goal all along Where can I look up the creation of facades? Including the 'inclusion' into views.

Thanks for being patient and helping me out btw.

Please sign in or create an account to participate in this conversation.