php 在 Laravel 4 上使用非 Laravel 包
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15190772/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Using a non-laravel package on Laravel 4
提问by Matanya
Is it possible to include a package that was not specifically designed for L4 in the framework?
If so, how is it done? I know I need to add the package to my composer.jsonwhich adds it to the vendorfolder, but can I register it somehow in the providersarray? are there any other steps necessary?
是否可以在框架中包含一个不是专门为 L4 设计的包?如果是这样,它是如何完成的?我知道我需要将包添加到 my 中composer.json,然后将其添加到vendor文件夹中,但是我可以在providers数组中以某种方式注册它吗?还有其他必要的步骤吗?
I would like to use the Google checkout packageoriginally designed for Yii
我想使用最初为 Yii 设计的Google checkout 包
回答by stormpat
Using third party composer packages with Laravel 4
在 Laravel 4 中使用第三方 Composer 包
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:
当开发人员创建 Composer 包时,他们应该使用 PSR-0 或 PSR-4 标准映射自动加载。如果不是这种情况,在 Laravel 应用程序中加载包可能会出现问题。PSR-0 标准是:
{
"autoload": {
"psr-0": { "Acme": "src/" }
}
}
And the PSR-4 standard:
和 PSR-4 标准:
{
"autoload": {
"psr-4": { "Acme\": "src/" }
}
}
Basically the above is a standard for telling composer where to look for name-spaced files. If you are not using your own namespaces you dont have to configure anything else.
基本上,上面是告诉作曲家在哪里寻找命名空间文件的标准。如果您不使用自己的命名空间,则不必配置任何其他内容。
SCENARIO 1
场景 1
PSR-0 standard following packages (with autoload classmap) in Laravel
Laravel 中的 PSR-0 标准跟随包(带有自动加载类映射)
This is a simple one, and for example i will use the facebook php sdk, that can be found:
这是一个简单的,例如我将使用 facebook php sdk,可以找到:
https://packagist.org/packages/facebook/php-sdk
https://packagist.org/packages/facebook/php-sdk
Step 1:
第1步:
Include the package in your composer.json file.
在 composer.json 文件中包含该包。
"require": {
"laravel/framework": "4.0.*",
"facebook/php-sdk": "dev-master"
}
Step 2:
第2步:
run: composer update
Step 3:
第 3 步:
Because the facebook package uses a class map its working out of the box, you can start using the package instantly. (The code example below comes straight from a normal view. Please keep your logic out from views in your production app.)
因为 facebook 包使用了一个开箱即用的类映射,所以您可以立即开始使用该包。(下面的代码示例直接来自普通视图。请让您的逻辑远离生产应用程序中的视图。)
$facebook = new Facebook(array(
'appId' => 'secret',
'secret' => 'secret'
));
var_dump($facebook); // It works!
SCENARIO 2
场景 2
For this example i will use a wrapper from the instagram php api. Here there need to be made some tweaks to get the package loaded. Lets give it a try! The package can be found here:
对于这个例子,我将使用来自 instagram php api 的包装器。这里需要进行一些调整才能加载包。试一试吧!该包可以在这里找到:
https://packagist.org/packages/fishmarket/instaphp
https://packagist.org/packages/fishmarket/instaphp
Step 1:
第1步:
Add to composer .json
添加到作曲家 .json
"require": {
"laravel/framework": "4.0.*",
"fishmarket/instaphp": "dev-master"
}
Then you can update normally (composer update)
然后就可以正常更新了(作曲家更新)
Next try to use the package like you did with the facebook package. Again, this is just code in a view.
接下来尝试像使用 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 ...
So we need to fix this issue. To do this we can examine the instagram composer.json, that has its autoload diffrent than the facebook php sdk had.
所以我们需要解决这个问题。为此,我们可以检查 instagram composer.json,它的自动加载与 facebook php sdk 不同。
"autoload": {
"psr-0": { "Instaphp": "." }
}
Compared to the facebook composer.json:
与 facebook composer.json 相比:
"autoload": {
"classmap": ["src"]
}
(Composer handles different kinds of autoloading, from files and class-maps to PSR. Take a look at your vendor/composer/folder to see how its done.)
(Composer 处理不同类型的自动加载,从文件和类映射到 PSR。看看你的vendor/composer/文件夹,看看它是如何完成的。)
Now we will have to load the class, manually. Its easy, just add this (top of your controller, model or view):
现在我们必须手动加载类。很简单,只需添加以下内容(在控制器、模型或视图的顶部):
use Instaphp\Instaphp;
composer dump-autoload, and it works!
composer dump-autoload,它有效!
step2 (optional)
步骤2(可选)
Another method is (if you dont want to use the "use" statement, you can simply tell composer to look for the files straight from your code. Just change the Instance like so:
另一种方法是(如果您不想使用“use”语句,您可以简单地告诉作曲家直接从您的代码中查找文件。只需像这样更改实例:
// 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 usestatement to make it clear to other developers (and your future self) what (external) classes/packages are used in the program.
但是,我建议使用该use语句向其他开发人员(以及您未来的自己)清楚说明程序中使用了哪些(外部)类/包。
SCENARIO 3
场景 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.
这里我们使用 Laravel 内置的 IOC 容器来注册服务提供者。请注意,某些软件包可能不适合这种方法。我将使用与场景 2 中相同的 Instagram 包。
Quick and dirty
又快又脏
If you don't care about design patterns and service providers you can bind a class like this:
如果你不关心设计模式和服务提供者,你可以像这样绑定一个类:
App::bind('Instaphp', function($app)
{
return new Instaphp\Instaphp;
});
And you resolve it like this.
然后你就这样解决了。
App::make('Instaphp');
Quick and dirty end
快速而肮脏的结局
If you're working on a bigger project, and you make use of interfaces you should probably abstract the bindings further.
如果您正在处理一个更大的项目,并且您使用接口,您可能应该进一步抽象绑定。
Step 1:
第1步:
Create a folder inside your app folder, for example a 'providers' folder.
在您的应用程序文件夹中创建一个文件夹,例如“providers”文件夹。
app/providers
Make sure Laravel auto-loads that folder, you can pass in some additional info to composer.json, like this:
确保 Laravel 自动加载该文件夹,您可以将一些附加信息传递给 composer.json,如下所示:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php",
"app/providers" // this was added
]
},
Now create a File inside the new folder called Instagram.php and place this inside:
现在在名为 Instagram.php 的新文件夹中创建一个文件并将其放入:
<?php
use Illuminate\Support\ServiceProvider;
class InstagramServiceProvider extends ServiceProvider {
public function register()
{
$this->app->bind('Instaphp', function()
{
return new Instaphp\Instaphp;
});
}
}
Now run composer dump-autoload again, and you can use the package. Note that the instagram package has a final private function __construct(), this means you cannot use that package outside the original class without changing the construct method to public. I'm not saying this is a good practice, and i suggest to use the scenario 2, in the case of the instagram package.
现在再次运行 composer dump-autoload,你就可以使用这个包了。请注意,instagram 包有一个final private function __construct(),这意味着您不能在原始类之外使用该包而不将构造方法更改为 public。我并不是说这是一个好习惯,我建议使用场景 2,对于 instagram 包。
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!
回答by conradkleinespel
Add "tvr/googlecheckout": "dev-master"this to your composer.json.
"tvr/googlecheckout": "dev-master"将此添加到您的composer.json.
Run composer install, then you can use the IoC container. Some code examples can be found in the official docs for Laravel 4: http://four.laravel.com/docs/ioc#basic-usage
运行composer install,然后就可以使用IoC容器了。一些代码示例可以在 Laravel 4 的官方文档中找到:http://four.laravel.com/docs/ioc#basic-usage

