Как стать автором
Обновить

Комментарии 27

Любопытная инициатива, присмотрюсь.

Irony_mode: Кто первым кинет в комменты картинку «Есть 14 различных стандартов....»? :)
здесь речь все-таки не об очередном стандарте, а о попытке абстрагироваться от конкретной реализации
зачем нужен адаптер на адаптер?

и в чем проблема использования curl и file_get_open вместе — это встроенные функции
а не какие то библиотеки на сотню классов как guzzl
НЛО прилетело и опубликовало эту надпись здесь
какие то примеры реального применения есть этой абстрактной прослойки?

вот я использую http://php.net/manual/ru/book.curl.php и мне хватает — он есть из коробки у всех нормальных провайдеров и в нормальных дистрибутивах
это и есть стандартная библиотека для PHp — т.е. стандарт.

а если кому то нечего делать и вместо решения задач придумывать какие то стандарты — так ради бога.
по молодости тоже страдал этим — писал абстрактные прослойки и адаптеры. но сейчас осознал Истину.

НЛО прилетело и опубликовало эту надпись здесь
> а завтра обнаружиться зеро-дей уявимость в реализации курла под пхп

во первых тема про http- клиент:

во вторых:
а на что вы поменяете? веть вы используете всего лиш абстрактную оболочку для того же курла.
эта прослойка позволит устранить данную уязвимость?

в третьих ваша прослойка умеет делать такое же при смене «адаптера»?
http://php.net/manual/ru/function.curl-multi-init.php
в третьих ваша прослойка умеет делать такое же при смене «адаптера»?

да, так как все альтернативы будут построены либо поверх стримов либо поверх сокетов. А stream/socket_select в PHP тоже есть в стандартной библиотеке.

какие то примеры реального применения есть этой абстрактной прослойки?

Проект молодой, поэтому примеров пока мало. Но мы используем его внутри нашей компании. Сейчас есть штук пять самостоятельных пакетов, использующих Httplug. Возможно со временем выложим их на GitHub.

вот я использую http://php.net/manual/ru/book.curl.php и мне хватает

Всё зависит от того, чем Вы занимаетесь. Мне тоже долгое время хватало. Пока жизнь не столкнула с такой ситуацией, где хватать перестало. Помните Маяковского? Если звёзды зажигают, значит это кому-нибудь нужно? Так и тут, если несколько человек разработали такую библиотеку, значит они видят в ней потребность, значит для их задач просто cURL уже не хватает.

по молодости тоже страдал этим — писал абстрактные прослойки и адаптеры. но сейчас осознал Истину.

Вы уж извините, но уверенность в обладании истиной (и уже тем более с большой буквы) характерна как раз для молодости :-)
но сейчас осознал Истину.

К чертку абстракции, все можно запилить на Bitrix.

Вы правы — битрикс это CMS — вещь конкретная и полезная.
а Инверсия зависимости что делает полезного?
в случае с http у меня вот нет никаких зависимостей я юзаю стандартную либу curl.
заменять на чтото другое несобираюсь — веть планов по внедрению в PHP более крутых либ вроде нет а если нет альтернатив — то обертки не нужны.
а Инверсия зависимости что делает полезного?

инвертирует направление зависимости, это ж вроде должно быть понятно из названия) Вот вам картинка что бы было проще понять:


image


а если нет альтернатив — то обертки не нужны.

обертки нужны для устранения дублирования и уменьшения сложности кода. Скажем нам нужно в десятке разных мест системы взаимодействовать с разными API. Ну вот такая сферическая задача. Например синхронизация с парочкой сторонних сервисов.


Если действовать согласно вашей философии, то у нас будет использование курла размазано по всей системе. И если создание контекста и т.д. это не так много кода, но обработка ошибок, или хэндлинг других каких-то вещей уже будут представлять собой дублирование кода. И нам всякий раз когда нужно будет пользоваться курлом нужно будет это учитывать. Завернуть это все в обертку (хотя бы функцию) — уже даст нам неслабый профит в плане организации кода и упрощению поддержки системы.


Ну или другой пример. Допустим мы пишем систему. Сегодня нам просто нужно было дернуть один метод API. Завтра — другой. После завтра нам нужно уже 10 запросов отправлять в 10 разных мест с разными параметрами для синхронизации с 10-ю различными сервисами. 8 из этих сервисов имеют SDK которые упрощают взаимодействие (например сложный механизм авторизации с подписью данных). Ну и 10 запросов вместе отжирают у нас 10 секунд времени обработки запроса (если делать все это последовательно).


