Вы видите копию треда, сохраненную 24 января в 08:52.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Это тред для начинающих. Слово «классы» у тебя ассоциируется только со школой, а в аттестате тройка по математике? Ты наш человек.
Предыдущий тред тут: https://2ch.hk/pr/arch/2023-10-09/res/2761920.html (М) . Старые треды можно найти в гугле по словам "клуб изучающих PHP".
С чего начать - основы PHP
Наши уроки по PHP собраны по адресу http://codedokode.github.io/phpbook . Это учебник для изучающих с нуля. Там есть задачи, их нужно решать. Но если этот учебник тебе не нравится, можно читать любой другой. Или официальный справочник ( https://www.php.net/manual/ru/langref.php ). Или все сразу.
Если что-то непонятно, запости код и попроси подсказку или поищи задачу в архиве тредов.
Какой редактор использовать
Простые задачки можно решать в онлайн-песочницах вроде onlinephp.io , но для программ посложнее лучше установить редактор. Есть (дорогая) IDE PhpStorm, есть бесплатный Netbeans и VSCode, условно-бесплатный Sublime Text. Чтобы в последних получить автодополнение для PHP, нужно установить и настроить PHP language server.
Вот инструкции по установке PHP на компьютер: https://github.com/codedokode/pasta/blob/master/soft/php-install.md
Гайд по командной строке: https://github.com/codedokode/pasta/blob/master/soft/cli.md
Что изучать дальше
Зная лишь основы PHP, сайт ты не сделаешь и работу не найдешь. Обычно от начинающего требуют чуть-чуть больше:
PHP, ООП, основы HTTP, HTML/CSS (основы верстки), JS, SQL, PDO, MVC, git, composer, какой-нибудь фреймворк (Laravel или Symfony), основы автоматического тестирования, основы linux, английский.
Вот неофициальный роадмап (карта того, что можно изучать): https://miro.com/app/board/o9J_lbUUBBQ=/
По многим из этих тем у нас есть уроки или задачки:
- для понимания, что такое веб-сервер, прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- для понимая MVC, работы с БД и формами, реши задачу про студентов, в ней много полезных советов: 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 (если ты не изучил ни одного фреймворка, то это будет рановато). Если хочешь увидеть примеры использования паттернов в реальном коде - ковыряй исходники Симфони, например Symfony Forms. Ну и скажем честно, начинающему без опыта, который не видел сложный код, паттерны понять будет сложно.
- для улучшения английского можно читать news.ycombinator.com - там много статей на тему IT.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- задачи на HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- хороший учебник по JS: https://learn.javascript.ru/
- задачи на 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/
- задачи на SQL: https://github.com/codedokode/pasta/blob/master/db/databases.md
Что еще почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- https://phptherightway.com/
- Книга: Профессиональное программирование на PHP Джордж Шлосснейгл
- Книга: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- Про Git: https://git-scm.com/book/ru/v2
- Задачи на алгоритмы: https://codeforces.com/problemset
Дополнительно
- скачать учебник: зайди на https://github.com/codedokode/phpbook, нажми зеленую кнопку Code -> Download ZIP, распакуй на рабочий стол и открой index.html
- что будут спрашивать на собеседовании, если 0 опыта - будут гонять по теории, по официальному мануалу PHP, давать дурацкие задачки на переворачивание строк, гонять по SQL (транзакции, внешние ключи, напиши запрос), по JS (как сделать анимацию при нажатии кнопки), ну погугли, не ленись
- сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-12 месяцев
Я создал формы с методом POST
В обработчике формы я написал цикл, который берет значения из массива $_POST, проводит с ними математические операции и в зависимости от того, какое значение примут эти ?? элементы?? выводит надпись. Проблема в том, что у меня не сходятся количество итераций и значение одной переменной.
Может кто-нибудь рассказать что можно и что нельзя делать с элементами массива $_POST?
Я могу перезаписывать значение элементов этого массива?
Могу проводить математические операции с элементами этого массива?
Я совсем запутался.
Обработчик формы пик1
Задание ОПа пик2
Выводит: время выплаты: 13 месяцев, сумма выплаты: 105000
13 тут, конечно, потому что цикл кажется бесконечный
Изначальная задача ОПа: пик3
Причем если закомментировать строчку, где я "меняю" значение кредита, то цикл перестает быть бесконечным
Не нужно менять значения в объекте $_POST. Сделай отдельные переменные для этого.
$amountOfCredit = $_POST["amountOfCredit"] и т.д.
и дальше уже работай только с ними.
Саму логику не проверял. Для начала это исправь.
Т.е. в начале каждому элементу массива POST дать свою переменную и их уже использовать в остальном коде?
Мне кажется, что я подобное пробовал делать, но вышло не то, но я попробую снова.
Я просто этот код пытался чинить несколько часов подряд и у меня уже голова кругом.
Спасибо, что откликнулся на мой вопрос!
Простите анончики, я с шапкой проебался
Не подумай лишнего, анон, но
Я пойму, если тебе не захочется разбираться в моем вопросе
Мне просто неловко навязываться к другим людям, чтобы они мне объясняли как маленькому, да и я чувствую себя в такие моменты тупым и надоедливым
Так вот, если у тебя нет желания, можешь не разбирать мой вопрос
(если ты хотел, конечно же), я тогда сам через гугл и уже на свежую голову буду разбираться завтра.
Для вс кода есть крутые плагины. К примеру, Error Lens, который отображает ошибки прямо рядом с кодом. Я настроил так, что они выглядят как красные комментарии. Визуально сразу видно, но при этом органично смотрятся.
Для шторма сейчас искал аналогичный плагин - ни черта не нашёл. Есть кривые поделки васянов с версией 0.0.1, где даже настроек нет. Превращают код в месиво из-за вставок ошибок.
Вроде ИДЕ платная, но нифига в ней нет.
Вот просто для сравнения сделал два скрина. Сразу видно "качество" платного шторма по сравнению с бесплатным вс кодом.
Да, правильно. Так и нужно. Массив $_POST менять не нужно.
Теперь по поводу цикла. Цикл бесконечный потому что у тебя переменная $amountOfCredit всегда больше нуля.
Зачем тебе вообще там цикл, объясни? Сначала себе попробуй объяснить. Может станет сразу ясно, что поправить нужно будет.
Пользуйся vs code конечно. Тем более он бесплатный. Главное чтобы дебаггер там был.
По твоей логике если я напишу для шторма плагин, который будет пукать моим секретным пуком, то шторм автоматически станет лучше для разработки чем вскод.
Этот плагин ПОЛЬЗОВАТЕЛЬСКИЙ. Его написал какой-то хуй. Поддерживает его тоже какой-то хуй. Разработчики вскода к этому плагину никакого отношения не имеют. И точно также на каких-то хуях держится вся поддержка пхп в вскоде. Нет никакого системного подхода, просто рандомы пытаются что-то для себя скроить.
>Так ли необходимо ставить PHPStorm во время обучения?
Чел, я в своё время только нотпадом++ обходился. Чем тебе удобней тем и пользуйся.
>Зачем тебе вообще там цикл, объясни?
Для того, чтобы значение $amountOfCredit уменьшалось каждую итерацию и по количеству итераций можно было узнать сколько месяцев ушло на уплату кредита.
Изначально я задумывал, чтобы значение $amountOfCredit уменьшалось с каждой итерацией в цикле, поэтому и поставил условие, что если $amountOfCredit больше 0, то продолжать уменьшать.
Окей, пускай плагины не имеют отношения в шторму. Но вопрос к разработчикам тогда, почему их поделие не поддерживает популярные фреймворки типа Лары или Симфони, и я вынужден ставить такие же васянские плагины?
Потому ни лара ни симфони создателям шторма не принадлежат.
Логично что поддержкой своих фреймворков занимаются создатели этих фреймворков.
Почему тогда в платной идее есть поддержка Спринга из коробки, а бесплатный плагин для коммьюнити от разработчиков "добрые" жидбрейнсы забанили?
А тебе не приходило в голову что разрабы идеи учавствовали в разработке спринга?
Есть язык такой на основе джавы "котлин", угадай кто его создал.
Но в итоге пользователи шторма получают некачественный продукт. Что он вообще может? Подсвечивать код на РНР? Серьёзно? Сейчас любой текстовый редактор это может. За что они деньги берут вообще?
У тебя должно быть всего одно условие: проверка что можно выплатить кредит, зачем еще? https://3v4l.org/0Rv5i
Хорошо быть биокарликом с магическим мышлением. Что-то как-то подсвечивается, а больше ничего и не надо.
Вкатыш, вкатулек, вкатусик, просто посмотри сюда https://youtrack.jetbrains.com/issues/WI?q=State:%20Resolved . Это issue трекер шторма (да, только пхпшной части не всей ide). Если осилишь прочитать до конца первой страницы у тебя глаза на лоб полезут от объема работы.
Каждый день, каждый месяц тысячи исправлений, уточнений, улучшений. Никакое камунити за спасибо и звездочку на гитхабе ничего подобного даже близко сделать не может. Там люди въебывают за бабки и чистят, чистят, чистят непрерывно.
Все, я понял.
Я тупой.
В изначальной задаче проценты равны 3.
А я вписывал в форму 10.
И ориентировался по памяти на цифру 61к за 13 месяцев.
Столько часов потратил, а ошибка оказалась такой тривиальной.
Спасибо, анон, за код.
Только благодаря тому, что я взглянул на проценты, я понял в чем моя ошибка...
Ты дебаггером пользуешься? Как ты проверяешь что у тебя в переменных находится каждую итерацию? Научись дебажить не принтами, начнёшь находить ошибки гораздо быстрее.
Посмотри на него внимательнее. Даже если ты в моем коде напишешь больше процент, никаких бесконечных циклов там не будет.
>>876671
Как раз нужно научиться сначала пользоваться принтами. Не нужен тут никакой дебаггер. Достаточно просто вывести прирост на каждом цикле и увидеть что он не такой как ожидалось.
>Посмотри на него внимательнее. Даже если ты в моем коде напишешь больше процент, никаких бесконечных циклов там не будет.
Но я не исправлял код, я всего лишь при заполнении формы написал 3 вместо 10 и все стало работать.
При этом если снова вписать 10 при заполнении формы, то цикл снова станет бесконечным.
Я ограничил его итерацию до 30 - продолжал считать, ограничил до 100 - также продолжает считать.
Если вписать 11, то сразу кидает, что невозможно оплатить кредит.
При этом если добавить равно в строку:
if ($increaseInCredit>=$monthlyPayment) { //Если банк хочет взять за пользование кредитом больше, чем школьник готов платить в месяц
То сразу отсылает, что кредит нельзя оплатить
Видимо из-за этого он уходил в бесконечность
Проблема в том что ты пытаешься делать несколько вещей одновременно и внутри цикла, который то можно выполнять, то нельзя.
Начни с того что сделай проверку на возможность выплаты кредита перед вычислением тела кредита. https://3v4l.org/85eBi
Проверку ведь можно сделать без цикла вообще.
Думаю, что это из-за того, что я не знал, что return можно использовать в if
И как я примитивно понял, он останавливает выполнение остального скрипта?
return прерывает выполнение и возвращает значение. Тут поскольку никаких функций нет просто прерывает выполнение. Как вариант можно писать die() https://3v4l.org/M6ob2 или if else https://3v4l.org/l3AoB
Важно чтобы ты понял что твоя программа состоит из двух маршрутов:
1) Выполнить цикл и вывести результат
2) Ничего не делать и вывести ошибку
А ты пытался это ветвление сделать внутри цикла, который всего лишь часть первого варианта. Ну и запутался офк.
Окей, я понял.
Спасибо за ответы.
Узнал немного нового, да и ситуация с кодом прояснилась.
Все оказалось так банально (даже слишком), тогда как в начале ошибка представлялась мне непознаваемой я серьезно думал, что проблема в том, что я как-то неправильно понимаю как устроены суперглобальные переменные
> Я могу перезаписывать значение элементов этого массива?
Да, но так делать не надо.
> Могу проводить математические операции с элементами этого массива?
Да.
$_POST представляет данные, переданные из формы. Их можно менять, но это неправильно, так как ты при этом стираешь исходные данные. Это запутывает при чтении программы, так как читающий будет думать, что в $_POST хранятся исходные данные, а на самом деле там уже хранится что-то другое. Ты должен вместо этого сделать свои переменные и менять их.
Также, тебе стоит сделать названия переменных чуть короче (но чтобы они оставались понятными). Сейчас из-за длинных названий, да еще и с добавлением $_POST, код тяжеловато читать. Вот, что можно поменять:
$canPayOrNot -> $canPay
$amountOfCredit -> $amount
$interestOnLoan -> $interest
Я прочитал код, но явной ошибки не вижу. Я советую тебе поставить лимит не на 13 месяцев, а на 20 или 30, и сделать в начале цикла вывод всех переменных (сумма кредита на начало месяца, прирост суммы, и тд), чтобы было видно, как меняются суммы в процессе выплаты, и не выскочит ли там что-то подозрительное.
Как я помню, там будет общая выплата в районе 65000 и выплачивать это придется около 13 месяцев.
> время выплаты: 13 месяцев, сумма выплаты: 105000
Вообще это странно, так как школьник за 13 месяцев может выплатить максимум 13 × 5000 = 65 000.
IDE обычно дает такие возможности:
- навигация по коду (переход к классу или функции по клику)
- автодополнение
- проверка на ошибки
В принципе, в VS Code можно это реализовать, подключив и настроив расширения вроде phpactor language server, или какое-то аналогичное. Но придется повозиться.
Но вообще, пока ты пишешь учебные задачи на 50 строк, можно без этого обойтись.
Если ты хочешь научиться пользоваться PhpStorm, то можно скачать пробную версию, чтобы освоить ее.
Кстати, оказывается, в PhpStorm тоже не все встроено, например, для поддержки Симфони надо покупать какое-то левое расширение от какого-то левого чувака, а в комплекте это не идет, хотя PhpStorm платный, а Симфони самый популярный фреймворк. То есть, надо платить 2 раза.
Ну так PHP создателям шторма тоже не принадлежит. По факту имеем то, что дорогая платная IDE не поддерживает из коробки популярный фреймворк Symfony, и в этом плане не отличается особо от VS Code.
И вообще, концепция VS Code с поддержкой language server более правильная, чем проприетарные плагины для PhpStorm. Так как если ты что-то пишешь для VS Code, то этот же плагин подойдет и к другим редакторам.
Тему треда с нумерацией проебал. Вот это самое худшее
Короче если тред будете перекатывать не забывайте, что этот 134
Мудила гороховый, пикрелейтед поддержка симфони в вскод. Ебальник завали свой и пиздуй автора на коленях умолять, чтобы он раз за пять лет обновил свой высер.
То что авторам фреймворков дается возможность самим решать как будет выглядеть поддержка их плагина и возможность эту поддержку монетизировать это целенаправленная политика.
>>877943
Какая хуй разница "правильная" там конецепция или "не правильная" если никакой поддержки языка по сути нет. Микрософт НЕ создает и НЕ поддерживает языковой сервер для пхп. Возне энтузиастов можно поаплодировать и порадоваться. Но пользоваться этим можно разве что пару функций написать.
Как выглядит нормальная поддержка я уже показывал: https://youtrack.jetbrains.com/issues/WI?q=State:%20Resolved непрерывная нудная бесконечная работа с выяснением косяков, закрытием багов и выбором фич. Ничего подобного у микрософта для пхп даже близко нет. Вскод редактор чисто для микрософтовских языков: тайпскрипта и шарпа, и то с шарпом там большие проблемы до сих пор.
То что где-то есть кастомный плагин, который под нужным углом чешет тебе яйца это конечно заебись. Только вот в шторм добавляют реально важные для работы вещи. Из последнего например поддержка редис. ПОЛНАЯ. С кластерами, консолью, просмотром, сортировками и всем всем всем. Я знаю людей, которые за такое убили бы нахуй, только покажи кого.
> например поддержка редис.
Похоже на бессмысленную работу. Мне redis-cli вполне хватает для рабочих задач.
>redis-cli вполне хватает
Пфф, похоже что эти ебланы из редиса сделали бессмысленную работу по созданию этой консоли. Мне она для рабочих задач нахуй не нужна. Сру и в кеш и сру, хули туда вообще смареть.
Спасибо за ответ.
Я уже разобрался в коде.
Насчет названий возьму на заметку.
Менять сам массив $_POST больше не буду пытаться, если действительно не будет в этом крайней необходимости (я новичок, поэтому всех ситуаций не знаю).
Похоже ты тупой еблан. Редис не только как тупо кеш используется. У редиски есть PupSub и структуры данных
Here are some common use cases for data structures in Redis:
Key-Value Store:
Redis is often used as a key-value store. You can store simple key-value pairs, with keys and values being strings. This is the most basic data structure in Redis.
Strings:
Redis supports simple strings as values. You can use them for caching, session management, counters, and other use cases where you need to store a single value.
Lists:
Redis lists allow you to store ordered collections of strings. They are useful for implementing things like job queues, activity streams, and more. You can push and pop elements from both ends of the list.
Sets:
Sets in Redis are unordered collections of unique strings. You can perform set operations like union, intersection, and difference, making them suitable for tasks like tracking unique elements or implementing tags.
Sorted Sets:
Sorted sets are similar to sets, but each member has an associated score, allowing you to store and retrieve data in a sorted order. They are useful for leaderboards, ranking systems, and more.
Hashes:
Redis hashes are maps between fields and values, and they are useful for storing structured data. You can think of them as key-value stores within key-value stores, making them ideal for storing user profiles, configuration settings, and more.
Bitmaps:
Redis provides bit manipulation operations, allowing you to use Redis as a bitmap. You can represent and manipulate individual bits, which is useful for tasks like tracking user online status.
HyperLogLog:
HyperLogLog is a probabilistic data structure for estimating the cardinality of a set. It's used for counting distinct elements in a very memory-efficient way.
Geospatial Indexes:
Redis has data structures for geospatial indexing. You can store geospatial data (e.g., latitude and longitude) and perform operations like finding nearby points.
Pub/Sub:
Redis supports publish/subscribe mechanisms, allowing you to implement message queues and real-time messaging systems.
Lua Scripting:
You can use Redis with Lua scripting to create custom data structures and perform complex operations on your data.
Streams:
Redis Streams are log data structures that allow you to publish and consume messages. They are suitable for building event-driven systems and message brokering.
Bloom Filters:
You can implement Bloom filters in Redis, which are probabilistic data structures used for testing whether an element is a member of a set.
Caches:
Redis is often used as a caching layer to store frequently accessed data, such as database query results, to improve performance.
Distributed Locks:
Redis can be used to implement distributed locks, which are crucial for ensuring the coordination of processes in a distributed system.
Похоже ты тупой еблан. Редис не только как тупо кеш используется. У редиски есть PupSub и структуры данных
Here are some common use cases for data structures in Redis:
Key-Value Store:
Redis is often used as a key-value store. You can store simple key-value pairs, with keys and values being strings. This is the most basic data structure in Redis.
Strings:
Redis supports simple strings as values. You can use them for caching, session management, counters, and other use cases where you need to store a single value.
Lists:
Redis lists allow you to store ordered collections of strings. They are useful for implementing things like job queues, activity streams, and more. You can push and pop elements from both ends of the list.
Sets:
Sets in Redis are unordered collections of unique strings. You can perform set operations like union, intersection, and difference, making them suitable for tasks like tracking unique elements or implementing tags.
Sorted Sets:
Sorted sets are similar to sets, but each member has an associated score, allowing you to store and retrieve data in a sorted order. They are useful for leaderboards, ranking systems, and more.
Hashes:
Redis hashes are maps between fields and values, and they are useful for storing structured data. You can think of them as key-value stores within key-value stores, making them ideal for storing user profiles, configuration settings, and more.
Bitmaps:
Redis provides bit manipulation operations, allowing you to use Redis as a bitmap. You can represent and manipulate individual bits, which is useful for tasks like tracking user online status.
HyperLogLog:
HyperLogLog is a probabilistic data structure for estimating the cardinality of a set. It's used for counting distinct elements in a very memory-efficient way.
Geospatial Indexes:
Redis has data structures for geospatial indexing. You can store geospatial data (e.g., latitude and longitude) and perform operations like finding nearby points.
Pub/Sub:
Redis supports publish/subscribe mechanisms, allowing you to implement message queues and real-time messaging systems.
Lua Scripting:
You can use Redis with Lua scripting to create custom data structures and perform complex operations on your data.
Streams:
Redis Streams are log data structures that allow you to publish and consume messages. They are suitable for building event-driven systems and message brokering.
Bloom Filters:
You can implement Bloom filters in Redis, which are probabilistic data structures used for testing whether an element is a member of a set.
Caches:
Redis is often used as a caching layer to store frequently accessed data, such as database query results, to improve performance.
Distributed Locks:
Redis can be used to implement distributed locks, which are crucial for ensuring the coordination of processes in a distributed system.
У меня есть HTML форма
У кнопки отправки формы есть изображение через тег img, ссылка - из Интернета
Я не знаю как работают вирусы/уязвимости, читал только про XSS
Примитивно понимаю как работает браузер через HTTP запросы
Так вот...вопрос!
Когда я пишу строчку тег img и ссылка из Интернета, это означает, что браузер, который будет выводить мой HTML-код, будет отправлять запрос сайту, на котором размещается изображение, чтобы вставить в мою HTML страницу?
И если так, есть тут вероятность, что я таким образом открываю дорогу чему-то вредному? Почему я вообще так подумал?
Потому что насколько я понял, XSS-уязвимость работает так, что при открытии страницы отрабатывает JS-код и когда браузер отправляет GET запрос сайту, он ??также открывает эту страницу (страницу с изображением)??
Простите, пожалуйста, если у того, кто это прочитает и знает, случится фейспалм.
Буду очень благодарен, если мне укажут на мои ошибки и разъяснят ситуацию.
Норм все, заебись перекатил
>Когда я пишу строчку тег img и ссылка из Интернета, это означает, что браузер, который будет выводить мой HTML-код, будет отправлять запрос сайту, на котором размещается изображение
да
>и когда браузер отправляет GET запрос сайту, он ??также открывает эту страницу (страницу с изображением)??
нет, загружается только картинка
если у тебя там ссылка http://pisechka.jpg, то это никакие JS парсеры не запустит
чтобы браузер начал парсить JS, то нужен корректный MIME-type text/javascript, а у <img src=....jpg> MIME-type будет image/jpeg.
JS не будет выполняться.
Окей, спасибо за ответ!
XSS-уязвимость подробно описана тут: https://github.com/codedokode/pasta/blob/master/security/xss.md
> Когда я пишу строчку тег img и ссылка из Интернета, это означает, что браузер, который будет выводить мой HTML-код, будет отправлять запрос сайту, на котором размещается изображение, чтобы вставить в мою HTML страницу?
Да.
> И если так, есть тут вероятность, что я таким образом открываю дорогу чему-то вредному?
Да. Ну для начала, сторонний сайт может отказаться отдавать изображение или при загрузке твоего сайта подменить его на что-то неприличное или даже незаконное.
У вас там совсем днище что ли?
Вроде дворников, таксистов, сборщиков клубники и т.д., ну где обычно работают мигранты.
Если ты у себя показываешь изображение с другого сайта, то другой сайт может подменить изображение и вместо него будет показываться что-то другое, например, что-то неприличное. Тоже своего рода уязвимость, так как сторонний сайт влияет на то, как выглядит твой сайт. При чем тут выполняться?
Картинки никак не поправить, если проёбан тег, номер или текст в шапке номерного треда то описывай что надо поправить в посте кидай на этот пост репорт, в тексте репорта указывай что надо поправить шапку.
Всем добра.
Вообще, я хотел бы такой вариант, что прихожу на собес, разговариваем за жизнь и потом мне говорят - если согласны работать за 20к, то берём. А я такой - конечно, согласен!
Реально ли это? Или тоже душка всякой мутатой типа СОЛИДов, паттернов всяких, алгозадачек?
>Вообще, я хотел бы такой вариант, что прихожу на собес, разговариваем за жизнь и потом мне говорят - если согласны работать за 20к, то берём. А я такой - конечно, согласен!
Как же я хотел чтобы всё было с точностью наоборот. Даже хуй знает что им рассказывать за жизнь можно. Для меня это будет как ёбанное испытание.
@
Что вы делали до 25 лет?
@
Хмм.... Это... Пук. Учился
У меня в целом с программированием нет проблем, я специализированный ВУЗ закончил и хуй забил. Но сейчас нужны деньги и боле менее стабильная работка с грейдами.
>Посоветуйте какое-то направление где максимально можно хуй забить, чтобы после работки были силы параллельно учить что-то другое(рисование/игровой движок какой-то дрочить).
Надо уметь с ним работать на уровне запустить проект/посмотреть логи/прокинуть файл
Джуна вряд ли будут о паттернах спрашивать, если спрашивают - там пидоры
Алгозадачки дают только бездарные хуесосы в вк/яндексе/авито
От конторы зависит. В целом, если в сроки укладываешься, то можешь спокойно после смены заниматься своими делами. Но чаще сроки заведомо делают маленькими, чтобы поработал ещё.
В общем, надо искать хорошую крупную фирму, но туда и вкат жестче. Новичку скорей светит ИП или ОАО "Рога и копыта", где лютая переработка.
Чел, сейчас дойти до этапа собеса уже ебейшее достижение. А спрашивать там могут что угодно, хоть про два стула.
>Вообще, я хотел бы такой вариант
А работадатель хочет что ты и бэк и фронт с 25 лет опытом в 22 года, с двумя красными дипломами и такими софт скиллами что хрюша тебе отдалась в подсобке, и это всё за 20к, согласен на такой вариант?
А если у меня не встанет на хрюшу?
Я путаюсь в SOLID, а именно в принципе единственной ответсвенности (SRP).
Я приведу пример, а вы опишите, пожалуйста, как сделать правильно?
Нужно создать класс "База данных", который реализует CRUD операции. За таблицу БД будет приниматься файл.
Первый вопрос:
Что должно находиться в таком классе, если нужно следовать принципу SRP? CRUD операции (insert, delete, select, update)? Окей, а метод создания таблицы (файла) расписывать в том же классе или для него нужен отдельный класс?
Так же допустим файл содержит строки вида:
Ключ:значение
я хочу создать метод, который будет получать ключ этой строки. Этот метод нужен только для работы CRUD методов. Вопрос: если учитывать SRP и что в класс "База данных" входят CRUD методы, нужно ли выносить метод получения ключа в другой класс или нужно и этот метод писать в класс БД?
Так же хотел уточнить SRP для метода. Вот есть insert. Я понял, что он не правильно написан, так как этот метод принимает внутри себя открытый файл, а надо, чтобы файл открывался в самом методе и закрывался там же, так как иначе у нас может просто висеть открытый файл , кстати я не совсем понял зачем. Есть какие-то ограничения на открытые файлы?.
Мне сказали, что если я буду открывать файлы в самом методе, то это не нарушит SRP. А я не понимаю уже, почему не нарушит, ведь теперь у метода отвественность за открытие файл, за закрытие файла, и за поиск строки по ключу. Я запутался. Как правильно-то, если нужно учитывать SRP?
public function insert($file, $key, $value): void
{
$recordKey = '';
while (($line = fgets($file)) !== false) {
$recordKey = KeyValueDatabaseModel::getKey($line);
if ($recordKey == $key) {
break;
}
}
fseek($file, 0, SEEK_END);
if ($recordKey != $key) {
fwrite($file, "$key:$value\n");
} else {
echo "Ключ " . $key . " уже существует в файле</br>";
}
rewind($file);
}
Я путаюсь в SOLID, а именно в принципе единственной ответсвенности (SRP).
Я приведу пример, а вы опишите, пожалуйста, как сделать правильно?
Нужно создать класс "База данных", который реализует CRUD операции. За таблицу БД будет приниматься файл.
Первый вопрос:
Что должно находиться в таком классе, если нужно следовать принципу SRP? CRUD операции (insert, delete, select, update)? Окей, а метод создания таблицы (файла) расписывать в том же классе или для него нужен отдельный класс?
Так же допустим файл содержит строки вида:
Ключ:значение
я хочу создать метод, который будет получать ключ этой строки. Этот метод нужен только для работы CRUD методов. Вопрос: если учитывать SRP и что в класс "База данных" входят CRUD методы, нужно ли выносить метод получения ключа в другой класс или нужно и этот метод писать в класс БД?
Так же хотел уточнить SRP для метода. Вот есть insert. Я понял, что он не правильно написан, так как этот метод принимает внутри себя открытый файл, а надо, чтобы файл открывался в самом методе и закрывался там же, так как иначе у нас может просто висеть открытый файл , кстати я не совсем понял зачем. Есть какие-то ограничения на открытые файлы?.
Мне сказали, что если я буду открывать файлы в самом методе, то это не нарушит SRP. А я не понимаю уже, почему не нарушит, ведь теперь у метода отвественность за открытие файл, за закрытие файла, и за поиск строки по ключу. Я запутался. Как правильно-то, если нужно учитывать SRP?
public function insert($file, $key, $value): void
{
$recordKey = '';
while (($line = fgets($file)) !== false) {
$recordKey = KeyValueDatabaseModel::getKey($line);
if ($recordKey == $key) {
break;
}
}
fseek($file, 0, SEEK_END);
if ($recordKey != $key) {
fwrite($file, "$key:$value\n");
} else {
echo "Ключ " . $key . " уже существует в файле</br>";
}
rewind($file);
}
Попробуй мысленно встать на место работодателя. Ты разрабатываешь проект, который должен принести прибыль. Людей не хватает, задач много, и проект движется медленнее, чем хотелось бы. Надо нанять новых людей.
Кого бы ты нанял? В идеале, конечно, сеньора с бородой и опытом в 15 лет, который с первого взгляда все поймет и сядет писать идеальный код, заодно исправив архитектуру, тесты и процессы в команде. Но таких очень трудно найти, так как они все давно трудоустроены.
Тогда, может сеньора с опытом поменьше или миддла? Но эти просят по 200-300 к в месяц, а работы делают отнюдь не на 300к.
Получается, надо взять джуна. Джуну можно платить 50к, и 6 джунов за 50к, наверно, напишут больше кода, чем один миддл за 300к.
Кандидатов в джуны столько, что из них можно выстроить очередь от Москвы до СПб, но качество кандидатов очень разное. А тебе надо человека, который сразу придет и начнет исправлять баги, добавлять новые фичи. В идеале, из этой очереди отобрать самого умного. Как это сделать? Тут всего несколько вариантов:
- в идеале - смотреть на диплом, но хороших университетов с глубоким обучением и беспощадным отсевом у нас так мало, что их можно по пальцам пересчитать
- либо задавать вопросы по теории и взять того, кто лучше ответит
- либо предлагать порешать задачки с leetcode
- либо предложить тестовое задание и посмотреть на код
А как "разговор о жизни" поможет в этой ситуации, я не очень понимаю. Ты сотрудника, генерирующего прибыль, ищешь, или человека для разговоров по душам?
Ну скажи честно, до 25 был дураком, а потом поумнел и начал думать о карьере, будущем, поэтому пришел в вашу компанию.
В идеале хорошо бы, если бы ты умел собрать образы php-fpm, nginx и mysql и объединить их с помощью docker-compose, чтобы внутри, например, запустить задачу про студентов.
Если хочешь изучать Докер, обязательно изучи сначала работу в командной строке Линукса: команды для работы с файлами, перенаправления, конвейеры, права итд.
Так и не могу выбрать. Симфони вроде покруче, но на Лару больше вакансий.
Так бы и делал если бы жил не в Украине где единственный способ заработать денег и не уехать пид Бахмут - удалёнка.
Насчет принципа единой ответственности, мы его разбирали в прошлом треде, в оригинале этот принцип говорит о разделении приложения на крупные модули, а не про отдельные классы. Вот посты, почитай: >>2840503 Там есть ссылка на пост (на англ.) от автора этого принципа с объяснениями.
Но часто этот прицип распространяют и на более мелкие куски кода, говоря, что каждый класс должен иметь свою зону ответственности или функция должна решать одну задачу.
> Нужно создать класс "База данных", который реализует CRUD операции
> За таблицу БД будет приниматься файл.
Ты хочешь создать свою БД на файлах, которая хранит пары ключ-значение? Тогда я советую разбить код на 2 части:
- движок БД (Engine). Этот класс позволяет работать с любой таблицей (файлом), и делать операции вроде вставки данных, удаления данных, поиска данных и тд. Он универсальный, и не содержит каких-то действий для конкретных таблиц (например, в нем нет методов вроде "получить последние 10 записей в блоге")
- классы для работы с конкретными таблицами. Например, если у тебя есть блог, то ты можешь сделать класс для работы с таблицей постов и в нем методы вроде "добавить пост", "удалить пост", "получить 10 последних постов". Эти классы ипользуют движок для хранения данных. На каждую таблицу делается свой класс.
При таком разделении ты сможешь в будущем поменять тип БД, например, отказаться от своей БД на файлах и перейти на MySQL или Postgres. Для этого достаточно будет только заменить "движок".
Вот пример, как может выглядеть класс Engine:
class FileDbEngine
{
// в конструктор надо передать папку, в которой хранятся файлы
public function __construct(string $directory);
// создает пустую таблицу
public function createTable(string $table);
// вставляет либо заменяет значение по ключу
public function insertOrUpdate(string $table, string $key, string $value);
// удаляет значение по ключу
public function delete(string $table, string $key);
// удаляет всю таблицу
public function drop(string $table);
// ищет по ключу
public function findByKey(string $table, string $key): ?string;
// ищет по диапазону ключей от A до B с сортировкой
public function findByRange(string $table, string $from, string $to): array;
}
Заметь, что здесь нет никаких файлов - мы передаем лишь имя таблицы, а движок сам определяет, в каком файле она хранится. Благодаря такой абстракции мы можем в будущем вместо файлов использовать что-то другое для хранения данных, и нам не придется менять остальной код.
Что касается высокоуровненвых классов для работы с конкретными таблицами, то есть уже готовые паттерны, они описаны тут: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
> Что должно находиться в таком классе, если нужно следовать принципу SRP? CRUD операции (insert, delete, select, update)? Окей, а метод создания таблицы (файла) расписывать в том же классе или для него нужен отдельный класс?
В "движке" надо сделать и создание таблиц, и удаление, и CRUD методы, но они должны быть универсальные, и должны работать с любой таблицей. То есть в "движке" не должно быть методов вроде "добавить комментарий к посту". А только универсальный метод вроде "вставить запись в таблицу".
> я хочу создать метод, который будет получать ключ этой строки. Этот метод нужен только для работы CRUD методов. Вопрос: если учитывать SRP и что в класс "База данных" входят CRUD методы, нужно ли выносить метод получения ключа в другой класс или нужно и этот метод писать в класс БД?
Не нужно выносить. Можно сделать это приватным методом.
> Я понял, что он не правильно написан, так как этот метод принимает внутри себя открытый файл, а надо, чтобы файл открывался в самом методе и закрывался там же, так как иначе у нас может просто висеть открытый файл
Да, верно. Надо принимать назание таблицы, а не дескриптор файла.
> Мне сказали, что если я буду открывать файлы в самом методе, то это не нарушит SRP.
Верно.
> А я не понимаю уже, почему не нарушит, ведь теперь у метода отвественность за открытие файл, за закрытие файла, и за поиск строки по ключу. Я запутался. Как правильно-то, если нужно учитывать SRP?
У класса Engine ответственность - это взаимодействие с БД на файлах. То есть создание, удаление, изменение и поиск данных. Если для этого надо открывать и читать или записывать файлы, то это тоже часть ответственности класса Engine.
При этом, ты можешь вынести часть функций в приватные методы, не обязательно все писать в одном методе. Например, преобразование имени таблицы в имя файла можно вынести в приватный метод.
> вы мой текст поняли, или я плохо выражаюсь?
Ну где-то на 80% понятно.
Насчет принципа единой ответственности, мы его разбирали в прошлом треде, в оригинале этот принцип говорит о разделении приложения на крупные модули, а не про отдельные классы. Вот посты, почитай: >>2840503 Там есть ссылка на пост (на англ.) от автора этого принципа с объяснениями.
Но часто этот прицип распространяют и на более мелкие куски кода, говоря, что каждый класс должен иметь свою зону ответственности или функция должна решать одну задачу.
> Нужно создать класс "База данных", который реализует CRUD операции
> За таблицу БД будет приниматься файл.
Ты хочешь создать свою БД на файлах, которая хранит пары ключ-значение? Тогда я советую разбить код на 2 части:
- движок БД (Engine). Этот класс позволяет работать с любой таблицей (файлом), и делать операции вроде вставки данных, удаления данных, поиска данных и тд. Он универсальный, и не содержит каких-то действий для конкретных таблиц (например, в нем нет методов вроде "получить последние 10 записей в блоге")
- классы для работы с конкретными таблицами. Например, если у тебя есть блог, то ты можешь сделать класс для работы с таблицей постов и в нем методы вроде "добавить пост", "удалить пост", "получить 10 последних постов". Эти классы ипользуют движок для хранения данных. На каждую таблицу делается свой класс.
При таком разделении ты сможешь в будущем поменять тип БД, например, отказаться от своей БД на файлах и перейти на MySQL или Postgres. Для этого достаточно будет только заменить "движок".
Вот пример, как может выглядеть класс Engine:
class FileDbEngine
{
// в конструктор надо передать папку, в которой хранятся файлы
public function __construct(string $directory);
// создает пустую таблицу
public function createTable(string $table);
// вставляет либо заменяет значение по ключу
public function insertOrUpdate(string $table, string $key, string $value);
// удаляет значение по ключу
public function delete(string $table, string $key);
// удаляет всю таблицу
public function drop(string $table);
// ищет по ключу
public function findByKey(string $table, string $key): ?string;
// ищет по диапазону ключей от A до B с сортировкой
public function findByRange(string $table, string $from, string $to): array;
}
Заметь, что здесь нет никаких файлов - мы передаем лишь имя таблицы, а движок сам определяет, в каком файле она хранится. Благодаря такой абстракции мы можем в будущем вместо файлов использовать что-то другое для хранения данных, и нам не придется менять остальной код.
Что касается высокоуровненвых классов для работы с конкретными таблицами, то есть уже готовые паттерны, они описаны тут: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
> Что должно находиться в таком классе, если нужно следовать принципу SRP? CRUD операции (insert, delete, select, update)? Окей, а метод создания таблицы (файла) расписывать в том же классе или для него нужен отдельный класс?
В "движке" надо сделать и создание таблиц, и удаление, и CRUD методы, но они должны быть универсальные, и должны работать с любой таблицей. То есть в "движке" не должно быть методов вроде "добавить комментарий к посту". А только универсальный метод вроде "вставить запись в таблицу".
> я хочу создать метод, который будет получать ключ этой строки. Этот метод нужен только для работы CRUD методов. Вопрос: если учитывать SRP и что в класс "База данных" входят CRUD методы, нужно ли выносить метод получения ключа в другой класс или нужно и этот метод писать в класс БД?
Не нужно выносить. Можно сделать это приватным методом.
> Я понял, что он не правильно написан, так как этот метод принимает внутри себя открытый файл, а надо, чтобы файл открывался в самом методе и закрывался там же, так как иначе у нас может просто висеть открытый файл
Да, верно. Надо принимать назание таблицы, а не дескриптор файла.
> Мне сказали, что если я буду открывать файлы в самом методе, то это не нарушит SRP.
Верно.
> А я не понимаю уже, почему не нарушит, ведь теперь у метода отвественность за открытие файл, за закрытие файла, и за поиск строки по ключу. Я запутался. Как правильно-то, если нужно учитывать SRP?
У класса Engine ответственность - это взаимодействие с БД на файлах. То есть создание, удаление, изменение и поиск данных. Если для этого надо открывать и читать или записывать файлы, то это тоже часть ответственности класса Engine.
При этом, ты можешь вынести часть функций в приватные методы, не обязательно все писать в одном методе. Например, преобразование имени таблицы в имя файла можно вынести в приватный метод.
> вы мой текст поняли, или я плохо выражаюсь?
Ну где-то на 80% понятно.
А ты не путаешься. Все именно настолько плохо, в определении нет конкретных способов достижения SRP. Только мутные истории типа: "у класса должна быть только одна причина меняться" итд. Так что ты задаешь правильные вопросы. На которые кстати очень сложно ответить по существу, в основном получается что-то типа >>881533 "я примерно вот так чувствую".
Теперь по существу.
Существует специальная метрика, под названием LCOM4. Суть её примерно такова: твой класс состоит из методов и свойств, одни методы используют другие методы и свойства, и так или иначе через твой класс можно проложить n независимых маршрутов. Если маршрут только один - поздравляю, ты соблюдаешь SRP. Если больше, то класс надо делить. https://www.aivosto.com/project/help/pm-oo-cohesion.html#LCOM4
Вот пожалуй единственный способ конкретно без "мне кажется" или "а я щитаю это одна ответственность" проверить соответствие SRP.
Ну можешь не знать. Ходить с умным ебалом и рассказывать что это кароч там одна ответственность, делает одну вещь кароч, но оччень хорошо, да.
99% так и делает, солид это вообще сектанство для ебланов.
вордпресс это кал
Я понимаю, что ты бы хотел, чтобы были строгие критерии, которые можно проверить алгоритмом, но это не всегда возможно.
Вот возьмем, например, "код должен быть понятым, прямолинейным, легко читаться, не содержать хаков. Названия переменных и функций должны быть понятными". Как ты это формализуешь? Я точно знаю, что код бывает хорошо и плохо читаемым, так как видел примеры и того, и другого. Но как сделать формальные критерии?
То есть, код бывает разный, но как его качество проверить алгоритмом - непонятно. А вот человек может увидеть это качество.
Можно сделать такую метрику: даем образец кода N программистам и смотрим, за какое количество времени они разберутся и ответят на вопросы относительно кода (чем быстрее разберутся - тем лучше код).
Иногда пытаются вводить алгоритмические метрики, вроде "у каждого публичного метода должен быть комментарий", что приводит к такому коду:
// finds user by name
public function findUserByName()
(по моему, PhpStorm адаптирован под эти метрики и генерирует подобные мусорные комментарии)
Аналогично, ты можешь ввести метрику вроде "функция должна содержать не более N строк" или "алгоритмическая сложность функции должна быть меньше N", но это тоже глупо, так как некоторые функции лучше сделать чуть больше, чем разбивать на части, с точки зрения понятности.
Подобная проблема есть и в других отраслях. Вот, например, как определить алгоритмически, что у здания красивый фасад? Подходишь к дому 19 века, сразу видишь, красиво построено, или к современной многоэтажке и видишь, какое все уродливое. А алгоритмом это непонятно как формализовать. Разве что нейросеть обучить и ей проверять.
Магическое мышление маленького вкатусика, вкатуночка. Все такое сложное, такое неопределенное вокруг.
>ты бы хотел, чтобы были строгие критерии
Начнем с того что не строгий критерий это блядь не критерий.
>Как ты это формализуешь мой набор буллщита?
Никак. На то он и буллщит. Нормально делай - нормально будет. Лучше быть здоровым и богатым, чем бедным и больным. Классика переливания из пустого в порожнее.
>Но как сделать формальные критерии?
Начни с того что почитай что такое цикломатическая сложность.
>Можно сделать такую метрику
Это не метрика а исследование. И подобные исследования проводились. Есть, например, исследования делающие вывод что однобуквенные переменные ухудшают понимание кода.
>по моему, PhpStorm адаптирован под эти метрики и генерирует подобные мусорные комментарии
Опять магическое мышление. Пхпшторм вообще не генерирует текстовые комментарии. А сам факт постоянной генерации комментариев остался с тех времен когда в пхп типы можно было указать только в пхпдоке, а шторм пхпдоки понимает, подсвечивает нарушения и делает вывод типов на их основе. Типизацию содержимого массивов до сих пор только в пхпдоке и можно указать.
>так как некоторые функции лучше сделать чуть больше
Опять магическое мышление. Откуда следует этот вывод? Тебе захотелось? Ты бахнул пивка и так решил?
>Вот, например, как определить алгоритмически, что у здания красивый фасад? Подходишь к дому 19 века, сразу видишь, красиво построено
Так архитекторы тоже на угад делали, выдумывали на ходу что "лучше сделать чуть больше" и хуярили, если не упало, то заебись. Я правильно воспроизвел логику нихуя не понимающего в теме мимокрокодила для которого причины и следствия это магия?
Пчел, нахуй ты рассказываешь про то в чем не понимаешь нихуя? Пикрелейтед, вот почему. За прошедшие тысячелетия архитектура давно формализована и структурирована. "Современная" архитектура это как раз судорожные попытки из формализации выйти. Попытки понять может ли быть красиво за рамками золотого сечения.
Магическое мышление маленького вкатусика, вкатуночка. Все такое сложное, такое неопределенное вокруг.
>ты бы хотел, чтобы были строгие критерии
Начнем с того что не строгий критерий это блядь не критерий.
>Как ты это формализуешь мой набор буллщита?
Никак. На то он и буллщит. Нормально делай - нормально будет. Лучше быть здоровым и богатым, чем бедным и больным. Классика переливания из пустого в порожнее.
>Но как сделать формальные критерии?
Начни с того что почитай что такое цикломатическая сложность.
>Можно сделать такую метрику
Это не метрика а исследование. И подобные исследования проводились. Есть, например, исследования делающие вывод что однобуквенные переменные ухудшают понимание кода.
>по моему, PhpStorm адаптирован под эти метрики и генерирует подобные мусорные комментарии
Опять магическое мышление. Пхпшторм вообще не генерирует текстовые комментарии. А сам факт постоянной генерации комментариев остался с тех времен когда в пхп типы можно было указать только в пхпдоке, а шторм пхпдоки понимает, подсвечивает нарушения и делает вывод типов на их основе. Типизацию содержимого массивов до сих пор только в пхпдоке и можно указать.
>так как некоторые функции лучше сделать чуть больше
Опять магическое мышление. Откуда следует этот вывод? Тебе захотелось? Ты бахнул пивка и так решил?
>Вот, например, как определить алгоритмически, что у здания красивый фасад? Подходишь к дому 19 века, сразу видишь, красиво построено
Так архитекторы тоже на угад делали, выдумывали на ходу что "лучше сделать чуть больше" и хуярили, если не упало, то заебись. Я правильно воспроизвел логику нихуя не понимающего в теме мимокрокодила для которого причины и следствия это магия?
Пчел, нахуй ты рассказываешь про то в чем не понимаешь нихуя? Пикрелейтед, вот почему. За прошедшие тысячелетия архитектура давно формализована и структурирована. "Современная" архитектура это как раз судорожные попытки из формализации выйти. Попытки понять может ли быть красиво за рамками золотого сечения.
Всегда проигрывал с этой хуиты про архитектуру.
Смотрим например на линии на втором пике и видим что на самом деле они не касаются ни че го. На левой они мимо башенок летят, на правой вообще от балды сквозь купола.
Ебать ты гений.
А то что толщина этих линий в реальности была бы около метра тебя не смущает?
Эти купола из чего-то сделаны, да еще и стоять должны, не падать. Речь о том какого размера купол должен быть ОТНОСИТЕЛЬНО здания, чтобы ты не смотрел на него и не думал: ну и залупа карликовая/гипертрофированная. У архитектора ответ на этот вопрос есть, причем это литерали база. Просто водолей из поста выше этого не знает.
Вот именно, что раз линии надо делать по метру то это натягивание совы на глобус, а линии нарисованы от балды. 3.153 или 3.567 какая разница да?
Всегда проигрывал с дебилов, которые что-то пытаются мерить по гвонокартинке разрешением три пикселя, нарисованной хуй пойми кем и каким-то полоскам нахуяренным сверху в пейнте.
Так ты сам привел эти картинки как аргумент. впрочем по другому с этими картинками и не бывает.
Используют ли библиотеки для того, чтобы пропихнуть вредоносный код? Есть ли шанс подключить библиотеку и сделать свой код уязвимым? Также есть ли шанс, что подключив библиотеку, и поставив ее в автоматическое обновление (composer вроде бы так делает, могу ошибаться), код библиотеки может переписаться кем-то и вместо безопасной библиотеки будет библиотека с вредным кодом? И если есть, то каковы эти шансы?
Добро пожаловать в опен сорс камунити. Слева попущенцы сидят по пол года и ждут когда автор либы исправит критическую багу. Справа сидят дегенераты и по пол года ждут, когда новый релиз можно считать достаточно безопасным.
Тут у нас все на ДОВЕРИИ и ДОБРОЙ ВОЛЕ.
В клозет сорсе то не подкладывают зонды и закладки, мда кек.
Главное, чтобы файлы в сердечки не превратили
Берешь и без задней мысли добавляешь.
Гит поддерживает глобальный .gitignore
Это значит, ты можешь один раз в одном файле вне репозиториев указать все специфичные для тебя файлы, показать этот файл гиту — и не срать ими в .gitignore отдельных проектов.
Мак/линукс:
git config --global core.excludesfile ~/.gitignore
Винда:
git config --global core.excludesfile "%USERPROFILE%\.gitignore"
и т.д.
В крупных компаниях не принято заносить сотруднико-специфичные файлы, к которым относятся конфиги IDE, в общий .gitignore, потому что я на емакс работаю, зачем мне твоя .idea?
>В крупных компаниях не принято заносить сотруднико-специфичные файлы, к которым относятся конфиги IDE, в общий .gitignore, потому что я на емакс работаю, зачем мне твоя .idea?
Чел, в крупной компании принят стандарт что все пишем на PHPStorm, если ты пишешь на другом - твои проблемы
У разных людей могут быть разные настройки IDE, соответственно незачем их вываливать в репозиторий.
Как-то лихо ты перескочил от "добавить одну строчку в гитигнор" к "вываливать настройки IDE в репозиторий".
Спокуху оформи. Если есть возможность защититься от пуша левых файлов в проект каким-то забывчивым додстером, совершенно поебать на пару лишних строчек в гитигноре. Можно хоть все актуальные IDE туда захуярить, похуй абсолютно.
composer require laravel/ui
php artisan ui bootstrap --auth
что дало возможность регистрироваться и логиниться через браузер.
>Можете объяснить на пальцах
Одеваем штаны на лямках, берем муриканскую азбуку и едем учиться читать в наш пхп детсад для альтернативно одаренных детей.
Первая остановочка https://github.com/laravel/ui . Заходим, читаем:
>This legacy package is a very simple authentication scaffolding built
>you should consider using Laravel Breeze for new projects
Поняли, приняли. Следующая остановочка https://laravel.com/docs/10.x/starter-kits#laravel-breeze . Заходим, читаем:
>Laravel Breeze is a minimal, simple implementation of all of Laravel's authentication features
Ага, фичи значит есть. Следующая остановочка: https://laravel.com/docs/10.x/authentication#laravels-api-authentication-services . Заходим, читаем:
>Laravel provides two optional packages to assist you in managing API tokens and authenticating requests made with API tokens: Passport and Sanctum.
>Passport. Passport is an OAuth2 authentication provider, offering a variety of OAuth2
>Sanctum. In response to the complexity of OAuth2 and developer confusion, we set out to build a simpler, more streamlined authentication package
Водитель волшебного автобуса уже минут пять сигналит, а значит эта остановочка конечная. Бери свои шмотки и выкатывайся нахуй, пока он тебя пинками по почкам не выпиздил.
Нужно и PHP код написать, и HTML сверстать, и валидацию данных сделать, и защиту от уязвимостей прописать, и, короче, много чего. Глаза разбегаются, не понимаю за что браться.
Может анон порекомендовать какие-нибудь советы как организовать себя?
Поставь ларавель по любому гайду с первой страницы гугла.
В описании к задаче много комментариев со ссылками.
Но начать можешь с вывода таблицы. То есть сделай таблицу в базе, руками туда вставь N человек и сделай чтобы при заходе на сайт выводился список этих людей.
Не до конца понимаю когда какой модификатор доступа ставить.
Ты забыл, что строка в PHP - это последовательность байт, а строки с кириллицей - это мультибайтные строки и такая адресация не сработает. Можно переписать через mb_substr():
$eng = 'help';
$rus = 'помогите';
echo mb_substr($eng, 1, 1) . ' ' . mb_substr($rus, 1, 1);
Зандстра пишет, что предпочтение следует отдавать конфиденциальности, сначала делайте свои свойства закрытыми или защищенными, а потом по мере необходимости ослабляйте ограничения.
Блин, вот проверял этот способ и он не работал, а сейчас скопировал твой код и работает. Наверное я где то опечатался, хз, спасибо в любом случае. А то кодировки менял минут 40 везде и всё никак
Вот как это всё оформляется в РНР? Делать три отдельных проекта? Или один проект с 3 папками под каждый сервис?
Почему тогда в платной идее есть поддержка Спринга из коробки, а бесплатный плагин для коммьюнити от разработчиков "добрые" жидбрейнсы забанили?
Так ли необходимо ставить HStorm во время обучения? Некоторые менторы вроде Альберта Степанцева заставляют его устанавливать. Но вот мне кажется, что VS Code ни чем не хуже для РНР.
Если хочешь быть профессионалом, то ставишь шторм. Других вариантов нет.
В платной идее хотя бы есть поддержка фреймворка, а шторме - фиг с маслом. Надо докупать плагин для фреймворков по отдельному ценнику.
Что от меня хочет ОП, когда пишет то, что описано на пике?
Раньше работал сис. админом и делал дампы базы данных в качестве бэкапов. Там по сути просто команды SQL, которые позволяют восстановить базу данных.
Ты можешь сохранить содержимое всей БД (структуру таблиц, полей и данные в них) в файл. Это называется дамп. А затем любой может скачать твой дамп и загрузить в свою базу.
Обычно дамп сохраняется в виде текстового файла с SQL-командами CREATE TABLE и INSERT. Вот пример дампа от другого анона: https://github.com/sergnik1995/students-list/blob/master/students.sql
Чтобы сделать дамп в mysql, используется команда mysqldump. есть также другие варианты, если ты, например, используешь какую-то графическую программу для работы с БД, то можно через нее. Если у тебя постгрес или что-то еще, то погугли сам.
Ставь максимально закрытый. То есть, private, если только у тебя нет причины поставить protected (если тебе надо в наследниках доступ) или public.
Есть 2 подхода: мнонорепозиторий (все в одном большом репозитории, при деплое на сервер выгружается только одна папка из него) и делать на каждый проект свой репозиторий. Плюс монорепозитория в том, что ты можешь одним коммитом поменять код в нескольких сервисах сразу и у тебя нет ситуации, когда один сервис еще использует старую версию кода, а второй новую.
Яндекс, по-моему, использует монорепозиторий, и по-моему, он называется "Аркадия". Вот хорошие статьи по теме:
https://habr.com/en/companies/yandex/articles/482926/ (здесь Яндекс рассказывает о размерах своего репозитория)
https://habr.com/en/companies/yandex/articles/469021/
Эти типа мне надо прочитать, что есть, забить в переменную и заново её записать? Не, там запишется новое значение.
Записать заранее в базу все айди и потом обновлять остальное по запросу? Мб ссылку на гайд дайте.
Так ли необходимо ставить PStorm во время обучения? Некоторые менторы вроде Альберта Степанцева заставляют его устанавливать. Но вот мне кажется, что VS Code ни чем не хуже для РНР.
На работе могут сказать мол работаем только в шторме, придётся осваивать. Почему не сделать это сразу? Всего лишь разобраться в программе, это ж не фотошоп какой-нибудь.
Полуграмотные пыхокорзинки, что с них взять?
Это местный мем или почему этот вопрос задают уже несколько раз и на него несколько раз отвечают?
Такой-то пеар.
У меня есть класс.
В нем есть:
Метод1
Метод1, который помогает методу1
Метод2, который помогает методу1
Метод3, который помогает методу1
Скорее всего, я буду вызывать только метод1 из внешнего кода.
Нормально ли, что в классе существуют методы, которые не вызываются из внешнего кода, а помогают одному методу?
Эти методы у меня появились, чтобы не плодить огромную функцию, а разделить их на маленькие.
У класса есть публичный интефейс, с которым взаимодействует клиент. И есть приватные методы, содержимое которых снаружи невидно и никого ебать не должно.
Спрашивают сколько должна прибухнуть мамаша на сносях, чтобы у неё родился мелкобуквенный хуесос.
Работает, значит нормально.
Он не до вопроса доебался а до того что ты с маленькой буквы пишешь, такое на доске не одобряется.
Т.е.
function check (One $object, Two $object)
One и Two - это классы.
Как-нибудь можно это реализовать?
Я попробовал, получилось только условие поставить, что объект должен быть определенного класса, а два не получается, да еще так, чтобы можно было обоих называть именем object внутри метода, но приписывать название класса.
Мне нужно не просто отдавать функции объекты разных классов.
Я хочу, чтобы я написал в параметрах функции (One $object, Two object), а потом внутри функции, например, сделал это:
$result = One $object->number + Two $object->number; (т.е. сложил то, что лежит в их полях number)
return $result;
Знаю, что это неправильный синтаксис, но мб это можно как-то реализовать?
Это не сильно принципиально, но мне немного надоело называть каждый отдельный объект по-разному.
Попахивает какой-то шизофренией.
Что конкретно тебе надо?
Тебе надо чтобы параметр функции мог быть двух типов? Это легко https://3v4l.org/BsaY7
Или тебе надо чтобы был какой-то один супертип? Это тоже легко https://3v4l.org/UbAHs
Или тебе надо чтобы можно было передать много параметров? И это легко https://3v4l.org/i0hYC
Вот так, напрмер, я бы реализовал функцию по суммрованию всей хуйни https://3v4l.org/8mMt3
Красиво.
Так че те надо вообще?
У меня параметры функции - три объекта.
Каждый объект принадлежит разному классу.
Я хочу вместо имен $objectClassNumber1, $objectClassNumber2, $objectClassNumber3
писать
ClassNumber1 $object, ClassNumber2 $object, ClassNumber3 $object.
Чтобы копилятор понимал, что под одним именем $object находятся 3 разных объекта, а различал он их с помощью названия класса, которое стоит рядом. Но, возможно, такое не существует в языке. И можно только в параметрах функции указывать, что объект, который передается функции, должен быть экземпляром указанного класса.
Значит про шизофрению мне не показалось.
Ок. Допустим ты так даже можно сделать. Каким хуем ты будешь отличать у которого объекта ты вызываешь метод? Как ты вообще себе представляешь работу с разными значениями по одному названию?
Окей.
Я увидел, что при создании функции можно написать так:
function Check (One $object) (т.е. чтобы функция принимала экземпляры только этого класса)
И подумал, что это более читаемо, чем $OneClassObject.
А затем возникла мысль, нельзя ли в коде функции при любом упоминании объекта этого класса придерживаться такой записи.
Т.е. чтобы я не писал $OneClassObject, а One $object
Ну так передавай туда массив, какие проблемы. Я же показал как: https://3v4l.org/aIYLn и переменная одна и типизация проверяется.
А что ты умеешь, чтобы стать падаваном?
Юнилингов так-то десять лет дрочили перед этим. Да еще к тому же джедаи сами выбирали себе по ученику и только если хотели. Между юнлингами проходили целые турниры, чтобы впечатлить будущего мастера.
А тех кого не выбрали назначали в "корпус обслуживания". То есть "очки в храме драить" и "бант пасти".
лан , тогда на заводе останусь, придется дальше спать в коморке
Короче насоздавал айдишек вручную, обновляю нужные параметры через гет, where нужный айди. Не забывайте переводить переменную в нужный тип.
в пыхо треде можно бесконечно Риситаса постить
Каша в браваёзере протухла
перелогиниться не забудь
Да. Но вспомогательные методы надо сделать приватными, чтобы было понятно, что они вспомогательные.
Гоняют по теории: PHP, ООП, SQL, БД, JS, HTML, CSS, алгоритмы итд. Могут дать простую задачку. Вопросы проще всего найти в инете где-нибудь.
Я плохо понял вопрос.
function check (One $object1, Two $object2)
Чем тебе такой вариант не годится?
Если ты хочешь, чтобы можно было передать либо объект класса One, либо Two, то можно написать так:
function check(One|Two $object)
А если надо передать 2 объекта, то можно так:
function check(One|Two $o1, One|Two $o2)
Вертикальная черта это union type, они появились в PHP 8.0.
У каждого класса методы.
Причем только методы.
Свойств нет.
Объекты этих классов постоянно используют методы друг друга.
Потому что логически каждый занимается своим:
Методы одного класса контактируют с БД, методы другого класса - с cookie и т.д.
Но мне кажется, что у меня начинается путаница в коде. Мои функции постоянно берут в качестве аргументов объекты, чтобы использовать присущие этим объектам методы.
Это считается нормальным в программировании?
У меня 0 опыт в ООП. Примитивно я понимаю что такое объект, класс и метод. А также их разновидности. Но когда дело доходит до проектирования класса, я вообще не понимаю что мне писать. Те классы, которые сейчас написаны, создаются по наваждению больше, чем по пониманию. У меня складывается впечатление, что я хаотично впихиваю методы и свойства в классы.
Например, я создал класс, у которого есть свойство - перечень символов для генерации пароля, есть метод, который перемешивает массив, а потом из перемешанного забирает произвольное количество символов. Создал метод внутри этого класса, который генерирует соль и хеш. Создал метод, который обращается к методу класса, который работает с БД, чтобы он положил соль и хеш в БД.
Еще там вроде бы есть метод, который обращается к классу с cookie, а именно к методу в этом классе, который создает куки и записывает туда пароль.
Короче, у меня теперь полная путаница в коде. И все из-за того, что объект одного класса лезет в методы другого объекта. Я не понимаю на что мне опираться, чтобы грамотно проектировать классы.
не нормально.
1) в методы надо передавать данные
2) зависимости в конструктор
3) конструктор лучше, чтобы зависел от интерфейсов (но не обязательно)
4) инстансы зависимостей создавать в одном месте (Service Locator, DI, простое проталкивание через все приложение)
5) должен быть только один скоуп, где все зависимости прокидываются в объект, который запускает всю логику приложения. Так называемый composition root
6) нужно иметь хороший пример архитектуры, а не с потолка придумывать свои трактовки
Все потому что ты не понимаешь что классы это всего лишь ДЕТАЛЬ реализации. Это просто способ писать код. >>891866 вот это все к проектированию никакого отношения не имеет, это частности.
Посмотри со стороны. У тебя есть какой-то функционал, какой-то сервис. Делает какую-то конкретную вещь, ему для этого требуются какие-то данные, и он, возможно, возвращает какие-то данные. Причем здесь на данном этапе ООП? Да ни причем, ты формируешь некое универсальное знание о сервисе, которое потом можно записать так как мы хотим. Именно это знание диктует нам как будут выглядеть классы в ООП.
Вот тебе пример. Нам нужен сервис для работы с куками. Что он делает? Преобразует данные в формат кук и обратно, дергает куки из массива $_COOKIES на вход и на выход. Записываем это в виде классов https://3v4l.org/D2RQi . Сколько там получится у тебя классов значения не имеет, ты можешь, например, вместо класса Coookie использовать массив, а энкодинг вынести в какой-нибудь CookieEncoder.
Важно что сигнатура твоего сервиса по работе с куками соответствует твоему проекту. Тебя интересует чтобы была публично доступная функция для установки и получения куки, ВСЕ. Этим ты пользуешься, это ты тестируешь итд. Что там внутри - абсолютно поебать. Ровно до тех пор пока это не доступно снаружи, разумеется. А вот как добиться недоступности снаружи уже следует их особенностей пхпшного ООП и тех самых частностей >>891866 .
>Это частности
>Кукисы вставляются вот сюда. Это проектирование
Другалек. Куда вставлются кукисы - это частности. Это джуну поручают, вставлять кукисы. А правильная композиция зависимостей, позволяющая расширять и тестировать код, это архитектура. Она одинаковая для всех языков и платформ.
Ну в общем-то да. Согласен. Я и говорю: важно понять что "композиция зависимостей" != "композиция классов".
Говорят мол чат на php выносит оперативку и прочее, а в чем разница если бы это был сайт например? Так же пишут что php дерит ебические нагрузки.
В чем принципиальная разница, если мы аяксом отправляем короткое сообщение и вторым запросом запрашиваем новые сообщения из чата? А сайт - ебейший бекенд + дохуя запросов к бд
>форума/чата
Так форума или чата? Форум это обычный сайт. Да и чат вполне может быть обычным сайтом, сто проц видел "чат с поддержкой" в разных интернет магазах.
>Говорят мол чат на php выносит оперативку и прочее
Отличие обычных веб запросов от подключения через сокет в том что обычный веб запрос поле отработки всю использованную память освобождает. А пока кто-то в чате подключен через сокет процесс будет висеть на сервере и память на него будет выделена.
>Так же пишут что php дерит ебические нагрузки.
Пхп ДОСТАТОЧНО быстрый. У тебя узким местом всегда будет получение данных. Даже из кеша данные получаться будут дольше чем отрабатывает весь пхп скрипт по их получению.
>В чем принципиальная разница, если мы аяксом отправляем короткое сообщение и вторым запросом запрашиваем новые сообщения из чата?
В периодичности этих аякс запросов. Сколько раз в секунду какое количество людей будет долбить твой бекэнд?
Я не понимаю хули вы прицепились к этим ебучим чатам? Вы дохуя чатов в 2к23 видите или что? Какие нахуй чаты вообще блядь?
Везде чаты. У пыхеров обычно купленые и интегрированные у третьих лиц, но иногда и в пыхе надо через вебсокет (или SSE) обновлять данные на фронте. Сравни ситуации
1) Событие на беке происходит раз в час. У тебя миллион клиентов (приложения для мобилок) дудусят твой код каждую секунду, на предмет было ли событие. Имеем милллион запросов в сек
2) Ты при событии на беке, ты раз в час рассылаешь сообщение клиентам. Имеем милллион запросов в час
Конечно ты можешь сказать что нахуй не нужно, ведь ты будешь пушами отправлять сообщения на мобилки. Т.е опять же через третье лицо. Но это просто пример описывающий кейс, когда одного рест апи недостаточно
>Везде чаты.
Где блядь везде? Если ты про >>892305
>"чат с поддержкой" в разных интернет магазах
То эта залупа просто ставится готовая, её никто не пишет и никаких сокетов там нет. Этой парашей пользуется один инвалид в год.
>Событие на беке происходит раз в час. У тебя миллион клиентов (приложения для мобилок) дудусят твой код каждую секунду
>Ты при событии на беке, ты раз в час рассылаешь сообщение клиентам
Круто. Сокеты то тут причем? Ты же не держишь миллион открытых коннектов постоянно, чтобы раз в час им что-то слать.
>описывающий кейс, когда одного рест апи недостаточно
Ну бывает такое иногда. ЧАТЫ блядь тут откуда сука? Это что-то из разряда "пишем свой фейсбук". Нахуй кому нужны новые чаты когда есть телега и слак. Ты блядь с обычным круд рестом разберись, какие нахуй сокеты хуекеты.
Ну то есть ты согласен, что пыха это для создания сайтов шаурмичных, а когда нужно создать SaS типо pusher.com то пыха пролетает, как говно над пропастью?
[
{
"type": 1,
"nsfw": 0,
"size": 272,
"width": 1200,
"height": 675,
"displayname": "image.jpg",
"fullname": "16981660903840.jpg",
"name": "16981660903840.jpg",
"path": "/b/src/294854520/16981660903840.jpg",
"md5": "4580a11b4056c5fd431d43fc8a299250"
}
]
Что я не так делаю? Картинка через апи не цепляется
Я знаю только основы языка и это мой первый язык программирования.
Чем так не устраивает php людей, которые о нем нелестно отзываются?
Почему постоянно говорят о смерти php?
Если самому запустить из консоли: docker-compose up, то всё прекрасно работает.
Вывод: хваленое творение жидбрейнсов опять обосралось.
это новый композ встраивается в докер. У тебя либо композ не установлен, либо старая стандалон версия
https://docs.docker.com/compose/install/linux/
Общий принцип в том, что у каждого класса должна быть какая-то одна зона ответственности. Один класс отвечает за хеширование паролей, другой за работу с БД, третий за отправку email.
Еще часто классы делят на сущности и сервисы. Сущности - это объекты со свойствами, например, "товар" со свойствами название, цена, описание и тд. А сервис - это объект, который не хранит данные, а выполняет различные операции, например: добавление товара в БД, удаление товара, регистрация пользователя, отправка email.
И, наконец, классы часто делят на "слои". Вот, например, регистрация. У тебя может быть класс для регистрации и логина. Он вызывает классы для работы с паролями (хеширование), для работы с email, для работы с таблицей пользователей. То есть, есть высокоуровневый класс, делающий какую-то сложную операцию, и низкоуровневые классы для более мелких задач. И высокоуровневый класс сам не лезет в базу, а вызывает методы класса работы с таблицей пользователей.
Я тебе могу посоветовать для начала почитать статьи, в них рассмотрены типичные ситуации, в том числе работа с БД, и как их решать с помощью ООП:
https://github.com/codedokode/pasta/blob/master/arch/mvc.md
https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
https://github.com/codedokode/pasta/blob/master/arch/di.md
> , у которого есть свойство - перечень символов для генерации пароля,
Скорее всего этот перечень никогда не меняется и его лучше сделать константой.
> Создал метод, который обращается к методу класса, который работает с БД, чтобы он положил соль и хеш в БД.
Вот до этого момента было все хорошо. Если твой класс отвечает за работу с паролями (генерация, хеширование, проверка), то он не должен работать с БД вообще. Так что убирай это.
> Еще там вроде бы есть метод, который обращается к классу с cookie, а именно к методу в этом классе, который создает куки и записывает туда пароль.
Это тоже убирай.
> Говорят мол чат на php выносит оперативку
Говорят, что кур доят. Думаю, что это зависит от того, как он написан.
Например, я встречал истории, что в приложении не на PHP, а на Ruby или Node.JS утекала память и орангутанги, которые не осилили профайлинг памяти, просто поставили в крон задачу перезапускать приложение раз в N часов. А вот для PHP, кстати, есть профайлер памяти, я им пользовался, единственный минус, сам профайлер и обработка его данных требует несколько гигабайт памяти, так что это не для бюджетных ноутов.
> А пока кто-то в чате подключен через сокет процесс будет висеть на сервере и память на него будет выделена.
Веб-сокеты работают по-другому. Там один (1) PHP процесс на любое количество веб-сокетов.
> Пхп ДОСТАТОЧНО быстрый. У тебя узким местом всегда будет получение данных
Вообще не всегда. Знаю случаи, когда выполнение PHP кода, шаблонов занимает больше времени просто потому что они сложные, там много условий, циклов и тд.
> Круто. Сокеты то тут причем? Ты же не держишь миллион открытых коннектов постоянно, чтобы раз в час им что-то слать.
Вообще такое иногда бывает, но не для миллиона пользователей. Представь например CRM (система для приема заказов, заявок). Когда один менеджер берет заявку в работу, у всех других она должна поменять цвет. Это можно делать через дерганье AJAX раз в секунду, но обычно делают через сокеты: каждая страница поддерживает постоянное соединение и по нему приходят обновления информации в реальном времени.
То же самое бывает в приложениях типа инстаграма: когда кто-то лайкает фото, надо, чтобы у всех пользователей приложения цвеличилась циферка.
Но в CRM конечно не миллионы пользователей. А если ты пишешь соцсеть на миллион человек, то ты напишешь сокет-сервер на Rust или Go.
Спасибо, анон. Я все это попробую пережевать и прочитаю то, что ты оставил ссылками.
>Вот до этого момента было все хорошо. Если твой класс отвечает за работу с паролями (генерация, хеширование, проверка), то он не должен работать с БД вообще. Так что убирай это
Ну, он не совсем работает с БД.
Он берет объект класса, который работает с БД.
Вызывает его метод, который кладет соленый хеш в БД.
Т.е. обращается к БД не класс, создающий и хеширующий пароли, а класс, работающий с БД.
Но, конечно, у меня все очень плохо с архитектурой.
Я прочитал статью про архитектуру программ, про паттерны и принципы проектирования, узнал про зависимости, про ослабление зависимости. Про декомпозицию.
Теория теорией, но когда я подхожу к практической части - собственно спроектировать свою программу, я не могу даже ответить на вопрос, а какие у меня основные модули, на которые я должен делить программу.
Я сейчас выполняю задание со списком студентов.
И единственное до чего дошел мой мозг - вернуться к MVC.
Я не отрицаю, что это хороший паттерн проектирования.
Просто и его я понимаю на поверхностном уровне.
ОП, или тот, кто составлял советы по задаче со студентами, пишет "в качестве модели можно создать такие-то классы" и я просто примитивно полагаюсь на это. У меня нет четкого понимания почему именно эти классы. Я просто беру как пишет ОП и делаю это (насколько позволяет опыт). Проблема в том, что это не из-за понимания (что я бы сам, своим умом дошел до мысли, что нужно создать такие классы), а из-за того, что у меня нет выбора. У меня 0 идей, почему именно эти классы должны представлять модель и если не они, то какие именно.
Извиняюсь за такую простыню, если ты будешь ее читать.
Спасибо, анон. Я все это попробую пережевать и прочитаю то, что ты оставил ссылками.
>Вот до этого момента было все хорошо. Если твой класс отвечает за работу с паролями (генерация, хеширование, проверка), то он не должен работать с БД вообще. Так что убирай это
Ну, он не совсем работает с БД.
Он берет объект класса, который работает с БД.
Вызывает его метод, который кладет соленый хеш в БД.
Т.е. обращается к БД не класс, создающий и хеширующий пароли, а класс, работающий с БД.
Но, конечно, у меня все очень плохо с архитектурой.
Я прочитал статью про архитектуру программ, про паттерны и принципы проектирования, узнал про зависимости, про ослабление зависимости. Про декомпозицию.
Теория теорией, но когда я подхожу к практической части - собственно спроектировать свою программу, я не могу даже ответить на вопрос, а какие у меня основные модули, на которые я должен делить программу.
Я сейчас выполняю задание со списком студентов.
И единственное до чего дошел мой мозг - вернуться к MVC.
Я не отрицаю, что это хороший паттерн проектирования.
Просто и его я понимаю на поверхностном уровне.
ОП, или тот, кто составлял советы по задаче со студентами, пишет "в качестве модели можно создать такие-то классы" и я просто примитивно полагаюсь на это. У меня нет четкого понимания почему именно эти классы. Я просто беру как пишет ОП и делаю это (насколько позволяет опыт). Проблема в том, что это не из-за понимания (что я бы сам, своим умом дошел до мысли, что нужно создать такие классы), а из-за того, что у меня нет выбора. У меня 0 идей, почему именно эти классы должны представлять модель и если не они, то какие именно.
Извиняюсь за такую простыню, если ты будешь ее читать.
Ну и да, я не имею ничего против того, чтобы учиться через код более профессиональных людей.Но было бы лучше, если бы я, видя, что делает человек, понимал, почему именно я должен это делать. Почему так, а не иначе.
>Веб-сокеты работают по-другому. Там один (1) PHP процесс на любое количество веб-сокетов.
На любое количество сокетов, подключенных к этому процессу. Только вот не всем нужен один и тот же процесс, один и тот же чат, одни и те же данные.
Даже если ты каким-то образом заставишь один процесс обрабатывать весь миллион пользователей он будет висеть в памяти и расти пока не упадет к хуям.
>Вообще не всегда. Знаю случаи, когда можно из воздуха накрутить бесконечный цикл, который никогда не выполнится
Сделать хуйню можно на любом языке. Речь о том что минимальное время получения данных из базы 12мс. Это запрос константы типа SELECT 1;. В хайлоаде "быстрыми" считаются запросы в пределах 100мс. А рабочий цикл огромного фреймворка симфони с генерацией шаблона и тысячами классов под капотом примерно 60мс. Скорость пхп ДОСТАТОЧНА для того чтобы не быть бутылочным горлышком в типичной работе сайта.
>Представь например CRM
>Это можно делать через дерганье AJAX раз в секунду
>но обычно делают через сокеты
Ага. Прямо между црмными крудами и оперднями вставляют всю эту асинхронную сокет дрисню. Что за маняфантазии? Именно запросы в цикле и хуярят, если вообще хуярят. Никому это в реалтайме нахуй не надо. Каждый кто с хоть каким-то подобием црм работал видел "баг" от гения, который форму неделю заполнял и у него csrf токен устарел.
>А если ты пишешь соцсеть на миллион человек
Весь поинт был в том что никто блядь не пишет соцсеть на миллион человек.
На одном сайте написано:
Отредактируем php.ini:
прописываем абсолютный путь до библиотеки (если прописать относительный, библиотека не подключается)
zend_extension='G:\webserver\php\ext\php_xdebug-2.2.1-5.3-vc9.dll'
в конце файла php.ini создаем секцию xdebug со следующими параметрами:
xdebug.remote_enable=on
xdebug.remote_handler=dbgp
xdebug.remote_host=localhost
xdebug.remote_port=9000
Вопрос: куда именно в php.ini вставлять подобный кусок текста?
В php.ini есть только одна +- схожая строка:
;zend_extension=opcache
>минимальное время получения данных из базы 12мс
>В хайлоаде "быстрыми" считаются запросы в пределах 100мс
>тысячами классов под капотом примерно 60мс
Ха-ха-ха. Чёт ржу накуй. У моей dynamodb примерно 2.89 миллисекунд на чтение и 4.33 миллисекунды на запись. Поржал с фразы хайлоад в пределах 100мс.
мимо-любитель-nosql
Да. Ещё и пасасямбру даёт всем реляционкам.
1) Работай в офисе
2) Устраивайся в хорошую компанию, где выдают железо удаленщикам
3) Ищи кабана, который не требует трекеры
4) Прогибайся и ставь трекеры на свое домашнее железо
Если ты пхп вкатун то опция 2 тебе скорее всего не доступна
У тебя там 100500 взаимосвязанных сущностей? Это обычный юзкейс реляционок. Если у тебя одна там жисонина для хранения говна юзеров, то иди нахуй со своими сравнениями.
>У моей dynamodb примерно 2.89 миллисекунд на чтение
А кто говорил про "чтение", дебс? Пикрелейтед реляционный постгрес отработал за 2мс, провел по губам твоей неконсистентной параше. Только есть нюанс - подключение к базе идет по сети и на передачу данных уходит гораздо больше времени. У тебя сетевой запрос физически быстрее 12мс выполниться не может. А где на твоем графике fetching, додстер?
>Поржал с фразы хайлоад в пределах 100мс.
Додик, а ты не думал откуда берутся данные, которые в твой кеш попадают? Очевидно что результат 100мс запроса кешируется. Но все равно этот запрос надо периодически выполнять. А малейшая обработка данных пролетает мимо этой дрисни. Аггрегации? Группировки? Ах да у нас же тупая как пробка ключ-значение параша, которых миллион.
И да кстати, твоя nosql дрисня гарантирует мне что при конкурентной записи порядок будет соблюден? Или это просто помойка в оперативе, которая смывается в унитаз при любой проблеме на серваке?
Петуху ниприятна. Ну и сиди со своими взаимосвязными сущностями)
>>895041
Вай вай, смотри как разошёлся! Короче, факт в том, что при любых расчётах DynamoDB быстрее. Если я включу DAX-кеширование, ты вообще охуеешь. Там чтение в районе микросекунды. Это даже не миллисекунды. Я боюсь такое показывать, у тебя вообще жопа сгорит. Ты конечно можешь аргументировать типа то не умеет сё не умеет... но я так скажу - плохому танцору всегда что-то мешает)
А чтение чего?
Вот в реляционной базе я могу данные как-то обрабатывать. Типа сложить помидоры с огурцами, получить салаты, посчитать их калорийность и выбрать самый калорийный салат для каждого набора ингредиентов.
А из DynamoDB я могу получить за кратчайшие микросекунды... что? Я понимаю использование в качестве кеша. Умная реляционная база за долго посчитала и положила в быструю. Ну так один хуй получается что твоя DynamoDB без реляционной просто бесполезна. А перфоманс системы все равно будет считаться в совокупности.
Нахуй твоя nosql параша нужна если не в качестве обслуги более умных реляционных баз?
Да эт всё есть. А с orm будут ещё и типы и подсказки и всё остальное https://electrodb.fun )
Какие-то древние настройки, похоже для второй версии, сейчас уже 3.2.0.
1) У меня в php.ini первой строчкой (макось):
zend_extension="xdebug.so"
2) Внизу файла php.ini идет секция xdebug:
[xdebug]
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.discover_client_host = true
xdebug.client_host = localhost
xdebug.log_level = 0
Перед инструкциями недолжно быть символа ';' - это комментарий.
3) Номер порта задается в настройках phpstorm -> двойной шифт, далее в поиске набираешь то что ищеш.
Там заданы через запятую порты 9000,9003 для версий xdebug соответсвенно 2.x, 3.x.
Или можно добавить в секцию [xdebug] для своей версии:
xdebug.remote_port=9003
Главное, чтобы загрузился модуль (проверить в консоли: php -v или в скрипте phpinfo(), или xdebug_info()),
Для установки на виндовс есть инструкция:
https://xdebug.org/wizard
Какие-то древние настройки, похоже для второй версии, сейчас уже 3.2.0.
1) У меня в php.ini первой строчкой (макось):
zend_extension="xdebug.so"
2) Внизу файла php.ini идет секция xdebug:
[xdebug]
xdebug.mode = debug
xdebug.start_with_request = yes
xdebug.discover_client_host = true
xdebug.client_host = localhost
xdebug.log_level = 0
Перед инструкциями недолжно быть символа ';' - это комментарий.
3) Номер порта задается в настройках phpstorm -> двойной шифт, далее в поиске набираешь то что ищеш.
Там заданы через запятую порты 9000,9003 для версий xdebug соответсвенно 2.x, 3.x.
Или можно добавить в секцию [xdebug] для своей версии:
xdebug.remote_port=9003
Главное, чтобы загрузился модуль (проверить в консоли: php -v или в скрипте phpinfo(), или xdebug_info()),
Для установки на виндовс есть инструкция:
https://xdebug.org/wizard
Спасибо за ответ
Кто-то где-то когда-то слышал что пхп 5 гавно, пукнул в чатике, васян запомнил и повторил
> Он берет объект класса, который работает с БД.
> Вызывает его метод, который кладет соленый хеш в БД.
И это неправильно. Смотри, какая у класса зона ответственности? Работа с паролями, хеширование и проверка. Сюда работа с БД никаким боком не входит. Ни напрямую, ни косвенно.
Кто должен класть пароли в БД? Класс, отвечающий за авторизацию. У него может быть 3 метода - зарегистрировать пользователя, авторизовать пользователя и разлогинить пользователя. Этот класс может работать с БД (через другой класс конечно), так как это нужно для выполнения его задач.
> ОП, или тот, кто составлял советы по задаче со студентами, пишет "в качестве модели можно создать такие-то классы" и я просто примитивно полагаюсь на это
Ну логика тут такая: у нас есть Студент со свойствами, очевидно, нам нужен какой-то объект, который будет его представлять (является моделью этого Студента). Потому что бе з этого - как мы будет представлять студентов в коде? Не массивами же (мы все-таки ООП используем, а не технологии 2000 года).
Далее, Студентов надо сохранять в БД, искать в БД по разным условиям, значит нужен класс-сервис для этого. Из статьи по ссылке видно, что можно использовать паттерн TableDataGateway для этого. Далее, при регистрации или редактировании нужно проверять, что данные введены правильно - значит, нужен сервис для валидации Студентов либо же сервис для регистрации/обновления Студентов, который будет включать в себя валидацию.
Далее, мы должны запоминать пользователя в куках, значит нужен класс для этого.
Ну то есть примерно так надо рассуждать. Ты можешь составить список классов и за что каждый отвечает и выложить сюда и аноны покритикуют.
Плюс такого разделения программы на классы:
- каждый класс отвечает за что-то одно и тебе, чтобы внести небольшие правки, не надо изучать весь код, а только тот класс, который ты хочешь поменять. За счет этого ты быстрее делаешь работу. Это актуально для реальных приложений, в которых может быть 5 000 классов и такой объем кода, что целиком его прочесть нереально.
- если ты используешь автоматические тесты, то классы можно тестировать по отдельности. То есть, написал один класс и тестируешь его, хотя весь код еще не дописан.
> Он берет объект класса, который работает с БД.
> Вызывает его метод, который кладет соленый хеш в БД.
И это неправильно. Смотри, какая у класса зона ответственности? Работа с паролями, хеширование и проверка. Сюда работа с БД никаким боком не входит. Ни напрямую, ни косвенно.
Кто должен класть пароли в БД? Класс, отвечающий за авторизацию. У него может быть 3 метода - зарегистрировать пользователя, авторизовать пользователя и разлогинить пользователя. Этот класс может работать с БД (через другой класс конечно), так как это нужно для выполнения его задач.
> ОП, или тот, кто составлял советы по задаче со студентами, пишет "в качестве модели можно создать такие-то классы" и я просто примитивно полагаюсь на это
Ну логика тут такая: у нас есть Студент со свойствами, очевидно, нам нужен какой-то объект, который будет его представлять (является моделью этого Студента). Потому что бе з этого - как мы будет представлять студентов в коде? Не массивами же (мы все-таки ООП используем, а не технологии 2000 года).
Далее, Студентов надо сохранять в БД, искать в БД по разным условиям, значит нужен класс-сервис для этого. Из статьи по ссылке видно, что можно использовать паттерн TableDataGateway для этого. Далее, при регистрации или редактировании нужно проверять, что данные введены правильно - значит, нужен сервис для валидации Студентов либо же сервис для регистрации/обновления Студентов, который будет включать в себя валидацию.
Далее, мы должны запоминать пользователя в куках, значит нужен класс для этого.
Ну то есть примерно так надо рассуждать. Ты можешь составить список классов и за что каждый отвечает и выложить сюда и аноны покритикуют.
Плюс такого разделения программы на классы:
- каждый класс отвечает за что-то одно и тебе, чтобы внести небольшие правки, не надо изучать весь код, а только тот класс, который ты хочешь поменять. За счет этого ты быстрее делаешь работу. Это актуально для реальных приложений, в которых может быть 5 000 классов и такой объем кода, что целиком его прочесть нереально.
- если ты используешь автоматические тесты, то классы можно тестировать по отдельности. То есть, написал один класс и тестируешь его, хотя весь код еще не дописан.
Ну тогда задавай конкретные вопросы, вроде "почему надо использовать паттерн X, а не Y" или "почему в статье рекомендуют X, как можно сделать по-другому" и тебе может быть ответят.
> Даже если ты каким-то образом заставишь один процесс обрабатывать весь миллион пользователей он будет висеть в памяти и расти пока не упадет к хуям.
Чушь. Есть сборка мусора, так что при правильно написанном коде расти ничего не будет.
> Речь о том что минимальное время получения данных из базы 12мс. Это запрос константы типа SELECT 1;
Где ты такое взял? Ты на 486 процессоре что ли код запускаешь? Или у тебя база находится на другом конце Земли?
На MysQL запросы спокойно выполняются за 1 мс и меньше, если в индексы попадают и ты не пытаешься выкачать миллион строк.
> У тебя сетевой запрос физически быстрее 12мс выполниться не может.
Откуда ты взял пинг в 12 мс? Это пинг от Москвы до Питера, то есть когда приложение в одном городе, а база в другом. Если в одном дата-центре то пинг там может быть в десятки микросекунд (специально померял).
> Ну и сиди со своими взаимосвязными сущностями)
Так почти всегда это и нужно. Ну банально, лайк и фоточка это взаимосвязанные сущности и я не хочу, чтобы у меня в БД были лайки со ссылкой на несуществующую фотку или юзера.
То же касается транзакций, если их нет то в базу мусор появляется с вероятностью, близкой к 100% и ты потом либо пишешь скрипты для исправления либо код для игнора таких ситуаций. Ну то есть, ты платишь деньгами за отсутствие транзакций или внешних ключей в любом случае.
Ты бы сказал, что у тебя миллион юзеров одновременно и транзакции нельзя реализовать в принципе, потому приходится лепить костыли, я бы понял. Но хвастаться тем, что нет транзакций и внешних ключей - ну это верх глупости.
> Если я включу DAX-кеширование,
Ну в MySQL тоже есть кеширование результатов запроса, один минус, кеш сбрасывается при внесении любого изменения в таблицу, использованную в запросе. Но для оптимизации однотипных запросов помогает.
Вообще, если бы ты изучил вопрос СУБД повнимательнее, то знал бы, что ради повышения одного показателя приходится жертвовать другими, например ради повышения числа коммитов в сек. приходится снижать надежность и отключать защиту от аварийных ситуаций и тд.
То есть когда тебя просят "а глянь сколько лайков поставили юзеры из Сахалина за последнюю неделю", ты идешь писать скрипт вместо того, чтобы просто быстро ввести 1 SQL-запрос?
Тебе время не жалко? Я часто пишу SQL-запросы (например: понять, сколько лайков в среднем ставит один юзер; есть ли юзеры, ставящие их очень много, чтобы решить как их оптимальнее обрабатывать), и не представляю, как бы я жил если бы мне надо было скрипты писать каждый раз.
>>896050
Лол, изначально разговор был про скорость. Ты сейчас переводишь в срач у кого функционал мощнее. NoSQL нахуй не нужны foreign keys, потому что там другие механизмы работают. У реляционщиков в мозгах одни ЗАПРОСЫ. Бля, в NoSQL не запросы меняют, а ДАННЫЕ адаптируют под запросы. Если мне нужно лайки связать с пользователем, я просто сделаю primary key USER#anon31232 и sort key что-то типа LIKE#5e7245ab. Если сделать query и подставить USER#anon31232, он просто будет выводить все сущности, которые принадлежат пользователю. Дальше я могу просто фильтровать, begins_with(LIKE#), begins_with(ARTICLE#), begins_with(GROUP#) и так далее. Я могу сколько угодно наклепать этих индексов, у меня может быть отдельный индекс где будет primary key PROJECT#das32dasd и просто буду запрашивать всё что относится к проекту.
Конечно никто не спорит, если у тебя там сложнейшие запросы, то лучше взять реляционную БД. Но то что NoSQL быстрее по скорости - это просто факт. Ну и плюс, мне не нужно делать ALTER TABLE, не нужно объявлять schema заранее. У меня нет шардинга в принципе, у тебя БД на миллион пользователей нужно будет шардить на несколько таблиц. Я об этой проблеме просто нахуй не думаю) Так что твой наезд мимо кассы.
>выложить сюда и аноны покритикуют
Звучит как что-то страшное.
В любом случае, спасибо за ответ. Я все возьму на заметку.
Мне немного жутко от мысли, что у меня ничего не получится.
>Мне немного жутко от мысли, что у меня ничего не получится.
Это тебе к психологу. Такие мысли не имеют ничего общего с программированием. Это признаки синдрома жертвы. 1) Выученная беспомощность. 2) Драматизация незначительных событий. 3) Низкая самооценка. 4) Жалость к себе.
В состоянии выученной беспомощности индивид, испытывающий неудобства, боль и тому подобные негативные факторы, не предпринимает попыток к улучшению своего положения, хотя имеет такую возможность. Это состояние возникает после серии неудачных попыток воздействовать на отрицательные обстоятельства среды или избежать их, для него характерны пассивность, отказ от активных действий, нежелание менять враждебную среду или избегать её, даже когда появляется такая возможность. У людей выученная беспомощность сопровождается потерей чувства свободы и контроля, неверием в возможность изменений и в собственные силы, подавленностью воли и депрессией вплоть до наступления смерти.
>то что NoSQL быстрее по скорости - это просто факт
Ломающие новости. Хуйня, которая ничего не умеет, ничего не проверяет и ничего не гарантирует оказывается быстрее.
В следующем выпуске еще больше откровений от нашего js зверька:
- Запись в оперативную память быстрее, чем на диск.
- Но что если сервак просто выключится?
- Я об этой проблеме просто нахуй не думаю)
Наша редакция с теплотой вспоминает далекий 2013 год и великолепную Сару Мей. Которая великолепно и безвозвратно разъебала бекэнд своей компании, после чего выпустила нашумевшую статью "Почему вы никогда не должны использовать MongoDB" https://habr.com/ru/articles/231213/
История циклична и наше джаваскрипт животное, неведомым образом вырвавшееся из своего загона, имеет все шансы повторить успех Сары с очередным nosql высером. Помянем.
>Чушь. Есть сборка мусора
Мусором считаются данные, на которые никто не ссылается. Речь же о том что с подключением каждого пользователя тебе нужно создать n объектов для его обслуживания. То есть выделить какое-то количество памяти, и далеко не факт что линейное. А еще в цикле обходить каждый раз миллион пользователей и читать данные в память. Ты бы хоть почитал как в пхп с сокетами работать, перед тем как пытаться умное ебало сделать.
>Где ты такое взял? Ты на 486 процессоре что ли код запускаешь? Или у тебя база находится на другом конце Земли?
Я как бы скриншот к посту добавил, там вообще 22мс. Причем это локальная база и запрос без доступа к диску. Процессор тут не причем, это сеть. Попробуй у себя локально поднять базу и проверь сколько времени займет фетчинг.
>>896048
>Если в одном дата-центре то пинг там может быть в десятки микросекунд (специально
Ты путаешь пинг и полноценную передачу данных. Просто подними локально какую-нить базенку и проверь. И это на одном кампуктере, а не в соседних стойках. Задержка локальных веб запросов это как бы одна из главных проблем микросервисов, можешь погуглить. Везде минималочка примерно столько и есть.
А всё, от рута не надо запускать
Мне надо как раз написать эту страницу, морду. Лезть в залупу и говнокодить не хочу, я так понимаю проще будет взять фронт фреймворк и на нем все сделать. Что взять попроще?
Зачем ты эту хуйню пишешь я не понимаю? Видно же что ты не шаришь в теме. Причём здесь mongodb и dynamodb? Причём здесь javascript вообще? Клиентская часть может быть на чём угодно написана. Ты щас пытаешься недостатки найти? Лол, не утруждай себя. Не надо писать "ой а вот там вообще всё плохо". Плохо - значит сиди на своих реляционных базах. Нет смысла переубеждать тебя)
>не шаришь
>трехсотая по счету nosql дрисня
>джаваскрипт макака
>)
Я это кино десять лет смотрю. Там все шутки про говно и мочу, а в конце главный герой умирает клянется никогда больше но потом повторяет все с новой nosql дрисней.
Я теряюсь в догадках и почему же его никто не использует и ни в одном гайде его нет. Может быть это все из-за надписей на красном фоне ВНИМАНИЕ НЕ ИСПОЛЬЗОВАТЬ БЛЯДЬ
это забавно, но я так на 2 работы устроился, чисто пиздя за жизнь.
Сначала устоирлся стажером за МРОТ. Потом устроился тимлидом
Сука как же мне повезло в первый раз и как не повезло во второй, это пиздец. Оказалось не только меня взяли на работу "просто попиздев". Но и еще 2 наебщиков системы спиздевших про опыт и которых мне приходится учить Челики даже гитом никогда не пользовались, но зп мидлов.
https://hh.ru/vacancy/88509650?from=vacancy_search_list&hhtmFrom=vacancy_search_list&query=php
Требования дохуя на зп 1000$.
В 2013 году, девочка знающая MODx без знаний js и mysql столько получала
Ну хз, может вкатун или 10 лет сидел на одном месте и пишет лапшекод в процедурном стиле для какого-нибудь магазина который в старой хрущевке во внутреннем дворе находится.
Так я и не собираюсь его в продакшене использовать
Кстати, расскажите дауну, у меня сетевой сокет ассоциируется с текстовой информацией, как фастсги работает-то в итоге, если он бинарный?
Разворачивай свой стручок, что непонятного?
"Текстовый" отличается от "бинарного" не передаваемыми данными, а тем что по протоколу нужно передать "текстовый" заголовок, например "Connection: Keep-Alive". Этот заголовок по протоколу должен быть читаем, т.е. понятен человеку. И разумеется имеет лишний оверхед.
А по бинарному протоколу передается то что удобно, читается и понимается только кампуктером и ничего лишнего для мясных мешков в заголовках там нет. При этом передаваться с помощью обоих протоколов могут абсолютно одни и те же данные.
Ладно, я кажется понял :)
Почему там написано, что статические методы в трейтах становятся доступны из базового класса?
Насколько я понимаю, базовый класс - класс, от которого наследуют.
В данном примере UtilityService наследуется от Service.
Т.е. базовый класс - Service.
А переводя строчку из пика3, получается, что вызвать статический метод из трейта можно, написав:
Service::calculateTax(100)
Но метод вызывается как на пике2 (я понимаю, что пик2 рабочий вариант, а то, что написал я - нет, но я не понимаю что подразумевает автор в строчке из пика3).
Php -S localhost:4000
version: '2.0'
services:
php-apache-environment:
container_name: php-apache
build: ./php
volumes:
- ./php/src:/var/www/html/
ports:
- 8000:80
db:
image: mysql:5.6.27
restart: always
environment:
MYSQL_ROOT_PASSWORD: PassWord
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: root
ports:
- "9906:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin
restart: always
environment:
PMA_HOST: db
PMA_PORT: 9906
PMA_USER: test
PMZ_PASSWORD: root
ports:
- '8080:80'
depends_on:
- db
version: '2.0'
services:
php-apache-environment:
container_name: php-apache
build: ./php
volumes:
- ./php/src:/var/www/html/
ports:
- 8000:80
db:
image: mysql:5.6.27
restart: always
environment:
MYSQL_ROOT_PASSWORD: PassWord
MYSQL_DATABASE: test
MYSQL_USER: test
MYSQL_PASSWORD: root
ports:
- "9906:3306"
phpmyadmin:
image: phpmyadmin/phpmyadmin
restart: always
environment:
PMA_HOST: db
PMA_PORT: 9906
PMA_USER: test
PMZ_PASSWORD: root
ports:
- '8080:80'
depends_on:
- db
спс
>apache
>mysql:5.6.27
Где ты эту хуйню древнюю откопал? Пиздец нафталином повеяло. Вернул мне мой 2013.
>локалхосты не открываются
Ты же блядь сам написал что порт на хосте не 80, который по умолчанию, а 8000
ports:
- 8000:80
host port:container port
Плюс хуй пойми че там у тебя в апаче настроено. Это ведь апач должен твой запрос получать и на пхп директить.
Потому что нужно читать литературу в оригинале, а не с каловым переводом от хуй пойми кого.
>Где ты эту хуйню древнюю откопал? Пиздец нафталином повеяло. Вернул мне мой 2013.
Можешь посоветовать актуальную сборку?
php-fpm 8.1+
nginx 1.23+
postgres 15+
redis 7+
Это база. АКТУАЛ ОЧКА
phpmyadmin нахуй не нужон. Все что нужно для работы с любой актуальной базой есть в шторме.
Вот хорошие примеры как надо делать:
https://github.com/tarohida/docker-php80-nginx-postgres-composer
https://habr.com/ru/articles/317504/
https://dev.to/nicolasbonnici/how-to-build-a-clean-docker-symfony-5-2-php8-postegresql-nginx-project-3l5g
Обновляешь версии контейнеров, выкидываешь лишние типа монги и вперед.
wsl --install
wsl --set-default-version 2
sudo add-apt-repository ppa:ondrej/php
sudo apt-get update
sudo apt-get install nginx postgresql php8.3-cli php8.3-curl php8.3-xml php8.3-pgsql php8.3-zip php8.3-mbstring
Согласен, лучше линух накатить на железо, но сборочками обычно виндовозы интересуются. Луноходы обычно ищут пакетный менеджер и репозиторий.
А теперь прямо отвечая на вопрос: мне лень гуглить команды фреймворка, поэтому я копипащу руками контроллер и меняю его, но вообще да, многие юзают
php artisan list
php bin/console list
На одну секунду забудешь какие на пхп пишут животные, и тебе сразу напомнят какой-нибудь невероятно тупорылой хуйней.
Ну если тебе надо положить контроллер условно в тот же неймспейс и он читает какую-то хуйню и похож структурно на уже существующий контроллер, то генерить его неудобнее, чем копипастнуть. Хорош выёбываться братишка
Да пробовал уже, вообще второй день хуею с этого докера, настолько кривая система, лучше бы по старинке все делали чем такое говно высирать
Ну ебаный по голове. Ну ты же видешь что нет службы с таким названием. Ну посмотри ты список служб, грепни оттуда все что с докером связано.
Я уж не говорю о том что ошибка гуглится.
с твоим уровнем только убунту
>Ну ты же видешь что нет службы с таким названием
И какого хуя её нету? То есть докер собственные службы установить не может?
это дело мейнтейнеров пакетов, докер имее официальные пакеты только для дебиан убунты и красношапки
попробуй
sudo systemctl enable docker.service
sudo systemctl enable containerd.service
Тебе, обмылку микрософта, линукс от бабки достался в наследство?
Пропиши блядь sudo systemctl list-units --type=service | grep "docker"
и узнай, чучело. Ты же блядь его устанавливал, а не я.
Начнем с того, что DynamoDB не предоставляет никто, кроме Amazon, так что ты сидишь на вендор локе и если они завтра в 10 раз поднимут цены или заблокируют доступ для россиян, тебе останется только терпеть.
Во-вторых, архитектура DynamoDB это не шаг вперед в сравнении с SQL, а возвращение к истокам, так как до появления SQL БД так и работали, когда ты вручную делал в таблицах индексы и вручную по ним искал записи (запросов-то не было).
В-третьих, по моему опыту данные практически всегда сильно связаны друг с другом и переделывать их в несвязанную NoSQL схему неудобно.
> не нужны foreign keys, потому что там другие механизмы работают.
Нет там никаких механизмов, в SQL ты делаешь ссылку на запись в другой таблице, а в NoSQL ты просто пишешь id - цифру которая ничего не значит и никак не проверяется.
> я просто сделаю primary key USER#anon31232 и sort key что-то типа LIKE#5e7245ab
Только вот у тебя ссылка на юзера это просто строка, которая никак не проверяется и ты можешь вписать туда что угодно. Как следствие, постепенно в базе появляется мусор и надо либо писать код для его исправления, либо для игнорирования таких записей, то есть надо делать лишнюю работу.
> Но то что NoSQL быстрее по скорости - это просто факт.
Ты ничего не понял, хотя я писал. Одни БД быстрее других не из-за того, что они используют SQL или NoSQL. А из-за того, что жертвуют чем-то, например, надежностью. Условно, SQL база не подтверждает коммит пока данные гарантированно не ушли на жесткий диск, а NoSQL сбрасывает данные раз в N секунд и если что-то потерялось, то это не ее проблема.
Ну сам подумай, в конечном счете скорость поиска данных сводится к наличию и типу индексов. Индексы есть и в SQL, и в NoSQL, значит скорость поиска там при прочих равных примерно одинакова. А при записи скорость сводится к тому, сколько данных надо записать и надо ли дожидаться подтверждения от диска, что они сброшены. SQL тут или NoSQL вообще не важно.
> Конечно никто не спорит, если у тебя там сложнейшие запросы,
при чем тут сложнейшие запросы, у меня обычные запросы. Мне перед тем как делать какую-то фичу, надо проанализировать данные: сколько пользователей делают те или иные действия, как они их делают, какие у них предпочтения и тд. И я вижу что с твоим NoSQL этот анализ будет занимать больше времени, что мне невыгодно.
> мне не нужно делать ALTER TABLE
Отсутствие структуры на практике приводит к тому, что в БД появляется мусор. То есть сделали фичу, начали писать данные, потом заметили, что пишется не то, что нужно, поменяли, а мусорные данные остались. На практике это так обычно выходит.
То есть, преимуществ я вижу мало. Единтсвенное что может если у тебя миллионы запросов, а целостность данных не особо важна (например, игра какая-нибудь для детей, данные потерялись и фиг с ними) то придется отказаться от удобной SQL в пользу неудобной NoSQL, но других причин использовать я не вижу, один минусы и недостатки.
Начнем с того, что DynamoDB не предоставляет никто, кроме Amazon, так что ты сидишь на вендор локе и если они завтра в 10 раз поднимут цены или заблокируют доступ для россиян, тебе останется только терпеть.
Во-вторых, архитектура DynamoDB это не шаг вперед в сравнении с SQL, а возвращение к истокам, так как до появления SQL БД так и работали, когда ты вручную делал в таблицах индексы и вручную по ним искал записи (запросов-то не было).
В-третьих, по моему опыту данные практически всегда сильно связаны друг с другом и переделывать их в несвязанную NoSQL схему неудобно.
> не нужны foreign keys, потому что там другие механизмы работают.
Нет там никаких механизмов, в SQL ты делаешь ссылку на запись в другой таблице, а в NoSQL ты просто пишешь id - цифру которая ничего не значит и никак не проверяется.
> я просто сделаю primary key USER#anon31232 и sort key что-то типа LIKE#5e7245ab
Только вот у тебя ссылка на юзера это просто строка, которая никак не проверяется и ты можешь вписать туда что угодно. Как следствие, постепенно в базе появляется мусор и надо либо писать код для его исправления, либо для игнорирования таких записей, то есть надо делать лишнюю работу.
> Но то что NoSQL быстрее по скорости - это просто факт.
Ты ничего не понял, хотя я писал. Одни БД быстрее других не из-за того, что они используют SQL или NoSQL. А из-за того, что жертвуют чем-то, например, надежностью. Условно, SQL база не подтверждает коммит пока данные гарантированно не ушли на жесткий диск, а NoSQL сбрасывает данные раз в N секунд и если что-то потерялось, то это не ее проблема.
Ну сам подумай, в конечном счете скорость поиска данных сводится к наличию и типу индексов. Индексы есть и в SQL, и в NoSQL, значит скорость поиска там при прочих равных примерно одинакова. А при записи скорость сводится к тому, сколько данных надо записать и надо ли дожидаться подтверждения от диска, что они сброшены. SQL тут или NoSQL вообще не важно.
> Конечно никто не спорит, если у тебя там сложнейшие запросы,
при чем тут сложнейшие запросы, у меня обычные запросы. Мне перед тем как делать какую-то фичу, надо проанализировать данные: сколько пользователей делают те или иные действия, как они их делают, какие у них предпочтения и тд. И я вижу что с твоим NoSQL этот анализ будет занимать больше времени, что мне невыгодно.
> мне не нужно делать ALTER TABLE
Отсутствие структуры на практике приводит к тому, что в БД появляется мусор. То есть сделали фичу, начали писать данные, потом заметили, что пишется не то, что нужно, поменяли, а мусорные данные остались. На практике это так обычно выходит.
То есть, преимуществ я вижу мало. Единтсвенное что может если у тебя миллионы запросов, а целостность данных не особо важна (например, игра какая-нибудь для детей, данные потерялись и фиг с ними) то придется отказаться от удобной SQL в пользу неудобной NoSQL, но других причин использовать я не вижу, один минусы и недостатки.
И еще, у тебя там есть скриншоты, если честно это больше напоминает свалку, чем базу данных:
- зачем-то, без всякой логики, данные разного типа свалены в одну таблицу ( list(не понял, что это), quiz, sentence, user, datasent )
- записи одного типа имеют разное количество атрибутов, значит, надо в приложении писать if и костыли на случаи, когда что-то отсутствует. Надеюсь, это делает ODM, а не ты руками
- в некоторые колонки засунут JSON (Quiz details), то есть для работы с ними нужно еще отдельно костыли писать и невозможен поиск по этим колонкам
- из-за отстутствия внещних ключей трудно надохить и удалять или изменять связанные записи. Например, ты решил удалить LIST, а как ты найдешь и удалишь все ссылки на него?
- как я понял, схемы нет и при ошибке скрипт может вставить данные неправильного формата и из-за этого потом что-нибудь сломается в приложении
Ну и простой вопрос, когда при регистрации вводят существующий email, но в другом регистре (
Заметь, что это выводы только по скриншотам, по которым трудно полностью понять, что это вообще такое.
Ну и скажу также, что база у тебя очень маленькая, там меньше 10 сущностей. А в реальности сущностей может быть 100 или больше.
> А еще в цикле обходить каждый раз миллион пользователей и читать данные в память. Ты бы хоть почитал как в пхп с сокетами работать, перед тем как пытаться умное ебало сделать.
Ты бы сам почитал. Сокет-сервер на PHP обрабатывает только данные, которые изменились, то есть когда от пользователя что-то пришло. А если нужно отправить данные, то они отправляются только тем, кому нужно, и в цикле обходить всех не надо.
По моему, ты просто не знаком с тем, как это делается и уже второй или третий пост подряд демонстрируешь глупость.
> Я как бы скриншот к посту добавил, там вообще 22мс. Причем это локальная база и запрос без доступа к диску. Процессор тут не причем, это сеть. Попробуй у себя локально поднять базу и проверь сколько времени займет фетчинг.
Я занимался профайлингом и многие запросы занимают менее 1 мс. Но правда там и сервер не нищебродский, и памяти много, и SSD стоит, а не жесткий диск.
> . Просто подними локально какую-нить базенку и проверь.
Я мерял на реальной БД в продакшене, находящейся под нагрузкой.
Я думаю, "стручками" называют узлы сети. То есть ты на сервере устанавливаешь этот софт и твой сервер становится "стручком".
Сокеты (я имею в виду сетевые сокеты Беркли, а не вебсокеты) вообще-то все бинарные, то есть ты посылаешь и принимаешь из сокета последовательность байтов (чисел от 0 до 255).
Ну представь, что у тебя термометр, который передает температуру через сеть.
Если протокол текстовый, и температура 25 градусов, то он шлет коды символов "2", "5" и перевод строки как признак того, что это конец числа: 34, 39, 13. То есть, он шлет строку "25\n".
А если протокол бинарный, то данные кодирутся в байты как-то по -другому (обычно для каждого протокола и устройства свои правила). Например, он может просто температуру послать как оин байт 25.
Текстовые протоколы легче читать, но они как правило требуют больше байт для передачи данных.
Ну то есть, все сокеты бинарные. Просто при использовании текстового протокола ты шлешь по сокету коды символов.
Здесь видимо базовым называется класс, в который добавлен трейт. Согласен с аноном, скинувшим английский оригинал, что это кривой перевод.
Тебе было бы хорошо не копировать конфиги докера и докер композе вручную, а изучить документацию или туториалы по ним. Например, то, что ты не добавил себя в группу Докер указывает, что ты либо не читал документацию, либо это какая-то дебиановская фишка с группами, а ты про нее не знал. Часто дистрибутивы вроде Дебиан немного меняют конфигурацию программы под себя.
Никогда не использовал, быстрее и удобнее самому писать, особенно если в редакторе настроены сокращения для ввода конструкицй вроде private int (у меня они есть, в PHPStorm их нету).
Не надо ничего генерить. Неймспейс в файл вставляется одной кнопкой в Sublime Text, не знаю конечно как в PHPStorm, там может такого и нету.
>>897890
Давай разберем. Во-первых, тебе надо хотя бы кратко читать документацию по каждой команде которую ты вводишь, а не копировать их бездумно.
Смотри, в чем проблема:
- во-первых, в разных дистрибутивах могут быть по-разному сконфигурированы программы. Ты читаешь туториал по Ubuntu 22, а у тебя Debian 12 и там все по-другому. Или у тебя Mac, а туториал под Windows.
- во-вторых, если туториал от Debian 11, а у тебя Debian 12, опять же, может не сработать
- в-третьих, ты мог невнимательно читать туториал и пропустил начало, где сказано что надо установить какой-то пакет или что--то поменять в конфиге, а ты этого не сделал
- в-четвертых, нужно минимальное знание основ линукс, например, пользователи, суперпользователь, права на файлы и тд
Потому первый вопрос: твоя версия ОС совпадает с версией ОС из туториала? Выполнил ли ты предварительные шаги, установил, что требуется и точно такой же версии, что требуется? Я вижу по подсказке, что у тебя NixOS, значит и туториал нужен под нее.
Теперь разберу каждую команду для твоего развития:
1) Ошибка с gnome-terminal: gnome-terminal работает только в графическом интерфейсе. Либо у тебя не запущен X/Wayland (например, ты подключился к серверу или виртуалке без графического интерфейса), либо там баг, что-то сломалось и надо перезагрузиться (у меня один раз такое было), либо ты чего-то не установил.
Когда я у себя набираю gnome-terminal, то открывается окно терминала. Но у меня другой дистрибутив, не NixOS.
2) ошибка с docker version. Докер состоит из 2 частей: демон/сервис, который работает постоянно, и клиент, который ты запускаешь и который подсоединяется к демону и просит выполнить команду (команда docker это и есть клиент). В твоем случае у тебя либо недостаточно прав для соединения с демоном, либо демон не запущен. Тебе надо найти не устаревший туториал или мануал по установке Докер на NixOS и строго следовать ему.
3) Failed to start docker.service - это значит, либо сервис называется не docker, а как-то по-другому (например: super-puper-docker-server), либо ты установил только клиент от Докера, а демон не установил.
Скорее всего. ты либо использовал туториал от другой ОС, где все по-другому сконфигурировано, либо накосячил при установке и пропустил какой-то шаг. Либо докер обновился и туториал устарел.
>>897890
Давай разберем. Во-первых, тебе надо хотя бы кратко читать документацию по каждой команде которую ты вводишь, а не копировать их бездумно.
Смотри, в чем проблема:
- во-первых, в разных дистрибутивах могут быть по-разному сконфигурированы программы. Ты читаешь туториал по Ubuntu 22, а у тебя Debian 12 и там все по-другому. Или у тебя Mac, а туториал под Windows.
- во-вторых, если туториал от Debian 11, а у тебя Debian 12, опять же, может не сработать
- в-третьих, ты мог невнимательно читать туториал и пропустил начало, где сказано что надо установить какой-то пакет или что--то поменять в конфиге, а ты этого не сделал
- в-четвертых, нужно минимальное знание основ линукс, например, пользователи, суперпользователь, права на файлы и тд
Потому первый вопрос: твоя версия ОС совпадает с версией ОС из туториала? Выполнил ли ты предварительные шаги, установил, что требуется и точно такой же версии, что требуется? Я вижу по подсказке, что у тебя NixOS, значит и туториал нужен под нее.
Теперь разберу каждую команду для твоего развития:
1) Ошибка с gnome-terminal: gnome-terminal работает только в графическом интерфейсе. Либо у тебя не запущен X/Wayland (например, ты подключился к серверу или виртуалке без графического интерфейса), либо там баг, что-то сломалось и надо перезагрузиться (у меня один раз такое было), либо ты чего-то не установил.
Когда я у себя набираю gnome-terminal, то открывается окно терминала. Но у меня другой дистрибутив, не NixOS.
2) ошибка с docker version. Докер состоит из 2 частей: демон/сервис, который работает постоянно, и клиент, который ты запускаешь и который подсоединяется к демону и просит выполнить команду (команда docker это и есть клиент). В твоем случае у тебя либо недостаточно прав для соединения с демоном, либо демон не запущен. Тебе надо найти не устаревший туториал или мануал по установке Докер на NixOS и строго следовать ему.
3) Failed to start docker.service - это значит, либо сервис называется не docker, а как-то по-другому (например: super-puper-docker-server), либо ты установил только клиент от Докера, а демон не установил.
Скорее всего. ты либо использовал туториал от другой ОС, где все по-другому сконфигурировано, либо накосячил при установке и пропустил какой-то шаг. Либо докер обновился и туториал устарел.
Часто в разных дистрибутивах программа сконфигурирована по-разному. Например, в одних для запуска Питона 3 надо писать python3, а в других просто python. Так же и с докером, названия служб, расположение конфига, настройки по умолчанию могут отличаться в разных дистрибутивах. Обычно в документации по дистрибутиву это написано.
То есть, ты сначала читаешь доки от оригинального Докера, а потом документацию от дистрибутива, что они там поменяли.
>Сокет-сервер на PHP обрабатывает только данные, которые изменились
Именно это я и имел ввиду когда писал что ты нихуя не понимаешь, чучело. Напиши блядь код для обработки хотя бы двух соединений. Ты же блядь вообще не понимаешь о чем говоришь. Тебе блядь в цикле придется читать из каждого соединения. А потом блядь эти данные отправить во все остальные соединения, которым они нужны. Это ж блядь хранить еще надо что куда писать. Сколько это времени для миллиона коннектов займет сам посчитай, хуйлуша. И это я не говорю про проблемы со свежими пользователями, которым нужно старую переписку показать. Нихуя память расти не будет, да чмоня?
>Я занимался профайлингом и многие запросы занимают менее 1 мс.
Ебанько, что означает "занимают"? Есть конкретные части запроса Planning Time, Execution Time, Fetching Time. Я говорю про Fetching Time. Покажи мне результат запроса где fetching занял меньше 10мс или заваливай ебало.
>Я мерял на реальной БД в продакшене
А у меня блядь виртуальная что-ли?
>находящейся под нагрузкой.
Ну под нагрузкой-то оно все быстрее идет чем без нагрузки. Хуйлуша, запрос был SELECT 1; какая нахуй нагрузка вообще?
Короче, обмудок солевой, ты давай в следующий раз сразу прикладывай рабочий код или пруфы своего гнилого пиздежа. А то твои кукаретические маняфантазии доебали уже.
>DynamoDB не предоставляет никто, кроме Amazon
Не пизди чего не знаешь) Есть куча решений совместимых с dynamodb, тот же яндекс-облако например.
>вручную по ним искал записи (запросов-то не было).
Про что ты несёшь, дурачок? Там есть запросы https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Query.html
Короче из всей твоей тирады понял что тебя не устраивает отсутствие schema. Блять, так это наоборот хорошо! Мне наоборот по кайфу гибкий подход. Зачем мне загонять данные в жёсткий тип, может я не знаю заранее какие у меня данные будут. Валидация - это вообще задача программиста. Ты можешь у себя на бекенде какие угодно валидации сделать. Мусор? Ну и что мусор.... Это же не конец света. Так у вас вообще на каждый чих нужно делать миграцию. Я же не ною, мол какие реляционки говно, всё засрали своими миграциями...
>>898211
Ты заебал уже, реально. Доебался до типов... Сказали же структура ГИБКАЯ. Чел, ты просто не шаришь. Там нет никаких костылей. Всё что нужно делается через ORM: валидация, типы, запросы, удаление. Надо мне к нижнему регистру привести всё, проверить почту - я делаю это через ORM. Надо мне объявить тип - я тоже сделаю это через ORM. Объявлю модель и там будет всё прописано. Вставить данные неправильного формата не получится - ORM не позволит. Непонятно что это такое - потому что ты не шаришь. Это служебная инфа, некий аналог foreign keys. При использовании ORM всё лишнее скроется под капотом, останется только одна мякотка. Такой "странный" способ хранения данных на самом деле приём под названием "single-table design", который знают все nosql'щики. Без разницы, кассандра ли это, монга или ещё что. Ты естественно можешь не следовать принципам single-table design, не ставить ORM, тебя насильно под автоматами не заставляют. Просто не надо проецировать реляционное мышление на другие базы данных. Здесь другая блять философия. Это всё равно что применять мышление классической музыки на техно концерте ёпт.
Почитай про reactor pattern прежде чем писать что-то дальше.
> что означает "занимают"?
Время от вызова функции до получения результата запроса, то есть время выполнения запроса + сетевые задержки.
>PHPStorm их нету
Не может быть! Ведь Альберт сказал, что шторм - это лучшая иде для профессионалов.
>Короче, обмудок солевой, ты давай в следующий раз сразу прикладывай рабочий код или пруфы своего гнилого пиздежа.
>пук
Спасибо за подробное объяснение, поставил обратно дебиан буду курить офф документацию
Ого круто
>Зато пхп макаки с индусами за весло барена не конкурируют.
Лол что, это самая индуксская область после жс
Все самые крупные галеры это джава и мобильная разработка. Жс там потому что все интерфейсы сейчас на жс.
А назови мне хоть одну пхп галеру хотя бы на двести гребцов? Может и есть такие, но придется побегать и поискать.
Прикладывай ссылку на код.
Если я правильно понял твой вопрос:
- когда выводишь данные в кавычках, производится подстановка переменных, а знак `` просто символ, поэтому умножения не происходит. Выводятся значения переменных и символ ``;
- когда выводишь данные в апострофах, подстановки значений переменных не происходит, строка выводиться как есть;
- когда выводишь переменные без кавычек и производишь над ними арифметические операции, то выводится результат этой операции.
https://3v4l.org/YQK6c
Тебе нужно почитать про интерполяцию и конкатенацию строк в php.
знак имел ввиду умножить *
Ну сразу видно что ты пацан ровный. Могу помочь с рефакторингом если есть желание.
Спасибо, да я займусь как-нибудь, надо только время выделить, а я всё функционалом в занимаюсь, не до того
Ну смари сам, если че заходи в дискорд https://discord.gg/6RJvFkDNWN
Если какая помощь нужна спрашивай.
О, благодарочка.
Бля, это просто случайный набор слов. Там и слим то никто никогда не обсуждал.
Добрый вечер. Подскажите какие знаки препинания нужно выучить (минимум и максимум).
Я понимаю что в отдельности значат классы, объекты, интерфейсы, что они делают, но у меня не получается их использовать по назначению.
Например, читаю цитату "Программирование в соответствии с интерфейсом, а не с реализацией".
Как научиться понимать эту и подобные цитаты как само собой разумеющееся?
Для меня это как формула.
Я могу заучить, что какой-то показатель нужно умножить, а потом поделить на другой показатель, но почему именно такие операции нужно совершить и именно с такими показателями - нет.
Есть класс, который хранит информацию.
Я планирую создать класс, который будет наполнять первый класс.
Т.е. таким образом я хочу, чтобы каждый класс делал одно.
Один хранит, другой забирает извне данные и вносит в первый класс.
Это нормально или я дохожу до абсурда?
Как понять в делении класса, насколько приемлемо его делить?
Задача: дан массив с числами, извлечь квадратный корень.
Как я понял, автор не предполагал, что там будут неудобные числа, потому что сама задача находится среди элементарных задач, суть которой просто закрепить понимание цикла for.
Я подумал и решил, что мне полезнее будет решить ее так, чтобы можно было давать и неудобные числа, например, 101761.
Нашел алгоритм извлечения корня из подобных чисел.
И т.к. я учусь писать на ООП, решил попробовать написать на ООП.
Хотелось бы почитать от опытных анонов какие бы классы они предложили для такой задачи.
Алгоритм на скриншотах.
http://spacemath.xyz/algoritm-izvlecheniya-kvadratnogo-kornya/
Ни одного класса. ООП нужно, когда ты добавляешь фичу в код и хочешь сделать это расширяемо и поддерживаемо, т.е на практике ООП бывает полезным, когда появляется необходимость управлять зависимостями, например для работы нужна одна реализация зависимости, а для тестирования другая. Для написания одного алгоритма ООП не нужно. А вот если ты пишешь код который использует несколько взаимозаменяемых алгоритмов, то ты можешь это дело реализовать в виде стратегии.
Не слушай >>901113 еблана, он не шарит нихуя.
Тебе как минимум понадобится разбивать входящее число на "грани" и хранить их. То есть некий RootableInt, который содержит массив Edge. Так же обрати внимание на результат, он формируется путем добавления чисел в конец. Сам по себе язык так не умеет, то есть нужна некая обертка Result, которая меняется путем appendNumber().
То же самое кстати с гранями - опять добавляются а не суммируются, то есть нужен какой-то новый тип, который сам число, а увеличивается не математическими действиями а путем добавления числа в конец. Один раз создаешь такой класс и просто пользуешься. Имаджинируй лапшу процедурного хуесоса выше.
Задача простым алгоритмом решается, нахуя для нее классы городить? Даже в промышленном коде. Напимер методом деления отрезка пополам. Все это в несколько строк кода помещается с двумя переменными (с тремя). Если ты концы отрезка поместишь в класс и сделаешь метод возвращающий другой такой же отрезок с корнем, ты ничего не добавишь к рещению. просто напишешь немного больше нерасщиряемого кода. Это не есть ООП.
Вот если тебе нужно несколько алгоритмов вычисления корня, и ты напишешь интерфейс с методом public function sqrt(float $a): float, это будет ООП. Но это задачу в вопросе не решает, это решает задачу совмещаения нескольких алгоритмов с одним интерфейсом.
Каловичек, спок. Предъяви процепердурную реализацию заданного алгоритма или завали ебало. "Ето не есть оопе", чучело блядь.
Не то о чем просили, да еще и не на том языке. Вся суть дегенеративных пхп макак.
Я хочу сказать что ты вертлявый хуесос.
Напиши на пхп в процедурном стиле алгоритм, который тебя попросили или съеби в закат, чмоня.
Не хочу. Ты путаешь OOP и ADT в языке. Если чел собирается изучить ООП ему надо задачу с проектированием, а не составление структур данных для алгоритмов. И с хуя ли ты такой здесь агрессивный, валерьякку пей если с нервами проблемы.
>Не хочу.
Ну и пшел нахуй отсюда. Пиздуй в плюсотред аббревиатурами жонглировать. Тебе там быстро шершавым по губам проведут.
Да он ебанкрат какой то, нахуя что-то объяснять дауну который не понимает что функции и ооп это подходы к архитектуре, что с ним будет если он на какой-нибудь работе будет свои аутистские умозаключения высирать, мол есть алгоритмическая задачка я думаю её функциями не решить, надо ооп и ларку поднять ящитаю, вот умора будет.
О, еще один процедурный хуесос. Сейчас сделаю так что он съебет в закат что-то там пердя про архитектуру.
Напиши на пхп в процедурном стиле этот алгоритм http://spacemath.xyz/algoritm-izvlecheniya-kvadratnogo-kornya/ . А я напишу используя классы.
А потом сравним что будет читаемым и понятным, а что будет ебучей лапшой.
Написал алгоритм твоей мамаше за щеку, проверь. А чо ты кстати переобулся и говоришь теперь что на классах код будет просто читаемее чем на функциях, чуть выше от тебя был тезис что есть алгоритмические задачки которые функции в принципе неспособны решить, а классы могут, а теперь оказывается что и так и так можно всё решить, но на классах просто красивее будет. Получается ты тут единственный вертлявый хусос, так что обоссан и пиздуешь в закат ты.
А что ты хотел? Ты на выдумывал хуйни какой-то.
>чуть выше от тебя был тезис что есть алгоритмические задачки которые функции в принципе неспособны решить, а классы могут
Это че? Стекломойный хуесос, где ты это прочитал?
Вот конкретная цитата:
>>901589
>Имаджинируй лапшу процедурного хуесоса выше.
Ебать процедурные фантазеры. Срут простынями бессмысленных аббревиатур, а когда их просят предъявить код сливаются и убегают.
Ссылка на паттерны из ОП-поста некорректная, надо убрать README.html
https://designpatternsphp.readthedocs.io/ru/latest/
Какой ооп лол, для этого одна функция есть
Давай разберем на примере с плюсом. Допустим ты пишешь:
$a = 2;
$b = 3;
echo $a + $b;
Здесь $a и $b это переменные, а + это операция. Конструкция $a + $b называется выражение, и PHP вычисляет выражения перед тем, как выполнить echo. PHP выполняет сложение, и получившееся число (5) передает команде echo, которая его выводит.
Теперь возьмем код:
echo "$a + $b";
Здесь кавычки все меняют. То, что в кавычках - это строка, набор символов. И знак "+" это не оператор сложения, а просто символ плюса. При этом, PHP подставляет переменные в строку, и вместо $a и $b он подставит "2" и "3", и получится строка (не маетиматическое выражение, а просто набор символов) "2 + 3". И echo выведет эту строку как есть.
Рассмотрим еще один пример:
echo '$a + $b';
Для строки в одиночных кавычках PHP вообще ничего не делает, и даже не подставляет в нее переменные. Поэтому эта строка просто выведется как есть.
То есть, $a + $b, "$a + $b" и '$a + $b' это три разных вещи (выражение, строка с подстановкой переменных, строка без подстановки переменных).
Выучить мало, надо понять, когда они используются и почему их используют вместо того, чтобы написать более простой код. Я могу посоветовать для начала: Builder, Pool, Dependency Injection, Fluent Interface, Entity-Attribute-Value.
> Программирование в соответствии с интерфейсом, а не с реализацией
Это довольно просто. Это значит, что при написании кода ты можешь ориентироваться только на то, что написано в интерфейсе. Представь, что реализации пока нет или ты ее никогда не видел или завтра ее поменяют на другую. Твой код в любом случае должен работать, если ты смотрел только на интерфейс.
> Как научиться понимать эту и подобные цитаты как само собой разумеющееся?
Может, просто туториал или книга плохо объясняет и надо почитать другую?
Также, ты можешь попробовать задать себе вопрос вроде: а зачем нужны интерфейсы, если можно обойтись без них? Почему делают так, а не иначе?
100% программистов, ты хотел сказать?
Покажи мне полностью формализуемые правила написания кода (не правила типа название класса начинается с большой букву, а именно правила написания кода).
Сейчас до сих пор исследователи не используют компьютерные доказательства в научных работах по математике, а ты ждешь что тебе сделают формальные правила для PHP.
Это часто используется. Классы с данными часто называют "сущности", а классы только с операциями называют "сервисы".
В чем ошибка?
https://onlinephp.io?s=LYvNCoJQEIXXCb7DEC4SxLLSipIepCIuYbnIsmsFEUG2cZEPI2Jkv88w940ayVnN951zBkPf9WWpXgfMMMEP4BsTEYoQc0xBhCAizIleFL4x14D8HVPim4hEDPgkSDATZ5pd8COu-Cjkl8SNMNZlSZYUxjk7gA0jo2F0LEMDo9lqm1rP6na0dsu0Jv2iNl9zh83cGpR9FoCyZ8udA-pRlirlb8PC86fBhm-549X-UqU90Dkzd11u9Op4VSV9-gE%2C&v=8.2.10
Вообще, в PHP уже есть готовая функция для этого.
Можешь сделать этот алгоритм, но если что, есть список методов в Википедии: https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4%D1%8B_%D0%B2%D1%8B%D1%87%D0%B8%D1%81%D0%BB%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BA%D0%B2%D0%B0%D0%B4%D1%80%D0%B0%D1%82%D0%BD%D1%8B%D1%85_%D0%BA%D0%BE%D1%80%D0%BD%D0%B5%D0%B9
Один из самых простых это метод Ньютона:
- пусть надо вычислить корень из y
- берем в качестве начального значения x = y/2
- затем берем среднее между x и y/x: x = (x + y/x) / 2
- повторяем последний шаг и получаем все более точные значения
- повторяем, пока x и y/x будут различаться больше чем какое-то очень маленькое число, например, 1/1 000 000. Это число определяет точность ответа, чем меньше, тем точнее ответ.
Классы тут не нужны, так как у нас нет объектов со свойствами. Достаточно 1-2 функций или 1-2 статических метода в одном классе.
Спасибо за совет, т.к. разобраться с 5-ю шаблонами мне будет проще, чем с 20-ю и более.
Эта функция gmp_sqrtrem() находится в составе математического модуля GMP, который не подключен на данном сайте. Можешь попробовать другой, например https://3v4l.org/ или поставить PHP себе на комп.
В закладки добавь https://translate.google.com/ и бросай туда ошибки.
Ок, спасибо
Заебисто для такого новичка как я.
У меня есть notepad++ и недостроенный VsCode (стоит PHP и xDebug, но я хз как сделать так, чтобы результат кода выводился внутри программы)
Пробовал NetBeans, но сложным показался интерфейс.
Так что решил ручками проверять результат через онлайн компиляторы и на бумаге расписываю коротко логику.
А вот что делать, если...
У меня есть класс, который проверяет уникальность email.
Для того, чтобы проверить ее, нужно обратиться к БД, чтобы алгоритм перебрал таблицу с информацией абитуриента и сравнил входный емайл с имеющимися.
БД в планах будет заниматься другой класс.
Как мне правильно поступить?
Пока что я остановился на том, что метод внутри своего тела просто будет вызывать метод, который объявлен внутри класса с БД. И результат, который вернет этот метод из класса БД, метод класса, который проверяет на уникальность, положит в другой объект-сущность, где хранятся тексты всех ошибок.
Прости, пожалуйста, что так забористо пишу. Приложу картинку, надеюсь, что станет понятнее.
зарплату какую хочешь?
Не достаточно просто вынести доступ к базе в отдельный класс. Нужно сделать так чтобы валидатор мог только получать данные, причем только нужные.
Вот пример https://3v4l.org/ObHTt
Мы отделили валидатор от доступа к управлению хранилищем, он не сможет ничего никуда записать или поменять. А еще от способа хранения. Нам не важно хранятся емэйлы в таблице пользователей или где-то отдельно. Код валидации от этой перемены никак не поменяется. И валидатор ничего не знает ни о каких пользователях, он получает "строчку" и никаких ненужных зависимостей у него нет.
И поставь блядь наконец шторм. Даже мне, пока я писал этот пример, он с десяток ошибок исправил а половину кода сгенерил.
Не знаю в чем вопрос и ничего не знаю по пхп. Советую использовать docker-compose, с ним намного все понятнее. Алсо, почему такой жирный образ? Используй alpine.
Каких "команд"?
В какой папке лежит твой скрипт?
На какую папку ведет $PWD?
Почему ты прокидываешь именно в /var/ww/html?
Что делает твойскрипт вообще, откуда там какие-то новые файлы должны возникнуть?
Тебе надо понять что происходит когда ты команду прожимаешь чтобы диагностировать свои заулпы. Что у тебя есть эмулятор терминала, что он форкает оболочку операционной системы с интерфейсом командной строки под названием BASH (скорее всего), баш форкает процесс, где докер CLI отправляет команду докер-деймону по API, что докер CLI шарит файловый дескриптор stdout'а с эмулятором терминала, поэтому ты на экране видишь данный текст... и так далее
Алсо по докеру дока пиздец охуенная. Тупо почитай её блять и всё. По архитектуре докера верхнеуровневой по тому что команда делает которую ты тыкаешь. Но учитывая что ты нулёвый я не знаю зачем тебе докер
>На какую папку ведет $PWD?
На ту, которая у него в промпте, /home/его юзер/php. Промпт её из этой переменной окружения и выковыривает я полагаю
А маунтит он на вар ввв хтмл потому что пхпшная приложуха в образе докера там валяется
>>905507
>я полагаю
1) Полагать ты можешь че угодно. Его код должен лежать в папке, на которую указывает $PWD, то есть "хуй пойми где" пока он не убедится где это на самом деле.
>пхпшная приложуха
your-script.php это блядь и есть "пхпшная приложуха", а запускает её апач. А откуда апач пытается её запустить, на какую папку он настроен? "хуй пойми на какую", пока он не проверит и не убедится.
То есть получается: он монтирует "хуй пойми что" в /var/www/html, а апач ищет пхп скрипт "хуй пойми где". После чего "хуй пойми какая" директория "хуй пойми почему" остается пустой.
Вот и "полагай" хуй к носу.
Я увидел что образ это апач+пхп. Теперь я додич. Всё. Маски сброшены. То что он какую-то хуйню вызывает это и так понятно, я не про это а в целом. Что неплохо бы разобраться
Но ты всё равно пидорас что так токсично навонял на меня. Иди нахуй пидорас
Ты просто пытался с умным ебалом что-то пиздануть, получился пердежь в воздух. Нахуя ты пытаешься делать вид что знаешь, когда ты нихуя не знаешь? Ты блядь даже не знаешь про какую папку он спрашивал.
Да никто тебя пиздить не будет, просто обоссым.
К VSCode можно подключить Phpactor (придется повозиться с конфигами) или intelephense (но там часть функций платная). Тогда будут подсказки и некоторые проверки.
Зачем тебе нужно запускать код прямо в IDE я не очень понял, но в VS Code ты просто можешь открыть консоль и набрать команду вроде php 1.php
Разумеется, валидация и работа с БД это разные вещи и ими занимаются разные классы.
Ты можешь сделать так (по-простому):
Класс-валидатор, который проверяет различные поля по разным правилам. При этом для проверки уникальности email он вызывает метод вроде isEmailUsed у класса для работы с БД.
Ты передаешь объект БД в аргументы. Но лучше передавать его в конструктор, используя DI (туториал: https://github.com/codedokode/pasta/blob/master/arch/di.md )
Или по-сложному:
Для каждого правила делаем свой класс-валидатор. То есть, для проверки, что поле не пусто, один класс, для проверки, что там только цифры, другой класс и тд. И главный класс, в который ты сначала добавляешь объекты-правила (в стиле "поле X должно соответствовать правилу Y") и он проверяет данные из формы на соответствие всем правилам. Это сложнее, но позволит лучше освоить ООП.
Это может быть примерно так:
$validator = new Validator([
'name' => [new NotEmptyValidator, new LengthMaxValidator(30)],
'...' => ...
]);
$errors = $validator->validate($form);
Конечно, $errors тоже можно сделать массивом объектов.
Если хочешь посмотреть, как валидацию делают в реальных фреймворках, можешь почитать:
- https://symfony.com/doc/current/components/validator.html
- https://laravel.com/docs/10.x/validation
Разумеется, валидация и работа с БД это разные вещи и ими занимаются разные классы.
Ты можешь сделать так (по-простому):
Класс-валидатор, который проверяет различные поля по разным правилам. При этом для проверки уникальности email он вызывает метод вроде isEmailUsed у класса для работы с БД.
Ты передаешь объект БД в аргументы. Но лучше передавать его в конструктор, используя DI (туториал: https://github.com/codedokode/pasta/blob/master/arch/di.md )
Или по-сложному:
Для каждого правила делаем свой класс-валидатор. То есть, для проверки, что поле не пусто, один класс, для проверки, что там только цифры, другой класс и тд. И главный класс, в который ты сначала добавляешь объекты-правила (в стиле "поле X должно соответствовать правилу Y") и он проверяет данные из формы на соответствие всем правилам. Это сложнее, но позволит лучше освоить ООП.
Это может быть примерно так:
$validator = new Validator([
'name' => [new NotEmptyValidator, new LengthMaxValidator(30)],
'...' => ...
]);
$errors = $validator->validate($form);
Конечно, $errors тоже можно сделать массивом объектов.
Если хочешь посмотреть, как валидацию делают в реальных фреймворках, можешь почитать:
- https://symfony.com/doc/current/components/validator.html
- https://laravel.com/docs/10.x/validation
PHP, запущенный внутри контейнера, не видит PHP-файл. Скорее всего ты забыл примонтировать папку с PHP-кодом внутрь контейнера или примонтировал ее не туда (смотри параметр volumes в конфиге Докера).
Ты можешь проверить, что видно из контейнера, запустив в нем команду ls:
docker exec имя-контейнера ls -a
Вот поэтому, кстати, я советую перед изучением Докера изучить основы Линукса - команды типа ls, pwd, mount в таких ситуациях помогают.
Мне кажется, неудачно выбрано название для метода __invoke в интерфейсе. Из-за этого нельзя сделать класс, реализующий несколько интерфейсов. Также, имя метода не является самодокументирующим. Мне не нравится такое название.
Далее, ты сделал метод "найти первого пользователя по email", но тут другая задача: проверить, что email не используется никем, кроме, может быть, текущего пользователя, и твой метод задачу не решает.
Далее, ты используешь странный способ наименования классов и интерфейсов: ты называешь их не существительными, а глаголами, как функцию. Почему? Ты это сам изобрел или где-то можно почитать такое соглашение об именах?
Далее, желательно бы не просто сообщать, что email невалидный, а пояснять, почему.
Наконец, так как это обучающий тред, объясни пожалуйста, зачем ты решил сделать интерфейсы, для которых существует только одна реализация и никогда не будет альтернативных реализаций?
И так как это обучающий тред, то пиши хотя бы кратко, почему ты делаешь так, а не иначе, ведь человеку нужны знания, а не готовое решение.
Твои PHP-файлы должны быть не внутри образа докер, а монтироваться внутрь контейнера. Если ты просто включил файлы в контейнер, то это неудобно будет.
Ты выполняешь команды, которые не пишут ничего в директорию. Например, docker ps.
Также, если ты что-то пишешь внутри контейнера, то это теряется при завершении контейнера. Тебе надо примонтировать директорию с хоста в контейнер, чтобы результат сохранялся. Сам контейнер неизменяемый.
>неудачно выбрано название для метода __invoke
Invoke не выбирают, это единственный способ сделать класс-функцию.
>Из-за этого нельзя сделать класс, реализующий несколько интерфейсов.
Каво? Пример кода пожалуйста.
>Также, имя метода не является самодокументирующим
Шо? Почитай доку по invoke. При таком подходе имя класса = имя метода.
>ты сделал метод "найти первого пользователя по email", но тут другая задача: проверить
У хранилища нет никакой задачи ничего проверять. Проверяет валидатор. Вся суть примера в том что валидатору насрать кто и откуда вытащил этот емэйл, он сам интерпретирует его наличие или отсутствие. В этом примере вообще не важно как там валидация работает, там половина методов вообще заглушки с true.
>Далее, ты используешь странный способ наименования классов и интерфейсов: ты называешь их не существительными, а глаголами, как функцию
Потому что они выполняют функцию. Причем единственную. Шизофрения и тавтология писать что-то типа $search->search() или $query->query(). Вместо этого пишется просто $search() или $query() или $findEmail().
>желательно бы не просто сообщать, что email невалидный, а пояснять, почему.
А еще желательно зависимости через di прокидывать, делать мне нехуй еще di писать. Пример вообще не про это.
>объясни пожалуйста, зачем ты решил сделать интерфейсы, для которых существует только одна реализация и никогда не будет альтернативных реализаций?
RuntimeUserStorage implements IUserStorage то есть хранилища в базе не будет "никогда"? А емэйлы "всегда" хранятся только в хранилище пользователей? Интересно откуда такие выводы.
>И так как это обучающий тред, то пиши хотя бы кратко, почему ты делаешь так, а не иначе, ведь человеку нужны знания
Что я имел ввиду я пояснил в посте. Писать все в виде комментариев, а потом давать комментарии к комментариям никакого здоровья не хватит. Я уже скидывал ссылку на дискорд: https://discord.gg/6RJvFkDNWN велком в войс, разберем хоть построчно.
Что по зарплатам на PHP? Реально ли для сеньора зарабатывать 4000$ в РФ или восточной Европе (например, Польше)?
Собираюсь вкатываться в пхп, но как мне кажется - потолок у сеньоров 3500, а то и 3000 долларов. Поправьте, если я не прав.
Второй вопрос: достаточно ли вакансий, нацеленных на фреймворки, а не на CMS/Bitrix?
Третий вопрос: что лучше сразу изучать: ларавел, или симфони? И где больше вакансий: на первом, или на втором?
Заранее благодарю за ответы.
Это о многом говорит. Нет.
Начиная от договора B2B, который не подходит для понаеха, заканчивая большим разбросом зарплат.
Сайты с зарплатами потыкать и я могу; это конечно хорошо, но лучше узнать о реальном положняке конкретно от итт экспертов.
>как мне кажется - потолок у сеньоров 3500, а то и 3000 долларов
Да, где-то так. Больше тебе вряд ли кто даст. Если только какая-нибудь залётная фирма из Швейцарии или Норвегии.
>нацеленных на фреймворки, а не на CMS/Bitrix?
Фу блять фу нахуй. Ничего не имею против ларавела/yii, классные фреймворки. Но работа на пхп фреймворках - это дно из дна просто. Ты будешь соревноваться с индусами работающими за $3/час, это самые низкооплачиваемые программисты из всех программистов по всем языкам. У программиста на ларавеле нет вообще никакой перспективы, у них примерно зарплата как у тестировщика. Может это парадоксально прозвучит, но даже на битриксе или вордпрессе больше платят. Даже мне кажется имеет больше смысла устроиться водителем такси в Москве или курьером/развозчиком еды.
>что лучше сразу изучать: ларавел, или симфони
Я бы вообще никакой пхп фреймворк не изучал. На мой взгляд, ниша пхп просто нахуй мертва. Я сам ушёл из пхп в рякт, ноду и раст, потому что бестолковая работа. Ну да, какбе вакансий много, но они низкооплачиваемые. Что толку от этих 3х или сколько там тысяч вакансий, если они в среднем предлагают тысяч 100. А те, которые 200-250 тысяч, там требования будут запредельными, длиннющий список из кубернетиса, баз данных, облаков и ещё бог пойми чего. То есть работы много, это абсолютная правда. И её на тебя хватит, это тоже правда. Но платить будут мало. То есть количество не равно качество.
Сейчас есть миллион БОЛЕЕ ИНТЕРЕСНЫХ ниш. Даже если какую-нибудь java взять и то будет лучше. На чисто мой взгляд, можно чисто для себя изучить WordPress/Bitrix. Но карьеру на этом строить я бы не стал.
> Ты будешь соревноваться с индусами работающими за $3/час
What? Я имел ввиду не фриланс, а работу в компании, если ты говоришь о фрилансе, тогда могу согласиться
> У программиста на ларавеле нет вообще никакой перспективы, у них примерно зарплата как у тестировщика
Возможно. Тогда стоит изучать симфони.
> На мой взгляд, ниша пхп просто нахуй мертва
Можно как-нибудь аргументировать? Я не спорю с тобой, просто из любопытства спрашиваю
> Но платить будут мало
А если не в РФ работать, а в Европе? Как там дела с пыхой обстоят?
>Сейчас есть миллион БОЛЕЕ ИНТЕРЕСНЫХ ниш. Даже если какую-нибудь java взять и то будет лучше.
Чистая правда. Заебался говорить вкатунам на пхп что им нахуй не нужен именно пхп. Что они себя загоняют в узкую тупиковую нишу.
>работа на пхп фреймворках - это дно из дна просто.
Тут началась какая-то хуйня. Найди мне хотя бы пару вакансий где не требуются фреймворки. Даже если проект по библиотекам собирать половина либ из тех же фреймворков будет.
>php работа бестолковая
>нода работа не бестолковая
Ну и написал бы: идите на фронт ребята, там бабки и знать нихуя не надо. Что частично правда. Но нахуя такую жирноту вываливать.
>можно чисто для себя изучить WordPress/Bitrix
И последняя строчка обесценивает всю простыню. Ты либо говна въебал, либо просто ничего про сегодняшние пхп реалии не знаешь. Просто как фонариком посветил и весь текст превратился в шизофазию с ебанутым выводом.
>Можно как-нибудь аргументировать?
А что здесь аргументировать? Язык просто медленно умирает, вот и всё. Его область использования ограничена говносайтами. Заказчики на пыхе не привыкли много платить, ты можешь хоть 10 лет опыта иметь и всё равно зарабатывать 180к. В пхп огромное количество говнокодеров, легаси, ебланов-заказчиков. Переехать куда-то в Европку по релокации тупо нереально, там своих пхпшников хватает. Интересных там каких-то модных молодёжных стартапов/проектов на php почти не бывает. То есть особых перспектив на будущее лично я не вижу. Да, под php много вакансий. Но это в основном всякая шелупонь типа личных кабинетов, говно-crm, говно-маркетплейсы, говно-магазины, говно-интеграции и так далее. Итого, чтобы подытожить:
- Нет релокации
- Мало интересных проектов
- Низкая зп по сравнению с другими программистами
- Много вакансий
- Много легаси и говнокода
- Особых перспектив у языка нет
- Область использования ограничена говносайтами
Чувак, если боишься пожалеть о вкате в пхп, то помни, что вкат в пхп - это окно выката в голанг. Он сейчас требуется в каждой третьей пхп вакансии
голанг в ваканисии пхп
@
устроился
@
легаси & монолит & лапша
@
в гите 100500 неизвестных "индусов"
@
дали задачу добавить редактирование неопубликованных комментов
@
на мите тимлид рассказывает как мужественно борется с единственным микросервисом на голанге
Бугурт от чела, который ни разу не видел что такое голанг в пхп конторе.
Смари как надо.
ГОЛАНГ В ВАКАНСИИ ПХП
@
ВСЕ КТО ПИСАЛ НА ПХП ЛЕГАСИ МОНОЛИТ И ЛАПШУ ПИШУТ ТЕПЕРЬ НА ГО
@
ТВОЙ ТИМЛИД ТОЖЕ
@
СЕРВИС НА ГО ОДНА СТРАНИЧКА КОДА
@
СЕРВИС НА ПХП МЕШАНИНА ИЗ СОТНИ ФАЙЛОВ
@
ПОНИМАЕШЬ ЧТО ТЕБЯ ВЗЯЛИ ПОДМЫВАТЬ ЭТУ ЛЕГАСИ ПХП ПАРАШУ
@
ГО РАЗРАБЫ СИДЯТ ЧИСТЯТ СВОИХ ХОМЯКОВ И СОРЕВНУЮТСЯ НА ЛИТКОДЕ
@
ТЫ ЧИСТИШЬ ЗА НИМИ КАЛ ПЯТИЛЕТНЕЙ ДАВНОСТИ
Го беженец >>906338 , верифицируй бугурт.
Я к тому что го в пхп конторе это мгновенная сегрегация на "го элиту" и "пхп плебс". А вчерашний раб это самый жестокий хозяин.
Если ты го вообще не знаешь или по какой-то причине именно го вакансии сейчас нет или что самое хуевое вас пхп программистов несколько, то отношение как говну и обслуге гарантировано.
А если сюда добавить тот факт что на го переписываются обычно самые важные части системы, то и от начальства будет отношение как к бесполезным ебланам которых мы вообще нахуя тут держим.
Хахаха дк это классика. Пхп+го это почти всегда говномонолит распиливать. Но деньхи-то плотют так что ладно
Да мало кто пыхо монолиты распиливает. В пыхоконторах вообще не принято давать время на устранение технического долга. Обычно есть МОНОЛИТ приносящий бабки, который ковыряют джуны с мидлами и несколько микросервисов интеграций на разных языках для развлечения сенек и тимлида
Зачем ты пишешь зарплату в долларах? Его курс меняется так часто, что трудно понять, сколько ты хочешь рублей.
> устроиться водителем такси
Ага, целый день общаться с неадекватами
> или курьером/развозчиком еды
То же самое, плюс дождь, грязь, сырость. Это подработка для способных выжить в любых условиях студентов и мигрантов, а не для взрослого человека.
> идите на фронт ребята, там бабки и знать нихуя не надо.
Да, постоянно на улице вижу рекламу такую.
> Область использования ограничена говносайтами
Ну давай, расскажи про достойные сайты и на чем они написаны. Только пожалуйста не приводи в пример озон, яндекс маркет и подобный отстой, который инвалиды не осилили сделать в виде монолита и сжигают деньги заказчика на микросервисы.
> микросервис
> несколько языков
Почему ты на этом месте не хлопнул дверью? Тебе, что, нравится в конфигах Докера ковыряться и JSON из сокета в сокет перекладывать вместо полезной работы?
Привет, помогите победить феменитивы. Я что-то пытался сделать в 120 строке, но нихуя не вышло, я тупой.
>Собираюсь вкатываться в пхп, но как мне кажется - потолок у сеньоров 3500, а то и 3000 долларов. Поправьте, если я не прав.
Ты где такие зарплаты видел? Потолок 80 тысяч рублей фантазер ты наш
>Второй вопрос: достаточно ли вакансий, нацеленных на фреймворки, а не на CMS/Bitrix?
Достаточно чтобы понять что вкатун нахуй не нужен
>третий вопрос: что лучше сразу изучать
Укладку плитки или сварочное дело
ларавел, или симфони? И где больше вакансий: на первом, или на втором?
Оба надо знать, вакансий нет
> И ещё мне вот что непонятно: кто исполняет php? Только apache или nginx тоже умеет?
Это бэкенд язык блять, он на любом сервере запускается в том числе встроенном лркалхосте
Хуйню сказал, просто так он не будет исполняться без определенных телодвижений.
У тебя функция inclineWord() после объявления переписывается два раза, зачем?
Также два раза рекурсивно вызывается функция numberToWords(), так задумано или ошибка?
Если у тебя нджинкс занимается, чем-то кроме отдачи статики, то у меня для тебя плохие новости
Программу на языке PHP исполняет интепретатор PHP. Интерпретатор PHP - это программа, написанная на Си. Она читает твой PHP код и выполняет команды в нем.
Когда ты используешь Апач, к нему подключается плагин с интепретатором PHP (он называется вроде mod_php). Если от браузера приходит запрос к файлу с расширением .php (вида http://localhost/test.php), то Апач вызывает плагин mod_php и интепретатор выполняет код скрипта test.php, и то, что программа выведет с помощью echo или как-то еще, интерпретатор отдает Апачу, а тот отправляет это назад в браузер. Обычно PHP-скрипт выводит HTML-код, и бразер его отображает.
То есть, связь такая:
Браузер <-> Апач <-> Модуль mod_php, содержащий интерпретатор PHP
Апач отвечает за взаимодействие с браузером, поддержку протокола HTTP, отдачу статических файлов (без кода PHP), а mod_php за выполнение PHP-скриптов.
Апач сейчас не очень часто используется, обычно используют nginx + php-fpm. Тогда схема такая:
Браузер <-> nginx <-> php-fpm
Отличие в том, что к Апачу PHP подклюается как модуль (плагин, расширение), а в случае с nginx мы отдельно запускаем nginx и отдельно запускаем php-fpm, и PHP здесь запускается как отдельная программа, а не модуль для nginx.
> Я привык видеть, что это какой-то колхоз в одном файлике из html, javascript и самого php,
PHP ничего не знает про HTML и Javascript и не пытается никак анализировать или выполнять такой код. Он выполняет код, который находится внутри тегов <?php ... ?> или <?= ... ?>, а все остальное просто выводит как есть. Соответственно, если ты напишешь HTML код снаружи тега PHP, то PHP просто его выведет как есть, а Апач передаст это в браузер.
> тем самым у нас самый что ни на есть SSR
Термин SSR обычно используют, когда говорят про SPA-приложения, я не уверен, что тут это можно использовать.
> Где с этим всем ознакомиться можно?
В документации по Апачу, mod_php, php-fpm, nginx.
> И ещё мне вот что непонятно: кто исполняет php? Только apache или nginx тоже умеет?
Только интепретатор PHP. Ни Апач, ни nginx ничего про PHP не знают. Им надо специально указывать в кофниге, чтобы запросы к php-файлам обрабатывал интепретатор PHP.
Программу на языке PHP исполняет интепретатор PHP. Интерпретатор PHP - это программа, написанная на Си. Она читает твой PHP код и выполняет команды в нем.
Когда ты используешь Апач, к нему подключается плагин с интепретатором PHP (он называется вроде mod_php). Если от браузера приходит запрос к файлу с расширением .php (вида http://localhost/test.php), то Апач вызывает плагин mod_php и интепретатор выполняет код скрипта test.php, и то, что программа выведет с помощью echo или как-то еще, интерпретатор отдает Апачу, а тот отправляет это назад в браузер. Обычно PHP-скрипт выводит HTML-код, и бразер его отображает.
То есть, связь такая:
Браузер <-> Апач <-> Модуль mod_php, содержащий интерпретатор PHP
Апач отвечает за взаимодействие с браузером, поддержку протокола HTTP, отдачу статических файлов (без кода PHP), а mod_php за выполнение PHP-скриптов.
Апач сейчас не очень часто используется, обычно используют nginx + php-fpm. Тогда схема такая:
Браузер <-> nginx <-> php-fpm
Отличие в том, что к Апачу PHP подклюается как модуль (плагин, расширение), а в случае с nginx мы отдельно запускаем nginx и отдельно запускаем php-fpm, и PHP здесь запускается как отдельная программа, а не модуль для nginx.
> Я привык видеть, что это какой-то колхоз в одном файлике из html, javascript и самого php,
PHP ничего не знает про HTML и Javascript и не пытается никак анализировать или выполнять такой код. Он выполняет код, который находится внутри тегов <?php ... ?> или <?= ... ?>, а все остальное просто выводит как есть. Соответственно, если ты напишешь HTML код снаружи тега PHP, то PHP просто его выведет как есть, а Апач передаст это в браузер.
> тем самым у нас самый что ни на есть SSR
Термин SSR обычно используют, когда говорят про SPA-приложения, я не уверен, что тут это можно использовать.
> Где с этим всем ознакомиться можно?
В документации по Апачу, mod_php, php-fpm, nginx.
> И ещё мне вот что непонятно: кто исполняет php? Только apache или nginx тоже умеет?
Только интепретатор PHP. Ни Апач, ни nginx ничего про PHP не знают. Им надо специально указывать в кофниге, чтобы запросы к php-файлам обрабатывал интепретатор PHP.
> function numberToWords($number)
Тебе надо дополнительно передавать в функцию род, в котором ты хочешь получить число, например так:
function numberToWords($number, $isFemale) // $isFemale = 0 - мужской, 1 - женский род
Или, если ты знаешь про булев тип, то можно передавать false = мужской род, true = женский.
Чтобы было так:
numberToWords(1, 0) // один
numberToWords(1, 1) // одна
Также, не объявляй функции внутри других функций. Это приведет к ошибке, если, например, у тебя вызвать функцию numberToWords дважды, то будет ошибка создания функции.
Также, не делай несколько копий функции inclineWords, достаточно одной.
Спрашивай, если что-то непонятно.
Спасибо большое. Теперь все понятно.
У меня никакой нжинкс ничем не занимается, я только разбираюсь.
Это же встроенная функция? Зачем она в файле composer.json?
Ранее тоже замечал и по другим функциям, например по работе с sqlite3.
Это функция добавляемая расширением php, например в убунте она добавляется через apt
sudo apt-get install php8.1-xml
Она вполне может отсутствовать в системе
> php -m | grep -i xml
libxml
SimpleXML
xml
xmlreader
xmlwriter
Вот на примере Simple XML, на скринах та же ситуация.
Модуль установлен, объект создается, а пхпшторм подсвечивает проблему.
Вопрос не особо важный, просто интересно, почему так.
А какая разница установлена ли у ТЕБЯ эта либа?
Шторм подсвечивает не проблему:
>Ты не сможешь выполнить этот код.
Шторм подсвечивает проблему:
>Никто не знает что для работы этого кода нужна либа.
Если ты не указываешь зависимости в менеджере зависимостей, то как сервер узнает что нужна либа? На сервере шторма нет. Как твой коллега узнает что нужна либа? А если ты это укажешь, то композер выдаст ошибку, в которой напишет все что нужно для запуска проекта, какой фреймворк, какой версии, какие либы, какая версия пхп в конце концов.
Хорошо, я понял.
Не подумал о том, что можно так сконфигурировать пхп перед установкой, что множества "стандартных" библиотек просто не будет установлено.
Без просада никак наверное. Если прямо до усрачки надо, я бы в таком случае джуном на го пошёл, наверное, или по знакомству попробовал
Эта функция входит в расширение xml. Допустим, другой человек скачает твой код, но из-за отсутствия расширения у него код не заработает. Поэтому лучше явно указать, что для твоего проекта нужно это расширение, и composer.json как раз подходящее место для этого. Композер при установке автоматически проверит его наличие.
> Это же встроенная функция?
Не совсем. У PHP есть ядро, а есть расширения, которые надо ставить отдельно (хотя в некоторых ОС они ставятся вместе с PHP). xml это как раз расширение, и функция находится в нем. Просто у тебя оно наверно установилось вместе с PHP и ты даже не заметил.
Это зависит от ОС, в некоторых ОС ставится PHP + стандартные расширения, а в некоторых ставится по умолчанию только ядро PHP.
>А по пыхе есть что нибудь такое?
Ну так открой тот же stepik, на котором ты читал Балакирева и вбей там в поиске php.
>Хто? Я?
Докер лёгкий, просто ты тупой))
У меня нет возможности пообщаться голосом, можешь объяснить тут текстом две строчки из своего кода?
>return array_shift($usersWithEmail);
Почему тут array_shift
>$foundEmail = ($this->findEmail)($email);
Что означает эта строчка?
Не совсем понимаю для чего там вторая скобка.
В переменную foundEmail кладется ссылка на объект типа IFindEmail, а дальше я не понял.
А что если файл представляет собой объявление класса и пустое тело, потому что он наследует от общего класса?
Все также в отдельный файл?
Насчет второй строчки можешь не пояснять, я понял.
>У меня нет возможности пообщаться голосом
В крайнем случае поставь дискорд на мобилку и всего делов. А микро тебе в итоге все равно понадобится, и на собесы и по работе.
>Почему тут array_shift
Потому что коротко и делает в точности то что нужно - возвращает первый элемент или null если элементов нет. Да, в идеале нужно получить первый ключ через array_key_first, а потом вернуть значение по этому ключу и так технически будет на наносекунду быстрее.
>Что означает эта строчка?
Это обращение к функции внутри свойства объекта. Скобки позволяют не вызвать функцию findEmail(), а вызвать функцию внутри свойства (findEmail)().
>кладется ссылка на объект типа IFindEmail
Все правильно, просто объект типа IFindEmail работает как функция. Я уже писал зачем: чтобы не писать тавтологию типа $findEmail->findEmail().
>А что если файл представляет собой объявление класса и пустое тело
Это не имеет значение. Автолоадинг классов работает по psr-4, а по пср имя файла = имя класса, один файл = один класс, структура папок = неймспейс, и ничего кроме классов в приложении не существует. Че там у тебя внутри класса похуй абсолютли.
Иметь ссылку на объект другого класса считается?
>Потому что коротко и делает в точности то что нужно - возвращает первый элемент или null если элементов нет.
Меня немного смутило описание этой функции в документации, а именно, что она вырезает первый элемент массива и его возвращает и я гадал, а зачем его вырезать в данном случае.
В любом случае, спасибо, что ответил.
Если ты можешь написать класс, не видя другого класса и даже не зная его название, то значит, первый класс ничего не знает о втором.
Если же ты:
- используешь название другого класса в коде
- получаешь или возвращаешь его объект
- пишешь логику с учетом логики другого класса
То, получается, твой класс "знает" о другом.
Хорошо, спасибо за ответ!
Я не хочу идти ни в какие дискорды, потому что нам надо для этого в одно время быть на связи. Плюс, здесь в треде не останется никаких сообщений, а наверно другим людям тоже любопытно их почитать.
Вот у тебя есть 2 интерфейса, сделанных по твоей системе:
interface UserFinderByEmail
{
public function __invoke(string $email): ?User;
}
interface UserKarmaFinder
{
public function __invoke(User $user): int;
}
Как ты сделаешь класс, который реализует оба интерфейса одновременно? Это недостаток твоего подхода.
>>ты сделал метод "найти первого пользователя по email", но тут другая задача: проверить
> У хранилища нет никакой задачи ничего проверять. Проверяет валидатор. Вся суть примера в том что валидатору насрать кто и откуда вытащил этот емэйл, он сам интерпретирует его наличие или отсутствие. В этом примере вообще не важно как там валидация работает, там половина методов вообще заглушки с true.
Я тебе хотел написать, что ты неправильно реализовал проверку уникальности email, но ты, похоже, это понять не можешь.
>>объясни пожалуйста, зачем ты решил сделать интерфейсы, для которых существует только одна реализация и никогда не будет альтернативных реализаций?
> RuntimeUserStorage implements IUserStorage то есть хранилища в базе не будет "никогда"? А емэйлы "всегда" хранятся только в хранилище пользователей? Интересно откуда такие выводы.
В реальности будет только хранилище в базе и никаких RuntimeUserStorage не будет. В реальных приложениях (по моему опыту) обычно ровно одна реализация любого сервиса. Если вдруг завтра решать хранить юзеров в другом месте (в облаке где-то), то сделают новый класс, а старый удалят.
Не нарушаешь ли ты тут YAGNI? То есть, нам сейчас не нужно иметь несколько реализаций, но ты пишешь интерфейсы на случай "а вдруг в будущем понадобится".
Я не хочу идти ни в какие дискорды, потому что нам надо для этого в одно время быть на связи. Плюс, здесь в треде не останется никаких сообщений, а наверно другим людям тоже любопытно их почитать.
Вот у тебя есть 2 интерфейса, сделанных по твоей системе:
interface UserFinderByEmail
{
public function __invoke(string $email): ?User;
}
interface UserKarmaFinder
{
public function __invoke(User $user): int;
}
Как ты сделаешь класс, который реализует оба интерфейса одновременно? Это недостаток твоего подхода.
>>ты сделал метод "найти первого пользователя по email", но тут другая задача: проверить
> У хранилища нет никакой задачи ничего проверять. Проверяет валидатор. Вся суть примера в том что валидатору насрать кто и откуда вытащил этот емэйл, он сам интерпретирует его наличие или отсутствие. В этом примере вообще не важно как там валидация работает, там половина методов вообще заглушки с true.
Я тебе хотел написать, что ты неправильно реализовал проверку уникальности email, но ты, похоже, это понять не можешь.
>>объясни пожалуйста, зачем ты решил сделать интерфейсы, для которых существует только одна реализация и никогда не будет альтернативных реализаций?
> RuntimeUserStorage implements IUserStorage то есть хранилища в базе не будет "никогда"? А емэйлы "всегда" хранятся только в хранилище пользователей? Интересно откуда такие выводы.
В реальности будет только хранилище в базе и никаких RuntimeUserStorage не будет. В реальных приложениях (по моему опыту) обычно ровно одна реализация любого сервиса. Если вдруг завтра решать хранить юзеров в другом месте (в облаке где-то), то сделают новый класс, а старый удалят.
Не нарушаешь ли ты тут YAGNI? То есть, нам сейчас не нужно иметь несколько реализаций, но ты пишешь интерфейсы на случай "а вдруг в будущем понадобится".
А ты наверно не знаешь основы Линукс, не умеешь работать в командной строке?
Докер это всего лишь аналог легкой виртуальной машины. Ты получаешь пустой контейнер и пишешь команды, которые установят в него нужный софт.
Для начала достаточно основ, потом будет смотреть по карте, что нужно пхп разработчику.
Не вижу особой проблемы.
Он дольше будет искать полноценный курс, чем будет учить так.
Единственное, что можно полазать по сторонним сайтам с пхп темами, потому что ОП не разбирает некоторые темы, например, те же стрелочные функции или анонимные классы, или коллбэки.
>потому что нам надо
Не нам, а вам. У меня никаких проблем с этим нет. Если договорились быть в определенное время - я буду.
>Вот у тебя есть 2 интерфейса, сделанных по твоей системе
Не у меня, а у тебя.
>Как ты сделаешь класс, который реализует оба интерфейса одновременно?
Лол, ок. Меняем страшный непонятный invoke на понятный find https://3v4l.org/7oMPs . Стало можно?
Очевидно что проблема в том что класс, который ты хочешь написать пытается делать одновременно разные вещи. И тут всего два пути. Либо эти разные вещи начнут между собой согласовывать свой функционал, в виде запрета на одинаковые методы например. И становятся зависимыми друг от друга. Либо мы держим дядьку в киеве, а бузину в огороде и чай с кофе не смешиваем.
>Я тебе хотел написать, что ты неправильно реализовал проверку уникальности email
1) Хочешь написать пиши. Очередная причина почему эта переписка бессмысленная поебень, в которой собеседники больше половины написанного не понимают.
2) Мне ПОЕБАТЬ на правильность проверки, пример не про проверку вообще.
>В реальности будет только хранилище в базе и никаких RuntimeUserStorage не будет.
В тестах тоже будет в реальную базу лезть? Вообще при обычном запросе на сайт, даже без базы вообще, в пхп есть как минимум три разных персистентных хранилища данных. А с базами, кешами и эластиком под десяток вариантов будет.
>В реальных приложениях (по моему опыту)
Судя по тому как ты на invoke вылупился опыта маловато.
>Не нарушаешь ли ты тут YAGNI?
А откуда мне знать? Это просто очередной не формализуемый баззворд. Одному кажется что понадобится, а другому кажется что не понадобится. Мнение против мнения. А если нет объективного критерия, то и разговаривать не о чем.
Короче тут мы заканчиваем. Беседа закольцевалась, и начала повторяться. На третий круг я не пойду.
Да, хотя бы автоматическое закрытие тегов, выпадающий список цветов для css.
Я новичок, это мой первый серьезный опыт верстки сайта.
Так что профессионально разобрать разницу не смогу.
Просто немного устал от notepad, который максимум немного подсветит текст и немного дополнит вводимый текст.
Какое нахуй закрытие тегов. Кто блядь теги руками пишет вообще?
https://code.visualstudio.com/blogs/2017/08/07/emmet-2.0
>Кто блядь теги руками пишет вообще?
Я писал.
Признаю, что ручками делать это муторно.
Но я не писал ничего сложнее тестовых страниц, чтобы разобраться с теорией по html и css.
>теги руками пишет
А, блять...
Не так прочитал.
В любом случае, я новичок, который ничего серьезного не писал и знает html и css на общем уровне.
>теорией по html и css
>знает html и css на общем уровне
Бля, а что там за "теория" такая? Звучит как: знаю json на общем уровне.
>Бля, а что там за "теория" такая?
Ну, описывают тег и его атрибуты и идешь ручками писать это и смотреть результат в браузере. Все.
Для лучшего усвоения знаний.
Сейчас я на примитивном уровне понимаю от чего пахать при верстке страницы и что гуглить.
Ну и для того, чтобы все это стало реальными знаниями, я стараюсь теперь сверстать свою страничку.
>Что надо вводить в Сервер?
IDDQD
Обмылок, ты сервер с базой поднял? Вот его адрес и вводи, чучело.
Может быть блядь потому что ты пытаешься задать образ php контейнера внутри массива links?
Допустим ты слишком тугой чтобы прочитать правила форматирования yaml файлов. Так раздупли свои зенки на эти красные полоски, которые тебе ide высветила. Может тебе невдомек, но в нормально написанных файлах никаких красных подчеркиваний нет.
>так раздупли свои зенки на эти красные полоски, которые тебе ide высветила. Может тебе невдомек, но в нормально написанных файлах никаких красных подчеркиваний нет.
Ну я поэтому и спрашиваю че ему не нравится
>Ну я поэтому и спрашиваю че ему не нравится
По монитору стукаешь и кричишь: ты че епта?
Ide всегда пишет че там не так, его два раза спрашивать блядь не надо.
Для стриминга типа для непрерывной передачи данных между клиентами в течение длительного времени? Не подходит конечно, пыха такое не умеет.
Из коробки - нет, а используя расширение Parallel - да, легко и элегантно.
https://www.php.net/manual/en/philosophy.parallel.php
Еще из наиболее интересных расширений - Swow. Мощная штука.
https://docs.toast.run/swow/en/
Про множество других проверенных временем и всем известных расширений писать не буду.
localhost или 127.0.0.1
Не пускает скорее всего из-за неправильного имени пользователя или пароля.
Если ты умеешь пользоваться командной строкой, ты можешь проверить наличие доступа так:
mysql -u пользователь -p пароль -h 127.0.0.1
Этот файл в формате YAML. Тебе надо хотя бы в общих чертах изучить YAML сначала.
В данном случае, он пишет, что в строке 6 какой-то неправильный символ.
Одна из ошибок при работе с YAML файлами это использование табов вместо пробелов. Табы в YAML запрещены (и правильно).
Также, обрати внимание, что отступы важны в YAML. Ты не можешь просто так взять и поменять число пробелов в начале строки, так как они определяют вложенность пунктов.
Не перечень паттернов проектирования, а именно логику.
Про связанность, зависимости и т.д.
Сорри, промахнулся тредом
Спасибо, обязательно гляну
Спасибо. Это я тоже обязательно гляну.
Надо просто пятьдесят раз попытаться открыть несуществующий файл и он появится.
Бля, эта линукс эпопея как сериал из дурки. Как эти сцены из будущего в "12 обезьян". Какие-то ебанутые люди делают какие-то ебанутые вещи и уже непонятно это блядь реальность или троллинг. Реально ли он думает что раз написано что файла блядь нет, то на самом деле это значит он просто неправильно попросил?
Ты как будто смотришь через мутное стекло на полуслепого полуглухого сумасшедшего, который мечется в разные стороны пытаясь по мутным образам и странным звукам собрать что-то волшебное из тумана и дождя.
Ему кричат: не тот пакет. И он бежит сломя голову по лужам собирая целофановые пакеты.
Ему кричат: не та команда, проверь там-то и там-то. Он задирает к небу невидящие глаза и пытается из камушков и веток на ощупь выложить какие-то случайные слова, смысл которых не понимает. Слова не работают, магия не получается. И он с остервенением раз за разом перекладывает палочки в надежде на чудо.
В конце концов он не выдерживает и в припадке злобы расшвыривает палочки и кучи дырявых пакетов, пинает камушки.
И с обидой и непониманием кричит во тьму консоли: ГОСПОДИ, ЗА ЧТО?
public function SomeMethod();
сигнатура метода в классе, реализующем этот интерфейс:
public function SomeMethod($name="", $text="") {...};
Я не совсем понимаю, как программируя от интерфейса, а не от реализации, я должен не оставлять параметры метода пустыми.
Сомнение в том, что, вот клиент будет опираться на интерфейс, но в самом интерфейсе не указаны ни типы, ни параметры, ни тип возвращаемого значения.
>Сомнение в том, что, вот клиент будет опираться на интерфейс, но в самом интерфейсе не указаны ни типы, ни параметры
Очередная причина почему пхп - язык говна.
ДОЛЖНЫ быть указаны все типы у всех параметров. Если у тебя в интерфейсе указано что возвращаемое значение void, вернуть значение в имплементации у тебя физически не получится. И всякие ебанутые вопросы сразу отпадают.
Это-то понятно.
А как по-умному сделать?
Абстрактно я понимаю, что класс, реализующий определенный интерфейс, должен выполнять такие и такие методы. Если это абстракция, как я буду прописывать сигнатурку метода с указанием типов? А учитывая требование, что сигнатура из интерфейса и сигнатура из класс, реализующего этот интерфейс должны быть совместимы, приходится прописывать нужные параметры в виде значений по умолчанию.
>Для каждого правила делаем свой класс-валидатор. То есть, для проверки, что поле не пусто, один класс, для проверки, что там только цифры, другой класс и тд.
Не совсем понял тебя.
У меня есть поле name, оно должно пройти три проверки: на пустоту, на минимальное и максимальное количество символов и на то, что оно содержит только определенные символы.
Мне нужно создать три класса-правила:
1. Класс, который проверяет поле name на пустоту;
2. Класс, который проверяет количество символов поле name;
3. Класс, который проверяет качество символов поле name.
? //и, конечно, аналогично для всех остальных полей
Или же у меня должно быть только 4 класса-валидатора
(проверка на пустоту, проверка на количество, проверка на качество и проверка на уникальность емайла - которые работают по всем полям формы, кроме тех, где нужно выбирать флажок)?
//Правила...валидатора, короче, не обращай внимание на название.
>как я буду прописывать сигнатурку метода с указанием типов?
Руками. Какая-то пустопорожняя болтовня. Вот тебе конкретный пример https://3v4l.org/FcbPh . Нахера выдумывать какие-то опциональные параметры, какую-то хуйню, малафью?
А еще класс, который будет содержать ошибку валидации. Класс- exception на случай если все сломается. Класс, который будет содержать все правила валидации, проходить по ним и собирать все ошибки. И класс, который будет создавать класс, в котром будут все нужные правила валидации. Надо ведь как-то определять какие правила валидации нужны и куда там какие доступы к базам и хелперы прокидывать.
Добро пожаловать в мир ООП.
>Если интерфейс это контракт
>сигнатура метода в интерфейсе
>public function SomeMethod();
тогда
>сигнатура метода в классе, реализующем этот интерфейс:
>public function SomeMethod($name="", $text="") {...};
нарушает данный контракт, так как ничего не сказано про параметры в сигнатуре метода интерфейса.
>интерфейс это контракт
Интерфейс - абстрактное понятие. Это не фича языка. Можно писать абстрактные интерфейсы с помощью одних только функций. Они будут выполнять ту же самую функцию.
$point1 = makePoint(1, 2);
Функция makePoint является интерфейсом для абстракции точка. Нет необходимости знать как она реализована. Главное, что она моделирует точку на координатной плоскости с помощью значений координат x и y.
Допустим необходима абстракция User.
<?php
// Online PHP compiler to run PHP program online
// Print "Hello World!" message
function makeUser($name, $birthday)
{
return [
'name' => $name,
'birthday' => $birthday
];
}
function getAge($user)
{
return calculateAge($user['birthday']);
}
function isAdult($user)
{
return getAge($user) >= 18;
}
function calculateAge($birthday)
{
$secondsInYear = 31556926;
return floor((time() - strtotime($birthday)) / $secondsInYear);
}
$user1 = makeUser('Vasya', '18.05.1996');
print getAge($user1);
Вот рабочий пример https://onlinephp.io/c/b1b5d
Таким образом можно реализовать любую сложную логику.
>интерфейс это контракт
Интерфейс - абстрактное понятие. Это не фича языка. Можно писать абстрактные интерфейсы с помощью одних только функций. Они будут выполнять ту же самую функцию.
$point1 = makePoint(1, 2);
Функция makePoint является интерфейсом для абстракции точка. Нет необходимости знать как она реализована. Главное, что она моделирует точку на координатной плоскости с помощью значений координат x и y.
Допустим необходима абстракция User.
<?php
// Online PHP compiler to run PHP program online
// Print "Hello World!" message
function makeUser($name, $birthday)
{
return [
'name' => $name,
'birthday' => $birthday
];
}
function getAge($user)
{
return calculateAge($user['birthday']);
}
function isAdult($user)
{
return getAge($user) >= 18;
}
function calculateAge($birthday)
{
$secondsInYear = 31556926;
return floor((time() - strtotime($birthday)) / $secondsInYear);
}
$user1 = makeUser('Vasya', '18.05.1996');
print getAge($user1);
Вот рабочий пример https://onlinephp.io/c/b1b5d
Таким образом можно реализовать любую сложную логику.
Я думаю, что мы друг друга не понимаем.
Я пишу валидацию.
Что должен делать валидатор?
Абстрактно - взять информацию, проверить ее по своему алгоритму, сообщить результат проверки/что-то сделать с результатом проверки.
Т.е. интерфейс для классов-валидаторов будет такой:
Метод, который забирает значение, которое нужно проверить;
Метод, который проверяет по своему алгоритму;
Метод, который что-то делает с результатом проверки.
Если держать в уме, что код должен проектироваться так, чтобы он оставался гибким, то как я могу указывать типы/параметры в сигнатурах методов в интерфейсе?
Сейчас метод, который что-то делает с результатом проверки просто записывает текст ошибки, т.е. его параметр - текст ошибки и куда его вписать. По такой логике я могу вписать в интерфейс эти параметры. А что если бы завтра я хотел бы иначе что-то другое делать с результатом проверки? И параметры тогда могли бы поменяться.
Я не считаю себя правым в этом диалоге, просто излагаю свою вкатунскую логику, чтобы опытные аноны могли указать мне на ошибки.
Контракт это более широкое понятние, чем интерфейс. Контракт может, например, включать в себя условия вроде "функция вернет число от 1 до 5", он обычно пишется для людей. А интерфейс это просто список методов, которые надо реализовать, и проверяется машиной.
> Я не совсем понимаю, как программируя от интерфейса, а не от реализации, я должен не оставлять параметры метода пустыми.
Ты не можешь передавать эти параметры, так как они не описаны в интерфейсе. Представь, что ты никогда не видел реализацию (или видел, но сеньоры уже успели ее переписатьи твои знания устарели).
То есть, ты можешь только вызывать someMethod() без параметров и все. Передавать в него что-то ты не имеешь права.
Ты невнимательно прочел пост. В интерфейсе указан метод без параметров. В реализации параметры добавлены, но со значениями по умолчани, что не нарушает требования интерфейса. В такой ситуации ты не имеешь права передавать эти параметры, если у тебя стоит в тайп-хинте интерфейс.
Так что читай внимательнее, прежед чем что-то вякать в сторону PHP.
> 1. Класс, который проверяет поле name на пустоту;
Нет, класс, который проверяет любое поле на пустоту. Он ничего не знает про поля и их названия. И мы можем этот класс использовать для нескольких полей.
Главный класс, который знает правила валидации (что к полю X надо применить правила Y и Z) как раз и будет брать нужные поля и передавать их в нужные классы.
> Функция makePoint является интерфейсом для абстракции точка.
Не согласен, интерфейс не содержит кода, а лишь описание функций и их параметров.
Окей, спасибо за ответ.
Идея, которую я предлагал где-то выше, заключается в том, чтобы разделить функционал "проверить данные формы" на части:
- есть классы-проверятели-правил, которые проверяют соответствие одного значения одному правилу (переданная строка не длиннее 10 символов)
- и есть главный класс, который содержит список правил и который берет по очереди каждое поле и проверяет его с помощью объектов-правил
Не очень понимаю, при чем тут интерфейсы. Если тебе хочется сделать интерфейс для классов, проверяющих правила, то он будет выглядеть как-то так:
interface RuleValidatorInterface
{
public function validate($value): ?Error;
}
> Метод, который забирает значение, которое нужно проверить;
Не нужно его делать. Класс-правило не должен ничего сам забирать, ему дадут уже готовые данные для проверки.
> Метод, который что-то делает с результатом проверки.
не нужен.
> А что если бы завтра я хотел бы иначе что-то другое делать
Тогда переделаешь код. Не надо пытаться предусмотреть все случаи на свете заранее.
Вот что-то пришло - обработать - раздать.
По NFS сетевые папки монтируют и тупо туда сохраняют? Еще слышал что с помощью Go пишут нечто подобное. Ну и взрослые компании S3 для этого используют?
>Тогда переделаешь код. Не надо пытаться предусмотреть все случаи на свете заранее.
А как же принцип открытости-закрытости?
Мимо другой, очень гибкие системы тоже не ок, особенно там где не нужно. От случая короче.
Немчинского послушай все плейлисты по рефакторингу, там много инфы
>Не согласен, интерфейс не содержит кода, а лишь описание функций и их параметров.
Ты не в теме. Почитай что нибудь. В СИКП это есть. Обобщенно, интерфейс - не языковая конструкция. Почитай про абстракцию данных. Конструктор, геттер, сеттер - тоже не языковая конструкция. Это все абстрации для построения АТД (абстрактных типов данных). Все это появилось задолго до появления этих языковых конструкций в языках, в том числе классов.
Все это реализуется на любом языке имеющем функции высшего порядка. И реализуется очень элегантно, безо всякой чепухе как в языках с классами.
http://aliev.me/runestone/Introduction/WhyStudyDataStructuresandAbstractDataTypes.html
В продожение... Интерфейс, как видно на этой картинке >>919251 обозначает операции. Над ядром, которое реализует тип данных. Посмотри на библиотеки. Говорят, что они имеют интерфейс. Что является их интерфейсом? Функции, которые выставлены наружу, чтобы использовать код библиотеки в других проектах. Интерфейс - операции над данными, а в конструкциях языка - просто функции.
Можно конечно из этого слепить интерфейс как языковую конструкцию, или налепить сверху классы, но это будут просто обертки. Суть не изменится.
Спросил у яндекса. А может реально по http, guzzle клиентом каким-нить и пост запросом с токеном между своими серверами? Или хуйня? Допустим видос 2гб нужно обработать
Внимательный окурок, я конечно понимаю что ты ни на пхп ни на каком либо другом языке не пишешь.
Однако, пидор тупой, не мог бы ты, перед тем как открывать свое тупое гнилозубое ебало, открыть редактор, написать в нем пару строчек кода и проверить то о чем ты собрался пиздеть?
Я понимаю что дохуя прошу, потому что, как выше упомянул, ты на пхп не пишешь и тебе такое тяжело.
Поэтому Вот тебе, тупорылый хуесос, разница между
"ты не имеешь права" https://3v4l.org/inEfe в говноязыке всем на твои права поебать
и
"в этом методе нет блядь аргументов" https://www.onlinegdb.com/_8IKCM2VL в нормальном языке ты действительно можешь писать open/closed код и что-то там пиздеть про солид.
>Я думаю, что мы друг друга не понимаем.
>Я пишу валидацию.
Это я пишу. Я не видел от тебя ни одного листинга с рабочим кодом.
>Т.е. интерфейс для классов-валидаторов будет такой:
Показывай реальный код, а не маняфантазии на тему.
>то как я могу указывать типы/параметры в сигнатурах методов в интерфейсе?
Может выйти в интернет с таким вопросом? "Должны ли в интерфейсах указываться параметры функций" это на новый подход в программировании тянет не меньше. Может и в имплементациях параметры не писать? Использовать func_get_args(), будет очень гибко. Если только тип не писать, то можно вместо емэйла коннекшен к базе передать, а так вообще все что угодно в каких угодно количествах. Красота.
>Сейчас метод, который что-то делает с результатом проверки просто записывает текст ошибки
Опять без кода не понятно что происходит. "записывает"? Куда записывает? В файл? На стену?
>А что если бы завтра я хотел бы иначе что-то другое делать с результатом проверки? И параметры тогда могли бы поменяться.
Опять без кода непонятно в чем проблема. Берешь результат проверки и делаешь с ним другое. Валидатор тут причем?
Ну хуй знает, может в специальное хранилище? Мне кажется это слишком специфическая задача, никто такое не делал никогда.
>надо будет писать какой-то главный модуль, который будет парсить url, в данном случае /video и отправлять нужному обработчику?
Да не, не надо.
Более 3 лет опыта PHPшником, одно говно только на галеры(аутстафф).
Последнее место работал на запад за евро на продукте, сейчас приходится говнище наше перебирать, делайте выводы :)
На западе вообще даже не рассматривают уже.
Не думал что скачусь до наших анальных галер опять, лол. Придётся брать что есть и попутно следующие пол-года искать нормальное что-то.
Сейчас у тебя роутингом занимается веб-сервер (Апач, например). То есть, приходит запрос /watch/video.php?id=123 и Апач вызывает скрипт watch/video.php
Ты можешь перенастроить его так, чтобы любой запрос обрабатывал один скрипт, например, index.php. Но разбирать URL тебе придется самому. То есть, тебе надо написать или взять готовую библиотеку-роутер.
Простейший роутер пишется примерно так:
if (preg_match("!^/video/([0-9]+)$!", $path, $m)) {
$videoId = $m[1];
require 'video.php';
return;
} else ...
А по деньгам предлагают хоть?
Нет.
private B $child;
public function __construct () {
$this->child = new B();
????????
$this->child->act();
}
}
class B {
private Cone|Ctwo $childchild;
public function act () {
$this->childchild = new ????????
}
}
Как сделать подобную фигню? Чтобы в классе A я мог указать, внутри B использовать Cone или Ctwo.
1) У тебя B нихуя не child, наследования нет.
2) Если A знает про содержимое B, то нахуй тебе вообще посредник в виде B? Пусть будет A и содержимое.
3) Ты можешь указать что использовать буквально передав Cone или Ctwo в конструктор B или в метод act.
1. Нужно было назвать govno и mocha, ладно.
2. Чтобы класс A не представлял из себя гигантскую портянку?
3. Как? Мне нужно именно что-то типа
$this->child->useCone();
Или там $this->child->cType("Cone");
Или как там ещё.
$this->child->act(new Cone);
Не подойдёт явно, потому что там должно быть new Cone(value), которое вычисляется в классе B. Короче, как мне сделать что-то типа
class A {
private B $child;
public function __construct () {
$this->child = new B();
$this->child->Ctype = "Ctwo";
$this->child->act();
}
}
class B {
public Ctype = "Cone";
private Cone|Ctwo $childchild;
public function act () {
$this->childchild = new {$this->Ctype};
}
}
1. Нужно было назвать govno и mocha, ладно.
2. Чтобы класс A не представлял из себя гигантскую портянку?
3. Как? Мне нужно именно что-то типа
$this->child->useCone();
Или там $this->child->cType("Cone");
Или как там ещё.
$this->child->act(new Cone);
Не подойдёт явно, потому что там должно быть new Cone(value), которое вычисляется в классе B. Короче, как мне сделать что-то типа
class A {
private B $child;
public function __construct () {
$this->child = new B();
$this->child->Ctype = "Ctwo";
$this->child->act();
}
}
class B {
public Ctype = "Cone";
private Cone|Ctwo $childchild;
public function act () {
$this->childchild = new {$this->Ctype};
}
}
>Чтобы класс A не представлял из себя гигантскую портянку?
А щас там не портянка? Вся нутрянка класса B итак в A.
>потому что там должно быть new Cone(value), которое вычисляется в классе B
Так а хули ты об этом не написал?. Какие-то блядь childchild'ы какой-то блядь act.
Короче .
Ты либо рассказываешь что конкретно ты делаешь, без бессмысленных A Б В. Либо так и будешь класс из строчки создавать и портянки наматывать.
Пиздец обфускатор ебать.
В PHP же есть неблокирующие сокеты? Почему тогда считается и везде пишут, что в PHP нет неблокирующего ввода-вывода?
При чем здесь вакансии? PHP язык программирования или что? Заглянул сейчас в гайд из шапки, не увидел ни слова про модель выполнения кода виртуальной машиной PHP. И в книгах об этом не пишут. По факту получается, что пхпшник даже не понимает как исполняется код. Это не программирование, а макакинг. Как без сокетов реализуешь вебсокет сервер?
>При чем здесь вакансии?
Вакансии это места где язык используют для зарабатывания денег. Нет вакансий в которых нужны знания сокетов = никто этой хуйней не пользуется.
>Заглянул сейчас в гайд из шапки, не увидел
Гайд из шапки написан аноном за бесплатно году в 2012. Чтобы помочь другим анонам заработать копеечку. zval'ы op'коды и прочая дрисня там не нужна.
По факту получается что пхп говно язык и на это куча причин. Но ты слишком тупой жирный хуесос и кормить тебя тут не будут.
Ладно, упрощу свой вопрос в 10 раз.
use Foo\Bar\MyYobaClass;
// ...
$className = "MyYobaClass";
$obj = new $className;
// PHP Fatal error: Uncaught Error: Class "MyYobaClass" not found
У меня есть варианты, кроме
$className = "Foo\Bar\MyYobaClass";
, Что мне нужно написать, чтобы вместо
use Foo\Bar\MyYobaClass;
// ...
$obj = new MyYobaClass();
Я смог
use Foo\Bar\MyYobaClass;
// ...
$className = "MyYobaClass";
$obj = new $className(); // ????
$className = MyYobaClass::class;
>use Foo\Bar\MyYobaClass;
>// ...
>$className = "MyYobaClass";
>$obj = new $className();
Работает, если создать класс в этом же файле
>class MyYobaClass{...}
>$className = "MyYobaClass";
>$obj = new $className();
Значит проблема именно в use, он не подтягивает из MyYobaClass из другого файла.
Попробуй использовать require вместо use.
Нет, это неправильно. Надо разделять ответственность между частями приложения. Допустим, у тебя есть приложение для скачивания и преобразования картинок с кучей настроек.
Мы делаем отдельно:
- модуль для скачивания картинок
- модуль для преобразования (изменения размеров, добавление водяных знаков итд)
- модуль для сохранения (в разных форматах с разным качеством)
Эти модули не должны знать ничего про аргументы командной строки. У них есть свои настройки, и они либо передаются напрямую (если их мало) или в виде объекта настроек. Модулю все равно, откуда пришли эти настройки - из аргументов, из конфига, из переменных окружения или из базы данных. Например, для модуля скачивания можно сделать класс настроек:
class DownloadSettings
{
private int $maxSpeed;
private array $proxies;
private int $timeout;
...
}
В основной программе ты разбираешь аргументы и создаешь настройки для каждого модуля.
> Заглянул сейчас в гайд из шапки, не увидел ни слова про модель выполнения кода виртуальной машиной PHP.
Я думаю, что надо написать, что код выполняется последовательно, строчка за строчкой, кроме случаев ветвлений и циклов. Этого наверно будет достаточно?
Это практически всегда плохая идея, передавать имя класса вместо объекта. Возможно, пришло время использовать какую-нибудь Фабрику тут. То есть, ты передаешь в конструктор одну из двух Фабрик, чтобы выбрать, какой объект надо создать.
Имя пользователя либо пароль неправильные, либо в MySQL запрещен доступ для этого пользователя. Надо подсоединиться к MySQL из командной строки и просмотреть права пользователей. Если и из командной строки не подключиться, то надо сбросить пароли для root.
1280x720, 0:07
>не надо упрощать и редуцировать, нужны детали и реальное назначение классов
>Ладно, упрощу свой вопрос в 10 раз.
>Этого наверно будет достаточно?
Надо написать, что модель выполнения PHP-процесса отличается от модели выполнения процессов на других языках. Что PHP-процесс всегда умирает после выполнения. Что в других языках не требуется внешний процесс (Apache, Nginx, etc) для запуска виртуальной машины. И какие это дает ограничения. Вообще нужно про всю историю и подноготную PHP написать, про CGI и прочее.
Зачем?
Ты менял пароль? Там по умолчанию вроде пустая строка
Какие проблемы?
Создаешь пустой класс. В нём описываешь все поля и типы в пхп доке. Указываешь типом декодированного объекта.
Дока по схеме есть, подсветка типов и комментов в коде есть. Автокомплит есть. Вы великолепны.
А что с массивами ебучими? Доки нет. Названия каждый раз руками писать. Опечатку никто не подсветит. Автокомплита тоже нет, писать руками обработку массива элементов на двадцать сомнительное удовольствие.
То, что ты описываешь это не "модель выполнения PHP", а лишь особенности работы PHP в составе Apache или PHP-FPM. Учебник же посвящен основам языка PHP.
> Что PHP-процесс всегда умирает после выполнения.
Любой процесс умирает после выполнения, хоть на Си, хоть на bash.
> Что в других языках не требуется внешний процесс (Apache, Nginx, etc) для запуска виртуальной машины.
В PHP ты можешь тоже сам написать сервер и не пользоваться ни Apache, ни nginx.
> И какие это дает ограничения.
Не понимаю, какие. Скорее плюсы, вроде отсуствия утечек памяти, наличия stateless обработчиков запросов (почти как функциональное программирование).
> про CGI
CGI годов с 90-х никто уже не использует. Может, ты имел в виду FastCGI, но это совсем другой протокол.
Нету. Сам по себе stdClass абсолютно дурацкая идея и я никому не советую им пользоваться. Потому что это как массив, но без удобных функций для работы с ним.
Ты делаешь какие-то кривые костыли. Реально там возвращается объект stdClass, а ты зачем-то присваиваешь ему фейковый класс и твоя кривая IDE не видит тут ошибки. Например, если в твой класс добавить метод, то он не появится у объекта.
stdClass хуже чем массив, так как для работы с ним нет удобных функций.
Надо либо описывать структуру массива (и тогда IDE увидит нужные поля):
/**@var array { age: int, name: string ... } */
Либо использовать десериализатор, который реально преобразует JSON в нужный объект.
И еще с твоим подходом не будет работать валидация в Симфони: если ты добавишь аннотации для валидаторов в класс UserJson, то валидатор Симфони их не увидит и не применит.
>Надо либо описывать структуру массива (и тогда IDE увидит нужные поля)
Ебанько, то что ты написал это psalm формат. Phpdoc из коробки не поддерживает описания массивов.
Ты делаешь абсолютно то же самое, только с помощью сторонних либ. Ты берешь декодированный массив и делаешь вид что у него "фейковое содержимое" соответствующее твоему комменту.
А разница в том, что у меня полноценное описание параметров с комментариями подтипами и вложенностью. Я могу описать условный json "адрес" и переиспользовать его в десяти эндпоинтах, а с массивами придется вдрачивать его полную структуру везде руками. Читать описание массива элементов из двадцати будет просто уебищно, где заканчивается одно, а начинается другое хуй разлепишь - все одинаковое.
Потому что psalm предназначен не для ОПИСАНИЯ, а для ПРОВЕРКИ. Автоматической причем. Эти комментарии очень полезны если ты используешь стат анализатор, они ГАРАНТИРУЮТ что содержимое массива именно такое как описано. Но читать их человеку неудобно и нахуй не нужно, это для машин. Да и сам pslam используют единицы.
>stdClass хуже чем массив, так как для работы с ним нет удобных функций.
И этой функцией был альберт эйнштейн?
>>925381
>И еще с твоим подходом не будет работать валидация в Симфони: если ты добавишь аннотации для валидаторов в класс
А с массивом очень легко добавить аннотации в класс. Ты совсем ебнулся, чучело? Валидируется модель. А это обычная dto с хуй пойми чем. Вот когда из этой dto будет создаваться модель пользователя, тогда и будет валидация.
>То, что ты описываешь это не "модель выполнения PHP", а лишь особенности работы PHP в составе Apache или PHP-FPM.
Это особенность работы виртуальной машины Zend Engine. Она фактически построена на принципах работы CGI. Для запуска виртуальной машины требуется SAPI.
Интерфейс программирования серверных приложений (SAPI) — это точка входа в Zend Engine.
Цитата из исходников PHP
https://github.com/php/php-src/tree/master/sapi/embed#the-embed-sapi
Все языки общего назначения кроме PHP, запускают веб-приложения безо всяких SAPI, просто передавая на вход движку файл с кодом. Zend Engine без SAPI не работает. Он рассчитан на модель запрос-ответ, после которого процесс умирает. Поэтому приложение с каждым запросом полностью подгружается в оперативную память. Из-за чего придумали всякие костыли, чтобы хоть как-то снизить этот оверхед. Данные между веб-сервером и приложением передаются через STDIN/STDOUT.
В других языках процесс не умирает, а продолжает принимать запросы. Веб-сервер и приложение работают в одном процессе и не используют STDIN/STDOUT/
Почитай PHP Internals или послушай Дмитрия Стогова, ведущего разработчика движка, он об этом говорит.
https://wiki.php.net/internals
https://www.phpinternalsbook.com/
> ты написал это psalm формат.
Не только psalm, но и phpstan его поддерживает, и открытые PHP-серверы LSP вроде phpactor. Если твоя проприетарная IDE его не понимает, это не моя проблема.
> Phpdoc из коробки не поддерживает описания массивов.
не моя проблема.
> Ты делаешь абсолютно то же самое, только с помощью сторонних либ. Ты берешь декодированный массив и делаешь вид что у него "фейковое содержимое" соответствующее твоему комменту.
В случае с десериализатором он генерирует настоящие объекты, с полями и методами.
> А с массивом очень легко добавить аннотации в класс.
Ну так при использовании десриалайзера ты получаешь объект, а не массив.
Короче, хватит тормозить. Ты, по моему, просто не работал с десериалайзерами и не понимаешь, о чем речь.
Не тупи. Во-первых, CGI давно уже нету. Во-вторых, ты точно так же можешь на PHP открыть порт, принять запрос и руками его распарсить и у тебя будет точно такой же сервер, как на Питоне или Руби, даже лучше.
> Данные между веб-сервером и приложением передаются через STDIN/STDOUT.
Еще раз говорю, CGI устарело, в php-fpm давно используют FastCGI. Почитай что-нибудь современное.
> Он рассчитан на модель запрос-ответ, после которого процесс умирает.
В случае php-fpm один процесс обрабатывает множество запросов. "умирает" только PHP-код, там очищаются переменные, и другие структуры, но сам PHP-процесс давно уже не умирает после каждого запроса. И опять же, ты можешь просто написать свой сервер и запускать его из CLI и он будет работать столько, сколько тебе нужно.
То есть, в других языках у тебя один вариант: писать свой FastCGI- сервер. В PHP у тебя выбор: либо писать свой FastCGI-сервер, либо использовать тот, что встроен в php-fpm и позволить ему очищать перемнные и память после каждого запроса, следить за таймаутом и лимитами по памяти и тд.
Даже в Википедии написано :
> В то время как CGI-программы взаимодействуют с сервером через STDIN и STDOUT запущенного CGI-процесса, FastCGI-процессы используют Unix Domain Sockets или TCP/IP для связи с сервером.
Ты опираешься на устаревшую информацию. В PHP-FPM поднимается N процессов-воркеров и Nginx распределяет между ними поступающие запросы. И никто процесс PHP после каждого запроса не завершает.
И еще скопирую для тебя из Википедии:
> FastCGI снимает множество ограничений CGI-программ. Недостаток CGI-программ — в том, что они должны быть перезапущены веб-сервером при каждом запросе, — что приводит к понижению производительности. FastCGI (вместо того, чтобы создавать новые процессы для каждого нового запроса) использует постоянно запущенные процессы для обработки множества запросов; это позволяет экономить время.
>Ну и СИКП конечно же (без шуток).
Начал с этой книги, книга ведь не о том, чтобы научить меня языку программирования лисп? Да, ведь?...
С каждой страницей мне хочется избить человека, который отвечал за всю ту воду, которая есть в книге. О своей важности-хуяжности автор мог поразмышлять в своей голове.
>десериализация в объекты лучше по этому и вот поэтому
>массивы неудобная хуета вот поэтому и поэтому
>а вот десериализаторы
Просто срыгни, попущ.
Как ты не верти сракой, а преобразование json'а в объект лучше чем в массив. Точка.
>CGI давно уже нету
Что значит нету? Принципы CGI встроены в ядро PHP. Движок PHP рассчитан на работу по модели CGI, чтобы его запускал внешний процесс веб-сервера, он отдавал результат и PHP-процесс умирал. PHP в режиме CGI по прежнему на любом виртуальном хостинге.
>ты точно так же можешь на PHP открыть порт, принять запрос и руками его распарсить и у тебя будет точно такой же сервер, как на Питоне или Руби
Не будет. В Питоне и Руби такой режим работы предусмотрен изначально, для этого есть необходимые либы. В PHP ничего кроме голых сокетов нет. К тому же процесс будет снова умирать, нужно лепить костыли.
>в php-fpm давно используют FastCGI
И что? Ядро PHP по прежнему работает по другому.
>"умирает" только PHP-код
О чем я и пишу. Движок запускается, а потом умирает. Это его модель работы. По этому причине, долгоживущие приложение создавать без костылей нельзя. Так работает только PHP.
>>926811
Процесс PHP-FPM и процесс запущенного приложения это отдельные процессы?
Суть есть в том, что лисп даже учить не надо, он элементарный и за счет его простоты учить программированию. Если бы ты выбрал аналогичную книгу на js/python/php/c++/c/<языкнейм>, то пришлось бы сначала посвещать тебя в язык, а не суть.
Лисп это сверхвысокоуровневый язык. Не смотря на то, что программа на нем выглядит на AST. Он позволяет не думать о языке и его ограничениях, а сконцентрироваться на данных, на задаче.
Приложение запускается на каждый запрос. Это модель работы CGI. То есть главный недостаток CGI не устранен. Кроме того, PHP-FPM не развивается уже 10 лет. За это время появились высокопроизводительные интерфейсы, вроде io_uring. По этим причинам у приложений с PHP-FPM очень низкая производительность, 10k RPS недостижимая емкость.
>FastCGI снимает множество ограничений CGI-программ. Недостаток CGI-программ — в том, что они должны быть перезапущены веб-сервером при каждом запросе, — что приводит к понижению производительности. FastCGI (вместо того, чтобы создавать новые процессы для каждого нового запроса) использует постоянно запущенные процессы для обработки множества запросов; это позволяет экономить время.
После запроса процесс не умирает, но все состояние уничтожается. При следующем запросе приложение нужно заново поднимать.
> В Питоне и Руби такой режим работы предусмотрен изначально, для этого есть необходимые либы. В PHP ничего кроме голых сокетов нет
Не пиши, о чем не знаешь. Для PHP точно так же есть "либы".
Он "элементарный" только в плане минимализма синтаксиса. Во всем остальном он сложнее и неудобнее того же Питона. В Питоне ты хотя бы математические выражения можешь писать нормально и скобок сотни не надо ставить.
> 10k RPS недостижимая емкость
То же можно сказать про Ruby on Rails, например.
10k RPS чаще всего бывает в дурацких тестах, которые отдают фразу hello world. У реальных приложений немного другой профиль, и там часто 100 RPS уже проблема. Сталкивался с подтормаживаниями и в проектах Яндекса, и Сбера, а они вроде не на PHP написаны.
Ты можешь написать приложение, которое не перезапускается. С PHP у тебя есть выбор, в отличие от других языков. Если ты не осилил, как это сделать, то это проблема твоего уровня образования, а не проблема PHP.
Специально померял, страница Яндекс-Маркета с товаром грузится 230 мс, весит 2,29 Мб (ужато до 400Кб). Может, конечно, виноват мой небыстрый Интернет, ну пусть она 100 мс грузится на быстром.
Объясни мне, как Маркету обеспечить 10k RPS в таких условиях? Не в дебильном тесте на отдачу текста hello world, а в реальном коммерческом приложении? Какой язык позволит это сделать?
Типа перезапуск приложения на каждом запросе это мелочи? К сожалению, сообщество у PHP соответствующее языку.
>>927351
Какие?
>>927355
Так это целые рельсы не могут 10k RPS, а тут голый PHP-FPM не может. Позорище. Последний коммит 10+ лет назад был. Давно пора выкинуть это легаси.
>>927356
С помощью чего?
>>927360
Это не аргумент, это их проблемы.Емкость приложения в 10k давно уже стандартное требование. Это вообще мелочи. Например, uwebsockets может тянуть 1 миллион нагруженных соединений на одном ядре. Так что 10k это детский лепет. А FPM и того не может.
>Емкость приложения в 10k давно уже стандартное требование
Какого приложения? От кого требование? Мудила, ты понимаешь что разные приложения делают разные вещи на разном железе? Если твое приложение, например, картинки форматирует, то ты хоть обосрись, а rps от затраченного процессорного времени зависеть будет. Если процессор тянет одновременную обработку только ста картинок, то хуй тебе в нос, а не 10к rps.
>может тянуть 1 миллион нагруженных соединений на одном ядре
Куда тянуть? Куда тянуть, сука ты тупая? Какая нахуй разница сколько там соединений если ядро загружено на сто процентов и один хуй процессор все это переварить не может? Какая нахуй разница сколько там соединений встало колом? Это просто означает что вместо того чтобы обслужить сколько можешь по очереди, ты заставляешь весь миллион пользователей сидеть ждать весь миллион.
Говна кусок
>процессор все это переварить не может
Тупой говна кусок
https://github.com/uNetworking/uWebSockets.js
https://unetworkingab.medium.com/millions-of-active-websockets-with-node-js-7dc575746a01
Миллион работающих соединений. Это сетевой стек, на котором работают крупные мировые биржи.
Ты так и будешь искать оправдания или что?
Вебсокет сервер в Bun построен на uwebsockets, говна ты кусок.
https://bun.sh/docs/api/websockets
>>927504
Кончелыга, никто не сомневается что твоя js дрисня существует. И никто не сомневается что сами по себе сокеты не грузят проц на сто процентов.
Только ты, тупорылый еблан, забыл что сервера выполняют полезную нагрузку. Никому не обосрались миллион сокетов, которые нихуя не делают. А как только сервер начнет делать хоть что-то, именно эта работа и станет узким горлышком, а не количество блядь сокетов, клоун ебаный.
А по поводу "мировых бирж". Смешная "маленькая" московская биржа, которую кастрировали и превратили в местную "кухню" хостися в "двух залах по 72 стойки серверов, 500м²". Макака тупорылая, ты со своей ссылкой на "6-year-old laptop" в этом зале заблудишься и умрешь от голода и холода.
Обосрался, говнюк, а теперь оправдываешься. Это не просто вебсокеты, а работающие вебсокеты. Код в открытом доступе, запусти и покажи если не так. В противном случае заткнись.
uWebsockets один из самых известных и топовых проектов на C++. А ты просто кукарекаешь.
https://github.com/uNetworking/uWebSockets
На Битриксе всегда потогонка ебаная? Вкатился пару месяцев назад что-то обомлел. Задачи заранее оценены лидом - 5 часов, 7 часов и т.д. Я не укладываюсь совсем, могу несколько дней просидеть, из-за этого куча стресса.
Да не слушай их, есть в пхп релокейт через любую галеру, и пхп это база веб-разработки.
1) Фронтенд. Знать и учить надо гораздо меньше. А вакансий больше. Потому что вротеэнд нужен для любого языка. Сейчас даже для десктопных приложений js используется, даже для игр.
2) Мобильная разработка. Рисуешь экранчики и никто не ебет тебя солидами хуелидами на собесах. А платят гораздо больше чем за пхп код.
3) Нормальные энтерпрайз языки. Шарп, жаба и производные. Будешь рисовать те же опердни для корпоратов, только за гораздо больший прайс.
Этот тред уезжает в архив. Не забывайте свои вещи в вагоне.
Вы видите копию треда, сохраненную 24 января в 08:52.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.