Вы видите копию треда, сохраненную 3 августа 2022 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
ОП довольно занят, но постарается ответить на все вопросы. Также, ответы и решения задач можно поискать в архиве тредов phpclub.
Это тред и для начинающих. Слово "классы" у тебя ассоциируется только со школой, а в аттестате тройка по математике? Ты наш человек.
Предыдущий тред был тут: >>1998470 (OP) . Все старые треды есть в архиве: https://phpclub.tech/ (там есть поиск, можно искать решения и обсуждения задач).
С чего начать
Наши уроки по PHP собраны по адресу http://codedokode.github.io/phpbook (вас отредиректит на другой домен, не запоминайте его, он временный). Это учебник для изучающих с нуля. Там есть задачи, их нужно решать. Но если этот учебник тебе не нравится, можно читать любой другой. Или официальный мануал. Или все сразу.
Если не знаешь как решать, запости код и попроси подсказку или поищи задачу в архиве тредов.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование. У нас есть задачи для изучения этого:
- для начала прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- установи Апач + PHP (советы выше и ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, PDO, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Laravel/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к Symfony или Laravel
- Почитать про паттерны http://designpatternsphp.readthedocs.org/ru/latest/README.html (если ты не изучил ни одного фреймворка, то это будет рановато), тут с примерами кода http://designpatternsphp.readthedocs.org/ru/latest/README.html . Имей в виду что без примеров использования их учить бесполезно - не поймешь, хочешь увидеть примеры использования паттернов - ковыряй исходники Симфони, например Symfony Forms. Не заучивай паттерны - смотри код и думай, зачем тут они использованы.
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/apache-install.md
Может тебе понадобится пользоваться командной строкой, вот гайд https://github.com/codedokode/pasta/blob/master/soft/cli.md
Параллельно стоит подучивать английский, на первых порах можно без него, но по мере развития придется все чаще сталкиваться с англоязычными статьями, так что лучше не откладывать. Читать можно news.ycombinator.com - это что-то вроде их хабра.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://github.com/codedokode/pasta/blob/master/db/databases.md
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
- Новости IT на англ. https://news.ycombinator.com/
- какой-то древний, устаревший, но большой и на русском справочник по веб-разработке, посоветованный аноном: https://starcat.dp.ua/doc/wdh/
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.
Платиновые вопросы
- Почему PHP? Потому что вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а зайди на https://github.com/codedokode/phpbook, нажми зеленую кнопку Clone or Download -> Download ZIP, распакуй на рабочий стол и получи личную копию сайта, не требующую интернетов.
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery. У нас в треде были люди, которые практически с нуля учились и смогли найти работу (ищи в архиве по слову "устроился").
- Что будут спрашивать на собеседовании если 0 опыта - гонять по теории, по официальному мануалу PHP, давать дурацкие задачки на переворачивание строк, гонять по SQL (транзакции, внешние ключи, напиши запрос), по JS (как сделать анимацию при нажатии кнопки), ну погугли, не ленись
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
И сходу вопрос, как вам 8.1?
https://www.php.net/releases/8.1/ru.php
Java еще тебя переживет
Братство умирающего говна.
А я про джаву плохого не писал
>Или официальный мануал.
Это который helloworld на 5 минут, или langref? Реально стоит langref прочитать в первую очередь?
Если ты начинающий, то в справочник стоит заглядывать, только чтобы прояснить непонятные моменты. Если ты готовишься к собеседованию и планируешь строить карьеру разработчика, то желательно пролистать весь справочник.
Спасибо, анон!
Хочу вкатиться в эти ваши пхп.
Есть знания HTML, CSS, JS
В планах быстренько разобраться с php, базами данных, возможно манявель зацепить, и пойти рабом на стажировку куда возьмут.
Про вротенд не нужно писать. С зумерками не смогу конкурировать. Уже смирился с тем, что я тупой. Мой потолок зарплаты через лет 10 - 2000/3000 в лучшем случае. А мне больше и не нужно.
Есть ещё какие то вакансии и стажировки на Magento 2
Стоит туда пытаться попасть?
Какие вообще подводные просматриваются?
У меня впечатление, что чисто беки на пхп начинаются с опытных мидлов и сеньоров, так как большие компании на пхп вакухи, недомидлов и джунов не ищут. А в мелких пхп галерах фулстачество обязательно потребуют.
Потому что аннотаций в пхп нет. В симфони испольуется doctrine annotations. в чистом пхп из рефлексии ты можешь получить только комментарий и парсить его.
Тогда ищи галеры, где проекты пишут с нуля, отдают заказчику и забивают на поддержку. Это сильно легче чем поддерживать несколько стеков на легаси проекте.
Аннотации были стандартом де факто, почти как ломбок в жабе, всех все устраивало, но нет, надо же обязательно запилить какую-то парашу с уебищным синтаксисом, спизженным из раста, блядь!
Преимущество в том, что они часть языка. То, что было раньше, с точки зрения интерпретатора было просто комментарием. Код doctrine-annotations парсил эти комментарии и извлекал из них информацию. Теперь это делает PHP, и делает по строго определенным правилам, а раньше строгих правил не было.
Доступ через reflection, так как в PHP нет объектов-классов, объектов-функций итд.
> и пойти рабом на стажировку куда возьмут
Никуда не возьмут, просто посмотри на требования у вакансий на джуна.
>Какие вообще подводные просматриваются?
Ебанутые тимлиды, завышенные требования к джунам, учить CMS смерти подобно. Подрастёшь до ООП, прыгай на symfony будет тяжело однако у большинства фреймворков она под капотом, да и прокачает она тебя не слабо.
>>244173
>то в чем их преимущество перед старыми добрыми аннотациями
Аннотации это строка которую парсят и получают класс с параметрами магическими методами, а атрибут это класс использующийся на прямую как я понимаю. могу ошибаться офк
>Никуда не возьмут, просто посмотри на требования у вакансий на джуна.
Так там эти самые и требования, чел даже жс знает, возьмут на джуна сразу
>завышенные требования к джунам
Это какие например?
>Подрастёшь до ООП
Мне казалось что без этого ХРюша не должна даже резюме открывать, не то что там собесить, а уже тем более на работу брать.
Опытные аноны докеры с куберами используют
>Это какие например?
Например опыт в коммерческой от года, пару фреймворков, докер, мускул\монго + редис, юнит-тесты, обязательно Вуе\Реакт и тд. Зайди на тот же хх и посмотри с пяток вакансий на джуниора. Имхо почти все такие вакухи это мидл мидл по требованиям, иногда больше.
Обычное хотение мидла, которой от 120 берёт, но на позицию джуна за 60, лол.
Какая ситуация на php галерах с кадрами? Глянул вакансии, их дохуя, но просмотров или откликов вообще нет. Это все потому что всякие вайтиблядские курсы не открывают у себя это направление и учат только верстке и реакту, иногда питону?
мимошел
>Глянул вакансии, их дохуя, но просмотров или откликов вообще нет.
Многие вакухи годами висят, так какой смысл на них откликаться? Там либо текучка лютая, либо условия рабские, либо хотелки большие, либо не очень нужно. Не поверю, что за полгода разработчика на нормальные не найти.
>Это все потому что всякие вайтиблядские курсы не открывают у себя это направление и учат только верстке и реакту, иногда питону?
ПХП не модный же, просто инструмент для работы. А так курсы найти не проблема, проблема потом работу найти - вайтишников с курсов почти нигде не берут.
>вайтишников с курсов почти нигде не берут
Ну и как вкатываться вообще, сидеть годами учить требования на вакансию, чтобы прийти и узнать что уже используются новые технологии?
Классическая мантра. Я то курсы не защищаю, просто непонятна логика. Почему их не должны брать, если человек имеет какие то знания и соответствует вакансии? Сейчас открываешь вакансии и много где написано, что ищем студентов, выпускников вузов или вайти курсов. Кого ебет где ты учился, в шараге, дома по книге или год на курсах за 300кк?
>сидеть годами учить требования на вакансию
А за полгода ты ничего не изучишь - максимум вордпресс какой пощупаешь. Самостоятельно решать девеловерские задачи на таком уровне не выйдет.
А так да - сидят и учать пару лет. Если не интересно, то попробуй что-нибудь другое.
>>245121
>Кого ебет где ты учился, в шараге, дома по книге или год на курсах за 300кк?
Да не проблема - дадут тестовое и ты обязательно соснёшь, или соснёшь на первой же таске. Дело не в курсах как таковых, а в том, что там ничему не учат - у них задача бабла нарубить в первую очередь. Хочешь научиться - придётся помимо курсов самому впахивать в три раза больше. Только тогда возникает вопрос - а нахуя эти курсы нужны получается, если большую часть работы делаешь сам?
Я так понимаю нужен только докер а все остальное выставляется в его зависимостях?
Не пинайте, прошу, я работал полтора года на заводе пхп макакой, где был апачи на локалхосте и виндус сервер и все уже было настроено, потому и не разбираюсь в администрировании
ставишь docker-ce и docker-compose
в проекте создаешь файл docker-compose.yaml
в файле прописываешь сервисы
services:
____baza:
________from: postgres:latest
____server:
________from: nginx:latest
____app:
________from: php-fpm:latest
конфиг не валидный просто для пояснения
Методом научного тыка настроить не получится, читай доки или смотри видосы. Под винду либо wsl2, не home версия винды нужна или проще поставить vmware player и туда убунту.
Да, только сам докер в Dockerfile ты описываешь какой образ тебе нужно php-fpm, nginx, postgres и нужную версию, а при билде он сам всё скачает, потом для разработки можно это всё дело поднимать при помощи docker-compose а на проде всякие кубернетисы, но это уже дела девопсов.
>Это какие например?
На ХХру просто ради интереса поищи вакансии ждунов, там порой доходит до абсурда. Год коммерческой разработки на чистом или же на каком либо MVC фреймворке, а есть ещё жизики которые требуют вышку... Просто представил: Отучился ты такой на погремиста, у тебя в багаже Си или плюсы и ты пиздуешь работать за 70к в контору на должность ПХП макаки.
PSR'ы, паттерны порою требуют.
>>245043
Пожалуй удвою энтого.
>>245111
>Ну и как вкатываться вообще
Придумываешь себе проект, открываешь доку по пхп, говнокодишь. Тратить деньги на курсы когда вся инфа в открытом доступе и передаётся онлине из страницы прямо тебе в глаза, дикий долбаебизм.
>сидеть годами учить
При плотном кодинге и заучивании пыха до ООП учится за полгода до сносного уровня, даже если год, то новые технологии не далеко уйдут вон 7.4 вышла 2года назад, а на ней до сих пор кодят.
>>245137
>А за полгода ты ничего не изучишь
Пыха один из самых простых и узконаправленных языков и за полгода учится вполне. Если хуйнёй не заниматься
>дадут тестовое
Никогда не беритесь за тестовые, это наебалово чистой воды.
>Никогда не беритесь за тестовые
Имхо тестовые на часок, решаемые практически вотпрямщас, когда ты на коленке можешь накидать, показать и обсудить, вполне можно делать. Что-то выше этого - просто неуважение к соискателю и его личному времени.
>Просто представил: Отучился ты такой на погремиста, у тебя в багаже Си или плюсы и ты пиздуешь работать за 70к в контору на должность ПХП макаки.
Лол, у меня полгода пхп Битрикса в расчёт можно не брать и 8 месяцев рельсы, я на 100 собесился и походу продешевил, мне как нехуй делать предлагали офер, вопросы простейшие кроме одного про то как работает интерпритатор и про пару гемов с которыми не работал после нг попробую на мидловые пооткликаться за 120+ и походу съебу на почти х2.
>после нг попробую на мидловые пооткликаться за 120
Сейм - после нг предстоит разговор о повышении с руководством, если не договоримся, то полечу на юга за новой зарплатой, громко курлыча.
> Никогда не беритесь за тестовые
И как работодатель оценит твой код без тестового? На словах-то все вы Львы Толстые.
По гитхабу.
Еще вопрос: есть ли возможность писать не как обычно когда скрипты на каждый запрос исполняются заново, а как на питоне когда есть рабочий цикл и он обрабатывает весь HTTP?
Можно. но в пхп это нетривиально и нераспространено. Роль аппликейшен сервера выполняет менеджер процессов php-fpm
Он создает пул php воркеров, принимает запрос через сокет и посылает на обработку воркеру. Если я не ошибаюсь пхп воркер не отрабатывает и умирает как в cgi, а работает между фазами инициализации php, в начальной фазе все данные в глобальных переменных стираются, очищается скоуп и тд и тп. Когда воркер сожрет слишком много памяти, php-fpm его гасит, и запускает новый процесс. Сейчас появляются новые менеджеры для пхп процессов. Например на голанге roadrunner, с ним пхп воркер способен сохранять свое состояние между запросами.
мне хоть и нравится php, но вот это вот мне не нравится
это порождает выкрутасы для нормального роутинга и жрет ресурсы наверное больше чем могло бы
node js норм или слишком зумерская хуйня?
сам js неплохой язык, но вот хочу узнать как он в сравнении с php в реальном использовании
>js неплохой язык, но вот хочу узнать как он в сравнении с php в реальном использовании
js - создавался для кручения дерева в браузере, php - создавался для бекенда. В контексте чего ты их сравнивать хочешь?
Наверно непонятно сказал. Нетривиально и нераспространено запускать скрипты через CLI и чтобы скрипт работал как нода или приложение на питоне обрабатывая запросы. В сам пхп встроен сервер чисто для разработки, запускаемый через CLI. Для прода используется менеджер процессов php-fpm.
Почему нельзя написать приложение на пыхе, а скажем вебсокеты, шлюз для раббита, редиса, и т.д написать на ноде? Будет у тебя нода пхп апишку дергать кода сообщение от редиски придет. Мне кажется это лучше чем на код пхп, там где надо контролировать, чтобы он не сожрал всю память, как редис консумер например.
Чтобы все писать на ноде? Это дело вкуса и наличия умения написать что-то сложное на ноде. Обычно же человек хорошо знает что-то одно, а остальное как вспомогательное осваивает.
>Обычно же человек хорошо знает что-то одно, а остальное как вспомогательное осваивает.
Ты умеешь кушать или какать? Что из этого ты умеешь, а что вспомогательное?
Какать это вспомогательное! Кушают долго с чувством наслаждения, а какают хорошо что не на бегу...
Вот рили ты изучишь симфони и нестжс, ты их собираешься попеременно применять или как? На проекте у тебя основным будет одно, ты его лучше изучишь. При поиске следующей работы ты снова выберешь, что лучше знаешь, чтобы зепка была.
>>245471
https://laravel.com/docs/8.x/octane
В ларавеле давно есть хуйня, которая меняет принцип работы на рабочий цикл с один раз инициализированным приложением, которое дальше лежит в памяти и не создаётся каждый раз при запросе. видел проект, где это использовалось, но сам ещё не трогал
бамп
Алсо, какой фреймворк выбрать из тех чтобы работать за деньги?
Нужен такой, чтобы можно было просто кидать в htdocs на хостинге.
Нахуй ты со строками арифметику делаешь? Приводи типы и у тебя всё будет нормально, на бекенде вообще в последнее время typescript везде, а он тебе не даст говнокод написать
Транслируется в обычный жс,а там на выходе такая лапша может быть...
Если ты везде any не будешь писать, то '2' + '2' - '2' у тебя не получится
Любой статический. Ипизированный язык трансдируется в то, где в раетайме нет никаких проверок и там может быть такая лапща из маш или байткожа, что ты не прелставляешь.
А сишка это фреймворк для исправления машкода... Когда уже сделают процессор с поддержкой Хаскеля?!
>фреймворка
Это диалект js, принцип подобен указанию типов в пхп начиная с 7 версий, принцип точно такой же - костыль для исправления косяков языка https://habr.com/ru/post/259497/ которым все пользуются, я в том числе когда на пыхе писал
Ты дилетантишка, для которого языки программирования это магия, работающая сама по себе. Поэтому ты и не понимаешь, какую дичь ты несешь.
Документация на первый взгляд не выглядит, как материал, по которому можно разобраться с фреймворком ньюфагу.
Есть какая то книга за 2020 год, но там версия 5.8, а сейчас уже 8 актуальная
За это время были какие то кардинальные изменения или можно ее прочитать?
>Это диалект js
Диалект это это например camelCase || snake_case, а TS попросту ебаная заглушка для языка который запилили на коленке, а потом на его поддержку либо забили хуй, либо сами не знают как исправлять эту поебень под названием JS.
В прошлом треде всё ясно расписывал анон, что можно просто ошибиться в наименовании свойства и засеттить какое то новое свойство, а жабаскрипт не то, что ничего не скажет, а сделает вид, что так и надо.
Когда запилят адекватный ЯП для фронта с типизацией и куртизанками - JS сдохнет.
Статейка от еблана сравнивающего через == и удивляющегося почему динамический язык при нестрогом сравнении ведёт себя так.
Или ты сравниваешь как человек используя тождество или идёшь нахуй с говнокодом своим ебаным, ибо адекватные языки вообще посылают нахуй когда видят '2' - '2' или же 2 == '2'.
Ещё и статья 2015го года...
Только вот почему то пыха делает всякие прикольные вещи в своём языке каждый патч, а для JS пилят фреймворк который латает дыры в костыле ведь JS не обновляется.
>я в том числе когда на пыхе писал
Если бы ты работал в интерпрайзе, то с такими сравнениями как: ==
Тебя сразу посылают нахуй из компании.
Что не так? Точно помню, что раньше все работало
Где можно про это подробней почитать/посмотреть? Как вообще вся эта кухня вместе работает?
Под твои запросы скорее подпадает роадраннер или php-pm, не путать с пхп-фпм. Почитать - в гугле.
А, там тебе анон и так написал про роадраннер. Не заметил.
Не знаю, поэтому и спрашиваю.
Прям чувствуется перегар битрискоида сквозь монитор, давай расскажи мне тупому что да как
Думаю, надо читать книги по тестированию. А так, у нас есть вводный урок, который в общих чертах рассказывает про автоматическое тестирование: https://gist.github.com/codedokode/a455bde7d0748c0a351a
>>245462
Да, есть. Ты можешь открыть порт и принимать соединения. В этом случае PHP запускается не из-под менеджера процессов вроде php-fpm, а из командной строки. Ты можешь написать код полностью сам или использовать библиотеки вроде ReactPHP.
>Диалект это это например camelCase || snake_case
Хоть бы статья почитал в Википедии для приличия, чтобы отличить нотацию от диалекта
https://ru.m.wikipedia.org/wiki/Диалект_(программирование)
>потом на его поддержку либо забили хуй, либо сами не знают как исправлять эту поебень под названием JS
Поинтересовался бы для начала как на его поддержку хуи забивают, новая версия ноды и v8 2 раза в год выходит, ts вообще постоянно обновляется. Сама спецификация языка в последнее время не обновляется это да.
>Когда запилят адекватный ЯП для фронта с типизацией и куртизанками - JS сдохнет.
Уже можно, хоть на плюсах, хоть на расте, хоть на го, wasm уже везде поддерживается, на расте даже пилится фреймворк yew типа реакта
>Только вот почему то пыха делает всякие прикольные вещи в своём языке каждый патч, а для JS пилят фреймворк который латает дыры в костыле ведь JS не обновляется.
Собственно в пхп к 8.0 довели типизацию до уровня typescript, потихоньку делают джавашарп из языка и взяли из раста аннотации и оператор match, плюс ещё куча всякой хуйни, просто тупо заваливают синтаксическим сахаром, оставив всё легаси для обратной совместимости, ладно хоть jit прикрутили. собственно одна из причин почему я ушёл от пыхи
Не надо вводить в заблуждение. Что значит "нетривиально"? В PHP есть сокеты, и более того, они могут работать в асинхронном режиме. Код получается такой же, как например, если бы его писали на Си.
>>245471
> это порождает выкрутасы для нормального роутинга и жрет ресурсы наверное больше чем могло бы
Наоборот. Так как PHP очищает память после каждого запроса, это позволяет избегать утечек памяти. В то же время на других платформах (вроде Ноды, Го, Java, Питон, Руби) такой возможности нет и там очень часто происходят утечки памяти. Погугли и ты найдешь вопросы "у нас сервер на языке X постоянно потребляет память, что делать" и советы вроде прибивать его каждый час по крону. Вот так высокие технологии! У них нет ни инструментов для поиска утечек, ни средств борьбы с ними и все, что остается незадачливым разработчикам - лепить костыли.
То есть, написать в командной строке node app.js это "тривиально", а если мы команду заменим на php app.js то это сразу же становится "нетривиально".
>>245487
> Мне кажется это лучше чем на код пхп, там где надо контролировать, чтобы он не сожрал всю память, как редис консумер например.
А что такого магического есть в ноде, что защищает от утечек памяти? Ты просто хочешь написать что-нибудь плохое про PHP без всяких оснований.
>>245559
Это небезопасно, выкладывать весь код в публичную папку. Забудь про хостинги и осваивай основы администрирования Линукс.
> Уже можно, хоть на плюсах, хоть на расте, хоть на го, wasm уже везде поддерживается, на расте даже пилится фреймворк yew типа реакта
Я сталкивался с приложениями на Дарт (по моему, они использовались в какой-то админке Гугла для управления рекламой), это выглядит как 6 или больше мегабайт яваскрипта, стиль Material Design и жуткие тормоза, как при загрузке, так и при работе если только ты не купишь самый дорогой макбук.
С тех пор я скептически отношусь к идее использовать что-то, кроме JS, для фронтенда.
Конечно, в теории WASM не обязывает тебя делать 6-мегабайтные бинарники. Но на практике выйдет именно это.
Это как препроцессоры CSS, вроде хорошие задумки, но на практике на них пишут только нечинаемую уродливую лапшу с 8 уровнями вложенности. Без них код бы получился лучше, хоть это и потребовало бы чуть больше времени.
В общем, эти макбук-технологии это дрянь. Покажи мне фреймворк на WASM который весит менее 50 Кб и не перерисовывает весь DOM на каждый чих и тогда я соглашусь что это хорошая технология.
Память на пхп нормально не очищается для cli скриптов
Пыху никто как питон скрипт не запускает, за исключением случаев использования асинхронных reactphp, amphp и т.д и там надо следить памятью костылями
Обычный режим работы пыхи через процесс менеджер типа fpm
Вспомнил распостраненный запуск пыхи в cli на проде - это очереди в ларке. Но это какой-то уровень сайта для чебуречной.
>ts вообще постоянно обновляется
>новая версия ноды и v8 2 раза в год выходит
Охуеть, фреймворки обновляются, а сама основа нет.
Ты без упоминания TSа и дня прожить не можешь?
>Сама спецификация языка в последнее время не обновляется это да
Мог бы до этого ничего не писать...
>Уже можно
С танцами по типу скачай установи скомпиль в JS. Нахуя они мне нужны если нативно не поддерживаются браузером?
>Уже можно, хоть на плюсах, хоть на расте, хоть на го
Уж лучше на нормальных языках, чем на надстройке\фрейморке JSа которые только раздувают код like as TS
>просто тупо заваливают синтаксическим сахаром
И от этого сахара почему то пыха работает всё быстрее из патча в патч.
>собственно одна из причин почему я ушёл от пыхи
Не смог в тождественное сравнение, Enum'ы или матчи?
А дело в том, что НИГДЕ
Традицию так легко изменить невозможно. Проще свичнутся в питон.
Этих чебуречных в мире миллионы.
>Не смог в тождественное сравнение, Enum'ы или матчи?
Не смог видеть как такие как ты этим пользуются) Плюс всякие уебищные конструкторы и прочие мелочи жизни, которые добавили в 8.
И что же такого уебищного в новых конструкторах? Чем хуево писать __construct(public readonly string $azaza) и иметь маленькие дтошки без ебли с геттерами и сеттерами?
>писать __construct(public readonly string $azaza) и иметь маленькие дтошки без ебли с геттерами и сеттерами?
Бля может ну его нахуй этот ПХП тогда и все на Жаву пересядем?
У джавы совершенно другая модель исполнения. И на шаред хостинг ты жаву не запихнешь.
Но ты можешь вместо массива дто передавать
Ты меня не не так. У меня нет проблем с валидацией ДТО (форм тоже, кстати, нет). Проблема исключительно в UniqueEntity и я хочу понять, то ли я не умею его готовить, то ли я все сделал правильно, написав свой констрейнт.
* не так понял
Да вроде понятно писал. Правила валидации в ДТО, из которого после успешной валидации создается сущность. Нужно проверять одноименное поле из сущности на наличие в БД.
Ну и к чему ты это ляпнул?
>шаред хостинг
Когда ты начинаешь писать public __construct(public readonly string $azaza), то часто там уже не до шаред хостинга и уже другие материи. По наблюдениям естественно.
И шо таки тебя смутило? Не иначе поле/свойство? Я недавно в таком сраче на тему терминологии уже поучаствовал и больше не хочу. И ничего странного я не леплю, просто давно решил, что сущности должны быть всегда валидны, следовательно в них нет места правилам валидации.
Да я понял что ты велосипедишь, это очень увлекательно, продолжай. Просто у меня, когда говорят дто, сначала возникает мысль что человек хочет отделить бизнес логику от фреймворка, инфраструктуры и т.д. Дто из реквеста валидируют чтобы выплюнуть фронту ошибку, это задача инфраструктуры. Требование уникальности это требование бизнес логики, но одновременно и протекающая абстракция, потому, что чисто в слое БЛ эту проверку сделать нельзя.
Спасибо, продолжаю дальше.
>>Требование уникальности это требование бизнес логики, но одновременно и протекающая абстракция, потому, что чисто в слое БЛ эту проверку сделать нельзя.
Просто нужно сделать ДТО для ДТО и проблема протекания исчезнет азаза
Валидация моделей БЛ это задача БЛ. ДТО валидируется чтобы вернуть фронту, что он забыл заполнить требуемое поле . Поле в форме - это очевидно не забота БЛ. Вопрос о границах и направлении зависимостей.
Проблема протекания не исчезнет никогда, ты не сможешь всю таблицу загрузить в модель БЛ и проверить там.
> Память на пхп нормально не очищается для cli скриптов
Зачем ты вводишь в заблуждение. В PHP есть и подсчет ссылок, и сборка мусора. Ровно то же самое, что в Питоне и в Node.JS.
>>246002
Чтобы разобраться, как работают асинхронные фреймворки вроде ReactPHP, тебе сначала надо почитать про сокеты (не вебсокеты, а сокеты Беркли), потом про асинхронные вызовы и poll/select, потом про промисы и дополнительно поковырять документацию или исходники ReactPHP или аналогичной библиотеки.
>>246138
Лучше бы конечно DTO сделали как в Питоне dataclasses.
> Есть констрейнт UniqueEntity, но проблема в том, что мне нужно применять его не к сущности, а к DTO.
Если поискать валидатор этого констрейнта: https://github.com/symfony/doctrine-bridge/blob/876bef571479727119e03ff82752a8ba56dc5c91/Validator/Constraints/UniqueEntityValidator.php#L85
То мы увидим там:
> $class = $em->getClassMetadata(\get_class($entity));
То есть проверять им можно только сущность Доктрины иначе метаданные в этой строчке не найдутся.
Так что похоже надо делать свой валидатор.
Это недостаток DTO. Когда у тебя в коде есть два разных объекта, представляющих одно и то же, приходится делать по две функции для работы с ними (иногда тут могут помочь интерфейсы, но не в этом случае).
Если у тебя заранее заготовлен ответ, то тебе запускать скрипт не нужно. Ты можешь настроить веб-сервер, чтобы при методе POST он, например, отдавал HTML-файл с диска. Как настроить - зависит от используемого сервера - nginx или Apache и, боюсь, тебе придется погрузиться в их документацию. Документация к nginx есть на русском.
В апаче вроде как можно использовать директиву Limit: https://httpd.apache.org/docs/2.4/mod/core.html#limit
>>246352
> Просто у меня, когда говорят дто, сначала возникает мысль что человек хочет отделить бизнес логику от фреймворка, инфраструктуры и т.д
ДТО может быть просто ДТО, которое например представляет данные из формы (или пришедшие из API), и нет никакой сложности сделать проверку на отсутствие таких данных в БД. А ты начинаешь додумывать, как там архитектура устроена.
Спасибо, всё оказалось гораздо проще, скрипт как ответ принимает содержимое файла к которому обращается
На хабре была статья про Битрикс, погугли. Если в кратце, то все очень плохо.
Зачем ты вводишь в заблуждение https://divinglaravel.com/avoiding-memory-leaks-when-running-laravel-queue-workers
Покеж пример уровня питоновской фляги на пхп или пример нодовского экспесса, где сел и поехал на аппликейшен сервере, а не лисапеды которые ты предлагаешь. Так то селект и епол везде можно вызывать, как и любое апи на сишке.
>Плюс всякие уебищные конструкторы
>Хнык хнык, пачиму так сложна
В 8ую пыху наоборот добавляют плюшки упрощающие жизнь, размер кода и производительность.
Хотя наоборот радует, что из года в год пыха становится типизированнее и из неё бегут всякие макаки которые сравнивают не тождество или не знают как работает их код.
>>246138
>И что же такого уебищного в новых конструкторах?
То что им сложна, а когда им сложна их на работу не берут и приходится уходить туда где попроще.
>Это небезопасно, выкладывать весь код в публичную папку. Забудь про хостинги и осваивай основы администрирования Линукс.
НАМ НУЖЕН САЙД НА МОДНОМ СРАЛАВЕЛЕ
@
ОК, ПОКУПАЙТЕ ВПС
@
ОЙ ДОРАХА, ДАВАЙ ТОГДА ВОРДПРЕС ХУЙ СНИМ
Вордпресс был современным только вначале прошлого десятилетия. Лучше не стоит ставить эти два слова вместе.
Ебало тимлида представили, когда мидл новый проект с таким кодом принесет, вместо круда на ларевеле. А когда эта хуйня начнет активно с орм работать и всю память в контейнере выжрет мидла ногами будут пинать или только обоссут?
На скрине обыкновенный код, который не вызовет удивления ни у мидла, ни у адекватного джуна.
Теоретик, спок. Я тебе написал причину почему твой код не будет работать в сложном приложении на пхп. Ты писал когда-нибудь долгоиграющие джоб воркеры на пхп? Предположим ты хочешь реквесты обрабатывать на манер экспресса и хранить какие-то данные в глобальном объекте для простоты. например статистику запросов. Тебе придется твой воркер перезапускать потому что пхп библиотеки не спроектированы для работы в CLI режиме. Глобальные данные придется сохранять и восстанавливать после перезапуска воркера. Короче костыли костылики
Любая пхп ормка насрет тебе столько в память, что ты будешь каждый час за ней прибирать
Представили ебало тупорылого пориджа, который кроме круда нихуя не видел в своей никчемной жизни? Никто в здравом уме и не будет тащить асинхронщину в обычное крудоподелие. А тот кто потащит будет знать, зачем ему это нужно и наверняка озаботится поиском асинхронного клиента для БД и борьбой с утечками памяти. И, кстати, пыха сама по себе давно уже не течет.
Так зачем оспаривать начали, что в пыхе менеджеры процессов используются как апп сервер, которые пыхины воркеры перезапускают, а работа в cli нетривиальная и нераспостраненная практика? Может не ты может другой анон, а ты влез без контекста.
А ты не пробовал писать воркеры, которые не протекают? Говорят, что это охуенная тема. А если не судьба, то периодическое прибитие воркеров и перезапуск их супервайзером с временным хранением данных в каком-нибудь редисе вполне себе нормальный подход, хоть и немного компромиссный. И уж точно не какой-то там невероятный костыль. Я кончил
>>а работа в cli нетривиальная и нераспостраненная практика
Ну это ты загнул. Лично мне на всех моих работах приходилось лепить что-то консольное. От простых команд до любимых тобой воркеров, так что это точно не экзотика
Чел, контекст. Вопрос был: "Хачю кок в ноде", впрос не стоял можно ли запустить комманд на пхп. Как в ноде - экотика. Если пойти по этому пути, то придется долго докладывать Кобанычу, что ты все еще борешься с трудностями а не решаешь бизнес задачу.
Чел, контекст. Вопрос был: "Хачю кок в ноде", впрос не стоял можно ли запустить комманд на пхп. Как в ноде - экотика. Если пойти по этому пути, то придется долго докладывать Кобанычу, что ты все еще борешься с трудностями а не решаешь бизнес задачу.
Уже экотика у меня от вас началась...
Ты пишешь ерунду. Такие же утечки могут быть (и бывают) в приложении на Ноде или Питоне. Только в отличие от Ноды или Питона, в PHP у тебя есть выбор - отсутствие утечек и перезапуск скрипта на каждый запрос или более высокая производительность, но требующая более высокого качества кода.
Возможность есть, хочешь - пользуйся, не хочешь - не пользуйся. Тебе просто хочется что-нибудь плохое написать про PHP, но так как ты не разбираешься в предмете, то начинаешь придумывать субъективные причины уровня "мне цвет логотипа не нравится".
> пример нодовского экспесса, где сел и поехал
Раз уж мы перешли на субъективные оценки, то твой Express это детская игрушка в сравнении с тем же роутером в Симфони, который поддерживает и YAML-конфиги и аннотации в отличие от Express в котором ты руками каждый коллбек прописываешь.
Аналогично, популярные шаблонизаторы в JS тоже примитивные в сравнении с тем же Twig.
Ну и бред. Перечитай свой пост. Ты пишешь: если мы будем "хранить данные в глобальном объекте" в PHP, то память будет тратиться. Также, данные надо куда-то сохранять. Поэтому PHP якобы непригоден (?) для работы из CLI.
А что, в Питоне и JS это работает как-то по-другому? Данные можно хранить в памяти, и при этом память не тратится и магическим образом сама куда-то сохраняется?
Ты же пишешь ерунду полнейшую.
>>246790
Неправда. Не скажу за любую ORM, но в той же Доктрине есть метод clear(), например. Успешно используется и ничего никуда не утекает.
>>246805
Если ты неграмотный, то для тебя все, что сложнее чем нажать кнопку на экране, будет "нетривиальным".
Ты читаешь жопой. Я не сказал что память будет течь из-за того что ты данные глобально хранишь. Я сказал, что предположим у тебя есть причина использования php через cli. Ты хочешь сохранить данные между запросами. Из-за того, что библиотеки не приспособлены для таких условий, у тебя будет течь память и тебе придется перезагружать скрипт и сохранять свои глобальные данные вне скрипта, как это было при работе через cgi.
Ты сам пробовал писать на пхп скрипты, которые месяцы живут без перезапуска, при этом интенсивно ворочают данными?
- Пиздец, пиздец!!! У клиентов письма не приходят!!! У клиентов статистики нет!!! У клиентов новых парсингов нет!! Проверяй, Сычов, скорее!!!
Сычев:
- Ой там очередь упала.
- Чини быстрее!!!
- Но сейчас же конец рабочего дня, пятница...
- Меня не ебет! Ты ЭТО писал, Сычов.
Не на пыхе, но не потому что пыху не люблю или дальше использовать не собираюсь. Хочу опыта больше иметь с разными технологиями.
Если что-то внезапно падает это признак говнокода. Поделом говнокодеру - пускай пашет все выходные, раз нормально писать не умеет. В следующий раз может поумнее.
Мне тоже дрисню на ноде ванильный жс присать приходилось как-то. Экспресс, вебсокеты и прочая хрень. На пхп код гораздо приятнее выглядит, и понятно почему ТС набирает обороты.
Делал кучу постоянно работающих скриптов на пхп, но они работали как кронжобы с стейтом в дб. Крон от минуты, но можно много процессов пускать каждую минуту как раз.
Процесс, работающий месяцами это тупость, даже если он не течет. Мало ли что случится.
У nginx на проде часто перезапускается? Почему он такой тупой - не хочет пререзапускаться!
Воркеры постоянно тасуются, как и следует. Что там делает мастер я хз, но соменваюсь, что он годами висит без перезапуска.
>и YAML-конфиги и аннотации
Хотя если быть правдивым давно пора от них отказаться и переходить на атрибуты, ямли это очень старый подход к роутингу или как описание для сущностей, аннотации чуть моложе, но всё равно костыль какой то.
>>247137
>Хочу опыта больше иметь с разными технологиями.
>нода
ПХП макаки ничего сложнее жабаскрипта или пэхапе не в состоянии обуздать? Нахуя нам после пыхи Шарп В решётку вообще на изи перекатиться т.к пыха много ООП плюшек переняла у джавы как и шарп, ГО, раст или же любой ЯП со строгой типизацией?! Неее мы не хотим расти как погремисты, всё что мы хотим это писать говнокод не понимаючи как он работает...
Мне просто лень искать про его перезапуски, гуляй пока.
>ничего сложнее жабаскрипта или пэхапе не в состоянии обуздать?
Что необходимо по работе - то и изучается. Никому в голову не придёт дрочить левый язык на выходных радо того, чтобы тебе что-то там доказать, мань.
Пыха вообще язык не для дроча и показухи всем - кокой ты у мамы погроммист, а для работы. И остальные подходы дальше такие же идут.
- выделяют серверу БД много памяти (десятки-сотни гигабайт), чтобы данные были в ней и не надо было лезть на диск, а также хорошие быстрые SSD, и много ядер CPU
- используют кеширование часто используемых данных. Выделяют много памяти и серверов под кеши.
- оптимизируют запросы, чтобы их было меньше и они быстрее выполнялись. Запрещаются любые запросы дольше нескольких мс. Собираются метрики и статистика, проблемные места выявляются и исправляются.
- если идет много чтения и не очень много записи, то можно применить репликацию - сделать один ведущий сервер и несколько ведомых, которые копируют данные с ведущего. Запись ведется на ведущий сервер, а чтение с ведомых. Так как их несколько, то нагрузка равномерно распределяется по ним.
- далее можно попробовать разнести базу данных на несколько частей и одни таблицы поместить на один сервер (при необходимости с репликами), а другие - на другой
- если и этого не хватает, то придется делать сложную операцию - шардинг. В этом случае создается много серверов БД и на каждом из них хранится часть данных. Например, пользователи 1-1000 и их данные хранятся на сервере 1, пользователи 1001-2000 на сервере 2 и тд. Сложных моментов тут два: надо переделывать приложение на поддержку такой схемы работы и надо реализовать балансировку: распределить данные так, чтобы нагрузка была равномерной. То есть не на каждый сервер положить по 1000 пользователей, а например на один - 500, но активных, на другой - 5000, но малоактивных.
Вот, ты уже вместо "php не приспособлен" пишешь "библиотеки не приспособлены". Давай уточнять дальше - не все библиотеки не приспособлены, а какие-то отдельные. Мог бы сразу писать какие именно, а не ходить вокруг да около.
Опять же, нет гарантий что в Питоне или Ноде не окажется такой же проблемной библиотеки. И, кстати, если библиотеки опенсурсные, то можно просто исправить их.
>>247180
YAML имеет тот плюс, что ты можешь просмотреть все роуты в одном месте и увидеть какие-то конфликты, что с аннотациями затруднено.
Бесплатный хостинг это что-то из нулевых.
Сейчас есть хостинг за копейки, есть впс за копейки.
Несколько лет назад на хероку была халява. Скорее всего и сейчас есть.
Да хотя это из пушки по воробьям, мне кажется для таких проектов лучше лара, но в учебных целях почему бы и нет
>для таких проектов лучше лара
Даже Лара слишком большая для такого - как-то писал для обучения и получилась несколько нелепая монструозная хрень с минимальным кодом. Ведь борда это обычная гостевуха + парсер постов для расстановки тегов и фильрации. Больше возни будет с админками\модерками, чем с основным функционалом.
Имхо лучше взять Слим и на его базе строить приложение, причём полезно продумать сборку в кэш уже готовых страниц и редактировать их только при добавлении постов, а вся эта хрень с Элоквентом и динамической сборкой для борды будет слишком медленно и в целом там самих моделей довольно мало получится.
С каких пор сборка своего фреймворка на базе Слима и необходимых композер-пакетов под задачу является велосипедом? Ты кроме Лары знаешь ещё что-то?
Да,рельсы
Этой штуке лет пять. Если повезет и все поднимется...
Смотри, анон, если твоя цель сделать борду - да, это норм гайд. Если же ты хочешь программировать, учиться, решать задачи - выкинь это все и начинай делать сам. Все готовые гайды от А до Я - ересь.
Сейчас посмотрел лару, бля, это пиздец какой-то, а не фреймворк. Одни синглтоны с уебанскими статическими методами, в елоквент-модели свойства в виде массива, мало пользуются аттрибутами.
Как бы симфони лучшим фреймворком в общем, так и остался.
Ну типа массив всех чисел,которые я накликал
>в елоквент-модели свойства в виде массива, мало пользуются аттрибутами
Это да, это прям позорище. Предлагаю выпилить массивы из ПХП.
Нет. Сервер не для твоих чисел писали.
Ты не выёбывайся, а пиши. Пока что смотреть не на что - любой движок больше твоего умеет.
Помню какой-то анон в одном разрделе на свою борду приглашал, а там у него была Симфони, вебмы, ещё 1000 чертей. Вот это вызывает респект.
$var = array(null);
var_dump(empty($var)); //false
var_dump(isset($var)); //true
$var[0] === null
Можно к вам перекатиться?
Хтмл+ цсс учил года 3 назад, sql тоже..
Если начну с пхп успею до июня вкатиться и трудоустроиться. А то контракт закончится на сисадмине, а профессия эта поднадоела.
Нельзя, я запрещаю вам перекатываться к нам.
Видел тебя в нюфаготреде или жс треде. Оставил идею вката во фронт? Ну и правильно. В пхп легче вкатиться
doc:
pattern: ^/api/(doc.json|doc)$
security: false
Там нет ограничения по времени? Я пытался там регаться написало что ошибка и хуй его знает что за ошибка
Да, и конкуренция больше
как вывести число повторов цикла сука у меня бомбит нахуй
В программировании ты должен полагаться не на интуицию ("это значение выглядит пустым"), а на определения из документации (какие значения считаются пустыми).
Вот, что написано в мануале про empty: https://www.php.net/manual/ru/function.empty.php
> Возвращает false, если var существует и содержит непустое ... значение...
Соответственно, true возвращается, если переменная не существует либо она содержит "пустое" (falsey) значение.
Что такое "пустое значение"? Это описано тут: https://www.php.net/manual/ru/language.types.boolean.php#language.types.boolean.casting
> При преобразовании в bool, следующие значения рассматриваются как false:
> само значение boolean false
> integer 0 (ноль)
> float 0.0 (ноль) и -0.0 (минус ноль)
> пустая строка, и строка "0"
> массив без элементов
> особый тип NULL (включая неустановленные переменные)
> объекты SimpleXML, созданные из пустых элементов без атрибутов, то есть элементов, не имеющих ни дочерних элементов, ни атрибутов.
Твой массив [null] не подпадает под определение "пустого" значения, так как он непустой - в нем есть один элемент. Следовательно, empty возвращает false.
Что касается isset, то с ним еще проще: он вернет true, если переменная существует и она не равна null. Переменная существует, массив с одним элементом [null] не равен null, потому isset вернет true.
Зря ты так. Java - мощный язык с богатыми возможностями, хотя и несколько многословный. Ты наверно просто не разобрался в нем глубоко, а просто скачешь по верхам, и оттого все тебе кажется сложным и непонятным.
А ведь вместо негодования ты бы мог извлечь из изучения Java полезные знания и навыки, паттерны, которые можно применять и в других языках.
Кстати, PHP многим похож на Java (что касается ООП).
>>250749
Да. Учти, что конфиг использует синтаксис YAML, потому тебе нужно также изучить виды строк в YAML и как в них экранируются символы. Возможно, что чтобы вписать в регулярку слеш, придется поставить два слеша. А возможно, что нет.
Сделай переменную, и каждый раз в цикле увеличивай ее на 1. После завершения цикла в ней будет искомое значение.
спасибо
Дай угадаю: питон и руби так же по недельке учил, да? А проекты твои это туториалы для нубов.
Иди куда-нибудь нахуй лучше.
У меня с ооп нет проблем. Я и с рекурсией и рефлексией и с коллекциями разобрался вполне себе легко. У меня проблема строго в спринге.
Да и то в голове больше. Я подумал что не хочу банками заниматься и прочей этой залупой, я хочу что-то ламповое. Работа занимает треть жизни и должна быть в радость.
Знания языка у меня ок, собесы легко проходил пока речь спринга не касалась. Я знаю что это для чего это и как устроено но просто не могу применить. Я привык читать литературу, смотреть видосики, внедрять новое к себе в проектик. А тут 10000 примеров и все хеловорды и туду листы.
Может это и отговорки слабака, не знаю.
Но изначально не было мыслей джавой заниматься, я хотел веб макакич, уж очень я сайтики люблю и сервисы всякие.
Я работал Django разрабом несколько месяцев, сам питон учил пол года где-то, руби, да недели 2-3 учил и запилил круд.
не, я не обсуждал это нигде. В жс не пытался даже смотреть. мне сказали джава ок, а как и почему не сказали. как и что я буду делать.
Вот работаю я сисадмином, тут все ультрапросто. Первые пару месяцев что-то новое, а дальше только рост зп, а я живу не деньгами, а временем потраченым, мне хочется большего и видеть результат своей работы.
Я нюфаня в этой теме, разъебите пожалуйста по фактам и докажите важность знаний.
Это вытеснило автономный местечковый макакинг образца нулевых-раннедесятых, хотя там давно уже потоптались соцсети. В глобальном плане ничего не меняет.
Короче я понял. Надо вкатываться. Какие подводные вообще есть в плане литературы или получения инфы/ поиска первой работы? в июле /июне хочу уже трудоустроиться
Что за тильда, это что-то типа битрикса? Я правда не знаю, что и битрикс из себя представляет и как на нем делают сайты.
Есть - документация называется. Расположена по адресу php.net и, между прочим, является одним из лучших примеров как надо делать документацию.
>каменты
Это которые под самой статьёй документации? Это не комменты, а советы и лайфхаки от других разрабов. Годнейшая вещь на самом деле - много полезного и интересного подсмотреть можно. Больше нигде такой системы не видел.
Ебанутые велосипеды и лойфхоки от индусов двадцатилетней давности, очень полезно, да.
Вообще, документация пхп это вечный памятник его хуевому начальному дизайну, с мильйоном упоротых функций с рандомными названиями.
Кисо обиделось.
Надо радоваться, что сейчас хорошо пилят, а не гореть по поводу тяжелого детства, это факт.
Это нормально вообще, что не могу выучить наизусть весь стек технологий и могу что-то делать только подглядывая в документацию?
Ты не практикуешь, вот и забываешь. А гуглить и смотреть в документацию по необходимости это норм.
Значит хуже. Чем удобнее и всеохватнее документация - тем лучше с точки зрения языка для которого она пилиться.
Что там должен и не должен знать программист - тема отдельного холивара.
Сделать запрос с фронта на бек.
Бамп вопросу.
У пхп не особо противный синтаксис, мне кажется си-подобность сильно упрощает жизнь. Еще у пхп адекватные скобочки по пср, сишарповые или гошные хуйня какая-то, в си тоже говно
Попробуй подумать логически. Допустим, кто-то хочет сделать сайт. Он может взять готовую CMS или сервис по созданию сайтов и создать сайт в нем без привлечения дизайнера или программиста. Но как только ему захочется нестандартное и уникальное оформление, тут нужен дизайнер и верстальщик, чтобы реализовать этот дизайн. А как только нужна нестандартная логика, нужен программист.
У разных заказчиков разные бюджеты и разные потребности.
Ты же почему-то не видишь большой картины, а думаешь, что рынок ограничен конструкторами сайтов. А так да, если ты можешь сделать только то, что можно сделать на конструкторе, то ты не очень-то вписываешься в рынок. Конструктор, в отличие от тебя, есть не просит и работает 24 часа в сутки.
Что касается магазинов, то шаблонные решения годятся лишь для маленьких магазинов или для офлайн-магазинов, для которых интернет не основной канал, а просто способ немного увеличить продажи. Если у тебя идет большой объем продаж через интернет, то без дизайнеров и программистов не обойтись:
- ты не хочешь дешевый шаблон, который встречается еще на куче сайтов, а хочешь фирменный стиль
- тебе нужны кастомные рассылки с красивыми картинками и аналитикой
- тебя не устраивает форма чекаута на 7 экранов, ты хочешь оптимизировать процесс покупки
- тебя не устраивает, что каждый товар надо отдельно открывать и редактировать, тебе нужны инструменты массовой модификации
- тебе нужны кастомные программы лояльности с заданными тобой правилами
- тебе нужны интеграции с платежными системами и службами доставки
- тебе нужна слежка за покупателями и аналитика
- тебе нужно отслеживание финансовых потоков
- тебе нужна интеграция с колл-центром
И так далее. Посмотри на крупные магазины вроде OZON - разве они сделаны на шаблонном сайте?
> с мильйоном упоротых функций с рандомными названиями.
Большинство названий идет от библиотек на Си. Ну нет в Си стандарта именования функций, и сишники, по моему сами не хотят чтобы он был, а хотят каждый быть уникальной снежинкой. У них и менеджера пакетов нет, да даже представления для строк нет.
Ну и PHP тут не одинок, открой, например, популярную библиотеку matplotlib на Питоне и оцени API: два набора функций (глобальное API на функциях и объектно-ориентированное), произвольный стиль именования функций. Вроде set_facecolor. Одно подчеркивание есть, а второго нету.
Не уверен. У Питона обычно одна страница на один модуль, и функции зачастую очень кратко описаны. А у PHP на каждую функцию или метод отдельная страница.
Также, у PHP описаны типы аргументов и возвращаемого значения, а в Python - нет.
Если уж приводить пример хорошей документации, я бы наверно взял Раст. Там даже примеры кода (которые работают как тесты) есть. Вот пример страницы: https://docs.rs/chrono/0.4.0/chrono/naive/struct.NaiveDateTime.html
Хотя в PHP тоже примеры кода бывают.
>>251805
Если ты забыл, как называется функция или какие у нее аргументы - то ок. А если ты общие принципы языка забываешь (например, что перед переменными надо ставить var/let/const) или синтаксис, то не очень хорошо.
Работа за деньги бывает разная. Можно пилить сложную систему на Симфони, можно менять цвет кнопок в шаблоне для CMS. И за то, и за другое платят деньги.
Ты можешь зайти на сайт поиска работы, сделать поиск по желаемому уровню дохода и посмотреть, что там требуется.
Значением массива является null и по этому массив не пустой, а isset проверяет на наличие переменной.
>>250530
>Можно к вам перекатиться?
Перекатывайся лучше в шарп, раст или ГО на худой конец.
1. На этих языках можно писать ещё что-то помимо сайтов.
2. Они типизированы и гораздо быстрее пыхи.
3. Будет больше понимания того, что пишешь, а не тупой говнокод сайтиков на фреймворках.
Пусть лучше жопа горит сильно сейчас, но от этих языков профита в разы больше чем от пэхапэ.
>>250970
>У меня с ооп нет проблем
Тем более, шарп очень много перенял у жавы, да и писать на нём одно удовольствие.
>>251771
>является одним из лучших примеров как надо делать документацию
Удвоил, сук попросту нет ничего похожего, чтобы коротко и по делу.
>php.net
Я чет не пынял, 7 и 8 версия языка параллельно существуют? Что за ребус?
мимо интересно
Интересно, что за система у них? Вроде бы всегда идет по порядку, а тут вчера обнова 8.10, сегодня 7.228, завтра 8.0.12. Че за?
Можешь попробовать перекатиться в дотнет и шарп, но один хуй там у тебя будут галеры и вместо спринга ASP.NET.
>>250970
>Я подумал что не хочу банками заниматься и прочей этой залупой, я хочу что-то ламповое
А что есть ламповое на современном рынке? Геймдев? Эмбеддед? Сомневаюсь в их ламповости. В энтерпрайзе ты работаешь в огромной конторе, которая финансируется за счет нефтяных денег и ей управляют друзья Путина, тот же Сбер, ВТБ и всякое подобное. В мелких конторах ты работаешь на какого-нибудь ИП Ашот. И в первом случае тебя ебут в жопу эффективные менеджеры и сотни каких-то руководителей хуй пойми зачем нужных, во втором случае тебя ебет лично кабан кабаныч или заказчики.
>Работа занимает треть жизни и должна быть в радость
Работа в радость это очень большая редкость. Рано или поздно все заебет. Поэтому лучше относись к работе просто как к способу заработка денег, причем не самого приятного, так жить будет гораздо проще.
>>250970
>Я знаю что это для чего это и как устроено но просто не могу применить.
Значит нужно просто больше практики со спрингом. Фреймворк поистине огромный, тяжелый и содержит много магии под капотом, но что поделать. Попробуй написать какой-нибудь клон авито для начала. Или систему для управления каким-нибудь выдуманным заводом. В общем главное больше практиковаться, тогда и начнет получаться.
Боюсь, что при написании бекенда на той же ноде или пхп у тебя возникнут аналогичные проблемы.
7 версия пыхи до сих пор актуальна и выпускают минорные обновления. Что непонятного?
Зачем поддерживать несколько актуальных версий вместо одной? Почему все не могут перекатиться на 8 версию?
Почему сначала идет пост 8.1.0 released, а затем 8.0.14 released?
Потому что в новых версиях есть breaking changes Кто то с 5.6 может перекатиться на 7, но не на 8. Не все захотят копаться в говне унаследованном из 5.6 ради переката на 8
Разве? Вроде только для 7.4 фиксы безопасности выпускают.
Если ты посмотришь, то там приписка: This is a bug fix release.
Видимо, разработчики исправили баги в версии 8 и заодно внесли исправления в версию 7 для тех пользователей, кто не обновился до 8-й версии.
Если у тебя проектик из 5 скриптов, то конечно обновиться не проблема, а если у тебя система из кучи сервисов с сотнями тысяч строк кода, то обновление, тестирование, миграция занимают значительное время и так просто их не сделать. PHP дает возможность таким проектам получать исправления багов и не вынуждает их бросить все и заниматься обновлением.
8.0 и 8.1 это как бы разные ветки, и обновляются независимо. Но опять же, я думаю, что новые фичи добавляются только в последнюю версию, а предыдущие версии получают только багфиксы и исправления безопасности.
Вот тут ты можешь увидеть правила релизов и какие версии поддерживаются сейчас: https://www.php.net/supported-versions.php
C&C для ботнета.
Нет смысла пилить что-то большое т.к один хуй посмотрят 3 класса максимум и этого будет с головой достаточно.
Запили CRUD по REST API с парочкой связанных сущностей.
Новичок из дна треда отправили к вам, сюда за вопросами:
Хочу вкатиться в битрикс, какие подводные? Вижу у себя в мухосрани дохуя вакансий с php+битрикс за условные 30к (лапшу с маслом)
Дваждую вопрос, это походу моя стезя.
Берешь первый попавшийся курс по битриксу, чтобы на примере какого проекта объясняли типа магазина, начиная от установки и заканчивая деплоем, смотришь уроки, пытаешься вникнуть во все сказанное и пишешь код копируя этот проект, потом грузишь его на свой гит и можешь идти искать работу, там уже на месте разбираться будешь, если не тупой то все нормально будет. Все это конечно при условии, что ты php/html/css уже знаешь.
>какие подводные?
Битрикс
Ты будешь на задворках остального мира разработки, будешь знать немного пхп, как верстать и писать лапшу на жиквери, короче вебмастер из нулевых. Ну и с инженерной точки зрения это говнище полное, ты можешь взять книги по архитектуре и патернам и смело начать растапливать ими печку, теперь ты будешь писать говно даже если ты этого не хочешь, а по другому иной раз никак. Но на хлеб с маслом пальмовым наверное заработаешь
Все! Получилось! Ура! Спасибо, уважаемые аноны за то, что выслушали меня.
Все! Получилось! Ура! Спасибо, уважаемые аноны, (ЗАПЯТУЮ КАК ПОСЛЕДНИЙ ДОЛБОЕБ ЗАБЫЛ) за то, что выслушали меня.
Реализовал я код, конечно, как последний долбоеб и ебанат. Такой убогой структуры кода я еще нигде и никогда не видел.
Не, ну вы просто гляньте на лаконичный, красивый и стройный код на скрине слева и на мое уебанское чудовище на скрине справа. Пиздец. Я в шоке.
Стоп, откуда у меня там взялась цифра 4000? Там же должно быть $monthlyPayment. Бляя... Пойду переделывать это дерьмо.
Какие требования и вопросы задают джуну на ларе? Нужно ли знать жс?
https://wordpress.org/plugins/bp-better-messages/
https://www.wordplus.org/downloads/bp-better-messages/
Обычно, введенные пользователем данные хранятся в базе "как есть", а все форматирование, защиты и прочие приколюхи делаются по факту получения и вывода.
В конце-концов, представь себе, что однажды ты захочешь сменить предназначение какого-то тега. Идти и писать миграцию всех постов - не круто.
Берёшь какой нибудь swoole и хуяришь без задней мысли.
а как их поймать?
file_get_contents?
net
Если хочешь $_POST то используй FormData https://learn.javascript.ru/formdata
Если хочешь отправлять json то используй
file_get_contents('php://input') https://www.php.net/manual/ru/wrappers.php.php
let formData = new FormData();
набери
var_dump($_POST);
дальше разберешься
по-нормальному вроде нужны заголовки и нужно отдавать строго plaintext
Хочу разобраться в одном вопросе. Есть сайт на вордпрессе, на дешевом шаред-хостинге. Нужно оптимизировать быстродействие сайта. Изучил методы повышения производительности сайтов на php и вордпрессе в частности, но не знаю как теперь это применить. Не понимаю как конфигурировать php. Локально я могу поставить composer, nginx + php-fpm, установить любые модули, выполнить любые настройки, но как это делать на шаред-хостинге? Там можно выбрать версию php, а больше нет.
Читай про суперглобальные переменные. В них хранятся все данные из поступающих запросов. Извлечь данные из массива думаю сможешь. Если нет, то научись, это не сложно.
Ты сам не очень разобрался, читатель. В $_POST содержатся данные, которые парсятся из тела реквеста при отправке формы.
https://www.php.net/manual/ru/reserved.variables.post.php
Если ты просто в аякс тело засунешь сериализованный жисон то в $_POST будет пусто
Если форма application/x-www-form-urlencoded то в теле запроса передается строка param1=value1¶m2=value2
И она как раз парсится пхп в массив $_POST
Ты читать по русски умеешь?
>php://input является потоком только для чтения, который позволяет вам читать необработанные данные из тела запроса.
все работает
-----жс-----
let xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:4000')
xhr.send(JSON.stringify([1, 2, 3]));
----пхп-----
$nums = file_get_contents('php://input');
print_r(json_decode($nums, true));
Иди лучше в кулинарный колледж.
https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Errors/Malformed_URI
Ты что то где то делаешь не так. Запасись терпением и начни все сначала.
>ниче не работает...
Это не конструктивный ответ. Опиши весь порядок действий и результаты каждого действия.
NULL
этого котика я делала много лет назад
приятно, что он стал маскотом пхп треда
сама-то я давно ушла вкатилась в жс, а пхп учила в рамках изучения бэкенда и повышения шансов на трудоустройство
этого котика я делала много лет назад
приятно, что он стал маскотом пхп треда
сама-то я давно ушла вкатилась в жс, а пхп учила в рамках изучения бэкенда и повышения шансов на трудоустройство
Глянул вакансии, вроде не очень-то и много их, ещё и Битрикс вонючий.
Добрый день. Где то около месяца изучаю html/css и хотелось бы узнать, а на каком вообще уровне нужно знать html и css для того, что бы можно было переходить к изучению php?
В вакансиях, для php джунов, требуют так же знания js. Нахуя? Т.е. мне еще и js придется выдрачивать?
Там еще больше требований с ждуна.
Молодец. Теперь прочитай и забудь через три месяца, или не забудь. Рассказывай "дремучим" пхп коллегам на митинге, что тестирование и непрерывная интеграция это важно. Они будут тебе поддакивать и считать минуты до конца. А ПМ скажет что потом обязательно, он всеми руками за, но сейчас нет времени на раскачку, сам знаешь, кстати когда таску доделаешь.
Чел, ну ты даешь. Зачем так больно делать?.......
Что нужно выносить в модель из контроллера? Я сейчас гоню весь прямо в контроллере. Просто потому, что так проще и я не понимаю, где граница между "так, это модель, а это контроллер". Хочу часть вынести в модели. Допустим, все обращения к БД надо убирать туда. А остальное? Так-то в контроллере вообще можно оставить один метод "пни модель - получишь результат, и тебе не к чему стремиться".
Я предпочитаю выносить в модель пихать по-минимуму логики потому, что AR-модели и без того со временем пухнут. Обычно только простые преобразования данных оставляю. Саму логику приложения пишу в сервисном слое.
Получается так: контроллер валидирует входящие данные и вызывает определённый сервис. Тот выполняет логику приложения и возвращает какие-то данные. Контроллер делает нужные проверки результата и формирует ответ.
Так все делают вроде, не?
>контроллер валидирует входящие данные
Мне казалось, что валидация - работа для мидлвере.
>вызывает определённый сервис. Тот выполняет логику
Логика в сервис провайдере? Как это обосновано? Я не спорю, просто непонятно.
Допустим, надо зарегистрировать пользователя.
Юзер дёргает за маршрут, отправляя в контроллер формреквест. Формреквест проверяет правильность заполнения полей, дальше в контроллере ты делаешь какие-нибудь дополнительные проверки и вызываешь метод специального класса - сервиса, UserAuthService::createNewUser(array $userData), например.
Сервис принимает уже отвалидированные данные, создаёт пользователя, сохраняет в бд, вызывает какую-то там логику, пишет в лог, запускает в очередь job с уведомлением о регистрации пользователя, звонит админу, вызывает небо и аллаха, а в контроллер возвращает только созданного юзера. После этого контроллер возвращает нужный ответ или ошибку.
Таким образом, тебе не нужно в контроллер подключать миллион классов, логгеров и всего прочего, он занимается только тем, чем и должен - обработкой запросов.
Где тут модель - в модели у тебя в основном методы для работы с бд (преобразование данных из бд в нужную форму, получение связанных сущностей, различные scope и тому подобное) и логика, напрямую привязанная к этой модели.
пример всратый, но в три часа ночи ничего лучше в голову не лезет
Спасибо.
А потом ты прочитаешь дядю Боба и Эванса и побежишь к батюшке исповедоваться...
почему то не открывается http://codedokode.github.io/phpbook
может кто то знает почему и надолго ли?
IsItDown показывает down
У меня обе ссылки нормально работают - исправляй у себя.
У меня тоже не открывается.
Спасибо за информацию. У меня сейчас открылось. Возможно, были какие-то временные баги.
Тут тоже пишет что все ок: https://downforeveryoneorjustme.com/phpbook.ga?proto=http
ряяя, лучше в pdf чтобы удобно искать и открывать сразу несколько страниц
>Контроллер делает нужные проверки результата и формирует ответ
Если эндпоинт валидирует принятые данные, тогда зачем ты ему снова отдаёшь данные которые нужно проверять?
Дошел до места правки public_functions при добавлении строки получения постов в виде массива ( $posts = mysqli_fetch_all($result, MYSQLI_ASSOC); ) такое вылазит
Какая-то ошибка с запросом, вот он и возвращает false вместо результата.
Создавай батник - запускающий скрипт и повесь его выполнение как задачу в планировщик.
зайти на https://www.php.net/manual/ru/language.oop5.php
и прочитать
еще можешь книжек почитать, самоучитель симдянова например
Че тут писать, начни писать хоть что одной стеной текста, со временем охуеешь как невозможно все это читать, начнешь заниматься инкапсулацией, кложурами всякими, вот тебе все ооп.
уже написал...
Это значит перечитывай доки до просветления. Телепатов не дождешься, они в отпуске до следующей кальпы.
>Можно к вам перекатиться?
Ко мне тут перекатился перец с 9 годами джявы за спиной, в край заебавшийся конпелировать эксэмэль в эксепшоны и возжелавший сменить стек на похапе. Так что вполне реально. После джавы современный похапе - как глоток свежего воздуха.
Советы уровня б. В том-то, блядь, и дело, что все сделано в строгом соответствии с доками.
Тогда иди батюшку с кадилом зови, чтобы чертей прогнал из кода.
Для начала надо изучить сам ООП. У нас в шапке есть учебник, в нем глава про ООП (с задачками), можно начать с нее. Она довольно просто написана.
Дальше можно почитать комментарии к задаче про список студентов: https://github.com/codedokode/pasta/blob/master/student-list.md - там все подробно расписано. Там требуется по сути сделать форму регистрации с применением ООП.
Идея ООП в том, что программа состоит из классов, каждый из которых имеет свою зону ответственности. Некоторые классы представляют "сущности" - например, класс Пользователь со свойствами Логин, Email, Хеш пароля. Некоторые классы являются "сервисами" или "менеджерами" и не содержат свойств, а лишь методы для управления сущностями.
Так абстрактно наверно сложно объяснить, напиши пример какой-то задачи (например: форма регистрации, страница товара в магазине итд), а я опишу, как ее можно сделать в ООП-стиле.
Ну, например, для страницы регистрации пользователя мы можем сделать такие классы:
- User - хранит информацию о Пользователе
- UserTableGateway - умеет сохранять объект Пользователя в БД и загружать из нее
- RegistrationData - представляет собой данные, введенные в форму регистрации
- RegistrationValidator - класс, проверяющий данные из формы на правильность
- RegistrationController -контроллер, управляет отображением страницы с формой и принимает данные, присланные методом POST
- Mailer - класс, который умеет отправлять письма
Вероятных причин множество:
- ты создал класс, но не зарегистрировал его в контейнере как сабскрайбер
- ты не указал, какие события слушаешь
- ты опечатался в названии события
- и тд
Для начала попробуй использовать описанную тут команду debug:event-dispatcher: https://blog.theodo.com/2015/03/debug-your-event-listeners-and-subscribers-easily-in-symfony-2/
Скорее всего ошибка выполнения запроса. Так как произошла ошибка, то в $result возвращается false, и из-за этого происходит ошибка в следующей строке, которую ты видишь на экране.
То есть ты видишь не исходную ошибку, а лишь ее последствия.
По умолчанию mysqli никак не сообщает об ошибках выполнения запроса и ты должен поступить одним из двух способов:
способ 1) ты должен после каждой команды писать код вроде:
$result = mysqli_query($conn, $sql);
if ($result === false) {
die("ОШИБКА В СТРОКЕ N: " . $conn->error);
}
То есть, тебе надо вставить аналогичный if после каждой команды вроде mysqli_query и подобных, которые что-то возвращают.
Этот способ имеет недостаток, что мы выводим текст ошибки на экран, что не должно использоваться на реальных сайтах (так как это раскрывает информацию о твоем приложении для атакующего).
способ 2) ты должен включить режим выброса исключений, который будет сам сообщать об ошибках в mysqli. Если ты не знаком с исключениями, советую про них почитать.
Для этого достаточно в начале кода до соединения с БД (до mysqli_connect) поставить строку:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Писать кучу if, как в способе 1, не требуется. Ошибки будут обнаруживаться и выводиться сами собой.
Мануал к этой функции тут: https://www.php.net/manual/ru/mysqli-driver.report-mode.php
Я советую использовать способ 2, только почитать про исключения. Также, можно написать автору статьи и спросить, почему он не использует в своем коде обнаружение и вывод ошибок. По моему, это просто не очень качественный код.
Ты можешь посмотреть примеры кода в мануале PHP - они используют mysqli_report: https://www.php.net/manual/ru/mysqli.query.php
Скорее всего ошибка выполнения запроса. Так как произошла ошибка, то в $result возвращается false, и из-за этого происходит ошибка в следующей строке, которую ты видишь на экране.
То есть ты видишь не исходную ошибку, а лишь ее последствия.
По умолчанию mysqli никак не сообщает об ошибках выполнения запроса и ты должен поступить одним из двух способов:
способ 1) ты должен после каждой команды писать код вроде:
$result = mysqli_query($conn, $sql);
if ($result === false) {
die("ОШИБКА В СТРОКЕ N: " . $conn->error);
}
То есть, тебе надо вставить аналогичный if после каждой команды вроде mysqli_query и подобных, которые что-то возвращают.
Этот способ имеет недостаток, что мы выводим текст ошибки на экран, что не должно использоваться на реальных сайтах (так как это раскрывает информацию о твоем приложении для атакующего).
способ 2) ты должен включить режим выброса исключений, который будет сам сообщать об ошибках в mysqli. Если ты не знаком с исключениями, советую про них почитать.
Для этого достаточно в начале кода до соединения с БД (до mysqli_connect) поставить строку:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Писать кучу if, как в способе 1, не требуется. Ошибки будут обнаруживаться и выводиться сами собой.
Мануал к этой функции тут: https://www.php.net/manual/ru/mysqli-driver.report-mode.php
Я советую использовать способ 2, только почитать про исключения. Также, можно написать автору статьи и спросить, почему он не использует в своем коде обнаружение и вывод ошибок. По моему, это просто не очень качественный код.
Ты можешь посмотреть примеры кода в мануале PHP - они используют mysqli_report: https://www.php.net/manual/ru/mysqli.query.php
Я поставил линукс в виртуалку
* /usr/bin/php8 /home/anon/hello.php
для каждой минуты
но чет кронтаб -л не хочет показывать что я сохранил
Ага, спасибо, теперь видно из-за чего ошибка
SOLID можно почитать, но если ты не разбираешься в основах ООП, и не пробовал писать ООП-код, то ничего не поймешь. Это довольно аюстрактные принципы.
>>260449
А ты правильное число звездочек поставил? Ты кронтаб редактировал правильной командой? Кронтаб от того пользователя, от которого нужно?
> if false === false, ты серьёзно?
Ты бы писал, что именно не так. По моему, код правильный.
> о Принципе подстановки Лисков?
Допустим, у нас есть класс A и код, который принимает объект класса A и что-то с ним делает. Мы пишем класс B, который наследуется от A:
class B extends A { ... }
Принцип подстановки Лисков говорит, что если мы в этот код передадим объект класса B вместо A, то код должен работать корректно. Он может работать по-другому и дать другой результат, но не должен выдавать ошибок.
То есть: в код, принимающий объект класса A, можно передать объект его наследника и все должно работать.
По этой причине ты, например, не можешь при наследовании удалить метод из класса или заменить публичный метод на приватный, так как это сломает код, который вызывает этот метод.
По этой же причине при наследовании нельзя добавить в метод аргументы без указания значений по умолчанию. То есть, если в классе A был метод:
doSomething($a)
то ты не можешь в классе B заменить его на:
doSomething($a, $b)
так как это сломает совместимость.
> if false === false, ты серьёзно?
Ты бы писал, что именно не так. По моему, код правильный.
> о Принципе подстановки Лисков?
Допустим, у нас есть класс A и код, который принимает объект класса A и что-то с ним делает. Мы пишем класс B, который наследуется от A:
class B extends A { ... }
Принцип подстановки Лисков говорит, что если мы в этот код передадим объект класса B вместо A, то код должен работать корректно. Он может работать по-другому и дать другой результат, но не должен выдавать ошибок.
То есть: в код, принимающий объект класса A, можно передать объект его наследника и все должно работать.
По этой причине ты, например, не можешь при наследовании удалить метод из класса или заменить публичный метод на приватный, так как это сломает код, который вызывает этот метод.
По этой же причине при наследовании нельзя добавить в метод аргументы без указания значений по умолчанию. То есть, если в классе A был метод:
doSomething($a)
то ты не можешь в классе B заменить его на:
doSomething($a, $b)
так как это сломает совместимость.
Чел, солид это архитектурные принципы, а не про стиль кодирования уровня не пишите методы на три экрана. Если ты делаешь в своем коде $person instanceof Manager, то ты значит нарушил принцип подстановки и пытаешься его обойти. Посмотри например паттерн посетитель, он как раз про то когда убираем проверку типа в пользователе
>Ты бы писал, что именно не так. По моему, код правильный.
В ИФе который принимает булево ты сравниваешь булево с булевым.
!$result было бы куда лучше, да и если прилетит null например как ты считаешь его обработает твоё тождественное сравнение? Правильно, такое сравнение пропустит null т.к (null !== false) -> true
Да и сравнивать булево с булевым есть тавтология.
>$somethingIsTrue == false
Лол.
Теперь открываем учебник и учимся нормально называть переменные.
Ты забыл написать $imNanosekPomidorManyaIsFalse == true, макака.
Скачал эту dll, кидал и в C:\Windows\SysWOW64, и в папку с самой программой, и ничего, всё так же пишет, что не найдено. Куда эту dll забрасывать?
Автоматическое устранение так же ничего не дает
Либо ставь линупс хоть в виртуалку, а в него докер либо ты не нужен. Честно, чел. Ты сейчас занимаешься мозгоебством, а не учишься решать проблемы которые у тебя будут на проде.
Нахуя докер нужен? Посмотрел сколько он занимает места и решил что буду продолжать сидеть с xampp,
Плюс по отзывам докер отваливается от каждого обновления.
Ну если ты сидеть собираешься, а не работать в конторе где деньги платят, тогда другое дело...
Понял, спасибо, добра
Слушай я не спорить пришел, особенно с человеком который где-то там работает, нахуй ты это делаешь, тебе нравится самоуверждаться?
Я тебе конкретный тематический вопрос, мне реально интересно было бы послушать советы опытного, заодно с упоминанием подводных камней.
Докер это виртуалка на облаке майкрософта где ты можешь среды выбирать чи що? Почему он столько весит?
И разве инструменты не должны облегчать работу, а не наоборот? Тут люди пришли на пыхыпы писать вещи, а не докер пердолить, например, а ты это показываешь так, что работа будет связана напрямую с пердолингом докера, спрашивается, зачем такое нужно.
Может он сайтики на вордпресс пилить собрался, а ты со своим докером к нему лезешь. Поехал уже?
Здесь клуб любителей виндоуз? Что ты пришел спрашивать какие-то ебанутые кейсы с которыми опытный разработчик не сталкивается. Потому что пользуется стандартными инструментами,а винду использует дома для игр. Докеризация сейчас почти во всех, даже мелких конторах. Несколько контор поменял и везде был докер и по 10 раз на собесе спрашивали, знаешь докер? с докером знаком? бухал с докером на брудершафт?
А может быть он просто заблудился в начале пути и ему надо помочь, а не отвести на помойку с вордпресами?
Наверни свежий курс Лаврика, только что на складчинах появился.
доступ к таким классам через намспейсы?
Накатил wsl2 на винду, накатил docker desktop, работает как часы, проекты держу в хомяке дистра, который на wsl2 крутится, команды в линуксовый терминал ввожу. И никакой ебли с виртуалками и дуалбутом. Да, я знаю, что wsl - это виртуалка.
Смотрю как соевый поридж выучил одну простенькую технологию, научился пилить конфиги для неё и уже везде с ней лезет, искренне полагая, что только так делать правильно.
Дедуля, речь не о том. Шаред хостинги это хуйня из 90-х и нулевых, когда не было виртуализации и вообще не быбло нихуя, поэтому пихали тысячу сайтов на один сервер с одним сетапом. Про распределение ресурсов и безопасность нет и речи. Это каменный век.
Сейчас впс стоит копейки и там разворачивается все что угодно.
Что, нету?
А я так хотел послушать про заливку говна по фтп, пхпмайадмин, письма хостеру с просьбой изменить настройку или включить экстеншены или разрешить порт 25. Вот это были технологии, не чета порриджевому говну.
вот что я вчера наговнокодил лол
Под простой сайтец тоже ВПС покупаешь, докер ставишь, поехавший?
Давайте разберем 2 заблуждения про Докер.
Первое: якобы Докер придумали для того, чтобы разработчик не мучался с установкой Апача и PHP на компьютер. Неверно! Докер придумали, чтобы заработать на тех, кто деплоит сложные микросервисные приложения в дорогие облачные провайдеры. Если у тебя сложное микросервисное приложение (то есть, ты можешь позволить себе нанять много инженеров) и ты используешь дорогой облачный провайдер вроде AWS, то у тебя наверно много денег и ты купишь корпоративный тарифный план. Докер написан ради таких клиентов и ради решения их проблем. А не ради бедняков, у которых нет денег даже на хостинг и которые не способны установить Apache на винде.
Ну например: он помогает перейти с одного дорогого облачного провайдера на другой дорогой без переписывания кода.
Второй миф: Докер это хорошее, грамотно спроектированное решение. Опять мимо! Давайте подумаем, что нужно, чтобы задеплоить приложение на сервер? Нужно установить это приложение со всеми требуемыми зависимостями. То есть, нужен менеджер пакетов. Но не обычный менеджер пакетов, а такой, который умеет ставить пакеты в определенную папку (а не глобально в /usr), умеет ставить одновременно разные версии одного пакета итд. Ну и хорошо бы, чтобы все устанавливаемые приложения и библиотеки были кроссплатформенными. То есть, нужен какой-то фреймворк или какое-то универсальное API, и нужно перевести все библиотеки на него, чтобы они работали одинаково под любой ОС.
И что же? Команда Докера написала хороший пакетный менеджер? Нет, они написали костыль: виртуальную машину, в которую ты bash-скриптом скачиваешь пакеты и компилируешь их там. При этом:
- на каждую команду Докер создает новый образ диска, потому люди пишут по 30 команд в одну строку, чтобы обойти эту "фичу". Вопрос: зачем нужна такая фича, которую все пытаются обойти?
- в виртуальной машине остается куча мусора вроде исходников, промежуточных файлов компиляции и тд.
- чтобы запустить образ Докера, нужен демон. Этот огромный демон, запускаемый из-под рута - отличная поверхность для атаки. Совсем не то, что хочется иметь на продакшен-сервере.
- вместо написания кроссплатформенного менеджера пакетов и универсального кроссплафторменного фреймворка библиотек и приложений Докер под Windows и Mac просто запускает тяжелую, медленную виртуальную машину с ядром Линукса, кучей системных служб, драйверами. В итоге каждый Интернет-пакет проходит через несколько слоев драйверов. Это просто не может работать быстро.
- публичные Докер-образы часто не обновляются и могут содержать уязвимости
То есть, Докер это костыль, а не решение сложной проблемы создания универсальной, платформонезависимой среды исполнения приложений и универсального пакетного менеджера.
Давайте разберем 2 заблуждения про Докер.
Первое: якобы Докер придумали для того, чтобы разработчик не мучался с установкой Апача и PHP на компьютер. Неверно! Докер придумали, чтобы заработать на тех, кто деплоит сложные микросервисные приложения в дорогие облачные провайдеры. Если у тебя сложное микросервисное приложение (то есть, ты можешь позволить себе нанять много инженеров) и ты используешь дорогой облачный провайдер вроде AWS, то у тебя наверно много денег и ты купишь корпоративный тарифный план. Докер написан ради таких клиентов и ради решения их проблем. А не ради бедняков, у которых нет денег даже на хостинг и которые не способны установить Apache на винде.
Ну например: он помогает перейти с одного дорогого облачного провайдера на другой дорогой без переписывания кода.
Второй миф: Докер это хорошее, грамотно спроектированное решение. Опять мимо! Давайте подумаем, что нужно, чтобы задеплоить приложение на сервер? Нужно установить это приложение со всеми требуемыми зависимостями. То есть, нужен менеджер пакетов. Но не обычный менеджер пакетов, а такой, который умеет ставить пакеты в определенную папку (а не глобально в /usr), умеет ставить одновременно разные версии одного пакета итд. Ну и хорошо бы, чтобы все устанавливаемые приложения и библиотеки были кроссплатформенными. То есть, нужен какой-то фреймворк или какое-то универсальное API, и нужно перевести все библиотеки на него, чтобы они работали одинаково под любой ОС.
И что же? Команда Докера написала хороший пакетный менеджер? Нет, они написали костыль: виртуальную машину, в которую ты bash-скриптом скачиваешь пакеты и компилируешь их там. При этом:
- на каждую команду Докер создает новый образ диска, потому люди пишут по 30 команд в одну строку, чтобы обойти эту "фичу". Вопрос: зачем нужна такая фича, которую все пытаются обойти?
- в виртуальной машине остается куча мусора вроде исходников, промежуточных файлов компиляции и тд.
- чтобы запустить образ Докера, нужен демон. Этот огромный демон, запускаемый из-под рута - отличная поверхность для атаки. Совсем не то, что хочется иметь на продакшен-сервере.
- вместо написания кроссплатформенного менеджера пакетов и универсального кроссплафторменного фреймворка библиотек и приложений Докер под Windows и Mac просто запускает тяжелую, медленную виртуальную машину с ядром Линукса, кучей системных служб, драйверами. В итоге каждый Интернет-пакет проходит через несколько слоев драйверов. Это просто не может работать быстро.
- публичные Докер-образы часто не обновляются и могут содержать уязвимости
То есть, Докер это костыль, а не решение сложной проблемы создания универсальной, платформонезависимой среды исполнения приложений и универсального пакетного менеджера.
Во-первых, я написал про LSP, а не про "стиль кодирования". Во-вторых, по моему ты путаешь назначение паттерна Посетитель. Он придуман для того, чтобы разделить обход сложной структуры и операции на ее узлах (например: обход дерева).
>>261183
Каждый класс в своем файле. Интерфейсы делать только там, где это нужно. Неймспейсы использовать. Следовать PSR-4. Вот урок: https://github.com/codedokode/pasta/blob/master/php/autoload.md
>>261501
Проблемы:
- в одном файле должен быть один класс, имя класса и файла соответствуют друг другу в соответствие с PSR-4
- поля должны быть названы осмысленно, а не $var
- названия классов неудачные. Правильнее было назвать LoginValidator, EmailValidator, итд. И логичнее проверяемое значение не передавать в конструктор, а в функцию проверки.
- возвращаемые данные должны быть одного типа (или тип + null/false). А ты в валидаторе Email возвращаешь то число, то строку.
Ты нарушаешь принцип разделения ответственности (каждый занимается своим делом). Задача валидатора - проверить правильность, но не выводить текст на экран. Ты должен возвращать ошибку через return, а не выводить ее. Вывод ошибки будет делаться где-нибудь в шаблоне и это будет делать другой код.
а ты не из дс2?
Что за графоманский бред. Пишешь за 5 минут docker-compose.yaml из готовых образов и запускаешь, или отдаешь другу и он запускает
командой docker-compose up
$sth->execute();
$result = $sth->fetch(PDO::FETCH_BOTH);
Это верный код?
У меня тоже почему-то белую страницу показывает.
>>262152
Ну как сказать. Он берет только первую строку результата, а наверно надо взять все. И вместо FETCH_BOTH наверно надо FETCH_ASSOC ?
>>262255
Массовая рассылка - это когда ты берешь из БД миллион юзеров и в цикле каждому отправляешь письмо. Непонятно, зачем тут лишняя прослойка в виде RabbitMQ.
RabbitMQ для случаев, когда ты например хочешь при регистрации отправить письмо в фоне, чтобы не замедлять процесс. Но массовая рассылка и так делается фоновым скриптом и RabbitMQ тут только мешает.
>>262317
Непонятно, почему. Ты бы хоть подробности описал.
Мой стек:
PHP 7 и 8, Symfony, Doctrine ORM, Zend, MySQL, Clickhouse, Redis, AWS, Google Analytics+Google Search Console, Mercure.
Писал и на ларке даже немного, небольшие навыки девопса. JS знаю неплохо со всякими вебпаками
Сколько требовать деняк? 1000$ норм?
Либо ты пиздишь и знаком со всем перечисленным на уровне хелловорлдов, либо очень сильно себя недооцениваешь.
Ну блин, хз. Во-первых у меня даже трудовой нет. Суммарно у меня 1,5 года опыта в айти, из них последний год на мелкой галерке неофициально работал за 500$.
Английского устного у меня нет, писать могу несложными предложениями. В универе я не учился.
Любые задачи, связанные с этим стеком, делал, почему хелоуворлд, нет. Где-то больше знаю, где то конечно меньше.
Сейчас вот прям недавно начал искать работу, каждая вторая хрюша разворачивает, узнав что я не могу разговаривать на английском.
Я сам в Беларусобульбашии живу. Может мне стоит нахуй слать беларуских хрюш и на россию смотреть? Может у вас адекватнее?
Я просто сам в мухосрани живу, в Беларуси 1000$ это огромные деньги, я таких никогда не видел ещё.
Сколько надо просить, не знаю. Я боюсь что даже на 1000$ буду искать долго и помру с голода. Я не очень верю, что в айти дефицит, хрюши тупо спамят, а оффер хрен вышлют, думаю.
Забудь про местных хрюш как про страшный сон и иди на джинн к хохлам. Оторвут с руками с таким стеком.
спасибо за совет, попробую. Пока на линкедине отвечал только, ну там только беларуские хрюши и писали.
Буду тут репортить, как что нового будет в поисках.
В рабсии Битрикс актуальнее
В свое время так делал задачу: https://github.com/Back1ng/vector
Тоже готов послушать критику
Учиться тебе ещё и учиться. Ни солида, ни ооп нормального, тайпхинты где? Почему так много публичных методов в одном классе? Почему классы в одном файле? Где автозагрузчик и нэймспэйсы? Вёрстка кривая, в блокноте чтоль писал?
Годится, если ты только сел изучать php. Садись фреймворк изучать любой, он поможет писать код намного правильнее.
Зачем ты логику пишешь в индексном файле и тем более функции там создаёшь? Изучи MVC. Фабрику изучи, чтоб не повторялся код. Интерфейсы изучи зачем и как писать. Тоже дели код, в идеале ОДИН ПАБЛИК МЕТОД на класс, что вы всё в один класс пихаете. Коммиты пиши чаще и нормально называй.
В целом получше, видно что старался, но надо учиться. Тоже за фреймворк садись и повторяй за опытными по гайдам.
>> Фабрику изучи, чтоб не повторялся код
Не вижу как мне здесь поможет фабрика для не повторения кода. Какого именно кода?
>> в идеале ОДИН ПАБЛИК МЕТОД на класс
Не могу такого представить, разве что разделить какие-нибудь методы на трейты.
>в идеале ОДИН ПАБЛИК МЕТОД на класс
Бред. Публичных методов нужно столько, сколько нужно для работы. Все остальные закрытые.
Чет я вообще не понимаю, почему не работает 2 задача
<?php
eror_reporting(-1);
echo "Бросаем кубик...\n";
&random = mt_rand(1, 6);
echo "Выпало &random \n";
Это называется принцип единственной ответственности. Нет ни одной причины нарушать его. Если у тебя 2 публичных метода - значит это 2 логики, которые можно вынести на 2 класса.
Публичные методы не имеют никакого отношения к SOLID. Это просто модификаторы доступа.
Ты видел контроллеры например? Обычный Ларовский контроллер ресурсный, где 4 или 5? публичных метода? А как насчёт шаблона Builder, который хорошо сочетается с fluent interface?
Например:
$windowBuilder = new WindowBuilder;
$windowBuilder->setWidth(600)
->setHeight(800)
->setColor(111)
->setName('new window')
->make();
Это всё публичный методы класса WindowBuilder.
>Чет я вообще не понимаю, почему не работает 2 задача
Этого мало для помощи - что выдаёт, сам что думаешь? Не покатит просто вывалить сюда код и ждать ответа - тут зарплатных нет и все сидят только по-фану.
Достаточно одного, но желательно его знать хорошо. Фреймворки спрашивают для того, чтобы убедиться, что разработчик знает распросранённые паттеры и решения, и не будет городить велосипеды с больной фантазией.
я хз че думать, уже 10 раз перечитал урок, вообще не врубаюсь. Очевидно в 4 строке ошибка, возможно нельзя одной строкой функцию в переменную запихнутьбля и почему решение нельзя было под спойлер запихнуть или в конце пособия оставить
Чел несет хуйню потому что многие принципы состоящие из одного предложения можно трактовать любой бредовой головой по-разному. SRP это про то что у класса должна быть одна причина для изменений, как сказал Мартин. Вот и ебись теперь с такой формулировкой как хочешь.
Синтаксис очень важен - канплуктер это очень тупая, но исполнительная машина и ей всё прям до буквы надо пояснять.
Ты планируешь сделать класс Профессия изменяемым. Но это не очень разумно. Трудно представить ситуацию, когда тебе надо понизить зарплату всем Инженерам во всем мире. Обычно тебе требуется поменять зарплату только части инженеров.
Поэтому возможность менять свойства Профессии несет мало пользы, и наоборот, создает риск ошибки, когда ты нечаянно изменениями затронешь больше работников, чем планировал. Такой класс лучше сделать неизменяемым (иммутабельным). В PHP8.1 появится ключевое слово readonly для дополнительных гарантий неизменности, а пока можно сделать, чтобы изменяющие методы создавали и возвращали новый объект Профессии.
Как тогда менять зарплату работникам? Есть два варианта: либо сделать в работнике свойства, которые переопределяют размер зарплаты, либо при изменении зарплаты создавать новую "профессию" и присваивать работнику.
> class Employee
> public string $department; //string
Логичнее хранить не название Департамента, а сам объект. Тогда можно легко писать конструкции вида:
$person->getDepartment()->getEmployeeCount()
А с твоим подходом нужны лишние поиски по названию. Плюс, в твоем варианте можно присвоить несуществующее название Департамента, а если присваивать объект, то такой проблемы нет.
> $baseRate;
> $is_boss;
Нужно использовать одинаковый стиль наименования.
> //как создать массив объектов?
Пока в PHP нельзя указать тип объектов, который будет храниться в массиве. Проверяй тип при добавлении в массив.
> $this->staffing[] = ['employee'=>$employee, 'amount' => $amount];
Ох, сколько ты будешь мучаться во второй части задачи из-за такой формы хранения информации...
> else {
> echo 'Такой департамент не существует!';
Правильно в такой ситуации выбрасывать исключение. Нужно прочесть урок https://github.com/codedokode/pasta/blob/master/php/exceptions.md и сделать свой класс для исключения.
И еще один момент. Сейчас у тебя все свойства публичные. Это значит, что их можно поменять из любого места кода и класс не может это никак проконтролировать. Ну например, можно поставить работнику ранг = 9 или добавить в массив департаментов не-департамент. Понятно, что специально вредить никто не будет, но можно это сделать по ошибке.
Если ты сделаешь свойства приватными и сделаешь возможность их изменения только через публичные методы (с проверками), то ты можешь защититься от ошибок и улучшить понятность кода. Плюс, это упростит изучение класса: чтобы понять, как используется класс, мы смотрим только на публичные элементы и игнорируем все приватное.
В остальном пока все хорошо.
Ты планируешь сделать класс Профессия изменяемым. Но это не очень разумно. Трудно представить ситуацию, когда тебе надо понизить зарплату всем Инженерам во всем мире. Обычно тебе требуется поменять зарплату только части инженеров.
Поэтому возможность менять свойства Профессии несет мало пользы, и наоборот, создает риск ошибки, когда ты нечаянно изменениями затронешь больше работников, чем планировал. Такой класс лучше сделать неизменяемым (иммутабельным). В PHP8.1 появится ключевое слово readonly для дополнительных гарантий неизменности, а пока можно сделать, чтобы изменяющие методы создавали и возвращали новый объект Профессии.
Как тогда менять зарплату работникам? Есть два варианта: либо сделать в работнике свойства, которые переопределяют размер зарплаты, либо при изменении зарплаты создавать новую "профессию" и присваивать работнику.
> class Employee
> public string $department; //string
Логичнее хранить не название Департамента, а сам объект. Тогда можно легко писать конструкции вида:
$person->getDepartment()->getEmployeeCount()
А с твоим подходом нужны лишние поиски по названию. Плюс, в твоем варианте можно присвоить несуществующее название Департамента, а если присваивать объект, то такой проблемы нет.
> $baseRate;
> $is_boss;
Нужно использовать одинаковый стиль наименования.
> //как создать массив объектов?
Пока в PHP нельзя указать тип объектов, который будет храниться в массиве. Проверяй тип при добавлении в массив.
> $this->staffing[] = ['employee'=>$employee, 'amount' => $amount];
Ох, сколько ты будешь мучаться во второй части задачи из-за такой формы хранения информации...
> else {
> echo 'Такой департамент не существует!';
Правильно в такой ситуации выбрасывать исключение. Нужно прочесть урок https://github.com/codedokode/pasta/blob/master/php/exceptions.md и сделать свой класс для исключения.
И еще один момент. Сейчас у тебя все свойства публичные. Это значит, что их можно поменять из любого места кода и класс не может это никак проконтролировать. Ну например, можно поставить работнику ранг = 9 или добавить в массив департаментов не-департамент. Понятно, что специально вредить никто не будет, но можно это сделать по ошибке.
Если ты сделаешь свойства приватными и сделаешь возможность их изменения только через публичные методы (с проверками), то ты можешь защититься от ошибок и улучшить понятность кода. Плюс, это упростит изучение класса: чтобы понять, как используется класс, мы смотрим только на публичные элементы и игнорируем все приватное.
В остальном пока все хорошо.
ООП там вполне нормальный.
> Почему так много публичных методов в одном классе?
Потому что с классом можно сделать такое количество операций. Эту претензию я вообще не понял. Ты что ли все классы по одному методу делаешь? Тяжело читать такое.
> Почему классы в одном файле? Где автозагрузчик и нэймспэйсы?
Потому что это лишнее усложнение для учебной программы из трех классов для изучения основ ООП. Тем более что мы пока не изучили неймспейсы.
Плюс, ты советуешь изучать фреймворк, но сначала надо изучить ООП, иначе ничего будет не понятно. Твой совет неправильный.
В Employee не очень удачная функция inverseLeader. Обычно нам надо либо назначить человека лидером, либо лишить этого звания. Соответственно, код вида "назначить лидером" получается логичный и понятный. А вот код "поменять признак лидера на противоположный" менее понятный, так как из него не очевидно, что именно делается. Надо изучать предудыщий код, а может этот работник получается в какой-то другой функции в другом месте кода. Это затрудняет чтение кода и повышает вероятность ошибки при правке.
> $employee = serialize($employee);
> unserialize($employee);
Правильно тут использовать оператор clone, но может понадобиться написать магический метод __clone, чтобы при клонировании клонировались объекты вроде Job внутри работника.
serialize имеет тот недостаток, что не все объекты можно сериализовать. Например, нельзя сериализовать дескриптор открытого файла, дескриптор соединения с базой данных.
> public function dismissEmployee(
Тут, по-моему, можно использовать array_search с параметром true для поиска работника в массиве.
> return new NullEmployee();
Это сделано, по моему, неудачно. Лучше было бы возвращать null. Во-первых, класс NullEmployee не заполняет поля вроде Job, rang и обращение к его методам вроде getRate() будет вызывать ошибки. Если уж ты создаешь объект, то надо создавать полноценный объект с заполеннными полями. Во-вторых, возврат объекта вместо null скрывает ошибку в коде, когда программист думает, что у любого департамента есть лидер, а в реальности его может не быть. Допустим, мы хотим сгенерировать ответ на обращение пользователя, и программист забыл поставить проверку, что у департамента есть лидер:
echo "Спасибо за обращение. С уважением, {$dep->getLeader()->getName()}\n";
В таком случае, лучше бы код свалился на попытке получить имя из null. А он отработает и вернет некорректный ответ.
Null Object наверно не подходит для этой ситуации.
В классе Job проблема в том, что он обращается к полям вроде rate, которых в нем нету. Это неправильно. Ведь любой может создать класс-наследник и не добавить нужные поля, и получится ошибка. Класс не должен обращаться к полям/методам, которые появятся только в его потомках. Также, у тебя никак не документировано, что нужно добавить поля при наследовании, и никак не проверяется это.
В твоем случае надо сделать абстрактные методы вроде getDefaultRate, и тогда PHP гарантирует, что нельзя будет унаследоваться, не определив эти функции. А программист, видя абстрактные методы, легко поймет, что надо их реализовать.
> array_map(function ($employee) use ($department) {
> $department->dismissEmployee($employee);
Когда видишь в коде array_map, то ожидаешь, что ее используют для создания нового массива. Ты же используешь ее для побочных эффектов в виде увольнений. Это нелогично. Тут нужно использовать цикл или array_walk.
> $employee->getJob()->setRate(1100)->setCoffee(75);
Не очень хорошо, что Job изменяемый. Что, если ты случайно присвоишь двум работникам один Job? Тогда и зарплата поменяется сразу у двух. Если бы объект Job был неизменяемым и setRate() создавала бы новый объект Job, такая ситуация была бы исключена.
> $leader = $department->getLeader();
> if (!($leader instanceof Analyst)) {
Здесь ошибка: getLeader() возвращает объект класса Employee, и instanceof всегда будет возвращать false. Тестирование программы выявило бы ошибку. Надо было мне (автору задачи) написать ожидаемые цифры, чтобы можно было сверить свою программу с ними.
Для смены лидера логично было бы сделать функцию в Департаменте. Наверно, все-таки это ответственность Департамента.
В Employee не очень удачная функция inverseLeader. Обычно нам надо либо назначить человека лидером, либо лишить этого звания. Соответственно, код вида "назначить лидером" получается логичный и понятный. А вот код "поменять признак лидера на противоположный" менее понятный, так как из него не очевидно, что именно делается. Надо изучать предудыщий код, а может этот работник получается в какой-то другой функции в другом месте кода. Это затрудняет чтение кода и повышает вероятность ошибки при правке.
> $employee = serialize($employee);
> unserialize($employee);
Правильно тут использовать оператор clone, но может понадобиться написать магический метод __clone, чтобы при клонировании клонировались объекты вроде Job внутри работника.
serialize имеет тот недостаток, что не все объекты можно сериализовать. Например, нельзя сериализовать дескриптор открытого файла, дескриптор соединения с базой данных.
> public function dismissEmployee(
Тут, по-моему, можно использовать array_search с параметром true для поиска работника в массиве.
> return new NullEmployee();
Это сделано, по моему, неудачно. Лучше было бы возвращать null. Во-первых, класс NullEmployee не заполняет поля вроде Job, rang и обращение к его методам вроде getRate() будет вызывать ошибки. Если уж ты создаешь объект, то надо создавать полноценный объект с заполеннными полями. Во-вторых, возврат объекта вместо null скрывает ошибку в коде, когда программист думает, что у любого департамента есть лидер, а в реальности его может не быть. Допустим, мы хотим сгенерировать ответ на обращение пользователя, и программист забыл поставить проверку, что у департамента есть лидер:
echo "Спасибо за обращение. С уважением, {$dep->getLeader()->getName()}\n";
В таком случае, лучше бы код свалился на попытке получить имя из null. А он отработает и вернет некорректный ответ.
Null Object наверно не подходит для этой ситуации.
В классе Job проблема в том, что он обращается к полям вроде rate, которых в нем нету. Это неправильно. Ведь любой может создать класс-наследник и не добавить нужные поля, и получится ошибка. Класс не должен обращаться к полям/методам, которые появятся только в его потомках. Также, у тебя никак не документировано, что нужно добавить поля при наследовании, и никак не проверяется это.
В твоем случае надо сделать абстрактные методы вроде getDefaultRate, и тогда PHP гарантирует, что нельзя будет унаследоваться, не определив эти функции. А программист, видя абстрактные методы, легко поймет, что надо их реализовать.
> array_map(function ($employee) use ($department) {
> $department->dismissEmployee($employee);
Когда видишь в коде array_map, то ожидаешь, что ее используют для создания нового массива. Ты же используешь ее для побочных эффектов в виде увольнений. Это нелогично. Тут нужно использовать цикл или array_walk.
> $employee->getJob()->setRate(1100)->setCoffee(75);
Не очень хорошо, что Job изменяемый. Что, если ты случайно присвоишь двум работникам один Job? Тогда и зарплата поменяется сразу у двух. Если бы объект Job был неизменяемым и setRate() создавала бы новый объект Job, такая ситуация была бы исключена.
> $leader = $department->getLeader();
> if (!($leader instanceof Analyst)) {
Здесь ошибка: getLeader() возвращает объект класса Employee, и instanceof всегда будет возвращать false. Тестирование программы выявило бы ошибку. Надо было мне (автору задачи) написать ожидаемые цифры, чтобы можно было сверить свою программу с ними.
Для смены лидера логично было бы сделать функцию в Департаменте. Наверно, все-таки это ответственность Департамента.
Нет, я не говорил, что надо каждое поле делать отдельным классом. Я лишь имел в виду, что каждый класс должен быть в отдельном файле.
В данном случае можно сделать один класс "валидатор", отвечающий за проверку данных, а в нем нужное количество методов.
>>265088
В индексном файле логика только для ручного тестирования программы. Сами классы оформлены как положено.
> Изучи MVC.
Это не веб-приложение, зачем тут MVC?
> Интерфейсы изучи зачем и как писать.
И зачем тут интерфейсы?
> Тоже дели код, в идеале ОДИН ПАБЛИК МЕТОД на класс, что вы всё в один класс пихаете.
Я плохо это понимаю. Вот у тебя есть класс Работник, у него есть методы получить зарплату, поменять зарплату, получить ранг, поменять ранг, и так далее. Ты предлагаешь его на 10 классов по одному методу разбить? Чушь какая-то.
Количество методов определяется количеством операций, которые можно выполнить над объектом.
Спасибо за комментарий, ОП.
>Ох, сколько ты будешь мучаться во второй части задачи из-за такой формы хранения информации...
Я так понял, что нельзя использовать объект в качестве ключа ассоциативного массива. А как еще можно хранить количество сотрудников с одинаковыми параметрами? Создать отдельный класс staffUnit, и использовать его объекты вместо массива ['employee'=>$employee, 'amount' => $amount] ?
А кто тебе сказал что Солид священная корова и контроллеры не нарушают Солид? ActiveRecord паттерн с моделями тоже нарушают, загугли.
Это исключения, для удобства не везде надо солид. Незачем модель делить. Но блять не для зелёных трейни, им надо солид пихать везде куда только возможно, потому что только с помощью солида ты будешь правильно писать приложения. У его нет ни билдеров, ни контроллеров, простые классы.
>>265336
>>ООП там вполне нормальный.
>>265338
>>И зачем тут интерфейсы?
>> зачем тут MVC?
>> солид это Чушь какая-то
>Количество методов определяется количеством операций, которые можно выполнить над объектом.
А нет анон, всё правильно делаешь, ты же у нас сеньёр-помидор, всё знаешь, опыта наверное лет 5 разработки на проде. Чего ещё ожидать от двача, в принципе, лол. На собеседованиях тебе быстро мозги вправят, погнав ссаными тряпками с твоим "да нахер здесь нужны интерфейсы с вашей расширяемостью", ахах.
Так что ты на правильном пути, так держать, анон
> Я так понял, что нельзя использовать объект в качестве ключа ассоциативного массива.
В массиве ключом может быть только число или строка. Но если ты используешь стандартный класс SplObjectStorage, то там можно использовать объекты как ключи.
Но я имел в виду не это. Твой способ хранения вполне подходящий.
Я имел в виду, что решение хранить сотрудников в виде групп одинаковых сотрудников помешает тебе при решении второй части задачи, когда тебе надо будет делать какие-то операции только с частью сотрудников. Дойдешь, увидишь.
> А нет анон, всё правильно делаешь, ты же у нас сеньёр-помидор,
А какая разница, какая у меня должность? Я стараюсь аргументировать, почему надо делать так или иначе, а ты просто приходишь и пишешь "так нельзя" без каких-либо пояснений. Так не годится.
а ты просил разжевать? Ты начал с пререканий, вместо мольбы подробнее пояснить. Я тебе что, училка в бесплатной гос.школе?
100$/час, разложу в скайпе по полочкам. Умей платить за информацию и чужое время, нахлебник. Тебе достаточно краткой характеристики твоего говнокода, ты даже за это спасибо не сказал. Можешь вообще даже ООП не использовать, мне как бы по барабану на тебя, лол.
>в идеале ОДИН ПАБЛИК МЕТОД на класс
Хуйня собачья. Для каждого закрытого свойства создаются открытые свойства, get set в большинстве случаев.
>>265170
>Публичных методов нужно столько, сколько нужно для работы
Тоже не совсем верно. Принцип единой ответственности нам гласит, что у одного класса должна быть одна ответственность.
Т.е например ты создал 2 закрытых свойства, написал для каждого геттер с сеттером и больше в этом классе методов быть не должно.
>>265227
>Публичные методы не имеют никакого отношения к SOLID
Вэб макака детектед. Прочитал, ничего не понял и выучил текст для собеседований так ничего и не поняв?
Для особо одарённых поясню, методы должны устанавливать значение для свойства или его предоставлять, но никак не манипулировать этим значением т.к это будет уже нарушать Принцип открытости/закрытости.
A class should have one, and only one, reason to change. R. Martin
Где? Если почитаешь Мартина, то найдешь, что он говорит о том что у кода должен быть один пользователь (один отдел компании со своими специфичными проблемами).
У него термин Actor используется
Принцип открытости/закрытости
Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification.
Ты как-то странно этот принцип понимаешь. Все тимлиды на собесе с тобой будут не согласны. Обычно от тебя ждут что ты скажешь: нельзя изменять существующий код, а только добавлять новый. Если код требует изменения существующих классов, методов при добавлении фичи, то это негодный код.
>ты создал 2 закрытых свойства, написал для каждого геттер с сеттером и больше в этом классе методов быть не должно
Дружок, ты дальше энтити-классов не проходил, да? Зачем ты лезешь к людям спорить о том, в чём не разбираешься? Если тебе интересно, то просто задай вопрос, а не пиши хуйню, покаывая себя клоуном.
1 строка это то, что в строке содержится. 2 строка, что получается вставить.
Понятно, что это может произойти с использованием одного лишь js, но только в рамках сессии, потом изменения сбросятся как вкладку закроют.
А чтобы обновить сам статичный документ на уровне самого файла нужно, получается, проитерировать его содержимое и расставить все теги с новой информацией скриптом?
мимо пытаюсь начать фуллстечить.
Привет. Где код? Нам угадывать что у тебя там неправильно написано может быть или телепатов позвать?
>>267168
>бекендовый язык редактирует конечную страницу после того, как с клиента пришла информация?
Бекенд только данные вставляет и собирает страницу из кусков если без микросервисов. Обычно подстановка данных идёт "на лету" - на каждый запрос пользователя.
>чтобы обновить сам статичный документ на уровне самого файла нужно
Никаких статичных файлов - страница собирается из готовых кусков каждый раз.
Либо микросервисы, когда она на клиенте собирается из данных, которые из бека идут. Но там уже бекенд только клиентское приложение отдаёт и обеспечивает нужные API эндпоинты.
Думаю рано тебе ещё в фулстаки подаваться - странные вопросы задаёшь.
Там буквально то, что я написал.
<?= data['city'] ?>
и
<input type="text" value=<?= data['city'] ?>>
<link rel="alternate" hreflang="de" href="https://сайтнейм.com/cp/?lang=de">
Вопрос то в том: что от меня ждут то? Ну то есть я не шарю в html и в js, и в задании написано что надо не знать, а суметь загуглить и решить задачу. И из-за того что я не шарю я и не могу понять - мне что, просто рандомную ссылку скриптом открыть и всё? Задание в открытом доступе, с работадателем я не в контакте пока, так что спрашиваю не там, а тут.
>что от меня ждут то?
Что ты бесплатно напишешь ребятам код, а они тебе откажут. Плавали знаем.
>>267726
Да, вы не поняли. Страницы уже существуют на куче языков. От меня просто ждут 1-2 строчки на js, чтобы переключиться на другой язык. Короче, я сделал сначала так:
window.location.replace("https://сайтнейм.com/cp/?lang=ru")
Но я засомневался, того ли они хотят. И вот такую поеботу родил.
function replaceUrlParam(url, paramName, paramValue)
{
if (paramValue == null) {
paramValue = '';
}
var pattern = new RegExp('\\b('+paramName+'=).?(&|#|$)');
if (url.search(pattern)>=0) {
return url.replace(pattern,'$1' + paramValue + '$2');
}
url = url.replace(/[?#]$/,'');
return url + (url.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue;
}
window.location.replace(replaceUrlParam(window.location.href,"lang", "en"))
А потом чтобы туда-сюда само:
function replaceUrlParam(url, paramName)
{
var paramValue = "en";
var pattern = new RegExp('\\b('+paramName+'=).?(&|#|$)');
if (url.search(pattern)>=0) {
if (url.indexOf("lang=en")>=0) {
paramValue = "ru";
}
return url.replace(pattern,'$1' + paramValue + '$2');
}
url = url.replace(/[?#]$/,'');
return url + (url.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue;
}
window.location.replace(replaceUrlParam(window.location.href,"lang"))
>>267726
Да, вы не поняли. Страницы уже существуют на куче языков. От меня просто ждут 1-2 строчки на js, чтобы переключиться на другой язык. Короче, я сделал сначала так:
window.location.replace("https://сайтнейм.com/cp/?lang=ru")
Но я засомневался, того ли они хотят. И вот такую поеботу родил.
function replaceUrlParam(url, paramName, paramValue)
{
if (paramValue == null) {
paramValue = '';
}
var pattern = new RegExp('\\b('+paramName+'=).?(&|#|$)');
if (url.search(pattern)>=0) {
return url.replace(pattern,'$1' + paramValue + '$2');
}
url = url.replace(/[?#]$/,'');
return url + (url.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue;
}
window.location.replace(replaceUrlParam(window.location.href,"lang", "en"))
А потом чтобы туда-сюда само:
function replaceUrlParam(url, paramName)
{
var paramValue = "en";
var pattern = new RegExp('\\b('+paramName+'=).?(&|#|$)');
if (url.search(pattern)>=0) {
if (url.indexOf("lang=en")>=0) {
paramValue = "ru";
}
return url.replace(pattern,'$1' + paramValue + '$2');
}
url = url.replace(/[?#]$/,'');
return url + (url.indexOf('?')>0 ? '&' : '?') + paramName + '=' + paramValue;
}
window.location.replace(replaceUrlParam(window.location.href,"lang"))
Ожидаемо макаба насрала мне в штаны. Ну суть вы и так поймёте.
Вопрос в том какого решения от меня ждут.
Я не очень понял суть задания. Ты пишешь автоматизированный тест, который должен протестировать переключение языков на сайте? Или же ты пишешь тест, который переключит язык и затем протестирует какую-то страницу на этом языке?
Тут есть несколько вариантов действий, в зависимости от устройства сайта. В любом случае, тебе надо сначала определить, как на сайте переключаются языки: автоматически или какой-то кнопкой, или какой-то страницей, или по GeoIp.
Если сайт определяет язык по HTTP-заголовкам, тебе надо просто их выставить. Если по GeoIP, то надо как-то имитировать вход с нужного IP-адреса. Если кнопкой, то надо программно нажать эту кнопку.
Для ускорения теста, можно, конечно, менять ссылку, но это не очень надежно.
Твой код довольно костыльный. URL надо разбирать не регулярками, а предназначенным для этого кодом, который разделяет URL на составные части, корректно кодирует/декодирует их и собирает обратно.
Спасибо!
> каждая вторая хрюша разворачивает, узнав что я не могу разговаривать на английском
Нахуя это надо вообще, ты сам должен с заказчиком общаться или что?
>Но надо начальный вариант какой-то отправить вместе с вопросом
Зачем? Тебе надо тестовое уточнить чтобы было предельно понятно что от тебя требуется.
А то начинается уже:
>Вопрос в том какого решения от меня ждут.
>От меня просто ждут 1-2 строчки на js, чтобы переключиться на другой язык.
Имхо у тебя там совсем мутное чего-то или ты так объяснил. Зачем QA в тестовом переключать языки на жс? Это работа разработчика, а не тестировщика.
У них раньше вообще требование к вакансии было "уметь создавать всё что есть в веб: сайты, скрипты, что-то там ещё". Сейчас переделали. Я вкатун, я не то чтобы могу выбирать.
>>267795
Задание:
С помощью JavaScript изменять язык на https://хззачемяскрываюсайт/cp/
В этом задании не нужно знать JavaScript на среднем или высоком уровне. Главное — исследовать и понять, как именно меняется язык и нагуглить скрипт в 1-2 строки.
Ожидаемый итог — JS-скрипт, который при вставке в консоль браузера изменит язык на my.сайт.com
>У них раньше вообще требование к вакансии было "уметь создавать всё что есть в веб: сайты, скрипты, что-то там ещё". Сейчас переделали. Я вкатун, я не то чтобы могу выбирать.
Ты, скорее всего, просто время с ними теряешь. Вот и всё.
Лучше ищи конторы с нормальными тестовыми, на которых можно чему-то научиться и показать потом - типа это я зделол.
>уметь создавать всё что есть в веб: сайты, скрипты, что-то там ещё
Вангую школота или студенты тупенькие там сидят. Никакая херочка так не напишет.
Да я думаю всем похуй на гитхаб, работадатели вкурсе что 90% тупо код копипастят, я для приличия тудушку залью.
Совсем начинающие никому не нужны. Если тебе кажется, что с тобой кто-то сидеть будет и учить тебя, а потом ещё и платить за это, то ты это зря. Обычно дают таску, пару напутственных и вперёд, могут только пиздюль дать чтобы быстрее работал.
Думаешь у тебя знаний достаточно, если ты много чего не применял(я про фичи лары)?
Да нет никаких джунов, вы заебали. Есть либо тот, кто ничего не умеет и его никто на работу не возьмёт, либо тот кто умеет, но его берут подешевле, типа "джун". Есть куча мест, где "синьоры" пишут код на уровне помойки.
В этом весь секрет.
>Есть куча мест, где "синьоры" пишут код на уровне помойки.
И вы там у них будете как джуны работать со своими алгоритмами.
Ну где? Там же где и все. Я вот почти устроился qa в контору, которые на маженто делают магазинчики. У них прямо было написано что ищут начинающих пхп программистов. Вот сейчас нагуглил вакансию: https://ulyanovsk.hh.ru/vacancy/39153634
Но начинающих они берут только на очную испыталку, если ты не местный, но извини. Потому я туда и не пошёл. Даже уговаривали, сказали всего 1.5 месяца в офисе посидишь (это для qa, разрабам 2 месяца) и на удалёнку пойдёшь. Но я отказался по своим причинам.
>>268329
>Совсем начинающие никому не нужны. Если тебе кажется, что с тобой кто-то сидеть будет и учить тебя, а потом ещё и платить за это, то ты это зря.
Ты не прав. С одной стороны, нужно вкатунов держать трезвыми, чтобы особо в сказки не верили, но "сидеть и учить тебя, а потом ещё и платить" это реальность российского ит. Люди заканчивают университет по ит специальностям и улетучиваются ровно так же как юристы с экономистами. У знакомого сишарпового кабанчика из его группы только он и ещё человека два пошли в ит, остальные прозябают в обычных нищих сферах труда. Так что у контор есть несколько путей: или ты бегаешь за спецами и конкурируешь с москвой по зп, или ты набираешь максимально неамбизиозных макак, или ты, внезапно, "сидишь, учишь, а потом ещё и платишь". У меня местная аутсорс контора учит бесплатно, потом себе набирают. Контора, что я кинул выше, тоже учит бесплатно под себя. Так что "воспитать под себя" это не только мечты инцелов из б, это ещё и рыночная практика в регионах.
Чел, я тебя отлично понимаю. Но ты сейчас смотришь с позиции сытого. А я голодный. Мне эту контору друзья хвалят, кое-кто даже предлагает обкашлять вопросики. Я не собираюсь дропать контору потому что у них вакансия составлена КРАЙНЕ СТРАННО. HR курочке сказали найти qa, она погуглила и написала как могла. Да, контору это не красит. И в других обстоятельствах это сигнал "стоп", но я qa вкатун после курсов. Конкуренцию себе представил? Нас легион. Я резюме разместил в ноябре, у меня 1 собес был (охуенный, но я сам отказался). Потому что нихуя никто на отклики не отвечает, а я сам не откликаюсь почти, потому что в каждой первой вакансии требуют знать какую-то совершенно анрелейтет для qa поеботу или опыт от трёх лет за 40к или ещё что-то там. Ну ещё потому что я шизоомежное уёбище. Чел, с которым я учился на qa напиздел (крайне топорно) про опыт и сидел ещё выбирал. 8 собесов за 2 недели. И не спрашивай "что мешает и тебе напиздеть?". Не знаю как можно без знания внутренних процессов изобразить что знаешь.
>Вот сейчас нагуглил вакансию: https://ulyanovsk.hh.ru/vacancy/39153634
Эта вакансия третий год висит, спамили ей как сумашедшие. Я как-то смотрел что там за контора и сильно похоже, что они курсы продают вкатунам таким хитрым способом.
А еще эта компиляция ебаная по 5 минут (да у меня калькулятор)
Можно ли к вам вкатиться? Вроде вакансии в моем мухосранске есть. Реально ли освоить это говно за короткие сроки после джавы? Еще когда-то учил жабускрипт, примерно себе представляю как SPA написать.
Но с жабы у меня лютый депрессняк, хоть вешайся.
Не знаю на счёт пхп, у меня было так: мне написала на почту, а потом позвонила hr, спросила ищу ли я работу qa, хочу ли я тестовое сделать. Согласился, сделал тестовое. Обычное такое тестовое - найти баги на их полигоне, расписать как бы тестил что-то там. Отослал. Ещё анкету заполнил стандартную. Перезвонили, наверное, через день, сказали что всё очень хорошо и предложили в офис приехать на интервью. Сказал что я работаю и мне неудобно. Согласились во время обеда моего по видеосвязи. Скинули ссылку с ознакомительным видео. Там дядя с таким низким голосом просто и будто без заготовки рассказывает что и как они делают, как у них новички вкатываются и всё такое. Всё именно про разработку, про qa ни слова. Типа 2 месяца с ментором учишься на учебных задачах, через два месяца уже в продакшен. Если ты крутой, то раньше. Это ты уже устроен и зп получаешь.
Ну пообщались. Сначала дядя (гендир типа) представился, спросил про цикл жизни по. Я рассказал. Спросил есть ли общие вопросы. Я спросил как вещи из видео переносятся на qa. Сказали, что всё то же самое, но на продакшен быстрее выводят, где-то месяца за полтора. Ну он откланялся и ушёл и я остался с двумя челами qa. Поспрашивали по теории тестирования и только по ней. Я отстрелялся хорошо вполне, чувствовал себя уверенно. Попрощались, обещали обратную связь через 2 дня.
Пока ждал, понял что в офис не пойду работать, обрадовался что сами не перезвонили через 2 дня. Через неделю звонок, типа вот мы закончили цикл собеседований, вы среди "позитивных" кандидатов, приезжайте в офис пообщаться. Я промычал что приоритеты изменились и в офис не пойду. Потом ещё раза 2 звонили, приглашали на стажировку какую-то, спрашивали не изменились ли у меня обстоятельства, "уговаривали" типа на испыталке только офис, дальше можно на удалёнку.
Я подвоха не заметил, если честно. Уж слишком дохуя усилий такую ширму возводить, когда лох и так готов платить за двухнедельные курсы дата саентиста. Что конкретно тебя смутило? Мои друзья из местного ит ничего про эту контору не слышали, кстати.
Не знаю на счёт пхп, у меня было так: мне написала на почту, а потом позвонила hr, спросила ищу ли я работу qa, хочу ли я тестовое сделать. Согласился, сделал тестовое. Обычное такое тестовое - найти баги на их полигоне, расписать как бы тестил что-то там. Отослал. Ещё анкету заполнил стандартную. Перезвонили, наверное, через день, сказали что всё очень хорошо и предложили в офис приехать на интервью. Сказал что я работаю и мне неудобно. Согласились во время обеда моего по видеосвязи. Скинули ссылку с ознакомительным видео. Там дядя с таким низким голосом просто и будто без заготовки рассказывает что и как они делают, как у них новички вкатываются и всё такое. Всё именно про разработку, про qa ни слова. Типа 2 месяца с ментором учишься на учебных задачах, через два месяца уже в продакшен. Если ты крутой, то раньше. Это ты уже устроен и зп получаешь.
Ну пообщались. Сначала дядя (гендир типа) представился, спросил про цикл жизни по. Я рассказал. Спросил есть ли общие вопросы. Я спросил как вещи из видео переносятся на qa. Сказали, что всё то же самое, но на продакшен быстрее выводят, где-то месяца за полтора. Ну он откланялся и ушёл и я остался с двумя челами qa. Поспрашивали по теории тестирования и только по ней. Я отстрелялся хорошо вполне, чувствовал себя уверенно. Попрощались, обещали обратную связь через 2 дня.
Пока ждал, понял что в офис не пойду работать, обрадовался что сами не перезвонили через 2 дня. Через неделю звонок, типа вот мы закончили цикл собеседований, вы среди "позитивных" кандидатов, приезжайте в офис пообщаться. Я промычал что приоритеты изменились и в офис не пойду. Потом ещё раза 2 звонили, приглашали на стажировку какую-то, спрашивали не изменились ли у меня обстоятельства, "уговаривали" типа на испыталке только офис, дальше можно на удалёнку.
Я подвоха не заметил, если честно. Уж слишком дохуя усилий такую ширму возводить, когда лох и так готов платить за двухнедельные курсы дата саентиста. Что конкретно тебя смутило? Мои друзья из местного ит ничего про эту контору не слышали, кстати.
Забыл сказать, что за всё время мы ни разу не обсуждали деньги. У меня в резюме 60к стояло, в анкете я 50к указал. Трудно поверить что местная контора без вопросов согласились. У нас тут жадные пиздец. Хотя я тут про тестовое спрашивал выше, на той вакансии 45-65, тоже местные.
>Уж слишком дохуя усилий такую ширму возводить
Да я не знаю какой у них там развод, но факт в том, что они 3 года вакуху с такими элементарными требованиями закрыть не могут - за это время армию джунов можно собрать и какую-нибудь небольшую страну завоевать. К тому же видел как их херочки активно спамили этой ваканисией в вк темах где разрабы сидят.
Это всё очень нездоровая хрень и лучше не связываться.
Ну так там магазины клепают под заказ, может они 20 команд уже собрали? Я поспрашиваю ради интереса, есть кабанчики, которые в любую дырку пролезут. Я с ними уже точно всё.
После жавы все быстро и просто, только приличных симфони вакансий на джунов в мухосранях небось нет
мне хоть какую-то. готов хоть за бесплатно первое время работать.
Я уже даже готов забашлять денег, но понимаю, что там то же самое в целом. Может где-нибудь можно скачать актуальные курсы?
>прошёлся
Вангую ты точно так же пройдёшься по курсу и точно так же останешься разрозненным и потерянным. Работать над задачками надо, вычитывать что там написано, практиковаться, самому уметь искать нужное и гуглить непонятное. И писать-писать-писать всякие петы, ковыряться в CMSках и коде с гитхаба.
Тебе никакой курс не поможет на мой взгляд.
Точку с запятой надо поставить? Поставил. Теперь пишет Could not open input file:. Хотя путь верный указал
Ну значит у тебя в канплуктере черти завелись и файл прячут когда его твой скрипт запрашивает. Вызывай отца Филофея для процедуры изгнания бесов.
В конце, но я вроде разобрался. Скачал нотепад ++ и заработало
Я могу предложить другую идею: ты находишь курсы, даешь ссылки на оглавление/список тем и анонимные эксперты расскажут, чего там не хватает.
Подвох с платными курсами в том, что часто они как раз не покрывают все, что нужно. Например, курс по PHP может не рассказывать нормально про ООП, или про SQL, или про инъекцию зависимостей.
Если ты хочешь быть специалистом, то вот что примерно тебе надо знать:
Бекенд:
- язык PHP
- ООП в PHP
- Dependency Injection, архитектура MVC
- шаблонизаторы
- SQL
- работа с БД из PHP: PDO, ActiveRecord или DataMapper
- возможно, какой-то фреймворк вроде Symfony или Laravel
Фронтенд:
- основы HTTP
- HTML, формы в HTML
- CSS
- JS
Общее:
- концепции устройства ОС: файлы, процессы, пользователи, права, сокеты Беркли
- основы командной строки Linux
Я могу предложить другую идею: ты находишь курсы, даешь ссылки на оглавление/список тем и анонимные эксперты расскажут, чего там не хватает.
Подвох с платными курсами в том, что часто они как раз не покрывают все, что нужно. Например, курс по PHP может не рассказывать нормально про ООП, или про SQL, или про инъекцию зависимостей.
Если ты хочешь быть специалистом, то вот что примерно тебе надо знать:
Бекенд:
- язык PHP
- ООП в PHP
- Dependency Injection, архитектура MVC
- шаблонизаторы
- SQL
- работа с БД из PHP: PDO, ActiveRecord или DataMapper
- возможно, какой-то фреймворк вроде Symfony или Laravel
Фронтенд:
- основы HTTP
- HTML, формы в HTML
- CSS
- JS
Общее:
- концепции устройства ОС: файлы, процессы, пользователи, права, сокеты Беркли
- основы командной строки Linux
>Эта вакансия третий год висит
Коротко о том как писать себе проекты бесплатно:
Создаёшь вакансию > на неё откликаются > предлагаешь сделать тестовое > делают > отказываешь и колесо сансары даёт оборот.
>>268767
>Можно ли к вам вкатиться?
Вкатывайся лучше в решётки, будет больше персектив.
>>271132
>Я уже даже готов забашлять денег
Вкатуны как всегда готовы платить за то, что лежит бесплатно в документации и прочих ресурсах.
Придумай себе идею сайта и начинай его потихоньку реализовывать, да, будет лютый говнокод, но это куда профитнее курсов да ещё и бесплатно.
Без задач -- никак. Иди в максимально байтоёбскую/промышленную контору, если уж так хочется.
Как же болит голова от программирования.
То ли затекает то ли просто усталость.
Странное чувство от того что код сам пишется уже почти наизусть и не застреваешь как раньше.
Наверное скоро вкачусь.
У меня один раз болела - когда я 12 часов пилил роутер для своего фреймворка. Сейчас конечно это всё смешно выглядит, но тогда ебать упахался. Код был говно, запутался в трёх функциях и в целом хуйни понаписал. Башка, правда, болела натурально.
>код сам пишется уже почти наизусть и не застреваешь как раньше.
>Наверное скоро вкачусь.
Не, ты только синтаксис изучил - с таким не берут ещё. Как по гиту, MVC, ООП, http? Это минимум для работы и обычно к этому добавь вёрстку и жс.
Программирование уровня /pr/
Да хуй знает, но учебник оп-хуя напрочь отбил желание вообще че-то учить. Так и сижу уже год афк чилю, работать пойду в макдак.
А я его и не читал лол
Логика программы правильная и ответ сходится. Но код написан не оптимально и не очень читаемо.
Во-первых, код надо отформатировать. Не так:
> for($month=1;$debt>0;$month++){
А так (добавлены пробелы):
for ($month = 1; $debt > 0; $month++) {
Надо поправить отступы, код внутри for должен быть сдвинут вправо.
Также, в коде много раз повторяется выражение $debt*$ratePercent+$rateFlat - надо избавиться от повторов.
В вакансиях наряду с пхп часто битрикс идет вдобавок, не планируется добавить главу про это в уроки из шапки?
А я читал и делал всё вплоть до файлового хостинга на Слиме. Потом ещё возвращался и перечитывал потому, что много упустил.
Ещё курсы украл на торрентах и их смотрел - что-то около 70 часов в общем. Это по ПХП только, а ещё с вёрсткой возился, жаваскриптом. Учебник реально годный и много хороших советов там.
Сейчас работаю 5 месяцев уже.
Так вот нашел вакансию "ученика программиста на пхп"
>тестовое задание (знание программирования не требуется) как условие для начала обучения
Это как вообще понимать?
>срок обучения до 2-х месяцев с последующей стажировкой
Что можно изучить за такой срок? Тут люди пишут про 7 месяцев минимум.
Еще и 5к "стипендии" платят, в чем подвох? И самое главное в чем им профит?
Дома ты учишься по паре часов, лениво листая книгу или делая очередной игрушечный круд, в лучшем случае, а в худшем смотришь курсы от васяна, про то как переменную объявить и в цикле вывести все четные числа, на нормальной стажировке от компании, ты будешь 8 часов сидеть, разбирать реальные кейсы с возможностью задать вопрос напрямую уже работающим программистам миддлам+.
Эти 2 месяца будут плодотворнее, чем год того, о чем я выше написал.
Да я не спорю про плодотворность, я просто удивляюсь, какое может быть тестовое без навыков программирования и зачем им учить кого-то да еще и приплачивать немного за это. Сейчас вроде нет недостатка в (малоквалифицированных) вкатунах.
Да учи все сам епт, гайдов полно. + ищи ребят из разработки, они не против будут помочь в 95% случаев
Так ты попробуй к ним откликнуться - сделай вид, что начинающий вкатун и дурак при этом. А там и увидишь всё. Главное не подписывай им ничего и данные свои не присылай.
Так-то правильно подвоха ждёшь - слишком халявно выглядит, не бывает так. Если такое выложить, то к вечеру уже почта\телега треснут от резюме вкатунчиков с курсов.
Возможно у них тестовое какой-то с подляной. В любом случае если увидишь там кидалово какое-то, то не лишним будет сюда имя этой шарашки и суть кидалова прислать. Или в мы-вам-перезвоним тред.
>Там изучать-то нечего, это микрофреймворк, весь его исходный код наверно можно за пару часов прочесть.
Что я получу от того, что прочитаю весь исходный код вместо документации? И под исходным кодом понимается вся папка вендор, или только слимовские пакеты?
ОП это выражение просто как пример небольшой библиотеки привёл - типа за день можно разобраться где там и что, если надо.
Сам код читать приходится часто, но всегда лучше начинать с документации. В дебри лезут только по необходимости - когда что-то работает не так как ожидалось. мне приходилось в этом Слиме ковыряться как-то, да и не только в нём
Ты эти вузы видел и чему там преподают? Я вот в таком учился, в тетрадке писал программы на бейсике и на уроке компьютерной графики рисовал в гимпе кота в спогах.
Как это правильно организовать,на каждое поле пилить функцию?
1 - воспользоваться любым фреймворком или библиотекой с формой
2 - сделать ф-ции и любые доп.валидаторы на типы полей
3 - да
нинужно
похуй на моду, тупо чтобы не глючило?
https://2ch.hk/s/res/3106239.html#3106400 (М)
>какой линукс ставить для РАБоты?
Я мяту себе накатил и радости не знаю предела. Долго использовал убунту, но этот неповоротливый бегемот просто проигрывает скорости и удобстве мяте.
>А чего не yii?
А Юи с ларавелем на чём основаны, как считаешь?
Симфония это панацея ящитаю, Битриксы, Юи и прочие это деградация.
Там проблема с сохранением файла сессий.
Да я нифига не знаю, просто тут местные вакансии в глуши почему-то yii хотят.
>почему-то yii хотят
Легаси параша - понаписали на нём много всего, но поддерживать некому, а сервис растёт. Yii2 уже устарел порядком, а у некоторых до сих пор даже первая версия. Да и денег за это легаси мало дают - сервис раскрутился, должны платить побольше, а вот хуй.
так я тоже поставил, но мне не повезло уже на 2-х компах: https://2ch.hk/s/res/3106239.html#3106400 (М)
>местные вакансии
Попробуй удалёнку поискать всяко опыт будет куда лучше нежели переписывать легаси за очередным уебаном максимум которого это Юи.
У меня опыт с легаси очень печальный был всегда, когда даже на симфонии тимлид подтягивает классы СТРОКАМИ блядь, а потом мне с красным еблищем рассказывают, что это фабричный метод нахуй. Второй 50 емейлов запихивает в одну строку, чтобы сделать рассылку онных пачкой, а я должен был исправлять его костыли.
А что там на Юи мне просто представить страшно...
Пора в решётки перекатываться с ваших пых с недокодерами на тимлидах.
>>277474
Ну пёс его знает тогда, мне сразу без танцев и шаманства установилась нормальная мята и это просто песня в сравнении с убунтой.
Тут хуй угадаешь как оно будет работать на твоём железе, так или иначе мята куда более стабильнее убунты. Можешь чистый дебиан попробовать мне он пердак разорвал, а дальше уже линуксовые дебри как по мне.
Только говнокодер на решётках это сеньёр тимлид для похапе, а говнокодер на пыхе это просто умственно отсталый дегенерат.
Залётыш, даже на решётках в разных конторах джуны, мидлы и помидоры часто имеют разный уровень. Что уж говорит о разных языках и сферах применения.
Свали в туман и не позорься больше.
Главы про Битрикс не будет. Это не тот код, на котором стоит учиться. Но если кому-то хочется изучить его, то думаю, знания PHP + чтения документации должно быть достаточно. По Битриксу много документации, и если ее мало, то есть исходный код.
Значит они рассчитывают тебя обучить так, что ты сможешь выполнить за 2 месяца задач больше чем на 10 000. И я не думаю, что у них много желающих, так как "вкатунам" на курсах обещают зарплаты в 50 000 - 100 000.
Приходится читать если документация скупая или в ней нет ответа. Если ты начинающий, то стоит читать код в целях изучения архитектуры фреймворка и стиля кода.
Обычно делают класс-валидатор, а в нем можно уже делать методы на каждое поле. Дело в том, что иногда надо проверять не одно поле, а сочетание нескольких полей (например, что введены одинаковые пароли в 2 поля). Если ты не любишь ООП, то можно сделать отдельный файл с функциями.
Если что, урок по обработке форм, может в нем что-то есть: https://github.com/codedokode/pasta/blob/master/forms.md
Это типа фреймворка на пхп? Я просто даже в глаза не видел.
И получить стену где объекты обращаться к методам?
Года 2 с половиной где-то.
Но я там не спешил и по-фану многое было. Например тех же студентов переписывал практически с нуля раза 3 потому, что в процессе много читал про архитектурки и ООП под бустом с курсов, и когда заканчивал очередную версию, то ловил фейспалм с говнокода и садился делать нормально. Потом когда сюда выложил показать какой-то анон сказал, что это троллинг.
Потом с файловым хостингом уже проще всё было - там на готовых библиотеках всё пилишь и больше с практикой заморачиваешься. Его не показывал уже. Тоже месяц-полтора сидел вечерами.
Позже уже была затяжная попытка выйти на фриланс и несколько всратых заказов за копейки после чего я зарёкся там работать. В процессе ковырял много всего: вордпресс, опенкарт, ларавел изучил. Ну а потом работу случайно нашёл - сразу мидлом на удалёнку взяли после тестового.
У меня в мухосрани всего 2 конторы по этому направлению и в одной нужны только верстальщики, а во-второй какие-то неадекваты просят тестовое в архиве на почту выслать и не отвечают на высланные решения тестовых при этом у них офис от меня через дорогу.
По моим впечатлениям джунов на удалёнку как-то не очень берут. По крайней мере это те джуны, которые мидлы фактически, по скиллам. Поэтому позже уже на джуна не ходил и смотрел только по требованиям на вакансию. Подписался просто как веб-разработчик.
У меня к тому времени уже и портфолио было и в гитхабе примеры кода были чтобы показать.
roadmap.sh
Например preg_match_all, которая сохраняет совпадения в массив.
Или можешь использовать preg_replace, где заменишь то, чего не должно быть и потом сравнишь со строкой, если начальная строка и измененная не равны, тогда юзаешь str_split на начальную строку и на измененную при помощи preg_replace, потом пишешь array_diff, где тебе выдаст массив с этим/этими элементами, которые не допускаются.
Попробуй сюда закинуть регулярку, и нужную строку. Там сразу покажет где проблема
https://regex101.com/
мимо старец 25 лвл
Или на завод
>Заниматься буду по 6 часов в день, еще 4 часа толочить на еду.
Ты это, 6 часов подряд не ебашь, сгоришь за неделю. Каждый час перерыв пять минут на зарядку, каждые два-три часа минут на 15 минимум отвлекись на что-нибудь типа уборки/готовки/магазина (не двачей или игрушек).
в общем - помидорка, только меньше времени на отдых
>Всё, я больше никогда не посмотрю в сторону битрикса.
>Заниматься буду по 6 часов в день
Твердо и четко?
А что там за подстава с битриксом?
Вроде зп одинакова. Просто мадженто это CMS, поэтому как-то даже не хочется связываться. Ну и вакансий на фреймворках в 10 раз больше.
Есть даже одна компания, которая обучает вкатунов. Вот только никто к ним не идет, потому что они находятся в далеком среднем провинциальном городке.
Уже похуй, пришел оффер на ларавел
syntax error, unexpected token "echo"
<?php
error_reporting(-1);
$manDice1 = mt_rand(1, 6);
$manDice2 = mt_rand(1, 6);
$compDice1 = mt_rand(1, 6);
$compDice2 = mt_rand(1, 6);
echo "У человека выпало $manDice1 и $manDice2\n";
echo "У компьютера выпало $compDice1 и $compDice2\n";
$manDiceSum = $manDice1 + $manDice2;
$compDiceSum = $compDice1 + $compDice2;
if ($manDiceSum == $compDiceSum) {
echo "Ничья!/n";
} elseif ($manDiceSum > $compDiceSum) {
echo "Победил человек!/n";
} else ($manDiceSum < $compDiceSum) {
echo "Победил робот!/n";
}
?>
Все, я долбаеб. Я исправил.
В директории проекта:
assets/ docker-compose.override.yml src/ vendor/
bin/ docker-compose.yml symfony.lock webpack.config.js
composer.json migrations/ templates/
composer.lock package.json translations/
config/ public/ var/
Что из этого нужно помещать в корень сервера?
Как вообще все это устроено?
Какого хуя у меня в корневой директории еще создалась скрытая папка .symfony5???
Что мне потом кидать на хостинг или в var/www где симфони не стоит?
>Создал пустой проект в симфони и там 8000+ файлов на 60+ мегабайт
И хули так много?
Я просто хочу круд сделать, простейший с десяткой полей, нах столько всего?
У него есть verbose для ВСЕХ файловых операций и того что и откуда он качает?
надо будет для прикола залить на хостинг и посмотреть упадет ли он
Как работает эта хуйня?
Где .htaccess?
Работает только корень (маршрут /), на всех остальных выдает 404.
Бляяять, нахуя так извращаться? В чем профит?
composer автоматом лезет в vendor и что-то оттуда запускает чтобы flex перегрузил методы composer или типа того?
откуда composer стартует flex?
Спасибо, но что-то не заработало.
Во-первых, в Open Server походу уже есть какой-то xdebug в папке модулей, во-вторых, он мне предложил скачать на основе phpinfo php_xdebug-3.1.2-7.2-vc15, а в статье написано что выше 2.5 не поддерживает vscode.
<table>
foreach ($row as $key->$v)
{
<tr class="стиль строки"> <td>столбец</td><td>столбец</td> </tr>
}
</table>
типа того
данные пишешь в массив
либо сам из чего тебе надо (json, файлы и т.д.)
либо из базы через fetch
В phpinfo есть xdebug, но в vscode пишет что типа не видит путь к php.exe, я уж в конфиге с разными слешами пробовал. И расширение php-debug не добавляет свой конфиг автотатом как в гайде при нажатии add configuration.
>>281432
Ну там можно точки останова ставить, смотреть промежуточные значения переменных. Я все с той задачей на рекурсию никак не разделаюсь, подумал может отладкой забрутфорсить решение.
Вроде заработало, помогло добавление "php.debug.executablePath", почему-то никто про это не писал нигде, один коммент мелким шрифтом, везде только про validate.
Осталось только понять, как работать с этим дебаггером.
есть id, sum, нужно вывести в новом столбце сумму по шагам к значению второго столбца, как бы вы это сделали?
В результате должно быть такое (скрин).
Там надо sql запрос сделать, не из php
Давай определимся с терминами. Корень проекта - это папка, в которую будет загружен проект, например: /var/www/project. "Публичная" папка - это папка, файлы из которой будет раздавать веб-сервер. Например: /var/www/project/public
В Симфони такая папка называется public. Идея в том, что мы не выкладываем весь код (включая конфиги, логи, пароли) в открытый доступ, а лишь одну папку public. А основной код находится за ее пределами и недоступен снаружи.
Загружать на хостинг нужно все, но надо настроить его так, чтобы он раздавал файлы только из public.
У тебя версия Композера старше 2.2.0 ? В ней внесли серьезные оптимизации в работу вычислителя зависимостей пакетов. У пакетов есть множество версий, а количество комбинаций этих версий вообще огромное.
Посмотреть лог можно, добавив опции -vvv и --profile, например:
composer --profile -vvv install some/package
flex реализован как "плагин" для композера. Если ты посмотришь его исходники, то там указано: type: "composer-plugin": https://github.com/symfony/flex/blob/1.x/composer.json
реальные задачи
ОП, а есть хорошо сделанные примеры решения student list? Желательно такие чтобы ты проверил и сказал "окей, студент, кончай ебать эту мертвую лошадь и иди учить сли и лару", а то некоторые найденные на гитхабе проекты эту проверку не проходят.
>некоторые найденные на гитхабе проекты эту проверку не проходят
Давай их сюда со своей критикой почему не проходят. А то беспредметный разговор получается.
Это из-за .ga домена небось.
можешь выложить свой, кто-нибудь из ананасиев проверит
очевидно, это зависит не только от технологии опенкарт.
Посмотри, есть ли у тебя с этими людьми общие ценности, комфортно ли тебе будет.
Опенкарт поможет втянуться в разработку? Хочу дальше скакнуть на laravel
Кто из шарящих может пояснить за это мнение? https://anton-pribora.ru/articles/php/mvc/
Что сложного? В чем вопрос? Mvc создан для удобства, пойми суть и не забивай голову. Начнешь делатт проект и поймешь
>Кто из шарящих может пояснить за это мнение?
Посмотрел диагонально - там мнение человека, который явно говнокодит. Он дальше MVC архитектуры не изучал и его максимум - мутные хелперы и толстые контроллеры. Сегодня это уровень джуна на уважающем себя проде.
Есть ли смысл слушть джунов, которые в своей же сфере не разбирются?
Проектов потом будет больше, так что трогать server root всего апача не хочется. Нагуглил https://httpd.apache.org/docs/2.4/vhosts/ но не уверен что это подходящий инструмент.
Попрыгун, снова ты? Учи и не выебывайся, все равно забросишь через неделю, проходили уж
Выбери стек твёрдо и четко один раз и больше не смей оглядываться. Иначе не вкатишься.
>К сожалению, область применения PHP такова, что в ней много простой работы, не требующей наличия моска, вроде допилить простейший скрипт и тому подобное. Настоящий программист никогда даже браться не будет за такой примитив, зато можно взять на работу школьника или макаку из зоопарка (что, впрочем, одно и то же). После двух дней изучения синтаксиса PHP, единственным правилом которого было и остаётся «одна перфокарта строка — одно действие», и школьник и макака могут делать эту работу — если, конечно, школьник не полный дебил.
>Стоит ли удивляться, что при таком раскладе 90% программистов на PHP — сказочные долбоёбы, которые не могут нормально написать ни одной программы сложнее вывода на экран «Hello World»?
>PHP впринципе никому нахуй не всрался.Ты никогда не будешь PHP-программистом,ну точнее взят именно на эту должность.Ты блядь станешь сразу всем,ну а зарплата...
> PHP (вместе с Pascal) — самые низкооплачиваемые языки программирования. Сколько бы книг ты ни прочитал, сколько бы мегабайт кода ни написал, ты никогда не будешь получать больше, чем Java-быдлокодер средней криворукости. «На Яве пишут Корпорации», а на Пыхе…
> Порог выхода такой же низкий, как и порог входа: если у программиста на полноценных языках с возрастом есть шанс стать ценным высокооплачиваемым специалистом, то у похапе-олдфага такой возможности нет просто ввиду убогости и примитивности решаемых задач, его спокойно можно выгнать на улицу, взяв взамен школьника, который обучится всем премудростям похапе-быдлокоддинга за пару месяцев, потребляя при этом в три раза меньше доширака.
> Возможно, сейчас тебе кажется, что делать сайты — достойное и интересное занятие, но если ты хоть немного программист, через пару лет такой работы ты просто завоешь от того, насколько это унылая и далекая от программирования деятельность.
> Некоторые начинают работать на PHP с надеждой потом перейти на что-нибудь другое. Но это тоже большая ошибка: во-первых, теряется драгоценное время для старта (наверное, самое важное и ценное в и без того короткой профессиональной жизни программиста), а во-вторых, PHP-опыт никому не нужен и нормальные программисты справедливо смотрят на него как на говно. «PHP» — клеймо быдлокодера на лбу и крест на карьере профессионального программиста, если ты пошёл по этому пути, назад дороги уже не будет. Единственное исключение — устроится похапешником на многопрофильную фирму, где тебя каким-то чудом заметят и предложат перейти на полноценную технологию, но это невероятная удача.
>>284131
Спасибо за совет.
>К сожалению, область применения PHP такова, что в ней много простой работы, не требующей наличия моска, вроде допилить простейший скрипт и тому подобное. Настоящий программист никогда даже браться не будет за такой примитив, зато можно взять на работу школьника или макаку из зоопарка (что, впрочем, одно и то же). После двух дней изучения синтаксиса PHP, единственным правилом которого было и остаётся «одна перфокарта строка — одно действие», и школьник и макака могут делать эту работу — если, конечно, школьник не полный дебил.
>Стоит ли удивляться, что при таком раскладе 90% программистов на PHP — сказочные долбоёбы, которые не могут нормально написать ни одной программы сложнее вывода на экран «Hello World»?
>PHP впринципе никому нахуй не всрался.Ты никогда не будешь PHP-программистом,ну точнее взят именно на эту должность.Ты блядь станешь сразу всем,ну а зарплата...
> PHP (вместе с Pascal) — самые низкооплачиваемые языки программирования. Сколько бы книг ты ни прочитал, сколько бы мегабайт кода ни написал, ты никогда не будешь получать больше, чем Java-быдлокодер средней криворукости. «На Яве пишут Корпорации», а на Пыхе…
> Порог выхода такой же низкий, как и порог входа: если у программиста на полноценных языках с возрастом есть шанс стать ценным высокооплачиваемым специалистом, то у похапе-олдфага такой возможности нет просто ввиду убогости и примитивности решаемых задач, его спокойно можно выгнать на улицу, взяв взамен школьника, который обучится всем премудростям похапе-быдлокоддинга за пару месяцев, потребляя при этом в три раза меньше доширака.
> Возможно, сейчас тебе кажется, что делать сайты — достойное и интересное занятие, но если ты хоть немного программист, через пару лет такой работы ты просто завоешь от того, насколько это унылая и далекая от программирования деятельность.
> Некоторые начинают работать на PHP с надеждой потом перейти на что-нибудь другое. Но это тоже большая ошибка: во-первых, теряется драгоценное время для старта (наверное, самое важное и ценное в и без того короткой профессиональной жизни программиста), а во-вторых, PHP-опыт никому не нужен и нормальные программисты справедливо смотрят на него как на говно. «PHP» — клеймо быдлокодера на лбу и крест на карьере профессионального программиста, если ты пошёл по этому пути, назад дороги уже не будет. Единственное исключение — устроится похапешником на многопрофильную фирму, где тебя каким-то чудом заметят и предложат перейти на полноценную технологию, но это невероятная удача.
>>284131
Спасибо за совет.
Эти высеры года эдак 15го? Сейчас пыха +- похожа на ЯП, однако я наверное скорее соглашусь с тем, что это слишком узкий язык и дальше вэба на нём не уехать, по крайней мере на данный момент.
голанг или решётки сейчас топ для изучения, да и к тому же перспектив и направлений больше.
Да вас послушай любой мануал в интернете говнокод, хуй знает как вообще задачу про студентов с оп поста делать
>>>2283313
С каких это пор энциклопедия мемасиков 2010 года стала сайтом об айти, я что-то пропустил?
>любой мануал в интернете говнокод
Почти всегда это и есть говнокод. Слышал такое: "кто умеет - делает, кто не умеет - учит делать"? Вот тут именно так всё.
Хочешь видеть хороший код - ищи на гитхабе живые опенсорс-проекты с большим количеством звёзд.
>хуй знает как вообще задачу про студентов с оп поста делать
Наверное есть смысл тут спрашивать что непонятно с задачей. Единственное, что не надо спрашивать в стиле "а как какать?" и самому активно погуглить перед публикацией вопроса.
Не работает роутер из web-server.md вместе с виртуальным хостом из apache-install.md. / работает, /index.php/home работает, /home показывает стандартный апачевский 404.
Если тебе надо убрать index.php из url, копай в сторону htaccess и rewriterule.
Надо поискать в архиве тредов. Там ведь выкладывались и задачи, и комментарии к ним.
>>283031
Я могу прокомментировать. Плохо, что ты не написал что именно вызывает противоречие.
Если что, у меня есть урок по MVC: https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Первоначально MVC было придумано (по моему, в 80-е) для десктопных приложений с окошками и кнопками. Представь себе приложение, в котором есть поле ввода для суммы в рублях, и оно отображает эту же сумму в долларах.
Пользователь вводит сумму. Вызывается Контроллер, считывает сумму из поля ввода и передает ее в Модель:
$model->setRoubles($roubles);
Модель вычисляет сумму в долларах и генерирует событие "сумма в долларах изменилась". Вид, который подписан на Модель, получает событие и обновляет сумму в долларах на экране.
В вебе, естественно, MVC работает по-другому и мало напоминает оригинал. Здесь Модель не генерирует никаких событий, а Вид ни на что не подписывается - вместо этого Контроллер явно вызывает его, чтобы сгенерировать страницу.
А вот та часть, где Контроллер вызывает Модель, чтобы совершить какую-то операцию или получить данные, осталась.
Мне кажется, у автора путаница из-за того, что словом "модель" иногда называют один класс, обеспечивающий взаимодействие с БД (например, класс User), а иногда "модель" это часть MVC-приложения, содержащая множество классов. Никто не говорит, что в MVC приложение должно состоять из одного Контроллера, одной Модели и одного Вида. И никто не говорит, что Модель это только класс, взаимодействующий с БД.
> Например, где хранить бизнес-логику? Вики говорит, что в модели, а здравый смысл шепчет: "в контроллере". Потому что контроллер есть всегда, а вот модель и вид... как карта ляжет
Бизнес-логика хранится в сервисах, которые являются частью модели MVC. Модель это не только сохранение данных в БД.
> почему на второй схеме есть роутер и действие, а в аббревиатуре никаких букв по этому поводу нет
Потому, что приложение состоит не только из M, V и С, а еще и из других вспомогательных классов. А "действие" это и есть Контроллер. Просто для удобства несколько действий объединены в один класс, который тоже называют контроллер. То есть мы можем сказать, что метод "играет роль контроллера при обработке запроса", и можем назвать класс с такими методами "контроллер", хотя по факту это набор нескольких контроллеров. Это немного путает, но суть-то не меняется: Контроллер это компонент, который отвечает за взаимодействие с пользователем (прием HTTP-запросов) и управляет Моделью.
> что является моделью в MVC для веба?
Модель это компонент приложения, содержащий бизнес-логику и не занимающийся отображением данных или приемом запрос от пользователей.
> А что делать, если на странице ДВА объекта-модели? На
И в чем проблема? Никто не говорил, что контроллер/вид обязаны работать только с одним классом из модели.
> Но при этом активно гнобят тех, кто пытается засунуть логику (например отправку письма или запрос к базе) в контроллер, называя это "плохой практикой".
Это и есть плохая практика. Если ты поместишь регистрацию пользователя в сервис, то этот код можно повторно использовать - вызвать из любого другого места приложения. А если в контроллер, то его нельзя вызвать, и если где-то еще понадобится зарегистрировать пользователя, то придется делать копипаст.
> Когда задача выходит за рамки документации, то начинается полёт буйной фантазии разработчиков. Обычно такие полёты и порождают монстров в тысячи строк. Это, увы, не редкость в современном веб-MVC.
Так это не проблема архитектуры MVC. Это проблема того, что разработчики ошибочно думают, что "модель это только код, работающий с БД" и пихают бизнес-логику в Контроллер.
> Некоторые оправдывают использование ООП для контроллеров возможностью писать юнит-тесты и повторно использовать отдельные методы класса.
Код в контроллере, как правило, нельзя повторно использовать (вызывать из других классов). Потому в Контроллере не должно быть много кода, и бизнес-логики.
> Наверное можно, но обилие лишних классов само по себе превращает проект в сплошной кусок сами-знаете-чего.
Они не лишние.
> Если бы я попытался идти по пути, например, Yii 2, то только представьте сколько форм, моделей, контроллеров пришлось бы создавать и как-то связывать вместе.
Не вижу проблемы. Если для решения задачи нужно написать 100 000 строк кода, то ты либо напишешь их все в одном файле, либо в 10 файлах по 12 000 строк, либо в 100 файлах по 1200 строк, либо в 1000 файлов по 120 строк. Я думаю, удобнее работать с кодом, где не более 500-1000-2000 строк в одном файле. Просто надо грамотно разнести этот код на классы, определить зону ответственности каждого класса. И не придумывать искуственных ограничений, вроде "модель может только работать с БД".
Надо поискать в архиве тредов. Там ведь выкладывались и задачи, и комментарии к ним.
>>283031
Я могу прокомментировать. Плохо, что ты не написал что именно вызывает противоречие.
Если что, у меня есть урок по MVC: https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Первоначально MVC было придумано (по моему, в 80-е) для десктопных приложений с окошками и кнопками. Представь себе приложение, в котором есть поле ввода для суммы в рублях, и оно отображает эту же сумму в долларах.
Пользователь вводит сумму. Вызывается Контроллер, считывает сумму из поля ввода и передает ее в Модель:
$model->setRoubles($roubles);
Модель вычисляет сумму в долларах и генерирует событие "сумма в долларах изменилась". Вид, который подписан на Модель, получает событие и обновляет сумму в долларах на экране.
В вебе, естественно, MVC работает по-другому и мало напоминает оригинал. Здесь Модель не генерирует никаких событий, а Вид ни на что не подписывается - вместо этого Контроллер явно вызывает его, чтобы сгенерировать страницу.
А вот та часть, где Контроллер вызывает Модель, чтобы совершить какую-то операцию или получить данные, осталась.
Мне кажется, у автора путаница из-за того, что словом "модель" иногда называют один класс, обеспечивающий взаимодействие с БД (например, класс User), а иногда "модель" это часть MVC-приложения, содержащая множество классов. Никто не говорит, что в MVC приложение должно состоять из одного Контроллера, одной Модели и одного Вида. И никто не говорит, что Модель это только класс, взаимодействующий с БД.
> Например, где хранить бизнес-логику? Вики говорит, что в модели, а здравый смысл шепчет: "в контроллере". Потому что контроллер есть всегда, а вот модель и вид... как карта ляжет
Бизнес-логика хранится в сервисах, которые являются частью модели MVC. Модель это не только сохранение данных в БД.
> почему на второй схеме есть роутер и действие, а в аббревиатуре никаких букв по этому поводу нет
Потому, что приложение состоит не только из M, V и С, а еще и из других вспомогательных классов. А "действие" это и есть Контроллер. Просто для удобства несколько действий объединены в один класс, который тоже называют контроллер. То есть мы можем сказать, что метод "играет роль контроллера при обработке запроса", и можем назвать класс с такими методами "контроллер", хотя по факту это набор нескольких контроллеров. Это немного путает, но суть-то не меняется: Контроллер это компонент, который отвечает за взаимодействие с пользователем (прием HTTP-запросов) и управляет Моделью.
> что является моделью в MVC для веба?
Модель это компонент приложения, содержащий бизнес-логику и не занимающийся отображением данных или приемом запрос от пользователей.
> А что делать, если на странице ДВА объекта-модели? На
И в чем проблема? Никто не говорил, что контроллер/вид обязаны работать только с одним классом из модели.
> Но при этом активно гнобят тех, кто пытается засунуть логику (например отправку письма или запрос к базе) в контроллер, называя это "плохой практикой".
Это и есть плохая практика. Если ты поместишь регистрацию пользователя в сервис, то этот код можно повторно использовать - вызвать из любого другого места приложения. А если в контроллер, то его нельзя вызвать, и если где-то еще понадобится зарегистрировать пользователя, то придется делать копипаст.
> Когда задача выходит за рамки документации, то начинается полёт буйной фантазии разработчиков. Обычно такие полёты и порождают монстров в тысячи строк. Это, увы, не редкость в современном веб-MVC.
Так это не проблема архитектуры MVC. Это проблема того, что разработчики ошибочно думают, что "модель это только код, работающий с БД" и пихают бизнес-логику в Контроллер.
> Некоторые оправдывают использование ООП для контроллеров возможностью писать юнит-тесты и повторно использовать отдельные методы класса.
Код в контроллере, как правило, нельзя повторно использовать (вызывать из других классов). Потому в Контроллере не должно быть много кода, и бизнес-логики.
> Наверное можно, но обилие лишних классов само по себе превращает проект в сплошной кусок сами-знаете-чего.
Они не лишние.
> Если бы я попытался идти по пути, например, Yii 2, то только представьте сколько форм, моделей, контроллеров пришлось бы создавать и как-то связывать вместе.
Не вижу проблемы. Если для решения задачи нужно написать 100 000 строк кода, то ты либо напишешь их все в одном файле, либо в 10 файлах по 12 000 строк, либо в 100 файлах по 1200 строк, либо в 1000 файлов по 120 строк. Я думаю, удобнее работать с кодом, где не более 500-1000-2000 строк в одном файле. Просто надо грамотно разнести этот код на классы, определить зону ответственности каждого класса. И не придумывать искуственных ограничений, вроде "модель может только работать с БД".
Если у тебя есть вопросы по ООП, можешь их задать. Если ты хочешь изучить основы ООП, то можно начать с главы про ООП для начинающих в учебнике в первом посте треда.
>>283261
Лучше сделать отдельную папку для проектов:
d:\projects\students (Windows)
/var/www/students (Linux)
Тебе понадобится VirtualHosts, если ты используешь Апач. Но для локальной разработки удобнее использовать встроенный в PHP сервер без Апача.
>>283798
Код на картинке как раз нормальный. А то, что он внизу статьи приводит, уже не совсем то.
Обычно это делают в функции получения данных. То есть функция делает запрос, получает результат, в идеале преобразует его в объекты (а не массив) и возвращает данные.
>>284288
Проверь, что пишется в адресной строке браузера. Если там
file:///c:/php/index.php
То это значит, что ты открываешь файл напрямую браузером в обход сервера и браузер, естественно, не будет выполнять PHP-код. При работе через сервер в адресной строке будет что-то вроде
http://127.0.0.1:5000/index.php
Также, проверь, что в PHP ты используешь открывающие теги <?php, а не <?.
Конкретно по MVC - в уроке тут https://github.com/codedokode/pasta/blob/master/arch/mvc.md есть пример кода (хоть и упрощенный). Можно делать по аналогии.
Если что-то непонятно - спрашивай.
>>284601
Роутер из урока работает только со встроенным в PHP сервером (который запускается через командную строку как php -S ....). Для Апача нужно сделать файл .htaccess, который будет перенаправлять все запросы на index.php
Для этого надо изучить mod_rewrite и после этого погуглить "apache перенаправление запросов на index.php". И взять код из результатов поиска.
Кстати, автор в конце приводит свой код "без MVC", но он как раз процентов на 80 соответствует MVC:
"action без MVC" играет роль Контроллера (никто не требует, чтобы Контроллер был классом: функция или скрипт тоже могут быть Контроллером)
Module('widgets')->execute('handle.php'); - это по моему неудачный код (так как идет в обход автозагрузки классов), но это видимо тоже кусок Контроллера, просто названный "handler".
> $items = Site\ConsultantRepository::findMany($searchParams, $pagination); - это явно обращение к Модели
> Template()->render('~/search-form.php', $searchParams); - это вызов Вида
> echo Widget('consultant.information', $profile, $this->params) -Это вызов другого Вида
>Бизнес-логика хранится в сервисах, которые являются частью модели MVC.
Не вижу буквы S - Services в аббревиатуре MVC. Имхо она вообще не про это, а про общие понятия архитектуры. И что плохо - дальше никто не рассказывает новичкам что это за сервисы в контексте архитектуры, максимум только в самых общих словах. Для понимания это темы нужно отдельно гуглить её. А вот пресловутое MVC из каждого утюга доносится.
>Модель это не только сохранение данных в БД.
Пихать в модель бизнес-логику тоже такое себе. Модель именно про работу с бд иначе получаем очередной монструозно распухший слой в приложении, только теперь вместо контроллеров будут модели.
>только теперь вместо контроллеров будут модели
В смысле вместо толстых контроллеров будут толстые модели. Шило на мыло кароч.
>Код на картинке как раз нормальный
>html в контроллере
>переменные которые вызываются лишь раз
>нормально
>html в контроллере
Скорее всего этот пример там скопипащен из туториала\документации. Хтмл-разметка там приведеня для примера как можно отдавать респонс и никто так не делает в реале.
>переменные которые вызываются лишь раз
А сколько раз их надо использовать? Или ты считаешь, что нормально и читабельно городить метод(другойМетод(третийМетод())) только ради того чтобы не использовать лишнюю переменную? Так-то они пользу приносят большую, рассказывая читающему программисту - какими данными оперирует текущий кусок кода.
> Не вижу буквы S - Services в аббревиатуре MVC.
Ты невнимательно прочел. Я написал "... сервисах, которые являются частью модели MVC". Модель - это не только работа с БД, но и бизнес-логика.
> Пихать в модель бизнес-логику тоже такое себе. Модель именно про работу с бд иначе получаем очередной монструозно распухший слой в приложении, только теперь вместо контроллеров будут модели.
Это ты сам себе придумал. Модель это не только работа с БД, а вообще вся бизнес-логика. Расчет скидки в зависимости от дня недели - это бизнес логика и она должна быть в модели, хотя здесь нет работы с БД.
> вместо толстых контроллеров будут толстые модели
Ты не понял, в чем проблема толстых контроллеров. В том, что код в них нельзя повторно использовать. Допустим, ты поместил расчет скидки в контроллер. Когда тебе где-то в другом месте кода понадобится рассчитать скидку, ты не сможешь его вызвать. А если ты поместишь этот код в сервис, то сможешь вызывать его откуда угодно.
И тестировать код будет удобнее. И не будет God-объектов контроллеров, которые отвечают за все на свете, включая расчет скидок.
>на уровне бутстрапа
В смысле? Бутстрап делают очень неплохие фронтенд-разработчики.
Верстать на его уровне это топ вёрстки с многолетним опытом продакшена с хайлоадом.
Если ты имеешь ввиду верстать на компонентах бустрапа, то это такое себе. Уровень бекенд разраба потянет - только чтоб показать как ты умеешь и что твой софт показывает и даже имеет интерфейс. Интерфейс который на человеческий похож в смысле.
А, ну и вёрстки сегодня вообще никак - никто тебя на работу не возьмёт скорее всего. По крайней мере без БЭМа, SAAS и прочих галпов. Вангую, что ещё за СЕО будут спрашивать и вордпресс какой-нить.
>только ради того чтобы не использовать лишнюю переменную
http://sandbox.onlinephpfunctions.com/code/67f495f3f87898a1147f5010c67551a262462430
Действительно, всего то 0.05 сек. в среднем в одном классе...
А когда у тебя сотни классов из которых выливаются тысячи таких переменных, что будет тогда? Секунды задержек, десятки секунд?
>пик3. Очень нечитабельно, правда? С таким мышлением не бывать тебе на хайлоад проекте.
>рассказывая читающему программисту
Это можно сделать комментариями которые будут полезнее и разрабу и сайту будет легче выполнять код с прямым вызовом, а не собирать потом десятки ненужных переменных в каждом классе.
Хнык хныыык! Зачем нам грамотный код, если он некрасивый!?
>Действительно, всего то 0.05 сек. в среднем в одном классе...
Ты чё, дурак? У тебя там 10 миллионов вызовов. Ты масштабы совсем не понимаешь что ли? И что только 0.05 сек? Откуда ты 10 млн данных взял? Посиди и подумай сколько времене та же ДБ тебе будет выдавать этот объём и прикинь в каком сравнении с 0.05сек.
>Хнык хныыык! Зачем нам грамотный код, если он некрасивый!?
Грамотный код - легко поддерживать, а значит читать и вносить изменения. Код, где дрочат быстроту - код наивного джуниора и не бывает грамотным.
Можешь сразу писать в байткодах - тогда вообще быстро будет. Ты ж любишь когда быстро и неподдерживаемо.
>Ты чё, дурак?
Дурак тут как раз ты, который не имел дело
1. С парсингом больших данных.
2. С загруженными проектами
>У тебя там 10 миллионов вызовов
Для контраста было 10кк вызовов, чтобы не искать с лупой разницу, а видеть её воочию.
10к человек вызвали страницу на которой цикл в скрипте делает 1к итераций. На сайте госсуслуг например 80кк запросов в сутки 55К запросов в минуту блядь, а это был простой скрипт вызова массива, а что если создавать лишнюю переменную для объекта?
>Грамотный код - легко поддерживать
Грамотно построенную архитектуру легко поддерживать, с хорошо описанным кодом, а грязный код с кучей лишних переменных наоборот его засоряет и читать становится сложнее.
>Код, где дрочат быстроту - код наивного джуниора
Как раз таки код с кучей лишних переменных я видел только при ревью джунов. Если ты оправдываешь подобный подход чистоты кода, то не сложно догадаться о твоём уровне.
>1. С парсингом больших данных.
Скорость получения этих данных мы не считаем, да?
>2. С загруженными проектами
Кем загруженными, вкатыш? Грузчиками?
>Для контраста было 10кк вызовов, чтобы не искать с лупой разницу, а видеть её воочию.
Синтетический тест без контекста это конь в вакууме и ни о чём не говорит. Обоссан.
Просто не знаю как это загуглить.
Нет удалёнки - это чисто для соевых ДСовцев вакуха с возможностью переката за бугор. Все остальные могут расслабить булки. Поэтому и зряплата под 300к, и то не каждый сунется.
Некуда тут вкатываться.
>Скорость получения этих данных мы не считаем, да?
Не виляй в скорость получения данных если ты ей сам препятствуешь выделяя лишнюю ячейку в памяти вместо того, чтобы просто передать данные напрямую.
Ты же реальный дебил который вместо прямого пути, рассказывает о том, что путь с лишней точкой будет лучше.
А когда ты понял, что жидко обосрался решил вильнуть в скорость получения данных, лул.
>Кем загруженными
Мамашей твоей жирной, клоун. Какая же ты тупая пэхапэ макака
>Синтетический тест
Сам то хоть понял, что написал?
>Обоссан
Как скажешь, пехапе макак, как скажешь.
>высрать тонну текста про ооп, паттерны программирования, шаблоны базы данных, валидацию и архитектуру
>ой, а че непонятно что-ли?
>>высрать тонну текста
Ты же здесь всем платишь, и все обязаны тратить на тебя своё время разжёвывая информацию из открытого доступа, правильно?
> Открываешь любой говноканал на ютубе > впитываешь...
use Roma\ReiTs\core\DB as database;
use DI\Container;
$container = new DI\Container();
class Turbo
{
public function __construct()
{
echo "kek";
}
}
$model_user = $container->get('database');
Класс турбо оно создает, а вот database кидает ошибку, и я не могу правильно как правильно передавать ему имя класса, постоянно в выдаче контейнер докера
Ты полагаешься на auto-wiring (автоматическое определение зависимостей через анализ параметров конструктора)?
Тогда надо передавать в get() полное имя класса. Не строку 'database', а строку 'Roma\Rei\core\DB'. Чтобы не писать эту строку, лучше писать просто database::class. ::class это встроенная константа, которая содержит полное имя класса.
В начале задачи написано:
> Требуется знать: PHP, основы ООП, основы языка SQL, основы HTML/CSS, формы, таблицы
Если ты не знаешь основ ООП, то советую открыть учебник из шапки, в нем главу про ООП. Там написано для начинающих.
По поводу остального, я постарался поставить ссылки на уроки. Хотя, наверно, не все объяснено, увы. Кроме уроков, можно попробовать самому гуглить незнакомые термины.
Я думаю сложен для многих переход от теории к практике, читаешь книжку/смотришь видео про язык и технологии, а потом открываешь какое-нибудь такое задание и вспоминаешь этот мем.
Когда стоит идти на собес по laravel? Где посмотреть вопросы примерные,?
Доделываю пет, затем планирую начать откликаться на вакансии. Быстро просмотрел несколько вакансий, где то есть пункт с тестовым, где то нет.
Какой сейчас положняк? Есть вариант найти работу без выполнения ебучих тестовых залуп? В жыесе я еще могу понять, там огромный наплыв и нужно как то отсеять орков этим тестовым, но в php нет такой активности.
Практически везде есть тестовое. Если есть похожий проект на гите то можно его показать, но не везде. Джуны всё равно нигде не нужны, а тестовое максимум несколько часов займет. Так что ничего страшного так-то
Ладно, придется потерпеть.
А че там в виде тестового дают обычно? Буду искать php, laravel, мб + htmlcssjsvue
Спасибо братанчик, работает. Единственно что приходится писать $container->get('\Roma\ReiTs\models\Model_User');
И кстати в видео с объяснением про диай-контейнер прочитал коммент что типа "УДАЧИ , ТИПА ТАКОЕ АРХИТЕКТУРНОЕ РЕШЕНИЕ ГОВНА КУСОК". Я теперь сижу и думаю, а почему это говно, как бы все пользуются все фреймворки пользуюься. Держи няшу.
Даже среди рубистов подрастающие разрабы есть
мимокатун
>подрастающие разрабы
Это типа школота вчерашняя? Ну так пока мамка кормит вот и учат всякое борщехлебское хипстерское - работать не надо. У взрослых же есть обязательства и им нужен просто инструмент для работы и, соответственно, работа.
Тоже как-то общался с таким 18-летним тимлидом - по ушам мне ездил какой он важный в конторе своих одноклассников кто ж его ещё тимлидом поставит?. Выглядело максимально инфантильно это всё.
Среди питонистов тоже вот малолеток дофига и что? Кому они нужны? С малолетками работать - одни проблемы обычно.
Нахуя все катятся в вп и битрикс, если уж хотите цмс, то почему не магенто?
Мадженто объемный, на нем мало вакансий. Единственная контора, которая обучает джунов, находится в Ульяновске. Там надо работать оффлайн. Никто не хочет к ним ехать, хотя они даже релокационный пакет предоставляют в виде оплаты 1 месяца хаты.
Может, кто знает где пример найти?
>Никто не хочет к ним ехать
Потому, что долбоёбов нет - лучше в ДС уехать тогда, чем в этот Ульяновск.
Это ещё при условии, что в Ульяновске не кидалово, хотя может быть таким. Потом поедешь обратно на попутках без денег, расплачиваясь пердаком.
Просто рынки РФ и Украины разные
У нас и salesforce популярный, в рфии о таком и не слышали наверное
Вп востребован больше, чем любая другая технология в вебе, вкатиться легче чем в ларавель, симфони и даже битрикс, через год можно стать твердым миддлом и получать на равне с симфони и ларавель разрабами. Ну и конечно возможность фриланса выше чем на другом стеке.
Есть в Воронеже контора, которая обучает salesforce. Так что не гони лошадей, РФ не хуже.
Я не гоню и не говорю, что лучше или хуже. Просто в РФ не так распространен аутсорс, отсюда и разная востребованность отдельных направлений
>Вп востребован больше, чем любая другая технология в вебе
Он востребован у дешманских кабанчиков, которые сами себе сайты делают. С ним не заработаешь, разве только если темы и плагины делать и продавать. Ну и уровень разработчика там хуёвенький довольно - ближе к верстальщикам даже.
>Просто в РФ не так распространен аутсорс
Да почти вся рашка на забугор работает в ИТ, в крайнем случае на ДС-заказчиков. Весь СНГ аутсорсом живёт потому, что нищета ебаная.
Дока в елокуент как то сильно уж впаяна в ларавель и как то оно мне выглядит не полной
Я в своей слимосборке идиорм использовал. Но там он только в виде билдера запросов чтоб с sql не возиться и самому поменьше писать. Поверх него репозитории уже.
А идти учиться основам сами знаете куда
_мимо бекендер 3 года опыта, бусь со студентами по вечерам_
eloquent легко отделяется от лары и не мертвое говно как cake
>Ты не понял, в чем проблема толстых контроллеров. В том, что код в них нельзя повторно использовать. Допустим, ты поместил расчет скидки в контроллер. Когда тебе где-то в другом месте кода понадобится рассчитать скидку, ты не сможешь его вызвать. А если ты поместишь этот код в сервис, то сможешь вызывать его откуда угодно.
Нахуя это выносить, если это делается в 2 клика идехой? Тем более нафига выносить, если используется в одном месте.
И можешь ли ты пояснить за сервисы - зачем они нужны?
Кто тебе мешает работать на западного барина, 12к+ задач на апворке по вордпрессу и цена там почти не отличается от разрабов на любом другом стеке.
Компоненты Симфони не привязаны к фреймворку и могут использоваться отдельно. Ты можешь найти документацию по компоненту валидации тут https://symfony.com/doc/current/components/validator.html
Да, строка RewriteCond должна провпускать замену URL со стилями.
Ты можешь выяснить, почему так не происходит, включив режим отладки mod_rewrite и перезапустив сервер. Чтобы включить отладку, надо вписать в конфиг указанную тут директиву: https://httpd.apache.org/docs/current/mod/mod_rewrite.html#logging
Специальные символы вроде < или & нельзя просто так вписать в HTML, так как они будут восприняты, например, как начало HTML-тега. Потому < надо заменять на <
Аналогично, " надо заменять на " так как иначе не получится вписать эту кавычку внутрь аттрибута.
Не надо делать красиво, надо делать правильно.
Лол, макака не экранирует html?
> если это делается в 2 клика идехой?
Я даже не понял, что ты предлагаешь. Скопировать код 2 раза? Это глупость, так как если ты захочешь что-то поменять, то тебе придется менять в двух местах и делать двойную работу.
IDE не сделает за тебя архитектуру. Это лишь инструмент.
> Тем более нафига выносить, если используется в одном месте.
Во-первых, сегодня оно используется в одном месте, а завтра не в одном. Во-вторых, код нужно автоматически тестировать, а для этого нужно, чтобы его можно было удобно вызвать, а для этого он должен быть не в контроллере.
> сервисы - зачем они нужны?
В них содержится бизнес-логика приложения, отделенная от интефрейса. "Бизнес-логика" - это правила, по которым работает приложение. Например, для магазина бизнес-логика это процессы расчета цены, расчета стоимости доставки, оформления заказа. "отделенная от интерфейса" значит, что сервисы не генерируют HTML-код, ничего не выводят и не принимают HTTP-запросы (GET/POST). Все, что нужно сервису, передается в него через переменные, и все, что он дает на выходе, также возвращается через обычный return. Никаких $_COOKIE, $_GET, $_POST, echo в нем нету.
Ну например, ты пишешь магазин и тебе надо рассчитывать стоимость доставки в определенный город. Ты делаешь для этого сервис. Функция в нем принимает id города и возвращает стоимость доставки или признак, что доставка невозможна.
Эта функция никак не привязана к интерфейсу сайта, потому ее можно вызывать откуда угодно, и из веб-скриптов, и из командной строки, и из тестов.
Или ты решил сделать регистрацию на сайте. Регистрация включает в себя: проверку правильности заявки на регистрацию, создание нового пользователя, отправку письма для подтверждения email, автоматический логин под только что созданным аккаунтом. Этим всем может заниматься один или несколько сервисов.
Даже если у тебя просто блог со статьями, в нем есть бизнес-логика: поиск статьи по URL, загрузка комментариев к посту, вывод ссылок на следующий/предыдущий пост. Это все бизнес-логика, которую логично поместить в сервис.
Официальное определение слоя сервисов ты можешь прочесть у Фаулера: https://martinfowler.com/eaaCatalog/serviceLayer.html Более подробное объяснение можно найти в его книге "Шаблоны корпоративных приложений". Она есть в том числе и на русском языке.
Эта книга может быть немного непонятна для начинающего без опыта, но она полезна, если ты хочешь научиться разбираться в архитектуре и изучить существующий опыт, а не изобретать велосипеды.
> если это делается в 2 клика идехой?
Я даже не понял, что ты предлагаешь. Скопировать код 2 раза? Это глупость, так как если ты захочешь что-то поменять, то тебе придется менять в двух местах и делать двойную работу.
IDE не сделает за тебя архитектуру. Это лишь инструмент.
> Тем более нафига выносить, если используется в одном месте.
Во-первых, сегодня оно используется в одном месте, а завтра не в одном. Во-вторых, код нужно автоматически тестировать, а для этого нужно, чтобы его можно было удобно вызвать, а для этого он должен быть не в контроллере.
> сервисы - зачем они нужны?
В них содержится бизнес-логика приложения, отделенная от интефрейса. "Бизнес-логика" - это правила, по которым работает приложение. Например, для магазина бизнес-логика это процессы расчета цены, расчета стоимости доставки, оформления заказа. "отделенная от интерфейса" значит, что сервисы не генерируют HTML-код, ничего не выводят и не принимают HTTP-запросы (GET/POST). Все, что нужно сервису, передается в него через переменные, и все, что он дает на выходе, также возвращается через обычный return. Никаких $_COOKIE, $_GET, $_POST, echo в нем нету.
Ну например, ты пишешь магазин и тебе надо рассчитывать стоимость доставки в определенный город. Ты делаешь для этого сервис. Функция в нем принимает id города и возвращает стоимость доставки или признак, что доставка невозможна.
Эта функция никак не привязана к интерфейсу сайта, потому ее можно вызывать откуда угодно, и из веб-скриптов, и из командной строки, и из тестов.
Или ты решил сделать регистрацию на сайте. Регистрация включает в себя: проверку правильности заявки на регистрацию, создание нового пользователя, отправку письма для подтверждения email, автоматический логин под только что созданным аккаунтом. Этим всем может заниматься один или несколько сервисов.
Даже если у тебя просто блог со статьями, в нем есть бизнес-логика: поиск статьи по URL, загрузка комментариев к посту, вывод ссылок на следующий/предыдущий пост. Это все бизнес-логика, которую логично поместить в сервис.
Официальное определение слоя сервисов ты можешь прочесть у Фаулера: https://martinfowler.com/eaaCatalog/serviceLayer.html Более подробное объяснение можно найти в его книге "Шаблоны корпоративных приложений". Она есть в том числе и на русском языке.
Эта книга может быть немного непонятна для начинающего без опыта, но она полезна, если ты хочешь научиться разбираться в архитектуре и изучить существующий опыт, а не изобретать велосипеды.
Текст поста исказился. Надо читать так:
Специальные символы вроде < или & нельзя просто так вписать в HTML, так как они будут восприняты, например, как начало HTML-тега. Потому < надо заменять на & lt ;
Аналогично, " надо заменять на & quot ; так как иначе не получится вписать эту кавычку внутрь аттрибута.
>Нахуя это выносить
Именно так и появляется страшный легаси
Допустим твой проект разрастётся до неебических размеров, представь какой ад ты сотворишь с таким подходом и с каким матом нужно будет менять что либо в этом контроллере.
>>293365
Пожалуй удвою и ходелось бы дополнить, что контроллер должен лишь передавать данные в определённый эндпоинт, а не получать данные, выполнять с ними бизнес-логику и передавать т.к это уже нарушает принцип единой ответственности.
Вроде всё описал, как бы вы оценили это место?
Но в то же время есть другая вакансия (нормальные стэк лары с вью, рест), где после первого собеседования (с нормальными тех. вопросами) дали тестовое по рест апи, потом будет ещё одно собеседование. Есть вариант его подождать.
Зарплата там и там +- одинаковая.
Наверное, только хекслет, но это не точно сам там не учился.
Максимум что могу придумать - это такой код.
Спасибо. Ты по какому-то учебнику/курсу учишься? Я 11 день вкатываюсь по учебнику Кузнецова и Симдянова по часу-два в день. Дошел до массивов, а ты уже на функциях.
Я на хекслете учусь (с платной подпиской) по 4-6 часов в день
Не нашел другого ресурса по php. Отзывы вроде бы хорошие, вот и решил попробовать. + мотивация быстрее пройти курс, потому что 3900 каждый месяц отдавать безработному зумерку как то не хочется
С работой совмещал? Сколько лет было когда вкатился?
чисто по функциям можно так решить =)
Погуглить основы и не пытаться осваивать Эверест без подготовки.
Говорить куда пойти не стану. Это неважно.
Бесконечный респект ОПу, у него отличные гайды, задачки. Но есть профессиональные люди, которые обучены под это дело и учат людей. В том числе дают много бесплатного контента.
Но спустя годы (в тч знаписания своего кода и обучения других) я вижу, что текущий подход все более неправильный и множество людей вкатилось вопреки, а множество не вкатилось вообще.
если 16-18 лет, то да. Но можно еще норм колледж\пту. Или курсы какие-нибудь хорошие.
Но универ, чтобы сменить профу на прогера - это лишнее.
>Я даже не понял, что ты предлагаешь. Скопировать код 2 раза? Это глупость, так как если ты захочешь что-то поменять, то тебе придется менять в двух местах и делать двойную работу.
Зачем копировать? Нужно прежде подумать несколько раз, нужно ли что-то выносить куда-то в сервис или любой другой класс.
Как правило дублирование кода не есть плохо. Будут места, где он будет всегда дублироваться. И если ты что-то вынесешь, то станет только сложнее.
Дублирование кода говорит о том, что есть какая-то абстракция (но далеко не всегда.
Чем проще код тем он лучше, а когда кода нет - все еще лучше. Условно говоря, тебе будет проще воспринимать код, если все будет в одном месте, на одном экране, чем размазано по куче вызовов
>Во-первых, сегодня оно используется в одном месте, а завтра не в одном. Во-вторых, код нужно автоматически тестировать, а для этого нужно, чтобы его можно было удобно вызвать, а для этого он должен быть не в контроллере.
Вот когда завтра оно будет не в одном месте, а в нескольких, тогда и поправишь. YAGNI
Просто нужно уметь писать тесты, а не городить 100500 юнитов с моками и стабами. Даже в Студентах тесты легко пишутся, когда код находится внутри условных контроллеров.
>В них содержится бизнес-логика приложения, отделенная от интефрейса.
Все так и есть, но это не означает, что этот слой нужно выделять в отдельные классы-сервисы. Нет просто такого требования. Это означает, что код вполне может быть внутри контроллера.
Опять же, пока у тебя чисто вебчик, без апи, кронов, событий чем проще код тем лучше.
Не нужно всем и вся рекомендовать выносить в сервисы код. Можно легко себе ноги отстрелить и ходить на костылях
p.s. книга у меня есть, на русском, просто читается местами тяжко
>Именно так и появляется страшный легаси
>Допустим твой проект разрастётся до неебических размеров, представь какой ад ты сотворишь с таким подходом и с каким матом нужно будет менять что либо в этом контроллере.
Лол, причем тут легаси и размер контроллера. При нормальном подходе такой код будет локализован в контроллере и его легко можно будет вынести отдельно. Легаси (в плохом понимании) появляется растет от того, что нет головы на плечах. Не нужно городить в рамках одного контроллера кучу всего. Тогда даже зависимостей будет минимум.
>Пожалуй удвою и ходелось бы дополнить, что контроллер должен лишь передавать данные в определённый эндпоинт, а не получать данные, выполнять с ними бизнес-логику и передавать т.к это уже нарушает принцип единой ответственности.
> нарушает принцип единой ответственности.
баззворды пошли
Но есть проблема, я не могу придумать проект. Подтолкните, пожалуйста в сторону.
Не пытайся натянуть задачу под технологии.
Попробуй сделать аналог любого популярного сервиса. Или просто интернет-магазин
Спасибо
Обычная подписка на 1 месяц с полным доступом ко всем курсам.
С оплатой на 100к это тоже самое, только на тебя вешают "наставника", есть какое то наблюдение, помощь в трудоустройстве и тд короче для ленивых или не волевых, но с деньгами
>>294377
Профессия php, только самостоятельно по подписке
>Лол, причем тут легаси и размер контроллера
>и его легко можно будет вынести отдельно
>что нет головы на плечах
Почему бы сразу его не вынести, чтобы твой класс сразу был чистеньким и тоненьким радуя глаз? А то как не придёшь на проект с легаси, а там классы по 2к строк, сидишь и думаешь: Нахуй оно мне надо!?
Затем, что это не нужно.
Сегодня мы вынесем это в отдельный класс. Завтра другое, третье десятое. Когда остановимся?
Если классы по 2к строк - то у ребят проблема. И дело вовсе не в том, что в контроллерях пишут код. Не надо путать причину и следствие
>Завтра другое, третье десятое. Когда остановимся?
>Давайте писать теперь всё это в контроллерах
>Если классы по 2к строк - то у ребят проблема
Это твоя проблема тоже, ты шаблон вообще не улавливаешь? Эти ребята тоже скорее всего думали, что выносить функционал нинужна, а теперь сидят с огромным классом который нарушает принципы SOLID и боятся в нём пёрнуть т.к нихуя не понятно и похуй, что там может 5 раз встретится один и тот же блок кода.
Разбираться ты как будешь когда твой контроллер разрастётся? Рефакторить целую неделю с горящим очком и красными экранами от каждого изменения в коде?
А может лучше сразу написать сервис и хелпер для контроллера, чтобы в будущем не рвать волосы на жопе когда нужно будет расширить функционал твоего контроллера?
Выше даже написали:
>>293365
>Во-вторых, код нужно автоматически тестировать, а для этого нужно, чтобы его можно было удобно вызвать, а для этого он должен быть не в контроллере.
> И дело вовсе не в том, что в контроллерях пишут код
А в чём же? Я весь внимание.
> Как правило дублирование кода не есть плохо. Будут места, где он будет всегда дублироваться. И если ты что-то вынесешь, то станет только сложнее.
Ты ошибаешься. Во-первых, дублирование приводит к увеличению объема кода, и увеличению затрат времени на его изучение. Во-вторых, если тебе надо что-то поменять, то с дублированием кода тебе придется менять это во многих местах, что опять увеличивает затраты времени.
Дублирование может быть выгодно только если твое время бесплатное.
Дальше, когда ты выносишь код в функцию, то его становится проще читать. Сравни:
$privs =DB::select(Privileges::class)->where('user', $user)->all();
if (!(in_array(Priv::CAN_EDIT_POST, $privs) &&
$post->getOwner() === $user &&
(new \DateTime())->diff($post->getTime()))->days < 10)) {
throw new AccessDeniedError();
}
И это:
if (!$auth->canEditPost($user, $post)) {
throw new AccessDeniedError();
}
Второе, очевидно, читается проще, а ведь здесь всего-то 4 строчки бизнес-логики.
> И если ты что-то вынесешь, то станет только сложнее.
Давай объективно рассмотрим, насколько код станет сложнее от его вынесения в функцию в другом файле.
Было: 20 строк кода
Стало:
- импорт функции из файла (1 строка)
- вызов функции (1 строка)
И в новом файле:
- заголовок функции (1 строка)
- 20 строк кода
- закрывающая скобка (1 строка)
Как мы видим, добавилось лишь 4 тривиальных строки. И, как мы видим из примера кода выше, код стал проще для чтения, а не сложнее. Экономится как время на изучение кода, так и на исправление.
> Как правило дублирование кода не есть плохо. Будут места, где он будет всегда дублироваться. И если ты что-то вынесешь, то станет только сложнее.
Ты ошибаешься. Во-первых, дублирование приводит к увеличению объема кода, и увеличению затрат времени на его изучение. Во-вторых, если тебе надо что-то поменять, то с дублированием кода тебе придется менять это во многих местах, что опять увеличивает затраты времени.
Дублирование может быть выгодно только если твое время бесплатное.
Дальше, когда ты выносишь код в функцию, то его становится проще читать. Сравни:
$privs =DB::select(Privileges::class)->where('user', $user)->all();
if (!(in_array(Priv::CAN_EDIT_POST, $privs) &&
$post->getOwner() === $user &&
(new \DateTime())->diff($post->getTime()))->days < 10)) {
throw new AccessDeniedError();
}
И это:
if (!$auth->canEditPost($user, $post)) {
throw new AccessDeniedError();
}
Второе, очевидно, читается проще, а ведь здесь всего-то 4 строчки бизнес-логики.
> И если ты что-то вынесешь, то станет только сложнее.
Давай объективно рассмотрим, насколько код станет сложнее от его вынесения в функцию в другом файле.
Было: 20 строк кода
Стало:
- импорт функции из файла (1 строка)
- вызов функции (1 строка)
И в новом файле:
- заголовок функции (1 строка)
- 20 строк кода
- закрывающая скобка (1 строка)
Как мы видим, добавилось лишь 4 тривиальных строки. И, как мы видим из примера кода выше, код стал проще для чтения, а не сложнее. Экономится как время на изучение кода, так и на исправление.
Ты так пишешь, как будто "вынести в другой класс" это какая-то непосильная задача. Если у тебя в голове или на бумаге описана архитектура, то ты сразу понимаешь, что где должно располагаться и сразу помещаешь в нужный класс без лишних затрат времени.
> Если классы по 2к строк - то у ребят проблема. И дело вовсе не в том, что в контроллерях пишут код. Не надо путать причину и следствие
По моему, ты ошибаешься. Если для решения какой-то задачи необходимо написать 10 000 строк логики - то их придется написать в любом случае. Нет какого-то секретного рецепта, как 10 000 строк превратить в 100. Просто их можно аккуратно расположить в соответствующих классах-сервисах, покрыть тестами, а можно свалить все в одну кучу, в которой страшно что-то трогать.
>пишешь, как будто "вынести в другой класс" это какая-то непосильная задача
Скорее всего для него это действительно непосильная задача потому, что он ООП не умеет и в архитекуру тоже. Там без вариантов будут методы по 100500 строк как у любого начинающего.
Документация это справочник в первую очередь. Хз как по справочнику вкатываться собрался.
>Это твоя проблема тоже, ты шаблон вообще не улавливаешь? Эти ребята тоже скорее всего думали, что выносить функционал нинужна, а теперь сидят с огромным классом который нарушает принципы SOLID и боятся в нём пёрнуть т.к нихуя не понятно и похуй, что там может 5 раз встретится один и тот же блок кода.
>Разбираться ты как будешь когда твой контроллер разрастётся? Рефакторить целую неделю с горящим очком и красными экранами от каждого изменения в коде?
>А может лучше сразу написать сервис и хелпер для контроллера, чтобы в будущем не рвать волосы на жопе когда нужно будет расширить функционал твоего контроллера?
>Выше даже написали:
Анон, зачем тым не пишешь про солид, про то, что написали? Есть своя голова на плечах? Я вот пишу свои костыли для студентов. Написал автотесты. все работает. Есть база, есть приложение. Думаешь, что я тестирую внутренности отдельно? Хуй тебе, я не долбоеб. Один нормальный тест заменяет сотню хуевых. Один нормальный тест помогает рефакторить все приложение внутри, а тесты не меняются. Если ты мне пишешь про хелпер и сервис, то ты не понимаешь что это такое, зачем это нужно.
Ты же сам пишешь про рефакторинг на целую неделю. Но нормальный код не проблема рефакторить неделю. Т.е. проблема не в том, что код к контроллере, а контроллер на 2к строк. Скорее проблема в программистах, которые писали само приложение.
Еще раз - современные средства разработки (aka фреймворки и IDE) позволяют тебе писать код в ТЫСЯЧУ раз проще и быстрее, чем раньше. Сравни тех же студентов на самописе (чисто пыха) и с либами\фреймворками.
Я уже заебался писать код на моменте работы с формой - провалидировать всю хуйню, экранировать, вывести ошибки. Передать туда сюда.
Думаешь у меня есть сервис? Нет, нихуя. У меня есть класс типа контроллера, в зависимостях класс для работы с бд (сохранение, поиск). И основной флоу описан именно в контроллере. - получить данные, собрать в форму, провалидирвоать, высрать ошибки или зарегать.
Всё. Никакой проблемы с этим нет. Если бы я это делал на ларавел, то делал бы еще проще - там есть механизмы валидации, вывода ошибок. Мне даже не пришлось бы создавать отдельный FormRequest (это в ларе класс с запросом, куда правила валидации можно прописать), потому что в этом нет смысла, сложность не вырастет, если я напишу это внутри метода. Метод выйдет ну на 50 строк и похуй, зато в методе сразу все будет описано и понятно.
Я призываю думать головой (в том числе к моим словам), потому что программисты- это культисты и фанатики, которые слепо верят всему, что говорилось ранее. Чистый код для них это библия, СОЛИД - мантра.
>Это твоя проблема тоже, ты шаблон вообще не улавливаешь? Эти ребята тоже скорее всего думали, что выносить функционал нинужна, а теперь сидят с огромным классом который нарушает принципы SOLID и боятся в нём пёрнуть т.к нихуя не понятно и похуй, что там может 5 раз встретится один и тот же блок кода.
>Разбираться ты как будешь когда твой контроллер разрастётся? Рефакторить целую неделю с горящим очком и красными экранами от каждого изменения в коде?
>А может лучше сразу написать сервис и хелпер для контроллера, чтобы в будущем не рвать волосы на жопе когда нужно будет расширить функционал твоего контроллера?
>Выше даже написали:
Анон, зачем тым не пишешь про солид, про то, что написали? Есть своя голова на плечах? Я вот пишу свои костыли для студентов. Написал автотесты. все работает. Есть база, есть приложение. Думаешь, что я тестирую внутренности отдельно? Хуй тебе, я не долбоеб. Один нормальный тест заменяет сотню хуевых. Один нормальный тест помогает рефакторить все приложение внутри, а тесты не меняются. Если ты мне пишешь про хелпер и сервис, то ты не понимаешь что это такое, зачем это нужно.
Ты же сам пишешь про рефакторинг на целую неделю. Но нормальный код не проблема рефакторить неделю. Т.е. проблема не в том, что код к контроллере, а контроллер на 2к строк. Скорее проблема в программистах, которые писали само приложение.
Еще раз - современные средства разработки (aka фреймворки и IDE) позволяют тебе писать код в ТЫСЯЧУ раз проще и быстрее, чем раньше. Сравни тех же студентов на самописе (чисто пыха) и с либами\фреймворками.
Я уже заебался писать код на моменте работы с формой - провалидировать всю хуйню, экранировать, вывести ошибки. Передать туда сюда.
Думаешь у меня есть сервис? Нет, нихуя. У меня есть класс типа контроллера, в зависимостях класс для работы с бд (сохранение, поиск). И основной флоу описан именно в контроллере. - получить данные, собрать в форму, провалидирвоать, высрать ошибки или зарегать.
Всё. Никакой проблемы с этим нет. Если бы я это делал на ларавел, то делал бы еще проще - там есть механизмы валидации, вывода ошибок. Мне даже не пришлось бы создавать отдельный FormRequest (это в ларе класс с запросом, куда правила валидации можно прописать), потому что в этом нет смысла, сложность не вырастет, если я напишу это внутри метода. Метод выйдет ну на 50 строк и похуй, зато в методе сразу все будет описано и понятно.
Я призываю думать головой (в том числе к моим словам), потому что программисты- это культисты и фанатики, которые слепо верят всему, что говорилось ранее. Чистый код для них это библия, СОЛИД - мантра.
>
>Ты ошибаешься. Во-первых, дублирование приводит к увеличению объема кода, и увеличению затрат времени на его изучение. Во-вторых, если тебе надо что-то поменять, то с дублированием кода тебе придется менять это во многих местах, что опять увеличивает затраты времени.
Я уже объяснял (видимо хуево), что дублирование кода не означает, что это один и тот же код.
Давай я тебе пример приведу - напиши консольное приложение-игру, где ты играешь с компьютером. Он дает тебе задачу - "Число N является простым?" или другую задачу - "Число N является четным?", ответить ты можешь только Yes и No
Казалось бы - у тебя две функции-игры, в которых есть явно общая логика - обе работают с ответом Yes и No. Нужно ли эту часть выносить куда-то наружу? Например писать общую функцию, которая по условию выдает Yes/No?
Скорее всего нет, потому что это не абстракция, это не процесс. Если ты выделишь этот код в общий, в абстракцию, ты сделаешь код сложнее. А какая выгода будет? Никакая, только вред.
Пойми, что когда видишь код, который у тебя дублируется, это скорее всего какой-то процесс, абстракция.
Но это не всегда так. Давай другой пример - у тебя есть сайт типа Авито, объявляения и админка. В админке тоже выводятся объявления. Но будет ли разумно переиспользовать шаблоны в админке и в обычной вьюхе? Нет, нихуя подобного. Потому что у тебя для админки может быть вообще другой интерфейс (типа без картинкой и таблицей). Если у тебя будет общий шаблон, то придется городить в интерфейсе код с проверками, может ли юзер сделать что-то, является ли он админом, в итоге шаблон превратится в парашу.
И гораздо проще будет разделить эти шаблоны, хотя казалось бы и тут и там выводится одно и тоже и можно это переиспользовать (нет, нельзя).
>Дальше, когда ты выносишь код в функцию, то его становится проще читать. Сравни:
$privs =DB::select(Privileges::class)->where('user', $user)->all();
if (!(in_array(Priv::CAN_EDIT_POST, $privs) &&
$post->getOwner() === $user &&
(new \DateTime())->diff($post->getTime()))->days < 10)) {
throw new AccessDeniedError();
}
И это:
if (!$auth->canEditPost($user, $post)) {
throw new AccessDeniedError();
}
Конечно, это проще читается. Сравнил тройное условие и понятный человекочитаемый метод.
Речь изначально шла про СЕРВИСЫ и про тонкие\толстые контроллеры.
Твой контроллер тоньше от этого не стал - просто твоя абстракция (проверки доступа) находится внутри метода.
>
>Ты ошибаешься. Во-первых, дублирование приводит к увеличению объема кода, и увеличению затрат времени на его изучение. Во-вторых, если тебе надо что-то поменять, то с дублированием кода тебе придется менять это во многих местах, что опять увеличивает затраты времени.
Я уже объяснял (видимо хуево), что дублирование кода не означает, что это один и тот же код.
Давай я тебе пример приведу - напиши консольное приложение-игру, где ты играешь с компьютером. Он дает тебе задачу - "Число N является простым?" или другую задачу - "Число N является четным?", ответить ты можешь только Yes и No
Казалось бы - у тебя две функции-игры, в которых есть явно общая логика - обе работают с ответом Yes и No. Нужно ли эту часть выносить куда-то наружу? Например писать общую функцию, которая по условию выдает Yes/No?
Скорее всего нет, потому что это не абстракция, это не процесс. Если ты выделишь этот код в общий, в абстракцию, ты сделаешь код сложнее. А какая выгода будет? Никакая, только вред.
Пойми, что когда видишь код, который у тебя дублируется, это скорее всего какой-то процесс, абстракция.
Но это не всегда так. Давай другой пример - у тебя есть сайт типа Авито, объявляения и админка. В админке тоже выводятся объявления. Но будет ли разумно переиспользовать шаблоны в админке и в обычной вьюхе? Нет, нихуя подобного. Потому что у тебя для админки может быть вообще другой интерфейс (типа без картинкой и таблицей). Если у тебя будет общий шаблон, то придется городить в интерфейсе код с проверками, может ли юзер сделать что-то, является ли он админом, в итоге шаблон превратится в парашу.
И гораздо проще будет разделить эти шаблоны, хотя казалось бы и тут и там выводится одно и тоже и можно это переиспользовать (нет, нельзя).
>Дальше, когда ты выносишь код в функцию, то его становится проще читать. Сравни:
$privs =DB::select(Privileges::class)->where('user', $user)->all();
if (!(in_array(Priv::CAN_EDIT_POST, $privs) &&
$post->getOwner() === $user &&
(new \DateTime())->diff($post->getTime()))->days < 10)) {
throw new AccessDeniedError();
}
И это:
if (!$auth->canEditPost($user, $post)) {
throw new AccessDeniedError();
}
Конечно, это проще читается. Сравнил тройное условие и понятный человекочитаемый метод.
Речь изначально шла про СЕРВИСЫ и про тонкие\толстые контроллеры.
Твой контроллер тоньше от этого не стал - просто твоя абстракция (проверки доступа) находится внутри метода.
>Ты так пишешь, как будто "вынести в другой класс" это какая-то непосильная задача. Если у тебя в голове или на бумаге описана архитектура, то ты сразу понимаешь, что где должно располагаться и сразу помещаешь в нужный класс без лишних затрат времени.
Анон, это так не работает.
Вся архитектура нужна, чтобы работать со сложностью. И нет идеальной архитектуры (их вообще много разных видов и они для приложений разной сложности). Когда ты создаешь АБСТРАКЦИИ, то твое приложение становится всегда СЛОЖНЕЕ (Complex).
И архитектура по сути это тоже АБСТРАКЦИЯ.
Я видел, как на бумаге делали одну архитектуру, а она разбивалась об реальнось. Когда у тебя куча разных выводов, а еще это приправлено интерфейсами, разного рода декораторами, то больше выясняешь, Как работает код, чем пишешь его
>Скорее всего для него это действительно непосильная задача потому, что он ООП не умеет и в архитекуру тоже. Там без вариантов будут методы по 100500 строк как у любого начинающего.
Хуйню несешь.
>в соответствующих классах-сервисах,
Чувак, сервисы это не классы, куда можно сложить код, чтобы вызывать "сервис" из контроллера
Берёшь и вкатываешься, в чем проблема?
Диды как то вкатывались без интернета, а у тебя полно информации бесплатной вокруг, но ты задаёшь такие вопросы
Скинь, пожалуйста, пример тестовых заданий на джуна. Не могу в инете нарыть, особенно с решениями совсем нет
Хочу порешать для себя
> Я вот пишу свои костыли для студентов
Сочувствую твоим студентам, у меня тоже препод долбаёбом был.
>Думаешь, что я тестирую внутренности отдельно? Хуй тебе, я не долбоеб.
В фонд золотых цицат
>>295128
Абстракции придуманы именно для упрощения разработки. Абстрагируясь от деталей реализации ты ясно увидишь логику приложения на том уровне, на котором смотришь код.
>Когда ты создаешь АБСТРАКЦИИ, то твое приложение становится всегда СЛОЖНЕЕ
АБСТРАКЦИИ и используются там, где пишется СЛОЖНОЕ приложение. Нет смысла городить ООП на скрипте в 100 строк, но такое пишут только школьники, а проф разработка подразумевает работу со сложным и комплексным проектом. Без АБСТРАКЦИЙ ты утонешь просто в сложности.
>Хуйню несешь.
Таки более квалифицированный разраб хорошо видит менее квалифицированного.
А что это? Просвети. Как бы мало просто доебаться до поста - нужно ещё и аргументировать.
Бля, уже сам понял.
>Сочувствую твоим студентам, у меня тоже препод долбаёбом был.
речь про задание ОПа "Студенты"
>АБСТРАКЦИИ и используются там, где пишется СЛОЖНОЕ приложение. Нет смысла городить ООП на скрипте в 100 строк, но такое пишут только школьники, а проф разработка подразумевает работу со сложным и комплексным проектом. Без АБСТРАКЦИЙ ты утонешь просто в сложности.
Анон. Всё, что было придумано создано чтобы управлять сложностью - и архитектура и ооп и к абстракции.
На сложных проектах не будет проблемы в том, что у тебя код будет внутри контроллера.
Сервисы, aka service layer это use cases. Это твоя предметная логика.
По сути это метод(функция) где описан весь основной флоу.
Этот код содержит чисто предметную область независимо от того, откуда это пришло.
Самый простой пример это Бух Учет. Я нем нет формочек, 1С. Есть только счета, дебит, кредит и прочие радости.
В Сервисном слое нет такой штуки, когда один сервис вызывает другой сервис (это самая распространенная ошибка).
Например я видел, когда создают сервисы, чтобы находить разные сущности (типа юзера, товар и так далее) и называли это SomeEntityService и использовали это как зависимость в другом сервисе. В маленьком приложении скорей всего нет потребности выделять этот сервисный слой, все может лежать внутри контроллера. Современные средства разработки позволяют сделать это легко. Типа Laravel.
Можно представить типичный кейс предметной области (бухучет многим непонятен и сложен) - заказ товара.
1. Найти товара
2. Проверить остатки
3. Зарезирвировать единицу товара
4. Вернуть заказ в статусе New.
5. Отправить письмо покупателю с инфой о заказе
6. Отправить информацию в аналитику
Все это может быть внутри контроллера. И еще мы видим, что такая штука (создание) ложится в CRUD контроллер - в создание.
У тебя может быть 1 метод контроллера OrderController с методом Create/Store
Сегодня у нас только интернет-магазин, где покупатель на страничке жмет кнопки. И в простейшем случае этого может быть достаточно. Зачем что-то куда-то выносить? Скорей всего не понадобится даже. И дублирования кода не будет, ведь он в одном месте. Принцип единой ответственности? Мартин вообще писал >A class should have only one reason to change.
Но руководствоваться этим принципом - последнее дело. Есть более важные, которые влияют на качество кода. Когда появится новый способ работы с этим use case, имеет смысл вынести в сервис и назвать его OrderService с методом ->createOrder()
Внутри не будет вызовов других сервисов, будут только зависимости для работы с конкретным кейсом - например репозиторий для работы с бд (но и этого может не быть если ActiveRecord), некий мейлер для отправки писем, логгер.
Тут нужно понимать, что штуки типа кеширования, отправки писем, логгеры - это не часть предметной области. Такие вещи не должны находиться в сервисе ПО-ХОРОШЕМУ и их делают по другому - используют события доменной области, которые обрабатываются.
Сервис создает событие OrderCreated, отправляются нужные письма, отправляются события в аналитику, пишутся логи. Сервисный слой остается чистым. но реальность такова, что нет серебряной пули. И если делать события, то код будет усложняться и усложняться. в теории это должно помогать изменять приложение не давать увеличиваться сложности расти пиздец как, но на деле - хуй знает.
В итоге, когда появляется класс-сервис, то в контроллере будет обычный вызов сервиса. Вероятнее всего в начале этого методак контроллера будет некая валидация входящих данных, первичная обработка, засовывание в условную DTO. А сервис будет с ним работать.
Сервисы, aka service layer это use cases. Это твоя предметная логика.
По сути это метод(функция) где описан весь основной флоу.
Этот код содержит чисто предметную область независимо от того, откуда это пришло.
Самый простой пример это Бух Учет. Я нем нет формочек, 1С. Есть только счета, дебит, кредит и прочие радости.
В Сервисном слое нет такой штуки, когда один сервис вызывает другой сервис (это самая распространенная ошибка).
Например я видел, когда создают сервисы, чтобы находить разные сущности (типа юзера, товар и так далее) и называли это SomeEntityService и использовали это как зависимость в другом сервисе. В маленьком приложении скорей всего нет потребности выделять этот сервисный слой, все может лежать внутри контроллера. Современные средства разработки позволяют сделать это легко. Типа Laravel.
Можно представить типичный кейс предметной области (бухучет многим непонятен и сложен) - заказ товара.
1. Найти товара
2. Проверить остатки
3. Зарезирвировать единицу товара
4. Вернуть заказ в статусе New.
5. Отправить письмо покупателю с инфой о заказе
6. Отправить информацию в аналитику
Все это может быть внутри контроллера. И еще мы видим, что такая штука (создание) ложится в CRUD контроллер - в создание.
У тебя может быть 1 метод контроллера OrderController с методом Create/Store
Сегодня у нас только интернет-магазин, где покупатель на страничке жмет кнопки. И в простейшем случае этого может быть достаточно. Зачем что-то куда-то выносить? Скорей всего не понадобится даже. И дублирования кода не будет, ведь он в одном месте. Принцип единой ответственности? Мартин вообще писал >A class should have only one reason to change.
Но руководствоваться этим принципом - последнее дело. Есть более важные, которые влияют на качество кода. Когда появится новый способ работы с этим use case, имеет смысл вынести в сервис и назвать его OrderService с методом ->createOrder()
Внутри не будет вызовов других сервисов, будут только зависимости для работы с конкретным кейсом - например репозиторий для работы с бд (но и этого может не быть если ActiveRecord), некий мейлер для отправки писем, логгер.
Тут нужно понимать, что штуки типа кеширования, отправки писем, логгеры - это не часть предметной области. Такие вещи не должны находиться в сервисе ПО-ХОРОШЕМУ и их делают по другому - используют события доменной области, которые обрабатываются.
Сервис создает событие OrderCreated, отправляются нужные письма, отправляются события в аналитику, пишутся логи. Сервисный слой остается чистым. но реальность такова, что нет серебряной пули. И если делать события, то код будет усложняться и усложняться. в теории это должно помогать изменять приложение не давать увеличиваться сложности расти пиздец как, но на деле - хуй знает.
В итоге, когда появляется класс-сервис, то в контроллере будет обычный вызов сервиса. Вероятнее всего в начале этого методак контроллера будет некая валидация входящих данных, первичная обработка, засовывание в условную DTO. А сервис будет с ним работать.
>АБСТРАКЦИИ и используются там, где пишется СЛОЖНОЕ приложение. Нет смысла городить ООП на скрипте в 100 строк, но такое пишут только школьники, а проф разработка подразумевает работу со сложным и комплексным проектом. Без АБСТРАКЦИЙ ты утонешь просто в сложности.
И вообще большинство не умеют строить абстракции. Поэтому при написании СЛОЖНОГО ПРИЛОЖЕНИЯ приходится постоянно лазать в кишки и смотреть как оно работает.
Потому что дауны любят писать хуету. К примеру метод, который работает со списком(массивом) может вернуть null
Во времена дедов достаточно было хэллоу ворлд уметь написать чтобы взяли джуном
Поясню - есть метод, который возвращает список сущностей (массив).
И ИНОГДА этот метод возвращает не массив, а нулл.
Почему? Ну потому что по кайфу проверять все значения на нулл.
Причем никакой особой логики нет. Просто проверки на нулл.
По-нормальному было бы всегда возвращать массив и проверять, что он пустой.
проблем с производительностью здесь нет
Если на нашел в шторме, в доках есть вкладка API Documentation, хотя можешь тоже самое в папке вендор найти.
Все нужные методы там в билдере - https://github.com/laravel/framework/blob/9.x/src/Illuminate/Database/Eloquent/Builder.php#L900
Создаю локальное окружение по инструкции
https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-20-04-ru
В одном из шагов по настройке Nginx упоминается файл /var/run/php/php7.4-fpm.sock, но у меня в директории run нету php. Еще смутило, что в инструкции написано установить только пакеты php-fpm php-mysql без самого php. Может поэтому директория пуста?
Устанавливаю на Ubuntu 20.04 в WSL2, то есть на Windows. Помогите разобраться.
php-fpm должен автоматически устанавливать php.
> /var/run/php/php7.4-fpm.sock,
Возможно это потому, что не запущен php-fpm, который и должен создать этот файл. Или он создает файл где-то в другом месте.
Можно проверить, запущен ли php-fpm, командой
sudo sysmtemctl status php-fpm
Ты можешь найти путь к этому файлу в конфигурации php-fpm, которая находится где-то в /etc/php/php-fpm/php-fpm.conf или в /etc/php/php-fpm/pool.d/ или путь может быть не /etc/php, а /etc/php/7.4/php-fpm/...
UPD. Стандартном конфиге Nginx www.conf обнаружил строчку listen = /run/php/php8.1-fpm.sock. Только и в директории /run/ нет php, как и в /var/run/. Почему такое может быть? В дополнение к php-fpm установил php. Он работает нормально.
>php-fpm должен автоматически устанавливать php.
Как отдельный пакет или же интерпретатор встроен в пакет php-fpm?
>озможно это потому, что не запущен php-fpm
Даже не знал, что php-fpm это сервис, что его запускать надо, думал это просто бинарник какой-то.
>sudo sysmtemctl status php-fpm
В WSL2 команда systemctl не работает, потому что не поддерживается systemd. Команда sudo service php-fpm status отвечает unrecognized service.
Спасибо за помощь.
Заработало! Сервис назывался php8.1-fpm. Он создал файл /run/php/php8.1-fpm.sock
Большое спасибо!
UPD. Заработало, да не всё. К сожалению не открывается домен. Стандартная заглушка для nginx из /var/www/html открывается, а новый настроенный домен нет. Делаю по этой инструкции https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-20-04-ru
Все проверил, все вроде бы правильно. Какие могут быть причины?
А траекторию курсов ты сам собираешь?
UPD. Правда что процессы воркеры Nginx должны работать от пользователя nginx, а не как по умолчанию после установки www-data?
Вот важная строка, где записано о проверке условия:
input='/style.css' pattern = '!-f' => matched
То есть, условие в RewriteCond (что файла с именем /style.css не существует) выполняется. Возможно, этот файл находится в какой-то другой папке или назван как-то по-другому.
Скорее всего ошибки в этом месте конфига:
> server_name your_domain www.your_domain;
> root /var/www/your_domain;
>>296838
Некоторые СУБД поддерживают "курсоры" - это такая штука, из которой можно по одной вытягивать строки результата. Бывают курсоры, которые могут двигаться только вперед (к следующей строке), и курсоры, которые могут перемещаться в произвольном направлении.
https://en.wikipedia.org/wiki/Cursor_(databases)
В данном примере каждый вызов PDO::fetch вытягивает текущую строку из курсора, и за счет опции FETCH_ORI_NEXT говорит курсору передвинуться на следующую строку. Когда строки закончатся, fetch вернет false (или null, не помню).
Зачастую СУБД сами не знают, сколько строк вернет запрос. Чтобы это узнать, надо выполнить запрос и сохранить все результаты в память. Это может потребовать много памяти и увеличивает время до отдачи первой строки результата. Поэтому вместо этого СУБД просто генерирует строки результата одну за другой, и пересылают их в клиент (PHP), пока они не закончатся. При такой системе СУБД не надо хранить весь результат в памяти.
В объекте stmt нет счетчика, он просто запрашивает строки из СУБД по одной, пока они не закончатся.
Думаю, что можно и так, и так. Разных пользователей используют для защиты от ошибок (чтобы nginx не мог случайно затереть какие-то файлы) и от уязвимостей (если в nginx окажется уязвимость, чтобы атакующий не мог проникнуть дальше).
К тебе придут интервьюеры твоего пет-проекта и будут спрашивать про бутстрап?
> Как отдельный пакет или же интерпретатор встроен в пакет php-fpm?
У пакетов есть зависимости, то есть установка одного пакета автоматически ставит другой. Ты можешь их увидеть, сделав команду
apt-cache show php-fpm
Она выведет строчку вроде:
Depends: php8.0-fpm
Это значит, что php-fpm требует пакет php8.0-fpm. Если сделать show для него, то там будет список побольше:
Depends: libmagic1, mime-support, php8.0-cli, php8.0-common (= 8.0.3-1+0~20210305.17+debian10~1.gbp899a74), php8.0-opcache, procps, systemd | systemd-tmpfiles, tzdata, ucf, libacl1 (>= 2.2.23), libapparmor1 (>= 2.7.0~beta1+bzr1772), libargon2-1 (>= 0~20171227), libc6 (>= 2.27), libpcre2-8-0 (>= 10.32), libsodium23 (>= 1.0.14), libssl1.1 (>= 1.1.0), libsystemd0, libxml2 (>= 2.8.0), zlib1g (>= 1:1.1.4)
Здесь в списке есть php8.0-cli. Это и есть интерпретатор PHP.
>Скорее всего ошибки в этом месте конфига:
В чем конкретно ошибка?
>>297198
>У пакетов есть зависимости
Это знаю, мог не расписывать. Сидел на линуксе несколько лет. Все равно спасибо.
>>297201
>Наверно, этот сокет создается только при запуске php-fpm.
Совершенно верно. Я этого не знал и в руководстве об этом не сказано. Странные вообще туториалы, часть инфы умолчана.
А что это за билдер? Я за это вообще не шарю
https://www.digitalocean.com/community/tutorials/how-to-set-up-nginx-server-blocks-virtual-hosts-on-ubuntu-16-04
Как это отменяет написанное? Чел шизофазию высрал и явно препод в шараге
Это снова я, тот кто вчера спрашивал про Nginx в WSL. Удалось настроить работу Nginx на новом виртуальном хосте, или по терминологии энджинэкса - серверном блоке. Короче чтобы был отдельный домен, например www.site.local, чтобы можно было держать несколько разных сайтов на разных доменах на локальной машине.
Хотя можно все держать на стандартном localhost добавляя /<название директории>, но мне захотелось разобраться как настраивать новые виртуальные хосты aka серверные блоки.
Много гуглив, наткнулся на один интересный гист. В нем было решение моей проблемы. Нужно было на Win10 добавить в файл Host сопоставление локалхоста с доменом, который прописан в настройках Nginx. Это сработало и теперь веб-сервер отдает html-ки на домене site.local. Но он отказывается работать с php файлами. Выдает 404.
Настраивал по туториалу https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-20-04-ru
Помогите понять в чем причина ошибки. Все вроде бы правильно сделано, php8.1-fpm запущен, сокет есть, а энджинэкс не хочет запускать php файл.
UPD. Почему Nginx может выдавать 404, если php файл находится по адресу? Настройка хоста:
server {
listen 80;
server_name your_domain www.your_domain;
root /var/www/your_domain;
index index.html index.htm index.php;
location / {
try_files $uri $uri/ =404;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php7.4-fpm.sock;
}
location ~ /\.ht {
deny all;
}
}
Не совсем понимаю синтаксис. Какая-то смесь php с чем-то.
UPD. Ошибся, Nginx по прежнему выдает стандартную заглушку, даже на новом хосте site.local. Печаль.
Я не знаю о чем говорю (до деплоя/пердоленья с линуксом еще не дошел в процессе обучения), но ты выше упомянул php8.1-fpm, а в кофиге у тебя 7.4, может дело в несоответствии версий?
Nginx почему то ищет файлы в /usr/share/nginx/html/ и не хочет воспринимать новый конфиг. В логе есть строчка
open() "/usr/share/nginx/html/index.php" failed (2: No such file or directory), client: 127.0.0.1, server: localhost, request: "GET /index.php HTTP/1.1", host: "site.local"
Почему может не принимать конфиг? Синтаксис конфига верный, это подтверждает проверка nginx -t. Символическая ссылка кинута куда надо. Все вроде бы правильно.
>Как называется php файл?
Не имеет значения. Создавал файл index.php, вызывал по корню домена - 404. Создавал файл info.php, вызывал через site.local/info.php - 404.
>>297726
>Я не знаю о чем говорю (до деплоя/пердоленья с линуксом еще не дошел в процессе обучения), но ты выше упомянул php8.1-fpm, а в кофиге у тебя 7.4, может дело в несоответствии версий?
Конфиг скопировал с туториала. Сейчас выложу свой.
server { listen 8080; server_name site.local www.site.local; root /var/www/site.local; index index.html index.htm index.php; location / { try_files $uri $uri/ =404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; } location ~ /\.ht { deny all; } }
server { listen 8080; server_name site.local www.site.local; root /var/www/site.local; index index.html index.htm index.php; location / { try_files $uri $uri/ =404; } location ~ \.php$ { include snippets/fastcgi-php.conf; fastcgi_pass unix:/run/php/php8.1-fpm.sock; } location ~ /\.ht { deny all; } }
Не знаю как нормально отформатировать.
>Не имеет значения
Возможно конфликт апачи и нгинкса и по этому бывает 404, посмотри запущен ли апач.
Да и строчка: index index.html index.htm index.php; Лишняя т.к индексный файл index.php он берёт автоматом
Как правильно работать с PDO и классами/сущностями? PDO::FETCH_CLASS нагло устанавливает значения приватных полей, игнорирует конструктор и сыпет фатальными ошибками если в бд нет запрашиваемого значения. Нагуглил решение на статическом методе в классе и решил на всякий случай тут спросить, нет ли подводных камней и/или более элегантного решения.
>Возможно конфликт апачи и нгинкса и по этому бывает 404, посмотри запущен ли апач.
Апач не установлен. Возможно проблема из за стандартных конфигов. У меня сначала была установлена версия из убунтовых репов, а потом я ее удалил и установил из репов энджинэкса. Проверил, при удалении пакета стандартные конфиги не удаляются.
>Да и строчка: index index.html index.htm index.php; Лишняя т.к индексный файл index.php он берёт автоматом
Он ищет файлы в /usr/share/nginx/html/, искать в директории прописаной в конфиге не хочет.
Что-то я не понял, почему нет ошибки.
> Модификатор private (закрытый) ограничивает область видимости так, что только класс, где объявлен сам элемент, имеет к нему доступ.
А, ясно, это разные свойства, хоть у них и одно имя.
По моим наблюдениям всё эти самописные фреймворки - детская хуита, написанная студентом, считающим себя шибко умным.
Если есть возможность, то уточни у них - чем обусловлено такое? Если ничего толком не ответят, то на проекте наверняка будет говнокод и свои кривые велосипеды на каждом шагу.
>все проекты на самописном фреймоврке
Считай легаси со старта. Плотить хорошо должны, раз ковыряние в легаси, которое нигде не котируется больше.
Если ты крепкий мидл знающий хоть один нормальный mvc фреймворк, то иди. Это быдет для тебя полезным опытом.
А если ждун, то лучше не стоит т.к учится на чужих костылях для велосипедов это занятие довольно таки странное и адекватного опыта хорошего кодинга там вряд-ли найдёшь. Будешь писать костыли на костылях.
>на текущей работе тупею и вообще не развиваюсь
Осмелюсь предположить, что это галеры на CMS'ке где ты изо дня в день пишешь плагины?
>можно двигаться и развиваться
1. Изучать более серьёзные языки и желательно как и пыха Cи подобные.
2. Изучать паттерны
Ну вот и я засомневался, я спросил чем вдохновлялись когда делали на нативном пхп, а я в тот момент общался с хр и она сказала, что ответить не может, но завтра я смогу пообщаться с лидом он сможет ответить.
>>298679
Ну вряд ли там легаси, php8, микросервисы на go, CI/CD, Docker и тд, по зп не сказать что много, но я джун и это еще удаленка.
>>298709
Ну я буквально 2 дня только искать начал, могу еще повыбирать.
>>298927
В этот то и проблема, что джун да и опыта на нативном пхп у меня вообще нет за исключением каких-то задач из книжен, а проекты я сразу на ларавеле писал.
Спасибо всем за ответы, думаю что я им откажу, а то это какой-то кот в мешке и опыт не особо релевантный будет.
>могу еще повыбирать
Перед тобой открылась дверь, а ты не заходишь. Ну и зря. Будешь потом полгода искать и никто не пригласит.
PHP без фреймворков имеет место быть. Может быть они пострили бекенд на событийной архитектуре, использую swoole или что-то похожее, для производительности и реалтайма. Поэтому и фреймворки не используют. Они же все легаси и тормоза. Laravel вроде запилили интерграцию swoole, но не знаю как оно там работает.
> Осмелюсь предположить, что это галеры на CMS'ке где ты изо дня в день пишешь плагины?
Не, микросервисы на симфе с докером. Да, на PHP, хех.
> 1. Изучать более серьёзные языки и желательно как и пыха Cи подобные.
Знание есть, в своё время хотел в джаву вкатываться и зазубрил всё, но потом понял, что на пыхе удалёнка, а так и на джаве приложеньки делал под ведро, и Си, Си++ с питонами всякие ещё с вуза есть и нервы знатно помотало. Сейчас думаю в Postgres, docker и симфу углубиться, но что-то сложно понять куда копать. Есть какие-то PHP гуру на ютубе например по симфе или хорошие проекты код поразбирать?
> 2. Изучать паттерны
Хорошая идея, но это довольно быстро делается, ибо их не так много, а если попытаться зазубрить всё, всё равно забудешь
Зачем тебе nginx? Для локальной разработки достаточно одного PHP
>>Скорее всего ошибки в этом месте конфига:
> В чем конкретно ошибка?
Возможно, неправильно написано имя домена или путь к корню сайта.
>>297713
Синтаксис описан в документации на русском языке: https://nginx.org/ru/docs/
Ты привел пример конфига, но не показал, что у тебя в snippets/fastcgi-php.conf. Возможно, там неправильно указан путь к папке со скриптами PHP.
Вот пример из документации nginx:
> fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
Если у тебя там стоит неправильный путь, то PHP-файлы не будут запускаться.
>>297741
А ты перезапустил nginx после смены конфига?
>>297727
Я вижу, что .htaccess у тебя почему-то не в public. Ты должен сделать папку public корнем веб-сервера (он по моему указывается в директиве DocumentRoot в виртуальном хосте) и положить .htaccess в нее.
Скорее всего, у тебя корень сервера и htaccess находится выше и URL вида /style.css не указывает на файл в public, а на файл в папке одним уровнем выше.
>>Скорее всего ошибки в этом месте конфига:
> В чем конкретно ошибка?
Возможно, неправильно написано имя домена или путь к корню сайта.
>>297713
Синтаксис описан в документации на русском языке: https://nginx.org/ru/docs/
Ты привел пример конфига, но не показал, что у тебя в snippets/fastcgi-php.conf. Возможно, там неправильно указан путь к папке со скриптами PHP.
Вот пример из документации nginx:
> fastcgi_param SCRIPT_FILENAME /home/www/scripts/php$fastcgi_script_name;
Если у тебя там стоит неправильный путь, то PHP-файлы не будут запускаться.
>>297741
А ты перезапустил nginx после смены конфига?
>>297727
Я вижу, что .htaccess у тебя почему-то не в public. Ты должен сделать папку public корнем веб-сервера (он по моему указывается в директиве DocumentRoot в виртуальном хосте) и положить .htaccess в нее.
Скорее всего, у тебя корень сервера и htaccess находится выше и URL вида /style.css не указывает на файл в public, а на файл в папке одним уровнем выше.
> PDO::FETCH_CLASS нагло устанавливает значения приватных полей, игнорирует конструктор
Да, это ошибка проектирования в PDO. Неправильно создавать объект в обход конструктора. Там есть малоизвестная опция PDO::FETCH_PROPS_LATE которая заполняет свойства после вызова конструктора. Она указывается как
$stmt->fetchAll(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, ...)
> и сыпет фатальными ошибками если в бд нет запрашиваемого значения
Вот этот момент не понял. Если в БД нет запрашиваемых данных, то он не будет создавать оьъекты.
> Нагуглил решение на статическом методе в классе
Минус этого решения в том, что оно нарушает принцип единой ответственности. Если у тебя есть класс для работы с таблицей студентов, то только он должен с ней работать. А ты вынес часть этого кода в класс Student. Функцию создания студента из данных PDO надо перенести в класс работы с БД.
В общем-то стандартное решение - сделать в классе работы с БД функцию, которая создает нужные объекты из данных из БД. Примерно то же, что сделал ты.
На большом проекте писать такие однообразные функции быстро надоест, потому используют ORM вроде Доктрины, который заполняет объекты автоматически. Также, он дает другие плюсы:
- поддержка отношений между объектами
- ленивая загрузка отношений
- реализация identity map
- автоматическое обнаружение изменений в объектах и сброс их в БД
Да, видимо поле $age видно только в Person, и потому в Student строчка $this->age = ... создает новое поле.
Ты можешь запретить создание несуществующих полей, сделав магический метод __set() и выбросив в нем исключение. Это можно сделать в виде трейта и легко подключать в любой класс.
>А ты перезапустил nginx после смены конфига?
Да. Дело в том, что он вообще не обращает внимание на конфиги для кастомных хостов. Ищет файлы только в /usr/share/nginx/html/ и хоть убей, не могу это изменить.
Возможно, он просто не читает твой конфиг. Если ты, например, добавил конфиг в .../sites-available/, но не добавил ссылку в /sites-enabled/ то он твой конфиг и не увидит.
Мне кажется, тебе бы стоило основной конфиг (/etc/nginx/nginx.conf), посмотреть, что он подключает и как и доходит ли дело до твоего конфига.
Минимально тебе нужен сам ПХП и какая-то база данных. Это всё на винду ставится запросто, но лучше сразу сборочку взять - xampp или openserver.
>Если ты, например, добавил конфиг в .../sites-available/, но не добавил ссылку в /sites-enabled/ то он твой конфиг и не увидит.
Добавил.
>/etc/nginx/nginx.conf
Заметил, что если ставить разные версии, этот конфиг почему то везде разный. Иной раз отличается в размере в 2 раза. Что в конфиге может быть не так мне непонятно.
Если хочешь использовать среду линукс, то в винде уже встроено ядро. Можно установить окружение Ubuntu через WSL2.
Кабаны на галере на заставят устанавливать всякую линуксопарашу?
давать вставлять только ссылку в форму, самому выводить встроенное видео с ссылкой.
Очевидно же.
Патамушта тебе надо будет рендерить шаблончики на PHP и добавлять в них динамики с помощью JS.
Это называется фулстек - швец, и жнец, и в дуду игрец.
Спасибо
>>301393
Кабанчики узнали что есть фронт и бэк, и ествесвенно пришла гениальная идея "ээээ бля епта а зачем это мне нанимать отдельно на ентот вронт и пэк спецов да ещё и платить сразу двум? Пускай один и то и другое делает, голова не лопнет глядишь гыгыгы".
Ну тебе должно быть пох что там хочет кабанчик и его отсасывающий аппарат хрюша, тебе код писать а не им.
Да обычное дело - хотят одного человека вместо двух на проект. Платить, разумеется, тоже будут хотеть поменьше обычно. Тебе в общем то правильно сказали - хотеть они могут чего угодно, но к таким лучше не ходить. В этой сфере упоротых неадекватов очень много, и не только со стороны тех кто работает, но и среди работодателей.
У тебя странное отношение. Наверное к тебе работодатели ломятся в очереди, что ты нос воротишь и считаешь где зашквар, а где нет.
Хотя скорее всего ты ни на какой CMS себе работу не найдёт с такими-то дебильными критериями выбора.
Ты че на проецировал себе, я просто хотел развести небольшой холивар, на тему того какие CMS уважаются, в пример привел друпал, а вот битрикс разрабу и руку пожать брезгливо.
Вас таких холиварщиков тут каждую неделю наносит как говна. Какой смысл доказывать что-то хер пойми кому? И уж тем более в контексте зашквар-не зашквар. Решает рыночек, а не холивары.
>Решает рыночек
То есть твоя позиция, что если это популярно и за это платят, то это хорошая технология?
Позиция анона про рыночек верная, а ты ее трактуешь как тебе вздумается. Технология, может, и говно. Но она востребована, а значит туда будут идти программисты.
В конце концов, если тебя так тянет блевать от Битрикса - ну иди напиши свою отечественную CMS, чтобы она переплюнула этот проект.
Или иди пиши красиво, со всеми "правильными" MVC, DI и прочей херней. Битрикс, вроде, не запрещает так делать.
>Технология, может, и говно
Хорошо с битриксом порешали, но на вопрос никто так и не ответил какие CMS не говно? про рыночек не отвечайте это к вопросу отношения не имеет
У тебя не вопрос, а байт на холивар. Да и ответили уже на него тебе.
Серебряной пули не существует и они всё говно в кривых руках.
https://young-caverns-30768.herokuapp.com/
Доделал ебучих студентов. Гештальт закрыт.
Задача конечно интересная, но дальше пердолиться уже не хотелось.
Если тебе уже код, то ссылку на исходники я скинул(только локально не будет работать тк я в последний момент поменял миграцию под постгрес)
Лучше задавай конкретные вопросы, потому что моё решение далеко от идеала и оно просто рабочее
> Заметил, что если ставить разные версии, этот конфиг почему то везде разный. Иной раз отличается в размере в 2 раза. Что в конфиге может быть не так мне непонятно.
Чтобы понять, что не так, надо изучить конфиг и посмотреть, какие еще конфиги он подключает.
Если ты меняешь настройки в конфиге, а результата нет, то это может значить, что например этот файл просто не используется.
Также, надо проверить, что в файле snippets/fastcgi-php.conf, который ты подключаешь из своего конфига. Может, там какие-то неправильные настройки.
Ты также можешь попробовать включить режим более подробного логгирования, подправив директиву error_log ( https://nginx.org/ru/docs/ngx_core_module.html#error_log ):
error_log /var/log/something.log debug;
Это надо у них спрашивать. В крайнем случае ты всегда можешь установить линкус в виртуальной машине.
>>301978
Глупый вопрос. Лучше было бы спросить "какие CMS обеспечивают высокую производительность разработки и позволяют мне решать задачи бизнеса быстрее?".
Я, правда, не знаю ответа на этот вопрос. Наверно, надо просто попробовать несколько CMS и сравнить. Кстати, ты бы мог поделиться результатами здесь и облегчить другим выбор.
CMS заточены на создание сайта через кликанье мышкой в админке, а как только нужно что-то сверх этого, приходится верстать темы оформления и писать плагины.
В бизнесе обычно все меряют с точки зрения затрат/прибыли. Если один человек может делать и фронтенд, и бекенд, и это окупается, то выгоднее ему это и поручить. А на больших проектах разделение на фронтенд/бекенд получается выгоднее.
Ты либо подстраиваешься под реалии бизнеса, либо создаешь свой бизнес по своим правилам.
Поле authors в composer.json можно не заполнять. Это было бы лучше, чем вбивать туда заведомо неправильные значения. Там вообще почти все поля необязательные.
Хорошо, что ты подключил средства статического анализа кода. Это помогает выявлять проблемы. И хорошо, что есть тесты, хотя они конечно тут в минимальном объеме.
Хотя, почему-то у тебя в phpstan.neon включена только папка public, но не src.
Для ускорения тестов можно создавать базу sqlite в памяти, используя DSN sqlite::memory: ( https://www.php.net/manual/en/ref.pdo-sqlite.connection.php ). Но если у тебя на продакшене Postgres, то тесты логично делать на той же БД, иначе ты можешь не отловить в тестах какую-то ошибку, которая возникает только с Postgres.
> $valuesParts = array_reduce(range(1, 30), function ($acc, $i) use ($birthday, $passwordHasher)
Я не уверен, что это хорошее применение array_reduce. Простой цикл foreach тут читался бы лучше, а так приходится постоянно бегать взгядом вперед-назад, чтобы понять, что делает эта функция. Но, должен признаться, мне вообще не нравится функция reduce и код с ней кажется неудобным для понимания.
> first_name VARCHAR NOT NULL
Желательно указывать макс. длину поля.
> gender VARCHAR NOT NULL
Тут бы подошло поле вроде ENUM, или ограничение CHECK, не позволяющее вставить неправильные данные.
> function sanitize($value): string
Ой-ой-ой, это функция из худших учебников. Просто применяет кучу разных фильтров без всякой логики, в надежде что уж так-то точно строка станет "безопасной". Не надо такие функции использовать вообще, а надо использовать фильтрацию или экранирование, подходящие к конкретному случаю.
У тебя getConfig() возвращает настройки для всех окружений, но удобнее было бы, если бы она получала на вход или определяла окружение и возвращала только настройки для этого окружения. Чтобы дальше уже не надо было из них выбирать нужные.
Ты создаешь все нужные для работы приложения объекты внутри Kernel. Но что, если они понадобятся где-то еще, например, в скрипте командной строки понадобится объект StudentsTableGateway? Тебе придется дублировать код его создания. Чтобы этого избежать, используют DI Container. Ты бы, конечно, мог сделать, чтобы Kernel создавал и возвращал эти объекты, но тогда Kernel и будет выполнять роль контейнера.
В твоей схеме роутинга URL анализируется в Kernel, а HTTP-метод анализируется уже в "хендлере" (который по сути выполняет роль контроллера). Было бы, наверно, логичнее собрать весь роутинг в одном месте?
При неправильном заполнении формы логина она почему-то очищается. Для работы с формами удобнее использовать описанный тут алгоритм, когда обработчик GET и POST находятся в одной функции: https://github.com/codedokode/pasta/blob/master/forms.md
> $statement->bindParam(':limit_param', $limitParam, PDO::PARAM_INT);
bindParam обычно используют для двухсторонней привязки (когда БД может обновлять значение в переменной). В твоем случае лучше подойдет bindValue().
Еще, у тебя нет обработчика ошибок. Это значит, что при фатальной ошибке пользователь увидит просто белую страницу с кодом 200 вместо старницы ошибки. А warning или notice не приведет к завершению скрипта, что тоже плохо (программа может выдать ошибочные данные вместо того, чтобы остановиться).
> function view(string $viewName, array $params = []): string
> ob_start();
> include $viewFullPath;
> return ob_get_clean();
Здесь нет обработки исключений, и при исключении буферизация вывода останется включенной. Правильно было бы обернуть include в try/catch и внутри catch отключать буферизацию.
Нету, к сожалению, ни поиска, ни сортировки списка.
Ты используешь много глобальных переменных (или классов со статическими полями, которые по сути выполняют роль глобальных переменных): $_REQUEST, $_POST, Auth, Session, и это делает твои тесты менее надежными и хуже изолированными. Например, ты в одном тесте проверяешь Auth::isSigned(), но где гарантия, что это состояние было установлено в тесте, а не осталось от предыдущего теста?
Аналогично с $_REQUEST: ты можешь в одном тесте что-то записать туда, что повлияет на другой тест.
По этой причине фреймворки обычно оборачивают параметры запроса и сессию в объекты (вроде Request/Session), и создают сервисы заново на каждый тест, а не используют статические классы.
В RegisterHandler и EditHandler есть общий код, а также в EditForm/RegisterForm. И в шаблонах edit.html.twig, register.html.twig. Логично было бы вынести его в отдельный класс, например "ProfileForm" или вообще объединить вместе регистрацию и редактирования профиля (хотя, конечно, на практике эти процессы могут различаться).
Валидация у тебя не собрана в одном классе, а размазана между EditForm и EditHandler (проверка занятости e-mail это тоже по сути валидация). Это плохо.
> private function isEmailBusy(Student $currentStudent, string $email): bool
> return $currentStudent->id === $otherStudent->id;
Тут, по моему, должно быть !==.
> private function getCurrentUser(): Student
> return $this->studentsTableGateway->getById(Auth::id());
Тут не проверяется ситуация, когда Auth::id() вернет id несуществующего пользователя. Можно было бы вообще всю функцию получения текущего пользователя перенести в Auth.
> $form->validate();
> if (!$form->isValid()) {
Это не очень удачный подход. Так как второе действие (isValid) требует сначала выполнить первое действие (validate), и это не очевидно. Более того, если мы поменяем что-то в форме и снова вызовем isValid(), то она вернет устаревшие, неактуальные данные. Правильнее возвращать результат через return, а не записывать его в скрытое состояние объекта, и сделать stateless-функцию:
$errors = $form->validate();
if ($errors) {
Такую функцию не получится использовать неправильно.
> http_response_code(422);
> return view('edit', [
Тут тоже не очень логично: код ты выставляешь сразу, а HTML-код только возвращаешь, и неизвестно что с ним будет дальше. Логичнее было бы писать return view(422, 'edit', [...]).
> class Hasher
> public static function build(): static
Непонятно, зачем нужен этот метод, когда есть конструктор.
> public static function login(Student|int|null $student): void
По моему, нелогично передавать в login() null. Это явно говорит об ошибке в программе.
> if (self::isGuest()) {
> http_response_code(401);
Это не очень хорошая идея, отдавать код 401, так как в ответ на него браузер показывает окошко ввода логина и пароля. Обычно при отсутствии авторизации перенаправляют на форму входа с выводом сообщения "для ... необходимо войти на сайт или зарегистрироваться".
> class Session
Это класс правильнее назвать SessionStarter, так как он не предоставляет методов работы с сессией, а лишь позволяет ее создать.
Логику логина (проверка email, пароля) логичнее было бы разместить не в контроллере LoginHandler, а в сервисе.
> $student = $this->studentsTableGateway->create($student->toArray());
Логичнее было бы сделать create($student), то есть передавать объект, а не массив. Так как в случае с массивом, трудно понять, какие там должны быть поля, какие у них типы итд, а в объекте это все описано.
В редактировании нет защиты от XSRF ( https://github.com/codedokode/pasta/blob/master/security/xsrf.md )
> public static function href
> return "href=\"{$url}{$queryString}\"";
Здесь нет экранирования специальных символов HTML вроде &.
> <a href="/logout" class="nav-link link-dark px-2" onclick="event.preventDefault();
Если у тебя кнопка выхода, то логичнее делать ее тегом button с type="submit", тем более что в Bootstrap есть класс btn-link, который делает ее похожей на ссылку. Хотя опять же, если это кнопка, то логичнее сделать ее отличающейся от ссылок.
Кстати, форма логаута тоже не защищена от XSRF.
> App\Functions\array_get($flash, 'success'
Флеш-уведомления через сессию имеют недостатки. Например: если у тебя открыто несколько вкладок и ты между ними переключаешься, то уведомление от одной вкладки может вывестись в другой.
> strtoupper($student->groupId)
Можно было бы сделать в классе Student метод, который возвращает нормализованное представление группы. И, кстати, надо использовать mb_strtoupper, так как strtoupper работает только с ASCII (не с кирилицей).
> HtmlHelper::href
Я думаю, это неудачная идея, что хелпер возвращает кусок HTML-тега. Лучше бы он возвращал просто ссылку, а href="" было бы прописано в HTML-коде. А так, у тебя HTML-код одного тега размазан по нескольким местам без необходимости. То же касается хелпера class().
Структура дерева контроллеров не соответствует структуре папок шаблонов. По моему, это неудачная идея и логичнее было бы использовать одинаковую структуру.
Поле authors в composer.json можно не заполнять. Это было бы лучше, чем вбивать туда заведомо неправильные значения. Там вообще почти все поля необязательные.
Хорошо, что ты подключил средства статического анализа кода. Это помогает выявлять проблемы. И хорошо, что есть тесты, хотя они конечно тут в минимальном объеме.
Хотя, почему-то у тебя в phpstan.neon включена только папка public, но не src.
Для ускорения тестов можно создавать базу sqlite в памяти, используя DSN sqlite::memory: ( https://www.php.net/manual/en/ref.pdo-sqlite.connection.php ). Но если у тебя на продакшене Postgres, то тесты логично делать на той же БД, иначе ты можешь не отловить в тестах какую-то ошибку, которая возникает только с Postgres.
> $valuesParts = array_reduce(range(1, 30), function ($acc, $i) use ($birthday, $passwordHasher)
Я не уверен, что это хорошее применение array_reduce. Простой цикл foreach тут читался бы лучше, а так приходится постоянно бегать взгядом вперед-назад, чтобы понять, что делает эта функция. Но, должен признаться, мне вообще не нравится функция reduce и код с ней кажется неудобным для понимания.
> first_name VARCHAR NOT NULL
Желательно указывать макс. длину поля.
> gender VARCHAR NOT NULL
Тут бы подошло поле вроде ENUM, или ограничение CHECK, не позволяющее вставить неправильные данные.
> function sanitize($value): string
Ой-ой-ой, это функция из худших учебников. Просто применяет кучу разных фильтров без всякой логики, в надежде что уж так-то точно строка станет "безопасной". Не надо такие функции использовать вообще, а надо использовать фильтрацию или экранирование, подходящие к конкретному случаю.
У тебя getConfig() возвращает настройки для всех окружений, но удобнее было бы, если бы она получала на вход или определяла окружение и возвращала только настройки для этого окружения. Чтобы дальше уже не надо было из них выбирать нужные.
Ты создаешь все нужные для работы приложения объекты внутри Kernel. Но что, если они понадобятся где-то еще, например, в скрипте командной строки понадобится объект StudentsTableGateway? Тебе придется дублировать код его создания. Чтобы этого избежать, используют DI Container. Ты бы, конечно, мог сделать, чтобы Kernel создавал и возвращал эти объекты, но тогда Kernel и будет выполнять роль контейнера.
В твоей схеме роутинга URL анализируется в Kernel, а HTTP-метод анализируется уже в "хендлере" (который по сути выполняет роль контроллера). Было бы, наверно, логичнее собрать весь роутинг в одном месте?
При неправильном заполнении формы логина она почему-то очищается. Для работы с формами удобнее использовать описанный тут алгоритм, когда обработчик GET и POST находятся в одной функции: https://github.com/codedokode/pasta/blob/master/forms.md
> $statement->bindParam(':limit_param', $limitParam, PDO::PARAM_INT);
bindParam обычно используют для двухсторонней привязки (когда БД может обновлять значение в переменной). В твоем случае лучше подойдет bindValue().
Еще, у тебя нет обработчика ошибок. Это значит, что при фатальной ошибке пользователь увидит просто белую страницу с кодом 200 вместо старницы ошибки. А warning или notice не приведет к завершению скрипта, что тоже плохо (программа может выдать ошибочные данные вместо того, чтобы остановиться).
> function view(string $viewName, array $params = []): string
> ob_start();
> include $viewFullPath;
> return ob_get_clean();
Здесь нет обработки исключений, и при исключении буферизация вывода останется включенной. Правильно было бы обернуть include в try/catch и внутри catch отключать буферизацию.
Нету, к сожалению, ни поиска, ни сортировки списка.
Ты используешь много глобальных переменных (или классов со статическими полями, которые по сути выполняют роль глобальных переменных): $_REQUEST, $_POST, Auth, Session, и это делает твои тесты менее надежными и хуже изолированными. Например, ты в одном тесте проверяешь Auth::isSigned(), но где гарантия, что это состояние было установлено в тесте, а не осталось от предыдущего теста?
Аналогично с $_REQUEST: ты можешь в одном тесте что-то записать туда, что повлияет на другой тест.
По этой причине фреймворки обычно оборачивают параметры запроса и сессию в объекты (вроде Request/Session), и создают сервисы заново на каждый тест, а не используют статические классы.
В RegisterHandler и EditHandler есть общий код, а также в EditForm/RegisterForm. И в шаблонах edit.html.twig, register.html.twig. Логично было бы вынести его в отдельный класс, например "ProfileForm" или вообще объединить вместе регистрацию и редактирования профиля (хотя, конечно, на практике эти процессы могут различаться).
Валидация у тебя не собрана в одном классе, а размазана между EditForm и EditHandler (проверка занятости e-mail это тоже по сути валидация). Это плохо.
> private function isEmailBusy(Student $currentStudent, string $email): bool
> return $currentStudent->id === $otherStudent->id;
Тут, по моему, должно быть !==.
> private function getCurrentUser(): Student
> return $this->studentsTableGateway->getById(Auth::id());
Тут не проверяется ситуация, когда Auth::id() вернет id несуществующего пользователя. Можно было бы вообще всю функцию получения текущего пользователя перенести в Auth.
> $form->validate();
> if (!$form->isValid()) {
Это не очень удачный подход. Так как второе действие (isValid) требует сначала выполнить первое действие (validate), и это не очевидно. Более того, если мы поменяем что-то в форме и снова вызовем isValid(), то она вернет устаревшие, неактуальные данные. Правильнее возвращать результат через return, а не записывать его в скрытое состояние объекта, и сделать stateless-функцию:
$errors = $form->validate();
if ($errors) {
Такую функцию не получится использовать неправильно.
> http_response_code(422);
> return view('edit', [
Тут тоже не очень логично: код ты выставляешь сразу, а HTML-код только возвращаешь, и неизвестно что с ним будет дальше. Логичнее было бы писать return view(422, 'edit', [...]).
> class Hasher
> public static function build(): static
Непонятно, зачем нужен этот метод, когда есть конструктор.
> public static function login(Student|int|null $student): void
По моему, нелогично передавать в login() null. Это явно говорит об ошибке в программе.
> if (self::isGuest()) {
> http_response_code(401);
Это не очень хорошая идея, отдавать код 401, так как в ответ на него браузер показывает окошко ввода логина и пароля. Обычно при отсутствии авторизации перенаправляют на форму входа с выводом сообщения "для ... необходимо войти на сайт или зарегистрироваться".
> class Session
Это класс правильнее назвать SessionStarter, так как он не предоставляет методов работы с сессией, а лишь позволяет ее создать.
Логику логина (проверка email, пароля) логичнее было бы разместить не в контроллере LoginHandler, а в сервисе.
> $student = $this->studentsTableGateway->create($student->toArray());
Логичнее было бы сделать create($student), то есть передавать объект, а не массив. Так как в случае с массивом, трудно понять, какие там должны быть поля, какие у них типы итд, а в объекте это все описано.
В редактировании нет защиты от XSRF ( https://github.com/codedokode/pasta/blob/master/security/xsrf.md )
> public static function href
> return "href=\"{$url}{$queryString}\"";
Здесь нет экранирования специальных символов HTML вроде &.
> <a href="/logout" class="nav-link link-dark px-2" onclick="event.preventDefault();
Если у тебя кнопка выхода, то логичнее делать ее тегом button с type="submit", тем более что в Bootstrap есть класс btn-link, который делает ее похожей на ссылку. Хотя опять же, если это кнопка, то логичнее сделать ее отличающейся от ссылок.
Кстати, форма логаута тоже не защищена от XSRF.
> App\Functions\array_get($flash, 'success'
Флеш-уведомления через сессию имеют недостатки. Например: если у тебя открыто несколько вкладок и ты между ними переключаешься, то уведомление от одной вкладки может вывестись в другой.
> strtoupper($student->groupId)
Можно было бы сделать в классе Student метод, который возвращает нормализованное представление группы. И, кстати, надо использовать mb_strtoupper, так как strtoupper работает только с ASCII (не с кирилицей).
> HtmlHelper::href
Я думаю, это неудачная идея, что хелпер возвращает кусок HTML-тега. Лучше бы он возвращал просто ссылку, а href="" было бы прописано в HTML-коде. А так, у тебя HTML-код одного тега размазан по нескольким местам без необходимости. То же касается хелпера class().
Структура дерева контроллеров не соответствует структуре папок шаблонов. По моему, это неудачная идея и логичнее было бы использовать одинаковую структуру.
Спасибо. Попробую разобраться.
Спасибо, анончик-опчик за потраченное время и ревью.
Постараюсь ответить, почему шо да как
>Поле authors в composer.json можно не заполнять.
Да, возможно. Изначально все было заполнено ок, просто решил скрыть свои данные. Ну и сам проект был сгенерирован с этим блоком.
> Хотя, почему-то у тебя в phpstan.neon включена только папка public, но не src.
Я просто забыл про него, когда продолжил разрабатывать проект (изначально в public/index.php накидывал код). Если заметишь - он не запускается в ci
>Для ускорения тестов можно создавать базу sqlite в памяти
Да, изначально так делал, потом переделал на файл, чтобы был общий конфиг для миграций\сидов и тд, чтобы на деве и тестах работало.
Но щас локально и тесты не работают, потому что когда в последний момент я деплоил на хероку, то поменял миграции (там постгрес, а локально sqlite, у них разные способы инкремента). В итоге на проде работает, на деве нет.
> Я не уверен, что это хорошее применение array_reduce.
Да, цикл здесь был бы проще.
> Желательно указывать макс. длину поля.
Возможно. Но Стандарт SQL не запрещает создавать размер). оправдываюсь тем, что sql постоянно гуглю
> Ой-ой-ой, это функция из худших учебников.
Охх, это я вообще в последний момент добавил, чтобы всяческую гадость удалять.
>У тебя getConfig() возвращает настройки для всех окружений
Да, это хорошая идея
> Ты создаешь все нужные для работы приложения объекты внутри Kernel.
Да, У меня так и получилось дублирование. Только в скрипте (функции) я там создавал свой PDO.
> В твоей схеме роутинга URL анализируется в Kernel
Ну тут роутинг для нищих. Просто роут мапится на хендлер и там дальше своя работа ведется. По-хорошему конечно не надо так делать и можно даже роуты динамически задавать.
> При неправильном заполнении формы логина она почему-то очищается.
Тут вопрос не ко мне, а к браузеру. Если посмотришь, то увидишь, что во вьюхах (кроме логина) вставляются введенные данные + выводится сообщение об ошибках. Для логина только флешка выводится.
> bindParam обычно используют для двухсторонней привязки (когда БД может обновлять значение в переменной). В твоем случае лучше подойдет bindValue().
Спасибо, нужно будет почитать. С PDO напрямую не работаю от слова вообще.
>Еще, у тебя нет обработчика ошибок.
Да, я его уже поленился сделать (задеплоил и решил забить). Там даже есть Todo на обработку.
> Здесь нет обработки исключений,
Согласен. Насчет буферизации вывода и тд я профан.
> Нету, к сожалению, ни поиска, ни сортировки списка.
Это да, но я про это потом совершенно забыл.
> Ты используешь много глобальных переменных (или классов со статическими полями, которые по сути выполняют роль глобальных переменных): $_REQUEST, $_POST, Auth, Session, и это делает твои тесты менее надежными и хуже изолированными. Например, ты в одном тесте проверяешь Auth::isSigned(), но где гарантия, что это состояние было установлено в тесте, а не осталось от предыдущего теста?
Да, так и есть. И насчет объекта Реквест\Респонса тоже думал, что так правильней. Ибо тогда не придется реально приложение запускать, достаточно передавать нужные данные и смотреть на выходе объект (как у Slim). Тесты изолированны (настройка в phpunit.xml). Поэтому они не будут друг другу мешать (но не будут работать, как я выше писал, из-за миграции в бд)
По-хорошему нужно еще вызывать setUp() или tearDown и чистить сессиии.
>В RegisterHandler и EditHandler есть общий код
Только не html.twig а phtml.php (без шаблонизатора).
Да, здесь разные процессы - редактирования и регистрация. Но на деле, они не отличаются, а оба класса - это копипаста друг друга (я даже поленился константы унести из форм, сделать подобие енама). В принципе можно было бы одну форму использовать.
> Валидация у тебя не собрана в одном классе, а размазана между EditForm и EditHandler (проверка занятости e-mail это тоже по сути валидация). Это плохо.
Тут нужно подробно пояснить почему так сделано - валидация может быть на разных слоях приложения. И на уровне представления\контроллера, т.е. места, где ты получаешь данные, так и в модели. В условной форме может быть валидация с чисткой данных, удаление всякого лишнего. на уровне модели (предметной области) валидация именно бизнес-логики. Например проверка что емейл не занят другим пользователем. По хорошему это хорошее место для сервис-слоя (а выше в треде я писал, шо сервис чаще всего не нужен и можно все хуярить в контроллер).
Может показаться, что проверку почты можно положить в форму, но это не так. Это не логика формы, это логика бизнеса. Тут нужно было вынести константы в Студента. Плюс хорошо было бы валидировать самого студента при создании (выше ты писал про констрейны, енам и тд, мне не нравится идея делать такую валидацию в бд, тк она тяжело масштабируется и часто ломает zerodowntime deploy, хотя наше приложение этим и не страдает, короче тут достаточно всей логики и валидации на уровне приложения) и в форме.
> Тут, по моему, должно быть !==
Верно, и тест на это я не написал.
> Тут не проверяется ситуация
Согласен. Но пришлось бы тогда инициализировать Auth с зависимостью, а у меня нет контейнера с зависимостями.
> Это не очень удачный подход.
Возможно.
Тут может быть на самом деле несколько подходов. Например через Validate вызывать эксепшен (кажется в какиз-то валидаторах такое есть).
Мне показалось хорошей идеей явно показать флоу
валидацию, проверка валидности формы, получение ошибок.
Сам валидатор по-хорошему стоило бы доработать.
>Тут тоже не очень логично
Тут по-хорошему нужен объект с ответом, чтобы в него передавать статус и контент.
> Непонятно, зачем нужен этот метод, когда есть конструктор.
По сути незачем, да.
> По моему, нелогично передавать в login() null. Это явно говорит об ошибке в программе.
Согласен, даже в коде нигде null не передается.
>Это не очень хорошая идея, отдавать код 401, так как в ответ на него браузер показывает окошко ввода логина и пароля.
Нет, с этим проблем не будет. Я проверял и у меня браузер просто показывал свою страницу c нужным контентом, если что-то передавал. (но тк я ничего не передавал, то ничего и не выводил кроме стандарной пустой страницы). Для вывода флеша и редиректа, нужно было бы способ работы флеш сообщений поменять (я сделал просто передачу переменной)
> Это класс правильнее назвать SessionStarter, так как он не предоставляет методов работы с сессией, а лишь позволяет ее создать.
Да, но там была идея добавить вообще добавление данных (для флеш)
> Логику логина (проверка email, пароля)
Кода не так много, чтобы делать сервис + сам код есть только в одном месте по сути.
> Логичнее было бы сделать create($student),
Да, там даже есть косяк с удалением ключа id
>Здесь нет экранирования специальных символов HTML вроде &.
Возможно, но
Это не требуется, так как пользовательские данные не передаются.
> В редактировании нет защиты от XSRF
Да.
> Если у тебя кнопка выхода, то логичнее делать ее тегом button
Да, тут уже сделал, как у других (не тех, кто делал студентов, а вообще как делают).
> Флеш-уведомления через сессию имеют недостатки.
Здесь они через переменную во вьюхе
>Можно было бы сделать в классе Student метод
Ну да, но у меня нет геттеров-сеттеров, Student не содержит логику, даже для представления. По хорошему нужно было бы делать класс-презентер
> Я думаю, это неудачная идея
ИЗначально так и делал. Вообще тут можно было бы пойти дальше и написать класс для формирования тегов. Тогда код выглядел бы чище.
> Структура дерева контроллеров не соответствует структуре папок шаблонов. По моему, это неудачная идея и логичнее было бы использовать одинаковую структуру.
Да, это хорошая идея.
Подытожу - делал проект, чтобы сделать, потому что в свое время его пропустил, уже давно работаю. Сильно большой мотивации делать замороченно у меня не было. Я когда-то, когда только начинал, делал подобный проект без фреймворков (правда тогда тесты на писал) и еще тогда задохнулся от того, чтобы всё делать руками Ну вот вообще нет интереса делать велосипед, тем более когда приходится в жизни писать на разных технологиях. Слишком меня это душило
Поэтому я довел просто до какого-то рабочего состояния. Если появится интерес, дорабатывать - попробую доработать. Нет, так нет, можно файловым хостингом на слиме заняться.
Свою реализацию оцениваю на 3\5, хоть у меня и есть тесты-линтеры-демо.
Я непременно вернусь в тред, чтобы в очередной раз не согласиться с ОПом или другим аноном.
Спасибо, анончик-опчик за потраченное время и ревью.
Постараюсь ответить, почему шо да как
>Поле authors в composer.json можно не заполнять.
Да, возможно. Изначально все было заполнено ок, просто решил скрыть свои данные. Ну и сам проект был сгенерирован с этим блоком.
> Хотя, почему-то у тебя в phpstan.neon включена только папка public, но не src.
Я просто забыл про него, когда продолжил разрабатывать проект (изначально в public/index.php накидывал код). Если заметишь - он не запускается в ci
>Для ускорения тестов можно создавать базу sqlite в памяти
Да, изначально так делал, потом переделал на файл, чтобы был общий конфиг для миграций\сидов и тд, чтобы на деве и тестах работало.
Но щас локально и тесты не работают, потому что когда в последний момент я деплоил на хероку, то поменял миграции (там постгрес, а локально sqlite, у них разные способы инкремента). В итоге на проде работает, на деве нет.
> Я не уверен, что это хорошее применение array_reduce.
Да, цикл здесь был бы проще.
> Желательно указывать макс. длину поля.
Возможно. Но Стандарт SQL не запрещает создавать размер). оправдываюсь тем, что sql постоянно гуглю
> Ой-ой-ой, это функция из худших учебников.
Охх, это я вообще в последний момент добавил, чтобы всяческую гадость удалять.
>У тебя getConfig() возвращает настройки для всех окружений
Да, это хорошая идея
> Ты создаешь все нужные для работы приложения объекты внутри Kernel.
Да, У меня так и получилось дублирование. Только в скрипте (функции) я там создавал свой PDO.
> В твоей схеме роутинга URL анализируется в Kernel
Ну тут роутинг для нищих. Просто роут мапится на хендлер и там дальше своя работа ведется. По-хорошему конечно не надо так делать и можно даже роуты динамически задавать.
> При неправильном заполнении формы логина она почему-то очищается.
Тут вопрос не ко мне, а к браузеру. Если посмотришь, то увидишь, что во вьюхах (кроме логина) вставляются введенные данные + выводится сообщение об ошибках. Для логина только флешка выводится.
> bindParam обычно используют для двухсторонней привязки (когда БД может обновлять значение в переменной). В твоем случае лучше подойдет bindValue().
Спасибо, нужно будет почитать. С PDO напрямую не работаю от слова вообще.
>Еще, у тебя нет обработчика ошибок.
Да, я его уже поленился сделать (задеплоил и решил забить). Там даже есть Todo на обработку.
> Здесь нет обработки исключений,
Согласен. Насчет буферизации вывода и тд я профан.
> Нету, к сожалению, ни поиска, ни сортировки списка.
Это да, но я про это потом совершенно забыл.
> Ты используешь много глобальных переменных (или классов со статическими полями, которые по сути выполняют роль глобальных переменных): $_REQUEST, $_POST, Auth, Session, и это делает твои тесты менее надежными и хуже изолированными. Например, ты в одном тесте проверяешь Auth::isSigned(), но где гарантия, что это состояние было установлено в тесте, а не осталось от предыдущего теста?
Да, так и есть. И насчет объекта Реквест\Респонса тоже думал, что так правильней. Ибо тогда не придется реально приложение запускать, достаточно передавать нужные данные и смотреть на выходе объект (как у Slim). Тесты изолированны (настройка в phpunit.xml). Поэтому они не будут друг другу мешать (но не будут работать, как я выше писал, из-за миграции в бд)
По-хорошему нужно еще вызывать setUp() или tearDown и чистить сессиии.
>В RegisterHandler и EditHandler есть общий код
Только не html.twig а phtml.php (без шаблонизатора).
Да, здесь разные процессы - редактирования и регистрация. Но на деле, они не отличаются, а оба класса - это копипаста друг друга (я даже поленился константы унести из форм, сделать подобие енама). В принципе можно было бы одну форму использовать.
> Валидация у тебя не собрана в одном классе, а размазана между EditForm и EditHandler (проверка занятости e-mail это тоже по сути валидация). Это плохо.
Тут нужно подробно пояснить почему так сделано - валидация может быть на разных слоях приложения. И на уровне представления\контроллера, т.е. места, где ты получаешь данные, так и в модели. В условной форме может быть валидация с чисткой данных, удаление всякого лишнего. на уровне модели (предметной области) валидация именно бизнес-логики. Например проверка что емейл не занят другим пользователем. По хорошему это хорошее место для сервис-слоя (а выше в треде я писал, шо сервис чаще всего не нужен и можно все хуярить в контроллер).
Может показаться, что проверку почты можно положить в форму, но это не так. Это не логика формы, это логика бизнеса. Тут нужно было вынести константы в Студента. Плюс хорошо было бы валидировать самого студента при создании (выше ты писал про констрейны, енам и тд, мне не нравится идея делать такую валидацию в бд, тк она тяжело масштабируется и часто ломает zerodowntime deploy, хотя наше приложение этим и не страдает, короче тут достаточно всей логики и валидации на уровне приложения) и в форме.
> Тут, по моему, должно быть !==
Верно, и тест на это я не написал.
> Тут не проверяется ситуация
Согласен. Но пришлось бы тогда инициализировать Auth с зависимостью, а у меня нет контейнера с зависимостями.
> Это не очень удачный подход.
Возможно.
Тут может быть на самом деле несколько подходов. Например через Validate вызывать эксепшен (кажется в какиз-то валидаторах такое есть).
Мне показалось хорошей идеей явно показать флоу
валидацию, проверка валидности формы, получение ошибок.
Сам валидатор по-хорошему стоило бы доработать.
>Тут тоже не очень логично
Тут по-хорошему нужен объект с ответом, чтобы в него передавать статус и контент.
> Непонятно, зачем нужен этот метод, когда есть конструктор.
По сути незачем, да.
> По моему, нелогично передавать в login() null. Это явно говорит об ошибке в программе.
Согласен, даже в коде нигде null не передается.
>Это не очень хорошая идея, отдавать код 401, так как в ответ на него браузер показывает окошко ввода логина и пароля.
Нет, с этим проблем не будет. Я проверял и у меня браузер просто показывал свою страницу c нужным контентом, если что-то передавал. (но тк я ничего не передавал, то ничего и не выводил кроме стандарной пустой страницы). Для вывода флеша и редиректа, нужно было бы способ работы флеш сообщений поменять (я сделал просто передачу переменной)
> Это класс правильнее назвать SessionStarter, так как он не предоставляет методов работы с сессией, а лишь позволяет ее создать.
Да, но там была идея добавить вообще добавление данных (для флеш)
> Логику логина (проверка email, пароля)
Кода не так много, чтобы делать сервис + сам код есть только в одном месте по сути.
> Логичнее было бы сделать create($student),
Да, там даже есть косяк с удалением ключа id
>Здесь нет экранирования специальных символов HTML вроде &.
Возможно, но
Это не требуется, так как пользовательские данные не передаются.
> В редактировании нет защиты от XSRF
Да.
> Если у тебя кнопка выхода, то логичнее делать ее тегом button
Да, тут уже сделал, как у других (не тех, кто делал студентов, а вообще как делают).
> Флеш-уведомления через сессию имеют недостатки.
Здесь они через переменную во вьюхе
>Можно было бы сделать в классе Student метод
Ну да, но у меня нет геттеров-сеттеров, Student не содержит логику, даже для представления. По хорошему нужно было бы делать класс-презентер
> Я думаю, это неудачная идея
ИЗначально так и делал. Вообще тут можно было бы пойти дальше и написать класс для формирования тегов. Тогда код выглядел бы чище.
> Структура дерева контроллеров не соответствует структуре папок шаблонов. По моему, это неудачная идея и логичнее было бы использовать одинаковую структуру.
Да, это хорошая идея.
Подытожу - делал проект, чтобы сделать, потому что в свое время его пропустил, уже давно работаю. Сильно большой мотивации делать замороченно у меня не было. Я когда-то, когда только начинал, делал подобный проект без фреймворков (правда тогда тесты на писал) и еще тогда задохнулся от того, чтобы всё делать руками Ну вот вообще нет интереса делать велосипед, тем более когда приходится в жизни писать на разных технологиях. Слишком меня это душило
Поэтому я довел просто до какого-то рабочего состояния. Если появится интерес, дорабатывать - попробую доработать. Нет, так нет, можно файловым хостингом на слиме заняться.
Свою реализацию оцениваю на 3\5, хоть у меня и есть тесты-линтеры-демо.
Я непременно вернусь в тред, чтобы в очередной раз не согласиться с ОПом или другим аноном.
Поздравляю. Молодец. Почему анонимный гитхаб? Мог бы левый акк и на обычном создать.
>https://anonymous.4open.science/r/student-list-97E4/readme.md
Почему столько странных файлов, xml, yml, keep, neon? Что все это такое?
Слишком неудобно.
Если что этот сервис позволяет дать ссылку на текущую версию репо, удалить картинки и ссылки. Но некоторые вещи (типа package.json) все равно нужно будет поправить).
Это конфиги
phpstan.neon это конфиг от статического анализатора PHPStan
.xml это конфиги для линтера и тестового фреймворка.
yml файлы (если ты про то, что в .github/workflows это CI конфиг, чтобы при коммите в гитхаб все запускалось и проверялось
>Слишком неудобно.
Почему? Кого ты боишься?
>Если что этот сервис позволяет дать ссылку на текущую версию репо, удалить картинки и ссылки.
Не понял насчет версии. Какие картинки и ссылки, зачем?
>Но некоторые вещи (типа package.json) все равно нужно будет поправить).
Для чего править? Ничего не понимаю.
Я понимаю, что это конфиги. Но зачем? Вопрос в том, что я не слышу нигде чтобы кто-то использовал такое в PHP проектах. Не встречается на гитхабе. Откуда ты про все это узнал и вообще узнаешь?
>Почему? Кого ты боишься?
Просто не хочу себя палить. Я просто анонимный пыхер
> Не понял насчет версии. Какие картинки и ссылки, зачем?
Сервис, на который я дал ссылку не настоящий git-хостинг. Это просто витрина для реальных репозиториев на Github.
Код можно посмотреть, можно скачать конкретный файл. Да и в общем-то все
> Для чего править? Ничего не понимаю.
Я пользуюсь гитом каждый день. У меня здесь указаны ФИО, ник, почта. Когда я сгенерировал новый проект через composer, подставилась моя почта, мой ник. Чтобы оставаться анонимным, я отредактировал authors внутри package.json
Я учился на Хекслете и собсвенно начал пользоваться этим очень давно.
Вместо этих инструментов могут быть и другие. Вместо Github Actions может быть Jenkins, Gitlab CI или другие штуки для континиус интегрейшон.
По поводу линтеров - ну блин это как помыть руки. Я настроил себе хук, чтобы не мог пушить код, который не прошел линтер.
Ну и тесты конечно же - куда без них. Тем более потренировался их писать на самописном приложении.
Статический анализатор - он как линтер, только смотрит на типы, иногда на логику кода и может что-то подсказать.
Короче в теории эти вещи помогают писать единообразный и рабочий код. Что-то вроде инструментов для качества. Я их один раз настроил и потом пользовался ими. В нормальных компаниях без этого никуда. Поэтому нужно эти инструменыт изучать, применять, Если хочется устроиться куда-то получше, чем условный битрикс или студию
>Просто не хочу себя палить.
Как ты себя спалишь?
>Чтобы оставаться анонимным, я отредактировал authors внутри package.json
Какая-то двойная жизнь. Тебе не кажется это не нормальным? Не понимаю причину страхов.
>>304398
>Я учился на Хекслете
Ты после Хекслета устроился на работу или уже работал? Всю профессию прошел? За какое время? Проходил проекты? Как устроился? Показывал код или хорошо отвечал на вопросы и решал задачки?
Это ты сделал всё что в шапке есть? На счет инструментов понятно. Просто, у меня ощущение, что в PHP нет стандартов никаких. Кто в лес, кто по дрова. Если взять хотя бы ноду, то для нее уже выработано что, где, зачем и как использовать.
>Как ты себя спалишь?
Ну начнут мою почту регать на сайты для сороколетних. Или еще че похуже.
>Какая-то двойная жизнь. Тебе не кажется это не нормальным? Не понимаю причину страхов.
Не, думаю это нормально. Аноним хуже пидораса, это истина с 2008 года
>Ты после Хекслета устроился на работу или уже работал? Всю профессию прошел? За какое время? Проходил проекты? Как устроился? Показывал код или хорошо отвечал на вопросы и решал задачки?
На тот момент прошел всю профу + первый проект. Делал тестовое задание для одной компании. Больше в гитхабе у меня ничего не было. Бомбил хх.ру, ждал пока позовут. Позвали в два места, пошел туда, где меньше спрашивали + свой продукт был. Вопросы даже не спрашивали - я спрашивал в основном.
Прошел месяцев за 8, но тогда контента поменьше было. На другом собесе был, там нужно было запросик sql писать, я там затупил, тк не знаю SQL наизусть.
Потом, на след работе ответил какую-то часть, но меня взяли на вырост (в итоге сам сьебал потом)
Оба раза давал ссылку на свой гитхаб.
>Это ты сделал всё что в шапке есть? На счет инструментов понятно. Просто, у меня ощущение, что в PHP нет стандартов никаких. Кто в лес, кто по дрова. Если взять хотя бы ноду, то для нее уже выработано что, где, зачем и как использовать.
Нет. Когда-то пытался решать задачки ОПа, но они не очень комфортные. Взять тот же код бейзикс - там задачи вылизаны, более объемные. Можно совместить то и другое.
ИЗ задач делал только студентов.
Да, в пыхе есть несколько инструментов для одной задачи. Для ноды кстати тоже что-то похожее. НАпример в пыхе можно два разных линтера юзать - PHP CS Fixer и PHP CodeSniffer. Но некоторые стандарты все равно есть. Плюс стандарты кодирования - все или почти все используют PSR1/2/12
Нащет ноды - там дофига всяких инструментов за время умерло. И куча фреймворков. Но оне не дотягивают по возожмностям из других языков (вроде как до сих пор нет нормальных ОРМ, фреййморков уровня рельсы)
>Это просто витрина для реальных репозиториев на Github.
Значит репо есть в твоем рабочем гитхабе? Значит его можно найти. Если уж ты так шифруешься, то должен был это предусмотреть.
>Значит репо есть в твоем рабочем гитхабе? Значит его можно найти. Если уж ты так шифруешься, то должен был это предусмотреть.
Да, можно. Но я его уже скрыл. Может что-то в интернетах и осталось.
Неофит на связи, немножко оффтоп. Стоит центось 7.9 и php remi repo (phpfpm7.4). Как изменить его инишник (нужно поменять пару параметров)? Изначально ебался с /etc/php.ini, в интернете сказали что я еблан и нужно через phpinfo.php посмотреть путь, я глянул - /etc/opt/remi/php74/php.ini, все поменял - нихуя. Пробовал задавать нужные параметры в надежде оверрайда в .htaccess, php.ini корня домена, даже в настройках вордпресса - н и х у я. Чяднт?
>>304720
>Собес на junior php разработчика, через 2 часа, что посмотреть сейчас, там вопросы должны быть по PHP SQL и Git, фреймворков нет, на что конкретно обратить внимание?
Лучше поспать, полчасика, чем в последний момент что-то доучивать.
Создайте скрипт, преобразующий число в арабской нотации (от 1 до 2000) в римские.
Делить на разряды и отдельно потом переводить на основе словаря в массиве. В шапке есть подобная задача от ОПа, только там перевод из цифр в слова, алгоритм в принципе тот же.
Да там оказалось собес 3-х этапный, вчера только с hr-ом попиздел минут 20 на общие вопросы о том чем занимался, что знаю ну и рассказала про компанию, ничего особенного.
Сказали что работа с magento 2 и wordpress будет, вордпресс я знаю, но сказали нужна магенто обязательно и будет тестовое по нем, вот дали неделю разобраться с ним.
Ну типа знакомство. Это не собес ещё.
>> Ой-ой-ой, это функция из худших учебников.
> Охх, это я вообще в последний момент добавил, чтобы всяческую гадость удалять.
Не надо наугад что-то удалять. Так как нет гарантии, что ты удаляешь именно то, что нужно. Вместо этого нужно использовать правильное экранирование (при выводе HTML, при вставке в БД) и проверки (например, что имя может содержать только буквы, пробелы, минус и апостроф).
> валидация может быть на разных слоях приложения. И на уровне представления\контроллера, т.е. места, где ты получаешь данные, так и в модели.
Да, так делают, когда есть какие-то дополнительные ограничения. Например, когда объект можно редактировать и через форму в админке, и через личный кабинет пользователя, и через API и там действуют разные правила проверки.
Но это не твой случай. У тебя ни в каком случае нельзя создавать двух пользователей с одинаковым email, и потому проверка email должна быть в валидаторе.
> Может показаться, что проверку почты можно положить в форму, но это не так. Это не логика формы, это логика бизнеса.
Да, потому логично было бы сделать класс-валидатор и перенести все проверки в него.
> выше ты писал про констрейны, енам и тд, мне не нравится идея делать такую валидацию в бд, тк она тяжело масштабируется
Проверки в БД это не валидация, а защита от ошибок в приложении, которое пытается вставить неправильные данные в БД. Они не заменяют проверок в валидаторе.
>>Это не очень хорошая идея, отдавать код 401, так как в ответ на него браузер показывает окошко ввода логина и пароля.
> Нет, с этим проблем не будет. Я проверял и у меня браузер просто показывал свою страницу c нужным контентом, если что-то передавал.
Да, я чуть напутал. Надо передавать заголовок WWW-Authenticate, чтобы появилась форма.
>>Здесь нет экранирования специальных символов HTML вроде &.
> Возможно, но
> Это не требуется, так как пользовательские данные не передаются.
Это все равно ошибка, так как символ &, который встречается в URL, имеет специальное значение и должен экранироваться. Любой валидатор HTML укажет тебе на ошибку здесь.
Например, отсутствие экранирования может привести к тому, что в строке вида ?page=2 & copy = 1 часть "& copy" будет интерпретирована как символ копирайта и ссылка превратится в ?page=2©=1.
>> Ой-ой-ой, это функция из худших учебников.
> Охх, это я вообще в последний момент добавил, чтобы всяческую гадость удалять.
Не надо наугад что-то удалять. Так как нет гарантии, что ты удаляешь именно то, что нужно. Вместо этого нужно использовать правильное экранирование (при выводе HTML, при вставке в БД) и проверки (например, что имя может содержать только буквы, пробелы, минус и апостроф).
> валидация может быть на разных слоях приложения. И на уровне представления\контроллера, т.е. места, где ты получаешь данные, так и в модели.
Да, так делают, когда есть какие-то дополнительные ограничения. Например, когда объект можно редактировать и через форму в админке, и через личный кабинет пользователя, и через API и там действуют разные правила проверки.
Но это не твой случай. У тебя ни в каком случае нельзя создавать двух пользователей с одинаковым email, и потому проверка email должна быть в валидаторе.
> Может показаться, что проверку почты можно положить в форму, но это не так. Это не логика формы, это логика бизнеса.
Да, потому логично было бы сделать класс-валидатор и перенести все проверки в него.
> выше ты писал про констрейны, енам и тд, мне не нравится идея делать такую валидацию в бд, тк она тяжело масштабируется
Проверки в БД это не валидация, а защита от ошибок в приложении, которое пытается вставить неправильные данные в БД. Они не заменяют проверок в валидаторе.
>>Это не очень хорошая идея, отдавать код 401, так как в ответ на него браузер показывает окошко ввода логина и пароля.
> Нет, с этим проблем не будет. Я проверял и у меня браузер просто показывал свою страницу c нужным контентом, если что-то передавал.
Да, я чуть напутал. Надо передавать заголовок WWW-Authenticate, чтобы появилась форма.
>>Здесь нет экранирования специальных символов HTML вроде &.
> Возможно, но
> Это не требуется, так как пользовательские данные не передаются.
Это все равно ошибка, так как символ &, который встречается в URL, имеет специальное значение и должен экранироваться. Любой валидатор HTML укажет тебе на ошибку здесь.
Например, отсутствие экранирования может привести к тому, что в строке вида ?page=2 & copy = 1 часть "& copy" будет интерпретирована как символ копирайта и ссылка превратится в ?page=2©=1.
> что я не слышу нигде чтобы кто-то использовал такое в PHP проектах
Я встречался с этими конфигами, в том числе они есть в open-source проектах.
>>304559
> Когда-то пытался решать задачки ОПа, но они не очень комфортные
А интересно, что именно тебе показалось некомфортным? Может, что-то можно исправить или улучшить?
> нужно через phpinfo.php посмотреть путь
Именно так и надо делать. Причем, путь к конфигам может быть разный при запуске из CLI и из-под Апача или другого веб-сервера.
> я глянул - /etc/opt/remi/php74/php.ini
Возможно, там не только этот конфиг, а он еще подключает другие конфиги. И настройки, которые ты вписал, переопределяются ниже в том же или в другом файле.
В линуксе часто делают отдельную папку, из которой инклудятся дополнительные конфиги. Логично тогда в такой папке создать свой конфиг. Тогда не будет проблем при обнолвении php, когда менеджер пакетов захочет обновить файл конфига и наткнется на твои правки.
576x1024, 0:08
Какая CMS лучше всего подходит для быстрого создания универсальных прототипов? Чтобы можно было за несколько дней накидать типичный сайт, которые чаще всего заказывают на фрилансе. Интересует ниша именно быстрых прототипов. Когда заказчик хочет сайт, но еще не знает каким он должен быть, как он будет работать и развиваться. Смотрю на Wordpress и Битрикс.
Wordpress не нравится из-за странной архитектуры. Не гибкого пайплайна обработки запросов. Из-за некоторой запутанности и множества легаси подходов. Хотя последнее время появляются современные и удобные фичи. Например CLI, Rest, etc.
Битрик кажется лучше подходит, хотя я плохо с низ знаком и могу ошибаться. Он простой, он нацелен на скорость разработки. Он популярный. Плохо, что он платный и дорогостоящий.
С другими CMS не знаком. Что посоветуете? Может Фреймворки, или же чистый PHP с библиотеками?
Стажер хочет заварить доширак. На упоковке написано, что время заварки 3 минуты. Стажер хочет приступить к еде ровно как только он заварится, но все что у него есть под рукой, чтобы отсчитать время это песочные часы на 4, 5 и 7 минут, каким образом ему отмерить ровно 3 минуты с помощью этих часов. Часы можно использовать на свое усмотрение и в любой момент налить кипяток в доширак.
Время выполнения 5 минут, не справился значит завалил.
На упаковкефикс*
Хуйня же, ставим часы на 4 и 7 минут одновременно, когда часы на 4 минуты кончаются - в часах на 7 останется сверху песка на 3 минуты, в этот момент вхуяриваем кипяток и готово. Там точно не другие цифры были? Обычно эти задачи с песочными часами посложнее.
То есть задекларированы определенные действия скрипта.
Но нечистоплотный держатель скрипта может же его в любой момент подменить и нарушить договоренности.
Ставим рядом часы на 7 и 4 минуты. Заливаем кипяток и переворачиваем часы на 7 минут. Когда количество песка уменьшится до объема как в часах на 4 минуты, начинаем употреблять.
Купленный шаблон заблокирован после переезда на другой домен, а разработчик, судя по всему, пропал на войне.
Easytoyou расшифровывает только первые 30 строк, значит это в принципе возможно, но оплатить там сейчас врятли получится, сами понимаете.
>Нельзя.
Но подожжи, анон.
То есть это получается некая системный пофигизм безопасности ?
Не может быть чтобы никто не озаботился каким-нибудь расширением-модулем пхп для контроля.
Просто чтобы в ответе например отправлялся хеш скрипта.
Весь пояс пхп получается какой-то анонимный, ну если видеть инфраструктуру умозрительно.
>А интересно, что именно тебе показалось некомфортным? Может, что-то можно исправить или улучшить?
посмотри code-basics - каждый урок по отдельной фигне. За раз ты изучаешь только малюсенькую малость.
Да, размазано и разжевано, зато объяснено.
поставить часы на 4 и 7 минут одновременно.
Когда часы на 4 минуты кончатся, залить дошик и отмерить оставшиеся 3 минуты.
Что мешает злоумышленнику, получившему доступ к серверу, подменить скрипт на новый, а хеш отправлять от старого скрипта?
Я думаю, это просто никому не нужно. Если тебе такое нужно, то исходный код интерпретатора PHP доступен - можешь исправить его, чтобы он отправлял хеш скрипта.
Вопрос очень странный.
Что ты подразумеваешь под "прототипами"? Если визуализацию, то какая-нибудь Тильда подойдёт, там функций достаточно для сборки простых проектов от лендоса до магазина.
Если же ты имеешь в виду функциональный прототип, когда речь идёт о чём-то более серьёзном, то бери Laravel или одну из CMS на ее основе (люто-бешено рекомендую October).
Там не надо ломаный, в версии 2020 или ниже можно просто триалку скипать каждый месяц.
А где его взять?
Если ты не можешь на чистой пыхе писать, то тебе в фреймворках делать нечего.
Пиши на PHP в ООП стиле, учись использовать готовые компоненты из packagist.org, используя composer. Фреймворк - это просто минимальный набор компонентов.
Тебя взломали
Скорее скелет,на который навешиваю код
На пыхе даже небо и аллах написаны, а его современный конкурент - го да да я знаю что задачи разные, но переписывают пыху на го - анально привязан к гуглу, так что сдохнет гарантированно.
просто супер дохуя говняка
настройки модулей пик 2
Фиксанул
маска ввода
а че так можно?
Все равно ошибка, запускал на Висте, хотя в системных требованиях написано что пхп работает на ней
$query1 = «SELECT word FROM pl_test LIMIT 1»;
$result = $conn->query($query1);
$record = mysqli_fetch_array($result);
echo $record[‘word’];
Ты откуда с такими кавычками вышел? Код в ворде набирал?
Для двойных кавычек "
Для одинарных '
Копируй, пользуйся.
объясните что значит -> в пыхе,я в гугле искал так и не нашел нормального объяснения
Обращение к элементам класса.
из сишки пошло
1400$ получаю, удалёнка на диване, нихуя не делаю, никакого контроля, только утренний митинг. Хорошо если часа 4 в день код попишу.
А как без его, только на нём и пишут. Не помню когда последний раз писал без ООП.
Что можно почитать про это? Более практические и прикладные вещи кроме базы вроде банальщины типа наследования.
Я из книг только Котерова читал и по SQL. ООП базовому я научился из видеокурсов, например сначала Виктора Зинченко на ютубе повторяешь, потом Афанасьева по Ларавелю к примеру. А дальше ещё англо-язычных смотреть, как они пишут код.
А уже нормальный уровень ООП поднимается на работе, когда видишь код опытных коллег, как они делают, и на ревью. И сам учишься более правильную архитектуру строить. Увы такого в книжках не прочитаешь.
Самое главное даже не паттерны, а солид и прочие принципы. Изучай солид, поймёшь его - будешь правильно ООП употреблять.
Что за ноунейм?
SQL за 10 минут, этого достаточно будет для старта. А дальше практика.
>>322066
Хз, 1,5 года может со самого старта, когда ещё попробовал прогу на Си, и заканчивая фриланс-проектом магазина знакомому на ларавеле.
А работаю в итоге вообще на симфони фреймворке.
>>322284
Тебе все равно надо уметь в базовую вёрстку и js. Базовая вёрстка с помощью любого css-фреймворка набрасывается быстро. Можешь спиздить ещё её, есть архивы с вёрсткой специально для пет-проектов.
А что подразумевается под базовым js? getelementbyid и менять css свойства объектов DOM?
учебник Кантора+мозилла док+гугл
есть неплохая книжка Мэтта Фризби Проф жабаскрипт ля веб деволоперов
Я не могу отправить ajax и прочитать его со стороны серва и вернуть обратно.
Есть запрос с X-requested-with и пыхыпы через $_SERVER видит его прекрасно - правда этот запрос без передачи данных.
А вот как именно отправить объект через ПОСТ и прочитать его - не разумею, в интернете столько всего перерыл, все абсолютно мимо. хотя казалось бы, такая базовая дефолтная вещь.
Со стороны жса:
xhr.open("POST", "../index.php", true); - метод оправки, адрес серва, асинхроность
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8"); - пробовал разные загаловки, но не особо помогает
xhr.send(JSON.stringify(node)); - по идее он должен любой объект отправлять, но раз уж принятно жсонами кидаться - ладно
Со стороны пыхи:
if (isset($_POST['data'])) {
echo "some response from POST/GET";
}
Вот со стороны пыхи вообще не понимаю как определить запрос, я столько всего напереставлял вместо индексов - и название отправляемого объекта, и свойства объекта и заголовки разные,
Подскажие-объясните, а то я кукухой поеду, уже тонну времени на такое угробил.
А насколько его знать надо? Могу в базовое взаимодействие с дом, события, запросы, этого достаточно?
Видеокурсы на рутрекере. Книжки нахуй, печку ими распаливать только.
Например, у меня есть функция getFiles(string $directoryPath): array, которая возвращает список файлов (без папок) из директории. Что делать если в функцию передадут путь до файла или путь до несуществующей директории?
В общем есть небольшие знания в программировании, циклы там, условия и тд Я посмотрела на курсы и офигела от количества. и тд, какой-то лаврик, Елисеев, отус, марлиндев. Короче десятки разных. Даже в дизайне их меньше, а тут просто сумасшедшее количество.
Шапку смотрела и прочитала до программы списка абитуриентов. Сейчас в процессе, но хочется что-то толковое в видео формате. Буду рада помощи. И да, PHP - жив, я верю в это и все вы красавчики)
>кодировка файла
>кодировка строки
>кодировка страницы
>utf-8
>windows-1251
>кодировка базы данных
Как во всем этом говне не запутаться? Подскажите куда копать.
Написано же задачки. Будешь делать, которые я не успеваю. Там все без коммерции это не магазин и прибыли никакой нет, можно сказать хобби с убытками в виде оплаты домена и хоста.
Почему PHP, а не фронтенд на JS/TS? PHP - этж ковыряться в данных, базах, серверах, потоках, командах, оптимизации. Это не сложно, просто твой бэкграунд в виде дизайна/вёрстки пригодился бы на фронтенде.
Считаю фронтенд не программированием. Не знаю как объяснить. Да и проще работу найти в моем регионе
Пусть она выкидывает исключение, а тот, кто вызывает, обрабатывает его.
https://3v4l.org/rTRoj
Перекатился с пхп я в C# на позицию Automation QA и господи, какой же это лютый ужас! Эти дженерики и коллекции, какой же это кал!
А по перспективам я ваще теперь хер знает как быть. На линкедине в ту же Швецию 188 вакансий на QA против 1000+ на PHP.
А так мечтал релокейтнуться...
Извините аноны, что не по теме, просто накипело.
>Считаю фронтенд не программированием.
Так ты ж не знаешь что это такое, ну всм нет опыта с ним. Не в плане кнопочки на jquery вешать, а серьёзный огромный фронтенд на тайпскрипте и ООП.
>Да и проще работу найти в моем регионе
Ты можешь откуда угодно работать веб-программистом.
Ну ты можешь и PHP попробовать, да. Ставь линукс(убунту) 20.04.4 LTS тогда первым делом.
Ну как бы да. Конкуренции мало, вакансий валом. Язык довольно простой, джава-подобный, быстрый, прошлифованный за столько то лет.
Хотя вот как-то в США маловато вакансий, а в европке много.
Перекатывайся обратно, мы ж тесты все и так пишем на пыхе.
Да, тайпскрипт не пробовала. Реакт+редакс клевая вещь, и поле там не паханное, делала некое подобие системы заказов, с авторизацией и статусами заказов, но уперлась в знания бд (делала на монге) и бэка в целом. Вообще реакт это прям имба в мире фронтенда. И пока это делала, стал очень интересен бэксайд.
Что-то из видосиков посоветуешь? Просто по видео лучше заходит, физиология видимо такая.
Да.
>>324399
Учебник Трепачёва загугли, там кратко простым языком и с задачками. Виктор Зинченко на ютубе, но там только "курс Старт". Дмитрий Афанасьев на ютубе с его курсом по ларавель-фреймворку. Какой-то курс по SQL смотрел ещё на рутрекере неплохой, но забыл что за он.
Из фреймворков лучшие на сегодня симфони и ларавель. В принципе годных прям курсов нет, потому как хайпа на язык нет, вот продавцы курсов и не клепают.
Если хочешь, то можешь спрашивать в телеге, а то на двачах редко сижу. https://t.me/forest_alf
Спасибо товарищ, родина этого не забудет! =)
Я слышал курсы это вообще хуйня зачастую. Типа зачем они этим занимаются, если сами все знают и могут подымать 300к/наносек напрямую разработкой.
https://vc.ru/legal/354002-klienty-geekbrains-podali-kollektivnyy-isk-k-platforme-iz-za-otkazov-vozvrashchat-dengi-za-kursy
Даже потом судятся с такими, деньги даже если и отсудишь, то время свое невосполнимое нет.
>кодировка файла
>кодировка строки
>кодировка страницы
>кодировка базы данных
это все одно и то же
кодировка это как символы кодируются (хранятся в байтах)
есть классика. очень старый формат ascii
1 символ = 1 байт
в базовом формате ascii можно хранить латиницу+цифры+символы
>utf-8
1 символ = 1-4 байта
это используют все нормальные люди
тк этот формат поддерживает ВСЕ языки + кучу символов(например эмодзи)
https://apps.timwhitlock.info/emoji/tables/unicode
https://www.postgresql.org/docs/current/multibyte.html
есть разные версии этого добра например utf8mb4_unicode_ci
https://zalinux.ru/?p=1071
https://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
>windows-1251
фу
>Как во всем этом говне не запутаться? Подскажите куда копать.
везде юзай utf-8
>кодировка файла
>кодировка строки
>кодировка страницы
>кодировка базы данных
это все одно и то же
кодировка это как символы кодируются (хранятся в байтах)
есть классика. очень старый формат ascii
1 символ = 1 байт
в базовом формате ascii можно хранить латиницу+цифры+символы
>utf-8
1 символ = 1-4 байта
это используют все нормальные люди
тк этот формат поддерживает ВСЕ языки + кучу символов(например эмодзи)
https://apps.timwhitlock.info/emoji/tables/unicode
https://www.postgresql.org/docs/current/multibyte.html
есть разные версии этого добра например utf8mb4_unicode_ci
https://zalinux.ru/?p=1071
https://stackoverflow.com/questions/766809/whats-the-difference-between-utf8-general-ci-and-utf8-unicode-ci
>windows-1251
фу
>Как во всем этом говне не запутаться? Подскажите куда копать.
везде юзай utf-8
https://dev.mysql.com/doc/refman/8.0/en/charset-server.html
>не писать в облачном редакторе вместо захламления локальног диска
>не иметь докера в в тукдвадцать
Ебать ты лох.
На самом деле мне похуй, сижу на ХАМППе потому что он легковесный и не лагерный в отличии от докера, когда-нибудь навреное придется устанавливать линупс, лет через 10 навреное раскочегарюсь
обслуживаю несколько апишек
апишка = стандарный набор контейнеров php nginx postgresql minio + ...
в каждом проекте есть makefile с командами start stop test install и тд
очень удобно
я б ебнулся это всё руками поднимать/останавливать/удалять
+ всегда можно сделать docker system prune --all и всё почистить
>Когда пишешь на php обязательно сидеть на Linux?
нет. юзают то что удобно. напр я привык юзать линух
докер нативно работает только под линух
под виндой и макос это работает значительно медленнее
есть костыли для макос
https://docker-sync.readthedocs.io/en/latest/
https://mutagen.io/documentation/introduction/installation
есть платные решения которые вроде хорошо работают -
Parallels Desktop
как по мне это просто лишний гемор
>Или нет смысла расширять свое очко?
ну я попердолился поначалу с линух
если железо плохо поддерживается - гемор да
сейчас всё ок
+ иногда будешь хоть на сервера смотреть что там не так
Ну как бы php это работа с сервером. Все без исключения сервера на линуксе. Ты обязан иметь навыки девопса/администрирования хотя бы на уровне джуна, знать как команду на крон повесить, супервайзер где настроить, сервер поднять, логи посмотреть, ключи настроить и т.д.
Только отбитые макаки уровня вордпресс пишут на пыхе с винды, в принципе я таких в жизни не встречал среди коллег.
регулярное на проверку мыла,что в нем не так ?
я учусь,хочу сам написать,есть что по регулярному сказать?
Если это регулярка именно для проверки - добавь флагов. regex101 рекомендует /m для использования символов ^ и $; я рекомендую /i так как черт его знает, откуда тебе придет эта строка и какого регистра символы там будут.
[a-zA-Z0-9] при проверке имени почтового ящика некорректна максимально. Там еще точка допустима, типа
{2,5} при проверке домена некорректна. У тебя даже @rambler не проходит, не говоря уже о длинных корпоративных адресах.
{2,5} при проверке домена верхнего уровня тоже не особо корректно, но тут уже не смертельно. Есть всякие .museum, .online и прочие. Встречается редко, но опять таки, кто ж знает, что ты пишешь.
Так что, по хорошему, находишь RFC на правила составления email-адресов и начинаешь его разбирать.
А с другой стороны, тебе все эти премудрости вообще нужны? <что угодно>@<что угодно>.<что угодно> не устроит?
Так-то устроит, спасибо что все расписал)
Посоветуйте хорошие онлайн курсы, сам не совсем прям новичек был опыт на питоне, знаю в шапке тоже все неплохо, но все еще многого не умею, спросить мне было бы проще чем вчитываться.
Какие требования для присоединения? Какие идеи есть?
Давай я попробую объяснить простыми словами. Данные, которые компьютер хранит в памяти, в файлах на диске, передает по сети - это все наборы байт. Байт это (если упростить) целое число от 0 до 255. Соответственно, любая информация должна быть закодирована в виде этих чисел.
Например, когда ты заходишь на сайт, то твой браузер отправляет запрос в виде потока байт и в ответ приходит страница сайта, опять же в виде последовательности байт.
Если мы хотим передавать/хранить текст, то мы должны договориться о том, какими байтами мы будем кодировать каждую букву. Кодировка - это таблица, в которой записано, какому символу какие байты соответствуют. Соответственно, в зависимости от кодировки, одни и те же байты могут обозначать разные символы, и наоборот один и тот же текст можно закодировать по-разному.
Проще всего было бы, если бы существовала только одна кодировка, и все бы ее использовали. Но по историческим причинам это не так, и кодировок существует довольно много. Раньше использовались однобайтные кодировки (вроде Windows-1251), в которой одному символу соответствовал ровно один байт, но у них есть ограничение: так можно закодировать всего 256 символов. Поскольку символов в мире существует намного больше (десятки тысяч), люди перешли к многобайтовым кодировками вроде utf-8, где один символ может кодироваться как одним, так и несколькими идущими подряд байтами.
Соответственно, когда ты в редакторе пишешь текст и хочешь сохранить файл, то ты должен выбрать кодировку: как кодировать введенные тобой буквы. И при открытии файла ты должен выбрать ту же кодировку, в которой ты его сохранял, иначе текст может исказиться. В простых текстовых файлах не записано, в какой он был сохранен кодировке, потому ее надо выбирать вручную.
PHP не привязан к какой-то кодировке. Когда ты пишешь код вроде
$x = 'hello';
то PHP просто копирует в переменную $x байты из файла с исходным кодом. То есть, PHP сам не знает, какие буквы там закодированы, он просто копирует эти цифры как есть. Получается, что текст в переменной закодирован в той же кодировке, которая была в файле с программой.
Чтобы минимизировать проблемы, стоит использовать кодировку utf-8 для файлов с PHP-кодом, так как она позволяет закодировать любой символ любого языка мира, в отличие от однобайтовых кодировок с ограничением в 256 символов.
Когда ты сохраняешь данные в файл, например, с помощью file_put_contents('file.txt', $x), то PHP опять же просто копирует байты из переменной $x в файл. И соответственно, а файле данные будут в той кодировке, в которой изначально был сохранен PHP-файл с кодом. Если ты хочешь сохранить файл в какой-то другой кодировке, ты можешь перекодировать текст функцией iconv(). Эта функция принимает на вход строку (набор байт) в одной кодировке и выдает набор байт, который кодирует ту же строку, но в другой кодировке.
Но я думаю, что удобнее сохранять все в utf-8.
Теперь про страницы. Когда веб-сервер отдает страницу браузеру (в виде набора байт), тот должен как-то понять, в какой она кодировке, чтобы отобразить текст из этой страницы. Для этого кодировка указывается либо в теге meta charset, либо в HTTP-заголовке Content-Type. Ты должен указать там ту кодировку, которая использовалась в PHP-файлах с исходным кодом, скорее всего это utf-8. Если ты не укажешь кодировку или укажешь ее неправильно, то браузер может отобразить текст некорректно. Потому стоит всегда писать <meta charset="utf-8"> внутри тега <head>, как можно раньше.
Теперь про базу данных. Когда ты из PHP отправляешь в базу данных запрос, например:
$pdo->query("SELECT id FROM pages WHERE name = 'hello'");
то опять же, PHP просто посылает в базу данных байты. Чтобы база данных могла понять, какой текст они кодируют, она должна знать кодировку текста. Для этого мы заранее указываем кодировку при соединении с БД. Для PDO это делается опцией charset в DSN ( https://www.php.net/manual/ru/ref.pdo-mysql.connection.php ), для mysqli - методом set_charset ( https://www.php.net/manual/ru/mysqli.set-charset.php ). Единственный подвох тут - в MySQL кодировка utf8 обозначает не utf-8, а ее сильно урезанную версию. Надо указывать utf8mb4 - для MySQL это значит "utf-8". Такая путаница получилась по историческим причинам, тут остается только запомнить эту особенность.
Кроме кодировки соединения (между PHP и MySQL), в MySQL еще есть кодировка таблиц - это кодировка, в которой данные сохраняются на диск. Ее указывают при создании БД или создании таблиц. Тут можно всегда выбирать utf8mb4. Если выбрать однобайтовую кодировку вместо utf-8, то не получится вставить в таблицу символы, которых нет в этой кодировке.
Надеюсь, что получилось не очень сложно. Если ты понял, что такое кодировка, то тебе станет понятно, зачем ее везде указывают.
Если у тебя остались какие-то вопросы, то спрашивай. Могу еще дать урок по кодировкам: https://github.com/codedokode/pasta/blob/master/cs/strings.md
Давай я попробую объяснить простыми словами. Данные, которые компьютер хранит в памяти, в файлах на диске, передает по сети - это все наборы байт. Байт это (если упростить) целое число от 0 до 255. Соответственно, любая информация должна быть закодирована в виде этих чисел.
Например, когда ты заходишь на сайт, то твой браузер отправляет запрос в виде потока байт и в ответ приходит страница сайта, опять же в виде последовательности байт.
Если мы хотим передавать/хранить текст, то мы должны договориться о том, какими байтами мы будем кодировать каждую букву. Кодировка - это таблица, в которой записано, какому символу какие байты соответствуют. Соответственно, в зависимости от кодировки, одни и те же байты могут обозначать разные символы, и наоборот один и тот же текст можно закодировать по-разному.
Проще всего было бы, если бы существовала только одна кодировка, и все бы ее использовали. Но по историческим причинам это не так, и кодировок существует довольно много. Раньше использовались однобайтные кодировки (вроде Windows-1251), в которой одному символу соответствовал ровно один байт, но у них есть ограничение: так можно закодировать всего 256 символов. Поскольку символов в мире существует намного больше (десятки тысяч), люди перешли к многобайтовым кодировками вроде utf-8, где один символ может кодироваться как одним, так и несколькими идущими подряд байтами.
Соответственно, когда ты в редакторе пишешь текст и хочешь сохранить файл, то ты должен выбрать кодировку: как кодировать введенные тобой буквы. И при открытии файла ты должен выбрать ту же кодировку, в которой ты его сохранял, иначе текст может исказиться. В простых текстовых файлах не записано, в какой он был сохранен кодировке, потому ее надо выбирать вручную.
PHP не привязан к какой-то кодировке. Когда ты пишешь код вроде
$x = 'hello';
то PHP просто копирует в переменную $x байты из файла с исходным кодом. То есть, PHP сам не знает, какие буквы там закодированы, он просто копирует эти цифры как есть. Получается, что текст в переменной закодирован в той же кодировке, которая была в файле с программой.
Чтобы минимизировать проблемы, стоит использовать кодировку utf-8 для файлов с PHP-кодом, так как она позволяет закодировать любой символ любого языка мира, в отличие от однобайтовых кодировок с ограничением в 256 символов.
Когда ты сохраняешь данные в файл, например, с помощью file_put_contents('file.txt', $x), то PHP опять же просто копирует байты из переменной $x в файл. И соответственно, а файле данные будут в той кодировке, в которой изначально был сохранен PHP-файл с кодом. Если ты хочешь сохранить файл в какой-то другой кодировке, ты можешь перекодировать текст функцией iconv(). Эта функция принимает на вход строку (набор байт) в одной кодировке и выдает набор байт, который кодирует ту же строку, но в другой кодировке.
Но я думаю, что удобнее сохранять все в utf-8.
Теперь про страницы. Когда веб-сервер отдает страницу браузеру (в виде набора байт), тот должен как-то понять, в какой она кодировке, чтобы отобразить текст из этой страницы. Для этого кодировка указывается либо в теге meta charset, либо в HTTP-заголовке Content-Type. Ты должен указать там ту кодировку, которая использовалась в PHP-файлах с исходным кодом, скорее всего это utf-8. Если ты не укажешь кодировку или укажешь ее неправильно, то браузер может отобразить текст некорректно. Потому стоит всегда писать <meta charset="utf-8"> внутри тега <head>, как можно раньше.
Теперь про базу данных. Когда ты из PHP отправляешь в базу данных запрос, например:
$pdo->query("SELECT id FROM pages WHERE name = 'hello'");
то опять же, PHP просто посылает в базу данных байты. Чтобы база данных могла понять, какой текст они кодируют, она должна знать кодировку текста. Для этого мы заранее указываем кодировку при соединении с БД. Для PDO это делается опцией charset в DSN ( https://www.php.net/manual/ru/ref.pdo-mysql.connection.php ), для mysqli - методом set_charset ( https://www.php.net/manual/ru/mysqli.set-charset.php ). Единственный подвох тут - в MySQL кодировка utf8 обозначает не utf-8, а ее сильно урезанную версию. Надо указывать utf8mb4 - для MySQL это значит "utf-8". Такая путаница получилась по историческим причинам, тут остается только запомнить эту особенность.
Кроме кодировки соединения (между PHP и MySQL), в MySQL еще есть кодировка таблиц - это кодировка, в которой данные сохраняются на диск. Ее указывают при создании БД или создании таблиц. Тут можно всегда выбирать utf8mb4. Если выбрать однобайтовую кодировку вместо utf-8, то не получится вставить в таблицу символы, которых нет в этой кодировке.
Надеюсь, что получилось не очень сложно. Если ты понял, что такое кодировка, то тебе станет понятно, зачем ее везде указывают.
Если у тебя остались какие-то вопросы, то спрашивай. Могу еще дать урок по кодировкам: https://github.com/codedokode/pasta/blob/master/cs/strings.md
Варнинги используются для предупреждений, которые не влияют на корректность работы программы, но могут быть полезны. Например, отсутствует файл, который должен был быть, но это не беда - программа сгенерировала его заново и ошибки нету. Программист прочтет предупреждение и может быть, разберется, почему файла не было.
Обычно trigger_error используют только в совсем простых программах. В больших программах используют логгирование через какую-нибудь библиотеку вроде monolog, где гораздо больше возможностей.
Ассерты это "утверждения". Например: assert($x > 0); значит "я мамой клянусь (гарантирую), что в этом месте $x всегда будет больше нуля, а если это не так, то значит программа написана неправильно и ее нужно завершить, а меня уволить (шутка)". Ассерт также помогает при чтении кода программы. Исключение же необязательно говорит о том, что программа написана неправильно. Исключение может, например, выбрасываться, если в правильно написанную программу пришли неправильные данные.
Минус утверждений в том, что их логика работы (завершать программу или просто выдать предупреждение и продолжить) определяется настройками в php.ini, и соответственно, может так получиться, что вместо завершения программы она продолжит выполняться с некорректными данными. Это серьезный недостаток и потому лучше использовать исключения, хотя они и занимают больше места.
Наконец, исключения. Они говорят о невозможности выполнить функцию. Например, мы вызвали функцию загрузки данных из файла, но файла с таким именем не существует. Функция не может загрузить данные и сигнализирует об этом выбросом исключения. Это неожиданная ситуация, в коде функции нет логики на такой случай, и она не может выполнить свою задачу. Однако, тот, кто вызвал функцию, может поймать исключение и как-то обработать эту ошибку. Или может не ловить - тогда программа завершится.
Обычно на каждую ошибку делают свой класс исключения.
> Что делать если в функцию передадут путь до файла или путь до несуществующей директории?
Это зависит от логики работы программы. Нормальная ли это ситуация или ненормальная? Если для нее нормальная ситуация, что в нее передают неправильные пути, и это не надо даже фиксировать - то можно вернуть пустой список файлов. Если же ожидается, что путь будет корректный, то надо выкидывать исключение. Которое, опять же, можно поймать и вывести какое-то сообщение.
Вот еще пример: функция проверки веденного email на правильность. Для такой функции получение на вход неправильного email - самая заурядная ситуация, потому логично вернуть в таком случае false, А вот если мы вызываем функцию отправки email пользователю и передаем неправильный адрес, то это нештатная ситуация, письмо мы отправить не можем и мы выкидываем исключение. Хотя, если у нас база данных наполовину забита мусором, неправильные email это обычная ситуация, и это письмо не особо важное, то можно просто вернуть false. Но лучше конечно до такого состояния проект не доводить.
Урок про исключения: https://github.com/codedokode/pasta/blob/master/php/exceptions.md
Варнинги используются для предупреждений, которые не влияют на корректность работы программы, но могут быть полезны. Например, отсутствует файл, который должен был быть, но это не беда - программа сгенерировала его заново и ошибки нету. Программист прочтет предупреждение и может быть, разберется, почему файла не было.
Обычно trigger_error используют только в совсем простых программах. В больших программах используют логгирование через какую-нибудь библиотеку вроде monolog, где гораздо больше возможностей.
Ассерты это "утверждения". Например: assert($x > 0); значит "я мамой клянусь (гарантирую), что в этом месте $x всегда будет больше нуля, а если это не так, то значит программа написана неправильно и ее нужно завершить, а меня уволить (шутка)". Ассерт также помогает при чтении кода программы. Исключение же необязательно говорит о том, что программа написана неправильно. Исключение может, например, выбрасываться, если в правильно написанную программу пришли неправильные данные.
Минус утверждений в том, что их логика работы (завершать программу или просто выдать предупреждение и продолжить) определяется настройками в php.ini, и соответственно, может так получиться, что вместо завершения программы она продолжит выполняться с некорректными данными. Это серьезный недостаток и потому лучше использовать исключения, хотя они и занимают больше места.
Наконец, исключения. Они говорят о невозможности выполнить функцию. Например, мы вызвали функцию загрузки данных из файла, но файла с таким именем не существует. Функция не может загрузить данные и сигнализирует об этом выбросом исключения. Это неожиданная ситуация, в коде функции нет логики на такой случай, и она не может выполнить свою задачу. Однако, тот, кто вызвал функцию, может поймать исключение и как-то обработать эту ошибку. Или может не ловить - тогда программа завершится.
Обычно на каждую ошибку делают свой класс исключения.
> Что делать если в функцию передадут путь до файла или путь до несуществующей директории?
Это зависит от логики работы программы. Нормальная ли это ситуация или ненормальная? Если для нее нормальная ситуация, что в нее передают неправильные пути, и это не надо даже фиксировать - то можно вернуть пустой список файлов. Если же ожидается, что путь будет корректный, то надо выкидывать исключение. Которое, опять же, можно поймать и вывести какое-то сообщение.
Вот еще пример: функция проверки веденного email на правильность. Для такой функции получение на вход неправильного email - самая заурядная ситуация, потому логично вернуть в таком случае false, А вот если мы вызываем функцию отправки email пользователю и передаем неправильный адрес, то это нештатная ситуация, письмо мы отправить не можем и мы выкидываем исключение. Хотя, если у нас база данных наполовину забита мусором, неправильные email это обычная ситуация, и это письмо не особо важное, то можно просто вернуть false. Но лучше конечно до такого состояния проект не доводить.
Урок про исключения: https://github.com/codedokode/pasta/blob/master/php/exceptions.md
Может это потому что ты 5 доменов пытаешься сразу взять?
>>318534
Пригодятся.
>>319548
Если ты не боишься командной строки, и у тебя есть хотя бы несколько Гб памяти, то можешь установить линукс в виртуалку и запускать последнюю версию PHP там. Ну или поменять свою висту (для которой уже не выпускаются обновления безопасности) на линукс целиком.
Если лениво изучать, то месяца через 2-4. Если целыми днями сидеть за компьютером, то быстрее.
>>320277
Это обращение к полю объекта или методу. Например:
$x = $o->field; // записать в $x содержимое поля field объекта $o
$o->method(); // вызвать метод у объекта
Если ты не знаешь что такое поле и метод, то можешь взять учебник из шапки и открыть там главу про ООП - там написано.
Точно, не работает. Можешь использовать другие сайты вроде https://replit.com/languages/php_cli или поискать "run php online". Или установить интерпретатор PHP.
>>319841
По умолчанию mysqli не показывает ошибки, возникшие при работе с БД. Это неправильно. Поставь в начале программы до соединения с БД команду:
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
Теперь ошибки должны выводиться на экран или писаться в логи.
В PHP 8.1 это исправят и писать команду больше будет не нужно.
Из твоего описания ошибки это не понять. Нужно привести текст ошибки и фрагмент кода, в котором она происходит.
>>321961
Для чего, по твоему, оно добавлено в учебник в шапке? Конечно нужно. Не надо его пугаться.
>>321984
В основном база и нужна. ООП не значит, что ты должен специально писать какие-то усложненные конструкции. Если ты видишь что-то похожее на объект - создай для него класс. Если не видишь - не создавай. Например, пользователя можно представить в виде объекта. После этого можешь учиться делать "сервисы" - это классы, которые не представляют какую-то сущность, а содержат набор операций над другими сущностями. Например, сервис регистрации, который содержит методы для проверки данных и создания пользователя.
ты похоже шаришь,что я должен знать чтобы устроиться на 30к в месяц ? (типо базовые вещи я вроде уже +- пишу и даже больше возможно,сложно себя оценивать)
А почему тебя выворачивает? Потому, что ты не понимаешь ее и тебя раздражает долгий подбор свойств наугад? CSS довольно логичный, если в нем разобраться. Или тебе кажется эстетически некрасивым результат?
В идеале нужно знать CSS так, чтобы в голове представлять, как расставятся элементы. Ты не подбираешь свойства, а сразу пишешь как надо, проверяешь в браузере и остаются лишь какие-то мелкие недочеты.
>>322335
> $conf = $this->xml->conf; // что делает эта переменная?
Она никак не используется в коде, наверно раньше использовалась, а потом код переделали. Можно убрать эту строку.
>Например, пользователя можно представить в виде объекта. После этого можешь учиться делать "сервисы" - это классы
Ну вот примеры все эти про юзеров и товары понятны, но там ведь более абстрактные вещи надо городить, архитектуры mvc эти, паттерны и тд. Я не знаю с какой стороны ко всему этому подойти.
> А вот как именно отправить объект через ПОСТ и прочитать его
В твоем случае, ты передаешь неправильный тип данных в заголовке Content-Type и потому PHP не может декодировать данные и получается пустой $_POST:
> application/x-www-form-urlencoded;
А должно быть application/json (без кодировки) если ты передаешь JSON.
Также, PHP поддерживает декодирование данных только в форматах application/x-www-form-urlencoded и multipart/form-data. Формат JSON не поддерживается. Ты должен самостоятельно определить, что пришел JSON (по заголовкам), самостоятельно прочитать тело запроса из php://input и самостоятельно декодировать. Не забудь проверять на ошибки.
> header("Content-Type: application/json");
Это пишут, если ты отдаешь данные в JSON (из PHP в браузер). На принимаемые из браузера данные это никак не влияет.
Если ты хочешь использовать поддерживаемый PHP формат, то передавай данные не с помощью JSON, а с помощью FormData и типа multipart/form-data, тогда они попадут в $_POST.
>>323405
Сверстать простую страницу с шапкой, подвалом, колонками и меню.
>>323711
Обычно у курсов есть демо-видео, можно их посмотреть и сравнить.
Вообще, дженерики и коллекции это неплохая вещь. Не знаю, правда, как они в C# реализованы. Думаю, что и в PHP они со временем появятся.
>>324466
Иногда, к сожалению, платформы для обучения применяют не очень хорошие трюки. Я помню, как на сайте одной такой платформы рядом с описанием курса по основам PHP были фразы (большими буквами) вроде "средняя зарплата PHP программиста X рублей" (не помню точно, сколько там было написано, может 100 000 или больше). Вот только они не пишут, что после одного такого курса X рублей платить никто не будет, более того, чтобы устроиться на работу надо пройти не один курс, а несколько. В общем, темные паттерны в действии.
Хотя сами по себе платформы для обучения это неплохо. Если там есть наставник, который будет указывать на ошибки, то это может быть быстрее, чем разбираться самому.
Знать основы линукс (процессы, права, файловая система, базовые команды) полезно. Установить линукс можно в виртуалку, минимальному дистрибутиву без графики хватит и 512-1024 Мб памяти.
>>325325
Да, прописывать в composer.json. Справедливости ради, если у тебя там 10-20 файлов, это особо на время загрузки не повлияет, а если использовать preloading, то ты можешь хоть тысячу файлов подключить.
Увы, автолоадинга пока нет. Согласен, что вместо статических методов функции использовать было бы логичнее.
Все. Например, последний элемент содержит от 2 до 5 символов, и имена вроде
Имя домена может содержать минусы, цифры, много точек. Например:
Более того, сейчас есть юникодные домены вроде
Где-то в RFC есть "правильная" регулярка для проверки email, но ты ужаснешься от ее длины. Вот она: https://stackoverflow.com/questions/20771794/mailrfc822address-regex
Такую регулярку глупо использовать в программе, так как в ней трудно разобраться и нужно много времени, чтобы проверить ее правильность. Код должен легко читаться.
Поэтому регулярка для проверки email может выглядеть как
(проверяем, что нет пробелов, что есть ровно один знак @ посередине и минимум одна точка справа)
Этого будет достаточно. Дополнительно ты можешь извлечь домен и проверить в DNS наличие MX записи для него.
Если есть желание, ты можешь усложнить регулярку, но тогда я советую тебе прочитать описание того, какие символы могут встретиться: https://en.wikipedia.org/wiki/Email_address и далее по ссылкам можешь почитать RFC5322 и 6854.
- PHP (с ООП)
- SQL
- как используется кеширование
- основы верстки (HTML/CSS)
- основы JS/DOM
- основы какого-нибудь фреймворка
- базовые команды линукс
Подробные требования ты можешь найти на сайтах с вакансиями.
Не нужно городить сложные вещи. Когда новичок прочел про паттерны и пытается везде их засунуть, код только ухудшается.
Про MVC ты можешь в общих чертах прочесть тут https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Про DI тут https://github.com/codedokode/pasta/blob/master/arch/di.md
Про работу с БД тут https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
Можешь также прочитать какой-нибудь туториал по Симфони, там можно поучиться хорошим практикам.
Также почитай про SOLID, но ищи объяснения без мудреных слов. Что касается сервисов, то они строятся исходя из принципа единой ответственности. Кто-то один должен отвечать за управление пользователями (добавление/бан) - давайте сделаем для этого сервис UserService. MVC тоже основан на принципе единой ответственности - каждый класс должен заниматься своим делом.
Очень надеюсь что дженериков в пхп не будет, потому что в действительности это походит на какое-то лютое дерьмо, да и зачем пыхе дженерики, если она и без них прекрасно живет?
При этом она получает тела запроса отдельно.
Я один не представляю как это сопоставлять вообще?
Ты можешь читать заголовки с $_SERVER['HTTP...'], но получаешь тело только через общий стрим.
Отправил ты запрос на функцию Вверх, а у тебя тело на функцию Вниз пришло пока ты читаешь заголовок Вверх.
Можно отправлять конечно доп данные в теле, типа Object.header(), но зачем тогда нахер нужны эти заголовки вообще?
Это ты сейчас описал асинхронный PHP или что?
Тут в подавляющем большинстве случаев запрос - это один запуск скрипта. У тебя там физически невозможна ситуация, когда ты получишь заголовки и тело от разных запросов.
Ладно, погоди. мне надо подумать. Я слишком много информации скушал в последние дни, нужно все разложить по полочкам.
Основы программирования на хекслете + курс Лаврика + Кантор
> Ты можешь читать заголовки с $_SERVER['HTTP...'], но получаешь тело только через общий стрим.
По моему, ты что-то не понимаешь. Когда ты из браузера отправляешь HTTP-запрос, ты передаешь в запросе URL, заголовки, и тело запроса. Соответственно, PHP их разбирает, заголовки помещает в $_SERVER, а тело, если его удалось распарсить - в $_POST. Если же не удалось то тело можно прочитать через php://input.
Что значит "общий стрим"? Если ты подумал, что он общий для нескольких выполняющихся скриптов, то это не так - у каждого выполняющегося скрипта свой php://input.
> Пыха может получать несколько заголовков сразу.
> При этом она получает тела запроса отдельно.
HTTP-запрос состоит из первой строки, заголовков и тела. PHP получает запрос целиком (а не по частям). И соответственно, он может извлечь из него первую строку (она содержит метод, URL, версию HTTP), заголовки и тело. Это все отдельные части запроса.
Каждый HTTP-запрос обрабатывается отдельной копией скрипта. Если браузер пошлет 3 разных запроса, то на сервере будет запущено 3 копии скрипта, и каждый будет обрабатывать свой запрос.
Ты можешь почитать про устройство HTTP-запроса тут: https://github.com/codedokode/pasta/blob/master/network/http.md
Ты наверно плохо разобрался в них. Дженерики позволяют делать более строгую типизацию. Ну например, с помощью дженериков ты можешь сделать обобщенный класс Список, и его конкретные версии вроде Список Пользователей или Список Товаров. А как ты это сделаешь без дженериков?
Спасибо, конечно, за отличный пост, но я и так это знал. Недавно пару книжек прочитал.
А задал я вопрос потому что увидел на ночь глядя вопрос про это на стаковерфлоу при чем с адекватным обсуждеием уровня 'да не может, но это можно исправить балбла' и он меня как раз таки этим удивил, поэтому я не включая мозги просто скопировал вопрос сюда чтобы узнать положняк. Но походу я просто ошибся вопросом и там был вопрос про output, но это я уже не вспомню так все было в дрему.
Она не должна быть последней, она должна быть той, которая прописана в файле.
Лучше скажите мне нафига нужен докер и почему эта нех жрет 10гб непонятно чего. Я все порываюсь скачать так как слышу докер то, докер се. но думаю зачем он мне. Языки есть, вебсервера есть. делаешь приложухи и закидываешь на хостинги, код хранится на гите.
При чем тут докер - непонятно.
https://www.php.net/downloads.php#gpg-8.1
Не получится. Допустим, у тебя есть класс Список и метод "добавить в список объект". В базовом классе Список ты не знаешь, что он будет получать на вход, потому не можешь указать тип и пишешь:
class List {
function add($x) {}
}
Затем ты наследуешь от Списка класс Список Пользователей. В нем ты хочешь, чтобы в add() можно было передавать только объект класса User. Но как ты это сделаешь? Вручную переопределишь все методы класса Список и проставишь тайп-хинты? Не много ли работы?
Более того, так сделать ты не сможешь, так как ты нарушишь принцип Лисков (LSP). Если ты напишешь в наследнике
class ListOfUsers extends List {
function add(User $x) {}
}
то PHP выдаст ошибку из-за нарушения LSP, так как объект класса-наследника больше нельзя передать вместо предка. Подробнее можно узнать, погуглив про ковариантность и контрвариантность.
А в случае с дженериками все решается просто. Ты делаешь обобщенный класс Список объектов класса T:
class List<T> {
function add(T $x) {}
}
И затем можешь создавать объекты с указанием конкретного типа вместо T:
$listOfUsers = new List<User>;
Честно говоря, не понимаю, как предложенный тобой вариант решает проблему. Без дженериков наследование ты применить не можешь и тебе придется руками писать несколько классов с кучей копипасты.
Возможно, эта проблема как-то решается без дженериков, но я такого способа не знаю.
Не получится. Допустим, у тебя есть класс Список и метод "добавить в список объект". В базовом классе Список ты не знаешь, что он будет получать на вход, потому не можешь указать тип и пишешь:
class List {
function add($x) {}
}
Затем ты наследуешь от Списка класс Список Пользователей. В нем ты хочешь, чтобы в add() можно было передавать только объект класса User. Но как ты это сделаешь? Вручную переопределишь все методы класса Список и проставишь тайп-хинты? Не много ли работы?
Более того, так сделать ты не сможешь, так как ты нарушишь принцип Лисков (LSP). Если ты напишешь в наследнике
class ListOfUsers extends List {
function add(User $x) {}
}
то PHP выдаст ошибку из-за нарушения LSP, так как объект класса-наследника больше нельзя передать вместо предка. Подробнее можно узнать, погуглив про ковариантность и контрвариантность.
А в случае с дженериками все решается просто. Ты делаешь обобщенный класс Список объектов класса T:
class List<T> {
function add(T $x) {}
}
И затем можешь создавать объекты с указанием конкретного типа вместо T:
$listOfUsers = new List<User>;
Честно говоря, не понимаю, как предложенный тобой вариант решает проблему. Без дженериков наследование ты применить не можешь и тебе придется руками писать несколько классов с кучей копипасты.
Возможно, эта проблема как-то решается без дженериков, но я такого способа не знаю.
Да я нубас, просто строю теории. Даже не знаю что за дженерики, похоже на шаблоны классов из C++.
А что если проверять какого класса объект передали в функцию с помощью get_class()? И возвращать false или exception например, если не то, что требуется.
Докер это способ упаковать программу вместе со всеми ее зависимостями (на мой взгляд, обладающий кучей недостатков). Если ты хочешь, чтобы программа гарантированно работала одинаково у разных разработчиков, то для нее нужно сделать одинаковое окружение.
То есть, у тебя есть программа. Она включает в себя код на PHP, которому нужна строго определенная версия PHP с строго определенными расширениями (вроде curl или json), базу данных PostgreSQL тоже строго определенной версии и веб-сервер nginx (опять же строго определенной версии).
Ты хочешь чтобы у всех разработчиков и на продакшене была такая же среда.
Сделать это не так просто, так как в версии ОС у разработчика может не быть нужной версии PHP, а значит, его надо скачивать и собирать руками, тратя на это время. Более того, линукс обычно не позволяет поставить одновременно несколько разных версий PHP, а это нужно при работе над несколькими проектами. Более того, у разработчиков могут быть разные ОС (linux/windows например).
Одно из решений - это сделать виртуальную машину, в которую установлены все нужные программы, но она может получиться довольно громоздкой (файл размером в гигабайты), плюс надо заново ее создавать, чтобы например обновить версию PHP. Ну и неудобно в гитхаб коммитить гигабайтные образы.
Докер пытается решить проблему, как упаковать эти три программы вместе, чтобы другой разработчик мог у себя воссоздать такое же окружение. И решает (на мой взгляд) довольно неудачно.
Идея докера в том, что для каждой программы (PHP, PostgrSQL, nginx) ты создаешь изначально пустую паравиртуальную машину* с установленным в нее линуксом, и скрипт, который устанавливает в эту машину нужную программу. Например, для PHP этот скрипт выполняет установку PHP и всех нужных расширений.
Затем ты передаешь только эти скрипты и конфиги другому разработчику. Он запускает Докер, у него создаются три виртуальных машины, и в каждой из них выполняется скрипт установки, который устанавливает нужные программы.
В теории Докер можно использовать и для выгрузки приложения на продакшен. Сисадмин для установки программ на сервер больше не нужен.
Вот пример скрипта для Докера, который создает виртуальную машину с Debian и PHP: https://github.com/docker-library/php/blob/af4cd1a2184cb2026431cddb5377391d19728fd4/8.1/bullseye/cli/Dockerfile
Что мне не нравится:
- если посмотреть на скрипт выше, то он огромный и нечитабельный, набит костылями. В нем под сотню бекслешей. А ведь он всего лишь устанавливает PHP.
- для PHP официальные версии Докера поддерживают только версии 7.4, 8.0 и 8.1. Хотя на практике может понадобиться даже PHP5 для какого-нибудь старого проекта.
- Докер это огромный сложный демон, предоставляющий наружу API, запускаемый из-под рута. Если в нем есть ошибка, его права позволяют например стереть все содержимое жесткого диска. Если в API есть уязвимость, атакующий может захватить полный контроль над машиной.
- многие образы Докера работают из-под рута, пусть и в контейнере, но было бы безопаснее без рута.
- Под Windows и Mac Докер использует настоящую виртуальную машину, что снижает производительность
- Докер создает новый образ диска на каждый шаг скрипта установки. То есть, если твой скрипт состоит из 10 шагов, то Докер создаст на диске 11 образов: образ диска до запуска скрипта, образ диска после выполнения первого шага, после второго шага и т.д. Докер использует оптимизацию для хранения этих образов (новый образ не сохраняется целиком, а хранит лишь изменения в сравнении со старым образом), но все равно это должно приводить к использованию лишнего места на диске и ухудшению времени доступа.
Из-за этого скрипты обычно пишут так, чтобы вместить в одну строчку как можно больше действий и их тяжело читать.
- базовый образ, в который устанавливаются программы, зачастую не пустой, и содержит много лишнего. То есть ты хотел виртуальную машину только в PHP, а туда еще будет установлен bash, куча утилит и библиотек, это все занимает место.
- для компиляции нужно установить в каждую виртуальную машину компилятор и утилиты. Даже если их потом удалить, они остаются на диске из-за того, что Докер сохраняет изменения после каждого шага в скрипте. Из-за этого образы Докера занимают много места. Если у тебя все свободное место занято аниме, то сначала придется что-то удалить. И чем больше у тебя проектов, тем больше придется удалять.
В общем, Докер это типичное linux-style решение проблемы, когда вместо серьезного решения просто на скорую руку пишут костыльные shell-скрипты.
Как, на мой взгляд, было бы правильно решить проблему:
- исправить менеджеры пакетов ОС, чтобы они позволяли устанавливать программы локально без рута, а не в /usr/bin, и позволяли ставить много версий одной программы
- написать универсальный менеджер пакетов, поддерживающий (в идеале) не только линукс, а любую ОС, позволяющий устанавливать любую программу или библиотеку любой версии, без центрального репозитория. Что-то вроде composer, только для проектов на любом языке. То есть ты только указываешь где лежит код программы, и какая версия с какими опциями тебе нужна и все ставится автоматически. Ну если сложно сделать для всех ОС, то хотя бы для линукса.
То есть, для PHP программ есть композер и он отлично работает. А для Си ничего подобного нету. Вряд ли получится убедить всех использовать один и тот же менеджер пакетов, поэтому возможно нужен какой-то суперменеджер, который будет управлять обычными менеджерами. То есть, если программа состоит из PHP кода, JS и библиотеки на Раст, то суперменеджер должен установить PHP код с помощью композера, JS с помощью npm, а Раст с помощью Карго.
- разработать что-нибудь, чтобы легко было писать кроссплатформенные программы
Это сложный и долгий путь. А разработчики Докера хотят простой и быстрый.
____
* - я знаю, что Докер использует контейнеры, а не настоящую виртуализацию, но принцип работы от этого не меняется.
Докер это способ упаковать программу вместе со всеми ее зависимостями (на мой взгляд, обладающий кучей недостатков). Если ты хочешь, чтобы программа гарантированно работала одинаково у разных разработчиков, то для нее нужно сделать одинаковое окружение.
То есть, у тебя есть программа. Она включает в себя код на PHP, которому нужна строго определенная версия PHP с строго определенными расширениями (вроде curl или json), базу данных PostgreSQL тоже строго определенной версии и веб-сервер nginx (опять же строго определенной версии).
Ты хочешь чтобы у всех разработчиков и на продакшене была такая же среда.
Сделать это не так просто, так как в версии ОС у разработчика может не быть нужной версии PHP, а значит, его надо скачивать и собирать руками, тратя на это время. Более того, линукс обычно не позволяет поставить одновременно несколько разных версий PHP, а это нужно при работе над несколькими проектами. Более того, у разработчиков могут быть разные ОС (linux/windows например).
Одно из решений - это сделать виртуальную машину, в которую установлены все нужные программы, но она может получиться довольно громоздкой (файл размером в гигабайты), плюс надо заново ее создавать, чтобы например обновить версию PHP. Ну и неудобно в гитхаб коммитить гигабайтные образы.
Докер пытается решить проблему, как упаковать эти три программы вместе, чтобы другой разработчик мог у себя воссоздать такое же окружение. И решает (на мой взгляд) довольно неудачно.
Идея докера в том, что для каждой программы (PHP, PostgrSQL, nginx) ты создаешь изначально пустую паравиртуальную машину* с установленным в нее линуксом, и скрипт, который устанавливает в эту машину нужную программу. Например, для PHP этот скрипт выполняет установку PHP и всех нужных расширений.
Затем ты передаешь только эти скрипты и конфиги другому разработчику. Он запускает Докер, у него создаются три виртуальных машины, и в каждой из них выполняется скрипт установки, который устанавливает нужные программы.
В теории Докер можно использовать и для выгрузки приложения на продакшен. Сисадмин для установки программ на сервер больше не нужен.
Вот пример скрипта для Докера, который создает виртуальную машину с Debian и PHP: https://github.com/docker-library/php/blob/af4cd1a2184cb2026431cddb5377391d19728fd4/8.1/bullseye/cli/Dockerfile
Что мне не нравится:
- если посмотреть на скрипт выше, то он огромный и нечитабельный, набит костылями. В нем под сотню бекслешей. А ведь он всего лишь устанавливает PHP.
- для PHP официальные версии Докера поддерживают только версии 7.4, 8.0 и 8.1. Хотя на практике может понадобиться даже PHP5 для какого-нибудь старого проекта.
- Докер это огромный сложный демон, предоставляющий наружу API, запускаемый из-под рута. Если в нем есть ошибка, его права позволяют например стереть все содержимое жесткого диска. Если в API есть уязвимость, атакующий может захватить полный контроль над машиной.
- многие образы Докера работают из-под рута, пусть и в контейнере, но было бы безопаснее без рута.
- Под Windows и Mac Докер использует настоящую виртуальную машину, что снижает производительность
- Докер создает новый образ диска на каждый шаг скрипта установки. То есть, если твой скрипт состоит из 10 шагов, то Докер создаст на диске 11 образов: образ диска до запуска скрипта, образ диска после выполнения первого шага, после второго шага и т.д. Докер использует оптимизацию для хранения этих образов (новый образ не сохраняется целиком, а хранит лишь изменения в сравнении со старым образом), но все равно это должно приводить к использованию лишнего места на диске и ухудшению времени доступа.
Из-за этого скрипты обычно пишут так, чтобы вместить в одну строчку как можно больше действий и их тяжело читать.
- базовый образ, в который устанавливаются программы, зачастую не пустой, и содержит много лишнего. То есть ты хотел виртуальную машину только в PHP, а туда еще будет установлен bash, куча утилит и библиотек, это все занимает место.
- для компиляции нужно установить в каждую виртуальную машину компилятор и утилиты. Даже если их потом удалить, они остаются на диске из-за того, что Докер сохраняет изменения после каждого шага в скрипте. Из-за этого образы Докера занимают много места. Если у тебя все свободное место занято аниме, то сначала придется что-то удалить. И чем больше у тебя проектов, тем больше придется удалять.
В общем, Докер это типичное linux-style решение проблемы, когда вместо серьезного решения просто на скорую руку пишут костыльные shell-скрипты.
Как, на мой взгляд, было бы правильно решить проблему:
- исправить менеджеры пакетов ОС, чтобы они позволяли устанавливать программы локально без рута, а не в /usr/bin, и позволяли ставить много версий одной программы
- написать универсальный менеджер пакетов, поддерживающий (в идеале) не только линукс, а любую ОС, позволяющий устанавливать любую программу или библиотеку любой версии, без центрального репозитория. Что-то вроде composer, только для проектов на любом языке. То есть ты только указываешь где лежит код программы, и какая версия с какими опциями тебе нужна и все ставится автоматически. Ну если сложно сделать для всех ОС, то хотя бы для линукса.
То есть, для PHP программ есть композер и он отлично работает. А для Си ничего подобного нету. Вряд ли получится убедить всех использовать один и тот же менеджер пакетов, поэтому возможно нужен какой-то суперменеджер, который будет управлять обычными менеджерами. То есть, если программа состоит из PHP кода, JS и библиотеки на Раст, то суперменеджер должен установить PHP код с помощью композера, JS с помощью npm, а Раст с помощью Карго.
- разработать что-нибудь, чтобы легко было писать кроссплатформенные программы
Это сложный и долгий путь. А разработчики Докера хотят простой и быстрый.
____
* - я знаю, что Докер использует контейнеры, а не настоящую виртуализацию, но принцип работы от этого не меняется.
А, забыл про еще про пару проблем.
- хотя задача Докера создавать воспроизводимые образы, зачастую они не вопроизводимые. Потому что, например, образ может установить не конкретную версию ОС или программы, а latest. Соответственно, такой образ в любой момент может сломаться.
- в разных средах разная конфигурация, но Докер это никак не учитывает. На продакшене могут быть машины с 256 Гб памяти и кучей ядер, у тимлида макбук с 64 Гб, а у разработчика дохлый ноут с 8 Гб. И образ, рассчитанный на тимлида, не запустится у разработчика, а образ для продакшена не запустится даже у тимлида.
По идее, как я написал выше, должен быть универсальный менеджер пакетов (по аналогии с композером). То есть ты только пишешь install php 8.1, а он все делает сам. Пока такого не написали, придется помучиться.
Это в лишний раз напоминает, каким дремучим легаси-болотом является Си.
Это плохое решение, так как раздувает код, надо писать каждый раз эту лапшу, плюс IDE и статические анализаторы не смогут определить тип аргумента функции и делать подсказки и проверки.
Спрашивал не я, но спасибо, было интересно почитать, очень подробно описал всё
Да, VK - это SPA-приложение. API их бэкенда, кстати, открыт для использования, что позволяет даже написать свой клиент.
> все страницы
Контент - да, подгружается с бэка, а вот набор компонентов (страниц) и их вёрстка, определены во фронтенд-приложении.
Где используют брокеры сообщений?
Есть ли какие-нибудь паттерны при работе с ними?
Ну и вдогонку, есть ли паттерны работы с Redis? (читал про стратегии cache-aside и write-through, но как лучше именно организовать код обращения к редиске?)
Согласен
Перепощу из sql треда
Сап, аноны. Есть 5 mysql бэкапов, но при загрузке каждого руется на разную строку с ошибкой ERROR 1824 (HY000) at line 2: Failed to open the referenced table ИМЯ ТАБЛИЦЫ
Что ему нужно? Я не разбираюсь в БД
Открыл базу в воркбенче, удалил ключи по другим таблицам. Там всего одна таблица грузилась на каждый бэкап. Все заработало.
Ну поработать с ним. Интегрируй кролика в тот же ларавель, сделай условный CRUD с записями, сделай в кролике пару очередей, и шли реквесты, обрабатываешь только не через ожидание ответа с результатом, а через очередь.
Пару команд можешь написать, напихай их в очередь и наблюдай как паралельно выполняются.
Загуглить не пробовал? В линуксе всё ставится через sudo apt-get install package. Для 8.1 возможно надо репу с этой версией подключить ещё перед этим.
Потому и говорю что линукс ставьте и изучайте, вы ж нулевые вообще в серверных вещах, как вы бэкендером собираетесь работать? Даже программу установить не можешь.
Говнище этот докер, всё руками собираю, всё быстро и легко поднимается, если не 100500 микросервисов.
Для докера надо девопс, который будет этим говном заниматься и поддерживать, иначе ад с ошибками и ужасами. Ещё докер засирает систему и может билдится целый час. Ещё докер отучивает разрабов от навыков пользования линуксом.
Анон, как можно скачать весь репозиторий packagist?
~338'000 пакетов https://packagist.org/explore/popular ?
Можно создать парсер, чтобы он постранично открывал страницы и скачивал строку из html страницы ,объекта "input" с адресом установки библиотеки типа "composer require symfony/process" с занесением в txt файл, а потом скачать все-все через composer? Вообще логично ли так скачивать все это в одну папку, дальше с подключением к проекту не возникнет проблем?
или лучше качать zip архивы с github(практически нереально)
Я никогда не пользовался composer и не знаю php(пока учу html/js), но хочу сохранить все паки себе на жесткий диск, репозиторий сайта packagist с github у меня есть, а самих библиотек там нет. Подскажи радихриста , что делать
Очереди событий используют в нескольких случаях:
1) организация очереди задач. Например, ты хочешь при сохранении статьи в админке перестраивать топ статей. Но это занимает много времени и из-за этого админка работает медленно. Ты можешь при сохранении статьи просто отправлять событие в очередь, а фоновый воркер подберет это событие и перестроит топ статей в фоне.
Или еще примеры: ты решил сделать клон Ютуба. При загрузке видео надо его конвертировать в нужный формат, но этот процесс занимает несколько минут. Опять же, очередь задач тут решает проблему.
2) сглаживание нагрузки. Допустим, у тебя на сайте есть какой-то действие, которое не очень быстро работает, и когда много пользователей его совершают, сайт начинает тормозить. Например, загрузка картинок с конвертацией. Можно использовать тут очередь задач и размазать нагрузку более равномерно.
3) взаимодействие между несколькими системами. Допустим, ты перешел от разработки простых сайтов к разработке сложных взаимодействующих систем. Пользователь создает заявку в одной системе, она передается для обработки в другую систему. Тут опять же будет полезна очередь задач, которая гарантирует сохранность сообщений даже при аварии питания.
Если ты на практике не используешь RabbitMQ, то в резюме ты можешь написать только про знакомство с ним. Я бы советовал прочесть документацию, разобраться в особенностях его работы и после этого упоминать в резюме.
Что касается редиса, то тут паттернов немного. Кроме cache-aside и write-through есть еще вариант, когда кеш перегенерируется по крону, например раз в час. Знать, конечно, надо не только названия паттернов, а плюсы и минусы.
В редисе есть различные структуры (хеш-таблицы, множества, списки), их стоит изучить.
Вот тебе пример задачи на использование редиса или очередей задач: допустим, у нас есть сайт, на котором происходит 1000 просмотров страниц в секунду. Мы хотим считать число просмотров (или даже лучше, число разных пользователей, просмотревших страницу) для каждой страницы. Самое простое решение - просто увеличивать счетчик в БД, но это приведет к нагрузке в виде 1000 транзакций в секунду и это неэффективно. Например, если за минуту 1000 человек просмотрело одну и ту же страницу, мы сделаем 1000 увеличений счетчика, хотя могли бы вместо этого накапливать такие просмотры и позже увеличивать счетчик в БД сразу на 1000.
Придумай и реализуй схему подсчета просмотров, которая с одной стороны, сразу показывает реальное число просмотров без задержки, с другой стороны, накапливает просмотры и периодически обновляет базу данных.
Очереди событий используют в нескольких случаях:
1) организация очереди задач. Например, ты хочешь при сохранении статьи в админке перестраивать топ статей. Но это занимает много времени и из-за этого админка работает медленно. Ты можешь при сохранении статьи просто отправлять событие в очередь, а фоновый воркер подберет это событие и перестроит топ статей в фоне.
Или еще примеры: ты решил сделать клон Ютуба. При загрузке видео надо его конвертировать в нужный формат, но этот процесс занимает несколько минут. Опять же, очередь задач тут решает проблему.
2) сглаживание нагрузки. Допустим, у тебя на сайте есть какой-то действие, которое не очень быстро работает, и когда много пользователей его совершают, сайт начинает тормозить. Например, загрузка картинок с конвертацией. Можно использовать тут очередь задач и размазать нагрузку более равномерно.
3) взаимодействие между несколькими системами. Допустим, ты перешел от разработки простых сайтов к разработке сложных взаимодействующих систем. Пользователь создает заявку в одной системе, она передается для обработки в другую систему. Тут опять же будет полезна очередь задач, которая гарантирует сохранность сообщений даже при аварии питания.
Если ты на практике не используешь RabbitMQ, то в резюме ты можешь написать только про знакомство с ним. Я бы советовал прочесть документацию, разобраться в особенностях его работы и после этого упоминать в резюме.
Что касается редиса, то тут паттернов немного. Кроме cache-aside и write-through есть еще вариант, когда кеш перегенерируется по крону, например раз в час. Знать, конечно, надо не только названия паттернов, а плюсы и минусы.
В редисе есть различные структуры (хеш-таблицы, множества, списки), их стоит изучить.
Вот тебе пример задачи на использование редиса или очередей задач: допустим, у нас есть сайт, на котором происходит 1000 просмотров страниц в секунду. Мы хотим считать число просмотров (или даже лучше, число разных пользователей, просмотревших страницу) для каждой страницы. Самое простое решение - просто увеличивать счетчик в БД, но это приведет к нагрузке в виде 1000 транзакций в секунду и это неэффективно. Например, если за минуту 1000 человек просмотрело одну и ту же страницу, мы сделаем 1000 увеличений счетчика, хотя могли бы вместо этого накапливать такие просмотры и позже увеличивать счетчик в БД сразу на 1000.
Придумай и реализуй схему подсчета просмотров, которая с одной стороны, сразу показывает реальное число просмотров без задержки, с другой стороны, накапливает просмотры и периодически обновляет базу данных.
Как я понимаю, репозиторий packagist хранит только метаданные - информацию о пакете, но не сами архивы с кодом. Парсить HTML не нужно? есть API.
Тут https://packagist.org/mirrors предлагается утилита https://github.com/Webysther/packagist-mirror которая, как я понял, скачивает информацию о всех пакетах.
Также, тут есть API https://packagist.org/apidoc и в нем есть URL для получения списка всех пакетов: https://packagist.org/packages/list.json - далее, имея список ты можешь получить информацию о них с помощью API https://packagist.org/packages/[vendor]/[package].json а там уже есть ссылки на архивы или репозитории.
Обрати внимание, что пакеты могут быть в разных форматах: некоторые в виде zip архива, некоторые в виде git репозитория, который надо клонировать и сделать checkout определенной версии или ревизии.
Клонировать репозиторий может быть выгоднее, так как это зачастую позволяет получить все версии пакета (если репозиторий не менялся), а в случае с архивами их надо скачивать по одному.
Вот пример из описания пакета symfony/cache версии 6.0.6:
"source": {
"url": "https://github.com/symfony/cache.git",
"type": "git",
"reference": "57faad4e0d694f9961f517fdd5e6fbb1f6d0e04f"
},
"dist": {
"url": "https://api.github.com/repos/symfony/cache/zipball/57faad4e0d694f9961f517fdd5e6fbb1f6d0e04f",
"type": "zip",
"shasum": "",
"reference": "57faad4e0d694f9961f517fdd5e6fbb1f6d0e04f"
},
Тут есть два варианта скачивания: как git репозиторий или как zip архив.
Увы, архивы находятся на гитхабе, а у него есть ограничение на число загрузок с одного IP. Потому логично не качать все подряд, а, например, качать самые популярные пакеты в первую очередь. Если качать не анонимно, а из-под логина, то ограничение чуть повыше:
> https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting
> User-to-server requests are limited to 5,000 requests per hour and per authenticated user.
> For unauthenticated requests, the rate limit allows for up to 60 requests per hour. Unauthenticated requests are associated with the originating IP address, and not the person making requests.
При скачивании не создавай излишнюю нагрузку на сервера и скачивай пакеты последовательно, а не параллельно. Если получаешь ошибку, то остановись и разберись в чем дело, а не повторяй запросы.
У композера есть команда archive https://getcomposer.org/doc/03-cli.md#archive, может она как-то пригодится.
Как я понимаю, репозиторий packagist хранит только метаданные - информацию о пакете, но не сами архивы с кодом. Парсить HTML не нужно? есть API.
Тут https://packagist.org/mirrors предлагается утилита https://github.com/Webysther/packagist-mirror которая, как я понял, скачивает информацию о всех пакетах.
Также, тут есть API https://packagist.org/apidoc и в нем есть URL для получения списка всех пакетов: https://packagist.org/packages/list.json - далее, имея список ты можешь получить информацию о них с помощью API https://packagist.org/packages/[vendor]/[package].json а там уже есть ссылки на архивы или репозитории.
Обрати внимание, что пакеты могут быть в разных форматах: некоторые в виде zip архива, некоторые в виде git репозитория, который надо клонировать и сделать checkout определенной версии или ревизии.
Клонировать репозиторий может быть выгоднее, так как это зачастую позволяет получить все версии пакета (если репозиторий не менялся), а в случае с архивами их надо скачивать по одному.
Вот пример из описания пакета symfony/cache версии 6.0.6:
"source": {
"url": "https://github.com/symfony/cache.git",
"type": "git",
"reference": "57faad4e0d694f9961f517fdd5e6fbb1f6d0e04f"
},
"dist": {
"url": "https://api.github.com/repos/symfony/cache/zipball/57faad4e0d694f9961f517fdd5e6fbb1f6d0e04f",
"type": "zip",
"shasum": "",
"reference": "57faad4e0d694f9961f517fdd5e6fbb1f6d0e04f"
},
Тут есть два варианта скачивания: как git репозиторий или как zip архив.
Увы, архивы находятся на гитхабе, а у него есть ограничение на число загрузок с одного IP. Потому логично не качать все подряд, а, например, качать самые популярные пакеты в первую очередь. Если качать не анонимно, а из-под логина, то ограничение чуть повыше:
> https://docs.github.com/en/rest/overview/resources-in-the-rest-api#rate-limiting
> User-to-server requests are limited to 5,000 requests per hour and per authenticated user.
> For unauthenticated requests, the rate limit allows for up to 60 requests per hour. Unauthenticated requests are associated with the originating IP address, and not the person making requests.
При скачивании не создавай излишнюю нагрузку на сервера и скачивай пакеты последовательно, а не параллельно. Если получаешь ошибку, то остановись и разберись в чем дело, а не повторяй запросы.
У композера есть команда archive https://getcomposer.org/doc/03-cli.md#archive, может она как-то пригодится.
Если предположить, что клонирование репозитория с гитхаба тратит один запрос, то ты можешь за час клонировать 5000 репозиториев, за сутки ~100 000 и скачать все пакеты за ~4 суток. Вполне реалистично.
Хочу какую-нибудь базу почитать по php, sql, laravel перед собесом
интересует что-то вроде: "вопросы для джуна 2022 год список 500 вопросов"
>Хочу какую-нибудь базу почитать по php, sql, laravel перед собесом
Надо не базу читать, а иметь пару-тройку проектов разной сложности на нём для демонстрации. Любой нормальный работодатель захочет посмотреть на твой код, а то народ сильно ебанутый бывает - ничего реально не умеет, но в уши срать мастер.
Блин, это я, читаю все подряд, а практики 0.
В главе о шаблонах из шапки не понял место про "умника" зачем первая строка если потом все равно переменная эта перезаписывается?
$tpl = file_get_contents('template.html');
$tpl = super_mega_template_engine( array('result' => $result) );
echo $tpl;
Алсо что из себя представляет эта шаблонизаторская функция.
Понимаю, у меня есть 3 проекта: блог, url shortener, wheather app. Но ведь вопросы будут задавать, хочу подготовиться хотя бы немного. А то сходу не смогу ответить, даже если знаю
Если писал приложухи, то должен знать ответы на все вопросы для джуна. Тут суть не в том, чтобы попасть на работу к первому попавшемуся работодателю, ответив на все его вопрося, а в том, чтобы найти адекватного работодателя который не будет тебе экзамен на собеседовании устраивать и понимает твой уровень.
Просто учти, что 80% джунов сегодня на том же хх это по факту мидлы по знаниям. Поэтому не парься сильно насчёт неадекватов к которым не подошёл - тут чистый рандом.
>80% джунов сегодня на том же хх это по факту мидлы по знаниям
Но их все равно не берут при этом, как я понимаю? Рынок перенасыщен специалистами или это только пхп/web сегмент?
Что ты понимаешь под базовыми? Везде база разная. Ты либо что-то умеешь, либо нет.
>>331857
Вопросы задаются элементарные, если ты запустил фреймворк то не ответить на эти вопросы не сможешь, фейспалм.
>>331907
Откуда вы такие лезете, зачем такое задавать в пыхыпы треде, иди в б лучше платиновые треды про айти задавай если тебе из пустого в порожнее хочется переливать.
Зачем ты вообще пыхыпы учил и делал приложухи если задаешь такие тупые вопросы, у меня аж мигрень от такого аутизма. Если мы тебе скажем что пыхыпы не нужен и рынок перенасыщен то ты что? В пяторочку пойдешь работать? Пойдешь учить хакскел?? Что ты ожидаешь вообще услышать????
Да я не тот анон, просто вклинился с вопросом. Чего так нервничать? Мог бы ничего и не отвечать, если нечего сказать.
>Рынок перенасыщен специалистами или это только пхп/web сегмент?
Да хороший спец себе работу всегда найдёт. Такие вопросыне про разработку как бы - так можно про любую профессию сказать. Везде всё перенасыщено, но теми, кто даром никому не нужен, а к нормальным очереди.
То, что там какой-то работодатель губу раскатал - так это его личное дело. Хотеть он чего угодно может, но будет вынужден выбирать из тех, кто к нему пойдёт. Просто учти, что на джуниора никакой опытный не пойдёт и исходи из этого, а что там понаписали из требований - побоку.
Там левый какой-то.
Окей, всем спасибо за ответы. Просто не был на собесах, даже и не знаю чего ожидать
В open server править конфиги надо не в ручную, а через него самого (правый клик - дополнительно - конфигурация - пхп).
править php.ini я могу, как ты говоришь через сам onep server, без ручных вмешательств. Но вопрос в другом, как поменять локальные конфигурации, ибо в файле .htaccess, в котором например хочу выключить display_startup_errors off , ставя значение off, то меняется не нужный php.ini . то есть мои конфигурации не пименяются, а идут лесом. Вот и вопрос, как все же для phpinfo сделать путь к верному php.ini, чтобы я могу делать не только мастер изменения, но и локальные, через .htaccess
Не надо ничего менять вручную в php.ini опен сервера. Проблема в твоем htaccess, ты уверен что там не .txt файл на самом деле?
уже решили, что рукаим я ничего не меняю. только глобально, через пкм -> дополнительно -> конфигурация -> PHP.
Но вот при добавлении файла .htaccess никаких локальных изменений не происходит, а вносит изменения в совсем другой php.ini :(( уже целый день пытаюсь решить в чем проблема, такого раньше не было просто на просто.
расширение указываю .htaccess не txt, он менят не для корневого php.ini в этом и трабл
решил проблему тем, что поменял apach на 2.2 5.2 -5.4
В phpinfo так и должно быть что указан тот "временный" php.ini.
Проверь, нет ли в файле htaccess BOM'ов.
Алсо ты точно уверен, что он не работает? Добавь в него какую-нибудь настройку более заметную типа аутентификации.
Сегодня про Украину, а завтра блокировать или просто напросто гадить начнут всем неугодным. Уже встречал предупреждение не использовать композер во избежание возможных вредоносных действий с их стороны.
Опенсорс кончается сегодня, пыхари.
Так такое везде, со всеми технологиями. плашки блм где только не висели раньше. Обычный пиар, вряд ли кто захочет видеть гнев русских хакиров.
Всё, разобрался
Нет, это в первую очередь большая проблема безопасности. Одно дело когда ты пет себе пишешь и совсем другое когда там какой-то прод, который вы всей бандой полгода писали и потом год ещё тащили пока не завелось.
И речь, наверное, здесь даже не о самом композере, а о опенсорсе в его сегодняшнем виде когда любой промытый в какую-то сторону может начать истерить и сделать всем нам огромную подлянку.
Макак спок. Будешь зато работой обеспечен, каждый год переписывать одно и тоже из пустого в пороженее. Плохо чтоли? Охуенно
> Но вот при добавлении файла .htaccess никаких локальных изменений не происходит
Настройки из htaccess могут не применяться, если это не разрешено в основном конфиге Апача директивами вроде AllowOverride и AllowOverrideList: https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride
Это проблема работает в обе стороны - никто не мешает делать опенсорс, а потом специально паскудить, воруя данные.
Ты долбоёб, если не понимаешь масштаба проблемы. Попенсорс превращается в помойку.
Проблема атак на цепь поставки реальна. То, что пакет выводит сообщение, конечно никакой угрозы не представляет, а вот если злоумышленник внедрит бекдор, это будет хуже. Причем не надо думать, что бекдор обязательно будет чем-то явно заметным вроде if (...) eval() или блоком кода закодированным в base64. Бекдор может быть сделан гораздо более тонко, я помню, в Линукс кто-то давно встроил бекдор, поменяв всего несколько символов в коде проверки прав пользователя.
Ты можешь защищаться от нее разными способами:
- сделать список доверенных авторов и ставить пакеты только от них
- проводить ревизию зависимостей вручную или вместе со статическим анализом
- или объединиться с другими разработчиками и совместно проводить ревизию
- или заплатить тем, кто это будет делать. Тут ты опять же опираешься на доверие к этим людям.
- или создать компанию, которая будет это делать и стать богатым (но это не точно)
Анон, не могу осилить пока что это. Я готов заплатить(а можно позвать кого нибудь еще), может обсудим это? @johnnyenn - tg.
Я так понял можно скачать сразу версии github и zip? через composer можно просто же устанавливать со своего локального источника эти пакеты если они грамотно будут распределены по каталогам?
Мы же сути без работы останемся, если его прикроют каким либо образом. Github в рф был первым заблокированным сервисом если помнишь, и сколько шумихи удалось поднять в соцсетях, его отбили можно сказать - а сейчас кто будет бороться? php на ру-площадке видимо останется надолго, может стоит задуматься о хранении пакетов? Создать torrent и раздавать к примеру можно, на rutracker/nnm повесить раздачу, чтобы можно было и новичков и опытных посылать для скачки туда.(я не из рф, но сделал например много рипов сайтов с мануалами для себя, рипы всех раздач торрентов имею на всякий случай, википедию на флешке и архив передач почти целого телеканала имею, незнаю может это болезнь лол) Мне php нравится, я считаю что он наиболее близок к настоящему функционалу настоящего сайта - не имеет ничего лишнего, все логично. Будет обидно остаться без него.
Анончик, ты молодец, полезным делом занялся.
Кто-то может конкретно назвать?
Часов 200-300, чтобы уверенно знать что к чему
На удаленочку вакансия
анон, подумай хорошо. я понимаю что ето труд скопипастить все пакеты, но это один из важнейших ресурсов для php. Но если можно скопом взять их, может сделать это пока не поздно? Кстати на packagist-mirror как ни странно, упоминания RU вообще нет, мы можем одни в большой лодке оказаться если инеты перекроют от них или у нас. Так-то можно будет кабанчикам делать сайты или кому нибудь еще.
Структуры данных - это способ хранения данных в памяти (или файле). Компьютерная память состоит из пронумерованных подряд ячеек, каждая из которых хранит один байт (число от 0 до 255). Соответственно, структуры данных - это способ, как хранить какие-то данные.
Тебе наверно ничего не понятно из определения выше, потому давай дам пример. Например, у нас есть список из N чисел, каждое число может быть от 0 до 99. Как их хранить в памяти?
Первая структура данных, которая приходит в голову, это Array List, который иногда называют вектором или просто массивом, или просто списком. Это когда мы просто храним числа подряд, начиная с какой-то ячейки. Например, у нас есть 1000 чисел, и мы храним их в ячейках с 5000 по 5999. Так как числа у нас от 0 до 99, то для хранения одного числа достаточно одной ячейки. Если бы числа были больше, мы бы выделили по несколько ячеек на каждое число.
Каждая структура данных имеет как плюсы, так и минусы. Плюс array list - это то, что он просто устроен, и он позволяет очень быстро находить число по номеру. Допустим, мы хотим найти элемент с номером 300 (считая с нуля) из списка, который хранится в памяти начиная с ячейки 5000. В этом случае мы складываем 5000 + 300 и получаем адрес 5300, где и хранится 300-й (считая с нуля) элемент.
Но у такого списка есть и минусы. Представим, что у нас есть список из миллиона чисел и нам надо вставить одно число в середину списка. Для этого нам придется переместить 500 000 идущих за ним чисел на одну ячейку дальше. То есть, в array list вставка значений в середину или их удаление выполняется медленно. Есть другие структуры данных, которые решают эту проблему (но у них тоже есть свои минусы).
Пример такой структуры это linked list (односвязный список). Он устроен таким образом: список состоит из узлов (node) (на каждый элемент списка делается один узел). То есть, если у нас в списке 100 чисел, то он состоит из 100 узлов.
Каждый узел это пара из двух значений: число, и "указатель" на следующий узел. Указатель - это адрес (номер) ячейки, начиная с которой хранится следующий узел. Ну например, пусть первый узел находится по адресу 5000 и содержит число 10, второй по адресу 7000 и содержит число 20, а третий по адресу 6000 и содержит число 30. Тогда в памяти хранятся такие данные:
По адресу 5000 хранится первый элемент списка - число 10
По адресам 5001-5008 хранится адрес следующего узла - число 7000 (мы используем 8 ячеек, так как адреса ячеек в 64-битных системах могут быть очень большими).
По адресу 6000 хранится третий элемент списка - число 30
По адресам 6001-6008 хранится 0 - это признак того, что больше узлов нету.
По адресу 7000 хранится второй элемент списка - число 20
По адресам 7001-7008 хранится указатель на третий узел - число 6000.
В такой структуре, чтобы добавить элемент в середину списка, нам ничего не надо перемещать, достаточно лишь поменять один указатель.
У array list есть и другие минусы. Например, мы хотим узнать, есть ли в списке число 5. Единственный способ определить это - это прочитать все элементы по очереди и сравнить с 5. Это тоже не очень быстро, если список большой, и есть структуры данных, которые позволяют быстро делать такие проверки.
Выше я привел пример структуры данных для хранения данных в памяти. Но есть еще структуры данных, предназначенные для хранения данных в файле, которые, например позволяют минимизировать число изменяемых блоков в файле при изменении данных (чтобы не пересоздавать весь файл, а поменять в нем только небольшой кусочек). Такие структуры используются, например, в базах данных. Отличие файла от памяти в том, что в памяти мы можем мгновенно обратиться к любой ячейке, а в файле мы должны сначала загрузить блок в память, чтобы что-то прочитать или поменять.
В общем, самые распространенные структуры данных это array list, linked list, doubly linked list, stack, hash table, set, tree, binary tree, red-black tree, graph.
Что касается PHP, это высокоуровневый язык и в нем никто напрямую не работает с ячейками памяти. Вместо этого используют уже готовые реализации структур данных - например: стандартный PHP-массив (который объединяет в себе хеш-таблицу и doubly linked list), одно/двухсвязные списки из Spl, множества.
Если ты не знаешь структур данных, то ты можешь выбрать неэффективный способ хранения данных и программа будет работать медленно или потреблять много памяти на больших объемах данных.
Что касается алгоритмов, то, думаю, имеются в виду алгоритмы для работы с этими структурами. Например, у тебя есть граф, и ты хочешь определить, есть ли в нем циклы. Для этого есть готовый алгоритм. Или ты хочешь добавить узел в красно-черное дерево, опять же, есть готовый алгоритм.
Структуры данных - это способ хранения данных в памяти (или файле). Компьютерная память состоит из пронумерованных подряд ячеек, каждая из которых хранит один байт (число от 0 до 255). Соответственно, структуры данных - это способ, как хранить какие-то данные.
Тебе наверно ничего не понятно из определения выше, потому давай дам пример. Например, у нас есть список из N чисел, каждое число может быть от 0 до 99. Как их хранить в памяти?
Первая структура данных, которая приходит в голову, это Array List, который иногда называют вектором или просто массивом, или просто списком. Это когда мы просто храним числа подряд, начиная с какой-то ячейки. Например, у нас есть 1000 чисел, и мы храним их в ячейках с 5000 по 5999. Так как числа у нас от 0 до 99, то для хранения одного числа достаточно одной ячейки. Если бы числа были больше, мы бы выделили по несколько ячеек на каждое число.
Каждая структура данных имеет как плюсы, так и минусы. Плюс array list - это то, что он просто устроен, и он позволяет очень быстро находить число по номеру. Допустим, мы хотим найти элемент с номером 300 (считая с нуля) из списка, который хранится в памяти начиная с ячейки 5000. В этом случае мы складываем 5000 + 300 и получаем адрес 5300, где и хранится 300-й (считая с нуля) элемент.
Но у такого списка есть и минусы. Представим, что у нас есть список из миллиона чисел и нам надо вставить одно число в середину списка. Для этого нам придется переместить 500 000 идущих за ним чисел на одну ячейку дальше. То есть, в array list вставка значений в середину или их удаление выполняется медленно. Есть другие структуры данных, которые решают эту проблему (но у них тоже есть свои минусы).
Пример такой структуры это linked list (односвязный список). Он устроен таким образом: список состоит из узлов (node) (на каждый элемент списка делается один узел). То есть, если у нас в списке 100 чисел, то он состоит из 100 узлов.
Каждый узел это пара из двух значений: число, и "указатель" на следующий узел. Указатель - это адрес (номер) ячейки, начиная с которой хранится следующий узел. Ну например, пусть первый узел находится по адресу 5000 и содержит число 10, второй по адресу 7000 и содержит число 20, а третий по адресу 6000 и содержит число 30. Тогда в памяти хранятся такие данные:
По адресу 5000 хранится первый элемент списка - число 10
По адресам 5001-5008 хранится адрес следующего узла - число 7000 (мы используем 8 ячеек, так как адреса ячеек в 64-битных системах могут быть очень большими).
По адресу 6000 хранится третий элемент списка - число 30
По адресам 6001-6008 хранится 0 - это признак того, что больше узлов нету.
По адресу 7000 хранится второй элемент списка - число 20
По адресам 7001-7008 хранится указатель на третий узел - число 6000.
В такой структуре, чтобы добавить элемент в середину списка, нам ничего не надо перемещать, достаточно лишь поменять один указатель.
У array list есть и другие минусы. Например, мы хотим узнать, есть ли в списке число 5. Единственный способ определить это - это прочитать все элементы по очереди и сравнить с 5. Это тоже не очень быстро, если список большой, и есть структуры данных, которые позволяют быстро делать такие проверки.
Выше я привел пример структуры данных для хранения данных в памяти. Но есть еще структуры данных, предназначенные для хранения данных в файле, которые, например позволяют минимизировать число изменяемых блоков в файле при изменении данных (чтобы не пересоздавать весь файл, а поменять в нем только небольшой кусочек). Такие структуры используются, например, в базах данных. Отличие файла от памяти в том, что в памяти мы можем мгновенно обратиться к любой ячейке, а в файле мы должны сначала загрузить блок в память, чтобы что-то прочитать или поменять.
В общем, самые распространенные структуры данных это array list, linked list, doubly linked list, stack, hash table, set, tree, binary tree, red-black tree, graph.
Что касается PHP, это высокоуровневый язык и в нем никто напрямую не работает с ячейками памяти. Вместо этого используют уже готовые реализации структур данных - например: стандартный PHP-массив (который объединяет в себе хеш-таблицу и doubly linked list), одно/двухсвязные списки из Spl, множества.
Если ты не знаешь структур данных, то ты можешь выбрать неэффективный способ хранения данных и программа будет работать медленно или потреблять много памяти на больших объемах данных.
Что касается алгоритмов, то, думаю, имеются в виду алгоритмы для работы с этими структурами. Например, у тебя есть граф, и ты хочешь определить, есть ли в нем циклы. Для этого есть готовый алгоритм. Или ты хочешь добавить узел в красно-черное дерево, опять же, есть готовый алгоритм.
Если не можешь осилить, то надо не спешить и постепенно разбираться. Не понимаешь, что такое JSON? Изучи. Не понимаешь, что такое API и как отправлять запросы? Изучи. Не понимаешь, как клонировать репозиторий? Изучи git. И так далее.
Если у тебя есть конкретные вопросы (я прочитал X, но не понял что такое Y), то задавай.
Увы, ты себе придумал задачу, которая за пару часов не решается.
Я не вижу особого смысла скачивать релизы (zip-архивы). Надо клонировать репозитории. Репозиторий содержит полную историю изменений библиотеки, то есть все ее версии. А zip-архив только одну версию. Какой смысл качать 100 архивов, если их можно заменить одним репозиторием?
Что касается поднятия локальной копии packagist, то это возможно, но я бы начал с копирования данных. А потом уже не спеша можно разбираться, как их использовать.
Смысл от локального packagist вообще? Взять один из опенсорсных подходящих для селфхоста код-хостингов на основе гита и просто на него с гитхаба спиздить все что нужно.
https://gitea.io/ru-ru/ - это, например
https://about.gitlab.com/install/ ну или классика
Потом уже кому надо разберутся с packagist. Ну или так как в случае отъебывания пакагиста и композера композером по понятным причинам больше не попользуешься, то просто на скорую руку напишут всратый пакетный менеджер для подтягивания либ прямо с этого нового гит-хостинга, как это работает в го.
Я понимаю что это значит, я спрашивал какие конкретно структуры данных и алгоритмы относятся к основным, но твоё объяснение все равно прочитал с кайфом
Массив, односвязный и двусвязный список, стек и очередь, рекурсия (в т.ч. хвостовая), бинарный поиск, сортировки (bubble, merge, quick, count, radix), бинарные деревья, BFS и DFS, префиксное дерево, графы (в т.ч. способы их хранения в коде), алгоритмы Прима и Дейкстры, бинарная куча, хэш-таблицы (в т.ч. метод цепочек и открытая адресация), знать асимптотическую сложность всего перечисленного выше. (Это стандартный курс универа по алгоритмам)
Могу посоветовать книгу Роберта Лафоре. Есть ещё "Грокаем алгоритмы" от Бхаргавы, но она для новичков совсем, но читается гораздо интереснее и иллюстрирована. Хороший сайт у ИТМО по алгоритмам, но там много редкоиспользуемых.
*с запросом все нормально
public function sender(){
try{
require_once ('database.php');
$data=$pdo->prepare("INSERT INTO student(`name`,`sername`,`otec`,`email`,`sum`,`ft`,`st`,`tt`,`direction`,`password`) VALUES ($this->name,$this->sername,$this->otec,$this->email,$this->sum,$this->ft,$this->st,$this->tt,$this->direction,$this->password)");
$data->execute();
header('Location:list.php');
}catch (PDOException $e){
$e->getMessage();
}
}
код(да говнокод и что )
Могу ошибаться, но по дефолту PDO не выбрасывает исключений, чтобы их включить, сразу после создания объекта $pdo выполни:
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
Ну и да, попробуй посмотреть логи БД, если запрос завершается неудачно, там точно должно что-то отобразиться.
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@yandex.ru,290,РусскийЯзык,Математика,ИнформатикÐ' at line 1
а вот это как пофиксить можно ? я ввожу адрес почты/сумму баллов/3 предмета и почему-то на слове Информатика А проебывает кодировку
INSERT INTO student(`name`,`sername`,`otec`,`email`,`sum`,`ft`,`st`,`tt`,`direction`,`password`) VALUES (`$this->name`,`$this->sername`,`$this->otec`,`$this->mail`,`$this->sum`,`$this->ft`,`$this->st`,`$this->tt`,`$this->direction`,`$this->password
Ой, >>235503, типо этого
Проверь свою бд через phpmyadmin или какая у тебя там тулза. Может не тот тип данных или ограничение по числу байт слишком жесткое(у varchar там число байт, а не символов в качестве параметра).
Ааа, байт блять. Всё понял принял, спасибо
>Нет. Когда-то пытался решать задачки ОПа, но они не очень комфортные.
ОП-хуй очень постарался оттолкнуть от изучения языка как можно больше людей, ему нужно медаль выдать за диверсионные действия.
Почему? Он помогает всегда с подробными ответами, это буквально противоположное отталкиванию.
Как бы ты поменял учебные материалы тогда?
Нахуя давать задачи на алгоритмы и при этом сразу не показывать алгоритм и не объяснять его суть? Мне он один раз так помог, я уже ~год не притрагиваюсь к изучению.
Да я тоже приуныл когда не осилил рекурсивный поиск пути, но с другой стороны может это сигнал, что не стоит и лезть туда, если ума нет.
Это сигнал, что ОП - хуй. Там и до поиска пути никаких объяснений нет.
вот такая бд,поменял запрос и получаю такую ошибку
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '@yandex.ru,290,ИВТ,9b04d152845ec0a378394003c96da594)' at line 1
сам запрос
INSERT INTO student(`name`,`sername`,`otec`,`email`,`sum`,`direction`,`password`) VALUES ($this->name,$this->sername,$this->otec,$this->mail,$this->sum,$this->direction,$this->password)
и пик 2 форма
ошибка решилась
VALUES ($this->name,$this->sername,$this->otec,$this->mail,$this->sum,$this->direction,$this->password)
должно быть
VALUES ('$this->name','$this->sername','$this->otec','$this->mail','$this->sum','$this->direction','$this->password')
кто-нибудь может пояснить почему их надо брать в апострофы ?
В mysql такой синтаксис, вот например если в phpmyadmin добавлять записи они будут записаны вот так. Я забыл про это когда выше сказал, что не нужны кавычки, т.к. подготовленными запросами пользуюсь, там не надо кавычки.
https://www.php.net/manual/ru/pdo.prepared-statements.php
так у меня тоже подготовленный запрос,но без апострофов он выдает ошибку
У тебя там нет плейсхолдеров типа :name или ?, которые ты привязываешь к переменным своим. Там нечему подготавливаться, ты мог просто написать с тем же успехом (отсутствие защиты от sql-инъекций).
$pdo->query("INSERT into ... ");
<?php
if (isset($_COOKIE['login'])){
header('Location:list.php');
}else{
require_once 'database.php';
$email=$_POST['mail'];
$password=md5($_POST['pass']);
$querry="SELECT FROM student WHERE `email`= '$email' AND `password`= '$password'";
$data=$pdo->prepare($querry);
$data->execute();
$res=$data->columnCount();
if ($res>1){
setcookie('login',1,time()+36003);
setcookie('email',$email,time()+3600*3);//в этом моменте поступаю не очень умно
header('Location:list.php');
}
}
?>
Куки потому что заданы и срабатывает первый if может? Открой форму в приватной вкладке.
Названия колонок (и таблиц) и значения оборачиваются в разные кавычки:
INSERT INTO `table` (`column`) VALUES 'Hello world';
Обрати внимание на тип кавычек в каждом случае. В стандарте SQL двойные кавычки используются для идентификаторов (названий колонок, таблиц), а одиночные для строковых значений. То есть:
'hello' - значит взять строку hello
"hello" - значит взять значение колонки с названием hello
Однако, в MySQL отступили от стандарта и у них и одиночные, и двойные кавычки обозначают строку, а косые кавычки обозначают идентификатор.
Далее, не подставляй напрямую переменные в SQL-запрос. Это ведет к SQL-инъекциям (уязвимостям). Вместо этого, используй подготовленные запросы, как описано тут: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md#методы-борьбы
Наконец еще одна ошибка это то, что ты забыл echo перед getMessage(), этот метод не выводит ошибку а лишь возвращает. Ну и правильнее конечно убрать try/catch вообще и вместо этого включить показ ошибок у себя (но не делай это на реальном сервере, иначе злоумышленники смогут получить информацию о внутреннем устройстве сайта!).
Потому что твой код проверяет наличие куки и делает редирект. Видимо, у тебя в браузере установлена кука и потому isset($_COOKIE... сразу же срабатывает.
Также, после header() желательно ставить die(), чтобы код не продолжал выполняться.
Также, не подставляй переменные в SQL-запрос. Ты создаешь SQL-инъекцию. Используй подготовленные запросы. Вот урок: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md#методы-борьбы
И у кого только рука поворачивается такому учить.
Также, если ты делаешь авторизацию через прописывание email в куку, это не очень безопасно. Потому что злоумышленник может записать себе в куки любой email и получить доступ к любому аккаунту. Нужно записывать в куки то, что злоумышленник подобрать не сможет.
Работаю в конторе, пишу минипроекты для нашего подразделения. Первый написал на Laravel (был опыт в php), второй проект пишу на Node.
А проблема в том, что я работаю один.
То есть, у меня нет реального опыта командной разработки. Да, я стараюсь делать всё по best practices на сколько мне это позволяет ICQ, но сама мысль, что у меня нет опыта командной разработки, меня сводит с ума.
Причём я сам могу выбирать стек, устанавливать сроки (в пределах разумного). А теперь вопрос, нужен ли этот опыт или оттягивать переход в команду как можно дольше?
Месяц на проект.
Логично, сори, я недавно вкатился
Пишу на laravel, но меня напрягает что мой код ужасно не красив, вся логика в контроллерах, смотрю чужой код а там всё так чисто и красиво, код разложен по всяким сервисам и репозиториям, как так же научится?
Еще бывают проблемы по некоторым вещам, стоит задача какая-то, я знаю как её сделать но понимаю что это скорее всего не правильно и на большой посещаемости возникнут тормоза и т.п а как по другому сделать не знаю
В курсах и т.п показываются какие то базовые вещи, это я уже всё знаю, а дальше то как качать скил? что читать или смотреть
Да. Зайди на любой сайт и открой Инструменты Разработчика (F12). Там будет вкладка с названием Resources или Storage, на ней можно просмотреть и заменить куки.
Куки хранятся на стороне пользователя (в браузере), потому он может делать с ними что угодно.
>>334742
Вообщем лучше поднять сервер gitea, получить адреса репозиториев git с помощью list.json(или как то так), себе сделать клоны?
По любому хорошие пакеты кроме адреса packagist имеет git-репозиторий, а пакеты ноунеймов редко используются. дай аллах все успеть.
Последний вопрос, я смогу установить пакет через composer имея клон пакета со своего gitea? (или просто со скаченного архива с gitea)
Тебе пока что не нужен gitea. Для начала, тебе надо склонировать репозитории на свой компьютер. Это делается с помощью консольной команды git clone, про которую ты можешь прочесть тут: https://git-scm.com/docs/git-clone (англ) или тут https://git-scm.com/book/ru/v2/Основы-Git-Работа-с-удалёнными-репозиториями (рус)
После того, как ты склонируешь все 300 000 репозиториев, у тебя есть два варианта: если тебе все это нужно для себя, то ты можешь устанавливать пакеты со своего диска, если же ты хочешь поделиться ими с другими, то тебе придется поднять свой аналог гитхаба (тот же gitlab, например). В любом из двух случаев тебе придется сделать также свой репозиторий для композера (на замену packagist), и в нем прописать, чтобы пакеты брались не с гитхаба, а с твоего источника.
Но это все можно сделать потом. Сейчас тебе нужно освоить команду git clone и клонировать себе все репозитории. Я еще раз напомню, что стоит также завести аккаунт на гитхабе, сгенерировать приватный/публичный ключи, загрузить их в свой профиль и клонировать репоизтории, используя эти ключи, так как на анонимное клонирование там сильные ограничения. Про SSH-ключи можно почитать тут: https://docs.github.com/en/authentication/connecting-to-github-with-ssh
> Последний вопрос, я смогу установить пакет через composer имея клон пакета со своего gitea? (или просто со скаченного архива с gitea)
Если этот пакет лежит у тебя на диске, то ты можешь просто прописать путь к нему в composer.json и он будет установлен из указанной папки (а не с гитхаба). Это прописывается в ключе repositories в composer.json: https://getcomposer.org/doc/04-schema.md#repositories
Спрашивай еще, если что-то непонятно. Как я понимаю, ты пока ничего не сделал, потому я бы начал с написания скрипта, который скачивает полный список пакетов с packagist и, например, для начала, выводит их названия. Потом можно доработать этот скрипт, чтобы он кроме названий, выводил бы еще адреса на гитхабе. А потом , чтобы он клонировал все репозитории по очереди.
Пишу там, вроде норм
Если ещё не работаешь, но справляешься с базовыми задачами (учебный проект хотя бы работает без багов, неважно под какой нагрузкой), то искать стажировку или вакансию ждуна. Когда допустят к реальному проекту, внимательно изучать его код, написанный более опытными разрабами.
Просмотр отдельных источников - хорошее дело, но без практики это не позволяет сформировать целостную картину.
Все логика идет через window.location ( route() ), на каждый пук по руту. Будущее за реактом.
Скорее всего, ты что-то не понимаешь. Бессмысленно, например, для блога городить сложное приложение на реакте.
Ну, реакт я уже знаю, в 2 присеста любой блог накатаю и соберу, а вот блейд я пытался понять, но решил что хватит тратить тонны времени впустую. На каждое действие какие-то древние темы где люди задают одни и теже вопросы, для такой локальной технологий это какая-то непозволительная роскошьне иметь такой ясности\казуальной документации.
Разве что все равно в некоторых случаях придется блейдом пользоваться тк только через него некоторые фишки фреймворка работают.
Я вот просто хотел на клик кнопочки отправить запросик(а возможно и проделать манипуляции в функции до оправки..) и возможно получить-или не получить кусок формочки на той же вьюхе с которой кликаю кнопочку.
Под конкретную вьюху впихивать жс, особенно для мелкого функционала - тот еще гемор, оверкил и антипатерн наверное даже.
Отправляем значить просто на рут, если захотим все таки добавить элементы на страницу то возвращаем новую вьху. которая просто расширяет ту, которая у нас уже была, но с добавочной @section, которая должна быть @yield в расширяемой вьюхе.
Слишком много телодвижений, я как с блейдом пытаюсь что-то делать, то спустя какое-то время у меня палец начинает болеть от всех этих лишних кликов и переходов между файлами-папками.
Мне кажется я не очень правильно это сделал
Ажаксы - фетчи и всякие жкуери юзай на онкликс через жс.
Хотя во многих пыха фрейморках по дефолту шаблонизаторы через формы делаются, так что да, может делать через формы, другого и нет.
что за книга и что за программа? где есть подобные тесты?(жевательно с ответами)
В шапке учебник есть, вот, это он, да.
http://codedokode.github.io/phpbook
Полезно иногда почитать шапку треда когда заходишь.
Сразу говорю,is_int() не сработает
Спасибо. Меня смущает тут использование intval. Может, лучше (int)? И нестрогое равенство - оно используется потому, что 0 - это инт, а $x-intval($x)) может быть флоатом?
echo (is_float($x)) ? "С плавающей точкой" : "Целое";
Вот моё решение
О, это интересный вопрос. Давайте его разберем.
Прежде чем двигаться дальше, напомню, что в PHP есть два вида чисел: int и float. С помощью int можно представить только целые небольшие числа (от примерно -9 до 9 ×1018), но зато они хранятся точно, каждая цифра как есть. Я везде описываю 64-битную версию PHP, в 32-битной лимиты другие, но она уже не актуальна.
С помощью float можно представить и целые, и дробные числа, величиной примерно до 10308. Но они хранятся в приближенном виде, сохраняются лишь первые 14-16 значащих цифр, а остальные цифры получаются произвольные. То есть, число 1 000 000 000 000 000 000 000 001 при преобразовании во float может легко превратиться в 1 000 000 000 000 000 987 654 321.
PHP старается использовать int, но если число становится большим или дробным, оно преобразуется во float.
Из-за того, что float использует двоичную систему счисления, многие десятичные дробные числа невозможно представить точно в виде float. Например, число 0.1 может превратиться 0.100 000 000 000 000 1 или 0.099 999 999 999 999 999. Если провести аналогию, то числа вроде 1/3 или 1/7 невозможно записать в десятичной системе (это бесконечные дроби). Аналогично, числа вроде 1/10 невозможно записать в двоичной системе, и выбирается наиболее близкое к нему число, которое можно записать.
Из-за этого, если мы попытаемся сделать сравнение вроде 0.1 + 0.2 === 0.3 , то мы получим false - числа не совпадают, потому что с одной стороны может получиться 0.30...01, а с другой 0.29...9. Поэтому float нельзя сравнивать через == или ===.
(если вам нужна более точная формула, то с помощью float точно можно представить только числа вида M × 2 E, где M и E - целые положительные или отрицательные числа. Например, можно точно представить числа вроде 1/2, 1/4, 3/4, 1/8, 5/16, 1/256 и так далее - внизу у дроби должна быть степень двойки. Число 10 не является степенью двойки, потому 1/10 представить точно невозможно).
Теперь вернемся к задаче.
Во-первых, давайте уточним условия задачи. Мы делим одно целое небольшое число на другое целое небольшое число? Или же числа могут быть большие или не целые?
В первом случае нужно вместо деления использовать деление с остатком: 100 % 10 и проверить, что остаток равен нулю. В этом случае мы используем только числа типа int, и можем использовать == для сравнения.
Во втором случае мы можем округлить результат и сравнить его с исходным числом: сравнить round($x) и $x. Но вспомним, что я написал выше: дробные числа хранятся неточно и их нельзя сравнивать через ==. Потому сравнивать надо, проверяя, что разница между числами меньше определенной величины:
$x = $a / $b;
$diff = abs($x - round($x));
if ($diff < 1e-8) { ... }
Тут мы считаем, что если разница меньше 10-8, то она эквивалентна нулю. Но что если реальная разница меньше этого числа, но не равна нулю (например, мы делим 1 на 1 000 000 000 000)? Тут, увы, нужно какое-то более сложное решение.
О, это интересный вопрос. Давайте его разберем.
Прежде чем двигаться дальше, напомню, что в PHP есть два вида чисел: int и float. С помощью int можно представить только целые небольшие числа (от примерно -9 до 9 ×1018), но зато они хранятся точно, каждая цифра как есть. Я везде описываю 64-битную версию PHP, в 32-битной лимиты другие, но она уже не актуальна.
С помощью float можно представить и целые, и дробные числа, величиной примерно до 10308. Но они хранятся в приближенном виде, сохраняются лишь первые 14-16 значащих цифр, а остальные цифры получаются произвольные. То есть, число 1 000 000 000 000 000 000 000 001 при преобразовании во float может легко превратиться в 1 000 000 000 000 000 987 654 321.
PHP старается использовать int, но если число становится большим или дробным, оно преобразуется во float.
Из-за того, что float использует двоичную систему счисления, многие десятичные дробные числа невозможно представить точно в виде float. Например, число 0.1 может превратиться 0.100 000 000 000 000 1 или 0.099 999 999 999 999 999. Если провести аналогию, то числа вроде 1/3 или 1/7 невозможно записать в десятичной системе (это бесконечные дроби). Аналогично, числа вроде 1/10 невозможно записать в двоичной системе, и выбирается наиболее близкое к нему число, которое можно записать.
Из-за этого, если мы попытаемся сделать сравнение вроде 0.1 + 0.2 === 0.3 , то мы получим false - числа не совпадают, потому что с одной стороны может получиться 0.30...01, а с другой 0.29...9. Поэтому float нельзя сравнивать через == или ===.
(если вам нужна более точная формула, то с помощью float точно можно представить только числа вида M × 2 E, где M и E - целые положительные или отрицательные числа. Например, можно точно представить числа вроде 1/2, 1/4, 3/4, 1/8, 5/16, 1/256 и так далее - внизу у дроби должна быть степень двойки. Число 10 не является степенью двойки, потому 1/10 представить точно невозможно).
Теперь вернемся к задаче.
Во-первых, давайте уточним условия задачи. Мы делим одно целое небольшое число на другое целое небольшое число? Или же числа могут быть большие или не целые?
В первом случае нужно вместо деления использовать деление с остатком: 100 % 10 и проверить, что остаток равен нулю. В этом случае мы используем только числа типа int, и можем использовать == для сравнения.
Во втором случае мы можем округлить результат и сравнить его с исходным числом: сравнить round($x) и $x. Но вспомним, что я написал выше: дробные числа хранятся неточно и их нельзя сравнивать через ==. Потому сравнивать надо, проверяя, что разница между числами меньше определенной величины:
$x = $a / $b;
$diff = abs($x - round($x));
if ($diff < 1e-8) { ... }
Тут мы считаем, что если разница меньше 10-8, то она эквивалентна нулю. Но что если реальная разница меньше этого числа, но не равна нулю (например, мы делим 1 на 1 000 000 000 000)? Тут, увы, нужно какое-то более сложное решение.
В общем, если числа имеют тип float, то определить это достоверно невозможно. Например, пусть мы делим два числа:
4 000 000 000 000 000 000.4
2 000 000 000 000 000 000.2
Очевидно, что ответ будет 2. Но так как при преобразовании во float цифры после 14-16-й искажаются, то вполне могут получиться числа, которые при делении не дадут ровно 2:
4 000 000 000 000 000 987
2 000 000 000 000 000 123
И в итоге мы не можем понять: это результат не целый, или это просто погрешность преобразования во float?
Как можно избежать этой проблемы? Нужно использовать специальный тип Decimal. Числа этого типа не преобразуются в двоичную форму, а хранятся в десятичной, и они хранят столько значащих цифр, сколько мы укажем. То есть, используя Decimal, мы можем точно представить произвольные числа и точно их поделить.
Пример библиотеки для чисел Decimal: https://github.com/direvus/php-decimal
То есть как запустить пхп скрипт на своес серваке с другого сервера? Может, сталкивался кто-нибудь
Я на чистой пыхе могу делать, а как делать с фремворками mvc - сразу стопор. Использую basic template проект.
В этом проекте если зайти за харкодед админа - все прекрасно заходится. Как только захожу за кастомного юзера пишет Cookie “_identity” has been rejected because it is already expired в браузере.
Все что я сделал своего - получаение данных из базы в getUsername().
Вручную присваивал authKey и accessToken - не помогло(да и не должно было вроде как)
Я думаю он имел в виду как сделать приложение на базе фреймворка, используя концепцию mvc.
> if ($diff < 1e-8) { ... }
В PHP, кстати, даже предусмотрена константа бесконечно малой величины специально для таких сравнений
if (abs($left - $right) < PHP_FLOAT_EPSILON)
Если я правильно понял, в контейнере2 лежит файл с php-кодом. Значит, его нужно как-то передать в контейнер1. Самый простой способ - поднять в контейнере2 веб-сервер (к примеру, Apache), который будет отдавать файл, и пробросить порт 80:XXXX наружу. А из контейнера1 слать запрос, чтобы скачать файл с кодом внутрь контейнера1, ну и собственно, уже там выполнить.
Конечно. Допустим, у тебя есть список платежей с копейками, и ты хочешь проверить, что сумма платежей совпадает с итоговой суммой. Если использовать float, то будут ошибки.
Да, именно так я и хочу сделать, поднять в контейнерах два вебсервера с разными портами, но суть в том, что слать запросы непростая задача. Вдруг здесь есть те, кто использует подобное или пытался
Какая-то ранимая пассивная агрессия, как же вы надоели.
Тут даже не вайти дело, вы просто овощи какие-то, как будто никогда нигде не работали. Есть тонна вакансий и фирм, все разные. требуют разное, платят разное, пишите, звоните, узнавайте, язык до Киева доведет, как говорят. Нет же, зайдем на любимый сосачик к таким же анонимным инфантилам и будем требовать инфу, а потом еще обвинать анонов в том что видите ли как-то не так дали инфу. Какой-то аутизм чес слово.
>вы просто овощи какие-то, как будто никогда нигде не работали
>Какой-то аутизм
Есть такое. Просим понять и простить.
Есть ещё идея, хз будет ли такое работать. Примонтировать к обоим контейнерам по каталогу (volume) и в одном каталоге сделать символическую ссылку на другой каталог.
Пхп макака на руководящей должности получает чуть больше, да и то в международной корпорации, где несколько рабочих мест на всю страну, учителей же миллионы. В бюджетным учреждениях технические специалисты зарабатывают на уровне уборщиц, начальники на уровне девочек из институтов, которые только устроились врачихами или училками.
Трудоустраиваются туда только дауны, которые не осилили высшее образование в принципе, среди пхп макак людей с высоким интеллектом нет, как класса. человек с интеллектом получает диплом и паразитирует на бюджете.
Хули тут рассуждать, если 80% ипотечников это врачи, учителя и силовики, а для рядовой пхп макаки ипотека это запредельная роскошь.
Все так, а теперь брысь отсюда.
Лечусь.
Хорошо бы уметь.
>>342384
Ты имеешь в виду linux контейнеры? Или что-то другое?
Linux контейнеры позволяют изолировать приложения друг от друга. К примеру, ты можешь создать два контейнера, и в каждом из них будут свои файлы, свои сетевые интерфейсы, в общем как будто это две отдельных виртуальных машины, просто с общим ядром.
Контейнеры можно использовать, чтобы, например, установить приложение и все нужные ему библиотеки, не трогая при этом основную систему. Также контейнеры позволяют управлять ресурсами, например, расходом памяти, процессорного времени.
Контейнеры обычно создают с помощью программ вроде lxc, docker, и подобных.
>>342447
Начать надо с чтения документации. Если по документации что-то непонятно, можно спросить тут.
Если ты плохо знаешь, как работают куки, опять же, надо про них прочитать. Каким заголовком ставятся куки, в каком заголовке они передаются, как посмотреть куки в браузере.
Если ты все это изучил, то надо проверять код, этап за этапом, что он работает как ожидается. То есть, проверить, что форма логина показывается со всеми нужными параметрами, что они отправляются на сервер, что они успешно проходят проверку, что генерируется правильный токен, что выставляется правильная кука итд. То есть, надо разробрать код и по шагам проверить его работу.
Что касается приведенной тобой ошибки, то похоже на то, что ты пытаешься выставить куку с датой в прошлом или отрицательным сроком жизни. Надо смотреть заголовок set-cookie, которым она ставится, и параметры куки в нем.
Там было что-то вроде. Запрос выполняется на null.
Задать в js json в виде массива, превратить его в строку через JSON.stringify(arr). На сервере принять строку и разджисонить через json_decode($_POST['param']);
Попытаюсь сейчас не-косноязычно сказать.
Почитав документации, книжки по чистому пхп и разные статьи в интернете, я понял что реализовать разные концепты можно по-разному. Разные подходы к одной и той же задаче.
И, как я знаю по определению фреймворков, одна из их задач это заставлять программиста следовать хотя бы определенному стандарту, а не городить колеса и заборы.
И так как ферймворки предоставляют возожность использовать некоторые вещи из коробки, подразумевается что ты не должен сам вручную прописывать полностью логику модуля. Иначе я мог бы сам всю систему авторизации написать и так, и сяк, но я же использую зачем-то фреймворк1
Конкретно в моем случае, как я уже сказал, я не менял ничего. кроме предоставления базовых данных о юзере. Был харкодед admin и demo, я просто сделал получение юзера из базы с теми же данными. Я, по идее, и не должен ничего больше менять-писать, никаких setcookie(), потому что ничего больше не поменялось. Но даже если так, во время логинирования прописывается вторым аргументом время работы куки от момента логинирования - я это не трогал, это должно работать как и работало.
Проблема здесь в какой-то непонятной магической херне под капотом по управлению аутентификацией юзеров, их identity. Я уже перечитал и модель юзера в документации, и интерфейс наследуемый, и манаджер идентити, который всем управляет, и даже полез выше, в модуль приложения - хотя это уже не нужно. И я нихера не понимаю как это устроенно, какие-то может скрытые принципы, архитектура, хз. Зачем мне самому городить колеса на чистом пыхыпы, когда с дефолтными юзерами все работает.
Одна из задач фреймворков - облегчать работу, ускорять ее, а в итоге я трачу кучу времени чтобы понять как работает то, что я могу уже написать на чистом пыхыпы коде, не круто.
>КАК принять на сервере сырой json
В смысле, как принять? Ты отправляешь на сервер данные либо в пост, либо в гет запросе. И там и там это - строки (ок, в посте можно передавать бинарники, но это явно не наш случай). Всё что тебе нужно - это сначала превратить джисон в строку,а потом конвертировать её обратно в объект, или что там у тебя внутри джисона.
>>344473
>$json = file_get_contents('php://input');
Не совсем. Для начала попробуй передать на сервер не джисон, а просто строку. Если это просто отправка данных со страницы, то она идёт обычно через <form>. Если это аякс, то аяксом. На сервере ты смотришь, чего прилетело в _POST или _GET, и разджисониваешь:
$json = $_POST['jsonstring'];
$data = json_decode($json, true);
let xhr = new XMLHttpRequest();
let body = JSON.stringify(arr_num);
xhr.open("POST", 'record_ticket.php', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.send(body);
xhr.onload = function() {
console.log(`Загружено: ${xhr.status} ${xhr.response}`);
};
>Если это просто отправка данных со страницы, то она идёт обычно через <form>
А если это не пользовательский ввод из какого-то text поля, что там тогда за объект в форме?
вот я про тоже,как отпралять данные,если это не форма по классике,мож я результат расчета ипотеки хочу отправть,как в банковских калькуляторах
так вот же - xhr.send(body);
в переменную body можно положить что угодно и отправлять на сервер.
мимо
> Если это аякс, то аяксом. На сервере ты смотришь, чего прилетело в _POST
и ничего не прилетело
1. перемення random не задействована по сути
2. зачем тебе тут цикл? Ты просто получаешь 1 раз рандомное число и выводишь значение по ключу массива
Фреймворк - это готовый код и набор паттернов. Он избавляет тебя от необходимости писать один и тот же код, но он не отменяет необходимость знать и понимать, как этот код работает.
В твоем случае причина может быть в куче разных мест. Может быть, ты что-то неправильно прописал в конфиге. Может быть, ты установил какой-то модуль, который конфликтует с другим модулем. Может быть, ты установил несовместимую версию плагина. Может быть, ты не выполнил какой-то шаг или требование из документации, или пытаешься сделать что-то непредусмотренное. Наконец, может быть, что в готовом компоненте есть ошибки.
Поэтому тебе нужно разбираться, как все работает и уметь находить причину ошибки.
Даже в CMS на практике приходится разбираться, а фреймворк - твой основной рабочий инструмент - надо знать.
Тебе все равно пригодятся такие знания, так как может понадобиться что-то подкрутить, что-то интегрировать и все равно придется разбираться как оно устроено.
Фрейморк большой, и поначалу может быть сложно в нем разобраться. Мне обычно при разборе кода помогают заметки и схемы на бумаге. Например, можно нарисовать связи между классами, или кто кого вызывает и что туда передает итд.
Если тебе пока не охота лезть внутрь кода фреймворка, то можно начать хотя бы с сравнения того, как работает код с фиксированными пользователями (работающий) и модифицированный (неработающий) код. Залоггировать, какие функции вызываются, что они получают и возвращают, и сравнить логи от двух версий кода. Может что-то станет понятнее.
Ну и что касается ошибки с кукой - надо смотреть инструменты разработчика, вкладку Network. И тебе надо знать, в каких заголовках передаются куки, если ты хочешь заниматься веб-разработкой.
Ты задавал в оригинальном посте такой вопрос:
> Может кто объяснить как происходит аутентификация в Yii2?
Ответ на этот вопрос находится либо в документации, либо в коде, если ее нету. Я не знаю, как устроен Yii, и даже если бы знал, то какой смысл мне пересказывать содержимое документации?
Фреймворк - это готовый код и набор паттернов. Он избавляет тебя от необходимости писать один и тот же код, но он не отменяет необходимость знать и понимать, как этот код работает.
В твоем случае причина может быть в куче разных мест. Может быть, ты что-то неправильно прописал в конфиге. Может быть, ты установил какой-то модуль, который конфликтует с другим модулем. Может быть, ты установил несовместимую версию плагина. Может быть, ты не выполнил какой-то шаг или требование из документации, или пытаешься сделать что-то непредусмотренное. Наконец, может быть, что в готовом компоненте есть ошибки.
Поэтому тебе нужно разбираться, как все работает и уметь находить причину ошибки.
Даже в CMS на практике приходится разбираться, а фреймворк - твой основной рабочий инструмент - надо знать.
Тебе все равно пригодятся такие знания, так как может понадобиться что-то подкрутить, что-то интегрировать и все равно придется разбираться как оно устроено.
Фрейморк большой, и поначалу может быть сложно в нем разобраться. Мне обычно при разборе кода помогают заметки и схемы на бумаге. Например, можно нарисовать связи между классами, или кто кого вызывает и что туда передает итд.
Если тебе пока не охота лезть внутрь кода фреймворка, то можно начать хотя бы с сравнения того, как работает код с фиксированными пользователями (работающий) и модифицированный (неработающий) код. Залоггировать, какие функции вызываются, что они получают и возвращают, и сравнить логи от двух версий кода. Может что-то станет понятнее.
Ну и что касается ошибки с кукой - надо смотреть инструменты разработчика, вкладку Network. И тебе надо знать, в каких заголовках передаются куки, если ты хочешь заниматься веб-разработкой.
Ты задавал в оригинальном посте такой вопрос:
> Может кто объяснить как происходит аутентификация в Yii2?
Ответ на этот вопрос находится либо в документации, либо в коде, если ее нету. Я не знаю, как устроен Yii, и даже если бы знал, то какой смысл мне пересказывать содержимое документации?
> а в итоге я трачу кучу времени чтобы понять как работает то,
Рассматривай это как инвестицию в повышение своего уровня.
>>344458
PHP не помещает в $_POST данные из JSON. Ты должен сам прочитать тело запроса из php://input и распарсить его.
>>344497
Выше приведен пример. Ставишь заголовок Content-Type: application/json, передаешь в теле запроса JSON и в браузере в инструментах разработчика на вкладке Network проверяешь что все верно.
Мануал : https://www.php.net/manual/ru/reserved.variables.post.php
> Ассоциативный массив данных, переданных скрипту через HTTP методом POST при использовании application/x-www-form-urlencoded или multipart/form-data в заголовке Content-Type запроса HTTP.
JSON в этом списке типов нету.
>>344954
Цикл используют, чтобы сделать что-то несколько раз подряд. Например, вывести каждый элемент массива по очереди. Или отобрать элементы, соответствующие какому-то условию.
Цикл тебе не нужен. Тебе нужно сделать так:
- используя array_rand, получить случайный ключ из массива (если ты забыл что такое ключ, то смотри начало урока про массивы, где есть рисунок). Ключ это будет число от 1 до 6. Напомню, что ключ это что-то вроде уникального "идентификатора", по которому можно найти элемент массива. В массиве не может быть два одинаковых ключа.
- затем по ключу тебе нужно получить значение элемента. Для этого нужно использовать квадратные скобки после имени массива - поищи примеры в уроке, если не найдешь, напиши, тебе подскажут.
Ты имеешь в виду SQLite или что-то другое? Если SQLite, то плюсы в том, что это встраиваемая база данных, то есть ей не нужна отдельная программа-сервер, не нужно никуда подключаться, данные просто хранятся в одном файле и легко можно его скопировать, удалить, заменить, переслать итд.
Ок, https://www.youtube.com/watch?v=Dn8vzTsnPps&ab_channel=LimpBizkitVEVO
Я на это и настроился, просто зашел на двачик спросить. Ну, типа находить информацию можно разными способами. все средства хороши, я должен был попробовать. Теперь со спокойной душой пойду ковыряться под капотом.
Спасибо, в общем-то, за наставление, сам разберусь дальше.
Помню где-то раньше была ссылка на роадмап https://miro.com/app/board/o9J_lbUUBBQ=/
здесь же вроде? Сейчас что-то не нахожу.
Сделать массив и 49
потом через цикл 6 раз генерировать ключ.
выводим число,удаляем по ключу число в массиве.
И так 6 раз.
А разобрался, ссылка была раньше в тредах в шапке, а теперь её нет, а https://phpclub.tech/ не работает (хорошо завязались на аноновские ненадёжные сервисы кста)
В общем я что хотел сказать - роудмапа была ничё так, причём не совсем понятно почему там было написано php, ведь она универсально подходит к любому бекенду, будь что пыха, питон, джава или ror.
>Это везде кроме .net так надо делать, что у тебя по сути нет кнопочки поставить ide-шку и нажать кнопку отладки и смотреть как твой говнопроект запустился
Это на любом интерпретируемом языке, не?
Правда? Я дальше c# и .net вообще ничего не знал. В универе был факультатив по c#+mssql+asp.net на 1.5 года, сейчас сижу охуеваю с мира интерпретируемых зыков.
Не совсем. Жди пояснительную бригаду, желательно не из долбоёбов типа меня которые хуйни наобъясняют.
Wsl2 это для тех, кто:
1. Знаком с разработкой в принципе
2. Хорошо знаком с жмупинусом, и с тем же докером на нем же.
Если ты жмупинус впервые видишь - забудь про wls, ставь виртуалку или дуалбут на минимум пару месяцев. про написание кода без wsl просто на винде даже и не думай
Вообще скриптовые языки как раз и хорошо тем, что для них не надо нажимать кнопочку и компилировать, им только рантайм нужен - но вот установка рантайма это отдельная штука. Собственно, прежде чем запускать что-то в докере, надо сначала разобраться, как этот рантайм подхватывает запрос и выполняет скрипт, а потом уже заворачивать в контейнеры. в случае nginx+phpfpm - nginx принимает запрос и по fastcgi передаёт в php-fpm, указав ему в параметрах, где лежит папка с index.php
Попробовал сделать проверку что они всегда уникальны. Так и есть.
Просто убираешь числа которые в итоговом массиве.
https://3v4l.org/XTIES
Redis это key-value хранилище, использующееся чаще всего для кеширования.
key-value хранилище - значит, что в нем нет никаких таблиц, никаких SQL запросов. Ты можешь просто сохранить строку под определенным ключом, а позже по ключу получить эту строку обратно. Ключ это тоже произвольная строка.
Ну, например, ты можешь сохранить JSON-строку '{"name": "Ivan", "point": 12345}' с ключом 'user:12345'. А позже получить ее обратно. Но запросы вида "найти все значения по условию" делать нельзя. Редис это не база данных.
Кеширование это сохранение результатов каких-то долго выполняющихся операций. Например, мы хотим выводить на сайте топ статей. Но его выборка из базы занимает целую секунду. Во-первых, это сильно замедляет загрузку страницы, во-вторых, если к нам зайдет 100 человек одновременно, то они положат базу.
Потому мы можем вместо этого рассчитывать топ статей по расписанию раз в 5 минут и сохранять в кеш. А при выводе страницы брать готовые данные из кеша, не тратя времени и не нагружая базу.
А для хранения данных можно как раз использовать Redis. Есть разные стратегии кеширования, погугли, если интересно.
Редис может работать в двух режимах: персистентном и не-персистентном. Во втором случае данные хранятся только в памяти и теряются при падении редиса, перезагрузке сервиса, перезапуске редиса. Но зато мы имеем максимальную производительность. В первом случае данные раз в N секунд сбрасываются на диск. Это улучшает сохранность данных, но создает нагрузку на диск и увеличивает время запуска редиса, так как ему придется прочитать все сохраненные данные, а их может быть много.
Редис это больше, чем просто key-value хранилище. Кроме строк, в редисе есть и другие структуры данных: очереди, списки, хеш-таблицы. Они могут быть полезны в некоторых случаях. Подробно про них ты можешь прочесть в документации по редису.
А что, в C# приложениях сервисы вроде СУБД, кешей, и прочего не используются? Если ты будешь писать микросервисы на C#, тебе точно так же понадобится и Докер, или аналог, и командная строка. Просто ты наверно делал очень простые монолитные приложения без баз данных и кешей, либо же не хотел автоматизировать свою работу.
> поставить php8.1
> композер глобально
Если у тебя такой мощный компьютер, который поддерживает запуск многих Докер образов, то ты мог бы и не мучаться с установкой, а запускать php и composer в нем тоже.
>>345857
У array_rand есть опция, которая позволяет сгенерировать 6 чисел за один вызов.
Этот тред закрыт. Если вдруг сенпай вас не заметил, задайте свой вопрос в новом треде.
Там в .net(c#) приложение накатывается фреймворк(entity framework) для работы с mssql/mysql и сразу же цепляешь свой сервер локально и он тебе классы моделек наделает на основе таблиц и ключей в бд. Нажимаешь кнопочку дебага/компиляции и он тебе запускает приложение и с командной строкой в ide и на локалхост развернет. Я понимаю, что Докер это сейчас мастхэв, но именно в самом начале даже знакомства он нужен везде, как я понял, кроме .net.
Чем тебя ресурсы не устраивают?
в контроллере по сконфигурированному URL, без задней мысли, берёшь и принимаешь
$request->json->all(); Вроде так.
js знаю на уровне скопировать код из документации и натянуть его на свои нужды, ну и немного промисы.
Цель трудоустроится.
В моем представлении js будет требоваться на галере, а WP для фриланса, так ли это?
И сильно ли сложен wp по сравнению с фреймворками(мой-yii2)
>js будет требоваться на галере
Жаес будет требоваться везде если ты хоть как то связан с вэбом. Ибо без этой помойки ни одного сайта не написанно.
>js или WP
Laravel или Symfony/Phalcon? Я бы советовал Лару для облегчённого трудоустройства или Symfony для более глубокого понимания фреймворков.
>>404455
>кто может помочь с php
>небольшая задачка
Сколько платишь?
Вы видите копию треда, сохраненную 3 августа 2022 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.