Это копия, сохраненная 28 марта 2021 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
ОП довольно занят, но постарается ответить на все вопросы. Также, ответы и решения задач можно поискать в архиве тредов phpclub.
Это тред и для начинающих. Слово "классы" у тебя ассоциируется только со школой, а в аттестате тройка по математике? Ты наш человек.
Предыдущий тред был тут: >>1731888 (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? — Да, однозначно. Посмотри любую вакансию.
Для этого достаточно вставить код на http://beta.phpformatter.com/ и нажать «format». Робот оформит все как надо. Если ты используешь IDE, то там есть горячая клавиша для этого. Список клавиш для IDE: https://gist.github.com/codedokode/8759492
Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть рекомендации PSR-1 и PSR-12. Вот как надо оформлять код:
- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек
- мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)
- ставим тайп-хинты на аргументы функций, результат функций и поля классов
Вот ссылка на рекомендации PSR, где все это описано подробнее и даны примеры оформления:
PSR-1 (рус.): https://svyatoslav.biz/misc/psr_translation/#_PSR-1
PSR-12 (англ.): https://www.php-fig.org/psr/psr-12/
пока что был на двух - джун и мидл, оба в отказ ушли
Спасибо. Насчет autowiring, он точно должен работать на компонентах? Читал о нем еще в твоем гайде по DI, но даже не пытался реализовать, т.к. был уверен что это лютейшая магия, работающая только на полном symfony. Сейчас вот попытался сделать как на пике, но что-то параметры в конструкторы не пробрасываются. Даже на новом голом тестовом проекте с одним лишь DI пробовал, всё равно безуспешно. Больше я бы, конечно, удивился, если бы оно работало.
Напоминаю =)
Тут ты попадаешь в очевидную ловушку, что на цмсках ты программирские скиллы не развиваешь, а дома это делать сложно и поправить тебя некому, когда говнокодишь.
На джуна можно скорее всего когда угодно, потому что котируются не столько навыки, сколько общий интеллект, мотивация и так далее.
Погуглил наборы вопросов на собеседованиях (только нормальные, а не всякое говно типа "что такое функция", "что такое класс"), желательно на миддла и учи, пока не сможешь на них максимально полно ответить.
Ещё сделай пару пет проектов (только по гайдам, скелетонам и так далее) и запули сюда или в любой чат и попроси обосрать.
Ещё имей ввиду, что на джуна нормальный офферрейт - это 1 оффер из 20 собесов.
>>785913
Зависит от того, что именно делаешь. Если на вордпрессе, джумле или yii что-то формошлёпствуешь, то лучше говори, что в гей-клубе хостесс работаешь. А если симфони, ларавел и какой-то средней руки продукт или аутсорс - то вполне норм, not great, not terrible.
>>785992
Можешь объявить в модели интерфейсы с геттерами, а реализовать их в классах ОРМки.
>Можешь объявить в модели интерфейсы с геттерами, а реализовать их в классах ОРМки.
Спасибо за ответ, я правильно понял что под классами ОРМ ты подразумеваешь сущность ( Entity )?
Сап пехепач. На РАБотке дали задачу создать "программу" для обмена данными между удаленными друг от друга офисами. Они должны заполнять документы в рамках одного дела и передавать их друг другу. Офис1 ставит свои печати (скачивает исходник, обрабатывает, заливает обновленную версию), потом это делают второй, третий и т.д. Все это нужно сделать на php, плюс интерфейс для "операторов пк на уровне пользователя". Я понимаю, что это наверняка крайне тривиальная задача, но сам имею лишь приблизительное представление, как это сделать. Дайте советов мудрых или обоссыте.
делал по этому гайду https://www.digitalocean.com/community/tutorials/how-to-install-linux-nginx-mysql-php-lemp-stack-on-ubuntu-20-04-ru
индексная страница nginx в итоге появилась, а когда прокинул на сам проект уже - то нихуя. показывает 404 в конфиге нгинса вот это висит
google drive чем не подходит?
Это (по сравнению с symfony ^4.0 и его autocofigure+autowire) типа эксплеситный метод описать и заинжектить сервисы и значения в контейнер?
Нет, джава намного более обширна как область (даже чисто как бекенл, не вспоминая про мобилки), намного совершеннее, как экосистема (тулчейн, akka, котлин, скалаштуки и тп) и намного денежнее в смысле зарплат.
PHP при всём его прогрессе за последние 10 лет будет для тебя дауншифтингом.
Дело конечно твоё, но количество не означает качество. Большинство фрилансеров - это индусы с крайне низким рейтом. Да, стать одним из них легко, но зато трудно прийти к успеху, не говоря уже про конкуренцию.
Приведу пример, ты можешь учиться 5 лет на юриста (может, изредка подрабатывая писарем в суде за 5к) и потом получишь престижную работу за 100к, или можешь пойти в сторожа в пятерочке за 20к прямо сейчас.
Да, в эти пять лет ты в пятерочке будешь получать больше, но и расти тебе некуда, так и останешься охранником (причём с возрастом уйти из охраны будет сложнее, потому что начинать придётся с нуля), а после юриста ты мог бы стать адвокатом, прокурором и тп, всё увеличивая профессионализм и зарплату.
То есть, у тебя выбор между локальным оптимумом и глобальным, дальше выбирай сам. Я бы выбрал второе.
Это невозможно, потому что для того, чтобы эмулировать действия пользователя тебе нужен браузер, где ты будешь исполнять фронтендовый код.
Как альтернатива, можешь расковырять апи сервера и отправлять запрос на сабмит формы прямо из php, но это уже будет не эмуляция.
> +js
И кто этот жс будет исполнять, Пушкин?
А вообще, это не интересная задача и весьма ебучая. Лучше сделать как угодно и избавиться от неё.
Дальше реализуешь на пхп виртуальную машину жс, дом модель документа, ну а там разберешься.
Я согласен с тем, что ты говоришь.
Но суть в том, что я хотел бы и в пыхе развиваться как нормальный девелопер. Прокачивать хардскиллзы, писать красивый и правильный код и т.д.
Ну и плюс иметь возможность пофрилансить/поработать удаленку (когда корона закончится и начнут возвращаться в офисы).
Джава захватывает тем, что я в любой момент сейчас могу свернуть в сторону андроида и делать там более-менее интересные проекты (всяко интереснее, чем если я попаду на проект в какой-нибудь банк и буду бекенд софта для местных бухгалтерш писать)
На самом деле пилка андроид приложений наверно самая унылая сфера из всех, даже обычный фронтенд интереснее.
Фриланс на пыхе это обычно смерть с джумлой и прочим ужасом, конечно можно найти себе какую-нибудь поддержку сайтеца на симфони 2, но такого не очень много. Нормального девелопмента на фрилансе в принципе обычно нет, никаких тестов, ничего нет, файлы кидай архивом и объясняй как установить по скайпу-обычное дело
Чувак, тебе уже сказали, что джава - она как php (в смысле, можешь делать всё то же самое), но просто совершеннее в смысле тулчейна, экосистемы, зарплат и так далее.
Хочешь говнякать фриланс на симфони - пожалуйста, жизнь твоя, решать тебе.
мимо
Делают новые огромные проекты, которые станут потом тем огромным легаси.
Если интересует прототипное говно для ип чебурек, то это нода, ларавель, джанго, рельсы.
Встрял с тем как отображать в twig флэш сообщения.
В идеале что то типа хелпера, который будет скрывать в себе всю логику флэш сообщений.
По документации на твиг нихуя не понял. И у меня даже почему то addGlobals не заработало.
хедлес браузеры
Джаву боюсь хоронят так же как пхп или с++. Вечно и постоянно.
Рождены что бы хорониться, лол.
Дальше ток JS , ему желают смерти все, но все понимают что он тупо не умрет никогда.
Хуйня в том, что я всю жизнь то фрилансил то подрабатывал на разных цмсях и/или фрейморках, и по итогу оказался в ситуации что могу пользовать всё, но нихуя не знаю. А современному рынку труда очень надо шоб ты знал симфоню. Осваиваю я любое говно быстро, есть план написать на гитхаб проектик на любом распространённом фреймворке шоб пощупать его кишочки, и говорить что знаю его(показывать результат при необходимости).
{"factory": "Восход", "material": "Пластик"}
Как лучше в таком случае реализовать фильтр товаров? Мне в голову пришло только сделать в каталоге формочку, которая отправляет get запрос вида /products?factory=Восход&material=Пластик
Это совсем говно, или сойдет? Ничего страшного в том, что кириллицу передаем в get параметрах, или может есть более элегантное решение?
Ебать ты атрибуты запихнул, конечно.
Я не в курсе за вашу ларавель, но бля. Из такой штуки тупо неудобно их искать же. Медленно через like выходит же.
>Ебать ты атрибуты запихнул, конечно.
Аттрибуты довольно разные, и точный список заранее неизвестен, поэтому нужно что-то гибкое и более-менее масштабируемое. От EAV решил отказаться, а nosql не хочется тащить сюда. Поэтому решил аттрибуты хранить в json и просто прописать их в админке при добавлении товара.
Like не нужен, в mysql завезли же поддержку json полей, искать можно так:
select * from `products` where json_unquote(json_extract(`attributes`, '$."factory"')) = 'Восход'
https://laravel.com/docs/7.x/queries#json-where-clauses
DB::table('products')->where('attributes->factory', 'Восход')->get();
Или ты думаешь что json лучше не хранить в mysql? Как тогда лучше поступить, какую струкуру бд выбрать, чтобы без json обойтись?
А то накачал сливов laracasts и всяких курсов, а там пятёрка.
Может у вас есть ссылки на посвежее?
Алсо, слезаю с иглы Битрикса, есть что-то особенное, что нужно знать при переходе на Ларавел?
>Аттрибуты довольно разные, и точный список заранее неизвестен
Можно создать таблицу в которой у тебя будут поля attribute_name, и attribute_value, и джойнить её.
>Like не нужен, в mysql завезли же поддержку json полей
И ты таки уверен что оно прям быстро работать?
>Можно создать таблицу в которой у тебя будут поля attribute_name, и attribute_value, и джойнить её.
Получается паттерн EAV (Entity-Attribute-Value), про который в гугле плохо пишут.
>И ты таки уверен что оно прям быстро работать?
На хабре статья была, где сравниваниют eav и jsonb, правда там posgresql, а не mysql, можешь глянуть https://habr.com/ru/post/475178/ . Если кратко, то "потери производительности очень незначительные".
>Получается паттерн EAV (Entity-Attribute-Value), про который в гугле плохо пишут.
Ну, плюс-минус все интернет-магазинные cms которые умеют в мультиатрибутность такую реализуют это как раз так.
>Если кратко, то "потери производительности очень незначительные".
Ну, если так, и если тебе так удобнее-вопросов нет. В конце коноцов то что я бы так не делал не значит что так не стоит делать же.)
Ну а yii в этом ряду откуда тогда? Он вообще рядом не стоит ни по качеству, ни по перспективам.
Симфони - это набор компонент и каждый проект на симфони может отличаться от другого, на самом деле, что-то взяли из симфони, что-то написали своё.
Но и для СИмфони и для Ларавела куча примеров на гитхабе, бери и изучай.
>>787969
Как везде, пишут новое, поддерживают старое. Так как джаве уже дохера лет, то просто статистически старого больше чем нового, накопилось за годы. В отличие от какого-нибудь го, который очень молод и, чтобы встретить на нём серьёзное легаси надо постараться.
>{"factory": "Восход", "material": "Пластик"}
Ебать я вскекнул. Очередной лопух начитался про jsonb. А хули ты будешь делать если нужно "factory" переименовать? Если у тебя там "fucktory" написано, ты весь миллион товаров апдейтить будешь? Особенно охуенно будет с десятками свойств типа "resolution", которые у каждого тапка свои.
>Получается паттерн EAV (Entity-Attribute-Value), про который в гугле плохо пишут
Ты бы хоть прочитал что такое EAV. EAV это когда вся БАЗА ДАННЫХ создается в виде одной единственной таблицы.
Вот каноничный пример EAV https://dbfiddle.uk/?rdbms=postgres_12&fiddle=1972d91317eeb172ffd647d363b72d1c сразу видно почему он считается антипаттерном. Нужно каждую сущность собирать буквально по частям. Схема данных спрятана внутри самой базы, именно поэтому EAV считается медленней, чем обычная реляционная схема. Нужен минимум один дополнительный шаг чтобы получить схему.
Когда ты строишь каталог, то у тебя есть четкая схема:
Product "DELL UltraSharp U2718Q" <- Type "Monitor" <- Property "Resolution" <- "3840x2160 (16:9)"
Эта схема состоит из нескольких таблиц, полностью реляционна и нормализована. И никакого блядь отношения к EAV она не имеет.
>>788899
>Когда ты строишь каталог, то у тебя есть четкая схема:
>Product "DELL UltraSharp U2718Q" <- Type "Monitor" <- Property "Resolution" <- "3840x2160 (16:9)"
>Эта схема состоит из нескольких таблиц, полностью реляционна и нормализована. И никакого блядь отношения к EAV она не имеет.
Вот тут нихуя не понял. Из каких таблиц состоит эта схема? Или ты предлагаешь на каждое свойство свою таблицу создавать?
Важно не из каких таблиц она состоит, это дело десятое. Какие нужны, такие и сделаешь. Важен сам факт того что если у тебя есть схема каталога и она состоит из таблиц, то это не EAV.
Если ты не знаешь как схему каталога составить, то посмотри популярные PIM системы вроде akeneo. Или просто погули "product catalog database scema". Вот тут, например, хорошо расписано https://www.codingblocks.net/programming/database-schema-for-multiple-types-of-products/
И всё-таки, настолько ли плох Json в моем случае? Планируется интернет магазин с тремя категориями товаров, всего товаров не больше 50 штук. Проблема в том, что атрибуты товаров заранее неизвестны. Или всё-таки реляционная и нормализованная бд лучше будет?
Чем меньше каталог, тем меньше причин использовать nosql. Сама структура у тебя сто проц будет реляционная. JSON можно использовать для значений, типа "значение, тип, единицы измерения" https://dbfiddle.uk/?rdbms=postgres_12&fiddle=34f95d845ab52b07b68c8aa37058b522 , и то лучше сделать отдельную таблицу для единиц измерения.
Ну и самое главное, если есть возможность выбирать. То используй Postgres, а не mysql. Та же работа с json в mysql 8 это сраная шутка, по сравнению с postgres.
>То используй Postgres, а не mysql
Согласен.
>Та же работа с json в mysql 8 это сраная шутка, по сравнению с postgres.
На правах срача. Если потребовалось работать с json в БД, то ты что-то сделал через жопу. То самый случай когда НИНУЖНО.
426x240, 3:54
Каждого любителя четвертой нормальной формы жизнь рано или поздно ебашит головой об угол стола. И пока он в полубессознательном состоянии сзади его приобнимает dba, приспускает штанишки и шепчет на ухо ДЕНОРМАЛИЗАЦИЯ.
>Денормализовать json-ами
Вернейший способ сделать кривое, неподдерживаемое, нерасширяемое говно. И вишенка на торте - тормозящее.
Работал я как-то у тимлида, который обожал кукареки про быстродействие sql и правильно составленные запросы. Когда выяснилось, что запросы даже с 4 джойнами работают всё ещё быстрее его сраного поиска по jsonнам, жопу ему разнесло как в хиросиме.
Денормализация делается отдельными индексными таблицами, и при ОЧЕНЬ ОСТРОЙ необходимости. Нахуй джсоны.
>запросы даже с 4 джойнами работают всё ещё быстрее его сраного поиска по jsonнам
Четыре LEFT джойна подряд могут занять четрые гб памяти изи. А подзапрос к четвертому джойну может насрать тебе в чай, потому что ты нагло пиздишь про скорость поиска по json'ам. Давай пруфы скорости, маня.
>Денормализация делается отдельными индексными таблицами, и при ОЧЕНЬ ОСТРОЙ необходимости. Нахуй джсоны.
По jsonb полю можно строить индекс. Gin или обычный btree, на любой вкус.
JSON в реляционную базу - минус мать
Я вас пидарасов с жсоном в базе всех сгною нахуй, вы черви-пидоры с говном в голове, пишете свою поебень в монгоебень или сразу в dev/null, быстро пиздец.
Ты своей тупорылой башкой понимаешь зачем вообще нормализуют данные? Текстовые поля тоже нормализуешь, дебич?
Я как раз отлично понимаю.
Если тебе надо сохранять хуиту в базу, которую целиком нужно писать/читать по айди - тебе нахуй не нужна для этого реляционная база, в противном случае, если у этих данных подразумевается структура, то нужна схема и нормализация, то есть не нужно JSON-говно.
JSON в реляционной базе, это как Any в статически типизированном языке.
>Ты нормализуешь текстовые поля?
Нормализовать можно таблицу, а не поля.
Тебе из моего ответа непонятно что нормализовать нужно то у чего есть интересующая структура? Если этот текст везде используется целиком (его структура не важна), - он хранится в одном поле, если важны составляющие - они хранятся отдельно.
JSON это блядь строка. Тебе, долбоебу, просто дали возможность эту строку анализировать. LIKE в запросах использовал, а ~ ? Так вот это то же самое.
И никто не хочет ради нескольких приятных фишек поднимать другую базу, мейнтейнить её, ебаться с синхронизацией. Это блядь всем очевидно, топовые разработчики Postgres'а годами работают над удобной и быстрой работой с JSON https://www.youtube.com/watch?v=WtkhZ5P1uA8
>JSON это блядь строка.
А, ясно, ты - дебил. Массив, стало быть, - тоже строка.
JSON в первую очередь подразумевает структуру, с полями и вложеностями (и неявно, так как их и нет - с типами).
Дебилы которые хуярят JSON в реляционную базу делятся на 2 вида:
1. Слегка дебилы. Они сохраняют JSON, структура которого не важна и будет важна. Эти люди скорее всего просто не осведомлены, что писать и читать всякое говно по ключу в реляционку не обязательно, что для этого есть масса других более подходящих инструментов.
2. Критические дебилы. У них просто нет мозга для надлежащего дата-дизайна, поэтому любую мало-мальски сложную структуру они энкодят в JSON и пихают в базу. Нахуя им вообще нужна реляционка, когда есть монгоперделка и другие доступные их имбецильным мозга хэш-таблицы - это остаётся загадкой природы.
Что же происходит когда все эти груды JSON-говна надо наконец захендлить? Ну они пишут горы невменяемого быдлокода с миллионом ифов, где через строчку гадают есть ли такое-то поле, нужного ли оно типа, не лежит ли там нулл, действительно ли существует такой айдишник - подобное вот петушение, которое без крови из глаз читать невозможно. А всё из-за недостатка когнитивных способностей.
Не знаю к какому виду дебилов ты относишься, сначала думал что к первому, но после твоего сравнения JSON с текстом - подозреваю что ко второму.
В любом случае продолжать с тобой разговор бесполезно. Просто выйди в окно - сделай миру хорошее.
Я видимо к первым отношусь. Пихаю джейсон в виде разных payload полей, которые никак не влияют на работу базы, а используются только бизнес логикой. По мне удобнее, чем нормализовать всю базу под кучу возможных вариантов таких документных записей.
мимо
>А, ясно, ты - дебил. Массив, стало быть, - тоже строка.
Тухлодырый ты пиздобол. "JSON is a text format" цитата блядь из RFC. Но тебе, хуесосу, конечно виднее что массив, а что текст.
>Эти люди скорее всего просто не осведомлены, что писать и читать всякое говно по ключу в реляционку не обязательно, что для этого есть масса других более подходящих инструментов.
Понятно, ты джун, который нихуя не понимает что такое гетерогенность и её последствия.
>В любом случае продолжать с тобой разговор бесполезно. Просто выйди в окно - сделай миру хорошее.
Тебе ещё и 18 нет.
Все ясно, дело раскрыто. Малолетний долбоеб, который с реальной базой никогда не работал, прочитал в википедии что такое четвертая нормальная форма.
>Давай пруфы скорости, маня.
Держи.
4 объекта, Data1, Data2, Data3 и Data4.
У каждого есть code, и привязки Data1->Data2, Data2->Data3 и тд.
Использовалась доктрина, но жестко прописывался селект во всех случаях, так что она возвращала массивы.
Делал 10000 выборок на каждый тип запроса.
Самое быстрое как и ожидалось поиск по прямому значению.
4 джойна сделали запрос тяжелее (естественно, лол), но не настолько как ожидалось.
А вот поиск в json оказался самым прожорливым. Причем прошу заметить json был одноуровневый.
Не надо меня деанонить позязя.
Ты кукухой поехал? Где запрос? Где схема базы? Какой нахуй пхп?
Вот тебе песочница https://dbfiddle.uk/?rdbms=postgres_12 напиши запросы по человечески.
Делай сам, лол. Но ты не сделаешь. Криворукий петуч с джсоном в базе (ЕБАТЬ МОЙ ХУЙ ГОВНО КРИВОРУКОЕ КРИВОЖОПОЕ ОТКРЫВАЕТ РОТ БЛЯДЬ) выебывается в треде.
Делать мне больше нехуй как прямые запросы писать.
Это троллинг тупостью? Возьми запрос, который сгенерила доктрина и сделай EXPLAIN. Пиздец, нахуй ты вообще выполз, дегенерат?
Что я получу, когда это сделаю? Твою порванную в клочья сраку окончательно? Зачем мне это?
Если бы ты общался культурно, я бы подумал над этим. Если бы тебе действительно было интересно, ты бы проверил сам. А так я только в лучшем случае добьюсь твоего слива.
Один в один история как с петухом, под руководством которого я работал 3 месяца. Когда он увидел, что я выкинул к хуям весь его код, упростил запросы вдвое и добился прироста производительности, он изошелся на говно.
В нынешней конторе мы просто не суем массивы в базу, всё. Ладно, суем, но только в тех случаях когда там будет хер знает что и по этому хер знает чему не будет никакой сортировки или поиска..
Че ты так порвался? Написать все это на пхп было в сто раз сложнее, чем сделать explain. У меня вообще ощущение, что это был не твой пост, а ты просто мимо проходящий хуеплет.
>Че ты так порвался?
Аргумент "у вас баттхерт" был моветоном уже в 2012. Простите, сэр, но в наше время это безнадежно устарело.
>Написать все это на пхп было в сто раз сложнее, чем сделать explain.
И фикстуры с псевдоданными заполнить, ага. И ключи для связей проставить. И индексы ручками генерить вместо кнопки в админке. Я слишком долго не имел дела с прямыми запросами, что бы ебаться с этим. Спулить 3 бандла и набросать схему мне гораздо проще.
Если бы тебя действительно это интересовало, ты бы сам проверил.
Я занялся этим только из спортивного интереса. Я знаю, как именно работает БД (без совсем уж подробностей, но в общих чертах), поэтому утверждение о том, что поиск в массиве может быть быстрее джойнов заставило меня охуеть. Я просто убедился в том, что я ещё не ебанулся и это говно таки медленнее, как и должно быть. Скриншот скинул для анонов.
Тут есть небольшой подвох. MySQL кеширует ответы на запросы, потому для чистоты эксперимента стоит добавлять SQL_NO_CACHE ( https://dev.mysql.com/doc/refman/5.6/en/query-cache-in-select.html ) в запрос. У тебя их нет, и если ты запустишь свой код второй раз, возможно, что ответы возьмутся из кеша и не будут отражать действительность.
Вторая проблема в том, что первому запросу может быть тяжелее выполняться, так как на момент его выполнения все данные лежат на диске, а последнему запросу не надо их загружать с диска, они уже в памяти. Чтобы избежать этого, тест можно прогнать первый раз для "прогрева" и второй раз уже для измерения.
Стоит учитывать эти 2 момента, чтобы не получить искаженные результаты.
Ну и то, что джойны тормозят - это не совсем так. Конечно, если джойнить и фильтровать 2 огромные таблицы без индексов, то будет тормозить, но разве джойны в этом виноваты?
>У тебя их нет, и если ты запустишь свой код второй раз, возможно, что ответы возьмутся из кеша и не будут отражать действительность.
У меня кеш по умолчанию отрублен. Ради интереса перепроверил, нихуя не поменялось.
А вот забавный момент - плейсхолдеры дают реальный прирост быстродействия, не ожидал. Конечно, на реальном проекте за 30000 запросов выебут, но тут они дали полуторократный прирост скорости.
>Ну и то, что джойны тормозят - это не совсем так.
Мне ОЧЕНЬ сильно печет жопу то, что с воплями про страшные и ужасные джойны делают кривую структуру БД, которая в результате тормозит сильнее чем изначальные джойны. Видел своими глазами. Данный товарищ со своими массивами просто проехался по старому бугурту.
Какими нахуй массивами, долбоеб? Я вообще всю дорогу говорил про тип данных jsonb в постгресе. Для которого давно есть индексы и язык запросов. Но ты же гений (долбоеб), который генерит запросы с помощью ОРМ без explain'а, и при этом высирающий что-то про тормоза и кривую структуру бд.
>Я вообще всю дорогу говорил про тип данных jsonb в постгресе.
Вот именно его я и использовал.
>Для которого давно есть индексы и язык запросов.
Использовался именно этот запрос.
И оно тормозит.
>Но ты же гений (долбоеб)
Оскорбления от человека, который на полном серьезе засовывает в БД json и рассказывает, как это заебись, не трогают меня, извини. Ты как слюнявый деревенский дурачок со спущенными штанами, который кричит прохожим, что у них грязные волосы. Я просто тыкаю в тебя палкой для собственного веселья, пока мне не надоест. Я потратил на тебя время, в ответ слышал только бессмысленные оскорбления, голословные (и насквозь лживые) утверждения о производительности, которые я опровергнул для себя, и требования предоставить больше данных. Ты этого не заслуживаешь, сори.
>Ну а yii в этом ряду откуда тогда?
Именно 3 указзанных мной фреймворка указаны в вакансиях. Зачастую так же в один ряд. Мол "знаещь хоть один? Пойдёт".
$a = null;
$b = $a["random_key"]; // $b == null !
$a["another_key"] = 100500; // $a теперь Array!
вы че ебанутые? вы че блять реально ебанутые?
Yii это маркер вакансий уровня "НЕ ЛЕЗЬ, ОНА ТЕБЯ СОЖРЁТ!". Соответственно, не лезь, анон, оно реально тебя сожрёт.
Переменная на то и переменная
А что собсна не так?
Конструкция $var[] = 321; добавляет новое значение в массив.
И есть простой вызов $var['random'], который возвращает пустое значение, так как оно пустое. =)
Этим же $var[рандомный индекс] можно брать символы из строки с соответствующим индексом.
Это каким же долбоебом нужно быть, чтобы писать что-то о производительности запросов используя ссаную ОРМ.
>Да медленнее епты, только запрос я не покажу. Какой нахуй эксплейн? Какой план запроса? Просто лень постить, все там медленнее. Просто это ты хуевый, поэтому запрос я постить не буду. Но там точно медленнее.
Одни из лучших программистов на планете пять лет ебуться чтобы добавить поддержку JSON работающую быстрее чем у оракл и монги. Но долбоебу на двачах нинужно. Ему ебать орм запросы пишет. У него все три таблицы в базе нормализованные, а значит никому больше JSON не нужон.
Ну подставляй ебало, долбоеб. Вот тебе тест производительности https://dbfiddle.uk/?rdbms=postgres_12&fiddle=d41fe5001e04b9f96465de3194c3060b запросы детские, чтобы ты, чмоня, в них разобрался.
Четыре LEFT JOIN' а подряд. Против Json path запроса в одну строчку. По скорости json выигрывает в два раза, по затратам в десять.
Так что, кукаретик, свои запросы запостишь? Какое на этот раз будет оправдание?
Ну давай разбирать по частям тобой написанное.
https://dbfiddle.uk/?rdbms=postgres_12&fiddle=2300a430c9380dd5a5979eb1769a88e4
Вот мы добавляем ещё одно условие и сортировку, и наша быстрота куда-то испаряется, потому что json говно оно и есть говно.
Да, я прекрасно знаю, что у нас теперь разные по факту запросы (проблема в wildcard и and), мне на это похуй. Можешь сам написать как правильно, я в этом не разбираюсь и не желаю разбираться.
Самое главное - в случае join ты получил именно требуемые данные.
В случае выборки json ты выбираешь его целиком. В результате в дереве у тебя пачка элементов, с fifth.id не удовлетворяющими твоему условию. Что ты будешь с ним делать?
Ну то есть я знаю, ты будешь петушить результат выборки перебором в коде, конечно. Muh speed.
>запросы детские
ну это неудивительно, чем сложнее будут запросы тем отсос json говна будет глубже.
Товарищ, который запостил
https://dbfiddle.uk/?rdbms=postgres_12&fiddle=34f95d845ab52b07b68c8aa37058b522
очень глубоко и сильно неправ. Это грубая архитектурная ошибка. Property не должно быть привязано к Product никаким образом. А вот Value привязано к обеим.
Вот это
https://dbfiddle.uk/?rdbms=postgres_12&fiddle=28a2795b841b1879b68413f0e10aea9c
Правильный вариант.
На всякий случай объясняю - что бы просьба отсортировать по диагонали не вызывала безысходный обсер. (У меня тоже не всё заебись, у Property должен быть Type и ссылка на НЕСКОЛЬКО РАЗНЫХ таблиц, в которых может быть INT, STRING и тд в колонке VALUE, а в нынешней схеме виден обсер при сравнении дианонали), но такая структура значительно ближе к рабочему варианту.
Где ты вообще там увидел Product? Там схема ProductType<-Property<-Value. Это вообще все сделано чтобы показать как можно использовать JSON в vaue.
>Вот мы добавляем ещё одно условие и сортировку, и наша быстрота куда-то испаряется, потому что json говно оно и есть говно.
Криворукий ты обмудок. Кого ты хочешь наебать? Пенек осиновый, ты ведь нихуя не понимаешь почему json тут быстрее, и почему я с самого начала знал что он быстрее.
JSON Path запрос выполняется всего один раз на каждый документ. А джойны генерят записи в геометрической прогрессии, примерно 350К записей по 14 колонок. Снаружи весь этот пиздец может быть не видно, но в память все это попадает перед фильтрацией. И чем больше связей, тем медленнее это будет работать. И никакие индексы тут не помогут, потому что размер индексов приближается к размеру самой таблицы. С каждым новым джойном затраты на Json path будут возрастать линейно, в то время как обычные SQL запросы будут убивать сервер нахуй. Я добавил всего 100К записей на пятый уровень и время увеличилось до секунды, в три раза медленнее чем json path. С миллионом не факт что вообще выполнится, а не отвалится по таймауту.
Это физический предел реляционной модели, манипулировать в запросах иерархиями такой глубины становится просто не выгодно.
https://dbfiddle.uk/?rdbms=postgres_12&fiddle=f8de9cd4c650a284b1c6d3416b2e06d3
Ссу тебе на ебало второй раз. Начинай маневрировать.
>а, я прекрасно знаю, что у нас теперь разные по факту запросы (проблема в wildcard и and), мне на это похуй
Что ты несешь долбоеб криворукий? С какого хуя вдруг они стали разными? Я специально добавил подсчет количества, чтобы было видно что выборка одинаковая. Если запрос составлен правильно, то количество записей будет одинаковое. Это же надо так обосраться, беги читать в википедии как лефт джойны работают.
>В случае выборки json ты выбираешь его целиком. В результате в дереве у тебя пачка элементов, с fifth.id не удовлетворяющими твоему условию. Что ты будешь с ним делать?
Это троллинг тупостью? Это типа не очевидно, что раз можно сделать запрос любой сложности, то и достать нужный кусок тоже можно? Специально для тебя долбоеба добавил запрос, который возвращает только элементы, в которых fifth.id удовлетворяет условию.
Обоссан по всем пунктам. Но ты ловко вильнул сракой и опять не запостил свои запросы, которые сто проц доказывают что json говно. Какое оправдание будет на этот раз?
>Вот мы добавляем ещё одно условие и сортировку, и наша быстрота куда-то испаряется, потому что json говно оно и есть говно.
Криворукий ты обмудок. Кого ты хочешь наебать? Пенек осиновый, ты ведь нихуя не понимаешь почему json тут быстрее, и почему я с самого начала знал что он быстрее.
JSON Path запрос выполняется всего один раз на каждый документ. А джойны генерят записи в геометрической прогрессии, примерно 350К записей по 14 колонок. Снаружи весь этот пиздец может быть не видно, но в память все это попадает перед фильтрацией. И чем больше связей, тем медленнее это будет работать. И никакие индексы тут не помогут, потому что размер индексов приближается к размеру самой таблицы. С каждым новым джойном затраты на Json path будут возрастать линейно, в то время как обычные SQL запросы будут убивать сервер нахуй. Я добавил всего 100К записей на пятый уровень и время увеличилось до секунды, в три раза медленнее чем json path. С миллионом не факт что вообще выполнится, а не отвалится по таймауту.
Это физический предел реляционной модели, манипулировать в запросах иерархиями такой глубины становится просто не выгодно.
https://dbfiddle.uk/?rdbms=postgres_12&fiddle=f8de9cd4c650a284b1c6d3416b2e06d3
Ссу тебе на ебало второй раз. Начинай маневрировать.
>а, я прекрасно знаю, что у нас теперь разные по факту запросы (проблема в wildcard и and), мне на это похуй
Что ты несешь долбоеб криворукий? С какого хуя вдруг они стали разными? Я специально добавил подсчет количества, чтобы было видно что выборка одинаковая. Если запрос составлен правильно, то количество записей будет одинаковое. Это же надо так обосраться, беги читать в википедии как лефт джойны работают.
>В случае выборки json ты выбираешь его целиком. В результате в дереве у тебя пачка элементов, с fifth.id не удовлетворяющими твоему условию. Что ты будешь с ним делать?
Это троллинг тупостью? Это типа не очевидно, что раз можно сделать запрос любой сложности, то и достать нужный кусок тоже можно? Специально для тебя долбоеба добавил запрос, который возвращает только элементы, в которых fifth.id удовлетворяет условию.
Обоссан по всем пунктам. Но ты ловко вильнул сракой и опять не запостил свои запросы, которые сто проц доказывают что json говно. Какое оправдание будет на этот раз?
Ты понимаешь, что этими 2 типами запростов ты решаешь принципиально разную задачу?
При создании массивов через рандом у тебя получается пирамида зависимостей.
Часть элементов пустые, часть заполненные.
https://pastebin.ubuntu.com/p/rBvgGmKG57/
Здесь json из твоей базы, удовлетворяющий условию. Смотри на него внимательно. В нем есть такие шикарные элементы, как third null, к примеру.
Что нам с ними придется делать? Правильно, в коде как мы их получили проверяем.
Фактически, своим json ты решаешь следующую задачу - выбрать ПЯТЫЙ круг, прилинкованные к нему элементы ПЕРВОГО круга (через всю цепь) и все дети ПЕРВОГО круга на похуях. Ну типа потом мы в коде их как - нибудь обработаем.
Не возражаешь, если я так же решу задачу джойнами? Линкуем сразу 5 круг на первый.
https://dbfiddle.uk/?rdbms=postgres_12&fiddle=7dc49b28145f6aa023b5093477c63c86
Смотрим на перфоманс и орем.
Из-за того, что я линковал тир к первому рандомом вместо правильной цепочки, там разное количество элементов. Если линковать правильно будет одинаковое. Можешь заняться.
То есть, я беру твою базу с json и нормализую.
Теперь у меня есть 2 пути.
1. Либо ОЧЕНЬ прожорливый запрос, который тем не менее выдает абсолютно чистые данные, с которыми потом гораздо быстрее работать.
2. Либо запрос, который решает твою задачу, но экономичнее в 100 раз.
Оба пути обладают своими плюсами и минусами. Оба пути позволяют отнести твою json базу туда, где её и место - на помойку.
Давай остановимся на втором варианте? Я ускорил твой запрос в 100 раз. Это достаточно, что бы до тебя дошло, что ты творишь дичь? Я ожидаю новый поток визга и оскорблений, но на этом этапе я просто молча ухожу, считая дальнейшее общение бессмысленным. Оставайся пердолить свой полудохлый сервак, забитый сраным говном, и считать это хайлоадом.
У меня дежа-вю. Красный, потный Олег понимал, что он целый год пилил кривую хуйню, пялился в код, из которого была выкинута его json параша, и который работал в десятки раз быстрее его говна, был свободно расширяем в любом направлении, и судорожно придумывал как бы обосрать, вытаскивал из головы сценарии, которые решались 2 часами моей работы и вообще не прокатывали на его коде, лол.
Ты понимаешь, что этими 2 типами запростов ты решаешь принципиально разную задачу?
При создании массивов через рандом у тебя получается пирамида зависимостей.
Часть элементов пустые, часть заполненные.
https://pastebin.ubuntu.com/p/rBvgGmKG57/
Здесь json из твоей базы, удовлетворяющий условию. Смотри на него внимательно. В нем есть такие шикарные элементы, как third null, к примеру.
Что нам с ними придется делать? Правильно, в коде как мы их получили проверяем.
Фактически, своим json ты решаешь следующую задачу - выбрать ПЯТЫЙ круг, прилинкованные к нему элементы ПЕРВОГО круга (через всю цепь) и все дети ПЕРВОГО круга на похуях. Ну типа потом мы в коде их как - нибудь обработаем.
Не возражаешь, если я так же решу задачу джойнами? Линкуем сразу 5 круг на первый.
https://dbfiddle.uk/?rdbms=postgres_12&fiddle=7dc49b28145f6aa023b5093477c63c86
Смотрим на перфоманс и орем.
Из-за того, что я линковал тир к первому рандомом вместо правильной цепочки, там разное количество элементов. Если линковать правильно будет одинаковое. Можешь заняться.
То есть, я беру твою базу с json и нормализую.
Теперь у меня есть 2 пути.
1. Либо ОЧЕНЬ прожорливый запрос, который тем не менее выдает абсолютно чистые данные, с которыми потом гораздо быстрее работать.
2. Либо запрос, который решает твою задачу, но экономичнее в 100 раз.
Оба пути обладают своими плюсами и минусами. Оба пути позволяют отнести твою json базу туда, где её и место - на помойку.
Давай остановимся на втором варианте? Я ускорил твой запрос в 100 раз. Это достаточно, что бы до тебя дошло, что ты творишь дичь? Я ожидаю новый поток визга и оскорблений, но на этом этапе я просто молча ухожу, считая дальнейшее общение бессмысленным. Оставайся пердолить свой полудохлый сервак, забитый сраным говном, и считать это хайлоадом.
У меня дежа-вю. Красный, потный Олег понимал, что он целый год пилил кривую хуйню, пялился в код, из которого была выкинута его json параша, и который работал в десятки раз быстрее его говна, был свободно расширяем в любом направлении, и судорожно придумывал как бы обосрать, вытаскивал из головы сценарии, которые решались 2 часами моей работы и вообще не прокатывали на его коде, лол.
>Здесь json из твоей базы, удовлетворяющий условию. Смотри на него внимательно. В нем есть такие шикарные элементы, как third null, к примеру.
>Что нам с ними придется делать? Правильно, в коде как мы их получили проверяем.
Ты в натуре ебанутый? Они пустые, потому что я их оставил пустыми, долбобеб. Я блядь своими руками создал этот JSON, убрать их дело двух секунд.
>Не возражаешь, если я так же решу задачу джойнами? Линкуем сразу 5 круг на первый.
Вот тут в голос. Ебать ты гений, лимит 400 поставил. 400 чего? Попугаев? Пиздуй в википедию читать как лефт джойны работают.
На сколько же ты хуевый. Ты продублировал колонку (не денормализация), добавил кучу foreign key'ев (долбоеб, там индексы и так есть), а производительность улучшилась только когда ты выкинул нахуй весь запрос и он теперь выдает рандомную хуйню. Буквально случайный набор цифр и букв.
После своих 20 IQ мувов ты больше не можешь добавлять записи на пятый уровень не зная какой id будет на первом. А как их получить? Да надо блядь опять пройти по всей иерархии, долбобеб. Ты же просто нагенерил случайной хуйни и этот Id просто не соответствует положению элемента в иерархии. Ахахахах, я до этого думал что ты просто джун, но теперь то понятно что ты с базой не работал никогда в своей жизни.
>То есть, я беру твою базу с json и нормализую.
Никто не делает всю базу на json, долбаеб. Ты просто можешь создать копию данных для более удобного поиска по ним. Собственно так и происходит в мое сниппете, слепой ты дегенерат.
>запрос, который решает твою задачу, но экономичнее в 100 раз
Охуенно ускорил, кек. Выдает рандомную хуйню, зато быстро.
>Давай остановимся на втором варианте? Я ускорил твой запрос в 100 раз. Это достаточно, что бы до тебя дошло, что ты творишь дичь?
Что ты ускорил, долбоеб? Ты типа думал я не открою и не посмотрю, или как? Ты серьезно думал что я не увижу лимит? Ты серьезно думал что я не увижу что запрос выдает мусор?
>я просто молча ухожу
А как же твои запросы, которые тебе так было лень показывать? Опять вильнешь сракой и проигноришь? Показывай запросики, хуйлуша.
>Здесь json из твоей базы, удовлетворяющий условию. Смотри на него внимательно. В нем есть такие шикарные элементы, как third null, к примеру.
>Что нам с ними придется делать? Правильно, в коде как мы их получили проверяем.
Ты в натуре ебанутый? Они пустые, потому что я их оставил пустыми, долбобеб. Я блядь своими руками создал этот JSON, убрать их дело двух секунд.
>Не возражаешь, если я так же решу задачу джойнами? Линкуем сразу 5 круг на первый.
Вот тут в голос. Ебать ты гений, лимит 400 поставил. 400 чего? Попугаев? Пиздуй в википедию читать как лефт джойны работают.
На сколько же ты хуевый. Ты продублировал колонку (не денормализация), добавил кучу foreign key'ев (долбоеб, там индексы и так есть), а производительность улучшилась только когда ты выкинул нахуй весь запрос и он теперь выдает рандомную хуйню. Буквально случайный набор цифр и букв.
После своих 20 IQ мувов ты больше не можешь добавлять записи на пятый уровень не зная какой id будет на первом. А как их получить? Да надо блядь опять пройти по всей иерархии, долбобеб. Ты же просто нагенерил случайной хуйни и этот Id просто не соответствует положению элемента в иерархии. Ахахахах, я до этого думал что ты просто джун, но теперь то понятно что ты с базой не работал никогда в своей жизни.
>То есть, я беру твою базу с json и нормализую.
Никто не делает всю базу на json, долбаеб. Ты просто можешь создать копию данных для более удобного поиска по ним. Собственно так и происходит в мое сниппете, слепой ты дегенерат.
>запрос, который решает твою задачу, но экономичнее в 100 раз
Охуенно ускорил, кек. Выдает рандомную хуйню, зато быстро.
>Давай остановимся на втором варианте? Я ускорил твой запрос в 100 раз. Это достаточно, что бы до тебя дошло, что ты творишь дичь?
Что ты ускорил, долбоеб? Ты типа думал я не открою и не посмотрю, или как? Ты серьезно думал что я не увижу лимит? Ты серьезно думал что я не увижу что запрос выдает мусор?
>я просто молча ухожу
А как же твои запросы, которые тебе так было лень показывать? Опять вильнешь сракой и проигноришь? Показывай запросики, хуйлуша.
PHP-компонента на нашем сервере периодически плюется ошибками (они размазаны по времени, встречаются у разных юзеров), которые утверждают что AUTH_COOKIE у клиента не найден, параллельно с этим nginx часто выбрасывает ошибку 502 ("no live upstreams"). С хрена ли вдруг кука для аутентификации пропадает?
Мои теории поначалу были в том что пыха не справляется с высокой нагрузкой и поэтому nginx говорит "502", но как объяснить отсутствие куки в запросе где она всяко должна быть?
Ты все скинул в одну кучу. Я читаю властелин колец, почему у меня болит нога, а мой друг периодически обсирается.
1) Я читаю властелин колец
>AUTH_COOKIE у клиента не найден.
Непонятно почему это вдруг стало ошибкой. Куки по определению ненадежное хранилище, и нужно быть готовым к тому что там либо хуйня, либо вообще ничего нет.
2) У меня болит нога
>С хрена ли вдруг кука для аутентификации пропадает?
Куки это часть HTTP запроса, их отправляет браузер. Перед отправкой запроса браузер смотрит домен, путь и время устаревания, и принимает решение отправлять или нет куку в запросе.
Так что кука либо есть в запросе, либо её нет. Кука может быть создана таким образом, что браузер её не отправил. Например домен не совпал или она протухла. А может быть кто-то модифицировал запрос уже после получения. В любом случае нужно смотреть что приходит на nginx непосредственно от пользователя.
3) Мой друг периодически обсирается
>nginx часто выбрасывает ошибку 502 ("no live upstreams")
Эта ошибка легко гуглится. Да, пхп не успевает вовремя ответить. Определяется так же логами nginx.
>Определяется так же логами nginx
Я их анализировал. upstream_response_time везде не превышает 1.5 секунды (таймаут выставлен в 5 секунд), возможно все дело в том что max_fails выставлен в 1
>Куки по определению ненадежное хранилище
Юзер аутентифицировался и кука хранится у него сутки. Потом спустя пару часов он ловит ошибку из-за отсутствия куки, с фига ли?
И опять же: ошибки nginx "no live upstreams" всегда соседствуют с ошибками про отсутствие куки. Совпадение? Какая-то связь точно есть
Так я тебе и пишу чтобы сами запросы смотрел. Главное что на nginx пришло, а не какой друг обосрался.
Подменить нет, может спиздить чужую (session hijacking) но ты от этого никак не защитишся, ну кроме наворачивания https и подобного.
Для вспомогательных функций, которым не нужен объект ($this) и его поля. Например:
- статические конструкторы, когда мы хотим сделать несколько способов создания объекта
- функции-утилиты, паттерн unility class
>>792471
INT(10) - при выводе числа на экран зарезервировать под него 10 символов. CHAR(20) - строка из ровно 20 символов.
>>792539
Куки могут отсутсвовать у поисковых роботов.
> Пробовал создавать новые объекты vector через сlone, не получалось
Если ты клонируешь объект, содержащий другие объекты (например, клонируешь Департамент, в котором есть Работники), то основной объект клонируется, а вложенные - нет, просто в объект-клон копируются ссылки на них. Надо использовать магический метод __clone и в нем вручную клонировать вложенные объекты.
Антикризисные меры логичнее сделать в отдельном объекте ("антикризисный комитет"). Так как у каждого класса должна быть своя зона ответственности, а в твоем примере Департамент отвечает и за управление списком работников, и за антикризисные меры. Дальше добавится еще задача, ты ее снова засунешь в Департамент, и получится класс-монстр, который занимается всем на свете.
> dismissEmployee(int $id)
Неудачно сделан аргумент - id - откуда мы его должны брать, он ведь не прописан в Работнике? Логичнее было бы сюда передавать объект-работника и пусть класс сам разбирается, как его найти.
Увольнение инженеров лучше было бы сделать так:
- выбрать всех инженеров (метод в департаменте)
- отсортировать по рангу (usort)
- отрезать первые 40% (array_slice)
- уволить по получившемуся списку
То есть тут можно использовать готовые функции работы с массивами вместо сложных циклов с кучей if внутри.
> $job = get_class($search->getJob());
> $search->setJob(new $job(), $maxRank, true);
Тут стоило сделать метод changeRank() в Employee. Так как этот класс отвечает за хранение и обновление ранга, и код логичнее всего поместить в него. И $e->changeRank(...) проще читать, чем это.
Неудачно сделан учет ранга. Логично иметь объект Job с базовыми (неизменными) ставками, и отдельно поле rank, и при расчете зарплаты учитывать ранг. А ты вместо этого меняешь сами базовые ставки в объекте Job. Если вызвать метод updateJob() несколько раз, то базовая ставка будет многократно увеличена:
$emp->updateJob(3);
$emp->updateJob(3);
$emp->updateJob(3);
То есть этот метод работает некорректно.
> Пробовал создавать новые объекты vector через сlone, не получалось
Если ты клонируешь объект, содержащий другие объекты (например, клонируешь Департамент, в котором есть Работники), то основной объект клонируется, а вложенные - нет, просто в объект-клон копируются ссылки на них. Надо использовать магический метод __clone и в нем вручную клонировать вложенные объекты.
Антикризисные меры логичнее сделать в отдельном объекте ("антикризисный комитет"). Так как у каждого класса должна быть своя зона ответственности, а в твоем примере Департамент отвечает и за управление списком работников, и за антикризисные меры. Дальше добавится еще задача, ты ее снова засунешь в Департамент, и получится класс-монстр, который занимается всем на свете.
> dismissEmployee(int $id)
Неудачно сделан аргумент - id - откуда мы его должны брать, он ведь не прописан в Работнике? Логичнее было бы сюда передавать объект-работника и пусть класс сам разбирается, как его найти.
Увольнение инженеров лучше было бы сделать так:
- выбрать всех инженеров (метод в департаменте)
- отсортировать по рангу (usort)
- отрезать первые 40% (array_slice)
- уволить по получившемуся списку
То есть тут можно использовать готовые функции работы с массивами вместо сложных циклов с кучей if внутри.
> $job = get_class($search->getJob());
> $search->setJob(new $job(), $maxRank, true);
Тут стоило сделать метод changeRank() в Employee. Так как этот класс отвечает за хранение и обновление ранга, и код логичнее всего поместить в него. И $e->changeRank(...) проще читать, чем это.
Неудачно сделан учет ранга. Логично иметь объект Job с базовыми (неизменными) ставками, и отдельно поле rank, и при расчете зарплаты учитывать ранг. А ты вместо этого меняешь сами базовые ставки в объекте Job. Если вызвать метод updateJob() несколько раз, то базовая ставка будет многократно увеличена:
$emp->updateJob(3);
$emp->updateJob(3);
$emp->updateJob(3);
То есть этот метод работает некорректно.
Спасибо. Сделаю рефакторинг и отправлю еще раз =)
Есть критика от незнающих, типа "ыыы пыха гавно я вот на ноде пишу", на нее похуй. Основные проблемы пхп это то что она в мелкосреднем бизе на говноцмс и среди всяких говношопов популярна, что равняет уровень разработчиков многих с нулем, ну и сама как язык технически ну такое.
Yii и битрикс говно, симфони ок, ларавель зависит от конторы, но это RAD, поэтому тоже может быть мелкосредний биз и говно.
Вкат в симфони это типа вката в спринг на самос деле, там блин чтоб json принять по паттернам пишут ивент листенер
Можешь по документации посмотреть, там есть возможность выбрать версию. Или посмотри по чейнджлогам. Как мне кажется, что-то основное не менялось.
спасите меня от битрикса, я начинаю понимать всю его пиздецовость. Ладно сайты на нём делать, я кастомной админкой сейчас занимаюсь и это такая хуйня, что я ебал. Никакой документации, ничего. А ещё в админке битрикса 2016 год стоит, в 2к20...
Чё за функция mail() блять?
По-хорошему нужно почту отправлять через апишку почтового сервиса (mailchimp, mandrill, sendgrid, mailgun etc), желательно с авторизованного ящика/домена, иначе это говно будет фильтроваться большинством почтовых серваков с вероятностью 76%.
> Чё за функция mail() блять?
http://www.php.su/mail()
> будет фильтроваться большинством почтовых серваков с вероятностью 76%.
И попадать в спам. Для меня это не страшно - мне главное, чтобы письмо дошло, а отправляться оно в итоге будет другим образом.
>Челы, а если функция mail() не отправляет письмо с сайта - проблема ведь в хостинге?
Ты джун? Без обид, просто интересуюсь.
Проверяешь скриптом https://conetix.com.au/support/simple-php-mail-test/. Если не уходит - говоришь, что проблема в хостинге и забиваешь хуй. Количество вещей, которые могут пойти через жопу, огромно, там нужен админ.
>>793951
Ну это перебор. Это платное ультимативное решение для рассылки собственно спама.
Если ты не шлешь 100 писем про увеличение члена в минуту, просто правильно настроенного smtp хватит.
Хотя на одном проекте я аж тест написал, запускающийся каждые 10 минут с проверкой не забанили ли нам очередной ящик, лол.
> Ты джун?
В пыхе и в бэке в целом - да. У меня задачи в основном фронтовые, бэк обычно одноклеточный на битриксе наверное только такой и есть, так что развития в нем особого нет, пока работу не сменю.
А вообще это именно то, что я делал. Письмо отправлялось без ошибок функция возвращала true но не доходило.
Вот этого удваиваю, дело говорит. Но только добавлю, что зачастую действительно ограничения (отсутствие ассинхронности, рожденность, чтобы умирать) языка делают больно, потому что не всё на свете работает по принципу "получил запрос, отдал синхронный ответ и умер".
Для какого-нибудь чтения из очередей или там работы по сокетам приходится городить костыли, появляются всякие roadrunner и так далее, что безусловно решает бизнес-задачу, но всё равно технически больнее, чем если бы в php была нативная поддержка всего этого.
>>793748
Во-первых, хуёвой архитектурой (огромная связность + костыли), заточенной на статики и повальное использование магических ассоциативных массивов.
В итоге _нормально_ писать на yii очень сложно. Оно конечно лучше битрикса, но только потому, что хуже битрикса сделать продукт просто невозможно.
Кстати, в тему всяких роадраннеров, воркеров, очередей и прочего. Поработав со всеми этими технолагиями я пришёл к выводу, что самое удобный и надёжный подход это (как ни странно) рождать и умирать php на каждый запрос. Делать мини-сервер на go или ноде, который будет вычитывать сообщение и слать его через http на локалхост (ну или куда угодно), где nginx через php-fpm уже запустит php-шный процесс, который обработает запрос и отдаст ответ.
Это позволяет использовать все стандартные инструменты php, не бояться утечек памяти в пхп, не бояться "забивания" очереди десятью тяжелыми задачами и тд и тп
Делать чтение билдером/сырым sql, а запись через орм - норма.
Фасады говно, но ларавельщикам сойдет
Понял, спасибо!
Тебе нужно вторым параметрам вставить число, на сколько знаков округлять. Не понятно зачем ты написал туда знак доллара.
импортируй нужные тебе js в app.js
какой БОГАТЫЙ синтаксис у языка
Пехапе это вакансии условно 1-2 левела, а джава 2-3. Вкатиться легче в php, но и говнокода и долбоебов там на порядок больше, а зп в среднем меньше (300к сакраментальные ты вряд ли наберёшь).
В джаву вход сложнее, но там все круче и денег больше.
Так как ты джун на дваче, скорее всего ты решишь, что тебе и 40к норм, зато вкат полегче и будешь в ближайшие 5 лет копаться в говне на битриксе или (при особой удаче) на ларавеле. Жду через пять лет пост от тебя здесь вида "кококо 5 лет прошло, а я до сих пор джун-формошлеп, все работодатели козлы, помогите вкатиться).
Php я не хейчу, если что, а вот любителей лёгких путей - да.
- оставил сериализацию
- сделал увольнение сотрудников по схожести объекта (Если один равен другому - удалить)
- прилепил ко всему встроенные функции, избавился от кучи условий
- зарплата считается на основе данных в классе профессии. (базовая ставка изменяется только для антикризисных мер)
Теперь правда отличаются прошлые данные (с ideone) и текущие.
Прочитал измененный код, вроде все должно быть хорошо =).
https://github.com/Back1ng/vector
Ору, анончик. Ты сделал мой день!
У фуллстеков как раз зарплата пониже почему-то, и их многие недолюбливают. Хз почему. Вроде считается что фуллстек нихуя не знает ни фронт, ни бэк.
Каждому свое, наверное. Я понимаю дизайн питона хвалить, но жс это же пиздец.
Ну я как бы спрашиваю, можно ли использовать игрушку дьявола во благо.
Это ненормально, что у тебя переменная может быть, а может не быть. Скорее всего, этот код плохой и ненадежный.
А я Опенкарт\Октябрь и Ларавел\Люмен учил и не хочу вилкой унитазы чистить.
>>794962
Да смотря что за фуллстеки - если просят глубокое знание обоих технологий, то это как "Глубокая Глотка 15. Растянутый анус.", а если подверстать кнопку\форму, но ещё норм. Но я в любом случае контекст долго переключаю и весь день ебстись с простой задачей из другого набора буду.
Кек. В жс треде говорят, что жс - говно, а пхп - это новая продвинутая жаба. А тут пишут, что жс выглядит лучше, а пхп - песок в глаза.
В жс треде сидят продвинутые пхпшники, которые пишут на современном пхп, который оче похож на жабу. А сюда ходят юные жсеры, которые нормального пхп и не видели никогда.
Так - наблюдения просто.
мимо-не видел ни того ни другого
https://symfony.com/
>>795244
Но только именно php-вторая джава, а не джава-второй php.
И да, про "продвинутость" пыхи по сравнению с джавой могут пиздеть только те, кто эту самую джаву не видел ни разу. В неё, её виртуальную машину и экосистему вложены сотни тысяч человеко-часов. То, что сейчас в php только вводят (аннотации,дженерики), в джаве существует уже много лет и активно используется. Это не вспоминая про треды, корутины, систему типов, диалекты типа скалы и котлина и тому подобное. Про либы я вообще не вспоминаю, за годы их успели отладить, оптимизировать и документировать до очень хорошего уровня.
Джава в отличие от C#, правда, долгое время стагнировала, но сейчас вроде разгоняется, да и колтлиноскалы никуда уходить не собираются и активно развиваются.
PHP в лучшем случае влезет в её нишу, но конкурировать с ней не сможет, пока в него столько же денег и времени не вложат. А смысла вкладываться именно в пыху нет, если можно вложится в ту же джаву, какой-нибудь котлин ну или там раст/го, если хочется особо модненького.
>>795380
Принципиальные отличия:
- В системе типов (дженерики, вся фигня, сравни rxjava и rxphp какой-нибудь), на джава больше штук за тебя проверит компилятор, больше ограничений/связей можно декларативно указать на уровне кода;
- В виртуальной машине, в jvm можно тюнить сборку мусора как угодно, в итоге джава при желании может быть _очень_ производительной, куда там пехапешному JITу. Да и джавовый JIT больше умеет, насколько я понимаю;
- В подходе/архитектуре, в джава ты можешь работать с сокетами, тредами и прочими промисами нативно, в пехапе это намного большее;
Кода примерно сравнимое количество, но джава, конечно, многословнее. С другой стороны, на джаве в последнее время активно пишут в функциональном стиле, rxjava, вот это всё - и кода выходит реально меньше и выглядит оно изящнее.
Это про жаву.
..Не настолько.
> Стрессово ли?
Да тупо чилю, делаю таски, стресс только в том, что надо работать.
> Надо ли общаться с заказчиками?
Нет.
> Жёстко ли ебут по срокам?
Нет. в создаватель не иди только.
> Че по ЗП в среднем (город-миллионник)?
Челябинск же или этих заводов как грязи? У меня меньше 40, но я работаю полгода в сфере только и стартовал совсем за еду.
> Как с удаленкой?
Она есть, при надобности, но не везде. Люди считают, что удаленка приведёт к потере эффективности. Думаю всегда можно договориться.
> Кто коллеги по масти?
Ну как в айти принято, все петушня - то, что нужно.
> Да и как в целом?
Нормально.
Есть сверстанные страницы, ТЗ не особо сложное, по большей части просто вывод из базы (база заполняется мной извне), по моим прикидкам работы месяца на полтора. Самое очевидное для меня - найти на апворке, но там (в т.ч. из-за комиссии) расценки больно кусаются, да и возможно многие тупо overqualified для моей задачи (налетают по $30/h).
На fl.ru на конкурсы откликаются почти исключительно битрикс и вордпресс-макаки. Самому выискивать по портфолио там не очень продуктивно, т.к. половина игнорит, из ответивших большинство обычно тупо заняты.
Куда еще податься? Или нужно выбирать из двух стульев?
>Анон, подскажи, где искать похапе-кодера по адекватной цене?
>хорошие спецы просят много
>хреновые мне не нужны(и то не соглашаются на работу)
>где найти хорошего спеца по цене хренового и чтобы работал?
Сам-то понел чё просишь? Нанимай того, кто возьмётся за твою работу, и не выпендривайся.
Алсо учти, что если у тебя низкий рейтинг(или ты новичок) на фриланс-биржах, то опытные ребята будут работать с тобой только на своих условиях - никто не знает что ты за фрукт и что можешь вытворить в процессе сотрудничества. Хотя, скорее всего, просто откажутся, если деньгами не заманишь.
И да - фрилансер стоит дороже чем офисный сотрудник. Отталкивайся от этого факта в первую очередь. 30$/h на апворке берут только жопорукие индусы.
Так а что за тайны, кидай сюда тз и можно будет точно сказать стоит оно таких денег или нет.
- добавление пары таблиц в БД
- (возможно)расширение уже 1-2 существующих таблиц
- создание моделей: TableDataGateway(там какой-то самописный фрейм на них) под 2 сущности
- пара крудов на каждую сущность: админка и фронтенд
- скорее всего придётся верстать в админке пару страничек и на фронтенде(хз чё там - заказчик понаписал хуиты в стиле "сделай как у них")
- скорее всего будет дополнительная логика в 1 класс
Фреймворк - хз какой, на фронте - хз что. Заказчик ни в зуб ногой вообще.
Думаю запросить без скромности - там у него не сайтик нифига, а сервис, который, по-хорошему, должна делать команда.
P.S. заказ, скорее всего, не будет выполнен никогда - персонаж там сам пытается что ковырять с вёрсткой, своими руками. Сомневаюсь, что там вообще что-то получится толковое. У меня создалось впечатление, что он просто спёр\купил чужой код и пытается сделать конкурента в ру-сегменте своими руками.
Спрашиваю скорее теоретически.
>по большей части просто вывод из базы (база заполняется мной извне)
Ну, около 4-5 дней....
>по моим прикидкам работы месяца на полтора.
Либо ты где-то ошибаешься, либо чего-то очень сильно не договариваешь и там километры бизнес-логики и штук 5 сторонних сервисов.
>>796089
То, что ты перечислил, на беке делается за час. А вот с фронтом на порядок интереснее. У админки хоть как-нибудь крудошлепство автоматизированно?
>Почему так?
Офисный сотрудник сидит на жопке и получает зарплату, зянимась одним делом. За него плотют отчисления в налоговую, ему больнички можно и оплачиваемые отпуска, работку ему подкидывают потоком.
У фрилансера ничего этого нет - волка ноги кормят. Сама себе офис, менеджер, маркетолог, программист и директор. Примерные цены на фрилансера можно посмотреть у чуваков, которые работают по ИП и договору - у них стоимость работы не сильно отличается от веб-студий.
Всё, что меньше этих сумму - очень большой риск проебать деньги и время.
Вообще, по моим наблюдениям, в СНГ создалась какая-то извращённая иллюзия, что на фрилансе сайтики за 2к делают, и везде дёшево всё. Тогда как сам СНГ-фриланс уже некоторе время в стабильной коме, как Алёха. Хуй знает почему так.
> Вообще, по моим наблюдениям, в СНГ создалась какая-то извращённая иллюзия, что на фрилансе сайтики за 2к делают, и везде дёшево всё
Потому что заходишь на кворк, а там 500 рублей вёрстка большой страницы. Только если глубже зайти в услугу, там выяснится, что цена другая, но и там будет не так уж и дорого.
> Тогда как сам СНГ-фриланс уже некоторе время в стабильной коме
Всмысле работать некому? Или заказов нет? Если первое, то я готов. Вёрстка хуйни любой сложности, фронтенд почти любой сложности, бэкенд на уровне "для цмс сойдёт". Недавно с нуля сайт заебашил на работе, причём вроде для бохатой конторы и им в принципе норм мне нет, тк я получу всё те же копейки.
>на беке делается за час
Там ещё и существующий переписывать надо под его логику. Ему не только добавление нового функционала надо, но и расширение уже существующего под новый.
>А вот с фронтом на порядок интереснее.
Так самая мякотка. У него только "хочу как у них" там веб-сервис с точно таким же дизайном и цветами, прям 1в1, но более прокачанный.
>У админки хоть как-нибудь крудошлепство автоматизированно?
Не похоже. Там просто MVC-фреймворк какой-то самописный.
>Всмысле работать некому? Или заказов нет?
Много сложных и комплексных заказов за условные 500руб.
Простые вещи они сами стараются делать. Видел домохозяйку, которая своими кривыми руками поломала свой лендинг и пошла на фриланс чтобы ей за 300 рублей всё обратно починили.
Много перекупов, а они ни нормальное тз обеспечить, в большинстве своём, не могут, ни отклик своевременный, ни оплату достойную.
Много людей, которые ничего заказывать не собираются, но создают заявки. Либо это кто-то смотрит сколько будет стоит их хотения так-то оценка задачи это тоже работа, либо сами создатели фриланс-бирж эти фейки публикуют для видимости.
Зацени сколько задач на средней бирже в выполнение улетает - порядка 10-15%, что намекает.
>Вёрстка хуйни любой сложности, фронтенд почти любой сложности, бэкенд на уровне "для цмс сойдёт".
Речь не о том, что ты можешь, а скорее о том, за сколько ты это готов продать. СНГ в большинстве своём не может купить твою работу за приемлемую цену.
Алсо много разводил и кидал с обеих сторон. Очень дохуя их. И поэтому если встречаются норм заказчик и норм исполнитель, то они долго не расстаются, понимая весь пиздец вокруг. Кстати, именно поэтому толковые фрилансеры всегда заняты работой.
>Ну, около 4-5 дней...
>чего-то очень сильно не договариваешь
Да нет, там действительно 80% - это тупо вывод. Просто страниц немало, плюс я закладываю время на правки, коммуникацию и чай. Могу ошибаться в оценках времени, но сложного кода точно не предвидится.
>>795997
>>796145
>Примерные цены на фрилансера можно посмотреть у чуваков, которые работают по ИП и договору - у них стоимость работы не сильно отличается от веб-студий.
Меня просто жаба душит платить русским на апворке 5000$/мес, когда на фуллтайм на hh.ru куча вакансий по 100к/мес. Я понимаю, что фрилансер захочет какую-то премию, но не тройную же.
Какой вообще сейчас адекватный прайс за месяц работы yii-фрилансера средней паршивости?
>жаба душит платить русским на апворке 5000$/мес
Классека. Найми индуса тогда - с ним даже объясниться нормально не сможешь.
>когда на фуллтайм на hh.ru куча вакансий по 100к/мес
Нологи с этой зарплаты посчитал? Электричество и прочую хрень?
Программер стоит не 100к\мес, а полную сумму. Сверху прикинь зряплату директора конторы - он тоже не даром там работает.
На хх вообще нефиг смотреть в твоём случае - ты человек не в офис берёшь.
Ты какой-то мутный хуй. Будет миллион желающих сделать месячный кусок работы за 100к, какие нахуй 5000$.
Ты если на fl напишешь "yii макака, 100к за месячный объем работы", то заебешься предложения разгребать. Бля, да я сам хоть ленивый хуй, и бабки не проблема, но подкалымил бы за 100к делая "просто вывод из базы".
Так что, сдается мне, ни о каких 100к речи не идет. А идет речь о чашке риса за сложную хуйню, за которую тебе самому браться не охота.
>но не тройную же
Эта тройная ставка подразумевает, что 2/3 времени из тебя будут клещами тянуть ТЗ, условия, допданные и прочую хрень.
Я очень сильно нагревался, когда целый день выяснял, что клиент хочет, что ему надо и как это реализовать в условиях кучи его говнокода, а потом мне на голубом глазу заявляли - ну ты же 10 строчек написал, там не больше получаса.
Разобрался, спасибо!
Просто одно дело - запилить абстрактный круд для микросервиса с аутентификацией и пользователями, и совсем другое - мутная комплексная хрень похожая на работу на пару дней времени.
Стоит связываться?
Может, у меня просто неудачный опыт был с прошлыми двумя сайтами (на текущий сайт я еще не искал кодера, хотел перед этим проконсультироваться на двачах). Но спасибо, мне нужно было мнение со стороны. Видимо, чуваки перезакладывали, не зная, чего от меня ожидать как от заказчика.
Деньги-то есть, и 100к и 200к вообще не вопрос. Просто пытался понять, нормальна ли такая ситуация, какие вообще рыночные расценки сейчас и где еще помимо fl.ru и апворка стоит искать. Более-менее понял.
Тебе уже сказали, что русский фриланс - это гремучий клубок со змеями с запредельным уровнем кидалова с обеих сторон.
Как заказчик рискует получить хуесоса, который сделает все через жопу, так и исполнитель имеет шанс попасть на бабки. Причем эти шансы абсолютно непотребные.
Лучше поищи через знакомых. Ну или в треде фейкомыло оставь, мб кто-то свяжется. Было бы лучше всего, если бы ты сам в этом разбирался хоть поверхностно и имел возможность контролировать процесс.
Да причем здесь русский фриланс или не русский.
У поциента просто концы с концами не сходятся.
Сначала говорит что задачи тривиальные и индусы для них слишком хороши, потом говорит что не хочет битрикс макак.
Сначала говорит что готов платить по цене рынка, потом какой-то лепет про неудачный опыт.
Я вижу типичное кроилово, когда за чел пытался найти долбоеба за еду. А теперь какие-то охуительные истории рассказывает про "200к не вопрос". Что несет, вообще охуеть.
>потом говорит что не хочет битрикс макак
Ни один человек в здравом уме не захочет Битрикс макак, это я говорю как Битрикс макака. Это говно криво, косо и ужасно.
Тривиальные задачи на нем превращаются в жопоеблю на ровном месте.
Какое говно? Битрикс макака крива и ужасна? Кто на ком верхом ездит и в жопу ебет? Ты можешь отличать инструмент и программиста?
Битрикс программисты зачастую не очень как программисты.
1. На Битрикс неплохо так платят и поэтому многие просто зависают там и никуда дальше не двигаются по скиллам.
2. На Битрикс не используются распространённые паттерны и решения, придуманные и вылизанные тысячами других программистов. Это такой манямирок обособленный. Помню, как какой-то чел радовался когда к ним в битрикс-команду пришёл новичок с умением в Симфони - типа тот, говорил, просто на голову выше местных макак оказался.
Ну бывают фреймворки и похуже. Ларавел хуже с точки зрения архитектуры, но зато попроще симфони и менее требовательный к прослойке между креслом и монитором. Но при этом наголову лучше всякого дна типа битрикса. Я бы сказал, есть Москва (Симфони), созданная по образу других европейских столиц (Берлин) с кучей денег и тп. Есть какой-нибудь Новосибирск (Ларавел), который вроде тоже ничо так, но сравнивать их глупо. А бывает Барнаул или вообще деревня Нижние Васюки (Битрикс).
>>796906
Битриксоиды как правило совсем не программисты, примерно как таксисты как правило не очень бизнесмены. Битрикс - мало того, что сделан из говна, так ещё и является CMSкой, то есть, всё уже написано, и "программисту" надо просто собрать квадратно-гнездовым способом сайт из набора кубиков. Ни о каком моделировании предметной области, эффективной работе с базой и тд и тп и речи не идёт: есть +- готовые шаблончики, из них и лепится всё с минимальной доработкой напильником, чтобы было похоже на то, что нужно заказчику.
Это, правда, не проблема конкретно битрикса, это проблема всех CMS-ок - ориентация на накликивание мышкой и настроечки. Битрикс просто ещё и ужасен по качеству исполнения.
Интересное сравнение, благодарю!
Нахуй ты мне это рассказываешь? Чел пишет что индусы на апворке видите-ли для него скилловые дохуя. А тут ты высрался. Как попка блядь. "Битрикс говно". Тебе говорят что речь не про битрикс вообще. А ты опять за каким-то хуем начинаешь расписывать какое он говно. Говно, епты, говно, успокойся.
Битрикс программисты идиоты что-ли клинические? Да блядь любой джун справится данные из базы в шаблон прокинуть. А если нужна дохуя архитектура, так хули тогда ценник на работу сбивать.
>>796916
>моделировании предметной области
Понесло макакена. Ты давно предметную область моделировал, поехавший? С доменными экспертами евент шторминг хуярил? Охуительный манямир. Да в 99% самых топовых компаний на симфони ты будешь "моделировать" таблички в базе и формы хуярить, просто за бОльшие бабки. Предметная область, пиздец вообще. Битрикс говнище - это факт, но бля, в себя приди, ты на пхп пишешь, а не на С#.
Я понял твою очку зрения, но ты не прав.
Любую (то есть, вообще любую) работу можно сделать как хорошо, так и плохо. Под хорошо/плохо в данном случае я подразумеваю возможность расширения/тестирования/производительность.
Я работаю и на симфони, и на битре. На симфони продукт делается ПРОЩЕ, качественнее и быстрее.
>Битрикс программисты идиоты что-ли клинические?
Те, кто не знает ничего кроме битры - да.
Ой все иди в пизду. Вам ботам ебучим что-то объяснять, только время тратить. Шел разговор, о том что для охуительно простой задачи челу не нужны дохуя скиллованые индусы, но он выставил на бирже такой низкий ценник, что свои услуги предложили только битрикс макаки. На что ему резонно заметили, что если он хочет качества, то должен за него заплатить.
Но тут блядь твоя нейросеть ебучая увидела слово "битрикс". У тебя в комнате взвыла сирена, и ты начал сюда копипастить свою хуйню о том какой хуевый битрикс и как заебись на фреймворках. Какую-то дженерик графоманию про архитектуру, еще пару раз про то какой хуевый битрикс, и еще немного графомании. О чем вообще шла речь тебя не ебет. Ведь ты увидел слово битрикс, а значит пройти мимо никак нельзя. Посты пусть долбоебы читают.
в итоге пришел к этому
https://ideone.com/XlQz9T
как я понимаю, изначально задача не задумывалась как сложная?
Иди нахуй, шизоид.
>но он выставил на бирже такой низкий ценник, что свои услуги предложили только битрикс макаки
Хуй знает, зачем ты фантазируешь и додумываешь за меня.
Я прошлый проект создавал с ценником "по договоренности", мне казалось это адекватным - дать соискателям самим оценить, а не пытаться самому угадать. В описании публиковал бриф, детальное ТЗ высылал по запросу. Проблема в том, что за ТЗ обратилось два или три человека с почти пустыми профилями, а остальное было засрато вордпресс-ботами, которые даже описание прочесть не удосужились. Когда сам на fl.ru искал кодеров и отправлял им на почту ТЗ с просьбой оценить, они не отвечали либо говорили, что уже заняты. Поэтому в следующий раз сразу пошел на апворк - но там средний ценник мне показался сильно выше fl.ru.
Сейчас доделываю ТЗ для нового проекта (более простого) и пытаюсь понять, мне просто в тот раз не повезло или же я неправильно/не там искал кодера (мне fl показался полудохлым). Видимо, вместо договорной цены нужно указывать примерный прайс, чтобы проект был заметнее.
Это советский менталитет. На fl.ru ты в глазах реальных исполнителей изначально по умолчанию рассматриваешься как тупой ахуевший жмот, наебщик, перекуп. А в глазах перекупов изначально по умолчанию рассматриваешься как тупой лох, которого всеми силами надо наебать, перехитрить.
>горячо спорящих о битриксе в постах выше
В что о нём спорить? Говно есть говно - как его маркетологическим наглым пиздежом не прикрывай. Программисты не любят с ним работать. К тому же это местечковое говно - дальше РФ оно никому даром не сдалось.
>>797022
>за ТЗ обратилось два или три человека с почти пустыми профилями
Ну и что? Думаешь, что у тех, у кого профили ломятся от работ не могут кинуть? Там народ зачастую сами у себя заказывают, аккаунты эти перекупают у друг-друга и любыми способами их качают. Смотри по вопросам, которые человек задаёт - понимает ли он о чём речь вообще идёт.
>отправлял им на почту ТЗ с просьбой оценить, они не отвечали либо говорили, что уже заняты
Либо заняты, либо просто не хотят связываться, либо вообще не программисты, а торговцы аккаунтами, либо разводилы.
>следующий раз сразу пошел на апворк - но там средний ценник мне показался сильно выше fl.ru
Потому, что на апворке дрючат безопасность и без жалости сливают мудака. Там исполнители действительно работают и цены\сроки соответствующие.
>Я прошлый проект создавал с ценником "по договоренности"
Это и есть кроилово. Сразу было понятно что ты что-то не договариваешь. Описываешь кисельные берега, и работа простая, и плата адекватная. А по факту ты выставил ценник "от 0 до скольки стргуемся". С очевидной целью минимизировать затраты.
Я ничего против минимизации затрат не имею, бабки на дороге неваляются. Но тут написал что ты "хоть 200К заплатить готов", но готов заплатить по средней зп 100К. Что есть очевидный пиздежь.
>>796180
>>796256
>>796853
>>797028
>>797030
Вы начали какую-то демагогию разводить о рынке труда, почему что-то не получилось. Про кидки, про то почему фрилансеры такие осторожные. Про то что битрикс хуевый. Про менталитет. А на деле все просто:
>проект создавал с ценником "по договоренности"
Все.
Все, ребята. Был мутный хуй, стал кристально чистый. О чем тут вообще рассуждать.
>проект создавал с ценником "по договоренности"
Это совершенно нормальное явление - он не может грамотно оценить ни объём работ, ни их сложность. Опять же люди по разному работают - на разных технологиях, и даже на вордпрессе никто не мешает высрать целый сложный веб-сервис внутренности этого ада лучше не видеть - там фактически свой фреймворк поверх ВП пишется с ПСР и композером.
Поэтому и цена у каждого своя. От него единственно что требуется - не вестись на слишком дешёвый ценник - точно проебёт, как минимум, время.
>он не может грамотно оценить ни объём работ, ни их сложность
>ставит минималку 0 рублей
>пишут только макаки и кидалы
Ну и как, теперь оценил?
Не забудь написать какое вордпресс и битрикс говно. Похуй что ты даже не знаешь на чем у него проект.
>А по факту ты выставил ценник "от 0 до скольки стргуемся". С очевидной целью минимизировать затраты.
На самом деле логика у меня была прямо противоположная - я боялся ошибиться с оценкой, занизить ценник и тем самым отпугнуть адекватов (хотя адекватам я был готов платить любую цену, которую они бы назвали - я ж поэтому-то в итоге и пошел на апворк).
Но все равно спасибо, я благодаря треду теперь лучше понимаю рынок и как меня видят потенциальные соискатели.
> блядь любой джун справится данные из базы в шаблон прокинуть. А если нужна дохуя архитектура, так хули тогда ценник на работу сбивать.
Было бы так просто всё, то не нужны были никакие сеньоры и паттерны. Как раз 80% задач - это, сюрприз, принять запрос, обработать его (сохранить в базу/загрузить что-то из неё) и отдать ответ. Только есть куча сложностей в том, где хранить, как хранить, что хранить, как отдавать, как обрабатывать и так далее.
Если джун будет делать всё сам, то он <?php @echo mysqli_query("select * from user where id=".$GET['user_id']) ?> нахерачит тебе прям в шаблонах и привет.
> Понесло макакена. Ты давно предметную область моделировал, поехавший? С доменными экспертами евент шторминг хуярил?
Жаль тебя расстраивать, но постоянно.
Во-первых, каждый программист не просто "пишет код", а моделирует какой-то бизнес-процесс в случае продукта или технический в случае, если пишет техническую тулзовину. И как раз, кстати, в этом вся проблема, что большинство даунов типа тебя не понимают этого и считают, что их основная задача - это просто херачить код, который что-то там делает.
Во-вторых, я уже третий год работаю в продуктах и есть реально продуктовые аналитики, которые описывают всякие процессы, а потом я проектирую это всё сначала на уровне концепций, а уже потом переношу в код. Но даже когда я работал в аутсорсе, была похожая схема: я, как тимлид, принимал от заказчика хотелки, описывал модель и потом раскидывал разные её части по разным разработчикам для реализации. И да, как раз таким умникам типа тебя неоднократно приходилось объяснять про слои приложения, контексты, модель и прочие причины, почему нельзя прям в контроллере в базу залезть, а в юзере править заказы.
>Если джун будет делать всё сам, то он <?php @echo mysqli_query("select from user where id=".$GET['user_id']) ?> нахерачит тебе прям в шаблонах и привет.
А че так нельзя что ли?
Мимо другой анон, вкатываюсь, тренируюсь, учусь*
Если это сарказм, то иди нахуй.
Если серьёзный вопрос, то:
Нет, нельзя, потому что каждая часть кода должна отвечать только за какую-то свою задачу. Грубо говоря, программирование-очень сложная штука, и когда каждый класс/файл/чтоугодно и швец, и жнец, и на дуде игрец, очень сложно определить что оно сделает в каждом конкретном случае. Отдельной проблемой также будет то, что оно реально будет требовать целую кучу зависимостей для всего, чего ты туда понапихаешь.
К примеру, если у тебя шаблон юзера, как здесь, использует GET['user_id'], то ты не можешь переиспользовать его для вывода юзера для какого-нибудь списка юзеров (потому что там будет GET['page_id'], к примеру).
Соответственно, ты дробишь одну очень сложную задачу "обработать запрос" на множество мелких независимых подзадач, каждая из которых делает что-то своё и ничего не знает ни про соседние, ни про те, что находятся выше уровнем.
Упрощённо это выглядит как-то так:
- Обработать запрос
- - Определить конкретный коллбек
- - Вызвать коллбек
- - - Вытянуть данные из запроса и провалидировать
- - - Сделать нужные действия (загрузить юзера из базы например)
- - - Отобразить юзера (вызвать шаблон)
В результате ты получаешь набор слабосвязанных компонентов: роутер, валидатор, бизнес-правило, вьюха. Каждый из них ты можешь переиспользовать в других местах, удобно независимо тестировать и так далее.
Смотри на код примерно как на завод с конвейерами, есть отдельный человек, который закупает расходники, отдельный человек, который их распределяет по на лентам, отдельный человек на конкретной ленте их пиздит кувалдой, отдельный человек клеит этикетки на выходе и так далее. Каждый делает своё дело и ему безразлично, откуда конкретно ему пришла деталь, от закупщика, из другой ленты или через дыру в крыше упала. И сам он на соседний завод за деталью не побежит.
А, ну и ещё тут есть 2 "ошибки", они достаточно очевидны, но вдруг:
- прямой запрос вместо использования какого-нибудь репозитория, обычно есть какой-нибудь класс, который делает запросы сам "под капотом" и ты просто вызываешь $usersRepo->load($userId);
- нет валидации данных из $GET['userId'], я могу туда написать тебе "; DROP DATABASE users" и всё, привет.
Бля, дядь, ты рофлишь или всерьёз?
Да за такие вопросы даже на васянских говнокурсах тебя опустят всем классом и посадят возле битриксиста, дав ноут с дырочкой
Да ты заебал уже, долбоёбушек. Он написал минималку просто потому, что ебал оценивать со стороны чужую работу. Это любому ментально здоровому человеку очевидно.
Если человек пишет 1 рубль за заказ, то это не значит, что он реально за рубль хочет кого-то нанять. Это значит - сторгуемся по ходу дела.
Нормальный спец умеет оценить задачу и сколько на неё потратит времени, а значит и цену за работу. Ты - не умеешь, но распизделся.
Макаки и кидалы ему пишут потому, что рашен фриланс полутруп, а не потому, что цена такая. Напишет 200к - сбежится просто ещё больше кидал.
>Битрикс программисты идиоты что-ли клинические?
Смотрите - битриксоид порвался. У вас там та ещё ебанутая атмосферка.
У меня дружище как-то к вам с советом пришёл, а вы его в ответ говном облили и сказали, что он нихуя не знает ваш ссаный битрикс.
Я вашего ебанутого брата за версту чую.
Лучше не использовать пути, я бы сказал. Грузишь все классы только через composer, include и require не используешь - и сразу становится хорошо.
Если нужны какие-нибудь фикстуры, то делай функцию, которая берёт их из _FILE_ и юзай её.
Если нужны просто файлы для приложения, то делай класс-обёртку, в которую в настройках будешь прокидывать абсолютный путь до каталога, а во время работы с ней или используй относительные пути (+ группируй всё по бакетам), или вообще имена/айдишники для файлов.
>почему нельзя прям в контроллере в базу залезть
Какой контекст у этого действия?
Я нуб (без иронии) и не понимаю. Например получить одну конкретную сущность по API (ресурс) в symfony. В контроллере я непосредственно воспользуюсь репозиторием, сериалазйером, а также неосознано кучей всего, что спрятано, типа эвентов. Вся бизнес-логика тут - это возьми и отдай, как это еще сильнее и глубже дробить?
Ну в общем нормально, если вся логика это взять из базы и отдать. Главное - никаких манипуляций с данными в контроллере, это не его дело. Он работает только с реквестами и респонсами, валидировать их может и проверять всячески, но предметной логики не должен содержать.
Потому что бизнес-логика - это не про сериализацию. Как замечает анон из >>797389 в частном случае такое делать можно, но в целом нужно разделять бизнес-логику и работу с источниками.
Прочитай про гексагональные приложения, чистую архитектуру и DDD (информации там дохуя, но всё равно).
Следует разделять инфраструктуру (принимает http запросы и передаёт их на следующий слой, маппит всё, сериализует, лазит в базу и тп) и предметную область (бизнес-процессы).
Соответственно, контроллер - это инфраструктура, всего лишь адаптер для http, он принимает запрос, парсит его, валидирует на корректность схемы (отсекает случаи "число вместо строки", "отсутствует необходимый аргумент" и тп) и вызывает соответствующий бизнес-сценарий. Потом получает ответ от этого сценария, форматирует его и отдаёт обратно.
А бизнес-сценарий - это, сюрприз, сценарий, например "создай юзера", "создай заказ", "оплати заказ", "поменяй юзеру пароль", он ничего не знает ни про http, ни про базу, он просто вызывает нужные бизнес-сущности и что-то с ними делает.
Таким образом, ты можешь вызывать один и тот же бизнес-сценарий из веба (контроллеры), из консольки (консольное приложение), на событие из кафки (обзервер), по крону и как ещё угодно.
Потому что бизнес-логика - это не про сериализацию. Как замечает анон из >>797389 в частном случае такое делать можно, но в целом нужно разделять бизнес-логику и работу с источниками.
Прочитай про гексагональные приложения, чистую архитектуру и DDD (информации там дохуя, но всё равно).
https://walkerjordan.com/wp-content/uploads/2020/05/The-Clean-Architecture-layers.png
Следует разделять инфраструктуру (принимает http запросы и передаёт их на следующий слой, маппит всё, сериализует, лазит в базу и тп) и предметную область (бизнес-процессы).
Соответственно, контроллер - это инфраструктура, всего лишь адаптер для http, он принимает запрос, парсит его, валидирует на корректность схемы (отсекает случаи "число вместо строки", "отсутствует необходимый аргумент" и тп) и вызывает соответствующий бизнес-сценарий. Потом получает ответ от этого сценария, форматирует его и отдаёт обратно.
А бизнес-сценарий - это, сюрприз, сценарий, например "создай юзера", "создай заказ", "оплати заказ", "поменяй юзеру пароль", он ничего не знает ни про http, ни про базу, он просто вызывает нужные бизнес-сущности и что-то с ними делает.
Таким образом, ты можешь вызывать один и тот же бизнес-сценарий из веба (контроллеры), из консольки (консольное приложение), на событие из кафки (обзервер), по крону и как ещё угодно.
Потому что бизнес-логика - это не про сериализацию. Как замечает анон из >>797389 в частном случае такое делать можно, но в целом нужно разделять бизнес-логику и работу с источниками.
Прочитай про гексагональные приложения, чистую архитектуру и DDD (информации там дохуя, но всё равно).
https://walkerjordan.com/wp-content/uploads/2020/05/The-Clean-Architecture-layers.png
Следует разделять инфраструктуру (принимает http запросы и передаёт их на следующий слой, маппит всё, сериализует, лазит в базу и тп) и предметную область (бизнес-процессы).
Соответственно, контроллер - это UI, всего лишь один из многих Middleware, он принимает запрос и вызывает соответствующий бизнес-сценарий. Потом получает ответ от этого сценария, форматирует его и отдаёт обратно.
А бизнес-сценарий - это, сюрприз, сценарий, например "создай юзера", "создай заказ", "оплати заказ", "поменяй юзеру пароль", он ничего не знает ни про http, ни про базу, он просто вызывает нужные бизнес-сущности и что-то с ними делает.
Таким образом, ты можешь вызывать один и тот же бизнес-сценарий из веба (контроллеры), из консольки (консольное приложение), на событие из кафки (обзервер), по крону и как ещё угодно. Но я так ни разу не делал, и не в курсе, что обработать пачку в 10К событий из кафки это нихуя не тот же сценарий, что при обычной работе приложения.
Таким вот уебищным образом:
https://regex101.com/r/56d4nh/4/
Два вопроса:
1. Когда парсишь сегмент:
Content-Disposition: form-data; name="file"; filename="test.jpg"
Content-Type: image/jpeg
тут данные. hex картинки, или строка base64
то в самом начеле есть символы
\\r\\n - исмволы возврата каретки и переноса строки
но в регулярке моей ищет успешно только когда установлен символ \\n
-переноса строки. Если добавить возврат каретки - не ище.
Там суть такая что заголовки отдельного блока в данных формы отделены от собственно данных такой последовательностью - "\r\n\r\n"
А перед заголовками только "\r\n". Соответственно я хочу получить заголовки и разобрать их уже по значениям.
2. Почему у меня в квадратных скобках символ точки "." ничего не ищет?
Предпочитаю пользоваться табами в IDE Eclipse PDT, но тот же гитхаб их криво отображает. Если настраиваю форматтер в редакторе, то он даже в момент редактирования начинает вставлять пробелы, и меня это не устраивает выглядит как говно.
В идеале хотелось бы иметь возможность локально писать так как мне нравится, а перед тем как заливать проект была возможность прогнать и отформатировать его с нужными настройками.
Должно же быть что-то такое?
По поводу \r\n vs \n - это может быть особенность regex101, что там перенос строки кодируется как \n и \r там нету. А вот в реальном запросе от браузера присутствует \r\n.
Ты можешь писать \r?\n, который должен работать и там и там.
> Почему у меня в квадратных скобках символ точки "." ничего не ищет?
Внутри квадратных скобок символ точки ищет знак точки, а не "любой символ".
Твоя регулярка не очень удачная, так как внутри заголовка могут быть различные символы, не только те, что указаны у тебя. Я бы советовал искать так:
- отрезаем от запроса первый набор заголовков (заканчивается \r\n\r\n)
- разбираем их на строки
- выделяем там значение boundary в заголовке Content-Type
- разбиваем остаток запроса на части по строке boundary
- каждую часть разбиваем на заголовки и тело по \r\n\r\n
- заголовки разбираем на строки
Вид POST-запроса с boundary можно посмотреть к примеру тут: https://habr.com/ru/post/511114/
Хз, IDEA автоматически табы на пробелы заменяет. Кто вообще эклипс юзает в 2020?
Если тебе нечего написать по этому кроме восхваления своей IDE, то мог бы и не стараться - я твоих советов по этому поводу не спрашивал.
Ты даже пост не прочитал толком.
Psr\Http\Message\RequestInterface - Representation of an outgoing, client-side request. - Представление исходящего запроса на стороне клиента - это как?
Этот интерфейс представляет запрос, который я с сервера отправляю куда нибудь?
Входящий на сервер запрос представляет по идее Psr\Http\Message\ServerRequestInterface этот интерфейс. Так?
> Этот интерфейс представляет запрос, который я с сервера отправляю куда нибудь?
Да. Например, твой код может быть клиентом, отправлять запрос к какому-нибудь API. Тут-то этот интерфейс и пригодится.
Всё равно, ты б ещё в виме программировал. И да, а чего ты от меня хочешь? или лазь в настройках своего говноэклипса, или юзай sed r/\t/\s какой-нибудь.
>И да, а чего ты от меня хочешь?
Нафиг ты мне нужен?
>лазь в настройках
О, спасибо - без тебя бы я не догадался зайти в настройки. Ты прям спас меня.
Всё равно, ты б ещё в виме программировал. И да, а чего ты от меня хочешь? или лазь в настройках своего говноэклипса, или юзай sed r/\t/\s какой-нибудь.
Ну и не пиши тогда ерунду на моих двачах тогда. Тут тебе не центр помощи даунам, которые в ideшке разобраться не могут
А всего-то надо было php_cs на прекоммит гита поставить.
Пипец тут народ водится - спрашиваешь их про варианты форматирования кода, а они тебе бред про свою "самую лучшую ИДЕ" несут в ответ.
Школота какая-то сильно тупая.
Вот я добавил файл, например, test.js в resources, выполнил "npm run dev", создался файл test.js в public с уже написанным кодом. И что дальше? Что за это код? В каком из двух файлов писать код? Зачем вообще нужно 2 файла?
Я всё пилю тупо в assets\js, потом подключаю в шаблонах. Если в Ларе есть возможность минифицировать и всячески конпелировать js и css, то не факт, что этим надо обязательно пользоваться. Будет отдел фронтенда, который на фреймворке станет писать - будем собирать, а так - если один пилишь, то нахуй это надо.
Спасибо
ressources - для исходников, которые собираются и вываливаются дефолтным конфигом в public.
>Вот я добавил файл, например, test.js в resources, выполнил "npm run dev", создался файл test.js в public с уже написанным кодом. И что дальше? Что за это код? В каком из двух файлов писать код? Зачем вообще нужно 2 файла?
Весь код лежит в resources, в public у тебя сбилженная версия твоего кода, которую ты желательно в гит игнор пихаешь, и билдишь при деплое, это не обязательно, просто чтобы не засирать комиты не нужной инфой.
У тебя при билде может происходить куча вещей, не просто копирование файла из одного места в другое. Как минимум код в es5 хуячится через бабель, если нужно то подключаются полифилы (например ты используешь Array.from, которого в ие11 нет, ну и промисы конечно же). При этом если вчера ты поддерживал ие11, а сегодня уже не поддерживаешь, то при билде полифилы для ие11 уже не подключатся. К тому же человеческая система модулей, если тебе нужно подключить либу, то ты её просто бля импортишь себе в скрипт, а не подключаешь в правильной последовательности где-то в верстке. Короче на самом деле очень удобное говно.
Вопрос с собеседования?
persist передает новую сущность под управление EntityManager (до этого он о ней не "знает"), она добавляется в Identity Map. У EM в Identity Map хранится список всех сущностей, о которых он знает. Если сущность загружается из БД, то EM о ней "знает" и вызывать persist не надо.
По flush() он проходится по списку, сравнивает поля каждой сущности с ранее сохраненной копией и определяет, какие поля изменились. На основе этих данных он генерирует SQL-запросы INSERT/UPDATE и выполняет их.
Спасибо что расписал. Не с собеседования, я просто очень любопытный. Начал читать пикрил про транзакции в доктрине и не понял, почему обычный persist()-flush() назвали неявной транзакцией, отсюда появилась мысль что там под капотом происходит что-то более интересное.
flush() делает begin/commit, потому это называют "неявной" расстановкой границ транзакций. То есть ты явно не указываешь сделать транзакцию, а он сам ее делает.
Явное разделение транзакций - это когда ты сам в коде расставляешь beginTransaction/commit. Например, ты можешь захотеть кроме flush() внести еще какие-то изменения в рамках одной транзакции.
persist тут не при чем.
Я юзаю echo для вывода html.
Это оценка кода интерпретатором. Научишься писать код получше, будешь десятки получать. Есть какой-то параметр, чтобы эти оценки скрывать в продакшене.
Бля, у меня ведь раньше была оценка 2к+. Чё то я не в ту сторону свернул значит
мне их скидывают в формате json с какой-никакой структурой и я уже должен буду самостоятельно написать какой то плагин-мигратор который мне из этого json распарсит уже в бд.
так вот встало два вопроса:
1)пыха же ведь без проблем даст мне такую возможность чтобы я мог открыть этот json файл, прочитать, пересобрать в массив и его уже загнать в бд через тот же цикл например?
2)сейчас смотрю этот json файл и там все данные в виде:
"name": "\u0448\u043a\u0438" как пример
и это можно спокойно будет обрабатывать и ззагонять прямо вот так в базу чтобы мне это нормально потом прочесть или же надо как то преобразовывать ?
Ну ты должен по крону видимо запускать консольную команду или просто скрипт который будет делать импорт в БД
Ну а юникодовские крякозябры не проблема, почитай про флаги у функций json_encode/decode, если надо в кириллицу красивую перегонять
Вот на последнем скрине оценка кода, она после всего остального выводится.
А то что внутри body это ты где-то нахуевертил.
Он ещё походу под виндой запускает код, на линуксе уже давно численная система A-F есть
inb4: джумла говно
У тебя в коде стоит return require ... Функция require выполняет шаблон, выводится HTML код. Затем, когда функция require отработает, она возвращает true. И ты командой return require .... дописываешь это true в конец (оно выводится как 1).
Тебе надо убрать require из return. Можно вообще убрать return.
Конечно, лучше делать структуру данных попроще. Если она сложная, то ты можешь описать ее с помощью ООП:
- создать объекты DTO, представляющие данные о вопросе, ответе, итд
- с помощью сериалайзера вроде JMS Serializer / Symfony Serializer преобразовывать приходящий массив в граф объектов
- работать с объектами
Также, можно обойтись без DTO и преобразовывать приходящий массив сериалайзером в объекты-модели. У тебя же есть объекты Вопрос, ВариантОтвета, Тест и тд?
Есть другие варианты. Если бы ты использовал библиотеку Symfony Form, ты бы мог описать форму, и она сама преобразовала бы приходящие массивы в объекты.
То есть, если структура данных сложная, то стоит описать ее с помощью объектов. Если не очень - можно просто обходить эти массивы и вручную переносить данные в объекты.
Было бы хорошо, конечно, использовать Symfony Form: она и преобразует приходящие массивы в объекты, и умеет их валидировать.
Объекты из функций по ссылке передаются?
Да, объекты передаются в функцию и из функции "как бы" по ссылке. Копирования не происходит.
Ну если долбоёб и хочется заняться полной хернёй (а чего, альтернатив-то джумле нет), то это оптимальный вариант.
первым вызывается метод $app->run(), в нем вызывается метод $this->process($request, $response), уже в $this->process получаем экземпляр роутера из контейнера:
$router = $this->container->get('router');
и вызывается метод $router->setasePath() я хз что за базовый путь. А дальше я нихуя не пойму что идет и зачем. Где идет сравнение роутов, где обработка роута. и т.п.?
Далее в этом же методе $this->process, после получения роутера вызывается :
$response = $this->callMiddlewareStack($request, $response);
Тоесть реквест прогоняется через цепочку мидлвэйров, я эту цепочку просматривал, и хз где там роутинг стартует.
Если кто в курсе - набросайте принцип действия.
Даже не представляю почему не получается и не знаю как посмотреть, если можно вообще.
Есть подозрение что он Auth не туда смотрит, хотя я поменял в config/auth.php ,в разделе User Providers, table => на название нужной таблицы (driver => database оставил).
Кто-нибудь может подсказать куда посмотреть?
Auth:attempt() использует стандартный гвард "auth" по дефолту. В документации читай о том где и что ты мог изменить, там разные вариант, в auth мидлвэйре, и в провайдере аутентификации есть настройки.
Смотри по каким полям ты лоигруешься, том по дефолту email и password
А ты не пробовал заглянуть в функцию callMiddlewareStack? Она находится в трейте. Там есть вызов функции $this->seedMiddlewareStack(); https://github.com/slimphp/Slim/blob/5ca71b9690998b8d7c096ac3e3599bd48637c9c1/Slim/MiddlewareAwareTrait.php#L111
Эта функция добавляет в качестве самого первого middleware $this, то есть объект Slim\App. И затем она вызывает это Middleware как функцию, в этом случае у объекта вызывается магический метод __invoke. Вот он: https://github.com/slimphp/Slim/blob/5ca71b9690998b8d7c096ac3e3599bd48637c9c1/Slim/App.php#L487
В нем уже идет обращение к роутеру. Задавай еще вопросы, если что-то непонятно. Сделано, конечно, очень головоломно, и лучше бы первое middleware добавлялось бы в конструкторе Slim\App - тогда все было бы очевиднее.
Базовый путь - это когда корень сайта находится внутри какой-то папки, например, главная страница не http://example.com, а http://example.com/site/. Тогда /site/ - это базовый путь.
Спасибо за ответ! В callMiddlewareStack я конечно смотрел , как и в трейт. И я предполагал что самый первый мидовэйр это this и есть.
Но вот разобрать код в этом методе я не смог, не смог понять где это прописано , завтра буду ещё раз внимательнее изучать.
$this внутри трейта это объект класса, в который встроен трейт (Slim\App в данном случае). И строчки
$kernel = $this;
$this->tip = $kernel;
в методе seedMiddlewareStack ставят первым миддлевейром именно объект Slim\App.
>>802203
Можно: в БД, в сессии, в файле, в куках (для любителей поизвращаться).
Вопрос суръёзный.
>Весь фронтенд эффективнее же делать на всяких JS-фреймворках
А как ты себе представляешь в 2020 году фронтенд на чём то КРОМЕ html+css+-js? Всё остальное померло, или требует финтов ушами не особо очевидных.
Бекенд можно делать на чём угодно. Хоть на java хоть на python хоть на руби-на-рельсах, хоть на go, хоть на node js, хоть на пыхе. Вон, половина(или около того) сайтов работает вообще на вордпрессе, и ничего. Вопрос выбора инструмента нельзя задавать в общем, надо в частных случаях смотреть почему тот или иной взят за основу.
>фронтенд на чём то КРОМЕ html+css+-js?
так можно же на других языках писать которые потом скопилятся тебе в js. только не понятно нахуя это надо
в питон треде зимой кидали ссыль на какой то сайт где был фронт на питоне написан. но там дакая лажа и дичь устаревшая лет на 10, что лучше бы вообще не делали этого
Спасибо. Все просматриваю по 10 раз анончик, пытаюсь понять как и что работает, стараюсь не использовать ничего лишнего, ни валидаций, ни мидлов, чтобы не сломать, делая вещи шаг за шагом.
У меня получилось решить частично проблему, но я все еще пытаюсь понять как. Вот что я сделал:
1)Reset все таблицы и заново migrate
У меня 2 немного отличающиеся таблицы, дефолтная users и еще lusers.
2)До этого у меня не работал DB:seed, я забил на проблему думая это проблема железа. Но консоль пишет что он пытается запихнуть моего LuserSeeder в таблицу users, а не lusers. //Почему? В create_lusers_table все прописано, вроде.
Я сделал таблицы почти идентичными. Он успешно засидил в users (а нужно было в lusers).
3)У меня в сидере был пароль-слово простое. Я поменял на Hash::make.
Формы, если что, у меня сделаны через ~blade: {{ Form::password('password') }}.
Таким образом все залогинилось, разлогинилось, начало работать, но я до сих пор не понимаю причину.
DB:seed не мог запихнуть моего сидера в нужную таблицу. Я делаю вывод что Auth::attempt() тоже смотрел не туда при проверке. Мог ли он ругаться на то что пароль без хеша?
Я пытаюсь пересматривать все файлы, связанные с аутентификацией.
В config/auth.php, как я говорил, я добавлял нужную таблицу lusers в веб провайдеры:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'users' => [
'driver' => 'database',
'table' => 'users',
],
'users' => [
'driver' => 'database',
'table' => 'lusers', //нужная мне таблица
],
],
Что я упускаю?
Спасибо. Все просматриваю по 10 раз анончик, пытаюсь понять как и что работает, стараюсь не использовать ничего лишнего, ни валидаций, ни мидлов, чтобы не сломать, делая вещи шаг за шагом.
У меня получилось решить частично проблему, но я все еще пытаюсь понять как. Вот что я сделал:
1)Reset все таблицы и заново migrate
У меня 2 немного отличающиеся таблицы, дефолтная users и еще lusers.
2)До этого у меня не работал DB:seed, я забил на проблему думая это проблема железа. Но консоль пишет что он пытается запихнуть моего LuserSeeder в таблицу users, а не lusers. //Почему? В create_lusers_table все прописано, вроде.
Я сделал таблицы почти идентичными. Он успешно засидил в users (а нужно было в lusers).
3)У меня в сидере был пароль-слово простое. Я поменял на Hash::make.
Формы, если что, у меня сделаны через ~blade: {{ Form::password('password') }}.
Таким образом все залогинилось, разлогинилось, начало работать, но я до сих пор не понимаю причину.
DB:seed не мог запихнуть моего сидера в нужную таблицу. Я делаю вывод что Auth::attempt() тоже смотрел не туда при проверке. Мог ли он ругаться на то что пароль без хеша?
Я пытаюсь пересматривать все файлы, связанные с аутентификацией.
В config/auth.php, как я говорил, я добавлял нужную таблицу lusers в веб провайдеры:
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'users' => [
'driver' => 'database',
'table' => 'users',
],
'users' => [
'driver' => 'database',
'table' => 'lusers', //нужная мне таблица
],
],
Что я упускаю?
Вопрос какой то тупой.
В общем-то не нужен, как не нужны и прочие 90% языков. В конце-концов, любую задачу можно решить на любом языке общего назначения, мог бы быть один язык для всего.
Но человечество так не работает, мы всему создаём альтернативы. Веусовщина, какие-то уникальные требования, по приколу - есть много причин, которые порождают множество языков, на которых люди пишут множествосхожих фреймворков, библиотек так далее.
Я тут хотел привести пример с розетками или кабелями для телефонов, чтобы ты понял, что всегда есть ещёодин стандарт или реализация,но внезапно вспомнил, что даже на метрическую систему ещё не все страны перешли.
Так что выберай язык под задачу и далее на свой вкус, на этом всё.
Хуйня. Состояние приложения не должно зависеть от контекста конкретного запроса.
>так можно же на других языках писать которые потом скопилятся тебе в js
>потом скопилятся тебе в js
Ну и нахуя тогда? В чём профит?
Прост на старте, на нём не надо думать про рантайм по сути(всё равно запрос-ответ-смерть процесса).
Он лучше по скорости разработки. Хотя ответ должен быть более комплексным.
Есть вот джава или шарп, строгие и очень многословные (однако выразительные весьма) языки.
Есть питон или жс - не так выразительны как джава/шарп, но сделать можно тоже самое, местами даже лучше, а что главное очень сильно быстрее.
И есть пхп, где-то по середине выразительности, и что важнее, хоть и вытекает из предыдещго - быстрее по скорости разработки.
По скорости тут не оч все, изза модели родился-сдох, сам по себе язык очень быстрый сейчас, но модель исполнения пускает это все по пизде (и нежелание разрабов делать коробочную асинхронность).
Ну и все выше сказанное относится к разработке на фреймворках или на голом пхп (если опытными людьми), но не относится к разработке на цмс разных (вордпресс, друпал, битрикс и тд). Ну или проще - не относится к разработке на пхп по старым гайдам. Это вообще другая сфера, она даже к программированию почти не относится. Чуть чуть пересекается только, потому и популярна так. Почти все норм разрабы предпочитают зрелую разработку, но на всяких цмсках такая тонна всего понаписана, что пыха от этого уже не отмоется наверно.
В целом соглашусь, но сентенцию про скорость разработки надо раскрыть детальнее.
Если писать на php "как надо", с типами, паттернами, слоями и так далее, то скорость написания будет несколько медленнее, но зато приложение не схлопнется в коричневую дыру после года разработки. Но при этом скорость будет очень близка или даже равна скорости разработки на джаве или шарпах.
А если писать на отъебись, чтобы побыстрее, забить на типы и архитектуру, то да, написание кода первое время будет быстрее.
Я как-то уже писал тут, что плюсы пхп лежат скорее в лёгкости освоения нубами (отчасти) и формошлепства на цмсках, а в энтерпрайз разработке он почти такой же, как та же жава, но похуже.
>>Если писать на php "как надо", с типами, паттернами, слоями и так далее
Однако это и плюс, потому что это поднитмает средний уровень разработчика до принятых стандартов, что облегчит миграцию на другой стэк. Как бы фронт библиотеки к примеру не толкали функциональное программирование - гранитное ООП живет и здраствует и альтернатив нет.
Тот же любимый всеми тайпскрипт - ооп ориентирован, там интерфейсы есть, тайпхинты и прочие радости.
Это способ сразу гидрировать данные для твоего реакта без лишнего Аякс запроса, ничего плохого не вижу
>>802990
Ну просто помимо человека, который так пишет в каком-нибудь пхпшторме или что там это считает нормальным, есть я - и я захожу немного поправить фронтенд и уйти заниматься другими делами, поважнее, а vs code хуяк, и форматирует код в теге script, как js скрипт, со всеми вытекающими. И тут есть 2 варианта развития событий - я либо не знаю, о том, что где-то произошла такая хуйня и ничего не исправляю, а потом люди охуевают с того, что оно всё само сломалось, либо я сижу и дрочу этот код, пока всё не поправится. Выключив перед этим prettier и прибуду, которая пхп форматирует.
Ну и я мельком глянул документацию пыхи, там пишут, что с 7й версии так делать не надо. Я конечно не секу, но как по мне, тег скрипт для жс, а не для пхп.
>>802685
>>802695
>>802712
Нахера эти платиновые извечные вопросы нужны. Во фронт тредах говорят что фронд для вкатывальщиков, но вот потом нужно обязательно что-нибудь нормальное учить! В ява треде говорят что это устарело и надо переходить на асп, в си тредах говорят что ява-то огого, там где-то хайпят всякие языки. Везде одни и те же вопросы, везде одно и тоже. Зачем это все. У соседа всегда трава зеленее будет.
>У соседа всегда трава зеленее будет.
Не видел еще чтобы где-то пхп нахваливали, кроме как в среде пыхеров.
Я не видел дочерей Мела Гибсона, и что.
потому что кроме пыхеров никто не в курсе, что PHP ВНЕЗАПНО единственный скриптовый язык с нормальным ООП здорового человека
>>802525
Ну ёптыть, ты доку по mail смотрел?
https://www.php.net/manual/ru/function.mail.php
первый коммент - про то как ошибку конкретную увидеть
$success = mail('
if (!$success) {
$errorMessage = error_get_last()['message'];
}
Телепатирую то у юзера, из под которого исполняется web сервер, нет прав на запись в директорию DIR="/tmp/fake_sendmail"
Бизнес-логику как раз удобнее писать сихронным кодом, а асинхронность JS все усложняет. Так как JS не умирает, в нем может жутко утекать память, в PHP такой проблемы нет. Так как в JS нет тайп-хинтов, код на нем читать тяжелее, а IDE не может его проверять и давать подсказки. PHP взрослее, и в нем есть библиотеки и фреймворки вроде Symfony, а в JS нет и там заново изобретают велосипеды. Если мне не изменяет память, шаблнизаторы в JS послабее того же твига. Также, в JS много странных особенностей, например, он не выдает ошибки при опечатке в имени свойства.
И почему ты решил, что писать бекенд на JS эффективнее? Нужны аргументы.
>есть я - и я захожу немного поправить фронтенд и уйти заниматься другими делами, поважнее, а vs code хуяк, и форматирует код в теге script, как js скрипт, со всеми вытекающими.
Честно не сильно представляю что там может сломаться, я у себя не замечал чтобы вскод в php файлах у меня жс вообще форматировал (может я отключил это, хз)
>Ну и я мельком глянул документацию пыхи, там пишут, что с 7й версии так делать не надо.
Не сильно понимаю какая разница какая тут версия. Если у тебя есть логика, которую удобно сделать на жсе, но которая требует какой-то конфигурации или данных с сервера, то это вариант напрямую в страницу в window ебануть эти данные, а потом на жсе распарсить, при этом сэкономив запрос (чаще всего это не какая-то залупа ненужная, а то что нужно сразу здесь и сейчас)
>Я конечно не секу, но как по мне, тег скрипт для жс, а не для пхп.
Как по мне, то если у тебя инлайновый жс никогда не меняется, то имеет смысл ебануть этот кусок сразу в бандл и выполнять по условию
Ну уровень разработчика-то поднимает, но зачем это делать на php? Хочешь писать энтерпрайз - иди сразу в джаву и всё, скачок между "программированием" на cms и "нормальным" программированием всё равно такого размера,
что вкат в новый язык будет незначительным.
Условно, вкат в php формошлёпство - это 20 часов, а в энтерпрайз, что на php, что на джаве - 2000 часов. Тебе сильно поможет, что на вкате в php ты сэкономил и тебе осталось 1980 часов? Скорее всего нет.
> Тот же любимый всеми тайпскрипт - ооп ориентирован, там интерфейсы есть, тайпхинты и прочие радости.
Как раз в тайпскрите функциональщины дохера и все радостно её юзают. Да и не только там, в джава-мире она тоже активно используется.
>>803085
Здесь много херни, отвечу по пунктам.
> Бизнес-логику как раз удобнее писать сихронным кодом, а асинхронность JS все усложняет
Бизнес-логика обычно синхронна - это верно. Но ассинхронность JS не то, чтобы сильно всё усложняла, уже на промисах всё было нормально с поддержкой такого кода, а с async/await код практически ничем не отличается от синхронного уже.
> Так как JS не умирает, в нем может жутко утекать память, в PHP такой проблемы нет.
Это решается простым правилом "не пиши никуда вне контекста запроса" и утечки данных прекращаются моментально, что в js, что в java, что в демонах на php. Серьёзно, за почти 5 лет разработки бекендов, которые не рождаются, чтобы умереть, проблема с утечкой у меня была одна-единственная, когда внешняя либа на php на каждый вызов метода сохраняла данные в статическое поле одного класса, типа черезжопный кеш. И то, нашёл и исправил. В js и других языках не встречал ни разу такого может потому что работаю в нормальных конторах и у нас мало долбоёбов работает
> Так как в JS нет тайп-хинтов, код на нем читать тяжелее, а IDE не может его проверять и давать подсказки.
Здесь есть здравое зерно, но именно что зерно. Даже бекенды на ноде уже пишутся на тайпскрите, где система типов уворована из C#, то есть намного более развита, чем в PHP: больше типов, больше проверок, больше возможностей, от дженериков до енумов и кортежей.
Но многие до сих пор принципиально пишут на голом js, что очень хорошо, потому что позволяет заранее ограничивать общение с даунами, иногда даже до собеседования.
> PHP взрослее, и в нем есть библиотеки и фреймворки вроде Symfony, а в JS нет и там заново изобретают велосипеды.
Они примерно одного возраста. Аналогов symfony в js действительно нет, но не потому, что он плох, а потому, что там не принято писать фреймворки-комбайны. Скорее как в го, есть куча библиотек из которых ты сам собираешь себе "фреймворк" под задачу. Библиотеки есть под любую задачу, можно подобрать аналог для каждого из компонентов симфони.
> Если мне не изменяет память, шаблнизаторы в JS послабее того же твига.
Очень странное утверждение, учитывая, что это именно JS выполняется на фронте и именно на нём написаны все эти реакты/вю/ангуляры. Вот уж где шаблонизации и вывода текста навалом..
> Также, в JS много странных особенностей, например, он не выдает ошибки при опечатке в имени свойства.
Особенностей много в любом языке и в php в том числе, а конкретно эта "особенность" во-первых, не является ошибкой с точки зрения логики js (в php-шных массивах ты тоже ошибки при опечатке не получишь, кстати), а во-вторых, резко стала неактуальной с появлением тайпскрипта.
> И почему ты решил, что писать бекенд на JS эффективнее? Нужны аргументы.
Он сказал, что на js эффективнее делать фронтенд и с этим спорить бесполезно. А для бекенда они +- равны, php за счёт своих фреймворкокомбайнов облегчает вкат и даёт возможность быстро нахерачить шаблонного кода, js/ts даёт больше возможностей, как язык, но несколько требовательнее к разработчику.
Ну уровень разработчика-то поднимает, но зачем это делать на php? Хочешь писать энтерпрайз - иди сразу в джаву и всё, скачок между "программированием" на cms и "нормальным" программированием всё равно такого размера,
что вкат в новый язык будет незначительным.
Условно, вкат в php формошлёпство - это 20 часов, а в энтерпрайз, что на php, что на джаве - 2000 часов. Тебе сильно поможет, что на вкате в php ты сэкономил и тебе осталось 1980 часов? Скорее всего нет.
> Тот же любимый всеми тайпскрипт - ооп ориентирован, там интерфейсы есть, тайпхинты и прочие радости.
Как раз в тайпскрите функциональщины дохера и все радостно её юзают. Да и не только там, в джава-мире она тоже активно используется.
>>803085
Здесь много херни, отвечу по пунктам.
> Бизнес-логику как раз удобнее писать сихронным кодом, а асинхронность JS все усложняет
Бизнес-логика обычно синхронна - это верно. Но ассинхронность JS не то, чтобы сильно всё усложняла, уже на промисах всё было нормально с поддержкой такого кода, а с async/await код практически ничем не отличается от синхронного уже.
> Так как JS не умирает, в нем может жутко утекать память, в PHP такой проблемы нет.
Это решается простым правилом "не пиши никуда вне контекста запроса" и утечки данных прекращаются моментально, что в js, что в java, что в демонах на php. Серьёзно, за почти 5 лет разработки бекендов, которые не рождаются, чтобы умереть, проблема с утечкой у меня была одна-единственная, когда внешняя либа на php на каждый вызов метода сохраняла данные в статическое поле одного класса, типа черезжопный кеш. И то, нашёл и исправил. В js и других языках не встречал ни разу такого может потому что работаю в нормальных конторах и у нас мало долбоёбов работает
> Так как в JS нет тайп-хинтов, код на нем читать тяжелее, а IDE не может его проверять и давать подсказки.
Здесь есть здравое зерно, но именно что зерно. Даже бекенды на ноде уже пишутся на тайпскрите, где система типов уворована из C#, то есть намного более развита, чем в PHP: больше типов, больше проверок, больше возможностей, от дженериков до енумов и кортежей.
Но многие до сих пор принципиально пишут на голом js, что очень хорошо, потому что позволяет заранее ограничивать общение с даунами, иногда даже до собеседования.
> PHP взрослее, и в нем есть библиотеки и фреймворки вроде Symfony, а в JS нет и там заново изобретают велосипеды.
Они примерно одного возраста. Аналогов symfony в js действительно нет, но не потому, что он плох, а потому, что там не принято писать фреймворки-комбайны. Скорее как в го, есть куча библиотек из которых ты сам собираешь себе "фреймворк" под задачу. Библиотеки есть под любую задачу, можно подобрать аналог для каждого из компонентов симфони.
> Если мне не изменяет память, шаблнизаторы в JS послабее того же твига.
Очень странное утверждение, учитывая, что это именно JS выполняется на фронте и именно на нём написаны все эти реакты/вю/ангуляры. Вот уж где шаблонизации и вывода текста навалом..
> Также, в JS много странных особенностей, например, он не выдает ошибки при опечатке в имени свойства.
Особенностей много в любом языке и в php в том числе, а конкретно эта "особенность" во-первых, не является ошибкой с точки зрения логики js (в php-шных массивах ты тоже ошибки при опечатке не получишь, кстати), а во-вторых, резко стала неактуальной с появлением тайпскрипта.
> И почему ты решил, что писать бекенд на JS эффективнее? Нужны аргументы.
Он сказал, что на js эффективнее делать фронтенд и с этим спорить бесполезно. А для бекенда они +- равны, php за счёт своих фреймворкокомбайнов облегчает вкат и даёт возможность быстро нахерачить шаблонного кода, js/ts даёт больше возможностей, как язык, но несколько требовательнее к разработчику.
Оно должно работать в 5.1? Что-то не получается
то что нода менее удобна для "обычных" приложений - это очевидно.
Там где на пхп без единой зависимости нуб накидает сайтец, даже динамический с базой. Нуб на ноде начнет сосать бибу на этапи парсинга входящего бинарного потока от банальной post-формы. В ноде такая банальная задача сразу тянет за собой понимание потоков, буферов, событий и их обработчиков, асинхронности. А еще и банально распарсить этот запрос нужно, выдрать из него файлы и все такое.
Мне нода нравится, но она для отдельных вещей. Пердолиться с сокетами сплошное удовольствие.
>>803264
>>Как раз в тайпскрите функциональщины дохера
Как и ооп-шины. Тайпскрипт в суперпозици между двумя стульями.
>>Ну уровень разработчика-то поднимает, но зачем это делать на php?
А зачем это не делать на пхп? Это демагогия. И вообще это очень джуновская постановка задачи, в духе -зачем в 2к20 учить одно, если другое точно лучше, мне так сказали на ютубе. Многие совсем не вчера начали писать на пхп, и рады тому что язык растет.
А рынок предлагает много работы на пхп ларавел/симфони, и помирать это все не собирается. То что ниша пхп в связи с ростом его как языка слегка смазалась, пока что не дает никаких возможностей предположить что дальше будет. Но по крайней мере я знаю что я если че смигрирую на го, или ноду, ее я знаю, или в жаву пхп форк жавы же :3
Можно и на питон, но Гвидо ушел, язык как мне кажется подзамер в развитии.
> Честно не сильно представляю что там может сломаться
<??> превращается в
<
?
>
?
Ну и код между ними.
Всё идёт по пизде из-за этого
>>уже на промисах всё было нормально с поддержкой такого кода
Все равно асинхронность лезет из щелей. Разница к примеру в возврате промисов из циклов for() и foreach() - где первый выполняется последовательно, что позволяет собрать промисы по очереди, а второй зарезолвит промисы как пойдет. И еще много всяких деталей.
>>Даже бекенды на ноде уже пишутся на тайпскрите
Но по сути же тайпсккрипт это сахар для js. Хотя я как то глянул - мне понравилось, нужно глубже познакомиться с ним.
>>а потому, что там не принято писать фреймворки-комбайны.
Не верю я в концепцию принято/не принято. Скорее сомгли /не смогли, и опять же на ноде есть nest - значит комьюните родило таки, а не "не принято". Подход собери солянку имееет свои весьма дерьмовые недостатки. Большой фреймворк и комьюнити вокруг него дают оч важную вещь - народ начинает писать по стандартам фреймворка, и фреймворки пишутся как правило компетентными людьми.
>>А для бекенда они +- равны,
Зависит от контекста задачи. Для типовых вещей пхп удобнее и гораздо. Но у ноды сови плюсы, мне она нравится но прям все подряд я на ней бы не стал писать, зачем когда есть проще и удобнее инструмент?
>>> Если мне не изменяет память, шаблнизаторы в JS послабее того же твига.
Думаю имеентся ввиду серверная шаблонизация mustache или pug
ну так ты отключи эту хуйню. есть вещи которые ты можешь ебануть туда только инлайном как анон выше описал. например мне с бека прилетают точки для карты которые надо парсить на js . и как предлагаешь мне это делать? писать на бэке отдельный ajax-контроллер для того чтобы он мне эти точки выгружал и еще раз гонять его ?
как не быть долбаебом и начать твой курс?
>>802887
Не слушай всяких долбоёбов. В 2020 не пользоваться шаблонизаторами-уебанство, так что у тебя никаких ни html ни js элементов в коде не должно быть.
>>803386
Шаблонизатор. Создаёшь тплку-захуяриваешь там свой сраный <script>, и в него уже передаешь что тебе надо.
Ну и в одной цмске видел вообще функцию которая создаёт js переменную(первый параметр имя, второй-значение).
ну вот я об этом. например работаю с blade шаблонизатором. как мне загнать туда переменную кроме как <script> const arr = @json($arr)</script> ?
Так это уже вполне норм практика. Тут нет смешения кода и отображения, тут нет пресловутых <??> которые упоминались в изначальном вопросе.
В данном конкретном случае можешь строку json генерить разве что до передачи в шаблон, а в шаблоне вызывать обычным {{ $var }}(так же вроде в блейде?), если тебя смущает преобразование внутри шаблона.
Как я понял все эти галеры хотят в проектике кнопку на один пиксель подвинуть, а проблема в том, что хуй пойми где это сделать, потому что style в элементе даже не где-то в темплейтах, а вообще в хуке, и то же самое со всей логикой приложения, которое тупо накидано?
на самом деле от самой галеры и от ее проектов зависит. в каких то местах говнище уровня сделать сайт за две недели для местного васяна у которого своя автомойка занидорага, в каких то наоборот ахуенно большие, сложные проекты где от битрикса/вп практически ничего не осталось. хороший пример - магазин эльдорадо
тут уже зависит от самого проекта и потребностей клиента, и в зависимости от него что то делают.
по поводу сверхлюдей - как человек который плотно комуницировал с битрикс/вп/джумла коммунити на протяжении уже полугода где то, то могу смело заявить что там 90% это нихуя не разработчики. это какие то вебмастера или сеошники которые там чуть-чуть в погромирование могут, но не более которые ну тупо знают эту хуйню в какой то степени.
>хотят в проектике кнопку на один пиксель подвинуть
задачи разные бывают. тут так и не скажешь сразу. иногда да рили бывали таски где лого на мобиле надо было поправить, а иногда развернуть большую хуйню. как пример: интеграцию полноценную с каким нибудь апи для рассылок смс сообщений своим клиентам
>то же самое со всей логикой приложения, которое тупо накидано?
здесь так же от проекта зависит и от того кто ведет. не угадаешь, но в большинстве своем - кал собачий. объясняется на самом деле просто: есть задача, надо ее как то решить. ты идешь в доку дай бог чтобы она еще была и ищешь инструменты этой cms/фреймворка которые помогут тебе это решить. если не находишь - идешь в гугл и там так же обсираешься. идешь к коммунити и спрашиваешь у них - они тебе просто ничего не отвечают потому что ничего из погромирования не знаю, а слово очередь у них ассоциируется с пятерочкой у дома. ну и ты почесав репу как это делать, начинаешь говнокодить чтобы хоть как то таску закрыть. вот как то так и накатывается этот снежный ком.
У тебя странный config/auth.php, там в массиве 3 записи с одинаковым ключом 'users' - наверно, ключи должны быть разные.
Ну вот ты демонстрируешь тут неумение пользоваться инструментами. Смотришь на эту кнопку в DevTools браузера (Ctrl + SHift + I), смотришь какие у нее классы и какие у соседних элементов. Правишь в DevTools стили, чтобы она сдвинулась на пиксель. Поиском по файлам находишь, где находится нужное CSS правило и переносишь туда правки из DevTools. Все, задача решена.
Тем же, чем остальные веб-макаки (крудошлепство, апишки, базоебля, нужное подчеркнуть), но в условиях извращенной как демоны хаоса логики CMS.
До определенного уровня CMS позволяет делать задачи просто и быстро, но достаточно быстро ты этот уровень перерастаешь и она начинает совать тебе палки в колеса.
>переносишь туда правки из DevTools
Допустим это выкакивается где-то через echo и классов на этом элементе нет, потому что кто-то уже двигал на два пикселя в другую сторону раньше и через атрибут style это было сделать проще. На размышление 0 секунд.
Я в принципе подразобрался с тем как устроены мидлвэйры. К сожалению прям много времени не смог потратить. Сейчас разбираюсь с роутером , есть такие вопросы:
какова задача класса \FastRoute\Dispatcher? Что он диспетчерит?
или для чего нужен класс Routable? Описание "Маршрутизируемый объект с поддержкой промежуточного программного обеспечения"
мне мало чего дало
Простые роутеры я сам конечно писал, где входящий url просто парсится регуляркой.
Тогда ищем по тексту кнопки, или по соседним элементам. Если задач по проекту много, то можно попробовать уговорить провести рефакторинг кода и сделать нормальные шаблоны.
Но по моему опыту, даже в системах на Симфони с Twig приходится действовать через поиск по имени класса или тексту. Так как шаблонов там могут быть тонны и это самый быстрый способ найти элемент. Хотя, конечно, криворукий верстальщик и проект на Симфони способен испортить.
> какова задача класса \FastRoute\Dispatcher? Что он диспетчерит?
Ты не ошибся в названии класса? Ты имел в виду интерфейс FastRoute\Dispatcher из библиотеки fastroute или FastRouteDispatcher из Slim 4?
Первое - это сторонняя библиотека для роутинга, которую использует Слим, и интерфейс Dispatcher там довольно простой (и с комментарием): https://github.com/nikic/FastRoute/blob/master/src/Dispatcher.php . По URL и HTTP методу ищется подходящий обработчик.
Второе - это видимо адаптер для этой библиотеки, который помогает ее вызывать из Слима 4.
Можно сделать поиск по FastRouteDispatcher и найдется пара интересных файлов:
- просто Dispatcher, который создает FastRouterDispatcher и набивает его информацией о роутах: https://github.com/slimphp/Slim/blob/cf68c2dede23b2c05ea9162379bf10ba6c913331/Slim/Routing/Dispatcher.php
- тест, в котором видно, как используется FRD: https://github.com/slimphp/Slim/blob/cf68c2dede23b2c05ea9162379bf10ba6c913331/tests/Routing/FastRouteDispatcherTest.php
> для чего нужен класс Routable
Как я понимаю, это основа для класса, представляющего один роут или группу роутов с общими свойствами. Там есть свойства pattern, callable, middleware. Я бы сделал поиск extends routable по коду (или посмотрел дерево наследования, если у тебя IDE) и посмотрел, кто от него наследуется.
Там находится как минимум:
class Route extends Routable
class RouteGroup extends Routable
То есть тут наследование используется, чтобы вынести общий код в базовый класс Routable.
> то что нода менее удобна для "обычных" приложений - это очевидно.
А что такое "обычное" приложение? Интернет магазин или странички с контентом? Но тогда и php не очень уже, надо цмску брать, где всё готовое уже. А если перекладывать JSONчики из сети в базу по кастомной бизнес-логике, то оно примерно одинаково, в php ближе к классическому ооп, в ноде больше к функциональщине.
> Нуб на ноде начнет сосать бибу на этапи парсинга входящего бинарного потока от банальной post-формы.
Втираешь какую-то дичь, такие задачи всегда решаются соответствующим пакетом. В php тоже, знаешь ли, никто с нуля не пишет ничего.
Про события и потоки отчасти верно, но очень отчасти, потому что реально там никого rocket science нет.
> А зачем это не делать на пхп? Это демагогия. И вообще это очень джуновская постановка задачи, в духе -зачем в 2к20 учить одно, если другое точно лучше, мне так сказали на ютубе. Многие совсем не вчера начали писать на пхп, и рады тому что язык растет.
Хз, это вы начали нести херню про то, что "JS не очь, пыха лучше будет". А я утверждаю, что писать на них суръезные вещи в целом одинаково. В пыху просто чуть легче вкат, в ноде больше возможностей.
>>803344
> Не верю я в концепцию принято/не принято. Скорее сомгли /не смогли, и опять же на ноде есть nest - значит комьюните родило таки, а не "не принято". Подход собери солянку имееет свои весьма дерьмовые недостатки.
Таки не принято, прекращай думать пехапешными шаблонами, я серьёзно. В какой-то момент ты вырастаешь из штанишек и понимаешь, что архитектура, тулчейн и тому подобное замечательно подбирается под задачу, ровно такие, какие нужны, вместо громоздких комбайнов.
Ещё раз, на любом языке библиотеки есть под любую задачу, на том же js можно подобрать аналог для каждого из компонентов симфони, будет то же самое, если тебе охота.
> Большой фреймворк и комьюнити вокруг него дают оч важную вещь - народ начинает писать по стандартам фреймворк
Весомый плюс только для галер, где нужно грести как можно быстрее и как можно проще рабов заменять.
В итоге у тебя получается деревянная архитектура, на которую идеально садятся новички, идеально по шаблону решаются любые задачи (просто копипастом с условного docs.phpframework.net) но при этом этот самый набор шаблонов со скрипом натягивается на любые случаи, отличающиеся от +- большинства. А любой серьёзный проект в итоге обрастает уникальными чертами знаешь-ли.
Кстати, даже если тебе нужен идеальный набор шаблонов, ты не поверишь, это работа на неделю максимум, собрать компоненты, связки, заточить это дело, накидать стандарты по архитектуре, подготовить темплейты для инфраструктуры и так далее. И можно точно так же тиражировать разработку. И для этого не нужен гениальный архитектор, делается усилиями просто компетентного сеньора. я сто раз так делал
Попробуй как-нибудь уволиться со своей галеры, взять другой язык и посмотреть по сторонам, охуеешь, насколько всё не так и насколько мирок php-разработки своеобразен.
> Для типовых вещей пхп удобнее и гораздо. Но у ноды сови плюсы, мне она нравится но прям все подряд я на ней бы не стал писать, зачем когда есть проще и удобнее инструмент?
А я начал спорить, когда услышал глупости, что-де на пхп удобнее бизнес-логику писать и прочую ересь. Реальные причины выбора языка, ты прав, это технические требования, знание командой, доступность и цена спецов на рынке и всё такое. Но при этом, глобально, нет причины всегда выбирать php или всегда ноду, они сравнимы.
Но конкретно для разработчика есть ещё такие критерии, как современность и развитость экосистемы, например. Или средний рейт. И вот здесь уже php выглядит, как не самый удачный вариант для инвестиций личного времени, потому что php-на-cms это но карьерный тупик (правда, быстро достижимый), а php-энтерпрайз, это та же джава, но несколько похуже (а если так, то, может, джаву взять?).
> Думаю имеентся ввиду серверная шаблонизация mustache или pug
Серверный рендеринг сейчас сильно развит в мире php потому что php родился ещё в ту эпоху, когда других способов и не было и все последние 20 лет использует инструменты для этого в своей экосистеме. Я вообще не уверен, что значимая часть людей использует серверный рендеринг на ноде, все больше склонны жсончики гонять, так что нет и стимула толкать mustache в какую-то другую сторону. Но даже если и так - они с твигом сравнимы. У твига может быть (кстати, хз) есть больше фич, которые всё равно 3.5 калеки используют, а основное, хм, "ядро" примерно такое же, как и в mustache, как и в питоновой джиндже, готемплейт или где-либо ещё.
> то что нода менее удобна для "обычных" приложений - это очевидно.
А что такое "обычное" приложение? Интернет магазин или странички с контентом? Но тогда и php не очень уже, надо цмску брать, где всё готовое уже. А если перекладывать JSONчики из сети в базу по кастомной бизнес-логике, то оно примерно одинаково, в php ближе к классическому ооп, в ноде больше к функциональщине.
> Нуб на ноде начнет сосать бибу на этапи парсинга входящего бинарного потока от банальной post-формы.
Втираешь какую-то дичь, такие задачи всегда решаются соответствующим пакетом. В php тоже, знаешь ли, никто с нуля не пишет ничего.
Про события и потоки отчасти верно, но очень отчасти, потому что реально там никого rocket science нет.
> А зачем это не делать на пхп? Это демагогия. И вообще это очень джуновская постановка задачи, в духе -зачем в 2к20 учить одно, если другое точно лучше, мне так сказали на ютубе. Многие совсем не вчера начали писать на пхп, и рады тому что язык растет.
Хз, это вы начали нести херню про то, что "JS не очь, пыха лучше будет". А я утверждаю, что писать на них суръезные вещи в целом одинаково. В пыху просто чуть легче вкат, в ноде больше возможностей.
>>803344
> Не верю я в концепцию принято/не принято. Скорее сомгли /не смогли, и опять же на ноде есть nest - значит комьюните родило таки, а не "не принято". Подход собери солянку имееет свои весьма дерьмовые недостатки.
Таки не принято, прекращай думать пехапешными шаблонами, я серьёзно. В какой-то момент ты вырастаешь из штанишек и понимаешь, что архитектура, тулчейн и тому подобное замечательно подбирается под задачу, ровно такие, какие нужны, вместо громоздких комбайнов.
Ещё раз, на любом языке библиотеки есть под любую задачу, на том же js можно подобрать аналог для каждого из компонентов симфони, будет то же самое, если тебе охота.
> Большой фреймворк и комьюнити вокруг него дают оч важную вещь - народ начинает писать по стандартам фреймворк
Весомый плюс только для галер, где нужно грести как можно быстрее и как можно проще рабов заменять.
В итоге у тебя получается деревянная архитектура, на которую идеально садятся новички, идеально по шаблону решаются любые задачи (просто копипастом с условного docs.phpframework.net) но при этом этот самый набор шаблонов со скрипом натягивается на любые случаи, отличающиеся от +- большинства. А любой серьёзный проект в итоге обрастает уникальными чертами знаешь-ли.
Кстати, даже если тебе нужен идеальный набор шаблонов, ты не поверишь, это работа на неделю максимум, собрать компоненты, связки, заточить это дело, накидать стандарты по архитектуре, подготовить темплейты для инфраструктуры и так далее. И можно точно так же тиражировать разработку. И для этого не нужен гениальный архитектор, делается усилиями просто компетентного сеньора. я сто раз так делал
Попробуй как-нибудь уволиться со своей галеры, взять другой язык и посмотреть по сторонам, охуеешь, насколько всё не так и насколько мирок php-разработки своеобразен.
> Для типовых вещей пхп удобнее и гораздо. Но у ноды сови плюсы, мне она нравится но прям все подряд я на ней бы не стал писать, зачем когда есть проще и удобнее инструмент?
А я начал спорить, когда услышал глупости, что-де на пхп удобнее бизнес-логику писать и прочую ересь. Реальные причины выбора языка, ты прав, это технические требования, знание командой, доступность и цена спецов на рынке и всё такое. Но при этом, глобально, нет причины всегда выбирать php или всегда ноду, они сравнимы.
Но конкретно для разработчика есть ещё такие критерии, как современность и развитость экосистемы, например. Или средний рейт. И вот здесь уже php выглядит, как не самый удачный вариант для инвестиций личного времени, потому что php-на-cms это но карьерный тупик (правда, быстро достижимый), а php-энтерпрайз, это та же джава, но несколько похуже (а если так, то, может, джаву взять?).
> Думаю имеентся ввиду серверная шаблонизация mustache или pug
Серверный рендеринг сейчас сильно развит в мире php потому что php родился ещё в ту эпоху, когда других способов и не было и все последние 20 лет использует инструменты для этого в своей экосистеме. Я вообще не уверен, что значимая часть людей использует серверный рендеринг на ноде, все больше склонны жсончики гонять, так что нет и стимула толкать mustache в какую-то другую сторону. Но даже если и так - они с твигом сравнимы. У твига может быть (кстати, хз) есть больше фич, которые всё равно 3.5 калеки используют, а основное, хм, "ядро" примерно такое же, как и в mustache, как и в питоновой джиндже, готемплейт или где-либо ещё.
Максимально двачую. Сам несколько лет "разрабатывал" на cmsках, в том числе были очень крупные интернет-магазины уровня Эльдорадо (не русские, были субподряды от европейских аутсорсеров).
Так вот, цмски всегда заточены на то, чтобы наклацать себе сайтик мышкой и потом мышкой же им управлять. В итоге, вся логика как ядра, так и модулей заточена на какой-то определённый флоу, что пользователь может накликать и зачем (что в базе от таких подходов твориться - не спрашивай. Про нормальные формы эти ребята только слышали). И пока ты действуешь в тех же рамках (накликиваешь поля, подсовываешь шаблончики, настраиваешь триггеры, ставишь модули для кеша и тп) всё прекрасно. А потом клиент хочет, к примеру, динамическое ценообразование в зависимости от ползунка (скажем, баррели нефти продаёт), а у тебя в цмске екоммерц-модуль работает в стиле "1 продукт типа ААА стоит 5$. Сколько продуктов добавить в корзину?" и 0.9 баррелей ты не насчитаешь никак - и всё внезапно коллапсирует в сверхкоричневую звезду, с матами и борьбой с cmsкой в её же кишках, которые на нестандартную логику ну вообще не рассчитаны.
И таких случаев возникает намного больше, чем может показаться, на очень средненьком проекте (от 600человекочасов) борьба бобра с ослом может занять от трети всего времени! И это не считая шквала неожиданных багов после всего этого дерьма. И всё это из-за того, что вместо того, чтобы взять бизнес-логику и просто реализовать её в коде (через симфони, что угодно), приходится ломать, гнуть и шлифовать логику цмски и её плагинов, чтобы оно приняло приблизительную форму той самой желательной бизнес-логики.
И это я ещё не упоминал дохерищу конфликтов между плагинами самой цмски, умение обходить которые - это отдельный сорт чёрной магии.
> wordpress/bitrix сверхлюди?
Я тута. Работаю в конторе, которая пытается выбиться в люди пытается делать хорошо, когда бюджет это булка с изюмом, с постепенным повышением ценника для будущих клиентов. В принципе работает, но это нужны такие опущи как я, которые готовы за еду стартануть в сфере. Но я что-то уже всё и похоже она лучше, чем многие в плане задач, в которые я не попал. Возможно когда-то и придёт к успеху, но я предпочту уйти на х3 к зп в уже успешную контору.
В общем за год задач в стиле "передвинуть кнопку" я не встречал, но иногда надо было целиком что-то адаптивным сделать - обычно футер или хэдер, делается это за час-два неча торопиться. Несколько сайтов верстал и натягивал на битрикс - довольно интересно по первому разу, но всё быстро сводится к копированию шаблона компонента news.list и его кастомизации. Поначалу верстал блоки для сайтов, когда только стажировался - верстал откровенное говно, но на уровень конторы оно тянуло - теперь верстаю пиздато и ситуация обратная.
Ещё есть 2 долгосрочных направления - собственный шаблон по-моему сначала стоило делать шаблон поменьше, что-то специализированное - для жкх например, где конкуренции меньше и сайт конторы, это вечные задачи, они не закроются, хоть обосрись, надо просто постепенно делать и стараться делать не говно.
Ещё остопиздевший тип задач - нерабочие или вовсе отсутствующие формы обратной связи - тоже быстро сводится к дрочеву одного и того же, а если нет - то лучше бы да.
>>803767
Подтверждаю.
А ещё в битриксе обычно предсказуемо стили лежат в папке шаблона в файле со всеми стилями шаблона.
>>А что такое "обычное" приложение?
Это приложение для которого пхп более чем достаточно, а остальное оверхед.
Нахуя магазину нода и асинхронность? Что бы разраб потеребил свое ЧСВ? Но так за банкет платит заказчик, и ему нужно решение, которое будет структурировано, поддерживаемо, и что бы на место разработчика каждый раз не приходил студент который исходя из своего уютного маня-мирка перепиливал все по единственно правильному паттерну, который он видел в своих маня мечтах аля - transport-agnostic API with remote interface scaffolding. А что бы приходил человек который уже занет какова архитектура, и который гарантировано не начнет все к хуям лопатить. Для этого бизнесу нужны фреймворки.
Банально - был бы я коммерсом, и имел бы я некое коммерческое решение - я бы выбрал ту архитектуру которая более структурирована, и которая даст мне возможность иметь больший пул потенциальных качественных разработчиков, и что бы эти разработчики держали своих мышей в клетке. Потому что ты опять же пляшешь от того что придет человек и сделает архитектуру хорошо, хотя ИРЛ в основном будет - пришел и сделал все через пизду. Потому что научиться архитектуре фреймворка и ее придерживаться - это как стих заучить. А по твоему варианту уже свосем другой уровень подготовки нужен, а как известно люди -ленивое говно и нихуя не делают. А те что не ленивы - хотят много денег.
У меня недавно был собес, вопрос был о том как пхп менялся на протяжении времени, крупная фирма, так собеседующий например крайне отрицательно отнесся к тому что в пхп ввели стрелочные функции. Вот что тут скажешь, люди в основном не особо хотят шевелиться.
И если бы я был маня-ойти стартапером, сидел бы в калифорни, и искал инвестора - то наверно я бы конечно что бы мозги запудрить намутил бы крутых и сложных архитектур на модных платформах и стэках.
А цмс-ки зачастую крайне деревянные, и гораздо более медленные.
>>Втираешь какую-то дичь,
>>соответствующим пакетом
Аргументация - "есть же пакет" это инвалидно. После такого в JS стартуют срачи "замыкания не используются и не нужны". Из коробки нода более низкоуровнева, и предоставляет сырые данные. Пхп более удобен и имеет кучу встроенных полезных вещей, хотя при желани так же можно парсить бинарник входящего потока. Для банального магазина - нода менее удобна, не имеет четкой структуры каждый ебашить будет как хочет, разрабов сложнее найти, не понятно что от них ждать, не ясно как в дальнейшем развивать.
>>В какой-то момент ты вырастаешь из штанишек и понимаешь, что архитектура, тулчейн и тому подобное замечательно подбирается под задачу
Нет никаких штанишек, нет никаких маня желаний. Все современной ойти сидит на своих зряплатах потому что есть бизнес. А бизнес решает свои задачи а не выбирает лучшую архитектуру. Поэтому и появились фреймворки комбаный, как ты сказал, и опять же "комбайн" отлично структурируется на части - и вот у нас есть Симфони. Причем "комбайны" появились они и в JS - что закономерно и показательно - платформа созрела. Если однажды go дорастет до уровня этого - и на нем нахуярят свой Ларавел, а заодно еще и ООП завезут.
>>Но при этом, глобально, нет причины всегда выбирать php или всегда ноду, они сравнимы.
Глобально - это синонимично сферическому коню в вакууме , в данном контексте. Был Руби, его любили, были фреймворк Синатра - удачный, и его архитектуру спиздили все другие платформы. Где он? Был и есть питон, так вообще чет идеальный кандидат на вэб-сервера, медленноват правда, и че? Где весь интернет сидящий на серверах на питоне?
Раз пхп все так же лидирует, раз его сообщество огромно, раз язык очень быстро развивается и вообще не буксует - то видимо есть какой то смысл выбирать пхп. Ниче не мешает на пхп-сервере пилить SPA на реакте/вуе/ангулар. Нахер мне руби, на котором хуй кто пишет, если есть пхп?
Тут делемма как с питоном - питон делает хорошо все во всех нишах, и в каждой нише найдется то, что делает задачу в рамках ниши лучше и удобнее чем питон.
иногда интересно на эти сугубо бесполезные темы подискутировать. Жизнь расставит все по местам. Лет 7 назад питон рвался в вэб, по итогу оказался в оче перспективном загончике дата-саенс и прочих нейронок.
>>А что такое "обычное" приложение?
Это приложение для которого пхп более чем достаточно, а остальное оверхед.
Нахуя магазину нода и асинхронность? Что бы разраб потеребил свое ЧСВ? Но так за банкет платит заказчик, и ему нужно решение, которое будет структурировано, поддерживаемо, и что бы на место разработчика каждый раз не приходил студент который исходя из своего уютного маня-мирка перепиливал все по единственно правильному паттерну, который он видел в своих маня мечтах аля - transport-agnostic API with remote interface scaffolding. А что бы приходил человек который уже занет какова архитектура, и который гарантировано не начнет все к хуям лопатить. Для этого бизнесу нужны фреймворки.
Банально - был бы я коммерсом, и имел бы я некое коммерческое решение - я бы выбрал ту архитектуру которая более структурирована, и которая даст мне возможность иметь больший пул потенциальных качественных разработчиков, и что бы эти разработчики держали своих мышей в клетке. Потому что ты опять же пляшешь от того что придет человек и сделает архитектуру хорошо, хотя ИРЛ в основном будет - пришел и сделал все через пизду. Потому что научиться архитектуре фреймворка и ее придерживаться - это как стих заучить. А по твоему варианту уже свосем другой уровень подготовки нужен, а как известно люди -ленивое говно и нихуя не делают. А те что не ленивы - хотят много денег.
У меня недавно был собес, вопрос был о том как пхп менялся на протяжении времени, крупная фирма, так собеседующий например крайне отрицательно отнесся к тому что в пхп ввели стрелочные функции. Вот что тут скажешь, люди в основном не особо хотят шевелиться.
И если бы я был маня-ойти стартапером, сидел бы в калифорни, и искал инвестора - то наверно я бы конечно что бы мозги запудрить намутил бы крутых и сложных архитектур на модных платформах и стэках.
А цмс-ки зачастую крайне деревянные, и гораздо более медленные.
>>Втираешь какую-то дичь,
>>соответствующим пакетом
Аргументация - "есть же пакет" это инвалидно. После такого в JS стартуют срачи "замыкания не используются и не нужны". Из коробки нода более низкоуровнева, и предоставляет сырые данные. Пхп более удобен и имеет кучу встроенных полезных вещей, хотя при желани так же можно парсить бинарник входящего потока. Для банального магазина - нода менее удобна, не имеет четкой структуры каждый ебашить будет как хочет, разрабов сложнее найти, не понятно что от них ждать, не ясно как в дальнейшем развивать.
>>В какой-то момент ты вырастаешь из штанишек и понимаешь, что архитектура, тулчейн и тому подобное замечательно подбирается под задачу
Нет никаких штанишек, нет никаких маня желаний. Все современной ойти сидит на своих зряплатах потому что есть бизнес. А бизнес решает свои задачи а не выбирает лучшую архитектуру. Поэтому и появились фреймворки комбаный, как ты сказал, и опять же "комбайн" отлично структурируется на части - и вот у нас есть Симфони. Причем "комбайны" появились они и в JS - что закономерно и показательно - платформа созрела. Если однажды go дорастет до уровня этого - и на нем нахуярят свой Ларавел, а заодно еще и ООП завезут.
>>Но при этом, глобально, нет причины всегда выбирать php или всегда ноду, они сравнимы.
Глобально - это синонимично сферическому коню в вакууме , в данном контексте. Был Руби, его любили, были фреймворк Синатра - удачный, и его архитектуру спиздили все другие платформы. Где он? Был и есть питон, так вообще чет идеальный кандидат на вэб-сервера, медленноват правда, и че? Где весь интернет сидящий на серверах на питоне?
Раз пхп все так же лидирует, раз его сообщество огромно, раз язык очень быстро развивается и вообще не буксует - то видимо есть какой то смысл выбирать пхп. Ниче не мешает на пхп-сервере пилить SPA на реакте/вуе/ангулар. Нахер мне руби, на котором хуй кто пишет, если есть пхп?
Тут делемма как с питоном - питон делает хорошо все во всех нишах, и в каждой нише найдется то, что делает задачу в рамках ниши лучше и удобнее чем питон.
иногда интересно на эти сугубо бесполезные темы подискутировать. Жизнь расставит все по местам. Лет 7 назад питон рвался в вэб, по итогу оказался в оче перспективном загончике дата-саенс и прочих нейронок.
>отрицательно отнесся к тому что в пхп ввели стрелочные функции
Просто не то чтобы они пиздец какую погоду делают, в то время как реально важнейших вещей в пхп еще целый ворох не достает. Сахар оно канеш хорошо, но больше хочется хорошего такого подъема по качеству самого языка, сахарок бонусом (как в свое время с 7 было, которая язык практически с дна спасла).
>>Просто не то чтобы они пиздец какую погоду делают
Не, он выразился как то в духе "дай Бог их не введут в стандарт", хз ему чем они не угодили.
Ну я так же могу выразиться про введение атрибутов в том виде, в ктором они сейчас. Может он чтото подобное имел ввиду (говенный синтаксис).
Если сам реализуешь весь АР, то нужна прямая связь с хранилищем с возможностью построения всех круд операций (для скл это построение запросов будет). Если просто спрашиваешь что в модели должно быть - только то, что описывсает саму модель (поля) и не привязанная никаким образом к базе логика.
Знаю, странно звучит, вроде как с АР удобно как раз логику пилить прямо так, но это как раз то, что делает Ар антипаттерном.
Думаю что его пугало то что стрелки автоматом будут захватывать контекст, а не только то что в use() прописано. хз в общем, я и на JS пишу, так что мне это по душе.
Ты забываешь, что у готового фреймворка есть плюс: он документирован и есть люди, которые его знают. И когда они приходят в проект, они уже знают, где что искать. Плюс есть информация в Гугле, ответы на stackoverflow.
У кастомного фреймворка есть минус: он как правило не документирован, и надо лезть в код изучать творение очередного велосипедиста, тратить на это время.
Мне как разработчику удобнее работать с кодом на Симфони, у меня нет желания изучать очередную самоделку на ноде. Нужды в них я не вижу, так как тянуть данные из базы, отдавать JSON или HTML вполне можно на Симфони. Асинхронность не нужна чтобы зарегистрировать пользователя или принять купон и выдать скидку.
Конечно, есть сложные проекты уровня Яндекса, где это оправданно, но 99% проектов это не Яндекс. Твой проект это с вероятностью 99% не Яндекс. Просто людям скучно нормально работать и хочется поиграться в сложную разработку за счет работодателя.
Далее, шаблонизаторы на сервере это удобный и простой способ генерации страниц, зачем делать клиентский рендеринг и по сути писать 2 приложения вместо одного, я не понимаю. Лишние трудозатраты, которые в большинстве случаев никак не окупятся. Плюс, по моему опыту использования SPA (твиттер, киви) они более тормозные и дольше грузятся, по частям, когда серверное приложение (например, двачик) просто отдает готовую страницу.
Функциональное программирование красиво решает задачи вроде чисел Фибоначчи, а бизнес-логика лучше пишется синхронным императивным кодом. Опять же, его тупо читать проще, чем изучать всякие самописные функции, их комбинации, map-reduce и разбираться как эти функции друг друга преобразуют. Страшно представить, сколько времени уйдет на проект на функциональщине хотя бы на 100К строк кода (это средний размер приложения на PHP на несколько человеко-лет).
Предлагать CMS для интернет-магазина можно только для простых, маленьких низкобюджетных проектов, большие магазины на CMS не пишут.
Ну и не забываем, что в JS нет тайп-хинтов, неудобно писать синхронный код, может течь память (кстати, как вы ищете утечки в проекте на 100К строк? Какой инструмент используете, если он вообще у вас есть?). Есть ли в JS GUI-отладчик? Есть ли инспекции и подсказки в IDE?
Наконец, последнее. Не помню, чтобы я когда-то видел грамотно организованный фронтенд. Верстальщики каждый по своему все раскидывают, без каких-либо стандартов, получается помойка, в которую лезть неохота. Помоечный SASS с блоками вложенности в 6 уровней, без devTools не разберешься, JS с костылями там, где можно просто серверный шаблон поправить. Имена классов в SASS разбиваются на части, и их нельзя найти поиском. Картинки импортируются в JS файлах (чесслово, не вру). Какие-то кривые JS-костыли, чтобы использовать SVG там, где хватило бы PNG. Шрифты в rem вместо нормальных пикселей (то есть в SASS они пишутся в пикселях, а трансофрмируются в rem). Вместо function x пишут const x = () => {.
Не за это ли ты выступаешь, чтобы такая же помойка была и на сервере?
>>804313
Наверно он испугался, что как в JS вместо читабельного function x начнут писать const x = () => {}.
Ты забываешь, что у готового фреймворка есть плюс: он документирован и есть люди, которые его знают. И когда они приходят в проект, они уже знают, где что искать. Плюс есть информация в Гугле, ответы на stackoverflow.
У кастомного фреймворка есть минус: он как правило не документирован, и надо лезть в код изучать творение очередного велосипедиста, тратить на это время.
Мне как разработчику удобнее работать с кодом на Симфони, у меня нет желания изучать очередную самоделку на ноде. Нужды в них я не вижу, так как тянуть данные из базы, отдавать JSON или HTML вполне можно на Симфони. Асинхронность не нужна чтобы зарегистрировать пользователя или принять купон и выдать скидку.
Конечно, есть сложные проекты уровня Яндекса, где это оправданно, но 99% проектов это не Яндекс. Твой проект это с вероятностью 99% не Яндекс. Просто людям скучно нормально работать и хочется поиграться в сложную разработку за счет работодателя.
Далее, шаблонизаторы на сервере это удобный и простой способ генерации страниц, зачем делать клиентский рендеринг и по сути писать 2 приложения вместо одного, я не понимаю. Лишние трудозатраты, которые в большинстве случаев никак не окупятся. Плюс, по моему опыту использования SPA (твиттер, киви) они более тормозные и дольше грузятся, по частям, когда серверное приложение (например, двачик) просто отдает готовую страницу.
Функциональное программирование красиво решает задачи вроде чисел Фибоначчи, а бизнес-логика лучше пишется синхронным императивным кодом. Опять же, его тупо читать проще, чем изучать всякие самописные функции, их комбинации, map-reduce и разбираться как эти функции друг друга преобразуют. Страшно представить, сколько времени уйдет на проект на функциональщине хотя бы на 100К строк кода (это средний размер приложения на PHP на несколько человеко-лет).
Предлагать CMS для интернет-магазина можно только для простых, маленьких низкобюджетных проектов, большие магазины на CMS не пишут.
Ну и не забываем, что в JS нет тайп-хинтов, неудобно писать синхронный код, может течь память (кстати, как вы ищете утечки в проекте на 100К строк? Какой инструмент используете, если он вообще у вас есть?). Есть ли в JS GUI-отладчик? Есть ли инспекции и подсказки в IDE?
Наконец, последнее. Не помню, чтобы я когда-то видел грамотно организованный фронтенд. Верстальщики каждый по своему все раскидывают, без каких-либо стандартов, получается помойка, в которую лезть неохота. Помоечный SASS с блоками вложенности в 6 уровней, без devTools не разберешься, JS с костылями там, где можно просто серверный шаблон поправить. Имена классов в SASS разбиваются на части, и их нельзя найти поиском. Картинки импортируются в JS файлах (чесслово, не вру). Какие-то кривые JS-костыли, чтобы использовать SVG там, где хватило бы PNG. Шрифты в rem вместо нормальных пикселей (то есть в SASS они пишутся в пикселях, а трансофрмируются в rem). Вместо function x пишут const x = () => {.
Не за это ли ты выступаешь, чтобы такая же помойка была и на сервере?
>>804313
Наверно он испугался, что как в JS вместо читабельного function x начнут писать const x = () => {}.
>проекты уровня Яндекса
Ох уж эти проекты уровня яндекса. Там до сих пор жиквери наравне или даже больше реакта используется. Размер и репутация компании нихера не значит, что там код не дно.
Удваиваю этого господина. У меня с галеры чел ушел в яндекс в 2019м, работал с трекером вроде, такой то фидбэк от него шел про дремучий пиздец, что даже не очень верилось сначала, но позже от еще одного знакомого из Казани точно такие же отзывы услышал. Тимлид 40 летний дегрод, который все эти "новомодные" js-фрэймворки знать не хочет и везде проталкивает свой велосипед, написанный ими почти 10 лет назад. При этом все это говно увязывалось с соседями, которые параллельно пилили микросервисы для них и свой фронт делали на реакте. Даже если они вполовину приврали, мне дико, что такая хуйня может быть в крупных корпорациях.
Именно в крупных чаще и происходит.
>Какая к чёрту логика в валидаторах.
Это вообще пушка. Приведи пример валидатора без логики.
>Anemic model vs Rich Domain model
По словам "domain model" можно со 100% вероятностью сдетектить джуна.
Если речь идет про Active Record, то моделью является "модель данных", а не модель "бизнес процесса", и твои баззворды тут ни к селу ни к городу.
валидация логики в стиле 'юзернейм не должен быть длиннее 256 симовлов' - это ОК в валидаторе. Это не бизнес логика.
Логика в стиле 'есть 2 вида счетов - обычный и кредитный. Обычный счет не может уходить в минус, а кредитный может' - это уже не для валидатора
Потому что если ты это в валидаторе напишешь - то получишь хуету в стиле 'сначала на кредитном счёте уходим в минус, потом переключаем тип счёта с кредитного на обычный и получаем невалидный обычный счёт'
В этом месте неадекваты типа тебя обычно начинают либо копипастить одну и ту же логику по нескольким валидаторам для разных полей, либо пишут один мега-валидатор для нескольких полей сущности сразу. И это даже работает, пока какой нить левый джун в другой части проекта не будучи в курсе о твоём мега-валидаторе, не начинает модифицировать поля в active record модели без обращения к твоему валидатору. Кончают такие проекты печально. Поэтому такая логика должна быть только внутри модели
Дохуя понаписал, а на вопрос не ответил.
У тебя есть объект User. Чтобы его создать нужно имя и фамилия. Есть форма, валидатор и твой объект. Куда поместишь правило "нельзя создать пользователя без фамилии"?
Прежде всего - в модель. Там должна быть проверка в стиле
public function setUsername(string $name)
{
if (!$name) throw new Exception('Fuck off! Username should not be empty!')
$this->username = $name
}
Модель ни при каких обстоятельствах не должна становиться невалидной
Ну а дальше для красоты можно её же ещё и в валидаторе продублировать, но это уже вторично-опционально-по желанию
кстати ещё добавлю что в адекватных проектах данные из формы не пишутся напрямую в модель. Создаётся промежуточная DTOшка для формы, она валидируется, и если всё ок, то данные из неё уже заносятся в модель
>вторично-опционально-по желанию
Ну я и говорю, что ты джун.
Ну запихал ты невалидные данные в модель, все пошло по пизде и упало с исключением. Допустим даже с именованным, а не дженерик хуйней. Как ты узнаешь что именно было причиной? Как ты узнаешь надо ли пользователя уведомить об ошибке? Как ты пользователю сообщишь, что ошибка произошла, чтобы он фамилию заполнил?
>Модель ни при каких обстоятельствах не должна становиться невалидной
Если ты имя устанавливаешь через сеттер, то изначально создаешь невалидный объект без имени. Обосрамс.
> все пошло по пизде и упало с исключением
см. >>804797
>Как ты узнаешь что именно было причиной? Как ты узнаешь надо ли пользователя уведомить об ошибке?
Очевидно причина в кривом запросе с фронтенда. Уведомить - элементарно (в случае не-дженерик эксепшна). В любом современном фреймворке можно впендюрить кастомный обработчик эксепшнов, который бы корвертировал подобный эксепшн в стандартный ответ
И что? Значит в валидаторе будет логика. Вне зависимости от существования dto это логика нужна для соблюдения контракта объекта пользователя. Если поменяешь правила там, придется менять и валидаторе и в dto. Че сказать-то хотел?
ну это я писал для случая редактирования имени уже после создания обьекта. Вообще, конечно, чтобы нельзя было создать невалидный обьект, надо иметь параметризированный конструктор
class User {
public function __construct(string $name)
{
$this-> username = $name
}
}
И всё, хрен создашь юзера без имени
Беда только в том, что это можно сделать только в нормальных Data Mapper ORMках, типа доктрины
Но для Active Record можно использовать приём >>804797
>Беда только в том, что это можно сделать только в нормальных Data Mapper ORMках, типа доктрины
Доктрина не использует конструктор. Опять обосрамс.
Не гори, через пару лет разберешься. А пока научись читать, я все в своем посте написал.
>>яскозал
>>детектит кого то по словосочетанию
>>азаза, бамбит
Аргументы истинного сеньора. Иди ка ты обратно в /b, там твоя шизофазия больше впечатления произведет.
>>они более тормозные и дольше грузятся
Как пример - новое онлайн приложение "Сбербанк онлайн" - эта параша грузится секунд 12. Сука, ну вот нахуя так?
>>Наверно он испугался, что как в JS вместо читабельного function x начнут писать const x = () => {}.
Тут ты не совсем прав, стрелки в JS делают код читаблельнее и лаконичнее в 99 процентах случаев. Потому что в массе своей нужны для коллбэков.
Разве что за исключением таких вариантов:
let z = () => () => console.log('Таки здраствуйте');
А в джаву я так не успею за полгода вкатиться. Чего стоит только Java EE и спринг. А я студентота, мне на работу надо до весны успеть чтобы начать кушать еду.
>А я студентота, мне на работу надо до весны успеть чтобы начать кушать еду.
Ну тогда в джаваскрипт тред загляни.
Сам пишу на фремфорках, как же вы заебали со своим "фреймфорк, куча макак". Фреймворк за вас писать код будет или установил фремворк и проект готов? Макаки часто пишут мимо фрейморков: гуглить как в доктрине делается union? А хуй, сейчас сырой скл напишу. В этом говне без документации потом не придется разбираться? Что происходит с каждым проектом на симфони через год? Куча заброшенных бандлов, куча самописных велосипедов.
Это учебный тред. Вместо того, чтобы проталкивать свой подход, лучше рассказать, о том, какие вообще есть варианты.
Есть подход, когда модель может быть невалидной (а проверка делается в валидаторе), и подход, когда не может (просто не позволяет ставить невалидные значения). В твоем подходе кроме плюсов есть недостатки:
- если валидация требует обращения к БД, каким-то сервисам, то это сделать трудно, так как в модели нет к ним доступа.Например, если хочется проверить, что в БД еще нет пользователя с таким же email.
- модель, кроме хранения данных, начинает отвечать за валидацию и раздувается
- если поля проставляются через сеттеры, то трудно реализовать проверку нескольких полей вместе, так как часть данных пока не проставлена
- бывает такое, что правила валидации в разных случаях разные. Например, пользователь может писать посты не более 1000 символов, а админ - сколько угодно. Такое тут будет трудно реализовать.
- если пользователь ввел неправильные данные, мы хотим показать форму с ними и предложить их исправить. Если мы не можем хранить неправильно введенные данные в модели, то непонятно где их хранить.
- как правильно заметил аноний, при создании объекта мы получаем невалидную модель. Получается, мы должны передавать все свойства модели в конструктор при создании.
- выброс ошибок через исключения позволяет сообщить только об одной ошибке, а что, если у нас несколько полей заполнены неправильно? При твоем подходе мы получим сообщение только об одном.
Хоть я и раскритиковал такой подход, я допускаю наличие простой валидации в модели. Но не для проверки данных из формы, а для защиты от ошибок разработчика. Например, не позволять задать отрицательную стоимость товара.
Также, есть еще один полезный трюк. Если поля модели связаны друг с другом (например: категория товара и ставка НДС), то логично вместо 2 отдельных сеттеров сделать один, чтобы эти поля можно было менять только вместе:
class Good {
public function setCategory(Category $category, float $vatRate) {}
}
ВариаНт сделать DTO для хранения данных формы и валидировать ее имеет тот недостаток, что мы не сможем валидировать саму модель, а только это DTO. Хотя, Symfony Form реализует такой DTO.
Это учебный тред. Вместо того, чтобы проталкивать свой подход, лучше рассказать, о том, какие вообще есть варианты.
Есть подход, когда модель может быть невалидной (а проверка делается в валидаторе), и подход, когда не может (просто не позволяет ставить невалидные значения). В твоем подходе кроме плюсов есть недостатки:
- если валидация требует обращения к БД, каким-то сервисам, то это сделать трудно, так как в модели нет к ним доступа.Например, если хочется проверить, что в БД еще нет пользователя с таким же email.
- модель, кроме хранения данных, начинает отвечать за валидацию и раздувается
- если поля проставляются через сеттеры, то трудно реализовать проверку нескольких полей вместе, так как часть данных пока не проставлена
- бывает такое, что правила валидации в разных случаях разные. Например, пользователь может писать посты не более 1000 символов, а админ - сколько угодно. Такое тут будет трудно реализовать.
- если пользователь ввел неправильные данные, мы хотим показать форму с ними и предложить их исправить. Если мы не можем хранить неправильно введенные данные в модели, то непонятно где их хранить.
- как правильно заметил аноний, при создании объекта мы получаем невалидную модель. Получается, мы должны передавать все свойства модели в конструктор при создании.
- выброс ошибок через исключения позволяет сообщить только об одной ошибке, а что, если у нас несколько полей заполнены неправильно? При твоем подходе мы получим сообщение только об одном.
Хоть я и раскритиковал такой подход, я допускаю наличие простой валидации в модели. Но не для проверки данных из формы, а для защиты от ошибок разработчика. Например, не позволять задать отрицательную стоимость товара.
Также, есть еще один полезный трюк. Если поля модели связаны друг с другом (например: категория товара и ставка НДС), то логично вместо 2 отдельных сеттеров сделать один, чтобы эти поля можно было менять только вместе:
class Good {
public function setCategory(Category $category, float $vatRate) {}
}
ВариаНт сделать DTO для хранения данных формы и валидировать ее имеет тот недостаток, что мы не сможем валидировать саму модель, а только это DTO. Хотя, Symfony Form реализует такой DTO.
> можно впендюрить кастомный обработчик эксепшнов
Это уже плохая архитектура. Такие обработчики ставят для показа страницы 503 и логгирования ошибки, например.
Что, если это исключение вылетит не при обработке данных формы, а при работе какой-то другой бизнес-логики? По идее, мы должны залоггировать ошибку и показать 503, а ты предлагаешь не логгировать ошибку и вернуть сообщение для фронтенда, который к нему не готов (он ведь не отправлял форму).
Условный пример: допустим, ты в методе setPrice() сделал выброс исключения "цена не может быть отрицательной". Если мы отправили запрос из формы ред-я товара, то тогда логично перехватить исключение и отдать сообщение фронтенду. А если мы вызвали setPrice() из какого-то другого места? Например, при покупке акционного товара мы понижаем цену для следующего покупателя. Тут будет нелогично при добавлении в корзину отдавать эту ошибку на фронтенд, она должна логгироваться.
А ты предлагаешь не логгировать ошибку (так что о ней не узнает разработчик), и показывать сообщение покупателю, добавляющему товар в корзину. Маразм же.
В общем, я наверно, путанно объяснил, но твой подход неправильный. Хотя я такое видел, но так делают из-за неумения разбить логику на части или слои: отдельно у нас валидация, отдельно обработка запроса и отдача ответа. А твой подход нарушает это разделение ответственности.
>Это учебный тред.
Двачую. Это продвинутый подход из области DDD. Для простых проектов а-ля CRUD это всё слишком сложно и нафиг не надо. Но для сложных - только так
>Что, если это исключение вылетит не при обработке данных формы, а при работе какой-то другой бизнес-логики?
Дык правильно! Для того то такой подход и нужен, чтоб у нас система никогда ни при каких условиях не входила в невалидное состояние. Чтоб несведующие джуны не могли ввести приложение в невалидное состояние и не могли запороть базу, просто забыв вызвать валидатор (про который они, естественно, будут не в курсе)
> По идее, мы должны залоггировать ошибку и показать 503
>А ты предлагаешь не логгировать ошибку (так что о ней не узнает разработчик), и показывать сообщение покупателю
Ну так перехвати эксепшн в middlevare каком нить (Laravel\Slim), или прям в контроллере (Symfony) а дальше уже возвращай какой угодно ответ фронту. Хочешь - ошибку валидации. Хочешь - залогируй попутно. Хочешь - верни 503. С мидлеварарами вообще бомба - можно сделать отдельный для логгирования подобных эксепшнов, а другие для конвертации их в стандартные ответы фронту.
Повторюсь ещё раз - простая валидация может быть возложена на валидаторы. Сложная (тесно связанная с бизнес логикой) - только в моделях. Модели должны нещадно кидаться эксепшнами. Ну а как потом с этими эксепшнами поступать - должны решать выщестоящие слои приложения. Перехватить эксепшн же можно где угодно. Накрайняк в контроллере прямо.
Ну и ещё раз - это для сложных приложений с применением приёмов из DDD. Просто для интересующегося анона, чтоб он был в курсе, что есть и такой подход.
Нахуя ты нам стелешь про то что сам никогда не писал?
Как ты поймешь что вызвало ошибку, пользовательские данные или баг в коде?
Как ты с помощью middlevare прокинешь ошибку в форму и покажешь пользователю?
Как ты отличишь одно исключение от другого? Напишешь catch на тысячу строк? Или напишешь по хендлеру на каждое исключение?
Что ты будешь делать если ошибки в трех полях, а не в одном?
Какие исключения нужно логгировать, а какие нет?
Как ты будешь делать в модели валидацию, требующую запроса в базу?
Ну и как вишенка на торте - ОРМ, которая при получении данных из базы ничего не валидирует. И ты в принципе не можешь знать в валидном ли состоянии модель, полученная из репозитория.
>Нахуя ты нам стелешь про то что сам никогда не писал?
Писал
>Как ты поймешь что вызвало ошибку, пользовательские данные или баг в коде?
не используй general exceptions. Каждый раз создавай отдельное кастомное. А-ля AccountCannotBeNegativeException. Если их ещё в продуманную иерархию собрать - будет вообще вин-вин
>Как ты с помощью middlevare прокинешь ошибку в форму и покажешь пользователю?
https://symfony.com/doc/current/controller.html#flash-messages
ну или для ларавела там тож какой то аналог есть
>Как ты отличишь одно исключение от другого? Напишешь catch на тысячу строк? Или напишешь по хендлеру на каждое исключение?
см. выше. Продуманная иерархия исключений тебе в помошь
>Что ты будешь делать если ошибки в трех полях, а не в одном?
что тебе мешает в кастомное исключение засунуть инфу об ошибках хоть в газзилионе полей.
Вот как тут например. https://github.com/symfony/symfony/blob/4.1/src/Symfony/Component/Messenger/Exception/ValidationFailedException.php
>Какие исключения нужно логгировать, а какие нет?
дык эт ты сам должен определиться
>Как ты будешь делать в модели валидацию, требующую запроса в базу?
в ActiveRecord моделях - элементарно. Там же прям внутри неё есть всё для доступа в БД. В Доктрине - передай ссылку на entityManager в метод модели аргументом
>ОРМ, которая при получении данных из базы ничего не валидирует.
вот именно поэтому так важно изначально не допускать записи невалидных данных в БД, чтоб потом быть уверенным, что всё что из БД извлекается - всё всегда валидно
Начались маневры.
У тебя есть RegisterUserForm с пятью полями. Есть модель User. У User должно быть имя и фамилия на русском и уникальный email. Если что-то заполнено неправильно, то нужно как все нормальные люди делают, в конкретном поле написать что оно неправильно заполнено, и как нужно заполнить правильно.
В твоем "виртуальном" (потому что на самом деле ты так никогда не писал) подходе нужно:
1) поймать исключение, выброшенное при создании объекта User
2) понять что это именно исключение User'а
3) понять что это исключение о неправильности полей
4) понять что в этих полях не правильно
5) понять что это исключение не надо логгировать
6) понять что информацию об ошибках нужно вернуть в форму
7) понять в какие поля формы какие ошибки засунуть
8) понять что форма с ошибками и её нужно опять показать
У нормальных людей это выглядит так:
1) вызвать у формы метод validate()
2) если форма с ошибками то показать её пользователю
А если сломался сам объект при создании, то просто залоггировать входные данные, потом посмотреть лог и исправить баг.
Если количество моделей будет хотя бы пол сотни поддерживать этот пиздец с "продуманной иерархией исключений" будет просто нереально.
1. Как точно работает DatePeriod? Вот я пишу такую конструкцию: $period = new \DatePeriod($dateStart, new \DateInterval('P1D'), $dateEnd). Где:
1. $dateStart - это начальная дата интервала.
2. $dateEnd - текущая дата сервера.
Потом перебираю $period с помощью foreach и эта падла в первый раз включала текущий день, а в следующий раз его игнорировала. Как это правильно работает? Перед этим время скорректировал с моим временем через date_default_timezone_set. Желаемый результат: получить массив дат, начиная с произвольной даты, до текущего дня.
2. MySQL. Как в одном поле таблицы ссылать на несколько записей из другой таблицы? К примеру, есть таблица, где хранят списки продуктов питания, у каждого естественно есть свой id. Пользователь хочется составить меню из нескольких продуктов. Как я понимаю, должна быть ещё одна таблица, где будут следующие поля:
id - айдишник созданного меню
product_id - список продуктов, которые включены в меню.
В поле product_id можно включать сразу несколько значений? Или подобную задачу решают как-то иначе?
>1. Как точно работает DatePeriod?
Очевидно что ты обосрался с часовыми поясами. Вот пример прямо из документации DatePeriod https://3v4l.org/bWeOq . Как видишь все работает.
>2. MySQL. Как в одном поле таблицы ссылать на несколько записей из другой таблицы?
Так не делают. На каждое сочетание создается отдельная запись. Почитай в википедии что такое нормальная форма и зачем она нужна.
То что ты описал называется связью "многие ко многим". Каждый из продуктов может быть в каждом меню. Да, для этого создается отдельная таблица, так называемая "junction table" таблица-перекресток. На каждое сочетание menu_id, product_id создается отдельная уникальная запись.
Вообще это азы. Скачай себе любой учебник по SQL и там все это будет расписано.
Возвращай 511, думаю норм будет.
>Очевидно что ты обосрался с часовыми поясами.
Но ведь я в начале объявил свой часовой пояс с помощью
date_default_timezone_set, и время в $dateStart выводится моё.
Ты сниппет видел? Добавь туда свои данные и проверь.
Получается DatePeriod не включается конечную дату? Чтобы он её включал, нужно модифицировать конечную дату на +1 день?
проще чем на другой язык, но всёж не так и просто
Всем надо чтоб ты пришел, и мог сразу со старта херячить таски. А для этого, как бы, фреймворк надо знать
Проще всего сделать какой нить пет проджэект на symfony, параллельно работе на yii, и тогда проблем возникнуть не должно
На ларавель легко относительно потому что много общего на самом деле, на симфони сложно
Либо 500, либо 503. 503 чуть логичнее, так как он значит Service Temporarily Unavailable. Причем ты можешь даже указать в заголовке (для роботов), через какое время им рекомендуется повторить попытку. Название заголовка не помню, нагугли.
Давай я еще раз напишу, видимо ты не понял. Вот у нас есть метод setPrice() который может выкинуть PriceTooSmallException (цена продажи ниже цены закупки). Вот твой миддлеваре, который ловит этот эксепшен. И есть 2 ситуации:
1) пользователь при редактировании товара попытался выставить низкую цену, вылетел эксепшен
2) при распродаже из-за бага в скрипте добавления в корзину код попытался выставить товару низкую цену, вылетел тот же самый эксепшен
В случае 1 мы должны отдать сообщение об ошибке. В случае 2 - залоггировать и отдать страницу 503. Как ты в middleware различишь эти ситуации, если исключение одно и то же?
Я вижу только один вариант: при редактировании перехватывать в try/catch исключение PriceTooSmallException, преобразовывать его в FormErrorException, а последнее - внутри миддлеваре в ответ для фронтенда. Но блин, как сложно получается, ты в коде редактирования формы должен перечистить все возможные исключения, и не забывать их добавлять при доработке модели. Опять же, тут есть выход, сделать, чтобы выбрасываемые моделью исключения реализовывали бы общий интерфейс ModelErrorInterface (?) и ловить в catch его, но как-то все сложно выглядит.
> В Доктрине - передай ссылку на entityManager в метод модели аргументом
Ну это же кошмар получается:
$user->setEmail('
А если этому методу еще что-нибуь понадобится (например, сделать DNS запрос чтобы проверить существование домена почты)? А если админу разрешено указывать невалидную почту?
> вот именно поэтому так важно изначально не допускать записи невалидных данных в БД, чтоб потом быть уверенным, что всё что из БД извлекается - всё всегда валидно
Э, не. Возможна ситуация, что правила меняются со временем, и то, что было валидным, стало невалидным.
По MySQL - гугли типы связей в БД: один-к-одному, один-ко-многим, многие-ко-многим и как они реализуются. Также гугли "внешние ключи в БД".
Тащем-та оба сорт оф правы.
Валидация в модели иногда имеет место быть, что бы в базу не попало токсичное говно, но не стоит делать из неё единственный механизм. не прокатит.
И с хуяли в валидаторах не может быть логики? Начиная с банального уник кончая хер знает чем.
>>1761738 →
Здравствуй ОП, внезапно возник вопрос по этой задаче, которую ты проверял. Я ее конечно поправил в соответствии с твоими рекомендациями
https://ideone.com/8Fqpq1 . Это задача вывода вопросов и проверки ответов, которая шла после изучения наследования и абстрактных классов. В твоем уроке было сказано о недостатке наследования
>нельзя поменять тип вопроса - надо создавать новый объект другого класса, что не очень логично (ведь мы не создаем новый вопрос - почему же мы создаем новый объект?). Эту проблему можно попробовать решить, применив композицию.
Собственно сам вопрос, подскажи, как решить эту задачу, без наследования, с использованием композиции или агрегации, у меня совершенно нет идей.
Правильно ли я понимаю, что любое решение задач, где применяется наследование, можно заменить агрегацией/композицией, кода станет больше, но он будет более гибкий ?
Спасибо за ответ, я по возможности разбираю код слима.
Сейчас в пакете fast-route. Мне этот пакет кажется сложноватым.
Ответь на такой нубский вопрос - в фаст-роут есть вариант настройки кэширования, я не оч хорошо понимаю что это есть вообще.
фаст роут кэширует маршрут? как это работает?
Выглядит так, что PHP очень подходит к этому юзкейсу - никаких фреймворков, просто HTTP-client (видимо curl) и JSON-парсер.
Можно ли настроить его на nginx так, чтобы он никогда не выдавал ошибки/варнинги в HTML-страницу, а вместо этого просто возвращал 500 в случае внутренней ошибки либо, если API-сервис ответил 4xx/5xx пробрасывал этот код ошибки?
Или лучше взять что-то другое?
Из альтернатив приходит на ум lua + nginx.
>Нужен сервис для конвертации JSON API в HTML по темплейтам.
Чего блядь?
Если у тебя есть какой то уже имеющийся JSON API, а тебе надо что то показать юзеру в виде красивого сайта, то для таких вещей берешь Angular или Vue.js и пишешь на них single page application на голом javascript
Это извращение, ты на голом месте сильно усложняешь. Бери Vue.js и делай на нём SPA которое будет напрямую с АПИ общаться. Блядь, vue простой как огурец, освоишь по ходу дела
> бери vue
> пердоль JS
> клади хуй на пользователей без JS
> клади хуй на время загрузки страницы
> ну тип ты на голом месте усложняешь))
Когда ты передаешь маршруты вида '/user/{id:[0-9]+}', роутер должен преобразовать их в массивы с регулярками для сопоставления с URL (вид массива описан тут: https://github.com/nikic/FastRoute#overriding-the-route-parser-and-dispatcher ).
По умолчанию при каждом запуске скрипта это делается заново. Если настроить кеш, то преобразование делается один раз и сохраняется в файл, а во второй раз данные уже берутся из файла, что ускоряет работу при большом числе роутов.
То есть кеширование позволяет сэкономить время на разбор роутов.
> клади хуй на пользователей без JS
Я конечно всяких дураков видал. Но этот тред постоянно берет новые вершины.
Чтобы возвращать 500 в случае внутренней ошибки, есть 2 варианта:
- переопределить обработчик ошибок (set_error_handler)
- преобразовывать ошибки в исключения с помощью ErrorException и настроить обработчик исключений set_exception_handler.
Я бы конечно советовал не голый PHP, а Slim + Twig + Guzzle.
У тебя JS-фанатизим. PHP вполне годится для данной задачи и если на нем это сделать быстрее, чем разбираться с Typescript, Webpack, Babel, то почему бы и нет? В PHP в отличие от JS есть тайп-хинты, не требуется никаких собрщиков и компиляторов.
Плюс, в SPA обычно получается медленная загрузка сайта. Сначала грузится HTML-заглушка, потом 1-2 Мб яваскрипта, потом делаются аякс-запросы, и только потом все рендерится. Вряд ли это приятный пользовательский опыт.
Умерь рвение.
Вопрос выдает в тебе неопытного вкатывальщика
У меня флешбеки со стажировки, прекрати пожалуйста
Это да, можно просто через query builder три джойна сделать и все. А можно ли такие отношения реализовать средствами eloquent? Чтобы из базы сразу модельки дергались, так наверное правильно будет. сори я нуб просто
Я хз что там с eloquent я вообще джавист, но вот честно, эта схема говно - если тебя не смущает завязка на postgres, то я бы положил все аттрибуты в JSONB
Бля, я так и сделал сначала. Но в этом же треде чуть выше мне сказали, что хранить аттрибуты в json это говно полное, пришлось переделывать.
Да, пролистал ту дискуссию выше.
Короче, JSONB - это встроенная поддержка EAV в postgres. Соответственно, вопрос стоит как "делать EAV по старинке и охуевать от джойнов" vs "использовать встроенные средства БД"
Вот рили. На мобилках невозможно пользоваться некоторыми сайтами, особенно когда на перерендере с того же аякса едет разметка и клик уходит в ебеня.
Я не знаток Laravel, но гугл выдает такую документацию по отношениям: https://laravel.com/docs/7.x/eloquent-relationships
Если я правильно тебя понял то тебе в определении связанной модели нужно такое :
return $this->belongsToMany('App\Role')->withPivot('column1', 'column2');
В этом случае ты в pivot получишь не только id-шник но и нужыне поля
Мне приходит запрос с токеном - я должен разбить токен по точке, взять первые 2 части и соединить через точку с хэшем этих частей ключом, а потом сравнить с пришедшим, так?
Access токен не храню, а рефреш? Например, я храню его в бд. При обновлении access токена я ищу рефреш токен из рекаеста в бд и если нахожу создаю новую пару, старый токен удаляю из бд, а новый добавляю? А если чел получил токен и почистил куки из которых я беру рефреш? Токен в бд будет лежать 10000000 лет?
Что ты пытаешься сделать? Накостылить свой OAuth сервер? Посмотри как это уже сделано https://oauth2.thephpleague.com/installation/ , прочитай RFC https://tools.ietf.org/html/rfc6749
Создаю массив случайной длины от 5 от 10 значений и заполняю каждый элемент случайным значением от 0 до 100. Потом использую asort, чтобы отсортировать значения по возрастанию, но при попытке вывода возвращается единица. Что за ерунда?
Пушо разрабы придурки. Вот бы выкупить у них права на пыху и сделать с нее конфетку такое вообще возможно?
Добро пожаловать. Со всеми вопросами можно. Там есть и спецы многолетние, в том числе на других языках.
https://t.me/php2ch
Может быть данные не совсем точные, я это тоже не гарантирую.
Дано:
- XAMMP
- На нём развёрнут Moodle локально.
- На Moodle с оф. сайта поставлены два плагина. Оба управляются из командной строки скриптом с тремя командами.
- Нужный скрипт sync.php найден в глубине htdocs.
- Ни с командной строки XAMMP-а, ни со строки из браузера этот скрипт не открывается, хотя доступ в настройках Moodle поставлен, и просит посмотреть специальную программу для этого поискать в интернете, ну или блокнотом открыть.
- В качестве эксперимента в ту же папку отправлен "Hello world!" из трёх строчек. В командной строке XAMMP после запуска сразу появились эти два слова.
- ЕЯПП, то обновлениями плагинов в Moodle управляет некий cron.php, он естественно тоже не открывается.
Правильно ли я понимаю, что для запуска этих плагинов необходимо на комплюктер поставить что-нибудь, что запустит скрипт?
Да, совсем забыл. Если я запускаю из браузера Hello.php, то всё появляется, а если sync.php, то вот:
Command line scripts can not be executed from the web interface
pivot это представление промежуточной таблицы в ORM elouent между двумя другими таблицами находящихся в отношение многие-ко-многим в sql.
нет, group by, а вместо объединений ( JOIN )
Нет, просто пишу пет прожект для себя в образовательных целях. Вроде самую очевидную задачу выбрал, а ебусь уже месяц безрезультатно.
Русским языком же написано, скрипты для cli негоже запускать из браузера. Открой этот скрипт, там будет проверка на это, можешь её убрать если хочешь
Единственное, что я нашёл относительно cli в скрипте - вот:
if ($unrecognized) {
$unrecognized = implode("\n ", $unrecognized);
cli_error(get_string('cliunknowoption', 'admin', $unrecognized));
}
Поищи может или прямо эту ошибку через ctrl + F, или функции get_sapi_name или http_response_code
Спасибо, буду разбираться.
Таки это не настолько глупо, как тебе кажется. Без у тебя js не заработает примерно половина интернета, примерно все сайты типа aviasales и так далее. Да даже двощ, скорее всего.
Короче, браузера без js сейчас не найти, а сознательно его отключают только конченные параноики, то есть где-то примерно никакая часть твоих пользователей. Можно на них забить.
Тред просто великолепный.
Не успел я охуеть с долбоеба, который считает что должно быть не похуй на отключенный джаваскрипт. Как тут же вылез долбоеб, который читать не умеет.
Что завтра? Долболебы которые случайные кнопки на клавиатуре жмут?
Так и я дохуя чего не говорил, однако это не помешало долбоебу приписать мне чужие слова.
Тебя провести за ручку? Рассказть что выучить? Найти тебе заказ? Договориться о оплате? Попинывать тебя что ыб ты не проебьывался а заказ выполнял?
Пишу в Sublime Text 3. Там есть плагин для PHP?
>Интересен вопрос их софтверной архитектуры.
Прикалываешься? Её там нет. Это исторически слежавшееся нагромождение костылей. За то и хейтят
RoR это круто!
Гугл:вакансии Laravel ситинейм.
Дальше сам. Сходишь на пару собесов, поймёшь что нихуя не знаешь, поддоучишься, и таки пройдёшь на работу мечты с зп 30к.
>Не успел я охуеть с долбоеба, который считает что должно быть не похуй на отключенный джаваскрипт.
Я не тот анон которого ты посчитал неумеющим читать, но мне тоже показалось, что тут >>806230 ты охуеваешь с гринтекста, а не с того что есть люди которым не похуй на людей с вырубленным js. Так что кажется это всё таки ты не особо выразительно охуел, а не ананас читать не умеет.
Это походу такой вариант кретинизма, когда видишь только последний пост, а на что это ответ прочитать не в состоянии.
Рыбы похавай, таблетки прими. Но не лезь, сука, в разговор если не способен прочитать хотя бы два последних поста.
Там контекст тоже однозначно не даёт уверенности в том с хуя ли ты вдруг охуел. Ветку я всю ту читал, так что выводы свои оставь себе, дружочек.
Походу некоторым тут нужно не курсы пхп, а курсы двощей проходить.
Куда лучше фронтенд, чем ковыряние цмс-ок которое к бэкенд разработке не относится. Можешь еще Го посмотреть. Это концептуально простой язык.
Да.
А что-то лучше, проще, доступней и... Качественней (?) написал? Раз всё так хуёво, то почему бы не сделать своё и не срубить миллиард шекелей?
Как и написано в сообщении, этот скрипт надо запускать из командной строки. Что именно происходит при попытке запуска из командной строки? Какую команду ты пишешь? Что выводится?
У токенов вроде бы есть срок годности. Ты можешь сделать скрипт, который будет удалять токены с истекшим сроком.
Есть мнение, что ресурсы, не работающие без JS, хуже индексируются поисковыми роботами. Или захочешь ты SEO аудит заказать, а у SEO-шника робот JS не понимает.
Потому SPA логично использовать для "приложений", где много всяких кнопок, диалогов, интерфейсов, для приложений, которые могут работать с нестабильным интернетом. А для "сайтов" с контентом, вроде сайта новостей, блога, энциклопедии мемов, обзоров игр лучше использовать традиционный серверный рендеринг.
Нужно выбирать инструмент под ситуацию, а не твердить, как дебил с двача, что "в 2020" серверный рендеринг это не можно.
Кстати, если тебе хочется, чтобы сайт работал без перезагрузки страницы, SPA тебе не нужен. Просто используй серверный рендеринг и поставь pjax (или напиши аналог), он все сделает сам.
Не в укор, скорее любопытство. Сколько бы не кидали ссылок на очередную поделку для дохуя упрощения работы, везде встретится упоминание, мол нас юзают компании знатные, при чём часто одни и те же. Сук, что у этих крупных компаний за экосистема внутренняя?
Мне кажется, в симфони специально сделали максимально уебищный синтаксис, чтобы всё писали в yaml.
>>Не понял вопроса.
Это ты значит что ты настоящий реакт-макакий, и все у тебя будет хорошо. И смузи будет, и свитшот и хуй в заднице .
Какой json отправлять? Откуда?
Если ты говоришь про бекенд, то на такой случай есть нода.
Просто понимаешь, я нахожусь выше тебя на 2 ступени развития, пихарь, мне не все ваши первобытные обезьяньи изречения понятны. В следующий раз говори конкретнее, ок?
в джава еще похлеще
SSR это усложнение и костылища. Так как твой JS код должен работать и в браузере, и на сервере, и это не всегда просто. И нам теперь надо поддерживать 2 с половиной приложения: бекенд и JS-приложение для сервера и клиента.
На мой взгляд, выгоды от SSR не стоят сложностей. Если тебе нужен SSR, то скорее всего тебе нужно не SPA, а традиционное серверное приложение. Если хочется обойтись без перезагрузки страниц, просто используй pjax.
Объясни плюсы SPA перед традиционным серверным приложением с pjax? Я их не вижу.
Код выглядит верно.
Что касается смены типа вопроса - такое может понадоиться, если мы, например, делаем сайт для создания тестов, и там можо при редактировании теста менять типы вопросов. Тогда придется изловчиться примерно так - сделать отдельно объект Вопрос, а отдельно несколько классов для Подробностей Вопроса:
class Question
{
// Текст есть у всех видов вопросов
public string $text;
// Баллы за правильный ответ
public int $points;
// А вот варианты ответов и логика проверки ответа разная
// Сюда можно поместить объект ChoiceQuestionDetails, NumericQuestionDetails итд.
public QuestionDetails $details;
}
> Правильно ли я понимаю, что любое решение задач, где применяется наследование, можно заменить агрегацией/композицией, кода станет больше, но он будет более гибкий ?
Возможно, что так, не задумывался об этом. Стоит исходить из условий задачи, если тип вопроса менять никогда не придется, то лучшеи не заморачиваться с композицией.
Нихуя там особо разницы нет, это всё искаропки на автомате работает, ты бы хоть посмотрел. Зачем мне твои костыли из pjax городить? Есть же решение лучше и современнее.
В общем, решение верное, но:
- вместо elseif (условие) лучше писать просто else { ... } без указания условия
- if/else можно заменить на вызов функции min (меньшее из 2 чисел) и упростить код
Чтобы писать всего одно приложение на PHP, а не два - бекенд и фронтенд. Я уже писал выше >>807534 что есть случаи, где лучше подходит SPA, и есть случаи, где лучше серверное приложение. А ты тут талдычишь бред про "современнее". Нет такого правила, что теперь мы должны закопать серверные приложения и переходить на очередной JS фреймворк, который устареет прежде чем ты на нем что-то напишешь.
У SPA есть множество недостатков, главный - трудозатраты, они часто тормозные, дольше грузятся, содержат мегабайты JS кода и тд.
>>792085
Может, прописать это в правила автозагрузки в composer.json?
Сериализация, это, конечно, костыльно, лучше бы ты разобрался с оператором clone и магическим методом __clone. Сериализация тебя может подвести, если в графе объектов есть циклические ссылки (объект A хранит в себе B, а B хранит в себе A, например, Работник хранит в себе ссылку на Департамент, а тот - на Работника).
В комитете, мне кажется, логичнее было бы передавать Компанию в метод setAntiCrisisMeasuresFirst($vector), а не в конструктор. Тогда один Комитет мог бы оптимизировать хоть несколько Компаний подряд.
> usort($engineers, function($a, $b) {
> if ($a->isLeader() && $b->isLeader()) return 0;
> if ($a->isLeader()) return 1;
> return $a->getRank() <=> $b->getRank();
> });
Тут не хватает if ($b->isLeader()) { return -1 }. Или, что лучше, написать так: if ($a->isLeader() != $b->isLeader()) { return (int)$a->isLeader() <=> (int)$b->isLeader(); }.
> array_map(function ($employee) use ($department) {
Тут, наверно, читабельнее было бы использовать foreach, ведь array_map предназначен для преобразования массива в другой, и это только сбивает с толку. Не стоит использовать array_map как замену для foreach, стоит использовать его там, где мы преобразуем один массив в другой.
Для замены босса было бы логично сделать в Департаменте метод replaceBoss($newBoss), а не руками переключать признак босса в цикле.
inverseLeader() хуже читается, чем makeLeader()/demoteLeader(), в последних явно видно, какое значение мы ставим. Это неудачная функция, и трудно представить ситуацию, где нам нужно именно инвертировать признак босса, а не установить конкретное значение да/нет.
> if (!($leader instanceof Analyst)) {
Тут по моему ошибка: $leader->getJob(). На такой случай можно бы сделать метод $emp->isJob(Analyst::class).
> * @param Department $department
Тип аргумента уже указан в тайп-хинте функции, незачем эту информацию дублировать, если в комментарии не содержится ничего нового.
> public function getAverageExpenses()
Тут можно было не дублировать код из функции getExpenses() , а вызвать ее.
> @return Employee|false
Лучше возвращать null, тогда можно указать тайп-хинт ?Employee - Employee или null. (кстати, в новом PHP будут union types - можно писать func(): Employee | false ).
> public function setRate(int $rate) : self
> $this->rate = $rate;
Тут у тебя ошибка - ты обращаешься к несуществующему в классе Job свойству. Нельзя обращаться к полям и методам, которые появятся только в наследниках. Так как когда кто-то будет наследовать твой класс, он может забыть добавить в него поля и методы и будет ошибка.
Правильнее было бы сделать в Job абстрактные методы getBaseRate(), getBaseCoffee() и тд, а в наследниках их переопределять.
На будущее, есть статические анализаторы кода вроде phpstan ( https://phpstan.org/ ), они покажут такие ошибки (и некоторые IDE тоже могут их находить). phpstan освоить несложно, достаточно скачать PHAR-файл и запустить из командной строки. Можешь попробовать освоить его. Поставь уровень побольше (опция -l). Также, есть статический анализатор psalm.
В остальном, не так и плохо. Если захочется еще повозиться с ООП, можешь найти задачу про ООП-гостиницу. Думаю, навыки работы с ООП тебе помогут. когда будешь разбираться с фреймворками, хотя там конечно абстракции будут посложнее.
Сериализация, это, конечно, костыльно, лучше бы ты разобрался с оператором clone и магическим методом __clone. Сериализация тебя может подвести, если в графе объектов есть циклические ссылки (объект A хранит в себе B, а B хранит в себе A, например, Работник хранит в себе ссылку на Департамент, а тот - на Работника).
В комитете, мне кажется, логичнее было бы передавать Компанию в метод setAntiCrisisMeasuresFirst($vector), а не в конструктор. Тогда один Комитет мог бы оптимизировать хоть несколько Компаний подряд.
> usort($engineers, function($a, $b) {
> if ($a->isLeader() && $b->isLeader()) return 0;
> if ($a->isLeader()) return 1;
> return $a->getRank() <=> $b->getRank();
> });
Тут не хватает if ($b->isLeader()) { return -1 }. Или, что лучше, написать так: if ($a->isLeader() != $b->isLeader()) { return (int)$a->isLeader() <=> (int)$b->isLeader(); }.
> array_map(function ($employee) use ($department) {
Тут, наверно, читабельнее было бы использовать foreach, ведь array_map предназначен для преобразования массива в другой, и это только сбивает с толку. Не стоит использовать array_map как замену для foreach, стоит использовать его там, где мы преобразуем один массив в другой.
Для замены босса было бы логично сделать в Департаменте метод replaceBoss($newBoss), а не руками переключать признак босса в цикле.
inverseLeader() хуже читается, чем makeLeader()/demoteLeader(), в последних явно видно, какое значение мы ставим. Это неудачная функция, и трудно представить ситуацию, где нам нужно именно инвертировать признак босса, а не установить конкретное значение да/нет.
> if (!($leader instanceof Analyst)) {
Тут по моему ошибка: $leader->getJob(). На такой случай можно бы сделать метод $emp->isJob(Analyst::class).
> * @param Department $department
Тип аргумента уже указан в тайп-хинте функции, незачем эту информацию дублировать, если в комментарии не содержится ничего нового.
> public function getAverageExpenses()
Тут можно было не дублировать код из функции getExpenses() , а вызвать ее.
> @return Employee|false
Лучше возвращать null, тогда можно указать тайп-хинт ?Employee - Employee или null. (кстати, в новом PHP будут union types - можно писать func(): Employee | false ).
> public function setRate(int $rate) : self
> $this->rate = $rate;
Тут у тебя ошибка - ты обращаешься к несуществующему в классе Job свойству. Нельзя обращаться к полям и методам, которые появятся только в наследниках. Так как когда кто-то будет наследовать твой класс, он может забыть добавить в него поля и методы и будет ошибка.
Правильнее было бы сделать в Job абстрактные методы getBaseRate(), getBaseCoffee() и тд, а в наследниках их переопределять.
На будущее, есть статические анализаторы кода вроде phpstan ( https://phpstan.org/ ), они покажут такие ошибки (и некоторые IDE тоже могут их находить). phpstan освоить несложно, достаточно скачать PHAR-файл и запустить из командной строки. Можешь попробовать освоить его. Поставь уровень побольше (опция -l). Также, есть статический анализатор psalm.
В остальном, не так и плохо. Если захочется еще повозиться с ООП, можешь найти задачу про ООП-гостиницу. Думаю, навыки работы с ООП тебе помогут. когда будешь разбираться с фреймворками, хотя там конечно абстракции будут посложнее.
И еще если не ошибаюсь Taylor Otwell ( автор laravel ) кажется предоставлял публике новый микрофремворк, но я забыл как он зовется. И ниче найти не могу на эту тему
Сейчас заметил что на приложенном скрине ни слова про дебаг мод. Чтобы было понятливее, у меня сообщение выглядит вот так.
За несколько последних лет работы на галерах сложилось впечатление, что бизнесу сайты уже не нужны. Нужны только приложения. Плюс ты пиздишь что СПА трудоемки. Они проще чисто серверных приложений, за счет разделения труда между бекендерами и фронтами и за счет снижения зацепления кода.
Да я мимо шел
Или же наоборот сейчас вкатыши в пхп - люди, которые знают чего хотят и не собираются драться с 7ми классниками питонистами, 8ми классниками нодистами и прочими модными-молодежными?
Так же как всякие лисперы, любители доказанных программ, индийские брамины которые себе яица камнями оттягивают чтобы просветлиться и др. чудики
В пхп идут потому что вакансии есть. Все тчк.
>что бизнесу сайты уже не нужны. Нужны только приложения.
Для автоматизации внутренних бизнес-процессов - да. То, для чего раньше писали десктопные приложения на каких нить плюсах, которые по всяким проприетарным протоколам связывались с такими же хрен-пойми-как сделанными серверными частями приложения, сегодня посвеместно вытеснила связка из JS SPA в браузере в роли клиентской части + серверная часть на Java\C#\PHP\Python. Но это не отменяет того факта, что для простых сайтов, где просто большим массам юзеров надо раздавать по большей части статичный контент, старый подход с серверным рендерингом без фронтового JSa всё ещё заходит лучше
> сейчас вкатыши в пхп - люди, которые знают чего хотят и не собираются драться с 7ми классниками питонистами, 8ми классниками нодистами и прочими модными-молодежными?
Я такой. Как мне кажется, сейчас большинство вкатышей в пхп должны быть такими. Потому что левый человек, пришедший за деньгами, просто введет в интернете "шо учить в 2020", где прочитает что пыха мертва, и нужно учить питон/жс. После этого он подпишется на канал "мемы о программировании", где увидит мемасики про то что пыха - говно, а пыхеры - не программисты. Загуглит инфографик зарплат в айти, где пыха среди языков предпоследняя ( так как последний - 1С ). После всего увиденного, он купит себе в кредит комплект "макбук и курс у инфоцыгана по жс", после чего будет столпиться на собеседованиях в очереди из точно таких же ребят. По какой причине этому парню вздумается наплевать на всё выше перечисленное и начать учить именно php? Для этого нужно быть ржаным, гречневым мужиком.
Я без иронии написал, серьезно. Кроме последнего предложения, разве что. Успел на разные языки посмотреть, понял что нравится бекенд. Питон и го ( как минимум в моей стране ) - это борщехлебинг. Нода просто не нравится. Зачем заниматься тем, что тебе не нравится? Джава более-менее нравится потому что она си-подобная, но выбрал все же пхп, так как меня привлекают менее крупные проекты, концентрация на логике, а не на бойлерплейте. Вот, я вижу, выше еще один такой анон пост написал >>806135. И его даже в пыхотреде отговаривают. Я раньше здесь задавал похожие вопросы, тоже отговаривали. Но, как видишь, я еще тут.
Начал обновлять резюме на хх и осознал, что мне нечего блять расписывать. 2/3 работы это специфика конкретной малопопулярной crm, из которых половина это скам в стиле "добавь поле, поправь багу в отчете, реализуй автозаполнение". Что стоит писать в "обязанностях на раб месте"? Из релевантного опыта только парсинг/генерация всяких xsl и json'ов и пара моментов с хитровыебанными запросами к бд.
учитывая, с каким трудом устроился даже на эту работу, с такой хуйнёй меня только в грузчики возьмут
Пиздец, не верю. Как они тогда пишут всякие магазинчики простенькие? Всё на аутсорсе у индусов что ли?
Блин, неудивительно, что тебе платили такие копейки, за чернушную работу. Добро пожаловать в реальный мир, есть разработчики, а есть обезьянки-сайткликеры, придётся тебе начинать примерно с нуля.
И да, беги оттуда, устраивайся на джуна куда угодно, где программируют, для начала.
Пишу следующее:
php htdocs\serv\local\metagroups\cli\sync.php -v
Пишет в ответ сложноподдающиеся определению символы, закрашенные разным способом прямоугольники и буквы из кириллицы. Наверное из-за кодировки, если скопировать, то вот:
?YNИ?????NЛ?? ??N?NИN?
?YNИ??????N? ????N?NЖ?????????? 2
Если я запущу php htdocs\serv\local\metagroups\cli\hello.php
То выведет в следующей строке Hello world!
>>ибо 16к зп
Лол, это прям страйк какой то. Такое бывает вообще?
>>Джава более-менее нравится
А как ты оцениваешь потенциал переезда с пхп на жаву?
Многие говорят что языки очень похожи - дает ли это основания полагать что это облегчит перекат с пхп на джаву.
Я правда еще думаю во флаттер и дарт вкатываться, новые горизонты жы.
>Лол, это прям страйк какой то. Такое бывает вообще
Я из мухосранска на 500к, плюс работаю неполный день. Фултайм было бы 30к. Зп низкая, кнеш, но и не совсем пиздец для города
Почему они все белые, по тонкому льду ходят
Бля, такая же ситуация, как ты описал выше, только я работаю фулл тайм и зп 30к. Надо менять работу, но уже предвкушаю жидкий обсер на первом же собесе.
Лол, нафига я морочусь в пхп по ооп, и по байтоебству немного? Сижу ковыряюсь в исходниках слим, на основе него пишу свой фрейм, что бы на тестовые на его основе фигачить. Раньше другой был, но уже не интересно, хочется что бы psr , реквест/респонс и мидлвэйры.
Ради того что бы 30 к получать?
бладж
Включи в самом xdebug логи (он xml в /var/log пишет) и смотри, куда он пытается подсоединиться и с какими ошибками у него это не получается.
Относительно просто ему будет, только если на php он действительно разрабатывал и знает, чем DI контейнер отличается от service locator, понимает про слоистую архитектуру, сайд эффекты и хотя бы solid (не говоря уже про стейт, сборку мусора, потоки и так далее). В идеале, если делал это на симфони и доктрине, будет похоже на спринг и гибернейт.
Но поскольку он "программировал" на crmке, причём малоизвестной (скорее всего, сделана из говна и палок 100 лет назад), скорее всего он не знает ничего, кроме совсем уж школьной базы (циклы, массивы, get, post, json, select, update, delete) и начинать ему придётся практически с нуля.
Штош, жизнь жестока.
Php можно выбрать в качестве первого языка программирования для изучения или это не для новичков в программировании?
Я РАБотаю в мухосранске с населением 200к. Тут вакансий практически нету, а если и есть, то они на авито) Собираюсь перекатываться на удаленку, там лучше кормят. Поэтому, если у тебя в городе нет нормальных вакансий, то лучше пытайся сразу на удаленку или перекатывайся в другой город. Устраиваться на хуевую работу ради получения опыта не стоит. Потеряешь дохуя времени, а опыта так и не получишь. По крайней мере у меня так получилось.
В дополнение скажу, что 30к по началу казались большими деньгами после того, как я слез с шеи родителей. Но теперь я понимаю, что даже ебатеку не могу оформить с такой зп
Любой язык можно выбрать в качестве первого, но лучше сиподобные, имхо. Пхп в их числе.
По наблюдениям если пыхе не правильно учить (а ее до сих пор чаще учат по протухшим гайдам и книжкам), то это создаст полную кашу в голове, которая даже хуже, чем вообще не знание ничего.
Лучше начинать с того языка, где обучающие материалы качественнее и меньше шанс такого говна наесться. (например шарп)
>Ну это же кошмар получается:
Совершенно верно. Если в симфони ты вдруг хочешь куда-то кидать EntityManager - ты 100% хочешь сделать хуйню.
Так как в симфони объекты могут гидрироваться через reflection, в симфони допускается невалидное состояние сущности до вызова валидатора при создании объекта из внешних данных. Правила валидации указываются у переменных класса через аннотации. Внутри сущности никакой работы с базой быть не должно, только внутри сервисов.
Отвечавший тебе господин тащит опыт Ларавела в Симфони, где он не всегда применим.
>>807705
Нормальных пхп-мидлов, шарящих за ООП, не так уж много. У пхп есть много ловушек для джунов, в которых те надолго или даже навсегда вязнут.
>>807670
Проверь .env и .env.local.
Дебаг-режим включается в index.php при наличии переменной окружения APP_DEBUG.
https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/5.1/public/index.php
>>808648
Можно.
>>808542
>на основе него пишу свой фрейм, что бы на тестовые на его основе фигачить
Чаще всего для тестовых заданий стэк выбирает работодатель. Варианты "напиши как хочешь" не редки, но и не часты. И порой это значит, что контора распиздяйская.
Скинь пример что-ли. Первое предположение - в foreach проходишь массивы, а уже внутренние сортируешь.
На дваче же те же айдишники в каждого комментария есть. Вот и думай, безопасно или нет.
$array = [
'd' => [
'f',
'e',
],
'a' => [
'c',
'b',
],
];
ksort($array);
foreach ($array as $k=>[$s,$j]) {
echo "массив $k буквы: $s и $j <br>";
}
Ну а результат какой ожидаем? Тебе нужно отсортировать массивы, элементы внутри массивов или что?
Если первое, то для массивов не определены операции "больше" и "меньше", делать можешь самостоятельно через usort.
Если второе, то навскидку array_map($array, 'ksort')
Ты глупенький что-ли? Что значит "все"?
Как ты предлагаешь отсортировать ['a'=>['f','e'] и 'd' => ['c','b']]?
> 300к сакраментальные ты вряд ли наберёшь
PHP-миддл с зп 240k в треде. Сколько зарабатывают синьоры и лиды я даже говорить не буду.
> в симфони допускается невалидное состояние сущности
Symfony Forms в 2020 никто в здравом уме не использует.
Хуйня. asort сортирует по значению, если немного поменять массивы, то 'a' никогда перед 'd' не встанет https://ideone.com/ICsPj1
Чтобы не ебаться с окружением. Даже если у тебя просто php, то у тебя на одном сервере могут крутиться два приложения, одно на php5, другое на php7, с разными наборами экстеншенов.
Докер, как виртуалка, очень всё это упрощает, описываешь нужную тебе систему один раз, и потом разворачиваешь то же самое где угодно, на своём компе, компе коллеги, тесте на беременность твоего парня или на продакшен сервере.
Не знаю, почему ты так решил. Но дело и не в нем.
Допустим, нам прилетает json. Мы десериализуем его в объект. Объект гидрируется через рефлексию. Внутри объекта на данный момент может быть что угодно - Симфони просто положила в переменные объекта значения из одноименных ключей json'а. После гидрации нужно обязательно вызвать валидатор, потому что состояние объекта может быть невалидным.
Ну и это необязательно сущность. Любая ДТОшка, например. Но в симфони можно обходиться и без них: в сущностях можно группировать переменные через аннотации и десериализовывать и валидировать только их. Но это уже магия для тех, кто умеет её готовить.
> Ну и это необязательно сущность. Любая ДТОшка, например. Но в симфони можно обходиться и без них: в сущностях можно группировать переменные через аннотации и десериализовывать и валидировать только их. Но это уже магия для тех, кто умеет её готовить.
Я чот тебя не понял. То сущность, то не сущность.
В твоём примере, раз прилетает json, "гидрации" не будет. Будет только десериализация json в объект конкретного типа.
Как обойтись без DTO, если методы и свойства внутри сущностей ограничены конкретными типами?
При попытке заполнить такую сущность невалидными данными посыпятся ошибки. И реализовывать в такой сущности какое-либо поведение очень неудобно. В методах нужно будет думать о том, валидные ли данные и писать кучу проверок.
Или не думать, но контролировать, чтобы во внешнем коде не вызывались методы сущности ДО её валидации. Появляются вот такие вот неявные грабли, на которые рано или поздно кто-нибудь да наступит. Плюс это не даёт нам с уверенностью использовать данные сущности внутри какого-либо сервиса - ведь кто знает, откуда она прилетела, прошла через валидатор или нет, выдаст ли данные ожидаемого типа.
Но да, такой подход возможен, если превращать сущности в простые контейнеры не пойми каких данных. И лишать себя возможности писать простой, предсказуемый типизированный код, в который можно вносить изменения, не задумываясь обо всех контекстах его использования.
Чет хуйня какая-то у тебя получается.
Во первых что значит "Допустим, нам прилетает json". Нам прилетает "сущность в виде JSON".
И схуя-ли ты должен её валидировать у себя? Откуда ты вообще можешь знать правила валидации? А если и знаешь схуя-ли ты их должен копировать эти правила себе в код?
>>809476
Пусть дана такая сущность
https://pastebin.com/XfZJSvv5
Пусть у нас есть сервис, где есть
(@var ValidatorInterface)
private $validator;
(@var SerializerInterface)
private $serializer;
PHPDoc заменен на скобочки, чтоб разметку не распидорасило
Пусть нам прислали такое:
{
"name": "Лёха",
"email": "не скажу",
"mobilePhone": "02))))))"
}
Делаем
$visitingCard = $this->serializer->deserialize($json, VisitingCard::class, 'json');
Получаем $visitingCard с невалидным состоянием.
Но следующей же строкой мы вызываем
$errors = $this->validator->validate($visitingCard); // будет 2 ошибки
if (count($errors) > 0) {
// оборачиваем список ошибок в эксепшн и кидаем его
}
Надеюсь, так яснее.
Это всё в методе сервиса. Снаружи - в других методах и тем более в контроллере - невалидного состояния сущности быть не может. Только между этих двух строк.
Собственно, если ты принимаешь json как-то по-другому, мне было бы очень интересно узнать как.
>>809476
Пусть дана такая сущность
https://pastebin.com/XfZJSvv5
Пусть у нас есть сервис, где есть
(@var ValidatorInterface)
private $validator;
(@var SerializerInterface)
private $serializer;
PHPDoc заменен на скобочки, чтоб разметку не распидорасило
Пусть нам прислали такое:
{
"name": "Лёха",
"email": "не скажу",
"mobilePhone": "02))))))"
}
Делаем
$visitingCard = $this->serializer->deserialize($json, VisitingCard::class, 'json');
Получаем $visitingCard с невалидным состоянием.
Но следующей же строкой мы вызываем
$errors = $this->validator->validate($visitingCard); // будет 2 ошибки
if (count($errors) > 0) {
// оборачиваем список ошибок в эксепшн и кидаем его
}
Надеюсь, так яснее.
Это всё в методе сервиса. Снаружи - в других методах и тем более в контроллере - невалидного состояния сущности быть не может. Только между этих двух строк.
Собственно, если ты принимаешь json как-то по-другому, мне было бы очень интересно узнать как.
Значит у тебя в JSON не сущность, а обычный пользовательский ввод, который ясен хуй надо валидировать. Тебе выше о том и написали, что ты нихуя с исходными данными определиться не можешь.
Если речь идет о сущностях, которые получены из REST API, напрмер, то какая нахуй может быть валидация бизнес правил на твоей стороне. А если речь идет просто о данных формы в виде JSON, то хули тут вообще рассказывать, все и так очевидно.
>Если речь идет о сущностях, которые получены из REST API, напрмер, то какая нахуй может быть валидация бизнес правил на твоей стороне.
Я тебя не понимаю.
Вот ты в своем REST API через POST создаешь объект класса. Тебе в теле запроса прилетает JSON. Ты его не валидируешь или что?
JSON от юзера - это частный случай REST API.
В какой-нибудь Safe Browsing угодил дорвей твой.
Проверь здесь https://www.virustotal.com/gui/home/url
не, вопрос сам собой отпал. выяснилось кароче что вирусняк попал и теперь там вместо файлов сайта лежат просто два txt файла. поэтому блять он и ругался и выдавал forbidden. у заказчика бэкапов никаких нет. с подливой...
Вот что бывает когда из веб сервера делаешь проходной двор, особенно в случае пхп, который может даже из жпега пхпшный код выполнять
>речь идет о сущностях, которые получены из REST API
Из REST API. Из.
Есть сервис, в котором создаются заказы. А ты ничего не создаешь, ты получаешь из этого сервиса данные заказов. И что ты будешь в этих данных валидировать? Ты не знаешь ни процесса оформления, ни инвариантов. Ты можешь попытаться что-то с заказом сделать, но это уже не валидация, а бизнес логика.
>JSON от юзера - это частный случай REST API
Пользовательский ввод нужно валидировать, это тривиально и тут не о чем писать вообще.
да че меня то жалеть. косяк не мой, а заказчика. поставил какой то хуевый плагин на свою cms она ему и все разъебала. у него еще 4 сайта на этом акке и хостинге висит, с ними все ок. хуй знает че они там делать будут. я через 4 часа в отпуске, мне поебать
>И что ты будешь в этих данных валидировать?
>Ты можешь попытаться что-то с заказом сделать
Вот если я буду с этим заказом что-то делать, я буду проверять, что нужные мне значения имеют смысл в моей бизнес-логике.
Мы так интегрировались с API одной госструктуры: чих влево, шаг вправо, и от них прилетает 500. Ой да, поправили, проверяйте. Кто ж знал, что вы такое нам прислать изволите.
Но ты не можешь валидировать сущность. Ты понятия не имеешь по каким правилам она создана. Ты можешь только утверждать что она тебе не подходит. Если это чужое API, например github'а или vk, то ты закрываешь ебало и начинаешь подстраиваться. Тебя ебать не должно по каким правилам формируются там сущности.
Избежать попадания модели в невалидное состояние можно только в одном случае - когда у нас внутри модели находится валидатор.
Как ещё?
Реквест все ещё в силе если что, нужна инфа по работе со строковыми элементами массива, в том числе индексов в виде строк
Посетил планету обезьян.
>>807631
Это фреймворк к реакту, хули там устаревать. API делается отдельно, дед.
>>807705
Еще один дед. Уже выкатил сайт на продакшен через FTP?
>>807727
Рыночек всех кого надо вместит, за исключением таких вкатышей долбаебов, про которых ты написал, они обычно сливаются через пару месяцев.
>>807745
Привыкай, пыхер. Щас бы кодил на реакте и попивал смузи, сидя на балконе с маком.
>>808141
Привыкай, пыхер.
>>808648
А кем ты хочешь стать? Натуралом или фронтенд?
>Проверь .env и .env.local.
>Дебаг-режим включается в index.php при наличии переменной окружения APP_DEBUG.
>https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/5.1/public/index.php
Так у меня же не фреймворк, а компоненты. Или я чего-то не понимаю?
PHP Notice: Array to string conversion in /home/8MaFON/prog.php on line 18
Пиздец ты хуйни нагородил.
Задача состоит из двух частей: сортировка по ключу на первом уровне и сортировка по значению на втором.
На первом уровне ты за каким-то хуем используешь array_multisort, хотя есть простой ksort.
На втором уровне вообще какая-то рекурсивная залупа, к тому же с ошибками, хотя можно использовать обычный sort.
https://3v4l.org/FmGre
Я понимаю, о чем ты. Конечно, я не знаю точных правил формирования сущности в другой системе.
Однако, хорошая документация всегда описывает, что можно ждать, а чего нельзя. Поэтому даже в случае детерминированного API, я предпочту проверять то, что может нарушить работу моего кода. Ответ от API втентакля тоже можно считать пользовательскими данными. Допустим, между мной и другим эндпоинтом случился MITM, и мне могут прислать что угодно. И если я слепо доверяю вконташечке и, например, просто сую ее данные на исполнение в консоль с рутовыми правами, которая управляет ракетным комплексом дальнего действия, может случиться что-нибудь плохое.
>>809952
Валидатор не находится внутри модели. Правила валидации - могут.
>>809991
Это репозиторий не фреймворка, а рецепт, который исполняется при определенных условиях при установке компонентов. Да и хттп-кернел и роутинг - это почти фреймворк для базовых нужд. Фреймворк Симфони - это и есть набор компонентов Симфони.
Заглянул бы уже внутрь index.php папки public, чем строчить на имиджборды.
Это ссылка. Значит, что в функции не будет создана копия переменной, а будет использоваться оригинал. То есть, это дает возможность менять ее значение.
тоже мимо
>Валидатор не находится внутри модели. Правила валидации - могут.
Поясни плиз.
Я пробовал использовать валидацию на аннотациях, но соснул хуев. Она в принципе хуево поддерживает навороченную логику.
На одном говнопроекте я просто перестал создавал модель ручками, а завел сервис который клепал нужную мне модель из DTO.
Мне ясно желание добиться всегда валидных моделей в коде, но я не представляю как этого добиться с условиями типа "лицо моложе 18 лет не может состоять в браке".
>Поэтому даже в случае детерминированного API, я предпочту проверять то, что может нарушить работу моего кода
Нарушение работы кода это лучшее что может случиться. Читаешь логи и все понятно.
Я говорю о проверке бизнес правил, например ты не можешь сказать правильно ли посчитана цена в заказе. Не можешь сказать подтвердил ли пользователь мыло. Не можешь сказать имеет ли пользователь права на доступ к проекту.
Сущность, которую тебе отдает апи, по умолчанию валидна для системы. А то что она лично тебе не подходит не делает её не валидной. Если ты не хочешь отображать маты в имени пользователя не означает что нельзя создать пользователя без матов в имени.
>Допустим, между мной и другим эндпоинтом случился MITM
Почитай что такое JWT.
Ты слушай больше. Ща он тебе расскажет чем "валидатор" отличается от "правил валидации" и что делать если для проверки нужно лезть в базу.
>лицо моложе 18 лет не может состоять в браке
Создай в классе такой сущности метод isValid(), где опиши все подобные правила бизнес-логики.
А дальше напиши над ним:
/
@Assert\IsTrue
/
И теперь если горячий горец захочет взять в жены невинную лоли, валидатор это не пропустит.
>Валидатор не находится внутри модели
>Поясни плиз
>Создай в классе такой сущности метод
Как называется эта болезнь?
Я согласен с тобой. И fail-fast я тоже люблю.
>Почитай что такое JWT.
Ключи шифрования могут быть скомпрометированы.
>>810045
>что делать если для проверки нужно лезть в базу
Для простых случаев, типа unique - есть аннотации. Валидатор сам сходит куда надо.
А в сложных случаях - это уже бизнес-логика, которая живет в сервисах.
Столько хуйни потому что сначала нормально не получалось. Пытался использовать sort с флагами, но не правильно разделил задачу, хотел все и сразу.
>PHP Notice: Array to string conversion in /home/8MaFON/prog.php on line 18
И если в твой вариант добавить еще один массив внутрь, будет та же ошибка.
А если в одном из вложенных массивов нужно будет опять сортировать по ключам, то тоже будет ошибка.
Мой код решает конкретную задачу, решает просто и эффективно. Писать какие-то рекурсии в попытке угадать содержимое массива хуйня полная.
Различай слова и буквы.
>А в сложных случаях - это уже бизнес-логика, которая живет в сервисах.
Проблема в том, что сложная логика по мере развития проекта заводится почти всегда.
И у меня валидация фактически переезжает в сервисы. Причем переезжает настолько, что можно выкинуть её ошметки из модели, а в комментарии к классу написать НЕ СОЗДАВАЙ ЕГО РУКАМИ СУКА ПОЛЬЗУЙСЯ ФАБРИКОЙ.
Это во всех случаях бизнес логика.
А "валидатор" твой это опять рефлексия, которая просто хакает все эти многоумные ооп построения. Создается объект через рефлексию, валидируется через рефлексию, зато все поля приватные, ага. А потом охуительные истории про то что модель не может быть в не валидном состоянии, а на деле это просто проходной двор.
Это не мой валидатор, это валидатор Симфони.
>НЕ СОЗДАВАЙ ЕГО РУКАМИ СУКА ПОЛЬЗУЙСЯ ФАБРИКОЙ
Ну так сделай конструктор приватным и сделай статических фабрик сколько хочешь.
>Это репозиторий не фреймворка, а рецепт, который исполняется при определенных условиях при установке компонентов. Да и хттп-кернел и роутинг - это почти фреймворк для базовых нужд. Фреймворк Симфони - это и есть набор компонентов Симфони.
Заглянул бы уже внутрь index.php папки public, чем строчить на имиджборды.
Как мне показалось по спойлеру, ты меня не понял. Как я уже написал, Symfony я не устанавливал ( composer create project symfony/website-skeleton projectname не делал ). То есть index.php у меня свой, самописный. Это типо неправильно? Но ведь если я проведу установку, разве я не получу полный фреймворк с множеством ненужных пакетов? Поясни пожалуйста, или подскажи что гуглить, а то что-то совсем теперь не понимаю, как должно правильно выглядеть использование компонентов. То что я сделал, это я повторил за каким-то потным битриксером с ютуба со светлой темой IDE, сразу понимал что этому человеку лучше не доверять.
>Поясни пожалуйста
>повторил за каким-то потным битриксером
Я ж не знаю, что ты там повторил. Покажи свой index.php тогда.
Ну я не полностью повторил, подглядел просто. Я в нем делаю то, что необходимо делать в точке входа для минимально работающего приложения: загружаю контейнер с файла, прокидываю контейнер в контейнер, чтобы он прокинулся в ContainerControllerResolver, ну и обрабатываю реквест http-кернелом. А почему вы таки спгашиваете?
Я это знаю, и написал об этом сразу же, когда задавал вопрос о дебаг-моде. Только это не HttpKernel, а абстрактный класс Kernel. Как мне показалось по его исходному коду, без фреймворка его использовать смысла нету. Да и в доках по независимому компоненту HttpKernel о нем ни слова. Так вот, на этот дебаг-мод я уже давно забил, и доябываю тебя последние два поста, чтобы понять разницу между фреймворком и использованием компонентов, и чтобы убедиться что второе я делаю правильно. А всё потому что ты навел меня на сомнения вот этим:
>Это репозиторий не фреймворка, а рецепт, который исполняется при определенных условиях при установке компонентов.
>Заглянул бы уже внутрь index.php папки public, чем строчить на имиджборды.
Верно.
Выше был перечислен >>805360 список недостатков такого подхода с "всегда валидными" моделями, внятного ответа не было, так что непонятно, что они тут на 50 постов обсуждают.
Понять принцип "пишем аннотации для валидации в модели" я могу (хотя аннотациями неудобно описывать сложную логику валидации), но вот засовывать валидатор в модель - дело гиблое.
Зачем сочиняешь? Доктрина, да, работает через рефлекшен (так как у объекта может просто не быть сеттеров для readonly-полей, или могут быть сложные сеттеры, которые задают сразу несколько полей), а валидатор работает через property accessor, который вызывает геттеры (сеттеры валидатору, очевидно, не нужны).
Это демагогия. Сущности создаются не для того чтобы из них данные вытягивать, для этого и массивы годятся. Все что необходимо для проверки, валидации и прочей хуйни, должно быть передано в конструктор. Точка.
Валидатор, хуятор, правила валидации, чесалка очка. Это должно происходить внутри. Если это происходит снаружи, то объект тебе нахуй не нужен.
Что делать если прилетает форма, мы валидируем данные, потом создаем новый объект из этих данных, а этот объект начинает тоже валидировать данные чтобы не попасть в невалидное состояние? Причем проверки бывают от "длина строки не больше 255" до "если сегодня четверг то что-то бля делаем по другому" например?
Можно использовать один и тот же валидатор для формы и для модели. Можно даже закешировать результат валидации, чтобы запросы в базу, например, не повторять.
Можно передать непроверенную форму и валидатор в конструктор или фабричный метод. Объект не создастся, а в валидаторе будет список ошибок.
Можно завернуть все поля в отдельные объекты. Например объект Email просто не создастся с невалидным email'ом. А значит в объекте User мыло проверять не надо. Объект UniqueEmail не создастся если мыло не уникально, а объект Name не создастся если имя длиннее двадцати символов. Опять меньше проверок в User. И поскольку все эти примитивы мы будем создавать по очереди нам не придется ловить какие-то экзотические исключения в мидлварях. Мы пытались создать имя, оно не валидно, и вот почему.
А в пхп 8 с юнион типами можно такую красоту делать. Почти как Option в лучших домах европы. https://3v4l.org/s9Eb9
>абстрактный класс
Значение знаешь?
>Только это не HttpKernel, а абстрактный класс Kernel.
Давай я схожу в исходный код App\Kernel за тебя.
https://github.com/symfony/recipes/blob/master/symfony/framework-bundle/5.1/src/Kernel.php
>class Kernel extends BaseKernel
>use Symfony\Component\HttpKernel\Kernel as BaseKernel;
>понять разницу между фреймворком и использованием компонентов
В случае с Симфони, фреймворком можно назвать базовый набор компонентов для выживания.
Он здесь в секции require:
https://github.com/symfony/framework-bundle/blob/master/composer.json
Если у тебя стоит всё это - считай, у тебя полноценный фреймворк. Если не всё, ну тогда не очень.
>>810471
>>810509
ребятки-котятки, у вас мысли идут в правильном направлении, но налицо явный недостаток фундаментальных знаний.
Чтобы не писать тут целую лекцию - палю вам лютейшую годноту.
Для начала закиньтесь лекцией Марко (ключевой автор доктрины) про дизайн моделей
https://www.youtube.com/watch?v=WW2qPKukoZY&ab_channel=fwdays
Когда потечёте - качайте как бы не лучшую книгу по программированию на сегодняшний день
https://obuchalka.org/20180912103712/predmetno-orientirovannoe-proektirovanie-patterni-principi-i-metodi-millett-s-tun-n-2017.html
прочтите, там есть все ответы на поднятые ИТТ вопросы. Про валидацию, правильный дизайн моделей, и какую логику куда пихать.
Примеры на C#, но если у вас есть хоть немного мозгов, вы поймёте как их переложить на PHP\Symfony\Doctrine
ALSO, когда дочитаете главу про CQRS, обратите внимание на вот этот компонент
https://symfony.com/doc/current/components/messenger.html
надеюсь сумеете сопоставить 2 и 2
кстати добавлю ещё, что когда прочтете главу про Value Objects, посмотрите сюда
https://www.doctrine-project.org/projects/doctrine-orm/en/2.7/tutorials/embeddables.html
>Давай я схожу в исходный код App\Kernel за тебя.
>class Kernel extends BaseKernel
>use Symfony\Component\HttpKernel\Kernel as BaseKernel;
И к чему это? Я все правильно написал, дебаг задается вторым параметром в конструкторе абстрактного класса Kernel. Под его использованием я, очевидно, имею в виду его наследование. Я ж не могу использовать этот App\Kernel, потому что у меня его нету. За это я и спрашивал, должен ли у меня быть исполнен этот рецепт при использовании компонентов, ведь при клонировании symfony/website-skeleton устанавливаются все пакеты. Сейчас я уже догадался, что самый минимум с одним бандлом устанавливается при клонировании symfony/skeleton. Я думал, что фреймворк - это использование абсолютно всех компонентов, а если хочешь не все - то нужно устанавливать компоненты независимо. Сейчас вроде бы понял систему бандлов, и что особо нету смысла, например, независимо устанавливать http-foundation, http-kernel, DI и роутинг, так как это почти что фреймворк-бандл, и отдельно все это связывать - глупо. Что-то такое я хотел от тебя услышать, хотя возможно я и сейчас заблуждаюсь.
> Для начала закиньтесь лекцией Марко (ключевой автор доктрины) про дизайн моделей
Дополню тебя презентацие от всё того же Марко.
https://ocramius.github.io/doctrine-best-practices/#/
Компоненты - это чтобы собрать свой фреймворк. Им не нужен Симфони. Бандлы работают только в фреймворке Симфони.
Меня раздражает что все это в кучу в одном файле. Раскидывать каждый класс в разные папки - тоже хуита. Я так понимаю вариантов кроме как вэбпаком сабирать бандл нету, да?
Можно делать выгрузку по шагам:
- выгрузить и выполнить миграцию
- выполнить скрипт, проставляющий значения (в это время код не работает с полем и никаких проблем это не вызовет)
- выгрузить (отдельным коммитом) код, который работает с этим полем
>>811113
700 строк можно и в 1 файл засунуть. Если проект простой, то проще без вебпака, просто сделать несколько файлов:
- общий JS, нужный на всех страницах
- отдельные JS файлы для каждого раздела сайта
Очевидно связи есть, в БД сохраняется все как надо, но когда возвращаю родительскую модель из контроллера, JSON одноуровневый, без вложенных моделей.
Сериализатором полноценно пользоваться не хочу, потому что все раньше работало, и у меня бугурт, потому что сейчас - нет.
можно, но зачем так усложнять?
если пишешь без фреймворка (где обязательно будет собственный способ хранения конфигов - просто прочти доку)
то сделай конфиг фаил в виде php файла
config.php
<?php
return [
'param1' => 'value1',
'param2' => 'value2',
];
потом где тебе надо данные из конфига
$config = require 'config.php';
echo $config['param1'];
>зачем так усложнять
1) Стильно же
2) Чтобы были подсказки от IDE, а не вспоминать постоянно как же ты назвал параметр, и в каком виде данные он возвращает
3) Чтобы исключить возможность ошибки при неправильном введении параметра
4) На самом же деле, в предложенном тобой варианте придется писать не require 'config.php', а "require `../../../../configs/config.php`", или require 'ab/so/lu/te/path/to/project/configs/config.php'
5) Чтобы менеджер с мозгами хлебушка мог в этом файле что-то изменить и не сломать все нахуй, а сломать все нахуй
тогда не морочь голову, а подключи через композер какую нить либу для работы с конфигами
Звучит, как пиздец. Полумёртвый и ни разу не качественный yii (архитектура говно, везде статические вызовы, говнопаттерны типа active record и сраные магические пехапешные массивы) и crm (без комментариев). Ещё вордпресс или джумлу вписал бы.
Интересно, почему в "наставники" всегда ломится вот такое вот, а не нормальные профи (symfony, ddd, паттерны-хуяттерны, ну просто как база).
Спасибо братишка. Ты реально спас этот тред, а то этот говнокодер почти помог мне вкатиться в пхп. Как представлю что меня на халяву менторил бы не Эрик Эванс, а какое-то чмо, не достойное такой чести, и меня аж передергивает.
Но ты реально выручил. Спасибо что ты сам вызвался быть моим наставником по DDD и паттернам. Как же заебись что ты профи и раскусил этого самозванца. Как с тобой связаться? Я готов приступить к учебе прямо сейчас.
> говнопаттерны типа active record
Кстати, а в орм ларавела же вроде тоже active record? Почему его тогда не поносят?
мимо-не юзал ларавел
> > говнопаттерны типа active record
> Кстати, а в орм ларавела же вроде тоже active record? Почему его тогда не поносят?
> мимо-не юзал ларавел
Да и ебал я симфони с ее доктриной с ее атрибутами и с функционалом где ты
- пользуешь методы а чуть шаг влево уже надо писать SQL
- diff геренрит какую то левую хрень с удалением админ таблиц mssql
- конфигурация не помнит может ли sqlite в ключи зависимости или нет
- нужно писать джойны хотя ты уже описал в сущностях связи
- а менеджер сущностей может просто отмереть и его нужно пере поднимать
Ну и т.д лучше уж лараверовский елоукент как бы он там не произносился
Зачем ты это написал? Да тут даже никто не понимает, что такое патерны, ддд, эктив рекорд. Я хотел просто показать как за час времени поднять сервер настроить окружение, езе за пару часов написать двач. А потом уже иди смотри свои патерны, лезь в свое ддд. Ты что реально думаешь что людям, которые читаю тред вот так вот возьмут и поймут твой ддд? Да с вашим подходом только желание у людей отбиваете. Я бы даже посмотрел на то как ты мегторишь своим ддд, человека который только вчера решил пхп изучать. А yii это просто, позволяет тебе с минимальными знаниями, начать что то делать.
Сейчас будут у тебя новобранцы. Тут в /b/ какой-то ебанутый последним временем клепает треды, в которых он, в стиле советских агитплакатов, призывает всех вкатываться в php, пиздить чужие проекты в свой гитхаб, пиздеть на собесах о этих проектах и опыте работы, задрачивать ответы на вопросы для собесов без понимания их сути. Рассказывает что кодинг не должен нравится, и этим можно заниматься без желания, только ради бабок. Это все выглядит как лютейшая толстота, но при этом у него множество ньюфагов просит советов по вкату. И это говно постоянно висит на нулевой. Интересно, для чего это.
Гораздо хуже примерно понимать ебалу типа DDD, DTO и прочего, именно ориентированного на архитектуру приложения, а не отдельный кусок.
Например я, неделю назад, как настоящий артист в поисках совершенства, дропнул через rm -r папку со своим пет-двощем, который писал 90% времени ебался с фреймворком почти 3 недели, потому что не мог переписать его в SOLID и был не доволен собой.
>symfony, ddd, паттерны-хуяттерны
это не для новичков. Они просто не поймут, нафиг все эти сложности нужны.
Чтоб понимать - надо поучаствовать в паре провальных говнопроектов, чтобы понять как НЕ надо. И возникли вопросы - а как же правильно
конечно. Это идеальный фреймворк для сверхскоростного клепания примитивных CRUD'ов. Для этого он идеален. Для всего сложнее есть symfony
Помоему вся суть этого треда чтобы юный абу, написал своего собственного кота, а дальше уже встал на верный путь и пошел самостоятельно или с помощью адептов из этого треда в глубины самопознания. Что бы на вопрос: "зачем тебе столько слоев абстракции?" мог ответить "потому что это сложно и требует больше времени и сил, нежели ваши круды".
налицо плохое знание доктрины
>пользуешь методы а чуть шаг влево уже надо писать SQL
не sql а dql. А с каких это пор в AR ORMках по другому?
>diff геренрит какую то левую хрень с удалением админ таблиц mssql
ты явно какую то хрень напорол в аннотациях. Ищи ошибки. Ничё он не удаляет
>конфигурация не помнит может ли sqlite в ключи зависимости или нет
доктриной не все СУБД полноценно поддерживаются. sqlite никем в боевых проектах не используется, поэтому на него всем пофиг
Алсо, раз такой умный, пойди и доработай.
> нужно писать джойны хотя ты уже описал в сущностях связи
баран, это специально сделано. Чтоб вытаскивая одну сущность тупики всякие не вытягивали по связям в память всё содержимое БЛ
>а менеджер сущностей может просто отмереть и его нужно пере поднимать
чё за бред. Таблетки давно принимал?
>Чтоб вытаскивая одну сущность тупики всякие не вытягивали по связям в память всё содержимое БЛ
Кстати, что делать если нужно вытянуть список сущностей по одинаковому фильтру, при этом нужно в одном месте джойнить одни связи, в другом другие и т.д.? Сделать общий метод для фильтров, который будет возвращать квери билдер, и на каждую ситуацию свой метод писать типа getEntitiesWithRelationship(1,2) образно говоря? Просто в ларке можно загрузить для всей коллекции эти связи через with или load, она через WHERE IN это делает и на пыхе потом сортирует по айдишникам нужные связи
мне интересно,что такого сложного пишут на пхп?
имею ввиду getEntitiesWithRelationship1, getEntitiesWithRelationship2 и т.д.
для начала тебе надо определиться, зачем ты вообще вытягиваешь такие массивы данных.
Обычно это делают для отчётов. Ну или просто юзеру что то показать. И вот тут то и кроется главная ошибка.
ORMки (любые, не только доктрина) НЕ ДЛЯ ОТЧЕТОВ!
Для отчетов есть другой, специально заточенный под это дело язык.
SQL называется
Если тебе надо просто достать из БД инфу и показать её пользователю - вообще не используй в этом месте в коде ORMку. Просто достань SQLем из БД массив данных, и тупо отдай его фронтенду.
Я уже скидывал тут ссылку на лекцию Марко по этому поводу. Он там об этом говорит. Пересмотри.
https://www.youtube.com/watch?v=WW2qPKukoZY&ab_channel=fwdays
> Чтоб понимать - надо поучаствовать в паре провальных говнопроектов
Ага, и потом набить руку на говнорешениях и искренне удивляться потом "а чо такого, все же так делают?".
Ты же не занимаешься сексом с мужчинами или там жирухами, чтобы понимать, чем плохой секс от хорошего отличается? Вот и тут так же, надо сразу учиться делать нормально, просто задавая вопросы "почему тут всё сделано так, а не иначе?".
>>812467
> Зачем ты это написал? Да тут даже никто не понимает, что такое патерны, ддд, эктив рекорд. Я хотел просто показать как за час времени поднять сервер настроить окружение, езе за пару часов написать двач. А потом уже иди смотри свои патерны, лезь в свое ддд.
Ну так про это и пиши, что готов научить наговнякать helloworld на денвере. Непонятно тогда, зачем ты yii и постгрес упомянул.
И да, ящитаю, штуки типа паттернов, ддд и прочего как раз в самом начале и стоит объяснять, когда человек уже научился писать логику (алгоритмы и структуры данных), но ещё не понимает, как её писать и зачем. И вот тут ты приходишь и рассказываешь, про абстракции, разделение ответственности и предметную область - и даёшь понимание, к чему стремиться и зачем всё это вообще нужно и почему нельзя запросы в темлпейтах писать.
>>812180
Пиши здесь или в телеге в канал по php, там тебе ответят, возможно даже я. А лучше устройся на хорошую работу джуном и там тебе твой наставник всё сам расскажет.
Лично у меня желания полноценно наставничать нет, но я и не претендовал. А отписался потому что раздражает, когда недомиддлы учат джунов всякой фигне и засоряют им мозги. Для новичков уже и статьи написали, и laracasts есть, и туева хуча материалов - обучайся-не хочу.
>надо сразу учиться делать нормально
слушай, если бы мне 10 лет назад, когда я только начинал, начали втирать какую то дичь про сущности, агрегаты, value objectы и разделение контекстов какое то, причём всё это сильно расходилось бы с тем, что я видел в базовых мануалах к популярным фреймворкам - я бы этих умников нахер послал. Как вот тут в треде посылают.
Бла бла бла. Нахуй ты вообще собираешь баззворд бинго если ты никогда так не писал? Ты никогда не использовал DDD в реальном проекте. Ты никогда не писал по SOLID и никогда не писал "алгоритмы" на пхп.
Ты про все это прочитал в умных книжках. Но никогда не использовал на практике. Так какого хуя ты срешь здесь о том что нужно писать только так? Несешь какую-то хуйню про предметную область, но при этом ни разу в жизни контекст не выделял.
DDD CQRS и event Sourcing на пхп это вообще пушка. Открой hh и напищи там php ddd. Сорок вакансий на всю страну, причем в 90% "понимание DRY KISS DDD", т.е. никто там DDD не пользуется. Или вот такое https://hh.ru/vacancy/38092145?query=php ddd "Связной" "мы используем Yii2, Symfony 5" "Понимание DDD" какие нахуй паттерны, там ебаное легаси, которое пытаются перетащить на симфони, и настолько обосрались что нужен долбоеб, который будет их говно разгребать.
Короче на пхп так не пишет почти никто. Я в свое время отказался от очень вкусных вакансий чтобы пощупать проект на реальном DDD, и это была нихуя не красная дорожка к заебатому коду. Пхп просто не готов к таким вещам, то что у вернона изи и само собой разумеется на пхп вызывает анальную боль. Про замшелый кал в виде библиотек типа доктрины я вообще молчу.
Если ты не писал, или попробовал и обосрался, то это не значит что это невозможно. Это просто значит что вы не потянули и обосрались
Последние 3 проекта писали на связке symfony/doctrine/cqrs/ddd. Для cqrs активно пользовали symfony messenger. Доктриной маппили доменные сущности напрямую в БД. Дробили проекты на полностью независимые контексты. Общались контексты только доменными событиями.
Причем это были реально сложные проекты. Не тупые инет-магазины или crmки.
Отзывы у всех участников были одинаковые
. Работать с кодобазой куда легче, можно было бы накручивать фичи ещё очень и очень долго. Без проблем с тех.долгом
> а менеджер сущностей может просто отмереть и его нужно пере поднимать
Это он про ситуацию, когда в ходе flush() выбрасывается исключение, EM "закрывается" и любые действия с ним приводят к ошибке Entity Manager is closed.
>>812754
Доктрина умеет подгружать связанные сущности лениво (при обращении к ним) или жадно (так же, как ты написал про Ларавел). Первое работает по умолчанию, для второго надо просто писать DQL-запрос вида SELECT a, b, c, ... или передать список сущностей в select() в QueryBuilder.
Смысл в том, что он предлагает чему-то научитьи поделиться опытом, а ты ничего предложить не можешь, кроме как грязью его облить. Получается, для начинающего ты менее ценен, чем он, точнее даже бесполезен.
Если уж на то пошло, множество проектов маленького или среднего размера пишется без DDD и работает. То, что SQL-запросы не пишут в шаблонах, понятно и без DDD.
вот так например
/
@Route("/{id}/resolve", methods={"PUT"}, name="resolve")
@IsGranted(CasesVoter::RESOLVE, subject="case")
*/
public function resolve(AbstractCase $case, ResolveCaseCommand $command, CommandQueryBusDecorator $bus)
{
$command->case = $case;
return JsonResponse::create($bus->execute($command));
}
>Если ты не писал, или попробовал и обосрался, то это не значит что это невозможно
Я не говорил что это не возможно. И не говорил что я не писал. И не говорил что я обосрался. Я говорил что это тяжелый труд и куча компромиссов, и чем дальше тем компромиссов и отсебятины больше, и тем менее это похоже на то что написано в красной книге.
>Для cqrs активно пользовали symfony messenger
Какой нахуй мессенджер? Выше постили ссылку на книгу, открой и почитай что такое CQRS >>810849 . Пиздец карго культисты поехавшие.
>Общались контексты только доменными событиями
Как они могут общаться доменными событиями если доменное событие это часть одного конкретного домена?
https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/domain-events-design-implementation
>Причем это были реально сложные проекты. Не тупые инет-магазины или crmки.
Но ты конечно же не расскажешь что это за проекты.
>Отзывы у всех участников были одинаковые
Ты там на солях? Это типа копирайтинг такой? Маша 22 года "Очень понравилось, буду теперь DDD использовать всегда".
Вообще уже по тому как ты это рассказываешь видно что ты пиздишь. На DDD и прочую хуйню очень много точек зрения, причем зачастую прямо противоположных. Даже если делать все по вернону, у которого каждый чих расписан на десять страниц, будут постоянно спорные ситуации, про те же доменные события кто только не высрался и все по разному https://emacsway.github.io/ru/domain-events-in-ddd/
>Вообще уже по тому как ты это рассказываешь видно что ты пиздишь. На DDD и прочую хуйню очень много точек зрения, причем зачастую прямо противоположных
не хочешь не верь.
Symfony messenger - это компонент симфони, специально заточенный для того, чтоб на его основе CQRS делали. Читай:
https://symfony.com/doc/current/messenger.html
https://symfony.com/doc/current/messenger/multiple_buses.html
АЛСО ссылку на книгу я постил
>Как они могут общаться доменными событиями если доменное событие это часть одного конкретного домена?
могут и между доменами перемещаться, если содержат только общую инфу о событии, без внутренних деталей из какого то домена. Типа сущностей (айдишники допустимы. UUID в помощь). Читай указанную книгу, там это описано.
А как ты иначе обеспечишь взаимодействие между доменными конетксати? Так чтоб они ничего друг о друге не знали. Один постит событие с общей инфой о том, что произошло. Другие контексты принимают и как то реагируют. По аналогии с микросервисами, кстати.
А разных точек зрения много потому, что у большинства знание о DDD основано на доисторической книге Эванса, где много теоретической воды, и вообще нет практических рекомендаций, да паре видосов с ютуба. Нужно более соверменную литературу читать, типа приведенной
Непонятно, зачем тут нужна шина. Она ведь только усложняет понимание кода и разбор того, как будет выполняться команда. Куда как проще было бы сделать ResolveCaseService и в нем явно прописать, что делать. И классов бы меньше надо было, и разбираться в коде проще.
А с этой шиной хрен разберешься, что происходит при выполнении команды.
Короче, вот переделанный и упрощенный код:
/
@Route("/{id}/resolve", methods={"PUT"}, name="resolve")
@IsGranted(CasesVoter::RESOLVE, subject="case")
*/
public function resolve(AbstractCase $case, CaseService $caseSvc, CaseJsonView $caseView)
{
$caseSvc->resolve($case);
return JsonResponse::create($caseView->toJson($case));
}
>не хочешь не верь
Очень основательная доказательная база. Отлично расписал что за проекты и что в них сложного.
Хотя погоди это ведь просто "пук".
>АЛСО ссылку на книгу я постил
А ты вообще ты читал её? Че-то в голос, норм ты серишь под себя.
>могут и между доменами перемещаться, если содержат только общую инфу о событии, без внутренних деталей из какого то домена
Тогда это не доменные события нихуя. Бля я думал ты просто начитался этой хуйни, но ты даже и не читал ничего. Просто пиздец.
>айдишники допустимы. UUID в помощь
Кстати UUID ты тоже никогда не использовал. Не спрашивай как я догадался, просто твои мысли читаю.
>А разных точек зрения много потому, что у большинства знание о DDD основано на доисторической книге Эванса
Я тебе скинул статью, с цитатами из кучи книг, от очень именитых авторов. Так ты, долбоеб, её даже не открыл.
>Нужно более соверменную литературу читать, типа приведенной
Бля опять кекнул. Ты ведь нихуя не читал, но продолжаешь срать.
>Непонятно, зачем тут нужна шина.
это CQRS. У тебя всё приложение получается состоящим из набора хэндлеров
AcceptCaseHandler
ResolveCaseHanfler
RejectCaseHandler
и так далее.
В команде - только данные. По сути просто из запроса извлекаются параметры и помещаются в команду
Команда автоматически валидируется
см. https://github.com/symfony/messenger/blob/master/Middleware/ValidationMiddleware.php
А потом исполняется хэндлером
Результат работы хэндлера возвращается фронтенду
Команды и хэндлеры пипец типичные, разобраться очень легко, кода писать минимум
Вся соль внутри метода $case->resolve() (вызывается из хэндлера);
добавлю ещё что хэндлер - это Application Layer в терминологии DDD
А Case и содержимое его методов, типа resolve() - это уже слой доменной логики
Нет, вопрос, зачем нужна шина и объект команды, когда можно просто напрямую вызвать хендлер из контроллера? Тогда перейти к хендлеру можно в один клик, и не надо искать кто что обрабатывает.
Паттерн команда был придуман для десктопных приложений, там они используются для undo/redo.
Нет дженериков.
Нет нормальной перегрузки методов и нужно городить и инжектить везде фабрики.
Нет модульности, нужно бегать и линейкой по пальцам хуярить чтобы никто классы из другого контекста не использовал.
Уебанская система типов, сейчас добавили ковариантность, но это роскошь для свежих проектов.
Крайне уебанские библиотеки вроде доктрины, все писать самим с нуля не реально.
Крайне хуевая иммутабельность. Городить __clone методы заебешься.
Ебучие исключения и ебучий null везде.
Можно и так, да. Это плюс-минус классический стиль написания кода под Symfony. Примерно то как обычно в доках рекомендуют.
Беда в том, что эта фигня с сервисами, внутри которых, собственно, находится логика - это, по сути, процедурное программирование. У тебя данные отдельно - в сущности. А логика отдельно - в сервисах. Можно и так, конечно. Особенно если логики немного и она простая. Но когда её много, всё это превращается в процедурную лапшу с несколькими сервисами а-ля CaseService, CaseManager, CaseHandler и т.д, где куча методов, которые все хаотично вызывают друг друга.
Плюс в этих методах у тебя смешивается доменная логика, и логика приложения. Всякие там извлечения-сохранения данных в БД, и т.п. И одно сложное, и другое. Сложность перемногжается и улетает в космос.
И когда, например, постороннему человеку надо посмотреть, что же происходит при резолве кейса - тебе приходится по всем этим сервисам прыгать по методам, как мартышке. Кде в куче загрузка из БД, куча логики, сохранение в БД, транзакции, сообщения на сторону и прочее и прочее. Понять в этом что то становится нереально сложно.
команду по отдельности валидировать очень удобно. Перед тем как логику запускать. Это же DTOшка.
загружаем в неё данные из Request,
и просто засовываем её в шину. В симфони мессенджере для этого даж ValidationMiddleware специальный предусмотрен. Для предварительной валидации команд перед обработкой.
https://github.com/symfony/messenger/blob/master/Middleware/ValidationMiddleware.php
А без шины request валидировать типа сложно. Пиздец, научился страть не снимая свитер.
А правила валидации ты куда будешь писать? С командой очень удобно - их можно написать аннотациями прямо над свойствами команды. А если команды нет - то куда?
Писать простыню правил валидации прямо в контроллер? А если захочется ту же команду ещё откуда то вызвать? Из консоли, например.
Создавать symfony form с правилами валидации? Опять же - а если из консоли хочешь сделать резолв кейса - то как эту форму заполнить.
Короче метод с валидацией команд на практике самый удобный
*, а есть не it-компания
все будет
>крупная it-компания с проектами на drupal 7, 8
Только на друпале? Эт че за айти-каомпания такая, лол?
Если помимо друпала там есть вещи посерьёзней -- однозначно идти. Слышал, в мейлру в личных кабинетах их жалких онлайн-игр активно используют друпал, но там можно получить и много полезного опыта.
В европе друпал очень популярен, можно с легкостью на нем непыльную удаленку найти. Да и у нас в общем тоже, но в основном на всяких правительственных сайтах. Вообще из цмсок он наверно самый лучший, но все равно это не серьезно совсем.
1. Есть потенциальная подработка - фирма занимается натяжными потолками, и возможно захочет что то типа "калькулятора цвета". То есть будет фотка комнаты, ну и будет натяжной потолок. И короче будет выбор цветов - и при нажатии на кнопку цвета - потолок на картинке должен менять цвет.
Самый ущербный вариант - иметь сотню одинаковых картинок с разным цветом потолка, и по нажатию на кнопку грузить аяксом с сервера. По сложности реализации в сущности хуйня.
Но мож есть какие другие варианты поумнее? Мож как то распердолить бинарник картинки?
Друпал 8 - безусловно, лучшая из CMSок (да и д7 был лучшим, 10 лет назад).
Но при этом между cms и не-cms лучше выбирать не-cms, потому что читай выше:
>>796916
>>804131
Но с другой стороны, yii - это то ещё говнише, конечно, лучше, чем какой-нибудь cakephp или codeigniter, но всё равно в разы хуже чем laravel или symfony с точки зрения современности, архитектуры и банального качества кода. Тем более, если компания не-it, то про профессиональный рост лучше забудь, скорее всего там всем на всё насрать и ты можешь хоть на perl писать всё.
Поэтому, добрый совет: ищи нормальную it-контору на symfony или laravel, а от текущих предложений откажись. Сэкономишь себе годы не самого качественного (не)профессионального опыта.
Но если вообще никак, то айти компания почти всегда лучше, чем не айти, за исключением ситуации, когда ты точно знаешь, что в этой не-айти конторе сильный айти отдел с людьми, которые готовы учить и требовать. По понятным причинам, такое - редкость.
Можно сделать картинку с прозрачностью и подложить снизу под нее див с нужным цветом. Также, можно попробовать помудрить с CSS-эффектами (которыми можно перекрашивать черно-белую картинку).
С твоей шиной все еще сложнее. Когда ты вызываешь сервис напрямую, легко отследить, как выполняется код, а в IDE в один клик перейти к сервису. А когда ты свою команду отправляешь в шину, то замучаешься разбираться, кто и что с ней делает, так как у тебя там в коде может быть 1000 обработчиков и замучаешься разбираться, какие из них задействованы.
Мне лично уже давно наставник не нужен, поэтому в целом наплевать, обучайте кого хотите чему хотите, хоть смоллтолк им за деньги преподавайте.
Новичков только жалко, сначала вы научите их плохому, а потом они опять будут ныть на моём дваче, что нормальную работу найти не могут и что потратили лучшие годы жизни не на то. Я уже не помню, сколько постов о неудачных попытках поиска работы или переката я прочёл за последний год.
>>812809
Дурачком значит был, раз вместо того, чтобы сразу спросить и понять, как делать правильно и вообще какие здесь правила игры, начал бы делать по своему.
>Дурачком значит был, раз вместо того, чтобы сразу спросить и понять
Джун не палится.
В 2010 симфони был в первой версии, ларавель в природе не существовало, а доктрина была active record'ом. Только вышел php 5.3, и симфони его даже не поддерживал.
Я сегодня почти весь день делал последнюю задачу из регулярных выражений про госзакупки. Сделал, но не целый день же на это убивать. Чому я такой тупой?
> 10 лет назад, когда я только начинал, начали втирать какую то дичь про сущности, агрегаты, value objectы и разделение контекстов какое то
Паттерны и ddd уже были, Эванс свою книгу вообще в 2003 выпустил. Да и сравнительно нормальную архитектуру делать можно было даже на первой симфони, с оговорками.
4 пыху не застал, хотя мой друг в 2012 вроде на ней что-то делал для каких-то американцев
Попробуй это почитать - https://laravel.com/docs/8.x/eloquent#local-scopes
и мб что-то такое получится: $products->maxPrice($request->get('max_price'))->minPrice...
Можешь попробовать сделать приватный метод, который обрабатывает реквест с прайсом.
И разве в if не должно быть isset? (ну типа без варнингов)
Если у тебя там 2 блока, я бы вообще не беспокоился. Или можно сделать функцию findByPriceRange($min, $max). Если условий будет много то можно сделать объект ProductFilter и метод findByFilter(ProductFilter $f).
>И разве в if не должно быть isset?
$request->get() возвращает NULL, так что не обязательно как я думаю
Что то можете о ней сказать?
Так то я на ларавел пишу, опыт у меня не большой пока что. А это просьба помощи, ну и денег конечно заплатят.
Но сильно как то погружаться в эту цмс-ку не хочу. Кто то имеет опыт работы с ней? Есть какие то гайды для быстрого понимания темы?
Просто беги оттуда и всё. А товарищу скажи, что не смог, занят. Ты совсем не обязан страдать.
>меня один товарищ попросил помочь
НАХУЙ И ВПИЗДУ.
Вообще неважно, на чем, как, куда.
НЕ РАБОТАЙ ПО ЗНАКОМСТВУ.
Дело кончится тем, что ты будешь пердолиться как пёс за копейки.
Позорище.
Зря взяли из ts идею объявления свойств в конструкторе, эта хуйня приводит к тому, что приходится смотреть список свойств в 2 местах вместо одного - и всё это ради экономии нескольких строчек кода.
Такое ощущение, что пытаются понапихать в язык побольше сахара, хотя лучше бы или виртуальную машину развивали или хотя бы иммутабельность добавили.
Половина всех строчных функций с кириллицей и прочей экзотикой не работает. В таком случае ищешь аналогичную функцию в mbstring, а если нету - сосешь бибу и делаешь костыли.
Спасибо, уже причмокиваю.
>или хотя бы иммутабельность добавили
Инфоцыганин от мира бизнес-программирования, куда ты лезешь, блять?
Просто по http://phpbook.ga/ в повторении есть задача, в которой необходимо поменять регистр первых букв предложений, но ни
ucfirst(), ни
mb_ucfirst(), ни
mb_convert_case("$names[$n]", MB_CASE_TITLE, "UTF-8")
не работают.
> А куда эту функцию поместить?
В сервис поиска товаров, наверно. Или, если в Ларавель так принято, то в модель. Вообще, правильная архитектура нужна, когда кода становится много и он становится сложным. Твои 6 строчек можно хоть в контроллере оставить, ничего это не поменяет.
>>814498
По моему, чуть правильнее будет не разделять minPrice/maxPrice, а сделать один метод withPrice($min, $max).
mb_ucfirst не существует. ucfirst не работает с кириллицей. В mb_convert_case лучше убрать лишние кавычки: mb_convert_case($names[$n], MB_CASE_TITLE, "UTF-8"). Она должна работать.
Более подробно про строчные функции и кириллицу тут: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
> Можно отрезать первый символ с помощью mb_substr(), перевести в верхний регистр с помощью mb_strtoupper() и приклеить остаток строки
Спасибо, буду копошиться.
В принципе дописал, но чет мои контроллеры жирноваты.
Пример - в контроллере получаю данные $post, атрибуты, далее провожу специфические проверки входящих данных ( число, is_null и т.п. ), далее загружаю конфиг для валидатора, валидирую пришедшие данные, после вызываю нужную модель абстракций у меня чет маловато, поэтому в модели уже запросы в базу через PDO, опять же вызов модели обернут в try...catch , после этого вызывается модель которая отвечает за запись проведенного действия ( типа если ресурс добавлен - то это пишется в таблицу соответствующую ), а после уже вызывается класс флэш-сообщений. Большая часть всего этого берется из контейнера, но чет все равно выглядит как куча - мала, мне не нравится.
Я выше читал упоминание про "слои", подскажите какую книгу нормальную на эту тему почитать? Как лучше отделить саму бизнес - логику от конкретно работы контроллеров, или работы класса ответственного за подключение к базе-данных?
Паралельно читаю исходники слим - вот как там сделано мне нравится.
И еще, ко всему этому у меня прикручена самопальная RBAC- система управления доступом и ролями.
И вот у меня есть учетные записи с ролями и разрешениями. Как лучше проверять то что данному пользователю можно выполнить действие по данному роуту?
У меня аутентификацией занимется класс Auth.
Думаю так - создать класс типа Roles который проверяет роли/разрешения у пользователя ( сам user определяется по сессии и добавляется в request в мидллвэйре, если он зареган конечно ). И с помощью класа Roles проверять в каждом контроллере право на доступ к нему пользователя.
А еще - я так понимаю что для того что бы уже в шаблоне допустим скрыть кнопку, если у юзера нет разрешения ее видеть - еужно в twig что то типа хелпера , как вларавел, делать? Я твиг не оч знаю.
А что тебе не нравится?
п.с.
А с этим modx придется много времени потратить на то что бы начать чето на нем делать, и притом одноразово - я потом цмс заниматься все равно не буду.
Сформулируй вопрос конкретнее. Что делаешь, что получаешь, что хотел бы получить.
Жму кнопку Run (зеленый треугольник), чтобы запустить код в файле "index.php"
Если же я открою другой файл, например "test.php" то, для того, чтобы запустить код в этом файле, надо в настройках Debug configurations руками назначать файл, который я хочу запустить.
А я хочу чтобы запускался код из файла, который открыт в текущей вкладке редактора без указания, что надо запускать именно этот файл.
Не уверен, что так в принципе можно сделать, потому что с "RUN" запускает конкретную конфигурацию.
Возможно, в шторме есть возможность "запустить текущий файл" (посмотри через "Search actions", по двойному нажатию на шифт) или "запустить конкретный файл" (через правую кнопку мыши на конкретном файле".
Ещё замечу, что такой возможности может и не быть, потому что так никто не делает: точка входа в приложение всегда одна, это index.php, а дальше уже подключаются файлы и работает роутинг, который определяет, что нужно вызвать в зависимости от запроса. В крайнем случае, две - index.php и cli.php
Пкм по файлу помог
Скорее всего будет легаси на менее развитом языке, без дженериков и всего такого + ворох хуёвых паттернов вида актив рекорд.
Скорее всего с тобой в команде будут долбоёбы, которые не отличают уникальный индекс от функционального, не слышали про нормальные формы и думают, что делать запросы в цикле (потому что орм и foreach ($id => $ids) {User::load($id)} выглядит не так страшно) это нормально.
Ещё запросто окажется, что дебажить все вокруг тебя будут принтами, а вместо гита будут просто править общий код на ftp, но это как повезёт уже.
Короч, я б рекомендовал найти нормальный проект или даже стартап на котлине вместо того, чтобы менять стек. Стек меняют ради рейтов, какой-то новой области (например, AI или там железки) или если тебя не устраивают особенности текущего стека, например рантайма.
Влетишь с двух ног, после джавы/шарпа (особенно если беком на них занимался) пых как родной за день осваивается, не считая технологий. Ну а про говнокод/легаси всякий выше верно написали, такое тут в 9 из 10 рабочих проектов. Есть канеш шанс, что на чтото не протухшее попадешь, но я бы особо не рассчитывал.
>Ещё запросто окажется, что дебажить все вокруг тебя будут принтами, а вместо гита будут просто править общий код на ftp, но это как повезёт уже.
Блять, анончики, скажите что это толстота. Ну не может же такого быть.
Ну про дебаг принтами могу подтвердить. Для мелких веб-студий, где джунов продают под видом сенёров - это норма. Почти никто не умеет пользоваться xdebug.
Что касается FTP - то я как то давненько такого не видел. Да, заливать на боевой сервак ручками по FTP - это сплошь и рядом. Но разработка всё же щас почти везде вертится вокруг git + gitlab\github
Лично я в последний раз слышал, чтобы кто-то вместо гита копировал файлики по фтп в 2015, но не удивлюсь, если до сих пор есть такое, особенно среди мелких говностудий и/или битриксоидов
Бывает, но пожалуй только в тех самых мелких говностудиях, которые выполняют очередную работу по аутсорсу. Видел такое, принимал их работу. Они и в коде устраивают кошмар. Но, понятно, в таких местах кроме отчаянных вкатунов никто работать не станет, так что в целом по больнице это скорее исключение.
Кстати о xdebug.
Чет как то не могу в вижуалстудиокод его настроить. Точнее как расширение его в пхп добавил, в сам редактор тоже.
И редактор его видит, но дебаггер спотыкается сразу об первый вызов класса - не видит нэймспэйсов что ли.
Притом что класс то доступен - приложение работает же.
Говнюк блин.
Включи в самом расширении дебаг лог и в /var/log смотри, куда он идёт коннектится и чего ловит.
Там архитектура простая - IDEшка поднимает сервер, xdebug стучится туда и говорит, что он сейчас сделал и что видит.
Слим простой как палка. Если это ты считаешь сложным - то у меня для тебя плохие новости
Если веб сервер и твоя локальная машина, где ты ведешь разработку - это две разные машины (ну или исполняется код в докере каком нить - что равносильно другому серверу) то его не так просто настроить. Куча подводных камней.
xdebug сообщает твоей IDEшке имя файла с полным путём к нему, который в текущий момент исполняется
Твоя IDEшка как то должна сопоставить сообщаемый её путь к файлу с локальным путём к файлам. Если машины разные - то он почти никогда не совпадает. Вот и спотыкается дебаггер
Чтоб разрешить проблему надо маппинг локальных\удаленных файлов настроить. ХЗ как это в студии делается. В PHPStorm это можно в настройках проекта задать
>>Слим простой как палка.
В использовании вполне.
То как устроено все внутри, с реализацией мидлвэйров, в том как это все вызывается, где что и откуда, и то зачем оно такое каоке есть - роутер, дипетчер, роут колелекторы и прочее не сказал бы что там прям просто.
Опять же сами правила регулярки парсера роута в либе stdParser не простые нихрена.
Ну это у меня первый опыт в ковыряния в потрохах. Так что возможно мне не с чем сравнить. Однако я сомневаюсь чет что все мпрям с ходу влезли в код этого фреймворка, и четко поняли что и откуда там работает
https://ideone.com/s07RqW
какая то дикая регулярка
Еще и скрин своего рабочего стола воткнул. Воистину я дурак, фейспалм
Вот сайт - https://regex101.com/ можешь потыкать.
Скопируй спойлер, вставить там и экспериментируй. Также там есть объяснения к регулярке (справа сверху):
\s([a-zA-Z_][a-zA-Z0-9_-])\s(?::\s([^{}](?:\{(?-1)\}[^{}])*))?
Сравнительно с другими фреймворками - там всё просто. Самое главное, что там нет или очень мало магии, всё, что происходит, задано явно и довольно очевидным образом.
почему хейтят? Для скоростного клепания CRUDов он идеален. Проблемы с ним начинаются только в больших и сложных приложениях, где на AR модели приходится слишком много обязанностией. Формы\валидация\работа с БД\бизнес-логика. Всё сразу.
В итоге, в среднестатистичеcком интернет-магазине, в AR модели Order (в каком нить Yii) я видал и по 15000 строк кода
ну это от молодёжного максмализма. Кто постарше и поопытней такой фигнёй не страдает.
У тебя приложение на 80% состоящее из CRUDов? Бери Laravel. Он, со своей AR ORMкой Eloquent, идеально заточен для подобных проектов
У тебя сложное приложение, где КРУДов почти нет, зато полно запутанной бизнес-логики? Чтож, Symfony+Doctrine+DDD то что тебе надо. Только DDD не забудь вначале освоить. Хотя бы базовые идеи и приемы.
Вообще, по моему скромному мнению, использовать доктрину в AR-стиле, с анемичными моделями и логикой, вынесенной в говносервисы - это забивать микроскопом гвозди. Она не для этого
Ubuntu или что-нибудь из списка https://ubuntu.com/download/flavours
Ещё Fedora юзабельна, но по убунте всяких гайдов гораздо больше.
Ну всему своё время же. Я только спустя четыре года научился ориентироваться в коде доктрины..
Тут есть много сложных моментов, и по моему, выражение тут излишне усложнено.
Сложный момент в регулярке - это использование рекурсивного шаблона (?-1). Они описаны тут: https://www.php.net/manual/ru/regexp.reference.recursive.php . Они позволяют ссылаться на ту же регулярку и обычно используются для случаев вроде тех, когда может быть любое число вложенных друг в друга скобок.
Вот пример выражения, которое ищет пары вложенных друг в друга угловых скобок вроде <<>>: https://regex101.com/r/RFHxCh/1
Вот выражение: <((?R)|)> - вначале идёт <, за ней либо ничего, либо рекурсивная ссылка на эту регулярку, за ней >. За счет рекурсии мы находим вложенные друг в друга любое число раз пары скобок.
Попрактикуйся на regex101 с рекурсией, чтобы лучше в ней разбираться.
Вот та регулярка из роутера и примеры строк, под которые она подходит: https://regex101.com/r/yxYBkY/1 - там рекурсия используется как раз, чтобы выражение могло быть любой вложенности.
Также, там у регулярки использован флаг x - игнорировать пробелы в ней.
(?: ... ) - это как обычные скобки (), но они не "захватывают" содержимое. Описано тут: https://www.php.net/manual/ru/regexp.reference.subpatterns.php
\{ - ищет фигурную скобку
[^{}] - ищет любой символ, кроме фигурных скобок
Также, там есть конструкции (SKIP) и (F), с которыми я не сталкивался, но гугление выдает пост с SO: https://stackoverflow.com/questions/24534782/how-do-skip-or-f-work-on-regex - они используются, чтобы исключить совпадение с выражением перед ними.
Вдобавок, это все используется внутри preg_split. Эта функция ищет в строке совпадения с выражением и разбивает строку по ним (оставляет только куски между совпадениями).
Чтобы понять рекурсивную регулярку, ты можешь сначала представить, что рекурсивная группа (?R) ничему не соответствует.
Например, если взять регулярку выше: <((?R)|)> и убрать из нее (?R), то мы увидим что она соответствует паре скобок <>. Теперь, когда мы поняли, что ищет регулярка, мы понимаем, что ищет (?R) так как она ссылается на эту же регулярку.
Самый простой способ - писать user_id/file_id/result в табличку, а по крону раз в минуту это всё обрабатывать (ну и на фронте дергать страницу с результатом раз в 10 секунд) Пользователю придётся подождать минуту до начала обработки, но зато код выйдет реально простой и для большинства задач такого хватит.
Для более сложных вещей уже придётся накручивать gearman или rabbitmq, очереди, всю фигню - трудозатраты вырастут на порядок.
Основная задача это распараллеливание и ускорение, так что не канает. А вот излишнего усложнения хотелось бы избежать, да.
> распараллеливание и ускорение
Всё равно может сканать, далеко не всегда юзер должен получить ответ прямо сейчас или уже никогда. Я бы сначала на вашем месте подумал, может, это оверинжиниринг и минутное ожидание действительно не критично.
Отдельно сразу подумайте над вопросом, как пользователь заберёт результат? Должно ли оно появиться у него совсем сразу (тогда сокет или лонг поллинг) или просто будете запрашивать результаты раз в N секунд на бекенде.
Если второе, то просто возьмите gearman, создавайте ассинхронные задачи и в результате задач пишите его в ту же табличку file, user, result, а юзер пусть просто из этой таблички запрашивает результаты.
gearman - потому что проще всего и не нужно ебать себе мозг с консьюмерами, протоколами и т.п.
_call это вообще магия, которой по-хорошему стоило бы избегать, но в данном случае у тебя нет выбора, юзай increment
Код труднее читать
Если в двух словах, то потому что чем больше в чём-то движущихся частей, тем чаще оно ломается. Любая "магия" - это как раз такая "движущаяся" часть.
Если чуть длиннее, то "магия" означает, что что-то работает каким-то сложным и неочевидным способом, с внутренней логикой и, работая с этим, кому-то придётся учитывать намного больше возможных исходов и побочных эффектов, с огромным шансом что-то не учесть или не догадаться в какой-то неочевидной тонкости работы. И проблемы, вызванные чем-то таким, проявятся не сразу, а когда-то потом, непонятно когда и непонятно в каком случае (кто-то сначала умрёт в процессе дебага, потом не будет понимать, баг это или фича и всё в таком духе).
Это всё причём при условии, что сама магия делает на 100% то, что планируется и не содержит багов (что вообще не всегда так, потому что софта без багов не бывает и чем сложнее штуку ты пишешь, тем больше шанс наследить).
Ну и не говоря о том, что любая магия увеличивает когнитивную сложность, что означаает трату ресурсов мозга на осмысление очередной волшебной штуки и учёт всех её побочных эффектов. А ресурсы у мозга конечны и подумав о чём-то одном, ты оставишь меньше ресурсов на мысли о чём-то другом, например, об эффективности работы твоей фичи с бд.
Поэтому вместо _call следует просто вызывать метод, а если ты заранее не знаешь, что у тебя там за метод надо вызвать и тебе приходится городить какие-то специальные механизмы определения того, какой же метод вызвать - то скорее всего ты где-то проебался с архитектурой и сделал слишком сложно то, что должно быть простым.
Это работает только на простых случаях. Когда столкнёшься со сложной системой, которая непонятно почему работает не так, как ты ожидал от неё, альтернативе пошаговой отладке не останется.
Есть функция getIdByName. Она лезет в бд ищет строку и возвращает значение столбца id. Id это число. Что должна вернуть функция если строки нет? 0, null, false или выбросить исключение?
>Что должна вернуть функция если строки нет?
Сейчас будет срач постов на 50, лол.
Зачем тебе понадобилась вообще такая функция?
Ну false лучше вообще не возвращать, лучше null. Существует мнение, что вот это всё зависит от семантики, т.е. если у тебя функция называется getIdByName(name): int то ты выбрасываешь IdNotFoundException например, при этом если у тебя функция называется findIdByName(name): ?int, то можно вернуть null, потому что по названию не всё так однозначно так сказатб. А вообще похуй, главное чтобы это консистентно, чтобы не было ситуации когда у тебя getIdByName выбрасывает ошибку, а getIdBySomeKey не выбрасывает и возвращает null
>или хотя бы иммутабельность добавили.
Посоны, поясните за иммутабельность.
Я не могу понять, в чем её смысл.
Либо у нас код потокобезопасный, и тогда похуй на мутабельность, либо опасный, и иммутабельность просто выдаст тебе правильный, но неактуальный результат. Не?
ну же, анон помоги. не могу никак разобраться. можно сделать через join но тогда почему то все едет (?) и к тому же нахуя я тогда связи выстраивал если приходится ручками джойнить ?
Из основного с чем сталкивался Джанго и Скрэпи для краулинга, я еще джунишка.
Судя по всему скорей всего предстоит писать чистый бэк на пхп. Одного Ларавель хватит или нужно знать какие-то связки?
Один раз написал пхп-код в перемешку с разметкой - и на этом завязывай.
Освой единую точку входа, роутер из if_else и MVC.
да я сам джунишка. в том года пару месяцев чет на джанге поделал и потом в ларку перекатился. из опыта могу сказать что зависит от задач че надо. сразу скажу: админки в одну команду в терминале как в джанге нет. надо ручками делать. по поводу того че знать связи: ну тут свой blade шаблонизатор, чем то схож с джангой, есть своя орм, про нее можешь читануть, свои очереди есть тоже, про них читани. часто используются трейты так как в пыхе нет множественного наследования из коробки то приходится такое юзать про них почитай чтобы многое отпало. это так навскидку что в голову пришло, думаю более опытные аноны с данного треда смогут насоветовать что получше
> отвратительно свои приложухи планирую
Ну если ты соло проекты делаешь, что ты хочешь получить от DDD? Почитай паттерны, почитай исходные коды на гите, как они устроены + зачем. (симфони, либы всякие)
Можешь почитать сначала какой-нибудь клин код + рефакторинг. Этого и хватит мб.
Дело не только в потокобезопасности, даже в рамках одного потока слишком легко что-то поломать, просто потому, что какая-нибудь функция неочевидно меняет переданный ей аргумент.
Да или просто по коду, ты сначала написал $id = $_GET['id'], а потом где-то посередине длинной функции какой-то пидорас написал $id = "($id)" потому что ему нужно было где-то выводить айдишник в скобках. А ты не знал об этом и где-то в самом конце напишешь User::load($id) и такой юзер логичным образом не найдётся никогда.
Короче, гарантия, что переменная не меняется уменьшит количество багов, когда что-то по пути изменилось, а ты и не узнал об этом.
По DDD читай Эванса и Вернона, но вряд ли оно тебе поможет сходу, такие вещи обычно нарабатываются практикой.
Поэтому сначала просто разберись с концепцией слоёв (инфраструктура, приложение, домен) и научись понимать, какая функциональность к какому слою относится и почему.
Потом нагугли примеры проектов (желательно DDD) и статьи по структуре проектов и попытайся сам разобраться, почему они делают так или иначе.
И резко станет хотя бы приемлемо.
А универсальное правило всё ещё одно - не миксуй мухи с котлетами, каждая часть кода должна отвечать за конкретную задачу (или техническую~, или бизнес~, никогда одновременно).
>Поэтому сначала просто разберись с концепцией слоёв (инфраструктура, приложение, домен) и научись понимать, какая функциональность к какому слою относится и почему.
Если знаешь - можешь что нибудь лаконичное на тему слоев скинуть? Мне наверное и правда это даже больше нужно.
15. Поддерживает ли РНР множественное наследование?
Нет, PHP не поддерживает множественное наследование. То есть у производного класса может быть только один родительский. Но с помощью “магической” функции __call() его можно эмулировать.
Поясните пожалуйст этот вопрос. Допустим, у нас есть клас Мужчина с методом хуй() и класс Женщина с методом пизда(). И нам нужен класс Членодевка, наследованный от обоих классов-родителей. Но в пхп это невозможно и наследуем мы от одного Мужчины. А чтобы метод пизда() был доступен, просто в классе Членодевка пишем метод __call() и реализуем его, копипастя из соответствующего метода класса Женщина? Фигня какая-то, при чём тут множественное наследование? Или это как-то по-другому работает?
Тут проблема не в мутабельности переменной $id, а в том, что написана огромная функция, в которой трудно разобраться. Это притянутый за уши пример.
Роутер вообще не обязателен. Можно отделить разметку от логики, если, например писать всю логику в начале файла, а шаблон в конце:
<?php
логика
логика
?>
шаблон
шаблон
>>824474
Множественного наследования нет специально, так как голову сломаешь, разбираясь в таком коде.
>>824886
Не надо ничего копипастить. Видимо идея в том, что при срабатывании метода __call тот идет в класс Женщина и ищет вызванный метод там, и вызывает его. В Женщине, соответственно нужна такая же штука для вызовов методов Мужчины.
Не представляю, где такая идиотская схема может понадобиться.
Исключение принято выбрасывать, если это неожиданная ситуация, то есть, неправильных id в принципе передаваться не должно. Если же это нормальная ситуация, логично возвращать null.
>>823206
Ты даже не написал, какая у тебя ОС и как ты устанавливал PHP. Если это Линукс, то скорее всего mbstring устанавливается отдельным пакетом. Если это Виндоуз, то расширение скорее всего шло в архиве вместе с PHP (надо проверить) и требует только вписать строчку для своей загрузки.
Также, если ты используешь всякие сборки вроде WAMP, там бывает несколько php.ini и ты мог исправить не тот. Какой файл php.ini используется, можно увидеть с помощью phpinfo().
То есть, пиши больше подробностей.
Если ты про уязвимости, то погугли "популярные уязвимости в веб-приложениях". У нас есть уроки про несколько основных уязвимостей: https://github.com/codedokode/pasta/tree/master/security
Попробуй встроенную в винду убунту
Я так понял мне для этого нужно использовать flock($fp, LOCK_EX), читать одну строку из файла, удалять её (чтобы её не взял другой скрипт), и разлочивать файл flock($fp, LOCK_UN), я правильно понимаю? Ну а остальные скрипты будут смотреть можно ли открыть файл и если он сейчас занят, будут уходить в sleep и потом снова проверять.
>Хочу распараллелить
>Я так понял мне для этого нужно использовать flock($fp, LOCK_EX)
Распараллеливание уровня б. Чтобы скрипт не трогал ненужные строки, то можешь ему просто в аргументах передавать какой-то OFFSET и LIMIT например. Ну и лично моё мнение, тебе это нахуй не нужно
Любой пример выглядит слегка абстрактным (на то он и пример), а любой тривиальный случай выглядит слишком простым, потому что проблемы начинаются с усложнением системы.
Тем не менее, суть решаемой проблемы мой пример передаёт верно - если ты не можешь изменить данные (они иммутабельны), значит, ты не поймаешь ошибку, связанную с тем, что кто-то непредсказуемо их изменил.
?: - тернарный оператор
1 > 0 ? da : net;
?? - если значение null поставить что-то другое:
$test = null ?? 'default'
Имелось в виду выражение вида $a ?: $b. Уже догадался, что при ?? идет строгая проверка на null или undefined, а при ?: нестрогая на true/false, как в if.
По работе нужна такая приложуха - быстрый по буквенный поиск ( ввел "а" - варианты начинающиеся на "а" вернет, "ab" - уже на "ab" ) -трабла в чем. База огромна, более 600 таблиц, в некоторых натурально по 60 млн записей. И если такой поиск делать сразу в базу - беспокоит что по каждой букве поиск будет долгий.
Думаю про такой вариант - одним вопросам раз в 10 минут например создавать/обновлять мини базу, в которой будет только данные общие по нужной мне выборке. И уже в этой мини базе искать побуквенно - будет по идее сильно быстрее. Ток я не пойму как это реализовать. По крону отдельным скриптом? Получил из большой базы выборку, удалил в маленькой базе все, и на место залил данные новые. Как то так думается, хотя звучит тупо
Отличие:
$a ?: $b эквивалентно $a ? $a : $b
$a ?? $b эквивалентно isset($a) && $a ? $a : $b.
Если ты обращаешься к несуществующему ключу массива, то $a['key'] ?: $b выдаст ошибку, а $a['key'] ?? $b нет.
Поиск по всем ВООБЩЕ ВСЕМ таблицам? Маловероятно, если честно, нахрен оно тебе надо?
В таких случаях пора прикручивать Sphinx. Тщательно выбирать, по каким таблицам и полям ты собираешься ебошить поиск и хуярить скрипт.
Отдельная поисковая таблица - нормальная тема, на самом деле. Правда, она обычно не по крону заполняется, а евентами. Учитывая твое количество контента, запрос на создание такой таблицы будет ебенячим.
Тебе нужен elasticsearch, sphynx или что-то подобное.
Что такое коннект к базе данных, и сколько он живет.
В чем суть, при старте приложения но ноде, я в одном из модулей создаю объект - или коннект, или пул коннектов с лимитом около 10.
Коннект с базой - это некое постоянное соединение? Или это просто объект с настройками, который при каждом вызове стучится в базу данных, делает то что должен и закрывается?
Далее в вызывающем коде я из этого объекта ( или из пула получаю 1 из 10 ) получаю соединение, выполняю запрос, получаю ответ, в в конце вызываю языковую конструкцию которая "закрывает" что ли соединени.
А если его вручную не закрывать - что получится?
А сколько в одну единицу времени может быть соединений?
Странно, что ты спрашиваешь это здесь, но так и быть.
Это зависит от реализации, но скорее всего там постоянное соединение, потому что постоянно открывать-закрывать их на каждый запрос тупо очень дорого.
Далее, там под капотом или одно соединение, или пул соединений (то есть, на каждый запрос берется отдельное соединение из базы), зависит тоже от реализации.
Но тут нужно учитывать условную "сессию", потому что если ты не закрыл транзакцию, то следующий запрос начнёт работать в рамках транзакции предыдущего, что пиздец. Хотя скорее всего это всё должен делать пакет, который ты используешь.
Максимальное число соединений зависит от конкретной базы, у pg их максимум 100 к примеру.
Если у тебя там тупой драйвер который реально создаёт и закрывает коннекты и ты не будешь их закрывать, то вероятно через 100 запросов ты выжрешь лимит по открытым соединениям и твой сервис перестанет обрабатывать соединения. Но это тоже зависит от реализации твоего пакета и от бд, может, он после сборки нодой мусора прекращает слать/отвечать на хартбит и постгрес сам начнёт закрывать эти коннекты, как неактивные.
Как-то так.
> то есть, на каждый запрос берется отдельное соединение из базы
Тьфу ты, имел ввиду, из набора. К примеру, у тебя в пуле 10 коннектов и ты каждому входящему запросу выдаёшь по коннекту, а потом забираешь его обратно, когда запрос кончился. Вряд ли у тебя это так, потому что нода однопоточная, но мало ли.
>>Странно, что ты спрашиваешь это здесь, но так и быть.
Ну не в JS же треде спрашивать, лол.
Спасибо.
Я как то более подробно читал - и там говорилось о том что коннекты закрываются, 60 секунд вроде чтоли. И получается приложуха и база совсем теряют соединение.
> Ну не в JS же треде спрашивать, лол.
Ну типа.. Да, может там даже кто-то юзал твою же либу и может подробно ответить.
> Я как то более подробно читал - и там говорилось о том что коннекты закрываются, 60 секунд вроде чтоли. И получается приложуха и база совсем теряют соединение.
Особенности реализации, но вообще это странно, так как внутри коннекта база и клиент пингуют друг-друга постоянно, соответственно, один и тот же коннект можно поддерживать бесконечно - и это намного дешевле с точки зрения времени ответа, чем открывать коннект во время запроса.
Опять же, если ты ввёл неправильные реквизиты базы, ты бы хотел узнать, что ты неправильно их ввёл, на этапе старта твоего приложения, а не тогда, когда к тебе в апи уже пользователь стукнул.
Кто-то даже юзает, лет пять назад ребята на соседнем проекте вроде использовали и оно даже работало, так что можешь заиспользовать, если хочется.
Но это в любом случае не родные для php костыли, были и будут. Если хочешь двустороннего общения и долгих коннектов, подними рядом простенький сервер на сраной ноде, который будет по локалхосту дёргать phpшный сервер и иметь маленькое апи, в которое сможет стукнуться твой php, а нода перепослала бы его обратно пользователю. Знания ноды нужны совсем минимальные, пишется такое за час, если использовать socket.io - то полчаса. И возможных проблем будет на порядок меньше, потом спасибо скажешь.
Как использовать JWT- и CSRF-токены вместе?
Я могу внутри JWT отправить CSRF-токен, но где его сохранить на стороне сервера или во что его включить, чтобы потом сравнить?
Мне нужно избежать сессий и речь идет о JWT в куках.
Вроде как должна помочь такая схема: при каждом посещении страницы с формой, которую надо защитить, генерировать новый JWT с CSRF внутри, то есть JWT после логина (первый) может вовсе не содержать CSRF пока не понадобится.
Так или нет? Где я не прав?
Спасибо, не знаю правильно ли я понял, но вот https://ideone.com/G2kGjb .
Только это все, похоже на агрегацию, а не на композицию, в уроке было сказано, что при композиции внутренние объекты не могут
существовать отдельно от внешнего, создаются самим внешним объектом в конструкторе или методах (а не где-то снаружи), и уничтожаются вместе с родителем.
Я же сделал все объекты "где-то снаружи", т.е. виде агрегации, но не композиции.
Девочка, ты сам нихуя не знаешь и другим хуйню пишешь. При обращении к несуществующему элементу массива тернарный оператор ?? выдаст ошибку. Ты же выше пример привел isset($a) && $a согласно нему isset($a[‘key’]) вернет ложь.
Вообще, для современных БД вроде MySQL, открытие нового соединения стоит недорого - менее 1 мс. Пулы идут из тех времен, когда открытие соединения было дорогим.
Сейчас из их преимуществ разве что то, что они позволяют защитить БД от перегрузки за счет ограничения на макс. число соединений. Хотя такое ограничение можно сделать и на стороне БД.
Так что не очень понимаю, какой в них смысл в наши дни.
Зачем помещать CSRF токен внутрь JWT? Это разные вещи для разных целей. JWT это авторизация, CSRF это защита от подделки запросов к серверу злоумышленником.
> но где его сохранить на стороне сервера или во что его включить, чтобы потом сравнить?
CSRF токен можно сохранить в куки. При отправке формы на сервер приходит 2 токена: один из кук, другой из формы. Сервер их сравнивает и проверяет, что они не пусты.
Не ври: https://ideone.com/rCxQfv
Ты бы хоть потратил 20 секунд на проверку перед тем, как писать чушь.
Почему?
>>826398
Если полностью положиться на ограничение макс числа коннектов на стороне бд, то ты будешь долбить её запросами даже для излишних соединений, что как бы не круто.
Да и там больше 1 мс, потому что база может находиться на другой машине, нужно зарезолвить адрес, иногда получить его из условного балансировщика (адрес реплики, имею ввиду), сходить по нему, всё такое.
Плюс
>>826192
Капец, налицо полное непонимание того, как работают CSRF атаки
1. Если ты пользуешь JWT и НЕ хранишь его в куки, а каждый раз, как и положено, добавляешь его ручками в запрос в заголовок 'Authorization: Bearer <token>', то никакая дополнительная защита от CSRF тебе не нужна
2. Анон, НИКОГДА! Повторяю - НИКОГДА не храни CSRF токен в куке! Тем самым ты полностью сводишь защиту на нет. CSRF токена надо или в тело запроса вставлять, или в заголовок какой нить. Но только не в куку.
Найди хорошую статью по CSRF. Перечитай, пойми как именно она работает (подавляющее большинство не понимают), и больше никогда не пиши подобной ерунды
>Authorization: Bearer <token>
Вот за это спасибо. Я что-то ебанулся и думал о токене только в рамках кук, а не HTTP.
Но что-то проще не стало. Когда я понял что такое CSRF атака, и впервые увидел токен в HTML форме я додумал процесс защиты следующим образом:
CSRF-токена должно быть два: сам токен и тот же токен для сверки. Токен рендерится сервером в форме и пихается в куку (его хэш). Если форма еще не отправлена, а клиентский куки попадает на сайт, делающий запрос, то ничего не происходит, потому что самого токена нет в форме нет - только его хэш. При отправке формы, отправленный токен сравнивается с хешем токена из куки, и, таким образом, проверяется его подлинность. Можно не пихать хэш токена в сессию, а хранить его на сервере, например в БД.
Это так работает или нет?
>Анон, НИКОГДА! Повторяю - НИКОГДА не храни CSRF токен в куке! Тем самым ты полностью сводишь защиту на нет. CSRF токена надо или в тело запроса вставлять, или в заголовок какой нить. Но только не в куку.
Ты походу не прочитал что анон выше написал:
>При отправке формы на сервер приходит 2 токена: один из кук, другой из формы. Сервер их сравнивает и проверяет, что они не пусты.
>One-to-one bidirectional и unidirectional
На уровне БД - ни в чем.
На уровне кода bidirectional позволит тебе лазить в оба направления,$user->getAvatar() и $avatar->getUser();
Спасибо. Так и догадывался.
ПАМАГИТЕ
Возможность писать типобезопасный но абстрактный код, который бы работал одинаково для разных типов.
К примеру, функция
function increment($a) {
return $a+1
}
не говорит тебе, что возвращает тот же тип, что и получила и в теории может получить int, а вернуть null и ты узнаешь об этом только тогда, когда это произойдёт на проде, когда топ менеджер твоего топ клиента захочет лично купить себе искусственную вагину на твоём сайте.
А если бы в пехапе были дженерики, ты мог бы сделать вот так:
function increment<T>(T $a): T {
return $a+1
}
И у тебя increment<float> всегда принимал ивозвращал бы float, а increment<int> - всегда принимал и возвращал int.
Для пехапешника плюсы такого подхода могут быть неочевидны, но в целом гарантий много не бывает и если свой код можно сделать надёжнее и избавиться от возможных ошибок (а раз в год и палка стреляет)- то лучше таки это сделать. Особенно, если пишешь код не для сайта-визитки автомастерской дяди Вазгена, а для ну хотя бы крупного интернет магазина.
Да, пардон, мой косяк. Как обычно, прочел первую половину предложения, и тут же пошел строчить ответ
>>826647
Сойдет, только хешировать необязательно совсем. Просто голый CSRF токен сохраняешь в БД или, ещё проще, в сессии. И потом сравниваешь пришедшее из формы с тем, что есть в сессии.
Два замечания:
1. Куку вместо сессии\БД юзать не желательно. Хотя, если поставить флаг http-only, то можно. Чтоб у юзера токен не спиздили через какие нить другие уязвимости (а-ля XSS). По сути такая кука - это аналог сессии (если не охота мудохаться с хранением сесии на server-side)
2. Если пишешь на фреймворке - НЕ ПЕРДОЛЬ СВОИ ВЕЛОСИПЕДЫ! Воспользуйся тем, что есть во фреймворке. Во всех что то есть про csrf. Даже для минималистичного слима есть миддлвейры
3. Если пишешь НЕ на фреймворке - пиши на фреймворке и см. пункт 2
Троллинг тупостью. Ясно-понятно.
https://www.php.net/manual/ru/migration70.new-features.php там про ?? почитай.
Дженерики (обобщенные типы) позволяют делать типы с параметрами.
Чаще всего они используются для реализации коллекций. С ними можно сделать класс вроде Collection<T>, который представляет коллекцию элементов типа T. Например, $users = new Collection<User> - коллекция объектов User.
Перечитай свой комментарий выше:
> При обращении к несуществующему элементу массива тернарный оператор ?? выдаст ошибку
Я тебе привел код, где ошибка не выдается. И кто тут троллит тупостью?
Алсо, ?? это не тернарный, а бинарный оператор. У тернарного оператора 3 аргумента.
Использование куки для CSRF имеет то преимущество, что не нужно сохранять токен на сервере вообще, не надо удалять устаревшие токены, и тд. Это проще, чем городить хранилище в БД или сессии, очищать устаревшие токены итд.
> Куку вместо сессии\БД юзать не желательно
Почему? Если злоумышленник может украсть куку с CSRF токеном, то он может украсть и сессионную куку, следовательно использование сессии защищенность не увеличивает, а только усложняет реализацию.
Если есть XSS уязвимость, то злоумышленник может отправить поддельный запрос независимо от того, где хранится токен. Опять же, сессия или БД тут не дают преимущества над куками.
> По сути такая кука - это аналог сессии
Это просто самый простой вариант хранения, зачем что-то усложнять?
>>826647
Хеширование не требуется. Непонятно, от чего оно должно защищать.
Добрый вечер. Хуярный это оператор, а не бинарный. Пример выше вернул залупу, такак после : возвращается ложь. Ясен хуй если у тебя есть массив с пропущенным элементом, то тернарный оператор вернет ложь. И не спорь со мною.
докер
которые платные чтоли? тут тебе врядли подскажут. иди в группы вк или в чатики в телеге тематические по этому говну и спрашивай. только будь осторожен: я один раз зимой вк спросил там у них вопрос и с того момента эти долбоебы частенько написывают и добавляются в друзья прося помощи по этой параше.
Нужно сгенерировать дофига документов по шаблону, изменяя в них только несколько переменных, чтобы потом эти документы вывести на печать. Допустим, нужно сгенерировать заявления для жильцов дома, в которых будут меняться только ФИО, адрес и их долг перед жэком.
Импорт данных предполагается из excel таблицы. Я максимально тупой гуманитарий, но с php как-то дело имел, мне в целом понравилось. Скажите, пожалуйста, что гуглить, читать, чтобы это реализовать? Какие библиотеки мб есть для этого?
Я вижу реализацию в общих чертах так:
1. Импорт из таблицы, создание массива
2. Построчное извлечение соответствующих переменных из массива
3. Их подставление в нужные места в документе
4. Генерация pdf
5. Переход к следующей строке и генерация следующего документа
>затем публикую вендор
Зачем?
Всё, что у тебя установлено, пишется в composer.lock. Команда install по факту - "установить всё как описано в этом файле".
>>828830
Пых ориентирован на веб. Ты ТОЧНО уверен, что хочешь делать именно веб приложение, а не взять допустим петухон? У него есть пачка особенностей, в том числе ориентированность на разовые прогоны скриптов. Пункты 1 и 2 вполне могут трансформироваться во что-то вроде "переписываем содержимое файла в промежуточное хранилище, достаем 100 штук за прогон (к примеру) и ебашим".
Учти, что у тебя 99.9% ёбки будет именно с пунктом 4. Библиотеки есть, но из-за того, что под капотом у PDF, речь не идет о просто подставить значения, придется поебаться. В основном, библиотеки любят конвертировать html в pdf, а не работать собственно с pdf шаблонами.
Кто-нибудь знает годную библиотеку по этому критерию (не уровня нагуглил, а именно сам юзал и остался доволен)?
> Пых ориентирован на веб.
Пых - это всё же язык общего назначения (пусть и чисто формально) и для скриптов он подходит не хуже питона.
Я вот вообще свою научную (магистерскую, машинное обучение, лол) работу на пыхе писал и ничего, норм было.
Для генерации документов он нормально подойдёт при наличии хороших библиотек (а они на php обычно есть).
>>828830
Я бы тебе предложил из экселя экспортировать в csv (или изначально в нём данные брать), мороки будет в разы меньше.
Остальное примерно так, как ты описал.
Для PDF я бы тебе советовал взять wkhtmltodpf, надежная штука, и юзать просто - через shell_exec или proc_open дёргай бинарник "./wkhtmltopdf <аргументы> mytemplate.html result.pdf" и он сам всё сгенерит, от тебя потребуется только html-ку организовать. Можешь генерить html'ки руками предварительно, а уже потом дёргать генератор, как вариант (мне больше нравится вариант, чтобы wkhtmltopdf ходил на сервер, но если ты гуманитарий, то тебе чем проще, тем лучше).
Вот как-то так будет выглядеть:
$lines = magic_load_function('data.csv');
$template = file_get_contents('template.html');
foreach ($lines $key=>$line) {
file_put_contents('file.html', strtr($template, ['placeholder_a'=>$line['a'], 'placeholder_b'=>$line['b']]));
shell_exec('wkhtmltopdf file.html result'.$key.'.pdf');
}
>>828884
Спасибо пацаны, схоронил ваши гайды, постараюсь разобраться.
Алсо, нагуглил библиотеку PHPWord, через нее, как я понял, можно генерировать docx файлы. В принципе, такой вариант мне тоже подошел бы, но учитывая, что в ворде от версии к версии отображение файла может отличаться, то наверное это не лучший вариант и pdf в данном случае подходит лучше.
Вариант wkhtmltopdf хорош как раз тем, что ты делаешь обычную сраную веб страницу, а он тупо генерит из неё pdf, примерно как если бы ты на ней Ctrl+P вызвал. Это позволяет стилизовать pdf как ты хочешь нормальными инструментами веб-разработчика, html, css и, изредка, js.
Подключаю трейт, который подключен в другом подключенном трейте.
Мне пыхшторм выдает ошибку синтаксического анализа, причем фатальную.
Но дело в том, что это точно не ошибка, трейт не будет подключен много раз, он будет подключен только 1 раз, даже если его потом еще 20 раз подключить в других трейтах.
Это нормальное поведение как бэ.
А это говно ведет себя так, будто я 2 разных трейта с одинаковым методом подключил.
Это баг или что?
Я даже счетчик седал считать запросы. Открываю стартовую страницу - и два utn запроса, причем это не фавиконка, она отдельным запросом передается. В файрфоксе один запрос.
Для чтения данных из Excel есть PHPSpreadsheet. Для генерации PDF из HTML есть wkhtmltopdf, как написали выше.
>>828852
На PHP эта задача решается прекрасно и быстро. Я генерацию PDF делал. wkhtmltopdf для этого прекрасно подходит. При чем тут ориентация на веб? При чем тут промежуточные хранилища? Ты по моему, просто, плохо знаешь PHP и его возможности.
>>829171
Ты можешь проверить файл на ошибки командой php -l имя-файла. Если PHP не выдает ошибок, то значит дело в IDE и стоит обращаться в её техподдержку.
>Ты можешь проверить файл на ошибки командой php -l имя-файла. Если PHP не выдает ошибок, то значит дело в IDE и стоит обращаться в её техподдержку.
Ну результат ожидаемый.
В соседнем треде даже скинули ссылку на баг:
>Fixed bug #63911 (identical trait methods raise errors during composition).
Когда-то такое поведение реально было, но это уже пофиксили.
При этом в шторме стоит 7.4 версия, но ему похуй.
Понял, спасибо, анончик. Попробую тогда этот вариант
кобол
Зачем? Обновляешь триалку и все, настройки останутся.
Вопрос, подключаю SendPulse к проекту, из-за блядских квадратных скобок в имени инпута не считываются переменные. СТалкивался кто? Как решить?
Суть - написал два приложения для моей конторы. Оба написал сидя на винде, в опен сервере. И оба нужно развернуть в нашей внутренней сети. И одно приложение будет наружу торчать, должно быть доступно извне.
Я поставил убунту, перетянул на не приложения. Как мне все это настроить, где почитать об этом, что бы на этой убунте было несколько серверов?
Да, жалко. Я считаю каждый день, который меня приближает к времени когда больше никогда не придётся РАБотать. Откладывать этот день на 5$ каждый месяц я не готов.
Вот мой код: https://ideone.com/ExgPc7
Гугли Nginx + fpm.
>>1762614 →
У меня в голове плотно засела функция которую я создал, и не могу придумать ничего другого сильно отличающегося. По другому я себе представляю, например такой вариант, вместо того, чтобы использовать статистические переменные, я могу их добавить в параметр функции, то есть изначально я буду передавать в этот параметр пустой массив, который будет заполняться, возможными путями. Далее внутри этой рекурсивной функции, я найду оптимальный из всех возможных вариантов с помощью отдельной функции. Помоги ОП, ничего другого не могу придумать.
Хз, пытаться накопить миллионы, экономя на таких копейках - это верный способ прожить жизнь в ожидании чуда (смотри "синдром отложенной жизни") и вообще сойти с ума в итоге.
Ты же программист, просто повысив себе зарплату тысяч на 20 ты за месяц заработаешь больше, чем копил бы 3-4 года по копеечкам. Лучше уж вкладываться в технические скиллы и инвестировать в свой профессиональный рост, а копить начать уже с будущей гигантской зарплаты.
Я вот из провинции, начинал с 15к (студентом в одной говноконторе, лол) и пока у меня зп не достигла 200к ничего не откладывал и не жалею.
Ты про вариант с рекурсией https://ideone.com/ukgSft ?
Тут надо подумать, что функция принимает на вход и что возвращает в результате своей работы.
Логично, что функции нужно получать:
- список возможных путей $paths
- список пройденных точек $pathDone (чтобы не заходить в них второй раз)
- цель $target
Время $time по идее можно вычислить из $pathDone, но лучше его тоже передавать, чтобы ускорить выполнение функции. $point можно не передавать, так как оно берется из $pathDone как end($pathDone) - последний элемент массива.
Теперь о том, что функция должна вернуть. Пусть мы находимся в точке a, и хотим попасть в c, и к ней есть 2 пути: a -> b -> c и a -> d -> e -> c. Как определить, каким воспользоваться?
Из точки a мы можем пойти либо в b, либо в d. Чтобы определить оптимальный путь, мы вызываем функцию дважды: с $pathDone = [a, b] и с $pathDone = [a, d]. Функция в ответ должна вернуть время до цели и путь к ней. Тогда мы сможем выбрать тот, который короче.
Допустим, вызов с [a, b] вернул нам путь [a, b, c] и время 10, а вызов с pathDone = [a, d] вернет [a, d, e, c] и время 5. Значит, второй вариант короче и правильный путь до цели будет [a, d, e, c].
То есть, блок else в функции makeOneMoreStep может выглядеть как-то так:
- попробовать проложить путь к цели через каждую точку (которая не входит в pathDone). Для каждой точки получить путь до цели и время до цели
- сравнить время и выбрать путь с минимальными временем
- вернуть этот путь и время прохождения
Как верно заметил анон, надо поставить число сторублевых купюр в 0: https://ideone.com/C1EoDe
Ты молодец, добился всего сам, но я не такой. Я обычный говнокодер, который до конца своих дней будет сидеть в дноконторе за низкий прайс. Чтоб подняться, нужно быть либо очень скилловым и умным, либо кабаном, который прёт напролом. У меня нет ни того, ни другого. Я просто выполняю задачи которые мне дают и проживаю день. Всё. 9 месяцев стажа, сижу сейчас в одной конторке в ДС за 50к делаю низкоквалифицированный труд, думаю, так ещё много лет будет.
Все пыхеры отсталые ретрограды, хуярящие приложухи по заветам из нулевых? У нас в жс-треде один из ваших "дедков" загулял, ссым ему всем тредом за шиворот уже несколько дней подряд, но он походу от этого особый кайф ловит
Как часто ты переустанавливаешь node_modules?
Я долбоёб с ГНУ/Пинусами. Здесь почти все кряки и скрипт не работают. Пиздос мда.
Хуй знает что там про дедков, возможно это я там в JS треде троллил. Но маня, знай что я и на nodejs пишу лучше чем 99% вашего идиотского треда. Так что иди как ты нахуй, программист на реакте.
Выкатывайся на винду, или лучше ищи
Как не работают? Я каждый раз по первой ссылке в гугле иду за гайдом по сбросу триала, всегда забываю. Тут все на пинусах так-то.
Так хочется разок крякнуть и не ебаться. а не раз в месяц чё-то там проворачивать. У меня есть так-то брат, у с которого можно студенческую получить, но последствия для коммерческого использования такой лицензии, да и сам процесс получения мне неизвестны.
На линкусе вроде вообще можно тупо папку удалить какую-то и триал сбросится, можешь крон задачу сделать. Как говорится, не хочешь ебаться то плати, не хочешь платить так немного хоть поебись
Ты прав, но там непонятно где файл, любой говнодел может их в разные папки пихать. Ну и почему-то именно пхпшторм медленно работает и жрёт всю систему на пинусах. Intellij, PyCharm и Android Studio отлично работают, а phpstorm нет. Казалось бы, на джаве написано, на одинаковых движках, кроссплатформа, а такое говно.
А нет, мб в этом и дело.
Суть такова есть приложение которое должно делать ajax побуквенный поиск по, пусть логинами,из одной оче большой йобы базы. Суть такова что база огромная, сложная, кривая, и получение нужной мне выборки по логинам одних только объединений получатся аж 15 штук. И запрос идет секунд 40. Никакого быстрого побуквенного поиска не вариант.
Решил сделать так - отдельным скриптом, по крону, из большой базы нужная мне выборка достается, и копируется в маленькую базу, в которой уже быстро идет побуквенный поиск.
Какие вопросы возникли:
1. Я получил выборку из большой базы, как мне лучше закинуть ее в маленькую базу - удалить все строки из маленькой, и инсертнуть весь массив строк из большой? Или , как мне кажется более медленный вариант - достать из маленькой все строки, и смержить с данными из большой, удалив дубликаты?
2.Более важный вопрос - допустим мое приложение по поиску работает, и именно в тот момент когда пользователь допустим ищет все совпадения по третьей букве "логина" в маленькой базе - в этот момент запускается вся процедура копирования - тут я даже не очень понимаю какие варианты развития событий.
Все процедура удаления таблицы, и заливка новых данных в маленькой базе - ну будет занимать секунд 5. И допустим в этот момент приложение будет отправлять запрос на поиск по букве. Что произойдет - приложение выдаст какой то error? Или будет ждать пока не заполнится таблица по новой в маленькой базе?
Если я правильно понял смысл вопроса, в очень простых случаях используют require, а в более сложных используют автозагрузку классов.
>>833931
Мержить будет правильнее - определяем, какие записи удаляются, какие добавляются и соответственно удаляем и добавляем. Впрочем, если записей не очень много - порядка 1000 - 10 000 то можно попробовать и просто все очищать и вставлять, авось успеет вставиться. Можно обернуть удаление/вставку в транзакцию, чтобы оно делалось атомарно и промежуточное состояние не было видно.
Не забудь сделать индекс по колонке с логином, чтобы поиск шел быстро.
> И допустим в этот момент приложение будет отправлять запрос на поиск по букве. Что произойдет
Поиск будет работать по тому, что успело вставиться в базу, то есть не все логины будут искаться.
Можно папку удалить, но тогда все настройки сбросятся и придется постоянно делать импорт/экспорт. Удобнее нехорошую строчку удалить.
У транспортных компаний есть API, по которому можно определить стоимость доставки в нужный город (пример для СДЭК: https://confluence.cdek.ru/pages/viewpage.action?pageId=15616129#id-Протоколобменаданными(v1.5)-4.13CalculatorКалькулятор также есть PHP SDK для их API: https://cdek-sdk.readthedocs.io/ ). Однако, стоит кешировать результат, чтобы не перегружать их API (если 10 человек из Москвы зашли на сайт, незачем слать 10 одинаковых запросов).
Также, обращение к сторонним API может подвисать, потому этот блок лучше подгружать аяксом, чтобы он не тормозил загрузку страницы.
Также, для правильной архитектуры хорошо бы сделать классы-адаптеры к каждому API, чтобы код со всего сайта через них ходил в API, а не каждый сам по себе. Если такие классы уже есть - можно их дополнить, если нет - то в идеале переделать весь код, чтобы они появились.
лезть во все 4 апи и пользователь будет ждать полминуты пока все просчитается и загрузится и сравнится что дешевле по доставке и быстрее? алсо, не все апи работают по город-город. в каких то надо указать индекс-индекс =/ и как тут поступать - хуй знает
>аяксом
точно не варик. а то будет как то странно выглядеть что юзер зайдет, листает страницу, и спустя полминуты там ему хтмл блок появляется под ценником лол
>классы-адаптеры
да я тоже сразу подумал на это. но сразу скажу что тут битрикс с лютым легаси и порой диким говнокодом. сдать надо в среду вечером, а на такую перепись уйдет неделя. так что такой себе варик.
в общем по итогу решил юзать калькулятор сдэка. он сразу и ценник вернет и даты. единственное че алгоритм выходит такой: определить айпи, по нему город, лезть в бд в таблицу городов сдэка чтобы вытянуть нужный айдишник города, отправить запрос с двумя айдишниками и весами и айдишником самого дешман тарифа лол. норм алгоритм и быстр ли? сейчас встрял на том что определение города по ип не работает правда..........................
ёбаный насос, с какими же некомпетентными дебилами мне приходится плеч-о-плеч работать. Какие, в жопу, маленькие базы, что ты творишь!
Для таких вещей специально придуманы поисковые системы типа elasticsearch или sphinx.
Уволься нахер. Пусть на твоё место придет кто нить более компетентный. Авось осилит настроить индексацию твоей БД эластиком, и выполнение поиска по нему, вместо тормознутой реляционной БД
people (id, name) (1,"David"),(2,"Jessica"),(3,"John")
animal (id, year) (1,"horse"),(2,"dog"),(3,"goat")
who_fucked_who (people_id, animal_id) (1,1),(1,2),(2,1),(2,2),(3,2),(3,3)
Каким образом мне получить список кого трахнул Джон?
SELECT a.id, a.year
FROM animal AS a
INNER JOIN who_fucked_who AS w ON a.id = w.animal_id
INNER JOIN people AS p ON p.id = w.people_id
WHERE p.name = 'John'
мимо
>юзер зайдет, листает страницу, и спустя полминуты там ему хтмл блок появляется под ценником лол
Показываешь блок заранее с анимацией загрузки, как подгрузится - меняешь загрузку на полученные данные.
Ты делаешь это неправильно.
Во-первых, нет никакого смысла добавлять +1 базу, это только добавит пиздеца в поддержке сразу нескольких баз. Количество баз не влияет на производительность (точнее конечно влияет, но совсем не так, как тебе кажется);
Во-вторых, прочитай про нормализацию и денормализацию, и про нормальные формы заодно. Это классика computer science и такое, вообще говоря, стыдно не знать. Грубо говоря, у тебя данные очень сильно нормализованы (разорваны на кучу таблиц), а тебе нужно работать с неким обобщением всех этих данных. Это можно решить несколькими путями, самый тупой - это создать отдельную таблицу (не базу!), в которую с помощью триггеров (гугли) писать нужные данные. Более удачный вариант - это создать вьюху, то есть материализованное представление своих данных и она сама будет подтягивать нужные данные из таблиц и хранить их в отдельной таблице. Очень грубо говоря, это такой запрос с кэшем, к результатам которого можно обращаться, как к таблице.
В-третьих, если тебе нужен полнотекстовый поиск (то есть, со словоформами, гуглишь "айфончики", а он ищет "айфон", то просто так на sql этого не сделать, тебе потребуется или ставить экстеншены (вроде для pg есть не самые ужасные, но всё равно это костыль скорее всего), или ставить рядом отдельную базу, предназначенную исключительно для этого. Например сфинкс, солр или эластик (самый популярный). Но там, во-первых, тебе придётся настраивать индексирование данных (что не так тривиально), а во-вторых, настраивать полнотекстовый поиск, что пипец как сложно. Словари, стэмминг, лемматизация и прочее просто взорвут тебе мозг. Поскольку ты явно не очень скилловый, если тебе реально нужен полнотекстовый поиск - то лучше отдай задачу кому-то поопытнее или просто откажись от неё, я серьёзно.
В-четвертых, "тупая" полная репликация данных по крону тебя убъёт на больших данных, даже если это делать через планировщик, то тебе нужно фетчить не все данные, а изменившиеся с последней репликации (колонка updated_at-то у тебя есть?).
В-пятых, если у тебя вдруг появилась задача репликации данных между двумя базами, это не делается созданием и удалением таблиц, потому что, как ты правильно понимаешь, это пиздец с точки зрения производительности и доступности. Это делается через обновление данных по внешнему ключу (или общему ключу, или ключу афинности), грубо говоря, во второй базе (ну или таблице) ты хранишь айдишники из первой и тогда твои запросы будут выглядеть как "создай такую-то строку, а если такой внешний ключ уже есть, то обнови вместо создания" (гугли upsert). Плюс, придётся запариться с удалением outdated-строк, делается как раз по дате последней репликации.
А скорее всего тебе тупо нужно создать индексы и оптимизировать запрос, и вместо 40 секунд он будет выполняться миллисекунду. Если не так - то создавай или вьюху, или таблицу (с триггерами и индексом) и будет тебе счастье.
>>834795
Привыкай, большинство т.н. разработчиков на самом деле долбоёбы и http-запрос от sql-query с трудом отличают. Но в последнее время (не в последнюю очередь благодаря skillbox и stackoverflow) средний уровень ухудшился значительно, тут ты прав.
Ты делаешь это неправильно.
Во-первых, нет никакого смысла добавлять +1 базу, это только добавит пиздеца в поддержке сразу нескольких баз. Количество баз не влияет на производительность (точнее конечно влияет, но совсем не так, как тебе кажется);
Во-вторых, прочитай про нормализацию и денормализацию, и про нормальные формы заодно. Это классика computer science и такое, вообще говоря, стыдно не знать. Грубо говоря, у тебя данные очень сильно нормализованы (разорваны на кучу таблиц), а тебе нужно работать с неким обобщением всех этих данных. Это можно решить несколькими путями, самый тупой - это создать отдельную таблицу (не базу!), в которую с помощью триггеров (гугли) писать нужные данные. Более удачный вариант - это создать вьюху, то есть материализованное представление своих данных и она сама будет подтягивать нужные данные из таблиц и хранить их в отдельной таблице. Очень грубо говоря, это такой запрос с кэшем, к результатам которого можно обращаться, как к таблице.
В-третьих, если тебе нужен полнотекстовый поиск (то есть, со словоформами, гуглишь "айфончики", а он ищет "айфон", то просто так на sql этого не сделать, тебе потребуется или ставить экстеншены (вроде для pg есть не самые ужасные, но всё равно это костыль скорее всего), или ставить рядом отдельную базу, предназначенную исключительно для этого. Например сфинкс, солр или эластик (самый популярный). Но там, во-первых, тебе придётся настраивать индексирование данных (что не так тривиально), а во-вторых, настраивать полнотекстовый поиск, что пипец как сложно. Словари, стэмминг, лемматизация и прочее просто взорвут тебе мозг. Поскольку ты явно не очень скилловый, если тебе реально нужен полнотекстовый поиск - то лучше отдай задачу кому-то поопытнее или просто откажись от неё, я серьёзно.
В-четвертых, "тупая" полная репликация данных по крону тебя убъёт на больших данных, даже если это делать через планировщик, то тебе нужно фетчить не все данные, а изменившиеся с последней репликации (колонка updated_at-то у тебя есть?).
В-пятых, если у тебя вдруг появилась задача репликации данных между двумя базами, это не делается созданием и удалением таблиц, потому что, как ты правильно понимаешь, это пиздец с точки зрения производительности и доступности. Это делается через обновление данных по внешнему ключу (или общему ключу, или ключу афинности), грубо говоря, во второй базе (ну или таблице) ты хранишь айдишники из первой и тогда твои запросы будут выглядеть как "создай такую-то строку, а если такой внешний ключ уже есть, то обнови вместо создания" (гугли upsert). Плюс, придётся запариться с удалением outdated-строк, делается как раз по дате последней репликации.
А скорее всего тебе тупо нужно создать индексы и оптимизировать запрос, и вместо 40 секунд он будет выполняться миллисекунду. Если не так - то создавай или вьюху, или таблицу (с триггерами и индексом) и будет тебе счастье.
>>834795
Привыкай, большинство т.н. разработчиков на самом деле долбоёбы и http-запрос от sql-query с трудом отличают. Но в последнее время (не в последнюю очередь благодаря skillbox и stackoverflow) средний уровень ухудшился значительно, тут ты прав.
то что на пике - это $rows. так вот вопрос как мне блять к каждому из массивов обратиться? чтобы не помещать в цикл foreach и для каждого по отдельности вызывать валидатор =/ есть ли какие то средства у фреймворка ?
Чет усложнили тебе задачу, проще просто 100 км принять как 1 день доставка, 200 - 2 и т.д.
> что смешного? есть какой то варик кроме как в цикле это делать ?
Так не говорят потому что. Оно даже в оригинале звучит, как "кастом", если ты не японец или немец.
Касательно самого вопроса - то он тупой, потому что ты спрашиваешь без контекста.
> есть ли какие то средства у фреймворка ?
Откуда кто знает, какой у тебя фреймворк? Мы тут не телепаты. Задавай вопросы нормально, что используешь, каких версий, что делаешь, что хочешь получить, что получаешь, что не нравится.
окей, хочу отвалидировать данные без цикла. вот такой массив допустим и функция валидатора https://ideone.com/mG8q9d
я могу переписать это в цикл чтобы вогнать туда $row[$i][device_id], но меня интересует можно ли это более как то грамотно средствами фреймворка замутить? использую ларку 7.6 вместе с 7.4 пыхой
>что не нравится
не нравится то что сейчас приходится два цикла делать т.е. один на валидацию каждый строчки, и затем уже другой на на запись в бд. хотелось бы как то упростить. ну и щас пока вот писал сообщение выяснилось что циклом то видимо особо не работает по этому коду https://ideone.com/NwDYm0 и я ловлю эксепшн Argument 1 passed to Illuminate\Validation\Factory::make() must be of the type array, object given
Во-первых, не цикла, а вызова конкретного правила, а во-вторых, просто забей, всё нормально.
Собсна, сам код, и решенная задача
https://ideone.com/y1YVYt
Заранее, благодарен
Не согласен. Добавление стороннего движка имеет недостатки:
- всем разработчикам надо тратить время, чтобы с ним разобраться, прочесть документацию. А добавление таблицы этого не требует
- усложняется деплой, dev-окружение ест больше ресурсов
Потому в его случае добавление таблицы как раз более выгодный вариант. Тем более что ему нужен только префиксный поиск - а его, по моему, эластик как раз делает не очень эффективно.
Ты учись сравнивать плюсы и минусы, а не рефлексивно орать "elasticsearch" при виде слова "поиск".
Также, тебе двойка за якобы "тормознутую" реляционную БД. Поиск по индексу (а это и требуется в задаче) работает с отличной скоростью за миллисекунду. А теперь расскажи, как настроить индекс для префиксного поиска в эластике, какой командой.
>>835382
Всё зависит блять от задачи. Инструмент всегда подбирается под конкретную задачу.
И вы ничем не лучше >>834795, когда начинаете орать, что "база лучше". Изначальный анон так и не пришёл и не сказал, что ему вообще нужно.
Если ему нужен тупой поиск по подстроке, то база подойдёт. А если ему нужен сложный поиск со словоформами или там фасетами, то условный эластик вероятно будет эффективнее.
Использование глобальных переменных - плохая штука. Например, если твою функцию вызвать 2 раза, чтобы проложить 2 пути, то результаты первого вызова повлияют на второй. Глобальные переменные нужно убрать.
Вместо них лучше сделать, чтобы функция возвращала найденный ей путь и время через return. Когда мы вызываем oneStep() рекурсивно, мы собираем возвращаемые ей пути и выбираем лучший, который в свою очередь возвращаем через return.
> $currentPath []= $changeStation;
> $bif = array_pop ($currentPath);
Тут лучше было сделать отдельную переменную для измененного пути, чтобы не требовалось добавлять/удалять элементы.
> if ( ! ($count == count ($paths[$startPoint])) ){
> return;
А это условие не лишнее? Нельзя тут писать просто continue без этой проверки?
В общем, код можно сократить и улучшить.
Што сцуко делать?
Попробуй проституцию
В том же постгрессе есть индексы GIN/GIST как раз для полнотекстовых поисков. Вполне сносно работают, если правильно приготовить.
Для 50 записей подойдет и неэффективный LIMIT. А вот если бы у тебя были десятки-сотни тысяч записей, то тебе бы пригодился способ отсюда https://use-the-index-luke.com/sql/partial-results/fetch-next-page (берем какое-нибудь поле вроде даты и вместо page.php?page=100 пишем page.php?fromdate=2020-01-05).
Чаю, анон.
Ну допустим, как хранить несколько файлов загруженных, и как сделать архив для скачивания этих файлов как на гитхабе, например.
Можно создать папку для группы файлов и хранить их там вместе. Для скачивания в виде архива использовать утилиту командной строки вроде zip, которая создаст этот архив.
Запускать утилиту в идеале надо через очередь задач, так как она может долго работать. Или можно по крону находить группы файлов без архива и создавать для них архив. Чтобы архив уже был готов заранее, до того, как пользователь захочет его скачать.
Стандартной библиотеки на ООП, мне кажется что в теории можно бок о бок оставить как процедурную часть так и новую сделать. Еще хочеться делать вот так [1, 2, 3, 4].filter(fn($n) => $n > 3); или 'word'.replace('or', ''); и тому подобное, с массивами так вообще страшно, всегда приходиться тянуть стороннюю либу для коллекций если много логики с массивами
посатвил sql , пхп и апач.
Тестовый сайт запустился.
Теперь такой вопрос, на пальцах объясните - как мне сделать так что бы на одном моем серваке висело N отдельных сайтов.
Как для апача настроить виртуальне хосты прочел.
Не понимаю вот что:
ip адрес у меня один. Соответственно разнык сайты должны висеть на разных портах, так? 5001, 5002 и т.д.
Это мне нужно в кунфигу апача для дополнительных портов проставлять порты отличные от 89 и 443?
Чет не совсем хорошо понимаю суть темы.
Я бы сказал, что выше всё правильно сказали: дженериков, енумов и прочих радостей богатой типизации - раз, возможностей работать удобно более, чем в одном потоке - два и функциональщины стандартной библиотеке (чтобы возвращать maybe вместо сраных исключений) - три.. Но!
Но! мы сразу же получим современную джаву, только на php и без 20 лет вкладывания миллионов человеко-часов в JVM и экосистему на базе богатства типов, метапрограммирования и тп.
Стоит ли превращать пыху в джаву - вопрос очень дискуссионный, потому что джава уже есть, на её поле её не обогнать (если ты не C# и не совсместим с джавой, как котлин или скала), а сделать вторую джаву, только хуже - верный способ загнать язык в гроб, потому что все, кто может, перейдут в джаву номер 1 (которая лучше, которая джава), а новички ищущие простого, как молоток, языка в решении их задач с вебом в язык приходить перестанут, потому что порог входа и общая сложность сильно вырастет. Так можно и старых пользователей разогнать, и новых не получить.
Возможно, лучше оставить пыху, как есть. Да, в чём-то недоязык, зато очень простой и легко осваивается индусами и студентами, позволяя по-быстрому им расширять нужную CMSку или писать маленькие пет-проектики.
Ты по моему просто плохо понимаешь исключения. Зачем нужно это Maybe, для работы с которым надо код писать внутри анонимных функций вместо нормальной работы?
Код с исключениями:
$a = f();
$b = g($a, $c);
Или даже короче:
$b = g(f($a), $c);
Код с убогим Maybe:
$a = f();
$b = $a->transform(fn($x) => g($x, $c));
Ну и ужас. Читать невозможно, куча лишнего в сравнении с кодом с исключениями.
У вас прямо какая-то религия, вы попробуйте реальный код с бизнес-логикой, базами данных и множественными костылями на своих функциональных языках с чистыми функциями писать, а не программу расчет числа Фибоначчи на 5 строчек. Может быть, ваше мнение поменяется и вы начнете более реалистично смотреть на языки программирования.
Можно сделать, чтобы каждый сайт был на своем порту. Или можно сделать, чтобы они все были на одном порту, за счет "виртуальных хостов".
Так как браузер в HTTP-запросе отправляет имя хоста, веб-сервер может по имени выбрать нужный виртуальный хост.
>>834795
Господа, то что в пену пускаете пахнет какой то инфантильностью ботаника. Уймитесь. Истерики удел детей.
Приложушку я уже написал, и она работает. Приложушка нужна руководству, и ее использовать будут человек пять, с мобилок в основном. И я ее вообще на ноде, из интереса написал.
>>835390
А вот этот анон мыслит здраво.
Поясню, для того что бы вы потенциально понимали, что истерить - не лучший варинт. Понятно что это двач, но обычно истеричный айтишники своими истериками в реальность протекает.
Исходжные задачи - просты. Есть база +600 таблиц, десятки миллионов записей в отдельных таблицах. База не мною спроектирована, спроектирована хуево, из десятилетие уже в нее накидали такого что я ебал, многие таблицы хуй пойми зачем висят, и названы как то в духе op_tp_lid , и эта база таба-думс не мною глобально поддерживается. Поверх базы лежит софт и все это аутсорсит отдельная компания за отдельные деньги. Так что все ваши предложения по добавлению инструментов/индексов/таблиц сразу идут мимо кассы. То что вы наманяфантазировали - ваши теоретические проблемы. Все что я могу - sql запросы писать статистические, иногда этими запросами я правлю данные в базе, ибо в софте ошибок не мало, и он кривой. Но я не имею права править структуру базы никак вообще. Лезть ее править на свое счастье мне нахуй не упало - этого не делают даже отдельные люди за отдельные деньги, исправлю -спасибо не скажут, сломаю - естественно крайним буду.
Тот запрос который я написал - это аналитический запрос, выборка собирается из 15 таблиц, причем в отдельных таблицах воозможность связывания идет только по тектовым значениям полей, что то типа LIKE или NOT LIKE. Все это дело идет секунд 50. Результат - около двух тысяч строк, и это средний максимум ежедневный, больше не будет. Остальное - удалить старые данные из дочерней базы, обработать полученные 2000 строк, воткнуть их в базу - 0.7 в среднем секунды.
Ожидаемая частота использования приложения - раз 20 за день посмотрят инфу.
Думаю что в моих условиях и кретину понятно что доп. индексы, таблицы и эластик - совершенно не вариант. То что вы сами нафантазировали, сами и батхертнули.
Как то так.
>>834795
Господа, то что в пену пускаете пахнет какой то инфантильностью ботаника. Уймитесь. Истерики удел детей.
Приложушку я уже написал, и она работает. Приложушка нужна руководству, и ее использовать будут человек пять, с мобилок в основном. И я ее вообще на ноде, из интереса написал.
>>835390
А вот этот анон мыслит здраво.
Поясню, для того что бы вы потенциально понимали, что истерить - не лучший варинт. Понятно что это двач, но обычно истеричный айтишники своими истериками в реальность протекает.
Исходжные задачи - просты. Есть база +600 таблиц, десятки миллионов записей в отдельных таблицах. База не мною спроектирована, спроектирована хуево, из десятилетие уже в нее накидали такого что я ебал, многие таблицы хуй пойми зачем висят, и названы как то в духе op_tp_lid , и эта база таба-думс не мною глобально поддерживается. Поверх базы лежит софт и все это аутсорсит отдельная компания за отдельные деньги. Так что все ваши предложения по добавлению инструментов/индексов/таблиц сразу идут мимо кассы. То что вы наманяфантазировали - ваши теоретические проблемы. Все что я могу - sql запросы писать статистические, иногда этими запросами я правлю данные в базе, ибо в софте ошибок не мало, и он кривой. Но я не имею права править структуру базы никак вообще. Лезть ее править на свое счастье мне нахуй не упало - этого не делают даже отдельные люди за отдельные деньги, исправлю -спасибо не скажут, сломаю - естественно крайним буду.
Тот запрос который я написал - это аналитический запрос, выборка собирается из 15 таблиц, причем в отдельных таблицах воозможность связывания идет только по тектовым значениям полей, что то типа LIKE или NOT LIKE. Все это дело идет секунд 50. Результат - около двух тысяч строк, и это средний максимум ежедневный, больше не будет. Остальное - удалить старые данные из дочерней базы, обработать полученные 2000 строк, воткнуть их в базу - 0.7 в среднем секунды.
Ожидаемая частота использования приложения - раз 20 за день посмотрят инфу.
Думаю что в моих условиях и кретину понятно что доп. индексы, таблицы и эластик - совершенно не вариант. То что вы сами нафантазировали, сами и батхертнули.
Как то так.
>>Можно сделать, чтобы каждый сайт был на своем порту.
Можешь подробнее разъяснить, а лучше скинуть инфу как сделать так?
Вот пример с разделением по портам: https://httpd.apache.org/docs/2.4/vhosts/examples.html#port
Вот с разделением по имени сайта: https://httpd.apache.org/docs/2.4/vhosts/name-based.html
Представь себе это так [new int, new string] и можешь сам придумать для чего это может понадобиться.
Спасибо, я уже разобрался.
Не верится, что я сам это делаю, но я просто скину тебе статью Фила с хабра: https://habr.com/ru/company/vdsina/blog/523618/
Он там в целом неплохо всё описал. В двух словах, монада (ну или union type, если бы функция loadUser возвращала не User, а User | Error) даёт возможность явно работать с ошибкой (в отличие от unchecked эксепшенов, принятых в пыхе (а других в пыхе и нет), когда ты никогда на 100% не знаешь, что у тебя откуда вылетит и точно ли ты своим catch'ем ловишь то, что вылетит или оно поменялось уже), при этом для того, чтобы использовать значение, ты обязан явно проверить возвращённое значение на результат.
То есть, в идеале у тебя компилятор (ну или линтер в случае пыхи) тебе явно скажет: "ты не обработал все возможные значения результата" или "ты пытаешься использовать результат, как юзера, а там может быть ошибка, иди нахуй". Такой себе аналог `function loadUser(string $id): ?User`, только вместо null | User у тебя там Error | User и ты можешь получать полезные значения из этого.
В php к сожалению такие вещи не на 100% пригодны из-за того, что он не статически типизируемый, так что ты можешь написать любой говнокод, который принимает объект юзера, а используешь ты его как строку и ничего тебе за это не будет. В компилируемых языках пользы от этого куда как больше. И уж конечно, от монаты становится намного больше пользы, когда весь код пишется в функциональном стиле и тогда оно начинает напоминать исключения, но намного более явно и более проверяемо статически. Смотри на это, как на продолжение тренда на статическую типизацию в пехапе.
Ну и да, не просто так функциональщина становится всё более популярна и не просто так в языках новой волны (go, rust, zig) исключения заменяют возвращаемыми значениями, а в "старых" пилят нативную поддержку самых простых функциональных концепций типа лямбд и некоторых монад.
А, ну и да, из твоего поста я понял, что ты никогда не пробовал использовать монады и вообще-то не особо представляешь, что это такое, просто слышал где-то про maybe.
Это неудивительно, поскольку php сообщество в целом довольно консервативно и отстаёт от трендов (ещё 10 лет назад язык был той ещё помойкой). Попробуй как-нибудь взять какой-нибудь в меру современный язык и попробовать на нём что-то написать в функциональном стиле, тебе понравится. Только хаскелль не бери, охуеешь (да и не пишет на нём никто почти).
btw, бизнес логика пишется даже лучше, потому что багов меньше на порядки, потому что функциональный подход - он не про заумь и теоркат, а про то, что все типы должны быть выведены статически и программа должна быть валидна на уровне типов в первую очередь, ничего неявно ни откуда не вылетать (исключения) и не меняться неожиданным образом (сайд эффекты). Всё остальное - это следствия.
Я тебе привел пример кода, где видно что с исключениями код проще и короче. Почему бы тебе не привести тоже пример кода?
> но я просто скину тебе статью
Там все притянуто за уши, чтобы выставить монады в выгодном свете. На самом деле все проще - если отсутствие пользователя это нормальная ситуация, то возвращаем null или объект ошибки, если исключительная - то бросаем исключение, которое не требуется обрабатывать. Вот и все. Работает без всяких монад.
В статье примеры кода с монадой большие и сложные, там приходится писать целый switch, и у тебя код будет наполовину из этих свитчей состоять. На исключениях код проще и короче, что я и привел выше.
> Самый увесистый минус Ecxeption лежит даже не в механике их работы, он в культуре использования. Процессы разработки часто устроены так, что человек понятия не имеет, что делать если операция провалилась.
И как монада решает эту проблему? Да никак, ошибку в монаде точно так же будет логгировать и игнорировать.
> когда ты никогда на 100% не знаешь, что у тебя откуда вылетит
Вообще, в phpDoc есть аннотация @throws на такой случай. Но знать на 100% и не требуется. Ты либо ловишь конкретное исключение в котором ты заинтересован, либо ловишь любые исключения (чтобы например откатить транзакцию и выбросить их дальше).
> В двух словах, монада (ну или union type, если бы функция loadUser возвращала не User, а User | Error) даёт возможность явно работать с ошибкой
Явный возврат ошибок всегда был возможен и без монад. Просто возвращаем 2 элемента: [$result, $error] = func(). Только вот это очень неудобный способ, так как постоянно приходится руками проверять наличие ошибки и прокидывать ее дальше, и эту проблему решают исключения.
> И уж конечно, от монаты становится намного больше пользы, когда весь код пишется в функциональном стиле и тогда оно начинает напоминать исключения, но намного более явно и более проверяемо статически.
Ерунда какая-то. Монады пришлось сделать не от хорошей жизни, а от того что в Хаскелле нет исключений, а есть чистые функции. В PHP таких ограничений нет, потому монады тут никому особо не нужны.
> и не просто так в языках новой волны (go, rust, zig) исключения заменяют возвращаемыми значениями
Я писал немного на Го, руками писать if после каждого вызова и возвращать ошибку быстро надоедает. Это просто какая-то дурь создателя языка, и недостаток, а не преимущество. Ты попробуй сам написать что-нибудь сложнее расчета числа Фибоначчи, тебе тоже надоест.
Я тебе привел пример кода, где видно что с исключениями код проще и короче. Почему бы тебе не привести тоже пример кода?
> но я просто скину тебе статью
Там все притянуто за уши, чтобы выставить монады в выгодном свете. На самом деле все проще - если отсутствие пользователя это нормальная ситуация, то возвращаем null или объект ошибки, если исключительная - то бросаем исключение, которое не требуется обрабатывать. Вот и все. Работает без всяких монад.
В статье примеры кода с монадой большие и сложные, там приходится писать целый switch, и у тебя код будет наполовину из этих свитчей состоять. На исключениях код проще и короче, что я и привел выше.
> Самый увесистый минус Ecxeption лежит даже не в механике их работы, он в культуре использования. Процессы разработки часто устроены так, что человек понятия не имеет, что делать если операция провалилась.
И как монада решает эту проблему? Да никак, ошибку в монаде точно так же будет логгировать и игнорировать.
> когда ты никогда на 100% не знаешь, что у тебя откуда вылетит
Вообще, в phpDoc есть аннотация @throws на такой случай. Но знать на 100% и не требуется. Ты либо ловишь конкретное исключение в котором ты заинтересован, либо ловишь любые исключения (чтобы например откатить транзакцию и выбросить их дальше).
> В двух словах, монада (ну или union type, если бы функция loadUser возвращала не User, а User | Error) даёт возможность явно работать с ошибкой
Явный возврат ошибок всегда был возможен и без монад. Просто возвращаем 2 элемента: [$result, $error] = func(). Только вот это очень неудобный способ, так как постоянно приходится руками проверять наличие ошибки и прокидывать ее дальше, и эту проблему решают исключения.
> И уж конечно, от монаты становится намного больше пользы, когда весь код пишется в функциональном стиле и тогда оно начинает напоминать исключения, но намного более явно и более проверяемо статически.
Ерунда какая-то. Монады пришлось сделать не от хорошей жизни, а от того что в Хаскелле нет исключений, а есть чистые функции. В PHP таких ограничений нет, потому монады тут никому особо не нужны.
> и не просто так в языках новой волны (go, rust, zig) исключения заменяют возвращаемыми значениями
Я писал немного на Го, руками писать if после каждого вызова и возвращать ошибку быстро надоедает. Это просто какая-то дурь создателя языка, и недостаток, а не преимущество. Ты попробуй сам написать что-нибудь сложнее расчета числа Фибоначчи, тебе тоже надоест.
>Я тебе привел пример кода, где видно что с исключениями код проще и короче
Код без трай кэтчей и вообще хендлеров исключений. Коротко пиздец. Топ кек.
>В статье примеры кода с монадой большие и сложные, там приходится писать целый switch, и у тебя код будет наполовину из этих свитчей состоять.
Каво? У тебя ВЕСЬ код состоит из if($foo !== null).Три четверти твоего кода это сраный бойлерплейт try catch if null.
>Вообще, в phpDoc есть аннотация @throws на такой случай.
И в методе контроллера у тебя по пять разных исключений прописано. Ну или ты тупо отключил варнинг об исключении в шторме. И то и то пиздец.
>Явный возврат ошибок всегда был возможен и без монад. Просто возвращаем 2 элемента: [$result, $error] = func().
А в типе написано array и что там внутри хуй его знает. Туплов нет, энумов нет, зато есть три тысячи наследников exception, но ловим все равно throwable, потому что exception для лохов и сам язык кидает ебаные ерроры, нотисы, варнинги и конские залупы.
>Ерунда какая-то. Монады пришлось сделать не от хорошей жизни, а от того что в Хаскелле нет исключений, а есть чистые функции.
Ну тут просто в голос. Создали кароч язык, начали на нем писать, а в нем исключений нет. Ну решили тогда делать функции чистыми, хули остается-то.
>Я писал немного на Го, руками писать if после каждого вызова и возвращать ошибку быстро надоедает.
А чекать Null не надоедает. Заворачивать вызов каждой либы в try catch не надоедает. Писать throws по всему стеку так вообще кайф.
> Три четверти твоего кода это сраный бойлерплейт try catch if null.
> Заворачивать вызов каждой либы в try catch не надоедает.
Да ты поехавший. В 90% случаев исключения не требуется ловить. Потому что они сигнализируют об исключительной ситуации, которую программно никак не исправить. Если у тебя база отвалилась, то надо ее поднимать, а не пытаться что-то на уровне кода делать. Если ты в функцию передал что-то не то, то надо код исправлять, а не пытаться это как-то ловить или обрабатывать.
А с твоими монадами надо в 100% случаев вручную обрабатывать ошибки (где обработка в 90% случаев сводится к прокидыванию ошибки вверх). Это и есть бойлерплейт. На том же Го такого бойлерплейта куча, потому что там нет исключений. Го довольно убогий в этом плане.
Ты ничего не понимаешь ни в исключениях, ни в обработке ошибок, а споришь. Такое ощущение, что ты ни на монадах, ни на исключениях ничего крупного писать и не пробовал, а рассуждаешь.
Я тебе привел примеры кода, где никаких try/catch нет, так что прекращай тупить, с исключениями код получился короче, непонятно о чем тут спорить. Если бы ошибки надо было проверять, то можно было бы написать if ($error) и получилось бы не больше кода, чем с твоими убогими монадами.
Зачем тащить монады, придуманные из-за ограничений языка туда, где таких ограничений нет? В PHP у тебя есть выбор: бросать исключение или возвращать объект ошибки явно. В хаскелле и Го выбора нет. Вот и вся разница.
> и сам язык кидает ебаные ерроры, нотисы, варнинги и конские залупы.
Их ловить не требуется. В этом и плюс исключений. В отличие от всяких Го и Хаскеллей где такие ситуации надо обрабатывать вручную.
Короче, я предполагаю, что монады нужны не как замена исключений, а как вариант на тот случай, когда требуется вернуть ошибку и требуется ее как-то обработать. Для случаев явного возврата ошибок. Они не заменяют исключения, а используются в коде наравне с исключениями.
А ты ничего в обработке ошибок не понимаешь, и с чего-то решил, что монады это замена для исключений, и пишешь "... возвращать maybe вместо сраных исключений)...". Ты с чего-то решил, что теперь при передаче неправильных аргументов функция должна возвращать Failure. И как, интересно, ты собрался обрабатывать ошибку, если причина ошибки - криво написанный код? Такие ошибки никто не обрабатывает, а просто выбрасывают исключение и ждут когда придет программист и починит код.
Ты почему-то решил, что все исключения надо ловить и писать вокруг вызовов функций try/catch, это одно говорит о том, что ты толком не разбираешься в исключениях. В большинстве случаев их никто специально не ловит, что делает код проще и короче в сравнении с явным возвратом ошибок (как в Го).
Вдобавок ты еще и PHP плохо знаешь, так как по дефолту большинство функций стандартной библиотеки никаких исключений не выбрасывают, а генерируют варнинги.
>Да ты поехавший. В 90% случаев исключения не требуется ловить.
Хуйню не неси. Как раз в 90% случаев исключения нужно ловить. Потому что бизнес не может себе позволить вываливать 500 на ебало пользователю. Я уж не говорю про такие банальные вещи как ошибки при записи логов или отправки в очередь или доступности кэша. Нужно как минимум отрисовать ту же страницу, и написать что-то то внятное.
>Я тебе привел примеры кода, где никаких try/catch нет
Ну раз ты не привел, то никаких кэтчей нету хули.
>Короче, я предполагаю, что монады нужны не как замена исключений, а как вариант на тот случай, когда требуется вернуть ошибку
Исключение это goto. Точка. Можно вместо выброса исключения просто прямо с помощью goto перемещаться в его обработчик и все.
>А ты ничего в обработке ошибок не понимаешь
Нет ты.
>Вдобавок ты еще и PHP плохо знаешь, так как по дефолту большинство функций стандартной библиотеки никаких исключений не выбрасывают, а генерируют варнинги
>потому что exception для лохов и сам язык кидает ебаные ерроры, нотисы, варнинги и конские залупы
Ты еще и читать не умеешь, долбоеб.
> Как раз в 90% случаев исключения нужно ловить.
И они ловятся одним простым catch-all обработчиком в самом верху, который показывает страницу 500 и логгирует ошибку. Мало ли что бизнес не может позволить. Если у тебя ошибка в SQL запросе и из-за этого вылетает исключение, ты программно ничего сделать не можешь. Потому и ловить такое исключение смысла нет.
Даже если бы ты захотел ловить все возможные исключения, и обрабатывать их, это потребовало бы потратить много времени на код, который с 99% вероятностью не будет выполняться. Бизнес вряд ли заинтересован в расходах на написание такого кода. Хотя я не исключаю, что кто-то ловит такие исключения, чтобы скрыть ошибки в своем коде от заказчика.
Вместо этого выгоднее инвестировать в тестирование кода, чтобы отлавливать баги до выкладки в продакшен.
Ты по моему, просто не разбираешься в обработке ошибок, раз думаешь, что в коде с исключениями везде приходится писать try/catch.
А вот в убогом Го, кстати, придется писать if на такой случай, так как там нет исключений и ошибки возвращаются явно. В Ноде до появления await тоже приходилось так делать.
> Исключение это goto.
Во-первых, нет (goto не позволяет переходить за пределы функции), во-вторых, какая разница? Это работающий инструмент. В проектах, с которыми я работал, исключения выполняли то, что от них требовалось. Отказ от них и переход на явный возврат ошибок усложнил бы код и удорожил бы его написание.
>И они ловятся одним простым catch-all обработчиком в самом верху
Слушай, долбоеб, если ты ничего сложнее хеллоуворлда не писал, то нехуй тут пиздеть.
Если пользователь заполнял сложную форму, то никаких отдельных страниц. Если пользователь оформлял заказ, то никаких отдельных страниц. Если пользователь набирал текст, то никаких отдельных страниц.
Более того тебе, долбоебу, невдомек как пишутся крупные сайты и приложения. Там десятки интеграций и отдельных сервисов. И то что какой-то из этих сервисов прямо сейчас не доступен не должно мешать делать дела.
Кароче съеби, джун, ты утомил свой тупостью.
2. Вывожу его через date('d.m.Y H:i')
3. Как сделать чтобы время выводилось по часовому поясу юзера?
>И то что какой-то из этих сервисов прямо сейчас не доступен не должно мешать делать дела.
Эммм. Не уверен, что вправе что-то советовать такому духовно богатому лицу (сарказм), но НАСТОЯТЕЛЬНО рекомендую повыносить свое говно в отдельный поток, а не пытаться в основной бизнес логике жевать периодически отваливающиеся сервисы.
Либо удаленный сервис критичен, и ты спокойно показываешь юзеру "ой, что-то пошло не так", либо не критичен, и он будет спокойно долбиться до победного в отдельном потоке.
Кто вообще говорит об отдельных сервисах в пехапе, лол? Обычный проект средней руки - это монолит на симфони/ларавел, что кстати совсем даже и не плохо.
И да, удваиваю того, кто говорил, что исключения надо ловить.
Логику можно (в смысле, эти слои всегда существуют, просто в коде ты можешь все три слепить хоть в один файл) разделить на три слоя:
[входные адаптеры] -> [приложение] -> [домен] <- [инфраструктура (реализации, репозитории)]
И каждый слой выкидывает наверх свои исключения.
К примеру, драйвер базы у тебя выкидывает PostgresException. Но драйвер у тебя вызывается внутри репозитория, интерфейс которого ничего про постгрес логично не знает. Поэтому домен у тебя должен выкинуть выкинет EntityNotFound, так что придётся отлавливать и матчить. Далее, сценарий в приложении у тебя не должен отдавать EntityNotFound, поскольку слои выше вообще ничего ни про какие entity не знают. Так что слой приложения отловит это исключение и обернёт его в InternalAppError или InvalidArgumentError. И уже последний слой, отловив одну из этих ошибок, вернёт 500 или 400.
В итоге, ошибки (да и просто результаты маппятся примерно так):
400<-[primary adapter]<-InvalidArgumentException<-[application]<-EntityNotFoundException<-[domain]<-PostgresNotFoundRowException<-[драйвер]
Поэтому таки да, в нормальной архитектуре работа с обработкой ошибок идёт постоянно.
> на три слоя
Их три, потому что инфраструктура на самом деле содержит реализации интерфейсов из доменного слоя.
бамп
Сап, есть ли какой-нибудь бесплатный плагин, который может реализовать и бронирование и оплату услуги?
Блин, это не вопрос, дополнение вопросу. Плагин нужен для wordpress
>400<-[primary adapter]<-InvalidArgumentException<-[application]<-EntityNotFoundException<-[domain]<-PostgresNotFoundRowException<-[драйвер]
> И уже последний слой, отловив одну из этих ошибок, вернёт 500 или 400.
А можно нихуя не делать и в глобальном хендлере отдавать 500, как всегда всё зависит от контекста. Просто из твоего примера можно подумать что в репозитории нужно ловить например отвал бд и выбрасывать EntityNotFound
Задание W5.1.
Спустя несколько месяцев с попытки вката я сделал очередную и наконец смог решить эту задачу. Это вменяемое решение или можно лучше сделать? https://ideone.com/Vmd3DQ
Мимо вкатывающийся туповатый анон
По моему, ты предлагаешь ошибочный подход. Как можно PostgresException (который может, например, соответствовать ошибке в тексте SQL запроса) преобразовывать в EntityNotFoundException? Это совсем разные вещи.
Если у тебя ошибка в SQL запросе, то тут ничего не поделать и не надо ловить это исключение в репозитории. Его поймает глобальный обработчик исключений, залоггирует и покажет страницу 500.
На практике, в большинстве случаев как раз ловить ничего не надо. Если ты написал кривой SQL запрос, то тут ничего сделать нельзя, надо ждать, пока программист его не исправит.
Что касается случая, когда сущность не найдена, то тут лучше просто возвращать null. А в самом верхнем слое, если вернулся null, отдавать 404 ошибку:
$entity = $repo->findById(...);
if (!$entity) {
return $this->createNotFoundResult();
}
Вот и все. Не нужно никаких сложных обработок ошибок.
> PostgresNotFoundRowException
Таких исключений нет, на уровне драйвера пустой результат это не ошибка. И не надо вводить это исключение, ты на ровном месте усложняешь код.
Тебе надо где-то взять часовой пояс юзера сначала. Он в заголовках не передается, его можно получить только через JS. Потому тебе сначала надо выполнить JS код, сохранить часовой пояс например в куки, и только потом ты сможешь выводить время так.
>>839158
Крон
>>839172
Так-то решение правильное, но в if/else есть 3 практически одинаковых строчки в каждой ветке. Ты мог бы вынести эти строчки за пределы if, чтобы они не повторялись.
Для определения monthlyPayment можно было бы использовать функцию min() вместо if.
> $creditBalance = $creditBalance - $monthlyPayment;
Тут можно использовать -= для сокращения кода.
трабл с error_reporting, оно не работает. Пошел в гугл, нагугли как его включить отредача кофиг, собсна отредачил -- заработало, но не так как надо
Прикол в том, что в конфиге поставил отображение как я понял ошибок
display_errors
Default Value: On
; Development Value: On
; Production Value: Off
display_startup_errors
Default Value: On
; Development Value: On
; Production Value: Off
error_reporting
Default Value: E_ALL & ~E_NOTICE & ~E_STRICT & ~E_DEPRECATED
; Development Value: E_ALL
; Production Value: E_ALL & ~E_DEPRECATED & ~E_STRICT
Но оно работает всё время, хоть ставь в начале error_reporting(0) хоть error_reporting(-1), ему все равно, оно будет работать.
Гугл сказал создать файл апач .htaccess и туда задать параметры, но оно не работает, ini_set('display_errors', TRUE) и подобное -- тоже.
Если в двух словах, оно работает всегда, или не работает вообще. Как фиксить? Или так должно быть? но вроде не должно, я смотрел, там люди как то переключают режим на своих сайтах, режим разраба там, и режим юзера, или что-то такое. и я так понял у меня к этому доступа не будет
Система:
убунту лтс 20
ламп ставил ручками без всяких денверов
эх как же хочется мудрого джедая
>Так-то решение правильное, но в if/else есть 3 практически одинаковых строчки в каждой ветке. Ты мог бы вынести эти строчки за пределы if, чтобы они не повторялись.
https://ideone.com/m11X2T
Переделал, спасибо за пояснение.
Ок, а как мне превратить время сохраненное из time() в нужный часовой пояс? Сервер стоит в москве, и видать поэтому все time() уже с GMT+3?
Время, которое возвращает time() - это unix time (число секунд с 1.01.1970), оно в UTC (то есть при вызове time() время конвертируется из часового пояса сервера в UTC).
Когда ты вызываешь date(), время преобразуется из UTC в местное время с учетом часового пояса в настройках сервера.
Чтобы явно преобразовать время в другой часовой пояс, можно попробовать использовать объект DateTime и этот метод: https://www.php.net/manual/ru/datetime.settimezone.php Ты можешь создать DateTime из unix time, и затем поменять ему часовой пояс.
>>839220
Вообще, вызов error_reporting() в коде приоритетнее того, что написано в конфиге.
error_reporting это не отображение ошибок, а полное игнорирование (не реагировать на них вообще никак, даже в логи не писать). Его лучше ставить в -1 или E_ALL. За отображение ошибок на экране отвечает display_errors. Вот его можно включить у себя локально и отключить на продакшене (на продакшене надо смотреть ошибки в логах).
> display_errors
> Default Value: On
Это у тебя так в конфиге? Почитай про синтаксис ini-файлов ( https://ru.wikipedia.org/wiki/.ini ), там не должно быть Default Value.
Там должны быть строки вида
ключ = значение
Например
display_errors = on
Цикл - это конструкция, которая выполняет один и тот же код много раз, пока выполняется какое-либо условие.
Почитай описание тут https://www.php.net/manual/ru/control-structures.for.php
Возьми там первый пример, попробуй запустить, потом что-нибудь поменять. Сравни пример 1 с примером 3.
Пиши, если есть более конкретные вопросы.
Про время понял, спасибо, буду копаться
>error_reporting это не отображение ошибок, а полное игнорирование
Мдээ уууш... А я-то думаю пачиму у миня пэхапэ ниработаит.
>Его лучше ставить в -1 или E_ALL.
Теперь понял. Раньше оперируя этими значениями пытался заставить пыху работать, лол, думал это рубильник такой вкл\выкл ошибок.
>За отображение ошибок на экране отвечает display_errors.
Понял, включил.
>Это у тебя так в конфиге?
Да. Vim говорит 96 сторока, но ниже 482 строка есть ключи=значения.
>Почитай про синтаксис ini-файлов
Да знаю, весь интернет перечитал, прежде чем лезть сюда с вопросами, оказалось не в ту сторону копаю.
Спасибо тебе
Ты глупенький что ли?
Я сказал
> PostgresNotFoundRowException
То есть, постгрес говорит тебе, что запрос не вернул ни одной строки, а ты самолично интерпретируешь эту ситуацию в EntityNotFound. Потому что постгрес мог вернуть DuplicateEntry и кучу других ошибок, которые ты интерпретируешь в какое-то бизнес-событие в зависимости от контекста.
Твой же вариант не учитывает того, что nullable entity может в теории значить много разных ситуаций + не позволяет передать никакой дополнительный контекст ситуации.
А, и да,
> А в самом верхнем слое, если вернулся null, отдавать 404 ошибку:
Это пиздец хуёвый код, потому что ты смешиваешь работу с сущностью (то есть бизнес-логику) и работу с результатами.
> Таких исключений нет, на уровне драйвера пустой результат это не ошибка. И не надо вводить это исключение, ты на ровном месте усложняешь код.
Это было к примеру, я уже не помню, что пехапешный драйвер возвращает и когда.
>>839095
Мой пример был про обработку конкретной ошибки. И пытался я им сказать, что различные результаты работы одного слоя интерпретируются в различные результаты на другом слое.
А ещё про то, что наружний слой не должен знать о внутреннем слое, о том, какой там драйвер и что вообще происходит.
> Твой же вариант не учитывает того, что nullable entity может в теории значить много разных ситуаций + не позволяет передать никакой дополнительный контекст ситуации.
У тебя примеры плохие, которые сбивают с толку. Допустим, нам надо получить сущность и заодно проверить что она не скрыта и к ней есть доступ.
Это элементарно решается явным возвратом ошибки:
class SomeController
{
...
[$entity, $error] = $someSvc->findVisibleEntity($id, $user);
if ($error) {
...
}
...
}
И соответственно в $error может быть объект с причиной ошибки. Хотя можно и try/catch сделать, но по моему явный возврат тут лучше читается.
Твой вариант плох несколькими вещами.
Первое - вопросы доступа решаются не совсем так, обычно оно выносится в какой-нибудь AccessManager (но это минорно, тк мало ли, какой говнокод ты пишешь, всякое бывает);
Второе - твой код возвращает нетипизированный массив, это даже не кортеж. Это означает, что хуй его знает, что там внутри, ни IDE, ни линтер нормально не сможет это проверить;
Третье - твой способ никак не защищает меня от возможности проигнорировать $error и заложиться на результат. Как-то так:
[$entity, $error] = $someSvc->findVisibleEntity($id, $user);
useEntity($entity);
И именно это было поводом для изначальной дискуссии "зачем нужны монады или возвращаемые ошибки": чтобы возвращать что-то, что будет явно отражено в сигнатуре метода, что ты будешь вынужден явно обработать и при этом не будет излишне громоздким.
Мои же примеры изначально были аргументом в пользу того, что ошибки не пробрасываются сразу на верхний уровень, а маппятся от слоя к слою. Соответственно, обрабатывать их приходится часто, много и разные. И соответственно же, try catch'ей приходится писать много и в какой-то момент они становятся более громоздкими, чем если бы возвращалось тупо значение.
Но это верно только для сравнительно серьёзных приложений. Всякая херня для малого (и среднего не-айти) бизнеса может быть написана вообще как угодно, там никогда не будет столько кода или ценности, чтобы это окупало вложения в правильную архитектуру
> вопросы доступа решаются не совсем так, обычно оно выносится в какой-нибудь AccessManager
Переусложнение. К тому же, может быть findVisibleEntity как раз его и вызывает для проверки. Чтобы не надо было эту проверку делать в 200 местах кода, она встроена в findVisibleEntity.
> ни IDE, ни линтер нормально не сможет это проверить
Это проблема IDE, а не моя. У меня в комментарии типы написаны.
Дожили, код под ограничения IDE подстраивать. Ради убогой жетбрейнсовской IDE делать код менее читаемым и переходить на исключения.
> твой способ никак не защищает меня от возможности проигнорировать $error и заложиться на результат
Тогда там будет исключение, так как $entity = null в этом случае.
> чтобы возвращать что-то, что будет явно отражено в сигнатуре метода, что ты будешь вынужден явно обработать и при этом не будет излишне громоздким.
В PHP нет способов заставить обработать ошибку.
Хотя выброс исключения как раз частично решает проблему (оно вылетит в любом случае, даже если ты его не ждешь). Но в PHP и других языках нет защиты от пустого обработчика ошибки:
try {
...
} catch (\Throwable $e) { }
Монады тут ничего не меняют, можно точно так же написать пустой обработчик ошибки и проигнорировать её.
Также, исходный комментатор предлагал на монады переделать стандартные функции PHP. То есть сделать, чтобы тот же PDO вместо исключений возвращал монады. И чтобы ты должен был после каждого SQL запроса вручную проверять ошибки. Ну убого же.
> И соответственно же, try catch'ей приходится писать много и в какой-то момент они становятся более громоздкими, чем если бы возвращалось тупо значение.
То есть ты предлагаешь после каждого SQL запроса проверять вручную, что не было ошибки? Зачем? Исключения решают эту проблему гораздо лучше, и ловить их в данном случае не требуется.
Я знаю про преобразование исключений, но сомневаюсь, что таких мест должно быть много.
> в правильную архитектуру
В последнее время для меня "правильная" архитектура это где код короче и проще. А не где паттерн на паттерне, и сотни микроклассов по 10 строк.
> вопросы доступа решаются не совсем так, обычно оно выносится в какой-нибудь AccessManager
Переусложнение. К тому же, может быть findVisibleEntity как раз его и вызывает для проверки. Чтобы не надо было эту проверку делать в 200 местах кода, она встроена в findVisibleEntity.
> ни IDE, ни линтер нормально не сможет это проверить
Это проблема IDE, а не моя. У меня в комментарии типы написаны.
Дожили, код под ограничения IDE подстраивать. Ради убогой жетбрейнсовской IDE делать код менее читаемым и переходить на исключения.
> твой способ никак не защищает меня от возможности проигнорировать $error и заложиться на результат
Тогда там будет исключение, так как $entity = null в этом случае.
> чтобы возвращать что-то, что будет явно отражено в сигнатуре метода, что ты будешь вынужден явно обработать и при этом не будет излишне громоздким.
В PHP нет способов заставить обработать ошибку.
Хотя выброс исключения как раз частично решает проблему (оно вылетит в любом случае, даже если ты его не ждешь). Но в PHP и других языках нет защиты от пустого обработчика ошибки:
try {
...
} catch (\Throwable $e) { }
Монады тут ничего не меняют, можно точно так же написать пустой обработчик ошибки и проигнорировать её.
Также, исходный комментатор предлагал на монады переделать стандартные функции PHP. То есть сделать, чтобы тот же PDO вместо исключений возвращал монады. И чтобы ты должен был после каждого SQL запроса вручную проверять ошибки. Ну убого же.
> И соответственно же, try catch'ей приходится писать много и в какой-то момент они становятся более громоздкими, чем если бы возвращалось тупо значение.
То есть ты предлагаешь после каждого SQL запроса проверять вручную, что не было ошибки? Зачем? Исключения решают эту проблему гораздо лучше, и ловить их в данном случае не требуется.
Я знаю про преобразование исключений, но сомневаюсь, что таких мест должно быть много.
> в правильную архитектуру
В последнее время для меня "правильная" архитектура это где код короче и проще. А не где паттерн на паттерне, и сотни микроклассов по 10 строк.
> В последнее время для меня "правильная" архитектура это где код короче и проще. А не где паттерн на паттерне, и сотни микроклассов по 10 строк.
С этого и надо было начинать, я бы сразу всё понял и не пытался что-то объяснять долбоёбам.
>Кто вообще говорит об отдельных сервисах в пехапе, лол?
Ну хз, как там в серьезных архитектурах, на моем говнопроекте есть штуки 4 удаленных сервисов. Все написаны хуесосами.
Блокирующим не является ни один из них, то есть юзер может делать свое дело даже если они лежат (опять).
Я позаводил таблиц, в одном поле json с входными параметрами, в другом флаги выполнен/ошибка и тд, прохожу кроном.
На 3 из них на самом деле всем похуй, я раз в месяц с лицом лягушки смотрю, что там уебалось, и чиню вилкой.
Четвертый при любом косяке шлет аварийные письма куче народу, в том числе мне, и мы с мыльной жопой думаем что делать.
Выкакайте мне SQL (для борды, например), кто-нибудь, пожалуйста.
Что-то вроде:
SELECT FROM 'thread'
LEFT JOIN 'post' ON 'post'.'thread_id' = 'thread'.'id'
WHERE 'thread'.'board_tag' = 'вставить тег'
ORDER BY 'thread'.'bumped_at' DESC, 'post'.'created_at'
Но вот как ДЛЯ КАЖДОГО треда выбрать по несколько последних постов?
Я думаю о под-запросах, но это что-то не то, потому что подзапрос - это выборка, выборка - это таблица, а мне нужно динамически определить эти выборки.
Я подумал еще немного.
В случае одного последнего элемента проблем нет.
Можно сгруппировать по внешнему ключу. Но что делать, если нужно несколько дочерних сущностей.
Ну ты самый цимес ухватил. Аналитические запросы на SQL это вообще пушка. Я знаю как минимум три способа сделать то что тебе нужно, но на постгресе:
1) Оконаая функция. Пишется просто, но чекает всю таблицу с постами.
2) LATERAL JOIN, уже быстрее, но нужно немного вывихнуть мозг.
3) Рекурсивный запрос, самый быстрый, но сам запрос будет выглядеть пиздец заумно.
Спасибо. Оконной функции мне пока что хватит. Не знал что такие штуки существуют
фриланс на PHP - это на 70% возня с вордпрессом. Платят копейки, конкуренция с индусами огромная.
Остальные 30% - это проекты на фреймворках Laravel или Symfony. Тут уже оплата норм.
На питоне да - царит Django
Я бы учил PHP + Laravel. Мне кажется на нём должно быть несложно удалёнку найти. Накрайняк можно всегда на вордпресс откатиться
питон для фриланс пиздец хуйня, не стоит брать. зачастую это какие то блять лабы либо же курсовые работы, реже боты для телеги. иногда видел что надо было автоматизированные тесты написать на нем, на джанге практически ничего не было мониторил только снг если че. а по поводу фриланса или удаленки то тебе лучше во фронт идти, там и вакансий больше и шанс наткнуться на хорошую работу со стеком лучше, да и удаленщиков чаще ищут + с фрилансом проблем нет. ну и будем честным - в жс тупо легче войти чем тот же питон или же пхп, сириусли
аноны, нужен ваш совет. вот уже практически год гребу на своей галере на всяком говне типо битриксов/вп/опенкартов. меня это в начале лета заебло и я начал там осваивать ларавель в нормальном темпе. в своем зажопье был в августе в двух конторах потому что ларавель только там на джуна и на мидла соответственно. оба тз выполнил нормально со слов самой конторы естественно но оба раза блять отказ. там где на ждуна сказали что с тз все окей, но из за пробелов в теории мы не можем вас позвать. там где на мидла - сказали просто что тз норм но позвать не можем, причины отказались объяснять.
с сентября немного фриланшу на ларавеле чтобы был какой то реальный практический опыт с кейсами а не вот вся эта учебка, но проблема в том что моя самооценка на днище и я просто боюсь кому то отсылать свое резюме. боюсь что снова ответят отказом, либо же позовут, сделаю тз и въебу свое время, а в итоге меня на интервью разъебут и будут пальцем тыкать что я пиздабол и нихуя на самом деле опыта реального работы у меня нет мне такое начальник конторы говорил который собесил на мидла. так вот нужен ваш совет: как поступать то?
по поводу тех что с теории - на собесе немного спрашивали уж. единственное с чем встрял - это чем отличается right join от left join ну и естественно паттерны. напряую сказал что знаю только теоретически и поверхностно тк из за стека на котором я работаю применять их просто невозможно. ну рассказал уж про базовую фабрику, синглтон, прототип, адаптер, декоратор. как то так. все. как блять перешагнуть то в итоге через себя, чтобы быть уверенным и иметь норм работу с нормальныым стеком и перспективами? щас сижу гребу на этом говне за 30к. с ними кста проблем нет. постоянно кто то зовет на опенкарт или же битрикс либо фрилансить либо на полноценные проекты
питон для фриланс пиздец хуйня, не стоит брать. зачастую это какие то блять лабы либо же курсовые работы, реже боты для телеги. иногда видел что надо было автоматизированные тесты написать на нем, на джанге практически ничего не было мониторил только снг если че. а по поводу фриланса или удаленки то тебе лучше во фронт идти, там и вакансий больше и шанс наткнуться на хорошую работу со стеком лучше, да и удаленщиков чаще ищут + с фрилансом проблем нет. ну и будем честным - в жс тупо легче войти чем тот же питон или же пхп, сириусли
аноны, нужен ваш совет. вот уже практически год гребу на своей галере на всяком говне типо битриксов/вп/опенкартов. меня это в начале лета заебло и я начал там осваивать ларавель в нормальном темпе. в своем зажопье был в августе в двух конторах потому что ларавель только там на джуна и на мидла соответственно. оба тз выполнил нормально со слов самой конторы естественно но оба раза блять отказ. там где на ждуна сказали что с тз все окей, но из за пробелов в теории мы не можем вас позвать. там где на мидла - сказали просто что тз норм но позвать не можем, причины отказались объяснять.
с сентября немного фриланшу на ларавеле чтобы был какой то реальный практический опыт с кейсами а не вот вся эта учебка, но проблема в том что моя самооценка на днище и я просто боюсь кому то отсылать свое резюме. боюсь что снова ответят отказом, либо же позовут, сделаю тз и въебу свое время, а в итоге меня на интервью разъебут и будут пальцем тыкать что я пиздабол и нихуя на самом деле опыта реального работы у меня нет мне такое начальник конторы говорил который собесил на мидла. так вот нужен ваш совет: как поступать то?
по поводу тех что с теории - на собесе немного спрашивали уж. единственное с чем встрял - это чем отличается right join от left join ну и естественно паттерны. напряую сказал что знаю только теоретически и поверхностно тк из за стека на котором я работаю применять их просто невозможно. ну рассказал уж про базовую фабрику, синглтон, прототип, адаптер, декоратор. как то так. все. как блять перешагнуть то в итоге через себя, чтобы быть уверенным и иметь норм работу с нормальныым стеком и перспективами? щас сижу гребу на этом говне за 30к. с ними кста проблем нет. постоянно кто то зовет на опенкарт или же битрикс либо фрилансить либо на полноценные проекты
Смотря что с чем сравнивать. Сетевой стек у фряхи лучше. В остальном линукс лучше.
Я деградирую. Ебал я в рот саморазвитие.
Что управление? Ксли веб-панель для сервера, то вроде ajenti вроде есть. Такого как webmin/cwp и др похожих даже отдаленно нет. В основном ручками в консольке.
Сложно, ебать. Это же прыщи2
Нужен сайт для массажного центра, где пользователь сможет забронировать и оплатить услугу. Можете посоветовать бесплатный плагин для wordpress или другое решение, которое позволит добавить данный функционал?
Лолчто. Есть библиотеки, которые это делают. Также, как и в других языках.
>В php разбираться начал час назад, и никак не могу нагуглить
Действительно, не нагуглить никак. Хуй знает куда спрятали.
На локалхосте пхп 7.2. Написал в composer.json зависимости, сделал composer self-update и composer update, зависимости скачались. Залил на сервер (там пхп 5.6). Запускаю - а оно мне вместо результата работы скрипта: "Composer detected issues in your platform: Your Composer dependencies require a PHP version ">= 7.2.5". You are running 5.6.30-0+deb8u1."
Почему композер требует пхп? Т о есть, вся его работа на сервере - это делать автолоад уже загруженных файлов. И почему требует такую новую версию? 7.0 прям его никак не устроит? Что эта тварь о себе возмнила? В зависимостях чётко указано, что для них требуется "php: ^5.5|^7.0" А для композера - фу ты ну ты! - 7.2.5 вдруг оказалось нужно. Пиздец, у меня пригорело. Можете объянить, в чём тут дело?
>В зависимостях чётко указано, что для них требуется "php: ^5.5|^7.0"
А конкретно в json написано
{
"require": {
"longman/telegram-bot": "^0.64"
}
}
И больше ничего.
У фреймворков свой роутинг. Ну а на чистом пыхе просто разбираешь $SERVER['REQUEST_URI']
Спасибо, то что нужно.
Возможно, longman/telegram-bot и не требует PHP > 7.0, а вот какая-то из его зависимостей требует.
Также, есть опция --ignore-platform-reqs, если хочется все равно установить потенциально неработающую библиотеку.
Пытаюсь написать регулярку для проверки правильности мобильных номеров из мануала. Но не понимаю что мне выводит сайт regex101. Объясните по человечески как на этом сайте понять результат моей регулярки?
Вроде разобрался. Но от разъяснений все равно не откажусь. Вдруг что-то не так понял
Не совсем. PHP-это большой и стабильный рынок проектов и большой рынок разработчиков, куда тебе, как разработчику, будет легко вкатиться (легче, чем в джаву, по-крайней мере) и где вполне можно получать серьёзные деньги.
Но!
Верхняя планка у php ниже, чем у той же джавы и найти зп больше 250к ты уже так просто не сможешь.
Также из-за сравнительно низких требований к разработке, обилия низкоквалифицированной рабочей силы и тёмного прошлого, очень легко нарваться на говнопроект или говнопродукт или говнокодера.
Также стоит разделять энтерпрайз-php (это одна тусовка) и cms-php (это вордпресс и индусы, туда лучше не лезь, я серьёзно, очень мало денег, очень много ебли).
Как-то так.
Я бы подытожил так, что для вката может и норм, но с ростом тебя, как специалиста, тебе вероятно придётся менять стек, как захочешь больше денег.
Щас бы разбирать и матчить урлы вручную, в 2020-то году. Регулярками, ага. Composer ведь ещё не изобрели.
"PHP Cookbook" David Sklar, Adam Trachtenberg.
Оно же есть на русском:
"PHP Рецепты программирования"
Третье издание вышло в 2015 году, про четвёртое не в курсе. Задачек и кода там - море разливное.
Почитал про права на папки/каталоги - потенциально логика ясна. Но общего понимания как правильно нет. Я в принципе слабо понимаю потенциальные угрозы.
Но как по стандарту правильно в общем ограничивать права на моей учетке на моем сервере, что бы негодяи не влезли, и не затроллели?
Есть у меня пользователь user. У него стандартные права - кроме дамашенего каталога без sudo нигде ниче не может.
две моих приложухи на php лежат в /var/www, а одна на ноде лежит в домашнем каталоге.
Располагать в /home/ приложение разумно?
Как правильно организовать права на /var/www/ и /home/ что бы потенциальный говнюк, не влез к примеру в код моих скриптов, или не посоздавал новых файлов которые допустим всю файловую систему снесут?
С каким правами исполняются файлы в /var/www/ ?
Я под четкой user сижу. К примеру права на index.php в одном из сайтов в этом каталоге:
"-rw-r--r-- 1 root root" - то есть получается владелец этого файла это root, и у него есть права на чтение, и на запись в файл. Но где права на исполнение - x? Пхп то код этого файла запускает. Или я не понимаю под какими правами работает пхп в линукс?
Мне вообще не очень понятно под какими правами запускаются скрипты как пхп так и ноды.
Как правильно настраивать права?
>> в жс тупо легче войти чем тот же питон или же пхп, сириусли
Вот интересно же. JS проще, но похоже только в контексте фронта и в контексте реакт/втю/ангулар(тут не точно, он вроде архитектурно сложный)). Сам по себе ЕКМА скрипт таит в себе хуеву тонну подводных, асинхроность и наклон в сторону функциональщины. Что в котексте эпичной нитки в JS-треде , в которой кто то доказывал что в JS нет нужды разбираться в замыканиях, озабавно символизировало о глубине знаний начинающей реакт макаки.
А вот нода, если это что то большее чем пара крудов на экспрессе - становится нетривильной. А без экспресса начинается ебля с событиями, бинарными потоками, буферами - и парсингом всего этого дела. Что бы хелловорднуться пхп проще. А вто дальще - уже нет.
Попробуй прогуглить группу www-data
Меньше слушай тестоблядей, такие же ушлепки как адепты ФП - изначально годная идея доведена до маразма и под её лозунгом творится дичь.
Пиши тесты так, как считаешь нужным. Тебе нахер не нужен абстрактный 100% test coverage, через который на граничных случаях радостно лезут косяки.
Тебе нужна уверенность, что если у тебя прошли тесты то всё заебись.
Пиши тесты на функции, которые реально сложные и могут пойти по пизде, и разбавляй интеграционными (примерно то, что ты и описал).
>>845357
Нода - смертельно опасная хуйня, которая позволяет сделать кривую архитектуру тысячей разных способов. Причем комьюнити с пеной у рта будет называть говно шоколадом. Когда все херачили на колбеках я говорил, что это теже яйца, что и goto, вид в профиль. Примерно пару лет назад это таки начало доходить до широких масс.
Сам я использую ноду в исклучительных случаях, когда мне нужна (вот прям реально нужна) асинхронщина, и я готов ради неё терпеть всё нынешнее js блядство.
Это какой-то платиновый вопрос, раз в неделю минимум находится очередной поехавший, обещающий смерть PHP. Зачем постить такой вопрос, если можно просто найти предыдущий и прочитать его обсуждение.
Чушь там написана. Во-первых, при переписывании на Руби или Питон качество кода само по себе не повысится. Наоборот, оно понизится из-за отсутствия в этих языках тайп-хинтов. Я плохо представляю, как на этих языках вообще возможно какой-то большой проект написать. По моим ощущениям, Питон - это write-once язык, написать на нем можно, но читать и разбирать написанный код нереально, так как нет тайп-хинтов и непонятно, что приходит в ту или иную функцию.
Откуда вообще взялась идея, что Руби или Питон чем-то лучше для веб-разработки? Наоборот, они хуже подходят.
Ява не имеет таких недостатков, но она более многословна чем PHP.
Ну и сама идея переписать - тоже дурацкая. Автор предлагает потратить кучу времени и денег, чтобы получить что? то же самое.
В большинстве случаев код на PHP занимается тем, что берет или кладет что-то в БД, и немного преобразовывает эти данные. Начиная с PHP5, никаких новых фич, которые могут радикально улучшить код, не появилось, и смысла в переписывании нету. Новые версии PHP хорошо совместимы со старыми, потому особых проблем переехать с PHP5 на PHP8 нету.
Скорее всего, это ошибочный код. Первый раз такое вижу.
>>845231
Там ты вверху пишешь регулярку, а внизу текст. Regex101 подсветит те части текста, которые совпадают с регуляркой. Ну например: вверху вводишь \d+, справа от регулярки выбираешь нужные флаги, внизу вводишь текст с цифрами и он их подсвечивает: https://regex101.com/r/EQn6LH/1
>>845355
Для PHP права на исполнение не требуются. Они нужны только когда ты напрямую через консоль запускаешь исполняемый файл, а не через интерпретатор. Ему хватит прав на чтение.
Если у тебя владелец файла root, то это значит, что тебе нужен sudo для обновления файлов. А это не очень хорошо. Обычно для каждого сайта заводят отдельного пользователя, и делают, чтобы файлы принадлежали ему. Соответственно, если ты логинишься под этим пользователем, то тебе не нужен sudo.
Под каким пользователем работает PHP, зависит от конфигурации. Если ты используешь Апач + mod_php, то скорее всего он работает под пользователем www-data. Если же php-fpm, то тут можно настроить запуск от имени любого пользователя. Логично использовать того же пользователя, которому принадлежит сайт. Тут правда появляется недостаток, что PHP-скрипт имеет возможность перезаписывать файлы сайта. А у пользователя www-data обычно доступ к ним только на чтение, что чуть безопаснее.
Фреймворк тестировать не надо. И тестировать надо не столько "эндпойнты", сколько фичи приложения. Фичи могут быть такие:
- контент-менеджер может создать статью
- контент-менеджер не может создать статью без заголовка
- контент-менеджер может приложить картинки к статье, и они сохраняются в хранилище картинок
- менеджер может удалить статью
На каждую фичу ты пишешь проверяющий её тест. Ты ведь руками тестируешь написанный код? Вот тут то же самое, только тесты делаются программой.
Также, если ты пишешь реальное приложение, там всегда полно бизнес логики даже в крудах. Ну например:
- при создании статьи для нее генерируется ЧПУ
- при смене заголовка ЧПУ статьи не меняется
- при создании статьи, должен сохраняться и выводиться ид автора
- под статьей должен выводиться список похожих статей
Это и надо тестировать. То есть ты тестами проверяешь соответствие кода сайта требованиям в ТЗ. (Если ТЗ нет - то ты его должен придумать сам)
https://ideone.com/DTLEMi
Все тот же туповатый анон неосилятор
спасибо за ответ.
Я не оч хорошо пока разбираюсь в этой теме.
Вот вопросы:
1. Я сейчас сижу под моим user, но апачевский процесс стартует под www-data? Как это проверить?
У меня вроде есть пользователь www-data, я смотрел в файле /etc/passwd. Однако на этой строке последнее слово nologin, это что значит?
2. Как посмотреть под кем исполняется процесс?
К примеру у меня в /home/user висит нода, я это приложение запустил руками открыв консоль. Так как это home я запускал под user, соответственно злоумушленник, если сломает мне как то ноду и получит доступ к скриптам, допустим подменит мой файл на другой хз как это можно сделать - будет иметь возможность сломать мне только каталог user, но астальное прав у него не хватит, так? Потому что мой процесс ноды не имеет этих прав.
А если я ноду запущу с привилегией sudo, что в данном случае будет? И sudo же вроде временные привелегии дает, минут на 15 что ли.
3. Нужно ли мне пхп сайты перенести из /var/www/ куда нибудь в домашний каталог другого пользователя? Сейчас там владелец root, и я без пароля даже код изменить не могу. Или мне нужно просто для этого каталога еще другого пользователя добавить в права на чтение?
4.Вот пример, есть сайт пхп, если не предусмотрено что клиент не будет заливать какие то файлы(картинки), то соответственно для того пользователя под которым запускается апач достаточно прав на чтение. Но если скрипт должен создавать какие нибудь файлы, допустим таблицы отчетов, для отправки их обратно клиенту - то можно на эту конкретную папку дать права на запись для пользователя под которым апач запущен?
5. Как вообще происходит, что злоумышленник может получить root права на вэб сервере? Залить как то зловредный скрипт, и он будет исполняться под рутом, если под рутом запущен сам сервер?
Где что нибудь полное на эту тему почитать, пока что гуглятся какие то одинаково-общие статьи, но полной картины я не могу из них углядеть.
сорр если вопросы тупые - плаваю в этой теме
Захватывают контекст без use()
> но апачевский процесс стартует под www-data? Как это проверить?
Тебе бы какой-нибудь учебник по линукс (по использованию и администрированию) почитать бы не мешало, там это описано.
1) можно посмотреть скрипты systemd, которыми запускается апач, там будет указан пользователь. Можно использовать команду ps , она выводит id пользователя, под которым запущен процесс.
2) Через ps. Или top, htop.
> будет иметь возможность сломать мне только каталог user, но астальное прав у него не хватит, так? Потому что мой процесс ноды не имеет этих прав.
Да.
> А если я ноду запущу с привилегией sudo, что в данном случае будет? И sudo же вроде временные привелегии дает, минут на 15 что ли.
Нет, постоянные. 15 минут - это время, в течение которого не запрашивается пароль.
3)
> Нужно ли мне пхп сайты перенести из /var/www/ куда нибудь
Нет. можно просто поменять права на папку с сайтом. Смотри команды chown, chmod.
> Но если скрипт должен создавать какие нибудь файлы, допустим таблицы отчетов, для отправки их обратно клиенту - то можно на эту конкретную папку дать права на запись для пользователя под которым апач запущен?
Да. Но тут есть подвох, что файлы будут создаваться с владельцем www-data. Иногда это не подходит.
> Как вообще происходит, что злоумышленник может получить root права на вэб сервере?
Есть разные способы. Если есть что-то запущенное под рутом и в нем узявимость - то можно через уязвимый сервис. Также, можно сначала получить доступ к непривилегированному сервису, а потом как-то поднять привилегии (например, если ты выдал этому сервису право запускать sudo без пароля).
Если ты все правильно делаешь, то это будет затруднительно. Конечно, есть еще так называемые zero-day эксплойты, но они стоят очень больших денег и не каждому взломщику доступны. От них на 100% не защититься, но можно сократить поверхность атаки, например, настраивая фаерволл, разграничивая права, запуская сервисы в контейнерах итд.
>>845527
Например, для сортировки с помощью анонимной функции мы передаем правило сортировки:
usort($array, function ($a, $b) {
return $a['age'] <=> $b['age'];
});
Также, смотри функции array_map, array_filter.
> но апачевский процесс стартует под www-data? Как это проверить?
Тебе бы какой-нибудь учебник по линукс (по использованию и администрированию) почитать бы не мешало, там это описано.
1) можно посмотреть скрипты systemd, которыми запускается апач, там будет указан пользователь. Можно использовать команду ps , она выводит id пользователя, под которым запущен процесс.
2) Через ps. Или top, htop.
> будет иметь возможность сломать мне только каталог user, но астальное прав у него не хватит, так? Потому что мой процесс ноды не имеет этих прав.
Да.
> А если я ноду запущу с привилегией sudo, что в данном случае будет? И sudo же вроде временные привелегии дает, минут на 15 что ли.
Нет, постоянные. 15 минут - это время, в течение которого не запрашивается пароль.
3)
> Нужно ли мне пхп сайты перенести из /var/www/ куда нибудь
Нет. можно просто поменять права на папку с сайтом. Смотри команды chown, chmod.
> Но если скрипт должен создавать какие нибудь файлы, допустим таблицы отчетов, для отправки их обратно клиенту - то можно на эту конкретную папку дать права на запись для пользователя под которым апач запущен?
Да. Но тут есть подвох, что файлы будут создаваться с владельцем www-data. Иногда это не подходит.
> Как вообще происходит, что злоумышленник может получить root права на вэб сервере?
Есть разные способы. Если есть что-то запущенное под рутом и в нем узявимость - то можно через уязвимый сервис. Также, можно сначала получить доступ к непривилегированному сервису, а потом как-то поднять привилегии (например, если ты выдал этому сервису право запускать sudo без пароля).
Если ты все правильно делаешь, то это будет затруднительно. Конечно, есть еще так называемые zero-day эксплойты, но они стоят очень больших денег и не каждому взломщику доступны. От них на 100% не защититься, но можно сократить поверхность атаки, например, настраивая фаерволл, разграничивая права, запуская сервисы в контейнерах итд.
>>845527
Например, для сортировки с помощью анонимной функции мы передаем правило сортировки:
usort($array, function ($a, $b) {
return $a['age'] <=> $b['age'];
});
Также, смотри функции array_map, array_filter.
так как в книгах задачек нету как в учебниках то мне это показалось интересным, как оцените ?
Здравствуй ОП, спасибо за подсказку! Вышло вот так, проверь пожалуйста https://ideone.com/BdyGPI .
Есть несколько вопросов, изначально я сделал функцию с использованием статических переменных, что было неверно, поэтому возник вопрос, когда их вообще реально используют, в интернете пишут мол в рекурсивных функциях, например какой-нибудь счетчик вызова, но тогда получается, такое значение счетчика я могу снять лишь после первого вызова такой рекурсивной функции, ведь при повторном вызове оно сохраняется.
А также я добавил в возвращаемый массив такой элемент как 'возможные пути', чтобы можно было узнать их количество, вопрос в том, можно ли было как-то по другому их узнать, чем как сделал я.
Я так понимаю, можно вообще любую дичь писать, если знать как веб работает.
Посоветуйте любые курсы, где я с нуля дойду до какого-нибудь интернет-магазина или еще чего посложнее, чтобы мог уже на работу куда-нибудь устроиться и свое что-то делать.
Если у вас есть личный опыт, расскажите, какие курсы вы проходили, в какой последовательности и что доучивали.
Этого уносите, он закончился.
с шарпов на php лезть земля тебе пухом братишка, как такие долбоебы вообще образовываются-то
>>846337
Скажи, как мне развиваться как C# разработчик? Я хочу в Европе работать, а у них либо еще парочка языков в придачу, либо работа в Android Studio, чем я не особо хочу заниматься, а веб универсален. Если подскажешь, что можно писать, я может и соглашусь, что я не прав, и даже работу на первое время себе найду, чтобы руку набить. пишу игрушки на Unity уже 5 лет
Хотя иди нахуй, в Нидерландах нихуя толкового по шарпу нет, хотя дохуя вакансий на пыхе. Если тебя устраивает перспектива ебашить десятилетиями в российском офисе какие-нибудь офисные приложухи, то удачи, я же хочу кататься по миру.
>Начиная с PHP5, никаких новых фич, которые могут радикально улучшить код, не появилось, и смысла в переписывании нету.
нихуясе нету. а как же более высокая производительность? а как же более строгая типизация? а как же движение в сторону статической типизации?
>Новые версии PHP хорошо совместимы со старыми, потому особых проблем переехать с PHP5 на PHP8 нету.
скажи это владельцам эльдорадо/красного и белого у которых сайты на битриксе где весь код ядра написан с короткими тегами и которые в восьмерке просто не заведутся
Функции ты используешь правильно, а вот сама программа работает неправильно. В задаче требуется вывести, сколько всего будет денег уплачено по кредиту, а у тебя выводятся какие-то непонятные отрицательные числа.
>>845920
> возник вопрос, когда их вообще реально используют
Редко. Можно, например, с помощью такой переменной закешировать какие-то данные, которые никогда не меняются, но которые долго генерировать. При использовании статической переменной они сгенерируются один раз независимо от того, сколько раз будет вызвана функция:
static $var = generateData();
Но это редко когда нужно, а в случае ООП делается более аккуратно через поля объекта.
> $waysAndTimes[] = ['path' => null, 'time' => INF];
Не очень понятно, зачем в массив класть этот элемент.
foreach ($paths[$point] as $subTarget => $timeAndBy) стоило поместить в else, так как он не должен выполняться, если мы на соседней точке с целью.
Насчет $theNumbOf, я не уверен, что он правильно считается. Если это количество всех проверенных путей, то мы должны суммировать значения, возвращаемые рекурсивно, то есть:
для (каждой соседней точки) {
[ ..., $waysCount ] = вызвать себя рекурсивно;
$totalWays += $waysCount;
}
Представь сам: мы стоим в точке A, из нее можно идти в B или C. Из B - 10 путей до цели, из C - 20. Всего путей до цели получается 30.
Также, мне кажется, вместо массива 'path and time' лучше было бы возвращать из функции отдельно path, и отдельно time. Так получается более простой массив с результатами функции.
Вместо list() можно использовать квадратные скобки [...].
Функции ты используешь правильно, а вот сама программа работает неправильно. В задаче требуется вывести, сколько всего будет денег уплачено по кредиту, а у тебя выводятся какие-то непонятные отрицательные числа.
>>845920
> возник вопрос, когда их вообще реально используют
Редко. Можно, например, с помощью такой переменной закешировать какие-то данные, которые никогда не меняются, но которые долго генерировать. При использовании статической переменной они сгенерируются один раз независимо от того, сколько раз будет вызвана функция:
static $var = generateData();
Но это редко когда нужно, а в случае ООП делается более аккуратно через поля объекта.
> $waysAndTimes[] = ['path' => null, 'time' => INF];
Не очень понятно, зачем в массив класть этот элемент.
foreach ($paths[$point] as $subTarget => $timeAndBy) стоило поместить в else, так как он не должен выполняться, если мы на соседней точке с целью.
Насчет $theNumbOf, я не уверен, что он правильно считается. Если это количество всех проверенных путей, то мы должны суммировать значения, возвращаемые рекурсивно, то есть:
для (каждой соседней точки) {
[ ..., $waysCount ] = вызвать себя рекурсивно;
$totalWays += $waysCount;
}
Представь сам: мы стоим в точке A, из нее можно идти в B или C. Из B - 10 путей до цели, из C - 20. Всего путей до цели получается 30.
Также, мне кажется, вместо массива 'path and time' лучше было бы возвращать из функции отдельно path, и отдельно time. Так получается более простой массив с результатами функции.
Вместо list() можно использовать квадратные скобки [...].
Чтобы писать магазин, тебе надо знать:
- какой-нибудь фреймворк, роутинг, шаблонизатор, ORM
- базы данных, SQL
- MVC
- ООП
- основы верстки, HTML, CSS, JS
- основы протокола HTTP
- сам PHP
Можешь попробовать гайды из шапки, если они тебе подойдут.
>>846496
> а как же более высокая производительность?
Так ради нее переписывать код не требуется.
> а как же более строгая типизация? а как же движение в сторону статической типизации?
Это хорошо, но если у тебя куча легаси кода, возможно, добавление там везде тайп-хинтов не окупится. Код работает, проверен - и ладно.
> у которых сайты на битриксе где весь код ядра написан с короткими тегами и которые в восьмерке просто не заведутся
Это проблема Битрикса. Хотя не понимаю, что мешает им автоматизированными средствами заменить короткие теги на нужные.
>Так ради нее переписывать код не требуется.
я и не имею в виду тупо ради скорости. я про изменения в языке. как пример: был проект на опенкарте который на 5.6 отлично работал. дали доработки - на локальной машине поставил его на 7.2. - как итог отвалились доставки и проблемы в ядре начались. но там ладно, полчаса и пофиксил эти проблемы. потом когда ушли на удаленку - решил у себя на ноуте его на 7.4 попробовать - отвалились добавления в корзину, частично сами товары, а оформление заказа вообще не работает. вот и иди ищи развлекайся как все пофиксить и переписать и в чем вообще проблема. проще было на 7.2 обратно откатиться
>что мешает им автоматизированными средствами заменить короткие теги на нужные.
так не только в этом соль. ты когда через админку создаешь что то он тебе автоматом генерит с короткими тегами. так что тут либо напрягать разраба чтобы сидел ядро допиливал и чтобы битрикс генерил с нормальными тегами, либо же контент менеджера заставлять при создании чего то нового заходить в код и менять теги ясен хуй такого никто делать не будет
> Это проблема Битрикса. Хотя не понимаю, что мешает им автоматизированными средствами заменить короткие теги на нужные.
А что мешало им сразу нормально ядро написать, без говнокода? Ответ тот же самый им это нахуй не всралось, жри что дают
>Функции ты используешь правильно, а вот сама программа работает неправильно. В задаче требуется вывести, сколько всего будет денег уплачено по кредиту, а у тебя выводятся какие-то непонятные отрицательные числа.
https://ideone.com/xwt58m
Также я перешел к заданиям по регулярке и кое как сделал самую первую, в основном пользуясь гуглом, потому что в учебнике лично для меня не все понятно. Если че то можешь подсказать по ним, что может в дальнейшем помочь, то буду рад
https://ideone.com/XjvcAT
Спасибо за этот ответ и заранее за все последующие.
Не очень понял, почему у тебя цикл с конечно заданным условием по расчету кредита?
На первый взгляд похоже на то что я делал, пару дней назад. Только я делал на цикле for без условия (2ая часть из 3ех) и выходил break когда сумма доходила до нуля.
heredoc многострочный и облегчает хардкод больших абзацев текста со множеством переносов. И да, он тоже бывает шаблонизирующий (как двойные кавычки) и нет (как одинарные).
Обычно такая тема, что одну-две строки задают в кавычках, больше - heredoc'ом
Теперь хочу php изучить, голый php, без фреймворков. Как думаете до Нового года 31 декабря 2к20 можно успеть изучить голый php для того, чтобы нахреначить на нем бекенд для примитивного блога, сайта-визики или пародии на интернет-магазин? Хочу потренироваться, но желательно до Нового года успеть.
Мне кажется у них там построено по принципу совковых заводов, тупое начальство, которое требует результат, похуй какой, но выкатить. Маркетологи эти недоделанные фичи преподносят заказчикам как явление Христа народу. Стиль написания кода в каждом файле свой, такое чувство что там текучка кадров и каждый пишет как умеет. Ну и плюсом ко всему наследие ретро кода, на которое все положили хуй ещё на этапе написания. А ещё они прямо в документации ложат хуй на все PSR и говорят как писать "правильно" https://dev.1c-bitrix.ru/learning/course/index.php?COURSE_ID=43&LESSON_ID=5759 я охуел как это увидел
Все зависит от тебя и от уровня твоих знаний. Я бы не советовал писать что-то прям совсем на голом php, в качестве обучения да, но в перспективе лучше смотри на фреймворки Лару или симфони, поскольку на работе будет что-то использоваться. И старайся обходить стороной Битрикс и ВордПресс.
Спасибо большое. Да, я для обучения, хочу просто голый php изучить. Но я боюсь, что это может оказаться слишком долго. Надеюсь до нового года управлюсь.
Отличие heredoc (и nowdoc) в том, что в нем можно использовать любые кавычки. Его используют для вставки кусков кода, например, JS или HTML.
>>847040
У тебя в коде ошибка, написана внизу страницы: PHP Notice: Undefined variable: totalPaid in /home/nhkUXP/prog.php on line 9
Её надо исправить. Также, числа получились неверные, там ответы вроде 61270, а не такие круглые числа. Для этого, наверно, надо выходить из цикла, когда выплата завершена и долг равен нулю. Также, в коде есть небольшая ошибочка, из-за которой получаются круглые суммы вместо правильных.
Также, функции обычно называют начиная с глагола, не calculator, а calculateCredit например.
} else { пишется в одну строку без переносов.
> (8|\+7|\\ 8
Тут было короче написать \s*8.
> (-|\\(|\\)|\s)
Тут короче использовать квадратные скобки вместо круглых
> [\d]
Тут можно писать просто \d без скобок.
>У тебя в коде ошибка, написана внизу страницы: PHP Notice: Undefined variable: totalPaid in /home/nhkUXP/prog.php on line 9
https://ideone.com/aTYHvg
>Тут короче использовать квадратные скобки вместо круглых
Тут не понял если честно.
Я бы сказал, что "проблема" в первую очередь бизнесовая. Какой бы говнокод они там не писали, всё равно основная аудитория - это формошлёпы, которые в код спускаются в лучшем случае чтобы пару строк написать со словарём прямо в main-файле каком-нибудь. При этом оно всё накладывается на то, что 1С де факто монополист в РФ и они просто на уровне вендор-заказчик продавливают свой софт, мнение разработчика тут нахуй никому не упёрлось а мнения то и нет, потому что читай первую причину.
Соответственно, битрикс не имеет нужды конкурировать с другими инструментами по качеству, он их давит административно. А нет конкуренции - нет и стимулов делать лучше.
Иными словами, надо обмазываться битриксом и потом за 100500 бабла решать проблемы русским гос. конторами и ИПшкам?
Оно обычно так и происходит, заказчик покупает "коробку", радостный идет ко всяким конторам, находит Васяна за еду, тот делает хуяк, клик, клик, хуяк, клик и все магазин готов. А потом начинается, надо бы платежный сервис прикрутить, чего-то с 1С как-то не хочет работать, шрифты говно, корзина хуй пойми как скидку считает и тд, Васян говорит: "Тут наши полномочия всё" и съебывает в закат, ну или что-то пытается наговнокодить, далет запросы в базу в шаблоне и прочую дичь, а потом съебывает. Тут бедный заказчик обращается в ТП, его там посылают нахуй к партнерам, а те как крокодилы к которым пришли зебры на водопой, начинают доить бедного заказчика, в итоге обычный магазин начинает сосать деньги в ниебических масштабах, а любая мелочь будет решатся очень сложным квадратно-гнездовым способом за большое количество еблячасов которые для заказчика будут стоить от 1000 р.
прям тырпрайзом Оракл повеяло
Теперь верно, только не надо по несколько команд в одну строку засовывать.
>>Тут короче использовать квадратные скобки вместо круглых
> Тут не понял если честно.
Вместо (a|b|c) можно написать [abc], если a, b, c - это отдельные символы.
Ок, понятно
От тебя зависит и знаний. Я за 6 дней накидал на голой пыхе блог и залетел на галеру грести стажером. js тогда не знал Щас перекатился на норм стек уже
<?php
error_reporting(-1);
/ Коды для замены букв /
$code = array(
'а'=>'1',
'б'=>'2',
'в'=>'3',
'г'=>'4',
'д'=>'5',
'е'=>'6',
'ё'=>'7',
'ж'=>'8',
'з'=>'9',
'и'=>'0',
'й'=>'#'
$flipped = array_flip($code)
);
$text = 'нас предали. явка провалена.';
$cipher = strtr($text, $code);
echo "Оригинал: {$text}\nШифровка: {$cipher}\n";
Кроме как перевернуть тупа флипом - мне ниче в голову не приходит, но флип почему то не работает.... Я уже разные варианты перепробовал и ниче не помогает я хуй знает, видимо код это не мое....
<?php
error_reporting(-1);
/ Коды для замены букв /
$code = array(
'а'=>'1',
'б'=>'2',
'в'=>'3',
'г'=>'4',
'д'=>'5',
'е'=>'6',
'ё'=>'7',
'ж'=>'8',
'з'=>'9',
'и'=>'0',
'й'=>'#'
$flipped = array_flip($code)
);
$text = 'нас предали. явка провалена.';
$cipher = strtr($text, $code);
echo "Оригинал: {$text}\nШифровка: {$cipher}\n";
Кроме как перевернуть тупа флипом - мне ниче в голову не приходит, но флип почему то не работает.... Я уже разные варианты перепробовал и ниче не помогает я хуй знает, видимо код это не мое....
короче скачал denwer
установил, открыл все нормально. так вот
создал диск Z, ну и в нем папку www. далее mysite
файл index.php
в денвере вбил код hello word
и как его блять открыть в браузере?
в видеоуроке у него это фраза отображается в браузере
разобрался
Вместо денвера лет 5 назад был winginx, попробуй, если будет интересно. А вообще как сможешь, перекатывайся на линукс. Веб-программирование на винде считается моветоном, если ты не дотнетчик.
нахера тебе эта пеха, иди джс учи, больше толку будет
Решил, что здесь тоже полезно запостить, это про переход с PHP на другие языки
Вот, кстати, живой пример:
MySQL
ROUND((price / $coefficient),2) AS price
PostgreSQL
ROUND((price::numeric / $coefficient),2) AS price
Если у постргеса не указать, что округляемое - нумерик, то будет ругаться и вернёт ошибку. А в майскул такую конструкцию не завезли, он просто округляет. Это можно подружить как-то?
Просто, везде говорят, мол, у нас тут круто всё, можно в конфиге фреймворка поменять используемую базу и вё будет норм. А когда меняешь - оказывается, что нихренашеньки.
У хероку, насколько я понял, два варианта: либо автодеплой с гитхаба, либо ручной коммит через хероку CLI (ещё есть докер, но я в нём ни ухом, ни рылом). Но конфиги-то коммитить нежелательно, .env у гита должен быть в игноре. Плюс, мне нужно И показать код на гитхабе, И развернуть готовое приложение на хероке, И иметь возможность работать с проектом локально.
Пока что придумал такой велосипед:
- Делаю коммит изменений, пушу на гитхаб.
- меняю в .env параметры доступа к БД с локальных на хероковые, убираю из гитигнора этот конфиг.
- Коммичу, пушу на хероку.
- Откатываюсь на предыдущий коммит, грохаю из истории коммитов всё, что выше.
И так при каждом коммите. Это норм вообще? Или я делаю нечто странное?
Это копия, сохраненная 28 марта 2021 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.