Madzmar Ullang Madzmar Ullang - 1 month ago 19
PHP Question

How to Load custom Service Provider in Laravel

I would like to load a serviceprovider from my vendor folder. I actually added this vendor into my project

Learning Laravel PayPal SDK

Now under the folder structure

vendor/
- paypal/
- rest-api-sdk-php/
- config/
- paypal.php
- docs/
- lib/
- PayPal/
- PayPalConfigServiceProvider.php
- sample/
- test/
- composer.json


As you can see I added some items on the vendor. I added
config
folder and a config file under it namely
paypal.php
and also under lib folder I added
PayPalConfigServiceProvider.php


Full path of service provider is
my_project/vendor/paypal/rest-api-sdk-php/lib/PayPalConfigServiceProvider.php


Now I would like to add that PayPalConfigServiceProvider so that when I run composer update or something the PayPalConfigServiceProvider will copy a config file to
myproject\config
folder. So I added

'providers' => [
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
Illuminate\Html\HtmlServiceProvider::class,

PayPal\PayPalServiceProvider::class,
]


on config/app.php under the providers array. But now when I try to run php artisan I get this error

PHP Fatal error: Class 'PayPal\PayPalServiceProvider' not found in myproject/vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php


So I assumed that this has something to do with my composer.json on my root directory and this is the content of it

{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"license": "MIT",
"type": "project",
"require": {
"php": ">=5.5.9",
"laravel/framework": "5.1.*",
"illuminate/html": "^5.0",
"doctrine/dbal": "^2.5",
"paypal/rest-api-sdk-php": "*"
},
"require-dev": {
"fzaninotto/faker": "~1.4",
"mockery/mockery": "0.9.*",
"phpunit/phpunit": "~4.0",
"phpspec/phpspec": "~2.1"
},
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
"autoload-dev": {
"classmap": [
"tests/TestCase.php"
]
}
}


It seems the paypal is already included now I'm not sure what I need to add for it to be recognized. I just need my PayPalServiceProvider to be initialized so that this code will be run

PayPalServiceProvider.php

namespace PayPal;
use Illuminate\Support\ServiceProvider;

class PayPalServiceProvider extends ServiceProvider {

/**
* Register the service provider.
*
* @return void
*/
public function register()
{
// TODO: Implement register() method.

}

public function boot()
{
$this->mergeConfigFrom(__DIR__ . '../config/paypal.php', 'paypal');
}
}


I also checked the paypal vendor folder and checked its composer.json and here's the content

{
"name": "paypal/rest-api-sdk-php",
"description": "PayPal's PHP SDK for REST APIs",
"keywords": ["paypal", "payments", "rest", "sdk"],
"type": "library",
"license": "Apache2",
"homepage": "http://paypal.github.io/PayPal-PHP-SDK/",
"authors": [
{
"name": "PayPal",
"homepage": "https://github.com/paypal/rest-api-sdk-php/contributors"
}
],
"require": {
"php": ">=5.3.0",
"ext-curl": "*",
"ext-json": "*"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"autoload": {
"psr-0": {
"PayPal": "lib/"
}
}
}


I know I can always add something like this on the composer.json on my root directory

"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"PayPal\\": "vendor/paypal/rest-api-sdk-php/lib",
}
}


And this will work when I run composer dumpautoload. But I don't want this kind of approach I see many libraries but non of them did something like this. Is there any approach where I can load my serviceprovider without adding an entry on my autoload under my composer.json on root directory? Its ok if I'll add something on the composer.json of the vendor folder. But how will I accomplish this? please help on this. Thanks

Answer

You should not add files into the package folder.

You can move your config files into the config folder and move your Paypal service provider (I think you write it by yourself) to the app/Providers folder and use your application namespace for that class.

However, if you still want to load your created class from the lib folder (again, I do not recommend to do that), put your service provider class into the lib/Paypal instead of lib. The reason is this class use PSR-0 class loading standard, you can see a clear explanation about the different between PSR-0 and PSR-4 in this answer on Stack Overflow.