Как создать глобальный объект Laravel - PullRequest
0 голосов
/ 14 мая 2018

Я использую Laravel 5.6 и Библиотека API Instagram .

Для работы с этим API Instagram мне нужно создать объект $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') в любом методе, вся информация профиля пользователя изменялась в этом объекте, но затем, если я вызываю dd($ig = app(Instagram::class)) в другом методе Controller, я вижу, что предыдущие данные не сохранялись. "WTF?"- Я сказал .

    Кто-то говорит мне, что singleton просто обещают мне, что не будет создан тот же объект, но он не сохраняет никаких изменений.

  • Я пытался использовать сессий :

    Однако, когда я пытался установить переменную с объектом в качестве значения, ничего не происходило.

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

    Я думаю, это из-за того, что я пытался положить большой предмет. И с другой стороны, это не безопасный метод!


Просто дайте мне знать:

Как можноЯ создаю объект, который мог бы использовать в каждом методе с сохранением изменений для следующих действий?

1 Ответ

0 голосов
/ 21 мая 2018

Когда я вызывал $ ig-> login ('name', 'pass') в любом методе, вся информация профиля пользователя изменялась в этом объекте, но потом, если я вызываю dd ($ ig = app (Instagram :: class)) в другом методе контроллера я вижу, что предыдущие данные не сохранялись.

Это правильное поведение. Когда в 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;
    }
}

Измените экземпляр singleton, чтобы он использовал класс 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 (если ответ на вход существует). Вам необходимо зарегистрировать это как , описанное здесь . Затем синглтон 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);
    }
}
...