Да, мы можем выкинуть SDK-ки и использовать мультикур, реализуя все эти чудные вещи самостоятельно (копипаста коды из библиотек), а можем подменить реализацию HTTP клиента и внутри использовать мультикурл + корутины что бы имитировать синхронную работу библиотеки и при этом работать с сетью асинхронно. В случае стандартных интерфейсов вроде Httplug мы можем реализовать свой адаптер и попросить SDK юзать его.


Словом, много чего могут предложить абстракции. Собственно их смысл — уменьшения сложности кода, декомпозиция системы, разделение ответственности. И это я не касался вопросов тестируемости кода. Замокать интерфейс проще чем замокать curl.


Собственно я не пытаюсь вас в чем-то переубедить, это ваше мнение. Я только знаю чем грозит такое отношение в контексте средних и больших проектов и в рамках разработки продуктов.

> Скажем нам нужно в десятке разных мест системы взаимодействовать с разными API

ну я создам себе класс или функцию и будут ее использовать — я могу взять при автозагрузке нужную имплементацию — в чем проблема? зачем внедрять какие то абстрактные патерны вроде инверсии зависимостей?

> Собственно я не пытаюсь вас в чем-то переубедить, это ваше мнение. Я только знаю чем грозит такое отношение в контексте средних и больших проектов и в рамках разработки продуктов.

просто надо рабивать на микросервисы — и переписывать высоконагруженные части на Go

код с высокой связанностью поддерживать одинаково сложно на каком бы языке он небыл написан. А система с использованием микросервисов при низком зацеплении и высокой связанности обойдется вам еще дороже.


Если разработчик не понимает зачем нужны такие "абстрактные паттерны" как "инверсия зависимостей" то он вряд-ли будет в состоянии спроектировать нормально монолит, не то что микросервисы использовать.

повашему коменту выходит что чтобы писать микросервисы надо знать паттерны типа инверсия зависимостей — я вообще не вижу логики здесь.
НЛО прилетело и опубликовало эту надпись здесь

ну тип того, и это не паттерн а принцип. Такой же как инкапсуляция или там принцип единой ответственности (на микросервисы тоже распространяется). Если вы не видите в этом логики — значит вы не можете применить те же правила на макро уровне (на уровне компонентов и микросервисов), а стало быть либо у вас все неплохо с чутьем (такое тоже бывает) и здравым смыслом, и вы эти паттерны и принципы применяете даже не зная об том, либо все очень плохо или будет очень плохо.


p.s. Вы сами то работали с микросервисной архитектурой? И давайте так, если база данных общая хотя бы для двух микросервисов — это уже не считается.

Это философский вопрос из разряда «А зачем нужны библиотеки»? Как правило для облегчения жизни программиста. Понятно, что всё то, что делает библиотека, можно написать самому. При этом кода будет меньше, чем в библиотеке, да и производительнее вполне может получиться. Но тут есть и оборотная сторона. Во-первых, использование библиотек повышает скорость разработки, что с каждым днём становится всё важнее. Во-вторых, как заметил один римский оратор, человеку свойственно ошибаться. Чем больше программист напишет кода, тем выше вероятность появления ошибки. Повторное использование кода — один из способов понижения этой вероятности.

Ну и если вернуться к Httplug, то особенно начинаешь его ценить по мере усложнения проектов, с которыми работаешь. В начале заметки я уже описал некоторые проблемы, с которыми мы столкнулись. Кроме того, благодаря переводу части компонентов на Httplug, мы получили возможность легко, в одной точке приложения, добавлять нужную нам функциональность. Например журналировать запросы/ответы для отладки и профилирования. Более того, мы можем включать некоторые вещи только в тестовой конфигурации и отключать в боевой. Это очень удобно и бережёт много времени и сил.
тоесть обертка guzzle не позволяет абстрагироваться от конкретной реализации и позволять навешивания логирования и прочих обработчиков — хотя вроде как предназначена как раз для этого
и вы решили вместо патчей в guzzle написать еще одну обертку над оберткой? «we need to go deeper»

тогда я видимо совсем не понимаю в разработке и предназначении опенсорсных библиотек.
Guzzle — это реализация. Httplug — интерфейс. Надо объяснять разницу?

И, к слову, написать решил не я. Но задумку считаю нужной.
> Guzzle — это реализация. Httplug — интерфейс.

тоесть это штука ровным счетом ничего не делает правильно?

> Как правило для облегчения жизни программиста

