Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 30.01.2016 18:01:54

Установка пакета http

L5.2
Установил пакет http://packalyst.com/packages/package/vinelab/http через композер.
Прописал в config/app.php

Edit app.php and add 'Vinelab\Http\HttpServiceProvider', to the 'providers' array.

Создал команду и пробую вызвать

 $response = HttpClient::get('http://example.org');
    // raw content
    $response->content();

Получаю

PHP Fatal error:  Class 'App\Console\Commands\HttpClient' not found in /Users/lodar/Works/PhpStorm/miran/modules/nbapi/app/Console/Commands/TestLog.php on line 47
                                               
  [Symfony\Component\Debug\Exception\FatalErrorException]  
  Class 'App\Console\Commands\HttpClient' not found  

Что не так сделал?

Изменено won (30.01.2016 18:02:21)

Не в сети

#2 31.01.2016 05:08:22

duster
Откуда: Мельбурн
Сообщений: 148

Re: Установка пакета http

Не хватает 'use' в начале файла. По умолчанию используется текущий namespace, поэтому когда Вы говорите 'HttpClient' - подразумевается App\Console\Commands\HttpClient, а такого класса нет.

Либо сверху правильный use - а ля use Vinelab\Http\HttpClient, либо при создании - полный путь: $response = \Vinelab\Http\HttpClient::get()

Вообще, в Laravel сразу входит популярный клиент - guzzle

Не в сети

#3 31.01.2016 12:01:11

Re: Установка пакета http

duster пишет:

Не хватает 'use' в начале файла. По умолчанию используется текущий namespace, поэтому когда Вы говорите 'HttpClient' - подразумевается App\Console\Commands\HttpClient, а такого класса нет.
Либо сверху правильный use - а ля use Vinelab\Http\HttpClient, либо при создании - полный путь: $response = \Vinelab\Http\HttpClient::get()

В сервис провайдере есть прописаны такие строки:

        public function register()
    {
        $this->app['vinelab.httpclient'] = $this->app->share(function ($app) {
            return new Client();
        });

        $this->app->booting(function () {

            $loader = \Illuminate\Foundation\AliasLoader::getInstance();
            $loader->alias('HttpClient', 'Vinelab\Http\Facades\Client');
        });
    }

Мне казалось, что указав в конструкторе класс, он инжектируется как зависимость или я не верно понимаю?

    public function __construct(HttpClient $client)
    {
        $this->client = $client;
    }

Не в сети

#4 31.01.2016 12:24:16

duster
Откуда: Мельбурн
Сообщений: 148

Re: Установка пакета http

У Вас же идет прямой вызов средствами PHP:

$response = HttpClient::get('http://example.org');

Тут type-hinting от Laravel непричем. PHP будет сам искать класс HttpClient, а ищет по дефолту - в текущем namespace.

Не в сети

#5 31.01.2016 12:38:45

Re: Установка пакета http

duster пишет:

У Вас же идет прямой вызов средствами PHP:

$response = HttpClient::get('http://example.org');

Тут type-hinting от Laravel непричем. PHP будет сам искать класс HttpClient, а ищет по дефолту - в текущем namespace.

Прошу прощения за путаницу. Посмотрел исходники, собственно вопрос к фасадам. В примере пакета указано

It will automatically alias itself as HttpClient so no need to alias it in your app.php, unless you would like to customize it - in that case edit your 'aliases' in app.php adding 'MyHttp' => 'Vinelab\Http\Facades\Client'

и тогда можно использовать как в первом посте

 $response = HttpClient::get('http://example.org');
    // raw content
    $response->content();

Что я не понимаю в l5? Ведь фасад по сути скрывает подробности реализации, так зачем мне прямой use на класс клиента?

Не в сети

#6 31.01.2016 13:15:39

duster
Откуда: Мельбурн
Сообщений: 148

Re: Установка пакета http

won пишет:

Что я не понимаю в l5? Ведь фасад по сути скрывает подробности реализации, так зачем мне прямой use на класс клиента?

Если ресолвить (получать) этот класс через "волшебные" методы Laravel (допустим, конструктор как в Вашем примере) - то незачем, и так будет работать.

А если Вы вдруг напрямую средствами PHP создаете объект - то тут уже Laravel не может никак вмешаться.

Раз Вы вызываете явным образом статический метод класса - PHP надо знать что это за класс. Это достаточно распространенная путаница.

Фасад, кстати, ничего не скрывает - это просто укороченный (внешне) способ достучаться до встроенных в $app классов (сервисов). Просто модная визуально фишка, укорачивает код smile

Подробности реализации скрываются за счет повсеместного использования интерфейсов (interface pattern), а не фасадов.

Не в сети

#7 31.01.2016 13:42:24

Re: Установка пакета http

duster пишет:
won пишет:

Что я не понимаю в l5? Ведь фасад по сути скрывает подробности реализации, так зачем мне прямой use на класс клиента?

Если ресолвить (получать) этот класс через "волшебные" методы Laravel (допустим, конструктор как в Вашем примере) - то незачем, и так будет работать.

use App\Package\Intis\Contracts\Sms;
use DateTime;

class IntisSms implements Sms
{

    public function __construct(HttpClient $client)
    {
        
    }
 [ReflectionException]                              
  Class App\Package\Intis\HttpClient does not exist

Так все же получается требуется use? Type-hint применяется для все классов созданных мной, с условием что зарегистрирован как сервис контейнер?

Вот пример, который у меня сработал на ура. И я пытаюсь понять почему не работает в данному случае.

Фасад

namespace App\Cb;


use Illuminate\Support\Facades\Facade;

class Cb extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'CbConfig';
    }
}

Сам класс

namespace App\Cb;


class Config
{
    private $config = [];

    public function getInstance()
    {
        if(count($this->config) == 0) {
            require(CLIENTBASE_DIR.'/include/config.php');
            $this->config = $config;
        }

        return $this->config;
    }

    /**
     * Возврат полного имени таблицы с данными
     *
     * @param int $tableId айди таблицы из кб
     * @return string
     */
    public function dataTable($tableId) {
        $this->getInstance();
        return $this->config['table_prefix']."data".$tableId;
    }

    /**
     * Возвращает полное имя таблицы пользователей
     *
     * @return string
     */
    public function usersTable() {
        $this->getInstance();
        return $this->config['table_prefix']."users";
    }

}

Провайдер

namespace App\Providers;

use App\Cb\Cb;
use Illuminate\Support\ServiceProvider;

class CbConfigProvider extends ServiceProvider
{
    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        Cb::getInstance();
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('CbConfig', 'App\Cb\Config');
    }
}

прописал в config/app.php

providers => [
...
 App\Package\Intis\IntisServiceProvider::class,
]

и вызов в контроллере, все ок

dd(Cb::dataTable(310))

Не в сети

#8 31.01.2016 15:12:50

duster
Откуда: Мельбурн
Сообщений: 148

Re: Установка пакета http

А в app.php в aliases[] у Вас разве нет фасада Cb? Если есть - то конечно вызов через Cb::method() будет работать - не из-за биндинга в сервис провайдере, а из-за фасада/алиаса.

А в верхнем случае нет ни фасада (в общем-то, класса) с именем HttpClient, ни класса внутри текущего namespace с таким именем - понятно, что неоткуда брать его! smile

Не в сети

#9 31.01.2016 15:26:24

Re: Установка пакета http

duster пишет:

А в app.php в aliases[] у Вас разве нет фасада Cb? Если есть - то конечно вызов через Cb::method() будет работать - не из-за биндинга в сервис провайдере, а из-за фасада/алиаса.

С этим я осознал. Спасибо.

duster пишет:

А в верхнем случае нет ни фасада (в общем-то, класса) с именем HttpClient, ни класса внутри текущего namespace с таким именем - понятно, что неоткуда брать его! smile

$this->app->booting(function () {

            $loader = \Illuminate\Foundation\AliasLoader::getInstance();
            $loader->alias('HttpClient', 'Vinelab\Http\Facades\Client');
        });

А разве этот код не прописывает алиас?

Изменено won (31.01.2016 15:26:45)

Не в сети

#10 01.02.2016 04:06:31

duster
Откуда: Мельбурн
Сообщений: 148

Re: Установка пакета http

won пишет:

А разве этот код не прописывает алиас?

Это алиас на уровне dependency resolverа самого Laravel. Когда, к примеру, просим у Laravel объект класса через App::make() - такой алиас будет работать. Для PHP его все еще не существует.

Не в сети

Подвал раздела