«phpClub» — архив тем ("тредов"), посвящённых изучению PHP и веб-технологий.
Аноним 2019/02/24 08:10:23  №1353745 1
Пхп вообще параша. Кто будет этим всем заниматься? Язык постоянно пытается стать жабой, когда сама жаба уже существует и просто плюет в сторону этого треда. Я уже не говорю про бек на питоне или голанге, где это дело более успешней, чем перебирать говнокод 10летней давности здесь.

Подумайте об этом.
Аноним 2019/02/24 08:39:25  №1353777 2
>>1353745
Количество вакансий и фирм глянь, где используется. Пхп очень популярен, прост в осовении и гибок, инструменты все современные есть, по скорости щас тоже отдалили. С жабой имеет смысл начинать, если есть огромный энтерпрайз, где кучи сервисов друг с другом коммуницируют. Жаба в крайне малом количестве стартапов сейчас используется, проще и быстрее все на пхп бывает написать и инвесторам результаты показать, чтобы получить дальнейшее финансирование.
Ответы: >>1353803
Аноним 2019/02/24 09:18:05  №1353803 3
>>1353777
Проще и быстрее писать на рельсах, если ты очередной манястартапер. Если же хочешь в норм контору - то тут уже юзается питчон, а если прям охуеваешь от своей тормознутости - присыпается голанг для убер маня хайлода.

>чтобы получить дальнейший говнокод.
Подправил.
Ответы: >>1353810 >>1353827 >>1353831
Аноним 2019/02/24 09:33:31  №1353810 4
>>1353803
Как ни грустно это осозновать, но двачую.
Аноним 2019/02/24 10:08:30  №1353827 5
>>1353803

Какие плюсы у Питона? Это же по сути и по синтаксису почти тот же Яваскрипт, нет даже тайп-хинтов. В Руби та же ерунда. В PHP больше возможностей статической типизации, есть фреймворки, ORM. И разработчиков найти проще.
Ответы: >>1353884
Аноним 2019/02/24 10:10:42  №1353831 6
>>1353803

И, конечно, непонятно, как просто использование Питона или Руби повышает качество кода. С чего бы вдруг? Что, менеджер по продажам, прошедший экспресс-курсы по Питону, будет писать более качественный код, чем после курсов по PHP? Вы, товарищи, просто распространяете очень далекие от реальности стереотипы.
Ответы: >>1353884
Аноним 2019/02/24 11:00:51  №1353884 7
>>1353827
>В PHP больше возможностей статической типизации, есть фреймворки, ORM. И разработчиков найти проще.
Это все нивелируется с существование жабы. Если бы ее не было, возможно пхп был бы еще уебищней.

>>1353831
Качественный код может написать любой человек который умеет читать доки.

Какую-то хуйню не аргументированную спизданул.
Ответы: >>1353901 >>1354506
Аноним 2019/02/24 11:12:24  №1353901 8
pyha.png (7, 799x506)
506x799
>>1353884
>Это все нивелируется с существование жабы.
Ну так и есть, пхп второй после жабы, пикрелейтед. Где жабу поднимать геморно, но удобство и функциональность жабы нужна, поднимают пхп.
Ответы: >>1353992
Аноним 2019/02/24 12:32:36  №1353992 9
>>1353901
>бекенд
>мочаскрипт

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

>>1353942
>Что мне делать дальше?
Делать сайты. Магазины, склады, игровые сайты, фильмы и т.д. Но мне тебя жаль.
Ответы: >>1354232 >>1354503
Аноним 2019/02/24 16:43:04  №1354232 10
>>1353992
всмысле жаль? ты охуел?
Ответы: >>1354305
Аноним 2019/02/24 18:03:12  №1354305 11
>>1354232
Да. Если бы я был бы тобой и только закончил бы опа таски - то я бы сменил род деятельности ( в програмаче ). Явно не жаба, там слишком много писать. Пошел бы в питон, если бы ничего больше не знал. А если бы я делал выбор сейчас - то остался бы в мобилках. Тут языки не нужно придумывать. Все стандартно. Но для бека я бы выбрал голанг или рельсы.
Аноним 2019/02/24 18:33:53  №1354342 12
>>1354305
Вот этот дело говорит.
мимо-как-год-перекатился-в-божественный-руби
Ответы: >>1354358
Аноним 2019/02/24 18:38:55  №1354348 13
>>1354305
а если в системное програмирование?
Аноним 2019/02/24 18:49:20  №1354358 14
>>1354342
>как-год-перекатился-в-божественный-руби
А я вот выбирал между гошкой и руби. Не понравилась мне динамика. Поэтому делаю внутрипроекты на гошке.
Аноним 2019/02/24 21:10:06  №1354495 15
>>1354379