если эта штука — ничего не делает то каким образом она облегчает жизнь программиста?
и для чего такие библиотеки создают?
если эта штука — ничего не делает то каким образом она облегчает жизнь программиста?

Инверсия зависимости.

Хорошая работа, но все же можно пару вопросов задать по коду? (ибо у меня вызывает сомнения)

1. «HttpClient» это класс или интерфейс? Почему бы не сделать рефакторинг
«HttpClient» => «HttpClientInterface» -> «HttpClientInterface.php»
«HttpAsyncClient» => «HttpAsyncClientInterface» -> «HttpAsyncClientInterface.php»
«RequestFactory» => «RequestFactoryInterface» -> «RequestFactoryInterface.php»
и т.д.
2. Для чего нужен puli? Это работает на windows? (у меня нет, к сожалению — как быть ?)
3. Нашел ошибку в адаптере curl — связано с отправкой асинхронных запросов — если добавить 2 одинаковых URL адреса в очередь (возможно не подряд) то выполнение второго прервется? файл MultiRunner.php строки 109-112
4. Зачем везде свойства помечены как «private»? Думается мне это может помешать, если в рамках проекта вдруг понадобиться сделать extends. Пожалуйста, если не трудно, хотелось бы услышать мнения, может я не понимаю или не прав
5. Также нашел ошибку в curl клиенте — клиент позволяется правильно отправить только GET, POST и HEAD? А что с остальным HTTP, например методы WebDav: PROPFIND, UNLOCK, MOVE, COPY и т.д. такие запросы нельзя отправить?
6. Опять же curl, метод PATCH по спецификации позволяет отправить тело? Curl адаптер не отправляет тело?
Эти вопросы можно пофиксить так:
Файл Client.php метод createCurlOptions (почему бы не сделать метод «protected» вместо «private» ?)
if (in_array($request->getMethod(), ['GET', 'HEAD', 'TRACE', 'CONNECT'])) {
// тело не отправляем
} else {
// ->createCurlBody()
// опцию CURLOPT_INFILESIZE использовать НЕ нужно, чтобы избежать проблем с родными потоками, такими как zlib.
}

Прошу меня извинить, что я пишу это тут.
1,2. Можно спросить авторов тут.

3. С чего бы ему прерываться?

4. Любые неприватные члены класса фактически становятся частью контракта этого класса, со всеми вытекающими последствиями в виде необходимости контроля данных, обеспечения совместимости между версиями и прочим, что неизбежно приводит к усложнению кода. При том что необходимость наследования этого класса представляется крайне маловероятной, соотношение накладных расходов к полученной выгоде представляется не очень разумным.

5. С чего Вы это взяли?

6. Сходу ответить не готов. Можете написать сюда.
5. и т.д. вот недавно я попробовал Httplug (а именно адаптер curl, т.к. сокеты и прочее не интересуют) и столкнулся с «аномалиями» таким как, при запросе PATCH игнорируется тело, и я не смог правильно отправить запросы к WebDav по тем же причинам. То же самое и асинхронными запросами. А что касается puli — на windows не устанавливается (а без puli не работают тесты) в dev режиме, и например, pull request авторам смысла не имеет т.к. тестирование не выполняется.

Ну не знаю Вам виднее, если все так и должно «работать» и ошибок нет, то я извиняюсь за беспокойство.
«HttpClient» это класс или интерфейс?

Это тип объекта в первую очередь. Вам не должно быть разницы интерфейс это или класс.


Для чего нужен puli? Это работает на windows? (у меня нет, к сожалению — как быть ?)

прочитайте статью (эту и по puli).


Зачем везде свойства помечены как «private»? Думается мне это может помешать, если в рамках проекта вдруг понадобиться сделать extends. Пожалуйста, если не трудно, хотелось бы услышать мнения, может я не понимаю или не прав

потому что не нужно их экстендить.


Как только вы делаете проперти объекта protected вы по сути делаете это частью "публичного" интерфейса библиотеки. А стало быть вы не сможете иметь в любой момент времени "поправить" реализацию. Чем меньше публичного — тем лучше и проще дальше поддерживать код библиотеки.


Опять же curl, метод PATCH по спецификации позволяет отправить тело?

конечно же, это же PATCH. Он "патчит" ресурсы.

конечно же, это же PATCH. Он «патчит» ресурсы.


Тут AaAAxzz, вероятно, прав. Сейчас curl-client не позволяет отправлять этим методом тело. Надо разбираться.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории