Reputation: 3772
I would like to load a serviceprovider from my vendor folder. I actually added this vendor into my project
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
Upvotes: 3
Views: 6606
Reputation: 1374
First, please don't try to modify things under package folder (vendor
) unless you know what you are doing, it's generated and should not be included into VCS like git.
So put your service provider under app/Providers
and define it under App\Provider
namespace.
As for your PaypalServiceProvider
, it should be given a full class name as App\Providers\PaypalServiceProvider
and put in my_project/app/Providers
.
If you want to create a package, you should learn something about Composer (getcomposer.org) and Packagist (packagist.org)
Secondary, about why your PaypalServiceProvider
could not be found, you should learn something about PSR-4 (www.php-fig.org/psr/psr-4/).
Upvotes: 0
Reputation: 19285
If you place your service provider inside your vendor folder you have to tell laravel where it is, and, as you said, putting this line in your composer.json:
"psr-4": {
"App\\": "app/",
"PayPal\\": "vendor/paypal/rest-api-sdk-php/lib",
}
will do that.
Anyhow, Beware of putting your code in the vendor folder: this is a very bad practice, as the vendor folder is reserved for the external packages of the progect. You can, and should, consider putting your service provider inside your App Folder, i.e: App\Providers\PayPalServiceProvider.php
And set the namespace this way:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class PayPalServiceProvider extends ServiceProvider {
//...
}
This way in your app.php you could set:
App\Providers\PayPalServiceProvider::class,
without adding anything in your composer.json
file
Upvotes: 1
Reputation: 8415
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.
Upvotes: 2