Это правильно называется "скрейперы", и как правило, абсолютно ничего сложного там нет, все элементарно:

- загружаем HTML код
- выделяем куски страницы с помощью какой-нибудь DOM-библиотеки, по имени CSS-класса, по тексту, по еще каким-то HTML-атрибутам
- выводим собранные данные в каком-нибудь формате

Если ты знаешь HTML и DOM, то это обычно элементарная задача.

Со сложными алгоритмами никто не заморачивается, так как обычно написанный вручную "скрейпер" стоит очень дешево, зачастую как 1 час работы профессионального разработчика.

Еще можно, как Телеграм, объявить конкурс и выбрать лучшее решение: https://habr.com/ru/post/438926/

Еще есть способы, когда ты берешь страницу, каким-то расширением для браузера помечаешь на ней нужные места, и оно автоматически генерирует код для скрейпинга (или, например, xpath- или CSS-выражения). Это, мне кажется, интересная идея, так как позволяет привлекать не-программистов (за меньшие деньги) к созданию скрейперов.

Но те, кому нужно заниматься скрейпингом массово, например, поисковые системы, иногда пытаются что-то придумывать: микроразметку, автоматическое выделение содержимого, итд. Простейший способ автоматического анализа - взять 2 разных страницы с сайта, сравнить и таким образом увидеть различающиеся и общие (не содержащие полезной информации) части. Я когда-то давно пробовал писать такую штуку, но там оказался огромный объем работы и я забил на нее.

http://xgu.ru/wiki/HTML_scraping

>>1354305

Какой смысл выучить один язык, забросить, и учить другой? Никакого.

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

Но учить язык только потому, что анонимные эксперты с двача называют его "боежственным", довольно глупо. Есть такие люди, которым в принципе работать не интересно, они весь день сидят, пишут код на Си, PHP, C# или Яве, страдают, а тут рассуждают про "божественные" языки (которые точно так же им наскучат через неделю, если попросить их поучаствовать в большом, реальном проекте на них в команде, с реальным кодом, а не задачками на 500 строк).
Ответы: >>1354777
Аноним 2019/02/24 21:13:46  №1354500 16
>>1354305

В Питоне нет тайп-хинтов, приватных полей. Там везде костыли вроде virtualenv (так как Питон и его окружение по умолчанию пытается устанавливать пакеты в системные директории, что не всегда хорошо). Несколько менеджеров пакетов, причем часто один менеджер используется только для установки другого. Ужасные сокращения, часто нелогичные (например: в matplotlib есть метод set_xlim, а не set_x_limit, но при этом есть set_xscale). Вообще, если брать библиотеки вроде numpy или matplotlib, то нелогичность названий и интерфейса там вполне сопоставима с таковой же в стандартной библиотеке PHP. matplotlib это вообще жесть. Хотя богатство возможностей, конечно, радует.

Расширять библиотеки часто сложно. Например, попробуйте прикрутить DNS-кеш или подменить DNS-резолвер в стандартной библиотеке urllib. Придется поломать голову.

Часто используются глобальные переменные, глобальное состояние, или статические методы. Например: в urllib3 для настройки логгирования вместо DI (создать логгер и передать в urllib3) предлагают использовать код:

logging.getLogger("urllib3").setLevel(logging.WARNING)

А для замены компонента SSL предлагают:

urllib3.contrib.pyopenssl.inject_into_urllib3()

Ну не жесть ли, везде глобальные переменные и кривые костыли вместо DI? Кстати, обратите внимание на разный стиль написания имен функций и бессмысленные части неймспейса вроде contrib.

То же самое в urllib.requests:

> urllib.request.install_opener(opener)
> Install an OpenerDirector instance as the default global opener.

Это функция, которая меняет глобальное состояние библиотеки, и я подозреваю, кому-то надо было иметь возможность подменять компоненты и он, не заморачиваясь с архитектурой и рефакторингом, просто влепил костыль по-быстрому.

Обратите внимание на стиль написания функций:

> urllib.request.build_opener()
> urllib.request.getproxies()

Я не уверен, есть ли бесплатные IDE с анализом кода, показом определений для Питон. Ну и вакансий вроде меньше.
Аноним 2019/02/24 21:14:16  №1354503 17
>>1354129

Ну так померяй, например, на миллионе вызовов. Желательно сделать время измерения большим, минуты или более, чтобы нивелировать разные прерывания работы программы.

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

>>1353992

Человек, обзывающий других дегенератом, хорошего впечатления не производит.

>>1353942

