Это копия, сохраненная 15 февраля 2022 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Оформляйте код аккуратно.
Учебник - https://codedokode.github.io/phpbook
ОП-паста - https://pastebin.com/gzQ8bGm0
Если рассчитываешь получить дельный ответ, сформулируй правильно вопрос: «что я хочу получить, что я для этого делаю, что я вместо этого получаю». Если когда самостоятельно найдёшь решение — поделись в треде, мы за тебя переживаем.
PHP developer roadmap - https://miro.com/app/board/o9J_lbUUBBQ=
Карта знаний - https://docs.google.com/spreadsheets/d/1KvoibcMHrRxck9mV6UPGHZ9ysnAFEIGddo3OuJTrx1k
оп хуй
Или из всех похапешников только один умеет перекатывать треды?
Подскажите, зачем использовать reverse proxy в связке Nginx + Apache, почему одного Nginx не достаточно, он же может обрабатывать и статику и работать с php-fpm? Скорость работы с динамическим контентом у Nginx и Apache сопоставимая, в чем преимущества одновременного использования обоих серверов?
А сейчас: заходишь в тред и надо делать лишний клик, идти на какой-то сторонний сайт, на котором текст написан плохо читаемым моноширинным большим шрифтом.
Причем половина человек никуда не бует переходить и будет задавать платиновые вопросы в очередной раз.
В чем смысл? Ты сделал неудобно читателям треда. Это глупость - выносить шапку треда с часто задаваемыми вопросами на посторонний сайт.
Объясните, какой смысл выносить шапку на посторонний сайт. Чем это удобнее?
Но там все устаревшее и обновлялось, в лучшем случае, в 2018-ом последний раз. Зачем оно вообще нужно? Пусть хотя бы в виде пасты на пастбине будет.
Этот факт не отменяет того что в РФ он очень популярен.
Осваиваю mvc, добавляю роутинг по гайду и на любом кастомном путе отличном от '/' получаю 403
Заклонил чужой пример, запустил и там тоже самое
Пользуюсь опенсервером, на xampp тоже самое
Я так понимаю нужно хтацесс писать для апача? Без него никак? в хостс смотрел, там мой домен стоит возле локального айпи как и должно быть
пикрил
как думаете, есть шансы? или в 28 лет уже не особо пойму что-то?
Я хуею как вы так планируете за один месяц, за два, за три, если ты нихуя понятия не имеешь, что там и сколько учить?
ну я так-то базу знаю. круд приложуху на голой пыхе могу написать и mysql, да и в вебе я уже давно шароёблюсь. думаю, 3 месяца на изучение голой пыхи и 1-2 месяца битрикса/ларавельки хватит (у нас как и битриксоиды требуются, так и ларавельщики)
>Что у вас за мода в утонувших тредах сидеть, кстати?
Это профессиональная потребность сидеть на легаси
на битриксе в рашке больше работы в разы. думал как-нибудь вообще в будущем перекатиться чекбоксы новые пилить в админке, да свистоперделки всякие за 120к в месяц. такой суммы мне хватит
бля, ну давай не будем обсуждать зп.
есть компании, которые готовы платить бабки, есть те, кто нихуя не платит.
я ГОД НАЗАД работал тестером в компании, где джун получал 65-85к. Спустя полгода работы ВСЕХ джунов повышали до +50р в час. Через полгода ещё так.
На текущем месте у нас обычный разраб получает от 60 до 120. Миддлы от 120к.
Причём джун должен уметь:
- брать верстку и насаживать на битрикс;
- уметь в битрикс или лару, или вп (что угодно);
а дальше кто насколько продаст себя. Приходят челы, которые думают, что со старта им никто 80к платить не будит и просят 50к. Им и платят 50к. А приходят челы, которые по сути слабо прогают, но они просят 85-90к и знаешь, им платят.
Дело всё в том, насколько ты наглый, изъебистый и насколько можешь подлизать лиду или миддлу хотя бы в случае чего.
Молчунов. жестких ебаторов битры у нас нет. Все чего-то знают, а чего-то не знают и мы все обмениваемся опытом.
Просто кто-то попросил n рублей, а кто-то попросил n+30k рублей. Вот и вся разница на рынке труда.
Поверь человеку который нырнул в это говно, ты будешь невостребованным нигде специалистом, PHP разработчик и Битрикс разработчик это такая же разница как автослесарь и слесарь сантехник. Я 6 месяцев работал в такой параше и перекатился на рельсы, то что у нас делал тимлид и помидоры 5ти летнем стажем и всем остальным это казалось мега сложным, то я делал в первые дни своей работы. Весь твой опыт будет нерелевантный, а с опытом ты будешь все глубже утопать в этой хуйне, ты не будешь уметь базовых вещей (работать с БД, докеры, хуекеры, всякие редисы, рабиты), не знать всяких паттернов, тот же MVC в Битриксе извращённый, это реально была пропасть у меня. Из плюсов скажу что я научился быстро верстать и накидывать на коленке лапшу на жиквери. хотя сейчас пилю микросервисы и фронт не вижу А в остальном у меня голова была занята особенностями работы с этой какашкой и полный инфоблок головного мозга. А сколько часов ты проведешь в поиске нужного файла, это не передать на словах, особенно шаблонов, кстати в одном из этих шаблонов в резалт_модифаер.пхп может оказаться вызов какой-нибудь ЦАйблокЭлемент::ГетПроперти в цикле который генерирует десятки запросов с джойнами при каждом вызове, вот и ебись ищи чего там тормозит и почему страница с товарами делает пару тысяч запросов при выключенном кэше, потому что спустя пару часов после его очистки там снова хуйзнает сколько гигов и место кончается. А если тебе достанется проект после говно студии, да и ещё на "готовом" решении, ещё и со свистелками, то это будет полный пиздец и какая нибудь задача поменяй картинку и передвинь этот блок может превратиться в недельную еблю. Когда я уволился, то удалил со своего ноута 300 гигов и там были проекты с которым я работал ежедневно.
Да забей на битриксошизика, пусть в своем болоте тонет
Справедливости ради, проблема с функцией, делающей тяжелые запросы из шаблона, легко отлавливается профайлером - там на графике потребления памяти, потребления CPU или графике числа запросов будет явно видный пик.
Как можно реализовать функционал, чтобы пользователь заходил на сайт, вбивал ссылку с изображением, эта ссылка поступала бы в мой парсер и затем изображение из парсера отправлялось бы пользователю? Парсер работает под виндой
Я знал, что в битриксе пиздец, но не знал, что настолько. Спасибо, прислушаюсь. В любом случае хотел пойти по такому пути:
голая пыха + sql, mysql и postgre. Потом yii2/symphony/laravel. Выбрал лару, потому что большинство говорят, что она лучше. Потом уже хотел изучить битрикс и работать в нем, но видимо, всё-таки прислушаюсь к тебе
Пили апишку на стороне Шарпа, пользователь заходит на сайт, сайт случиться к апи на C# там запускается парсер и отдает результат сайту, сайт отдает результат пользователю
Спс
Как в ларавеле добавить элементы в вьуху через контролер?
Ну и вообще динамично добавлять.
Что ты подразумеваешь под "хорошим"? Какие известные генераторы ты уже рассмотрел и почему отверг?
Генераторы случайных чисел это математика, и довольно хардкорная. Например, простой генератор на основе сдвигов и XOR опирается на поля Галуа, где можно голову сломать, пытаясь разобраться. И это относительно простой генератор.
В конфиге ты настраиваешь общую конфигурацию, которая не зависит от окружения (одинаковая на машинах всех разработчиков и в продакшене). В частности, ты указываешь, что параметры соединения с БД не фиксированные, а их надо брать из env-файла.
То есть, конфиг у всех общий. И ты не можешь туда прописать пароль от своей базы, так как у твоего коллеги будет другой пароль.
А в env ты выносишь параметры, которые либо разные в разных окружениях, либо которые хочется свободно менять. env файл у каждого разработчика и на продакшене свой, и они могут его менять как хотят, не мешая другим.
Хороший ответ, чаю.
https://ideone.com/rlxbLa
Ой, по идее в paymentTotal надо же ещё и взносы/комиссии включать.
Вот ты создаешь запрос, отправляешь, скрип останавливается и ждет ответа(ограниченное кол-во времени)
В ответ возвращается заголовок, типа от того-то, туда-то.
Вот что есть этот туда-то? То бишь в заголовке написано отправить на рут(url) MyController. А как этот контролер знает что данные заголовка надо кидануть в определенную часть скрипта, а не начать обрабатывать запрос с самого начала скрипта?
Извини, но я не очень понял, о какой ситуации идет речь: браузер отправляет HTTP-запрос на сервер, где работает PHP-скрипт, или PHP-скрипт отправляет запрос на другой сервер? Или речь (судя по слову контроллер) о каком-то фреймворке? Опиши подробнее, что за ситуация. Используется ли фреймворк или самописный код и кто кому отправляет запрос.
Если ты из скрипта отправляешь HTTP-запрос на другой сервер, то никакие контроллеры не вызываются. Ты просто отправляешь запрос и скрипт останавливается до получения ответа. После получения ответа он продолжает свою работу с того места, где остановился:
// эта строчка отправляет HTTP-запрос и скрипт останавливается до получения ответа
$result = curl_exec($ch);
Как это? Передачу переменной в пределах одного php файла? Да, если переменная условно-глобальная, то ее будут видеть все функции. Просто суй ее в них.
Использовать переменную, созданную в одном файле, в другом файле? Зачем так делать? Это не очень правильно. Она должна использоваться там, где создалась.
Передавать данные из, например, формы отправки сообщения, и передавать их в скрипт обработки этих данных? Да, можно. В форме указываешь урл скрипта/сам скрипт. И через массиве $_GET или $_POST передаешь.
Обращаться к определенным глобальным переменным/сущностям в современных движках? Да, можно. В yii2 или laravel для вот этой страницы уже есть некий набор стандартных переменных с полезной информацией. Например, текущий урл, имя сервера и прочие штуки. Тебе их не надо самому создавать, они есть.
Если у тебя два голых файла, то тебе надо указать в одном ссылку на другой через require_once или require
То-есть в одном файле создаешь переменную.
Затем в другом файле пишешь require_once("первый файл")
И теперь все переменные из первого файла доступны во втором после строчки с require_once
Но в движках используют use с namespace обычно, плюс автолоады с композерами
я даже не знаю что это
Обычно код пишут в функциях. И ты вызываешь функцию и передаешь ей нужные переменные. А не пишешь стены кода без разделения на функции.
Нет, неправильно. Это не путь (хотя он может частично с ним совпадать). Неймспейс это начальная часть длинного имени класса.
То есть, если полное имя класса \Zend\Db\Error, то короткое имя класса это Error, а неймспейс это \Zend\Db.
Зачем это нужно, можно прочитать в уроке про неймспейсы: https://github.com/codedokode/pasta/blob/master/php/autoload.md
>>126927
Зачем ты сбиваешь человека? Неймспейс это не путь к классу, а префикс длинного имени класса, который может совпадать с путем к классу. А может и не совпадать.
PHP отправляет через curl, в процессе исполнения скрипта, ждет ответа.
Фреймворк пусть будет ларавел\симфони, но это не особо важно, у них под капотом таже пыха с адресом скрипта.
>останавливает
И как это происходит? Изнутри если? Как он знает с какого места продолжить исполнение?
>Неймспейс это не путь к классу, а префикс длинного имени класса, который может совпадать с путем к классу. А может и не совпадать.
Да, ты прав. Но по правилам хорошего тона неймспейс должен совпадать с путем к классу. Зачем изначально прививать человеку "неприличные" практики?
Так его же попускать будут на таких вопросах. Пусть знает, как оно внутри устроено
>Так его же попускать будут на таких вопросах.
Современные среды разработки сами за тебя пишут неймспейсы. Программисту об этом не надо думать. Ему за "а я знаю как оно внутри устроено" не доплатят. Ну разве что перед друзьями похвалиться.
Только собеседующий задаст вопрос и не получив ответ, сделает отметку, что перед ними макака, которую можно попустить по зп
>перед ними макака, которую можно попустить по зп
Новичку в любом случае не дадут высокую зарплату. Если есть шанс попасть в хорошую контору, где работают профессионалы, за еду - это уже праздник. Кроме того от конторы зависит. Да, ты прав, есть такие, что будут и метод пузырька спрашивать, и неймспейсы каноничные, менять две переменные без помощи третьей и прочие олимпийские задачи - то есть все, что в реальности не очень-то и используется/автоматизировано. А потом будут зарплату урезать за то, что скобочку у класса переносишь/не переносишь. Но это скорее неадекваты, и оттуда надо убегать.
А есть конторы, которые не дадут большую зарплату, но где нужны люди чтобы работать вот прямо сейчас. Им как-то не до мелочных придирок.
Я всегда был не в ладах с реактом сам по себе, а тут понадобилось в ларавел запихнуть.
И это ппц, чтобы я не читал и не пробовал у меня ничего не работает.
А сегодня я вообще потерял важный файл с жс скриптом потому что laravel.mix, ебучий вебпак(ссука как же я ненавижу вебпак и еблю с зависимостями фронетнда) просто потер его.
Я делал:
Установил ларавел/ui. Установил реакт, нпм, все зависимости разрешились. перегрузились, ошибок нет. Делаю npx mix watch.
В блейде у меня <script src="/js/app.js"></script>. //реакт
Также <script src="/js/main.js"></script> //мой кастомный скрипт
Делаю import ReactDOM from 'react-dom', затем ReactDOM.render() в main.js - пишет не может использовать вне модуля
Я и в package.json type='module' делал, и в блейде script type='module' делал, и в webpack.mix.js писал mix.js(...main.js) . Когда делаешь все это то это походу костыли и появляется следующая ошибка типа пропишите путь, хотя
предполагаю такого не должно быть вообще когда делаешь импорт реакта Я просто не понимаю как эта херовина должна работать, может кто объяснить.
А то что файл потерял это в 10 раз обиднее, сука ненавижу вебпак.
Ну да, тут еще зависит от того, на какой грейд мы собеседуемся.
Для джуна ценнее получить оффер на любую сумму и достаточно набрать какой-то минимум по очкам, чтобы получить оффер.
К мидл+ критерии жестче
Ты херней занимаешься, пытаясь совместить блейд с реактом.
От ларавеля реакту нужна только апишка, из которой он будет фетчить данные.
Никакие ларавел миксы не нужны, т.к. они жестко привязывают фронт к беку.
В идеале у тебя два отдельных приложения, живущих своей жизнью: апи на ларавел и спа на реакте
1)Не раз уже слышу абреввиатуру СПА. Что она значит? Как расшифровывается?
S - service, A-apllication, по логике
2)Спасибо, я понял конечно, но у меня бомбит что все гайды и официальные документации заставляют тебя использовать определенные технологии, а они на самом деле не работают и не нужны, а ты сидишь и ковыряешь в этом гумне часами. Класс.
Я бы все таки хотел понять, просто понять как оно на самом деле должно было работать. Микс контролирует сборку, вебпак и прочая. Все зависимости докачиваются, пакетики встроенные.
Сказано просто добавить script src. Больше ничего не сказано.
Очевидно по логике js-а ты кидаешь import-ы. И раз написано что микс добавил, и все смотрит - какого лешего мой срипт не видит реакт?
Что я делаю не так?
ПС фронтенд приложения куда принято кидать в проекте, в /public?
сингл пейдж апликейшн, загружается эта сингл пейдж и работает на клиенте, на бэке только апи для отправки-приема данных.
single page application
Так нужно базу веба знать, а не бросаться грызть гайды, тогда и фундаментальное понимание будет как работает та или иная технология и как их вместе собрать.
А то получается идем по гайду, шаг вправо-влево и наши полномочия всё. Или гайд устарел - тоже пук.
>ПС фронтенд приложения куда принято кидать в проекте, в /public?
В идеале это отдельная репа, которая находится вне репы твоего бекенда.
Как это примерно работает:
Ты вбиваешь урл spa.hui, тебе грузится само spa, которое представляет собой грубо говоря хтмл, жс, цсс, т.е. статика.
Где-то отдельно крутиться бекенд апи, урл которого знает твой спа.
Если спа нужно получить/сохранить данные, он будет обращаться к бекенду. Роутинг происходит на уровне спа.
Наглядный пример - приложение погоды.
Есть некий внешний апи (не твой) weather.com, у которого ты можешь запросить текущую погоду, температуру, влажность, осадки и т.д.
Ты пишешь жс приложение, которое получает от апи погоду и выводит юзеру в браузер.
Классическое приложение: отправляешь запрос на сервер, получаешь страницу с ответом.
Типичное SPA приложение: отправляешь запрос на сервер, получаешь заглушку со спиннером. Ждешь, пока загрузится пара мегабайт яваскрипта, потом ждешь пока она скачает пару мегабайт джейсона с бекенда и только потом, может быть, увидишь результат.
Хотя SPA не обязаны быть медленными, на практике почему-то SPA долго грузятся. То есть, я бы хотел увидеть сразу данные, а не смотреть на заглушку.
Примеры: Сбербанк-онлайн - есть заглушка, загрузка медленная. Твиттер - есть заглушка, загрузка медленная. Ютуб - есть заглушка, загрузка медленная. В твиттере с ютубом работают разработчики мирового класса и все равно тормозит. А у обычного разработчика результат будет в 10 раз хуже.
Да я и спрашиваю поэтому как это работает под капотом, никто не знает.
В свое время, года назад, пытался во фронт, задание тестовое на работку я конечно сделал, но все равно не понял нафига оно нужно(это другой вопрос и тема, срачи вечные, достаточно осказано). Сам факт что я задавал на 3 разных форумах(двач в том числе) про зависимости, пакетирование, ведь это гумно просто так не работает.
В итоге люди сами ничего не знают, просто говорят использовать установщик из коробки - он у меня в общем-то и заработал. А вебпак и лярд других завсимостей я проклинаю по сей день, но люди говорят это норма, щито поделать.
Да, я понял, спасибо, обычное апи, я с такими работаю. Просто у меня проблема с бест практис, я каждый чих выдрочился спрашивать. Типа папка, там фронт, там бек. Я просто не отразил сразу что я не буду прописывать руты вручную. Короче, посмотрю.
>>127691
Лярд зависимостей. Не нравится мне все это.
>Да я и спрашиваю поэтому как это работает под капотом, никто не знает.
За всех то не говори
>Просто у меня проблема с бест практис, я каждый чих выдрочился спрашивать. Типа папка, там фронт, там бек
Так ты должен сам на эти вопросы себе отвечать.
Как работает моё приложение?
Как связаны бекенд с фронтендом?
Как запрос идет через бек?
и т.д.
>Лярд зависимостей. Не нравится мне все это.
У тебя и на беке будет лярд зависимостей. Загляни в composer.json (ларавеля к примеру) на досуге. У него свои зависимости, у тех зависимостей - свои т.д.
Без зависимостей мы не получим достаточно большую скорость выкатки фич на прод
Программа это последовательность команд, которые идут друг за другом и выполняются строго по очереди. Когда ты запускаешь PHP-скрипт, то PHP компилирует (преобразует) его в последовательность команд и затем выполняет эти команды. То есть у тебя в программе могут быть сложные циклы, if, функции, но в итоге все это превращается в последовательность простых команд идущих друг за другом.
У каждой команды есть адрес (номер). И есть счетчик команд, он хранит номер текущей выполняющейся команды. Счетчик увеличивается после выполнения каждой команды.
Команды выполняются строго по очереди. Допустим, программа выглядит так:
1) отправить запрос на http://example.com/page.html
2) сохранить ответ в переменную $x
3) вывести $x на экран
В этом случае сначала выполняется команда 1. Она отправляет запрос и ждет ответа. Пока она ждет, ничего не происходит и никакие другие команды не выполняются. Когда ответ приходит, начинает выполняться команда 2.
Как это работает на более низком уровне. Программа сама не может пересылать данные по сети. Этим занимается только операционная система (ОС). Программа, используя "системные вызовы", просит операционную систему сделать ту или иную сетевую операцию. При этом, пока операция выполняется, программа "стоит на месте" и ничего не делает.
Вот, например, как выглядит отправка запроса к http://example.com на более низком уровне:
1) сформировать HTTP-запрос, собрав вместе все нужные заголовки
2) попросить ОС установить соединение с сервером example.com
3) попросить ОС передать HTTP-запрос на сервер example.com
4) попросить ОС принять данные от сервера
5) разобрать пришедший ответ и извлечь из него нужные данные (заголовки, тело ответа и тд)
Операции 2, 3 и 4 "блокирующие" - то есть, пока они выполняются, программа ничего не делает. Как только операция выполнится, программа продолжает работу.
Как это работает на еще более низком уровне: у каждой команды в программе есть адрес (номер), и есть "счетчик команд", он хранит номер текущей выполняемой команды. Когда завершается выполнение операции и управление возвращается программе, она продолжает выполнение с того номера, который записан в счетчике команд.
> Как он знает с какого места продолжить исполнение?
Номер команды, на которой остановилось выполнение, записан в счетчике команд.
Программа это последовательность команд, которые идут друг за другом и выполняются строго по очереди. Когда ты запускаешь PHP-скрипт, то PHP компилирует (преобразует) его в последовательность команд и затем выполняет эти команды. То есть у тебя в программе могут быть сложные циклы, if, функции, но в итоге все это превращается в последовательность простых команд идущих друг за другом.
У каждой команды есть адрес (номер). И есть счетчик команд, он хранит номер текущей выполняющейся команды. Счетчик увеличивается после выполнения каждой команды.
Команды выполняются строго по очереди. Допустим, программа выглядит так:
1) отправить запрос на http://example.com/page.html
2) сохранить ответ в переменную $x
3) вывести $x на экран
В этом случае сначала выполняется команда 1. Она отправляет запрос и ждет ответа. Пока она ждет, ничего не происходит и никакие другие команды не выполняются. Когда ответ приходит, начинает выполняться команда 2.
Как это работает на более низком уровне. Программа сама не может пересылать данные по сети. Этим занимается только операционная система (ОС). Программа, используя "системные вызовы", просит операционную систему сделать ту или иную сетевую операцию. При этом, пока операция выполняется, программа "стоит на месте" и ничего не делает.
Вот, например, как выглядит отправка запроса к http://example.com на более низком уровне:
1) сформировать HTTP-запрос, собрав вместе все нужные заголовки
2) попросить ОС установить соединение с сервером example.com
3) попросить ОС передать HTTP-запрос на сервер example.com
4) попросить ОС принять данные от сервера
5) разобрать пришедший ответ и извлечь из него нужные данные (заголовки, тело ответа и тд)
Операции 2, 3 и 4 "блокирующие" - то есть, пока они выполняются, программа ничего не делает. Как только операция выполнится, программа продолжает работу.
Как это работает на еще более низком уровне: у каждой команды в программе есть адрес (номер), и есть "счетчик команд", он хранит номер текущей выполняемой команды. Когда завершается выполнение операции и управление возвращается программе, она продолжает выполнение с того номера, который записан в счетчике команд.
> Как он знает с какого места продолжить исполнение?
Номер команды, на которой остановилось выполнение, записан в счетчике команд.
>за всех
Ну я говорю за всех кто мне встречался, очевидно.
>сам отвечать
Я бы рад)))) Но как только я делаю самодеятельность какую-ту, мне начинают вонять что ну тип у нас не совсем так, не сяк. Мне уже похуй что-то там думать, я просто напрямую спрашиваю - как это у вас делается.
Еще я понял что если ты сделаешь как тебе виднеется лучше или как люди говорят в интернете - то потом придется переделывать, а я понял что это лютый треш и лучше до такого не доводить.
>беке
Так на беке зависимости остаются на беке, юзеру только определенная инфа приходит. А фронт приложухи полноценные кидает для разверстки.
Я хочу сконцентрировать внимание на том, что неймспейс это не путь к файлу. А лишь часть полного имени класса. Неправильно думать, что use это аналог require из древних скриптов.
>>126995
Это организация классов, когда их много. До неймспейсов люди давали классам длинные имена и получалось что-то вроде
Zend_Db_Table_Row
Почему имена классов длинные?
- в начале указывается имя фреймворка или библиотеки, чтобы в разных библиотеках не было классов с одинаковым именем. Иначе ты не сможешь в одной программе подключить две библиотеки.
- в середине указываются имена, которые позволяют группировать классы в модули (фреймворк Zend, модуль Db, подмодуль Table, класс Row)
То есть, длинные имена неизбежны. Неймспейсы позволяют упростить код. До неймспейсов ты писал:
$x = new Zend_Db_Table_Row();
С неймспейсами ты пишешь:
use Zend\Db\Table\Row;
$x = new Row();
И, чтобы было проще, путь к файлу выбирают, чтобы он совпадал с полным именем класса.
Тебе правильно написали - надо сначала изучить, как работает laravel.mix и вебпак. И тогда не придется с ним бороться.
Также, тебе надо изучить, как работает импорт модулей в JS.
Ну например, если ты пишешь import ... from 'react-dom', то это значит, что у тебя рядом с main.js должен лежать react-dom.js. Потому что react-dom это имя файла. А у тебя его нет, потому и не работает.
Потому обычно код с импортами обрабатывают вебпаком, который удаляет импорты и вставляет вместо них содержимое запрошенного файла.
Ты не хочешь изучать технологии, а хочешь тыкаться наугад. Вот и результат, что ничего не работает.
Вообще, идея с "фетчить данные" плохая. Если ты взялся за SPA, то логично сразу в страницу заложить все нужные ему данные, чтобы он не делал кучу аякс-запросов при запуске.
>>126998
> Программисту об этом не надо думать
Ты пишешь ерунду. Если программист не разбирается в неймспейсах, он не сможет их правильно использовать и на выходе может быть будет и синтаксически корректный, но нечитаемый код. IDE может исправить синтаксис за тебя, но она не может сделать твой код правильным.
Программист должен понимать каждый символ в коде, который он пишет.
>>127710
> В итоге люди сами ничего не знают
Либо ты плохо сформулировал вопрос, либо ты его спрашивал в треде, где сидят одни неучи, которые считают, что "программисту не надо думать".
Даже если никто не может ответить на твой вопрос, что тебе мешает прочесть целиком документацию по вебпаку? Если ответа в документации нет, можно прочесть целиком исходный код вебпака и найти ответ там. Было бы желание.
Ценность разраба в том, что он делал 1 вариант, понял его плюсы/минусы, делал 2 вариант, там свои плюсы минусы. Из этого складывается умение разраба для задачи Х подобрать оптимальное решение Y учитывая все трейдоффы.
Не бойся делать и ошибаться, так ты получишь опыт и вырастешь как спец.
Только не надо участвовать в холиварах и поисках единственно верного решения - таких просто не существует. Пусть холиварщики холиварят, а нам надо фичи выкатывать.
>А фронт приложухи полноценные кидает для разверстки.
Оно приходит юзеру в виде единого сжатого жс файлика, который кладется в кеш.
Так я и пытаюсь. Прыгаю по докам микса вверх-вниз ничего кстати по теме, все что написано там работает, а по факту реакта ета . И по вопросам.
>содержимое
Так я про это и говорю, микс не видит. И если говорить о том как оно все работает, то скрипт приложения идет до моего скрипта.
>Хочешься тыкаться
Я не хочу. Я прочитал, не сработало, я сделал предположения на основе того как это может работать изнутри, тоже не работает. Че я еще могу сделать-то.
Мне вот сказали просто забить и делать проще\практичнее. Ну ты мне сейчас сказал что знаешь что импорты относятся к файлам.
В общем, пока что ни на йоту не приблизился к еще большему понимаю чем уже есть. Даже сейчас опять попробовал пару фишек и понял что я уже это все делал. Когда не работают самые логичные варианты ты переходишь к менее логичным. Боль.
>Че я еще могу сделать-то.
1. Залезть под капот той технологии, в которой не разбираешься
2. Задать вопрос на стаковерфлоу
>фетчить данные плохо
Блин, а я так надеялся что это топовый вариант. Говоришь, костылик?
>что тебе мешает
У человека опыта нет, без практики информация просто не усвоится.
Это как вкатыш пошел учить реакт по гуидам, ему надо сделать просто хелловорд. Просто хелловорд чтобы начать разбираться в штуке, а потом уже как дорога заведет. А вместо чтобы просто потыкать-попробовать нужно ли ему это, его отправляю в пешее эротическое читать непонятно что, бабели какие-то, жсксы. В итоге пришел делать одно, делаешь абсолютно другое - диссонанс.
Немудрено что многие не осиливают.
Да и в принципе это логично. ты делаешь небольшой функционал, он работает, ты доволен что он работает, у тебя есть то, о чего можно отталкиваться, ты начинаешь углубляться, понимая как это работает. А без позитивного опыта ты обречен делать ложные выводы или не делать их вообще, не зная за что зацепиться.
Я наверное совсем пропащий и обдвачевался, но мне казалось на дваче лучше получить ответ, и быстрее и качественней получится, все таки обитель 3000ккк наносек.
Типа если на стаке не гуглится в первых двух запросах вопросик, то как бы все совсем плохо и нет смысла даже пытаться самому задавать.
а в докере я тоже могу работать с линуксом,апачем,пхп,но допустим смотреть что натворил в мозилле из винды,прост из виртуалки у меня все тупит
те в файле будет класс sign_up а в нем метод с пдо и конструктором с входящими данными?
Как классы и функции помогут писать ООП код?
Что помешает обернуть процедурную лапшу в класс и назвать это ООП?
Ничего не мешает
>Я хочу сконцентрировать внимание на том, что неймспейс это не путь к файлу
Твое объяснение только запутает новичка. По правилам хорошего тона там пишется путь. Если новичок будет писать вместо пути набор рандомных символов/папок - это ему не поможет. Поэтому не совсем корректная фраза "там пишется путь" полезней для него, чем твоя пространная демагогия, которая в конечном счете все равно сведется к "там желательно писать путь".
Сейчас ты находишься в довольно затруднительном положении. У тебя достаточно знаний, чтобы помогать новичкам, но все свои силы ты тратишь на то, чтобы придираться к словам и указывать на чужие несущественные ошибки. Это вполне обычно для программистской среды, потому что каждый хороший программист - токсичный самовлюбленный ребенок, который пытается самоутвердиться за чужой счет. Поэтому не забывай, зачем ты здесь. Самолюбование останавливает твое развитие и не помогает другим.
Любые. Даже стажеру могут задать сеньорскую хуиту, это нормально.
Про это будет означать что либо смотрят на твою эрудицию и реакцию, либо сама фирма ебанашки. Одно из двух.
Гадать нет смысла.
>>128642
Двачую. Нахуй на дваче еще спрашивать. Пришел, поговорили, узнали, приняли-отложили-забили. Тебя поход на собес ничему не обязывает.
Укаазать его ади и имя в БД?
Он сейчас спросит, куда это вводить.
»2130729
>Ampps
Перейди на localhost/phpmyadmin и не еби мозги
но запрос пустой
зачем ты сюда лезешь, если настолько не ориентируешься даже просто в использовании компьютера?
Если делают ебучие картинки с коробочками то сразу хуйня.
Клиент mysql - это консольная программа. У нее нет окошек или кнопок. Его надо запускать не кликом мышкой, а из консоли.
Консоль это такое черное окно куда ты вводишь команды и компьютер их выполняет. Чтобы узнать, как ей пользоваться, прочти короткий урок https://github.com/codedokode/pasta/blob/master/soft/cli.md
Сначала тебе надо открыть консоль. Это удобнее всего сделать, если открыть папку на твоем скриншоте и ввести в адресную строку cmd и нажать Enter. Тогда консоль откроется с уже выбранной папкой. Если запускать ее другим способом, то тогда придется вручную перейти в папку с mysql.
Появится черное окно с мелкими буквами. Настрой более удобный размер шрифта. Затем набери mysql и должен либо запустится клиент mysql, либо вывестись сообщение об ошибке. Если все ок, то ты можешь набирать запрос к базе данных и тебе будет выведен его результат.
Тебе надо добавить на страницу яваскрипт-код. Этот код должен ждать события нажатия кнопки, и при нажатии кнопки отправлять аякс-запрос, например на URL /start-process.php
При отправке аякс-запроса не забудь сделать индикатор прогресса (крутящийся диск или что-нибудь такое). Не забудь, что запрос может завершиться ошибкой, в этом случае надо ее вывести на экран и дать возможность пользователю отправить запрос повторно.
Если ты ориентируешься только на самые современные браузеры, то для отправки запроса можно использовать функцию fetch(). Если хочешь поддерживать любой браузер за последние лет 15, то используй объект XMLHttpRequest.
Тогда при нажатии кнопки отправится запрос на сервер и сервер запустит скрипт start-process.php. А этот скрипт уже может делать что угодно.
Думаю, требуется именно опыт интеграции какого-то сервиса. Например: сервис приема платежей, сервис геокодирования, служба доставки итд.
>>128109
Я думаю, что это не придирка к словам. Если неймспейс не является путем к файлу, то надо так и писать, а не пытаться "упрощать", скрывая важные детали. Люди не такие глупые и прекрасно все поймут, если им объяснять и если они хотят понять.
> ввести в адресную строку cmd и нажать Enter
Хуя лойфхок. Я всегда делол через шифт+правая кнопка.
В программировании часто встречается такое, что есть какие-то "сущности", у которых есть свойства и с которыми можно делать какие-то действия. Например, в магазине есть сущность "товар", у нее свойства: цена, вес, скидка, наличие. И есть действия: поменять цену, добавить скидку, снять с продажи, выставить в продажу, посчитать прибыльность.
Для удобной работы с такими сущностями и придуманы объекты. Ты сначала создаешь класс, описывая, какие есть у сущности свойства (поля) и действия (методы). А потом создаешь объекты этого класса.
Например, если ты хочешь добавить в магазине новый товар, ты создаешь объект класса Товар. Затем вызываешь у него методы задатьНазвание, задатьЦену, и заполняешь все его свойства. Затем ты обращаешься к объекту СохранятельТоваров и с его помощью сохраняешь товар в базу данных.
А когда тебе надо вывести информацию о товаре, ты с помощью СохранятеляТоваров загружаешь объект товара из БД, и вызывая его методы вроде узнатьЦену, узнатьНазвание выводишь информацию о нем на странице.
Но классы годятся не только для представления сущностей. Можно создавать объекты, у которых нет каких-то особых свойства, а есть только действия. Например: РегистраторПользователей. У него нет свойств, а есть только метод "создать нового пользователя".
Думаю, ты уже видишь, как ООП можно использовать для регистрации пользователей. Мы можем создать такие классы:
- Пользователь (User) со свойствами: email, хеш пароля, дата регистрации, имя итд. И методами: задать Email, узнать Email, задать пароль, проверить пароль итд.
- СохранятельПользователей (UserTableGateway) - это класс, который умеет сохранять объекты пользователя в БД или извлекать из нее. У него будут методы вроде вставитьПользователяВБазу, обновитьПользователяВБазе, найтиПользователяПоEmail.
- ВалидаторПользователя (UserValidator) - это класс, который получает данные из формы регистрации пользователя и проверяет их на правильность: что все поля заполнены, что email похож на настоящий email итд.
Заметь, что мы не пихаем все в один класс, а для каждой задачи используем отдельный класс. У каждого класса своя зона ответственности.
В принципе, это достаточный минимум, но можно при желании добавить еще другие классы. Например, класс ДанныеФормыРегистрации, объект которого хранит данные, которые введены в форму. В некоторых фреймворках Форма и ПолеФормы тоже сделаны в виде объектов (то есть, форма регистрации это объект и каждое поле в ней тоже объект).
Если ты плохо знаешь ООП, я советую тебе начать с учебника из шапки, в нем есть глава про ООП, а в ней задача про ООО Вектор. Ее надо решить, чтобы освоиться с ООП.
Далее я тебе советую посмотреть задачу про студентов из шапки. К ней есть подробные комментарии, и она научит тебя, как использовать ООП для работы с формами регистрации, базой данных: https://github.com/codedokode/pasta/blob/master/student-list.md
Если тебе лень делать задачу, и ты все схватываешь на лету, то может быть тебе достаточно будет прочесть комментарии к задаче. И пользуясь ими, ты можешь попробовать сделать ООП-регистрацию самостоятельно. Можешь выложить код на гитхаб, я как-нибудь гляну и дам замечания.
В программировании часто встречается такое, что есть какие-то "сущности", у которых есть свойства и с которыми можно делать какие-то действия. Например, в магазине есть сущность "товар", у нее свойства: цена, вес, скидка, наличие. И есть действия: поменять цену, добавить скидку, снять с продажи, выставить в продажу, посчитать прибыльность.
Для удобной работы с такими сущностями и придуманы объекты. Ты сначала создаешь класс, описывая, какие есть у сущности свойства (поля) и действия (методы). А потом создаешь объекты этого класса.
Например, если ты хочешь добавить в магазине новый товар, ты создаешь объект класса Товар. Затем вызываешь у него методы задатьНазвание, задатьЦену, и заполняешь все его свойства. Затем ты обращаешься к объекту СохранятельТоваров и с его помощью сохраняешь товар в базу данных.
А когда тебе надо вывести информацию о товаре, ты с помощью СохранятеляТоваров загружаешь объект товара из БД, и вызывая его методы вроде узнатьЦену, узнатьНазвание выводишь информацию о нем на странице.
Но классы годятся не только для представления сущностей. Можно создавать объекты, у которых нет каких-то особых свойства, а есть только действия. Например: РегистраторПользователей. У него нет свойств, а есть только метод "создать нового пользователя".
Думаю, ты уже видишь, как ООП можно использовать для регистрации пользователей. Мы можем создать такие классы:
- Пользователь (User) со свойствами: email, хеш пароля, дата регистрации, имя итд. И методами: задать Email, узнать Email, задать пароль, проверить пароль итд.
- СохранятельПользователей (UserTableGateway) - это класс, который умеет сохранять объекты пользователя в БД или извлекать из нее. У него будут методы вроде вставитьПользователяВБазу, обновитьПользователяВБазе, найтиПользователяПоEmail.
- ВалидаторПользователя (UserValidator) - это класс, который получает данные из формы регистрации пользователя и проверяет их на правильность: что все поля заполнены, что email похож на настоящий email итд.
Заметь, что мы не пихаем все в один класс, а для каждой задачи используем отдельный класс. У каждого класса своя зона ответственности.
В принципе, это достаточный минимум, но можно при желании добавить еще другие классы. Например, класс ДанныеФормыРегистрации, объект которого хранит данные, которые введены в форму. В некоторых фреймворках Форма и ПолеФормы тоже сделаны в виде объектов (то есть, форма регистрации это объект и каждое поле в ней тоже объект).
Если ты плохо знаешь ООП, я советую тебе начать с учебника из шапки, в нем есть глава про ООП, а в ней задача про ООО Вектор. Ее надо решить, чтобы освоиться с ООП.
Далее я тебе советую посмотреть задачу про студентов из шапки. К ней есть подробные комментарии, и она научит тебя, как использовать ООП для работы с формами регистрации, базой данных: https://github.com/codedokode/pasta/blob/master/student-list.md
Если тебе лень делать задачу, и ты все схватываешь на лету, то может быть тебе достаточно будет прочесть комментарии к задаче. И пользуясь ими, ты можешь попробовать сделать ООП-регистрацию самостоятельно. Можешь выложить код на гитхаб, я как-нибудь гляну и дам замечания.
При использовании вебпака ты пишешь свой код, затем вебпак склеивает твой код с файлами, который ты импортируешь и получившуюся сборку ты уже подключаешь на странице.
А ты пытаешься без вебпака напрямую подключить реакт. Он на такое, по видимому, не рассчитан.
Тебе надо разобраться и с вебпаком, и с миксом. И писать код так, как они требуют, и располагать его там, где требуется.
Есть данные в БД, как до них достучаться и, скажем, засунуть их в квиз? Квиз написан на JS, и я хочу при вводе данных в поля в WordPress передавать вопросы в вопросник JS. Я сделал так - непосредственно на странице сайта, которую я натягиваю на WP, объявил переменную в JS и засунул в нее переменную php, которая содержит массив данных полей. Получилась строка. Строку я превратил в массив и далее вычленил элементы уже в вопросник. Но сука, я чувствую, что так не должно быть. То, как я это сделал, это блять неправильно и вообще неадекватно.
Думаю что есть вариант через fetch, но как через него достучаться до БД?
Подскажите плз нормальный человеческий способ, как в реальной практике происходит взаимодействие JS с базой данных (скажем, на WP).
>>132017
>Пользователь (User) со свойствами: email, хеш пароля, дата регистрации, имя итд. И методами: задать Email, узнать Email, задать пароль, проверить пароль итд.
- СохранятельПользователей (UserTableGateway) - это класс, который умеет сохранять объекты пользователя в БД или извлекать из нее. У него будут методы вроде вставитьПользователяВБазу, обновитьПользователяВБазе, найтиПользователяПоEmail.
Я так понимаю класс Save это отдельный файл и тут нужны будут намспейсы и use ?
>без вебпака подключть реакт
Почему без вебпака? У меня микс должен работать вместо вебпака, микс автоматически использует вебпак, он создан для упрощения работы с вебпаком, подразумевается там ручками ничего не надо настраивать - надо делать все через микс.
Давай разобьем вопрос на несколько частей:
1) как передать в JS начальные данные при загрузке страницы. Тут правильным способом будет получить эти данные в PHP при загрузке страницы, преобразовать их в JSON и явно передать в нужную функцию:
<script>
initQuiz(<?= json_encode($data); ?>);
</script>
Плюс такого подхода в том, что нам не надо делать лишние аякс-запросы и мучать пользователя ожиданием - данные уже встроены в страницу и мгновенно могут быть использованы скриптом. Также этот подход очень явный - если ты наткнулся на этот код, ты можешь в IDE в один клик перейти к функции initQuiz() и увидеть, что дальше делается с данными.
Минус тут может быть только в том случае, если данных очень много, и они почти никогда не используются. В этой ситуации ты заставляешь пользователя грузить не нужные ему данные.
Иногда этот подход не подходит, так как у нас скрипт загружается асинхронно и функцию initQuiz мы вызвать не можем (так как скрипт еще не загрузился). В таком случае мы можем создать внутри страницы "остров" с JSON-данными. Скрипт при загрузке находит в теле страницы этот остров и берет данные из него:
<script id="quizData" type="application/json">
<?= json_encode($data); ?>
</script>
Обрати внимание на атрибут type: он говорит, что это не яваскрипт, а JSON и браузер не будет пытаться его выполнить.
Этот подход, на мой взгляд, менее явный, так как при просмотре кода неочевидно, для кого предназначен этот остров и как найти скрипт, который его использует, если у тебя тысячи скриптов. IDE тут не поможет.
2) Как в процессе работы скрипта получать или отправлять данные без перезагрузки страницы? Тут нужны аякс-запросы. Ты отправляешь запрос на сервер, а там PHP-скрипт его обрабатывает как нужно. Логично отправлять данные на сервер как данные формы, а принимать с сервера ответ в формате JSON.
То есть, тебе нужно иметь скрипт на сервере, который положит или достанет данные из БД. Помни про безопасность: хакер может прислать твоему скрипту что угодно. Не доверяй приходящим данным, а тщательно проверяй каждый элемент на соответствие разрешенным значениям.
WordPress тут вообще не при чем. Я не думаю, что в нем есть что-то для таких сценариев работы. Это просто движок для блогов, а не универсальный фреймворк.
Давай разобьем вопрос на несколько частей:
1) как передать в JS начальные данные при загрузке страницы. Тут правильным способом будет получить эти данные в PHP при загрузке страницы, преобразовать их в JSON и явно передать в нужную функцию:
<script>
initQuiz(<?= json_encode($data); ?>);
</script>
Плюс такого подхода в том, что нам не надо делать лишние аякс-запросы и мучать пользователя ожиданием - данные уже встроены в страницу и мгновенно могут быть использованы скриптом. Также этот подход очень явный - если ты наткнулся на этот код, ты можешь в IDE в один клик перейти к функции initQuiz() и увидеть, что дальше делается с данными.
Минус тут может быть только в том случае, если данных очень много, и они почти никогда не используются. В этой ситуации ты заставляешь пользователя грузить не нужные ему данные.
Иногда этот подход не подходит, так как у нас скрипт загружается асинхронно и функцию initQuiz мы вызвать не можем (так как скрипт еще не загрузился). В таком случае мы можем создать внутри страницы "остров" с JSON-данными. Скрипт при загрузке находит в теле страницы этот остров и берет данные из него:
<script id="quizData" type="application/json">
<?= json_encode($data); ?>
</script>
Обрати внимание на атрибут type: он говорит, что это не яваскрипт, а JSON и браузер не будет пытаться его выполнить.
Этот подход, на мой взгляд, менее явный, так как при просмотре кода неочевидно, для кого предназначен этот остров и как найти скрипт, который его использует, если у тебя тысячи скриптов. IDE тут не поможет.
2) Как в процессе работы скрипта получать или отправлять данные без перезагрузки страницы? Тут нужны аякс-запросы. Ты отправляешь запрос на сервер, а там PHP-скрипт его обрабатывает как нужно. Логично отправлять данные на сервер как данные формы, а принимать с сервера ответ в формате JSON.
То есть, тебе нужно иметь скрипт на сервере, который положит или достанет данные из БД. Помни про безопасность: хакер может прислать твоему скрипту что угодно. Не доверяй приходящим данным, а тщательно проверяй каждый элемент на соответствие разрешенным значениям.
WordPress тут вообще не при чем. Я не думаю, что в нем есть что-то для таких сценариев работы. Это просто движок для блогов, а не универсальный фреймворк.
Почитай рекомендации оформления кода PSR-1 и PSR-12 (PSR-1 есть на русском языке). В них записано, что каждый класс помещается в отдельный файл, и кроме класса в этом файле не должно быть ничего постороннего. Имя файла должно соответствовать имени класса с точностью до регистра букв.
Почитай рекомендации и следуй им.
Что касается неймспейсов - выбор за тобой. Если у тебя весь проект состоит из 5 файлов, ты можешь просто сложить их в одну папку и не использовать неймспейсы. Если проект больше, то стоит добавлять подпапки и неймспейсы.
Пхп - говно
Ну попробуй, скачай, посмотри пару лекций. Скажешь потом, насколько информативно.
Спасибо. Да, фетчи когда я изучал, то создавал php файл, который как бы выступает мостом между JS и базой данных.
По поводу варианта получать данные сначала в PHP и потом их преобразовывать я тоже понял, но не понял только вот чего: что значит "php скрипт на стороне сервера"? Вот у меня есть на локалхосте условный php-файл. А на реальном сервере при переносе он точно так же и хранится? То есть мне нужен тупо php-файл обработчик?
Изначально пхп это перл для даунов, но потом его покусала жаба и понеслось.
Поддвачну
Тебе в любом случае нужен код на стороне сервера. Ты не можешь из JS кода из браузера напрямую залезть в базу данных MySQL - и это хорошо, так как иначе любой желающий мог бы в нее залезть.
Сервер - это то, откуда браузер скачивает страницу сайта. Если ты поднял вордпресс на локалхосте, то сервер это твой компьютер.
"Код на стороне сервера" значит php-скрипт или, например, приложение на Node.JS.
Я написал, что в MySQL нельзя залезть JS-скриптом из браузера. Но есть базы данных, в которые залезть можно из браузера без использования PHP-кода. Это severless базы данных вроде FireBase. Но она может быть платной, и документация к ней на английском и разобраться в ней может быть непросто.
Как обеспечивается безопасность при работе с субд из браузера пользователя? Что мешает считать всю базу, или стереть её?
Немного другой вопрос был. Код на стороне сервера - в смысле, это просто php_файл? То есть вот на сервере у меня файлы сайта, и среди них есть файл обработчик.php, который занимается обработкой запросов из JS. Правильно понял?
Работа с данными осуществляется не на уровне браузера, а через серверный слой приложения (в нашем случае это РНР), в котором реализована логика всех запросов, доступных пользователю.
>Код на стороне сервера - в смысле, это просто php_файл?
В простейшем случае это может быть 1 пхп файл + сервер, который обрабатывает поступающие запросы и перенаправляет к пхп файлу
ответьте
Да, это файл-обработчик.
>>133917
Там можно настроить права доступа к каждой таблице. Например: юзер может только добавлять или просматривать комменты и не может удалять их.
>>134484
Это сочетание особенности float с особенностью представления отрицательных чисел в int.
float - это приблизительный тип. В 64-битном PHP float сохраняет только 15-16 значащих цифр числа и порядок. То есть, он хранит число в виде M * 2 N (где M и N целые). Ты можешь убедиться, попробовав сделать var_dump(1000000000000000000000123.0) - "123" на конце потеряется, так как PHP сохраняет только первые 15-16 цифр. И PHP выведет 1e24 - то есть, 1 * 1024. Последние цифры потерялись.
Если хочешь узнать подробнее, погугли IEEE754. Этот стандарт описывает, как числа с плавающей запятой преобразуются в двоичный вид.
Когда ты преобразуешь PHP_INT_MAX в float, точности не хватает, чтобы сохранить все цифры числа и последние цифры округляются в большую сторону. Попробуй сдампить var_dump(PHP_INT_MAX) и var_dump((float)PHP_INT_MAX); и сравнить числа. Ты увидишь различие из-за округления.
Округление происходит в большую сторону и число становится больше PHP_INT_MAX.
Когда ты пытаешься преобразовать это число обратно в int, возникает проблема: число больше, чем максимальное положительное значение int и преобразовать в int его невозможно. Правильно, конечно, было бы выдавать ошибку в таком случае, но PHP все равно его преобразует, при этом получается отрицательное число.
Ты можешь сдампить var_dump((int)1e19); и увидеть отрицательное число.
Но почему при переполнении int получается отрицательное число? Это особенность хранения int в компьютере. Рассмотрим ячейку памяти размером в 1 байт. В ней можно сохранить число от 0 до 255. Если мы хотим хранить в ней еще и отрицательные числа, то мы должны придумать какой-то способ, как их закодировать. Можно, например, договориться так: числа от 0 до 127 обозначают сами себя, а числа от 128 до 255 обозначают -128 ... -1 соответственно. Это называется "дополнительный код" (дополнение до 2).
Почему придумали именно такую систему? Потому что с ней компьютеру просто и удобно складывать и вычитать положительные и отрицательные числа. Человеку такое представление не очень удобно, но он потерпит.
Теперь если мы в такую ячейку попытаемся записать слишком большое число, например число 129, то при чтении оно будет воспринято как -127, так как мы ранее договорились, что числа > 128 обозначают отрицательные числа.
Вот примерно то же самое происходит при преобразовании в int. Число слишком большое и оно попадает в область, которая представляет отрицательные значения.
Почитать подробнее про дополнительный код: https://ru.wikipedia.org/wiki/Дополнительный_код
Да, это файл-обработчик.
>>133917
Там можно настроить права доступа к каждой таблице. Например: юзер может только добавлять или просматривать комменты и не может удалять их.
>>134484
Это сочетание особенности float с особенностью представления отрицательных чисел в int.
float - это приблизительный тип. В 64-битном PHP float сохраняет только 15-16 значащих цифр числа и порядок. То есть, он хранит число в виде M * 2 N (где M и N целые). Ты можешь убедиться, попробовав сделать var_dump(1000000000000000000000123.0) - "123" на конце потеряется, так как PHP сохраняет только первые 15-16 цифр. И PHP выведет 1e24 - то есть, 1 * 1024. Последние цифры потерялись.
Если хочешь узнать подробнее, погугли IEEE754. Этот стандарт описывает, как числа с плавающей запятой преобразуются в двоичный вид.
Когда ты преобразуешь PHP_INT_MAX в float, точности не хватает, чтобы сохранить все цифры числа и последние цифры округляются в большую сторону. Попробуй сдампить var_dump(PHP_INT_MAX) и var_dump((float)PHP_INT_MAX); и сравнить числа. Ты увидишь различие из-за округления.
Округление происходит в большую сторону и число становится больше PHP_INT_MAX.
Когда ты пытаешься преобразовать это число обратно в int, возникает проблема: число больше, чем максимальное положительное значение int и преобразовать в int его невозможно. Правильно, конечно, было бы выдавать ошибку в таком случае, но PHP все равно его преобразует, при этом получается отрицательное число.
Ты можешь сдампить var_dump((int)1e19); и увидеть отрицательное число.
Но почему при переполнении int получается отрицательное число? Это особенность хранения int в компьютере. Рассмотрим ячейку памяти размером в 1 байт. В ней можно сохранить число от 0 до 255. Если мы хотим хранить в ней еще и отрицательные числа, то мы должны придумать какой-то способ, как их закодировать. Можно, например, договориться так: числа от 0 до 127 обозначают сами себя, а числа от 128 до 255 обозначают -128 ... -1 соответственно. Это называется "дополнительный код" (дополнение до 2).
Почему придумали именно такую систему? Потому что с ней компьютеру просто и удобно складывать и вычитать положительные и отрицательные числа. Человеку такое представление не очень удобно, но он потерпит.
Теперь если мы в такую ячейку попытаемся записать слишком большое число, например число 129, то при чтении оно будет воспринято как -127, так как мы ранее договорились, что числа > 128 обозначают отрицательные числа.
Вот примерно то же самое происходит при преобразовании в int. Число слишком большое и оно попадает в область, которая представляет отрицательные значения.
Почитать подробнее про дополнительный код: https://ru.wikipedia.org/wiki/Дополнительный_код
а по делу?
А если серьезно то бери и совмещай голанг с пхп если потребность есть. А не рассматривай всякие ультрамаргинальные говны типа свуле или реакт пхп. Нода для фулстеков обслуживающих экономных кабанчиков с малыми или средними проектами.
Если у тебя начался вывод, то уже нельзя делать header, потому что пошло тело ответа.
Про буферизацию хуй знает.
Если ты не знаешь, что такое HTTP-заголовки, то тебе надо подучить протокол HTTP и лучше понимать, как браузер взаимодействует с сервером, на котором запускается PHP скрипт. Прочти, например, этот урок: https://github.com/codedokode/pasta/blob/master/network/http.md
Когда ты генерируешь страницу и отдаешь ее в браузер, ты можешь перед ней добавить HTTP-заголовки. Заголовки нужны, чтобы сообщить браузеру о типе ответа или например чтобы ставить куки, или чтобы отдать содержимое не как страницу, а как файл для скачивания.
Когда твой PHP-скрипт генерирует ответ, то он сначала должен выдать HTTP-заголовки, если они нужны, а только потом выводить HTML-код страницы. Если ты вывел хоть один символ, то заголовки выдавать уже поздно.
Допустим, ты инклюдишь файл с таким содержанием:
<?php код ?> тут несколько пробелов
Все, что находится за пределами тегов, PHP выводит как есть.
При подключении такого файла PHP выведет эти несколько пробелов. И значит ты не можешь уже отдавать заголовки.
Если ты не пользуешься заголовками, то тебе это не очень важно, но лучше сразу приучиться не ставить закрывающий тег.
----
Буферизация - это режим в PHP, когда выводимые через echo или другим способом данные не отправляются в браузер, а перехватываются и сохраняются в переменную. И ты с ними можешь делать что угодно. Например, ты можешь таким образом вырезать из HTML-кода лишние пробелы, чтобы уменьшить размер страницы.
В примечании написано, что если ты используешь буферизацию то эти лишние пробелы попадут в захваченный контент и могут как-то помешать тебе.
Такие книги пышут устаревшим процедурным кодом без ООП, полным уязвимостей. Там тебя не научат ни ООП, ни современным фреймворкам.
Если ты хочешь, то учи по книге, но потом возьми нашу задачу про студентов из ОП-поста и по ней научись современным подходам.
понял, спасибо за совет
Это какая-то дохуя передовая фича, на этом сайте видимо напиздели, что там 8.
Но я бы лучше не делал ничего по этому видосу, там всё очень плохо.
Именованные аргументы только с 8 версии
англ пока что подтягиваю, не пойму многого из ен книги.
можете что-нибудь из ру сегмента покидать, уважьте, пожалуйста
хрен его знает, ООП оъесняют, паттерны показывают, что да как. ДУмаю тут более менее современные данные
да, по шапке уже взял инфу. больше хочется, наверно, сделать упор на какой-то пет-проект на голой пыхе и мускл.
Через полгодика в ларавельку сунуться и там уже развиваться.
Не подскажешь ещё, в 25 лет не поздно это делать? Сейчас как вообще смотрят на возраст у вкатунов на пыхе?
Поздно. Делай подтяжку лица, фейковый паспорт, может тогда повезет прорваться.
должно быть пофиг на этой
Максимум на голом пхп с мускулом можешь сделать примитивную гостевую книгу чтобы тупо посмотреть как Коннект к бд сделать и примитивные инсерты / селекты / делиты запилить + немного хтмл и формочки ну ещё можешь ажакс на том же джейквери посмотреть - для начала его за глаза хватит. Это задача на пару вечеров / неделю.
Ты заебешься орм и mvc велосипедить. Запутаешься через пару недель в своем же коде и просто потеряешь время.
Пхп без фреймворков нахуй не всрался если это конечно не консольный скрипт.
Так что сразу учи ларавель.
Спасибо за совет. Я просто не до конца правильно выразился. Я хочу для начала голую пыху нормально знать. Циклы, условия, ооп базово. (я это итак знаю, просто надо вспомнить именно синтаксис пхп, в вузе всё-таки пилил круд-приложения на пыхе и мускл).
Просто привык делать всё от самого начала. Это как смотреть сериал. Смотрел 5 лет назад сериал 4 сезона. А сейчас уже их 10. Я не буду продолжать с пятого. Я буду с первого смотреть заново, т.к. всё забыл.
Также и тут. Базовый синтаксис знаю, но без углублений. Думаю месяц хотя бы на пхп и мускл потратить и дальше наверно в ларавельку.
По твоей ссылке человек подставляет переменные прямо в SQL-запрос и создает SQL-инъекцию. Чтобы не совершать таких ошибок, прочти наш урок про SQL-инъекции: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
При выводе он не экранирует данные, что создает угрозу XSS. Прочти еще и этот урок: https://github.com/codedokode/pasta/blob/master/security/xss.md
SQL-код он пишет прямо в шаблоне.
Если тебя интересует создание CRUD без фреймворков, используя ООП и современные подходы, прочти комментарии к задаче про студентов: https://github.com/codedokode/pasta/blob/master/student-list.md Это тот же самый CRUD по сути.
У нас, конечно, не веселые видео, а скучный текстовый формат, но он поможет тебе вправить мозги на место после таких уроков.
В нашей задаче про студентов объясняются и правила работы с формами, и ООП-модели, и паттерны вроде DI или TableDataGateway. Вполне современно, знакомит человека с паттернами, которые используются во фреймворках, или чего-то еще не хватает?
Ты правильно рассуждаешь. Если ты с нулевыми знаниями возьмешься за фреймворк, ты просто утонешь в его сложности. Фреймворк это абстракция на абстракции. Для изучения основ ООП я тебе советую учебник из шапки, в нем глава ООП, в ней задача Вектор. Для освоения CRUD я тебе советую задачу про студентов из шапки, к ней идут подробные комментарии. При этом ты можешь параллельно читать любые другие уроки и учебники.
После студентов можно браться за фреймворки.
Спасибо большое за советы.
Мне кажется, или карта знаний для джуна в шапке сильно раздута?
В ларавеле публичная папка называется public и файлы за ее пределами недоступны. Так что твой CSS надо класть туда.
Ты также можешь использовать https://laravel.com/docs/8.x/mix который скомпилирует и опубликует файлы из других папок в public.
Понял, спасибо. Я просто увидел, когда вьюшки создавал, что в папке resources есть папка css, и с какого-то хрена решил, что оно должно там храниться лол.
И таких комментарий почти под каждым видео на тему авторизации и отправки форм
На мой взгляд, это неправильный подход. Я такое видел не только в видео на Ютубе, но и в книгах: автор ради упрощения не объясняет про безопасность, и выкладывает код с уязвимостями. И между строк где-нибудь добавляет "не забудьте проверять данные в реальном коде". Понятно, что человек просто пропустит это замечание и приучиться писать неправильный код.
Я не обхожу тему безопасности. Например, в нашей задаче про студентов даются ссылки на уроки про XSS/CSRF/SQl-инъекции. В примерах кода работы с БД я использую плейсхолдеры. В уроке про шаблонизаторы я использую экранирование.
Потому я вам советую после уроков с ютуба делать нашу задачу про студентов и внимательно прочесть все замечания к ней. Тогда вы научитесь писать нормально.
Обычно так показывают веб часть core php, которым на практике никто не пользуется, а сидят на фреймворках, в которых это учтено.
Нахуя это делать и смотреть - другой вопрос.
У меня есть уроки по самым распространенным уязвимостям. Там объясняется, как от них можно защититься. Прочти их все:
Как хранить пароли: https://github.com/codedokode/pasta/blob/master/security/password-hashing.md
SQL-инъекция: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
Уязвимость XSRF: https://github.com/codedokode/pasta/blob/master/security/xsrf.md
Уязвимость XSS: https://github.com/codedokode/pasta/blob/master/security/xss.md
Если после прочтения будут вопросы, спрашивай.
Возможно. В прниципе, для тех же иньекций это просто решается.
А обвешивать какой-то учебный пример обработкой ошибок и прочей хуйней в десять раз больше самого примера тоже как-то уныло.
Хочу сделать такую же типа site.ru/redirect.php и с помощью гет параметров передавать в него ссылку куда направлять человека, и у меня ВСТАЛ вопрос, а что должно быть в файле redirect.php чтобы всё по красоте, я так понимаю это заголовки типа
header('X-Robots-Tag: noindex, nofollow');
header('Location: http://2ch.hk');
И всё? Мне надо чтобы поисковики на это шишкой не встали и чтобы чего лишнего наружу не передать, по хорошему бы ещё рефер удалить, помню раньше были такие сайты типа удаляют рефер и прочую хуйню когда переходишь по ссылке через их редирект, подскажите а как правильно собрать redirect.php, чё туда необходимо
Там обычно один редирект. Но можно включить followlocation, тогда пойдет сколько угодно.
смотри Игоря Борисова, он есть на нонейме вроде. Там курс по 5.6 пыхе, но базу вроде не плохо подает да и шутейки есть.
Бамп
Суть: хочу чтобы ссылки на внешние сайты были вида site.ru/redirect.php?to=2ch.hk
Что должно быть в файле redirect.php помимо кода редиректа header Location аноны?
Чтобы всё было как положено и не было подозрительно или плохо для поисковиков
В идеальном мире все пишут идеальный код без единой ошибки. В реальном мире у нас сайт из сотен тысяч строк кода, написанный людьми, которые давно уволились. И CSP позволяет повысить его уровень защищенности без перечитывания этих сотен тысяч строк кода. Разве это плохо?
Правда, если на сайте есть инлайновые скрипты, нам придется разрешить unsafe-eval, что ослабляет защиту.
CSP повышает стоимость нахождения уязвимости. Условно, без CSP уязвимость можно найти за X времени, а с CSP ее найти труднее и надо 10X времени. Соответственно, поиск уязвимости становится менее привлекательным для хакера и он пойдет лучше атаковать сайт без CSP.
Хорошо, спасибочки
Надеюсь хотя бы он не говорит в конце что так делать нельзя как он показал?
А всё зачастую потому, что не очень шаристые в IT кабаны думают что веб каким-то магическим образом ускорит разработку программы в несколько раз ("ты вон какой форум за месяц можешь заебенить, давай также заебенишь CRM нам?"). Платформы разные да но архитектура системы остается одной и той же (если не разносить ее части по эмбеду, конечно).
Отсюда и дроч на всякие MVC, роутинги внутри приложения, монструозные фреймворки в мире PHP.
Что хотел сказать - нихуя не ясно.
Фреймворки используют, потому что искаробочный веб сразу превращает всё в легаси, каковым он и является. Это хуйня из 90-х, подходы изменились за прошедшее время.
Да да да. Пхп говно. Все в этом треде это хорошо знают.
Два чая адеквату
Допустим простая админ панель
Через реквер вставляем внешний код который читает БД или пилим функцию чтения и там как то прикручиваем хтмл,но опять же в хтмл как то надо вывести данные
Не, ну если нужно чтобы приложение было доступно со многих устройств (а пилить одно и то же под разные платформы дорого) то веб хороша как платформа. А вот приложение которое заточено только под десктоп, но работающее под вебом- это тупо попытка сэкономить на разработке, не понимая в чем именно экономия по времени у веба.
Вопрос отменяется, я прочитал оп-пасту
>не очень шаристые в IT кабаны думают что веб каким-то магическим образом ускорит разработку программы в несколько раз ("ты вон какой форум за месяц можешь заебенить, давай также заебенишь CRM нам?"). Платформы разные да но архитектура системы
Бизнес думает проектом: его надо сделать и вписаться в ресурсы. Плохое качество может получаться из-за низкой квалификации веб-макак. В то же время, множество проектов на РНР успели выросли до глобальных, финансово успешны и устойчивы, понемногу оптимизируют код.
>В то же время, множество проектов на РНР успели выросли до глобальных, финансово успешны и устойчивы, понемногу оптимизируют код.
Привет, а можно пару примеров таких проектов (и на чем именно они написаны)?
Привет, не буду заморачиваться и отбирать, отвечу тем что на ум пришло (на чем именно -- ты в треде РНР):
wikipedia
vkontakte
badoo
tumblr
dostavista.global
tilda.cc
в РФ это (помимо прочего) все крупные e-commerce: Lenta, Magnit, Leroy Merlen, MTS, etc.
Да нет смысла даже перечислять, до сих пор 80% веба это PHP
Охуенный язык для быстрого старта бизнеса, чтобы потом, уже при деньгах, звдротствовать и байтоёбить.
пикрандом.
Route::get('#/[a-z]+-to-[a-z]+#', function () {
return view('welcome');
});
Вроде на сайтах по проверке регурярок все правильно, но не работает. Где я проебался?(
Бро. Нет смысла отвечать на такие посты, ибо некоторые не понимают что пхп это всего лишь инструмент, у которого свои минусы и плюсы.
>vkontakte
Там под капотом уже далеко не простой пхп, свои интерпритаторы, ВК даже в опенсорс его выкладывали там была штука которая компилировала пхп в код C++ и тот уже компилировали для прода осталось прихуярить монитор
>badoo
Эти затейники ещё те, мало того что хайлоад, так ещё на пхп написали нейронку, которую блюрит дикпики в личных сообщениях сколько же они хуев увидели при разработке
>Magnit, Leroy Merlen, MTS
Смотри вакансии, там пыхи давно уже нет, более того МТС давно уже отказался от магазинов на битриксе, у них раньше много чего на нём крутолось. А у магнита вроде всегда питоноджависты были.
хаскел
Я спрашивал абсолютно без сарказма.
>Плохое качество может получаться из-за низкой квалификации веб-макак.
А зачем их тогда бизнес нанимает? Правильно, чтобы сдешевить. Те же джава-разработчики выйдут дороже.
Главная проблема не в "веб-макаках" а в жадности кабанчиков, которые целятся не на те технологии, когда хотят запилить "сурьезный софт", для чего пхп плохо подходит изначально, ибо заточен под сайты.
Это не Notepad++ и даже не VSCode, че ты хотел, эклипса?
Ты её недооцениваешь, она за милую душу все 4+ гига оперативы сожрёт.
Она на жабе крутиться и жрет всю оперативку, я пока 16 гигов не воткнул такая же хуйня была
1280x720, 0:28
>Смотри вакансии
чо мне там смотреть, все эти компании сейчас сами звонят мне и коллегам и хотят PHP-разрабов
>более того МТС давно уже
https://shop.mts.ru/bitrix/admin/
Короче, цена твоей экспертизы для меня оказалась крайне невысока.
Это query string, он кладется в объект Request, не считай квери стринг частью адреса полноценной, роутеру чисто похуй на нее. Достать из реквеста надо конкретный нужный параметр в контроллере через $request->get('param'), $request->query(тут самое правильное), Input::get и т.д
Там от магазина вэбморда только осталась, остальное все что у них было переписали давно, где-то на Хабре комментировали. Похожая ситуация у Эльдорадо.
От души душевно в душу. И почему в гугле это не выдается, наверное потому что я искал типа "laravel route url parameters", а не query string.
Серьёзно, все на чистом пхп?
Или ты имеешь в виду это: фреймворки написаны на чистом пхп, а значит и проекты, написанные на фреймворке, тоже написаны на чистом пхп?
Серьёзно, на чистом PHP.
И это удивительно только для пориджей, а в то время было так: открываешь редактор и начинаешь писать, с первой строки до последней.
>И это удивительно только для пориджей
Да что сразу поридж-то, уже и спросить нельзя, чего ругаешься
Ну а откуда у тебя в голове предположение, что в приложении всенепременно должен быть некий фреймворк?
Фреймворки тащат с собой overhead, фактор black box, уязвимости и необходимость отслеживания зависимостей и обновлений.
В то время как приложения без них работают годами вообще без вмешательства человека. Но вот "фактор автобуса" в них зашкаливает, основная проблема в этом.
Во фреймворках уязвимости детектируются толпой лемингов. В самописной хуйне их вообще никто не учитывает. Это где блекбокс то? В самописной хуйне для новичка. Обновление в самописной хуйне вообще непосильная задача, а во фреймворках даже гайды есть как обновиться.
>толпой
Вот именно, поэтому как только в паблик выходит новая уязвимость, боты-сканеры тут же массово хакают все вордпрессы и прочие ларавелы, пиздят данные и расставляют майнеры. Первый день в интернете, что ли?
>никто не учитывает
не суди по себе
И во фреймворка компоненты отточены временем и вниманием многих участников, багрепортами, а в самописной системе все существует по принципу и так сойдет.
Нет, конечно, таких не существует. Только при чём здесь это?
640x640, 0:10
Это ошибка или хороший выбор? По сравнению с жс тем же. Реальный вопрос, я не тролль.
Хуево то что для вкатуна чисто пхпэшную работу найти очень трудно. Поэтому совет: если тебя заставляют одновременно несколько обязанностей разных профессий выполнять, делай одно очень хорошо, а на другое забей и делай плохо. Так победим!
Смотря сколько у тебя времени и какая цель.
Для обучения не самый лучший, прощает очень много ошибок и подходит только для веба.
Для работы на веб-фрилансе -- хороший, позволяет делать вещи очень быстро, и вакансий полно.
Я так понимаю, помимо пхп нужно обязательно знать html, css, js (хотя бы на начальном уровне), sql?
Учи пхп и sql И не только запросы. А вообще грамотное представление о СУБД нужно иметь. Чтоб прямо на собесе молодцом. А на всякие вопросы знаешь ксс хтмл, говори да немного знаю, делал... И в первую очередь ищи работу где нет намека на фулстачество. Это, конечно, советы, если ты программист, а не мамкин фрилансер.
Если данных немного и если тебя устраивает необходимость их вручную обновлять, то можно хранить в виде массива или массива объектов.
>Смотря сколько у тебя времени и какая цель.
Проект есть в планах. Для сайтов с большим функционалом и посещением пхп подойдёт или лучше выбрать другой язык?
мимо другой тоже вкатывающийся анон
слуш, ну если ты у себя в деревне вакансии на РНР не нашёл, то земля тебе пухом, братишка
>Есть ли тут аноны, которые совершили переход с пхп в какие-нибудь другие стэки?
Я на рельсы съебал после ларавеля и битрикса по сути тот же MVC фреймворк, всё +/- одинаково, только в рельсах много чего автоматом делается, кроме пары моментов разобрался почти сходу. А вот сам Руби дофига чего умеет и обладает более сахарным синтаксисом, с ним сложнее, как увидел в проекте так и охуел, но потихоньку через месяц освоился. На собеседник никто не дрочил, так за жизнь попиздели, вообще в рельсах рабочих рук не хватает в отличии от пхп и питона тут нет очереди из вкатунов.
Если ты шаришь за PHP и SQL, то вкатывайся в веб-уязвимости и зарабатывай на Bug Bounty.
Рельсы заинтересовали кстати. Коллега по работе получила оффер из ДС на удаленку как раз с Руби связанном. Почитал что ей написали, по сути расписали как тестовое сделать, около недели делать если прикинуть. А ты, анон, как вышел на такую работку? ХХ?
В деревне вакансий много, денег мало дают за это.
Зато интересная.
В телеге вакансию нашел и постучался хрюше
Его исправляют от даунского изначального состояния, оставляя совместимость с даунизмом.
Это примерно одного уровня языки, обслуживающие разные направления.
Шаурмячники снисходительно относятся к нашей шашлычной.
Свою или чужую? :3
Относительно языков -- по сути, так и есть, C# гораздо быстрее и подходит для широкого круга задач. Единственный плюс РНР -- адовая скорость разработки в вебе (да и то, фреймворки рано или поздно всех уравняют).
Но, справедливости ради, вкатывальщики сосут за копейки на любых языках, и в итоге всех рассудит только рыночек и итоговые банковские счета.
Чому злой такой?
> в двух словах
Чтобы меньше руками писать, плюс фреймворк дает порядок все лежит на своем месте и вокруг фреймворков обычно есть целая инфраструктура с кучей полезных библиотек
А в чем это выражается?
Ларавель вдохновлён рельсами
>Как вам 8.1 версия?
>Итс революшн,Джонни!?
Пока что больновато - многие пакеты еще не поддерживают его, в частности, ramsey/uuid и prophecy, прибитый пока что к phpunit.
Революшен (вернее сказать - ренессанс) начался уже некоторое время назад, еще до восьмерки. То, что основная масса макак сдриснула в какой-то момент на питон и голанг, имело неожиданный эффект: кристаллизовалась довольно продвинутая тусовка людей, способных двигать язык вперед. В итоге язык имеет реальный шанс порвать со своим лоховским прошлым. Он уже не совершит ошибок джавы, он впитывает лучшее из современных языков. Но это уже не будет тот хиленький язычок для вкатунов, который мы помним, и этакой интерпретируемой джявой он тоже не станет.
Атрибуты, файберы, паттерн-матчинг; гибкая модель типов, сочетающая жесткость, когда надо, и гибкость, когда надо. Асинхронность - и, кто знает, может, мы скоро увидим эвент-луп, подобный гошному. Станет ли гадкий утенок прекрасным лебедем?
Время покажет.
>Он уже не совершит ошибок джавы, он впитывает лучшее из современных языков.
Впитывает из джавы?
PHP становится мировой валютой ...
>Впитывает из джавы?
Вот синтаксис атрибутов из раста впитал, кек. У джавы основной дефект дизайна - это nullable-типы, причем, насколько я помню, сделать тип non-nullable нельзя. Похапе от этого свободен изначально.
В 2021 есть три php фреймворка: симфони, ларавель и в рашке немного легаси Yii2. В 99% случаев эти три. Нахуя при таких раскладах что-то еще непонятно.
Статические методы в таких случаях это плохо, почему, я объясняю в уроке по DI: https://github.com/codedokode/pasta/blob/master/arch/di.md
Если кратко:
- статические свойства "отравляют" код и вынуждают делать его весь в таком стиле. Например, ты сделал класс для работы с БД на статических методах. А ему нужно где-то брать конфиг, получается придется и класс конфига сделать на статических методах
- при использовании статических методов нельзя создать 2 объекта с немного разными настройками. Например, нельзя создать 2 объекта для работы с двумя БД. Или два соединения с одной БД. Это мешает при тестировании. В тестах мы хотим создать объект, попользоваться им и выкинуть, чтобы после этого не осталось никаких следов. У тебя же после теста в классе остается состояние в статических полях и оно может повлиять на другие тесты.
- при использовании статических методов нельзя заменять зависимости. Например, нельзя сделать второй класс работы с БД и подсунуть его вместо основного, так как в коде жестко прописано его имя. Это мешает делать подмену в тестах, а также при использовании сторонних библиотек. Нельзя заменить роутер на другой (например, с функциями отладки).
- вместо того, чтобы получать настройки через конструктор, класс со статическими методами сам их откуда-то берет. Это делает код менее логичным и понятным.
То, что в твоем случае тебе нужен лишь один экземпляр класса - это не повод использовать статические методы или синглтоны. Нужен один экземпляр - создай его с помощью new и используй.
Я так понимаю этот ваш пхп это именно для разработки внешнего вида сайта. Макака короче. Я так понял все рекламируют питон, но он для крутейших парней которые внутренности разрабатывают, там машинным обучением занимаются и всякой другой мутной темой.
Нет, неправильно понимаешь
В двух словах - работы на PHP много, но она почти вся низкооплачиваемая. Бывают редкие исключения. Очень много индусов. Ниша ларавела и фреймворков вусмерть забита индусами. На релокейт в Европу с PHP тоже рассчитывать особо не стоит.
>Нужен один экземпляр - создай его с помощью new и используй.
Все это конечно заебись на бумаге. Но в случае конекшена к базе именно что НЕЛЬЗЯ давать возможность создать несколько коннекшенов. И это именно что повод использовать синглтоны и статические методы.
>И это именно что повод использовать синглтоны и статические методы.
Всегда спрашиваю про область применимости синглтонов на собесах и как только слышу подобное - собес провален.
Нихуя ты жесткий. Ну такому жесткому в самый раз бегать с порванной сракой и считать инстансы коннекшенов к базе когда они закончились. Попутно еще вытирать с лица струю мочи от дба, которому ты сказал что тебе нужно только 50.
Ну попробуй в path прописать
Во-первых, изменение PATH через настройки компьютера требует перезагрузки, чтобы настройки применились.
Во-вторых, проверь, действительно ли PATH поменялся, командой
echo % %PATH% % (без пробелов между процентами)
>>154242
Иногда нужен отдельный коннект. Бывает, что баз несколько, например slave/master.
Чтобы не было возможности сделать несколько коннектов, используют DI контейнер и берут соединение из него, а не создают каждый раз вручную с помощью new.
>используют DI контейнер и берут соединение из него, а не создают каждый раз вручную с помощью new
>Нужен один экземпляр - создай его с помощью new и используй.
Мне поебать че там кто берет или не берет. Какие-то гарантии можно получить только если физически невозможно проебать в никуда коннект. Вас кукаретиков за километр видать. Вы просто не понимаете насколько "некрасивый код" мелкая хуйня в сравнении с отвалом базы.
Причем тут смузихлеб,доки реально надо переделать
У меня восьмерка, пробовал и через mb_substr b utf-8 прописывать, и через регулярки
>бегать с порванной сракой и считать инстансы коннекшенов к базе когда они закончились
Сразу видно дурачка, не умеющего в инъекцию зависимостей. Бегать с порванной сракой будешь ты, когда у тебя случится шардинг, кек.
>Через сколько десятилетий завезут поддержку кириллицы?
А что не так с юникодом? Не помню, когда в последний раз испыьывал с ним проблемы.
>Он у меня не работает
Ну что тут сказать, видимо, ты уникум. Чему там работать-то, епта? Показывай код.
И что ты тут нап показывпешь, отсутствие $_POST при запуске кода в песочнице? Минималистичный пример покажи, чтоб скармливаешь строку mb_* функции, а она плюется.
Ну вот так работает, а в браузере все равно ошибка что функция mb_substr не найдена
http://sandbox.onlinephpfunctions.com/code/4075c11b300f92b7c0e85a1b7934ea411ecc2a1c
Ну всё, смирись значит. Не положено тебе.
Оставь многобайтные кодировки людям, а сам иди дальше.
Ты даже документацию на русском языке осилить не можешь.
Не твоё это.
Возьму пики точены...
Да понял уже что надо было просто включить расширение php_mbstring.dll в ini, вообще у меня следующий вопрос - какого хуя нужна ручками править расширение у ini файла а потом так же ручками все туда писать? Нельзя сразу сделать все юзерфрендли?
>Лэндинги на пыхе
>Андроид разработка
>Блабла стратап бигдада
>Разработка it инфраструктуры
Я не спорю он может быть охуенным программистом. Пробился и добился, респект.
Только причем тут пхп ебаный? Какая нахуй связь между пхп и миллионами в месяц?
Там у него еще CSS написано. Хули не рассказываешь как доверстаться до миллионов в месяц? Пиздец просто, выбирай кароч норм язык с перспективами, вместо пхп параши, и вперед. Охуенно замотивировал.
Очередной Славик-затычка в каждой производственной дырке? Таких в пхп много, ибо пхп выбирают для экономии на штате
upwork помойка уже как 10 лет не актуальный ресурс поиска работы , для старту переезда в Восточную европу вполне хватит фуллстека (Польша, Чехия ,Германия etc )
Присоединяюсь к вопросу анона! Для каких задач нужна пыха? Я понимаю в каких случаях стоит выбрать джаву/котлин, в каких питон, а в каких, допустим, раст.
Руководствуясь чем можно выбрать пыху, кроме аргумента хорошего аргумента, который очень часто решает что мы тут, бля, знаем пыху, поэтому будем на пыхе. Ммм?
не вброс, реально задался этим вопросом, а тут анончик в треде уже его озвучил
>Есть ли у php сильные конкуренты?
Питон не смог. Успех голанга в основном держится на хайпе по микросервисам, а он уже проходит потихоньку; у голанга большие проблемы с выразительностью, бизнес-логику на нем писать трудновато. Но и сам похапе меняется быстро, сложно скащать, успеет ли удержать трон. Его проблема - в немодности; общественное мнение все еще вспоминает вордпрессы и битриксы при слове похапе.
>на хайпе по микросервисам, а он уже проходит потихоньку
В твоих фантазиях разве что. Вообще микросервисы конкуренты не пыхе, а крупным проектам на джаве/шарпе. Пыха находится в нише быстрых однопоточных решений не нацеленных на хайлоад. Вместе с джангой, рельсами и нодойжс.
Хуйлоадом хвастаться - это все равно как хвастаться что ты байтоеб на заводе, а не ленивая веб макака 300kk/sec. Просто узкая специфика.
Алсо я через openserver создал папку домена, чтобы открывался именно сайт, а не содержимое типа как в ftp, нужно именно index.php иметь всегда в корневике, верно?
>>156212
Я слышал про битрикс вроде как дополнение к php, что с ним не так? Вордпресс это вроде совсем другая вещь.
Я кстати ошибся, это аналогичные продукты, а ты даже не поправил. Вроде как 2/3 сайтов используют КМС, а вы как, разработчики здешние?
>Есть ли у php сильные конкуренты?
В плане говномакакинга в стиле взял mega_govno_cms_beta_2.1.14.zip и любой васян распаковал эту хуйню на хостинге, за пару тысяч натянул верстку и ты уже можешь публиковать новости на официальном сайте ООО "Кирпичнозаводский металлургический комбинат" с формой обратной связи и схемой проезда в ебеня промзоны. И подобные простые сайты визитколендосы на дешевых хостингах, тут конкурентов нет.
Есть чуть посерьезнее всякие магазины на битриксах и подобных цмс, тут тоже конкуренции особо нет, есть всякие cms на других языках, на тех же рельсах и джанге куча cms, но они не взлетели поскольку требуют большей квалификации и уже не разместить на говнохостинге.
А вот то что уже уровнем выше, то там во всю подпирают с разных сторон, MVC фреймворки Yii, Laravel подпирают Django, Rails и куча всякой хуйни на Node.js. Взять Symphony то там те же конкуренты, в некоторых тырпрайзных случаях уже .net и spring.
Микросервисы тоже много на чем пишут go для быстродействия , js для асинхронности, на рельсах удобно общаться между сервисам есть гемы spyke и her, да и крудить удобно, на джанге удобно круды писать есть djangorestframework, плюс у питона куча библиотек на все случаи жизни, на flask и sinatra можно быстро на коленке накидать апишку и будет быстрее чем в ларавелевском люмене. Некоторые умудряются сервисы на спринге это делать, но там отдельная история.
Значит грязно, не задумываясь об архитектуре наделать post get эндпоинтов.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.38.0/install.sh | bash
nvm install --lts
mkdir mycoolapp
cd mycoolapp
npm install express
vim app.js
let express = require('express');
let app = express();
app.get('/hello', function(req, res) {
res.json({hello: "world"});
});
app.listen(3000, () => {
console.log(`App started listening on a port 3000`)
})
node app.js
Допустим нужно быстро сделать примитивный микросервис с парой эндпоинтов и крудом, где не нужна архитектура или какое нибудь временное решение чтобы проверить гипотезу. Вместо того чтобы поднимать рельсы или джангу берешь микрофреймворки хуяк хуяк, на фронте тоже хуяк хуяк и готово, получили прототип.
ну и? лучше быть затычкой за пару миллионов в месяц
проблема в отсутствии асинхронности и многопоточности из коробки, и довольно низкими показателями скорости
>проблема в отсутствии асинхронности и многопоточности из коробки
Ох, это прям боль была на одном проекте надо было постучать к 5 разным партнерам и получить цены, немного математики и отдать пользователю, из-за того что нет асинхронных запросов то нужно либо ждать и отваливаться по таймауту, либо что-то делать. В итоге на фронте наколхозили выкрутились. уже хотели микросервис на ноде делать
Спасибо. У меня правда php не установлен как таковой, он в составе open server портативной, можно ли как-то их "подружить" с vscode?
А, ладно. Но выглядит клево все равно.
Я как-то дебагер подключал, уже забыл как делал, сейчас продуктами жидбрейнса пользуюсь
>проблема в отсутствии асинхронности
Тут поможет Amp.
> и многопоточности из коробки
С этим хуже, но в целом мультипроцессные сервисы неплохо работают на том же Amp.
> и довольно низкими показателями скорости
Похапе - один из самых быстрых интерпретируемых языков, если не самый. Я не так давно для одной задачки писал прототипы простенькой числодробилки на пыхе, голанге и расте. Голанг оказался шустрее всех, но однопоточный пых отставал от него всего на один порядок (а ведь можно было еще и многопоточность наколдовать, но было некогда).
Swoole
Отправляю с этой страницы ажаксом реквест с пост информацией.
Пыхыпы должен вернуть новосгенерированную страницу такого же типа с новыми данными.
Но она не возвращается. точнее не обновляется в браузере!
Логами проверил - генерация данных идет вполне себе корректно.
Создаю new \DOMDocument("1.0", "ISO-8859-15"), навешиваю на него измененные данные, возвращаю назад, но остается старая страница. Не понимаю почему, все же логично делаю.
Хмм эта проблема со всеми редиректами, не важно какие данные.
Упрощу вопрос - отправляешь ажас запрос, пыхыпы возвращает страницу, как ее получить и отобразить? location.reload() перезагружает только текущую страницу
>Создаю new \DOMDocument("1.0", "ISO-8859-15")
Тут непонятно, что ты нахуевертил.
А в plain PHP, просто:
<?php
if ($_POST) {
echo 'blablabla <pre>' . print_r($_POST, true) . '</pre>';
// ну и тут делаешь что хочешь
}
Учи, вот
https://www.php.net/manual/en/domdocument.construct.php
Версия и кодировка.
Мне кажется ты вообще не понял вопроса :/
У меня вопросов нет, программирую на РНР с 2004 и работаю на США-штую корпу.
Так что, потрудись сформулировать, иначе мне просто неинтересно.
>AJAX
Значение знаешь?
>пыхыпы возвращает страницу, как ее получить и отобразить
Ну например, просто прихуячь результат через element.innerHTML
>я я я да я вы говно
Классека.
Работай дальше, нах пишешь раз неинтересно
>>160162
>значение
Намек на то. что я возвращаю целую страницу, а не кусок? Да, просто я тестирую сейчас как это все работает вообще, потом поменяю как именно надо.
>просто прихуячь
Через document.documentElement получилось! Спасибо.
Однако у меня вопрос остался.
Нормальная ли это практика и почему у меня просто возвраты страниц, редиректы, из обработчика реквеста ажакса, не работают?
Представил как ты вскидываешь голову с запястьем на лбу.
>Нормальная ли это практика и почему у меня просто возвраты страниц, редиректы, из обработчика реквеста ажакса, не работают?
Ты какое-то говно делаешь. Если ты редиректишь аякс запрос, то именно он и будет редиректится (чекни в девтулз, у тебя по итогу будет два запроса), если хочешь через жс это делать то можешь попробовать window.location.href = URL, а сам юрл хоть плейн текстом отправлять. Через innerHTML менять всю страницу такая себе идея, потому что у тебя все обработчики в жсе отвалятся, и нужно будет заново их биндить, у тебя ломается история в браузере, нужно руками обновлять урл, делать обработку back, хранить где-то предыдущую страницу, вешать на неё обработчики если юзер нажал на back, короче делать всё то, что браузер делает за тебя, идея говно по дефолту.
Я не хочу это делать через жс, жс просто отправляет данные на серв что нужна страница с такими-то данными.
Страница у меня собирается скриптово, по кускам.
Мне нужно после запроса ажакса получить эту страницу.
Вот человек вводит рут - рут кидает на обработчик - обработчик отправляет вьюху - вот как это обычно работает.
Я же отправляю запрос ажаксом - запрос в обработчик - обрабочик отправляет вьюху - вот последний пункт тут у меня не работает. (классическим способом) И мне очень интересно узнать, почему именно этот способ не работает?
>почему именно этот способ не работает?
А чего ты решил что он должен работать? Браузер должен магическим способом понять что хтмл в аяксе это новая разметка страницы? Это уже твоя задача обрабатывать эти кейсы.
>Страница у меня собирается скриптово, по кускам.
У тебя куски хтмла приходят? Нужно брать строку ответа из аякса и руками маунтить (можно просто через innerHTML у элементов контейнеров для этого хмтла).
>Я же отправляю запрос ажаксом - запрос в обработчик - обрабочик отправляет вьюху - вот последний пункт тут у меня не работает.
Если у тебя в обработчике страница приходит полностью (с <html></html> и этим всем), то сделай просто ссылку на эту страницу, зачем это через жс делать я не сильно понял, и как я уже говорил у тебя это просто не получится.
Не будет ли проблем в однопоточном режиме, если страница сразу 2 гет-запроса со скриптов отправит?
Какие вообще подводные связываться с вами?
До этого только запускал тестовые серваки на ноде всякие.
PHP ничем не отличается от любого другого серверного языка.
Ваша цель -- договориться о понятном и однозначном протоколе передачи данных. Хотите потратить время -- GraphQL; хотите быстро и чтоб работало -- как можно более простой REST API.
Хм, ну наверняка тогда придется делать один запрос.
Задача стоит в, прежде всего, чтобы работало.
Сначала вообще передачу не осилили, надеюсь, из-за CORS.
Когда в последний раз заглянул в гит то увидел вместо страниц кучу php-файлов и вообще не понял что происходит.
>Не будет ли проблем в однопоточном режиме, если страница сразу 2 гет-запроса со скриптов отправит?
Не будет, самих процессов может быть много, не парься
Ну а причём тут git.
Вам нужен некое общее тестовое окружение, на котором ты будешь отрабатывать свои запросы.
Например, бекенд предоставляет тебе инструкцию по развёртыванию его приложения (например, в docker-контейнерах), вы договариваетесь о способе обработки статики (например, твои скрипты должны собираться в public-папке в его ФС), и так продвигаетесь от релиза к релизу.
Или проще, по-олдскульному -- он деплоит на некую тестовую площадку, а ты работаешь со своими скриптами там же.
>куски приходят
Не-не, я просто упоминаю кастомность страницы чтобы объяснить что
это не просто левая страничка на которую можно было бы легко перенаправить в руте. И мало ли, я даже думал, что из-за кастомного создания страницы я мог бы теоретически что-то делать не так с тонкими настройками, метатегами, и браузер просто не читал бы страницу, потому что считал бы что описание у нее одно, хоть содержание разное, поэтому можно и не обновлять - вы бы такое тоже могли бы упомянуть, но сейчас я знаю что не в этом точно причина.
Ну и я думал что вообще отправляю что-то сломанное - тоже отмел этот вариант сразу же.
Просто вот пытался сказать что есть html страница, ее надо вернуть.
>страница полностю
Нет, приходят данные разные просто, потом это все доминошкой обрабатывается и создается новое.
>с чего решил
Я просто видел примеры как люди возвращали страницы(не пыхыпы, но логика таже), я и подумал что реквесты делаются не с ожиданием конкретных данных, типа я отправляю тебе строку, а ты мне число и не смей больше ничего отправлять кроме числа, то бишь запрос от клиента идет, а что обратно будет это серв решает.
И вот серв решил вернуть страницу, какая проблема ее скушать, ведь с рутами же все работает нормально? Ты видишь тот же штмл формат, видишь теги, в чем проблема?
ПС спасибо
У тебя шиза (это нормально).
Постарайся сделать раза в 3 более простые и работающие приложения.
А уже потом, когда поймёшь принцип, начинай внедрять более сложные уровни абстракции.
https://www.youtube.com/watch?v=hEAl3QTkehc
>двач у меня не растет бицуха, тягаю 3-12 8кг гантелями, может на гриф перейти?
>старайся делать зарядку, разминать мышцы, спорт полезен
>???
Работаю над твоей мамкой на данный момент.
Устарел, зато работает в джва раза быстрее, всякого новомодного говна, вроде питона и имеет понятный и вменяемый синтаксис
сыночка-корзиночка нашел к чему докопаться, по другим вопросам возражений нет?
Проще искать до чего не докопаться, вся стандартная либа это говно говна, которое тащат для совместимости.
https://www.php.net/manual/en/ref.strings.php
https://www.php.net/manual/en/ref.array.php
В итого залезут в капсулу фреймворка и сидят в этом болоте.
С жс было что-то подобное, но это важный язык и за него серьезно взялись большие дядьки и пилят.
Хрен его тогда знает. Пыху учи. Правда не знаю, сможешь ли ты попасть на фриланс, миновав опыт в офисе.
В моей мухосрани появилась вакансия "PHP Программист", платят 30к на руки:
"Младший программист.Базовые знания HTML CSS Javascript.Базовые знания PHP.Базовые знания SQL и построение простых запросов (Select,Update,Delete, Insert). "
Все знаю, кроме пыхи. Так вот, что подразумевают под "Базовые знания PHP" в такой вакансии? Какой проект по быстренькому заделать чтоб хотя бы позвали на собесед и заскочить уже кабанчиком в АЙТИ? Времени вагон. Заранее спасибо за ответы
Это для галочки пишут, на самом деле всем похуй, на собесе спросят не дебил ли ты и посмотрят на реакцию, не более.
Проблемы начнутся на самой работе, когда ты всем напиздишь что шаришь, а по факту не сможешь вывезти базу.
Я лично через это проходил, теперь вообще смотрю на требования сквозь пальцы, так как надо смотреть между букв.
От тебя зависит. Если фирма большая то пизды могут дать в первые недели так как им надо чтобы шестерни работали и сдавали таски. Если фирма очень большая, то могут забить хуй и позволить тебе считать точки на потолке(только ты еще устройся кык). Ну и в студийках как договоришься, тут тет-а-тет решать надо.
Короче, ты как и большинство вкатунов, задаете одни и теже тупые вопросы, но как бы вам не отвечали это вам все равно никак не поможет. Ты либо овощ, либо нет.
От тебя зависит. Если фирма большая то пизды могут дать в первые недели так как им надо чтобы шестерни работали и сдавали таски. Если фирма очень большая, то могут забить хуй и позволить тебе считать точки на потолке(только ты еще устройся кык). Ну и в студийках как договоришься, тут тет-а-тет решать надо.
Короче, ты как и большинство вкатунов, задаете одни и теже тупые вопросы, но как бы вам не отвечали это вам все равно никак не поможет. Ты либо овощ, либо нет.
Да я знаю, что я овощ и так, пытаюсь еще до собеса по-максимуму изучить процесс создания сайтов с пхп.
Перед смертью не надышишься. Вероятно ты учишь левую хрень, а тебя могут спрашивать за другое. Просто иди и устраивайся.
>Какой проект по быстренькому заделать чтоб хотя бы позвали на собесед и заскочить уже кабанчиком в АЙТИ?
Проект по нажатию на кнопку "Откликнуться", осилишь?
Если серьёзно, в пхп нет ничего, что нужно прям "учить", если ты знаешь вообще хоть какой угодно язык программирования. Просто прям на работе вводишь в гугл "php how to do (хуйнянейм)", и копируешь что найдёшь на стековерфлоу. Я таким образом уже несколько месяцев как вкатился.
Смущает что там жс ещё, как обычно нужен бэкендер которому не надо будет платить за работу фронтенда
Спасибо, попробую. Результатами поделюсь в треде, если местечко уже не займут к этому времени
>нужен бэкендер которому не надо будет платить за работу фронтенда
Так-то похуй - рабочее время 8 часов. Какая разница что ковырять вилкой - ПХП или ЖС? Если они думают, что ты в 2 раза быстрее работать будешь на двух языках, то быстро разочаруются.
Хотя 30к это очень-очень мало для человека, который умеет в пхп и жс. Там не задрищенская шароёбская веб-студия какая? Смотри чтоб не посадили тебя различные CMSки ковырять от заказчиков - охуеешь за эти деньги.
Это очень похоже на студию, обычно стек более подробно пишут, а тут походу придется со всем по чуть-чуть работать и в основном битриксы с вордпрессами, еще на гуслях играть и ебаться вприсядку, трекая каждые 10 минут рабочего времени
>Обычная зп для мухосранска
У меня кореш на автомойке столько же зарабатывает без всякой ебли с кодом. В том и дело, что это обычная зарплата в мухосрани для человека без навыков, а тут какие-то требования требуют ещё.
>Кмски разве не созданы для облегчения создания сайта?
Как бы да, но каждая свои костыли костылит и их надо знать. Т.е. помимо того же пхп, жс, вёрстки, тебе ещё придётся и внутрянку CMS понимать. За 30килорублей это нихуйственные требования уже.
>>161161
Чёто тоже кажется, что так и будет. Не удивлюсь ещё и серой зарплате задним числом.
Нихуя не понял, буду дальше читать.
>с помощью echo <<< выводите форму?
Так никто не делает нынче. Обычно уже есть свёрстанный шаблон формы, куда подставляются уже подгтовленные в пхп или любом другом ЯП данные. Напрямую в шаблоне присутствует только логика для отображения, но не работы с данными.
>>161496
>можно ли заработать на парсинге сайтов (для себя)?
Ну если ты сам себе платить будешь, то ради бога.
>писать парсеры и размещать у себя на хостинге/впс?
Не всё так просто - каждая страница имеет свою структуру и под неё придётся писатб свой набор запросов. К этому добавь разные наборы полей и тот факт, что далеко не всем это нравится = что их парсят.
В целом готовься тратиться на толстого VPS и канал. От 50$ в месяц, в самом нищебродском варике. К этому добавь обязательные прокси + логику по их проверке. Некоторые сервисы надо парсить не через html, а через запуск полноценного хедлесс браузера с отработкой жаваскрипта, что тоже требует мощностей, делать всё надо многопоточно - сколько по железу потянешь. Ещё часто будет слетать парсинг - изменения в страницах, добавление проверок на стороне источника и тд - это всё на тебе.
В общем попробуй канешно, но будет непросто.
Ты че бля, в такую рань толко на завод работяг собеседуют, а не господ макакенов.
>>161780
>>161857
Анончик, репортую:
Пришёл я значит в намеченое время (на 11) к ним в офис. Встретила HR-ка. Встретила тёпло. Предложила кофе. Я культурно отказался. Обстановка в целом в офисе - уютно, тихо и спокойно. Без никакого кипиша. Половина народу с кружками ходит, попивают кофе. Посадили в отдельною комнату, я так понял для митингов.
Блять, как же я нервничал в это время, это пиздос. Не педать словами. Первый раз такое в жизни. Думал что сейчас будет глобальный разъёб во все щели....
Короче, ближе к делу. На собеседовании было 5 человек + я: hr, бэк лид, фронт лид, директор конторы (не наш человек, я так понял с сша) и переводчик для него. Начали спрашивать по очереди, сначала бэк: база даных, что такое индексы и для чего нужно, какие есть связи. По php спросил что такое контроллер, потом спрашивал по ларке: спросил о посредниках (middleware), request, response, как использовать form request, eloquent, как сделать дополнительное условие (orWhere), как сделать связи (relations). Потом почал спрашивать фронт: в основном о Vue.js (я о нем написал в резюме, что сталкивался с ним). Спросил о vuex, state, getters, setters, mutation, как получить данные из стора в дочерних компонентах, хуки и жизненный цикл, чем отличается data компонента и глобальный (экземпляра), далее спросил о SSR (серверный рендеринг, для чего нужен и как лучше) и кое что ещё. Всё не запомнил.
Все это время переводчик переводил мои ответы и говорил с главным. Он ничего не спрашивал, только в конце сказал типа "Okey, я вас понял".
В конце меня поблагодарили за собеседование, и за уделенное им время.
Вот здесь было реально интересно, и в тоже время очень приятно. Сказали что им понравилось, и что они после обсуждения свяжутся со мной и огласят решение. Ок.
Я собрался и ушёл.
Через час позвонили, сказали что я им подхожу. Согласовали зп (сказали что будут мне платить ту сумму которою я указал в резюме. я указал комфортную для меня на данный момент, как джуну Первый пересмотр зп будет через 4 месяца. Назначили день и время, когда мне прийти и согласовать режим роботы, "адаптацию" к команде и ещё некоторые вопросы.
В общем всё прошло, на удивление, отлично. Когда вопросы закончились - я просто выдохнул и начал дышать. Серьёзно. Я не ожидал что будет так просто. Всё это время я готовился по примерах собеседований в интернете. А там было всё: паттерны, принципы, psr и ещё кучи-кучи вопросов. А тут такое.
Вот так, анон у меня прошёл сегодняшний день.
>>161780
>>161857
Анончик, репортую:
Пришёл я значит в намеченое время (на 11) к ним в офис. Встретила HR-ка. Встретила тёпло. Предложила кофе. Я культурно отказался. Обстановка в целом в офисе - уютно, тихо и спокойно. Без никакого кипиша. Половина народу с кружками ходит, попивают кофе. Посадили в отдельною комнату, я так понял для митингов.
Блять, как же я нервничал в это время, это пиздос. Не педать словами. Первый раз такое в жизни. Думал что сейчас будет глобальный разъёб во все щели....
Короче, ближе к делу. На собеседовании было 5 человек + я: hr, бэк лид, фронт лид, директор конторы (не наш человек, я так понял с сша) и переводчик для него. Начали спрашивать по очереди, сначала бэк: база даных, что такое индексы и для чего нужно, какие есть связи. По php спросил что такое контроллер, потом спрашивал по ларке: спросил о посредниках (middleware), request, response, как использовать form request, eloquent, как сделать дополнительное условие (orWhere), как сделать связи (relations). Потом почал спрашивать фронт: в основном о Vue.js (я о нем написал в резюме, что сталкивался с ним). Спросил о vuex, state, getters, setters, mutation, как получить данные из стора в дочерних компонентах, хуки и жизненный цикл, чем отличается data компонента и глобальный (экземпляра), далее спросил о SSR (серверный рендеринг, для чего нужен и как лучше) и кое что ещё. Всё не запомнил.
Все это время переводчик переводил мои ответы и говорил с главным. Он ничего не спрашивал, только в конце сказал типа "Okey, я вас понял".
В конце меня поблагодарили за собеседование, и за уделенное им время.
Вот здесь было реально интересно, и в тоже время очень приятно. Сказали что им понравилось, и что они после обсуждения свяжутся со мной и огласят решение. Ок.
Я собрался и ушёл.
Через час позвонили, сказали что я им подхожу. Согласовали зп (сказали что будут мне платить ту сумму которою я указал в резюме. я указал комфортную для меня на данный момент, как джуну Первый пересмотр зп будет через 4 месяца. Назначили день и время, когда мне прийти и согласовать режим роботы, "адаптацию" к команде и ещё некоторые вопросы.
В общем всё прошло, на удивление, отлично. Когда вопросы закончились - я просто выдохнул и начал дышать. Серьёзно. Я не ожидал что будет так просто. Всё это время я готовился по примерах собеседований в интернете. А там было всё: паттерны, принципы, psr и ещё кучи-кучи вопросов. А тут такое.
Вот так, анон у меня прошёл сегодняшний день.
Спасибо!
Запусти через консоль
Нужен отдельный воркер, а ты со своего скрипта можешь отправлять ему задачи.
php my_cool_program.php
24
Заебумба. Поздравляю.
>директор конторы (не наш человек, я так понял с сша)
Бтв, а что муриканец забыл в пердях?
Профильная вышка есть?
> Бтв, а что муриканец забыл в пердях?
Честно - вообще не понял. Может он в своих западах в основное время пребывает, решил проведать, а я просто случайно на него попал.
> Профильная вышка есть?
Профильной - нет. Есть техническая.
минус
Как в php выделять отдельные запросы с клиента, по кастомным заголовкам?
Вообще, чтобы ты понимал, он перестаёт работать не после закрытия, а немного перед открытием. Если страница пришла, значит скрипт полностью выполнился. (В основном). Поэтому задача в принципе некорректно поставлена.
Хуй тебя проссышь, анон, о чём ты глаголешь. С какого клиента, какие запросы, почему ты обычные токены не используешь?
Со SPA в целом ебли всегда в 2 раза больше чем с классическими шаблонами. Так-то бы просто сессию поставил пользовательскую и нет проблем.
Мне особенно доставило, что у автора книжки видимо тоже нихуя не работало и он решил просто добавлять это значение без экранирования, но забыл полностью поменять функцию для этого случая просто на соответствующее значение из массива $_POST.
Я понимаю опечатки бывают, но это вообще ни в какие ворота. Хотя может это я туплю, не исключено.
>Экранируемые символы NUL (ASCII 0)
Это и есть char 0, верно? Но почему тогда вообще пустая строка была добавлена, а не цифры оставшиеся кроме нулей?
>анон взял книжку для изучения пхп
>код не по PSR
>автор хуй забил на проверку своего же кода
>get_post берёт данные из post это как вправолево и повернуть налево
Книжку выкинь.
>get_post берёт данные из post
Дай угадаю: а функция получения данных из get он назовёт get_get кек. А если будет в запросе параметр get, то вообще охуеешь $get = get_get('get'); словно масляное масло масляно маслит.
Лучше создавать элементы для страницы на фронте, а запросами отправлять чистые данные?
Потому что на данный момент процесс выглядит так:
Создаю документ на пыхе, через него элемент. Отправляю весь документ в HTML в запросе, на фронте создаю новый документ, даю ему данные HTML что скинул, и только после этого получаю свой элемент через getElement.
Выглядит максимально костыльно.
Примерно так:
$doc = new \DOMDocument("1.0", "ISO-8859-15");
$ele = $doc->createElement("lol");
$doc->saveHTML();
Отправляй чистые данные, а на фронтенде уже формируй их представление. По простому если: бекенд - для данных, фронтед - для их отображения. К тому же сервер у тебя один, а клиентов, в теории, может быть много и каждому из них страничку рисовать это дополнительная нагрузка - пускай они сами себе рисуют.
От задачи зависит - если ожидается, что будут высокие нагрузки, то нужно выносить часть логики на клиент, а если у тебя там простой сайтик и ты ему SPA начал пилить, то это так себе идея с оверхедом под 100%
Да-да, я так и представляю себе.
Что вообще такое "сессия"? Где она хранится? Что ты туда ставишь? У тебя аутентификация(логин) имеет место или нет? Мне кажется, что сессия -- это какой-то наебательский термин.
real_escape_string уже никто не юзает больше 10 лет, уже наверное лет 15. Используй php pdo вместо mysqli и вместо экранирования строк подставляй их отедльными параметрами.
Это один из вариантов, ныне более трендовый. Оба варианта рабочие. Я бы не сказал, что если высокие нагрузки, то якобы рендер HTML отъест много нагрузки. Это ещё предстоит доказывать. Во-первых начнём с того, что раз ты такие вопросы задаёшь, то ты новичёк, и тебе по-настоящему высокие нагрузки не светят в ближайшие 2-3 года или больше. Во-вторых SPA такого типа часто отдают дохрена js, который может есть кучу трафика. Вообще полностью готовых гарантированных рецептов как готовить высокие нагрузки, нет. Ты должен всё измерять и сопоставлять. Некоторые вещи на SPA делать очень сложно.
Спасибо, почитаю про это отдельно тогда.
Не думал, что так устарел материал, книжка 16го года (4е издание).
Старья с mysqli уже очень мало. Я ни разу не видел. Это невыгодно и бессмысленно. Если попадёшь, что вряд ли уже, то проще послать их нахуй и пойти на другую работу. Не трать время анона зря.
>Что вообще такое "сессия"?
Базу подтяни. Это классика, это знать надо.
https://habr.com/ru/post/437972/
https://www.php.net/manual/ru/book.session.php
Почему все упоминают спа спа спа спа?
>не светит 2-3
Лол, меня брали джуном в фирму среднего размера, своим продуктом и соответственно приличными нагрузками.
Хз чем там считаются большие нагрузки, 5-10кк запросов?
>Хз чем там считаются большие нагрузки, 5-10кк запросов?
Конкретных цифр не и быть не может - это зависит от реализации бекенда и бюджета на него. Хайлоад начинается где-то там, когда выгодней и проще потратить неделю работа бекенд-разработчика ок 150 тыс руб на оптимизацию работы приложения, чем просто купить ещё мощностей.
>Почему все упоминают спа спа спа спа?
Потому что это похоже на то, что ты описал. И это трендово, плохо это или хорошо.
>5-10кк запросов
В какую еденицу времени? Это в секунду?
Если тебя взяли джуном, то там над тобой есть куча старших кодеров, которые тебя пасут. Решение, где генерировать HTML, на беке или фронте, -- будет не за тобой.
>>163428
Если честно, никогда до конца не понимал, зачем это было реализовано в самом PHP. Мне кажется, в этом есть какая-то странность.
Да бекендер говорит что с одной страницы сложна реализовать принятие запросов, лучше разбить на страницы, вот и думаю что ему подсказать, что направить гуглить и не переделывать макет.
Это аутентификация или что? Там есть логин? Если у него уже есть аутентификация полностью готовая, то подстройся под неё. Он тебе должен сам сказать, что он считывает. Только скорее всего аутентификация работает через кукисы. Их можно так и оставить, но это угроза CSRF. Надо перекладывать из куки в localStorage и отправлять через хедер. Или ебаться с csrf-токенами.
В тч аутентификация. Куки все будут http, по идее. Он просто привык делать по ssr сайты в стиле 2007, а я еще фронт не прикручивал к чему-то отличному от ноды, поэтому у нас всплывают проблемы интеграции всякие вот сейчас.
Спасибо, в общем. Насчет localStorage нужно будет обсудить, но если хоть запросы по ajax осилим, то уже будет хорошо.
HTTP -- это и есть HTTP. На пхп можно сделать практически всё, что и на Ноде. В волшебной переменной $_SERVER есть все хедеры. Скорее всего пхп-шнику придётся наматывать на сессию хедеры через специальную либу/фреймворк какую-то.
>делать по ssr сайты в стиле 2007
Ждун, твой любимый SPA в 2010 появился - не сильно моложе. И нечасто нужен.
>Их можно так и оставить, но это угроза CSRF. Надо перекладывать из куки в localStorage и отправлять через хедер.
И чем это безопасности поможет? Я считал локалсторедж менее секюрной хуйней, куку можно сделать секюронли, хттп онли и т.д., а локалсторедж - решето
Потому что у разных техник есть внезапно преимущества и недостатки. localStorage и куки без httpOnly уязвимы к XSS, при условии, что XSS-атака была успешно совершена. А куки любые в принципе потенциально уязвимы к CSRF-атаке. Теоретически, если одновременно установлены оба флага httpOnly и SameSite=strict, то кука будет полностью защищена от CSRF. Наверное. Для вида атаки SameSite=strict обязателен. Но без него у тебя может перестать работать CORS, так что учитывай. С другой стороны, если у тебя XSS произошёл, то и без воровства кук злоумышленник всё равно устроит на сайте катастрофические проблемы, и потенциально всё равно легко украдёт акаунты другими способами.
https://habr.com/ru/company/oleg-bunin/blog/412855/
Статья могла устареть. Или стать вновь актуальной
Голая пыха никому в хуй не уперлась, на ней делать только чтобы базу языка подтянуть. Намного быстрее и эффективней на фреймворках.
А смысл? Не хочешь тяжёлую ларку - возьми куски от symphony, собери что тебе нужно и пиши на них, все равно же придётся роутинг и реквесты/респонсы велосипедить. К чему страдания?
Так симфони сложнее
>все равно же придётся роутинг и реквесты/респонсы велосипедить. К чему страдания?
Какие страдания? Это за день даже за половину делается если чистый пхп знаешь.
Новичку это нужно для понимания как оно работает на низком уровне. Те, кто начинает сразу с изучения фреймворков потом хуже понимают что делают.
Не поймёшь всё равно. Во-первых меня бесит, что говорит "чистая пыха". Пыха с фреймворком -- это не "изменённая модифицированная пыха." Либы не могут менять синтаксис. Пыха всегда "чистая". Ты должен учиться создавать функции и классы, дробить код на файлы и т.п. А ты хочешь просто сделать один файл и позырить на все суперглобальные переменные. Плюс ты не сможешь определить, какие паттерны подходят под задачу, и какие функции считаются устаревшими и плохими. Ты должен изучать хорошие практики программирования. И ты должен изучать особенности веб-приложений. Если не занимался веб-программирование раньше, то лучше начать всё-таки с фремворка и потом просто залесть внутрь него и там покапаться. И http и протоколы изучай.
>>166615
Аутентификацию самостоятельно сделать без уязвимостей почти нереально, например, если ты уже не опытный спец.
В принцппе я думаю, что скорее всего надо учиться и так, и так. В принципе не настолько важно, в каком порядке. Мне в своё время больше всего понравился подход Майкла Хартла. Это была книга не пхп, а по Руби, но пофиг. Вот он сразу пошёл по фреймворку, но он расписывал все хорошие практики программирования.
Каноны меняются от года к году. Мнения разных программистов противоречивы. Реализации ООП и задачи различаются. Вопрос слишком сложный. Хороший ответ на Дваче ты не сможешь найти. Посмотри как внутрене используются фреймворке. Они частично навязывают тебе, как использовать классы. Потом начни читать Макконела Совершенный код и Мейера "Объекто-ориентированное конструирование ПО" или что-то типа.
На основе класса создаётся объект. Объект это такая удобная переменная, которая не просто хранит какие-то данные, но и умеет с ними делать всякие полезные штуки.
По канонам как-то так.
Пиздец, я без задней мысли просто переименовывал txt файлы блокнота в php, а там оказывается какие-то невидимые пробелы добавлялись(BOM), из-за которых header'ы не обновлялись, а я думал модуля не было http-аутентификации.
Только где эти переменные сервера устанавливать?
https://web-programming.com.ua/http-basic-authentication-ili-http-avtorizaciya/
Попробовал по этому гайду, не работает, ошибка 500. В htaccess вроде сделал окончания строк по unix-совски(lf).
Почему такие подводные камни везде?
Нашел ошибку, слеши нужны прямые в пути к файлу пароля, а не обратные. А знаки переноса виндосовские все же.
Установи xdebug и настрой его. И научись юзать дев-панель браузера и curl. Ты должен отлаживать всё сам.
>Ты должен отлаживать всё сам.
Начинающим это трудно понимается - что дебажить их писанину никому не интересно и в целом трудозатратно.
Есть, например, у меня сервер с виртуал хостом типа testurl.test
я хочу, чтобы у меня по адресам page1.testurl.test и testurl.test/page2 открывались определенные страницы
Как это вообще делается? Как это называется? Подскажите хотя бы, что загуглить дебилу
Да. Самое главное -- отладка должна в первую очередь сокращать объем кода, в котором точно есть проблема. Локализация ошибки должна происходить. Начинающий фактически даёт слишком много информации о своей ошибке. Тут же и вёрстка, и клиентский код, и серверный, и база. Надо отследить, какие этапы отработали норм, а какие сломались. И искать ошибку уже в одном маленьком месте.
>Надо отследить, какие этапы отработали норм, а какие сломались.
Ага, по выложенному коду найти где там он обкакался. Т.е. никакой динамики и тестовых запусков - посмотри на картинку и скажи где я тут был не прав.
Ну да - щас бы чужой код дебажить. За спасибо.
Вообще так по мне это самое нудное в программировании - дебаг.
Самое нудное в программировании -- это перестать пиздеть и начать разрабатывать работающие программы.
>Если рассчитываешь получить дельный ответ, сформулируй правильно вопрос: «что я хочу получить, что я для этого делаю, что я вместо этого получаю». Если когда самостоятельно найдёшь решение — поделись в треде, мы за тебя переживаем.
Я и не делаю пока еще ничего чтобы это дебажить и искать ошибки логики, просто небольшие примеры где пока вон синтаксис/настройки сервера неправильные.
Сразу и синтаксис, и настройки сервера -- это сликшом большая область в каком-то смысле. Ты мог бы отдельно исследовать эти оба вопроса более минималистичными примерами.
Я знаю, что ты это не делаешь. Пора начинать. Тебе самому проще будет.
>перестать пиздеть
>двач
Тогда на твои тупые вопросы совсем некому будет отвечать.
Постскриптум, такскать.
>синтаксис/настройки сервера неправильные
>переименовывал txt файлы блокнота в php
Тут ничего даже не посоветуешь толком. Рано ещё тебе вопросы задавать мне думается.
Попробуй себе окружение нормальное поднять что ли. Погугли как люди работают и что используют. Какой, в задницу, блокнот, алё?
Я говорю к тому, что многие программисты много выдвигают всяких теорий, а потом многри из них не могут доказать на практике их работоспособность. И зачастую ещё и даже не хотят. Потому что баги фиксить не кайф, потому что отлаживать не интересно, потому что кодинг вообще не так интересен. Концепции на концепциях. Если менеджер приходит с задачей, которая не вписалась в концепцию, то концепция не виновата, а вот задача то сука плохая. Если медленно работает, то юзеры виноваты, нагрузили сервис, не могли сука потерпеть. Если баги, то ну и хуй с ними, концепкция есть, а баги не кайф фиксить, ну их нахуй. Если что-то не работает, то, значит, не не свезло, потомк ак-нить заработает. Но знать концепцию, даже не рабочую, всё равно сука надо. А писать работающий корректный код, нарушая при этом концепцию, -- ну это вообще удел быдла как бы. Если кто-то говорит, что концепция неудачно, то её просто не умеют готовить.
тебе нужна функция роутера, которая будет принимать адрес, разбирать его, и на основе запрограммированных правил отдавать нужный контент
Туда же всевозможные биллинги, и многие сервисы в телеком-компаниях и финтехе.
Там и управление памятью на PHP, и прочие "радости", которые рядовой программер РНР не увидит за всю жизнь.
Их немного, но платят, кстати, отлично.
332x480, 0:22
Инсайд: во многих (далеко не всех) банках, кстати, фреймворки вообще запрещены из-за уязвимостей и зависимостей от постоянно компрометируемых компонентов.
Такие банки предпочитают нести затраты на разработчиков своих, но более безопасных "велосипедов", в которых не возникают 0-day уязвимости в рандомные моменты по всему интернету.
>>168793
>>168791
>>168792
Как сказать... Java на своём месте.
А PHP проекты зачастую возникают как быстрые решения (в этом PHP нет равных) и постепенно прорастают в инфраструктуру
Например, написали 10-15-20 лет назад CRM или биллинг или телефонию на PHP -- что делать с такими программами? Работают отлично, новые функции оперативно впиливаются. Так и "едут" такие проги вместе с банком десятилетиями.
Да и что плохого, кроме, может, быть моды?
К каким книжкам (или не книжкам) можно приобщиться, чтобы быть способным ковырять такие серьёзные прожекты?
320x400, 0:13
Я недавно работал в финтех-корпорации на проекте РНР.
Нас было 5 человек в команде, у нас было 2 проекта (платёжный биллинг и программа внутреннего учёта) и "ехал" этот отдел примерно за 1.5M₽/месяц ФОТ.
За неплохую зарплату меня выжимали как тряпочку, при помощи всех современных практик отчётности.
>>168797
ИМХО, чтобы приобщиться к таким прожектам, надо в первую очередь культурно соответствовать запросам корпораций. Как и везде, негласно и неявно работает система свой-чужой.
А по книгам -- меня сейчас тут забросают камнями -- но https://fktpm.ru/file/84-soversennyi-kod.pdf , например.
А это правда, что опыт в какай-то момент приобретает ту критическую массу, при которой конкретный язык отходит на второй план?
То есть в голове полностью сформирована картина того, что и как в итоге должно получиться, и сделать это можно на чём угодно, хоть на пхп, хоть на ноде, хоть на джаве, хоть на голанге?
>>168813
И да, и нет. Я бы уточнил вопрос.
Теоретически -- однозначно да, язык отходит на второй план, т.к. методики и абстрактные конструкции проникают во все (многие) языки почти одновременно. Поэтому да, с опытом возникает понимание, как делаются вещи вне зависимости от языка программирования.
Практически -- почти однозначно нет, т.к. за каждым языком тянется инфраструктура, некоторые тонкости (окружение, менеджер пакетов, быстродействия, область эффективного применения, специфические ограничения) -- и у хорошего исполнителя всё это должно быстро "отскакивать от кончиков пальцев".
Аноны, из тех кто РАБотает, поясните какое у вас рабочее окружение на локальной машине? Я правильно понимаю, что все на линуксах сидят? Или есть те, кто на винде? Используете ли xampp, openserver или через вагрант, или docker? Как с mysql взаимодействуете - через phpmyadmin, workbench или еще как-то?
Очевидная макось, докер. С майскл - через любой клиент бля, какой пхпмайадмин?
Линукс, убунту, KDE. Хочу попробовать уйти на Дебиан на xfce, потому что кеды достали багами. Иногда docker, иногда просто. С базой через Phpstorm.
Да у кого как.
Я долгое время просидел под виндой на XAMPP, потом на WSL/Debian.
Потом понадобился докер, но под виндой он сильно тормозит, и придётся снова ставить линукс.
>с чего начать, чтобы не задемотивироваться этим дерьмом
Начни с документации. На самом деле Лара снаружи довольно простая и удобная. Почти CMS, но только для программиста, а не хуятора типовых сайтиков на шаблоне.
Всегда начинай с документации - сперва бегло ознакомься, а потом начинай свои пет-проекты хеллоуворлдить согласно туториалам.
Я вот люблю простой блог делать, с админкой и комментариями. Для ознакомления с новым фреймворком это хороший проект.
Как оно? Какие основные отличия от Symfony?
Просто пойми, что в других технологиях и фреймворках тебя ждёт то же самое. Без миграций веб-приложения никто не делает за пределами CMS. А фасады были описаны для С++ в начале 00-х. Так что осваивать Ларавель надо точно так же, как и всё остальное.
Drupal -- это CMS. Это абсолютно другое. Это больше для типа просто сайтов. Меньше кодинга и больше конфигурации.
>в геттерах и сеттерах получать и отправлять данные в бд
Получается запрос к бд на каждый пук и кек над моделью? А если у тебя этих моделей пару десятков тысяч крутится в рантайме?
>делать отдельной функцией получение данных из бд и внесение
Это.
Как я понимаю ты с ActiveRecord сразу начал. Попробуй сперва TableDataGateway паттерн использовать - хотя бы поймёшь как с базой надо общаться.
Везде по-разному. Есть паттерны ActiveRecord и DataMapper. Почитай, как сделано в существующих фреймворках в их собственных доках. Вот честно, я думаю, что без опыта ты не сможешь сделать всё идеально. Ну возможно сделаешь неплохо или нормально. На самом деле даже в этих фреймворках хоть это и работает для многих примеров, но иногда ООП в базах данных работает плохо, и приходится его покидать. В высоконагруженных проектах минимум часть взаимодействия с дб написано на голом или почти голом SQL, ну естественно с соответствующей защитой от SQL-инъекций. Есть такое понятие как "объектно-реляционное несоответствие". Реляционные таблицы плохо ложатся на объекты. Там всегда сложности. Есть вроде у Фаулера обзор обоих этих паттернов. ActiveRecord неплохо реализован Yii2, а DataMapper вроде реализован в Doctrine ORM.
У Роберта Мартина в clean code кое-где высказывается мнение, что объекты со своим поведением и объекты как структуры данных с полями -- это всё-таки разные вещи. Мне нравится эта идея и исходя из неё объектам, которы представляют таблицы дб, геттеры и сеттеры нафиг не нужны. Нужны только методы для работы с дб, типа сохранить или найти. Либо в самом объекте(ActiveRecord), либо в дополнительных объектах(DataMapper). Слои абстракции с логикой уже анкидываются где-то сверху, возможно в других объектах на уровень выше. Если это обосновано и удобно в целом.
Сайт обрабатывает только POST запросы
Laravel то фреймворк для даунов. В том смысле, что он очень простой и своей простотой поощряет писать говно. Пишу на нём год, нечеловеческие усилия прилагаю, чтобы писать всё нормально. Второй параллельно проект на Симфони и вроде всё очень похоже, вроде нет проблем с пониманием как что-то и там и там сделать, но переходы всегда такие тяжёлые, я ебу. На Лару как раз вкатывался, было тяжело с пониманием всей хуйни, благо дока охуенная была и ответов в тырнете много. А вот через полгода столкнулся с Симфони и тут говна поел знатно, порог вхождения блять на порядки выше, даже с учётом, что в Ларе половина компонентов оттуда, дока говна ебаного, нихуя не понятно. Если знаешь ООП, то может Симфони больше подойдёт, там написано без говняка(в плане кода) хотя бы. В плане видосов есть канал Дмитрия Афанасьева, в своё время очень нравилось, прямо заебумба. И самый очевидный совет: забей хуй на фасады. Просто забудь, что они существуют, пока ты не понимаешь почему на них срут в интеренет, но в момент осознания может быть уже поздно. Поставь Brave браузер и удали этот кусок css'а со страницы документации.
Очевидно надо
Полно новых проектов на симфони/ларе
А новые на чем пилят то? Вообще такое ошчушчение, что так говорят про все языки возвраста Пыхи и старше. Но по факту более новые языки растут разочаровывающе вяло. Иногда попадаешь на работу, а там оказывается, что тимлиды и CTO косонько смотрят на все твои типа "новые" Го, Ноды и Свифты. Многие программисты продолжают считать новыми и пугающе непонятными все языки и технологии новее 2003 года. И такие челы зачастую принимают много решений, реально влияющих на рынок. Часто вообще попадаются пыхеры, которые, как будто с 2007 с места не сдвинулись.
,
>тимлиды и CTO косонько смотрят на все твои типа "новые" Го, Ноды и Свифты
Ну так никто не хочет превращать проект в зоопарк языков и технологий. Где потом людей на него искать? Если есть возможность сделать на основном языке, то нафиг не нужны Го, Ноды и Свифты, а с этим у ПХП вполне норм - у него очень много библиотек.
Товарищ говорит, что большая часть пыхи -- легаси. Я спрашваю -- если это так, то на чём НЕ легаси тогда?
На том, чему меньше двух часов
Шапку читай - там есть всё нужное, вкатун.
Описание, правда немного устаревшее, есть тут: https://github.com/codedokode/pasta/blob/master/soft/php-install.md
Скачать версию для WIndows можно тут: https://windows.php.net/download#php-8.0
Там ты заметишь что есть несколько разных сборок с загадочными названиями вроде "VS16 x64 Non Thread Safe". Вот как они расшифровываются:
VS16 = Visual Studio 16 - это версия компилятора, которым была собрана сборка. Ее надо запомнить. Если ты будешь позже скачивать расширения к PHP, а также Апача, то надо использовать собранную таким же компилятором (VS16) версию. Иначе может не заработать. Если ты не планируешь ставить расширения и Апач, то можно не запоминать.
x64 = 64-битная версия, x86 - 32-битная. Если у тебя 64-битная ОС, выбирай 64-битную версию. Расширения PHP и Апач должны быть такой же битности, так что запомни, какую версию выбрал.
Non Thread Safe/Threas Safe - поддержка многопоточности. Надо выбирать версию с поддержкой многопоточности (Thread Safe), иначе могут быть проблемы при запуске PHP из-под Апача.
Далее, папку с PHP хорошо бы прописать в PATH и перезагрузить компьютер. Это описано тут: https://apache-windows.ru/как-добавить-путь-до-php-в-переменную-окр/
Далее, у тебя могут возникнуть сложности при работе с командной строкой. Прочти этот урок, чтобы их решить: https://github.com/codedokode/pasta/blob/master/soft/cli.md
Разные языки предназначены для разных задач и у них свои плюсы и минусы. Ну, например, Свифт придуман для написания GUI программ под iOS, и вряд ли кто-то будет на нем делать веб-сервис.
Что касается сравнения Ноды и Го, я не вижу тут особых плюсов у Ноды. Разве что, возможно, у нее больше пакетов для разных целей в экосистеме. Нода вообще, по моему, плохо подходит для написания бизнес-логики, так как в ней все асинхронное и у тебя код будет наполовину состоять из async/await.
Можешь посмотреть Го и попробовать на нем что-нибудь написать. Потом можешь отписаться тут, чем он лучше или хуже PHP.
Приведу пару моментов, где PHP удобнее. Ну например, в PHP добавление в массив числа пишется короче:
$array = [];
$array[] = 10;
А в Го длиннее:
var array []int
array = append(array, 10)
Или в PHP ты можешь легко создавать массивы на ходу:
$city = ['name' => "Москва", population => 10_000_000];
А в Го ты в такой ситуации должен будешь сначала объявить тип. Это можно считать как плюсом, так и минусом, смотря с какой стороны смотреть.
Если ты хочешь язык, где надо меньше писать кода, то лучше подойдет не Го, а Питон. Но он медленный в работе, зато быстрый в написании кода.
Надо. Access-Control-Allow-Origin говорит, можно ли отдавать ответ с твоего сайта скрипту на другом сайте. Но он не запрещает отправлять запросы с другого сайта на твой. То есть, ты можешь запретить только показывать результат запроса, но не можешь предотвратить его отправку. Этот заголовок введен не для включения защиты от CSRF, а наоборот, для отключения защиты.
Ну сам подумай: чтобы увидеть этот заголовок, браузер сначала должен отправить запрос на твой сервер.
Например, можно сделать страницу с формой с method='POST' и яваскриптом отправить эту форму на твой сайт и она успешно отправится.
Почему так неудачно сделано? Из-за совместимости. Так как раньше сайты могли отправлять запросы друг другу, то решили это не ломать и оставить такую возможность. Лучше бы, конечно, было бы с самого начала либо запретить такие трюки, либо использовать какой-то отдельный вид запроса для межсайтовых запросов.
Если ты хочешь радикальное решение проблемы CSRF, то откажись от авторизации через куки. Вместо кук отправляй авторизационный токен с каждым POST-запросом либо в теле запроса либо в заголовках. Тогда CSRF будет тебе не страшен.
CSRF возникает именно из-за того, что при отправке POST-запроса вместе с ним автоматически шлются куки и для сервера это выглядит, как будто это легитимный пользователь отправил запрос.
Еще один вариант решения - проверять заголовок Origin ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin ). Если вдруг запрос пришел без Origin, надо отвергать такой запрос. Это значит, старые браузеры без Origin не будут поддерживаться.
Еще один вариант борьбы - это атрибут SameSite=strict у кук ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite ). Он говорит, что куки не надо отправлять, если запрос к тебе отправлен с другого сайта. Минус - при переходе на твой сайт с другого пользователь оказывается разлогиненным, так как куки не отправляются и только при следующем переходе куки будут отправлены. Это не очень удобно на практике.
Надо. Access-Control-Allow-Origin говорит, можно ли отдавать ответ с твоего сайта скрипту на другом сайте. Но он не запрещает отправлять запросы с другого сайта на твой. То есть, ты можешь запретить только показывать результат запроса, но не можешь предотвратить его отправку. Этот заголовок введен не для включения защиты от CSRF, а наоборот, для отключения защиты.
Ну сам подумай: чтобы увидеть этот заголовок, браузер сначала должен отправить запрос на твой сервер.
Например, можно сделать страницу с формой с method='POST' и яваскриптом отправить эту форму на твой сайт и она успешно отправится.
Почему так неудачно сделано? Из-за совместимости. Так как раньше сайты могли отправлять запросы друг другу, то решили это не ломать и оставить такую возможность. Лучше бы, конечно, было бы с самого начала либо запретить такие трюки, либо использовать какой-то отдельный вид запроса для межсайтовых запросов.
Если ты хочешь радикальное решение проблемы CSRF, то откажись от авторизации через куки. Вместо кук отправляй авторизационный токен с каждым POST-запросом либо в теле запроса либо в заголовках. Тогда CSRF будет тебе не страшен.
CSRF возникает именно из-за того, что при отправке POST-запроса вместе с ним автоматически шлются куки и для сервера это выглядит, как будто это легитимный пользователь отправил запрос.
Еще один вариант решения - проверять заголовок Origin ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Origin ). Если вдруг запрос пришел без Origin, надо отвергать такой запрос. Это значит, старые браузеры без Origin не будут поддерживаться.
Еще один вариант борьбы - это атрибут SameSite=strict у кук ( https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie/SameSite ). Он говорит, что куки не надо отправлять, если запрос к тебе отправлен с другого сайта. Минус - при переходе на твой сайт с другого пользователь оказывается разлогиненным, так как куки не отправляются и только при следующем переходе куки будут отправлены. Это не очень удобно на практике.
Ты можешь почитать в уроке обзор подходов для работы с БД с помощью ООП: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
В сеттерах и геттерах не пишут запросы, так как это неэффективно: на каждый вызов будут отправляться запросы к базе.
>>169452
1) Их применяют там, где не нужна привязка к объекту. То есть это функции, которым не нужен экземпляр объекта. Например: функция, считающая число дней между двумя датами. Ей не нужен $this, она не привязана ни к каким объектам, потому она статическая.
Паттерн Utility Class - это сборник таких статических функций. Например, класс TimeUtility может содержать функции для работы с датой/временем, ArrayUtility - для работы с массивами.
Тут можно заметить, что такую функцию логичнее вообще было бы не помещать в класс, а сделать обычной функцией. Да, логичнее. Но в Яве нельзя писать функции вне классов, потому там придумали такой паттерн. А в PHP можно, но нет автозагрузки для функций, потому мы используем такой паттерн. Но ты все равно можешь сделать файл functions.php, подключить его в композере и класть функции туда.
2) Для статических конструкторов. Иногда есть несколько способов создать объект с указанием разных параметров. И мы хотим иметь несколько конструкторов для объекта. Тогда мы можем реализовать их в виде статических методов.
Симфони это фреймворк. Ты пишешь код сайта сам. Drupal это конструктор. Ты просто настраиваешь параметры сайта через админку, а пишешь только шаблоны страниц и модули, если какой-то функционал нельзя сделать стандартными средствами.
>>169389
Миграции придумали не в Ларавель. Они нужны, чтобы документировать изменения в базе данных через код. Представь, как плохо было бы без миграций. Ты решил добавить таблицу. Ты ее сначала руками добавляешь у себя, тестируешь. Затем идешь на продакшен и повторяя те же действия, добавляешь таблицу там. Затем выгружаешь код, затем сообщаешь своим коллегам, чтобы они тоже вручную добавили у себя эту таблицу. Какой смысл в совершении однообразных действий? А если тебе надо не одну, а 10 таблиц добавить?
Мне кажется, у тебя сложности не из-за Ларавеля, а из-за того что ты не знаком с правильной веб-разработкой.
Что ты хочешь сделать? И какой сервер ты используешь?
Если два независимых виртуальных хоста, на каждом из которых свой независимый код, то тебе надо сделать в Апаче 2 виртуальных хоста и 2 папки для них, а в случае с nginx/php-fpm - надо сделать 2 конфигурации и опять же, 2 папки для PHP кода.
Если же ты хочешь, чтобы у тебя был единый PHP код, и к нему поступали запросы для обоих хостов, то тебе нужно сделать один виртуальный хост в Апаче с Servername testurl.test, но прописать к нему Serveralias page1.testurl.test или даже Serveralias ★.testurl.test. В Nginx аналогично, настраиваем конфигурацию для всех поддоменов.
В случае с Апачем, документация по виртуальным хостам (англ) тут: https://httpd.apache.org/docs/2.4/vhosts/name-based.html
Переменные $_SERVER тебе задавать не надо. Их задает веб-сервер и PHP при поступлении запроса. Тебе надо только проверять их содержимое.
Ты можешь увидеть содержимое $_SERVER, сделав var_dump($_SERVER);
Для редактирования кода лучше взять бесплатный Notepad++ или пробную версию Sublime Text или бесплатный VS Code.
>>166942
Если ты пробовал писать что-то сложнее скрипта на 100 строчек, то ты наверно замечал, что у нас часто встречаются сущности, у которых есть свойства и действия над ними. Например, если ты пишешь магазин, то у тебя будет сущность "товар", у которого есть свойства: название, фото, цена, скидка, вес. И над которым можно делать действия: создать, выставить в продажу, снять с продажи, поменять количество. Аналогично, в магазине будут другие сущности вроде "покупатель", "заказ", "категория товара".
Для работы с такими сущностями удобно использовать классы. Мы описываем с помощью класса, какие есть свойства у сущности и добавляем функции (методы) для совершения операций над ними. После этого мы можем создавать объекты этих классов и работать с ними.
Далее, мы можем заметить, что у нас есть действия, которые вроде бы относятся по смыслу к сущности, но которые нельзя поместить в ее класс. Например, загрузка товара из базы данных: мы не можем поместить ее в класс товара, так как объект товара не существует до загрузки. Да и нехорошо, все складывать в один огромный класс. Такие функции удобно собрать вместе в класс "сохранятель товаров". Аналогично, мы можешь сделать класс вроде "оформитель заказов", "регистратор пользователей", "управлятель заказами" и так далее. Эти классы не соответствуют какой-то сущности, и у них нет свойств, и они содержат лишь наборы действий.
Постепенно мы весь код программы разложим по классам. Это и будет "каноничное" использование классов.
Если ты хочешь изучить ООП, то открой учебник их первого поста треда и прочитай там главу про ООП. Если что-то непонятно, спрашивай. Желательно на конкретном примере (то есть, что ты хочешь сделать с помощью ООП).
Переменные $_SERVER тебе задавать не надо. Их задает веб-сервер и PHP при поступлении запроса. Тебе надо только проверять их содержимое.
Ты можешь увидеть содержимое $_SERVER, сделав var_dump($_SERVER);
Для редактирования кода лучше взять бесплатный Notepad++ или пробную версию Sublime Text или бесплатный VS Code.
>>166942
Если ты пробовал писать что-то сложнее скрипта на 100 строчек, то ты наверно замечал, что у нас часто встречаются сущности, у которых есть свойства и действия над ними. Например, если ты пишешь магазин, то у тебя будет сущность "товар", у которого есть свойства: название, фото, цена, скидка, вес. И над которым можно делать действия: создать, выставить в продажу, снять с продажи, поменять количество. Аналогично, в магазине будут другие сущности вроде "покупатель", "заказ", "категория товара".
Для работы с такими сущностями удобно использовать классы. Мы описываем с помощью класса, какие есть свойства у сущности и добавляем функции (методы) для совершения операций над ними. После этого мы можем создавать объекты этих классов и работать с ними.
Далее, мы можем заметить, что у нас есть действия, которые вроде бы относятся по смыслу к сущности, но которые нельзя поместить в ее класс. Например, загрузка товара из базы данных: мы не можем поместить ее в класс товара, так как объект товара не существует до загрузки. Да и нехорошо, все складывать в один огромный класс. Такие функции удобно собрать вместе в класс "сохранятель товаров". Аналогично, мы можешь сделать класс вроде "оформитель заказов", "регистратор пользователей", "управлятель заказами" и так далее. Эти классы не соответствуют какой-то сущности, и у них нет свойств, и они содержат лишь наборы действий.
Постепенно мы весь код программы разложим по классам. Это и будет "каноничное" использование классов.
Если ты хочешь изучить ООП, то открой учебник их первого поста треда и прочитай там главу про ООП. Если что-то непонятно, спрашивай. Желательно на конкретном примере (то есть, что ты хочешь сделать с помощью ООП).
Реальные приложения пишут на фреймворках - либо на готовых, либо на разработанных внутри компании. Но прежде чем браться за фреймворки, надо изучить основы. Потому задачу про студентов лучше сделать без использования фреймворков, а после нее браться за них.
Если ты возьмешься сразу за фреймворки, то тебе будет очень трудно разобраться из-за незнания основ. Задача про студентов как раз и позволяет изучить основы.
>>165247
Теоретически, если злоумышленник не может внедрить код на твой сайт (XSS), то хранить авторизационные данные в localStorage безопаснее, так как они не добавляются в запрос автоматически, в отличие от кук, что исключает CSRF.
Если же у злоумышленника есть возможность внедрять скрипты, то хоть куки ты используй, хоть localStorage - он сможет отправлять поддельные запросы от имени пользователя.
Получается, localStorage безопаснее.
Да я в принципе понял идею, но в книжке что-то дичь с этими примерами аутентификации, там дальше левая бд создается, и типа пары логин пароль будто бы будут подходить, хотя пароли хранятся в другом текстовом файле .htpasswd, который про эту бд и не знает.
Автору следовало просто наверное инпут поля формы сделать и все.
Ты не очень ясно описал, что ты делаешь, потому я предположу, что задача выглядит так: ты на клиенте хочешь по нажатию кнопки (или какому-то еще событию) отправить запрос на сервер, и после получения ответа обновить информацию на странице.
Хороший вариант тут - отправить запрос на сервер, тот возвращает кусок HTML кода и этот кусок просто вставляется в текущий документ (без создания новых). Например, так:
// допустим, с сервера пришел HTML код в переменной html
document.getElementById('result').innerHTML = html;
Если ты хочешь формировать страницу на стороне сервера, то использовать DOMDocument не лучшая идея. Так как тебе придется писать очень много лишнего кода. Лучше использовать шаблонизацию, как описано тут: https://github.com/codedokode/pasta/blob/master/php/templates.md
То есть, ты заранее делаешь шаблон и потом просто подставляешь в него данные. Есть хороший и удобный шаблонизатор Twig.
Если же ты хочешь перенести шаблонизацию на клиент, то в общем случае это усложняет код и утяжеляет фронтенд. Теперь пользователь должен будет загрузить на клиент шаблонизатор, шаблоны. Шаблонизацию на клиенте имеет смысл делать, если у тебя сложная логика на клиенте и ты обрабатываешь и преобразуешь там данные. Если тебе просто надо что-то отобразить, то проще получать с сервера кусок HTML и вставлять в нужное место страницы.
Это плохой код, и плохая книга, если в ней такому учат. Параметры в запрос надо подставлять через плейсхолдеры и подготовленные запросы (пример для mysqli: https://www.php.net/manual/ru/mysqli.quickstart.prepared-statements.php ). Тогда данные автоматически экранируются как надо.
Если тебе хочется экранировать данные вручную, то надо это делать непосредственно перед запросом (а не в функции get_post).
Экранировать данные в момент их получения из $_POST неправильно. Потому что в большой программе место, где данные экранируются, будет расположено далеко от места, где они подставляются в запрос и очень сложно и долго проверить, что все данные экранированы (для этого тебе придется отследить их путь по всему коду). Данные нужно экранировать там, где они используются. Плейсхолдеры как раз решают эту проблему.
Также, тут неправильно обрабатываются ошибки. Они выводятся на экран. Это значит, что если произойдет ошибка, то пользователь ее увидит и ничего не поймет, а администратор сайта о ней не узнает. Ошибки надо писать в логи. Проще всего включить режим выброса исключений в mysqli ( функцией https://www.php.net/manual/ru/mysqli-driver.report-mode.php с параметрами MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT). Тогда локально ошибки будут выводиться на жкран, а на продакшене - писаться в логи.
Ошибка где-то в другом месте. real_escape_string может превратить данные в пустую строку только если в них содержится совсем уж мусор (что маловероятно). Потому сдампь содержимое POST с помощью var_dump($_POST); и сдампь что получается после real_escape_string.
>>162318
Да.
>>161979
Нужна очередь задач, а не костыли.
>>161891
Наверно, нужны обработчики запросов, которые отправляются из этих модальных окон.
>>161496
Только если у тебя есть готовые наработки и ты способен быстрее других писать парсеры, обходить капчи, блокировки итд. Так как скрейпинг довольно простая задача, там высокая конкуренция и низкая оплата.
Мы используем шаблоны https://github.com/codedokode/pasta/blob/master/php/templates.md
>>159811
Потому что браузер не обрабатывает ответ на аякс-запрос. Если ты отправил запрос аяксом, то ты сам должен яваскриптом обработать ответ на него. Браузер за тебя это не сделает.
>>155161
Это и есть юзерфрендли, просто оно юзерфрендли для админов, а не для домохозяек. Тебе кажется, что если бы вместо текстового файла было окошко с настройками, то было бы проще? Но это не так.
Начнем с того, что настроек очень много - сотни. И у тебя будет не просто окошко, а окошко из 20 разных страниц с десятками опций на каждой. И хорошо, если к нему прикрутят поиск по имени, а если нет - то ищи нужную настройку. И точно так же тебе надо будет разбираться, какая настройка за что отвечает.
То есть, надо много трудозатрат, чтобы сделать такое окошко, а пользы от него будет мало.
А смотри, какие плюсы есть у текстового файла:
- в нем есть поиск по имени
- его можно обрабатывать программами, например, можно пропустить его через фильтр и увидеть только настройки с определенным словом в названии
- его легко сохранить, забекапить, восстановить из бекапа, объединить с другим файлом
- его можно обновлять или генерировать программно
То есть, возможностей текстовый конфиг дает намного больше, чем окошко с галочками.
Это ты напутал.
HTTP-авторизацию можно проверять в двух местах - на уровне веб-сервера (apache или nginx) или на уровне PHP. В первом случае при запросе без правильного пароля сервер его отвергает и PHP даже не вызывается. Во втором случае веб-сервер на пароль не смотрит и передает все запросы в PHP.
Обычно проверку на уровне веб-сервера делают, чтобы ограничить доступ к сайту целиком для небольшой группы людей. Например, это какой-то сайт, доступ к которому есть только у сотрудников компании. Без знания пароля невозможно зайти ни на одну страницу.
Файл htpasswd используется именно в такой ситуации, если ты хочешь делать проверку на уровне Апача. В твоем же примере на скриншоте проверка делается в PHP, и в этом случае не нужен файл htpasswd и не нужно ничего настраивать в веб-сервере.
Если ты хочешь сделать что-то похожее на обычную регистрацию, то лучше не использовать HTTP-авторизацию, а использовать авторизацию на основе секрета в куках. Потому что куками легко управлять: поставить куки, очистить куки. А HTTP-авторизацией управлять неудобно, например, нет простого способа "разлогинить" пользователя.
Да я понял в общих чертах про переменные сервера уже, vscode установил как выше советовали и Notepad++ для удаления BOM'ов (может и вскод умеет, но я не нашел).
>>171089
Ну он говорит в книге дальше, что лучше через подстановку prepare делать, там постепенно как бы примеры идут.
>>171097
Ничего вообще не менял, только добавил дамп этих только переменных, все работает как надо. Чертовщина какая-то, может опять из-за каких-нибудь BOMов пусто было.
>>171121
Еще не дошел в книге про это, возможно там вообще нет про это, отдельно тогда поищу.
>>171127
Да, точно. Из-за BOM'а в подключаемом файле не работали хедеры http 401, а я думал что-то из-за модуля апача. Нельзя быть самоуверенным, особенно новичку.
Спасибо за подробные ответы, вот уж не лень писать действительно!
Ну собственно вот отличный пример, почему к пхп макакам относятся как к конченному быдлу и непрофессионалам.
Есть мир белых людей, в котором везде, от джаваскрипта и питона до котлина и раста, используют структуры данных и знают чем они отличаются. Что такое массив, список, стек и мапа, когда что из этого нужно применять, какие у них плюсы и минусы.
А есть мир уебанов, в котором какой-то долбоеб в далеком 1995 году решил, что простому Джону нахуй не надо знать все эти структуры данных. Программирование шмаграммирование, мы тут персональные странички делаем в сети интернет. И назвал хеш мапу ебать массивом, ну чисто по приколу.
И вот, 26 лет спустя, какой-то вырожденец на каменном ебале сравнивает массив и хеш мапу. И пердит про "удобно" "не удобно".
> И назвал хеш мапу ебать массивом, ну чисто по приколу.
Есть термин ассоциативный массив. Отсюда это и пошло. Если ты такой умный, то дай определение массива из какого-нибудь более или менее серьёзного источника. "массив -- это вот так и вот так", потому что такая терминология в библиотеке твоего любимого ЯП, -- это не аргумент. Терминология от технологии к технологии постоянно меняется. Про джаваскрипт вообще смешно даже. Массив в PHP -- это очень хитрая структура, которую так просто не опишешь. Технически под капотом она реально может эффективно функционировать и как хеш-мап, и как индексированная последовательность.
Вообще очень смешно, что чел ебался писать эти километры объяснений для нубов, а какой-то орущий сноб под конец решил, что может просто так снисхуя унизить его. Вот так помогай новичкам.
Я воспринимаю программирование как работу, а не как способ возвыситься в узком кругу ценителей. Поэтому учу только скучные технологии строго под задачи и рынок. Даже если в пхп будут все эти крутые структуры, то код с ними будет менее понятен и дороже в поддержке. Не только потому, что пхпшники их не знают. Это лишний бойлерплейт и лишнее думанье. Структуры в этих языках намеренно упрощены, а алгоритмы прячутся под капот, чтобы разработка была эффективнее. Я всегда думаю про цену поддержки, надёжность и отказоустойчивость, а не тупо накидать, чтобы было круто. Ты не студент случайно? Мне кажется, что эту еботерию про охуеть интеллектуальные алгоритмы и байты уровня первокурсоты какого-нибудь матфака Урюпинска пишут именно студенты, возможно преподы или научные работники, которые редко пишут больше 1000 строк в одном проекте. Как много ты писал бенчмарков, которые на реальных задачах могут продемонстрировать реальный прирост производительности твоих эффективных "стеков на векторе"? Не задачах с олимпиад, а реальных задачах бизнеса. Сколько строк было в максимально большом проекте? А сколько максимально людей было у тебя в команде?
Фанаты Хаскеля, Раста и других неебаться крутых языков вообще всё время пишут в интернете про то, какие популярные мейнстримовые языки говно. Какого говно жс, пхп, с++, джава. Но рынок и технологии продолжают крутиться вокруг них, а не вокруг любимых всеми Растов и Хаскелей.
> И назвал хеш мапу ебать массивом, ну чисто по приколу.
Есть термин ассоциативный массив. Отсюда это и пошло. Если ты такой умный, то дай определение массива из какого-нибудь более или менее серьёзного источника. "массив -- это вот так и вот так", потому что такая терминология в библиотеке твоего любимого ЯП, -- это не аргумент. Терминология от технологии к технологии постоянно меняется. Про джаваскрипт вообще смешно даже. Массив в PHP -- это очень хитрая структура, которую так просто не опишешь. Технически под капотом она реально может эффективно функционировать и как хеш-мап, и как индексированная последовательность.
Вообще очень смешно, что чел ебался писать эти километры объяснений для нубов, а какой-то орущий сноб под конец решил, что может просто так снисхуя унизить его. Вот так помогай новичкам.
Я воспринимаю программирование как работу, а не как способ возвыситься в узком кругу ценителей. Поэтому учу только скучные технологии строго под задачи и рынок. Даже если в пхп будут все эти крутые структуры, то код с ними будет менее понятен и дороже в поддержке. Не только потому, что пхпшники их не знают. Это лишний бойлерплейт и лишнее думанье. Структуры в этих языках намеренно упрощены, а алгоритмы прячутся под капот, чтобы разработка была эффективнее. Я всегда думаю про цену поддержки, надёжность и отказоустойчивость, а не тупо накидать, чтобы было круто. Ты не студент случайно? Мне кажется, что эту еботерию про охуеть интеллектуальные алгоритмы и байты уровня первокурсоты какого-нибудь матфака Урюпинска пишут именно студенты, возможно преподы или научные работники, которые редко пишут больше 1000 строк в одном проекте. Как много ты писал бенчмарков, которые на реальных задачах могут продемонстрировать реальный прирост производительности твоих эффективных "стеков на векторе"? Не задачах с олимпиад, а реальных задачах бизнеса. Сколько строк было в максимально большом проекте? А сколько максимально людей было у тебя в команде?
Фанаты Хаскеля, Раста и других неебаться крутых языков вообще всё время пишут в интернете про то, какие популярные мейнстримовые языки говно. Какого говно жс, пхп, с++, джава. Но рынок и технологии продолжают крутиться вокруг них, а не вокруг любимых всеми Растов и Хаскелей.
>Терминология от технологии к технологии постоянно меняется
Не позорься, просто погугли пару минут и поймешь какую хуйню ты сморозил.
>Массив в PHP -- это очень хитрая структура, которую так просто не опишешь
Это хеш мапа. Все структуры данных в пхп это хеш мапы. И объекты и массивы и небо и аллах.
>Вообще очень смешно, что чел ебался писать эти километры объяснений для нубов
Именно это и нужно знать нубам. Пхп программист это белая ворона, паршивая овца. У него пробелы в фундаментальных знаниях. Сам факт того что ты буквально первый шаг в обучении программированию превозносишь как какой-то невероятный элитизм об этом просто кричит. Эта хуйня идет сразу после "научиться писоть". Буквально: "почитать синтаксис", "написать хеллуворлд", "прочитать про структуры данных".
>Я воспринимаю программирование как работу, а не как способ возвыситься в узком кругу ценителей
В этом и проблема языка. Банальные вещи, которые знает каждый джун превращаются в "способ возвыситься".
Дальше какой-то поток сознания про цену и надежность, хуй знает как ты это все измеряешь офк никак, просто надо пиздануть.
Новичку из твоей стены текста нужно знать вот это: "Поэтому учу только скучные технологии строго под задачи и рынок". Ты сам не понимаешь что это приговор? Человек, который пишет на ссаном го имеет возможность пощупать любой свежий или несвежий яп. Потому что принципы у них будут общие. Термины одинаковые. И начать писать это дело банальной привычки. Для таких людей выбор языка для проекта это действительно выбор инструмента.
А пхп макаке либо нужно самостоятельно дрочить computer science, потому что в повседневной работе он с этим просто не сталкивается. И становиться "элитой". Только это не элитизм, а обычное положение вещей для нормальных языков. Либо шипеть "нинужно" и какие-нибудь мантры про понятный простой и надежный бойлерплейт, в стиле твоего поста.
>относятся как к конченному быдлу и непрофессионалам
Это проблемы быдла и непрфессионалов вроде тебя.
>а если я хочу сделать функции по типу сколько всего человек в базе, сколько из них храмые, то эти функции необходимо уже размещать в другом классе
Да, но вообще мне кажется что ты без определенных юзкейсов не поймешь почему тот или другой подход лучше или хуже. Попробуй придумать абсолютно разные задачи, которые работают с твоими людьми, сделай например какой-то демографический сервис, который считает людей по годам или городам, сделай какой-то налоговый сервис, который считает людей по зп или пенсии, то есть чтобы у тебя разные модули общались с каким-то общим классом. Мне кажется что так у тебя быстрее выработается картина, что и на какие слои удобнее делить.
>Не позорься, просто погугли пару минут и поймешь какую хуйню ты сморозил.
Ты только снимаешь с себя необходимость что-то доказывать этими словами.
Может быть, ты этого не понимаешь, но я хоть и не учёный по теме CS и не плюсовик, но знаю эти базовые структуры данных типа стеков/очередей/деков, умею наивным универовским способом реализовать связный список на указателях или кучу на массиве. Я знаю в целом, как рабоатет С и С++ и что такое стек вызовов и куча в памяти, и как работает планеровщик процессов в ОС. И я пробовал писать на Хаскеле и знаю, что такое монады. Но пишу всё равно на пыхе и жиесе. Для меня в основном выбора языка под задачи то и не существует. Язык выбирает начальник, который за это платит. Потому что "а где мы найдём других таких как ты потом" и "мы не хотим зоопарк языков".
>Человек, который пишет на ссаном го имеет возможность пощупать любой свежий или несвежий яп. Потому что принципы у них будут общие.
Ты же в курсе, что в Го нет исключений и дженериков, кстати? Создатели языка тоже шли по пути упрощения, только упрощали другие моменты.
>А пхп макаке либо нужно самостоятельно дрочить computer science, потому что в повседневной работе он с этим просто не сталкивается.
Слабо представляю, как может быть иначе. CS требует подготовки.
>Это хеш мапа
Не совсем просто хеш мапа. Во-первых это упорядоченная хеш-мапа. Т.е. она помнит порядок пар ключ-значение. И там есть указатели на следующий/предыдущий элмент как в linked list. Так что фактически это упорядоченный хеш-мап, совмещённый со связным списоком.
>Ты только снимаешь с себя необходимость что-то доказывать этими словами.
Доказывать что свзязный список это связный список, а массив это массив? Мне это не надо, спасибо.
>Для меня в основном выбора языка под задачи то и не существует. Язык выбирает начальник, который за это платит.
Я об этом и говорю. Выбора у тебя никакого нет. На работе мнения макаки формошлепа по выбору языка никто спрашивать не будет. А при смене работы придется отказаться от от специфическогго пхп опыта и по сути начать вкат сначала.
И эта проблема специфична именно для пхп. Потому что меняющий стек плюсовик это по прежнему опытный программист, который быстро нагонит за счет общей базы. А меняющий стек пхп макакен это человек со специфическим опытом и образом мышления, за которым нужен глаз да глаз. И будь он хоть супер гением работодатель десять раз подумает нахуй ему такой талант вне пхпшного загона обосрался.
>Ты же в курсе, что в Го нет исключений и дженериков, кстати?
Ну если бы какой-нибудь долбоеб сравнивал дженерики с массивами я бы об этом и написал.
VSCode умеет сохранять файлы без BOM. Нужно выбрать кодировку "utf-8" (также есть кодировка utf8bom, она добавляет BOM в начало файла). заходишь в settings -> поиск по encoding -> выбираешь utf8.
>>171208
Ты написал фигню. Есть такое понятие "ассоциативный массив". Хеш-таблица - это лишь одна из возможных реализаций ассоциативного массива. Так что название "массив" в PHP абсолютно нормальное.
https://xlinux.nist.gov/dads/HTML/assocarray.html
Ты не разобрался, а брызжа слюнями, побежал всех вокруг обзывать "макаками".
Представь, что кто-нибудь скажет, что "белые люди" самостоятельно выделяют и освобождают память и указывают типы всех переменных, а "макаки" пользуются сборщиком мусора и динамической типизацией. И вот теперь ты стал макакой.
Странно, но там UTF-8 и стоял по дефолту.
Никакого смысла хешировать их нету. Хешируют пароли (обязательно с солью) при сохранении в базу данных.
>>171417
Я бы тебе советовал выложить твои классы на гитхаб для проверки. Вдруг ты ошибся, а тебе укажут на ошибки и помогут исправить.
Обычно функции, которые работают с таблицей в базе, собирают в один класс. Есть несколько паттернов (я описал из тут: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md ), самый простой это TableDataGateway.
То есть ты делаешь класс PeopleGateway, а в нем методы для получения числа человек в базе, поиска людей по каким-то признакам, удаления людей из базы и тд. Вся работа с таблицей людей делается в этом классе, но только работа с базой данных. Там не должно быть работы с GET, POST, формами, вывода чего-либо на экран.
Это называется "принцип разделения ответственности". У каждого класса своя "зона ответственности" и он не занимается тем, за что отвечает другой класс.
Частая ошибка начинающих в том, что они пытаются все запихнуть в один класс. Например, обработку формы редактирования, проверку на ошибки, работу с базой данных, вывод результата. В результате получается не ООП, а обычная лапша, завернутая в класс.
>Ты написал фигню. Есть такое понятие "ассоциативный массив"
Капуцин ебаный, ты читать умеешь? Я именно именно о том и говорю что "массив" и "ассоциативный массив" это разные вещи.
Я хуй знаю, давай я тебе аналогию приведу что-ли.
У чела есть вилка и ложка. Он ест мясо вилкой, а суп ложкой.
Подходит пхп макака и говорит:
- Моя ложка удобнее твоей вилки.
Подходит еще один и добавляет:
- Да. У нас в дурке вообще вилок нет. Сидим кайфуем, удобно пиздец. Вилки это сложно и элитарно. Даже если бы они и были, мы в дурке сто пудов бы запутались.
>>171756
Мимо. Я такая же пхп макака, только опыта побольше.
Наведи курсор и прочитай во вспылающем окне подсказочку или через alt+enter посмотри что IDE посоветует исправить.
Наверное дело в том, что определить строковую константу можно задать через const.
И закрывающий тег тут не нужен. Он может навредить, так как все символы до следующего открывающего тега (например случайный пробел) улетят в stdout и расхуячат скрипт.
Да, тыкнул на подсказку и он счам исправил, до чего техника дошла
У тебя константа root_path существует?
Может config.php надо все-таки самим первым подключать? Или в пыхе это не критично?
Да, именно его и нужно сначала подключить. Посмотри на первый скрин - у него ROOT_PATH там дефинится.
Я просто видел в примерах в книге, что определение функции идет в конце файла после вызова уже, думал тут интерпретатору пофиг где что. Похоже это работает только внутри одного файла.
Ты сделал как-то неправильно. Идея папки public в том, что это единственная доступная снаружи папка, и обратиться к другим папкам снаружи нельзя.
У тебя же судя по тому, что ты дописываешь public в путь, это не так и все файлы доступны снаружи. В htaccess это можно попробовать как-то исправить, но это неправильный путь.
Нужно посмотреть внимательнее документацию хостинга и настройки в панели хостинга. Обычно у хостингов есть корневая директория, куда можно загружать файлы, и в ней публично доступная папка, просто она может называться не public, а например www или как-то еще. В этом случае тебе надо переделать свой сайт, чтобы у тебя вместо public использовалась та папка, которая используется на хостинге.
Ты конечно можешь сделать весь код сайта доступным снаружи, но безопаснее использовать публичную папку только для тех файлов, которые можно скачивать.
Также, ты можешь изучить линукс и взять вместо хостинга VPS, где ты сам сможешь настроить веб сервер как хочешь.
Во-первых, начнем с REST. REST это набор определенных концепций, но на практике под REST подразумевают API с методами вроде GET/POST/DELETE/PUT и URL вроде /product/1234. То есть на практике, когда говорят "REST API" имеют в виду просто API на основе протокола HTTP.
Теперь про GraphQL. Допустим, у тебя большой сайт и база с тысячей таблиц. Тебе понадобилось аяксом выводить список комментариев. Ты сделал для этого обработчик. Дальше тебе понадобилось получать список комментариев, но с другим набором полей. Ты доработал обработчик. Дальше тебе понадобилось получать список лайков. Ты написал еще один обработчик. И так далее. Когда ты напишешь 100 штук похожих обработчиков, тебе начнет приходить в голову мысль: а не пора ли это оптимизировать?
Это и привело к созданию GraphQL. Его идея в том, что ты на клиенте (в яваскрипте) пишешь GrpahQL-запрос, описывая сущности, которые ты хочешь получить:
- какие поля тебе нужны
- какие связанные сущности нужны (например: добавить к комментариям информацию об авторе и о числе лайков)
- по каким условиям выбирать сущности
А сервер ищет и отдает нужные данные. Это напоминает SQL-запрос, но тут есть отличия:
- поля сущностей не обязаны соответствовать полям в БД, а могут как-то генерироваться программно
- аналогично, сущности не обязаны соответствовать таблицам в БД
Более того, кроме тебя есть еще тысячи разработчиков, которые пишут такие же однотипные обработчики для аякс-запросов. С GraphQL вы все можете установить себе GraphQL-сервер и перестать писать обработчики. Представь, сколько времени это экономит вам совокупно.
Разумеется, тут есть множество сложных моментов:
- нужно настроить права доступа, иначе злоумышленник через GraphQL "запросит" персональные данные пользователей, их email, пароли и все, что есть в твоей базе. Более того, права доступа могут быть сложными, в стиле "пользователь с кармой больше 100 имеет доступ к разделу X", и это надо как-то вкрутить в GraphQL сервер.
- тебе могут присылать "тяжелые" запросы, которые вытянут миллионы сущностей без индекса и положат твой сервер. Надо как-то оптимизировать выборку, причем тут ты заранее не знаешь, какой запрос может прийти и должен оптимизировать под все возможные случаи.
Но эти проблемы решаемы при грамотном подходе.
Во-первых, начнем с REST. REST это набор определенных концепций, но на практике под REST подразумевают API с методами вроде GET/POST/DELETE/PUT и URL вроде /product/1234. То есть на практике, когда говорят "REST API" имеют в виду просто API на основе протокола HTTP.
Теперь про GraphQL. Допустим, у тебя большой сайт и база с тысячей таблиц. Тебе понадобилось аяксом выводить список комментариев. Ты сделал для этого обработчик. Дальше тебе понадобилось получать список комментариев, но с другим набором полей. Ты доработал обработчик. Дальше тебе понадобилось получать список лайков. Ты написал еще один обработчик. И так далее. Когда ты напишешь 100 штук похожих обработчиков, тебе начнет приходить в голову мысль: а не пора ли это оптимизировать?
Это и привело к созданию GraphQL. Его идея в том, что ты на клиенте (в яваскрипте) пишешь GrpahQL-запрос, описывая сущности, которые ты хочешь получить:
- какие поля тебе нужны
- какие связанные сущности нужны (например: добавить к комментариям информацию об авторе и о числе лайков)
- по каким условиям выбирать сущности
А сервер ищет и отдает нужные данные. Это напоминает SQL-запрос, но тут есть отличия:
- поля сущностей не обязаны соответствовать полям в БД, а могут как-то генерироваться программно
- аналогично, сущности не обязаны соответствовать таблицам в БД
Более того, кроме тебя есть еще тысячи разработчиков, которые пишут такие же однотипные обработчики для аякс-запросов. С GraphQL вы все можете установить себе GraphQL-сервер и перестать писать обработчики. Представь, сколько времени это экономит вам совокупно.
Разумеется, тут есть множество сложных моментов:
- нужно настроить права доступа, иначе злоумышленник через GraphQL "запросит" персональные данные пользователей, их email, пароли и все, что есть в твоей базе. Более того, права доступа могут быть сложными, в стиле "пользователь с кармой больше 100 имеет доступ к разделу X", и это надо как-то вкрутить в GraphQL сервер.
- тебе могут присылать "тяжелые" запросы, которые вытянут миллионы сущностей без индекса и положат твой сервер. Надо как-то оптимизировать выборку, причем тут ты заранее не знаешь, какой запрос может прийти и должен оптимизировать под все возможные случаи.
Но эти проблемы решаемы при грамотном подходе.
http://code.mu/ru/php/book/prime/auth/session/
Делаю как тут и ничего не работает.
>ничего не работает
Не пиши как Тупая Пизда, а описывай проблему нормально. Что не работает, какая ошибка, что было предпринято?
Сделай дамп переменной user перед последним If, может что-то с бд?
>Это и привело к созданию GraphQL. Его идея в том, что ты на клиенте (в яваскрипте) пишешь GrpahQL-запрос, описывая сущности, которые ты хочешь получить:
>А сервер ищет и отдает нужные данные.
Но ведь это не так. Нужно ещё пердолить скиму к этому всему. И получается "100 штук похожих обработчиков", просто в другом виде. А так-то конечно было бы здорово просто отправить квери к серверу и он магическим образом как-то бы вытягивал по этому квери данные, но увы, магии нет, нужна скима (которая почти дублирует квери), бойлерплейт, моча, говно
Тебе время пытаются сохранить, сейчас ты его буквально тратишь на хуйню.
Ты никогда в реальной задаче не будешь писать код вот таким образом, а именно:
у тебя не экранирован запрос, то есть злоумышленник может легко получить доступ к базе, ты используешь глобальные переменные, что ведет к протечке абстракций, делает код уязвимым и привязывает его к конкретным переменным и их состоянию.
По сути материал чисто для вката в ПХП просто понять, че там и как, писать так не стоит даже в самом начале.
Учись юзать композер сразу, избавишься от этих простыней в виде куч рекуаер.
Ну так вызывай, кто тебе мешает-то?
Ты фабрику задумал что ли, злодей?
https://refactoring.guru/ru/design-patterns/factory-method
Есть урл на пикчу, допустим
сайт/upload/resize_cache/iblock/9c7/862_471_1/9c7e59ec57153040155471666a50f54a.jpg
По урл видно, что картинка отресайзана чтобы вывести ее в iblock (видимо плагин такой? неважно)
Как мне найти оригинал картинки?
С ним полтреда работало и эти же полтреда его искренне ненавидят, чем больше работали тем больше ненавидят.
В отличие от петухов с хабра которым просто сказали что это говно тут с ним лично знакомы.
Что ты хочешь? Нахуй тебе исходный файл? НЕ ВЗДУМАЙ работать с картинками загруженными в битру как с файлами, забудь про это.
Судя по урлу, картинка загружена как свойство элемента инфоблока и пожала через ResizeImageGet.
Да сайт не мой, и о говенности битрикса я наслышан.
Я просто я не могу вытянуть из него фотку в оригинальном разрешении, она скейлится, даже если я в инспекторе ставлю устройство с 8К экраном. А в ресурсах только вот урл на resize_cache. Думал по этому урлу можно собрать урл до оригинальной картинки
Вебасист ещё параша похожая - приходилось иметь дело. Точно такая же разрекламированная хуита с говнокодом.
А в ларавель есть
Нашел вот такую хуету https://pineco.de/filtering-eloquent-queries-based-on-http-requests/
Насколько этот метод индусский?
Спасибо, сработало :3
Ну ладно. Удачи тогда.
Да.
Вдруг я талантливый программист с провинции, а работодатель не берёт таких на удалёнку, в итоге работает с посредственностями ирл, но с ДС.
>Вдруг я талантливый программист с провинции
Пикрелейтед прямо.
>работает с посредственностями
На работе надо работу работать, а не талантом сверкать.
Адрес хоста, где расположена база данных. Если у тебя (скорее всего так и есть) база данных расположена на том же самом компьютере, то вводи 127.0.0.1.
>>174822
Ты не можешь "вызвать" класс. Ты можешь только вызвать метод в классе. Если это статический метод, то так:
SomeClass::someMethod();
Если не статический, то тебе сначала надо создать объект и потом у него вызвать метод:
$o = new SomeClass();
$o->someMethod();
Если ты не знаком с ООП, то советую открыть учебник из шапки и в нем прочесть главу про ООП.
Есть два варианта:
- можно сделать для админки отдельную страницу входа и там проверять его логин/пароль
- можно сделать вход через общую страницу входа, там же где и вход для обычных пользователей, просто в базе ты как-то помечаешь, что этот аккаунт - это админ. Например, добавляешь поле is_admin = 1
У меня были пятёрки в ВУЗе по программированию и я один из первых с потока сдал лабу сайт-визитку на РНР с гостевой и счетчиком.
ну а если у тебя не огромная коллекция и тебе надо фильтровать эту не огромную коллекцию на стороне кода?
тогда похуй
Ты не слепошарый. Ты нахальный и самоуверенный. В этом треде наверняка написано пицот раз, чтобы ты юзал нормальный профессиональный редактор кода. Он должен был такие вещи подсвечивать. Хватит выёбываться со своим блокнотом. "Почему вы упорствуете, мистер Андерсон?"
Старина я про это и спрашиваю.
Создал реквест -> написал правила валидации ->получаю провалидированный массив с данными. Дальше же идёт куча ифов с проверкой есть ли тот или иной параметр или нет. Если да то хуярим в квери ещё один where.
И это заебывает. Вот и ищу хоть какой нибудь стандарт как это все менее всрато сделать. Находил инструкции от индусов разной степени уебищности. На многих сайтах ссылаются на либу какого то Ивана Иванова Джона Смита. Но как то не особо хочется ставить новый пакет из-за казалось бы пустяковой задач.
Вот и думаю мб что-то в доках пропустил.
Алсо. Вариант который более менее понравился - https://pineco.de/filtering-eloquent-queries-based-on-http-requests/
Однако здесь есть нюанс который вызывает вопросы. Зачем в фильтр передается реквест, а не массив который нам выдаётся из метода $request->validated()?
Плюс строчка $this->request->all() немного напрягает ибо на сколько я понимаю мы забиваем на валидвцию в таком случае?
>Однако здесь есть нюанс который вызывает вопросы. Зачем в фильтр передается реквест, а не массив который нам выдаётся из метода $request->validated()?
Плюс строчка $this->request->all() немного напрягает ибо на сколько я понимаю мы забиваем на валидвцию в таком случае?
Тебе ничего не мешает создать Form Request (читни в доках) и точно так же принимать весь реквест, он будет ларкой сперва проводится через твои правила валидации, а потом юзаться в контрллере(или где там у тебя), метод $request->validated(), можно будет явно не вызывать, если у тебя нет последующих условий, каких нибудь. Скорее всего это просто было опущено как очевидное.
Чему вы извращаетесь с этими редакторами, когда есть пхпшторм где подсвечивается вообще все, даже небо и аллах и с коробки дается полностью весь нужный функционал для экосистемы пыхи? Платность шторма решается же?
>Тяжёлая хрень. Заебали вы со своим штормом - не всем он нравится.
Ты его в руках что-ли носишь? Что значит "тяжелая"?
Пиздец конечно рассуждение категориями "нравится/не нравится". Шторм закрывает вопрос работы с пхп. Совсем. И закрытие тегов это самая маленькая хуйня которую он решает.
Это иллюзия новичка, что можно обойтись просто редактором, без IDE. Как только начнется реальная работа сразу выяснится что недостаток функция в редакторе придется восполнять сторонним софтом. Git, docker, db, ftp, http запросы.
Потом начнутся проблемы с актуальностью версии php. Нужна будет подсветка синтаксиса и под вышедшую вчера версию и под версию десятилетней давности. Потом понадобятся доп инструменты под конкретный стек, типа плагинов для лары или симфони. Потом понадобится возможность гибко изменять кодстайл, чтобы руками сотни файлов не править. Потом понадобится дописать что-то на TypeScript, или какой-нибудь scss. И все вышеперечисленное умножай на два.
Так что шторм это по сути единственный вариант для профессиональной разработки на пхп. Да сложный, да нужно его долго изучать. Но по факту альтернатив нет. Раньше начнешь пользоваться - раньше привыкнешь. За годы идеально настроишь его под себя, от внешнего вида, до автогенерации кода и будешь рофлить на пассажами про "не нравится".
>Это иллюзия новичка
Я не новичок, мань. Как раз новички сразу в шторм лезут, думая, что он им всё закроет. Так не бывает и любая ide будет хуже чем конкретный софт под задачу.
>Потом понадобятся доп инструменты под конкретный стек, типа плагинов для лары или симфони.
Лол. Что дальше - плагины для плагинов для пакетов лары и симфони?
>Потом понадобится дописать что-то на TypeScript, или какой-нибудь scss. И все вышеперечисленное умножай на два.
Функционал обычного редактора кода. Причём тут шторм, поехавший?
>шторм это по сути единственный вариант для профессиональной разработки на
Маркетолог залогинься.
>Что значит "тяжелая"?
"Тяжёлая" это когде мне нужно максимум 20% от того, что даёт шторм в некотором конкретном случае. Мне не нужны все 100500 его функций на каждом проекте.
>Я не новичок, мань. Как раз новички сразу в шторм лезут, думая, что он им всё закроет. Так не бывает и любая ide будет хуже чем конкретный софт под задачу.
>Функционал обычного редактора кода. Причём тут шторм, поехавший?
Сто процентов новичок. До сих пор мыслишь категориями "пишу буквы, хули еще надо". А надо убедиться что написанное не конфликтует с тысячами уже написанных строчек кода. Надо скомпилить. Надо задеплоить.
>Лол. Что дальше - плагины для плагинов для пакетов лары и симфони?
Если это сэкономит время, то да. Че думаешь от нехуй делать IDE пользуются? Еще больше убеждаюсь что ты нубас.
>Маркетолог залогинься.
Не, ну ты похоже даже не джун. Кто вообще шторм покупает? Тебе принесут лицензию на любую хуйню, если она увеличит твою производительность. Погугли сколько джира стоит, например. И че-то так совпало, что за десять лет я везде видел только шторм. Один раз на собесе дали ноут с нетбинсом и дико извинялись, мол "не успели шторм поставить".
Так убери то чем не пользуешься с панелей и из меню. Настрой тему под себя, сочетания клавиш, поставь шрифт удобный. Я когда-то пользовался nusphere и привык к цветам и хоткеям. При переходе на шторм просто наебенил все один в один как там, хуй отличишь.
>надо убедиться что написанное не конфликтует с тысячами уже написанных строчек кода
Лол, чё несёт, охуеть. Без костылей уже и ходить не может.
>Тебе принесут лицензию
Пиздец. Хуй на лицо тебе принесут.
Ты охуевший вкатунам вкатунам шторм советовать, мань? Ничего кроме него не знаешь и везде лезешь со своими тупыми советами.
>Ты охуевший вкатунам вкатунам шторм советовать
Так именно вкатунам и надо его советовать. Половины треда не было бы юзай они шторм. Жалко денег - спирать. Спиздить хорошую вещь у буржуев святое дело. Но не надо заниматься хуйней и искать незакрытые теги и опечатки.
Если хочешь работать работу в офисе и писать на пхп, то там будет только шторм, просто без вариантов. А если фрилансить, то сам побежишь его покупать, потому что время = деньги.
>Ничего кроме него не знаешь
Вот как раз потому что знаю и советую.
Забытые скобки подсвечивают все редакторы. Настрой более грамотно. Vscode должен это делать. Даже Sublime может. Все редакторы чекают синтаксис. Шторм идёт дальше, он чекает частые логические ошибки, используя статический анализ кода, который почти что компилит весь код на лету. Это и жрёт память. А сопоставить скобки там много ума не надо -- это везде должно быть. Строки выделяются одним цветом обычно. Возможно у тебя редактор вообще не настроен понимать php.
Я не забыл скобку, а поставил ее не там.
<a href='page.php' Щелкните здесь для продолжения></a>
Тю. На твоём скрине эта скобка на месте, а пропущена другая скобка, круглая. Ну во-первых учись проверять конечный результат вывода программ и функций. Ты должен был в браузере посмотреть возвращаемый код и понять. Там в браузере тоже бы всё подсветилось. Во-вторых HTML в идеале, конечно, выносить из строковых литералов в отдельные файлы. Гугли, как делается вьюха, view file. Тогда html тоже будет подсвечиваться.
1) Когда ты создавал проект, то он появился у тебя в подпапке myapp. Так что перед очередным вызовом композера надо было выполнить cd myapp. Во-первых выучи команды ls, чтобы видеть, где ты вообще и где файлы. Ты же видешь написано, что файла composer.json нету. Так почему ты не начал его искать. Во вторых там сверху написано, что проект создаётся в ./myapp .
2) Попытка игнорировать требования пакетов вероятно только создаст тебе ещё больше проблем. Тебя попросили установить ext-fileinfo. Лучше поставь по-хорошему. Если ставил пых из пакетов, то это тоже будет пакет скорее всего.
Да все, надо было раскомментировать в php.ini extension_dir = "ext" и добавить extension=php_fileinfo.dll
Первый рабочий проект писал с помощью notepad++
Юзай phpstorm. Ипользуй триал, наеби с учобой или просто спизди.
"Но я же только учусь и пишу для себя, мне не нужен остальной функционал" это нуб трапа. Откуда ты узнаешь что тебе нужно? Что сократит количество ошибок, а что сократит затраты времени? Книжек об этом не написано.
А обучение инструментам разработки это такое же обучение как и сама разработка. IDE со старта сэкономит тебе миллиард нервных клеток. Вместо 125 тредов было бы от силы 50 если бы все начали со шторма.
VSCode это хороший редактор. Но он полностью стоит на плагинах, которые во первых нужно найти, а во вторых созданы случайными людьми. Без плагинов писать в VSCode на пхп нереально. А добавляя плагины ты по сути пытаешься воспроизвести phptorm, только хуже.
Вот тебе пример. Я за семь лет на шторме забыл вообще про существование кнопки Save. Я пишу буквы, потом закрываю файл, закрываю IDE и пиздую домой. Не сохраненые изменения? Каво нахуй? Я прекрасно знаю, что в момент когда я закончил печатать все уже сохранилось. И я прекрасно знаю что есть история локальных изменений. И если я позавчера написал функцию, потом подумал "не, хуйня какая-то" и удалил её, то сегодня я подумав "да не, не хуйня" могу открыть историю, чекнуть че там было написано и одним кликом вернуть её на то самое место если нужно. И с файлами и папками это тоже работает. И это не git, эта система не требует что-то коммитить или пушить.
Это блядь как дышать. Как без этого вообще возможно работать даже со средним проектом хуй его знает.
А вот как это выглядит в VSCode. По сути есть только плагин Local History https://marketplace.visualstudio.com/items?itemName=xyz.local-history . Сразу внимание на количество скачиваний: 370,389. Это просто мизер. Например PHP Intelephense, без которого в принципе невозможно писать код на пхп, 4 ляма. Большинство просто не в курсе что такая охуенная фишка существует. Дальше. Кто автор? Куда бежать с порванной сракой если багует? Некие zabel-xyz и João Morais. Куда тебе идти со своими багами можно понять по ебалу Мораиса пикрелетед и issue за 2019 в статусе in progress. К тому же плагин создает какую-то там локальную папку, все неуклюже, без нормального интерфейса, но вроде работает.
Короче юзай шторм сразу, в нем есть куча специфичных для пхп подсказок и приколов. Тебя все время будут крепко держать за яйца плечо и не дадут писать хуйни. Всегда предупредят что вот тут "возможна ошибка". Не просто "есть ошибка". А именно предупредят, что код написан таким образом что частенько в такой ситуации возникают ошибки. Ни один другой редактор или IDE больше поддержки новичку не даст. Это определенно стоит того чтобы погуглить с кряк десять минут.
Юзай phpstorm. Ипользуй триал, наеби с учобой или просто спизди.
"Но я же только учусь и пишу для себя, мне не нужен остальной функционал" это нуб трапа. Откуда ты узнаешь что тебе нужно? Что сократит количество ошибок, а что сократит затраты времени? Книжек об этом не написано.
А обучение инструментам разработки это такое же обучение как и сама разработка. IDE со старта сэкономит тебе миллиард нервных клеток. Вместо 125 тредов было бы от силы 50 если бы все начали со шторма.
VSCode это хороший редактор. Но он полностью стоит на плагинах, которые во первых нужно найти, а во вторых созданы случайными людьми. Без плагинов писать в VSCode на пхп нереально. А добавляя плагины ты по сути пытаешься воспроизвести phptorm, только хуже.
Вот тебе пример. Я за семь лет на шторме забыл вообще про существование кнопки Save. Я пишу буквы, потом закрываю файл, закрываю IDE и пиздую домой. Не сохраненые изменения? Каво нахуй? Я прекрасно знаю, что в момент когда я закончил печатать все уже сохранилось. И я прекрасно знаю что есть история локальных изменений. И если я позавчера написал функцию, потом подумал "не, хуйня какая-то" и удалил её, то сегодня я подумав "да не, не хуйня" могу открыть историю, чекнуть че там было написано и одним кликом вернуть её на то самое место если нужно. И с файлами и папками это тоже работает. И это не git, эта система не требует что-то коммитить или пушить.
Это блядь как дышать. Как без этого вообще возможно работать даже со средним проектом хуй его знает.
А вот как это выглядит в VSCode. По сути есть только плагин Local History https://marketplace.visualstudio.com/items?itemName=xyz.local-history . Сразу внимание на количество скачиваний: 370,389. Это просто мизер. Например PHP Intelephense, без которого в принципе невозможно писать код на пхп, 4 ляма. Большинство просто не в курсе что такая охуенная фишка существует. Дальше. Кто автор? Куда бежать с порванной сракой если багует? Некие zabel-xyz и João Morais. Куда тебе идти со своими багами можно понять по ебалу Мораиса пикрелетед и issue за 2019 в статусе in progress. К тому же плагин создает какую-то там локальную папку, все неуклюже, без нормального интерфейса, но вроде работает.
Короче юзай шторм сразу, в нем есть куча специфичных для пхп подсказок и приколов. Тебя все время будут крепко держать за яйца плечо и не дадут писать хуйни. Всегда предупредят что вот тут "возможна ошибка". Не просто "есть ошибка". А именно предупредят, что код написан таким образом что частенько в такой ситуации возникают ошибки. Ни один другой редактор или IDE больше поддержки новичку не даст. Это определенно стоит того чтобы погуглить с кряк десять минут.
И где должна быть вторая форма входа,на секретном урле?
360x638, 0:15
Как-то это подозрительно выглядит, не? Или это нормальная практика?
Двачую адеквата
вкатывальщики в 2021 должны страдать
Честно?
Документацию я читал только по мере надобности.
А вот все вкатывальщикам я бы посоветовал тратить время на теорию - архитектуру сетей, базовое администрирование, etc.
Поставь OpenServer, напиши hello word, и начни разбираться что и как происходит когда ты переходишь по ссылке в браузере, прям детально.
>А вот все вкатывальщикам я бы посоветовал тратить время на теорию - архитектуру сетей, базовое администрирование, etc.
А при чем тут пхп, или в вакансию входит все подряд включая заправку принтеров кроме написания кода?
Это похоже на "вредный совет" чтобы вкатуны подольше занимались бесполезной хуйней и не мешали конкуренцией
у меня спрашивали (помимо php)
1) Что такое сессия
2) Можем ли мы на сервере увидеть User-agent и изменить его
3) Что такое schema и какие операции можно делать с sitemap?
Это всё к какому разделу относится?
>Поставь OpenServer, напиши hello word, и начни разбираться что и как происходит когда ты переходишь по ссылке в браузере, прям детально.
то есть это веб-аналитика? А xampp для этого не пойдёт
Жаль, что PHP (и все остальные) приложения постепенно превращаются в бесконечный набор через жопу связанных и постоянно меняющихся дырявых зависимостей.
Повторюсь, в некоторых секурных компаниях использование фреймворков по причине выше просто запрещено. Но, тогда в моменте из конкуренты приобретают преимущество в скорости разработки.
В основном фреймворки запрещают в госконторах(или ТИПА не гос), по причине ИМПОРТОЗАМЕЩЕНИЯ, что ставит разработчиков всех уровней в позицию долбоёбов, которые пилят свои велосипеды, также обрастающие говнозависимостями, только своими, довольно сомнительного качества. Всегда приятно думать, что в мире живут одни долбоёбы и ты(вы) напишешь(-те) лучше, но это не так и никогда так, собственно, не будет. Заниматься байтоёбством и микросекундами имеет смысл только на очень низких уровнях, а небольшая каша зависимостей на пхп/жс/джаве/шарпах/.. это ничтожная плата за скорость разработки и, очень часто, качество кода с регулярными обновлениями. Единственный толковый(с моей конечно же точки зрения) совет это - писать по возможности функционал самим, а не тянуть говнопакет на любому поводу, особенно на суперэнтерпрайзе каком-нибудь. Меньше всего этого придерживаются фронтендеры, но у них и так жизнь тяжёлая, поэтому можно понять.
Что касается ошибок синтаксиса ("неазкрытые скобки"): vscode точно должен это уметь - проверять синтаксис файла во время редактирования и подчеркивать ошибки. Описано тут: https://code.visualstudio.com/Docs/languages/php#_linting
Для статического анализа кода не обязательно покупать phpstorm. Лучше будет использовать анализаторы вроде phpstan и psalm. Они покажут не только ошибки вроде незакрытых скобок, но и более сложные случаи, например, когда ты пытаешься сложить массив со строкой или передать в функцию что-то не то, или опечатался в ее названии. Их можно запускать из командной строки или из vscode, вот пример такого расширения: https://marketplace.visualstudio.com/items?itemName=calsmurf2904.vscode-phpstan
Что касается ситуации с ошибкой в HTML коде внутри текстовой строки, не знаю, помог бы PHPStorm тут или нет. Он отнюдь не всемогущ.
>Справедливости ради, не понимаю смысла функции "локальная история". Это выглядит как бесполезное дублирование функционала гита.
Не путай историю изменений и историю коммитов.
Ты в процессе работы менял файл пять раз. А закоммитил только последний вариант, который посчитал готовым. Предыдущих четырех итераций для гита не существует. Гит это "глобальная история", тяжеловесная и неповоротливая. Каждый коммит намертво вплетается в репозиторий. Для сохранения обязательно нужно выполнять далеко не мгновенные команды. И обычно существуют внутренние правила как дробить коммиты именовать итд. Зато глобально синхронизироваться нужно относительно редко.
А "локальная история" отрабатывает мгновенно, никаких телодвижений от пользователя не требует, сохраняет вообще все и ни с чем не конфликтует. В пхпшторме в локальной истории видны и действия с гитом, и даже изменения, которые были сделаны в другом редакторе.
Да и вообще локальная история это просто пример. Таких вещей в шторме миллион.
Это уже легаси сегодня. Если хочешь ковырять вилкой тонны чужого говнокода, то учи на здоровье - работы на нём вагон.
Почему легаси, третья версия же вроде не вышла
Нахуя тебе битрикс после изучения лары? Еще понятно, когда до, но вот так?..
работаю в конторе где +-25 бекендеров на симфони
стандратный набор = убунту+докер+шторм
а так юзай что хочешь главное чтоб таски сделал
это тебе просто экономит время:
docker-compose up и погнал работать
почистить? docker system prune --all
у нас проекты сделаны через makefile - вообще песня
make start
make test
...
многие выбирают линукс тк докер не тормозит
на макоси тормоза - можно :cached(частично решает проблему) или купить Parallels (100$ в год)
на винде хз но думаю тоже тормоза
>mysql взаимодействуете
давно юзал воркбенч. сейчас шторм
Там всего пару строк надо прописать, а оно все равно не пашет.
Кто использует отпишитесь.
>PHP developer roadmap
>Карта знаний
Братишка уважаю!
Но там много всего.
Выдели основное.
Лучше норм знать базу чем кучу технологий посредственно.
Это кнопка. Нажми и выбери нужную версию.
В настройках шторма можно выбрать интерпретатор, чтобы можно было внутри шторма скрипты запускать. От этого тоже меняется версия.
Купить можно на офф сайте. Там же можно схалявить если ты студент или "студент".
Ну а "купить" можно с помощью сброса триала или чужого кода активации. На кряки не ведись, качай саму прогу только с офф сайта.
Это инструмент, с помощью которого можно строить асинхронные движки. Самое главное, что файберы позволяют "остановить" синхронный код, переключиться на другие задачи, а после продолжить выполнение с места останова.
Это позволяет использовать синхронные библиотеки в асинхронном коде.
Например, у тебя есть Доктрина. Это синхронная ORM. Она использует синхронную же библиотеку соединения с БД (DBAL) и в асинхронном режиме работать не может.
Код получения сущности из БД выглядит так:
$user = $em->find(User::class, 10);
Видно, что тут нет никакой асинхронности: нет ни промисов, ни коллбеков.
То есть, когда Доктрина делает SQL-запрос, то она останавливается и ждет ответа и другие задачи в это время никто выполнять не может. Но если мы подсунем ей вместо DBAL специальную библиотеку с файберами, то мы сможем "останавливать" выполнение кода доктрины, переключиться на другие задачи, а потом, когда придет результат SQL-запроса, продолжить выполнение. И мы получаем код, который выглядит как синхронный (нет ни промисов, ни коллбеков, ни await), а работает асинхронно.
Чет ты хуйню написал.
>То есть, когда Доктрина делает SQL-запрос, то она останавливается и ждет ответа и другие задачи в это время никто выполнять не может. Но если мы подсунем ей вместо DBAL специальную библиотеку с файберами, то мы сможем "останавливать" выполнение кода доктрины
Это основная проблема почему считается что PHP нихуя не асинхронный. Ты можешь приостановить СВОЙ код. Для этого нахуй никакие файберы не нужны, пишешь yield и все. А вот функции самого PHP ты приостановить не можешь нихуя, поэтому непосредственно выполнения запроса дождутся вообще все как миленькие, никуда не денутся.
Все что делают файберы можно делать в PHP прямо сейчас, без всяких реактпхп и свулов, с помощью генераторов. Файберы нужны исключительно чтобы скрыть асинхронность, чтобы с любой функцией можно было работать одинаково асинхронная она или нет. Все, точка. Сам пхп по прежнему однопоточная залупа, никакого прироста производительности из этого выжать не получится, до того же Go по прежнему как до луны раком.
Подскажите, пожалуйста, как генерировать уникальные ссылки на скачивание файлов для http-сервера apache.
И реально ли организовать следующий сценарий: при появлении трёх разных файлов в указанной папке надо сгенерировать для них уникальные ссылки и выгрузить в текстовый файл.
>Вызов PDO::prepare() и PDOStatement::execute() для запросов, которые будут запускаться многократно с различными параметрами, повышает производительность приложения, позволяя драйверу кешировать на клиенте и/или сервере план выполнения запроса и метаданные, а также помогает избежать SQL-инъекций, так как нет необходимости экранировать передаваемые параметры.
То есть PDO::quote() не надо вместе с этим использовать и внутри методов prepare и execute как-то внутри все экранируется для безопасных запросов к бд? Скачал примеры из нового издания той книги, там он через quote() типа экранирует и потом просто пихает в $pdo->query().
И вдогонку опция PDO::ATTR_EMULATE_PREPARES должна быть обязательная включена для экранирования? Или это влияет только на скорость работы?
В твоем посте столько злости на PHP, что можно подумать, что злые разработчики PHP тебе не дают писать на любимом Го.
> Ты можешь приостановить СВОЙ код. Для этого нахуй никакие файберы не нужны, пишешь yield и все.
Это костыль. Yield не предназначен для создания асинхронного кода, а для создания генераторов. Использование его для асинхронного кода приводит к плохой читаемости.
Если, как ты, отвергать удобные средства языка, то тогда и yield не нужен. Просто используешь везде коллбеки, как в старых версиях Ноды, и пишешь асинхронный код.
> А вот функции самого PHP ты приостановить не можешь
Это можно сказать про почти любой язык. Просто не используй синхронные функции, если тебе нужны асинхронные, и все.
> Файберы нужны исключительно чтобы скрыть асинхронность,
Они нужны, чтобы асинхронный код выглядел нормально, а не как уродище с кучей await. Это средство для создания асинхронных библиотек. По моему, удобный инструмент. И как побочное явление, они позволяют использовать не-асинхронные библиотеки вроде Доктрины в асинхронном коде. Очень умно придумано.
Посмотри примеры кода тут: https://www.php.net/manual/ru/pdo.prepared-statements.php
Идея подготовленного запроса в том, что ты не вставляешь данные в запрос, а лишь оставляешь в запросе плейсхолдеры (они выглядят как ? или :name) в том месте, где надо подставить данные. И затем ты отдельно задаешь значения для плейсхолдеров. В этом случае база данных сама подставит значения в запрос со всем требуемым экранированием и SQL-инъекции не будет.
То есть:
$sql = "SELECT ... WHERE x = $x .. "; <-- Тут SQL-инъекция возможна
$sql = "SELECT ... WHERE x = :x" <-- тут нет
PDO::quote при использовании плейсхолдеров использовать не надо.
>>187786
> И вдогонку опция PDO::ATTR_EMULATE_PREPARES должна быть обязательная включена для экранирования? Или это влияет только на скорость работы?
Если эта опция включена, то PDO сам подставит значения в запрос (со всем требуемым экранированием) и пошлет в базу готовый запрос. Если выключена, то PDO не будет подставлять значения в запрос, а пошлет в базу отдельно запрос и отдельно значения.
На безопасность это не влияет. На работу программы тоже. Зачем это нужно?
Дело в том, что некоторые базы данных не поддерживают плейсхолдеры вообще, а некоторые поддерживают, но только один вид, а не оба (например только ?, но не :name). Эта опция позволяет использовать плейсхолдеры даже с такими базами данных.
Спасибо.
С quote() вообще по-моему там не работает, у меня вместо целого числа добавлялся 0 в БД из формы, а вместо char строки только одни кавычки. Нового издания не нашел, может там пояснение какое-то было про это, только примеры из книги на гитхабе. Хотя может быть это из-за того, что я пытался совместить эти 2 метода(execute(array(..)) и quote для каждой переменной из массива POST).
У меня, например, есть персональная динамическая галерея.
Юзер может зайти в свой профиль, нажать на галерею и получить возможность листать по картине(с инфой, интерфейсом и тп) влево-вправо.
Интуиция говорит, я видел отрывочно в примерах, но не обращал внимания, что url для каждой страницы картин генерируется что-то типа /gallery + /img + img.cnt
Когда я сам начал делать такое, то стал задаваться вопросом как правильно делать, учитывая информацию которую я написал выше. Ведь для реализации такого не нужно создавать-изменять ссылку, просто есть какой-нибудь GalleryController, который сам изнутри знает какую ему картинку отдать когда юзер нажимает влево-вправо. Пользователь просто будет видеть один и тот же урл /gallery, все, больше ничего и не надо, так?
Ну для начала можно и на нем, но лучше сразу привыкать к пхпшторму так как все равно придешь к нему в дальнейшем
Читал что у шторма траблы со сбросом триала, есть такое?
А VS code как бы всегда будет гарантированно работать.
А разницу в функционале я навряд ли увижу на начальном уровне.
Как быстро развивается VS ?
Ты очень плохо объяснил задачу. Как реализована твоя галерея?
1) пользователь заходит на страницу, смотрит картинку, затем переходит к следующей картинке с перезагрузкой страницы
2) пользователь заходит на страницу, в страницу встроен список всех картинок и они переключаются яваскриптом без перезагрузки страницы
Если у тебя вариант 1, то ты обязан указывать в URL номер картинки, иначе как сервер поймет, какую картинку выводить? Если URL всегда одинаковый, то пользователь всегда будет видеть одну и ту же картинку.
Если у тебя вариант 2, то номер картинки в URL можно не указывать, но тогда сайт просто будет неудобный. Если ты не обновляешь URL, то при перезагрузке страницы все сбросится на первую картинку. Также, нельзя будет поделиться ссылкой на определенную картинку. Если ты перешел по ссылке и вернулся назад, опять-таки, все сбросится на первую картинку.
Поэтому логичнее добавлять номер картинки в URL.
В варианте 2, номер картинки можно встроить как в часть URL, которая передается на сервер (до знака #), так и в ту, что не передается (после #). В первом случае над обновлять URL с помощью History.pushState(), чтобы страница не перезагружалась, во втором можно обновлять как обычно, так как от замены части после # страница не перезагружается.
По мне так ты все хорошо понял)
У меня вариант 1, с перезагрузкой страницы.
>если вариант 1
По нажатию кнопки влево-вправо. Галерея начинается с 0 картинки, клик далее и индекс +1, клик назад индекс -1.
Все данные галереи хранятся в сессии.
В таком случае и без урл будет работать.
>cбросится
В сессии сохраняется актуальный индекс картинки. Не сбросится в таком случае.
>нельзя поделиться ссылкой
Бинго! Теперь точно дошло зачем так делать надо.
>hash
Я все понял, пойду почитаю, спасибо тебе.
Очередной параноик у которого украдут картинки? За 15 лет в интеренте ни разу не видел херни, которую ты описываешь. Если я захочу спиздить твои картинки, то я спизжу - они один хуй згружаются если подергать ссылку несколько раз. Но нахуя пользователям такая система я хуй пойму.
Я задал просто вопрос, использовав абстрактную ситуацию, мне надо просто понять как работает та или иная технология.
>подергать ссылку несколько раз
Слишком много гемора, ты расхочешь спиздить.
А ты подходи со стороны пользователя, который будет эту галерею смотреть. Ему на твою паранойю насрать. Если ему неудобно он развернется и уйдет. А парсеру поебать много ссылок тыкать или одну.
Использование сессии не позволит открыть несколько экзепляров галереи в нескольких вкладках. Точнее позволит, но они будут влиять друг на друга.
Потому лучше добавлять номер картинки в URL. Ну и с точки зрения оптимизации выгоднее было бы загрузить сразу список всех картинок и переключать яваскриптом без перезагрузки страницы, но с обновлением URL.
Как посмотреть какие данные приходят? Кликая на кнопку сабмит, должны фоточки отдаваться, как глянуть какие?
Мимо вебмакака, бэк на ларавеле.
Годно.
Вкатывайся в рельсы
Использовать MVC вместо страниц и держать в /public только index.php, вызывающий роутер, очевидно. Ты бы хоть гайд в шапке почитал.
Открой инструменты разработчика в браузере (F12) на вкладке Network и нажми на кнопку. Там должен отобразиться запрос и ответ на него.
>>191545
Класс App\Kernel не найден. Впрочем, в новых версиях Симфони его вроде и не должно быть.
>>191716
На тех страницах, доступ к которым есть только после авторизации, надо проверять ее наличие. Если нет - редиректить на форму логина.
Ещё проблемы с закрашиванием, у меня было так, что из четырёх неиспользуемых переменных предупреждение появляется только на двух из них.
Почему так? В IntellijIDEA такого не было.
c:\php\php.exe" -S localhost:9091
В чем может быть проблема?
Вернее сам сервер запускается, но файл не проходит, тупо как текстовый редактор выводит код во вкладкке.
Все работает, если набирать через localhost.
Но у меня вроде как через правую мышь открывалось или меня глюкануло?
так же не должно работать?
но это уже после установки XAMPP.
Но у меня как то же работало без него в первый раз со встроенным.
а теперь он открывает только через файловую систему.
Где то прописывать надо, чтобы он через сервер заходил?
В принципе я все же XAMPP , буду пользоваться, но просто на будущее хотелось бы знать, что случилось и как это работает.
https://ideone.com/dCEerL
Может просто заменить htmlentities на htmlspecialchars?
Правильно с использованием htmlspecialchars при выводе в шаблон: https://github.com/codedokode/pasta/blob/master/security/xss.md
Обрати внимание, экранирование надо делать при выводе. А не в начале скрипта, когда мы читаем данные из GET/POST.
Код на твоем скриншоте очень старый. Так как magic quotes давно отключены по умолчанию.
Проблема с использованием array_map тут в том, что код довольно тяжело разбирать. Так как он не написан в стиле "сделай первое, сделай второе", а в стиле "преобразуем массив функцией, которая преобразует другой массив другой функцией, которая вызывает третью функцию".
Мне кажется, было бы лучше не писать все одним огромным выражением, а разбить на 2-3 действия.
Функция mb_toArray названа неудачно, и еще и стиль в названии не выдерживается. Ее лучше было назвать toLetters, splitToLetters.
По идее ты должен просматривать страницу, набирая в браузере localhost/.... Если ты открвываешь файл напрямую, то браузер показывает содержимое PHP файла, но не выполняет его.
Спасибо.
Пятое издание книги все то же от 19го года, в примерах к 6му 21года все то же самое. Надо наверное по быстрому ее дочитать и переходить к вашей шапке.
file_get_contents("http://" . SanitizeString($_POST['url']));
Хотя автор как-то к news.com коннектился, раньше по http тоже была поддержка? Http-страницы вроде загружаются, хоть и с вопросительными знаками вместо букв. Не пойму, это его экранирующая функция виновата или у меня в 7ке винде шрифты не обновленные какие-то.
function SanitizeString($var)
{ $var = strip_tags($var);
$var = htmlspecialchars($var);
return stripslashes($var); }
Это все в контексте главы про AJAX. Inb4 древний код тоже, там дальше jquery, это вроде тоже в тему.
И как я понял charset нельзя передать через setRequestHeader.
Я выяснил, что это, вроде как, умеет Mockery - https://laravel.com/docs/8.x/mocking#mocking-objects или http://docs.mockery.io/en/latest/reference/partial_mocks.html#runtime-partial-test-doubles
Но у меня все-равно вызывается оригинальный метод ("fetchCurrencies").
Ну и вообще как тестировать сервисы, которые ходят к сторонним api?
Сейчас многие сайты не поддерживают http, а только https. Может, в этом проблема? По идее, если при соединении происходит ошибка, то ты должен видеть либо на экране, либо в логах, причину ошибки.
> Я так понимаю эта функция не будет работать с https сайтами
Ну в ней же написано http, а не https, естественно не будет.
> Http-страницы вроде загружаются, хоть и с вопросительными знаками вместо букв.
Тебе надо корректно работать с кодировками. Во-первых, при выводе страницы указать кодировку в теге meta charset (желательно utf-8), во-вторых, если страница, которую ты скачиваешь, в другой кодировке, то ее надо преобразовать в utf-8.
Также, код мягко говоря странный. Там надергано каких-то функций вроде stripslashes и непонятно, для чего они нужны. Ты понимаешь, что они делают? Если нет, то это плохой учебник.
Ну и логику функции я не очень понимаю. Эта функция позволяет сделать произвольный запрос к произвольному сайту и это тоже не хорошо, так как таким образом твой сайт можно использовать как прокси для каких-нибудь нехороших дел. А в черные списки попадет в итоге твой сайт.
Эти странные функции экранирования надо убрать. Далее, надо переделать логику функции, чтобы она не позволяла делать запросы к произвольным сайтам, а только к разрешенным. Или как-то ограничить доступ, чтобы этим мог пользоваться только админ, а не любой желающий.
Надо понимать, как работает Mockery. Как я понял, ты используешь Proxied Partial Doubles (так как ты передаешь в конструктор мока объект, а не имя класса: http://docs.mockery.io/en/latest/reference/creating_test_doubles.html#proxied-partial-test-doubles ). То есть, ты создаешь объект Mockery, вызываешь supportsCurrency, он вызывает этот метод на исходном объекте. И если дальше вызываются какие-то другие методы вроде fetchCurrencies, то прокси этого никак не видит и ничего сделать не может.
Тебе нужен другой тип мока, который создается как \Mockery::mock(SomeClass::name). И то, надо понимать, что он например не сможет перехватывать обращения к приватным методам, так как он работает путем создания класса-наследника и переопределения методов исходного класса.
И часто объект не мокают частично, а заменяют целиком. То есть, если у тебя есть какая-то логика и работа с API , то ты делаешь два класса. И мокаешь тот, что работает с API, а класс с логикой не трогаешь. Такое разделение хорошо и с архитектурной точки зрения.
Работу с API обычно тестируют через заглушки/моки. Мы подменяем класс, который взаимодействует с API, чтобы он вместо обращения к API отдавал заготовленный ответ. Для этого не обязательно использовать Mockery, можно например просто сделать второй класс-заглушку и передать его, используя Dependency Injection:
$fakeApi = new FakeAPI(['USD' => 70]); // заглушка
$currencyService = new CurrencyService($fakeApi);
И еще, один момент. Мне крайне не нравятся тесты, которые проверяют, что определенный метод был вызван, или что он был вызван с такими-то аргументами. Это плохие, хрупкие тесты, так как они полагаются на знание, как устроен тестируемый код. Завтра ты чуть перепишешь код, и тест сломается.
То есть ты не должен проверять, что твой класс обращается к API получения курсов валют ровно один раз. Какая тебе разница, куда и сколько раз он обращается? Ты должен проверять, что он возвращает правильный курс (при этом, конечно, ты используешь заглушку, чтобы твои тесты не зависели от стороннего API).
Надо понимать, как работает Mockery. Как я понял, ты используешь Proxied Partial Doubles (так как ты передаешь в конструктор мока объект, а не имя класса: http://docs.mockery.io/en/latest/reference/creating_test_doubles.html#proxied-partial-test-doubles ). То есть, ты создаешь объект Mockery, вызываешь supportsCurrency, он вызывает этот метод на исходном объекте. И если дальше вызываются какие-то другие методы вроде fetchCurrencies, то прокси этого никак не видит и ничего сделать не может.
Тебе нужен другой тип мока, который создается как \Mockery::mock(SomeClass::name). И то, надо понимать, что он например не сможет перехватывать обращения к приватным методам, так как он работает путем создания класса-наследника и переопределения методов исходного класса.
И часто объект не мокают частично, а заменяют целиком. То есть, если у тебя есть какая-то логика и работа с API , то ты делаешь два класса. И мокаешь тот, что работает с API, а класс с логикой не трогаешь. Такое разделение хорошо и с архитектурной точки зрения.
Работу с API обычно тестируют через заглушки/моки. Мы подменяем класс, который взаимодействует с API, чтобы он вместо обращения к API отдавал заготовленный ответ. Для этого не обязательно использовать Mockery, можно например просто сделать второй класс-заглушку и передать его, используя Dependency Injection:
$fakeApi = new FakeAPI(['USD' => 70]); // заглушка
$currencyService = new CurrencyService($fakeApi);
И еще, один момент. Мне крайне не нравятся тесты, которые проверяют, что определенный метод был вызван, или что он был вызван с такими-то аргументами. Это плохие, хрупкие тесты, так как они полагаются на знание, как устроен тестируемый код. Завтра ты чуть перепишешь код, и тест сломается.
То есть ты не должен проверять, что твой класс обращается к API получения курсов валют ровно один раз. Какая тебе разница, куда и сколько раз он обращается? Ты должен проверять, что он возвращает правильный курс (при этом, конечно, ты используешь заглушку, чтобы твои тесты не зависели от стороннего API).
Warning: file_get_contents(): SSL operation failed with code 1. OpenSSL Error messages: error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed
Вот такая была ошибка, но я разобрался, надо создать массив контекста и в подмассиве ssl для ключей verify_peer и verify_peer_name поставить false, потом добавить этот контекст как параметр в ф-ию file_get_contents. http или https в строке внутри функции - не важно как ни странно.
А вот как переделать кодировку? Там страница в windows-1251 передается со стороннего сайта и встраивается в мою аяксом.
request = new new XMLHttpRequest()
request.open("POST", "urlpost.php", true)
request.setRequestHeader("Content-type",
"application/x-www-form-urlencoded")
Я прочел, что в этот заголовок нельзя добавить еще какие-то параметры.
request.onreadystatechange = function()
{
if (this.readyState == 4)
{
if (this.status == 200)
{
if (this.responseText != null)
{
document.getElementById('info').innerHTML =
this.responseText
}}}}
request.send("url=on-line-teaching.com/index.html)
> Вот такая была ошибка, но я разобрался, надо создать массив контекста и в подмассиве ssl для ключей verify_peer и verify_peer_name поставить false,
Вообще, это не очень правильное решение. Ты отключаешь проверку сертификатов, а значит, не сможешь распознать если кто-то попытается перехватить HTTPS-соединение. Правильнее было бы добавить нужные корневые сертификаты, чтобы PHP мог их проверять. Смотри, например, эту страницу https://neurotechnics.com/blog/ssl-ca-bundles-for-curl-and-php/
> А вот как переделать кодировку?
Функцией iconv на стороне PHP. Ты получаешь страницу в Windows-1251, конвертируешь ее в utf-8 и отдаешь с правильным заголовком Content-Type (в котором указана кодировка utf-8).
Блин, спасибо, преобразовалось как надо все и отобразилось.
Да я не дошел ни до каких курлов пока. У него в книге он просто как-то подрубился к сайту news.com непонятным образом безо всяких контекстов. Япросто скопировал пример из книги и в браузере выскочил ssl warning вышеуказанный вместо страницы. А это потом уже все костыли, которые я скопипастил со stackoverflow как водится.
У меня этот сервис только внешний api дёргает и результатом гидрирует value-objects. А я не понимаю как это тестировать.
А советы дельные, спасибо.
Bump...
> как генерировать уникальные ссылки на скачивание файлов
Непонятно, в чем сложность. Ты не знаешь, как устроена ссылка? Как сгенерировать случайный набор символов?
> И реально ли организовать следующий сценарий: при появлении трёх разных файлов в указанной папке надо сгенерировать для них уникальные ссылки и выгрузить в текстовый файл.
Реально. Чтобы отслеживать появление файлов надо либо использовать что-то вроде inotify (из постоянно работающего скрипта), либо запускать скрипт по крону и проверять список файлов.
Ты можешь попробовать использовать мок другого типа, когда ты передаешь в конструктор Mockery не объект, а имя класса. И используя этот мок, перехватить функцию, которая отправляет запрос.
Но, по моему, это будет плохой тест, так как ты полагаешься на знание внутреннего устройства класса, а это плохо.
Гораздо лучше будет подменить HTTP-клиент. Если у тебя нормальная архитектура, то ты не отправляешь запрос вручную вызывая функции вроде curl_init, а используешь класс HTTP-клиента вроде Guzzle. Его и можно подменить, или использовать встроенную в Guzzle возможность подменять ответы.
Если у тебя плохая архитектура и ты прямо в классе делаешь HTTP-запрос с помощью file_get_contents или curl, то единственный правильный вариант тестирования такого кода - это поднять веб-сервер с заглушкой и сделать, чтобы запросы слались к нему вместо настоящего сервера.
https://ideone.com/4ulLwE
Та статья про курл, но она применима и к твоей ситуации. В контексте для ssl ( https://www.php.net/manual/en/context.ssl.php ) есть опции cafile и capath.
В cafile указывают путь к файлу со всеми корневыми сертификатами.
В capath указывают путь к "correctly hashed" папке с отдельными файлами-сертификатами. Как я понимаю, такая папка есть в системах на linux.
Соответственно, правильно было бы скачать файл с сертификатами в нужном формате и указать путь к нему в опции cafile.
Вручную скачать файл с корневыми сертификатами, собранными Mozilla, можно тут: https://github.com/composer/ca-bundle/blob/main/res/cacert.pem
Так как список корневых сертификатов может меняться, тебе надо периодически обновлять файл.
Но удобнее было бы, используя композер, установить пакет composer/ca-bundle и далее использовать код из документации к нему: https://github.com/composer/ca-bundle#to-use-with-php-streams
Тогда ты будешь проверять сертификаты и использовать безопасное шифрованное соединение. А советы по отключению проверки просто вредные.
Пример кода в книге раньше работал скорее всего потому что в то время сайты использовали в основном нешифрованный HTTP, и проблемы с проверкой сертификатов не было. И не сработал сейчас, так как сейчас практически все сайты используют HTTPS.
Как генерировать уникальные ссылки-айдишники? В целом, уникальную строку.
Каждый раз при создании-изменении записи в базе нужно либо самому проверять не использовалось ли значение раньше, либо если колонка имеет свойство "уникальность", то база при записи будет сама проверять все это, так?
То бишь у тебя записей 100, ты делаешь 101 и скрипт смотрит на 100 записей и сравнивает их с новой. И если у тебя, скажем, 10кк записей, то при добавлении новой, он будет перебирать все эти 10кк? Из чего можно сделать вывод, что нагрузка на оборудование растет в прогрессии.
Знаю, что это не тянет на открытие Америки, просто хотелось бы послушать мнения-отсылки-примеры на этот счет.
Понятно, пасиба за ответ я пойду учить
>Ты не знаешь, как устроена ссылка? Как сгенерировать случайный набор символов?
Да, не знаю. Особенно как это делается в плане Apache.
Допустим, подсунули в каталог www или как его там в Апаче нужный файл foo.txt.
Ссылка на него будет выглядеть наверно так http://localip/foo.txt
Как изменить ссылку, например, на http://localip/90490458qniauelink333 чтобы она продолжала указывать на искомый файл.
Короче, как это называется - я съебу в интернеты в на поиски.
А то тут такие наезды, как-будто я HTTP сервера каждые полчаса поднимаю и настраиваю.
>То бишь у тебя записей 100, ты делаешь 101 и скрипт смотрит на 100 записей и сравнивает их с новой. И если у тебя, скажем, 10кк записей, то при добавлении новой, он будет перебирать все эти 10кк
Ну формально так. Очевидно пусть этим занимается БД.
Приделай индекс к этому полю, тогда 10кк строк можно будет перебрать за 17 итераций или вообще за одну (зависит от индекса).
О, таким и занимаюсь. Самописная CMS-ка без документации. Но не вижу в этом ничего плохого, если это будет первой работой в этой сфере
>У меня кореш на автомойке столько же зарабатывает без всякой ебли с кодом
О да, без всякой ебли с кодом, ебля с немытыми машины намного лучше за эти деньги, а перспективы-то какие!
Если ты просто создаешь таблицу и будешь делать по ней поиск, то да, чем больше таблица, тем дольше поиск. Поиск по таблице из миллиона записей будет в миллион раз дольше, чем по таблице с одной записью. То есть алгоритм поиска по умолчанию такой: берем по очереди каждую строчку таблицы и проверяем, соответствует ли она условию. Время поиска растет с ростом таблицы и пропорционально числу записей в ней.
Но, к счастью, в базах данных есть возможность создать индекс. Индекс - это структура, которая позволяет выполнять определенные виды поиска очень быстро. Например, индекс по колонке x позволяет очень быстро найти в ней значение 123456. Или убедиться, что такого значения нету.
Что значит "очень быстро"? Значит, время поиска в индексе пропорционально не числу записей в таблице, а логарифму по основанию 2 от него.
Пусть поиск по таблице из 1 записи занимает t. Поиск по таблице из миллиона записей займет 1000000t. А поиск по индексу на миллион записей займет log2(1000000) ~ 20t. То есть, поиск по индексу для таблицы в миллион записей будет всего в 20 раз медленнее чем по таблице с одной записью и в 50 000 раз быстрее чем поиск без индекса.
То есть, если ты создаешь таблицу уникальных кодов и сделаешь в ней индекс, то поиск будет происходить быстро.
Проверить, используется ли эффективный поиск по индексу или медленный поиск методом полного обхода таблицы, можно командой EXPLAIN.Например :
EXPLAIN SELECT * FROM codes WHERE code = 123456;
В общем, иди читать про индексы и команду EXPLAIN. Если будут вопросы, то уточняй.
Ты просто плохо сформулировал первоначальный вопрос, так как из него непонятно, что именно ты не понимаешь. А сейчас, наоборот, стало понятно.
Изменить ссылку на файл можно как минимум двумя способами.
1) путем переименования файла. Во-первых, это плохая идея класть файл прямо в папку www, так как он сразу будет доступен по прямой ссылке. Лучше сделать специальный каталог private. недоступный из веба, и класть файл туда.
Допустим, кто-то положил файл foo.txt в каталог private. Если мы хотим сделать на него трудноподбираемую ссылку, то мы можем просто скопировать этот файл в папку Апача, дав ему произвольно длинное имя. Также, мы можем сохранить информацию о файле в базу данных, чтобы его потом можно было найти.
2) веб-сервер можно настроить таким образом, чтобы при открытии ссылки он не пытался искать файл с таким именем, а вызывал PHP-скрипт, например index.php. А дальше уже PHP-скрипт анализирует URL, проверяет его корректность и если все ок, то отдает файл из папки private (к которому нельзя обратиться в обход PHP-скрипта, так как эта папка недоступна Апачу).
При таком подходе мы можем, например, сделать файлы доступными только определенным пользователям, или например, ограничивать число скачиваний - в общем, делать произвольные проверки.
Гугли информацию по mod_rewrite для этого метода. Лучшая информация это официальная документация Апача на английском.
в пыхе нулевой
Регайся на stepik. Под бесплатные курсы Python выдавали лицуху для PyCharm на 3 месяца, можно продлевать. Кто знает, может и с пыхой так.
Спасибо, анон, попробую. Не покупать же в самом-то деле.
>Или вообще другие библиотеки?
Сейчас все боготворят SPA. Поэтому актуальны React, Vue, Angular.
jQuery постепенно опускается в могилу, ибо никому уже не всралась поддержка ie9, часть неработающих селекторов и ужасная производительность.
Не, я просто вротендер, сейчас рассматриваю вариант немного прокачаться как фулстек, на этом проекте используется битрикс. Выбор у меня либо дрочить реакт, либо дрочить реакт+ битрикс.
Как вообще разделяется работа фронт и бек-ендеров? Например в случае использования ajax? Верстальщик это третье лицо или тоже во фронтенд входит?
>Как вообще разделяется работа фронт и бек-ендеров?
>Например в случае использования ajax?
Ну создается ишью, по нему пилится отдельный метод на бэкенде с этими вашими крудами, затем (или параллельно) интегрируется в приложение.
> Верстальщик это третье лицо или тоже во фронтенд входит?
Смотря какой размер проекта. На больших проектах есть целые отделы верстальщиков, на более мелких верстает как правило фронтендер.
Устраивайся не в мухосрань. У меня одногруппник джуном пыхером устроился на удаленку в ДС за 50к.
Так джунов берут на удаленку сразу? Или все-таки есть период "стажерства" где под присмотром в офисе работаешь?
Берут на испытательный срок, что бы убедится, что ты в рабочее время будешь грести, а не устраивать срачи в /po/
>Это паникод для кирилических доменов. Его сам Chrome делает. В Firefox все норм
Как вместо кода панина возвращать Email?
>Я прочел, что в этот заголовок нельзя добавить еще какие-то параметры.
Плохой источник у тебя. Ты можешь добавить encoding в content-type и все у тебя будет работать (если ты используешь XMLHttpRequest). Если ты используешь fetch, то тебе нужен будет создать TextDecoder для перекодировки из бинарных данных в UTF кодировку.
Спасибо, не нашел этого тогда.
request.setRequestHeader("Content-type",
"application/x-www-form-urlencoded")
Вот что там было у xhr.
Лол, и как я не заметил. Спасиба.
хостинг reg.ru взломали
О, это тот самый Бабак из эпичного треда в /b
Это неправильный подход. Ты предлагаешь с сервера отдавать ответ с некорректной кодировкой в заголовке, а на клиенте переопределять этот заголовок. Надо на сервере отдавать и правильную кодировку, и правильный заголовок.
Тем более, что человек учится, и ему надо изучать, как решить задачу правильно, а не как бездумно воткнуть костыли.
Я нуб пока и путаю может что-то, но тот пример состоял в том, что страница делает аякс запрос, вызывается php скрипт, в нем с левого сайта из инетра с помощью file_get_contents помещается страница в переменную, а эта переменная асинхронно встраивается в innerHTML элемента исходной страницы.
Ну если у тебя проходит через твой сервер, то да, лучше декодировать прямо на твоем сервере, чем на клиенте.
>эта переменная асинхронно встраивается в innerHTML
Почистить контент переменной от опасных тегов не забудь.
Решил проблему :)
Чтобы не писать два раза, сколько было кэша вначале и как рассчитывается процент, лучше использовать цикл while.
https://ideone.com/6tEU0x
Срабатывает даже если не считать процент перед циклом. И я что-то не догоняю почему, если переменная процента инициалировалась нулем, тогда по идее ошибка была бы в один год т.к. во время первой итерации ничего не прибавилось к сумме, а год увеличился на 1.
For работает так:
1. Инициализация счётчика.
2. Проверка условия.
3. Если условие истинно, выполняем блок действий.
4. Изменяем значение счётчика.
Пункт 4 выполняется после п.3, поэтому значение процента будет рассчитано и учтено уже на первой итерации цикла.
И ещё, условия должно быть <1000000, иначе ровно миллион твой скрипт проигнорирует.
И не надо длть прмнн вида $с, $p.
>пишем учебник перегруженный математикой практически без намека на реальные интересные приложения
>думаем что новичкам это будет очень интересно изучать
>ехидно умиляемся наивным вкатунам
Домашний каталог указал /
Стартовую позицию указал web/index.php
Главную страницу показывает нормально, но когда роуты строит подставляет /web и все не работает (( Еще и .htaccess нет в для windows
Вот это правильный совет. Действительно, тут возможна такая атака: сторонний сайт, с которого берется контент, вставляет в него скрипт, этот скрипт попадает вместо с контентом на страницу, и начинает срабатывать у пользователей. Также, есть чуть менее опасная атака: сторонний сайт вставляет в контент CSS-стили и они ломают отображение сайта.
Получается, надо библиотекой вроде htmlPurifier удалять теги script/style/iframe и фильтровать CSS-правила в атрибуте style.
>>206837
Подскажи, где тут перегрузка математикой? Я не думаю, что вычисление процентов это такая уж тяжелая математика.
И что касается "интересных приложений", интересы ведь у каждого свои. Тут вряд ли получится за всех решить, что им интересно. Плюс, учебник учит основам PHP, тут сложно что-то "реальное" сделать, пока его не пройдешь.
>>207219
Я не очень понял, что такое "стартовая позиция", ты не мог бы скинуть скриншот настроек хостинга?
Ты не написал, какой веб-сервер используется (Apache или IIS). Под Windows теоретически можно использовать Апач, который поддерживает htaccess. Но если используется IIS, то у него наверно есть свой механизм для настройки соответствия между URL и файлами на диске.
>>204889
Да это все я одними и теми же с вопросами, вкатывальщики похоже закончились пока.
Дочитал ту книгу многострадальную, в конце он делает типа мини блог/соцсеть, ну типовое задание как я понимаю. Так вот он там никаких связываний не делает, если где-то надо к бд обратиться, использует функцию где просто передает строку запроса SQL:
function queryMysql($query)
{
global $pdo;
return $pdo->query($query);
}
Как по уму тут делать надо, или хотя бы с привязыванием значений к запросу, функцию с переменным числом аргументов и туда добавлять значения запроса как аргументы?
Алсо страницы сайта у него в формате php, то есть если страница юзера одного выводится, там добавляется GET значение к ссылке members.php?$user=..
Это и есть шаблоны о которых говорилось или надо как-то отдельно html страницы делать, а в них вызывать php скрипты? У него html код через отдельные echo или heredoc выводится внутри этих скриптов.
Также решил глянуть учебник из шапки, т.к. автор книги ооп не коснулся вообще, паттернов, mvc, etc ну и практики нет по факту. Так вот самому даже что-то простое написать гораздо сложнее чем читать чей-то код, с этим кредитом на айфон такой затуп произошел, что я уже что-то сомневаюсь теперь про вкат, по крайней мере в бекэнд (а там и на фронте в js логика ведь тоже нужна).
Ну а вопрос вот про вывод индекса здесь в примере, разве он не с нуля начинается? 0..15 для 16 элементов.
SPA, само собой, написан на жс. А то как-то двусмысленно написал.
Вроде правильный результат, ответа нет в той главе. Кстати почему переменные внутри echo бывают выделены фигурными скобками, чтобы отдельно точками не складывать строку?
С нуля.
Когда работают с массивами, и нужно по индексу и получить доступ к элементу и вывести индекс в человеческом формате (начиная с 1), то в одном месте придётся добавлять или вычитать единицу из индекса.
Раз вывело 16, а индексы в массиве 0..15, значит $randomText = $letters[$random - 1]
Там просто предлагалось использовать array_rand(), а он возвращает индексы как есть.
Не понимаю, как указать в регулярке символы на любой позиции. На стековерфлоу про какой-то lookahead говорили, но в статье из шапки нет про это, значит какое-то более простое есть решение.
Уже выучил(или как минимум знаком):
PHP, Git, Docker(docker-compose), composer, начал недавно Laravel изучать, MySQL(простые SQL запросы, типы данных), знаю немного SOLID, MVC, DRY/KISS(читал), парочка простых паттернов проектирования.
Этого хватит для вката или что ещё нужно осилить? Напрягает, что в дохуище мест требуют JS, я его вообще не шарю.
Привет, а что у вас в php используется вместо шаблонов? Например, как я могу сделать наследование шаблонов? Или хотя бы шаблон внутри шаблона?
Спасибо, нужно на чистом php, без фреймворков. required для этих целей использовать нормально?
Симфони как конструктор работает, можешь из него только twig взять. В документации должны быть рекомендации по подключению.
Не парься, джс не сложный для php-разработчика, сложные вещи делать не надо будет скорее всего.
^[-\s\(\)](8|\+7|\+ 7)[-\s\(\)][\d][-\s\(\)][\d][-\s\(\)][\d][-\s\(\)][\d][-\s\(\)][\d][-\s\(\)][\d][-\s\(\)][\d][-\s\(\)][\d][-\s\(\)][\d][-\s\(\)]*[\d]$
Во, утро вечера мудренее, обрабатываются номера теперь вот такой регуляркой. Так и задумывалось или можно короче сделать?
https://ideone.com/CMjiOq
Как кстати длинную строку разделить на более короткие в редакторе, но чтобы не вставилось символов переноса?
>Как кстати длинную строку разделить на более короткие в редакторе, но чтобы не вставилось символов переноса?
Через конкатенации. Можно записать:
$var = 'ab';
но можно и так:
$var = 'a'
. 'b';
Точно, почему-то не подумал про это, спасибо. Думал там символ типа бекслеша как в питоне надо.
Ну так у пистона конец инструкции это конец строки, а у php как у сишки точка с запятой, ему на твои переносы строк похуй.
Что-то я не понял как в задаче об "опечаточниках" в конце в одном регулярном выражении корректно найти все возможные варианты чередования языка и еще чтобы вдобавок выделить их скобками в нужном месте.
Костыли это тоже решение, как по мне. И автоисправление что-то тоже не очень понятно, для каждой буквы отдельно прогонять через preg_replace? Сомнительно.
https://ideone.com/KiYApX
https://ideone.com/UchUS6
https://ideone.com/z8RG0m
Кое-как пробираюсь через задачи, хотя наверное говнокод получается обычно. Два вопроса возникло:
Как правильно сравнивать элемент массива с пробелом? Я так понимаю " " и "\\s" это равнозначно.
Это норма что сразу не выходит и приходится через var_dump смотреть промежуточные результаты и как бы брутфорсить решение?
Хелп, уже полдня не могу сгенерировать Laravel - приложение по официальному гайду.
Что я делаю:
sudo systemctl start docker
curl -s https://laravel.build/example-app | bash
Послушно ввожу пароль.
cd example-app
./vendor/bin/sail up
Что я получаю:
[+] Running 0/1
⠿ laravel.test Error 0.4s
и далее:
https://pastebin.com/nZm49Br1
В сети информации не нашел, писали, что могли криво пакеты выкачаться либо места на диске не хватать, но я специально очистил 8+ гигов и кучу раз все перекачивал (возможно, не все, но я хз, где еще может храниться кэш вот отсюда: https://laravel.build/)
Прошу хоть намекнуть, в каком направлении двигаться. Система - Arch Linux, возможно, не хватает каких-то пакетов, хотя по идее одного докера должно быть достаточно.
> использует функцию где просто передает строку
Это неправильно. Надо отдельно передавать запрос с плейсхолдерами и отдельно переменные для него.
Здесь есть примеры корректного кода для PDO, MySQLi: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md#методы-борьбы
Дополнительно я советую почитать описания функций PDO prepare, bindValue, execute в мануале (он переведен на русский): https://www.php.net/manual/ru/pdo.prepare.php
> Как по уму тут делать надо, или хотя бы с привязыванием значений к запросу, функцию с переменным числом аргументов и туда добавлять значения запроса как аргументы?
Да, функцию, которая принимает запрос и массив параметров к нему. Вот пример такой функции в библиотеке DBAL, там еще можно третьим параметром передать типы аргументов:
$stmt = $conn->executeQuery('SELECT * FROM articles WHERE id IN (?)',
array(array(1, 2, 3, 4, 5, 6)),
array(\Doctrine\DBAL\Connection::PARAM_INT_ARRAY)
);
> Это и есть шаблоны о которых говорилось
Нет. Что такое шаблоны, описано тут: https://github.com/codedokode/pasta/blob/master/php/templates.md
> У него html код через отдельные echo или heredoc выводится внутри этих скриптов.
Это очень неудобно и код получается плохо читаемый.
Чем больше ты решаешь задач, тем проще становится. Так что не беспокойся, а больше пиши код.
Индексы в массиве по умолчанию (если ты их не задаешь сам) действительно начинаются с 0. Но здесь переменная $i не используется как индекс массива, а просто для отсчета количества слогов, потому можно начинать ее с 1.
>>210904
Переменную можно (но не обязательно) окружать скобками, чтобы отделить от текста (чтобы он не был частью имени переменной): echo "{$weight}kg". Если у тебя за переменной идет пробел или знак препинания, то скобки не требуются.
То есть, можно писать так:
echo "Вес $weight кг\n";
По коду: во-первых, код надо выравнивать правильно. Код внутри функции должен быть сдвинут на 4 пробела вправо. Читать тяжело такой код.
> while($credit!=0){
Безопаснее писать $credit > 0. А то вдруг из-за округления получится не 0, а -0.000001 и тогда цикл никогда не закончится.
> if($credit<$payout) $payout=$credit;
Тело if надо заключать в фигурные скобки (язык позволяет не заключать, но рекомендации по стилю кода PSR рекомендуют ставить их). Эту строчку можно заменить на более короткий вызов функции min().
> $credit=$credit-$payout;
Здесь можно использовать -=
Ответы выглядят правильно.
Регулярки так не работают. Регулярка это последовательность: сначала идет x, за ним идет y, за ним z. Ты не можешь "вернуться" назад и сказать: а вот там 5 символов назад должна быть буква w.
Потому ты должен написать примерно так:
- сначала идет +7 или 8
- за ними идет 10 повторяющихся групп; каждая группа состоит из любого количества знаков, за которым идет одна цифра
Как описать "10 повторяющихся групп"? Используй круглые скобки, чтобы создать группу и применить квантификатор (знак повторения) к ней. Например:
(abc)+ значит "1 или более раз повторяется abc". Если бы скобок не было, то знак плюс применился бы только к букве c, а так он применяется ко всей группе.
lookahead это другое и тут не поможет. Но давай я расскажу при lookahead и lookbehind. Это "утверждения", assertions, они отличаются от других выражений тем, что не "поглощают" символы, которые проверяют, а лишь проверяют условие.
Например, это выражение:
[a-z]{4}
Значит "4 любых буквы". А как сказать "слово из 4 букв, не начинающееся с xyz"? Тут и нужен отрицательный lookahead:
(?!xyz)[a-z]{4}
Тут (?!xyz) значит "дальше должно быть не xyz".
Другой пример - lookbehind. Он проверяет условие ДО текущей позиции. Например: найти все буквы a, перед которыми стоит не цифра:
(?<![0-9])a
Выражение в скобках значит "слева от текущей позиции должна быть не цифра".
assertions не поглощают символы и не сдвигают текущую позицию. То есть, если несколько утверждений идут подряд, то они все относятся к одному и тому же месту в строке. Например, это:
(?!xyz)(?!abc)[a-z]{4}
Значит "слово из 4 букв, не начинающееся с xyz и не начинающееся с abc".
Наверно надо изучить фреймворк. Так как реальные проекты часто пишутся на фреймворках, а не с нуля.
>>211836
На "чистом" PHP тебе придется изобретать свой шаблонизатор для этого. Проще отказаться от наследования шаблонов и вручную из страницы подключать шапку и подвал с помощью require.
>>211836
Можно, но это будет просто подключение одного шаблона из другого, а не настоящее наследование, когда ты расширяешь шаблон и заменяешь в нем одни части другими.
> Как кстати длинную строку разделить на более короткие в редакторе, но чтобы не вставилось символов переноса?
У регулярных выражений есть специальный флаг x, который включает игнорирование пробелов и переносов строк и даже позволяет добавлять комментарии прямо в регулярку:
$regexp = "/
# Это комментарий
hello |
world |
something
/ux";
Пробелы в такой регулярке обозначают с помощью \s.
Нужно использовать группировку с помощью круглых скобок.
>>212269
> в одном регулярном выражении корректно найти все возможные варианты чередования языка
А тебе не надо искать все варианты. Тебе надо найти слова, в которых за любой буквой одного алфавита идет любая буква другого алфавита.
То есть: любые буквы, кирилица + латиница или латиница + кирилица, любые буквы.
> И автоисправление что-то тоже не очень понятно, для каждой буквы отдельно прогонять через preg_replace?
Ты можешь использовать strtr, она принимает массив символов и их замен. И preg_replace по моему тоже принимает массив (смотри мануал).
Только тебе сначала надо определить язык слова, чтобы ты в английском слове не заменял буквы на русские. Это можно сделать, например, по первой букве слова, или по большинству букв.
> $parts
Лучше назвать $sentences
> $arr
Ужасное название. Используй $letters.
Форматируй код (клавиша Tab) или используй редактор, который умеет это делать сам.
> $i=0;
> while(true)
Тут цикл for бы лучше подошел. А вообще, отрезать пробелы можно с помощью функции trim().
Функцию makeFirstLetter... нужно значительно укоротить. Там хватит trim + замена первой буквы.
> $res
Тоже плохое название так как ничего не говорит о содержимом.
> preg_replace("/\,/ui","",$text);
Запятую безопаснее заменять на пробел, а не удалять целиком.
> $final=makeFirstletterUppercase($sentence);
> $final.=". ";
> $result.=$final;
Лучше складывать предложения в массив, а в конце склеить его в строку. Будет короче и читабельнее.
Ты можешь установить редактор и печатать код в нем. И даже запускать, если установишь PHP.
>>216135
Может быть проблема с местом. Установщик использует команду:
apt-get install -y lsb-release > /dev/null 2>&1
которая скрывает сообщения об ошибках и не дает возможности понять, в чем проблема.
Ты можешь проверить свободное место с помощью df.
Другой вариант - проблемы с проверкой подписей. там есть сообщения:
W: Failed to fetch http://ppa.launchpad.net/ondrej/php/ubuntu/dists/hirsute/InRelease At least one invalid signature was encountered.
Но так как установщик не пишет реальную причину ошибки, то понять что-то трудно. Может баг в установщике, тогда можно попробовать взять чуть более старую версию.
> где еще может храниться кэш вот отсюда: https://laravel.build/)
Установщик выполняет операции в докер-контейнере, потому надо смотреть мануалы, где докер хранит образы и как их можно почистить.
>>217605
Спасибо, df делал сразу, места на системном диске 2+ гига, на пользовательском - 8+ гигов. Но когда я посмотрел, сколько занимают все мои образы командой docker image ls, то охренел. Возможно, стоит перенести /var/lib/docker на диск с 8 гигами и попробовать снова, но после удаления всех образов на системном диске освободилось аж 4 гига и теперь я сомневаюсь, что хватит моих восьми на пользовательском диске )
C PPA ondrej/php у меня еще пару лет назад проблемы были, когда пытался писать на yii. Это кстати одна из причин, почему сменил убунту на арч.
Короче, пока забил на этот sail, решил установить по-старинке, через composer.
Во, спасибо за ответы! Я уж думал что-то стряслось ну или в крайнем случае вопросы слишком тривиальные для комментариев.
>нужно использовать группировку с помощью круглых скобок
Точно, что-то не подумал про это вообще. Вроде запомнил все эти фичи регулярок, но как что-то конкретное надо сделать, получается недоумение.
https://ideone.com/u6Ulad
По поводу названий переменных и форматирования, я понимаю что в реальных проектах надо по-другому, а тут просто ведь небольшие скрипты, вот и пишу немного коряво. Хотя может лучше сразу привыкнуть.
VS code есть, но там ведь в браузер вывод php файла и надо немного по-другому форматировать, а ideone я так понимаю выводит просто консоль, поэтому в ideone и делаю, чтобы тут запостить результат.
Еще небольшой вопрос, я заметил некоторые стандартные функции принимают по ссылке аргумент, а не которые вроде как по значению. Так вот чтобы много лишних переменных не плодить, но чтобы и результат был нужный, надо стараться одну перезаписывать все время в любом случае? Типа
$someArray=array_reverse($someArray);
$someArray=sort($someArray);
По идее IDE должна подсказывать параметры.
Надо с самого начала приучаться нормально оформлять код. В VS Code есть команда format (Ctrl + Shift + P -> Format document). Ты можешь писать код в VS Code и копипастить его в ideone. Или, что лучше, настроить VS Code для запуска кода в консоли по горячей клавише. Если что, тут можно почитать про запуск PHP из консоли (не в VS Code, а вообще): https://github.com/codedokode/pasta/blob/master/soft/cli.md
Переменные тоже надо называть нормально. Вот я смотрю твой код, вижу там $k и как я должен догадаться, что это такое? Ты это держишь сейчас в голове, но если ты через пару месяцев откроешь свой же код, ты тоже не вспомнишь. Подумай о тех, кому придется читать твой код.
Также, у твоей программы неправильно сделан вывод. Если правильный номер не прошел проверку, она пишет точно такое же сообщение, что и для неправильного номера. И глядя на результат, непонятно: правильно отработала программа или нет. О таких вещах тоже надо приучаться думать, удобно ли воспринимать результат работы твоей программы? Можно ли с первого взгляда понять, правильно ли она работает?
Вместо "$x ошибок" лучше писать "ошибки: $x". Тогда не будет неправильного текста вроде "2 ошибок". Или можно сделать функцию, которая будет выбирать корректную форму слова.
Код должен быть с одной стороны читабельным, как будто это текст на английском, но с другой стороны коротким и лаконичным. То есть не стоит доходить до фанатизма и делать названия по 30 символов. Например, $correctNumbers допустимо сократить до $correct или $valid.
Также, хорошо будет избегать создания лишних переменных, например в такой ситуации:
$regexp = "/abc/u";
...preg_match($regexp, ...);
можно обойтись без переменной и вставить регулярку прямо в выражение. Переменную, однако, тут допустимо использовать, если ее название несет какую-то важную и неочевидную информацию, например:
$fixSpaceAfterCommaRe = "/.../u";
Хотя эту информацию можно написать и в комментарии. В твоей программе регулярка используется дважды, потому ее лучше оставить в переменной.
Не стоит создавать кучу переменных в такой ситуации:
$number1 = trim($number);
$number2 = preg_replace)(..., $number1);
$number3 = mb_strtoupper($number2);
Одним из решений тут было бы отказаться от ненужных промежуточных переменных и написать все одним выражением (с отступами и форматированием!):
$number = mb_strtoupper(preg_replace(..., trim($number)));
Но когда функций больше 2-3, из-за обилия скобок становится непонятно, кто кого вызывает и в каком порядке. Эту строку по идее надо читать справа налево, и человеку это неудобно делать. Потому приходится записывать это в несколько строк с присваиванием обратно в ту же переменную.
> Еще небольшой вопрос, я заметил некоторые стандартные функции принимают по ссылке аргумент, а не которые вроде как по значению.
Передача аргумента по ссылке - это в общем костыль, унаследованный из языка Си. Правильно делать так: функция принимает аргументы в скобках, и возвращает произвольное количество значений через return:
[$a, $b, $c] = func($x, $y, $z);
Сразу видно, что на входе, а что на выходе (в отличие от передачи по ссылке). Но язык Си не умел возвращать несколько значений, и там придумали передачу по ссылке (а также это позволяло оптимизировать код в некоторых случаях). Все это было очень давно и сейчас неактуально. Единственный случай, когда нужна передача по ссылке - это когда у тебя очень огромный массив (миллионы значений), ты хочешь чтобы функция что-то с ним сделала и при этом не делались промежуточные копии массива. Опять же, по идее интерпретатор должен сам все это оптимизировать, но пока он такое не умеет и приходится лепить костыли.
Что касается функции sort, то ее результат не используют и пишут просто
sort($array);
> По идее IDE должна подсказывать параметры.
Полагаться на IDE тоже плохо. По идее, код должен быть понятен без IDE. Например, если у функции много аргументов (> 3-4), то лишние аргументы должны быть с именами, так как вряд ли кто-то помнит наизусть, какой 5-й параметр у preg_replace:
$x = preg_replace("...", "...", $str, count: 10);
Именованные аргументы появились в PHP8.0. Используй их, если в твоей функции более 3-4 аргументов или если у тебя много необязательных аргументов.
Надо с самого начала приучаться нормально оформлять код. В VS Code есть команда format (Ctrl + Shift + P -> Format document). Ты можешь писать код в VS Code и копипастить его в ideone. Или, что лучше, настроить VS Code для запуска кода в консоли по горячей клавише. Если что, тут можно почитать про запуск PHP из консоли (не в VS Code, а вообще): https://github.com/codedokode/pasta/blob/master/soft/cli.md
Переменные тоже надо называть нормально. Вот я смотрю твой код, вижу там $k и как я должен догадаться, что это такое? Ты это держишь сейчас в голове, но если ты через пару месяцев откроешь свой же код, ты тоже не вспомнишь. Подумай о тех, кому придется читать твой код.
Также, у твоей программы неправильно сделан вывод. Если правильный номер не прошел проверку, она пишет точно такое же сообщение, что и для неправильного номера. И глядя на результат, непонятно: правильно отработала программа или нет. О таких вещах тоже надо приучаться думать, удобно ли воспринимать результат работы твоей программы? Можно ли с первого взгляда понять, правильно ли она работает?
Вместо "$x ошибок" лучше писать "ошибки: $x". Тогда не будет неправильного текста вроде "2 ошибок". Или можно сделать функцию, которая будет выбирать корректную форму слова.
Код должен быть с одной стороны читабельным, как будто это текст на английском, но с другой стороны коротким и лаконичным. То есть не стоит доходить до фанатизма и делать названия по 30 символов. Например, $correctNumbers допустимо сократить до $correct или $valid.
Также, хорошо будет избегать создания лишних переменных, например в такой ситуации:
$regexp = "/abc/u";
...preg_match($regexp, ...);
можно обойтись без переменной и вставить регулярку прямо в выражение. Переменную, однако, тут допустимо использовать, если ее название несет какую-то важную и неочевидную информацию, например:
$fixSpaceAfterCommaRe = "/.../u";
Хотя эту информацию можно написать и в комментарии. В твоей программе регулярка используется дважды, потому ее лучше оставить в переменной.
Не стоит создавать кучу переменных в такой ситуации:
$number1 = trim($number);
$number2 = preg_replace)(..., $number1);
$number3 = mb_strtoupper($number2);
Одним из решений тут было бы отказаться от ненужных промежуточных переменных и написать все одним выражением (с отступами и форматированием!):
$number = mb_strtoupper(preg_replace(..., trim($number)));
Но когда функций больше 2-3, из-за обилия скобок становится непонятно, кто кого вызывает и в каком порядке. Эту строку по идее надо читать справа налево, и человеку это неудобно делать. Потому приходится записывать это в несколько строк с присваиванием обратно в ту же переменную.
> Еще небольшой вопрос, я заметил некоторые стандартные функции принимают по ссылке аргумент, а не которые вроде как по значению.
Передача аргумента по ссылке - это в общем костыль, унаследованный из языка Си. Правильно делать так: функция принимает аргументы в скобках, и возвращает произвольное количество значений через return:
[$a, $b, $c] = func($x, $y, $z);
Сразу видно, что на входе, а что на выходе (в отличие от передачи по ссылке). Но язык Си не умел возвращать несколько значений, и там придумали передачу по ссылке (а также это позволяло оптимизировать код в некоторых случаях). Все это было очень давно и сейчас неактуально. Единственный случай, когда нужна передача по ссылке - это когда у тебя очень огромный массив (миллионы значений), ты хочешь чтобы функция что-то с ним сделала и при этом не делались промежуточные копии массива. Опять же, по идее интерпретатор должен сам все это оптимизировать, но пока он такое не умеет и приходится лепить костыли.
Что касается функции sort, то ее результат не используют и пишут просто
sort($array);
> По идее IDE должна подсказывать параметры.
Полагаться на IDE тоже плохо. По идее, код должен быть понятен без IDE. Например, если у функции много аргументов (> 3-4), то лишние аргументы должны быть с именами, так как вряд ли кто-то помнит наизусть, какой 5-й параметр у preg_replace:
$x = preg_replace("...", "...", $str, count: 10);
Именованные аргументы появились в PHP8.0. Используй их, если в твоей функции более 3-4 аргументов или если у тебя много необязательных аргументов.
Понял, в следующий раз по-человечески постараюсь отформатировать и проименовать все.
>Что касается функции sort, то ее результат не используют и пишут просто sort($array);
Ну вот я как раз делал про Йоду ту небольшую задачку и не переворачивались слова, я смотрю array_reverse в php мануале, а там
>array_reverse(array $array, bool $preserve_keys = false): array
И я понял, что нужно в новую переменную результат помещать, т.к. передается по значению. Потом еще другие некоторые функции глянул и заметил, что sort передает по ссылке
>sort(array &$array, int $flags = SORT_REGULAR): bool
И результат тем самым не теряется, если никуда его не присваивать.
Это есть смысл делать, если эти сервисы как-то мешают разработке (например: выдают ошибки или тормозят). Если они не мешают, то особой необходимости их подменять нет.
Плюс, если ты поставишь заглушку, а кому-то понадобится протестировать взаимодействие с этими сервисами, то что делать?
Впрочем, если ты пишешь автоматизированные тесты, то тогда надо изолироваться от внешних сервисов.
Не понял прикола про "жадный" алгоритм, у меня вроде работает просто так.
Тут выше про математику и троллинг писал кто-то, сколько реально приходится решать новые алгоритмические задачи на практике и сколько делать типовые вещи с использованием готовых подходов?
есть странице, на нем видео на фоне в блуре, 480p, 50 секунд, 10 мегабайт, mp4, звука нет.
и вот странице виснет, вижу что фпс падает. но ничего сложного кроме видео она не делает.
на мобилках - збс. на винде - збс. даже не на все линуксах виснет, но вот на некоторых прям дропы до 15-20 фпс.
я пытался накомпресировать как-то иначе. и ниче.
Так шли кабанчика нахуй и ищи другого
Вообще, mp4 это лишь формат контейнера, который ничего не говорит об использованном формате видео и сложности его воспроизведения. Воспроизведение видео не бесплатное: оно требует большого объема вычислений.
Также, я не понял про "блур". Ты имеешь в виду, что видео уже размытое, или ты берешь четкое видео и размываешь его средствами CSS? Тогда на процессор ложится дополнительная нагрузка по обработке десятков миллионов пикселей в секунду. Видео должно быть изначально размытым; тогда оно и сжиматься будет лучше. А то ты пересылаешь ненужные данные.
Но тут надо не гадать, а открыть инструменты браузера и сделать профайлинг. И посмотреть, на что расходуется время и какой получается fps.
Ну и по моему, вставлять видео на фон в общем плохая идея.
Поменяй число сотенных купюр на ноль и в твоей программе вываливается ошибка: https://ideone.com/XhnzJE
Можешь поломать голову и попробовать это исправить. Когда надоест ломать голову - почитай разбор этой задачи: https://github.com/codedokode/pasta/blob/master/algorithm/atm.md
Также, в твоем коде не хватает пробелов, например, пробелы после запятой. Научись оформлять код по рекомендациям PSR.
Ошибка потому что не хватает купюр. 5000+500+3х200=6100 только, а надо 6600. Или я задачу не так понял?
А, глянул статью на гитхабе, вижу теперь эти проблемные ситуации.
Тут наверное какое-то простое решение, но я его не смог к сожалению придумать, только брутфорс, только хардкор. Я так не вывезу в реальных проектах.
Кстати в процессе у меня возник вопрос, как пройтись по ассоциативному массиву циклом for? Или он не предназначен для этого в принципе?
Посоветуйте что-нибудь для вот таких целей:
1.Вывод ошибок в отдельное место (консоль браузера, отдельный монитор или вкладка или еще что, главное чтобы вместе с запросом, просто не на странице, хотя бы во фрейме если в 2021 они еще работают).
2.Давно у кого-то на youtube видел на пятой пыхе цветной вывод ошибок и var_dump, где такое найти?
3.Помимо ошибок я хочу выводить свой отладочный вывод в то же место.
Чтобы был работающий проект и рядом окно с текстом о том что происходит.
Неужели это никому не интересно?
Помохите, анончики, как установить ебаный мбстринг? Комментарий в .ini убрал, сам файл с дополнением есть, сервак перезагрузил, хули ему ещё надо-то?!
Выполни php-файл с таким содержанием:
<?php
phpinfo();
Он выведет, какие конкретно ini-файлы использовались. Изменения надо вносить в них.
Также, ты точно тот ini-файл правил? Там есть образцы ini-файлов вроде php.ini-production, их править бесполезно.
Блин, нашел ошибку, невнимателен.
Кто юзал xdebug? Как заставить его писать вывод в отдельное место, но не файл?
Чтобы только к текущему запросу например в отдельном окне писал ошибки и то что я захочу.
php вроде не дураки делают, так что наверное не сильно
главное чтобы сжв и копирасты не добрались
Ошибки и предупреждения можно выводить в отдельном окне, и для этого даже не требуется phpdebug, хватит стандартных возможностей PHP.
PHP может писать сообщения в файл. Путь к файлу определяется параметром error_log в php.ini ( https://www.php.net/manual/en/errorfunc.configuration.php#ini.error-log ). Если этот параметр пуст, то поведение отличается в зависимости от используемого веб-сервера:
- если PHP запущен из-под Апача, то сообщения передаются в Апач и тот пишет их в файл, указанный в настройках Апача
- если ты используешь встроенный в PHP веб-сервер, запускаемый из консоли, то сообщения пишутся в эту же консоль
Соответственно, тут два варианта:
- запускать встроенный в PHP сервер вместо Апача и тогда ошибки будут отображаться в консоли, где он запущен
- использовать Апач. Тогда ошибки пишутся в файл, и тебе нужно лишь запустить программу, которая будет отображать их.
Под Линуксом отображение данных из файла в реальном времени делается командой tail -f /var/error.log. Под Windows ты можешь использовать команду Powershell или искать другие варианты, которые описаны тут: https://stackoverflow.com/questions/36430524/is-there-an-equivalent-of-tail-f-on-windows
Еще, как вариант, ты можешь сам написать программу чтения лога на PHP.
Это же звучит как бред, не. Я могу просто в процессе запроса мотнуть его по кругу, сделав запрос к чему угодно и поменяв конечный ответ - это же и есть динамика.
Я знаю что там есть конкретные прям отличия, но меня интересует какого лешего упоминают про динамичный контент, как будто веб серв не может его подавать( в общем-то он это и делает в 99% случаев)
У меня есть урок про интерфейсы: https://github.com/codedokode/pasta/blob/master/php/interfaces.md
Если кратко, то интерфейсы нужны, когда у тебя есть несколько разных классов, которые умеют делать одну и ту же вещь. Например, у тебя есть прием платежей через разные платежные системы. За каждую систему отвечает свой класс. Но они все реализуют один и тот же интерфейс PaymentInterface с методом "выставить счет" (createInvoice()). И тогда код, который принимает на вход объект PaymentInterface, может работать с любой платежной системой.
Или когда у тебя один класс, но ты хочешь, чтобы его можно было позже заменить на другой. Например, тебе надо делать запросы к другим сайтам. Ты можешь сделать класс CurlHttpClient, и прописать в тайп-хинты этот класс. Но тогда функции будут принимать только объект этого класса. А если ты создаешь интерфейс HttpClientInterface и пропишешь в тайп-хинты его, то можно будет передать любой объект, реализующий этот интерфейс. Например, класс-заглушку, который не делает никаких запросов, а отдает заранее подготовленный ответ.
А что ты знаешь об обработчиках ошибках типа как в laravel и symphony?
Хочу с минимумом ебли направить все что выходит на странице в отдельную вкладку или окно или консоль браузера или хотя бы скрываемый div.
Чтобы вообще ничего не протекало в шаблон.
Знаю, что можно отключить, но мне удобно когда я вижу что все отработало как задумано.
Например, здесь под веб-сервером имеется в виду "веб-сервер, настроенный на отдачу статических файлов из папки".
>>220685
Ты можешь писать в лог ошибок с помощью функции error_log().
Также, ты можешь использовать навороченную библиотеку-логгер вроде Monolog, там вообще можно перенаправлять сообщения как угодно и куда угодно.
>>220380
> Кстати в процессе у меня возник вопрос, как пройтись по ассоциативному массиву циклом for?
Никак. Надо либо использовать foreach, либо получить массив ключей с помощью array_keys и пройтись циклом по нему.
> foreach($strings as $key => $str){
>$maxLength = max($maxLength, mb_strlen($str));
Тут можно использовать функцию array_map и избавиться от цикла.
> foreach($arr as $value)
> { echo $value." | ";}
Тут нужно использовать implode вместо цикла.
По моему, так лога в консоли более чем достаточно. Но если тебе зачем-то нужно выводить сообщения в консоль браузера, то можно использовать FirePHP: http://www.firephp.org/
Ты правильно заметил, что ничего не должно "протекать" в шаблон. Пользователи не должны видеть сообщения об ошибках, которые могут содержать важную информацию об устройстве сайта.
Обычно делают так: на продакшене вывод ошибок отключают и они пишутся только в лог. На машине разработчика включают вывод ошибок и смотрят их либо на экране, либо в консоли.
реально ли написать свой обработчик чтобы он все писал в переменную и потом ее слать как скрытую часть страницы или js, который напишет в консоль?
1280x720, 0:38
Это мне каждый раз создавать файл в гите и ручками копипастить содержимое примера?
Уже нашел. Путь выстраивается в зависимости от исполняемого(!) скрипта, это я не про тот, который через точку. Видимо мудрейшим из мира php ,было невдомек, что задачи бывают сложнее чем домашнюю страничку сверстать.
>Видимо мудрейшим из мира php ,было невдомек, что задачи бывают сложнее чем домашнюю страничку сверстать.
Ну это вкусовщина, мне неудобно тоже, но не сказать что прям проблема.
Так-то он довольно толковый, мне доставило.
>>221483
>Что ты делаешь и зачем тебе пути к файлам, если сейчас используется автолоад через psr-4?
автолоад только для классов емнип, никто же не запрещает выносить в отдельные файлы просто куски кода
print_r это не заменитель var_dump и он не печатает bool.
как можно получить вывод var_dump в переменную?
Тебе написали как раз, что делать, что бы ручками не работать.
Laravel какой нибудь?
С CI гита знаком? Экшены как ставить знаешь? Makefile вкурсе что такое?
Вот шаблон, бери, пользуйся. Программист должен уметь автоматизировать то, что обязано быть автоматизировано, если ты делаешь руками что то, больше одного раза, это считай триггер.
>>221591
Что из себя представляет вывод var_dump? Ответь на этот вопрос и получишь ответ.
>должен уметь
Я?? поститесамисмешное.жпеге
Файл который исполняет команды, интересно, пойду почитаю. Спасибо за подсказку.
Ты должен использовать абсолютные пути. То есть писать require __DIR__ . './index.php' или require '/var/site/index.php';
Если ты пишешь require 'index.php' то это не значит "искать в той же папке что и текущий файл". Кто тебе такое сказал? Это значит "искать в текущей директории процесса", а текущая директория может быть какой угодно (её можно узнать через getcwd() и задать через chdir()). Такой код никогда не будет работать надежно, если только ты не задашь текущую директорию через chdir(). но лучше и проще использовать абсолютные пути.
Дополню еще. Когда ты пишешь require 'index.php', файл может искаться не только в "текущей директории" (текущей директории процесса!, а не той, где расположен вызывающий файл), но еще в include_path. Эта фича по задумке работает таким образом:
- ты выделяешь папку для бибиотек, например /usr/lib/php/
- ты прописываешь ее в include_path
- после этого ты иклюдишь файл через require 'file.php' и он ищется в папке для библиотек
То есть, это явно не то, что тебе нужно. Тебе нужны абсолютные пути. Правила поиска файла без абсолютно пути описаны в мануале https://www.php.net/manual/ru/function.include.php . Если ты будешь читать мануал, имей в виду что "текущая директория" там значит "текущая директория процесса".
Мы не можем коммитить .env в гит, так как настройки у каждого разработчика разные. Потому он в игноре. А .env.example не должен быть в гитигноре, это образец файла, из которого ты делаешь свой .env.
>>221486
Никто не запрещает, но в современных проектах обычно нет кода на верхнем уровне - код только внутри функций или классов и потому нет необходимости что-то инклудить.
>>221591
Есть var_export - он не подойдет? Также, есть json_encode.
Ну обосрешься знатно, потом просто добавят тебя в чс все эйчарки в айти или как минимум в пхп, если прознают. Даже если разберешься, то часто чекают по антиплагиату, твой это код или нет. Правда в самых ущербных типа рога и копыта не делают так, потому что им на такое похуй в целом, но в более менее адекватных уже сами хрюши чекают код на плагиат, только после этого твоё дело двигается дальше.
В общем, дело твоё. Тут ведь еще зависит от того, насколько ты сейчас способен выполнять ИРЛ задачи. Если ты ни одного проекта не сделал, то потом даже если пройдешь собес, то на самой работе обосрешься и вылетишь с треском через неделю/месяц. У нас был такой пчел, напиздел в резюме, сумел пройти собес каким-то хуем, ну и зафейлил пару задач, потом пришло МНЕ допиливать за ним вечером после работы блять. Разумеется его сразу уволили, когда узнали, что они ничего не может сделать. Но думаю собес он прошел только из-за своего ссаного диплома. Хз.
Кароче, я считаю, что если не сделал ни один проджект хотя бы самый всратый САМОСТОЯТЕЛЬНО, то лучше все-таки сделать.
Большое спасибо, теперь понятно.
4 пет проекта на гите два из них на Laravel, ссу делать даже резюме.
ООП знаю поверхностно, отличу абстрактный класс от интерфейса, знаю парочку простых шаблонов типа стратегии, композциции, dto, di, осторожен с наследованием, отличу self от static.
SQL ну такое, JOIN через JOIN напишу конечно, но что то супероптимизированное нет, конечно на стороне кода всю базу в цикле не перебираю, в коде только минимальная выборка коллекции, остальное на стороне базы, это мое правило.
Про нормализацию знаю, со связями тоже вроде порядок.
Знание гита "уверенный пользователь", не пушу в мейн, мержу после апрува CI(своих же тестов и линтера, лол).
Виртуализация на данный момент только Vagrant, с Dockeroм пока не подружился.
Но есть и очень серьезные минусы, например мне абсолютно не известен html/ccs, для проектов тупо копипастил с доки бутстрапа так как мне надо было, подглядывая в примеры из интернетов. Весь фронт для меня как темный лес, марджин лишает дара речи, а паддинг заставляет трястись. Что же касается пыхи, тут трудности с рекурсией, не дается она мне, я ее ненавижу, я тупой для нее слишком видимо, смирился.
В принципе написать простейшую Api не вижу проблем, но я уверен, на собеседовании на просьбу перевернуть строку просто встану и уйду молча, а дома расплачусь в подушку.
Думаю стоит, желательно что бы проект был напрямую связан с вебом, работой с запросами, ответами, базой, сессиями, куками, лучше с ООП. Я вот сразу за фреймворки взялся и теперь некомфортно, многое кажется магией.
>тут трудности с рекурсией, не дается она мне
Та же фигня, ментальный блок просто. Весь день пытался сделать задачу про поиск пути из шапочного учебника, ничего не выходит.
https://ideone.com/I24WUd
Почему бы тебе не освоить HTML/CSS? CSS во многом логичный и в нем есть определенные правила. Просто надо их изучать, а не пытаться по-быстрому накопипастить код откуда-то или наугад подбирать значения.
>>222470
Если у вас трудности с рекурсией, может решите пару задачек на нее? Простая и сложная.
1) Дано математическое выражение в виде массива. Нужно вычислить его значение.
Вот формат массива: массив, представляющий выражение, содержит несколько элементов, где первый элемент это знак операции (+, -, *, /, ** - возведение в степень), а оставшиеся - операнды (слагаемые, множители и тд). При этом операнды тоже могут быть массивами-выражениями.
Например, вот как представляется выражение 2 + 3 + 4:
['+', 2, 3, 4]
Вот выражение 5 - 4 - 3:
['-', 5, 4, 3]
А вот выражение с вложенностью: (2 + 3) / (4 + 5):
['/',
['+', 2, 3],
['+', 4, 5]
]
Здесь операндами операции деления являются массивы-суммы. Благодаря вложенности любое математическое выражение можно представить в виде такого "дерева" из массивов. "Деревом" эта структура называется, потому что у нее есть "корень" - главный массив, в котором содержатся "ветки" - вложенные массивы.
Возведение в степень надо вычислять справа налево, то есть
['**', 2, 3, 4] значит "2 ** (3 ** 4)".
Твоя функция принимает на вход массив и должна вернуть число - результат вычисления выражения.
>>222470
Если у вас трудности с рекурсией, может решите пару задачек на нее? Простая и сложная.
1) Дано математическое выражение в виде массива. Нужно вычислить его значение.
Вот формат массива: массив, представляющий выражение, содержит несколько элементов, где первый элемент это знак операции (+, -, *, /, ** - возведение в степень), а оставшиеся - операнды (слагаемые, множители и тд). При этом операнды тоже могут быть массивами-выражениями.
Например, вот как представляется выражение 2 + 3 + 4:
['+', 2, 3, 4]
Вот выражение 5 - 4 - 3:
['-', 5, 4, 3]
А вот выражение с вложенностью: (2 + 3) / (4 + 5):
['/',
['+', 2, 3],
['+', 4, 5]
]
Здесь операндами операции деления являются массивы-суммы. Благодаря вложенности любое математическое выражение можно представить в виде такого "дерева" из массивов. "Деревом" эта структура называется, потому что у нее есть "корень" - главный массив, в котором содержатся "ветки" - вложенные массивы.
Возведение в степень надо вычислять справа налево, то есть
['**', 2, 3, 4] значит "2 ** (3 ** 4)".
Твоя функция принимает на вход массив и должна вернуть число - результат вычисления выражения.
>>222470
2) довольно сложная задача на рекурсию
Напиши функцию, которая принимает на вход имя файла и маску и проверяет, соответствует ли файла маске или нет.
Формат маски такой:
Знак вопроса ? обозначает "ровно один любой символ"
Звездочка * обозначает "любое число любых символов, в том числе ноль символов"
Любой другой символ обозначает сам себя.
Например:
??? - значит, имя файла состоит ровно из трех любых символов
x??* - имя файла начинается с x, за ней идет 2 или более любых символов
*x* - имя файла состоит минимум из одной буквы и должно содержать букву x
x*y*z - имя файла начинается с x, заканчивается на z и где-то между ними должна быть буква y, все остальные символы любые в любом количестве.
Более каверзный пример:
*xy??z* этой маске соответствует имя "123xy456xy78z9". Здесь в имени содержится две пары xy, и буквам xy в маске соответствует вторая пара (за которой идет 78z9), а не первая.
Несколько звездочек подряд равносильны одной звездочке. Если маска или имя файла пустые, то функция должна вернуть "не соответствует". В именах и масках можно использовать кирилицу.
В функции нельзя использовать регулярные выражения, так как тогда это будет задача не на рекурсию, а на регулярки.
>>222470
2) довольно сложная задача на рекурсию
Напиши функцию, которая принимает на вход имя файла и маску и проверяет, соответствует ли файла маске или нет.
Формат маски такой:
Знак вопроса ? обозначает "ровно один любой символ"
Звездочка * обозначает "любое число любых символов, в том числе ноль символов"
Любой другой символ обозначает сам себя.
Например:
??? - значит, имя файла состоит ровно из трех любых символов
x??* - имя файла начинается с x, за ней идет 2 или более любых символов
*x* - имя файла состоит минимум из одной буквы и должно содержать букву x
x*y*z - имя файла начинается с x, заканчивается на z и где-то между ними должна быть буква y, все остальные символы любые в любом количестве.
Более каверзный пример:
*xy??z* этой маске соответствует имя "123xy456xy78z9". Здесь в имени содержится две пары xy, и буквам xy в маске соответствует вторая пара (за которой идет 78z9), а не первая.
Несколько звездочек подряд равносильны одной звездочке. Если маска или имя файла пустые, то функция должна вернуть "не соответствует". В именах и масках можно использовать кирилицу.
В функции нельзя использовать регулярные выражения, так как тогда это будет задача не на рекурсию, а на регулярки.
Там в примеры масок попали лишние пробелы, не обращайте на них внимания.
>>222484
> $result=array();
Тут можно использовать [] вместо array
> $result['time'] += $time;
Тут ошибка: в массиве нет элемента time, а ты пытаешься к нему что-то прибавить.
> if(isset($result['path'][$target])) break;
Здесь ты перебираешь соседние точки, и если мы в одной из них уже были, прерываешь цикл. Но надо не прерывать цикл, а просто пропускать одну такую точки и продолжать перебирать остальные.
> make1step($paths, $result['path'], $result['time'], $station, $target);
Здесь ошибка: ты вызываешь функцию поиска пути, но не используешь то, что она вернула.
Код перебора точек надо переделать так:
1) Создаем пустой список путей к цели
2) перебираем соседние точки и для каждой:
- если мы в ней были, пропускаем ее
- иначе, вызываем себя, чтобы найти путь к цели через эту точку. Найденный путь добавляем в список возможных путей к цели.
3) После завершения цикла у нас есть список (возможно, пустой, если до цели из текущей точки не дойти) возможных путей до цели. Они различаются длиной - какие-то длиннее, какие-то короче. Мы берем из этого списка кратчайший путь, и возвращаем его. Если список пуст, то возвращаем информацию, что из текущей точки до цели не дойти.
У тебя не хватает создания списка путей и выбора кратчайшего.
Там в примеры масок попали лишние пробелы, не обращайте на них внимания.
>>222484
> $result=array();
Тут можно использовать [] вместо array
> $result['time'] += $time;
Тут ошибка: в массиве нет элемента time, а ты пытаешься к нему что-то прибавить.
> if(isset($result['path'][$target])) break;
Здесь ты перебираешь соседние точки, и если мы в одной из них уже были, прерываешь цикл. Но надо не прерывать цикл, а просто пропускать одну такую точки и продолжать перебирать остальные.
> make1step($paths, $result['path'], $result['time'], $station, $target);
Здесь ошибка: ты вызываешь функцию поиска пути, но не используешь то, что она вернула.
Код перебора точек надо переделать так:
1) Создаем пустой список путей к цели
2) перебираем соседние точки и для каждой:
- если мы в ней были, пропускаем ее
- иначе, вызываем себя, чтобы найти путь к цели через эту точку. Найденный путь добавляем в список возможных путей к цели.
3) После завершения цикла у нас есть список (возможно, пустой, если до цели из текущей точки не дойти) возможных путей до цели. Они различаются длиной - какие-то длиннее, какие-то короче. Мы берем из этого списка кратчайший путь, и возвращаем его. Если список пуст, то возвращаем информацию, что из текущей точки до цели не дойти.
У тебя не хватает создания списка путей и выбора кратчайшего.
До пхп
Python привлекает перспективностью и тем, что это хорошее вложение на будущее.
А PHP тем, что он для мне уже легко даётся и вроде бы он быстрее и производительнее.
Да, это размышления нуба, поэтому и спрошиваю совета.
ЧТО ПОСОВЕТУЕТЕ ВЫБРАТЬ?
>Python привлекает перспективностью и тем, что это хорошее вложение на будущее.
ну смотря в какой области ? AI, BA да, WEB очень сомнительно потому , аннон выбирай с того что ты будешь делать в бедующем
Причем здесь шведский футболист?
>Что же касается пыхи, тут трудности с рекурсией, не дается она мне, я ее ненавижу, я тупой для нее слишком видимо, смирился.
Какой смысл в рекурсии в пхп, у пхп нет tail call оптимизации.
> быстрее и производительнее
На самом деле, сомнительный аргумент. Реальные плюсы РНР:
- он чуть легче в изучении
- отлично живёт на недорогих вирт.хостингах (на пистоне ты будешь вынужден обслуживать виртуалку, либо пользоваться немногочисленными платформами для выполнения пистоновских аппов)
- РНР не зависает
> web проект
для веба в виде веб-сайтов и HTML страниц, однозначно РНР
шпалы! такое только на дваче могут посоветовать
Ты руби ещё не пробовал
Дан массив целых чисел вроде [1, 4, 3, 5, 10, 12, 11]
Надо вывести его, сжав последовательно идущие числа в группы. При этом вывести числа надо в порядке возрастания. Например, для массива выше надо вывести 1, 3-5, 10-12.
Массив может быть пуст, тогда надо вывести пустую строку.
Я думаю аноны знают что есть сайты где этих задачек полно.
Как же я ненавижу это говно
Скорее всего, ты не настроил параметры удаленного репозитория (origin) и потому ветки origin/master нет. Или же ты настроил параметры, но ни разу не делал fetch, и потому ветка origin/master не скачалась к тебе. Кстати, желтенький текст об этом и говорит.
И, кстати, буквы в консоли можно сделать покрупнее, щелкнув на заголовок правой кнопкой мыши.
То есть, проверь:
- что в гите добавлен удаленный репозиторий origin (командой git remote -v )
- если репозиторий есть, проверь, что ты сделал fetch из него
>>224883
Вроде на картинке все в порядке. Ты бы хоть написал, что не так.
Я вот сижу, думаю попробовать установить laravel breeze. Установил. А он взял и удалил(заменив) мои нужные файлы типа рутов. Вот откуда я должен был знать что он поступит так, а не по-другому, например, спросив нужно ли заменить файл, или выбросив ошибку что дескать файлы созданы отменяю загрузку. В репо сказано смотрите в офф доках ларавеля, а в них об это ничего не сказано. Сижу с лицом лягухи. Благо я не потерял лишь один вечер работы, ведь какой я молодец что задумался недавно о необходимости бекапов.
Что вообще у веб програмиста считается за навык, понимание сквозь опыт как работает конкретный стек? Потому что логикой фиг поймешь все эти вещи, сплошной гуглинг и пердолинг.
Еще посоветуйте, если можете, каких-нибудь челленджей для средней макаки. Я запросы отправлять умею, в базы кидать информацию умею. Какой там набор бекенд-джентельмена.
ПС И заодно если знаете то подскажите что можно сделать с реактом прикольного. Я его научился запускать-устанавливать, но не понимаю для чего он нужен. Все взаимодействия с фронендом которые приходят мне на ум спокойно решаются обычным жсом.
> Как учить этот ваш ларавел
Читаем официальную документацию, потом гуглим то, чего нет в документации. Если Гугл выдает ерунду, то открываем и читаем исходный код. В нем всегда можно найти ответ, хотя это может занять некоторое время, и придется порисовать диаграммы на бумаге.
> А он взял и удалил(заменив) мои нужные файлы типа рутов
Я не понял, что такое "рут". Может быть, "роут"? В любом случае, если ты устанавливаешь шаблон проекта, то его надо ставить в пустую папку.
Ну и я не уверен, что хорошая идея пользоваться установщиками, не понимая, как они работают. Было бы лучше разобраться и установить все вручную, а не запускать от администратора непонятные скрипты. То есть, установить нужные пакеты композера, установить нужные утилиты, расширения, библиотеки. А когда ты поймешь, как происходит настройка и установка, можно запускать установщик, который сделает все за тебя.
> Потому что логикой фиг поймешь все эти вещи, сплошной гуглинг и пердолинг.
Логикой понять все можно, просто надо начинать с основ, а не браться сразу за сложное. Постепенно идя от простого к сложному, можно разобраться в чем угодно (по крайней мере в программировании). Ну к примеру, не имеет смысла изучать Докер, если ты не умеешь пользоваться командной строкойв линуксе, bash и не знаешь основные команды. Ты просто ничего не поймешь и напишешь такой же разочарованный пост. Соответственно, если ты используешь какую-то систему, основанную на Докер, то получается сначала хорошо бы изучить основы командной строки, основы линукс (файловые системы/права/сетевые настройки/основные утилиты), потом Докер и только потом использовать эту систему.
Или если ты хочешь пользоваться ООП-фреймворком, то необходимо сначала знать сам ООП, ORM, MVC, паттерны вроде внедрения зависимостей. Если ты будешь их изучать, параллельно читая код фреймворка - будет вообще идеально. Немного информации есть тут: https://github.com/codedokode/pasta/
> Еще посоветуйте, если можете, каких-нибудь челленджей
У нас есть задача сделать сайт для прохождения тестов TestHub ( https://gist.github.com/codedokode/8733007 ). Можешь попробовать ее реализовать, или придумать что-то свое аналогичное по сложности. Это будет по уровню близко к реальным проектам.
> И заодно если знаете то подскажите что можно сделать с реактом прикольного. Я его научился запускать-устанавливать, но не понимаю для чего он нужен.
Если ты не понимаешь, то скорее всего просто в данной задаче он тебе не нужен и избавившись от него, ты упростишь себе работу и ускоришь загрузку сайта. Клиентские фреймворки нужны в тех случаях, когда сайт это не сайт со страницами, а сложное интерактивное приложение, или когда необходимо реализовать поддержку оффлайн-режима работы.
Например:
- редактор электрических схем, который позволяет в браузере составить схему из отдельных компонентов и запустить ее в симуляторе
- табличный процессор вроде Google Spreadsheet
- нотный редактор
- мессенджер вроде Телеграм, работающий в браузере
- приложение для учета съеденных калорий, которое сохраняет данные и рисует графики даже при отсутствии интернета
- приложение для просмотра интересных постов и картинок без перезагрузки страниц, работающее даже при прерывающемся интернете, с поддержкой комментирования, выставления лайков, сохранения в избранное
Такие приложения можно попробовать написать на чистом яваскрипте, но в итоге либо получится лапша с повторяющимся кодом, либо ты изобретешь свой аналог реакта.
Если тебе хочется попробовать применить реакт на практике, то ты можешь попробовать сделать одно из описанных выше приложений, либо нашу задачу на SPA: https://github.com/codedokode/pasta/blob/master/js/spa.md
> Как учить этот ваш ларавел
Читаем официальную документацию, потом гуглим то, чего нет в документации. Если Гугл выдает ерунду, то открываем и читаем исходный код. В нем всегда можно найти ответ, хотя это может занять некоторое время, и придется порисовать диаграммы на бумаге.
> А он взял и удалил(заменив) мои нужные файлы типа рутов
Я не понял, что такое "рут". Может быть, "роут"? В любом случае, если ты устанавливаешь шаблон проекта, то его надо ставить в пустую папку.
Ну и я не уверен, что хорошая идея пользоваться установщиками, не понимая, как они работают. Было бы лучше разобраться и установить все вручную, а не запускать от администратора непонятные скрипты. То есть, установить нужные пакеты композера, установить нужные утилиты, расширения, библиотеки. А когда ты поймешь, как происходит настройка и установка, можно запускать установщик, который сделает все за тебя.
> Потому что логикой фиг поймешь все эти вещи, сплошной гуглинг и пердолинг.
Логикой понять все можно, просто надо начинать с основ, а не браться сразу за сложное. Постепенно идя от простого к сложному, можно разобраться в чем угодно (по крайней мере в программировании). Ну к примеру, не имеет смысла изучать Докер, если ты не умеешь пользоваться командной строкойв линуксе, bash и не знаешь основные команды. Ты просто ничего не поймешь и напишешь такой же разочарованный пост. Соответственно, если ты используешь какую-то систему, основанную на Докер, то получается сначала хорошо бы изучить основы командной строки, основы линукс (файловые системы/права/сетевые настройки/основные утилиты), потом Докер и только потом использовать эту систему.
Или если ты хочешь пользоваться ООП-фреймворком, то необходимо сначала знать сам ООП, ORM, MVC, паттерны вроде внедрения зависимостей. Если ты будешь их изучать, параллельно читая код фреймворка - будет вообще идеально. Немного информации есть тут: https://github.com/codedokode/pasta/
> Еще посоветуйте, если можете, каких-нибудь челленджей
У нас есть задача сделать сайт для прохождения тестов TestHub ( https://gist.github.com/codedokode/8733007 ). Можешь попробовать ее реализовать, или придумать что-то свое аналогичное по сложности. Это будет по уровню близко к реальным проектам.
> И заодно если знаете то подскажите что можно сделать с реактом прикольного. Я его научился запускать-устанавливать, но не понимаю для чего он нужен.
Если ты не понимаешь, то скорее всего просто в данной задаче он тебе не нужен и избавившись от него, ты упростишь себе работу и ускоришь загрузку сайта. Клиентские фреймворки нужны в тех случаях, когда сайт это не сайт со страницами, а сложное интерактивное приложение, или когда необходимо реализовать поддержку оффлайн-режима работы.
Например:
- редактор электрических схем, который позволяет в браузере составить схему из отдельных компонентов и запустить ее в симуляторе
- табличный процессор вроде Google Spreadsheet
- нотный редактор
- мессенджер вроде Телеграм, работающий в браузере
- приложение для учета съеденных калорий, которое сохраняет данные и рисует графики даже при отсутствии интернета
- приложение для просмотра интересных постов и картинок без перезагрузки страниц, работающее даже при прерывающемся интернете, с поддержкой комментирования, выставления лайков, сохранения в избранное
Такие приложения можно попробовать написать на чистом яваскрипте, но в итоге либо получится лапша с повторяющимся кодом, либо ты изобретешь свой аналог реакта.
Если тебе хочется попробовать применить реакт на практике, то ты можешь попробовать сделать одно из описанных выше приложений, либо нашу задачу на SPA: https://github.com/codedokode/pasta/blob/master/js/spa.md
> открываем и читаем исходный код.
Не слишком сложно для новичка? Мне кажется таким только крепкие мидлы занимаются
Если нет, то как обычно поступают?
Это, конечно, плохая идея, так как будет приводить к путанице. Программист видит, что в функцию приходит Post, думает, что это актив-рекорд и начинает писать код. А потом тратит время, чтобы разобраться, почему он не работает.
Человек не робот и не может проверять неймспейс в каждом классе. Потому лучше избегать классов с одинаковыми названиями. И, как я понимаю, даже IDE тут не поможет и не подскажет, что это не тот Post, который нужен.
Далее, даже если ты назовешь классы по-разному, это тоже будет плохая идея. Так как у нас в программе теперь одна сущность представляется несколькими разными классами. И одной функции нужен один класс, а другой - другой.
> Есть смысл делать какой-то общий интерфейс для них?
Это решит проблему с функциями, но приведет к дублированию кода.
Правильно будет иметь один класс для представления одной сущности.
Ты можешь заметить, что тебе не хотелось бы давать сервису доступ к базе данных, а хотелось бы дать им только Post. Это слабое место Active Record - в ней модель и код работы с БД переплетены и не отделяются друг от друга.
Иногда бывает такое, что класс большой и сложный, а нам нужна лишь небольшая его часть и не хотелось бы создавать объект целиком. В такой ситуации можно попробовать сделать DTO, но тогда понадобятся методы для конвертации Post в PostDTO.
Понятненько. Значит придётся как-то конкретизировать классы в зависимости от задачи.
Ну с капчой сразу на хуй
Ты думаешь тут экстрасенсы сидят? Если это laravel экран ошибки на него смахивает, но могу ошибаться, то смотри логи в storage
>начать с основ
Мне коллега с прошлой подработки наоборот говорил "та поъуй сваргань лишь бы работало там потом сам разберешься".
И все равно я не понимаю какие такие основы надо знать чтобы понять что Laravel Breeze без всякого разрешение заменит определенные файлы, если они есть. Некоторые другие установщики, например, все прекрасно спрашивают, выкидывают ошибки и сворачиваются.
Сейчас то я конечно знаю как это работает, но как логикой я должен был допереть до этого?
>тебе не нужен
Да, мне не нужен, но он нужен рыночку, чтобы получить работу)
За задачи спасибо, я из них свое портфолио сварганю.
Ошибка 500 это неизвестная ошибка сервера. Это значит что это ты, а не прога, где-то накосячил. Причина может быть абсолютно любая.
Правильно тебе сказали логи посмотреть.
так бери и смотри в симфони
Копрофил спок.
idn_to_utf8(): INTL_IDNA_VARIANT_2003 is deprecated
Почему сайт на хостинге выдает эту ошибку, а на локальной машине этого нету? Разница в версиях php?
Мимо вебмакака.
И какие альтернативы, где реально будет найти работу стажером или джуном? Думал о GO, но там даже джуны никому не всрались
> Насколько перспективно вкатываться в PHP?
Зависит от тебя, в том числе, это лишь инструмент.
> В будущем не хотелось бы писать всякую парашу
Никто не застравляет
> какие альтернативы, где реально будет найти работу стажером или джуном
Любые. Открываешь вакансии и смотришь.
На каждое поле формы пилить функцию проверки? А как сделать итоговую проверку,типа если хоть одно поле не верно,остановить вход и выбросить сообщение что допустим такоко логина нет
скорее всего
В первом приближении, достаточно одной проверки и одного сообщения об ошибке. Нафиг тебе дать дополнительную инфу непонятно кому, какие у тебя есть логины?
Просто написать логин и пароль неверны?а кодом как выглядеть будет? В допустим есть эти две функции, одна ищет в бд логин, вторая пароль,вызываем функции и логическим оператором проверяем на тру результат?
Почитай какую-нибудь книжку, там такие типовые вещи расписаны, вот например.
<?php // Example 27-7: login.php
require_once 'header.php';
$error = $user = $pass = "";
if (isset($_POST['user']))
{
$user = sanitizeString($_POST['user']);
$pass = sanitizeString($_POST['pass']);
if ($user == "" || $pass == "")
$error = 'Not all fields were entered';
else
{
$result = queryMySQL("SELECT user,pass FROM members
WHERE user='$user' AND pass='$pass'");
if ($result->num_rows == 0)
{
$error = "Invalid login attempt";
}
else
{
$_SESSION['user'] = $user;
$_SESSION['pass'] = $pass;
die("<div class='center'>You are now logged in. Please
<a data-transition='slide' href='members.php?view=$user'>click here</a>
to continue.</div></div></body></html>");
}
}
}
echo <<<_END
<form method='post' action='login.php'>
<div data-role='fieldcontain'>
<label></label>
<span class='error'>$error</span>
</div>
<div data-role='fieldcontain'>
<label></label>
Please enter your details to log in
</div>
<div data-role='fieldcontain'>
<label>Username</label>
<input type='text' maxlength='16' name='user' value='$user'>
</div>
<div data-role='fieldcontain'>
<label>Password</label>
<input type='password' maxlength='16' name='pass' value='$pass'>
</div>
<div data-role='fieldcontain'>
<label></label>
<input data-transition='slide' type='submit' value='Login'>
</div>
</form>
</div>
</body>
</html>
_END;
Почитай какую-нибудь книжку, там такие типовые вещи расписаны, вот например.
<?php // Example 27-7: login.php
require_once 'header.php';
$error = $user = $pass = "";
if (isset($_POST['user']))
{
$user = sanitizeString($_POST['user']);
$pass = sanitizeString($_POST['pass']);
if ($user == "" || $pass == "")
$error = 'Not all fields were entered';
else
{
$result = queryMySQL("SELECT user,pass FROM members
WHERE user='$user' AND pass='$pass'");
if ($result->num_rows == 0)
{
$error = "Invalid login attempt";
}
else
{
$_SESSION['user'] = $user;
$_SESSION['pass'] = $pass;
die("<div class='center'>You are now logged in. Please
<a data-transition='slide' href='members.php?view=$user'>click here</a>
to continue.</div></div></body></html>");
}
}
}
echo <<<_END
<form method='post' action='login.php'>
<div data-role='fieldcontain'>
<label></label>
<span class='error'>$error</span>
</div>
<div data-role='fieldcontain'>
<label></label>
Please enter your details to log in
</div>
<div data-role='fieldcontain'>
<label>Username</label>
<input type='text' maxlength='16' name='user' value='$user'>
</div>
<div data-role='fieldcontain'>
<label>Password</label>
<input type='password' maxlength='16' name='pass' value='$pass'>
</div>
<div data-role='fieldcontain'>
<label></label>
<input data-transition='slide' type='submit' value='Login'>
</div>
</form>
</div>
</body>
</html>
_END;
Походу тредом ошибся. Извиняюсь
>Зависит от тебя, в том числе, это лишь инструмент.
>Никто не застравляет
Я, очевидно, о реальной ситуации на рынке спрашиваю, ИТТ думаю больше видели
Не окажется ли так, что нормальных вакансий на джуна кот наплакал, а 99% будет связано с написанием интернет-магазинов на CMS
Такой вопрос. Что посоветуете (не срача ради, а для решения задачи вопрос) из двух вариантов использовать для бэкенда:
1) React + React Native (под мобильные устройства) + PHP + PostgreSQL
либо
2) React + React Native (под мобильные устройства) + NodeJS + база пока не выбрана.
Есть ли у вас какие-либо советы или мысли? Они не помешают.
Желательный вариант - максимальная производительность и минимальное потребление ресурсов.
Аа всё, дошло наконец.
Если ты хочешь писать на Го, то не забудь что для этого тебе надо будет изучить Си, основы Линукса, основы сетевых сокетов.
>>233068
Это пример плохого кода. Во-первых, пароли надо солить и хешировать, а не хранить в открытом виде. Это описано тут: https://github.com/codedokode/pasta/blob/master/security/password-hashing.md
Во-вторых, переменные плохо подставлять в SQL-запрос напрямую, надо использовать плейсхолдеры и подготовленные запросы, иначе можно получить SQL-иъеккцию. Это описано тут: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
При выводе данные надо экранировать, иначе может получиться уязвимость XSS. Это описано тут: https://github.com/codedokode/pasta/blob/master/security/xss.md
Я советую прочитать перечисленные статьи и исправить код на правильный.
Ты указал неправильные параметры после make:factory. Чтобы увидеть , какие параметры есть у команды, набери:
php artisan make:factory --help
Скорее всего ключ -m не нужен, а нужно что-то другое.
>>234452
И солить.
>>234467
Если тебя интересует максимальная производительность, то надо брать Го или Раст. Если с этим тяжко, то хотя бы Java или C#. И делать бенчмарки.
Не знаю, что посоветовать. У нас есть несколько уроков по этой теме: https://github.com/codedokode/pasta/tree/master/security
Что такое а в if $_POST[...] = a, это птица, это самолёт?
И ключи надо в кавычки заключить $_POST["q1"]
Порт идентифицирует не машину, а программу, запущенную на ней. У разных программ он разный. Если тебя интересует порт веб-сервера, то это обычно 80 для http и 443 для https. Обрати внимание, что на хостингах часто один веб-сервер (с одним и тем же IP и портом) обслуживает множество сайтов.
>>236543
Строки в PHP пишутся в кавычках. И a, и q1 надо заключить в кавычки.
Спасибо за подсказки, медицина тут бессильна правда. После перерыва решил опять попробовать, но все равно ничего не получилось. Не знаю, если постоянно такие задачи придется решать вместо чего-то типового, наверное стоит менять планы о вкате.
>в массиве нет элемента time, а ты пытаешься к нему что-то прибавить
Я думал интерпретатор сам инициализирует нулем, ошибку не выдает, только notice. https://ideone.com/qlvSd5
>Но надо не прерывать цикл, а просто пропускать одну такую точки и продолжать перебирать остальные
Да там вообще бред был у меня написан, надо было не через isset проверять (ключ, которого там нет вообще), а сравнивать напрямую значение. Проблема в том, что без break там похоже бесконечный цикл.
>Fatal error: Allowed memory size of 1610612736 bytes exhausted (tried to allocate 65488 bytes) on line 148
Странно только, что выделить вроде немного пытается памяти-то по сравнению с доступной.
https://ideone.com/Q86SZT
Думаю, что я упускаю внутри цикла создание еще одного промежуточного массива внутри которого массив массивов result, и там уже выбирать из него надо подмассив с наименьшим временем. Я сейчас похоже все подряд записываю в result, поэтому и не работает.
Спасиб, уже сам понял. Но вот у меня постоянно ошибка доступа 403 вылазит, пробовал менять разрешения, файл .htaccess по адресу /.cache/composer выглядит вот так:
RewriteEngine on
RewriteCond %{HTTP_HOST} ^www.mysite\.ru$ [NC]
RewriteRule ^(.*)$ http://mysyte.ru/$1 [R=301,L]
ErrorDocument 403 "Access forbidden / Доступ запрещен"
How Hard is it to Learn WordPress Development?
Time to become an entry-level WordPress developer: 6 months to a year. This is 6-12 months of steady, active learning. The outcome of being an “entry-level developer” is the ability to take on simple WordPress projects with minor twists: “Build a straight-ahead site for my bowling league, and can we have a calendar of our upcoming tournaments?” Time to become a full-fledged WordPress developer: 2 years, plus continual ongoing learning.
Короче, я нагуглил, что джва года надо каждый день ёбстись с вротпрессом, чтоб стать минимальным вротпресс кодером
Назначение миграций - это обновление базы данных у других разработчиков и на продакшене. Миграция может содержать не только DDL запросы (CREATE/ALTER TABLE), но и DML (INSERT/UPDATE/DELETE). Например, если ты добавляешь справочник городов, то тебе понадобится его заполнить, для этого нужны INSERT запросы.
При этом надо понимать, что у разработчиков может быть другое содержимое БД. Например, вместо настоящих пользователей у них могут быть несколько тестовых пользователей. И миграция должна корректно отработать и у них.
По этой причине, если тебе нужно сделать что-то, не связанное с изменением схемы БД, и не нужное другим разработчикам, то лучше сделать для этого отдельный скрипт и запустить на продакшене вручную. Отдельный скрипт удобен еще тем, что его можно в процессе отладки перезапускать много раз, в то время как миграцию нельзя запустить два раза, также у скрипта могут быть дополнительные параметры. Например: какие сущности надо исправить.
Если ты используешь фреймворк вроде Симфони/Ларавель, то можно создать отдельную команду для таких тестовых одноразовых скриптов. Я также советую сделать у команды два режима: тестовый и реальный. В тестовом режиме команда пишет, что она будет делать, но не вносит изменений в БД. В реальном изменения записываются. Это можно реализовать через откат/коммит транзакции. Это позволяет тебе убедиться, что команда отработает верно.
Например, после внесения изменений ты можешь запустить команду второй раз в тестовом режиме и убедиться, что больше изменений не требуется.
Небольшой минус отдельного скрипта - это то, что для миграций можно увидеть историю их выполнения, а когда и кто запускал скрипт - неизвестно.
> ошибку не выдает, только notice
Нотис это и есть ошибка. Правильно написанная программа не выдает ни ошибок, ни нотисов. В такой ситуации, если появится нотис, то ясно, что что-то пошло не так и надо изучить код. А если разрешить нотисы в коде, то нотис, говорящий о реальной ошибке останется незамеченным среди сотен "нормальных" нотисов.
Просто приведу пример: допустим, ты опечатался и вместо
$balance += 1
написал
$bOlance += 1;
Если твоя программа при нормальной работе не выдает нотисы, то эта ошибка сразу станет заметна. Опечатки возникают очень часто при написании программ. По-хорошему, тут надо не нотис выдавать, а аварийно завершать программу, пока она не испортила какие-нибудь важные данные из-за этой опечатки.
Поэтому нельзя полагаться на то, что PHP сам за тебя проинициализирует переменную или массив - это надо делать явно.
> Проблема в том, что без break там похоже бесконечный цикл.
Там бесконечная рекурсия. Вот она:
> function make1step(....)
> foreach($paths[$point] as $station => $values){
> $step = make1step($paths, $result['path'], $result['time'], $station, $target); // <-- рекурсивный вызов
Здесь мы вызываем сами себя. После этого внутри нового вызова мы снова вызываем сами себя. Затем снова. И так пока память не закончится. Ты можешь это увидеть, если поставишь в начало функции make1step вывод значений переменных. Вот результат: https://ideone.com/RgBoBM
Как видишь, он постоянно ходит из одной точки в другую и обратно.
Чтобы бесконечной рекурсии не было, надо проверять до вызова make1step, не были ли мы уже в этой точке (что $station нету в $pathDone).
> $step['path'][count($step['path'])-1]
Это можно записать короче как end($step['path']). end() передвигает внутренний указатель массива (что нам неважно) и возвращает значение последнего элемента.
Ну и повторюсь, каждый раз, когда ты рекурсивно вызываешь make1step, она тебе возвращает путь к цели. Так как ты делаешь вызов в цикле несколько раз, ты получаешь несколько путей. Ты должен собрать их, например, в массив и выбрать самый лучший из них.
> Странно только, что выделить вроде немного пытается памяти-то по сравнению с доступной.
Ну так он выделяет память не огромными кусками, а по мере надобности.
> Думаю, что я упускаю внутри цикла создание еще одного промежуточного массива внутри которого массив массивов result, и там уже выбирать из него надо подмассив с наименьшим временем.
Да. Тут два варианта. Либо создать массив путей и выбирать самый лучший. Либо сделать переменную "лучший путь" и каждый раз сравнивать новый путь с ней. Если новый путь лучше, то записывать его в переменную.
> Не знаю, если постоянно такие задачи придется решать вместо чего-то типового, наверное стоит менять планы о вкате.
Реальные задачи могут быть сложнее. Массивы там могут быть гораздо более сложной структуры, и объем кода будет не 20, а например 2000 строк. Лучше сейчас как следует потренироваться на учебных задачах.
> ошибку не выдает, только notice
Нотис это и есть ошибка. Правильно написанная программа не выдает ни ошибок, ни нотисов. В такой ситуации, если появится нотис, то ясно, что что-то пошло не так и надо изучить код. А если разрешить нотисы в коде, то нотис, говорящий о реальной ошибке останется незамеченным среди сотен "нормальных" нотисов.
Просто приведу пример: допустим, ты опечатался и вместо
$balance += 1
написал
$bOlance += 1;
Если твоя программа при нормальной работе не выдает нотисы, то эта ошибка сразу станет заметна. Опечатки возникают очень часто при написании программ. По-хорошему, тут надо не нотис выдавать, а аварийно завершать программу, пока она не испортила какие-нибудь важные данные из-за этой опечатки.
Поэтому нельзя полагаться на то, что PHP сам за тебя проинициализирует переменную или массив - это надо делать явно.
> Проблема в том, что без break там похоже бесконечный цикл.
Там бесконечная рекурсия. Вот она:
> function make1step(....)
> foreach($paths[$point] as $station => $values){
> $step = make1step($paths, $result['path'], $result['time'], $station, $target); // <-- рекурсивный вызов
Здесь мы вызываем сами себя. После этого внутри нового вызова мы снова вызываем сами себя. Затем снова. И так пока память не закончится. Ты можешь это увидеть, если поставишь в начало функции make1step вывод значений переменных. Вот результат: https://ideone.com/RgBoBM
Как видишь, он постоянно ходит из одной точки в другую и обратно.
Чтобы бесконечной рекурсии не было, надо проверять до вызова make1step, не были ли мы уже в этой точке (что $station нету в $pathDone).
> $step['path'][count($step['path'])-1]
Это можно записать короче как end($step['path']). end() передвигает внутренний указатель массива (что нам неважно) и возвращает значение последнего элемента.
Ну и повторюсь, каждый раз, когда ты рекурсивно вызываешь make1step, она тебе возвращает путь к цели. Так как ты делаешь вызов в цикле несколько раз, ты получаешь несколько путей. Ты должен собрать их, например, в массив и выбрать самый лучший из них.
> Странно только, что выделить вроде немного пытается памяти-то по сравнению с доступной.
Ну так он выделяет память не огромными кусками, а по мере надобности.
> Думаю, что я упускаю внутри цикла создание еще одного промежуточного массива внутри которого массив массивов result, и там уже выбирать из него надо подмассив с наименьшим временем.
Да. Тут два варианта. Либо создать массив путей и выбирать самый лучший. Либо сделать переменную "лучший путь" и каждый раз сравнивать новый путь с ней. Если новый путь лучше, то записывать его в переменную.
> Не знаю, если постоянно такие задачи придется решать вместо чего-то типового, наверное стоит менять планы о вкате.
Реальные задачи могут быть сложнее. Массивы там могут быть гораздо более сложной структуры, и объем кода будет не 20, а например 2000 строк. Лучше сейчас как следует потренироваться на учебных задачах.
Также, я бы тебе после этой задачи советовал порешать задачи на рекурсию, которые я писал выше. Также, ты можешь посмотреть алгоритм Дейкстры для поиска кратчайшего пути, но он проще и не позволит тебе получше изучить рекурсию.
>>237150
Папка /.cache/composer вообще не должна быть доступна снаружи. Она должна располагаться за пределами публичной папки сайта.
Думаю, что твоя ошибка не имеет никакого отношения к htaccess в этой папке.
>>237157
Тебе надо изучить PHP, потом ООП, потом базы данных, только после этого можно браться за вордпресс. Не надо пытаться стать "вордпресс разработчиком", становись PHP разработчиком. Тогда изучение вордпресса не потребует столько времени.
Начал делать задачу ОПа про "ООО Вектор" и чет прилип. Есть что-то промежуточного уровня?
Хочу зарегистрировамтся (((
>Думаю, что твоя ошибка не имеет никакого отношения к htaccess в этой папке.
Оказалось что дело в ссылке в папке public на public_html, просто скопировал все оттуда в public_html и заработало, это нормально?В инструкции было написано что так надо, типа паблик_хтмл ларавел не читает и все держит в своей папке паблик поэтому нужно перенаправление
Чтоу
>ООП
>>237799
>ООП
А как долго учится ООП? Я в книге Зандстры прочитал про Синглтон и Фабричный методы. Примерно понял сами примеры, как работают идеализированные упрощённые для понимания примеры в книжке, но как применять ИРЛ так и не понял. А это джва паттерна. Я слышал их там 24 кажется или сколько? И мне кажется, что я буду изучать ООП до минимального стартового уровня пиздец как долго. Сколько освоение ООП занимает у норм поссонов по времени?
просто пишем свойства потом пишем метод проверки на прааильность символов в форме и метод щаписи в бд,и как все это соединить вместе?
Ты можешь уточнить тут непонятные моменты. Ты также можешь попробовать поискать другие статьи, но учти, что некоторые из них сложные и начинают сыпать понятиями вроде "полиморфизм", "инкапсуляция", "состояние", которые хорошо знать, но после того, как разобрался с основами ООП. Например, статья в Википедии написана максимально нечитабельно, единственный понятный раздел там "недостатки ООП", и такое ощущение, что авторы только его и хотели опубликовать.
>>238141
Нет. Если у тебя есть один класс, то у тебя может быть от 0 до бесконечности объектов этого класса (хотя, если ты не планируешь создавать объекты, то класс становится довольно бесполезен).
Класс это разновидность объекта. Каждый объект относится к какому-то классу. Класс определяет, какие поля (свойства) и методы (функции) есть в объекте.
Возьмем, например, магазин. В нем мы можем сделать класс Товар со свойствами: название, цена. И затем создать несколько объектов этого класса: объект1 (название = "Телевизор Samsung", цена = 20000), объект2 (название = "Холодильник LG", цена = 10000). У этих товаров разные цены и названия, но объединяет их то, что у них есть такие свойства.
Заметь, что объект товара здесь обозначает не конкретную единицу товара (один конкретный телевизор), а лишь его характеристики (сколько он стоит и как называется).
Дальше, допустим мы хотим сделать регистрацию в нашем магазине. Мы делаем для этого класс Пользователь со свойствами: email, хеш пароля, телефон, адрес. И можем создать несколько объектов-пользователей. У них будут разные значения свойств, то общее то, что у них у всех есть и email, и телефон.
То есть, в нашем магазине есть множество объектов, и они могут быть разных классов. У товара есть цена, но нет email, а у пользователя есть email, но нет цены.
Эти паттерны трудно понять, пока ты не столкнешься с ситуацией, когда они тебе понадобятся. Если тебе хочется увидеть, где они применяются, ты можешь попробовать почитать код сложных фреймворков и библиотек вроде Доктрины (там применяются паттерны ORM вроде Identity Map, Unit of Work, Repository) или некотоые компоненты Symfony, например Symfony Forms (там применяются Factory, Builder).
Поначалу ты скорее всего заблудишься, но если ты будешь рисовать схему взаимодействия классов и если твоя IDE умеет переходить к определению метода, то со временем ты разберешься.
Если ты пишешь простой код для себя, то зачастую паттерны тебе не нужны. Они часто нужны в библиотеках и фреймворках. В сложных больших системах со сложной архитектурой. Возьмем, например, фабрику. Это объект, который создает ("порождает") другие объекты. Зачем он нужен? Ведь ты можешь создать объект через new. Это короче читабельнее и лучше.
Но если ты пишешь библиотеку, которой будут пользоваться другие люди, ситуация меняется. Допустим, твоя библиотека создает какие-то объекты. А пользователи хотят, чтобы она создавала их по-другому или вообще создавала объекты написанного ими класса. В этом случае ты можешь вынести создание объектов в фабрику, и тогда пользователь твоей библиотеки может написать свою фабрику, передать в твою библиотеку и она начнет создавать то, что требуется.
Другой пример - стратегия. В своем коде проще и читабельнее будет написать switch. А вот если ты пишешь библиотеку и хочешь сделать часть ее логики заменяемой или расширяемой пользователем, то придется использовать Стратегию. Ну например, ты пишешь библиотеку для расчета налогов с продаж и хочешь, чтобы пользователи могли добавлять свои формулы и условия расчета в нее через написание классов-стратегий.
Соответственно, если ты хочешь разбираться в паттернах, то тебе надо найти примеры кода, где они используются, распознать их и понять, зачем они тут используются вместо более простого кода. Тогда ты можешь считать, что изучил паттерны.
Ну или, если у тебя очень хорошее воображение, то ты можешь сам мысленно догадаться, в какой ситуации они используются.
Если просто заучивать определения, то толку не будет. Типичная ошибка начинающих - они читают про паттерн вроде Стратегии и бегут заменять в коде свитчи на кучу классов.
Синглтон обладает кучей недостатков, портит код и в большинстве случаев вместо него лучше применять внедрение зависимостей.
Эти паттерны трудно понять, пока ты не столкнешься с ситуацией, когда они тебе понадобятся. Если тебе хочется увидеть, где они применяются, ты можешь попробовать почитать код сложных фреймворков и библиотек вроде Доктрины (там применяются паттерны ORM вроде Identity Map, Unit of Work, Repository) или некотоые компоненты Symfony, например Symfony Forms (там применяются Factory, Builder).
Поначалу ты скорее всего заблудишься, но если ты будешь рисовать схему взаимодействия классов и если твоя IDE умеет переходить к определению метода, то со временем ты разберешься.
Если ты пишешь простой код для себя, то зачастую паттерны тебе не нужны. Они часто нужны в библиотеках и фреймворках. В сложных больших системах со сложной архитектурой. Возьмем, например, фабрику. Это объект, который создает ("порождает") другие объекты. Зачем он нужен? Ведь ты можешь создать объект через new. Это короче читабельнее и лучше.
Но если ты пишешь библиотеку, которой будут пользоваться другие люди, ситуация меняется. Допустим, твоя библиотека создает какие-то объекты. А пользователи хотят, чтобы она создавала их по-другому или вообще создавала объекты написанного ими класса. В этом случае ты можешь вынести создание объектов в фабрику, и тогда пользователь твоей библиотеки может написать свою фабрику, передать в твою библиотеку и она начнет создавать то, что требуется.
Другой пример - стратегия. В своем коде проще и читабельнее будет написать switch. А вот если ты пишешь библиотеку и хочешь сделать часть ее логики заменяемой или расширяемой пользователем, то придется использовать Стратегию. Ну например, ты пишешь библиотеку для расчета налогов с продаж и хочешь, чтобы пользователи могли добавлять свои формулы и условия расчета в нее через написание классов-стратегий.
Соответственно, если ты хочешь разбираться в паттернах, то тебе надо найти примеры кода, где они используются, распознать их и понять, зачем они тут используются вместо более простого кода. Тогда ты можешь считать, что изучил паттерны.
Ну или, если у тебя очень хорошее воображение, то ты можешь сам мысленно догадаться, в какой ситуации они используются.
Если просто заучивать определения, то толку не будет. Типичная ошибка начинающих - они читают про паттерн вроде Стратегии и бегут заменять в коде свитчи на кучу классов.
Синглтон обладает кучей недостатков, портит код и в большинстве случаев вместо него лучше применять внедрение зависимостей.
ООП подразумевает разбиение кода на классы, где каждый класс делает что-то одно, у него своя зона ответственности. Если ты возьмешь свой обычный код, где все написано одной длинной стеной, и напишешь перед ним class Registration, то это не ООП.
Давай попробуем разобрать, из чего состоит процесс регистрации и что в нем происходит?
Итак: нам приходят данные из формы (в переменной $_POST). Мы должны их проверить, в случае ошибки - показать форму с заполненными данными и сообщение об ошибке, в случае успеха - создать в БД нового пользователя, и, может быть, послать какое-то письмо (например, для подтверждения email). Также, мы можем сразу залогинить пользователя, чтобы он не вводил свои данные в форму логина повторно.
Если ты плохо знаешь, как работать с формами, то немного есть в этом уроке: https://github.com/codedokode/pasta/blob/master/forms.md
Соответственно, мы можем выделить тут такие процессы и объекты:
- объект: данные из формы. Мы могли бы представить эти данные в виде массива вроде ['email' => ..., 'password' => ...], но так как мы изучаем ООП, то мы представим их в виде объекта RegistrationData с полями email, password и тд.
- процесс: прием данных из формы. Нам нужен код, который читает данные из $_POST и создает и заполняет объект RegistrationData на их основе. Мы можем пойти простым или сложным путем. Простой путь - мы делаем класс RegistrationController (контроллер это термин из MVC, если ты не знаешь, что это, то читай https://github.com/codedokode/pasta/blob/master/arch/mvc.md ) и в нем делаем прием данных для формы регистрации. Если нам потом понадобится сделать еще одну форму, мы напишем аналогичный код для нее заново. И так для каждой новой формы. Сложный путь - мы делаем универсальный класс для приема данных из любой формы - BaseForm. Затем на его основе делаем класс RegistrationForm, который описывает форму регистрации (какие в ней есть поля). И в RegistrationController используем этот класс, чтобы он прочитал данные из POST и создал нам RegistrationData.
- процесс: проверка данных. Опять же, тут можно пойти двумя путями. Простой путь - делаем класс RegistrationFormValidator. Он принимает на вход объект RegistrationData и возвращает список объектов FormError, которые содержат информацию об ошибке: текст ошибки, название поля с ошибкой (одна ошибка - один объект). Если нам понадобится сделать еще одну форму, мы сделаем для нее новый класс Validator. Сложный путь - доработать универсальный класс BaseForm, чтобы в нем можно было указывать правила проверки для полей (каждое правило это отдельный объект, у нас же ООП). Тогда в классе RegistrationForm, который представляет собой описание полей формы, мы добавляем правила проверки и все само проверяется на правильность.
- процесс: создание пользователя в БД. Во-первых, нам нужен класс, который умеет работать с таблицей пользователей. Мы назовем его UserTableGateway (что такое паттерн table data gateway, можно прочесть тут https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md ). У тебя может возникнуть соблазн передать в UserTG объект RegistrationData, но это неправильный подход. Ведь тогда UserTG сможет создавать пользователей только через форму, и нельзя будет создать пользователя без использования формы. Да и не должен класс работы с БД знать о форме регистрации и о регистрации вообще - это не его зона ответственности. Нужен более универсальный подход. Потому мы делаем класс User, который хранит информацию о пользователе. Преобразуем RegistrationData в объект User. И передаем User в UserTG, чтобы тот вставил их в БД. То есть UserTG не важно, откуда мы взяли объект пользователя - из формы или откуда-то еще.
- процесс: отправка письма. Тут все просто: делаем класс Mailer, который умеет отправлять письма. При желании можем сделать объект-письмо MailMessage, который надо заполнить и передать в Mailer для отправки
- процесс: залогинить пользователя (то есть, записать что-то в сессию или выставить куки). Разумеется, для управления залогиненностью мы сделаем отдельный класс: AuthorizationManager. Он будет уметь залогинивать, разлогинивать пользователей и определять, залогинен ли текущий пользователь.
Наконец, нам может понадобиться еще кто-то, кто будет координировать все это: тот, кто проверит данные, вставит пользователя в БД, отправит письмо. Для этого можно сделать класс UserService. Или пойти простым путем и сделать вызовы из RegistrationController.
В общем, вот минимальный набор классов:
RegistrationController - показывает станицу с формой регистрации, разбирает POST-запрос, создает RegistrationData, вызывает все нужные методы других классов.
RegistrationData - содержит введенные в форму данные
User - представляет объект пользователя с информацией о нем, который можно загрузить из БД или вставить в БД. У него те же поля, которые есть в таблице пользователей. Он похож на RegistrationData, тем что у них есть одинаковые поля (вроде email). Но есть и различия: в RegistrationData хранится две копии пароля в открытом виде, а в User хранится лишь хеш пароля. Также, в User могут быть поля, которых нет в форме регистрации, например: права пользователя, аватарка и тд.
RegistartionFormValidator - проверяет данные формы на правильность
UserTableGateway - умеет вставлять пользователей в БД и загружать из нее
Mailer - отправляет письма
AuthorizationManager - умеет залогинивать/разлогинивать пользователей
Попробуй теперь написать код. Если будут вопросы - задавай.
ООП подразумевает разбиение кода на классы, где каждый класс делает что-то одно, у него своя зона ответственности. Если ты возьмешь свой обычный код, где все написано одной длинной стеной, и напишешь перед ним class Registration, то это не ООП.
Давай попробуем разобрать, из чего состоит процесс регистрации и что в нем происходит?
Итак: нам приходят данные из формы (в переменной $_POST). Мы должны их проверить, в случае ошибки - показать форму с заполненными данными и сообщение об ошибке, в случае успеха - создать в БД нового пользователя, и, может быть, послать какое-то письмо (например, для подтверждения email). Также, мы можем сразу залогинить пользователя, чтобы он не вводил свои данные в форму логина повторно.
Если ты плохо знаешь, как работать с формами, то немного есть в этом уроке: https://github.com/codedokode/pasta/blob/master/forms.md
Соответственно, мы можем выделить тут такие процессы и объекты:
- объект: данные из формы. Мы могли бы представить эти данные в виде массива вроде ['email' => ..., 'password' => ...], но так как мы изучаем ООП, то мы представим их в виде объекта RegistrationData с полями email, password и тд.
- процесс: прием данных из формы. Нам нужен код, который читает данные из $_POST и создает и заполняет объект RegistrationData на их основе. Мы можем пойти простым или сложным путем. Простой путь - мы делаем класс RegistrationController (контроллер это термин из MVC, если ты не знаешь, что это, то читай https://github.com/codedokode/pasta/blob/master/arch/mvc.md ) и в нем делаем прием данных для формы регистрации. Если нам потом понадобится сделать еще одну форму, мы напишем аналогичный код для нее заново. И так для каждой новой формы. Сложный путь - мы делаем универсальный класс для приема данных из любой формы - BaseForm. Затем на его основе делаем класс RegistrationForm, который описывает форму регистрации (какие в ней есть поля). И в RegistrationController используем этот класс, чтобы он прочитал данные из POST и создал нам RegistrationData.
- процесс: проверка данных. Опять же, тут можно пойти двумя путями. Простой путь - делаем класс RegistrationFormValidator. Он принимает на вход объект RegistrationData и возвращает список объектов FormError, которые содержат информацию об ошибке: текст ошибки, название поля с ошибкой (одна ошибка - один объект). Если нам понадобится сделать еще одну форму, мы сделаем для нее новый класс Validator. Сложный путь - доработать универсальный класс BaseForm, чтобы в нем можно было указывать правила проверки для полей (каждое правило это отдельный объект, у нас же ООП). Тогда в классе RegistrationForm, который представляет собой описание полей формы, мы добавляем правила проверки и все само проверяется на правильность.
- процесс: создание пользователя в БД. Во-первых, нам нужен класс, который умеет работать с таблицей пользователей. Мы назовем его UserTableGateway (что такое паттерн table data gateway, можно прочесть тут https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md ). У тебя может возникнуть соблазн передать в UserTG объект RegistrationData, но это неправильный подход. Ведь тогда UserTG сможет создавать пользователей только через форму, и нельзя будет создать пользователя без использования формы. Да и не должен класс работы с БД знать о форме регистрации и о регистрации вообще - это не его зона ответственности. Нужен более универсальный подход. Потому мы делаем класс User, который хранит информацию о пользователе. Преобразуем RegistrationData в объект User. И передаем User в UserTG, чтобы тот вставил их в БД. То есть UserTG не важно, откуда мы взяли объект пользователя - из формы или откуда-то еще.
- процесс: отправка письма. Тут все просто: делаем класс Mailer, который умеет отправлять письма. При желании можем сделать объект-письмо MailMessage, который надо заполнить и передать в Mailer для отправки
- процесс: залогинить пользователя (то есть, записать что-то в сессию или выставить куки). Разумеется, для управления залогиненностью мы сделаем отдельный класс: AuthorizationManager. Он будет уметь залогинивать, разлогинивать пользователей и определять, залогинен ли текущий пользователь.
Наконец, нам может понадобиться еще кто-то, кто будет координировать все это: тот, кто проверит данные, вставит пользователя в БД, отправит письмо. Для этого можно сделать класс UserService. Или пойти простым путем и сделать вызовы из RegistrationController.
В общем, вот минимальный набор классов:
RegistrationController - показывает станицу с формой регистрации, разбирает POST-запрос, создает RegistrationData, вызывает все нужные методы других классов.
RegistrationData - содержит введенные в форму данные
User - представляет объект пользователя с информацией о нем, который можно загрузить из БД или вставить в БД. У него те же поля, которые есть в таблице пользователей. Он похож на RegistrationData, тем что у них есть одинаковые поля (вроде email). Но есть и различия: в RegistrationData хранится две копии пароля в открытом виде, а в User хранится лишь хеш пароля. Также, в User могут быть поля, которых нет в форме регистрации, например: права пользователя, аватарка и тд.
RegistartionFormValidator - проверяет данные формы на правильность
UserTableGateway - умеет вставлять пользователей в БД и загружать из нее
Mailer - отправляет письма
AuthorizationManager - умеет залогинивать/разлогинивать пользователей
Попробуй теперь написать код. Если будут вопросы - задавай.
Да, я знаю, что существуют паттерны. Я могу объяснить на собеседовании, что такое синглтон и зачем он нужен. И про солид знаю. И "Чистый код" читал. Но когда пишу реальный код, то быстро в нём вязну. Когда ТЗ меняется в процессе и теперь нужно где-то в потрохах кода добавлять лишнюю проверку, и в зависимости от результата скорректировать работу ниже и выше(!) этого участка. Появляются какие-то магические числа, в параметры функций уходят уже по 6-8 переменных, и так далее. Код становится монструозным и его тяжело "загружать в мозг", чтобы погонять чисто там. Всё чаще приходится писать строчку и смотреть, чего будет. Хорошо - ну ок, пишем следующую. Не получилось? Ну, попробуем тут тип данных изменить, может в этом проблема? А, нет, проверка на ноль. Тоже нет. Так, что там вообще эта хуйня возвращает? Инт, но может и false. Или перехватить сразу эксепшен и стринг выдать... Таааак, падажжи, ёбана...
Поздравляю. Вот ты и добрался до дна пхп. Если ответить на твой вопрос коротко, то НИКАК.
Весь этот дрочь на паттерны, солиды, ддд и прочую поебень от бессилия. На каждом собесе спрашивают про эту хуйню, а когда спрашиваешь как у них успехи с солидом морщат ебало и говорят что стараются, и вообще это не догма надо семь раз отмерять и один раз проебаться. А в коде бардак, знания о котором можно перенять только со стороны - либо в конфлюенс если все более-менее хорошо. А если совсем пизда, то только у автора кода.
Причина в том что в пхп нет инструментов для создания абстракций более чем из одного класса. Нет возможности разделить код на более высоком уровне, на модули например. Сказать: вот эти классы приватные, сюда не смотри. Вот публичная входная точка, вот выходная, остальное тебя ебать не должно. DtoInput -> черный ящик -> DtoOutput, пошел нахуй.
А раз инструментов нет, то должны помочь паттерны. И обязательно нужно называть классы так чтобы было видно что это паттерн. StrategyInterface, AmazingFactory. Нормальный человек пальцем у виска покрутит, а в пхп это норма, других то способов разделения кода нет нихуя.
Отсюда же растет раскладывание кода по папочкам. Своими глазами видел как два чела под сорок лет до хрипоты спорили в какую папочку класс положить - в домен или в инфраструктуру. А какая хуй разница если потом ни там ни там не найдешь его.
И это все еще покрывается тестами. Вайтбокс тестами на моках. Пернул в коде - двадцать тестов отвалилось. Не потому что в коде ошибка, а просто их теперь переписать надо. А без тестов проект не соберется и в прод не попадет. Все на серьезном ебале - безопасность ебать. Только баги по кд от ТП сыпятся. И нахуя эта тысяча тестов с их постоянными false positive нужна хуй его знает.
И так везде. Как только проект набирает определенное количество строк начинается вся эта поебень. Спасения от неё нет и похоже ближайшие лет десять не будет. Переписывай начисто, рефактори до посинения один хуй со временем опять будет так же.
Поздравляю. Вот ты и добрался до дна пхп. Если ответить на твой вопрос коротко, то НИКАК.
Весь этот дрочь на паттерны, солиды, ддд и прочую поебень от бессилия. На каждом собесе спрашивают про эту хуйню, а когда спрашиваешь как у них успехи с солидом морщат ебало и говорят что стараются, и вообще это не догма надо семь раз отмерять и один раз проебаться. А в коде бардак, знания о котором можно перенять только со стороны - либо в конфлюенс если все более-менее хорошо. А если совсем пизда, то только у автора кода.
Причина в том что в пхп нет инструментов для создания абстракций более чем из одного класса. Нет возможности разделить код на более высоком уровне, на модули например. Сказать: вот эти классы приватные, сюда не смотри. Вот публичная входная точка, вот выходная, остальное тебя ебать не должно. DtoInput -> черный ящик -> DtoOutput, пошел нахуй.
А раз инструментов нет, то должны помочь паттерны. И обязательно нужно называть классы так чтобы было видно что это паттерн. StrategyInterface, AmazingFactory. Нормальный человек пальцем у виска покрутит, а в пхп это норма, других то способов разделения кода нет нихуя.
Отсюда же растет раскладывание кода по папочкам. Своими глазами видел как два чела под сорок лет до хрипоты спорили в какую папочку класс положить - в домен или в инфраструктуру. А какая хуй разница если потом ни там ни там не найдешь его.
И это все еще покрывается тестами. Вайтбокс тестами на моках. Пернул в коде - двадцать тестов отвалилось. Не потому что в коде ошибка, а просто их теперь переписать надо. А без тестов проект не соберется и в прод не попадет. Все на серьезном ебале - безопасность ебать. Только баги по кд от ТП сыпятся. И нахуя эта тысяча тестов с их постоянными false positive нужна хуй его знает.
И так везде. Как только проект набирает определенное количество строк начинается вся эта поебень. Спасения от неё нет и похоже ближайшие лет десять не будет. Переписывай начисто, рефактори до посинения один хуй со временем опять будет так же.
>ТЗ меняется в процессе и теперь нужно где-то в потрохах кода добавлять лишнюю проверку
Когда ТЗ меняется "на горячую", то запрашивай больше времени - тебе придётся делать дополнительный рефракторинг уже написанного под новые требования.
>Появляются какие-то магические числа
Все магические числа определяй константами класса к которому они относятся.
>в параметры функций уходят уже по 6-8 переменных
Если переменных уже больше 2-3, то где-то ты проебал создание класса. Скорее всего эта функция хорошо будет работать как метод класса или принимать объект.
>Код становится монструозным и его тяжело "загружать в мозг", чтобы погонять чисто там
Потому, что проёбываешь то самое создание класса и, скорее всего, пишешь процедурно большую часть кода. У тебя мало абстракций, а это именно они облегчают понимание системы.
>>238785
>Причина в том что в пхп нет инструментов для создания абстракций более чем из одного класса. Нет возможности разделить код на более высоком уровне, на модули например
Ты чушь каку-то несёшь. В пхп классы универсальни и модули из них делаются очень легко - только определи нужные интерфесы которые нужны системе.
Так как вопрос довольно абстрактный, без примеров кода, то и ответ будет довольно абстрактный. Надо писать код так, чтобы он был максимально понятен для понимания. Чтобы в нем было трудно случайно что-то сломать.
Попробуй посмотреть на код и подумать, из-за чего он сложный? Почему в нем долго разбираться? Если бы ты для примера написал кусок кода в аналогичном стиле и запостил сюда, мы бы, может быть, могли что-то посоветовать.
Один из приемов - разбивать код на небольшие функции, каждая из которых делает что-то одно, и давать им понятные названия. Ну например, тебе надо проверить, имеет ли право пользователь удалить комментарий. Ты можешь написать код, который проверяет, кто автор комментария, сравнивает с id пользователя, заодно проверяет, не админ ли он. Но правильнее будет сделать тут вызов функции:
if (isGranted($user, Comment::ACTION_DELETE, $comment)) {
...
}
Или так:
if ($commentService->canDelete($user, $comment)) {
...
}
Такой код гораздо короче и его проще прочесть, чем если бы мы вписали проверку прав доступа непосредственно в код.
Такой подход с разбиением на функции хорошо работает и для сложных алгоритмов. Вместо того, чтобы писать стену кода, мы описываем алгоритм как небольшой набор действий. Если твой алгоритм требует 1000 строк кода, то ты вряд ли его сожмешь до 500. Но ты можешь разбить его на функции так, что основная функция будет занимать 20-50 строк кода и логика алгоритма будет понятна без изучения всего кода.
Функции надо стараться писать так, чтобы они принимали данные через аргументы и возвращали результаты через return. Плохо, если функция для своей работы берет данные откуда-то еще (из каких-нибудь статических полей) и вдвойне плохо, если одна функция записывает такое поле, а другая его читает. Так как глядя на код, это трудно увидеть.
Если у тебя появляются массивы сложной структуры, надо либо их упрощать, либо заменять на объекты. Если тебе в функцию приходит массив, то невозможно понять, что он может содержать. В случае с объектом ты легко можешь увидеть, какие у него свойства и методы.
> Появляются какие-то магические числа,
Используй константы вместо магических чисел.
> в параметры функций уходят уже по 6-8 переменных,
Лучшим решением будет отрефакторить такие функции. Если в них приходит так много параметров, это может значить, что функция выполняет не одну задачу, а сразу несколько и ее можно заменить на несколько отдельных функций. Если же это сделать нельзя, то в PHP8 (по моему) появились именованные аргументы, которые могут улучшить ситуацию. Или же, возможно, некоторые аргументы можно сгруппировать в объект.
> Код становится монструозным
Надо разбивать на функции с понятными названиями и логикой.
> Инт, но может и false.
В такой ситуации можно сделать два возвращаемых значения: объект ошибки и результат:
[$error, $result] = someFunction();
Так как вопрос довольно абстрактный, без примеров кода, то и ответ будет довольно абстрактный. Надо писать код так, чтобы он был максимально понятен для понимания. Чтобы в нем было трудно случайно что-то сломать.
Попробуй посмотреть на код и подумать, из-за чего он сложный? Почему в нем долго разбираться? Если бы ты для примера написал кусок кода в аналогичном стиле и запостил сюда, мы бы, может быть, могли что-то посоветовать.
Один из приемов - разбивать код на небольшие функции, каждая из которых делает что-то одно, и давать им понятные названия. Ну например, тебе надо проверить, имеет ли право пользователь удалить комментарий. Ты можешь написать код, который проверяет, кто автор комментария, сравнивает с id пользователя, заодно проверяет, не админ ли он. Но правильнее будет сделать тут вызов функции:
if (isGranted($user, Comment::ACTION_DELETE, $comment)) {
...
}
Или так:
if ($commentService->canDelete($user, $comment)) {
...
}
Такой код гораздо короче и его проще прочесть, чем если бы мы вписали проверку прав доступа непосредственно в код.
Такой подход с разбиением на функции хорошо работает и для сложных алгоритмов. Вместо того, чтобы писать стену кода, мы описываем алгоритм как небольшой набор действий. Если твой алгоритм требует 1000 строк кода, то ты вряд ли его сожмешь до 500. Но ты можешь разбить его на функции так, что основная функция будет занимать 20-50 строк кода и логика алгоритма будет понятна без изучения всего кода.
Функции надо стараться писать так, чтобы они принимали данные через аргументы и возвращали результаты через return. Плохо, если функция для своей работы берет данные откуда-то еще (из каких-нибудь статических полей) и вдвойне плохо, если одна функция записывает такое поле, а другая его читает. Так как глядя на код, это трудно увидеть.
Если у тебя появляются массивы сложной структуры, надо либо их упрощать, либо заменять на объекты. Если тебе в функцию приходит массив, то невозможно понять, что он может содержать. В случае с объектом ты легко можешь увидеть, какие у него свойства и методы.
> Появляются какие-то магические числа,
Используй константы вместо магических чисел.
> в параметры функций уходят уже по 6-8 переменных,
Лучшим решением будет отрефакторить такие функции. Если в них приходит так много параметров, это может значить, что функция выполняет не одну задачу, а сразу несколько и ее можно заменить на несколько отдельных функций. Если же это сделать нельзя, то в PHP8 (по моему) появились именованные аргументы, которые могут улучшить ситуацию. Или же, возможно, некоторые аргументы можно сгруппировать в объект.
> Код становится монструозным
Надо разбивать на функции с понятными названиями и логикой.
> Инт, но может и false.
В такой ситуации можно сделать два возвращаемых значения: объект ошибки и результат:
[$error, $result] = someFunction();
> Пернул в коде - двадцать тестов отвалилось. Не потому что в коде ошибка, а просто их теперь переписать надо.
Значит, проблемы с архитектурой. Тесты нужны. Или ты считаешь, что ты уникальный и пишешь код без единой ошибки?
Ты берешь пример неудачного проекта и делаешь вывод, что все другие проекты такие же.
>В пхп классы универсальни и модули из них делаются очень легко - только определи нужные интерфесы которые нужны системе.
Это ты хуйню несешь. Ты композер пакет хоть раз писал? В пхп нет способа с помощью кода объяснить как им пользоваться. Только с помощью гайда можно понять какой класс что делает. Причем тут нахуй интерфейс, когда любой из твоих пятидесяти классов в либе может использоваться. И чтобы понять какой и как нужно нырнуть в этот унитаз головой. Тебе человек о том и пишет что когнитивно всю эту поеботу осилить нельзя. И я объяснил почему. Язык блядь такой. Многословный, без высокоуровневых абстракций. Все что ты можешь сделать это либо именовать классы как-то по особенному, либо раскладывать по папочкам в особом порядке. Пиздец джуны пошли, уже и читать нихуя не умеют.
>Значит, проблемы с архитектурой. Тесты нужны. Или ты считаешь, что ты уникальный и пишешь код без единой ошибки?
Нужны епта, нужны. А ты их писал? Вот есть у тебя сервис, который использует два других сервиса. Надо тестить. Че ты тут гениального напишешь? Замокаешь интерфейсы, пропишешь: дергается n раз, возвращает такие-то объекты. И напишешь дата провайдер этих объектов. Ты напишешь, Вася напишет, Коля напишет. А потом нужно будет в метод одного из этих сервисов параметр добавить. Или убрать. Даже еще проще - в один из возвращаемых объектов параметр добавить. Вопрос: сколько тестов деграднет после изменения одной единственной строчки? Ответ убил: а хуй его знает. Тебе придется проверить все тесты, в которых эти милые люди упоминали изменяемый сервис. Удачи сделать это даже с использованием шторма. А если это системный сервис, который дохуя где используется инфа стотка что ты какое-нибудь место проебешь. И будет у тебя тестироваться там какая-то поебень вместо актуального поведения. А уж если кто-то додумался контроллеры тестировать, интеграционно, то это вообще пизда. Там мокается даже небо, даже аллах.
>Ты берешь пример неудачного проекта и делаешь вывод, что все другие проекты такие же.
Я этих проектов видел за сотню. Везде одно и тоже, просто с разной степенью пиздеца. Были такие где был условный порядок, но в таких местах спартанская дисциплина, кросс ревью от пяти человек, солюшен ревью и отдел качества. И скорость разработки там крайне низкая (читай нехуй делать). Сейчас у меня вообще прям показательный пример. Было несколько команд, у каждой по пять-шесть пхп проектов. После того как ковид уебал их всех разогнали, а проекты остались. Люди разные, подходы разные. А проблемы у всех одинаковые. Хрупкие тесты, мессиво из классов и интерфейсов и полное отсутствие понимания как это должно работать. Кто-то свое мессиво раскладывал по ДДД как Эванс завещал, у кого-то чистая архетиктура по Мартину - порты ебут адаптеры, а адаптеры твой мозг. Но если в проекте было много конрибьютеров и туда много писали - готовь ебало к фейспалмам. И яне утверждаю что эти люди были какие-то говнокодеры, просто язык вот такой. Наступает момент когда мозг перестает усваивать объем кода и начинается неизбежная деградация.
>В пхп классы универсальни и модули из них делаются очень легко - только определи нужные интерфесы которые нужны системе.
Это ты хуйню несешь. Ты композер пакет хоть раз писал? В пхп нет способа с помощью кода объяснить как им пользоваться. Только с помощью гайда можно понять какой класс что делает. Причем тут нахуй интерфейс, когда любой из твоих пятидесяти классов в либе может использоваться. И чтобы понять какой и как нужно нырнуть в этот унитаз головой. Тебе человек о том и пишет что когнитивно всю эту поеботу осилить нельзя. И я объяснил почему. Язык блядь такой. Многословный, без высокоуровневых абстракций. Все что ты можешь сделать это либо именовать классы как-то по особенному, либо раскладывать по папочкам в особом порядке. Пиздец джуны пошли, уже и читать нихуя не умеют.
>Значит, проблемы с архитектурой. Тесты нужны. Или ты считаешь, что ты уникальный и пишешь код без единой ошибки?
Нужны епта, нужны. А ты их писал? Вот есть у тебя сервис, который использует два других сервиса. Надо тестить. Че ты тут гениального напишешь? Замокаешь интерфейсы, пропишешь: дергается n раз, возвращает такие-то объекты. И напишешь дата провайдер этих объектов. Ты напишешь, Вася напишет, Коля напишет. А потом нужно будет в метод одного из этих сервисов параметр добавить. Или убрать. Даже еще проще - в один из возвращаемых объектов параметр добавить. Вопрос: сколько тестов деграднет после изменения одной единственной строчки? Ответ убил: а хуй его знает. Тебе придется проверить все тесты, в которых эти милые люди упоминали изменяемый сервис. Удачи сделать это даже с использованием шторма. А если это системный сервис, который дохуя где используется инфа стотка что ты какое-нибудь место проебешь. И будет у тебя тестироваться там какая-то поебень вместо актуального поведения. А уж если кто-то додумался контроллеры тестировать, интеграционно, то это вообще пизда. Там мокается даже небо, даже аллах.
>Ты берешь пример неудачного проекта и делаешь вывод, что все другие проекты такие же.
Я этих проектов видел за сотню. Везде одно и тоже, просто с разной степенью пиздеца. Были такие где был условный порядок, но в таких местах спартанская дисциплина, кросс ревью от пяти человек, солюшен ревью и отдел качества. И скорость разработки там крайне низкая (читай нехуй делать). Сейчас у меня вообще прям показательный пример. Было несколько команд, у каждой по пять-шесть пхп проектов. После того как ковид уебал их всех разогнали, а проекты остались. Люди разные, подходы разные. А проблемы у всех одинаковые. Хрупкие тесты, мессиво из классов и интерфейсов и полное отсутствие понимания как это должно работать. Кто-то свое мессиво раскладывал по ДДД как Эванс завещал, у кого-то чистая архетиктура по Мартину - порты ебут адаптеры, а адаптеры твой мозг. Но если в проекте было много конрибьютеров и туда много писали - готовь ебало к фейспалмам. И яне утверждаю что эти люди были какие-то говнокодеры, просто язык вот такой. Наступает момент когда мозг перестает усваивать объем кода и начинается неизбежная деградация.
> В пхп нет способа с помощью кода объяснить как им пользоваться.
Во многих других языках так же - например, Питон, JS.
> Вот есть у тебя сервис, который использует два других сервиса. Надо тестить. Че ты тут гениального напишешь? Замокаешь интерфейсы, пропишешь: дергается n раз, возвращает такие-то объекты.
Это плохой тест, так как ты полагаешься на знание внутренней логики сервиса. Что он вызовет такой-то метод. И ты тестируешь непонятно что. Ты сервис написал, чтобы он вызывал методы или чтобы он сделал что-то полезное? Надо тестировать конечный результат работы сервиса, а не то, сколько раз он для этого вызовет какой-то метод.
Заглушки, конечно, нужны, но без фанатизма. Отправка писем, HTTP-запросы - это все, конечно, мокается. Но не с целью посчитать, сколько раз был вызван метод отправки письма и сколько в него передано аргументов, а с целью убедиться что письмо отправлено и содержит требуемые данные.
То, что ты описал, я бы писать не стал - лучше без тестов, чем с такими тестами. Но еще лучше поломать голову и придумать способ протестировать код нормально. Тестирование это довольно сложная штука и не всегда очевидно, как его делать.
> Даже еще проще - в один из возвращаемых объектов параметр добавить. Вопрос: сколько тестов деграднет после изменения одной единственной строчки?
Ага, то есть ломаются у тебя только тесты, а код не ломается от этих изменений? Опять же, проблема в тестах. Тесты должны использовать тестируемый юнит точно так же, как его будет использовать код. И тогда ломается либо все, либо ничего.
Ну и еще, если ты в тестах копипастишь 100 раз вызов какого-то метода, то может быть стоит применить принцип DRY и сделать, чтобы этих вызовов было не 100, а меньше. Тогда и исправлять меньше придется. Нужны фабрики, которые позволяют без копипасты подготовить окружение для теста.
> А уж если кто-то додумался контроллеры тестировать, интеграционно,
Да, контроллеры это часть интерфейса и их наверно лучше тестировать через E2E тесты, из эмулятора браузера. Если это сложно организовать, то можно просто вызвать контроллер напрямую и убедиться, что он отдает код 200. Это будет лучше, чем ничего, и поможет обнаружить самые заметные ошибки.
То есть, что касается тестов, я не думаю, что тут PHP как-то виноват. Тесты везде пишутся одинаково.
> И яне утверждаю что эти люди были какие-то говнокодеры, просто язык вот такой. Наступает момент когда мозг перестает усваивать объем кода и начинается неизбежная деградация.
Ок, давай пример языка, на котором те же самые люди при таком же объеме проекта и сроках напишут идеально читаемый код.
> В пхп нет способа с помощью кода объяснить как им пользоваться.
Во многих других языках так же - например, Питон, JS.
> Вот есть у тебя сервис, который использует два других сервиса. Надо тестить. Че ты тут гениального напишешь? Замокаешь интерфейсы, пропишешь: дергается n раз, возвращает такие-то объекты.
Это плохой тест, так как ты полагаешься на знание внутренней логики сервиса. Что он вызовет такой-то метод. И ты тестируешь непонятно что. Ты сервис написал, чтобы он вызывал методы или чтобы он сделал что-то полезное? Надо тестировать конечный результат работы сервиса, а не то, сколько раз он для этого вызовет какой-то метод.
Заглушки, конечно, нужны, но без фанатизма. Отправка писем, HTTP-запросы - это все, конечно, мокается. Но не с целью посчитать, сколько раз был вызван метод отправки письма и сколько в него передано аргументов, а с целью убедиться что письмо отправлено и содержит требуемые данные.
То, что ты описал, я бы писать не стал - лучше без тестов, чем с такими тестами. Но еще лучше поломать голову и придумать способ протестировать код нормально. Тестирование это довольно сложная штука и не всегда очевидно, как его делать.
> Даже еще проще - в один из возвращаемых объектов параметр добавить. Вопрос: сколько тестов деграднет после изменения одной единственной строчки?
Ага, то есть ломаются у тебя только тесты, а код не ломается от этих изменений? Опять же, проблема в тестах. Тесты должны использовать тестируемый юнит точно так же, как его будет использовать код. И тогда ломается либо все, либо ничего.
Ну и еще, если ты в тестах копипастишь 100 раз вызов какого-то метода, то может быть стоит применить принцип DRY и сделать, чтобы этих вызовов было не 100, а меньше. Тогда и исправлять меньше придется. Нужны фабрики, которые позволяют без копипасты подготовить окружение для теста.
> А уж если кто-то додумался контроллеры тестировать, интеграционно,
Да, контроллеры это часть интерфейса и их наверно лучше тестировать через E2E тесты, из эмулятора браузера. Если это сложно организовать, то можно просто вызвать контроллер напрямую и убедиться, что он отдает код 200. Это будет лучше, чем ничего, и поможет обнаружить самые заметные ошибки.
То есть, что касается тестов, я не думаю, что тут PHP как-то виноват. Тесты везде пишутся одинаково.
> И яне утверждаю что эти люди были какие-то говнокодеры, просто язык вот такой. Наступает момент когда мозг перестает усваивать объем кода и начинается неизбежная деградация.
Ок, давай пример языка, на котором те же самые люди при таком же объеме проекта и сроках напишут идеально читаемый код.
>Во многих других языках так же - например, Питон, JS.
В JS уже есть понятие модуля, сейчас в тайпскрипте добавляют области видимости для модулей. Когда сделают будет еще один смачный харчек в ебло пхп. Жаль что фронтендеры не понимают какую манну небесную им дали и пишут на тайпскрипте такую поебень что глаз дергается.
>Это плохой тест, так как ты полагаешься на знание внутренней логики сервиса. Бла бла бла... нормально делай - нормально будет.
Никакой конкретики так и не выдавил. Вот тебе конкретный пример: https://3v4l.org/AD5bt простой сервис, наливает воду в чашки. Покрой тестами FillCupsWithWater, ну так примерно как чувствуешь должно быть правильно.
>Если это сложно организовать, то можно просто вызвать контроллер напрямую и убедиться, что он отдает код 200. Это будет лучше, чем ничего, и поможет обнаружить самые заметные ошибки.
Сразу видно что ты такое никогда не писал. Любой логгер где-то по пути может просто уронить к хуям тест когда ломанется наружу из тестового окружения. Придется его замокать. Шины сообщений придется замокать или перевести с реббита на что-то более локальное. Ебаться с доктриной - это подгрузи заранее, это наоборот очисти. Каждый тест будет как праздник с новыми подарками, только в подарках говно. А самое веселое это когда ты поменяешь код, а отвалится чужой тест. Ты его откроешь, а там сетап на два экрана. И ближайшие два часа пройдут незабываемо.
>Ок, давай пример языка, на котором те же самые люди при таком же объеме проекта и сроках напишут идеально читаемый код.
Про идеально читаемый код хуйня конечно, но выдать лучше чем на пхп изи.
TypeScript если писать будут бекендеры. На Go будет не идеальный код, но гораздо короче и понятнее че мна пхп. А чтобы вообще охуеть от зависти и боли в очке просто посмотри как вся эта многословная поебень исчезает в нормальном языке https://www.youtube.com/watch?v=PLFl95c-IiU . Система типов заменяет 90% тестов, никаких ебучих абстрактных фабрик интерфейсов, весь домен умещается на одной странице.
>Во многих других языках так же - например, Питон, JS.
В JS уже есть понятие модуля, сейчас в тайпскрипте добавляют области видимости для модулей. Когда сделают будет еще один смачный харчек в ебло пхп. Жаль что фронтендеры не понимают какую манну небесную им дали и пишут на тайпскрипте такую поебень что глаз дергается.
>Это плохой тест, так как ты полагаешься на знание внутренней логики сервиса. Бла бла бла... нормально делай - нормально будет.
Никакой конкретики так и не выдавил. Вот тебе конкретный пример: https://3v4l.org/AD5bt простой сервис, наливает воду в чашки. Покрой тестами FillCupsWithWater, ну так примерно как чувствуешь должно быть правильно.
>Если это сложно организовать, то можно просто вызвать контроллер напрямую и убедиться, что он отдает код 200. Это будет лучше, чем ничего, и поможет обнаружить самые заметные ошибки.
Сразу видно что ты такое никогда не писал. Любой логгер где-то по пути может просто уронить к хуям тест когда ломанется наружу из тестового окружения. Придется его замокать. Шины сообщений придется замокать или перевести с реббита на что-то более локальное. Ебаться с доктриной - это подгрузи заранее, это наоборот очисти. Каждый тест будет как праздник с новыми подарками, только в подарках говно. А самое веселое это когда ты поменяешь код, а отвалится чужой тест. Ты его откроешь, а там сетап на два экрана. И ближайшие два часа пройдут незабываемо.
>Ок, давай пример языка, на котором те же самые люди при таком же объеме проекта и сроках напишут идеально читаемый код.
Про идеально читаемый код хуйня конечно, но выдать лучше чем на пхп изи.
TypeScript если писать будут бекендеры. На Go будет не идеальный код, но гораздо короче и понятнее че мна пхп. А чтобы вообще охуеть от зависти и боли в очке просто посмотри как вся эта многословная поебень исчезает в нормальном языке https://www.youtube.com/watch?v=PLFl95c-IiU . Система типов заменяет 90% тестов, никаких ебучих абстрактных фабрик интерфейсов, весь домен умещается на одной странице.
В postgres больше свистелок и перделок, некоторые вещи отличаются, но в целом они по использованию одинаковые, а с ORM вообще разницы не почувствуешь.
В JS куча унаследованных проблем и довольно уродливый синтаксис.
> Покрой тестами FillCupsWithWater
Хорошо. Давай посмотрим, что это за сервис и какие к нему предъявляются требования. Ведь тесты пишутся для проверки того, что код соответствует требованиям.
Требования, конечно, лучше всего брать из ТЗ или документации, но так как ТЗ нету, нам придется восстановить их из кода.
- FillCupsWithWater получает (возможно, ограниченный) источник чашек и неограниченный источник воды, описанные интерфейсами
- он должен заполнить все доступные (1), но не более N (2), чашек
- чашки могут быть частично наполнены изначально
- чашки должны заполняться до максимума, но не переполняться (3)
Цифрами я пометил правила, которые мы будем тестировать.
Соответственно, для теста нам понадобится создать 2 вспомогательных класса: источник воды - TestTap и источник чашек - TestCupboard, который принимает в конструктор набор чашек. Мы можем сделать их отдельными классами или можем динамически сконструировать как моки, но в любом случае, мы не будем проверять, какие методы у них вызывались и какое число раз. Это не важно и это не входит в требования к тестируемому классу.
Если мы сделаем их отдельными классами, то мы сможем переиспользовать их в любом количестве тестов.
Соответственно, тесты будут такие:
1) вызываем FillCupsWithWater с N = 2, притом что TestCupboard предоставляет 3 пустых чашки. Проверяем, что нам вернули 2 чашки, что в них больше воды, чем было изначально. Дополнительно можно проверить, что третья чашка не заполнена.
2) вызываем FillCupsWithWater с N = 5 при том, что TestCupboard предоставляет 3 пустых чашки. Проверяем, что нам вернули 3 чашки, что воды в них больше, чем было изначально.
3a) берем чашку емкостью 100 с начальным заполнением 0, и кран, выдающий по 20 воды за раз. Подсовываем их FillCupsWithWater и проверяем, что чашка наполнена на 100.
3b) берем чашку емкостью 100 с начальным наполнением 10, и кран, выдающий 20 воды за раз. Проверяем, что чашка наполнена до уровня 90.
Если присмотреться, то при желании можно увидеть, что не все сценарии продуманы: что, если кран выдает разные порции воды? Что, если чашки могут быть разной емкости и начального наполнения? Что, если мы берем больше воды, чем нужно, и проливаем ее мимо чашки? Покрыть 100% входных данных тестами даже в таком простом коде не получится. Если мы наткнемся на баг, связанный с чашками разного размера или неравномерным источником воды, то, или если в ТЗ на это будет обращено внимание, то мы напишем дополнительные тесты, а пока хватит этого.
Написанные тесты проверяют, что класс соответствует предъявляемым к нему требованиям.
> Придется его замокать
Конечно, придется. Но ты делаешь это один раз, а не в каждом тесте. То же касается очереди сообщений - надо сделать, чтобы сообщения не отправлялись наружу, а немедленно обрабатывались, опять же, один раз для всего проекта.
Да, для каждого сервиса, который лезет куда-то наружу, надо сделать тестовую заглушку.
> На Go будет не идеальный код, но гораздо короче и понятнее
В Го очень много, мягко говоря, странностей. Например, там одно время была идея, что все модули должны лежать в выделенной папке - GOPATH, или идея использовать маленькие/большие буквы для обозначения видимости, что по моему портит код (и плюс, если ты хочешь поменять видимость, то тебе придется делать кучу замен). Странная идея писать адрес с гитхаба для импорта модуля. Нельзя задавать значения для полей по умолчанию. Нет возможности делать коллекции. Ужасный модуль flags, основанный на глобальных переменных,
а не на ООП, для разбора параметров командной строки.
Также, как я помню, в Го методы объекта не помещаются в класс, а их разрешено раскидывать по нескольким разным файлам, что тоже добавляет веселья при чтении кода. То ли дело PHP - все методы класса собраны в одном месте, каждый класс лежит в отдельном одноименном файле.
Тот код на Го, который я видел, я бы не сказал что он радикально читабельнее и понятнее, чем на PHP.
> Система типов заменяет 90% тестов,
Это заблуждение. Ты не сможешь переделать свой же код с чашками так, чтобы система типов проверяла корректность его логики.
В JS куча унаследованных проблем и довольно уродливый синтаксис.
> Покрой тестами FillCupsWithWater
Хорошо. Давай посмотрим, что это за сервис и какие к нему предъявляются требования. Ведь тесты пишутся для проверки того, что код соответствует требованиям.
Требования, конечно, лучше всего брать из ТЗ или документации, но так как ТЗ нету, нам придется восстановить их из кода.
- FillCupsWithWater получает (возможно, ограниченный) источник чашек и неограниченный источник воды, описанные интерфейсами
- он должен заполнить все доступные (1), но не более N (2), чашек
- чашки могут быть частично наполнены изначально
- чашки должны заполняться до максимума, но не переполняться (3)
Цифрами я пометил правила, которые мы будем тестировать.
Соответственно, для теста нам понадобится создать 2 вспомогательных класса: источник воды - TestTap и источник чашек - TestCupboard, который принимает в конструктор набор чашек. Мы можем сделать их отдельными классами или можем динамически сконструировать как моки, но в любом случае, мы не будем проверять, какие методы у них вызывались и какое число раз. Это не важно и это не входит в требования к тестируемому классу.
Если мы сделаем их отдельными классами, то мы сможем переиспользовать их в любом количестве тестов.
Соответственно, тесты будут такие:
1) вызываем FillCupsWithWater с N = 2, притом что TestCupboard предоставляет 3 пустых чашки. Проверяем, что нам вернули 2 чашки, что в них больше воды, чем было изначально. Дополнительно можно проверить, что третья чашка не заполнена.
2) вызываем FillCupsWithWater с N = 5 при том, что TestCupboard предоставляет 3 пустых чашки. Проверяем, что нам вернули 3 чашки, что воды в них больше, чем было изначально.
3a) берем чашку емкостью 100 с начальным заполнением 0, и кран, выдающий по 20 воды за раз. Подсовываем их FillCupsWithWater и проверяем, что чашка наполнена на 100.
3b) берем чашку емкостью 100 с начальным наполнением 10, и кран, выдающий 20 воды за раз. Проверяем, что чашка наполнена до уровня 90.
Если присмотреться, то при желании можно увидеть, что не все сценарии продуманы: что, если кран выдает разные порции воды? Что, если чашки могут быть разной емкости и начального наполнения? Что, если мы берем больше воды, чем нужно, и проливаем ее мимо чашки? Покрыть 100% входных данных тестами даже в таком простом коде не получится. Если мы наткнемся на баг, связанный с чашками разного размера или неравномерным источником воды, то, или если в ТЗ на это будет обращено внимание, то мы напишем дополнительные тесты, а пока хватит этого.
Написанные тесты проверяют, что класс соответствует предъявляемым к нему требованиям.
> Придется его замокать
Конечно, придется. Но ты делаешь это один раз, а не в каждом тесте. То же касается очереди сообщений - надо сделать, чтобы сообщения не отправлялись наружу, а немедленно обрабатывались, опять же, один раз для всего проекта.
Да, для каждого сервиса, который лезет куда-то наружу, надо сделать тестовую заглушку.
> На Go будет не идеальный код, но гораздо короче и понятнее
В Го очень много, мягко говоря, странностей. Например, там одно время была идея, что все модули должны лежать в выделенной папке - GOPATH, или идея использовать маленькие/большие буквы для обозначения видимости, что по моему портит код (и плюс, если ты хочешь поменять видимость, то тебе придется делать кучу замен). Странная идея писать адрес с гитхаба для импорта модуля. Нельзя задавать значения для полей по умолчанию. Нет возможности делать коллекции. Ужасный модуль flags, основанный на глобальных переменных,
а не на ООП, для разбора параметров командной строки.
Также, как я помню, в Го методы объекта не помещаются в класс, а их разрешено раскидывать по нескольким разным файлам, что тоже добавляет веселья при чтении кода. То ли дело PHP - все методы класса собраны в одном месте, каждый класс лежит в отдельном одноименном файле.
Тот код на Го, который я видел, я бы не сказал что он радикально читабельнее и понятнее, чем на PHP.
> Система типов заменяет 90% тестов,
Это заблуждение. Ты не сможешь переделать свой же код с чашками так, чтобы система типов проверяла корректность его логики.
Аргументирую по поводу уродливого синтаксиса в JS. Вот объявление функции в PHP:
function test(...): Result
Человек читает текст слева направо, и тут мы видим, что перед нами функция, и что она называется test. Прекрасно. Вот объявление функции в Питоне:
def test(...) -> Result:
Тоже прекрасно читается. А вот что изобрели гении от яваскрипта:
const test = (...) => {
Что мы видим: перед нами якобы "константа" с названием test. И только дочитав до конца и разобрав кучу скобочек и стрелочек, мы можем понять, что перед нами функция. Такое объявление плохо читаемо и не несет никакой выгоды. Я не понимаю, почему так пишут: неужели всем остальным это кажется читабельным и понятным?
Более того, тут еще и const нас обманывает. const - это не константа, как можно подумать. const означает лишь, что переменной нельзя присвоить другое значение. А константа - это неизменное значение. Более того, константы принято писать большими буквами.
Или другой пример кода из JS:
someObject.someInvalidProperty = 1;
этот код не выдает ни ошибки, ни предупреждения, хотя я опечатался в названии свойства и попробовал присвоить значение несуществующему свойству. JS вместо того, чтобы указать мне на ошибку, скрыл ее, и мне придется тратить время на отладку, чтобы найти это место.
Или, если ты забудешь слово var, то JS не смутится и просто создаст глобальную переменную.
Еще один пример: JS не выбросит исключение при чтении несуществующего свойства, или при делении на ноль, хотя математика это запрещает. Мне нужно нормальное математическое деление а не деление вида "ой, давайте не проверять деление на ноль, чтобы сэкономить 1 байт кода". И язык, который помогает находить ошибки, а не делает вид, что все в порядке.
Аргументирую по поводу уродливого синтаксиса в JS. Вот объявление функции в PHP:
function test(...): Result
Человек читает текст слева направо, и тут мы видим, что перед нами функция, и что она называется test. Прекрасно. Вот объявление функции в Питоне:
def test(...) -> Result:
Тоже прекрасно читается. А вот что изобрели гении от яваскрипта:
const test = (...) => {
Что мы видим: перед нами якобы "константа" с названием test. И только дочитав до конца и разобрав кучу скобочек и стрелочек, мы можем понять, что перед нами функция. Такое объявление плохо читаемо и не несет никакой выгоды. Я не понимаю, почему так пишут: неужели всем остальным это кажется читабельным и понятным?
Более того, тут еще и const нас обманывает. const - это не константа, как можно подумать. const означает лишь, что переменной нельзя присвоить другое значение. А константа - это неизменное значение. Более того, константы принято писать большими буквами.
Или другой пример кода из JS:
someObject.someInvalidProperty = 1;
этот код не выдает ни ошибки, ни предупреждения, хотя я опечатался в названии свойства и попробовал присвоить значение несуществующему свойству. JS вместо того, чтобы указать мне на ошибку, скрыл ее, и мне придется тратить время на отладку, чтобы найти это место.
Или, если ты забудешь слово var, то JS не смутится и просто создаст глобальную переменную.
Еще один пример: JS не выбросит исключение при чтении несуществующего свойства, или при делении на ноль, хотя математика это запрещает. Мне нужно нормальное математическое деление а не деление вида "ой, давайте не проверять деление на ноль, чтобы сэкономить 1 байт кода". И язык, который помогает находить ошибки, а не делает вид, что все в порядке.
Это макаки неграмотные пишут.
С хера ли функцию в константу загонять надо? Они для другого придуманы.
>этот код не выдает ни ошибки, ни предупреждения, хотя я опечатался в названии свойства
На 100% решается TS
>Или, если ты забудешь слово var, то JS не смутится и просто создаст глобальную переменную.
наличие use strict или TS, опять же, решает эту проблему
>JS не выбросит исключение при чтении несуществующего свойства
Во первых, это решается TS. Во вторых, с огромной вероятностью в таком случае тебе будет выброшено исключение последующими строками кода.
> при делении на ноль
Часто приходится делить на ноль в реальной разработке?
А можно вкрации, что там такое?
>Всё чаще приходится писать строчку и смотреть, чего будет. Хорошо - ну ок, пишем следующую. Не получилось? Ну, попробуем тут тип данных изменить, может в этом проблема? А, нет, проверка на ноль. Тоже нет. Так, что там вообще эта хуйня возвращает?
Коротко и ясно о современных реалиях пхп кодеров.
Я знаю шаблоны проектирования, читал книги разные, но я хуй его знает как работает мой код =)
>Так, что там вообще эта хуйня возвращает?
Тайпхинты уже давным давно завезли. Не надо позориться.
Ебать ты хитрый. Заебись конечно что ты расписал требования. Но меня интересовала именно непосредственная реализация, реальный код, который будет написан чтобы протестировать простейшую хуйню. Я именно это и хотел показать. Сетап для тестирования одной маленькой функции будет в десять раз больше её кода. Еще мне интересно было глянуть как ты будешь генерить тестовые данные и проверять что там внутри приватных свойств объектов. А если добавить кружкам айдишники, а если эти айдишники будут еще и uuid'ами будет вообще бурлеск. Так между прочим напомню что количество багов на количество строчек кода это константа. Чем больше кода в тестах, тем больше багов в тестах. Фейки это конечно лучше чем моки, но они и дороже как когнитивно, так и по времени.
>Если присмотреться, то при желании можно увидеть, что не все сценарии продуманы
Это тоже очень важный момент. Ты по своей внутренней интуиции решил что те условия, которые ты покрыл, покрыть нужно, а остальные уже по факту багов. Но правда в том что все они равнозначны, а трудозатраты на полное покрытие никогда не окупятся. Почему тогда вообще не перейти на написание тестов по факту багов?
>Конечно, придется. Но ты делаешь это один раз, а не в каждом тесте. То же касается очереди сообщений - надо сделать, чтобы сообщения не отправлялись наружу, а немедленно обрабатывались, опять же, один раз для всего проекта.
Еще раз повторю, что сразу видно что ты с таким никогда не сталкивался. Краник наливающий воду в чашку порождает нехуйный граф граничных условий. А полный прогон через крупное приложения порождает бездну. Моя позиция что таких тестов не должно быть вообще, слишком много false позитив, а когда заткнешь дырки моками, то вообще хуй пойми что в итоге тестируется. Но их пишут и пишут дохуя.
>В Го очень много, мягко говоря, странностей
А в пхп мало? В не зависимости от недостатков го, переписанные на го проекты которые я видел, всегда были короче в несколько раз. И в них было меньше мусора.
>Это заблуждение. Ты не сможешь переделать свой же код с чашками так, чтобы система типов проверяла корректность его логики.
Ты пишешь хуйню. Просто посмотри видос из предыдущего поста, там отлично показывается что такое хорошая система типов.
>>239987
Тебе >>240416 правильно написал что TypeScript все это решает. Но я немного добавлю чтобы было понятно что это на самом деле такое.
TypeScript это компилируемый, асинхронный, строго типизированный, модульный, полностью поддерживающий как ООП так и ФП парадигму язык, созданный ведущими архитекторами C#. В TypeScript есть: вывод типов, дженерики, туплы, readonly свойства, энумы и куча синтаксического сахара.
Вот на этом сегодня фронтендеры пишут селекты и дропдауны. Просто блядь представь, что у каждого деревенского теперь есть новенький спорткар, которым они по старинке пашут поле и возят картоху на заднем сиденье. А у тебя старый ржавый корч, на котором тебе нужно ехать 24 часа Нюрбургринга.
Ебать ты хитрый. Заебись конечно что ты расписал требования. Но меня интересовала именно непосредственная реализация, реальный код, который будет написан чтобы протестировать простейшую хуйню. Я именно это и хотел показать. Сетап для тестирования одной маленькой функции будет в десять раз больше её кода. Еще мне интересно было глянуть как ты будешь генерить тестовые данные и проверять что там внутри приватных свойств объектов. А если добавить кружкам айдишники, а если эти айдишники будут еще и uuid'ами будет вообще бурлеск. Так между прочим напомню что количество багов на количество строчек кода это константа. Чем больше кода в тестах, тем больше багов в тестах. Фейки это конечно лучше чем моки, но они и дороже как когнитивно, так и по времени.
>Если присмотреться, то при желании можно увидеть, что не все сценарии продуманы
Это тоже очень важный момент. Ты по своей внутренней интуиции решил что те условия, которые ты покрыл, покрыть нужно, а остальные уже по факту багов. Но правда в том что все они равнозначны, а трудозатраты на полное покрытие никогда не окупятся. Почему тогда вообще не перейти на написание тестов по факту багов?
>Конечно, придется. Но ты делаешь это один раз, а не в каждом тесте. То же касается очереди сообщений - надо сделать, чтобы сообщения не отправлялись наружу, а немедленно обрабатывались, опять же, один раз для всего проекта.
Еще раз повторю, что сразу видно что ты с таким никогда не сталкивался. Краник наливающий воду в чашку порождает нехуйный граф граничных условий. А полный прогон через крупное приложения порождает бездну. Моя позиция что таких тестов не должно быть вообще, слишком много false позитив, а когда заткнешь дырки моками, то вообще хуй пойми что в итоге тестируется. Но их пишут и пишут дохуя.
>В Го очень много, мягко говоря, странностей
А в пхп мало? В не зависимости от недостатков го, переписанные на го проекты которые я видел, всегда были короче в несколько раз. И в них было меньше мусора.
>Это заблуждение. Ты не сможешь переделать свой же код с чашками так, чтобы система типов проверяла корректность его логики.
Ты пишешь хуйню. Просто посмотри видос из предыдущего поста, там отлично показывается что такое хорошая система типов.
>>239987
Тебе >>240416 правильно написал что TypeScript все это решает. Но я немного добавлю чтобы было понятно что это на самом деле такое.
TypeScript это компилируемый, асинхронный, строго типизированный, модульный, полностью поддерживающий как ООП так и ФП парадигму язык, созданный ведущими архитекторами C#. В TypeScript есть: вывод типов, дженерики, туплы, readonly свойства, энумы и куча синтаксического сахара.
Вот на этом сегодня фронтендеры пишут селекты и дропдауны. Просто блядь представь, что у каждого деревенского теперь есть новенький спорткар, которым они по старинке пашут поле и возят картоху на заднем сиденье. А у тебя старый ржавый корч, на котором тебе нужно ехать 24 часа Нюрбургринга.
>PHP developer roadmap
>Карта знаний
Реально все это спрашивают со стажера за 0-30к и с джуна 50?
В ооо рога и копыта тебя заставят деплоить ваше говно на линуксы, так что обойтись нельзя, если не хочешь на ровном месте обосраться, но и учить что-то дальше базовых команд не нужно. в больших конторах скорее всего джуну линукс не понадобится
Вообще, требования важны. Так как они определяют, что мы будем проверять, а что нам не важно. Ты же дал код без требований, так что по идее тут можно было просто сказать "нет требований - значит тесты не требуются".
Код я не стал писать, так как подумал, что мы оба представляем, как он будет выглядеть. Ну вот тебе код для примера (твоя ссылка сейчас не открывается, так что пишу по памяти):
> вызываем FillCupsWithWater с N = 2, притом что TestCupboard предоставляет 3 пустых чашки. Проверяем, что нам вернули 2 чашки, что в них больше воды, чем было изначально. Дополнительно можно проверить, что третья чашка не заполнена.
public function testFilledCupsLimitIsRespected()
{
$testCupboard = new TestCupboard([
new Cup(100, 0),
new Cup(100, 0),
new Cup(100, 0)
]);
$testTap = new TestTap(20);
$dut = new FillCupsWithWater($testCupboard, $testTap);
$cups = $dut(2);
$this->assertCount(2, $cups);
$this->assertGreaterThan(0, $cups[0]->getLevel());
$this->assertGreaterThan(1, $cups[0]->getLevel());
// при желании проверим последнюю чашку
$this->assertEquals(0, $testCupboard->getCup(2)->getLevel());
}
Код можно чуть улучшить, если вынести проверку уровня в функцию и написать:
$this->assertCupNotEmpty($cups[0]);
Здесь требуется создать классы TestTap/TestCupboard, но они очень маленькие (в отличие от реальных классов, в которых будут сотни строк или больше), и их можно переиспользовать во многих тестах. Как альтернатива, можно использовать моки, но тогда придется копипастить однотиный код из теста в тест, а это, по моему, плохо.
Если ты поменяешь какой-либо из интерфейсов, то код придется переделать. Но его бы пришлось переделывать и в отсутствие тестов. И если мы используем классы вроде TestCupboard, то придется переделывать лишь этот класс, а не все тесты, которые его используют.
Тест получился немаленький, но ведь скорее всего код тестируемого сервиса будет намного больше, чем в твоем примере. А считается нормальным, если объем тестов сопоставим с объемом кода.
На практике сетап, конечно, может быть сложнее. Ну например, для теста тебе нужен товар на складе, а у товара десятки свойств, плюс для его размещения надо оформить разные акты, ведомости, провести его через систему учета. В такой ситуации, естественно, нужен вспомогательный класс-фабрика, который проведет все операции и выдаст правильно оформленный товар. Неправильно будет копипастить сложный сетап в десятки тестов. И создание товара тогда сведется к строчке вроде:
$product = $this->warehouseBuilder->addProduct(['name' => ..., 'price' => ...]);
То есть, если тебе нужен товар на складе с названием N и ценой X, то объем информации, которая требуется для создания этого товара такой: "товар на складе", N, X. И соответственно, это создание можно реализовать одной строчкой.
Естественно, в этом случае мы получаем не юнит-тест, а интеграционный, но если тестируемый код плотно привязан к системе складского учета, то может быть и нет особого смысла его тестировать в изоляции от нее.
Плюс таких фабрик еще в том, что если ты поменяешь что-то в процессе создания товара, то тебе придется переделать лишь одну фабрику, а не сотню тестов, использующих ее.
Также, при тестировании кода, работающего с БД, можно не изолировать такой код (что очень сложно), а проводить интеграционное тестирование. В таком случае мы перед началом тестов загружаем пустую тестовую базу, каждый тест заворачиваем в транзакцию с роллбеком по окончании теста, и в начале теста создаем с помощью классов-помощников нужные сущности в этой БД.
Вообще, требования важны. Так как они определяют, что мы будем проверять, а что нам не важно. Ты же дал код без требований, так что по идее тут можно было просто сказать "нет требований - значит тесты не требуются".
Код я не стал писать, так как подумал, что мы оба представляем, как он будет выглядеть. Ну вот тебе код для примера (твоя ссылка сейчас не открывается, так что пишу по памяти):
> вызываем FillCupsWithWater с N = 2, притом что TestCupboard предоставляет 3 пустых чашки. Проверяем, что нам вернули 2 чашки, что в них больше воды, чем было изначально. Дополнительно можно проверить, что третья чашка не заполнена.
public function testFilledCupsLimitIsRespected()
{
$testCupboard = new TestCupboard([
new Cup(100, 0),
new Cup(100, 0),
new Cup(100, 0)
]);
$testTap = new TestTap(20);
$dut = new FillCupsWithWater($testCupboard, $testTap);
$cups = $dut(2);
$this->assertCount(2, $cups);
$this->assertGreaterThan(0, $cups[0]->getLevel());
$this->assertGreaterThan(1, $cups[0]->getLevel());
// при желании проверим последнюю чашку
$this->assertEquals(0, $testCupboard->getCup(2)->getLevel());
}
Код можно чуть улучшить, если вынести проверку уровня в функцию и написать:
$this->assertCupNotEmpty($cups[0]);
Здесь требуется создать классы TestTap/TestCupboard, но они очень маленькие (в отличие от реальных классов, в которых будут сотни строк или больше), и их можно переиспользовать во многих тестах. Как альтернатива, можно использовать моки, но тогда придется копипастить однотиный код из теста в тест, а это, по моему, плохо.
Если ты поменяешь какой-либо из интерфейсов, то код придется переделать. Но его бы пришлось переделывать и в отсутствие тестов. И если мы используем классы вроде TestCupboard, то придется переделывать лишь этот класс, а не все тесты, которые его используют.
Тест получился немаленький, но ведь скорее всего код тестируемого сервиса будет намного больше, чем в твоем примере. А считается нормальным, если объем тестов сопоставим с объемом кода.
На практике сетап, конечно, может быть сложнее. Ну например, для теста тебе нужен товар на складе, а у товара десятки свойств, плюс для его размещения надо оформить разные акты, ведомости, провести его через систему учета. В такой ситуации, естественно, нужен вспомогательный класс-фабрика, который проведет все операции и выдаст правильно оформленный товар. Неправильно будет копипастить сложный сетап в десятки тестов. И создание товара тогда сведется к строчке вроде:
$product = $this->warehouseBuilder->addProduct(['name' => ..., 'price' => ...]);
То есть, если тебе нужен товар на складе с названием N и ценой X, то объем информации, которая требуется для создания этого товара такой: "товар на складе", N, X. И соответственно, это создание можно реализовать одной строчкой.
Естественно, в этом случае мы получаем не юнит-тест, а интеграционный, но если тестируемый код плотно привязан к системе складского учета, то может быть и нет особого смысла его тестировать в изоляции от нее.
Плюс таких фабрик еще в том, что если ты поменяешь что-то в процессе создания товара, то тебе придется переделать лишь одну фабрику, а не сотню тестов, использующих ее.
Также, при тестировании кода, работающего с БД, можно не изолировать такой код (что очень сложно), а проводить интеграционное тестирование. В таком случае мы перед началом тестов загружаем пустую тестовую базу, каждый тест заворачиваем в транзакцию с роллбеком по окончании теста, и в начале теста создаем с помощью классов-помощников нужные сущности в этой БД.
Там хуиты много написано из манямира.
> Сетап для тестирования одной маленькой функции будет в десять раз больше её кода.
Странно. На практике, наоборот, у тебя будет сервис, в котором 500-1000 строк, и к нему куча тестов по 15-20 строк каждый. Если ты пишешь свой код в виде сервисов по 20 строк, то может быть ты что-то делаешь не очень правильно.
> Еще мне интересно было глянуть как ты будешь генерить тестовые данные и проверять что там внутри приватных свойств объектов.
Мы не проверяем, что внутри приватных свойств, так как это состояние объекта не наблюдаемо снаружи. Нам важно либо наблюдаемое состояние (что можно увидеть через публичные методы) либо сайд-эффекты (изменения в БД, отправленные письма, HTTP-запросы итд). Какая разница, что у объекта в приватном свойстве, если он выдает правильные значения через публичные методы?
В ТЗ же не пишут "после вызова функции приватное свойство должно равняться true". Обычно там пишут более высокоуровневые вещи, которые мы и проверяем.
Если все-таки надо проверять приватные свойства, то к ним пишутся геттеры.
> . А если добавить кружкам айдишники
То мы не будем их проверять, так как объект обладает идентичностью и их можно сравнивать через $a === $b. Однако, если в требованиях требуется, чтобы был определенный id, то тогда будем проверять. Если требуется сравнить много свойств, то мы пишем функцию преобразования объекта в массив и сравниваем массивы. Функция, естественно, пригодится и в других тестах.
> Ты по своей внутренней интуиции решил что те условия, которые ты покрыл, покрыть нужно, а остальные уже по факту багов.
Ты не дал ТЗ.
> Но правда в том что все они равнозначны, а трудозатраты на полное покрытие никогда не окупятся. Почему тогда вообще не перейти на написание тестов по факту багов?
Задача тестов 1) проверить, что код соответствует требованиям 2) что при правках кода он не перестал соответствовать требованиям. Нам не требуется покрывать 100% входных данных, так как во-первых, это нереально, во-вторых, мы предполагаем, что разработчики добросовестные люди, которые в общем стараются писать правильно, просто иногда могут что-то нечаянно сломать (не зная, что один компонент влияет на работу второго). Тесты как раз и отлавливают такие нечаянные поломки. Конечно, баги могут просочиться. Но сравни это с ситуацией, когда тестов нет. Тогда правки кода напоминают прогулку по минному полю, что приводит к тому, что никто не рефакторит и не исправляет код, а только добавляет новый.
Если, к примеру, мы производим винты, то мы же не меряем микрометром каждый оборот резьбы. Мы делаем несколько контрольных измерений, если они в норме, значит винт соответствует требованиям.
> В не зависимости от недостатков го, переписанные на го проекты которые я видел, всегда были короче в несколько раз.
Они могут быть короче только по одной причине: в них меньше функционала. Объясни, какие конструкции есть в строго типизированном языке Го, которые заменяют конструкции большего размера в PHP? По моим ощущениям, из-за статической типизации код на Го как раз получается больше при равно функционале.
> Сетап для тестирования одной маленькой функции будет в десять раз больше её кода.
Странно. На практике, наоборот, у тебя будет сервис, в котором 500-1000 строк, и к нему куча тестов по 15-20 строк каждый. Если ты пишешь свой код в виде сервисов по 20 строк, то может быть ты что-то делаешь не очень правильно.
> Еще мне интересно было глянуть как ты будешь генерить тестовые данные и проверять что там внутри приватных свойств объектов.
Мы не проверяем, что внутри приватных свойств, так как это состояние объекта не наблюдаемо снаружи. Нам важно либо наблюдаемое состояние (что можно увидеть через публичные методы) либо сайд-эффекты (изменения в БД, отправленные письма, HTTP-запросы итд). Какая разница, что у объекта в приватном свойстве, если он выдает правильные значения через публичные методы?
В ТЗ же не пишут "после вызова функции приватное свойство должно равняться true". Обычно там пишут более высокоуровневые вещи, которые мы и проверяем.
Если все-таки надо проверять приватные свойства, то к ним пишутся геттеры.
> . А если добавить кружкам айдишники
То мы не будем их проверять, так как объект обладает идентичностью и их можно сравнивать через $a === $b. Однако, если в требованиях требуется, чтобы был определенный id, то тогда будем проверять. Если требуется сравнить много свойств, то мы пишем функцию преобразования объекта в массив и сравниваем массивы. Функция, естественно, пригодится и в других тестах.
> Ты по своей внутренней интуиции решил что те условия, которые ты покрыл, покрыть нужно, а остальные уже по факту багов.
Ты не дал ТЗ.
> Но правда в том что все они равнозначны, а трудозатраты на полное покрытие никогда не окупятся. Почему тогда вообще не перейти на написание тестов по факту багов?
Задача тестов 1) проверить, что код соответствует требованиям 2) что при правках кода он не перестал соответствовать требованиям. Нам не требуется покрывать 100% входных данных, так как во-первых, это нереально, во-вторых, мы предполагаем, что разработчики добросовестные люди, которые в общем стараются писать правильно, просто иногда могут что-то нечаянно сломать (не зная, что один компонент влияет на работу второго). Тесты как раз и отлавливают такие нечаянные поломки. Конечно, баги могут просочиться. Но сравни это с ситуацией, когда тестов нет. Тогда правки кода напоминают прогулку по минному полю, что приводит к тому, что никто не рефакторит и не исправляет код, а только добавляет новый.
Если, к примеру, мы производим винты, то мы же не меряем микрометром каждый оборот резьбы. Мы делаем несколько контрольных измерений, если они в норме, значит винт соответствует требованиям.
> В не зависимости от недостатков го, переписанные на го проекты которые я видел, всегда были короче в несколько раз.
Они могут быть короче только по одной причине: в них меньше функционала. Объясни, какие конструкции есть в строго типизированном языке Го, которые заменяют конструкции большего размера в PHP? По моим ощущениям, из-за статической типизации код на Го как раз получается больше при равно функционале.
>решается TS
>или TS
>это решается TS
Классное оправдание костылей языка тем, что у него есть надстройка которая решает проблемы языка.
>Часто приходится делить на ноль в реальной разработке?
Чаще чем хотелось бы.
>>240560
>Не надо позориться
Удвоил.
>>240802
>что TypeScript все это решает
Тайпскрипт придэ порядок наведэ!
Когда в других языках фреймворки решают проблемы скорости разработки на этом языке, TS решает проблемы JS'а.
>Классное оправдание костылей языка тем, что у него есть надстройка которая решает проблемы языка.
А у PHP нет этих надстроек в виде фреймоврков?
>Когда в других языках фреймворки решают проблемы скорости разработки на этом языке, TS решает проблемы JS'а.
Граница между определением фремворка и typescript'а настолько мала, что её невозможно заметить невооруженным глазом.
ПЕРЕКАТ https://2ch.hk/pr/res/2241613.html (М)
ПЕРЕКАТ https://2ch.hk/pr/res/2241613.html (М)
ПЕРЕКАТ https://2ch.hk/pr/res/2241613.html (М)
ПЕРЕКАТ https://2ch.hk/pr/res/2241613.html (М)
Это копия, сохраненная 15 февраля 2022 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.