在Laravel 4上使用非laravel包

Mat*_*nya 43 php package laravel laravel-4

是否可以在框架中包含一个不是专门为L4设计的软件包?如果是这样,它是如何完成的?我知道我需要将包添加到我将composer.json其添加到vendor文件夹中,但是我可以在providers数组中以某种方式注册它吗?还有其他必要步骤吗?

我想使用最初为Yii设计的Google结帐包

sto*_*pat 100

在Laravel 4中使用第三方作曲家包

当开发人员创建编写器包时,他们应该使用PSR-0或PSR-4标准映射自动加载.如果不是这种情况,则在Laravel应用程序中加载包时可能会出现问题.PSR-0标准是:

{
    "autoload": {
        "psr-0": { "Acme": "src/" }
    }
}
Run Code Online (Sandbox Code Playgroud)

和PSR-4标准:

{
    "autoload": {
         "psr-4": { "Acme\\": "src/" }
    }
}
Run Code Online (Sandbox Code Playgroud)

基本上上面是告诉作曲家在哪里寻找名称间隔文件的标准.如果您没有使用自己的名称空间,则无需配置其他任何名称空间.

情景1

Laravel中的PSR-0标准后续软件包(带有自动加载类映射)

这是一个简单的,例如我将使用facebook php sdk,可以找到:

https://packagist.org/packages/facebook/php-sdk

步骤1:

在composer.json文件中包含该包.

"require": {
    "laravel/framework": "4.0.*",
    "facebook/php-sdk": "dev-master"
}
Run Code Online (Sandbox Code Playgroud)

第2步:

run: composer update
Run Code Online (Sandbox Code Playgroud)

第3步:

因为facebook软件包使用了一个开箱即用的类映射,所以您可以立即开始使用该软件包.(以下代码示例直接来自普通视图.请保持逻辑与生产应用程序中的视图不同.)

$facebook = new Facebook(array(
    'appId'  => 'secret',
    'secret' => 'secret'
));
var_dump($facebook); // It works!
Run Code Online (Sandbox Code Playgroud)

情景2

对于这个例子,我将使用instagram php api的包装器.这里需要做一些调整来加载包.试一试吧!包裹可以在这里找到:

https://packagist.org/packages/fishmarket/instaphp

步骤1:

添加到作曲家.json

"require": {
    "laravel/framework": "4.0.*",
    "fishmarket/instaphp": "dev-master"
}
Run Code Online (Sandbox Code Playgroud)

然后你可以正常更新(作曲家更新)

接下来尝试像使用facebook软件包一样使用软件包.同样,这只是视图中的代码.

$instagramconfig = array(
    'client_id' => 'secret',
    'client_secret'=> 'secret',
    'access_token' => 'secret'
);

$api = Instaphp::Instance(null, $instagramconfig);                
var_dump($api); // Epic fail!
Run Code Online (Sandbox Code Playgroud)

如果您尝试上面的示例,您将收到此错误:

FatalErrorException: Error: Class 'Instaphp' not found in ...
Run Code Online (Sandbox Code Playgroud)

所以我们需要解决这个问题.要做到这一点,我们可以检查Instagram composer.json,它的自动加载不同于facebook php sdk.

"autoload": {
         "psr-0": { "Instaphp": "." }
    }
Run Code Online (Sandbox Code Playgroud)

与facebook composer.json相比:

"autoload": {
        "classmap": ["src"]
    }
Run Code Online (Sandbox Code Playgroud)

(Composer处理不同类型的自动加载,从文件和类映射到PSR.看看你的vendor/composer/文件夹,看看它是如何完成的.)

现在我们必须手动加载类.它很简单,只需添加它(控制器顶部,模型或视图):

use Instaphp\Instaphp;
Run Code Online (Sandbox Code Playgroud)

composer dump-autoload,它的工作原理!

step2(可选)

另一种方法是(如果你不想使用"use"语句,你可以简单地告诉作曲家直接从你的代码中查找文件.只需更改实例如下:

// reference the name-spaced class straight in the code
$api = Instaphp\Instaphp::Instance(null, $instagramconfig); 
var_dump($api); // It works
Run Code Online (Sandbox Code Playgroud)

但是我建议使用该use语句向其他开发人员(以及您未来的自己)明确说明程序中使用了哪些(外部)类/包.

情景3

在这里,我们使用内置在IOC容器中的Laravels来注册服务提供者.请注意,某些软件包可能不适合此方法.我将使用与场景2中相同的Instagram软件包.

又脏又脏

如果你不关心设计模式和服务提供者,你可以绑定一个这样的类:

App::bind('Instaphp', function($app)
{
    return new Instaphp\Instaphp;
});
Run Code Online (Sandbox Code Playgroud)

你这样解决它.

App::make('Instaphp');
Run Code Online (Sandbox Code Playgroud)

快速而肮脏的结局

如果你正在开发一个更大的项目,并且你使用了接口,那么你应该进一步抽象出绑定.

步骤1:

在app文件夹中创建一个文件夹,例如'providers'文件夹.

app/providers
Run Code Online (Sandbox Code Playgroud)

确保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
    ]

},
Run Code Online (Sandbox Code Playgroud)

现在在名为Instagram.php的新文件夹中创建一个File,并将其放入:

 <?php

    use Illuminate\Support\ServiceProvider;

    class InstagramServiceProvider extends ServiceProvider {

    public function register()
    {
        $this->app->bind('Instaphp', function()
        {
            return new Instaphp\Instaphp;
        });

    }

}
Run Code Online (Sandbox Code Playgroud)

现在再次运行composer dump-autoload,您可以使用该包.请注意,instagram包有一个final private function __construct(),这意味着您不能在原始类之外使用该包而不将构造方法更改为public.我不是说这是一个很好的做法,我建议使用方案2,在instagram包的情况下.

无论如何,在此之后您可以使用这样的包:

$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!
Run Code Online (Sandbox Code Playgroud)

  • 我们可以通过提供步骤#1,#3(稍微多一点)#5和#7的示例代码来更好地回答问题吗?以及$ this-> app-> bind的简要说明.我理解为#5和#7.听起来很愚蠢,我不能用它. (2认同)