А что ты хочешь делать? Устроиться на работу, сделать свой проект, сдать сессию, какая у тебя цель?

Если на работу - то с задачами про студентов и файлообменник, навыками верстки, SQL, JS вполне может быть достаточно знаний. Можно, конечно, дополнительно освоить какой-нибудь фреймворк вроде Симфони или Ларавель, или посмотреть какую-то популярную CMS. Вроде как у нас были люди, которые послет студентов или файлообменника устраивались на работу и дальше задачи не делали.
Ответы: >>1354526
Аноним 2019/02/24 21:15:31  №1354506 18
>>1353884

> Качественный код может написать любой человек который умеет читать доки.

Неверно. Вот, допустим, человек прочитал документацию по Питону - станет ли он писать качественный код? Да не факт, Питон очень провоцирует городить списки из словарей, называть переменные непонятно итд. Будет ли этот человек знать MVC, ООП, паттерны? Вряд ли.

Вот посмотри библиотеки matplotlib или urllib. Их, наверно, писали люди, читавшие доки, но качество кода очень страдает, мягко говоря. Они даже функции назвать единообразно не смогли, не говоря уж про такие вещи, как DI. Я не вижу особого различия в качестве между PHP- и Питон-библиотеками.

>>1353745

Тогда что ты, болезный, забыл в нашем треде? Выкатывайся в свой тред и нахваливайте друг друга петухами и кукушками. У нас тут учебный тред, а не тред для самоубеждения, что у нас самый лучший язык.
Аноним 2019/02/24 21:38:23  №1354526 19
>>1354503
>А что ты хочешь делать? Устроиться на работу, сделать свой проект, сдать сессию, какая у тебя цель? Если на работу - то с задачами про студентов и файлообменник, навыками верстки, SQL, JS вполне может быть достаточно знаний. Можно, конечно, дополнительно освоить какой-нибудь фреймворк вроде Симфони или Ларавель, или посмотреть какую-то популярную CMS. Вроде как у нас были люди, которые послет студентов или файлообменника устраивались на работу и дальше задачи не делали.


Я хочу устроиться на работу, но не абы куда, студии мимо, хочу заняться серьезным серверным программированием. Мне в вузе очень нравилось проектировать базы данных, вследствие этого за мной тянется фундаментальный багаж знаний о реляционных и нереляционных баз данных. Здесь я только пхп учил. Смотрел, кто из знакомых по вузу где зацепился, большинство не работает по профессии, некоторые админят (тоже не по профессии), некоторые пашут на мобилках, делают приложения, один ушел в 1С. Говно, в общем. Что делать, куда идти? Может свой проект сначала написать какой-то, чтобы крупные компании на меня обратили внимание?
Ответы: >>1354549 >>1359945
Аноним 2019/02/24 22:12:40  №1354549 20
>>1354526
В стартап либо компашку поменьше иди джуном. На собесе задавай вопросы, что они там пилят, если какой свой проект и начинают про архитектуру рассказывать, то круто, если про 100500 клиентов и как они им один и тот же фреймворк или цмс фигачат, то не очень. Можно в принципе и в студии свой уровень подтянуть, если по ходу дела книгу вроде зандстры осваивать и кусками паттерны и нормальный код стараться организовывать, но это дольше. Свой проект на гитхабе конечно лучше сразу, если еще и ООП нормальный там будет, то на собеседовании тебя уже будут нормально воспринимать, и будет о чем рассказать.
Аноним 2019/02/25 11:19:03  №1354777 21
>>1354495
>Это правильно называется "скрейперы"
Да нет, проблем с написанием его нет. Меня интересует как и на каких технологиях разворачивают крупные скрейперы а-ля momondo или другие агрегаторы. Вот допустим есть агрегатор который должен содержать актуальную информацию, то-есть нужен не только первоначальный сбор инфы с сайта но и постоянный перепарсинг сайта (не учитываем тут защиту сайтов, считаем что её нет и принимаем работу что не все сайты нужно парсить, у некоторых есть удобное API).
Можно ли использовать Apache Beam для таких целей или что-нибудь подобное? Или как вообще они устроены? Докеризированные контейнеры которые разворачиваются on purpose? Меня не сам процесс парсинга интересует (тут я имею немного опыта, писал как PHP-парсеры так и мультипоточные парсеры на selenium-js) а вот та инфраструктура которая позволяет поддерживать беспрерывную работу парсеров под большой нагрузкой и в автоматическом режиме.
Ответы: >>1354803
Аноним 2019/02/25 11:48:22  №1354803 22
>>1354777
У нас в шараге под подобное были докеры на амазоне, запускались по таймеру из дженкинс, результаты потом дампом БД пересылались в основную базу. Платили только за время работы парсеров. Но наверняка есть лучшие методы.
Ответы: >>1354827
Аноним 2019/02/25 12:19:58  №1354827 23
>>1354803
То-есть в докере генерились дампы, не было прямого взаимодействия с бд? Был какой-то микросервис отдельный который принимал дампы на импорт? Немного подробнее пожалуйста этот момент объясни.
Ответы: >>1355029
Аноним 2019/02/25 16:15:51  №1355029 24
>>1354827
Да, докер ставился на паузу через дженкинс с внешнего сервера, так что процессорное время не тратилось, когда там ничего не обрабатывалось. Парсеры забирали данные с внешних сайтов, у себя обрабатывали, во время работы на amazon aurora все промежуточные результаты хранили. В конце дамп с авроры делался и копировался на продакшн сервак и микросервис там висел, чтобы внешние парсеры запускать импорт дампов могли. Единственные сложности были с ключами в БД, которые между собой конфликтовали, но мы там потом все составные сделали основной ключ + номер парсера.
Ответы: >>1355051
Аноним 2019/02/25 16:39:13  №1355051 25
>>1355029
Благодарю, буду разбираться, ну хоть направление есть теперь
1-52 Аноним 2019/03/06 02:31:41  №1359945 26
>>1354215

