4

Sorry for newbie question, but I cant find any example on how to actually use Service Providers (Laravel documentation shows only how to create them).

Since Laravel's paginator doesn't work with grouping, I want to create my own paginator service, but I dont know how to inject said service into controller. Forum controller throws me exception: Class App\Http\Controllers\CustomPaginator does not exist, but I thought that if I bind service class to service container, it can be resolved using custom name?

Here are the files:

app/Http/Controllers/For

<?php

namespace App\Http\Controllers;

use App\ForumModel;
use Illuminate\Http\Request;

class Forum extends Controller
{
    public function index($page = 1, CustomPaginator $paginator)
    {
        $topics = ForumModel::orderBy("sticky", "DESC")->orderBy("lastpost", "DESC");

        return view("forum", ["topics" => $topics]);
    }
}

app/Providers/CustomPaginatorServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class CustomPaginatorServiceProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind("CustomPaginator", CustomPaginatorServiceProvider::class);
    }

    public function a()
    {
        echo "It works!";
    }
}

Providers table in app config

'providers' => [

    /*
     * Laravel Framework Service Providers...
     */
    Illuminate\Auth\AuthServiceProvider::class,
    Illuminate\Broadcasting\BroadcastServiceProvider::class,
    Illuminate\Bus\BusServiceProvider::class,
    Illuminate\Cache\CacheServiceProvider::class,
    Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
    Illuminate\Cookie\CookieServiceProvider::class,
    Illuminate\Database\DatabaseServiceProvider::class,
    Illuminate\Encryption\EncryptionServiceProvider::class,
    Illuminate\Filesystem\FilesystemServiceProvider::class,
    Illuminate\Foundation\Providers\FoundationServiceProvider::class,
    Illuminate\Hashing\HashServiceProvider::class,
    Illuminate\Mail\MailServiceProvider::class,
    Illuminate\Notifications\NotificationServiceProvider::class,
    Illuminate\Pagination\PaginationServiceProvider::class,
    Illuminate\Pipeline\PipelineServiceProvider::class,
    Illuminate\Queue\QueueServiceProvider::class,
    Illuminate\Redis\RedisServiceProvider::class,
    Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
    Illuminate\Session\SessionServiceProvider::class,
    Illuminate\Translation\TranslationServiceProvider::class,
    Illuminate\Validation\ValidationServiceProvider::class,
    Illuminate\View\ViewServiceProvider::class,

    /*
     * Package Service Providers...
     */
    Laravel\Tinker\TinkerServiceProvider::class,

    /*
     * Application Service Providers...
     */
    App\Providers\AppServiceProvider::class,
    App\Providers\AuthServiceProvider::class,
    // App\Providers\BroadcastServiceProvider::class,
    App\Providers\EventServiceProvider::class,
    App\Providers\RouteServiceProvider::class,
    App\Providers\CustomPaginatorServiceProvider::class

],

1 Answers1

4

Don't bind CustomPaginatorServiceProvider inside CustomPaginatorServiceProvider

and bind an instance.

$this->app->bind('CustomPaginator', function () {
    return new Services\CustomPaginator();
});
  1. create service provider CustomPaginatorServiceProvider
  2. register service provider CustomPaginatorServiceProvider in app config
  3. create service CustomPaginator
  4. bind service CustomPaginator in CustomPaginatorServiceProvider

btw You can bind service CustomPaginator in AppServiceProvider instead of creating new service provider


config/app.php in alias array:

...
'CustomPaginator' => \App\Services\CustomPaginator::class,
...

inside controller action:

public function someAction(\CustomPaginator $paginator)
{
    dd($paginator);
}

And if you need to pass some data into CustomPaginator method __construct - just write this in ServiceProvider:

$this->app->bind(\App\Services\CustomPaginator::class, function () {
    return new \App\Services\CustomPaginator($firstParam, $secondParam, ...);
});
skido
  • 452
  • 1
  • 4
  • 11
  • After reading the documentation I was pretty sure that services are just methods of ServiceProvider class. Especially since there isn't a single word on how to create services, Is there any convention, or can I just smash any class I want into the provider? –  Jul 24 '17 at 10:09
  • 1
    @Yotsuya I store them in _app\Services_ ) – skido Jul 24 '17 at 10:23
  • Okay, so this is exactly what I did, I removed `CustomPaginatorServiceProvider` and bound my CustomPaginator in the `AppServiceProvider`. Now when I call it from `app()` helper, it works as intended (i use `app()->make("CustomPaginator")`; However, trying depedency injection with bound name throws me error `Class App\Http\Controllers\CustomPaginator does not exist`. What do I need to do so the service can be injected into my controller method? –  Jul 24 '17 at 10:27
  • Wish I could upvote you more. I also leared that I could achieve what I wanted by contracts, but the method you proposed works too. Thanks a lot! –  Jul 24 '17 at 11:16