Если хочется отправить пачку HTTP запросов асинхронно и нативно, то можно попробовать поиграться со stream_select. Сам таким не занимался, но, в теории, должно будет сработать.
P.S.: я буду обновлять комментарии, я буду обновлять комментарии…
По-этому и я перечитываю документацию, время от времени. Но человеческий мозг несовершенен (как вы и сами сказали) и всё равно некоторые вещи забываются, а на некоторые, уже знакомые, не хочется тратить времени.
«Два часа» из моего сообщения, на самом деле, длились не более 20 минут (хотелось указать на драматизм ситуации с неочевидностями PHP), и, конечно же, я полез читать документацию. Нестоит осуждать людей, если не знаете всей их истории.
Вроде бы, уже не первый год на Хабре, но всё не устаю поражаться русскоязычному коммьюнити. Все такие напыщенные и высокомерные, что стоит поделиться кусочком своих знаний (https://habrahabr.ru/post/307248/#comment_9738110) или раскаяться в незнании и забывчивости (https://habrahabr.ru/post/307822/#comment_9753478), как тебя тут же забросают фекалиями всех сортов и попытаются выставить дурачком.
Я абсолютно согласен и не отрицаю, что у языка есть существенные недостатки, связанные с тяжёлым грузом легаси, но всё ведь ненастолько печально, как описываете это вы и в своей нише ему сложно найти конкурентов :)
К слову, о нежданчиках. В самом начале своей карьеры, помнится, я читал об этом нюансе, но случев «неправильного использования» было крайне мало и эта подробность забылась.
Современный PHP это уже не тот язык, что был в далёком 2008. Здесь тоже есть кровавый энтерпрайз (привет, Симфони!) с декомпозицией всего и вся, с поддержкой статической типизации и хорошим пакетным менеджером.
Конечно, можно писать и без фреймворков, по-старинке складывая всё в один файлик, но тут уж всё зависит от программиста.
Для чего вы делаете `composer update`? При развёртывании нужно устанавливать ровно те версии зависимостей, с которыми разрабатывалось и тестировалось приложение, а они хранятся в composer.lock, который `update` перезапишет с новыми версиями. Нужно использовать `composer install` и хранить composer.lock в системе контроля версий.
> Сравнить хотя бы два этих куска кода:
Которые не еквивалентны.
Вы забыли таки построить строку, которую делаете билдером. Сейчас у вас измеряются аллокации/копированя для новых строк (вариант 1) и добавление элемента в конец списка (вариант 2).
А потом приходит заказчик, говорит, что есть проект и тут чуть-чуть доделать нужно. Смотришь туда, а слёзки кровавые сами текут, и остановить это, не отказавшись от проекта, невозможно. А для быстрого развёртывания подходят и существующие AR решения, которые имеют более богатый функционал (что, как раз, добавляет скорости разработки) и проверены временем, и тестами.
И не набросились, а предоставили аргументированную критику.
Велосипедостроение это полезно, сам таким занимаюсь, но выносить это на публику и предлагать как единственно верное решение («связи не нужны», «если нужны — делай create view ...», «ORM в топку» @автор) — нехорошо.
Создание нового замыканя потребляет ресурсы (ЦП+ОЗУ) для захвата области видимости, должно быть очевидно.
Нужна максимальня производительность — избегайте замыканий в любом виде.
> более точно цитирую
Куда уж точнее кусочка, вырезанного из комментариев в исходнике? :)
Автор не говорит о «возможном способе упрощения кода», автор прямо признаёт, что две реализации данной функции это следствие слабого линкера (и нежелания, судя по всему, создавать пакет с одной функцией внутри).
> Вы эту концепцию в принципе не понимаете или конкретно с примером в strconv она вам не нравится?
Скопировать строчку-три-пять ещё, возможно, пойму, но не всю же функцию в 40 строк. Тем более, позднее выяснилось, что это другая реализация функции IsPrint, и, соответственно, разработчикам необходимо [было написать и] поддерживать обе её версии.
Спасибо за затраченное вами время, но я не вижу далее продуктивного обсуждения данной дискуссии.
> Там написано, что эту реализацию можно будет убрать, если линкер сможет убирать неиспользуемые таблицы
В моём комментарии (в частности, цитата из quote.go) именно это и сказано. Для чего вы повторяете слова собеседника?
Прошу прощения, но я не вижу выгоды в необходимости поддержки двух разных версий одной и той же функции (и, да, я смотрел исходный код и версии в пакете unicode).
> Небольшое копирование лучше небольшой зависимости
> Как пример — функция IsPrint из пакета strconv
А я посмотрел исходники. Там написано, что это костыль из-за слабого линкера, а не из-за «небольшое копирование лучше небольшой зависимости». 40 строк кода (не учитывая тестов) без единого изменения это не «небольшое копирование», а индусский код.
Пруф:
>> 405 // TODO: IsPrint is a local implementation of unicode.IsPrint, verified by the tests
>> 406 // to give the same answer. It allows this package not to depend on unicode,
>> 407 // and therefore not pull in all the Unicode tables. If the linker were better
>> 408 // at tossing unused tables, we could get rid of this implementation.
>> 409 // That would be nice.
Ничего ведь не мешало вынести функцию в самостоятельный пакет, подключать его в нужных местах и избежать забот о совместимости двух функций.
С табуляцией всё не так страшно, поскольку вы её в любом случае ставите, даже в языках, где она ни на что не влияет.
В целом, имею положительное отношение к Go, но подобные моменты, типа магических комментариев, макросов, прикрученных сбоку (go generate), отсутсвие (ненужных, ага) генериков, немного огорчают. К тому же, могли бы добавить пилюлю от NPE, в 21-м веке-то (здесь нравится подход Kotlin с Int и Int?).
Если есть нужда хранить большое количество бинарников — на сегодня есть git lfs.
Справедливости ради, заголовки получить можно, но весьма таки неинтуитивным способом.
> file_get_contents(«http://example.com»);
> var_dump($http_response_header);
Если хочется отправить пачку HTTP запросов асинхронно и нативно, то можно попробовать поиграться со stream_select. Сам таким не занимался, но, в теории, должно будет сработать.
P.S.: я буду обновлять комментарии, я буду обновлять комментарии…
«Два часа» из моего сообщения, на самом деле, длились не более 20 минут (хотелось указать на драматизм ситуации с неочевидностями PHP), и, конечно же, я полез читать документацию. Нестоит осуждать людей, если не знаете всей их истории.
Удивительно как много людей не читают чужих сообщений.
Наверное, нужно повторить.
> В самом начале своей карьеры, помнится, я читал об этом нюансе
Но за давностью ознакомления сей нюанс вылетел из головы.
К слову, о нежданчиках. В самом начале своей карьеры, помнится, я читал об этом нюансе, но случев «неправильного использования» было крайне мало и эта подробность забылась.
> $var['smth'] = null;
> isset($var['smth']) // false
> array_key_exists('smth', $var) // true
Как-то убил пару часов на отладку этого :)
Современный PHP это уже не тот язык, что был в далёком 2008. Здесь тоже есть кровавый энтерпрайз (привет, Симфони!) с декомпозицией всего и вся, с поддержкой статической типизации и хорошим пакетным менеджером.
Конечно, можно писать и без фреймворков, по-старинке складывая всё в один файлик, но тут уж всё зависит от программиста.
https://habrahabr.ru/company/mailru/blog/307168/#comment_9736410
Вы поделились кусочком совего знания (предложили посоревноваться в знании PG, ага), я поделился кусочком своих знаний.
Имелось ввиду, что можно использовать существующую функциональность и не вносить дублирование кода.
> User::find()->where([User::primaryKey() => $userid])
Подсветки, ессесн, нет, спасибо НЛО.
Аривидерчи, Влад.
В Yii2 можно юзать ActiveRecord::primaryKey()
https://github.com/yiisoft/yii2/blob/master/framework/db/ActiveRecord.php#L318
Которые не еквивалентны.
Вы забыли таки построить строку, которую делаете билдером. Сейчас у вас измеряются аллокации/копированя для новых строк (вариант 1) и добавление элемента в конец списка (вариант 2).
И не набросились, а предоставили аргументированную критику.
Велосипедостроение это полезно, сам таким занимаюсь, но выносить это на публику и предлагать как единственно верное решение («связи не нужны», «если нужны — делай create view ...», «ORM в топку» @автор) — нехорошо.
upd: я без наездов. Сам бы рад, чтобы он захватывал только необходимый минимум из доступных в области видимости данных, но увы. :(
Создание нового замыканя потребляет ресурсы (ЦП+ОЗУ) для захвата области видимости, должно быть очевидно.
Нужна максимальня производительность — избегайте замыканий в любом виде.
Куда уж точнее кусочка, вырезанного из комментариев в исходнике? :)
Автор не говорит о «возможном способе упрощения кода», автор прямо признаёт, что две реализации данной функции это следствие слабого линкера (и нежелания, судя по всему, создавать пакет с одной функцией внутри).
> Вы эту концепцию в принципе не понимаете или конкретно с примером в strconv она вам не нравится?
Скопировать строчку-три-пять ещё, возможно, пойму, но не всю же функцию в 40 строк. Тем более, позднее выяснилось, что это другая реализация функции IsPrint, и, соответственно, разработчикам необходимо [было написать и] поддерживать обе её версии.
Спасибо за затраченное вами время, но я не вижу далее продуктивного обсуждения данной дискуссии.
В моём комментарии (в частности, цитата из quote.go) именно это и сказано. Для чего вы повторяете слова собеседника?
Прошу прощения, но я не вижу выгоды в необходимости поддержки двух разных версий одной и той же функции (и, да, я смотрел исходный код и версии в пакете unicode).
> Как пример — функция IsPrint из пакета strconv
А я посмотрел исходники. Там написано, что это костыль из-за слабого линкера, а не из-за «небольшое копирование лучше небольшой зависимости». 40 строк кода (не учитывая тестов) без единого изменения это не «небольшое копирование», а индусский код.
Пруф:
>> 405 // TODO: IsPrint is a local implementation of unicode.IsPrint, verified by the tests
>> 406 // to give the same answer. It allows this package not to depend on unicode,
>> 407 // and therefore not pull in all the Unicode tables. If the linker were better
>> 408 // at tossing unused tables, we could get rid of this implementation.
>> 409 // That would be nice.
Ничего ведь не мешало вынести функцию в самостоятельный пакет, подключать его в нужных местах и избежать забот о совместимости двух функций.
В целом, имею положительное отношение к Go, но подобные моменты, типа магических комментариев, макросов, прикрученных сбоку (go generate), отсутсвие (ненужных, ага) генериков, немного огорчают. К тому же, могли бы добавить пилюлю от NPE, в 21-м веке-то (здесь нравится подход Kotlin с Int и Int?).