Вообще, это неудобно. Что, если пользователь нажал кнопку, а данные еще не пришли?

Сначала лучше сделать так: пользователь заполняет все поля и жмет кнопку. Отправляются по очереди все нужные запросы.

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

Если у тебя нет понимания, как это делать, то скорее всего ты пока плохо знаешь Яваскрипт. Пройди учебник http://learn.javascript.ru/ и обрати особое внимание на события, анонимные функции (коллбеки), почитай про промисы.

>>1354526

Часто, чтобы попасть в "серьезную" компанию, надо сначала где-то приобрести опыт, возможно, что в веб-студии, в аутсорсере или где-то еще, где берут джуниоров. Ты можешь сам посмотреть вакансии компании, которая тебе нравится, на hh.ru и оценить требования.

Например, если ты любишь проектировать БД, то тебе подойдет какая-нибудь компания, которая делает софт на заказ, всякий софт для банков, телекомов, госорганов - там точно будут сложные базы данных.

>>1354531

Реестр - это паттерн, который описывает объект, в который можно класть и получать данные ( https://martinfowler.com/eaaCatalog/registry.html ). Часто он реализуется на статических методах:

ServiceRegistry::set(ServiceA::class, new ServiceA);
...
$srvA = ServiceRegistry::get(ServiceA::class);

Но это не обязательно. Как я помню, в той же Симфони есть такие реестры:

- реестр кастомных (добавленных пользователем) типов полей Доктрины
- реестр типов элементов форм

Там, где Реестр противопоставляется DI контейнеру - противопоставляется, наверно, статическая версия реестра. То есть подход

ServiceRegistry::get('ServiceA')

и

$container->get('ServiceA');

У Реестра и Контейнера могут быть такие отличия:

- Реестр часто бывает статический, а контейнер - нет
- Реестр не создает объекты: он хранит то, что в него положат. DI контейнер может создавать объекты, если ему дать описание, как это делается (например, описать, что надо передавать в конструктор, или позволить ему самому это понять анализом аргументов в конструкторе).
- Реестр может хранить что угодно, например, числа какие-нибудь или настройки. DI контейнер, как правило, хранит объекты-сервисы. Хотя в Симфони он хранит и настройки.

Ответы: >>1360508
Аноним 2019/03/07 00:13:51  №1360508 27
>>1359945
>Реестр - это паттерн, который описыв
Спасибо, исчерпывающий ответ. Написал бы ты всеобъемлющую книгу по всем этим аспектам. Они ведь не устаревают. Будет пользоваться популярностью.

>>1359946
>У меня просто времени иногда нет, последние пару недель адски загружен.

А можно узнать, чем ты занимаешься? В студии трудишься или в каком-нибудь банке софт ваяешь?

>Ни в коем случае. Идея DI контейнера - IoC - предполагает
Хорошо, проблему синглтона контейнер решает.
А вот еще вопрос. Создал я класс подключения к мускулу, сделал для него сервис-провайдер, где он создается, а потом внедряю его, куда нужно.

А вот, скажем, мне нужен не один объект, а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?

>Я думаю, сервис провайдеры и сервисы хранятся в отдельных папках.

Спасибо, теперь все понятно.

>>1359948
Если у тебя используется дата маппер, то в нем и будет метод для загрузки моделек из БД.

То есть вообще всем управляет маппер, а сущности это такие пассивные ячейки памяти, к которым маппер обращается, и сущность сама по себе ничего делать не должна? И в контроллере правильно будет вызывать именно методы маппера?

>>1359949
> В задаче про студентов сортировку логично сделать аргументом в методе для получения студентов:

Спасибо за разъяснение особенно за последний абзац и за метод, ты сэкономил мне кучу времени.

>То есть перед выполнением нужных действий проверяем наличие логина. При отсутствии - редирект на форму логина с передачей текущего URL

А можно такую проверку делать в конструкторах? Например, в общий абстрактный контроллер засунуть. А то не делать же ее в каждом методе (боль, лол). И если юзверь не залогинен, то просто будет редирект на контроллер залогинивания, который этот конструктор не наследует.

>В твоем варианте пользователь может попробовать обойти авторизацию, вызвав напрямую метод "методПослеПосещения".

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

>Не думал, что у файлообменника такая сила. Сейчас, вроде начинающие разработчики делают сокращатели ссылок, но это уже неприлично просто.

А это разве не проще, чем файлообменник? Там ведь просто идет редирект на реальный URI при обращении к твоей ссылке. За вечер-другой можно сделать.

>>1359951
>Обычно делают отдельно шаблон для "лейаута" (шапка/подвал) и "контента". Лейаутов может быть несколько - например, один для морды, другой для админки. Как передавать параметры для лейаута? Тут есть варианты:


Я придумал вот что. Я в контроллере общем создал контейнер обычный массив data, куда записываю данные со всех уголков контроллеров и приходящие данные из моделей. В контроллерах-родителях задаю общие данные, в контроллерах специфичные, в методах контроллеров данные еще специфичнее. Данные записываются не через переопределение свойств, а через методы суперкласса.
Потом этот контейнер передаю в вид и обращаюсь к нему из шаблонов типа $data['title'], foreach($data['posts'] as $key => $post) {}, ну и все в таком духе. То есть "лейаут" и "контент" получаются данные из одного глобального массива data, переданного в вид. Так нормально?

>Не очень понятно, как это. Вызывать из одного шаблона другие шаблоны можно.

Ну я имел ввиду, можно ли несколько "контентов" подключать в "лейаут".

Спасибо за ответы, ты будто чистое знание вливаешь мне прямо в мозг. Я, бывает, что-то очень долго ищу, бывает, несколько дней занимает поиск ответа на какой-то вопрос, иногда бывает сам додумываюсь до ответа, но проблема в том, что я не знаю, правильный он или нет. Но вот так очень круто зайти сюда и прочитать ответы на все, что я задавал. Пасиба.
Ответы: >>1360509 >>1361818
Аноним 2019/03/07 00:15:56  №1360509 28
>>1360508
>а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?
Хранить в контейнере factory, через нее создавать объекты.
Ответы: >>1360515
Аноним 2019/03/07 00:35:41  №1360515 29
>>1360509
Еще до фабрик не дошел, сейчас самое время, спасибо, анонче.
Аноним 2019/03/10 06:19:53  №1361818 30
>>1360508

> А можно узнать, чем ты занимаешься?

Просто обычная удаленная работа.

> А вот, скажем, мне нужен не один объект, а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?

Можно хранить фабрику (класс, создающий нужные объекты), можно в контейнере сделать метод, который позволяет создавать объекты с параметрами. Но вообще, надо подумать, а нужны ли в таких объектах зависимости? Обычно, если это объект типа "Пользователь", у них нет зависимостей и их можно просто создавать через new. То есть такие "сущности" обычно в контейнер не кладут.

> То есть вообще всем управляет маппер, а сущности это такие пассивные ячейки памяти, к которым маппер обращается, и сущность сама по себе ничего делать не должна? И в контроллере правильно будет вызывать именно методы маппера?

Если ты читал мой урок https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md то знаешь, что есть ACtiveRecord, где сущности умеют сами себя сохранять в БД и Data Mapper, где они не умеют.

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

> А можно такую проверку делать в конструкторах?

Плохая идея, из конструктора нельзя возвращать значения, да и он не для этого. Но ты можешь сделать метод вроде beforeRequest() и обязательно его вызывать из фронт-контроллера.

> Я придумал вот что. Я в контроллере общем создал контейнер обычный массив data, куда записываю данные со всех уголков контроллеров и приходящие данные из моделей. В контроллерах-родителях задаю общие данные, в контроллерах специфичные, в методах контроллеров данные еще специфичнее. Данные записываются не через переопределение свойств, а через методы суперкласса.

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