Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
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)
Не в сети
Не хватает 'use' в начале файла. По умолчанию используется текущий namespace, поэтому когда Вы говорите 'HttpClient' - подразумевается App\Console\Commands\HttpClient, а такого класса нет.
Либо сверху правильный use - а ля use Vinelab\Http\HttpClient, либо при создании - полный путь: $response = \Vinelab\Http\HttpClient::get()
Вообще, в Laravel сразу входит популярный клиент - guzzle
Не в сети
Не хватает '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;
}
Не в сети
У Вас же идет прямой вызов средствами PHP:
$response = HttpClient::get('http://example.org');
Тут type-hinting от Laravel непричем. PHP будет сам искать класс HttpClient, а ищет по дефолту - в текущем namespace.
Не в сети
У Вас же идет прямой вызов средствами 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 на класс клиента?
Не в сети
Что я не понимаю в l5? Ведь фасад по сути скрывает подробности реализации, так зачем мне прямой use на класс клиента?
Если ресолвить (получать) этот класс через "волшебные" методы Laravel (допустим, конструктор как в Вашем примере) - то незачем, и так будет работать.
А если Вы вдруг напрямую средствами PHP создаете объект - то тут уже Laravel не может никак вмешаться.
Раз Вы вызываете явным образом статический метод класса - PHP надо знать что это за класс. Это достаточно распространенная путаница.
Фасад, кстати, ничего не скрывает - это просто укороченный (внешне) способ достучаться до встроенных в $app классов (сервисов). Просто модная визуально фишка, укорачивает код
Подробности реализации скрываются за счет повсеместного использования интерфейсов (interface pattern), а не фасадов.
Не в сети
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))
Не в сети
А в app.php в aliases[] у Вас разве нет фасада Cb? Если есть - то конечно вызов через Cb::method() будет работать - не из-за биндинга в сервис провайдере, а из-за фасада/алиаса.
А в верхнем случае нет ни фасада (в общем-то, класса) с именем HttpClient, ни класса внутри текущего namespace с таким именем - понятно, что неоткуда брать его!
Не в сети
А в app.php в aliases[] у Вас разве нет фасада Cb? Если есть - то конечно вызов через Cb::method() будет работать - не из-за биндинга в сервис провайдере, а из-за фасада/алиаса.
С этим я осознал. Спасибо.
А в верхнем случае нет ни фасада (в общем-то, класса) с именем HttpClient, ни класса внутри текущего namespace с таким именем - понятно, что неоткуда брать его!
$this->app->booting(function () {
$loader = \Illuminate\Foundation\AliasLoader::getInstance();
$loader->alias('HttpClient', 'Vinelab\Http\Facades\Client');
});
А разве этот код не прописывает алиас?
Изменено won (31.01.2016 15:26:45)
Не в сети
А разве этот код не прописывает алиас?
Это алиас на уровне dependency resolverа самого Laravel. Когда, к примеру, просим у Laravel объект класса через App::make() - такой алиас будет работать. Для PHP его все еще не существует.
Не в сети
Страницы 1