如何创建全局对象Laravel

时间:2018-05-14 18:15:41

标签: php laravel instagram-api

我正在使用 Laravel 5.6 Instagram API library

要使用此Instagram API,我需要创建对象$ig = new \InstagramAPI\Instagram()。然后,为了获取任何用户的信息,我每次都必须使用$ig->login('username', 'password')

所以我不想一直使用这个功能。第一个我想创建一个包含$ig = new \InstagramAPI\Instagram()的全局变量。但是,我不知道如何正确地做到这一点。

  • 我尝试使用singleton

    $this->app->singleton(Instagram::class, function ($app) {
        Instagram::$allowDangerousWebUsageAtMyOwnRisk = true; // As wiki says
        return new Instagram();
    });
    

    当我在任何方法中调用$ig->login('name', 'pass')时,此对象中的所有用户配置文件信息都已更改,但如果我在另一个Controller方法中调用dd($ig = app(Instagram::class)),则会看到先前的数据未保存。的" WTF&#34?; - 我说

      

    有人告诉我, singleton 只是向我保证不会创建相同的对象,但它不会保存任何更改。

  • 我尝试使用sessions

    但是,当我尝试将对象设置为值时,任何事情都没有发生。

    $ig = new \InstagramAPI\Instagram();
    session(['ig' => $ig]);
    

    我认为是因为我试图放一个大物体。 从另一方面来说,这不是安全的方法!

请告诉我:

如何创建一个可以在每个方法中使用的对象,并为下一个操作保存更改?

1 个答案:

答案 0 :(得分:0)

  

当我在任何方法中调用$ ig-> login('name','pass')时,所有用户配置文件的信息都在此对象中更改,但是如果我调用dd($ ig = app(Instagram :: class)) )在另一个Controller方法中,我看到以前的数据没有保存。

这是正确的行为。向Laravel发送新请求时,会创建Instagram的新实例。我不确定你是否理解单例的含义,但就Laravel而言,每个HTTP请求都有一个实例。

由于您使用的Instagram API不包含重新登录的功能,因此我创建了一个类(将放在app/Classes文件夹中)。

<?php
namespace App\Classes;

use InstagramAPI\Instagram;
use InstagramAPI\Response\LoginResponse;

class CustomInstagram extends Instagram {
    public function relogin(LoginResponse $response) {
        $appRefreshInterval = 1800;

        $this->_updateLoginState($response);
        $this->_sendLoginFlow(true, $appRefreshInterval);

        return $this;
    }
}

更改单例实例,使其使用App\Classes\CustomInstagram类。

$this->app->singleton(Instagram::class, function ($app) {
    Instagram::$allowDangerousWebUsageAtMyOwnRisk = true; // As wiki says
    return new App\Classes\CustomInstagram();
});

为了将Instagram对象与经过身份验证的用户一起使用,需要保留登录信息。这将放在登录发生的位置。

try {
    $response = app(Instagram::class)->login($username, $password);

    if ($response->isTwoFactorRequired()) {
        // Need to handle if 2fa is needed (we're not completely logged in yet)
    }

    // Can use session to persist \InstagramAPI\Response\LoginResponse but I'd recommend the database.
    session(['igLoginResponse' => serialize($response)]);
} catch (\Exception $e) {
    // Login failed
}

然后创建一个中间件以将用户重新登录到Instagram(如果存在登录响应)。您需要将其注册为described here。然后,可以在控制器中使用Instagram单例。

namespace App\Http\Middleware;

use Closure;
use InstagramAPI\Instagram;

class InstagramLogin
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $responseSerialized = session('igLoginResponse');

        if (!is_null($responseSerialized)) {
            $ig = app(Instagram::class);

            $response = unserialize($responseSerialized);

            $ig->relogin($response);
        }

        return $next($request);
    }
}