是否可以在框架中包含一个不是专门为L4设计的包?
I would like to use the Google checkout package originally designed for Yii
是否可以在框架中包含一个不是专门为L4设计的包?
I would like to use the Google checkout package originally designed for Yii
Using third party composer packages with Laravel 4
When developers create composer packages, they should map the auto-loading using PSR-0 or PSR-4 standards. If this is not the case there can be issues loading the package in your Laravel application. The PSR-0 standard is:
{
"autoload": {
"psr-0": { "Acme": "src/" }
}
}
And the PSR-4 standard:
{
"autoload": {
"psr-4": { "Acme\\": "src/" }
}
}
基本上,以上是告诉composer 在哪里查找名称间隔文件的标准.如果您不使用自己的名称空间,则无需配置任何其他内容.
SCENARIO 1
PSR-0 standard following packages (with autoload classmap) in Laravel
这是一个简单的例子,我将使用facebook php sdk,可以找到:
https://packagist.org/packages/facebook/php-sdk
Step 1:
Include the package in your composer.json file.
"require": {
"laravel/framework": "4.0.*",
"facebook/php-sdk": "dev-master"
}
Step 2:个
run: composer update
Step 3:
由于facebook软件包使用了一个类映射,因此您可以立即开始使用该软件包.(下面的代码示例直接来自普通视图.请将您的逻辑排除在生产应用程序的视图之外.)
$facebook = new Facebook(array(
'appId' => 'secret',
'secret' => 'secret'
));
var_dump($facebook); // It works!
SCENARIO 2
在本例中,我将使用instagram php api中的包装器.这里需要做一些调整来加载包.让我们试一试!
https://packagist.org/packages/fishmarket/instaphp
Step 1:
添加到composer .json
"require": {
"laravel/framework": "4.0.*",
"fishmarket/instaphp": "dev-master"
}
Then you can update normally (composer update)
接下来,试着像使用facebook软件包一样使用该软件包.同样,这只是视图中的代码.
$instagramconfig = array(
'client_id' => 'secret',
'client_secret'=> 'secret',
'access_token' => 'secret'
);
$api = Instaphp::Instance(null, $instagramconfig);
var_dump($api); // Epic fail!
If you try the above example you will get this error:
FatalErrorException: Error: Class 'Instaphp' not found in ...
所以我们需要解决这个问题.为此,我们可以查看instagramcomposer .json的自动加载功能与facebook php sdk不同.
"autoload": {
"psr-0": { "Instaphp": "." }
}
Compared to the facebook composer.json:
"autoload": {
"classmap": ["src"]
}
(Composer处理不同类型的自动加载,从文件和类映射到PSR.看看你的vendor/composer/
文件夹,看看它是怎么做的.)
现在我们必须手动加载该类.很简单,只需添加以下内容(位于控制器、模型或视图的顶部):
use Instaphp\Instaphp;
composer dump-autoload, and it works!
step2 (optional)个
另一种方法是(如果你不想使用"use"语句,你可以简单地告诉composer直接从你的代码中查找文件
// reference the name-spaced class straight in the code
$api = Instaphp\Instaphp::Instance(null, $instagramconfig);
var_dump($api); // It works
However I suggest using the use
statement to make it clear to other developers (and your future self) what (external) classes/packages are used in the program.
SCENARIO 3
Here we use the Laravels built in IOC container to register service providers. Please note that some packages might not be suitable for this method. I will use the same Instagram package as in scenario 2.
Quick and dirty
如果您不关心设计模式和服务提供者,您可以像这样绑定一个类:
App::bind('Instaphp', function($app)
{
return new Instaphp\Instaphp;
});
And you resolve it like this.
App::make('Instaphp');
Quick and dirty end
如果您正在处理一个更大的项目,并且使用了接口,那么您可能应该进一步抽象绑定.
Step 1:
Create a folder inside your app folder, for example a 'providers' folder.
app/providers
Make sure Laravel auto-loads that folder, you can pass in some additional info to composer.json, like this:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/providers" // this was added
]
},
现在在名为Instagram的新文件夹中创建一个文件.php并将其放入:
<?php
use Illuminate\Support\ServiceProvider;
class InstagramServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('Instaphp', function()
{
return new Instaphp\Instaphp;
});
}
}
现在再次运行composer dump autoload,就可以使用这个包了.请注意,instagram包的值为final private function __construct()
,这意味着如果不将构造方法更改为public,就不能在原始类之外使用该包.我并不是说这是一个好的实践,我建议在instagram软件包中使用场景2.
Anyway, after this you can use the package like this:
$instagramInstance = App::make('Instaphp');
$instagramconfig = array(
'client_id' => 'secret',
'client_secret'=> 'secret',
'access_token' => 'secret'
);
$instagram = new $instagramInstance();
$userfeed = $instagram->Users->feed($instagramconfig);
var_dump($userfeed); // It works!