Это копия, сохраненная 22 января 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Да, в нашем треде отвечают почти на все вопросы, только бампайте каждые 5 дней. И не разводите флуд, если вам скучно, лучше сходите померзните на улице, например.
Это тред для начинающих. Не способен сам переустановить Windows и имеешь тройку по математике? Ты наш человек.
Предыдущий тред был тут: >>1281608 (OP) . Остальные треды есть в архиве: https://phpclub.tech/ (там есть поиск, так что можно легко найти обсуждение какой-то задачи или ответы на свой старый пост) или ищутся в гугле по словам "клуб изучающих php" и в архиваче.
Мейлач лежит, модератор зверствует? Есть запасной тред на доброчане: /s/res/23225.xhtml#i46467
Форматируй свой код, если хочешь, чтобы его читали (как, написано во втором посте).
Правила: ведем себя воспитанно, помогаем новичкам, читаем учебники, решаем задачки, постим ссылки на решения, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.
С чего начать
У нас есть свои уроки по основам PHP, они собраны и выложены по адресу http://codedokode.github.io/phpbook (вас отредиректит на другой домен, не читайте, не сохраняйте, не запоминайте его, он временный). Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то можно начать с него. Он простой и понятный. Там есть задачи, их нужно решать (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению. С другой стороны, если этот учебник тебе не нравится, можно читать любой другой. Или официальный мануал. Или все сразу.
Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Visual Studio Code, Netbeans PHP или PhpStorm (с ним будет удобнее).
Если не знаешь как решать, запости код, напиши в каком месте остановился и попроси подсказку.
Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.
Надо переходить к более серьезным задачкам, которые научат тебя всему этому.
- для начала прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- установи Апач + PHP (советы выше и ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, PDO, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к Symfony 3/Doctrine 2
- Почитать про паттерны http://designpatternsphp.readthedocs.org/ru/latest/README.html (если ты не изучил ни одного фреймворка, то это будет рановато), тут с примерами кода http://designpatternsphp.readthedocs.org/ru/latest/README.html . Имей в виду что без примеров использования их учить бесполезно - не поймешь, хочешь увидеть примеры использования паттернов - ковыряй исходники Симфони, например Symfony Forms. Не заучивай паттерны - смотри код и думай, зачем тут они использованы.
Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:
https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/apache-install.md
Может тебе понадобится пользоваться командной строкой, вот гайд https://github.com/codedokode/pasta/blob/master/soft/cli.md
Решения задач лучше показать мне, особенно на ООП,так как сам ты вряд ли увидишь все ошибки. Пости свой код на гитхаб и вкидывай ссылку в тред по мере решения. Я прокомментирую и укажу на ошибки.
Параллельно стоит подучивать английский, на первых порах можно без него, но по мере развития придется все чаще сталкиваться с англоязычными статьями, так что лучше не откладывать. Читать можно news.ycombinator.com - это что-то вроде их хабра. Также можно начинать смотреть фильмы и видео на английском.
Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.
- HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://github.com/codedokode/pasta/blob/master/db/databases.md
Что почитать
- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1
- Новости IT на англ. https://news.ycombinator.com/
- какой-то древний, устаревший, но большой и на русском справочник по веб-разработке, посоветованный аноном: https://starcat.dp.ua/doc/wdh/
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.
Платиновые вопросы
- Почему PHP? Потому что вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery. У нас в треде были люди, которые практически с нуля учились и смогли найти работу.
- Что будут спрашивать на собеседовании если 0 опыта - гонять по теории, по официальному мануалу PHP, давать дурацкие задачки на переворачивание строк, гонять по SQL (транзакции, внешние ключи, напиши запрос), по JS (как сделать анимацию при нажатии кнопки), ну погугли, не ленись
- Можно подробнее про поиск работы, собеседования - нет, ОП писать не будет, но может кто из анонов захочет рассказать. Поищите тред перезвонивших, а также раздел /wrk/
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.
Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492
Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть стандарты PSR-1 и 2. Вот как надо оформлять код:
- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек
- мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)
Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:
PSR-1: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-2-coding-style-guide.md
Ну и посмотрите, я там в конце треда на многие вопросы ответил.
>2019
>php
Как меня бесит когда пидарасы всякие { ставят в одну линию с условием. Только в css так делаю
Актуальный вопрос. Поддвачну.
У кого какой?
>926-981
>
>Аноны, а интересно, как бы вы перевели "statement", например, отсюда:
>
>> As in C or Perl, PHP requires instructions to be terminated with a semicolon at the end of each statement.
>
>Я обычно и statement, и instruction перевожу как "команда".
>
>Ну и заодно, как бы вы перевели "clause" из SQL, например, "ORDER clause", "WHERE clause"?
Я бы перевёл как "выражение".
Со словом "clause" встречаюсь впервые, но знания с википедии дают простой ответ.
Во-первых: https://en.wikipedia.org/wiki/Clause
>In language, a clause is the smallest grammatical unit that can express a complete proposition.
Во-вторых: https://en.wikipedia.org/wiki/Clause_(logic)
>In logic, a clause is an expression formed from a finite collection of literals...
И наконец: https://en.wikipedia.org/wiki/Clause_(disambiguation)
>Clause, a constituent component of statements and queries in SQL
Так что, это слово можно перевести так же - "выражение". То есть, все эти слова близкие по смыслу но разные по семантике, иными словами, синонимы.
Или можно так и переводить - "клауза" (https://ru.wikipedia.org/wiki/Клауза).
>Функции и новый айпад
>
>Если у тебя есть соблазн сделать все, тупо скопипастив код 3 раза — знай, это решение не пройдет. Так-то.
А у меня прошло. Так-то! Ну или ОП ворвется и скажет, что strawbery не начисляет процент на свои 7777, тогда этот случай придется считать немного иначе.
У всех разная скорость обучения. Да и не перекаты учат, а решённые задачи.
Каво нахуй?
Переведу стандартную ситуацию в более реальную плоскость - для решения задачки уровня 2+2 второкласнику предлагают сначала выучить диффуры.
Четыреждеблядская ярость уже отошла. Я просто шлю фпизду этот фреймворк. Вот серьезно.
Страдать, что ж еще. Вообще, бэк-энд(нормальный) это не какая-то хуйня. Безопасность, вот это всё - учитывается. Отсюда с наскоку осилить установку/настройку не просто.
Подскажите, почему в $_SERVER нет элемента 'HTTP_REFERER'?
Потому, что страница, с которой был переход, в ссылке имеет rel="noreferrer" ? https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types
Это я валет. Элемент появляется, если перешел по ссылке, а я руками урл писал. Но всё равно спасибо, добрый человек!
>$row = $pdo-> query('select * from users') -> fetch();
И потом при выводе через
><td>Name</td>
<tr><? echo $row['name'];?></tr>
<td>Login</td>
<tr><? echo $row['login'];?></tr>
<td>Password</td>
<tr><? echo $row['pwd'];?></tr>
<td>email</td>
<tr><? echo $row['email'];?></tr>
Я вижу только 1 запись в базу?
Где я еблан?
PDOStatement::fetch — Fetches the next row from a result set
PDOStatement::fetchAll — Returns an array containing all of the result set rows
>atement::fetch — Fetches the next row from a result set
>PDOStatement::fetchAll — Ret
fetchAll - не выводит в итоге вообще нихуя
И базу данных не прикрутишь никак без костылей.
Вопрос следующий: видеокурсы, типа "Cпециалист php"(хвалебные) не прокатят? Начинать нужно именно с книг?
дополню вопрос: пытался вкатить в js, по книге нихуя не понял(начинать вкатывание с объектов это охуеть конечно), с видеокурса очень даже зашло.
Курсы норм, только устарели порядком и учат там говнокоду по сути. Но для того чтобы разобраться поначалу покатит, правда потом уже самому надо пыхтеть, чтобы не писать лапшу как в 2015 году.
С книжками, по идее, так же должно быть - устаревают пока тираж печатается. потому в ходу книжки с пространными философскими рассуждениями и без практики - общая теория не стареет
https://www.youtube.com/playlist?list=PLSdH7dYnlGYgrWg5wsEG4v03MiJ1WSOTx
https://www.youtube.com/playlist?list=PLSdH7dYnlGYgQ6ElbHRpG2zRXbkgkO3zQ
https://www.youtube.com/playlist?list=PLSdH7dYnlGYht0eGi9-14X87hrSl9plCc
https://www.youtube.com/playlist?list=PLSdH7dYnlGYh4uk8fMvnjuKl5PI7Xoxnj
Сделал всё как в видео, но почему-то когда вызываю метод printItem, в самом конце, срабаывает только код который выдаёт текс "Новость :" а оставшаяся часть $this->title нигде не срабатывает. Проверял все переменные, всё работает корректно, то есть если я хочу вывести инфу вроде author_name или conten из $row то всё отображается, а если в методе $this->author_name то уже нет.
Запятую пропустил, смотри внимательнее.
>>05442
В PSR указаны пробелы. Табы отображаются по-разному и этим плохи.
>>05584
Выражение (expression) это обычно что-то, что можно вычислить и оно вернет результат. Вроде 2 + 2.
>>05599
Сайт новостей вроде meduza.io, клон Hacker news, сайт для проведения почтовых рассылок, сайт для поиска опен сурс проектов, которым можно помочь (поиск по навыкам, плюс рейтинг по количеству незакрытых багов), сайт, который показывает код с Гитхаба, но добавляет функционал для навигации по нему как в IDE, видеохостинг pipe, сайт для поиска/сдачи жилья, сайт для поиска временных работников, фриланс-биржа.
Радио, которое играет песни с помощью Ютуба.
И, кстати, сайт для проверки знаний, наш TestHub: https://gist.github.com/codedokode/8733007 .
А почему это должен быть флаг? В чем принципиальная разница? Почему ты думаешь, что использование флага это "полноценно"? Также, в PHP обычно используют регулярные выражения диалекта PCRE, а не расширенные выражения POSIX, которые используешь ты.
Ну и если ты хотел покритиковать язык, то для тебя уже сделали готовую методичку: https://habr.com/post/315152/
Решено верно.
Мне больше не нравится наличие глобальных настроек для mb_ereg...: http://php.net/manual/ru/function.mb-regex-set-options.php
Из-за них один и тот же код может работать по-разному.
>>05614
У тебя как раз сделано нормально: код вынесен в функцию вместо копирования его. Но не все хорошо.
Не пиши по 2 команды в одной строчке, это ухудшает читабельность. В if принято использовать фигурные скобки по PSR. Кстати, у тебя if можно заменить на min/max.
Не очень понятно, зачем писать ++ перед $months. Это в принципе правильно, но смотрится непривычно.
Вместо array() можно писать [].
Одинаковые вещи лучше называть одинаково: 'price' => $total_price
А так, решено верно.
>>05810
Давайте спокойнее. И в учебнике ОПа про mb_ereg, по моему, ничего нету.
А почему это должен быть флаг? В чем принципиальная разница? Почему ты думаешь, что использование флага это "полноценно"? Также, в PHP обычно используют регулярные выражения диалекта PCRE, а не расширенные выражения POSIX, которые используешь ты.
Ну и если ты хотел покритиковать язык, то для тебя уже сделали готовую методичку: https://habr.com/post/315152/
Решено верно.
Мне больше не нравится наличие глобальных настроек для mb_ereg...: http://php.net/manual/ru/function.mb-regex-set-options.php
Из-за них один и тот же код может работать по-разному.
>>05614
У тебя как раз сделано нормально: код вынесен в функцию вместо копирования его. Но не все хорошо.
Не пиши по 2 команды в одной строчке, это ухудшает читабельность. В if принято использовать фигурные скобки по PSR. Кстати, у тебя if можно заменить на min/max.
Не очень понятно, зачем писать ++ перед $months. Это в принципе правильно, но смотрится непривычно.
Вместо array() можно писать [].
Одинаковые вещи лучше называть одинаково: 'price' => $total_price
А так, решено верно.
>>05810
Давайте спокойнее. И в учебнике ОПа про mb_ereg, по моему, ничего нету.
Это может говорить о том, что у тебя недостаточно навыков по работе в командной строке и недостаточное знание Windows/Linux. А у нас, кстати, есть простой гайд по основам командной строки: https://github.com/codedokode/pasta/blob/master/soft/cli.md
Композер тоже надо изучить, хотя бы на минимальном уровне. Иначе ты будешь похож на того школьника, который пытается решать дифуры, не зная о производной.
Для решения совсем простой задачки ты, конечно, можешь просто написать скрипт на 100 строчек. Зачем усложнять? Фреймворк для более сложных задач, для сайтов с таблицами, формами, админками итд. Учись выбирать правильный инструмент.
Почитал документацию по Laravel ( https://laravel.com/docs/5.7/installation ), мне конечно не нравится идея устанавливать утилиту laravel глобально, ведь у тебя может быть несколько проектов с разными версиями laravel. Я бы установил ее не глобально, а только для проекта. А так, вроде с виду ничего сложного.
>>05754
Это вообще не обязательный заголовок. Например, при переходе с HTTPS страницы на HTTP он может не передаваться или передаваться в урезанном виде.
>>05776
Прочти мануал по каждой используемой тобой функции PDO, обрати внимание, какие данные они принимают и какие возвращают. Если надо, с помощью var_dump() выведи возвращаемые данные, для каждой функции. Не пиши наугад. И тогда, может быть, ты увидишь причину. А может нет - тогда напиши, мы посмотрим.
А почему zlib1g? Также, я подозреваю, что для pecl может понадобиться не пакет с динамической библиотекой, а с заголовками и статической библиотекой.
Вот смотри, содержимое пакета zlib1g: https://packages.ubuntu.com/cosmic/amd64/zlib1g/filelist
Видно, что там есть только динамическая библиотека libz.so - это файл, в котором содержатся скомпилированные функции zlib. Программа может подключить эту библиотеку и вызывать ее функции. Чем-то похоже на библиотеки PHP. Но! Си - это не PHP. В Си, прежде чем запустить программу, ее надо скомпилировать из исходников в машинный код. А чтобы скомпилировать программу, которая будет вызывать функции библиотеки zlib, компилятору нужно дать их описание (в zlib.so его нету). Для этого нужны специальные заголовочные файлы, обычно они имеют расширение .h. В исходниках программы стоит ссылка на них и компилятор по описанию сможет сгенерировать код для вызова этих функций.
А вот содержимое zlib1g-dev: https://packages.ubuntu.com/cosmic/amd64/zlib1g-dev/filelist
Здесь мы видим заголовочные файлы вроде zlib.h, которые содержат описания (заголовки) функций библиотеки zlib на языке Си. Тебе наверняка любопытно, что это за файл, он выглядит примерно так: https://github.com/madler/zlib/blob/master/zlib.h
Там есть определения констант (#define), типов данных (typedef, struct), а также описания функций и комментарии. Содержимого функций там нету, только заголовки.
Также, в пакете ты можешь увидеть статическую библиотеку libz.a. Она содержит скомпилированный код функций, тот же самый, что в libz.so, но в другом формате. Статическая библиотека позволяет встроить (слинковать) код функций zlib прямо в скомпилированную программу. А динамическая библиотека zlib.so - она предназначена для подключения только в момент запуска программы.
Ну и еще в пакете есть документация и примеры использования.
Команда pecl компилирует расширения PHP их исходников. Если расширению нужна библиотека - то для компиляции такого расширения нужны именно заголовки из пакета zlib1g-dev. А для работы скомпилированного расширения - нужна zlib.so из zlib1g.
>>05840
Я бы советовал попробовать и то, и другое параллельно. Так будет лучше всего разбираться.
А почему zlib1g? Также, я подозреваю, что для pecl может понадобиться не пакет с динамической библиотекой, а с заголовками и статической библиотекой.
Вот смотри, содержимое пакета zlib1g: https://packages.ubuntu.com/cosmic/amd64/zlib1g/filelist
Видно, что там есть только динамическая библиотека libz.so - это файл, в котором содержатся скомпилированные функции zlib. Программа может подключить эту библиотеку и вызывать ее функции. Чем-то похоже на библиотеки PHP. Но! Си - это не PHP. В Си, прежде чем запустить программу, ее надо скомпилировать из исходников в машинный код. А чтобы скомпилировать программу, которая будет вызывать функции библиотеки zlib, компилятору нужно дать их описание (в zlib.so его нету). Для этого нужны специальные заголовочные файлы, обычно они имеют расширение .h. В исходниках программы стоит ссылка на них и компилятор по описанию сможет сгенерировать код для вызова этих функций.
А вот содержимое zlib1g-dev: https://packages.ubuntu.com/cosmic/amd64/zlib1g-dev/filelist
Здесь мы видим заголовочные файлы вроде zlib.h, которые содержат описания (заголовки) функций библиотеки zlib на языке Си. Тебе наверняка любопытно, что это за файл, он выглядит примерно так: https://github.com/madler/zlib/blob/master/zlib.h
Там есть определения констант (#define), типов данных (typedef, struct), а также описания функций и комментарии. Содержимого функций там нету, только заголовки.
Также, в пакете ты можешь увидеть статическую библиотеку libz.a. Она содержит скомпилированный код функций, тот же самый, что в libz.so, но в другом формате. Статическая библиотека позволяет встроить (слинковать) код функций zlib прямо в скомпилированную программу. А динамическая библиотека zlib.so - она предназначена для подключения только в момент запуска программы.
Ну и еще в пакете есть документация и примеры использования.
Команда pecl компилирует расширения PHP их исходников. Если расширению нужна библиотека - то для компиляции такого расширения нужны именно заголовки из пакета zlib1g-dev. А для работы скомпилированного расширения - нужна zlib.so из zlib1g.
>>05840
Я бы советовал попробовать и то, и другое параллельно. Так будет лучше всего разбираться.
>Выражение (expression) это обычно что-то, что можно вычислить и оно вернет результат. Вроде 2 + 2.
Но любая функция в программировании это же математическое вычисление, не так ли?
if тоже можно представить как математическое выражение (вычисление).
Тогда, "statement" можно перевести как "утверждение". Если касаться перевода.
>нуб
Потише, бывалый.
>Ты чем учебник ОПа читал? Там есть всё.
Учебник не канон, а всего лишь гид.
Документация - канон, я читал её.
Сайт аренды жилья давно уже думал сделать. Когда искал квартиру, неделю впустую звонил и ездил ко всяким долбаебам, у которых условия меняются на ходу, фотки не как в реальности, агенты повсюду.
Что, если создать систему подтверждения владельца квартиры, проверку качества и правдоподобности фотографий. Системы бронирования для просмотра, чтобы хозяин квартиры мог просто в нужное время прийти для осмотра жилья,без тупых созвонов. Если на месте оказался не хозяин с сайта, то жмёшь жалобу и аккаунт в бан улетает, если условия или цена с сайта не совпадает с реальностью-тоже самое. Если клиент не пришёл смотреть хату в нужное время - его уже наказывают. Можно прикрутить к аккаунтам отзывы,о хозяинах и жильцах.
Единственная проблема с этим всем, как понять, когда жалуются на человека это правда или просто ебанутый клиент. Не всех же в бан кидать после 1 жалобы, клиент вообще мог прийти, а хозяин все равно пожаловался, что того не было. Для разбора всех этих конфликтов, наверное, персонал нужен сайту.
>Сайт новостей вроде meduza.io, клон Hacker news, сайт для проведения почтовых рассылок, сайт для поиска опен сурс проектов, которым можно помочь (поиск по навыкам, плюс рейтинг по количеству незакрытых багов), сайт, который показывает код с Гитхаба, но добавляет функционал для навигации по нему как в IDE, видеохостинг pipe, сайт для поиска/сдачи жилья, сайт для поиска временных работников, фриланс-биржа.
>
>Радио, которое играет песни с помощью Ютуба.
>
>И, кстати, сайт для проверки знаний, наш TestHub: https://gist.github.com/codedokode/8733007 .
Какие замечательные идеи для стартапов! Любой анон может реализовать любую из этих идей и получать пассивный доход.
Сап, аноны.В php я полный ноль, потому нужна ваша помощь. Как сделать CRUD для комментариев?
https://github.com/someApprentice/Reactive-Express/
Как вы знаете, изначально, я хотел написать шифровальное приложение которое сможет работать без поддержки JS и на старых браузерах. Но в процессе разбора этих инструментов, ко мне пришло понимание, что в этом нет смысла, потому что приватные ключи должны оставаться приватно у пользователя в локальном хранилище IndexedDB кажется лучшим местом, и поэтому все процессы шифровки/дешифровки тоже привязаны к клиенту.
Может, хотя бы, получиться поддерживать старые браузеры. Нужно проводить тесты.
Что касается использования уже существующих протоколов шифрования, то TOX привлекателен. Мне нужно поразмыслить стоит ли его брать.
У меня есть только один небольшой вопрос по коду:
https://github.com/someApprentice/Reactive-Express/blob/master/src/app.js
React Router так же обрабатывает роуты на серверной части помимо самого express'а. Поэтому для express'а нет никакого смысла ставить обработчик на каждый роут. Как можно заметить роут для '/' и для '/somewhere' имеет абсолютно идентичный код. Так может для рендеринга просто поставить обработчик с регулярным выражением для всех роутов '/.*', а сверху перезаписать отдельные для POST (если такие потребуются) и для API?
Ну так зачем кидать идеи человека без собственной фантазии?
С помощью чего можно сделать выбор строки, программно прокручивать текст и выделять нужную, как на рисунке.
А какой язык программирования и какую платформу ты используешь для написания приложения?
Если HTML/JS то для прокрутки есть методы DOM:
https://developer.mozilla.org/ru/docs/Web/API/Element/scrollTop
https://developer.mozilla.org/ru/docs/Web/API/Window/scroll
Подсветку строки можно делать по-разному. Можно каждую строку программы сделать отдельным элементом DOM и добавлять ей CSS класс. Можно изловчиться и сделать один элемент DOM в виде прямоугольника с подсветкой и один блок текста и перемещать его к нужной строке.
Имей в виду, что если у тебя большой текст, и ты каждую строку делаешь элементом DOM, то вставка в DOM десятков тысяч элементов DOM может подвесить браузер. Может понадобиться оптимизировать код, например, создавая элементы только по мере прокрутки.
> А какой язык программирования и какую платформу ты используешь для написания приложения?
Голый JavaScript и HTML. Браузер хром.
Дизассемблированный код пихается в блок div у которого overflow-y: scroll
Каждая строчка это div в котором ещё 5 дивов. Адрес, мнемоника и аргументы
> scrollTop
Это я нашёл. Но как вычислять чему этот scrollTop равен к примеру для 4 строчке.
> Подсветку строки
Это буду делать изменяя background-color дива
> Имей в виду, что если у тебя большой текст
Адресное пространство от 0 до 0хfff
т.е. максимальное число строк 4095
Но по факту будет меньше, поскольку часть памяти идёт на видеобуфер, часть под переменные.
Главная функция эмулятора дёргается каждые 16мс. Если с таким интервалом менть css свойства браузер нормально будет отрабатывать?
Я в php умею совсем чуть-чуть, без ООП, с фрейморвками не работал. Максимум что могу - написать какой-нибудь парсер или примитивный дорген (сейчас в процессе обучения по шапке).
Искал для своих целей клон реддита, из нескольких вариантов остановился на одном (ларавел), но есть нюанс: комментарии рисуются на стороне клиента через js, а не самим фреймворком.
Хочу переделать, чтобы комментарии доставались сервером и на нем рендерились в html. Не могли бы вы оценить трудоемкость этой задачи?
Ссылка на этот кусок js кода https://github.com/Michael-J-Scofield/plebbit/blob/master/resources/views/threads/thread.blade.php#L245
Какой смысл брать готовое решение и чуть-чуть подправлять? делай с нуля. В нашей задаче про студентов из шапки есть много полезных советов и комментариев, которые и тут пригодятся.
цель - запустить как можно быстрее, а не научиться юзать ларавел.
>
>React Router так же обрабатывает роуты на серверной части помимо самого express'а. Поэтому для express'а нет никакого смысла ставить обработчик на каждый роут. Как можно заметить роут для '/' и для '/somewhere' имеет абсолютно идентичный код. Так может для рендеринга просто поставить обработчик с регулярным выражением для всех роутов '/.', а сверху перезаписать отдельные для POST (если такие потребуются) и для API?
Уточнение: Можно ли поставить обработчик всех роутов с помощью регулярного выражения '/.', не смотря на то что такой обработчик считается неприемлемым?
https://github.com/someApprentice/Reactive-Express/blob/master/src/app.js#L22-L30
https://github.com/someApprentice/Reactive-Express/blob/master/src/app.js#L38-L46
Что ты ожидал? Ты складываешь строки, при этом они конвертируются в числа, при конвертации отбрасывается хвост после первого нечислового символа.
Чтобы соединить строки нужно использовать "."
понял, спасибо большое!
Я делал комменты через рекурсию.
Нагуглил функцию и под себя переделал.
Вроде как понимаю, что написано, а вроде нет.
Имеется некое подобие подачи заявки. Необходимо отправлять в бд дату подачи заявки.
Проблема в следующем:
Сама инфа отправляется в бд с помощью sprintf через %s\%d(плейсхолдеры вроде?)
Как отправить дату через эти плейсхолдеры? Гугол уже прочитал чёт там по поводу даты ничего нет. Мануал официальный тоже прочитал есть только про строки( str_to_date мэйби юзануть?)и про числа(напомню в бд столбец сделан с datetime)
Собственно вопрос как подготовить строку для отправки, для datetime
Отбой тревоги пасаны. Я еблан и писал в отображении заявки а не в подаче.
Короче если кому-то будет необходимо то datetime отправляется в бд через sprintf с помощью строчного коофициента( '%s')
А что, обязательно дату в базу отправлять из приложения? Там должна быть встроенная функция автозаполнения датой, при создании новой записи. На MySQL есть, я пользовался.
Допустим я забрал весь html через file_get_content, дальше с помощью http://php.net/manual/ru/domdocument.loadhtml.php
я спарсил их кривой html, и получил все урлы на страничке. Из них уже выбрал те что ведут на сами csv и названия файлов.
Теперь у меня есть список всех этих файлов и нужно наладить скачивание. Что бы раз в месяц Крон гонял скрипт который будет все это дело собирать.
Меня немного смущает размер файлов и то с какой скоростью сервер отдает их.
Типа я же не могу просто форичем пройти по всем файлам и сделать file_get_content(), потому что в перспективе это займет уйму времени или скрипт просто отвалится по лимиту памяти, ведь наверняка каждый файл будет забивать собой память на сервере.
Какое можно надежное решение придумать в подобной ситуации?
>можно авторизоваться
>нет валидации, куков
Это как? Ну а вообще думаешь долго доделать этимелочи? Посидеть вечерок и попилить хотя бы пару заготовок для всяких классов там. Ну и в целом конечно же стоит.
Мануалы курил, но нихрена не понял)
Проект уже весь запилен, осталось запилить папку API для react приложения.
Есть может у кого в закромах посмотреть где, как организованно API со всеми настройками..
Никак не пойму как настроить маршруты внутри http/lockalhost/projectName/API/index.php !!
Тут могу отдавать что угодно, а вот дальше как подключать контроллеры, экшены самомго API, не понимаю...
>Какое можно надежное решение придумать в подобной ситуации?
Отключи уйму времени и качай по очереди.
В крон-скриптах лимит времени можно ставить любой, по умолчанию там его скорее всего нету. А чтобы память не тратилась, не храни все в памяти, а сохраняй на диск. В принципе, при желании можно сделать скачивание сразу в файл, например, с помощью stream_copy_to_stream или опций к curl, Guzzle.
Если я пишу сразу на удаленный сервак, то никак не получится накрутить xdebug?
Благодарю за развернутое объяснение, всё получилось. Задача у меня изначально была подружить пхп-клиент с го-сервером по грпц, докеризировать всё это дело и довести до продашкн-реди ума.
Если будет кому интересно, могу залить на гит то, что в итоге получится.
Понял, не нужно
Когда что то не работает или чето не понимаешь каким образом работает, то распечатывай переменную, которая вызывает вопросы.
Ты можешь распечатать твой скл запрос:
$sql ='INSERT INTO hooy WHERE id = zhopa ......';
echo $sql;
И ты увидишь что конкретно сжирает сервер
Если у тебя публичный статически ip можеш попробовать в настройках php на сервере:
xdebug.remote_enable=1
xdebug.remote_host=твой айпи
xdebug.remote_port=твой открытый порт
В настройках иде слушаешь этот порт.
SSH тунель едва-ли подходит под танцы с бубном - прокидываешь порт и айпи ставишь локальный.
Зато сразу защищено и не требует статики.
Чтобы автоинкремент заработал тебе не нужно вообще указывать id в INSERT, пропускай этот столбец.
Спасибо! Похоже я раньше, что-то не так сделал и это не работало
Почему YII и Symfony, а не Laravel?
Считается, что в Symfony много джавовой наркомании. Но это не точно. Поэтому спросил почему именно они.
Симфони - более тырпрайзный вариант, эдакий спринг для мира пхп.
Ларавел больше про хуяк-хуяк-в-продакшен.
Юи не трогай - устаревший кусок говна.мимо 1.5 года сидел на юи2 в галерке
Ну-ну.
Такие же запросы можно использовать? Просто в задаче про студентов написано, что нельзя переменные вставлять прямо в запрос. Но здесь нет никаких данных введенных пользователем, для них же защита не нужна?
>Но здесь нет никаких данных введенных пользователем, для них же защита не нужна?
Ты, скорее всего, функцию запроса к БЖ не очень удачно реализовал - в норме она очищает вообще все данные извне, пользователь там или само прилетело.
Покаж функцию свою.
public function getStudentsByLimit($limit, $offset){
$db = $this->dbase;
$stmt = $db->prepare("SELECT * FROM student LIMIT $limit OFFSET $offset");
$stmt->execute();
$result = $stmt->fetchAll();
return $result;
}
Это ваще пиздец, особенно когда это не что-то очевидное, вроде сложений значений массива, а какая-нибудь ебанутая хуйня. Тратишь кучу времени на нормальную реализацию и поиск решения, а потом узнаешь, что уже есть готовая функция для этого случая, а ты просто изобретал велосипед.
Знакомо. Наверное, все через это проходили.
Рекомендую всегда, вообще всегда, смотреть документацию при работе с каким-то типом данных.
Вот работаешь ты с массивами - открой вкладку со списком функций на сайте и просмотри их все.
Это же самообман всё - думаешь, что долго открывать, искать эти функции, как дурак, тогда как ИРЛ всё обычно наоборот - функции имеют понятное название, а пилить велосипед с тем же foreach выйдет гораздо дольше, чем просто взять и использовать нужную из документации.
в вебе уже всё изобретено, гуглишь как сделать хуйня нейм и получаешь уже готовый код
А откуда ты в функции знаешь, откуда пришли данные? На них это не написано. Плюс, offset явно создается на основе данных пользователя.
Ну вот ты напишешь функцию:
function getStudent($limit, $offset)
{
....
'SELECT * FROM student LIMIT $limit OFFSET $offset'
...
}
Как проверить, что она безопасна? Где гарантия, что в нее всегда передают только числа? Это ты думаешь, что в нее передают только числа, но завтра кто-нибудь напишет
getStudents($_GET['limit'], ...)
И у нас инъекция.
Должно быть видно, что функция безопасна, без исследования остального кода. Она должна быть написана так, чтобы быть безопасной, что бы в нее не передавали.
Кстати, в случае чисел для защиты достаточно применить intval() или поставить тайп-хинт int, но через плейсхолдеры все же будет надежнее. Их убрать труднее, чем заменить int на string, не заметив что это для обеспечения безопасности.
Не оч реализация, как по мне.
Обычно так пишу - https://ideone.com/TPhsrf
я там скобки посеял где-то пока писал
Если у кого есть ещё идеи - делитесь.
Пользователь не может передать туда ничего, у меня там идет не через гет, а просто типа site.com/page/2. Там все рассчитывается для создания пагинации. В оффсет и лимит не может попасть ничего кроме числа по идее. Я понимаю что этого не видно и тут не экстрасенсы сидят. Может я вопрос не так задал: можно ли вставлять переменные прямо в sql запрос, если я уверен, что туда не попадет какая-нибудь левая хуйня? Не будут ли на меня смотреть как на дауна из-за этого?
А хотя не, что-то я невнимательно твой ответ прочитал. Чтобы кто-нибудь, кто 'в теории' будет использовать скрипт, не сломал ничего, нужно действительно использовать какую-нибудь защиту. Завтра сделаю.
Ты то ли невнимательно прочел пост, то ли что-то не так понял.
Функция, работающая с SQL, должна работать безопасно, что бы в нее не передавали. И защита должна быть сделана в самой функции. Чтобы смотря только на эту функцию, было видно что она безопасна.
Функция >>08062 этим требованиям не соответствует.
Ты не можешь гарантировать, что в твою функцию будут передавать только числа. Так как это знание есть только в твоей голове, завтра тебя уволят, наймут нового разработчика и он передаст туда строку от пользователя.
Попробуй подумать чуть масштабнее: проект может разрабатывать несколько человек, код может быть большой и ты замучаешься весь изучать. Потому функция была должна быть написана безопасно сама по себе, чтобы для ее проверки не надо было изучать остальной код.
Да, спасибо, я понял. Просто не подумал, что нужно защищать код не только от злых хакеров (лол), но и от мифического человека, использующего мой скрипт.
>от мифического человека, использующего мой скрипт
Ты сам через месяц забудешь что там накалякал.
>$db = $this->dbase;
Какая-то бессмысленная строка. Зачем она нужна?
Почему заместо этого всего:
>$db = $this->dbase;
>$stmt = $db->prepare()
просто не использовать:
$this->dbase->prepare()
https://ideone.com/YZhoeC
ООП-Будильник 2.0 с учетом замечаний из предыдущего треда, надеюсь ничего не упустил. Спасибо за подробные замечания, всё очень доступно и понятно!
https://ideone.com/Kj2GBG
Версия с тестами, выглядит не так стильно но работает. Ну эмм, я пошел делать вектор.
Сумма прописью ULTIMATE FINALLY (надеюсь) EDITION - https://repl.it/@MaksimSienchien/GrowingStarkProducts
В калькуляторе, кроме как условиями, возможно реализовать выполнение действий? Я чет не допетрил как
https://repl.it/@MaksimSienchien/LimitedTrimAfkgaming-1
http://sandbox.onlinephpfunctions.com/code/bf265b1dcfaab38559a459812aa03f0c5583fc7b
Также есть вопрос по оформлению кода, в PSR-1, PSR-2 ответа не нашел, PHPStorm на автомате не форматирует это. Как правильно разбивать построчно различные конструкции. Вот примеры у меня в коде - 55-60 строки (сокращенный if), 188-192 строки (длинное условие в if-е), 268-274 строки (массив).
Может ли не работать перенаправление header("Location: /") из за того, что есть деприкейтед ошибка, на которую я пока забил хуй?
Cannot modify header information - headers already sent by...
Разобрался. Если кому интересно, да, может. Выводимые серваком ошибки не дают изменять заголовки
Там упомянута задача про "Банкомат", кстати. Тоже сначала дают данные, с которыми работает жадный алгоритм, а потом такие, с которыми не работает.
Там код на яваскрипт, но его без проблем можно написать и на PHP. Аноны, поломайте голову, проверьте себя. Я подскажу, если есть вопросы.
>>1299665
> https://repl.it/@underbottom/ATM - банкомат.
> $count100 = 0;
> $count200 = 0;
> $count500 = 0;
Если ты начинаешь создавать переменные с цифрами на конце, скорее всего тебе нужен массив. Не $count100, а $count[100]. У тебя, чтобы добавить новый номинал, надо переделывать весь код.
В общем, там сейчас один и тот же код скопирован 6 раз, надо использовать массив и цикл вместо копипасты.
В Википедии написано, что жадный алгоритм работает только для "канонических" систем монет или купюр: https://ru.wikipedia.org/wiki/Жадный_алгоритм#Размен_монет
> https://repl.it/@underbottom/smart-ATM -головоломка.
Да, тут идея относительно верная - перебирать все сочетания количеств купюр. Но проблема в том, что время выполнения программы быстро растет. Допустим, у тебя по 10 штук каждой купюры = это 10^6 = 1 млн. итераций (терпимо). Но если купюр будет по 100 штук, то это уже 100^6 = 10^12 = триллион итераций. Слишком долго будет работать.
Потому надо внедрять оптимизации перебора, вроде таких:
- если мы хотим выдать 6600, то не имеет смысл проверять варианты, где 2 и более купюры по 5000. Имеет смысл проверять варианты только 0x5000 и 1x5000
- если мы хотим выдать 500500, то сначала стоит попробовать вариант 100 x 5000, так как он ближе всего к цели, и только потом 99x5000, 98 x 5000 и тд.
- если мы хотим выдать 500500, и у нас сумма купюр номиналом < 5000 равна 6000, то не имеет смысла проверять варианты вроде 96 x 5000, 95 x 5000 итд., так как при их использовании нам не хватит мелких купюр.
Если ты будешь внедрять оптимизации, я тебе советую добавить в программу счетчик итераций, чтобы видеть эффект от них.
Я должен предупредить, что задача о размене - это разновидность задачи о ранце и при желании можно подобрать такие начальные условия, что даже с оптимизациями потребуется полный перебор вариантов. Но в реальных условиях (когда номиналы купюр круглые и купюр не более нескольких сотен), это должно работать. Если тебе интересно проверить это, можно подавать в цикле на вход твоей программе разные суммы и смотреть, сколько итераций потребуется на каждую.
Ну и у тебя скопировано 6 циклов, было бы выгоднее заменить их на рекурсивный вызов функции с одним циклом. Почитай про рекурсию и попробуй заменить циклы на нее. А то если мы хотим сделать 4 или 7 номиналов, надо код переделывать. Хватит копипастить.
Похожая задача о сдаче: https://habr.com/post/109384/
Почитать про задачи о размене: https://neerc.ifmo.ru/wiki/index.php?title=Задача_о_рюкзаке#.D0.97.D0.B0.D0.B4.D0.B0.D1.87.D0.B0_.D0.BE_.D1.80.D0.B0.D0.B7.D0.BC.D0.B5.D0.BD.D0.B5
В этих задачах число купюр неограниченно. Потому тебе можно изучить алгоритм и доработать его для ограниченного числа купюр.
>>1299665
> https://repl.it/@underbottom/ATM - банкомат.
> $count100 = 0;
> $count200 = 0;
> $count500 = 0;
Если ты начинаешь создавать переменные с цифрами на конце, скорее всего тебе нужен массив. Не $count100, а $count[100]. У тебя, чтобы добавить новый номинал, надо переделывать весь код.
В общем, там сейчас один и тот же код скопирован 6 раз, надо использовать массив и цикл вместо копипасты.
В Википедии написано, что жадный алгоритм работает только для "канонических" систем монет или купюр: https://ru.wikipedia.org/wiki/Жадный_алгоритм#Размен_монет
> https://repl.it/@underbottom/smart-ATM -головоломка.
Да, тут идея относительно верная - перебирать все сочетания количеств купюр. Но проблема в том, что время выполнения программы быстро растет. Допустим, у тебя по 10 штук каждой купюры = это 10^6 = 1 млн. итераций (терпимо). Но если купюр будет по 100 штук, то это уже 100^6 = 10^12 = триллион итераций. Слишком долго будет работать.
Потому надо внедрять оптимизации перебора, вроде таких:
- если мы хотим выдать 6600, то не имеет смысл проверять варианты, где 2 и более купюры по 5000. Имеет смысл проверять варианты только 0x5000 и 1x5000
- если мы хотим выдать 500500, то сначала стоит попробовать вариант 100 x 5000, так как он ближе всего к цели, и только потом 99x5000, 98 x 5000 и тд.
- если мы хотим выдать 500500, и у нас сумма купюр номиналом < 5000 равна 6000, то не имеет смысла проверять варианты вроде 96 x 5000, 95 x 5000 итд., так как при их использовании нам не хватит мелких купюр.
Если ты будешь внедрять оптимизации, я тебе советую добавить в программу счетчик итераций, чтобы видеть эффект от них.
Я должен предупредить, что задача о размене - это разновидность задачи о ранце и при желании можно подобрать такие начальные условия, что даже с оптимизациями потребуется полный перебор вариантов. Но в реальных условиях (когда номиналы купюр круглые и купюр не более нескольких сотен), это должно работать. Если тебе интересно проверить это, можно подавать в цикле на вход твоей программе разные суммы и смотреть, сколько итераций потребуется на каждую.
Ну и у тебя скопировано 6 циклов, было бы выгоднее заменить их на рекурсивный вызов функции с одним циклом. Почитай про рекурсию и попробуй заменить циклы на нее. А то если мы хотим сделать 4 или 7 номиналов, надо код переделывать. Хватит копипастить.
Похожая задача о сдаче: https://habr.com/post/109384/
Почитать про задачи о размене: https://neerc.ifmo.ru/wiki/index.php?title=Задача_о_рюкзаке#.D0.97.D0.B0.D0.B4.D0.B0.D1.87.D0.B0_.D0.BE_.D1.80.D0.B0.D0.B7.D0.BC.D0.B5.D0.BD.D0.B5
В этих задачах число купюр неограниченно. Потому тебе можно изучить алгоритм и доработать его для ограниченного числа купюр.
С локального сервера или через браузер все работает, но при отправлении текста из сервера "Aukštųjų" превращается в "Auk", а с urlencode в "Aukštųjų". Что делать? Использую Heroku, если это важно.
ОП, что там с решением задачки TestHub? Есть какие-то варианты? Не совсем понимаю как сделать БД для вопросов с несколькими вариантами ответа.
Мы же вроде обсуждали это где-то выше. Можно использовать такую схему:
- вопросы - questions
- варианты ответов - options - связаны с вопросами как M-1
- сеанс теста - session
- ответ на вопрос - answer, связан с session и questions
- выбранные варианты ответов - selected_options, связаны с answer и options
>>1299989
> Почему не открывается страница в браузере из PHPStorm.
Тебе надо проверить настройки PHPStorm, вот этот раздел
https://www.jetbrains.com/help/phpstorm/settings-tools-web-browsers.html
https://www.jetbrains.com/help/phpstorm/configuring-local-interpreter.html
>>1299566
> Почему дампы выводятся дважды, причем показывают они разную информацию?
Потому, что код выполняется 2 раза.
>>1299564
> https://ideone.com/AbXtmY правильно ли я решил задачу со школьником взявший кредит на айпад?
Нет. Ты сделал 3 функции, по одной для каждого банка. Но ведь они полностью одинаковые. Нужно сделать одну функцию, которая способна посчитать кредит для любого банка (на основании передаваемых ей данных). И вызвать эту функцию 3 раза.
>>1299056
> Вкатился к вам после 3х месяцев Си (мой первый язык). Пока идёт просто, хочу сразу узнать какая самая сложная тема в пхп для новичков
Ссылки и ООП наверно.
>>1299989
> Почему не открывается страница в браузере из PHPStorm.
Тебе надо проверить настройки PHPStorm, вот этот раздел
https://www.jetbrains.com/help/phpstorm/settings-tools-web-browsers.html
https://www.jetbrains.com/help/phpstorm/configuring-local-interpreter.html
>>1299566
> Почему дампы выводятся дважды, причем показывают они разную информацию?
Потому, что код выполняется 2 раза.
>>1299564
> https://ideone.com/AbXtmY правильно ли я решил задачу со школьником взявший кредит на айпад?
Нет. Ты сделал 3 функции, по одной для каждого банка. Но ведь они полностью одинаковые. Нужно сделать одну функцию, которая способна посчитать кредит для любого банка (на основании передаваемых ей данных). И вызвать эту функцию 3 раза.
>>1299056
> Вкатился к вам после 3х месяцев Си (мой первый язык). Пока идёт просто, хочу сразу узнать какая самая сложная тема в пхп для новичков
Ссылки и ООП наверно.
> Если по мануалу опа я не смог в MVC - я сильно тупой?
Мануал может быть написан не идеально, лучше задать вопрос в треде.
>>1298653
> https://repl.it/@underbottom/words-out-of-digits - Числа прописью.
> function makeThree($number) {
> $number/=1000;
Тут стоит сделать округление, а то % рассчитан на работу с целыми числами.
> function makeWordOfKeys ($number,$currencyName) {
Эта функция выглядит усложненно. Вот я писал другому анону про то, какие должны быть функции, прочитай пост: https://phpclub.tech/pr/res/1281608.html#1304593
> Видимо ты не понял идею разбиения кода на функции. Суть в том, что длинный кусок кода, который делает несколько вещей, сложно понять. Его сложно править, в нем много переменных, и можно нечаянно что-то сломать. Ну и физически прочитать 1000 или 10 000 строк кода быстро невозможно. Поэтому код разбивают на отдельные действия и выносят эти действия в функции. Так, что мы можем вместо огромной портянки кода читать только небольшую функцию, которая нас интересует.
> Но для этого функции должны быть отделены от других частей кода. Они должны иметь определенное назначение (не размытое, вроде "делает одно действие, кусочек другого и готовит данные для третьего"). Они должны иметь понятное название, в котором описано их назначение. И они должны иметь понятный набор входных аргументов, что они принимают на вход, и что возвращают.
> Вот пример более адекватной функции:
> /**
> * Принимает на вход целое число от 0 до 999 и возвращает его
> * текстовое представление.
> *
> * Например, для числа 312 вернет "триста двенадцать".
> */
> function spellNumber(int $number): string
>
> Согласись, что даже если ты не прочитал код функции, ты из описания уже понимаешь, что она делает, и как ее можно использовать. Например, так:
>
> echo spellNumber(123) . "\n";
>
> Комментарий /** ... */ - это комментарий в формате phpdoc ( https://ru.wikipedia.org/wiki/PHPDoc ). Слово int и string - это тайп-хинты, советую их изучить:
>
> - http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration
>
> То есть ты должен в идеале каждую функцию так описать. Если ты не можешь понятно описать назначение функции и формат ее аргументов, то скорее всего, ты что-то неудачно спроектировал.
Функция makeWordOfKeys несамостоятельна и неуниверсальна. Она принимает на вход массив из 3 чисел и массив из 9 слов (это кстати не описано в комментариях и надо самому догадываться). И она явно привязана к другой функции, которая содержит этот массив из 9 слов. Лучше было бы сделать функцию, которая получает на вход число, формы слов и выбирает одну из форм. Тогда она будет достаточно отделена от остального кода. А так, у тебя это просто продолжение другой функции.
Вдобавок, в ней еще куча копипасты.
Та же проблема с makeWordOfThree. Непонятно, почему она должна получать именно массив из 3 чисел, а не одно число, например. И написание цифр лучше не передавать в нее, а поместить либо в нее, либо в отдельную функцию. В аргументы мы передаем значения, которые влияют на работу функции. Но этот массив с написанием чисел всегда одинаков и его передавать не надо.
> Если по мануалу опа я не смог в MVC - я сильно тупой?
Мануал может быть написан не идеально, лучше задать вопрос в треде.
>>1298653
> https://repl.it/@underbottom/words-out-of-digits - Числа прописью.
> function makeThree($number) {
> $number/=1000;
Тут стоит сделать округление, а то % рассчитан на работу с целыми числами.
> function makeWordOfKeys ($number,$currencyName) {
Эта функция выглядит усложненно. Вот я писал другому анону про то, какие должны быть функции, прочитай пост: https://phpclub.tech/pr/res/1281608.html#1304593
> Видимо ты не понял идею разбиения кода на функции. Суть в том, что длинный кусок кода, который делает несколько вещей, сложно понять. Его сложно править, в нем много переменных, и можно нечаянно что-то сломать. Ну и физически прочитать 1000 или 10 000 строк кода быстро невозможно. Поэтому код разбивают на отдельные действия и выносят эти действия в функции. Так, что мы можем вместо огромной портянки кода читать только небольшую функцию, которая нас интересует.
> Но для этого функции должны быть отделены от других частей кода. Они должны иметь определенное назначение (не размытое, вроде "делает одно действие, кусочек другого и готовит данные для третьего"). Они должны иметь понятное название, в котором описано их назначение. И они должны иметь понятный набор входных аргументов, что они принимают на вход, и что возвращают.
> Вот пример более адекватной функции:
> /**
> * Принимает на вход целое число от 0 до 999 и возвращает его
> * текстовое представление.
> *
> * Например, для числа 312 вернет "триста двенадцать".
> */
> function spellNumber(int $number): string
>
> Согласись, что даже если ты не прочитал код функции, ты из описания уже понимаешь, что она делает, и как ее можно использовать. Например, так:
>
> echo spellNumber(123) . "\n";
>
> Комментарий /** ... */ - это комментарий в формате phpdoc ( https://ru.wikipedia.org/wiki/PHPDoc ). Слово int и string - это тайп-хинты, советую их изучить:
>
> - http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration
>
> То есть ты должен в идеале каждую функцию так описать. Если ты не можешь понятно описать назначение функции и формат ее аргументов, то скорее всего, ты что-то неудачно спроектировал.
Функция makeWordOfKeys несамостоятельна и неуниверсальна. Она принимает на вход массив из 3 чисел и массив из 9 слов (это кстати не описано в комментариях и надо самому догадываться). И она явно привязана к другой функции, которая содержит этот массив из 9 слов. Лучше было бы сделать функцию, которая получает на вход число, формы слов и выбирает одну из форм. Тогда она будет достаточно отделена от остального кода. А так, у тебя это просто продолжение другой функции.
Вдобавок, в ней еще куча копипасты.
Та же проблема с makeWordOfThree. Непонятно, почему она должна получать именно массив из 3 чисел, а не одно число, например. И написание цифр лучше не передавать в нее, а поместить либо в нее, либо в отдельную функцию. В аргументы мы передаем значения, которые влияют на работу функции. Но этот массив с написанием чисел всегда одинаков и его передавать не надо.
> Квантификаторы - условия задаваемые выражению внутри скобок.
нет, квантификаторы - это символы, которые задают число повторов идущего перед ними символа или выражения. Например: ?, +, *, {...}
> 2) Фигурные скобки. Внутри них задаётся число повторений от n до m.
Верно.
> 3) Круглые скобки - объединяют набор символов и квантификаторов в один элемент(тупая формулировка наверное).
Верно.
> задачка. Число находим вот так [\d]+. Найти число с запятой [\d]+(\,\s).
> >[\d]+(\,\s)*
Нет, неверно. У тебя написано:
искать число, за ним выражение ( запятая, пробел ), которое повторяется любой число раз.
То есть твое выражение это:
число (запятая пробел)*
Но нам надо искать число, за которым может идти сколько угодно других чисел через запятую:
число (пробелы запятая пробелы число)*
Попробуй записать это на языке регулярок.
>>1298000
> https://repl.it/@underbottom/povtorenie1 - (исправление пробелов и заглавные буквы)
Здесь можно было обойтись одним preg_replace:
> $regexp = "/(\S+)(\s)([,.!?:;]+)(\s)/ui";
> $text = preg_replace($regexp,"$1$3",$text);
> $regexp = "/([,.?!:;]+)([a-zа-яё0-9]+)/ui";
> $text = preg_replace($regexp,"$1 $2",$text);
В первом выражении [,.!?:;]+ квантификатор плюс "жадный" ( http://php.net/manual/ru/regexp.reference.repetition.php ) и захватит максимально возможное число символов в тексте. То есть, если там будет многоточие, то эта конструкция захватит все точки в нем. И потому можно одним preg_replace и убрать лишние пробелы, и добавить один пробел после знака.
> function makeLetterUp ($match) {
Эта функция сделана не очень логично, что она принимает массив, а не строку с буквой. Для использования с preg_replace_callback выгоднее было бы использовать анонимную функцию:
$upcaseLetter = function ($match) { ... };
...preg_replace_callback(..., $upcaseLetter);
Или вообще, убрав переменную:
...preg_replace_callback(..., function ($match) {
...
});
Почитать: http://php.net/manual/ru/functions.anonymous.php
Также, у тебя отдельно меняется регистр первой буквы в тексте, а отдельно - первых букв в предложениях. Можно было бы объединить это в одно действие.
А так, решено верно.
> https://repl.it/@underbottom/repeat4 - поправил недочёты.
> [^\\s]
Можно просто \\S
> $changedText=str_replace("здел","сдел",$changedText);
Слово "раздел" будет заменено на "расдел".
> [^,а-я0-9a-z]
ё не входит в диапазон а-я и его надо указывать отдельно.
> (а|но\s)
Здесь \s относится только к "но", но не к "а". Также, здесь проще использовать \b, чтобы указать, что там должна быть граница слова.
В общем, пока тут есть проблемы.
> https://repl.it/@underbottom/repeat3 - Исправил. Я перемудрил.
Ок, верно.
> https://repl.it/@underbottom/value-credit - долго думал, как реализовать вычисления наименьшей цены. Оказалось min сравнивая массивы берёт только валью нулевой строки.(пытался ставить миллион дней результат не поменялся).
Если 3 банка, то можно просто поставить 2 if. Также, можно сделать цикл по массиву, сравнивая каждый элемент с ранее найденным мин. значением. Также, можно отсортировать массив и взять первый элемент.
> $result [0] = 0;
> $result [1] = $i;
Это не очень понятный код, так как непонятно, что хранится в элементах массива. Что значит $result[0]? Лучше использовать переменные, а в конце функции написать:
return [$price, $bankName, ..];
Так виден формат результат и что в нем. Дополнительно можно описать это в комментарии перед функцией.
Я, кстати, не знал про такое использование min() и не встречал такое нигде. Но почему бы и нет.
Решено верно, но код мог бы быть понятнее.
> https://repl.it/@underbottom/ExcitingUnimportantExperiments - переделал регулярку, уверен, что нужно не так. Но вроде работает.
Ошибка 404 при попытке открыть ссылку.
> https://repl.it/@underbottom/repeat1 - переделал регулярку и способ решения.
> $phone = preg_replace ("/\+7/","8",$phone);
тут стоило добавить привязку к началу строки, а то +7 может быть и в середине. В остальном верно.
> https://repl.it/@underbottom/exam-after-chapter - опять перемудрил. Исправил.
Твоя программа считает одиночную латинскую букву вроде x или z ошибкой: https://repl.it/repls/ForsakenUnitedFreesoftware
Также, она должна бы находить русские буквы в латинских словах.
> $word = [];
> $phrases = [];
Эти глобальные переменные никак не используются.
> function makeYodaStyleText($text) {
> $phrases = [];
> $i = 0;
Это можно было не писать.
> ([.|!|?|;])
В квадратных скобках верт. черта не является спецсимволом и не имеет специального значения. Надо писать либо [.!?;] либо \.|!|\?|; . И круглые скобки не нужны тут. Что они делают тут?
> foreach ($word as $idinahooi) {
$words as $word. Как читать твою программу?
Раз ты разбил текст на предложения, можно было сразу же сделать первую букву в предложении заглавной и избавиться от функции fixText.
В общем, сильно переусложнено.
> Квантификаторы - условия задаваемые выражению внутри скобок.
нет, квантификаторы - это символы, которые задают число повторов идущего перед ними символа или выражения. Например: ?, +, *, {...}
> 2) Фигурные скобки. Внутри них задаётся число повторений от n до m.
Верно.
> 3) Круглые скобки - объединяют набор символов и квантификаторов в один элемент(тупая формулировка наверное).
Верно.
> задачка. Число находим вот так [\d]+. Найти число с запятой [\d]+(\,\s).
> >[\d]+(\,\s)*
Нет, неверно. У тебя написано:
искать число, за ним выражение ( запятая, пробел ), которое повторяется любой число раз.
То есть твое выражение это:
число (запятая пробел)*
Но нам надо искать число, за которым может идти сколько угодно других чисел через запятую:
число (пробелы запятая пробелы число)*
Попробуй записать это на языке регулярок.
>>1298000
> https://repl.it/@underbottom/povtorenie1 - (исправление пробелов и заглавные буквы)
Здесь можно было обойтись одним preg_replace:
> $regexp = "/(\S+)(\s)([,.!?:;]+)(\s)/ui";
> $text = preg_replace($regexp,"$1$3",$text);
> $regexp = "/([,.?!:;]+)([a-zа-яё0-9]+)/ui";
> $text = preg_replace($regexp,"$1 $2",$text);
В первом выражении [,.!?:;]+ квантификатор плюс "жадный" ( http://php.net/manual/ru/regexp.reference.repetition.php ) и захватит максимально возможное число символов в тексте. То есть, если там будет многоточие, то эта конструкция захватит все точки в нем. И потому можно одним preg_replace и убрать лишние пробелы, и добавить один пробел после знака.
> function makeLetterUp ($match) {
Эта функция сделана не очень логично, что она принимает массив, а не строку с буквой. Для использования с preg_replace_callback выгоднее было бы использовать анонимную функцию:
$upcaseLetter = function ($match) { ... };
...preg_replace_callback(..., $upcaseLetter);
Или вообще, убрав переменную:
...preg_replace_callback(..., function ($match) {
...
});
Почитать: http://php.net/manual/ru/functions.anonymous.php
Также, у тебя отдельно меняется регистр первой буквы в тексте, а отдельно - первых букв в предложениях. Можно было бы объединить это в одно действие.
А так, решено верно.
> https://repl.it/@underbottom/repeat4 - поправил недочёты.
> [^\\s]
Можно просто \\S
> $changedText=str_replace("здел","сдел",$changedText);
Слово "раздел" будет заменено на "расдел".
> [^,а-я0-9a-z]
ё не входит в диапазон а-я и его надо указывать отдельно.
> (а|но\s)
Здесь \s относится только к "но", но не к "а". Также, здесь проще использовать \b, чтобы указать, что там должна быть граница слова.
В общем, пока тут есть проблемы.
> https://repl.it/@underbottom/repeat3 - Исправил. Я перемудрил.
Ок, верно.
> https://repl.it/@underbottom/value-credit - долго думал, как реализовать вычисления наименьшей цены. Оказалось min сравнивая массивы берёт только валью нулевой строки.(пытался ставить миллион дней результат не поменялся).
Если 3 банка, то можно просто поставить 2 if. Также, можно сделать цикл по массиву, сравнивая каждый элемент с ранее найденным мин. значением. Также, можно отсортировать массив и взять первый элемент.
> $result [0] = 0;
> $result [1] = $i;
Это не очень понятный код, так как непонятно, что хранится в элементах массива. Что значит $result[0]? Лучше использовать переменные, а в конце функции написать:
return [$price, $bankName, ..];
Так виден формат результат и что в нем. Дополнительно можно описать это в комментарии перед функцией.
Я, кстати, не знал про такое использование min() и не встречал такое нигде. Но почему бы и нет.
Решено верно, но код мог бы быть понятнее.
> https://repl.it/@underbottom/ExcitingUnimportantExperiments - переделал регулярку, уверен, что нужно не так. Но вроде работает.
Ошибка 404 при попытке открыть ссылку.
> https://repl.it/@underbottom/repeat1 - переделал регулярку и способ решения.
> $phone = preg_replace ("/\+7/","8",$phone);
тут стоило добавить привязку к началу строки, а то +7 может быть и в середине. В остальном верно.
> https://repl.it/@underbottom/exam-after-chapter - опять перемудрил. Исправил.
Твоя программа считает одиночную латинскую букву вроде x или z ошибкой: https://repl.it/repls/ForsakenUnitedFreesoftware
Также, она должна бы находить русские буквы в латинских словах.
> $word = [];
> $phrases = [];
Эти глобальные переменные никак не используются.
> function makeYodaStyleText($text) {
> $phrases = [];
> $i = 0;
Это можно было не писать.
> ([.|!|?|;])
В квадратных скобках верт. черта не является спецсимволом и не имеет специального значения. Надо писать либо [.!?;] либо \.|!|\?|; . И круглые скобки не нужны тут. Что они делают тут?
> foreach ($word as $idinahooi) {
$words as $word. Как читать твою программу?
Раз ты разбил текст на предложения, можно было сразу же сделать первую букву в предложении заглавной и избавиться от функции fixText.
В общем, сильно переусложнено.
https://repl.it/@underbottom/povtorenie1
https://repl.it/@underbottom/repeat4
https://repl.it/@underbottom/repeat3
https://repl.it/@underbottom/value-credit
https://repl.it/@underbottom/ExcitingUnimportantExperiments
https://repl.it/@underbottom/repeat1
https://repl.it/@underbottom/exam-after-chapter
https://repl.it/@underbottom/yodashuffler
Проверены тут: >>08852
> Допустим, я хочу сделать простенькую игру с сервером на пхп. Это означает, что нужно курить веб сокеты?
Веб-сокеты - это постоянное соединение с сервером (вместо работы по принципу отправил запрос - запустился скрипт - получил ответ). Для их поддержки на сервере надо долгоживущее приложение, которое будет принимать и поддерживать сотни или тысячи соединений. Для этого тебе придется изучить:
- сетевое программирование и сокеты Беркли
- веб-сокеты и что-то вроде WAMP
- ReactPHP для асинхронной работы с сокетами
Если у тебя однопользовательская игра, проще обойтись без сервера. Если многопользовательская - придется делать сервер. Вот тут я писал, как это делают в настоящих играх: https://phpclub.tech/pr/res/1281608.html#1304936
Ты можешь делать на PHP, но если хочешь максимум производительности и десятки тысяч пользователей, то придется задействовать Си/Го/Раст/D/Java - что-то из этого набора. Но если ты не игровая студия, то можно и на PHP сделать.
> Анончики, требуется помощь с задачей ОПа.
> Что я накрутил - ([\s\-()]\+7|8)([\s\-()][0-9]){10}$. Не ищет номер с пробелом между + и 7. Очевидным решение будет написать \s* между ними и тогда всё заработает, но сомневаюсь, что это правильное решение
Вообще-то это будет правильным решением. Если между ними может быть пробел, надо так и написать. Так, регулярка верная.
>>1297532
>>Потому ArrayObject надо оборачивать:
> То бишь, самому реализовать все нужные интерфейсы?
Да. Ты создаешь свой класс, не унаследованный от ArrayObject, и не обязан сохранять совместимость с ним.
>>1293491
> Когда можно начинать выкладывать свой говнокод? У меня нет никаких практических реализаций работающих сайтов, но есть решения небольших задачек. ... Так вот, где публиковать, что читать по этому поводу, есть ли вобще в этом смысл?
Если ты хочешь критику, ты можешь в этот тред выкладывать, может кто-то прокомментирует, или поискать, может есть какие-то форумы, где можно обсудить код. На SO есть https://codereview.stackexchange.com/ , но он на английском - может есть русская версия?
> что делает эта функция? mysqli_fetch_array()
В офиц. мануале написано. Что именно там непонятно?
> И почему в конце mysqli стоит буква i?
Потому что было расширение mysql. Потом сделали улучшенное расширение под названием mysqli (MySQL Improved) и все функции из него имеют этот префикс, чтобы их не перепутали с функциями расширения mysql.
>>1292670
> Единственное что - создаётся ощущение, что я делаю что-то не так. Пока не буду выкидывать код(т.к. он не дописан), но распишу что он из себя представляет. Надеюсь что Добрый Анон скажет где я проебался.
Извини, без примеров кода это трудно.
> И вот когда я начал писать функцию подсчета общего числа работников, зп и прочего, у меня возникло чувство, что я что-то делаю не так. С одной стороны, это можно было запихнуть в объект департамента, а общий итог - в объект компании.
Можно.
> С другой стороны департамент и компания - это абстрактные классы, а значит вызвать или создать объект из них я не смогу.
Зато ты можешь создать объект класса-наследника и на нем вызвать этот метод.
> И да, я столкнулся со вполне очевидной проблемой - не могу найти общую сумму т.к. все свойства объектов я сам же и защитил.
Надо код расчета суммы поместить в тот же самый класс, и тогда он будет иметь доступ к свойствам.
>>1292613
> Задача про калькулятор
eval() лучше избегать по нескольким причинам. Например, что если у тебя нет достаточной фильтрации и пользователь сможет в математическое выражение засунуть вредоносный код, который eval выполнит? Тут он не требуется. Проще сделать функцию вычисления результата с if/elseif внутри.
Вот если ты не боишься очень сложного кода, посмотри, как разработчики PHPExcel реализовали вычисление выражений: https://github.com/PHPOffice/PhpSpreadsheet/blob/develop/src/PhpSpreadsheet/Calculation/Calculation.php
Функции strpos, strlen надо избегать, так как они не поддерживают utf-8: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
Команда
$op;
выглядит странно.
Переменную $flag нужно назвать более осмысленно, чтобы было понятно, что в ней.
Надо сделать сущность "рассылка" и связь многие-ко-многим между рассылками и пользователями, чтобы было записано, кому какая рассылка отправлялась. Сложность в том, что если вставлять запись до отправки письма, то пользователь при ошибке отправки второй раз не будет выбран. А если после - то при ошибке вставки записи пользователь может получить второе письмо.
>>08429
> public function addRooms(array $roomsForAdding)
Это неудобная функция, так как непонятно, какого формата массив в нее передается. Логичнее было принимать сразу массив объектов-комнат. Это гораздо гибче, так как в таком случае можно как угодно настроить эти комнаты, и даже передать вместо комнаты ее наследника (правда, не очень представляю, зачем). А у тебя - нельзя.
Или хотя бы сделать функцию addRoom() с человекопонятными параметрами.
То есть ты зачем-то возлагаешь на Hostel задачу по созданию комнат, хотя это можно делать снаружи. Или тут есть какой-то смысл? Ты в Hostel хочешь контролировать процесс создания комнат?
> echo "Добро пожаловать в гостиницу '$name'";
Это для отладки? в реальном коде такого быть не должно. Представь, ты хочешь на сайте вывести информацию о комнатах, создаешь объект, а он пользователю на страницу выводит надпись "добро пожаловать", причем в самом верху страницы, еще до шапки, и в неправильной кодировке (так как метатег, задающий кодировку, еще не передан).
Гостиница не должна сама ничего выводить. Она только принимает и возвращает значения.
> public function checkGuests(array $guestsList, string $entryDate, string $departureDate)
> string $entryDate
Почему не DateTimeInterface? У нас уже есть объект для представления времени. Это избавляет нас от необходимости проверять правильность строки, например.
> public function checkGuests(array $guestsList, string $entryDate, string $departureDate)
Стоит добавить проверку, что вторая дата больше первой. Это позволит быстро обнаружить ошибку программиста. А так - ошибка останется не замеченной, просто не получится заселить гостей, как будто номеров нету. Это собьет всех с толку и затруднит обнаружение причины проблемы.
> // сортировка пузырьком по (цене/кол-во гостей) по возрастанию
usort тут не подходит? Надо как минимум это выносить в отдельную функцию, это же тяжело читать, там такие многоэтажные выражения.
> $guestsForRegestration = array_slice($guestsList, 0, $roomForRegestration->getCapacity());
> $guestsList = array_slice($guestsList, $roomForRegestration->getCapacity());
Есть array_splice для этого.
В общем, checkGuests слишком большая для понимания, надо ее уменьшить. И кстати, у тебя есть 2 пути - регистрация всех в одном номере и регистрация в нескольких номерах - но ведь первое это частный случай второго и можно использовать для них один и тот же код.
> public function printFreeRooms
Гостиница ничего не выводит. Она должна просто вернуть данные. Выводом занимается внешний код. Разделение ответственности.
> public function printGuestHistory(string $name)
Стоило бы Гостя тоже сделать объектом, можно даже без полей. Ну и интуиция подсказывает, что Гостиница захочет знать, кто вместе с кем приезжает, потому может понадобиться даже ГруппаГостей. Но делать ее пока не надо, раз это не просят.
> if (in_array($name, $regestration->getGuests())) {
Лучше бы сравнивать не имена, а сами объекты. Объект обладает идентичностью, он уникален, и подходит для сравнения.
> for ($fromTheDate; $fromTheDate <= $toTheDate; $fromTheDate->add(new DateInterval('P1D'))) {
> $dailyIncome = 0;
> foreach($this->regestrations as $regestration) {
А нельзя ли тут как-то оптимизироваться за счет, например, сортировки броней по дате? Или, например, первым проходом отсеять брони, попавшие в интервал, а вторым - пройтись по ним и посчитать массив сумм по дням. А то у тебя тут сложность O(days x regestrationsCount) получается.
> if (($entryDate >= $regestration->getEntryDate() && $departureDate <= $regestration->getDepartureDate()) ||
А можно еще сделать if ($regestration->includes($entyrDate)) или даже $regestration->intersects($entry, $departure). Это повысит читабельность. А то ты относишься к объектам как к массивам, которые ничего не умеют кроме хранения данных и ничего сами сделать не способны.
Также, здесь можно было ради читабельности сократить $regestration до $r.
> array_splice($freeRooms, $key, 1);
Плохая новость: у array_splice и у array_search сложность O(N), а у array_key_exists/unset() всего лишь O(1), то есть гораздо быстрее. Массивы заточены на поиск по ключу, а не значению. Можно бы оптимизировать, заменив splice на unset. Еще один вариант - использовать SplObjectStorage, который умеет хранить коллекцию объектов как ключи массива и искать или удалять их за O(1).
Если у нас 100 номеров и 10 000 броней, то получается порядка 100 x 10 000 шагов, а с оптимизацией - в 100 раз меньше.
Это конечно задача на ООП, но почему бы заодно не поучиться оптимизации?
> public function __construct(Room $room, DateTimeImmutable $entryDate, DateTimeImmutable $departureDate, array $guestsList) {
Проверка что одна дата больше другой не помешала бы. Также было бы неплохо для гибкости принимать DateTimeInterface, а не только DateTimeImmutable.
И еще, для проверки можно бы использовать юнит-тесты. Вот я тут подробно про них писал: https://phpclub.tech/pr/res/1281608.html#1303707
И вот что у анона получилось: https://ideone.com/Kj2GBG
Ты бы мог тоже использовать их, не исключая другие способы проверки кода.
> Как правильно разбивать построчно различные конструкции. Вот примеры у меня в коде - 55-60 строки (сокращенный if), 188-192 строки (длинное условие в if-е), 268-274 строки (массив).
А точно ли PSR не говорит?
> 5. Управляющие конструкции
> Перед закрывающими круглыми скобками НЕ ДОЛЖНО быть пробелов.
> Между закрывающей круглой скобкой и открывающей фигурной скобкой ДОЛЖЕН быть один пробел.
Тут кое-что написано. У тебя явно не выполняется требование про отсутствие пробелов перед круглой скобкой.
А вообще, если что-то не определено в PSR, и есть несколько вариантов, то лучше определить это в документации к проекту или в внутрикорпоративном стандарте. Можно также посмотреть, как это сделано в Симфони и сделать так же: https://github.com/symfony/symfony
Также, можно почитать https://github.com/php-fig/fig-standards и поднять вопрос в их mailing list. Например, предложить свой вариант стандарта. Вот здесь ты можешь почитать, как неспешно идет обсуждение новых стандартов: https://groups.google.com/forum/#!forum/php-fig
Надо сделать сущность "рассылка" и связь многие-ко-многим между рассылками и пользователями, чтобы было записано, кому какая рассылка отправлялась. Сложность в том, что если вставлять запись до отправки письма, то пользователь при ошибке отправки второй раз не будет выбран. А если после - то при ошибке вставки записи пользователь может получить второе письмо.
>>08429
> public function addRooms(array $roomsForAdding)
Это неудобная функция, так как непонятно, какого формата массив в нее передается. Логичнее было принимать сразу массив объектов-комнат. Это гораздо гибче, так как в таком случае можно как угодно настроить эти комнаты, и даже передать вместо комнаты ее наследника (правда, не очень представляю, зачем). А у тебя - нельзя.
Или хотя бы сделать функцию addRoom() с человекопонятными параметрами.
То есть ты зачем-то возлагаешь на Hostel задачу по созданию комнат, хотя это можно делать снаружи. Или тут есть какой-то смысл? Ты в Hostel хочешь контролировать процесс создания комнат?
> echo "Добро пожаловать в гостиницу '$name'";
Это для отладки? в реальном коде такого быть не должно. Представь, ты хочешь на сайте вывести информацию о комнатах, создаешь объект, а он пользователю на страницу выводит надпись "добро пожаловать", причем в самом верху страницы, еще до шапки, и в неправильной кодировке (так как метатег, задающий кодировку, еще не передан).
Гостиница не должна сама ничего выводить. Она только принимает и возвращает значения.
> public function checkGuests(array $guestsList, string $entryDate, string $departureDate)
> string $entryDate
Почему не DateTimeInterface? У нас уже есть объект для представления времени. Это избавляет нас от необходимости проверять правильность строки, например.
> public function checkGuests(array $guestsList, string $entryDate, string $departureDate)
Стоит добавить проверку, что вторая дата больше первой. Это позволит быстро обнаружить ошибку программиста. А так - ошибка останется не замеченной, просто не получится заселить гостей, как будто номеров нету. Это собьет всех с толку и затруднит обнаружение причины проблемы.
> // сортировка пузырьком по (цене/кол-во гостей) по возрастанию
usort тут не подходит? Надо как минимум это выносить в отдельную функцию, это же тяжело читать, там такие многоэтажные выражения.
> $guestsForRegestration = array_slice($guestsList, 0, $roomForRegestration->getCapacity());
> $guestsList = array_slice($guestsList, $roomForRegestration->getCapacity());
Есть array_splice для этого.
В общем, checkGuests слишком большая для понимания, надо ее уменьшить. И кстати, у тебя есть 2 пути - регистрация всех в одном номере и регистрация в нескольких номерах - но ведь первое это частный случай второго и можно использовать для них один и тот же код.
> public function printFreeRooms
Гостиница ничего не выводит. Она должна просто вернуть данные. Выводом занимается внешний код. Разделение ответственности.
> public function printGuestHistory(string $name)
Стоило бы Гостя тоже сделать объектом, можно даже без полей. Ну и интуиция подсказывает, что Гостиница захочет знать, кто вместе с кем приезжает, потому может понадобиться даже ГруппаГостей. Но делать ее пока не надо, раз это не просят.
> if (in_array($name, $regestration->getGuests())) {
Лучше бы сравнивать не имена, а сами объекты. Объект обладает идентичностью, он уникален, и подходит для сравнения.
> for ($fromTheDate; $fromTheDate <= $toTheDate; $fromTheDate->add(new DateInterval('P1D'))) {
> $dailyIncome = 0;
> foreach($this->regestrations as $regestration) {
А нельзя ли тут как-то оптимизироваться за счет, например, сортировки броней по дате? Или, например, первым проходом отсеять брони, попавшие в интервал, а вторым - пройтись по ним и посчитать массив сумм по дням. А то у тебя тут сложность O(days x regestrationsCount) получается.
> if (($entryDate >= $regestration->getEntryDate() && $departureDate <= $regestration->getDepartureDate()) ||
А можно еще сделать if ($regestration->includes($entyrDate)) или даже $regestration->intersects($entry, $departure). Это повысит читабельность. А то ты относишься к объектам как к массивам, которые ничего не умеют кроме хранения данных и ничего сами сделать не способны.
Также, здесь можно было ради читабельности сократить $regestration до $r.
> array_splice($freeRooms, $key, 1);
Плохая новость: у array_splice и у array_search сложность O(N), а у array_key_exists/unset() всего лишь O(1), то есть гораздо быстрее. Массивы заточены на поиск по ключу, а не значению. Можно бы оптимизировать, заменив splice на unset. Еще один вариант - использовать SplObjectStorage, который умеет хранить коллекцию объектов как ключи массива и искать или удалять их за O(1).
Если у нас 100 номеров и 10 000 броней, то получается порядка 100 x 10 000 шагов, а с оптимизацией - в 100 раз меньше.
Это конечно задача на ООП, но почему бы заодно не поучиться оптимизации?
> public function __construct(Room $room, DateTimeImmutable $entryDate, DateTimeImmutable $departureDate, array $guestsList) {
Проверка что одна дата больше другой не помешала бы. Также было бы неплохо для гибкости принимать DateTimeInterface, а не только DateTimeImmutable.
И еще, для проверки можно бы использовать юнит-тесты. Вот я тут подробно про них писал: https://phpclub.tech/pr/res/1281608.html#1303707
И вот что у анона получилось: https://ideone.com/Kj2GBG
Ты бы мог тоже использовать их, не исключая другие способы проверки кода.
> Как правильно разбивать построчно различные конструкции. Вот примеры у меня в коде - 55-60 строки (сокращенный if), 188-192 строки (длинное условие в if-е), 268-274 строки (массив).
А точно ли PSR не говорит?
> 5. Управляющие конструкции
> Перед закрывающими круглыми скобками НЕ ДОЛЖНО быть пробелов.
> Между закрывающей круглой скобкой и открывающей фигурной скобкой ДОЛЖЕН быть один пробел.
Тут кое-что написано. У тебя явно не выполняется требование про отсутствие пробелов перед круглой скобкой.
А вообще, если что-то не определено в PSR, и есть несколько вариантов, то лучше определить это в документации к проекту или в внутрикорпоративном стандарте. Можно также посмотреть, как это сделано в Симфони и сделать так же: https://github.com/symfony/symfony
Также, можно почитать https://github.com/php-fig/fig-standards и поднять вопрос в их mailing list. Например, предложить свой вариант стандарта. Вот здесь ты можешь почитать, как неспешно идет обсуждение новых стандартов: https://groups.google.com/forum/#!forum/php-fig
class Child extends Parent {};
interface X
{
public function get(): Parent;
}
interface Y extends X
{
public function get(): Child;
}
Готовится изменение, которое это разрешит: https://wiki.php.net/rfc/covariant-returns-and-contravariant-parameters
Кто там хотел больше правил? Налетайте.
Стандарт еще не принят и можно вносить пожелания и отмечать недостатки вот тут: https://groups.google.com/forum/#!forum/php-fig (читайте правила прежде чем постить).
Вот пока то, что накалякал за сегодня по примерам: https://ideone.com/pG9yPF
Использовал вот этот подход https://phpdelusions.net/pdo_examples/insert#multiple как пример.
Тестовую дату из двух значений она отработала, а вот на 300 массивов по 16 значений уже не переваривает (белый экран без ошибок на локалке с включеным error_reporting(-1); )
Можно и другой формат рассмотреть, где будут отдельно передаваться ключи, и отдельно массив из массивов значений (не ассоциативные), главное что бы это дело отрабатывало как часы и могло за раз сделать в базу хотя бы 10 000 записей.
Губу закатай - с хайлоадом надо ебстись порядочно и простой функцией тут не отделаешься.
Это не особо хайлолад. Просто есть csv файлы которые нужно парсить раз в месяц. В самом большом файле 1.1милиона строк пока.
Или лучше поставить пробельчики Authorizer.authenticate(() => { this.setState({ redirectToReferrer: true }) })?
Или ещё лучше переносить всё на новую строку?
Authorizer.authenticate(() => {
this.setState(
{
redirectToReferrer: true
}
)
});
Нет, ты просто ленишься и предпочитаешь задавать людям тупые вопросы вместо самостоятельных поисков.
Бесполезная хуйня
Бро ты прав как никто. Просто меня пугает документация т.к. раньше я вобще не понимал ни слова там и поэтому мне легче спросить.
Я посидел сейчас 5 блять минут в гугле и всё понял лол
Как с этим бороться?
>Как с этим бороться?
Учить PHP. Именно понимание документации показывает твой уровень владения.
Я тоже раньше боялся, а вчера себя поймал на том, что одним глазом смотрю стрим, а вторым - читаю php.net впрок.
Теперь пугаюсь гитхабов и прочих толстых библиотек.
Привыкай короче.
Значит школьник, 17лвл. В течении 2-х месяцев нужно начать, как минимум самому себя содержать а желательно чуть больше и шоб жить было где. Так вот, прочел значит я летом 4-е издание Робин Никсона "Создаем Динамические сайты...", и еще посоздавал всякого чисто для себя, совсем не мног. Чуть чуть почитал статей да мануала. Естественно немног из того, что рекомендует ОП.
Вроде не глупый, да и в теме нравиться разбиратся. Я очень хорошо обучаюс и готов впахивать. Но тут у меня возникают проблеммы с вектором развития: я просто не понимаю, что за чем будет эффективнее, и в какой момент я стану востребованным юниором. Хочу выйти хотя бы уверенно на фриланс, но пока точно не справлюсс.
Умею еще видосики нарезать, но не более.
Как лучше мне сейчас поступить?
P.S.
Понятно, что сидеть просто так я и сейчас не буду. Просто хотелось бы узнать твою точку зрения анон.
P.P.S.
Наверн часто подобное влетает в тред?
Зачем вобще нужен механизм наследования абстрактных классов, если можно тупо создать класс со статическим методом и вызывать его где только можно?
>Зачем вобще нужен механизм наследования абстрактных классов
Чтобы C++ дебилам было дегче стать Java дебилам.
>можно тупо создать класс со статическим методом и вызывать его где только можно?
Нельзя, получатся жестки связи, а это плохо.
Лучше создать Класс с нужным тебе методом и передавать его в обьект другого класса.
гугли внедрение зависимостей
> 2-х месяцев
Идешь на ВСЕ фриланс биржи, ищешь заказы на WordPress, берешь и делаешь сидишь по 8 и хуяришь, получаешь свои гроши.
Могу попробовать, но с WP не особо дружу, да и не очень он мне нравиться. Как вариант, спасибо
Твой вопрос был бы конечно гораздо лучше, если бы ты привел задачу и примеры классов, а то так абстрактно трудно рассуждать.
> Зачем вобще нужен механизм наследования абстрактных классов
Абстрактный класс нужен, чтобы сделать незаконченный класс, на основе которого создаются другие классы. например, автор библиотеки может сделать абстрактный класс и пару наследников, а пользователь библиотеки сделать пару своих наследников для своих целей.
> если можно тупо создать класс со статическим методом и вызывать его где только можно?
А зачем создавать статический метод, если можно сделать просто функцию? И твой вопрос становится равносилен вопросу "А зачем использовать ООП". Ради упрощения сложного кода, разделения кода на независимые части, ради использования инкапсуляции.
Ну и у абстрактных классов есть, например, возможность определить абстрактные методы. Что-то мне кажется, ты не очень разбираешься в теории.
Абстрактный класс - это незаконченный класс, в котором есть часть функционала, а часть функционала отсутствует и вместо нее стоят заглушки - абстрактные методы. Наследник должен будет реализовать эти методы. Я не представляю, как это можно на что-то другое заменить.
Ну условно, мы делаем редактор схем и хотим иметь возможность представить элементы схемы с помощью классов. При этом мы можем сделать базовый абстрактный класс, с кодом, который применим ко всем элементам, а от него унаследовать конкретные классы с кодом, который относится только к одному типу элемента.
Ну например, в базовом классе может быть абстр. метод "получить количество выводов":
class Element
{
abstract public function getPinCount();
}
Класс резистора определит его как
class Resistor extends Element
{
public function getPinCount()
{
return 2;
}
}
А у транзистора их будет, например, 3. У микросхемы - вообще разное число в зависимости от типа корпуса:
class IC extends Element
{
public function getPinCount()
{
if ($this->packageType == self::DIP_16) {
return 16;
} else ...
...
И я не очень понимаю, как ты это собрался заменять статическими методами.
Может, тебе какую-нибудь задачу на абс. классы решить?
Допустим: сделай классы для представления математического выражения в виде дерева объектов. Выражение состоит из таких элементов:
- целое или дробное число: 2, 3.5
- константы: Пи, e (для Пи есть юникодный символ)
- переменная: x, y, hello_world
- сумма, разность: x + 2 + y
- произведение: 3x, 2*2
- деление: 1/6, (x + 1)/y
- возведение в степень: 2^5
- функции: sin, cos, tan
Нужно сделать классы, представляющие эти конструкции, чтобы мы могли бы создавать выражение из частей, например:
$exp = new Sum(new Number(3), new Variable('x'));
Затем нужно сделать вывод выражения. Выражение выше должно быть выведено как:
3 + x
Затем нужно сделать функцию упрощения выражения. А именно, применить следующие правила:
- в сумме/разности можно сложить все числа в одно: 2 + x + 3 - 1 -> 4 + x
- в произведении можно умножить числа: 2 * 3x -> 6x
- в делении можно делить числа без потери точности: 4/6 -> 2/3, 5x / 5 -> 1x, но нельзя заменить 4/6 на 0.666 так как это не точно. Можно заменить 1.5 / 0.5 -> 3. Нельзя делить на ноль: 2/0 не упрощается.
- в возведении в степень можно заменять числа без потери точности: x ^ (2 ^ 3) -> x^8
- синусы и косинусы для круглых значений можно заменять: sin(pi / 6) -> 1/2.Для некруглых приблизительные вычисления делать нельзя
- можно суммировать одинаковые переменные: 2x + 3x -> 5x
- при умножении на 0 выражение ликвидируется, если в нем нет ошибок: 2x -2x + 3 -> 0x + 3 -> 3. Но нельзя убрать умножение тут: 0 * (2 / 0)
- 0/2 -> 0. 0/x можно заменить на 0 только если x != 0
- умножение/деление на 1 убирается: 1x -> x, y / 1 -> 1
- возведение в 0 степень дает 1, в первую степень - остается то же число: x ^ 1 = x
- можно дополнить список своими правилами
Попробуй при этом использовать возможности ООП. Ну например при желании правила упрощения можно тоже представить в виде объектов. А можно - в виде набора шаблонов, вроде такого:
{n1} {v1} + {n2}{v2} -> {n1 + n2}{v1}
А программа уже применяет эти шаблоны к выражению. Но это ой как сложно. Зато кратко и понятно.
Уверен, тут ты статическими методами не обойдешься
Твой вопрос был бы конечно гораздо лучше, если бы ты привел задачу и примеры классов, а то так абстрактно трудно рассуждать.
> Зачем вобще нужен механизм наследования абстрактных классов
Абстрактный класс нужен, чтобы сделать незаконченный класс, на основе которого создаются другие классы. например, автор библиотеки может сделать абстрактный класс и пару наследников, а пользователь библиотеки сделать пару своих наследников для своих целей.
> если можно тупо создать класс со статическим методом и вызывать его где только можно?
А зачем создавать статический метод, если можно сделать просто функцию? И твой вопрос становится равносилен вопросу "А зачем использовать ООП". Ради упрощения сложного кода, разделения кода на независимые части, ради использования инкапсуляции.
Ну и у абстрактных классов есть, например, возможность определить абстрактные методы. Что-то мне кажется, ты не очень разбираешься в теории.
Абстрактный класс - это незаконченный класс, в котором есть часть функционала, а часть функционала отсутствует и вместо нее стоят заглушки - абстрактные методы. Наследник должен будет реализовать эти методы. Я не представляю, как это можно на что-то другое заменить.
Ну условно, мы делаем редактор схем и хотим иметь возможность представить элементы схемы с помощью классов. При этом мы можем сделать базовый абстрактный класс, с кодом, который применим ко всем элементам, а от него унаследовать конкретные классы с кодом, который относится только к одному типу элемента.
Ну например, в базовом классе может быть абстр. метод "получить количество выводов":
class Element
{
abstract public function getPinCount();
}
Класс резистора определит его как
class Resistor extends Element
{
public function getPinCount()
{
return 2;
}
}
А у транзистора их будет, например, 3. У микросхемы - вообще разное число в зависимости от типа корпуса:
class IC extends Element
{
public function getPinCount()
{
if ($this->packageType == self::DIP_16) {
return 16;
} else ...
...
И я не очень понимаю, как ты это собрался заменять статическими методами.
Может, тебе какую-нибудь задачу на абс. классы решить?
Допустим: сделай классы для представления математического выражения в виде дерева объектов. Выражение состоит из таких элементов:
- целое или дробное число: 2, 3.5
- константы: Пи, e (для Пи есть юникодный символ)
- переменная: x, y, hello_world
- сумма, разность: x + 2 + y
- произведение: 3x, 2*2
- деление: 1/6, (x + 1)/y
- возведение в степень: 2^5
- функции: sin, cos, tan
Нужно сделать классы, представляющие эти конструкции, чтобы мы могли бы создавать выражение из частей, например:
$exp = new Sum(new Number(3), new Variable('x'));
Затем нужно сделать вывод выражения. Выражение выше должно быть выведено как:
3 + x
Затем нужно сделать функцию упрощения выражения. А именно, применить следующие правила:
- в сумме/разности можно сложить все числа в одно: 2 + x + 3 - 1 -> 4 + x
- в произведении можно умножить числа: 2 * 3x -> 6x
- в делении можно делить числа без потери точности: 4/6 -> 2/3, 5x / 5 -> 1x, но нельзя заменить 4/6 на 0.666 так как это не точно. Можно заменить 1.5 / 0.5 -> 3. Нельзя делить на ноль: 2/0 не упрощается.
- в возведении в степень можно заменять числа без потери точности: x ^ (2 ^ 3) -> x^8
- синусы и косинусы для круглых значений можно заменять: sin(pi / 6) -> 1/2.Для некруглых приблизительные вычисления делать нельзя
- можно суммировать одинаковые переменные: 2x + 3x -> 5x
- при умножении на 0 выражение ликвидируется, если в нем нет ошибок: 2x -2x + 3 -> 0x + 3 -> 3. Но нельзя убрать умножение тут: 0 * (2 / 0)
- 0/2 -> 0. 0/x можно заменить на 0 только если x != 0
- умножение/деление на 1 убирается: 1x -> x, y / 1 -> 1
- возведение в 0 степень дает 1, в первую степень - остается то же число: x ^ 1 = x
- можно дополнить список своими правилами
Попробуй при этом использовать возможности ООП. Ну например при желании правила упрощения можно тоже представить в виде объектов. А можно - в виде набора шаблонов, вроде такого:
{n1} {v1} + {n2}{v2} -> {n1 + n2}{v1}
А программа уже применяет эти шаблоны к выражению. Но это ой как сложно. Зато кратко и понятно.
Уверен, тут ты статическими методами не обойдешься
>Просто есть csv файлы которые нужно парсить раз в месяц. В самом большом файле 1.1милиона строк пока.
Очевидный import numpy as np, pandas as pd очевиден
так и есть
Привыкай это не только в пыхе, это везде.
Блядь, запарился уже. Всё перепробовал. Если просто выводишь получаемые данные в браузер и копируешь их, вставляешь в код и отправляешь через heroku же, то все работает. Вручную и через локальный сервер и без этого работает. А когда данные просто получаются извне и отправляются, то обрезаются до первого необычного символа. Все эти utf8_decode, utf8_encode, htmlentities - ничего не помогает, максимум - символы заменяются на š. Как я ненавижу все эти кодировки.
есть строка на входе. Ищу регляркой там дату в определенном формате. нужно к дате добавить например ЗАЛУПА.
исходная - предлагаю 10.04.2014 пообедать.
Сделать:
предлагаю 10.04.2014 Залупа пообедать.
ну оно заменит полностью найденое совпадение, а мне надо добавить прост слово к совпадению.
напиши регулярку, которая будет искать слово пообедать рядом с датой и замени его на залупа пообедать
или можно просто заменить слово пообедать на залупа пообедать, без регулярок, че ты мозги ебешь
https://ideone.com/34FAk8
Специально придумали prettier, чтобы каждый разработчик не делал как ему вздумается: https://github.com/prettier/prettier
Я запускаю его так: prettier --print-width=110 --tab-width 4 --single-quote --trailing-comma=es5 --write"
Алсо почему у тебя авторайзер занимается аутентификацией? Почитай про разницу между авторизацией и аутентификацией: https://stackoverflow.com/a/6367931
Как то тут уютно у вас, господа. Пожалуй пополню ваши ряды. Всем добра.
Добро пожаловать!
На нём говорили древние?
https://simtech.ru/wp-content/themes/simtechrutheme/book/Brett McLaughlin.PHP and MySQL.- 2013.pdf
первый жи код
<?php
echo "Приветствую вас здесь. Слышал, вы учитесь на PHP-программиста!\n";
echo "Почему бы вам не набрать свое имя для меня:\n";
$name = trim(fgets(STDIN));
echo "\nСпасибо, " . $name . ", очень рад с вами познакомиться.\n\n";
?>
нормально не работает!Ни на сервере(у меня сайт есть), ни в онлайн интерпритаторе. Может кто-нибудь объяснить почему. Буду благодарен.
спасибо , анон . Еще бы узнать можно ли это как то запустить на сервере? Ну реалньо, смотрю , полезная вроде книга, но даже первый код не запускается
И пытаться не стоит на данном этапе. Лучше разберись с установкой php, у ОПа есть уроки:
Установка и настройка PHP - https://github.com/codedokode/pasta/blob/master/soft/php-install.md
Как начать пользоваться командной строкой - https://github.com/codedokode/pasta/blob/master/soft/cli.md
ну да, я не профессионал,не понимаю. Но интересный вопрос зачем это выполнять через консоль?Разве php не дл серверов делалось?
Извини, я кое-что недопонл . Зачем мне его устанавливать на комп? У мне есть сайт на серваке, который поддерживает php. Я уже создал там ряд работающих php скриптов, как то , например : скачивани файлов по паролю , форма обратной свзи, автоматическая отправка email. Все они работают.А этот нет? Почему нельзя примеры из этой книге запускать на сервере своего сайта? Их же наверное можно там как-то применить , иначе какой в них смысл? Уж не думал что имея сайт , придется что-то на комп устанавливать
Буду благодарен ответам.
У PHP есть разные режимы (интерфейсы) работы.
PHP-CGI - интерфейс для работы с веб-сервером (через этот интерфейс работает твой сайт).
PHP-CLI - интерфейс для работы из командной строки.
Почему не работает?
Давай посмотрим на fgets(STDIN):
fgets - функция, которая читает строку из файла.
STDIN - это стандартная константа php, её значение - php://stdin.
php://stdin - это поток (файл), в который попадает всё, что ты ввёл с клавиатуры в терминале (командной строке).
В итоге получается, что скрипт пытается прочитать строку из потока, который попросту "не существует", т.к. PHP работает в режиме CGI, а не CLI.
Не знаю как проще обьяснить.
Ну так а как ты с сервером общаешься?
Да , спасибо, щас понял почему не работает.
Просто , безусловно, хотелось бы на сервере применить то что написано в книге.Понятно что не этот конкретно пример.Получается, код что написан в книге не будет работать на сервере?Ну что нибудь там конечно уже более серьезное.
Да ради обучения можно сказать нужное ПО и все это запустить и тп. Но в конечном то итоге все равно все на сервере применять придется. И вот как этого добится? Может есть пособия где сразу на сервере показано?
Начни с гайда в ОП-посте.
>Получается, код что написан в книге не будет работать на сервере?
Будет, просто у тебя знаний не хватает.
>И вот как этого добится?
Перестать задавать тупые вопросы и читать гайд ОП.
>Может есть пособия где сразу на сервере показано?
Иди нахуй
UPD: ,иди читать
но мне интересно применение на сервере
>>10459
просто , щас вот какой момент. В сети есть не мало материалов, про PHP и MySQL , но очень мало где бы было показано как это связано. Допустим даже такой банальный пример как, есть у нас база данных , мы к ней подключились. Пытаюсь использовать функию SHOW TABLES [FROM db_name]; , но выдет ошибки . Вот такая простая вещь. И хоть бы пример хоть одного работающего php кода найти связанный с базой.
<?php
$address = "----"; //Адрес базы данных
$user = "--------"; //Имя пользователя базы данных
$password = "------"; //Пароль пользователя
$name_db = "--------"; //Имя базы данных
//Подключаемся к базе данных
$conn = mysqli_connect($address, $user, $password, $name_db);
if (!$conn) {
die("Conneion failed: " . mysqli_connect_error());
}
echo "Connected successfully";
$result = mysql_query( "SHOW DATABASES");
?>
Почему это может не работать? Connected successfully выводит. То есть все подключились. А тут такая вроде элементарна функия и предупреждения рисует. Наверное я что-то делаю не так, но вот где написано что имено?
просто видешь анон, я ведь вроде понимаю как код работает, по крайней мере котрый кописащу. Я ж не только кописастил, я нашел в сети самоучитель на сайте https://myrusakov.ru , шел по нему. Там вроде более менее понятно. Плюс сразу решил учится на практике, то есть на своем сайте.Если возникали, какие-то задачи,решал их по материалам самоучителя или гуглил, потом под свои нужды правил нагугленый код и тп. Я думал это правельный подход для обучения.
А потом решил сделать систему регистраии-авторизаии, и вот чот не получается. Точнее "регистрировать", то есть вносить в БД из формы на сайте вполне удолось(накопипастил-подправил), но с авторизаией проблемка вышла. Стал гуглить книги, что б понять связь php-mysql, нагуглил то с чем пришел, а она оказывается не для серваков.
Так вот анон, что мне щас посоветуешь, весь гайд с нуля читать? Я ведь вроде понимал что писали в том онлайн самоучителе. Устанавливать ПО на комп , что бы работать по гайду? Оно стоит того?Больше даст чем онлайн самучители? ТАк то ель знания преобрести у меня.
А есть где-нибудь написанная спецификая с договоренностями как писать? Я лучше сам буду писать правильно.
>Я запускаю его так: prettier --print-width=110 --tab-width 4 --single-quote --trailing-comma=es5 --write"
Должен быть отступ в 2 пробела.
https://en.wikipedia.org/wiki/Authentication#Authorization
>The process of authorization is distinct from that of authentication. Whereas authentication is the process of verifying that "you are who you say you are", authorization is the process of verifying that "you are permitted to do what you are trying to do". This does not mean authorization presupposes authentication; an anonymous agent could be authorized to a limited action set.
And also
>For example, a client showing proper identification credentials to a bank teller is asking to be authenticated that he really is the one whose identification he is showing. A client whose authentication request is approved becomes authorized to access the accounts of that account holder, but no others.
So that means that by any mean, authorization is not restricted to make authentication.
Друзья, хочу удалить строку из базы. Пишу запрос в пхп файле: "DELETE FROM db WHERE id_cat = 1". Результата ноль, ошибок тоже нет.
Удаляю эту самую строку из пхп май админ рукой, тупа кликнув удалить и пхп май админ выдает такой запрос
DELETE FROM `db` WHERE `db`.`id_cat` = 5
Вопрос: зачем после WHERE писать db.id_cat? Для чего нужно еще раз указывать название базы?
Порешать онлайн:
Timus Online
codewars
Померятся хуями:
TopCoder
Посмотреть:
Stanford Online Algorithms: Design and Analysis
Robert Sedgewick курс с coursera. Если там закрыли бесплатный доступ, то есть на трекерах.
Почитать современную классику:
CLRS
Thomas H. Cormen
Charles E. Leiserson
Ronald L. Rivest
Clifford Stein
Introduction to Algorithms
Спасибо.
Надеюсь успел ответить, и мой ответ дойдет до тебя.
Если ты хочешь стать как можно быстрей востребованным юниором, то, возможно, с твоим объемом знаний стоит выбрать какой-нибудь фреймворк для PHP и сделать что-нибудь на нём для портфолио. Symfony великолепен.
Выполни на нём задачу про студентов из шапки и/или файлхостинг и этих заний тебе должно хватит чтобы устроится на PHP джуниора.
Может быть как раз за пару месяцев получиться это сделать.
Однако.
Сейчас в вебе преобладает JS. Значит профитней всего будет учить его. Раз ты прочел ту книгу значит должен знать хотя бы его основы.
Отшлифуй знания прочитав mdn https://developer.mozilla.org/bm/docs/Web/JavaScript и/или туториал на https://javascript.info/
Затем ознакомься с нодой https://nodejs.org/en/docs/guides/ https://nodejs.org/en/docs/guides/getting-started-guide/
Затем выбири один или несколько фреймворков: React, Vue, Angular... (перечисленно по мере востребованнсоти), и попутно изучи webpack
Всё что я перечислил это достаточный объем зананий чтобы свободно писать приложения на JS.
Ну и английский естественно must have.
И если ты так хочешь во фриланс, то может быть тебе лучше будет найти просто удалённую работу?
Я не он, но ты хуйню советуешь, настоящие масты идут в девопс, фуллстак. Ты сидишь в Пыхотреде и советуешь JS, ну не ебанутый? Без обид.
>фуллстак
Это которые CMS обслуживают? Они кроме говнокода ничего родить не могут - знают всё, но самые азы.
$DealId="{=Document:ID}";
$res=CCrmDeal::LoadProductRows($DealId);
for($i=0;$i<=count($res);$i++){
if($res[$i]['PRODUCT_ID']==648){
$this->SetVariable('Variable1', 2);
}
}
и
$DealId="{=Document:ID}";
$res=CCrmDeal::LoadProductRows($DealId);
for($i=0;$i<=count($res);$i++){
if($res[$i]['PRODUCT_ID']==647){
$this->SetVariable('Variable1', 1);
}
}
как мне их в один слить? не вот эту проверку
for($i=0;$i<=count($res);$i++){
if($res[$i]['PRODUCT_ID']==648){
$this->SetVariable('Variable1', 2);
if($res[$i]['PRODUCT_ID']==647){
$this->SetVariable('Variable1', 1);
сделать одним куском?
$DealId="{=Document:ID}";
$res=CCrmDeal::LoadProductRows($DealId);
for($i=0;$i<=count($res);$i++){
if($res[$i]['PRODUCT_ID']==648){
$this->SetVariable('Variable1', 2);
}
}
и
$DealId="{=Document:ID}";
$res=CCrmDeal::LoadProductRows($DealId);
for($i=0;$i<=count($res);$i++){
if($res[$i]['PRODUCT_ID']==647){
$this->SetVariable('Variable1', 1);
}
}
как мне их в один слить? не вот эту проверку
for($i=0;$i<=count($res);$i++){
if($res[$i]['PRODUCT_ID']==648){
$this->SetVariable('Variable1', 2);
if($res[$i]['PRODUCT_ID']==647){
$this->SetVariable('Variable1', 1);
сделать одним куском?
Не видел таких.
Должно выйти через array_map.
Аноны, я почти доделал движок по видеоурокам.
Но блять где то в коде я сделал дамп сессии и теперь не могу его найти ааааааа
Вот что делать?
Я бы сделал так:
$foo = function ($fn) {
return function ($item, $key) use ($fn) {
switch ($item['PRODUCT_ID']) {
case 647: return $fn(1);
case 648: return $fn(2);
}
}
}
$bar = function ($v) use ($this) {
$this->SetVariable('Variable1', $v);
}
$DealId="{=Document:ID}";
$res=CCrmDeal::LoadProductRows($DealId);
array_walk($foo($bar), $res)
>Да и 2 вариант понравился.
Двачую, бротиш. Пацаны в жс треде подтвердили, учишь ЕКСПРЕСС + ВУЕ + МОНГО и со старда 300к минимум будешь получать на удалёнке. Говорят, будешь делать СПА с БОГАТЫМ АПИ и АСИНХРОННЫМ БЭКЕНДОМ и горя не знать. Работаешь, говорят, 3 часа в день максимум. Остальное время играешь в эксклюзивы и ссышь пукарям в /v на головы 4к скриншотами. В общем, все советуют подумать о будущем сразу вкатываться в НОД ЖС.
Аноны, у меня в коде вобще нет print_r и var_dump. Я в шоке, как такое может быть? Хелп!
Фича на в том какие педали ты там давишь. Все вменяемые редакторы имеют опцию ставить 4 пробела по нажатию Tab. Нужно для того, что бы код выглядел более менее одинаково, независимо от размера табуляции.
Выучил alert и confirm, можно уже джс джуном идти устраиваться? Или еще надо html выучить?
Ну у тебя из бд прилетает массив же прямо в html шаблоне берешь и хуяришь такую конструкцию:
<? foreach ($arrayOfSomeShit as $shit) : ?>
<div>
<img src="<? echo $shit['img_url']; ?>" />
<span><? echo $shit['title']; ?></span>
</div>
<? endforeach; ?>
Жирным выделил то что является собственно php-кодом внутри твоего html кода. Надеюсь макаба не испортит разметку
Критика приветствуется
https://github.com/02Cetch/xenos
Если кому интересно, то очень помог вот этот курс:
https://www.youtube.com/watch?v=B1Q44OKh5YA&list=PLSdH7dYnlGYht0eGi9-14X87hrSl9plCc
Да, так, баловался. На реакте делал проект, чуть не ёбнулся без Redux. Запутался в архитектуре и сделал кучу костылей. А так реакт, как view часть в SPA - это вещь
Бля молодец.
О, я тоже через пару дней начинаю. Сейчас закончил пхп старт. Дашь какое нибудь напутствие?
Конспекты, ОБЯЗАТЕЛЬНО. Не большие, но по важным темам нужно делать. + читать хотя бы чуть-чуть литературы, которую он к урокам прикрепляет. Выполнять домашку, которую он даёт(не обязательно самостоятельно, можно опять же взять решение на сайте, но, при этом, разобрать всё, что он написал.)
В практике к курсу посоветую не бояться, сесть и запилить комментарии к постам(дальше поймёшь о чём я).
Ну и лично моё правило - уставший и заёбаный? Отдохни и хотя бы 3-5 минут осиль от видео, так хотя бы будешь двигаться потихоньку к своей цели.
Удачи
Спасибо, мужик
да, кстати встречал в задачках учебника глупые моменты
>и АСИНХРОННЫМ БЭКЕНДОМ
Ну-к, на этом моменте поподробней. Возможно ли делать с помощью Vue + React асинхронный server side rendering?
Я ебу? Мне посоны в жс треде сказали... Иди у них спрашивай.
Не надо нас поднимать!
бамп
Я хз, на апворке за далары всё.
Я не знаю, анон. Я сам сделал студентов и файлообменник, плюс еще один говнопроект. Получается говнокод, но с каждым разом получше. Сейчас еще один круд сделаю и начну ларавель задротить. Ну и жс начну учить. Надеюсь к лету вкачусь.
Если пишу код, то могу целый день сидеть. Не знаю часов 8. А если я смотрю какие-нибудь видосы или читаю туториалы всякие, то гораздо меньше. Сразу лень становится и все такое. Короче 1-3 часа в день, если смотрю что-то и до 7-8 часов если пишу код.
Сидеть учить PHP, Laravel, Js, в базах данных разобраться получше, чем просто делать самые простые запросы. Ну и английский. В алгоритмах разобраться хоть на каком-то начальном уровне, чтобы на собеседовании не обосраться. В конце марта - середине апреля уже начну искать работу, ну и просто по собеседованиям ходить (если меня на них пустят ваще, лол). А то типа я могу так и три года сидеть изучать всякую хуйню на васянском уровне, а потом даже джуном не возьмут.
Следующей задачей после регулярки идет задача "Чилса прописью". От нее я просто охуел. Я не знаю как ее решать. В моей голове вообще нету никаких идей и знаний от прочитанных уроков. Искать информацию в уроках ОПа невозможно. Что мне делать, искренне хочу научиться PHP
А что у тебя конкретно не получилось. Пришли свои наработки, пиши вопросы
Для поиска документация же есть, а у опа наглядные картинки, где выбрано основное и разжевано.
Так же сижу - то практика день-два, то теории три. Поначалу так вообще сидел: 7 статей прочитай - одно говно напиши. Уже четвертый месяц так торчу.
Бля а я сижу читаю и одновременно ебашу код, тип проект есть нужно сайт с каким то функционалом до определенного времени создать (Это я для себя цель поставил) и я его сделать должен за месяц.
--мимокрок
Как это чекнуть? Алсо через командную строку всё myqsl исправно добавляет базы, проблема именно в phpmyadmin
Напиши какого пользователя (пароль не надо) ты указываешь в phpmyadmin.
Затем в командной строке зайди в mysql под пользователем или под админом и выведи, какие права даны пользователю:
SHOW GRANTS FOR 'username'@'localhost';
или
SHOW GRANTS FOR CURRENT_USER;
Обрати внимание что в mysql права привязаны к IP адресу. То есть ты можешь дать одни права пользователю x, заходящему с localhost, и другие - пользователю x, зашедшему с 10.0.0.1
Решил проблему, установил более старую версию пхпамйадмина и всё само заработало. Видимо в последней версии разрабы что то напортачили
Мне кажется зря, мог бы просто через права все решить. Присвоить как тебе кот показал.
$letterNumber = 0;
for($i = 0; $i < $maxLength; $i++){
foreach ($lines as $key => $value) {
if (mb_substr($value, $letterNumber, 1) != ""){
echo "|", mb_substr($value, $letterNumber, 1);
} else {
echo "| ";
}
}
echo "|\n";
$letterNumber++;
}
число прописью, я там проверяю десятки и добавляю их в массив, но условие почему то не выполняется
Эта задача сверху вниз слова пишет?
Там $key->$value лишний, можно на $line заменить
Вывод будет такой:
Д | К
ы | о
м | м
Помогите, аноны.
Такая бадья соответственно
https://repl.it/@askarpro24/VivaciousFaithfulScandisk-1
не могу понять как использовать массив из 1й функции чтобы через foreach подставить из массива с (400,20,1) сделать (четыреста,двадцать,один), просто обратиться к массиву из другой функции я так понял нельзя.
//В основном теле программы:
$result = numberToText(421);
$text = smallNumberToText($result,0);
echo $text;
//в smallNumberToText:
$translatedNumber = "";
foreach ($result as $num){
$translatedNumber = $translatedNumber . ' ' . $spelling[$num];
}
return $translatedNumber;
Ну так у тебя нет правил, которые бы задавали центрирование. Элемент с блочным позиционированием можно отцентрировать с помощью трюка с margin = auto:
- http://softwaremaniacs.org/blog/2005/08/27/css-layout-flow/
- и немного тут https://github.com/codedokode/pasta/blob/master/html/positioning.md
Пробежался по статейкам. Так там используется display, в задании сказано, что без него нужно делать. Или я просто тупой
Бля, работает. Спасибо большое
У блочных элементов вроде div по умолчанию стоит display: block, и явно это прописывать не требуется. Думаю, имелось в виду это.
viewer_type=4&api_result=%3C%3Fxml%20version%3D%221.0%22%20encoding%3D%22utf-8%22%3F%3E%0A%3Cresponse%20list%3D%22true%22%3E%0A%20%3Cuser%3E%0A%20%20%3Cuid%3E5159802sex%3E%0A%20%3C%2F
Я пытаюсь декодировать api_result и вытащить из него sex=2. Перечитал весь Stack overflow, ничего не работает. Как вытащить переменную sex из параметра api_result?
Настоящие индейцы уже не декодируют полученные строки?
Прогони через
http://php.net/manual/ru/function.urldecode.php
Я прогонял, няша. Он выдает мне списком все данные оттуда имя фамилия пол. А как вытащить конкретную переменную?
Ты умеешь работать с XML и массивами в PHP? Если нет, то иди читай теорию, так как невооруженным глазом видно, что строка в XML.
>как вытащить конкретную переменную?
В документации должны быть описаны типы данных со всеми ключами.
Просто прогоняешь черед декодеру url, потом декодеру json, и в результате просто указываешь ключ.
Почитай ещё доки по декодеру json - там есть подводный камушек.
>>12416
>XML
Там json, как я видел.
>$result = numberToText(421);
>$text = smallNumberToText($result,0);
>echo $text;
спасибо, теперь разобрался как вызывать функции чтобы они массив возвращали
заработало вот так:
<?php
$string = $_GET['api_result'];
$xml = simplexml_load_string($string);
$json = json_encode($xml);
$array = json_decode($json,TRUE);
echo $array['user']['sex'];
?>
Всем спасибо за совет, целую вас в аунсы каждого.
Сеньор Регулярка Девелопер?
>json_encode
>json_decode
Ты сперва закодировал, потом раскодировал.
$response = $_GET['api_result'];
>рас
$json= urldecode($response);
>дфа
$result= json_decode($json,TRUE);
И готово.
echo $result['user']['sex'];
>8 часовой курс про регулярки
Есть ссылка на курс? Может я чего упустил, когда за полчаса их освоил? Вдруг ими Абу можно унижать?
Что плохого, что человек хочет нормально разобраться в предмете, а не проскочить и потом задавать вопросы, как извлечь текст из строки?
Хочешь нормально разобраться - напарси говна через регулярки, а курсы хоть 24 часа смотри - без практики толку 0.
Никак. Пиши каждый день немного кода. Само запомнится до уровня автомата.
Вот курс https://www.youtube.com/playlist?list=PLT0-cCYWU-_SIlYYwScRLLKpTRQlTqp1r
Ну скажите мне чего почитать чтобы делать что-нибудь типо этого http://php.net/manual/ru/tutorial.forms.php
Так и запоминаем. В голове только часто используемые функции и основные операторы синтаксиса. За специфическими фичами приходится лазать в доки.
На хтмлакадеми фастом проходишь основы хтмл, там формы будут, потом у опа читаешь про http(get,post), как поставить wamp. Можешь ещё это все в видосах php start глянуть, тут советовали пару раз.
Что то я не нашел вменяемого способа. Или упаковывают foreach в функцию и рекурсивно вызывают ее или упаковывают в цикл while.
Короче, сам замутил чота такое. Делает 10 попыток и завершает цикл. Как раз сегодня про goto узнал.
$num = 0;
repeat:
foreach($list as $id) {
действия
if ($id == null) {
if ($num < 10) {
$num++;
goto repeat;
} else {$num = 0; break;}
}
}
Забыл, что отступы убираются. А о том, что они превращаются в \t, я вообще не знал. Прастити.
goto это пиздец...
1. Можно вынести foreach в функцию и просто выходить из неё когда надо, сбрасывая его.
2. Посмотри на пхп.нет про итераторы-генераторы.
goto не используй вообще никогда - нинужно и говнокод.
В шапке все ссылки есть, ищи.
Пытаешься изобрести bnb?
Произошёл пиздец, старый конфиг наебнулся, сделал новый. Далее:
>vagrant up
А мне консоль в ответ
>Microsoft Windows [Version 6.1.7601]
C:\Users\55555>cd /d T:\m2\www\laravel-dev\homestead
T:\m2\www\laravel-dev\homestead>vagrant up
Bringing machine 'homestead-7' up with 'virtualbox' provider...
==> homestead-7: Box 'laravel/homestead' could not be found. Attempting to find
and install...
homestead-7: Box Provider: virtualbox
homestead-7: Box Version: >= 6.3.0
==> homestead-7: Loading metadata for box 'laravel/homestead'
homestead-7: URL: https://vagrantcloud.com/laravel/homestead
==> homestead-7: Adding box 'laravel/homestead' (v6.4.0) for provider: virtualbo
x
homestead-7: Downloading: https://vagrantcloud.com/laravel/boxes/homestead/v
ersions/6.4.0/providers/virtualbox.box
==> homestead-7: Box download is resuming from prior download progress
homestead-7: Progress: 0% (Rate: 31580/s, Estimated time remaining: 19:30:02
homestead-7: Progress: 0% (Rate: 38358/s, Estimated time remaining: 17:40:50
homestead-7: Progress: 0% (Rate: 49230/s, Estimated time remaining: 16:16:52
homestead-7: Progress: 0% (Rate: 40903/s, Estimated time remaining: 16:35:30
homestead-7: Progress: 0% (Rate: 34871/s, Estimated time remaining: 17:01:47
homestead-7: Progress: 0% (Rate: 21877/s, Estimated time remaining: 18:20:30
homestead-7: Progress: 0% (Rate: 16459/s, Estimated time remaining: 18:56:37
homestead-7: Progress: 0% (Rate: 20666/s, Estimated time remaining: 19:28:40
homestead-7: Progress: 0% (Rate: 17938/s, Estimated time remaining: 20:52:37
homestead-7: Progress: 0% (Rate: 17998/s, Estimated time remaining: 21:06:38
homestead-7: Progress: 0% (Rate: 30227/s, Estimated time remaining: 20:13:23
homestead-7: Progress: 0% (Rate: 37105/s, Estimated time remaining: 19:57:13
homestead-7: Progress: 0% (Rate: 38358/s, Estimated time remaining: 20:03:33
homestead-7: Progress: 0% (Rate: 31266/s, Estimated time remaining: 20:07:17
homestead-7: Progress: 0% (Rate: 34983/s, Estimated time remaining: 19:35:12
homestead-7: Progress: 0% (Rate: 40784/s, Estimated time remaining: 19:14:06
homestead-7: Progress: 0% (Rate: 45479/s, Estimated time remaining: 19:05:20
homestead-7: Progress: 0% (Rate: 45256/s, Estimated time remaining: 18:32:13
)
Произошёл пиздец, старый конфиг наебнулся, сделал новый. Далее:
>vagrant up
А мне консоль в ответ
>Microsoft Windows [Version 6.1.7601]
C:\Users\55555>cd /d T:\m2\www\laravel-dev\homestead
T:\m2\www\laravel-dev\homestead>vagrant up
Bringing machine 'homestead-7' up with 'virtualbox' provider...
==> homestead-7: Box 'laravel/homestead' could not be found. Attempting to find
and install...
homestead-7: Box Provider: virtualbox
homestead-7: Box Version: >= 6.3.0
==> homestead-7: Loading metadata for box 'laravel/homestead'
homestead-7: URL: https://vagrantcloud.com/laravel/homestead
==> homestead-7: Adding box 'laravel/homestead' (v6.4.0) for provider: virtualbo
x
homestead-7: Downloading: https://vagrantcloud.com/laravel/boxes/homestead/v
ersions/6.4.0/providers/virtualbox.box
==> homestead-7: Box download is resuming from prior download progress
homestead-7: Progress: 0% (Rate: 31580/s, Estimated time remaining: 19:30:02
homestead-7: Progress: 0% (Rate: 38358/s, Estimated time remaining: 17:40:50
homestead-7: Progress: 0% (Rate: 49230/s, Estimated time remaining: 16:16:52
homestead-7: Progress: 0% (Rate: 40903/s, Estimated time remaining: 16:35:30
homestead-7: Progress: 0% (Rate: 34871/s, Estimated time remaining: 17:01:47
homestead-7: Progress: 0% (Rate: 21877/s, Estimated time remaining: 18:20:30
homestead-7: Progress: 0% (Rate: 16459/s, Estimated time remaining: 18:56:37
homestead-7: Progress: 0% (Rate: 20666/s, Estimated time remaining: 19:28:40
homestead-7: Progress: 0% (Rate: 17938/s, Estimated time remaining: 20:52:37
homestead-7: Progress: 0% (Rate: 17998/s, Estimated time remaining: 21:06:38
homestead-7: Progress: 0% (Rate: 30227/s, Estimated time remaining: 20:13:23
homestead-7: Progress: 0% (Rate: 37105/s, Estimated time remaining: 19:57:13
homestead-7: Progress: 0% (Rate: 38358/s, Estimated time remaining: 20:03:33
homestead-7: Progress: 0% (Rate: 31266/s, Estimated time remaining: 20:07:17
homestead-7: Progress: 0% (Rate: 34983/s, Estimated time remaining: 19:35:12
homestead-7: Progress: 0% (Rate: 40784/s, Estimated time remaining: 19:14:06
homestead-7: Progress: 0% (Rate: 45479/s, Estimated time remaining: 19:05:20
homestead-7: Progress: 0% (Rate: 45256/s, Estimated time remaining: 18:32:13
)
чёт обосрался. ебался с регулярками, оказывается в пхп есть функция filter_input которая заменяет длинную регулярку одним словом
Постоянно такая хуйня.
1. Не понял.
2. Еще сильнее не понял.
И я не понимаю, почему говнокод? Запись короткая, читается легко, работает хорошо.
>И я не понимаю, почему говнокод? Запись короткая, читается легко, работает хорошо.
Потому что говнокод. Запись короткая, читается легко и все прочее - это пока у тебя скрипт на 10 строк. Если бы все скрипты были в 10 строчек, то ваще не нужно ни ооп, ни всякая другая хуйня, все сразу понятно. А так ты высрешь в процедурном стиле скрипт на 500 строк с бесконечными циклами, разветлениями и прочей залупой. А сверху еще приправишь это goto. И твой код нельзя будет без ящика водки прочитать.
>И твой код нельзя будет без ящика водки прочитать.
Это заблуждение. Если писать говно, то и с ООП и без ООП говно будет. А если писать нормально, то и в процедурном, и в ООП, и даже с гоуту хороший код будет.
Это довольно плохой код. Идея структурного кода (это когда ставят фигурные скобочки и отступы) в том, что мы видим блоки в коде и при беглом анализе можем читать код по диагонали.
То есть мы видим
if () {
...
}
x();
И понимаем, что независимо от того, выполнится if или нет, управление дойдет до вызова x() (если только там нет return или throw). А с goto логика выполнения может быть сколь угодно запутанной.
Также, у тебя не соблюдаются отступы.
Если тебе надо сделать что-то с 10 попыток - сделай цикл от 1 до 10 и вызывай функцию N раз. А ты пишешь это каким-то запутанным способом, выворачивая все наизнанку. Зачем?
Также, есть break. Если ты про него не знал, то тебе надо начать с перечитывания мануала по PHP.
>Делает 10 попыток и завершает цикл
>Как раз сегодня про goto узнал
А про for ты ещё не узнал? Нахуевертил чёрт пойми чего. Выглядит так, будто ты меня в жопу этим кодом послал.
Лучше бы просто описал чего конкретно хочешь.
>>13031
>Если писать говно, то и с ООП и без ООП говно будет
Если человек дорос до использования ООП, то уже понимает зачем это и почему.
>даже с гоуту хороший код будет
НЕ-БУ-ДЕТ. Это низкоуровневая хуета из ассемблера.
Используют её 2 типа людей: 1 - дикие нубасы-говнокодеры, и 2 - годные спецы на диких и очень специфичных задачах, когда обычным методом выйдет хуже и сложнее.
>Если человек дорос до использования ООП, то уже понимает зачем это и почему.
Нихуя. Мало кто правильно использует ООП. В основном вырвиглазная неподдерживаемая хуита.
>НЕ-БУ-ДЕТ. Это низкоуровневая хуета из ассемблера.
Если используется так, что понятно что происходит, то почему бы и нет?
>Мало кто правильно использует ООП.
Чего ты несёшь? Давай показывай тогда как правильно - код свой приведи, или кукаретик.
>Если используется так, что понятно что происходит, то почему бы и нет?
В твоём правильном ООП, ты хочешь сказать?
>Чего ты несёшь? Давай показывай тогда как правильно
Правильно это как-то так: https://github.com/yegor256/takes
>В твоём правильном ООП, ты хочешь сказать?
Да в любом, где есть хоть немного императивного кода.
>Правильно это как-то так: https://github.com/yegor256/takes
Там обычный ООП, пионер.
>Да в любом, где есть хоть немного императивного кода.
В приведённой тобой ссылке покажи.
Ты главное гото почаще ставить в код не забывай, ссылаясь на настоящий ООП и срать левыми ссылками в ответ на реквест пруфа своих навыков.
> низкоуровневая хуета из ассемблера.
Читал про разработку первых электронных таблиц VisiCalc (1978) - интересно, что там, хоть и писали на ассемблере, использовали макросы для имитации if/else: http://rmf.vc/implementingvisicalc
> The assembler had macros so that instead of directly coding to the machines conditional instructions I could use an "aif/aelse/aendif" set in order to assure that the structure of the code was maintained.
А тут можно увидеть кусочек кода с do/until: http://www.bricklin.com/history/saiearly.htm
> Если используется так, что понятно что происходит, то почему бы и нет?
Потому что с структурными конструкциями будет понятнее. Может, конечно, есть ситуации, когда goto понятнее, но я что-то такого припомнить не могу. В Си его используют для освобождения ресурсов, но в PHP обычно такой проблемы нет.
Приведи пример, где goto имеет преимущество перед структурным программированием.
>там, хоть и писали на ассемблере
Так это, по-моему, первое, чему учат программеров - наглядности кода, а goto тут явно расходится с парадигмой.
Да даже доморощенные макаки как-то понимают, что goto это путь в жопу и алкоголизм.
>Приведи пример, где goto имеет преимущество перед структурным программированием.
Да хотя бы организовать быстрый выход из нескольких вложенных циклов. Есть, конечно, языки с чем-нибудь типа break n;
Но в питоне, например, нет такой конструкции, и гото тоже нет, лол, и приходится извращаться.
>хотя должен заработать index.php
Он у тебя не пустой надеюсь? Вывод ошибок включен?
Просто надо исключить сам пхп.
Сам недавно трахался, то только с апачем - есть убунта серв, ну типичный такой lamp, только пых там не заводится - модуль не подключается. А не подключается потому, что его нету в списке модулей, хотя ставил. Возможно это из-за того, что я php на консолько ставил изначально. Думаю снести всё это дело и поставить по гайду.
>организовать быстрый выход из нескольких вложенных циклов
>goto
В аду заставляют работать с твоим кодом.
Красиво, наверное, выглядит этот бросок через десятки строк и конструкций, вникуда.
>не пишу больше десяти строк в одной процедурке. А уж в циклах и подавно.
>быстрый выход из нескольких вложенных циклов
Кто-то запизделся.
Не, ну если брать во внимание строчки с одной операторной скобкой по PSR-2, то, таки, да, я напиздел, лол.
>путает скобки и вложенные циклы
>юзает гото
>называет кого-то имбецилом
А ты шутник, как я посмотрю.
Иди нахуй, короче. А то ОП придёт и во флуде обвинит из-за тебя - мудака жопорукого.
А ты, типа, не используешь операторные скобки при написании циклов?
Кроме того, я лишь сказал, что в гото ничего плохого нет, если его правильно готовить, а твое больное воображение нарисовало, что я его использую везде, лол.
Примерно та же ситуация. Интересных задач нету, а бессмысленное говно писать, ненужное никому, смысла нету. Вот и сидим как фуфелы.
почему нет треда совместной разработки? можно было бы вместе реализовать интересное говно, заодно получив опыт работы в команде
так возьми отпуск. сходит в баньку с посонами. водовки наверни, блядей помацай
на ёбаной пыхе свет клином не сошелся
Бля ахаха сделал мой день анон
Вот, что мне в голову приходит:
- трейт для контроллера с какой-то небольшой полезной функцией. Ну например, функцией отдачи файла с выставлением нужных заголовков (FileSenderTrait). Или функцией выдачи какой-то ошибки. В теории, это можно вынести в сервис, или в базовый класс, или в статический utility метод. Вынесение в базовый класс может привести к загромождению базового класса ненужным функционалом. Статический метод, как и отдельный сервис, не имеет доступа к состоянию контроллера и его защищенным методам. В то же время, подключить трейт довольно просто и удобно.
- трейт для добавления функционала в модели. Ну например, мы хотим в несколько моделей Доктрины добавить поля "когда и кто последним редактировал сущность". Это удобно оформить в виде трейта. По-другому невозможно, так как множественное наследование не разрешено.
Трейты можно тестировать, хотя для этого придется сделать пустой класс-хозяин.
Какие есть минусы?
Люди могут начать подключать зависимости класса в виде трейтов вместо использования отдельного класса и DI. Это плохо, если например, зависимость - это HTTP клиент с кешем, то при включении ее как трейта в каждом классе будет свой экземпляр кеша. Важно не использовать трейты как замену DI (как и статические методы на замену DI).
Сейчас у трейтов нет способа задать требования к классу-хозяину. Ну например, трейт вызывает какой-то метод хозяина, но в момент подключения трейта наличие этого метода не проверяется. Мне кажется, это можно решить, добавив в трейт "требования", чтобы класс был наследником класса, реализовывал какой-то интерфейс или включал другой трейт:
trait LastEditLogger requires SomeBaseClass, SomeInterface, SomeOtherTrait.
Также, у трейтов нет конструкторов и нельзя сделать инициализацию.
Также, надо, чтобы трейт можно было указать в качестве тайп-хинта:
function x(SomeTrait $y)
А вы, аноны, видите в таком подходе какие-то минусы? И видите другие применения трейтов? Поломайте голову, если хотите лучше разбираться в ООП.
Вот, что мне в голову приходит:
- трейт для контроллера с какой-то небольшой полезной функцией. Ну например, функцией отдачи файла с выставлением нужных заголовков (FileSenderTrait). Или функцией выдачи какой-то ошибки. В теории, это можно вынести в сервис, или в базовый класс, или в статический utility метод. Вынесение в базовый класс может привести к загромождению базового класса ненужным функционалом. Статический метод, как и отдельный сервис, не имеет доступа к состоянию контроллера и его защищенным методам. В то же время, подключить трейт довольно просто и удобно.
- трейт для добавления функционала в модели. Ну например, мы хотим в несколько моделей Доктрины добавить поля "когда и кто последним редактировал сущность". Это удобно оформить в виде трейта. По-другому невозможно, так как множественное наследование не разрешено.
Трейты можно тестировать, хотя для этого придется сделать пустой класс-хозяин.
Какие есть минусы?
Люди могут начать подключать зависимости класса в виде трейтов вместо использования отдельного класса и DI. Это плохо, если например, зависимость - это HTTP клиент с кешем, то при включении ее как трейта в каждом классе будет свой экземпляр кеша. Важно не использовать трейты как замену DI (как и статические методы на замену DI).
Сейчас у трейтов нет способа задать требования к классу-хозяину. Ну например, трейт вызывает какой-то метод хозяина, но в момент подключения трейта наличие этого метода не проверяется. Мне кажется, это можно решить, добавив в трейт "требования", чтобы класс был наследником класса, реализовывал какой-то интерфейс или включал другой трейт:
trait LastEditLogger requires SomeBaseClass, SomeInterface, SomeOtherTrait.
Также, у трейтов нет конструкторов и нельзя сделать инициализацию.
Также, надо, чтобы трейт можно было указать в качестве тайп-хинта:
function x(SomeTrait $y)
А вы, аноны, видите в таком подходе какие-то минусы? И видите другие применения трейтов? Поломайте голову, если хотите лучше разбираться в ООП.
теперь мне опять нужно писать на слонике.
Я теперь не могу нормально относится к этому синтаксису. Что делать?
>Сейчас у трейтов нет способа задать требования к классу-хозяину. Ну например, трейт вызывает какой-то метод хозяина, но в момент подключения трейта наличие этого метода не проверяется.
А разве нельзя в трейте просто создать необходимы абстрактные методы? Тогда класс, использующих их должен реализовать эти методы.
Я-новичек-если-сказал-хуйню-не-бейте-лучше-обоссыте
Inteface + trait>>13439
>- трейт для контроллера с какой-то небольшой полезной функцией. Ну например, функцией отдачи файла с выставлением нужных заголовков (FileSenderTrait). Или функцией выдачи какой-то ошибки.
Тупое говно тупого говна.
Лучше это решать через композицию.
Сервисы, DTO.
>- трейт для добавления функционала в модели. Ну например, мы хотим в несколько моделей Доктрины добавить поля "когда и кто последним редактировал сущность". Это удобно оформить в виде трейта.
Да можно, типа TimestampTrait. Ток надо проверить сможет ли доктрина прочитать анотации в трейте.
>Какие есть минусы?
Мало кто умеет ими пользоваться. Обычно не очень умные ларавельщики начинают пихать в трейты дохуя логики, потом эти трейты плодятся и становятся взаимоисключающими)
>>13439
>Также, надо, чтобы трейт можно было указать в качестве тайп-хинта:
Трейты можно в тайпхинте использовать.
>>13439
>И видите другие применения трейтов?
Interface + trait.
У тебя ксть какой-то интерфейс, в нем много болерплейтной логики, которую по сути можно было, не руками копипастить, а например унаследовать.
Наследоваться мы можем только от одного класса.
Получается что мы не даем классу наследоваться от другого класса, только из-за какого-то болерплейтного кода.
Вот сюда приходят на помощ трейты.
Пример использования:
https://github.com/igorw/evenement/tree/master/src/Evenement
Inteface + trait>>13439
>- трейт для контроллера с какой-то небольшой полезной функцией. Ну например, функцией отдачи файла с выставлением нужных заголовков (FileSenderTrait). Или функцией выдачи какой-то ошибки.
Тупое говно тупого говна.
Лучше это решать через композицию.
Сервисы, DTO.
>- трейт для добавления функционала в модели. Ну например, мы хотим в несколько моделей Доктрины добавить поля "когда и кто последним редактировал сущность". Это удобно оформить в виде трейта.
Да можно, типа TimestampTrait. Ток надо проверить сможет ли доктрина прочитать анотации в трейте.
>Какие есть минусы?
Мало кто умеет ими пользоваться. Обычно не очень умные ларавельщики начинают пихать в трейты дохуя логики, потом эти трейты плодятся и становятся взаимоисключающими)
>>13439
>Также, надо, чтобы трейт можно было указать в качестве тайп-хинта:
Трейты можно в тайпхинте использовать.
>>13439
>И видите другие применения трейтов?
Interface + trait.
У тебя ксть какой-то интерфейс, в нем много болерплейтной логики, которую по сути можно было, не руками копипастить, а например унаследовать.
Наследоваться мы можем только от одного класса.
Получается что мы не даем классу наследоваться от другого класса, только из-за какого-то болерплейтного кода.
Вот сюда приходят на помощ трейты.
Пример использования:
https://github.com/igorw/evenement/tree/master/src/Evenement
Нахуй оно нужно? Чтобы забить пробел между интерфейсами и наследованием: нет как множественного наследования, так и дефолтной имплементации у интерфейсов. Трейт - это код, который копипастится в твой класс с.
Вот тебе некоторый абстрактный пример:
https://ideone.com/jZYlWs
сел за комп , головокружение, затупы, как будто сильно нервничаю. Раньше сидел играл в ту же дотку по 5-8 часов к ряду и все было збс, а сейчас ни по прогать ни поиграть нормально не могу. Всего лишь 23лвл, может у кого похожее было, как фиксить?
Возможно, микроинсульт схватил, сходи к врачу.
Ыыы а у меня спондилез шеи в 20.
В пизду блядство и алкоголизм - я у мамы погроммист.
Да, голова болит довольно часто если перестаю соблюдать режим, шея хрустит при резких поворотах либо когда наклоняю голову назад.
Некогда обьяснять, мышцы твоей шеи в хлам после сидений(плюс ты наверняка напрягаешься и пережимаешь все что угодно), ложишься на ровное, вытягиваешься, на спине поднимаешь голову(как маленький ребенок если ты видел, когда он учится шею держать) 5-6 подходов по 5-10 секунд держания на весу
Чем выше держишь, тем легче, со временем можно будет совсем немного поднимать и это будет обеспечивать хорошую нагрузку
На животе руки по швам смотришь вниз(не вперед) - то же самое делаешь, аля маня учится ползать в кроватке в годик
Через недельку должно быть полегче, ключевые слова "нестабильность шейного отдела позвоночника"
Делаю постоянно перед сном, если совсем пиздец можно погреть в ванной
цэпэ! тоже делает упражнениее второе
>>13830
Спасибо за советы, но думаю это одна из проблем. Такая вещь как тут >>13562 еще происходит если выпить кофе/какао. У врача был, поставил ВСД, но в интернетах пишут что этот диагноз все совковые врачи ставят, а на платных еще не заработал.
Еще на счёт шеи, может какую гель/мазь посоветуйте?
Извиняюсь сразу за оффтопы, просто это решает судьбу, не представляю как я буду работать по 8 часов в офисе если дома не могу и 2-3 часов нормально поучиться.
Сами темпы обучения идут быстро, планирую уже через 6-8 месяцев искать работку
У меня была подобная проблема. Занялся легким спортом и она ушла. Сейчас забросил и периодически проблема возникает.
Мази все хуйня, укрепляй мышцы регулярными несложными упражнениями, чай можно не пить, всд хуйня, начинай думать о здоровье, вон космонавты тоже по кайфу чилят в невесомости, но потом если не будут там заниматься по пизде сразу всё пойдет как спустятся, те же перегрузки отсутствием нагрузки
всд + па стаж 5+ лет
Шапка опа.
Посоны, есть такое желание: получать переменные окружения для всех сайтов на хостинге (сайтов много - больше 50) из одного источника, не копируя в каждый виртуальный хост apache.
Но веб-сервер ограничен в правах и не может получать переменные окружения из /etc/profile.d например.
Как быть? Как делают гуру?
нигде не нужен чисто пых прогер, обычно нужно знать пых, хтмл, жс и прочую малафью
Грань между бекендом и фронтом щас размывается. Можно хуярить всё на одном языке (js). Ты со своим "онли пхп" уже динозавр.
Да дохуя знать надо. Может если только ты выпускник вуза какого-нибудь в Москве, можешь изи вкатиться на джуна. Там вроде вакансии есть с требованиями аля знать синтаксис php. А так ебашить придется и учить много хуеты. Я сам начал джс учить потихоньку так лень пиздец.
>>14065
Покажи код!
>>14078
>То есть если я просто хочу клепать сайтики на bitrix, wordpress за дошикм, надо столько всякой ебалы знать?
Зависит от требований работодателя. Мы не можем знать что ему потребуется. Наблюдай за рынком, смотри что требуется.
Моё личное мнение, JS для проектов на таких помойных фреймворках обладает таким же низким уровнем вхождения. А промисы и коллбэки, это не конкретная специфика JS и есть в любом языке. Понимание этого зависит от твоего общего уровня программирования. Коротко говоря, моя мысль заключается в том, что ты можешь изучить и JS, и это так же легко как html/css для твоего выбранного уровня.
А что в массивах находится показать? Пожалуйста, старайся выдать максимальное количество информации о своей проблемы за один пост, дабы не разводить флуд.
>Моё личное мнение, JS для проектов на таких помойных фреймворках обладает таким же низким уровнем вхождения.
Там весь Джай Асс - прикрутить Джай Куэри и поназначать селекторы для эффектов. Где там программирование вообще? Мартышки отлично справляются тыкая наугад.
Уровень ПХП там точно такой же.
мимоковырятель вордпресса палочкой
>while($row = mysqli_fetch_array($result)) {
> $array[] = $row[0];
> $array1[] = $row[1];
>}
Во-первых, ты можешь воспользоваться выражением ключ -> значение в массиве, то есть ключом элемента массива будет название имени столбца полученного из БД (базы данных), а значением будет его значение.
[
'name' => 'Boris'
'password' => '12345'
]
Для этого тебе нужно воспользоваться оператором foreach
https://secure.php.net/manual/ru/control-structures.foreach.php
Подумай сам как это сделать.
Подсказка:
foreach($row as $key => $value) {
...
}
>$array = array();
Можно писать проще $array = [];
Переменные лучше называть тем что они обозначают, т.е. $array лучше переименовать в $users.
Затем, ты складываешь в $array все значения имён, а в $array1 все значение паролей, потом выводишь на новую строку <tr> данные имен <td> из $array и закрываешь эту строку </td>, и снова создаешь новую строку и выводишь в неё данные паролей из $array1. Кстати, при выводе $array1 ты в цикле обходишь $array >for($i=0;$i< count($array);$i++){ print_r($array1[$i])... Тебе нужно в каждой строке выводить данные И имён, И паролей.
Также, почитай про разделение логики и представления. Тебе понадобиться это в будущем, если ты планируешь дальше изучать PHP.
Например это:
https://true-coder.ru/php/razdelenie-koda-i-shablona-mvc-chast-1.html
https://true-coder.ru/php/razdelenie-koda-i-shablona-mvc-chast-2.html
mysqli уже давно устаревшая технология, и все пользуются PDO.
https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
https://secure.php.net/manual/ru/book.pdo.php
Если ты хочешь научиться PHP, то прочитай шапку этого треда, там много полезных ссылок и задач от которых твои навыки просто взлетят вверх.
Можешь свободно задавать любые вопросы если они появились.
>while($row = mysqli_fetch_array($result)) {
> $array[] = $row[0];
> $array1[] = $row[1];
>}
Во-первых, ты можешь воспользоваться выражением ключ -> значение в массиве, то есть ключом элемента массива будет название имени столбца полученного из БД (базы данных), а значением будет его значение.
[
'name' => 'Boris'
'password' => '12345'
]
Для этого тебе нужно воспользоваться оператором foreach
https://secure.php.net/manual/ru/control-structures.foreach.php
Подумай сам как это сделать.
Подсказка:
foreach($row as $key => $value) {
...
}
>$array = array();
Можно писать проще $array = [];
Переменные лучше называть тем что они обозначают, т.е. $array лучше переименовать в $users.
Затем, ты складываешь в $array все значения имён, а в $array1 все значение паролей, потом выводишь на новую строку <tr> данные имен <td> из $array и закрываешь эту строку </td>, и снова создаешь новую строку и выводишь в неё данные паролей из $array1. Кстати, при выводе $array1 ты в цикле обходишь $array >for($i=0;$i< count($array);$i++){ print_r($array1[$i])... Тебе нужно в каждой строке выводить данные И имён, И паролей.
Также, почитай про разделение логики и представления. Тебе понадобиться это в будущем, если ты планируешь дальше изучать PHP.
Например это:
https://true-coder.ru/php/razdelenie-koda-i-shablona-mvc-chast-1.html
https://true-coder.ru/php/razdelenie-koda-i-shablona-mvc-chast-2.html
mysqli уже давно устаревшая технология, и все пользуются PDO.
https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md
https://secure.php.net/manual/ru/book.pdo.php
Если ты хочешь научиться PHP, то прочитай шапку этого треда, там много полезных ссылок и задач от которых твои навыки просто взлетят вверх.
Можешь свободно задавать любые вопросы если они появились.
Или че.
Слава аллаху отзывчивому анону, не знал что так можно делать, только сейчас узнал о функции array_combine
http://sandbox.onlinephpfunctions.com/code/34c2e0e95accd4a9551b591f8b10745da88877bd
>>14426
Да нифига. Просто группировка переменных и обрабатывающего их функционала в один пакет.
Тот же класс для дебага удобно в виде статика использовать - всё включается и выключается в одном месте, и смысла в инициализации тут нету.
Другое дело, когда всё на ней пишут - тогда пиздос.
Типичная аксиома Эскобара короче.
Потому что JAMstack
>Просто группировка переменных и обрабатывающего их функционала в один пакет.
Инкапсуляция, конечно, всегда хорошо. Но статические сущности в ООП не нужны.
Речь не об ООП, а о хелперах, намертво прикрученных к приложению.
Пересмотреть архитектуру приложения.
Есть два стула: один - с толстыми контроллерами, другой - на статиках сделанный. Что себе оставишь, что на собес отправишь?
Как положено заходить в опен спейс? Если тебе под ноги кружку печенек кинут, что надо делать?
Как определить тимлида, где его рабочее место должно быть?
Буду ебашить лапшу кода покамест монстр не разрастется до размеров галактики, а потом сьебну на другую работу мидлом. И так до сеньора с 300к в день.
>Как положено заходить в опен спейс?
на гироскутере
>Если тебе под ноги кружку печенек кинут
сразу же спросить где тут смузимашина свежайшего смузи испить
>Как определить тимлида, где его рабочее место должно быть?
ближайшее к смузимашине
А не боишься, что тебе неперезвонят с такими закидонами? Пойдёшь веслать в козлиную галеру.
>смузимашина свежайшего смузи испить
С этим - к гламурным питорастам. У ПХПшников за это не погладят - у нас народ суровый и прожжёный.
Это вообще шениально - называть людей неизвестной тебе профессии уёбками и макаками.
>б-г миловал
Веб от тебя.
Этот лев.
Самый простой способ - просто сделать 2 картинки, одна чистая, другая затемненная. Затемненная имеет низкий контраст и может быть сильно сжата тем же JPEG. Если ты можешь гарантировать, что ее серединка всегда будет закрыта попапом, то можешь сделать серединку просто серой, что уменьшит вес. В попапе сделать закругление и фоном поставить цветную картинку. Чтобы картинки совпадали по расположению, можно:
- задать для них привязку к центру элемента. Это позволит сделать цветную картинку маленькой
- использовать привязку фона через http://htmlbook.ru/css/background-attachment и привязать их к углу экрана
Дальше - можно попробовать взять одну картинку, но заморочиться с фильтрами: https://developer.mozilla.org/ru/docs/Web/CSS/filter (интересно, что впервые фильтры появились в древних Internet Explorer, я помню, они были в IE6, вышедшем в 2003).
Надо понимать, что некоторые фильтры вроде blur не бесплатны. Например, у меня на телефоне применение фильтра blur к странице приводит к тому, что скроллинг идет со скоростью 2-3 fps (это очень дерганно).
Также, надо по caniuse проверить, насколько хорошо они поддерживаются: https://caniuse.com/#feat=css-filters
Заметь, что поддерживаются они так себе: в FF 2014 года надо включать флаг для их поддержки.
Попробуй сделать по описанию, и можешь выложить результат на codepen или jsfiddle для проверки.
На самом деле у него всё ещё хуже:
1 - он жирный-пассажирный, который за каким-то хреном залез в пхп-тред и троллит тут. Уж точно не от избытка общения такое делают.
2 - он не жирный, а просто идиот, который залез в пхп-тред из-за нехватки дураков в /б.
>>14454
Есть еще мнение, что для дебага лучше использовать дебаггер, или сделать логгирование или натыкать var_dump.
>>14425
Флаг u говорит о том, что шаблон для поиска и строка в кодировке utf-8. Увы, он не влияет на тот факт, что PREG_MATCH_OFFSET возвращает смещение в байтах, а не символах. Русские буквы занимают 2 байта.
Если тебе принципиально надо перевести байты в символы, то это можно сделать через mb_strlen(substr(....)), используя тот факт, что функции без mb_ работают со смещением в байтах. Вырезать кусок строки, указав смещение в байтах, и найти его длину в символах.
>>14368
Это все хорошо, но не храни пароли в открытом виде, а храни соленый хеш от них: https://github.com/codedokode/pasta/blob/master/security/password-hashing.md
>>13537
Надо указать кодировку заголовком Content-Type или тегом meta charset. Не стоит использовать устаревшие однобайтовые кодировки вроде 1251, в них, например, нет эмодзи и многих других символов.
Вообще, можно просто поместить их определение в отдельный файл и заинклудить.
>>14098
Для такой простой задачи строить сложную систему из кучи контейнеров и мучаться с ними не требуется.
>>13508
Так-то идея неплохая - завернуть особенности в трейт, но вот конструктор туда класть - это на мой взгляд неправильно, так как конструктор почти всегда у разных типов разный. Трейт BoxedValue лучше вообще убрать или оставить там только getValue().
>>13451
Сервис ради такой простой задачи, как добавить пару полезных функций - это оверкилл. Плюс, сервис не имеет доступа к внутреннему состоянию контроллера. Ну например, функция формирования ответа может быть заложена в контроллере, и никто другой его формировать не может.
> DTO
Не очень понятно, при чем тут это.
> Ток надо проверить сможет ли доктрина прочитать анотации в трейте.
Может.
> Трейты можно в тайпхинте использовать.
Ты проверял эту информацию? У меня не работает: https://3v4l.org/0KcVF
> Пример использования:
> https://github.com/igorw/evenement/tree/master/src/Evenement
Мне, кстати, не нравится, эта система, так как там нет проверки на правильность написания события:
$x->on('dataaaReceived', ...)
А если бы были методы вроде
$x->onDataReceived(...)
То была бы и защита от опечаток, и видно, какие события доступны. Еще один вариант - через публичные свойства или методы, как в .NET:
$x->dataReceivedEvent->addListener(function ($e) {
...
});
Этот подход также защищает от опечаток и позволяет увидеть доступные события. А подход Evenement, скопированный с Node.JS, мне не очень нравится. Но это мое мнение.
Вообще, можно просто поместить их определение в отдельный файл и заинклудить.
>>14098
Для такой простой задачи строить сложную систему из кучи контейнеров и мучаться с ними не требуется.
>>13508
Так-то идея неплохая - завернуть особенности в трейт, но вот конструктор туда класть - это на мой взгляд неправильно, так как конструктор почти всегда у разных типов разный. Трейт BoxedValue лучше вообще убрать или оставить там только getValue().
>>13451
Сервис ради такой простой задачи, как добавить пару полезных функций - это оверкилл. Плюс, сервис не имеет доступа к внутреннему состоянию контроллера. Ну например, функция формирования ответа может быть заложена в контроллере, и никто другой его формировать не может.
> DTO
Не очень понятно, при чем тут это.
> Ток надо проверить сможет ли доктрина прочитать анотации в трейте.
Может.
> Трейты можно в тайпхинте использовать.
Ты проверял эту информацию? У меня не работает: https://3v4l.org/0KcVF
> Пример использования:
> https://github.com/igorw/evenement/tree/master/src/Evenement
Мне, кстати, не нравится, эта система, так как там нет проверки на правильность написания события:
$x->on('dataaaReceived', ...)
А если бы были методы вроде
$x->onDataReceived(...)
То была бы и защита от опечаток, и видно, какие события доступны. Еще один вариант - через публичные свойства или методы, как в .NET:
$x->dataReceivedEvent->addListener(function ($e) {
...
});
Этот подход также защищает от опечаток и позволяет увидеть доступные события. А подход Evenement, скопированный с Node.JS, мне не очень нравится. Но это мое мнение.
Да, можно.
>>13426
Поищи сам в архиве: https://phpclub.tech/search/?q=устроился
>>13401
На практике это будет не очень хорошо работать, так как ты например можешь ждать, пока кто-то сделает свою задачу, а он прокрастинирует. Но вообще, я подумывал над организацией чего-то такого. У тебя есть идеи, что бы можно было делать, в идеале что-то полезное?
>>13247
А что для тебя было бы интересно?
>>08331
Комментариев, мягко, говоря маловато. Непросто будет другому разработчику понять, как использовать код. Хотя бы комментарий перед классом стоило добавить (а в идеале перед всеми неочевидными публичными методами).
> $this->time = $hour.':'.$minute;
А не выгоднее ли хранить время как часы и минуты отдельно, чтобы не мучаться с преобразованиями?
> $hour = 0..$hour;
А зачем тут 2 точки? Это получается 0. (0 без дробной части) . $hour.
> $minute > 60
А 60 минут - это допустимо?
> $datesAndTimes[] = $currentTime->modify($ordinal.' '.$spelling[$dayOfWeek].' '.$this->time);
Интересное решение.
> public function setAlarm(int $id, Alarm $alarm): void
> public function getAlarm(int $id): ?Alarm
А зачем этот id? Для тестов? Мне кажется, проще вообще без него. Или ты не уверен, что когда ты меняешь свойства тревоги, они поменяются внутри AlarmClock ? А это уже к тебе вопрос: поменяются или нет?
> if ($object == $alarm) {
Изучи, в чем отличие == и === для объектов в PHP мануале: http://php.net/manual/ru/language.oop5.object-comparison.php
> public function findNearestAlarm(DateTimeImmutable $currentTime): Alarm
Возможно, было бы лучше использовать DateTimeInterface, чтобы можно было передавать и DateTime, хотя тогда придется беспокоиться, что ты не поменяешь его содержимое.
> $alarms[] = [$alarmTime, $alarm];
> sort($alarms);
В таких местах обязательно надо ставить комментарий, так как я, например, не помню наизусть как работает сортировка для массивов. Иначе при правке этот код могут сломать по незнанию (тесты, впрочем, могут помочь это обнаружить).
> sort($datesAndTimes);
> return $datesAndTimes[0];
Здесь есть проблема: если ни один день недели не выбран, то массив будет пуст и произойдет ошибка (для проверки, что ошибки не будет, можно написать тест).
> sort($alarms);
> return $alarms[0][1];
То же самое.
> private function isTriggeredAlarm(Alarm $alarm, DateTimeImmutable $currentTime): bool
Мне кажется, тут было бы быстрее сравнить время, день недели и признак активности. Хотя использованный подход тоже годится.
> $currentTime = new DateTimeImmutable('13:00');
Здесь в тесте появляется зависимость от текущего дня. Лучше бы жестко прописать дату, чтобы убрать случайности.
> assert(get_class($alarmTime) == DateTimeImmutable::class);
Лучше было бы писать $alarmTime instanceof DateTimeImmutable - ведь мы не обязаны вернуть строго этот класс, а допустимо вернуть его наследника в соотв. с принципом Лисков (LSP).
> assert($alarmClock->getAlarm(0) === null);
Вот тут вместо поиска по id (а откда ты знаешь, какой у тревоги id? Это нигде не документировано) было бы лучше сделать метод вроде getAllAlarms() или hasAlarm() и проверять через них. А с твоим подходом - появляется необходимость в id, и тест становится хрупким, зависящим от деталей реализации класса: если завтра мы начнем нумеровать тревоги с 1, то тест сломается. А это затраты времени и денег на переписывание.
> assert($nearestAlarm === $alarm || $nearestAlarm === $alarm2);
Этот тест не проверят, что тревога определена правильно. Лучше было бы явно прописать, какая тревога должна найтись.
> $alarm2->setType(Alarm::TYPE_NON_REPEATING);
> $alarmClock->setAlarm(0, $alarm2);
Вообще, вызывать setAlarm не требуется. Ты объект заменяешь тем же самым объектом.
В общем, сделано хорошо.
Ну и на будущее, сейчас ты писал тесты руками, но вообще есть готовые фреймворки для написания тестов, где много готовых полезных методов, где есть вывод отчетов о выполнении тестов. Самый известный - это PhpUnit, это PHP-версия семейства фреймворков xUnit, которые есть почти для любого языка (версия для Явы, например, называется JUnit). Это семейство началось с фреймворка для Smalltalk SUnit, описанного Кентом Беком в статье 1989 года ( http://swing.fit.cvut.cz/projects/stx/doc/online/english/tools/misc/testfram.htm - там есть полный код фреймворка). Почти 30 лет прошло!
Чтобы пользоваться PhpUnit, нужно его установить через композер, но если ты пока с ним не знаком, то его можно просто скачать в виде .phar-файла.
>>08331
Комментариев, мягко, говоря маловато. Непросто будет другому разработчику понять, как использовать код. Хотя бы комментарий перед классом стоило добавить (а в идеале перед всеми неочевидными публичными методами).
> $this->time = $hour.':'.$minute;
А не выгоднее ли хранить время как часы и минуты отдельно, чтобы не мучаться с преобразованиями?
> $hour = 0..$hour;
А зачем тут 2 точки? Это получается 0. (0 без дробной части) . $hour.
> $minute > 60
А 60 минут - это допустимо?
> $datesAndTimes[] = $currentTime->modify($ordinal.' '.$spelling[$dayOfWeek].' '.$this->time);
Интересное решение.
> public function setAlarm(int $id, Alarm $alarm): void
> public function getAlarm(int $id): ?Alarm
А зачем этот id? Для тестов? Мне кажется, проще вообще без него. Или ты не уверен, что когда ты меняешь свойства тревоги, они поменяются внутри AlarmClock ? А это уже к тебе вопрос: поменяются или нет?
> if ($object == $alarm) {
Изучи, в чем отличие == и === для объектов в PHP мануале: http://php.net/manual/ru/language.oop5.object-comparison.php
> public function findNearestAlarm(DateTimeImmutable $currentTime): Alarm
Возможно, было бы лучше использовать DateTimeInterface, чтобы можно было передавать и DateTime, хотя тогда придется беспокоиться, что ты не поменяешь его содержимое.
> $alarms[] = [$alarmTime, $alarm];
> sort($alarms);
В таких местах обязательно надо ставить комментарий, так как я, например, не помню наизусть как работает сортировка для массивов. Иначе при правке этот код могут сломать по незнанию (тесты, впрочем, могут помочь это обнаружить).
> sort($datesAndTimes);
> return $datesAndTimes[0];
Здесь есть проблема: если ни один день недели не выбран, то массив будет пуст и произойдет ошибка (для проверки, что ошибки не будет, можно написать тест).
> sort($alarms);
> return $alarms[0][1];
То же самое.
> private function isTriggeredAlarm(Alarm $alarm, DateTimeImmutable $currentTime): bool
Мне кажется, тут было бы быстрее сравнить время, день недели и признак активности. Хотя использованный подход тоже годится.
> $currentTime = new DateTimeImmutable('13:00');
Здесь в тесте появляется зависимость от текущего дня. Лучше бы жестко прописать дату, чтобы убрать случайности.
> assert(get_class($alarmTime) == DateTimeImmutable::class);
Лучше было бы писать $alarmTime instanceof DateTimeImmutable - ведь мы не обязаны вернуть строго этот класс, а допустимо вернуть его наследника в соотв. с принципом Лисков (LSP).
> assert($alarmClock->getAlarm(0) === null);
Вот тут вместо поиска по id (а откда ты знаешь, какой у тревоги id? Это нигде не документировано) было бы лучше сделать метод вроде getAllAlarms() или hasAlarm() и проверять через них. А с твоим подходом - появляется необходимость в id, и тест становится хрупким, зависящим от деталей реализации класса: если завтра мы начнем нумеровать тревоги с 1, то тест сломается. А это затраты времени и денег на переписывание.
> assert($nearestAlarm === $alarm || $nearestAlarm === $alarm2);
Этот тест не проверят, что тревога определена правильно. Лучше было бы явно прописать, какая тревога должна найтись.
> $alarm2->setType(Alarm::TYPE_NON_REPEATING);
> $alarmClock->setAlarm(0, $alarm2);
Вообще, вызывать setAlarm не требуется. Ты объект заменяешь тем же самым объектом.
В общем, сделано хорошо.
Ну и на будущее, сейчас ты писал тесты руками, но вообще есть готовые фреймворки для написания тестов, где много готовых полезных методов, где есть вывод отчетов о выполнении тестов. Самый известный - это PhpUnit, это PHP-версия семейства фреймворков xUnit, которые есть почти для любого языка (версия для Явы, например, называется JUnit). Это семейство началось с фреймворка для Smalltalk SUnit, описанного Кентом Беком в статье 1989 года ( http://swing.fit.cvut.cz/projects/stx/doc/online/english/tools/misc/testfram.htm - там есть полный код фреймворка). Почти 30 лет прошло!
Чтобы пользоваться PhpUnit, нужно его установить через композер, но если ты пока с ним не знаком, то его можно просто скачать в виде .phar-файла.
Спасибо тебе огромное и побольше здоровья.
>Есть еще мнение, что для дебага лучше использовать дебаггер, или сделать логгирование или натыкать var_dump.
У меня ПХП как консольное приложение крутился - вывод прямо на экран в реалтайме.
>var_dump
Если у тебя скрипт 10 строк, то да, а если под 300? Задолбаешься потом это вар_дамп выковыривать из кода.
> Возможно, было бы лучше использовать DateTimeInterface, чтобы можно было передавать и DateTime
Я не тот, кому адресован ответ, просто для справки отвечу - DateTimeInterface лучше не использовать. Это бесполезный интерфейс, так как если функция работает с аргументами типа \DateTime, на которых вызываются методы modify или setTime, то при передаче в функцию аргументов типа \DateTimeImmutable функция вернёт другие результаты, верно и обратное.
Например во Flow даже есть специальные конструкции, позволяющие пометить аргументы, для которых запрещено мутирование: https://flow.org/en/docs/types/interfaces/#toc-interface-property-variance-read-only-and-write-only
Ещё есть RFC от разработчика доктрины, предлагающее выпилить DateTimeInterface: https://wiki.php.net/rfc/drop-datetimeinterface
Похоже, что этот интерфейс вводился для поддержки перезрузки операторов вроде >, < для объектов дат.
Иммутабельные объекты-значения вроде денег и времени исключают огромное количество трудноуловимых багов. Кстати, в мире JS есть библиотека moment, в которой даты не иммутабельны и разработчики писали пост с извинениями за то, что сразу не сделали нормально. Сейчас уже слишком поздно что-то менять из-за обратной совместимости, поэтому приходится постоянно клонировать даты.
Вообще, да, справедливое замечание. Не стоит тогда менять DTImmutable на DTInterface.
Я ловил себя на мысли, что эти классы не очень совместимы, но как-то глубоко не думал.
Действительно, интерфейс определяет не только названия методов, но и определенные требования к ним. И неправильно, когда одна реализация modify создает новую сущность, а другая - модифицирует существующую. Трудно написать интерфейс, который корректно работает с обоими типами.
Это изображение, лол.
екземпл
Вспомнил свою спам-молодость.
И только попробуйте мне пиздануть, что нельзя парсить HTML регулярками — я напишу регулярку в 10 раз быстрее, чем вы будете подключать свою нескучную либу от васяна (которая ещё и поперхнется при первом нарушении формата) и этого будет достаточно для 98% задач.
Держи нас в курсе.
Необходим дохуя простой фреймворк. Часто приходится написать простой веб интерфейс с парой кнопок, под который юзать лару не имеет смысла - пишу свой велосипед. Есть что-то дохуя простое для подобных целей?
И еще вопрос. Какой фреймворк считается самым тру? Симфони вроде как?
>
Необходим дохуя простой фреймворк.
Slim/Silex.
> Какой фреймворк считается самым тру?
Zend > Symfony> Yii > ...
медленный,самый главный тормоз
Есть некий сайт с видео на пример возьмём паблик вкакахе. Нужно написать скрипт, который будет выкачивать видео оттуда и заливать на фтп. Пхп с этим справится? Если что, каждое видео открывается в новом окне. Скачивание вручную происходит путём ПКМ->Сохранить видео как...
Да, вполне справится.
Вот код index.php:
<?php
require 'vendor/autoload.php';
$app = new \Slim\App();
$app->run();
Нет. Настроил по видео https://www.youtube.com/watch?v=TcFUNG7M3VE&t=554s хостинг выдает ошибку
100к
>Сервис ради такой простой задачи, как добавить пару полезных функций - это оверкилл. Плюс, сервис не имеет доступа к внутреннему состоянию контроллера
Понятно, дальше не читал.
Да, придётся подтянуть матчасть чтобы понять что написано.
Все я разобрался
Спасибо за замечания!
>Комментариев, мягко, говоря маловато
Понял, сделаю
>А зачем этот id?
Переделаю
>Интересное решение.
> $currentTime->modify($ordinal.' '.$spelling[$dayOfWeek].' '.$this->time);
Что-то не так? Есть вариант с $time-add(DateInterval::createFromDateString('параметры')); , но он выглядит слишком массивно и по-моему имеет какой-то подвох.
>Здесь есть проблема: если ни один день недели не выбран, то массив будет пуст и произойдет ошибка
Но это невозможно, массив с днями недели не может быть пустым.
У меня возник вопрос насчет функции setAlarm. Как она в нынешнем виде (замена объекта на объект) может пригодиться в реальном проекте? Ведь можно завести метод getAlarms():array и настраивать нужный нам объект выбрав его из массива. Это нарушит принцип solid?
У меня возникли вопросы по вектору!
Нужно каким-то образом наполнить компанию департаментами и сотрудниками. Для начала я написал обычную функцию, которая генерирует сотрудников для переданного департамента. Всё остальное (создание компании, департаментов и добавление их в компанию) делалось вручную.
Но я подсмотрел в phpclub.tech, что вы рекомендовали для построения фирмы использовать паттерн Builder.
Я вижу два варианта решения, первый - это создать класс CompanyBuilder в котором будут методы создатьДепартаменты, создатьРаботников, получитьКомпанию.
Пример https://ideone.com/3FEnva
Второй вариант, это - создать класс DepartmentBuilder с методами создатьРаботников, получитьДепартамент.
Пример https://ideone.com/PkdeAs
Вдохновлялся этим образцом https://github.com/domnikl/DesignPatternsPHP/blob/master/Creational/Builder/TruckBuilder.php
Ещё была идея сделать фабрику со статическим классом, которая будет отдавать нам массив с работниками.
Пример https://ideone.com/Fwij7Q
>чтобы ее возможно было менять, надо сделать отдельно класс Сотрудник, и отдельно же классы для каждой профессии.
Также я написал абстрактный класс Profession для возможности смены профессии сотруднику из которого наследуются инженер, менеджер, аналитик и маркетолог. Помимо смены профессии, ничего не мешает добавить работнику несколько профессий или персонально поменять какие-то свойства.
Надеюсь принципы ООП не запрещают иметь внутри объекта Employee объект профессии, который может быть у каждого работника уникальным или наоборот у всех сотрудников одной профессии в компании он будет одинаковым.
Буду благодарен за подсказки. Возможно я ещё не дорос до уровня на котором стоит пытаться вникать в паттерны?
У меня возникли вопросы по вектору!
Нужно каким-то образом наполнить компанию департаментами и сотрудниками. Для начала я написал обычную функцию, которая генерирует сотрудников для переданного департамента. Всё остальное (создание компании, департаментов и добавление их в компанию) делалось вручную.
Но я подсмотрел в phpclub.tech, что вы рекомендовали для построения фирмы использовать паттерн Builder.
Я вижу два варианта решения, первый - это создать класс CompanyBuilder в котором будут методы создатьДепартаменты, создатьРаботников, получитьКомпанию.
Пример https://ideone.com/3FEnva
Второй вариант, это - создать класс DepartmentBuilder с методами создатьРаботников, получитьДепартамент.
Пример https://ideone.com/PkdeAs
Вдохновлялся этим образцом https://github.com/domnikl/DesignPatternsPHP/blob/master/Creational/Builder/TruckBuilder.php
Ещё была идея сделать фабрику со статическим классом, которая будет отдавать нам массив с работниками.
Пример https://ideone.com/Fwij7Q
>чтобы ее возможно было менять, надо сделать отдельно класс Сотрудник, и отдельно же классы для каждой профессии.
Также я написал абстрактный класс Profession для возможности смены профессии сотруднику из которого наследуются инженер, менеджер, аналитик и маркетолог. Помимо смены профессии, ничего не мешает добавить работнику несколько профессий или персонально поменять какие-то свойства.
Надеюсь принципы ООП не запрещают иметь внутри объекта Employee объект профессии, который может быть у каждого работника уникальным или наоборот у всех сотрудников одной профессии в компании он будет одинаковым.
Буду благодарен за подсказки. Возможно я ещё не дорос до уровня на котором стоит пытаться вникать в паттерны?
(
[0] => $10 000 business start up
[1] => $10 000 investment opportunities
[2] => $10 000 to invest
[3] => $1000 investment ideas
)
В этом простом скрипте, который юзает этот массив: ключ - это номер страницы, а значение - это ключевое слово страницы как бы. Надеюсь понятно.
Таким образом, мы дергаем domain.ru/?page=1
А там выводится "$10 000 business start up"
Как мне вывести их наоборот, да так, чтобы этот массив начался с единицы, т.к. странцы в url начинаются с единицы, да еще в виде карты сайта? Но не xml в в виде списка <a href="domain.ru/?page=1">$10 000 business start up</a>... и так далее.
Короче пройтись по всему массиву, сделать по сути смещение на единицу и вывести с таким синтаксисом?
Даже не так лучше, анончики, простите: нужно просто вывести карту сайта в виде всех страничек (то есть просто вы ключи из массива без значений):
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.domain.com/?page=0</loc>
<lastmod>2005-01-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>http://www.domain.com/?page=0</loc>
<lastmod>2005-01-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
</urlset>
Даже не так лучше, анончики, простите: нужно просто вывести карту сайта в виде всех страничек (то есть просто вы ключи из массива без значений):
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>http://www.domain.com/?page=0</loc>
<lastmod>2005-01-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
<url>
<loc>http://www.domain.com/?page=0</loc>
<lastmod>2005-01-01</lastmod>
<changefreq>monthly</changefreq>
<priority>0.8</priority>
</url>
</urlset>
Тут по хорошему нужно бы разнести на несколько файлов и реализовать хотя бы примитивный темплейт, но если "хуяк хуяк и в продакшн" то как то так:
<?php
$keys =[
0 => '$10 000 business start up',
1 => '$10 000 investment opportunities',
2 => '$10 000 to invest',
3 => '$1000 investment ideas'
];
$myShittyCode = '';
foreach ($keys as $key => $value) {
$myShittyCode .= '<a href="domain.ru/?page=' . ($key + 1) .'">' . $value . '</a>';
}
echo $myShittyCode;
/ или использовать цикл for()
или получать имя ключа функцией key() . тут нужно будет читнуть мануал по массивам
*/
Спасибо большое! Сделал твой вариант в виде html и сделал xml по этому коду: gist.github.com/artlung/210438
Все получилось.
array_reduce();
Необязательно, но желательно. Зависит от того, чем ты хочешь заниматься.
Если и лезть в эту тему, то с головой, не стоит относится к этому ЯП с пренебрежением или с отвращением. Подойдите к этому как к навыку работы с еще одним инструментом, который заслуживает отдельного внимания и детального изучения. К тому же, изучение JS приведет к встряске устоявшихся ментальных конструкций, полученных при изучении PHP.
Учусь писать простейший парсер.
Есть самописный интернет магазин. В нем есть блоки с товарами.
Я хочу запарсить к себе на другой сайт эти блоки, чтобы информация из них записывалась в массив такого вида:
$items= array(
0 => array(
"img" => "site/hooy.img",
"name" => "Штаны Гоша рубчинский",
"prcie" => "10000"),
1 => array(
"img" => "site/hooy2.img",
"name" => "Ватник",
"prcie" => "50"),
)
)
);
И так далее
Составил такую регулярку просто чтобы для начала вытянуть все блоки с товарами, а дальше че нибудь придумаю:
$pattern = '~<div class="item"(.*)</div>~';
preg_match_all($pattern, $content, $matches);
Возвращаются пустые массивы. Я не понимаю. Что я делаю не так?
Я знаю, что этот вопрос решили уже 100 раз. Я делаю это исключительно в целях обучения.
То есть мне надо кодировать всю страницу в json, найти там нужные мне блоки, записать их, а потом раскодировать?
Кодера найми просто и он всё сделает за день. Сам ты неделю возиться будешь, мозг сломаешь, и не факт, что результат будет.
А так ты ересь несёшь.
Если там мускул, то жсон не нужен - прямо с базы можно брать данные.
Бро ты чего какой злой? Я учу пхп, хочу понять как мне запарсить блоки, вот и спрашиваю.
Почему я злой? Нормально общались вроде.
Если сайт твой - парсить его выдачу смысла не имеет и создаёт лишнюю нагрузку.
Проще запрос к БД составить и получить свой массив куда надо. Ну или API с json прикрутить, но тут долго пыхтеть будешь.
Мне не принципиально с какого сайта парсить, хоть с яндекс ньюс. Просто у меня есть свой сайт, который я написал сам, мне проще парсить с него.
Цель - научиться и понять как вытаскивать блоки с одинаковым классом и записывать информацию из них в массив на чистом пхп.
На данный момент я запутался.
Получаешь страницу, парсишь регулярками по ситуации. Или какой-нибудь либой, которая уже умеет прекрасно работать с дом. Вероятно соснешь на динамичном контенте, придется выкручиваться.
жмот
Спасибо.
Fatal error: Uncaught Error: Call to undefined function Intervention\Image\mb_convert_case() in /var/www/images/vendor/intervention/image/src/Intervention/Image/AbstractDriver.php:105
Как я понял, у меня нет функции mb_convert_case(). Не понимать. Функции для пхп можно как то доустанавливать?
Разобрался. Надо было установить mbstring
Почему так происходит? Почему надо что то доустанавливать в пхп лол?
Есть необходимость иметь отдельный виртуальны сервер под MySQL (в моем случае MariaDB).
Настроил все на VirtualBox. Проблема в том, что соединение с хоста происходит очень долго. Кто-то может пояснить почему и можно ли это исправить?
На виртуалке использую ubuntu server 18.04 и виртуальный адаптер хоста со статическим ip. Виртуальный адаптер хоста нужен для того, чтобы с базой можно было соедениться как с хоста, так и с других виртуальных образов.
Я тупой, поэтому если кто знает в чем проблема поясните на пальцах плез
$x = 2;
echo "$x $x = ($x$x)\n";
Мне нужно, чтобы выводило 2 2 = 4, а не 2 2 = (2*2)
Заведи новую переменную, в нее помести результат умножения и эту переменную подставляй в строку. В строку нельзя вставлять выражения.
Ну что, погроммисты, можете сдать грейд на мидла?
Въебал бы тебе за щеку за тупые выебоны на детской теме. Кодер из тебя дерьмо, если ты экономишь переменные в ущерб читабельности.
Выглядит как набор обязательных знаний для любого разработчика. А, кстати, в вебе применяется паттерн Команда? Мне на ум в основном приходят примеры вроде редактора текста, где бы подошел этот паттерн.
>Давайте вести себя культурнее.
Да я, вроде, старался в стиле поста ответить. Но ты прав, пожалуй.
Есть rfc, но это лишь бумажка для подтирания жопы, которой уже подтерлись.
Нужен какой-то реальный рабочий код или мод языка
>>18647
Какая-то хуита. Вообще ничего нет про виртуализацию/контейнеризацию и системы деплоя.
Нихуя нет про сети кроме "http протокол".
При этом вопросы по БД на более высоком уровне, чем требуется при разработке 95% говносайтов.
При этом еще и чисто под SQL заточены, судя по всему.
Я уж молчу про отсутствие требований знаний структур данных и алгоритмов.
Можно ли в пыхе изменять область видимости члена класса при наследовании?
В настройках всего этого сетевого говна (в убунте 18.04 это netplan). У меня было написано:
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
Что создавало какую-то залупа с DNSами всякими (хуйово в этом шарю). На практике, эта хуйня при запуске оси, записывала в этот файл: /etc/resolv.conf строку: nameserver: 127.0.0.53
Насколько я понял из гугла. При соединении мускуль тратит какоето время на поиск чегото там связанного с днс, хз в общем, но везде советуют в конфиг мускуля добавить такой параметр:
skip-name-resolve
Что мне не помогло, но я оставил. А помогло банальное удаление строк:
nameservers:
addresses: [8.8.8.8, 8.8.4.4]
из настроек netplan
и удаление
nameserver: 127.0.0.53
из:
/etc/resolv.conf
>область видимости члена класса
Какого ещё члена? Ты класс объявляешь или объект этого класса? И причём тут наследование?
Ничего не понятно из твоего поста.
Скорее всего, нет. Также, согласно принципу Лисков наследник класса должен быть совместим с с предком, и это значит, ты не можешь скрывать публично доступные поля.
А вообще, почему бы тебе не сделать эксперимент? Сделай 3 базовых класса с 3 разными видимостями полей, для каждого по 2 наследника, где видимость меняется, чтобы были все комбинации. И тогда обсудим, почему так выходит.
>>18705
Уже сделал.
1. В пыхе нельзя менять область видимости членов класса.
2. Можно объявить в дочернем классе член с таким же именем и увеличить ему область видимости, но это будет не тот же самый член, что в базовом классе, а новый член, прост с таким же именем. Значение не копируется.
При этом если уменьшить область видимости члена с идентичным именем, то выкинет фатал еррор.
private члены класса видны только в нем. Если ты хочешь расширить область видимости, надо брать в базовый класс protected, а в наследнике делать public.
При этом фактически я возвращаю дочерний и далее из метода возвращается полноценный дочерний объект.
Но если задать тайпхинт на дочерний, пых падает с фатал-еррором.
Это случайно не связано с багом, который описан тут:
- https://phpclub.tech/pr/res/1305368.html#1308865
- https://phpclub.tech/pr/res/1281608.html#1297483
То есть когда ты в наследнике сужаешь возвращаемый тайп-хинт? Расширять его нельзя из-за приципа Лисков, а сужать можно, но PHP не позволяет.
Up!
Снимаю все вопросы, кроме.
>Надеюсь принципы ООП не запрещают иметь внутри объекта Employee объект профессии, который может быть у каждого работника уникальным или наоборот у всех сотрудников одной профессии в компании он будет одинаковым.
Объект профессии не имеет смысла в системе без объекта сотрудника, получается его нужно создавать внутри конструктора сотрудника? Композиция, так кажется это называется.
Да, сужаю. В 7.2 подвезли какой-то костыль для этих дел, но это бред
https://wiki.php.net/rfc/object-typehint
Дженериков нет и не будет. Даже если будут, всё перечёркивает динамическая натура PHP, так как проверки типов происходят в рантайме, то есть эффект "скомпилировалось - значит работает" недостижим в PHP. Есть статические анализаторы, поддерживающие дженерики, например psalm, phpstan, phan: https://github.com/phan/phan/wiki/Generic-Types
Сейчас всё больше open source проектов внедряют статический анализ, например Doctrine ORM, но в локальной разработке это очень неудобно - на данный момент статические анализаторы плохо поддерживаются в IDE, у каждого статического анализатора свой синтаксис дженериков + для сторонних библиотек нет тайпингов и никто их не делает. Для того же TypeScript есть репозиторий DefinitelyTyped. Тем не менее, вот человек использует статический анализ в PHP: https://www.youtube.com/watch?v=sf39f2q15cU
Совет - бери другой язык. Сам последние полгода 90% времени пишу на тайпскрипте, остальные 10% мучаюсь с PHP. Тем, кто писал только на динамических языках, нас не понять.
>статический анализ
Ну это же костыль, причем лютейший, чет уровня "тайпхинтов в комментах".
К тому же, как показывает практика, такая хуйня в принципе никогда нормально не работает, а всегда что-то, да наебнется.
>кто писал только на динамических языках, нас не понять
Нахуй вообще нужны динамические языки? Для домохозяек? Что б тип было "проще" писать?
Они всегда генерят только гораздо больше проблем, чем дают профита.
Точнее лично я вообще ни вижу какие весомые преимущества могут быть в динамической типизации.
Это просто бесполезная тупая хуйня, кто это придумал вообще, пиздос...
Code MUST follow a “coding style guide” PSR [PSR-1].
Code MUST use 4 spaces for indenting, not tabs.
There MUST NOT be a hard limit on line length; the soft limit MUST be 120 characters; lines SHOULD be 80 characters or less.
There MUST be one blank line after the namespace declaration, and there MUST be one blank line after the block of use declarations.
Opening braces for classes MUST go on the next line, and closing braces MUST go on the next line after the body.
Opening braces for methods MUST go on the next line, and closing braces MUST go on the next line after the body.
Visibility MUST be declared on all properties and methods; abstract and final MUST be declared before the visibility; static MUST be declared after the visibility.
Control structure keywords MUST have one space after them; method and function calls MUST NOT.
Opening braces for control structures MUST go on the same line, and closing braces MUST go on the next line after the body.
Opening parentheses for control structures MUST NOT have a space after them, and closing parentheses for control structures MUST NOT have a space before.
В одном месте скобка на той же строке, в другом блядь на следующей. В одном месте есть пробелы возле скобок функции, в другом нет.
Какой говнарь это писал?
Ооо блядь, там и группового форматирования полей и переменных нет. Фу блядь, фу нахуй.
Жрите вы сами это говно, я ебал.
Стандарт-хуедарт, в рот ебал это казино блять, так им и передайте.
> вообще ни вижу какие весомые преимущества могут быть в динамической типизации
Это удобно тогда, когда вся программа может уместиться в голове: https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two
Реальные проекты большие, их пишут много людей одновременно, за всеми не успеешь и тут статическая типизация оказывает огромную помощь, поскольку позволяет без тестов, не запуская код, без прокликиваний до нужного места обнаружить баги.
> Ну это же костыль, причем лютейший, чет уровня "тайпхинтов в комментах".
Зависит от реализации, например Flow для JS это статический анализатор, но по мощи и удобству использования он обходит многие статически типизированные языки вроде джавы благодаря выводу типов. Только вот за анализаторами для JS стоят крупные компании - Facebook и Microsoft, анализаторы для PHP пишут энтузиасты в свободное время.
>>18813
Поставь php-cs-fixer, сделай его precommit-хуком и не парься.
Фейсбук, как мне помнится, был написан на динамическом языке и принес неплохие деньги основателю. Если серьезно - я думаю. в некоторых случаях это просто быстрее и проще. В PHP ты просто берешь пишешь скрипт, шаблон и получаешь работающий сайт. Память сама очищается, скрипт сам перезапускается, все прекрасно работает. В некоторых случаях это удобно.
Сайт ОПа например представляет собой HTML-страницы с небольшой обвязкой на PHP (для вывода меню, подвала, ссылок итд), слепленной за один вечер.
Мне каждый шаг цикла нужно записывать процент от суммы кредита, чтобы в конце посчитать потраченную сумму общую. Как мне это сделать?
https://ideone.com/l2f86A
Бамп вопросу
Все изи, как-то даже не густо, но вот по бд накрутили лишнего помоему, обычно эти тонкости мало кто знает до реального опыта проблем. + nosql обязательно, хотя бы парочку популярных на общем уровне.
Ну что, анонче, наконец-то выдалась свободная минутка, давайте быстренько пройдемся по вопросам, прежде чем уходить на каникулы. Если вам вдруг будет нечем заняться, вы знаете, что делать: шапка треда, гитхаб ОПа. Если убивать время, давайте убивать его чем-нибудь полезным.
>>18942
> $count;
Это немного странный способ создать переменную, и он не работает: https://ideone.com/WabCGW
Из примера кода можно увидеть, что переменная не создается и эта строчка по факту ничего не делает (вообще, она должна выдавать ошибку, но видимо из-за совместимости со старым кодом или по другим причинам это не сделано).
Ты должен создать переменную перед тем, как пытаться ее использовать в выражении. Это делается с помощью оператора равно:
$count = 0;
А так, у тебя происходит ошибка, о чем тебе говорит PHP:
> PHP Notice: Undefined variable: count in /home/2Eccp2/prog.php on line 11
Параметры кредита (процент, выплата) лучше сделать переменными ради читаемости и удобства изменения. $percent гораздо понятнее чем просто "3". А если к ним еще комментарии добавить....
Дальше, у тебя проблема в том, что программа всегда вычитает из кредита ровно 5000. Но если в последний месяц осталось, например, 1000, то надо заплатить 1000, а не 5000.
>>18899
> Мне каждый шаг цикла нужно записывать процент от суммы кредита, чтобы в конце посчитать потраченную сумму общую. Как мне это сделать?
Лучше по-другому:
- считаем, сколько набежало процентов
- прибавляем к долгу
- считаем, сколько мы заплатим в этом месяце
- уменьшаем долг
- увеличиваем сумму потраченных денег
Ну что, анонче, наконец-то выдалась свободная минутка, давайте быстренько пройдемся по вопросам, прежде чем уходить на каникулы. Если вам вдруг будет нечем заняться, вы знаете, что делать: шапка треда, гитхаб ОПа. Если убивать время, давайте убивать его чем-нибудь полезным.
>>18942
> $count;
Это немного странный способ создать переменную, и он не работает: https://ideone.com/WabCGW
Из примера кода можно увидеть, что переменная не создается и эта строчка по факту ничего не делает (вообще, она должна выдавать ошибку, но видимо из-за совместимости со старым кодом или по другим причинам это не сделано).
Ты должен создать переменную перед тем, как пытаться ее использовать в выражении. Это делается с помощью оператора равно:
$count = 0;
А так, у тебя происходит ошибка, о чем тебе говорит PHP:
> PHP Notice: Undefined variable: count in /home/2Eccp2/prog.php on line 11
Параметры кредита (процент, выплата) лучше сделать переменными ради читаемости и удобства изменения. $percent гораздо понятнее чем просто "3". А если к ним еще комментарии добавить....
Дальше, у тебя проблема в том, что программа всегда вычитает из кредита ровно 5000. Но если в последний месяц осталось, например, 1000, то надо заплатить 1000, а не 5000.
>>18899
> Мне каждый шаг цикла нужно записывать процент от суммы кредита, чтобы в конце посчитать потраченную сумму общую. Как мне это сделать?
Лучше по-другому:
- считаем, сколько набежало процентов
- прибавляем к долгу
- считаем, сколько мы заплатим в этом месяце
- уменьшаем долг
- увеличиваем сумму потраченных денег
Стандарт не обязан соответствовать твоим вкусам.
>>16130
>>18743
> Нужно каким-то образом наполнить компанию департаментами и сотрудниками
Сделать отдельную функцию для этого. Или класс, хотя тут хватит и функции. В этой задаче главное - правильно спроектировать классы. На практике, если бы мы писали часть какого-то большого приложения, то как создавать эти объекты - это была бы не наша задача, наша задача лишь сделать классы, которые можно использовать для достижения цели.
То есть условно, наша главная задача тут не забить гвоздь (посчитать расходы), а сделать хороший молоток (спроектировать классы), которым любой сможет забивать гвозди. В ООП примерно такой подход - класс это что-то вроде инструмента для решения задачи. И приложение собирается из таких вот инструментов.
> Но я подсмотрел в phpclub.tech, что вы рекомендовали для построения фирмы использовать паттерн Builder.
Удивительно, но я такого не помню. Но, не исключаю, что советовал.
> первый - это создать класс CompanyBuilder в котором будут методы создатьДепартаменты, создатьРаботников, получитьКомпанию.
Хороший подход, но я бы назвал метод не "создать работников", а "добавить работников", так как это намекает, что его можно вызывать многократно.
> Второй вариант, это - создать класс DepartmentBuilder с методами создатьРаботников, получитьДепартамент.
Тоже неплохо. Я бы, наверно, выбрал один билдер, которым можно создавать все (работников, департаменты и тд). Так как он нужен будет только один раз, и создавать на каждый класс свой отдельный билдер мне кажется переусложнением для простой задачи. Но в какой-то другой ситуации правильнее будет делать несколько билдеров.
> Ещё была идея сделать фабрику со статическим классом, которая будет отдавать нам массив с работниками.
Не стоит. Массив работников - это по сути входные данные для программы. В реальной программе они может быть будут не заложены в коде, а спрашиваться у пользователя или загружаться из файла, импортироваться из базы данных. Такие вещи стоит просто прописать в коде на верхнем уровне (не в функции или классе).
Возвращаясь к аналогии с инструментами, нам надо сделать молоток, но не надо в него встраивать гвоздь и доску.
> Также я написал абстрактный класс Profession для возможности смены профессии сотруднику из которого наследуются инженер, менеджер, аналитик и маркетолог.
Хорошо.
> Помимо смены профессии, ничего не мешает добавить работнику несколько профессий или персонально поменять какие-то свойства.
Да, но тут надо смотреть по задаче. В задаче под "профессией" имеется в виду скорее роль, то есть человек может иметь кучу навыков, но в компании он выполняет только роль инженера. И остальные его навыки пока не важны. Но, конечно, это может понадобиться в будущем или в какой-то другой задаче.
> Надеюсь принципы ООП не запрещают иметь внутри объекта Employee объект профессии, который может быть у каждого работника уникальным или наоборот у всех сотрудников одной профессии в компании он будет одинаковым.
Логичнее один объект. У нас же у многих работников одна и та же профессия. Значит, логично и объект сделать один. Если у каждого будет своя копия профессии, то мы:
- получим сложности при создании (нам надо создавать кучу объектов-профессий с одинаковыми свойствами и ничего не перепутать)
- при сравнении (сравнение $e1->getProfession() === $e2->getProfesion() не сработает и непонятно, как сравнивать профессии - придется добавлять какой-то идентификатор или название и следить за их уникальностью)
- при обновлении данных. Представим, что у профессии есть свойство "надбавка к пенсии", и нам надо ее поменять. Нам надо будет найти каждый объект профессии в программе и обновить у него это свойство.В большом, сложном коде, где создается и хранится много объектов в разных местах, это сделать нереально.
Вообще, в базах данных есть такой принцип как нормализация, когда избегают дублирования (урок Объект профессии не имеет смысла в системе без объекта сотрудника, получается его нужно создавать внутри конструктора сотрудника? Композиция, так кажется это называется. ). Тут похожий принцип.
> Возможно я ещё не дорос до уровня на котором стоит пытаться вникать в паттерны?
Ну почему, с билдером же ты разобрался. В реальности, например, билдер используется в Symfony Forms для построения форм (вроде формы регистрации).
> Объект профессии не имеет смысла в системе без объекта сотрудника, получается его нужно создавать внутри конструктора сотрудника? Композиция, так кажется это называется.
Не так. Вроде (я не уверен) композиция применяется когда объект является составной частью другого. Ну например, мотор и машина. Или факультет и университет. Профессия не является частью работника.
Стандарт не обязан соответствовать твоим вкусам.
>>16130
>>18743
> Нужно каким-то образом наполнить компанию департаментами и сотрудниками
Сделать отдельную функцию для этого. Или класс, хотя тут хватит и функции. В этой задаче главное - правильно спроектировать классы. На практике, если бы мы писали часть какого-то большого приложения, то как создавать эти объекты - это была бы не наша задача, наша задача лишь сделать классы, которые можно использовать для достижения цели.
То есть условно, наша главная задача тут не забить гвоздь (посчитать расходы), а сделать хороший молоток (спроектировать классы), которым любой сможет забивать гвозди. В ООП примерно такой подход - класс это что-то вроде инструмента для решения задачи. И приложение собирается из таких вот инструментов.
> Но я подсмотрел в phpclub.tech, что вы рекомендовали для построения фирмы использовать паттерн Builder.
Удивительно, но я такого не помню. Но, не исключаю, что советовал.
> первый - это создать класс CompanyBuilder в котором будут методы создатьДепартаменты, создатьРаботников, получитьКомпанию.
Хороший подход, но я бы назвал метод не "создать работников", а "добавить работников", так как это намекает, что его можно вызывать многократно.
> Второй вариант, это - создать класс DepartmentBuilder с методами создатьРаботников, получитьДепартамент.
Тоже неплохо. Я бы, наверно, выбрал один билдер, которым можно создавать все (работников, департаменты и тд). Так как он нужен будет только один раз, и создавать на каждый класс свой отдельный билдер мне кажется переусложнением для простой задачи. Но в какой-то другой ситуации правильнее будет делать несколько билдеров.
> Ещё была идея сделать фабрику со статическим классом, которая будет отдавать нам массив с работниками.
Не стоит. Массив работников - это по сути входные данные для программы. В реальной программе они может быть будут не заложены в коде, а спрашиваться у пользователя или загружаться из файла, импортироваться из базы данных. Такие вещи стоит просто прописать в коде на верхнем уровне (не в функции или классе).
Возвращаясь к аналогии с инструментами, нам надо сделать молоток, но не надо в него встраивать гвоздь и доску.
> Также я написал абстрактный класс Profession для возможности смены профессии сотруднику из которого наследуются инженер, менеджер, аналитик и маркетолог.
Хорошо.
> Помимо смены профессии, ничего не мешает добавить работнику несколько профессий или персонально поменять какие-то свойства.
Да, но тут надо смотреть по задаче. В задаче под "профессией" имеется в виду скорее роль, то есть человек может иметь кучу навыков, но в компании он выполняет только роль инженера. И остальные его навыки пока не важны. Но, конечно, это может понадобиться в будущем или в какой-то другой задаче.
> Надеюсь принципы ООП не запрещают иметь внутри объекта Employee объект профессии, который может быть у каждого работника уникальным или наоборот у всех сотрудников одной профессии в компании он будет одинаковым.
Логичнее один объект. У нас же у многих работников одна и та же профессия. Значит, логично и объект сделать один. Если у каждого будет своя копия профессии, то мы:
- получим сложности при создании (нам надо создавать кучу объектов-профессий с одинаковыми свойствами и ничего не перепутать)
- при сравнении (сравнение $e1->getProfession() === $e2->getProfesion() не сработает и непонятно, как сравнивать профессии - придется добавлять какой-то идентификатор или название и следить за их уникальностью)
- при обновлении данных. Представим, что у профессии есть свойство "надбавка к пенсии", и нам надо ее поменять. Нам надо будет найти каждый объект профессии в программе и обновить у него это свойство.В большом, сложном коде, где создается и хранится много объектов в разных местах, это сделать нереально.
Вообще, в базах данных есть такой принцип как нормализация, когда избегают дублирования (урок Объект профессии не имеет смысла в системе без объекта сотрудника, получается его нужно создавать внутри конструктора сотрудника? Композиция, так кажется это называется. ). Тут похожий принцип.
> Возможно я ещё не дорос до уровня на котором стоит пытаться вникать в паттерны?
Ну почему, с билдером же ты разобрался. В реальности, например, билдер используется в Symfony Forms для построения форм (вроде формы регистрации).
> Объект профессии не имеет смысла в системе без объекта сотрудника, получается его нужно создавать внутри конструктора сотрудника? Композиция, так кажется это называется.
Не так. Вроде (я не уверен) композиция применяется когда объект является составной частью другого. Ну например, мотор и машина. Или факультет и университет. Профессия не является частью работника.
Значит, пока сужать нельзя, надо потерпеть. Ну или просить разработчиков ускорить процесс.
>>18708
> но это будет не тот же самый член, что в базовом классе, а новый член, прост с таким же именем. Значение не копируется.
Если это случай когда:
class Parent
{
protected $x = 5;
}
class Child extends Parent
{
public $x;
}
То ты переопределяешь значение по умолчанию на null и потому оно не "наследуется".
>>18682
Читать ужасно. Элементы массива надо разбить переносами по одному на строке. Чтобы не копипастить $this->ts(), сохрани это в переменную и обращайся к ней.
Ненормально, когда у функции конструктора 10 аргументов. Замени их на массив с понятными ключами либо используй сеттеры.
Не используй подчеркивание перед переменной.
Не ставь пробел перед ().
И еще я не очень понял, зачем ты хранишь имена ключей массива где-то отдельно. Если ты пытаешься переименовать поля из БД, то это в общем плохая идея и приводит к путанице.
Пока, код плоховат.
Значит, пока сужать нельзя, надо потерпеть. Ну или просить разработчиков ускорить процесс.
>>18708
> но это будет не тот же самый член, что в базовом классе, а новый член, прост с таким же именем. Значение не копируется.
Если это случай когда:
class Parent
{
protected $x = 5;
}
class Child extends Parent
{
public $x;
}
То ты переопределяешь значение по умолчанию на null и потому оно не "наследуется".
>>18682
Читать ужасно. Элементы массива надо разбить переносами по одному на строке. Чтобы не копипастить $this->ts(), сохрани это в переменную и обращайся к ней.
Ненормально, когда у функции конструктора 10 аргументов. Замени их на массив с понятными ключами либо используй сеттеры.
Не используй подчеркивание перед переменной.
Не ставь пробел перед ().
И еще я не очень понял, зачем ты хранишь имена ключей массива где-то отдельно. Если ты пытаешься переименовать поля из БД, то это в общем плохая идея и приводит к путанице.
Пока, код плоховат.
Потому что не всем это нужно. Те, кому не нужно, могут это расширение даже не компилировать. Ну и если оно вдруг окажется глючным, можно его отключить и работать без него. Плюс, эта схема позволяет писать свои расширения к PHP и добавлять в него свои функции.
В PHP огромное число, тысячи функций. Без разделения на расширения будет тяжело ориентироваться.
Твоя задача узнать, как ставить расширения в твоей ОС и где задавать их настройки. Судя по пути, это линукс и там все просто и расширения ставятся либо пакетным менеджером, либо если его там нет, через pecl.
>>17102
У меня буквы почему-то маленькие. Трудно читать в таком виде.
>>16313
> Составил такую регулярку
Возможно, проблема в том что точка соответствует любому символу кроме перевода строки. Почитай официальный мануал по рег. выражениям http://php.net/manual/ru/pcre.pattern.php если не знал.
>>16164
Сайтмап удобно генерировать методами DOM так как это обеспечивает его корректность и экранирует все нужные символы. Гугли DOMDocument. Не надо тут делать велосипеды и писать уродливые циклы с конкатенацией строк.
>>16084
Я написал "интересное решение" без иронии, потому исправлять там ничего не надо.
>>Здесь есть проблема: если ни один день недели не выбран, то массив будет пуст и произойдет ошибка
> Но это невозможно, массив с днями недели не может быть пустым.
Но чтобы это проверить, надо изучить весь код. И где гарантия, что завтра не разрешат удалять все дни? Лучше не писать код, в котором могут быть неопредлеенные переменные.
> У меня возник вопрос насчет функции setAlarm. Как она в нынешнем виде (замена объекта на объект) может пригодиться в реальном проекте? Ведь можно завести метод getAlarms():array и настраивать нужный нам объект выбрав его из массива. Это нарушит принцип solid?
Она никак не может пригодиться и довольно бессмысленна, и ты скорее всего ее написал, так как не выучил, как копируются указатели на объекты. Если ты пишешь:
$a = new Alarm();
$b = $a;
$a->setEnabled(true);
То тут $a и $b указывают на один объект и писать $b->setEnabled() или дополнительное $b = $a не требуется. А ты зачем-то это пишешь.
В реальном проекте у тревог, скорее всего, придется сделать какие-то id (ради сохранения в БД например) и ты скорее всего будешь их искать по id и придется добавить findAlarmById(). Но, конечно, зависит от ситуации, можно и без идентификаторов.
Потому что не всем это нужно. Те, кому не нужно, могут это расширение даже не компилировать. Ну и если оно вдруг окажется глючным, можно его отключить и работать без него. Плюс, эта схема позволяет писать свои расширения к PHP и добавлять в него свои функции.
В PHP огромное число, тысячи функций. Без разделения на расширения будет тяжело ориентироваться.
Твоя задача узнать, как ставить расширения в твоей ОС и где задавать их настройки. Судя по пути, это линукс и там все просто и расширения ставятся либо пакетным менеджером, либо если его там нет, через pecl.
>>17102
У меня буквы почему-то маленькие. Трудно читать в таком виде.
>>16313
> Составил такую регулярку
Возможно, проблема в том что точка соответствует любому символу кроме перевода строки. Почитай официальный мануал по рег. выражениям http://php.net/manual/ru/pcre.pattern.php если не знал.
>>16164
Сайтмап удобно генерировать методами DOM так как это обеспечивает его корректность и экранирует все нужные символы. Гугли DOMDocument. Не надо тут делать велосипеды и писать уродливые циклы с конкатенацией строк.
>>16084
Я написал "интересное решение" без иронии, потому исправлять там ничего не надо.
>>Здесь есть проблема: если ни один день недели не выбран, то массив будет пуст и произойдет ошибка
> Но это невозможно, массив с днями недели не может быть пустым.
Но чтобы это проверить, надо изучить весь код. И где гарантия, что завтра не разрешат удалять все дни? Лучше не писать код, в котором могут быть неопредлеенные переменные.
> У меня возник вопрос насчет функции setAlarm. Как она в нынешнем виде (замена объекта на объект) может пригодиться в реальном проекте? Ведь можно завести метод getAlarms():array и настраивать нужный нам объект выбрав его из массива. Это нарушит принцип solid?
Она никак не может пригодиться и довольно бессмысленна, и ты скорее всего ее написал, так как не выучил, как копируются указатели на объекты. Если ты пишешь:
$a = new Alarm();
$b = $a;
$a->setEnabled(true);
То тут $a и $b указывают на один объект и писать $b->setEnabled() или дополнительное $b = $a не требуется. А ты зачем-то это пишешь.
В реальном проекте у тревог, скорее всего, придется сделать какие-то id (ради сохранения в БД например) и ты скорее всего будешь их искать по id и придется добавить findAlarmById(). Но, конечно, зависит от ситуации, можно и без идентификаторов.
Ну, гугление выдает например http://php.net/manual/ru/book.pthreads.php
Но я должен предупредить, что там много подвохов. Ну банальный пример: один тред что-то пишет в массив, другой из него читает, чтобы не было ошибок (прочитана половина старых и половина новых данных), придется делать блокировки, то есть усложнять код. Если ты можешь обойтись без тредов, лучше без них обходиться.
>>15498
Чтобы познакомиться с фреймворком, надо на нем что-то сделать, чем сложнее, тем лучше.
>>12807
Судя по всему, у тебя там проблемы с соединением с сервером и файлы не качаются. Либо проблемы на удаленном сервере, либо с интернетом.
Я бы для начала просто скопировал URL https://vagrantcloud.com/laravel/boxes/homestead/v
ersions/6.4.0/providers/virtualbox.box в браузер и попробовал скачать файл через него для проверки. Если не качается - сделал бы traceroute и посмотрел, доходят ли пакеты до сервера.
>>12701
Наверно тут: https://github.com/codedokode/pasta/
>>12528
Да, урок про регулярки требует улучшения.
Форматируй код. Добавляй отступы. Если редактор не позволяет это делать, возьми редактор кода получше. А то читать невозможно.
> global $gender;
Не используй глобальные переменные, это затрудняет чтение кода, ведь теперь мы должны изучить весь код, чтобы понять, как эта переменная используется. А хотелось бы ограничиться изучением одной функции.
> $flor = floor($amount1/100)*100; //хра
Лучше $hundreds (сотни)
Разбиение на функции сделано не очень удачно. Каждая функция должна быть изолированной. Чтобы ее можно было использовать отдельно. То есть у нее есть понятное название, описание, что она делает, что ей передать и что она вернет. У тебя же описания нету, одна функция разбивает число на массив чисел непонятного вида, другая заменяет в этом массиве числа на слова. И одну не имеет смысла использовать без другой. То есть по сути это не 2 отдельных независимых функции, а 2 половинки одной функции и нет смысла их делать отдельными.
Ты можешь переделать код. Вместо этого:
$result = numberToText(125);
$text = smallNumberToText($result,0);
Вызывать smallNumberToText из numberToText так, чтобы она в итоге за один вызов возвращала бы сразу строку с текстом:
$text = numberToText(125);
То есть это:
elseif ($flor>0){ //записываем сотни
$result[]=$flor;
Мы заменяем на:
elseif ($flor>0){ //записываем сотни
$result[]=smallNumberToText($flor);
И вот мы получаем 2 независимых функции:
- первая умеет заменять простое число на слово
- вторая умеет превращать число в текст, используя первую
Но это тоже не идеально, так как в таком сценарии первая функция умеет заменять не любое число, а только круглые. И это не описано нигде, это знает только вторая функция. Значит, они сильно спутаны друг с другом и являются частями одной функции. Потому их стоит в идеале объединить.
Форматируй код. Добавляй отступы. Если редактор не позволяет это делать, возьми редактор кода получше. А то читать невозможно.
> global $gender;
Не используй глобальные переменные, это затрудняет чтение кода, ведь теперь мы должны изучить весь код, чтобы понять, как эта переменная используется. А хотелось бы ограничиться изучением одной функции.
> $flor = floor($amount1/100)*100; //хра
Лучше $hundreds (сотни)
Разбиение на функции сделано не очень удачно. Каждая функция должна быть изолированной. Чтобы ее можно было использовать отдельно. То есть у нее есть понятное название, описание, что она делает, что ей передать и что она вернет. У тебя же описания нету, одна функция разбивает число на массив чисел непонятного вида, другая заменяет в этом массиве числа на слова. И одну не имеет смысла использовать без другой. То есть по сути это не 2 отдельных независимых функции, а 2 половинки одной функции и нет смысла их делать отдельными.
Ты можешь переделать код. Вместо этого:
$result = numberToText(125);
$text = smallNumberToText($result,0);
Вызывать smallNumberToText из numberToText так, чтобы она в итоге за один вызов возвращала бы сразу строку с текстом:
$text = numberToText(125);
То есть это:
elseif ($flor>0){ //записываем сотни
$result[]=$flor;
Мы заменяем на:
elseif ($flor>0){ //записываем сотни
$result[]=smallNumberToText($flor);
И вот мы получаем 2 независимых функции:
- первая умеет заменять простое число на слово
- вторая умеет превращать число в текст, используя первую
Но это тоже не идеально, так как в таком сценарии первая функция умеет заменять не любое число, а только круглые. И это не описано нигде, это знает только вторая функция. Значит, они сильно спутаны друг с другом и являются частями одной функции. Потому их стоит в идеале объединить.
Мы можем выводить текст только слева направо. Потому мы берем исходный текст, разбиваем его на буквы, и сначала выводим все первые буквы строк, потом на следующей строке все вторые буквы итд.
Это надо сделать самому.
>>11770
> elseif (($remainder>10) & ($remainder<20)){
Ты использовал вместо логического И && оператор "побитовое И" &, который делает кое-что другое: https://ru.wikipedia.org/wiki/Битовые_операции
Также, в блоке if-elseif... срабатывает только одна ветка и остальные не проверяются.
>>11658
да, урок по регуляркам требует обновления.
Если не получается - выкладывай написанный код и пиши что именно непонятно, жди советов мудрых. Ну или как повезет.
Спасибо за информацию о непонятных моментах в учебнике.
>>11196
Никак. Она может только поставлять найденные подстроки без изменений. Тебе придется освоить preg_replace_callback и прочесть про анонимные функции.
>>11141
С виду нормально. Выражение сложноватое получилось, и можно было вынести получение слова отдельно:
$part1 = $word1[array_rand(...)];
>>11135
Как в следующем посте можно. Или через цикл по такому массиву:
$choices = [
['Чудесных', ....],
[варианты второго слова],
[варианты третьего],
...
];
Мы можем выводить текст только слева направо. Потому мы берем исходный текст, разбиваем его на буквы, и сначала выводим все первые буквы строк, потом на следующей строке все вторые буквы итд.
Это надо сделать самому.
>>11770
> elseif (($remainder>10) & ($remainder<20)){
Ты использовал вместо логического И && оператор "побитовое И" &, который делает кое-что другое: https://ru.wikipedia.org/wiki/Битовые_операции
Также, в блоке if-elseif... срабатывает только одна ветка и остальные не проверяются.
>>11658
да, урок по регуляркам требует обновления.
Если не получается - выкладывай написанный код и пиши что именно непонятно, жди советов мудрых. Ну или как повезет.
Спасибо за информацию о непонятных моментах в учебнике.
>>11196
Никак. Она может только поставлять найденные подстроки без изменений. Тебе придется освоить preg_replace_callback и прочесть про анонимные функции.
>>11141
С виду нормально. Выражение сложноватое получилось, и можно было вынести получение слова отдельно:
$part1 = $word1[array_rand(...)];
>>11135
Как в следующем посте можно. Или через цикл по такому массиву:
$choices = [
['Чудесных', ....],
[варианты второго слова],
[варианты третьего],
...
];
Всем удачного вката и пусть никто не уйдёт обиженным.
>в некоторых случаях это просто быстрее и проще
>Сайт ОПа например представляет собой HTML-страницы с небольшой обвязкой на PHP (для вывода меню, подвала, ссылок итд), слепленной за один вечер.
Ну я и говорю, в этом есть смысл, только если ты домохозяйка с говносайтом из 1.5 страниц.
В любом нормальном приложении статически типизируемый язык будет БЫСТРЕЕ И ПРОЩЕ
Чекните мой список студентов
Надо сделать функцию, которая его сортирует.
Внимание, охуительный вопрос.
Как мне проверить, что мне передали в функцию именно массив времен в заданном формате, а не какое-то левое говно?
Добавил проверку к array_rand() на предмет одинаковых элементов массива. Почему каждый раз пишется предупреждение? По сути же должно писать только тогда, когда выпадает 2 одинаковых элемента массива.
Или как сделать так, чтобы никогда одинаковые элементы не выпадали?
https://ideone.com/mUEyfD
preg_grep, пихаешь регулярочку и твой массив и получаешь именно те элементы которые соответствуют формату. Ну или прям в функции где будешь сортировать регулируй и сортируй.
'[012]\d:[0-5]\d'
Что у тебя там с гейтвеем Студента? Вроде запрос описал , а дёргаешь чистый PDO в половине методов.
мимокрок
Бамп
Работаем с тем, что есть.
Заебался уже на каждый пук свое исключение делать.
Иногда надо просто просигнализировать, допустим, если аргумент хуевый и все.
> Формат - часы:минуты.
Что ты подразумеваешь под часами и минутами? Под твой формат подходит как период времени, например "30:20" - 30 часов 20 минут, время в пути или временная отметка, например "23:00" - 11 часов вечера.
Если тебе нужно второе, то можешь обернуть время в объект \DateTime, тогда можно применить usort и проставить тайп-хинты:
$dates = [new \DateTime('+1 year'), new \DateTime('+1 day'), new \DateTime('-1 day')];
usort($dates, function (\DateTime $left, \DateTime $right) {
return $left <=> $right;
});
Код: https://ideone.com/5mm9Hc
В PHP есть ещё \DateInterval и \DatePeriod из полезного.
Вообще хорошая практика для таких ситуаций использовать объекты значения: https://codete.com/blog/value-objects/
>>19499
> '[012]\d:[0-5]\d'
Можно выбрать 29 часов? Если проблему можно решить без регулярки, её лучше решить без регулярки.
>>19591
> Заебался уже на каждый пук свое исключение делать.
Ну и это бессмысленно, у ОПа есть урок по исключениям: https://github.com/codedokode/pasta/blob/master/php/exceptions.md
> Иногда надо просто просигнализировать, допустим, если аргумент хуевый и все.
http://php.net/manual/en/class.invalidargumentexception.php#102218
Свои исключения есть смысл делать только тогда, когда тебе их нужно ловить.
> Формат - часы:минуты.
Что ты подразумеваешь под часами и минутами? Под твой формат подходит как период времени, например "30:20" - 30 часов 20 минут, время в пути или временная отметка, например "23:00" - 11 часов вечера.
Если тебе нужно второе, то можешь обернуть время в объект \DateTime, тогда можно применить usort и проставить тайп-хинты:
$dates = [new \DateTime('+1 year'), new \DateTime('+1 day'), new \DateTime('-1 day')];
usort($dates, function (\DateTime $left, \DateTime $right) {
return $left <=> $right;
});
Код: https://ideone.com/5mm9Hc
В PHP есть ещё \DateInterval и \DatePeriod из полезного.
Вообще хорошая практика для таких ситуаций использовать объекты значения: https://codete.com/blog/value-objects/
>>19499
> '[012]\d:[0-5]\d'
Можно выбрать 29 часов? Если проблему можно решить без регулярки, её лучше решить без регулярки.
>>19591
> Заебался уже на каждый пук свое исключение делать.
Ну и это бессмысленно, у ОПа есть урок по исключениям: https://github.com/codedokode/pasta/blob/master/php/exceptions.md
> Иногда надо просто просигнализировать, допустим, если аргумент хуевый и все.
http://php.net/manual/en/class.invalidargumentexception.php#102218
Свои исключения есть смысл делать только тогда, когда тебе их нужно ловить.
>usort($dates, function (\DateTime $left, \DateTime $right)
Лол, так и сделал. Только я малец прихуел с оператора <=>.
Не знал о его существовании, существенно укорачивает код, збс.
Один хуй пришлось писать велосипед про проверке регуляркой массива времен.
>хорошая практика для таких ситуаций использовать объекты значения
Это самый лучший вариант, но только это все ДОЛГО пиздец, на каждый пук отдельный объект писать, создавать класс, геттеры, сеттеры и прочую поебистику.
А встроеенных классов в пых не завезли.
И с исключениями вопрос бы решился.
В яве я тупо за 5 сек накидываю прямо в классе исключение, чисто чтобы у него было свое название и все, всем все понятно.
В пыхе же надо отдельный класс городить и срать тысячей файлов.
>Свои исключения есть смысл делать только тогда
Вот вообще в корне не согласен. По моему мнению, исключения надо кидать всегда, когда ты не можешь полноценно выполнить метод.
Возвращать нуллы, нули, пустые строки, фолсы и прочее говно - прямой путь к говнокоду.
Ты или возвращаешь полноценный результат или высираешь исключение и все, нехуй пытаться решить проблему, которую невозможно решить на данном уровне.
Вот если тебе надо вернуть там какой-нибудь объект файла, допустим.
А файла-то нихуя и нет.
Что ты будешь делать - возвращать какое-то говно в виде "пустого" объекта, нула и прочую срань?
Ну с появлением nullable-типов в пыхе, кстати, не самый плохой вариант, хотя бы сразу понятно, что метод тебе может вернуть.
Но когда ты физически не можешь обеспечить корректное дальнейшее выполнение метода - имхо, надо просто выкинуть исключение.
Причина, по которой программа на яве почти никогда не падает, если она скомпилилась - именно в политике языка в повсеместном кидании исключений при малейшей ошибке и принуждению говнокодера их все ловить.
А не как в пыхе и c++.
>usort($dates, function (\DateTime $left, \DateTime $right)
Лол, так и сделал. Только я малец прихуел с оператора <=>.
Не знал о его существовании, существенно укорачивает код, збс.
Один хуй пришлось писать велосипед про проверке регуляркой массива времен.
>хорошая практика для таких ситуаций использовать объекты значения
Это самый лучший вариант, но только это все ДОЛГО пиздец, на каждый пук отдельный объект писать, создавать класс, геттеры, сеттеры и прочую поебистику.
А встроеенных классов в пых не завезли.
И с исключениями вопрос бы решился.
В яве я тупо за 5 сек накидываю прямо в классе исключение, чисто чтобы у него было свое название и все, всем все понятно.
В пыхе же надо отдельный класс городить и срать тысячей файлов.
>Свои исключения есть смысл делать только тогда
Вот вообще в корне не согласен. По моему мнению, исключения надо кидать всегда, когда ты не можешь полноценно выполнить метод.
Возвращать нуллы, нули, пустые строки, фолсы и прочее говно - прямой путь к говнокоду.
Ты или возвращаешь полноценный результат или высираешь исключение и все, нехуй пытаться решить проблему, которую невозможно решить на данном уровне.
Вот если тебе надо вернуть там какой-нибудь объект файла, допустим.
А файла-то нихуя и нет.
Что ты будешь делать - возвращать какое-то говно в виде "пустого" объекта, нула и прочую срань?
Ну с появлением nullable-типов в пыхе, кстати, не самый плохой вариант, хотя бы сразу понятно, что метод тебе может вернуть.
Но когда ты физически не можешь обеспечить корректное дальнейшее выполнение метода - имхо, надо просто выкинуть исключение.
Причина, по которой программа на яве почти никогда не падает, если она скомпилилась - именно в политике языка в повсеместном кидании исключений при малейшей ошибке и принуждению говнокодера их все ловить.
А не как в пыхе и c++.
Дополню, вернуть null вместо ожидаемого результата - весьма приемлимый вариант, но эта затея идет по пизде как только у тебя возникает несколько типов ошибок в методе.
Тут онли исключения.
Ну и еще идеологически исключения полезны, когда возникает совершенно лютая хуйня, при которой дальнейшее выполнение бессмысленно.
Такие исключения я обычно не ловлю (уходят в самый верхний обработчик).
Всех. Чем больше его знаю, тем больше бесит.
> Один хуй пришлось писать велосипед про проверке регуляркой массива времен.
Зачем, \DateTime ведь выбросит исключение, если не сможет создать дату из строки.
> это все ДОЛГО
Ну ты же из джавы и должен уметь пользоваться IDE и кодогенерацией, PHPStorm умеет по пропертям генерить геттеры/сеттеры. Лично меня большое количество классов не напрягает.
> И с исключениями вопрос бы решился.
Я же скинул ссылку, в PHP целая куча классов для исключений - InvalidArgumentException, LogicException, DomainException, RuntimeException. Вот полный список: https://habr.com/post/329140/
> Ты или возвращаешь полноценный результат или высираешь исключение и все, нехуй пытаться решить проблему, которую невозможно решить на данном уровне.
Согласен, но тут в 95% случаев хватит встроенных исключений в PHP.
Ещё я пользуюсь плагином Php Inspections Extended, он как раз будет ругаться, если не будешь обрабатывать if'ами nullable типы: https://github.com/kalessil/phpinspectionsea
Вообще, я ещё раз посоветую просто взять другой язык. (Я вот вообще во фронтенд укатился)
>\DateTime ведь выбросит исключение, если не сможет создать дату из строки
Да, но DateTime жрет далеко не только hh:mm.
>в 95% случаев хватит встроенных исключений в PHP
Это да.
Кстати, PhpStorm, ВНЕЗАПНО, почему-то не сует в throws в phpdoc для встроенных исключений. А для сторонних сует.
Надо пилить что-нибудь, лучше свое, но если идей нет то копию чего-нибудь что нравится.
От документации лары у меня тоже депрессия наступает.
Лично мне больше нравится Symfony. Но игнорировать лару в текущей ситуации невозможно. Это как фронтенд. По идее знать php пограмисту не обязательно, но тогда сильно сокращаются опции на рынке труда.
почему сиmфони?
Это не от пыха зависит.
Дело в дисциплине, почитай про это.
"Будь лучшей версией себя", "правило в 10 раз больше".
Не нравится - катись в другой. Жаловаться на свою немощь в пхп-треде это удел маминого неосилятора.
Держи в курсе.
https://ideone.com/CWYEdX
Ты зачем операцию в условие цикла засунул, норкоман? Если туда можно класть что-то, что срабатывает каждую итерацию, то это ещё не значит, что туда можно класть всё подряд.
Там место только для обработки условия, а само действие пиши где положено - в теле цикла.
Что у тебя с повторами? Телепаты уехали за бугор, от жизни такой.
Бля, не ту ссыль дал. Уже завтра скину.
А это я просто код с хелпы тестировал. Там такой давали в примере, так что вопрос не ко мне.
Алсо, перекатывать тред кто-то будет?
Тебя никто не заставляет, можешь читать любые говносайты, какие захочешь, разрешаю
Надо отсортировать массив объектов.
Как это делается в нормальном языке.
В объекте переопределяется компаратор и все.
А в пхп тонна анальных извращений.
bump
Поехавший?
Начнем с того, что как картинки, так и треды доступны по http.
Во-вторых, обычно низкоуровневой работой с SSL занимается библиотека, с помощью которой ты осуществляешь запросы.
Как обычно много гонору, а толку ноль. Все твои проблемы решаемы за считанные минуты, если ты банально на уровне джуна кодить умеешь. Или хотя бы гуглить. И да, дженерики к данной ситуации вообще не относятся, узколобая ты обезьяна.
Вся суть в том, что в крестах или яве операции выполняют САМИ коллекции.
А в пхп надо писать левые велосипеды, чтобы отсортировать массив объектов.
Короче процедурщина ебаная получается.
https://github.com/italolelis/collections
https://github.com/akanehara/ginq
Минута в гугле. Там еще дохуя такого же. И всегда можно сделать самому себе под задачу, а не сокрушаться, что язык плохой, и не как у людей.
Сраный говнокод. Вся суть коллекций в том, что это коллекции не рандомного дерьма, а объектов одного типа.
Принес какие-то нескучные обертки над массивами и выебывается тут.
Я вообще не понимаю зачем обращать внимания на такие посты. По мне, так это один и тот же жиртрест пишет, чтобы тред в срач скатить.
Ну не нравится - не используй это язык, пиши на ноде, или яве. Какой смысл тут высераться своим очень нужным всем мнением?
Точно жиробас.
>что это коллекции не рандомного дерьма, а объектов одного типа.
List<object> тебе за щеку, ни к чему строгому коллекции не обязывают.
>Принес какие-то нескучные обертки над массивами
То есть ты настолько донный, что не представляешь как сделать собственную коллекцию на коленке со строгой типизацией? Просто прекрасно, что ты хейтишь пхп - одним говнокодером у нас будем меньше.
Добавлю, что не все коллекции это дженерики, и кину в лицо тебе пожалуй коллекцию из шарпа - ArrayList - которая даже по названию очевидно нескучная обертка над массивом (хотя хуй знает в действительности ли это так, лень ради тебя это чекать).
Специально для "без массивов" ебни коллекцию на ссылках. Реализовать таким образом можно что угодно, были бы руки из того места.
>>20354
Настроение поганое, захотелось проораться.
>сделать собственную коллекцию на коленке
Да заебался я уже делать на коленке то, что обычно за меня уже сделано.
В итоге не проект пишешь, а коленочные реализации всякой хуйни.
Возвращайся давай!
Задание на пике.
https://ideone.com/M66Z31
1. Почему кол-во месяцев $month не прибавляется? Я же, вроде, в цикле прибавляю.
2. Как сделать проверку на отрицательное число остатка по выплате?
То есть, школьник в 12 месяц останется должен банку какую-то сумму, но цикл закончится, так как стоит условие $price>0. Как мне ему остаток-то выплатить?
И сразу же 1-ый вопрос снимается. Пока писал - проверил, а там, оказывается, хуйня написана.
Не обманывай. Ничего там гениального, тупо пересказ документации.
Так не бывает, чтобы всегда были готовые решения. Особенно такие, чтобы подходили как родные на каждый конкретный случай. Как пример - древовидные (но не симметричные) структуры с разным типом нод внутри, логика у которых разная, и работу с которыми нужно оптимизировать - тут уже слабо помогут готовые коллекции, т.к. много работы с источниками данных, хитровыебанным кешированием, да и просто сама логика коллекции не ложится на готовые реализации из-за специфических требований. В общем писать свои коленочные решения так или иначе придется.
То есть, массив вида [3=>15, 42=22, 1005=>13]
Копировать содержимое во временные массивы нельзя
>Как удалить несколько элементов из массива во время итерации по нему
unset($varname)
>>20401
>if($forOpen!=0)
Убирай проверку $forOpen на 0. Зачем она там нужна? Достаточно просто сложить её с кредитом вначале. Если 0, то и будет + 0. А ещё лучше укажи этот $forOpen на 0 по умолчанию при объявлении ф-ции.
>for($price = 40000 + $forOpen;$price>0;$price = ($price + $inMonth +$comm)-5000)
Тут вообще бред.
У тебя цикл со счётчиком, а ты его как условный юзаешь по сути. Тут лучше танцевать от месяцев, а не от прайса. Просто за каждый месяц пересчитывай кредит.
Ну и циклы объявлять научись - там не надо лишнего писать.
Так а как я буду от месяцев плясать, если неизвестно как раз количество месяцев, требуемое для погашения кредита?
>Убирай проверку $forOpen на 0. Зачем она там нужна?
Тут согласен. Не подумал об этом.
>А ещё лучше укажи этот $forOpen на 0 по умолчанию при объявлении ф-ции.
Типо вот так сделать$forOpen = 0?
Зачем?
>У тебя цикл со счётчиком, а ты его как условный юзаешь по сути.
И вот тут по подробнее, пожалуйста.
>Так а как я буду от месяцев плясать, если неизвестно как раз количество месяцев, требуемое для погашения кредита?
$month++
И пересчитывай кредит. В теле цикла, а не в объявлении.
>Типо вот так сделать$forOpen = 0?
>Зачем?
Затем, что в 2х случаях из 3х она не указывается. Будет логично сделать её необязательной.
>вот тут по подробнее
For () - цикл со счётчиком. У тебя нет счётчика. Вернее есть $month=$month+1, но криво реализованный и к циклу отношения не имеет. Отсюда и цикл поехавший.
Закидывал в каталог апачи. Бесполезно. Есть более менее разбирающиеся аноны. Хочу проконсультироваться. Отпишите пожалуйста.
Я тут цикл починил.
https://ideone.com/aJTU6W
Всё ещё второй вопрос остался открытым
>Как сделать проверку на отрицательное число остатка по выплате?
То есть, школьник в 12 месяц останется должен банку какую-то сумму, но цикл закончится, так как стоит условие $price>0. Как мне ему остаток-то выплатить?
https://ideone.com/EeoltU вот тут в условиях задачи про игру в кубики было сказано только про дубли, но одинаковая сумма может выпасть и при разных числах, правильно ли решена задача?
Просто через эхо вывод стиха, норм?
>Как сделать проверку на отрицательное число остатка по выплате?
>но цикл закончится, так как стоит условие $price>0
Как вариант - поставить условие $price>$pay, где $pay это ежемесячный платёж. А сразу после цикла вывести остатки.
Тогда в минус не должно уходить.
>без всяких пробегов по массивам
Говорят, что индусы так пишут. Или китайцы.
Меня бы писать так задолбало. Лучше головой разок цикл прикинуть, чем по клавишам долбить как секретарша.
Короче, сносишь это васянское говно и ставишь все необходимое окружение на линух на виртуалке
\W[7|8][\d\W]{10}
Мне нужно, чтобы искал ТОЛЬКО 10 цифр и любое кол-во символов между ними. А исходя из моей - ищет всего 10 любых символов. ЧЯДНТ?
Хорошо, спрошу по другому. Как мне заставить регулярку искать только 10 цифр, а кол-во других символов не имеет значения? Конструкция вида [\d{10}\W] не работает.
Я за тебя регулярку писать не буду. https://regexr.com/ вот хороший ресурс для понимания регулярок.
Можешь пример успешных/не успешных строк предоставить? Я по описанию чутка даже охерел, либо не так понял. Мб поебусь тогда, если она действительно интересная.
>>20627
Я делю задание ОПа. Ищу номера телефонов любого формата.
https://regex101.com/r/qF7vT8/3
Вот тут заготовка.
.php в названии не надо? или к чему ты обращаешься
https://ideone.com/JdJq9X я не пойму, цикл должен получиться бесконечным или же до суммы 81, но тогда куда впихнуть условие?
Думаю, что не нарушают, но хочется все сделать красиво
Таки да, я просто пропустил, что в echo можно прописывать математические операции типа умножения и т.д.
Говно этот ваш гитхаб.
Полно людей с очень высокими зп, которые в эту помойку никогда ничего не комитили.
К тому же, толку от полутора говнопроектов на полторы строки один хуй немного, а погромировать больше без оплаты - так себе занятие.
К тому же, твой говнокод быстро устаревает или становится неактуальным.
Короче, поддерживать гитхаб в актуальном качественном состоянии - достаточно геморойное занятие в большинстве случаев.
Ну хуй знает, просто все пишут что вкатиться с проектами на гитхабе легче, чем без него.
Легче всего вкатится с подвешенным языком и нормальными навыками коммуникации, когда ты за всё можешь всем легко пояснить. В общем-то, как и везде.
А вот зеленый гитхаб тебе вряд ли поможет, если ты совсем уж отбитый аутист.
Тащи туда то, что другим пригодиться может. Если нечего тащить, и работу рано тебе искать.
А варианты из этой статьи про шаблонизаторы не подходят? https://github.com/codedokode/pasta/blob/master/php/templates.md
Не очень понятно, зачем тут изобретать велосипед.
Госпаде исусе, ну и дерьмо.
1) Сейчас десятилетие SPA, але, как там слышно из 2007-го? Бек только генерит жсон и все.
2) Пых имеет отличные встроенные средства шаблонизации, гугли как это сделано в Yii. То, что ты написал - кал чистой воды.
Ну я вижу ты не слишком умный, поэтому предостерегаю: к параше типа smarty или twig не вздумай даже прикасаться.
Ты слишком категоричен, что часто бывает у неопытных разработчиков, впервые с чем-то новым познакомившихся. SPA имеет немало недостатков:
- надо разрабатывать 2 приложения вместо одного
- долгая загрузка
- больше возможностей для ошибки
- плохая индексация поисковиками
Есть случаи, когда SPA больше подходит, есть, когда нет. Я не очень понимаю, зачем делать SPA, если страницу с описанием товара может сразу отдать сервер? Вот человек кликает в Яндекс Маркете на ссылку и получает готовую страницу товара. И не надо ждать пока твой SPA загрузится, загрузит мегабайт яваскрипта, сделает 10 AJAX запросов и тд (это можно оптимизировать, но это требует времени и стоит денег. SPA обойдется гв итоге ораздо дороже). Я не очень понимаю, зачем тут SPA.
Если тебе хочется, чтобы у тебя при просмотре каталога страницы переключались без перезагрузки, хватит обычного jQuery, или даже pjax (это требует минимум затрат труда, подключается быстро, при этом совместимо с поисковиками).
Попробуй вместо категоричных заявлений рассматривать разные подходы со всеми плюсами и минусами.
Ну ладно, про SPA это я утрировал.
Но
>надо разрабатывать 2 приложения вместо одного
Очнись, ты обосрался, уже давно надо разрабатывать 2 приложения.
По сути, сейчас чисто серверной бизнес-логики куда меньше, чем фронтенд-логики.
Взять ту же гостевую книгу. Серверный цруд там можно за 100 строк написать, а вот фронт можно такой нахуевертить, что браузер заглохнет.
И находится ли это фронт-приложение в спа или в пых-шаблонах - вопрос вторичный.
Разметку с кодом перемешал смотрю. Нынче так уже не принято делать. Вроде как плохой стиль.
Хотя вордпрессу не мешает, лол.
Так что это скорее кунг-фу веб-мастера, чем веб-кодера. Иди в \web\ - там твои все.
Есть библиотека на гитхабе, 2000 звездочек.
Ну автор, наверное, крутой поц, уж мне ли ему говорить как код надо писать?
Думал я.
А сейчас понимаю, какой же этот чел отбитый говноед, весь код этой либы - полное говно, где каждый пердеж сделан через __callStatic(), магию и КОММЕНТЫ классов блять.
Еще и ПРИМЕРЫ того, как надо юзать его либу, написанные самим автором.
Я по своей наивности слепо им следовал, в итоге только сейчас начал понимать, какой это отбитый кал.
Методы длиной в 500 строк нахуй.
Статик на статике и статиком погоняет.
Мечта тестера блять, тестировать магию нахуй, которой не существует.
Вместо value-объектов тупо массивы))0) с ключами-захардкоженными строками блять, рандомно упоминающимися по всему проекту.
И только теперь я понял, в какой пучине говна я погряз, потому что слепо следовал выданным мне рекомендациям.
Такая хуйня вот
>не будут ли поисковые роботы кидать мой сайт во вредоносные
Они твой серверсайд не видят. С чего бы?
>не будет ли это все потом тормозить при большой посещаемости?
Вот когда убьют будет тормозить, тогда и приходите. А ранняя оптимизация - зло.
Ну так пиши нормально теперь, чего убиваться? Если знаешь, где неправильно - уже полдела.
Экран маловат, но первое время можно пользоваться. Такой маленький ноутбук удобен, если ты будешь его куда-то с собой носить, например. Если же ты будешь дома сидеть и есть деньги, лучше купить большой монитор с высоким разрешением. Если нет - то небольшой, с высоким разрешением.
>>20962
Смысл не в наличии гитхаба, а в том, что там выложено. Люди часто присылают примеры кода на гитхабе перед собеседованием, но там обычно лежит какой-нибудь хелло ворлд, по которому о человеке ничего не сказать. А вот если есть примеры реального кода - другой вопрос. Но мне лично километры кода смотреть неохота, обычно просим прислать кусочек хорошего кода, которым человек может гордиться. И по нему уже можно вопросы позадавать.
В общем, если похвастаться нечем, то можно не заводить. Если же ты делаешь полезные опен-сурс проекты, или выкладываешь хорошие примеры кода, то конечно, это будет плюс.
Мне неинтересно смотреть: хелло-ворлды, скопированный код, ознакомительные примеры, созданные по туториалу, шаблонный код (геттеры, сеттеры) без логики.
>>20833
$n можно было не использовать, сразу писать 9.
Из вопроса непонятно, что делает метод. И нельзя сказать, к чему он относится. Приведу примеры:
- допустим, этот метод задает пользователю аватарку. Тогда он должен быть в модели (или в сервисе):
$user->setImage('avatar.jpg');
$userService->setImage($user, 'avatar.jpg');
- допустим этот метод принимает присланный пользователем файл и задает его как аватарку, используя сервис - тогда это часть контроллера:
private function setImage()
{
$form = new UploadForm();
$form->file = UploadedFile::getInstance($form, 'imageFile');
if ($form->validate()){
$this->userService->setImage($form->file);
} else {
...
}
}
Урок про MVC, ты прочел его? https://github.com/codedokode/apasta/blob/master/arch/mvc.md Там нет ответа?
>>20753
Можно завести переменную:
$y = $x * $x;
echo "$x -> $y\n";
Цикл можно сделать от 1 до 9.
Из вопроса непонятно, что делает метод. И нельзя сказать, к чему он относится. Приведу примеры:
- допустим, этот метод задает пользователю аватарку. Тогда он должен быть в модели (или в сервисе):
$user->setImage('avatar.jpg');
$userService->setImage($user, 'avatar.jpg');
- допустим этот метод принимает присланный пользователем файл и задает его как аватарку, используя сервис - тогда это часть контроллера:
private function setImage()
{
$form = new UploadForm();
$form->file = UploadedFile::getInstance($form, 'imageFile');
if ($form->validate()){
$this->userService->setImage($form->file);
} else {
...
}
}
Урок про MVC, ты прочел его? https://github.com/codedokode/apasta/blob/master/arch/mvc.md Там нет ответа?
>>20753
Можно завести переменную:
$y = $x * $x;
echo "$x -> $y\n";
Цикл можно сделать от 1 до 9.
А ты не искал определение, как должно быть правильно? Документация PHP говорит: http://php.net/manual/ru/language.operators.arithmetic.php
> Результат операции остатка от деления % будет иметь тот же знак, что и делимое — то есть, результат $a % $b будет иметь тот же знак, что и $a. Например:
>>20614
Ищем слово "кот": кот
Ищем кота + 1 или более пробелов: кот\s+
Ищем предыдущее выражение 10 раз подряд: (кот\s+){10} (ищет фразу вроде "кот кот кот кот кот кот кот кот кот кот")
Скобки тут используются, чтобы {10} применялось ко всему их содержимому.
>>20440
Судя по скриншоту, Апач запущен и отвечает на запрос браузера, просто передан неправильный URL или файла нет на диске или в конфиге Апача указана не та корневая папка.
Попробуй такой алгоритм в цикле:
- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000
«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
С подключением, скоро ты начнешь подозревать, что мир не всегда вписывается в три маня-термина: "Model, View, Controller".
Например, будут возникать куски кода, ответственные за обработку данных от разных моделей, используемые в разных контроллерах. Ну и куда это пихать?
Хороший ответ, пробежал глазками статью, теперь понял, как надо.
>>21175
>Сейчас десятилетие SPA, але, как там слышно из 2007-го?
Да какая по сути разница? В чем принципиальное отличие SPA от кучи страничек для пользователя? Я стараюсь почти весь код серваку отдать, чтобы пользователя не нагружать ебланскими js-вычислениями.
>Пых имеет отличные встроенные средства шаблонизации, гугли как это сделано в Yii. То, что ты написал - кал чистой воды.
Окей, спасибо, погуглю.
>Ну я вижу ты не слишком умный, поэтому предостерегаю: к параше типа smarty или twig не вздумай даже прикасаться.
Похоже, что придется прикоснуться, хотя бы для расширения кругозора.
>>21181
Двачую.
>>21191
>Нынче так уже не принято делать
Я вот не понял, и что? Что значит "нынче"? Мне понятен мой код, а главное - работать он будет быстро.
Если отбросить весь этот мусор с кучей библиотек и тонн кода, из-за которого подвисает броузер, то мы увидим, что интернет не изменился с того же самого 2007. Просто изменился дизайн, хтмл5 заменил флеш, ssl прикрутили. Все остальное программисты усложнили сами для себя же, чтобы получать больше бабла.
Model это не конкретные модельки в том же yii2. Model - это весь слой бизнес логики, он же и самый жирный со всего проекта. Обычно 90%+ кода в проекте и есть модель. И сделать ты его можешь как угодно.
>Я вот не понял, что значит "нынче"?
Последние 30 лет?
>Мне понятен мой код, а главное - работать он будет быстро.
Ты пишешь код не для того, чтобы он тебе был понятен.
Если ты не думаешь о других программистах, кто будет работать над проектом, ты - говнокодер, без вариантов, иначе быть не может.
Плюс это тебе сейчас кажется, что ты не в рот ебаться как хорошо разбираешься там. Через пару месяцев уже будешь вспоминать что и как, через полгода будешь вообще охуевать как ты мог такое высрать и хуй разберешь.
Выше верно сказали. Когда сделаешь перерыв и вернешься будешь со своим же кодом разбираться как с незнакомым, и тогда будет печально, если нахуевертил с легкой руки.
Всегда стремись писать так, чтобы тебя понимали другие программисты - писать на одном с ними языке. Иначе ты никогда не выберешься из вот такого своего июньского лапшекода.
Умные люди много всего нужного и полезного придумали для облегчения разработки. Зачем самому себе буратиной быть?
>Через пару месяцев уже будешь вспоминать что и как, через полгода будешь вообще охуевать как ты мог такое высрать и хуй разберешь.
Самое забавно в этой ситуации, что в процессе обучения бывает напишешь код и думаешь, что он идеален и вообще гениален. Через месяц смотришь на него и фейспалмы делаешь, думая - как же хорошо, что его никто не видел.
У меня такое пару-тройку раз было.
Пиши верно https://3v4l.org/UaM8i
Yoda Speak https://3v4l.org/coKeP
Сумма прописью https://3v4l.org/NSeMe
Калькулятор https://3v4l.org/n6fuv
так пусть жалоба подается с каким-то доказательством, будь то видео или что-либо еще
Это норма и признак того, что ты развиваешься.
Бывает даже когда просто некоторое время проект не трогал и "свежим взглядом" на него посмотришь, без предвзятости, и видишь - что код-то говнявый.
Когда ты постоянно долго над проектом работаешь, тут скостылишь, там скостылишь, не замечаешь этого.
А потом уже смотришь и видишь - ну очевидно хуйня же и фейспалмишь.
А когда читаю - не понимаю, нахуй оно надо, если только ты не работаешь с проектами в 500кк строк.
Посоветуйте, с чего начать и что почитать по этому поводу.
>Если ты не думаешь о других программистах, кто будет работать над проектом, ты - говнокодер, без вариантов, иначе быть не может.
Я не он, но взял тут симфони, написал composer update после чего он сожрал 2гб озу и ушел в своп. Нахуй не надо такие варианты.
>пишу все в одном файле
Выноси функции в отдельный файл библиотеки хотя бы, если их немного, если много - тоже разбивай на задачи\типы. Настройки всякие тоже в отдельной папке храни.
Я у себя ещё папку делают - \dev, куда валится всякая колбаса для разработки, формочки всякие, наброски кода\псевдокода, вроде как описание проекта.
Хотя сомневаюсь, что тебе это надо - ты, наверняка, сразу садишься писать что в голову взбрело, без описания задачи и т.д.
>в ООП не умею
Охотно верю.
>не понимаю, нахуй оно надо, если только ты не работаешь с проектами в 500кк строк.
Ты не напишешь ни одного более-менее толкового приложения меньше 1к строк. С нуля в смысле - без васянских либ. Но для школоскриптиков в 100 строчек это и правда - нахуй не надо. Тут ты прав.
>Посоветуйте
Ты в треде по ПХП. Советую читать ОПа.
Егор, ты?
Погоди, это ты ещё охуительные васянские фреймворки и либы на js не паковал. Там все 16 на изи сожрёт
Оказывается нужно указывать оператор echo, тогда выражения высчитываются.
Попробую, спасибо.
Какой сикп блять, ты че. Мы хардкорные макакоиды, заставляем вкладку браузера жрать 4 гига памяти и грузить проц на 60% на отрисовку веб-странички.
Подключаем зависимости композера на несколько гигов, чтобы использовать оттуда функцию калькулятора.
Сикп, лол...
Нормально делай - нормально будет.
Во-первых, почему на ideone.com не работает кириллица? Указываю и кодировку и mb_ приписываю - ошибка и всё.
Во-вторых, почему я после preg_split не могу через foreach пройтись по массиву и поменять буквы на заглавные с помощью ucfirst?
https://ideone.com/MmXhsI
Для начала научись правильно разбивать код на независимые функции. Скопирую из старого ответа:
-----
Видимо ты не понял идею разбиения кода на функции. Суть в том, что длинный кусок кода, который делает несколько вещей, сложно понять. Его сложно править, в нем много переменных, и можно нечаянно что-то сломать. Ну и физически прочитать 1000 или 10 000 строк кода быстро невозможно. Поэтому код разбивают на отдельные действия и выносят эти действия в функции. Так, что мы можем вместо огромной портянки кода читать только небольшую функцию, которая нас интересует.
Но для этого функции должны быть отделены от других частей кода. Они должны иметь определенное назначение (не размытое, вроде "делает одно действие, кусочек другого и готовит данные для третьего"). Они должны иметь понятное название, в котором описано их назначение. И они должны иметь понятный набор входных аргументов, что они принимают на вход, и что возвращают.
Вот пример более адекватной функции:
/**
* Принимает на вход целое число от 0 до 999 и возвращает его
* текстовое представление.
*
* Например, для числа 312 вернет "триста двенадцать".
*/
function spellNumber(int $number): string
Согласись, что даже если ты не прочитал код функции, ты из описания уже понимаешь, что она делает, и как ее можно использовать. Например, так:
echo spellNumber(123) . "\n";
Комментарий /** ... */ - это комментарий в формате phpdoc ( https://ru.wikipedia.org/wiki/PHPDoc ). Слово int и string - это тайп-хинты, советую их изучить:
- http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration
- http://php.net/manual/ru/functions.returning-values.php
То есть ты должен в идеале каждую функцию так описать. Если ты не можешь понятно описать назначение функции и формат ее аргументов, то скорее всего, ты что-то неудачно спроектировал.
-----
Почитай про хороший код: https://github.com/codedokode/pasta/blob/master/good-code.md
Там недописанный урок, потому самостоятельно погугли про "хороший код" и выпиши еще 5-10 правил.
Потом почитай про шаблоны и про MVC:
- https://github.com/codedokode/pasta/blob/master/php/templates.md
- https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Если нужны книги - поищи "Совершенный код" (Code Complete), хотя он, может быть, будет сложноват тебе.
Наконец, ООП. В ОП-посте есть учебник и в нем есть глава по ООП. Для практики попробуй решить ООП-задачи и вкинуть на проверку:
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
- ООП-Математика: https://phpclub.tech/pr/res/1305368.html#1309814
Предыдущие решения этих задач можно найти на phpclub.tech.
Можешь также вкинуть примеры своего кода, может кто-то прокомментирует и укажет на ошибки. А может ты сам их увидишь после изучения ссылок.
Насчет "нужно" - конечно, нужно, как другой человек будет разбирать твой код?
Для начала научись правильно разбивать код на независимые функции. Скопирую из старого ответа:
-----
Видимо ты не понял идею разбиения кода на функции. Суть в том, что длинный кусок кода, который делает несколько вещей, сложно понять. Его сложно править, в нем много переменных, и можно нечаянно что-то сломать. Ну и физически прочитать 1000 или 10 000 строк кода быстро невозможно. Поэтому код разбивают на отдельные действия и выносят эти действия в функции. Так, что мы можем вместо огромной портянки кода читать только небольшую функцию, которая нас интересует.
Но для этого функции должны быть отделены от других частей кода. Они должны иметь определенное назначение (не размытое, вроде "делает одно действие, кусочек другого и готовит данные для третьего"). Они должны иметь понятное название, в котором описано их назначение. И они должны иметь понятный набор входных аргументов, что они принимают на вход, и что возвращают.
Вот пример более адекватной функции:
/**
* Принимает на вход целое число от 0 до 999 и возвращает его
* текстовое представление.
*
* Например, для числа 312 вернет "триста двенадцать".
*/
function spellNumber(int $number): string
Согласись, что даже если ты не прочитал код функции, ты из описания уже понимаешь, что она делает, и как ее можно использовать. Например, так:
echo spellNumber(123) . "\n";
Комментарий /** ... */ - это комментарий в формате phpdoc ( https://ru.wikipedia.org/wiki/PHPDoc ). Слово int и string - это тайп-хинты, советую их изучить:
- http://php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration
- http://php.net/manual/ru/functions.returning-values.php
То есть ты должен в идеале каждую функцию так описать. Если ты не можешь понятно описать назначение функции и формат ее аргументов, то скорее всего, ты что-то неудачно спроектировал.
-----
Почитай про хороший код: https://github.com/codedokode/pasta/blob/master/good-code.md
Там недописанный урок, потому самостоятельно погугли про "хороший код" и выпиши еще 5-10 правил.
Потом почитай про шаблоны и про MVC:
- https://github.com/codedokode/pasta/blob/master/php/templates.md
- https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Если нужны книги - поищи "Совершенный код" (Code Complete), хотя он, может быть, будет сложноват тебе.
Наконец, ООП. В ОП-посте есть учебник и в нем есть глава по ООП. Для практики попробуй решить ООП-задачи и вкинуть на проверку:
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
- ООП-Математика: https://phpclub.tech/pr/res/1305368.html#1309814
Предыдущие решения этих задач можно найти на phpclub.tech.
Можешь также вкинуть примеры своего кода, может кто-то прокомментирует и укажет на ошибки. А может ты сам их увидишь после изучения ссылок.
Насчет "нужно" - конечно, нужно, как другой человек будет разбирать твой код?
Не хочешь исследовать причины проблемы и исправить её? Или, может, кто-то из анонов хочет помочь улучшить композер? Для начала, ты бы мог дать пример composer.json и написать, что сделать, чтобы отъесть столько памяти.
На ideone нету mb-функций так как админы забыли поставить расширение mbstring, используй например repl.it.
ucfirst работает только с латинницей в ограниченных случаях, урок: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md
Функции более широкое понятие нежели просто блок кода. Функция прежде всего выступает абстракцией, черным ящиком. Например функция возведения в квадрат, это механизм, черный ящик содержащий в себе механизм. Из таких маленьких механизмов можно строить более сложные. Вся программа это тоже черный ящик как и функция. В него опускают данные, и получают результат. Функция может принимать другую функцию, также как и программа можно принимать на вход другую программу.
Я увидел только то, что ucfirst не работает с utf-8 кодировкой. Однако тут всё отлично работает. https://ideone.com/vqpoX8
Алсо. Чтобы без ucfirst сделать - это мне после разбивки на предложения, надо с помощью substr брать первую букву и переводить её в заглавную?
Или там проще решение есть?
$page на месте с 1
Абсолютно всем. Попробуй найти хоть одну хуйню, что в пхп сделана лучше, чем в яве.
Не найдешь.
По имени и фамилии
Бампую этот вопрос и прикладываю ещё один.
Пытаюсь писать калькулятор по заданию ОПа, но встал на моменте выполнения вычислений. То есть строку вида "241+142" я разобрал посимвольно, выяснил, где цифра, а где знак мат. операции и засунул цифры в переменную. Как быть со знаком? Я могу для каждого отдельного случая написать условие, вида: if($char == "+") {$result = $a+$b} elseif($char == "-") {$result = $a-$b}
Но можно же как-то компактней сделать это, правильно? У ОПа в примере есть кусок if($char == "+" || $char == "-"){}
Но что с этим делать - ума не приложу.
Мысль интересная, но что-то я вообще запутался.
Если я все числа кладу в переменную, то у меня получается просто строка с числами. Было 442+511, а стало 442511.
Что-то вообще хуйня получается.
Все там такое же. А иногда и хуже.
.at() или как там
если у тебя на работе битрикс, беги оттуда
Да там смотреть-то нечего особо.
Ну вот всё, что навоял за это время.
https://repl.it/@JoeGreen/GrossPunctualTrapezoids
Алсо, дайте сборник задач годных. Для начинающих. А то в интернетах не особо много. И есть ли конфа пхпшников или что-то такое, а то на борде ответа ждать - долго получается.
если честно, эти задачи в отрыве не так уж много и дают. пройти Опшные и иди дальше. в ооп и в создание проектов. больше профита будет
Так в том то и дело, что я даже задачи опа не могу толком решить. После основного курса, в разделе "Повторим?" вообще толком ни одной не могу. Вот, как пример - калькулятор. Мой максимум - написать функцию или цикл, кажется.
По этому и думаю - другие задачи порешаю, проникнусь/закреплю знания, а дальше попроще будет.
если честно, я тоже не смог изначально решить большинство задач. и я забил на многие. пока что ничего сложнее этих задач, я не встретил. а я работаю уже пол года.
Что ты хочешь написать, калькулятор? Из сообществ советую slack-чат Хекслета, или чаты в Телеграм.
>если честно, эти задачи в отрыве не так уж много и дают. пройти Опшные и иди дальше. в ооп и в создание проектов. больше профита будет
Не советуй такое. Он скорее всего еще толком ничего не писал. Нужно решать алгоритмические задачи, рекурсия, циклы, структуры данных, деревья. ООП вообще не нужно. Можно писать в ФП стиле. С ООП нужно знакомиться, когда уже уверенно пишешь код. Иначе неокрепший мозг сломается, и получится очередное "ООП головного мозга". И советую тот же путь.
>Так в том то и дело, что я даже задачи опа не могу толком решить.
Потому что мало решал задачек. Советую эти курсы, там и задачек полно https://ru.hexlet.io/professions/php#education
Рано писать калькулятор, когда не понимаешь как составить алгоритм его работы. Лучше думай над этим алгоритмом. А когда поймешь, то сможешь реализовать. Пока у тебя еще мало опыта, поэтому не понимаешь. Но важно разработать алгоритм решения, а не тупо пытаться писать код. Так не получится. Сначала решение должно появиться в голове.
Я ни разу не применил рекурсию за время работы. Мне не нужна было знать, что такое стек, деревья, графы (ну графы кстати в одной задачке Опа используются), до того момента пока я не начал писать, на низкоуровневом языке. Мне кажется, что задач со строками и циклами хватит на большую часть веба. А остальное нужно просто знать и может быть, если ты не останешь говнокодером на всю жизнь, те это пригодится.
Скорее всего на Битриксе.
Роутинг на деревьях как реализовывать будешь?
Я просто хочу решить задачу ОПа, а она состоит в написании калькулятора.
>>22635
>Потому что мало решал задачек.
Так никто и не спорит. Я решал только те, что были по ходу курса ОПа и всё.
Потом пытался найти в интернете что-то, но там всё примерно одинаковое - "заполните массив 10 случайными числами" или "посчитайте, сколько секунд в часе" и тому подобное.
За хекслет спасибо - завтра посмотрю.
>Так никто и не спорит. Я решал только те, что были по ходу курса ОПа и всё.
Я не смотрел, но мне кажется там алгоритмических задач нет. Нужны именно алгоритмические. Лучше Хекслета ничего не найдешь, потому что кроме алгоритмических задач, там отлично обучают. Вряд ли где то еще тебя научат как применять функции высшего порядка. А просто на досуге задачки порешать можно на Codewars.
Понял, спасибо. Завтра точно гляну.
>Иначе неокрепший мозг сломается
Иначе люди пишут такой ООП, который та же функциональщина.
Недавно тут один апи смотрел - там поц засунул все запросы на сервер в один метод. Пара десятков запросов в одном методе, Карл!
> Я увидел только то, что ucfirst не работает с utf-8 кодировкой. Однако тут всё отлично работает. https://ideone.com/vqpoX8
Если в отдельных случаях (латинница в utf-8) работает, а в отдельных - нет, то это называется "не работает".
Нужно использовать mb-функции, отрезать первую букву, увеличивать и приклеивать остаток строки. Можно это оформить как свою отдельную функцию и использовать в будущем и в других программах.
>>22001
Непонятно, что именно у тебя не работает? При наборе определенного URL получается страница 404? Пагинатор (какой?) генерирует неправильные ссылки? Поясни, чтобы было понятно.
Также, если ты прописал в роуте "/{page}" то он не будет открываться, если в URL просто "/". Для этого надо сделать отдельный роут, и желательно в /{page} запретить вариант page = 1.
>>22219
Вам сюда: https://habr.com/post/315152/
И хватит разводить бессмысленный флуд. Ладно, если бы ты конкретные примеры приводил, а твои посты бессодержательны.
Написать блок if/elseif и не заморачиваться. Вот тебе пример калькулятора из phpExcel, если интересно: https://github.com/PHPOffice/PhpSpreadsheet/blob/master/src/PhpSpreadsheet/Calculation/Calculation.php
Он разбирает и вычисляет с помощью PHP значения формул в синтакисе Excel.
>>22603
Можно без стека.
>>22627
Ты разбираешься в фукнциональном программировании? Можешь дать образец качественного, понятного не только автору, подходящего для использования в команде функционального кода? Не из учебника (вычисление числа Фибоначчи), а из реального проекта. Не из 30 строчек, а реального уровня сложности, с логикой.
Поддерживается ли ФП в IDE? Есть ли там переход к определению и прочие радости?
Я не то чтобы против ФП, но плохо представляю, как его использовать, например в бекенде мессенджера, соцсети, IoT-устройства или интернет-магазина.
>Я не то чтобы против ФП, но плохо представляю, как его использовать, например в бекенде мессенджера, соцсети, IoT-устройства или интернет-магазина
ФП это просто способ писать код. Набор правил или рекомендаций если угодно.
Код в императивном стиле обычно выглядит как набор инструкций, который последовательно изменяет и сохраняет состояние программы. Ключевой момент в императивном коде это переменные. В них хранится состояния. Оно постепенно изменяется и перезаписывается.
Код в функциональном стиле выглядит как выражение. Как в математике. Выражение вычисляется и возвращается результат. В этом все отличие. Нет состояния, нет инструкций по изменению состояния. Важно понять отличие выражений и инструкций. Есть языки, в которых все является выражением. Они очень удобны, код на них краткий и понятный. Напротив, языки в которых много инструкций очень неудобны, и код на них многословен.
В Лиспах к примеру if является выражением. Он всегда возвращает результат. И его можно вставлять в любой участок кода. В императивных языках if является инструкцией. Он ничего сам не возвращает, не становится значением. А выражение всегда возвращает значение. Поэтому if в императивных языках громоздкий и ограниченный по возможностям.
>Код в функциональном стиле выглядит как выражение. Как в математике. Выражение вычисляется и возвращается результат.
На словах очень хорошо звучит, но на практике мне адово тяжело это читать. Даже когда понимаешь хуле там делается и код сам красивенький - все равно нюансы ускользают. 8 лет опыта работы.
Математику в школе все учат. В математике все представляется в виде выражений. Почему это сложно понимать?
Еще в школе нас учили бегать, прыгать и играть в мячик. Это не делает тебя спортсменом или даже разбирающимся в спорте человеком. Я субъективное мнение высказал - функциональщина на больших объемах для меня является лапшой, которая не стоит затраченного на нее времени, особенно на поддержку. Для тебя может и по другому.
>функциональщина на больших объемах для меня является лапшой, которая не стоит затраченного на нее времени, особенно на поддержку
Может ты просто не понимаешь о чем речь. Откуда знать что ты там видел, и что называешь функциональщиной. ФП код не может быть лапшой по определению. Значит ты видел что-то другое.
>Еще в школе нас учили бегать, прыгать и играть в мячик. Это не делает тебя спортсменом или даже разбирающимся в спорте человеком.
Не очень хорошая аналогия. Я бы привел в пример шахматы. Человек, который сыграл хотя бы несколько десятков партий, как минимум знает как ходят фигуры. Поэтому для него нет проблемы понимать как течет партия. Даже если он смотрит партию гроссмейстеров. Да, он не может делать такие же умные ходы, но он знает как двигаются фигуры, по каким правилам, и может видеть кто выигрывает или проигрывает. Со школьной математикой все даже лучше. Если человек решал школьные задачи, а не бездельничал, то он легко может понимать математические выражения. Это не выдающееся умение, просто навык.
Значит у тебя нет навыка. И ты не хочешь его приобретать. Поэтому придумываешь отговорки, что оно непонятно и сложно. Хотя в реале все наоборот. Это просто и понятно.
>>22885
А помоему довольно хорошая. Это изначальный тезис был говном.
Это же как приравнять способность к рисованию блоксхемок на информатике к написанию сложных приложений. Вроде и соблюдено начальное условие, но промежуточные напрочь игнорируются.
Если так упрощать любую концепцию, то почему не каждый, кто умеет говорить способен еще и петь? Или че это не каждый из нас художник, хотя карандаш в руках держать способен? А те, кто и способен и художник - хуле не в "приавильном" стиле художники? И тут бы уже пора художникам завести спор о четкости предпочитаемого стиля.
О, а че это этот чувак зная правила шахмат не имеет даже разряда?
Список можно продолжать - это попытка излишнего упрощения в суждениях.
Аналогия с шахматами тоже излишне упрощена. Конечно любой, кто знает правила игры, сможет просто налюдать любую другую игру. Но видеть он ее будет на своем уровне, а нихера не близко к тому майндгейму, который в головах профессиональных игроков происходит. Да и как бы наблюдать игру гроссмейстера не значит сыграть с ним хотя бы достойно. Иначе в чем смысл этой аналогии? Типа тот, кто понимает "правила" фп сможет раздуплить фп код? Да все даже проще - их и понимать то не надо, чтобы раздуплить при достаточной сноровке, т.к фп хоть и оперирует выражениями, но не делает вообще никакой магии (потому что ее, понятное дело, не существует), кроме наложения новой парадигмы с опеределнными целями. Мимо простейшей логики у нас не пройти и все можно свести к ней же, так что упертость поможет решить проблему чтения кода на любом языке с любой применяемой парадигмой даже конченному барану. Захочешь - разберешь. Даже если из математики только яблоки складывать умеешь.
То, на что тот тезис про математику был ответом, вообще не имеет отношения к сказанному изначально, видимо меня не верно поняли. Придется уточнить приведением мысленного примера - если мне дать две версии кода сферического небольшого приложения, но одно будет написано на фп, а второе нет - то второе я смогу и разобрать и поддерживать практически мгновенно, даже если там довольно херовый код, в то время как на фп это будет гораздо медленее проиходить у меня. Не "не понято двоечником", а просто усложнен процесс инвестегирования и прочей поддержки. Объем приложения к примеру в сферические 30к строк императивного кода, на фп хз сколько. Нахер мне про школьную математику втирать, если я в состоянии работать с фп, просто не хочу это повторять?
Почему это должно быть не правдой, тем более что я четко указал, что это конкретно меня касается? На том моменте про "не понял" линию диалога понесло куда-то в сторону "докажи, что твой оппонент просто дурак любым способом". Это же вопрос обычной практики. Для того, кто наяривал фп наверняка все будет по другому, и это тоже не мешает ему высказать свое мнение по этому вопросу и остаться по своему правым. Правда тут есть только субъективная, т.к. это сраный спор о вкусах, где только время покажет, кто жрал говно, а кто нет. А скорее всего время покажет, что говно жрали все, как оно обычно и бывает, и одаримся мы какой-нибудь хитровыебанной парадигмой, на хую вертевшей всех, когда гению в башку клюнет. Сейчас на это по большому счету насрать, потому что элементы фп в любом современном языке чуть ли не в рекомендациях к действую имеются, и это тоже плюс, очень удобно по случаю (хотя и без специального сахара можно было обойтись, нихера же не меняется). Но вот чистое фп, чтоб аж скупая слеза у хардкорных адептов скатилась, пока что не сильно угрожает императивному коду, насколько бы оно простым не казалось например для тебя. Только не говори что в оценке на глаз я тут не прав, ты и сам знать должен, как дела обстоят. На данный момент ниша фп на подхвате в тех местах, где императивщина некрасивой становится. Такое себе перетягивание каната выходит.
Я кстати не спорю, что может я и с какой-то паленой приложухой на фп работал, откуда мне знать, я не прошаренный сильно в этой теме. Однако после этого, как ты верно заметил, желание искать на свою жопу новых функциональных впечатлений у меня отпало. Пока до новой необходимости приоритеты расставлены.
>>22885
А помоему довольно хорошая. Это изначальный тезис был говном.
Это же как приравнять способность к рисованию блоксхемок на информатике к написанию сложных приложений. Вроде и соблюдено начальное условие, но промежуточные напрочь игнорируются.
Если так упрощать любую концепцию, то почему не каждый, кто умеет говорить способен еще и петь? Или че это не каждый из нас художник, хотя карандаш в руках держать способен? А те, кто и способен и художник - хуле не в "приавильном" стиле художники? И тут бы уже пора художникам завести спор о четкости предпочитаемого стиля.
О, а че это этот чувак зная правила шахмат не имеет даже разряда?
Список можно продолжать - это попытка излишнего упрощения в суждениях.
Аналогия с шахматами тоже излишне упрощена. Конечно любой, кто знает правила игры, сможет просто налюдать любую другую игру. Но видеть он ее будет на своем уровне, а нихера не близко к тому майндгейму, который в головах профессиональных игроков происходит. Да и как бы наблюдать игру гроссмейстера не значит сыграть с ним хотя бы достойно. Иначе в чем смысл этой аналогии? Типа тот, кто понимает "правила" фп сможет раздуплить фп код? Да все даже проще - их и понимать то не надо, чтобы раздуплить при достаточной сноровке, т.к фп хоть и оперирует выражениями, но не делает вообще никакой магии (потому что ее, понятное дело, не существует), кроме наложения новой парадигмы с опеределнными целями. Мимо простейшей логики у нас не пройти и все можно свести к ней же, так что упертость поможет решить проблему чтения кода на любом языке с любой применяемой парадигмой даже конченному барану. Захочешь - разберешь. Даже если из математики только яблоки складывать умеешь.
То, на что тот тезис про математику был ответом, вообще не имеет отношения к сказанному изначально, видимо меня не верно поняли. Придется уточнить приведением мысленного примера - если мне дать две версии кода сферического небольшого приложения, но одно будет написано на фп, а второе нет - то второе я смогу и разобрать и поддерживать практически мгновенно, даже если там довольно херовый код, в то время как на фп это будет гораздо медленее проиходить у меня. Не "не понято двоечником", а просто усложнен процесс инвестегирования и прочей поддержки. Объем приложения к примеру в сферические 30к строк императивного кода, на фп хз сколько. Нахер мне про школьную математику втирать, если я в состоянии работать с фп, просто не хочу это повторять?
Почему это должно быть не правдой, тем более что я четко указал, что это конкретно меня касается? На том моменте про "не понял" линию диалога понесло куда-то в сторону "докажи, что твой оппонент просто дурак любым способом". Это же вопрос обычной практики. Для того, кто наяривал фп наверняка все будет по другому, и это тоже не мешает ему высказать свое мнение по этому вопросу и остаться по своему правым. Правда тут есть только субъективная, т.к. это сраный спор о вкусах, где только время покажет, кто жрал говно, а кто нет. А скорее всего время покажет, что говно жрали все, как оно обычно и бывает, и одаримся мы какой-нибудь хитровыебанной парадигмой, на хую вертевшей всех, когда гению в башку клюнет. Сейчас на это по большому счету насрать, потому что элементы фп в любом современном языке чуть ли не в рекомендациях к действую имеются, и это тоже плюс, очень удобно по случаю (хотя и без специального сахара можно было обойтись, нихера же не меняется). Но вот чистое фп, чтоб аж скупая слеза у хардкорных адептов скатилась, пока что не сильно угрожает императивному коду, насколько бы оно простым не казалось например для тебя. Только не говори что в оценке на глаз я тут не прав, ты и сам знать должен, как дела обстоят. На данный момент ниша фп на подхвате в тех местах, где императивщина некрасивой становится. Такое себе перетягивание каната выходит.
Я кстати не спорю, что может я и с какой-то паленой приложухой на фп работал, откуда мне знать, я не прошаренный сильно в этой теме. Однако после этого, как ты верно заметил, желание искать на свою жопу новых функциональных впечатлений у меня отпало. Пока до новой необходимости приоритеты расставлены.
>Конечно любой, кто знает правила игры, сможет просто налюдать любую другую игру. Но видеть он ее будет на своем уровне, а нихера не близко к тому майндгейму, который в головах профессиональных игроков происходит.
Ну ты видел математику, а теперь говоришь, что выражения в программировании сложно понимать. Во первых они проще математических. Во вторых что сложного вообще может быть в выражении? Есть операнды, есть операторы, есть приоритет операций, - все, больше ничего нет.
>Типа тот, кто понимает "правила" фп сможет раздуплить фп код? Да все даже проще - их и понимать то не надо, чтобы раздуплить при достаточной сноровке, т.к фп хоть и оперирует выражениями, но не делает вообще никакой магии (потому что ее, понятное дело, не существует), кроме наложения новой парадигмы с опеределнными целями.
Ну так чего ты тогда голову морочишь.
>Придется уточнить приведением мысленного примера - если мне дать две версии кода сферического небольшого приложения, но одно будет написано на фп, а второе нет - то второе я смогу и разобрать и поддерживать практически мгновенно, даже если там довольно херовый код, в то время как на фп это будет гораздо медленее проиходить у меня. Не "не понято двоечником", а просто усложнен процесс инвестегирования и прочей поддержки. Объем приложения к примеру в сферические 30к строк императивного кода, на фп хз сколько. Нахер мне про школьную математику втирать, если я в состоянии работать с фп, просто не хочу это повторять?
Так и скажи, что не осилил, не хочешь, не понимаешь, и т.п.
Делай двойной перенос строки, дели текст на небольшие абзацы. Такую простыню сложно читать.
>Вот тебе пример калькулятора из phpExcel, если интересно:
Может и интересно, но я почти ничего не понимаю, что там происходит.
>Написать блок if/elseif
Чек.
Написал, всё работает. Единственное НО - я не понимаю, как выполнить операцию без указания её самой. То есть, если есть выражение 2+2, то я пишу if($char=='+') {$a+$b}
Я намеренно указываю, что а+б. Так как сделать так, чтобы код сам узнавал оператор?
https://repl.it/@JoeGreen/GrossPunctualTrapezoids
И да. Есть ли смысл на код бейсик проходить тренинги? На Хаскеле написано, что там первая часть уроков находится.
>а теперь говоришь, что выражения в программировании сложно понимать
Думаю тебе так показалось, я об этом не говорил. Может не достаточно ясно писал выше.
Мне проще понимать императивный код, чем функциональный - вот и все, что я с самого начала хотел сказать. Зачем это все выворачивать?
По мне: для поддержки он в несколько раз проще, чем фп. Это критичный момент, и я его упоминаю. Сопровождение кода самое больное место. Написать может любой и в закат уебать довольный, а кому-то потом разгребать и развивать всю красоту. Например тебе или мне. Как это вообще можно забыть? Как будто кривого кода никогда не встречал. (фп я к говнокоду сейчас не приравниваю, просто пример о восприятии)
Я не раз упрощал свои абстрактные финты ушами, чтобы понятнее становилось, зато лучше всем остальным работалось. Красота в понимании одного - проблемы для другого. Надо фидбек получать, чтобы не укатиться в корыто.
А так пойму любой код, дело только в комфорте поддержки, что лирика. Правда эта лирика в человекочасы конвертится.
>>23044
Смотри выше.
>>23045
Жопой читаешь.
>>23046
Оке. Не привык писать длинные посты, чет пробило в этот раз.
>И да. Есть ли смысл на код бейсик проходить тренинги? На Хаскеле написано, что там первая часть уроков находится.
Чёхго? Ты про code-basics.ru? На Хаскелле? Может Хекслете. Стоит проходить, очень даже стоит.
>По мне: для поддержки он в несколько раз проще, чем фп
Как код с изменяемым состоянием может быть проще в поддержке? Все знают, что изменяемое состояние это зло. Если функция где-то что-то изменяет, то это приводит к ошибкам, и это сложно обнаружить. А ты говоришь это легко отлаживать. Не может быть у тебя 8 лет опыта, как ты написал.
Никто ни к чему никого не обязывает, ты путаешь холодное с сладким. Ты можешь делать имутабельной импертивщину прикинь))) Главное в правильных местах, чтобы жопа не горела. Хоспаде, откуда вы лезете, надоели уже. Опытнее станьте, а не по методичкам твердите. Хочешь поговорить с кем-то с головой, а тебе уже третий пост цитатами без смысла наяривают.
>Ты можешь делать имутабельной импертивщину прикинь)))
Смешная шутка.
>>23116
>Опытнее станьте, а не по методичкам твердите.
Эта еще смешнее, если учесть, что ты плаваешь в простых понятиях, а говоришь, что у тебя 8 лет опыта.
Как может императивный код быть иммутабельным, если он состоит из состояний, которые последовательно меняют? о_О Иммутабельный переводится как неизменяемый.
>Иммутабельный переводится как неизменяемый.
Ну пятерочку по ангельскому ты заслужил, но схуя ты думаешь, что имутабельность это свойство определенной парадигмы, а другие НУ НИКАК не смогут? То, что ты больной не предлагай, слишком очевидно.
Приведу цитату из словаря:
ИМПЕРАТИВНОЕ ПРОГРАММИРОВАНИЕ
Парадигма программирования, которая, в отличие от декларативного программирования, описывает процесс вычисления в виде инструкций, изменяющих состояние программы.
Императивное = изменяемое состояние. Как оно может быть иммутабельным?! Вопрос риторический.
То есть когда я что-то иммутабельное на чистом ооп напишу ты глазам своим не воверешь, что это не императив? Ну ты и даун, хоспаде.
>имутабельность это свойство определенной парадигмы
Иммутабельность это свойство состояния. Состояние становится неизменяемым. Неизменяемые структуры данных. Неизменяемые переменные (Джо Армстронг называет их по-другому, не помню как) как в Эрланге.
Ой, а что если я просто напишу чистую функцию? Это все, я стал чернокнижником? Вы головой, а не словарями, думать умеете? А что если я функциональщину кааак ебну посреди мутабельного состояния - это будет фп или зашкваренное грязным пхп фп? У вас на районе как с этим? У меня всем похуй.
Ты выдрал часть саркастического предложения и на серьезных щах на это отвечаешь. Иммутабельно так сказать.
>когда я что-то иммутабельное на чистом ооп напишу ты глазам своим не воверешь, что это не императив?
Сам понял что написал. Учись ясно выражать свои мысли.
Ну ясно все с вами, тогда отчаливаю, слишком жестко.
>Ты выдрал часть саркастического предложения и на серьезных щах на это отвечаешь. Иммутабельно так сказать.
У тебя проблемы с логикой. Только состояние может быть иммутабельным. Как и то, что только жидкость может быть жидкой.
А что такое фп тогда? Просто способ написания кода. Иммутабельность можно сделать везде, и хоть мы тут друг друга уже говном закидываем очень блядь странно что вы этого вообще не понимаете, а на своей непогрешимой параше настаиваете запугивая бедных нюфагов в этом треде. Делов то полкопейки - парадигму под реальный мир приспособить. Чего вам, видимо, не дано. Фанатизма слишком много. Всегда у тебя будет состояние, в этом и ключевой косяк фп - слишком идеализируют и от этого сосут на всем, что выходит за рамки синуса. Вот и не взлетает выше хелперов к грязным мутабельным языкам это хваленое фп (покпок щас кинут какойнибудь твиттер). Хотя чего странного, по вики шпарите, практики и своих мыслей нихуя. Даже ценность мутабельности и иммутаьелности разъяснить не можете, только кейвордами покидаться есть силы.
>>23145
С чего ты взял что состояние обязано быть везде, кроме фп? С чего ты взял, что везде, кроме фп состояние будет? Что по твоему такое вообще состояние? И с чего ты взял, что это главная фишка фп? Ты думаешь фп это про иммутабельность? Вы там клей нюхаете или что? - одна чушь охуительнее другой.
Ой, извините, с чего ты взял что состояния в фп нет? Еще как есть, ты просто немного в глазки идеализируешь. Я в ахуе с этих даунов, у них состояние просто в идеальном случае не в куче лежит, а на стеке, а они уже из себя уже форму жизни из темной материи строят. И то идеальных случаев не бывает, мы тут не фпшной сказке живем.
>У тебя проблемы с логикой
Сначала за свою логику со школьной математикой ответьте. Хотя куда там фп и логика, сорян за принижение.
>плохо представляю, как его использовать, например в бекенде мессенджера, соцсети, IoT-устройства или интернет-магазина.
>
Писал простой интернет магазин на функциях задавайте отверты. Вполне реально это делать.
Другое дело, что там без современных модных фич. Да тот же Вордпресс 90% через функции написан.
>Ну ты видел математику, а теперь говоришь, что выражения в программировании сложно понимать
Какая математика? Все стремятся к созданию\описанию модели небольшого кусочка реального мира посредством языка программирования, создавая объекты. Кому нужна математика в программировании? Это было актуально в 70х годах, но не сегодня.
Я тебе что, математик, чтобы формулы писать и считать? Пека у меня для чего нужна тогда? Мне, как кодеру, достаточно только уметь общаться с ней, донося, что хочет заказчик.
Не буду толочь воду в ступе. Слишком много текста чтобы на каждое предложение отвечать. Да и почти все они не предполагают ответа.
Ты сам все спутал изначально, а теперь выкручиваешься. Состояние есть везде, но в ФП состояние не изменяемое, то есть то самое иммутабельное. В Эрланге к примеру все неизменяемое. Ты пишешь, что можно сделать иммутабельное состояние при императивном программировании, что само по себе абсурд.
>Все стремятся к созданию\описанию модели небольшого кусочка реального мира посредством языка программирования, создавая объекты.
Ешьте в забегаловке у ООП, миллион мух просто так не прилетят.
А если серьезно, то кто сказал, что все стремятся? В математике такого и близко нет. ФП как раз математическая модель, выросшая из Лямбда-исчисления Чёрча.
>>23190
>Кому нужна математика в программировании? Это было актуально в 70х годах, но не сегодня.
Это вообще нонсенс. Ты хоть знаешь, что все программирование имеет математику под собой. Кроме ООП конечно, это чистой воды костыль, не имеющий никакого серьезного фундамента.
Так и скажи, что неосилил ООП и пишешь как джун.
И не осилишь никогда, судя по всему.
>в забегаловке у ООП
>миллион мух просто так не прилетят
>математическая модель
>все программирование имеет математику под собой
>ООП - костыль
Большего бреда я давно не видел. Мало того, что ты не можешь в ООП и несёшь явную дичь, так ещё и про математику у тебя заело.
Ещё раз - все стараются уйти от математики в программировании, просто потому, что это слишком низкоуровневая тема. Все, кроме тебя.
>>23234
Во первых не обобщай. Кто все? Ты несешь такую пургу, что даже смешно. Математика у него низкоуровневая. Я такой чепухи никогда в жизни не слышал. Уйти от математики в программировании - это смешно не меньше. Честно говоря, тебе уже ничем не помочь. К сожалению твой уровень вряд ли поднимется выше написания бесполезного инфраструктурного кода, ибо до алгоритмов (математики) ты не дорос. Пиши дальше бесполезные бойлерплейты.
>Кто все?
Все программисты. Байткод->ассемблер->ЯП->функционалка->ООП.
Ты либо сказочный пионер, либо зеленый.
Есть ли адеватное, блять, решение такой элементарной задачи? Почему это так сложно и не работает ничего?
Моя логика в том, что платя за ипотеку 30к, из этой трицадки в среднем 15к и будут проценты. В то время как лучше эти 15к положить на сберегательный счет. И в этом случае проценты уже начинают работать в обратную сторону.
Идея была даже в том, что бы написать скрипт, который бы работал по следующему алгоритму.
Скажем мы простой работяга у которого есть в месяц Х свободных тысяч рублей. Далее что мы делаем. Когда наши накопления становятся больше 50к (минимальный вклад в сбере), то кладем их в наш сбербанк под 7% (опять же есть такой вклад, если время минимум год.
Например имеем такие по 12.5тр. в месяц, стало быть через 4 месяца делаем первый вклад. Через еще 4 месяца уже второй. И так далее.
Допустим мы начали всю нашу затею в сентябре, и наш первый вклад пришелся на новый год. Стало быть через год и 4 месяца начала всей нашей затеи, мы уже снимаем 53.5 тысячи рублей с вклада. Плюсуем их к тому что у нас есть сейчас на руках с зарплаты и создаем новый вклад. Далее процесс начинает циклично повторяться. Снимаем вклады, плюсуем к тому что у нас заработано и закидываем в банк. За какое время при таком подходе мы накопим себе 2 милиона рублей?
Далее допустим мы накопили 2 милиона, сняли все текущие вклады и купили себе квартиру, которую можно тоже сдавать и добавить к нашему доходу еще 12.5к в месяц.
Осуществимо ли это вообще, если скажем изначальная цена квартиры 2миллиона, но при этом она будет в среднем дорожать на 1% каждый месяц на протяжении всего цикла?
В общем никто не хочет начать решать? Сам поделился скорее что бы не забыть, просто сегодня сильно заебан на работке и лень думать.
http://php.net/manual/ru/function.file.php
Ну вот тебе даже алгоритм примерный: применяешь это на файл, получаешь массив в котором каждая строка твоего файла = элемент массива.
Далее редактируешь нужный элемент, и проворачиваешь обратное уже действие, уверен что функция прямо в описании будет как подсказка.
Ну и еще проверь что бы у твоего интерпретатора доступы были к папкам в которых ты шаришься и что бы путь к файлу был правильный и все такое.
Спасибо, не ожидал увидеть ответ, писал уже просто от отчаяния. Но тут тоже не могу разобраться, как обратную операцию провести, т.е. записать измененный массив в файл. Еще же ведь и перезапись нужна, а не в конец писать. Ох.
$filePath = 'closed/logpassDB.txt';
// Запись.
$data = serialize($DB);
file_put_contents($filePath, $data);
// Чтение.
$data = file_get_contents($filePath);
$DB = unserialize($data);
Ах, да. Id у кнопок генерируются динамически, так что простым с жикверным $().on('click', ...) тут не получится совладать, как мне кажется.
Можно сделать форму с hidden полем, через js туда передавать id и после этого отправлять форму.
А что, с базой можно соединиться только посредством формы?
Для игр винда, для администрирования лексус.
А примера кода нету?
> Код в императивном стиле обычно выглядит как набор инструкций, который последовательно изменяет и сохраняет состояние программы
А я не про это. Вот, например, в императивном стиле у нас есть классы, и известно в каком файле какой класс. И часто редактор позволяет перейти к нужному методу (а если нет - можно догадаться). А есть ли такое в ФП? Не будет ли большая программа в ФП выглядеть как гигантское выражение, которое надо прочесть и изучить целиком, прежде чем можно что-то понять и начать править? Или как длинный набор определений, которые, опять же, надо все прочесть сначала? Не будет она выглядеть как код на Питоне или JS в плохом смысле этого слова?
Также, не провоцирует ли ФП вместо простого кода из последовательности действий писать сложные обертки из функций, которые обрабатывают друг друга и где надо полчаса разбираться, чтобы понять, что происходит?
Вот был бы пример кода - можно было бы посмотреть.
> Выражение вычисляется и возвращается результат.
Я плохо представляю выражения размером хотя бы в 10 000 строк.
В вордпрессе процедурное программирование, а не функциональное. Ты можешь посмотреть определения в википедии.
Лучше класть id в дата-атрибуты, которые для этого придуманы. Также, можно каждую кнопку обернуть в форму со скрытым полем и обойтись без JS.
>Я плохо представляю выражения размером хотя бы в 10 000 строк.
Никто не в состоянии написать выражение такой величины. И цели такой нет ни у кого. Наоборот, функциональное программирование склоняет к минимализму.
>>23537
>А примера кода нету?
На PHP у меня готового кода нет, и искать не хочется. PHP разработчики могут не до конца или не правильно понимать ФП, поэтому учиться ФП по PHP коду плохая идея. У ФП есть математическая база - Лямбда-исчисление, ее нужно понять прежде чем подходить к ФП. Могу посоветовать темы для изучения, книги, курсы.
Для начала можно посмотреть это https://www.youtube.com/watch?v=7BPQ-gpXKt4
Ты скозал?
Вместо иф-элс используй switch
Это что, за хуйня? Залез в пхп тред, на пхп не пишет, несёт ебень какую-то и впаривает ФП. Коммивояжёр 2.0
Иди-ка ты нахуй с треда, теоретик.
Удвою. Пока что стабильно служит, блокировок не наблюдаю. Да и вообще хорошо с ним работается.
Можно поискать тут: https://vps.today/ или https://poiskvps.ru/
Учти, что все, что принимает российские платежные системы вроде webmoney или yandex - это скорее всего российские компании, даже если там стоит другая страна.
Также учти, что реальные характеристики можно выявить только тестами.
Не бери OpenVZ: там часто нельзя загружать модули ядра, менять iptables итд в силу архитектуры. Также, там память считается таким образом, что ее расходуется в 1,5 - 2 раза больше. 1 Гб на OpenVZ может примерно соответствовать 500-700 Мб на KVM.
Хетцнер русских не любит и сразу требует документы.
Многие хостинги не примут виртуальные карты из России. Например, DO не принимает виртуальные карты киви. Другие хостинги не принимают карты сами, а делают это через пейпал, где от русских требуют заполнить подробную анкету. По моему опыту, удобнее всего платить биткойнами, без лишних заморочек.
>Хетцнер русских не любит и сразу требует документы.
Разве так плохо с документами? Я просто хз, не был владельцем тут, но понравились цены сильно.
Обидно что никто не заинтересовался задачкой, по сути расширенный вариант задачи с процентами. Одни фрилансеры сидят теперь судя по треду, которые не могут id из дата-аттрибута в мускуль-запрос скормить.
А ты сам чего?
ВПС брать - дороха. Ещё не известно выйдет ли чего путного, а деньги уже уплочены будут.
Какая ещё задачка? Там портянка левого текста на 5 килобайт. Кто это будет дочитывать?
С первый строк уже насрать на тебя и твоего дружбана.
У Мускула есть встроенная функция таймштампа, просто укажи её в поле даты по умолчанию. Не надо такие вещи посылать в базу.
digitalocean если зарегаешься по чей-то рефке упадет 10$, на 2 месяца минимального тарифа хватит.
Один хуй форматировать на стороне клиента придется, ибо мне нужна дата в определенном формате.
Чем лучше?
>мне нужна дата в определенном формате
Таймштамп на то и таймштамп, что перегоняется в любой формат.
Твоя функция может принимать его - date ( $format, $timestamp)
Используй документацию, Люк. И не городи огород.
http://php.net/manual/ru/function.date.php
Ччерт, я поражаюсь твоей терпеливости, антончик. Спасибо за помощь.
Я тут кстати еще недавно спрашивал совета насчет вытягивания айдишника из элемента и передачи его в обработчик пхп.
Мне посоветовали создать форму с невидимым элементом, передавать в него значение и отправлять. А я сделал еще короче. Я заменил айдишник на value у элемента с тем же значением, вытягиваю его $_POST и отправляю запрос.
Ты забыл еще сказать, что юзая таймштам, нужно передавать ему функцию UNIX_TIMESTAMP(), чтобы метка времени была удобочитаемая функцией date().
https://repl.it/@JoeGreen/testing
Сама задача:
> Дана строка. Если ее длина больше 10, то оставить в строке только первые 6 символов, иначе дополнить строку символами 'o' до длины 12.
Я пробовал через .htacess выставлять Deny from all
Но тогда сайт перестаёт конектится к базе.
>как в конец строки вставить определённое кол-во символов.
>С помощью substr_replace()
Конкатенация же.
В отдельной директории лежит конфиг.
У меня например есть пара мест где я бы хотел исправить овер 9000 строк говнокода, перевести всё к PHP7.0 но я имею 0 опыта работы в командных репозиториях и вообще не понимаю как это будет работать на практике. Помогите советом.
Обычно в репозитории есть список необходимой работы, в issue. И описание требований для контрибьюторов, стиль кода, и все остальное. Смотришь задачи, клонируешь репо, решаешь, отправляешь пулл реквест. Если твой код устроит, то его внедрят в мастер ветку.
640x360, 2:32
>Укорачивание за счёт удаления перевода строки
>Конкатенация через While
Ну... такое себе решение.
>Есть ссылка на исходник
>залезь под капот
Так и так всю функцию видно. Это не повод засовывать туда while, когда можно обойтись без него.
Я про subst_replace или что он там написал. Залезь в самые недра, так сказать.
А что если репозиторий старый. Я например видел несколько игруль где код не одновлялся аж с 2009 примерно. Там даже ЧПУ не привезли. Можно ли взять этот код и редактировать, но уже как свой проект?
Спасибо за ответ анон.
Тебе кто то мешает форкнуть проект? Я разрешаю.
Какая конечная цель? Докер удобен для запуска чего угодно в изолированном окружении.
Если ты вывалил весь код в публично доступную папку сервера, то это неправильно. Надо создать в проекте папку public, настроить ее как корневую, и в эту папку класть только то, что нужно - js/css/картинки, index.php.
Тогда конфиг будет не доступен из веба.
Закрывать папки и файлы по одному, как ты предлагаешь - это ненадежные костыли.
Немного не то. Я хочу не просто приклеить +n символов, а как-то это в цикле сделать, что ли. Там в задаче написано, мол, если длина меньше 10, то в конец добавить символ "о", чтобы длина стала 12.
>>24143
Спасибо. Вчера тоже пытался через while сделать, но не приклеивал, а в теле substr_replade() делал.
Алсо, почему вот такой код работать не будет?
while($count < 12)
{
$result = substr_replace($text, "o", $count);
echo $result;
}
То есть, как я это вижу:
Пока длина $text < 12 символов, делаем substr_replace (добавляем в конец строки) символ "о". Где я ошибаюсь?
Ошибаешься например в том, что $count не пересчитываешь. Да и вообще попытка такого решения как-то наизнанку простую вещь делает.
Плохой код. Ты считаешь длину получающейся строки каждую итерацию вместо того, чтобы один раз высчитать нужное количество новых символов.
За str_repeat() спасибо. Не знал.
Почему ты к str_replace так привязался? Это само по себе не нужно тут. Да и моя придирка была совершенно в другом. Выше лежит мой пример, где показано как высчитать сколько тебе символов нужно. Можно это же сделать тупо циклом, а не str_repeat, но при этом ты считать каждый раз длину строки не будешь.
А была бы она по условию задачи до 1кк символов дополнить например - тогда бы уже точно было некрасиво глаза закрыть на лишние действия.
https://3v4l.org/sd4Hd
Вот держи, тут изменил немного, без реплейса канеш, ибо это совсем глупость, но с циклом вместо готовой функции и без какого-либо пересчета длины строки на каждой итерации.
И еще вот наглядную демонстрацию почему это плохо завез.
https://3v4l.org/Qr6sY - выполняется хотя бы.
https://3v4l.org/59mRU - ну фактически тоже выполняется, но уже не успевает за лимиты этого сайта выйти.
Из-за одной такой мелочи в простейшем месте можно получить натуральный удар по яйцам. И ведь даже указал на это сразу, а все равно пришлось разжевывать.
>А была бы она по условию задачи до 1кк символов дополнить например - тогда бы уже точно было некрасиво глаза закрыть на лишние действия.
Я, конечно, понимаю, что тут не /web, и на практику тут забивают, но вы все-таки думайте хоть немного при разработке не абстрактно. Если не требуется проверять строку в 1000000 символов, то и нечего мозги ебать, тем более, что цикл, что функции твои встроенные практически с одной скоростью выполнят процедуру.
В общем, хочу я сказать, что задачу решить можно разными способами, но для каждой задачи нужно подбирать оптимальный способ.
Человек, который закрывает глаза на такие неприятные мелочи может наделать их огромное количество, что уже вполне будет аналогично выполнению вот этой залупы на 1кк строк.
Делов то просто сразу написать чуть по другому, понимая что делаешь, даже не затратив дополнительного времени и усилий на это. Не какая-то хардкорная оптимизация или преждевременная, а просто здравый смысл, привычка не писать глупость по принципу "да все ок, не ебанет" в мелочах. Да и попросту привычка не писать говнокод необоснованный. Даже анализатор шторма такие моменты подсвечивает, а он вообще разумом не обладает. И на ревью за это не погладят, а проведут разъяснительную беседу, только уже поспорить не слишком получится.
Ладно, вижу что не понят и оставлю вас при своем.
Проверить, что $i делится на 10 без остатка.
Например
https://3v4l.org/ooCHC
Или завести переменную счетчик и сбрасывать ее когда она становится 10.
Алсо, накидайте каких-нибудь интересных, не сложных заданий. А то в интернетах какое-то всё не то.
range есть к примеру
Это ведь стандартный хостинг с доступом только к публичной папке.
>в задаче написано, мол, если длина меньше 10, то в конец добавить символ "о", чтобы длина стала 12.
Вообще тебя не понял. Ну удали лишние символы. Всё равно решение подходит для задачи.
Вот из-за таких разрабов хром сжирает к хренам по 2-3 гига оперативы загружая какой-нибудь фэйсбук. И заставляя Крузис тихонько курить в сторонке. Ну подумаешь цикл лишний раз прикрутил туда, где он просто нафиг ненужен. "Чё мозги ебать". Правильно. Говнокодьте и не думайте головой. Зачем это в 2019?
>UNREGISTERED
Ну не хочу я платить за то, чем можно пользоваться бесплатно. Тебе-то какое дело?
>Windows XP
Что плохого в хрюше?
>это нелепое замазывание струйкой
Это распылитель, даун тупой.
Двачую, XP - лучшая ось эвар.
Лол, нет конечно. Все, что у опа представлено для обучения - должно с легкостью щелкаться нормальным джуном, не говоря о сеньорах.
Ну пездос вы тут гении тогда, если и тут нужно разбираться в таких сложных вещах, а кто-то еще макаками кличет
>стать пхп-сеньором 300к
Ты хотя бы джуниором стать. Неразумно делить шкуру еще не убитого медведя. Сколько вас таких.
Тогда скажу, что некоторые не могут написать даже fizz buzz, но успешно работают программистами. Есть много статей на эту тему. Если задача не решается долго, то не стоит зацикливаться, а идти дальше. В дальнейшем решение может открыться внезапно. Изучаешь новые темы, и вдруг понимаешь, что это то, что нужно для решения. Например стоит изучить деревья, рекурсию, динамическое программирование. Если я правильно понял задачу, то это те темы, которые нужно знать для ее решения. Как звучит задача формально?
>некоторые не могут написать даже fizz buzz, но успешно работают программистами
Это настолько печально, что даже верить в это не хочется.
Да читал давным давно еще, но пока не встречал ниодного даже самого глупого стажера, который бы физзбазз не осилил.
1. Как из одной функции менять переменные другой? Они же закрытого типа.
2. Почему меня echo $yodaText не работает?
Для чего? Почитай про область видимости, лексическую область видимости, и про изменение состояния.
return $result; вместо echo $result;
FizzBuzz:
for ($i = 1; $i <= 100; $i++) {
if ($i % 3 === 0) {
echo 'Fizz';
}
if ($i % 5 === 0) {
echo 'Buzz';
} else {
echo $i;
}
echo "/n";
}
Насколько я конечный?
Все ок. Жаль только этот метод отсеивает только тех, кто с одним только подвешенным языком на работу приходит устраиваться.
Без цикла сможешь? Хорошая практика создавать функцию и в ней прятать вычисление. Еще у тебя одно условие не соблюдено, когда делится и на 3 и на 5 должно выводить FizzBuzz.
Из какого фильма пикча?
>Еще у тебя одно условие не соблюдено, когда делится и на 3 и на 5 должно выводить FizzBuzz.
Еще один некомпетентный петух, и все главное так уверенно отвечают и дают советы, ахаха.
Микроитог: даже ИТТ трое из четырех не смогли в физзбазз. И ладно один из трех честный ньюфаг, а двое других пытались косить под гуру и давать советы.
Такие пироги.
Да, должно корректно выводить.
>У тебя на числах кратных 3 (но не кратных 5) помимо Fizz еще и само число будет выведено
Бля, вообще ты прав. На самом деле я минут 10 думал, как написать этот FizzBuzz, лол, наиболее лаконично.
Вообще 100%-й вариант:
for ($i = 1; $i <= 100; $i++) {
if ($i % 3 !== 0 && $i % 5 !== 0) {
echo $i;
}
if ($i % 3 === 0) {
echo 'Fizz';
}
if ($i % 5 === 0) {
echo 'Buzz';
}
echo "\n";
}
Но это как-то избыточно выглядит.
2 раза проверять условия, говно какое-то.
Основной трабл с тем, чтобы без лишних if-ов и дополнительных переменных корректно вывести в нужных местах fizz и buzz и знак переноса строки.
Ну по выводу выглядит правильно. Однако меня ты удивил таким использованием is_int, даже вдуплить не могу схуяли это работает вообще.
if($i%3 == 0 $$ $i%5==0)
{
echo "fizzbuzz";
}
if ($i % 3 === 0)
{
echo 'Fizz';
}
if ($i % 5 === 0)
{
echo 'Buzz';
}
echo "$i\n";
}
Пофиксил тебя.
А хотя пригледялся - понял. Не обратил внимание, что ты реально делишь. Хитрый ты черт.
Ну если без остатка разделилось, получится целое число, пых сконвертит его в тип int.
Да просто не подумал, что там без % обошлось, невнимательность.
I know that feel. Можно строку использовать.
for ($i = 1; $i <= 100; $i++) {
$s = '';
if ($i % 3 === 0) {
$s .= 'Fizz';
}
if ($i % 5 === 0) {
$s .= 'Buzz';
}
if (!$s) {
$s .= $i;
}
echo $s."\n";
}
Нет больших условий, но по лаконичности все равно такое.
Все практически готово, теперь Вам следует совершить оформление сайтнейм в поисковиках сети Интернет. Оплатить заявку Вы должны до 21.01.2019.", что это за ебала, развод?
Спасибо.
https://ideone.com/2yiyEu
Надо регулярку ещё приделать. Чтобы будущий работодатель все скиллы сразу видел.
Можно ещё Симфони поставить и через роутер правил наделать.
Все значения брать из хранилища через орм, с валидациями на unsigned int. Весь вывод кинуть в очередь на ребит например на второй скрипт, чтобы на первом только процессинг оставался.
Ага, двухуревновое.
>Весь вывод кинуть в очередь на ребит например на второй скрипт, чтобы на первом только процессинг оставался.
Можно еще сразу горизонтальное масштабирование наладить.
Вполне здравая мысль так то. Не говори мы о физбазе правда.
Придется прямо на собесе ее обучать, неловко выйдет. Да и все равно у нейронок 100% точности не бывает.
Твоя задача написать нейронку на листочке, как ее будут запускать — не твоя забота
Собственно, сам вопрос - что делать теперь? Что учить/читать/смотреть?
>Решить их = знаний не хватает.
Значит неуверенно себя чувствуешь - незватает знаний и что-то не усвоил.
Гайд ОПа отлично идёт если его использовать как дополнение. Укради где-нибудь нормальный курс лекций и пройди его, парралельно читая ОПа.
Выдумай себе проект, может даже были мысли что-то сделать - и въебывай.
>Что посоветуешь в роли нормального курса лекций?
Я "Специалист" проходил. Правда не до конца - на третьем курсе сам полез уже копаться на хабре и гите, но это я уже умел немного в код ещё до этого.
Один курс - часов 12-13 по времени.
>банкомат
То чувство, когда не зря прочитал всю книжку препода про дискретную комбинаторную оптимизацию.
Тут весь прикол как раз в том, что "в лоб" она нихуя не решается без продвинутой сложнее школьного курса математики.
Что-то много всего по данному названию вылазит. Не вот этот ли? smart-torrent.org/viewtopic.php?t=117118
Вроде то.
>некоторые не могут написать даже fizz buzz, но успешно работают программистами
Как-то встречал таких когда вкатывался. Одно из их любимых выражений - "Нах ты вручную всё пишешь? Иди ларавель возьми, а то заебёшься."
Вот такие мартышки на низкоуровневых задачках и сыпятся - выучили только работу с фреймворком, не понимая принципов.
Фактически это уровень детишек с вордпресса, которые только темы накатывать могут из админки, суть та же. Зато все синьоры-помидоры в свои 23 года.
Интуитивно догадался, что не имеет смысла перебирать всевозможные варианты.
Вы оба говноеды, а использовать какой-нибудь популярный фреймворк при разработке 90% приложений нужно, потому что:
1) Он почти наверняка будет спроектирован и документирован лучше, чем твоя самописная архитектура.
2) Проект будет гораздо более понятен новым сторонним разработчикам.
3) Нехуй писать велосипеды в тех 90% проектов, где можно спокойно использовать уже написанные.
А вот и маня-синьор с фреймворком наперевес.
Как и следовало ожидать может только в крайности и не понимает, что знание самого языка и понимание алгоримов со структурами данных - почётная обязанность каждого программиста.
Знание фреймворков тут не столь важно - в процессе научится т.к. там никакой фантастики.
>Проект будет гораздо более понятен новым сторонним разработчикам
Пиши как положено и всё понятно будет. А от говнокода даже ларавель не спасёт.
>Нехуй писать велосипеды в тех 90% проектов
А это уже не тебе решать где и что использовать, а разработчику. Нехуй советы давать.
Что непонятного?
Пых говорит тебе, что не знает о существовании этой функции.
Посмотри в phpinfo или php -i включено ли расширение.
Возможно также ты вызываешь ее в своем неймспейсе, обращайся через обратный слеш.
Ну и почему ты не используешь PDO?
>Посмотри в phpinfo или php -i включено ли расширение.
Возможно также ты вызываешь ее в своем неймспейсе, обращайся через обратный слеш.
все это смотрел
>Ну и почему ты не используешь PDO?
это учебный проект
Ой, нафлудили, пока меня не было...
>>25282
Возможно, не установлено расширение mysqli. Сделай phpinfo() и посмотри, есть ли оно там.
>>25301
Есть php -m, но я бы не советовал проверять через CLI, так как в некоторых дистрибутивах конфиги CLI и для веба разные.
>>25135
Там есть простая версия, с определенными суммами купюр, которая успешно решается жадным алгоритмом. Но если тебе хочется посложнее, то можно и заморочиться с полноценной версией, которая напоминает задачу о размене.
>>25115
Один из вариантов - вкинуть написанный код в тред и задать вопрос. Вполне возможно, что кто-то знает ответ и решение проще, чем тебе кажется.
> Как из одной функции менять переменные другой? Они же закрытого типа.
Они специально закрыты, для изоляции внутреннего состояния функции (значений ее локальных переменных) от остального кода. Это сильно упрощает разбор кода - тебе не надо беспокоиться, что код снаружи может как-то повлиять на работу функции. И можно читать лишь код этой функции и не смотреть на остальной код.
Также, тебе не надо бояться, что созданная внутри функции переменная затрет переменную с таким же именем в другом месте кода.
Ты передаешь данные, нужные функции, как аргументы при вызове, и она возвращает результат с помощью return. Вот пример, функция принимает на вход строку, удаляет из нее все пробелы и возвращает результат:
function deleteSpaces($string)
{
$string = str_replace(' ', '', $string);
return $string;
}
А вот, как ее можно использовать:
$input = 'Hello World';
$result = deleteSpaces($input);
echo $result; // HelloWorld
> function makeFirstletterUppercase($text)
> {
> strtolower($result);
> ucfirst($result);
> }
Тут куча ошибок:
- strtolower и ucfirst не работают с кирилиецей в utf-8, используй mb-функции
- результат вызова функций никуда не сохраняется
- в функции нет return и она ничего не вернет
Также, обрати внимание, что mb_split использует диалект регулярных выражений Extended POSIX Regular Expression, в отличие от preg_split, которая использует диалект PCRE.
Также, желательно перевести слова в нижний регистр и хорошо бы расставить точки. Это делается так:
- разбиваем текст на массив предложений
- для каждого предложения, переставляем слова
- склеиваем массив предложений обратно через точку
> Дано 2 функции, но зачем там вторая - ума не приложу.
Можно разбить код на отдельные функции, а не писать длинной портянкой, чтобы он был проще, и чтобы некоторые функции потом можно было бы использовать и в других программах. Но это не обязательно.
> Как из одной функции менять переменные другой? Они же закрытого типа.
Они специально закрыты, для изоляции внутреннего состояния функции (значений ее локальных переменных) от остального кода. Это сильно упрощает разбор кода - тебе не надо беспокоиться, что код снаружи может как-то повлиять на работу функции. И можно читать лишь код этой функции и не смотреть на остальной код.
Также, тебе не надо бояться, что созданная внутри функции переменная затрет переменную с таким же именем в другом месте кода.
Ты передаешь данные, нужные функции, как аргументы при вызове, и она возвращает результат с помощью return. Вот пример, функция принимает на вход строку, удаляет из нее все пробелы и возвращает результат:
function deleteSpaces($string)
{
$string = str_replace(' ', '', $string);
return $string;
}
А вот, как ее можно использовать:
$input = 'Hello World';
$result = deleteSpaces($input);
echo $result; // HelloWorld
> function makeFirstletterUppercase($text)
> {
> strtolower($result);
> ucfirst($result);
> }
Тут куча ошибок:
- strtolower и ucfirst не работают с кирилиецей в utf-8, используй mb-функции
- результат вызова функций никуда не сохраняется
- в функции нет return и она ничего не вернет
Также, обрати внимание, что mb_split использует диалект регулярных выражений Extended POSIX Regular Expression, в отличие от preg_split, которая использует диалект PCRE.
Также, желательно перевести слова в нижний регистр и хорошо бы расставить точки. Это делается так:
- разбиваем текст на массив предложений
- для каждого предложения, переставляем слова
- склеиваем массив предложений обратно через точку
> Дано 2 функции, но зачем там вторая - ума не приложу.
Можно разбить код на отдельные функции, а не писать длинной портянкой, чтобы он был проще, и чтобы некоторые функции потом можно было бы использовать и в других программах. Но это не обязательно.
Лучше всего задать вопрос в треде в таком случае. Эта задача в простом случае решается "жадным алгоритмом", который выглядит так. Допустим, дана сумма 6600 руб:
- берем самую старшую купюру (5000) и берем ее по максимуму, исходя из суммы выплаты и запаса купюр. Например, в данном случае берем только одну такую купюру, остается выплатить 1600
- берем вторую по старшинству купюру (1000) и берем ее по максимуму, остается к выплате 600
- и так до самой младшей купюры. Если в итоге осталось выплатить 0 - значит, выплата возможна.
В более сложном случае - например, если значения купюр равны 1000, 500, 200, 100 - жадный алгоритм не работает и придется делать полный перебор всех комбинаций, который можно попробовать оптимизировать.
То есть, алгоритм в общем случае такой:
- перебираем все возможные комбинации купюр
- если текущая комбинация в сумме составляет требуемую сумму, то останавливаемся на ней
Он конечно потребует перебрать очень много вариантов, потому можно его оптимизировать - откидывать варианты, когда сумма выходит слишком большой (для выдачи 11000 нет смысла брать более двух 5000-х купюр) или слишком маленькой.
Также, можно почитать похожую задачу о размене, и может быть, использовать алгоритм из нее:
- http://aliev.me/runestone/Recursion/DynamicProgramming.html
- https://habr.com/post/109384/
- https://neerc.ifmo.ru/wiki/index.php?title=Задача_о_рюкзаке#.D0.97.D0.B0.D0.B4.D0.B0.D1.87.D0.B0_.D0.BE_.D1.80.D0.B0.D0.B7.D0.BC.D0.B5.D0.BD.D0.B5
Уверен, что любопытство, а также стремление разобраться в любой задаче до конца и не сдаваться быстро cмогут помочь твоей будущей карьере.
>>24707
Справедливости ради, там не цикл, а желание получить большее быстродействие за счет увеличения расхода памяти, которое требуется для современных навороченных HTML5 страниц.
Лучше всего задать вопрос в треде в таком случае. Эта задача в простом случае решается "жадным алгоритмом", который выглядит так. Допустим, дана сумма 6600 руб:
- берем самую старшую купюру (5000) и берем ее по максимуму, исходя из суммы выплаты и запаса купюр. Например, в данном случае берем только одну такую купюру, остается выплатить 1600
- берем вторую по старшинству купюру (1000) и берем ее по максимуму, остается к выплате 600
- и так до самой младшей купюры. Если в итоге осталось выплатить 0 - значит, выплата возможна.
В более сложном случае - например, если значения купюр равны 1000, 500, 200, 100 - жадный алгоритм не работает и придется делать полный перебор всех комбинаций, который можно попробовать оптимизировать.
То есть, алгоритм в общем случае такой:
- перебираем все возможные комбинации купюр
- если текущая комбинация в сумме составляет требуемую сумму, то останавливаемся на ней
Он конечно потребует перебрать очень много вариантов, потому можно его оптимизировать - откидывать варианты, когда сумма выходит слишком большой (для выдачи 11000 нет смысла брать более двух 5000-х купюр) или слишком маленькой.
Также, можно почитать похожую задачу о размене, и может быть, использовать алгоритм из нее:
- http://aliev.me/runestone/Recursion/DynamicProgramming.html
- https://habr.com/post/109384/
- https://neerc.ifmo.ru/wiki/index.php?title=Задача_о_рюкзаке#.D0.97.D0.B0.D0.B4.D0.B0.D1.87.D0.B0_.D0.BE_.D1.80.D0.B0.D0.B7.D0.BC.D0.B5.D0.BD.D0.B5
Уверен, что любопытство, а также стремление разобраться в любой задаче до конца и не сдаваться быстро cмогут помочь твоей будущей карьере.
>>24707
Справедливости ради, там не цикл, а желание получить большее быстродействие за счет увеличения расхода памяти, которое требуется для современных навороченных HTML5 страниц.
>>25131
> Нужно создать таблицу на основе дампа в students.sql.
А где дамп? И конечно, хотелось бы чуть более подробный readme, например, такой: https://github.com/foobar1643/filehosting/blob/master/README.md (хотя, я бы его подсократил).
Если ты будешь отправлять, например, тестовое задание, то качество документации и комментариев тоже может повлиять на оценку.
Желательно сделать публичную папку и вынести все остальное за ее пределы, как описано тут: https://github.com/codedokode/pasta/blob/master/student-list.md#выносим-код-за-корень-сервера
> $di->bind('StudentTableGateway', new StudentTableGateway);
Не стоит писать имена классов руками, стоит использовать встроенную константу class:
bind(StudentTableGateway::class, ...)
Бонусом получаешь автодополнение в IDE и защиту от опечаток.
Описания коммитов можно делать лучше: https://github.com/asdasdasdasddasasdasdas/StudentList/commits/ads
В коде желательно перед каждым классом, кроме очевидных, описать, зачем он нужен и за что отвечает.
https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/index.php
use должно идти в самом начале файла по PSR. Код надо отформатировать.
В автозагрузчике ты не указал корневую папку, и делается поиск от текущей директории, которая может меняться, например функцией chdir(), погугли "текущая директория процесса". Лучше явно указать корневую папку с помощью __DIR__.
> $router = new Router($di);
Роутер тоже можно положить в контейнер.
> public function bind($key, $value)
Не помешали бы тайп-хинты. Вместо key, value лучше писать name, service или object.
Раз ты делаешь свой контейнер, советую глянуть рекомендацию PSR-11, которая предлагает единый интерфейс для контейнеров: https://www.php-fig.org/psr/psr-11/
https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/core/Router.php
Отформатируй код (смотри второй пост треда), тяжело это читать.
> if($params[1]){
Тут может быть ошибка, если второго элемента в массиве нету. Нужен count/array_key_exists.
Если URL неправильный, надо отдавать страницу ошибки с HTTP-кодом 404, а не выдавать страницу. Страница в идеале должна быть доступна только по одному URL, а не по любому.
> ControllerFactory::CreateController($controller,$this->di)-
А если передано неправльное имя контроллера? Должно быть 404.
> switch($controller)
> {
> case "main":
Не лучше ли определение имени контроллера сделать в роутере, и передавать имя класса? А то, получается, у нас фабрика занимается разбором URL страницы. Нарушается принцип разделения ответственности между классами.
> public static function CreateController($controller,$di)
Нужны тайп-хинты, в идеале и на возвращаемое значение.
> $search=htmlspecialchars($_GET['search']);
зачем тут htmlspecialchars? Она же используется при выводе текста в HTML шаблоне.
> $keyword = "%$search%";
Эту подстановку лучше делать в модели. А то ты внутреннее знание выносишь из модели наружу. Код снаружи не должен знать тонкостей SQL и как устроена модель, он должен лишь передавать строку для поиска в модель и получать результат. И, кстати, пробелы тоже хорошо бы заменять на %.
> $this->paginator->countPage($this->countStudents);
А зачем paginator делать полем? Не проще было сделать просто переменную?
> $_GET['page'] = $_GET['page']==null?1:$_GET['page'];
Не надо ничего записывать в $_GET. Это входные данные, а не временная переменная.
> $offset = $limit*($_GET['page']-1);
Здесь даже нет проверки, что в GET положительное число.
> $_GET['search']!==null
В $_GET не может быть null, там может быть лишь строка или массив. Тебе надо включить вывод ошибок, у тебя он отключен и ты их не видишь. Поставь error_reporting = -1, display_errors = 1 в php.ini.
> public function Cookie($hash)
Имя функции обычно начинают с глагола и с маленнькой буквы, сделайЧтоТо(). Плюс, оно должно отражать, что делает функция, а у тебя это не так. Тут должно быть что-то вроде "залогинить" или "авторизовать как".
> $this->auth->checkHash();
Результат никак не используется.
> private $perpage = 5;
> private $CurrentPage;
Поля начинаются с маленьких букв. Почитай PSR-1 и 2, пожалуйста.
>
$this->render('app/view/profile/profile.php',['student'=>$this->model->getStudentByHash($_COOKIE['hash']),'errors'=>$errors]);
Переменная errors не определена.
Также, я советую сделать обработку формы как описано в уроке, и не возиться с сохранением данных в сессию: https://github.com/codedokode/pasta/blob/master/forms.md
Например, использование сессии имеет такой недостаток: пользователь отправляет форму, видит ошибки. Закрывает страницу, открывает форму и снова видит старые ошибки.
Также, при ошибке проверки формы надо отображать форму с введенными значениями полей - это сделано?
Обновление данных лучше делать так:
- загрузить из БД в объект
- обновить
- сохранить
Иначе можно легко потерять данные, если например в будущем мы добавим новые поля в объект, но не добавим в форму.
> strval(trim
Лучше trim(strval()) иначе будет ошибка при передаче массива в $_POST['name'].
Регистрацию и обновление данных можно бы совместить, там много общего.
https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/controller/controller.php
Имена классов пишут с большой буквы.
> public function ValidateAll($student)
> $this->errors['name_error']=
Не лучше ли использовать просто переменную вместо поля?
> elseif($this->db->CheckEmail($email)){
> return "Такой E-mail уже сущестует";
При редактировании проблемы не будет?
> Вы не ввели свой пол
"Вы не указали свой пол". Или, что лучше, "Пожалуйста, укажите свой пол.".
> $this->male=1;
> $this->female=0;
Не очень понятно, почему тут 2 поля, а не одно поле с вариантами GENDER_MALE/GENDER_FEMALE.
> public function generateHash(){
В таких функциях нужна документация. Что за хеш? Зачем он нужен? Когда использовать эту функцию и для чего? Качество документирования кода пока что очень плохое. Представь, как неудобно будет другому человеку разбирать твой код.
> function __construct(){
> $config = require 'app/config/db.php';
> $this->db = new PDO('mysql:host='.$config['host'].';dbname='.$config['name'].';',$config['user'],$config['password']);
Параметры соединения лучше бы передавать в конструктор. А еще лучше - передавать объект PDO как зависимость. Иначе, у тебя каждый Gateway будет создавать свое отдельное соединение к БД.
Также, ты не включил для PDO режим выброса исключений. Также, стоит задать кодировку соединения и включить строгий режим MySQL.
Код надо форматировать. Второй раз я читать неформатированный код точно не буду.
> public function CheckEmail(string $email){
Эта функция, наверно, должна возвращать true/false?
> <input type="text" class="search" name="search" placeholder="Поиск по имени">
Сюда стоит подставлять введенное ключевое слово.
> <td class="px-5"> <?=$students[$key]['name']; ?></td>
А не лучше ли сюда передавать объекты, а не массив?
> href=<?="/?page=".$this->paginator->getPreviousPage();
Это тяжело читать. Надо сделать функцию или метод-помощник для формирования ссылок. Также, выводимые в HTML данные надо экранировать.
Если страниц 1 или менее, пагинацию можно не выводить.
> value="<?=$student['name'];?>">
Почитай урок про XSS: https://github.com/codedokode/pasta/blob/master/security/xss.md
> ><?= $_SESSION['errors']['name_error'];
View должен использовать переданные ему данные, а не лезть сам в глобальные переменные.
> <input id="inputLGEx"
id должны быть уникальны.
Для формы стоит добавить HTML5 валидацию.
https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/view/registration/registration.php
Здесь скопирована форма из профиля. Надо избавиться от дублирования кода.
Я наверно немного сумбурно все написал, задавай уточняющие вопросы, если что.
>>25131
> Нужно создать таблицу на основе дампа в students.sql.
А где дамп? И конечно, хотелось бы чуть более подробный readme, например, такой: https://github.com/foobar1643/filehosting/blob/master/README.md (хотя, я бы его подсократил).
Если ты будешь отправлять, например, тестовое задание, то качество документации и комментариев тоже может повлиять на оценку.
Желательно сделать публичную папку и вынести все остальное за ее пределы, как описано тут: https://github.com/codedokode/pasta/blob/master/student-list.md#выносим-код-за-корень-сервера
> $di->bind('StudentTableGateway', new StudentTableGateway);
Не стоит писать имена классов руками, стоит использовать встроенную константу class:
bind(StudentTableGateway::class, ...)
Бонусом получаешь автодополнение в IDE и защиту от опечаток.
Описания коммитов можно делать лучше: https://github.com/asdasdasdasddasasdasdas/StudentList/commits/ads
В коде желательно перед каждым классом, кроме очевидных, описать, зачем он нужен и за что отвечает.
https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/index.php
use должно идти в самом начале файла по PSR. Код надо отформатировать.
В автозагрузчике ты не указал корневую папку, и делается поиск от текущей директории, которая может меняться, например функцией chdir(), погугли "текущая директория процесса". Лучше явно указать корневую папку с помощью __DIR__.
> $router = new Router($di);
Роутер тоже можно положить в контейнер.
> public function bind($key, $value)
Не помешали бы тайп-хинты. Вместо key, value лучше писать name, service или object.
Раз ты делаешь свой контейнер, советую глянуть рекомендацию PSR-11, которая предлагает единый интерфейс для контейнеров: https://www.php-fig.org/psr/psr-11/
https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/core/Router.php
Отформатируй код (смотри второй пост треда), тяжело это читать.
> if($params[1]){
Тут может быть ошибка, если второго элемента в массиве нету. Нужен count/array_key_exists.
Если URL неправильный, надо отдавать страницу ошибки с HTTP-кодом 404, а не выдавать страницу. Страница в идеале должна быть доступна только по одному URL, а не по любому.
> ControllerFactory::CreateController($controller,$this->di)-
А если передано неправльное имя контроллера? Должно быть 404.
> switch($controller)
> {
> case "main":
Не лучше ли определение имени контроллера сделать в роутере, и передавать имя класса? А то, получается, у нас фабрика занимается разбором URL страницы. Нарушается принцип разделения ответственности между классами.
> public static function CreateController($controller,$di)
Нужны тайп-хинты, в идеале и на возвращаемое значение.
> $search=htmlspecialchars($_GET['search']);
зачем тут htmlspecialchars? Она же используется при выводе текста в HTML шаблоне.
> $keyword = "%$search%";
Эту подстановку лучше делать в модели. А то ты внутреннее знание выносишь из модели наружу. Код снаружи не должен знать тонкостей SQL и как устроена модель, он должен лишь передавать строку для поиска в модель и получать результат. И, кстати, пробелы тоже хорошо бы заменять на %.
> $this->paginator->countPage($this->countStudents);
А зачем paginator делать полем? Не проще было сделать просто переменную?
> $_GET['page'] = $_GET['page']==null?1:$_GET['page'];
Не надо ничего записывать в $_GET. Это входные данные, а не временная переменная.
> $offset = $limit*($_GET['page']-1);
Здесь даже нет проверки, что в GET положительное число.
> $_GET['search']!==null
В $_GET не может быть null, там может быть лишь строка или массив. Тебе надо включить вывод ошибок, у тебя он отключен и ты их не видишь. Поставь error_reporting = -1, display_errors = 1 в php.ini.
> public function Cookie($hash)
Имя функции обычно начинают с глагола и с маленнькой буквы, сделайЧтоТо(). Плюс, оно должно отражать, что делает функция, а у тебя это не так. Тут должно быть что-то вроде "залогинить" или "авторизовать как".
> $this->auth->checkHash();
Результат никак не используется.
> private $perpage = 5;
> private $CurrentPage;
Поля начинаются с маленьких букв. Почитай PSR-1 и 2, пожалуйста.
>
$this->render('app/view/profile/profile.php',['student'=>$this->model->getStudentByHash($_COOKIE['hash']),'errors'=>$errors]);
Переменная errors не определена.
Также, я советую сделать обработку формы как описано в уроке, и не возиться с сохранением данных в сессию: https://github.com/codedokode/pasta/blob/master/forms.md
Например, использование сессии имеет такой недостаток: пользователь отправляет форму, видит ошибки. Закрывает страницу, открывает форму и снова видит старые ошибки.
Также, при ошибке проверки формы надо отображать форму с введенными значениями полей - это сделано?
Обновление данных лучше делать так:
- загрузить из БД в объект
- обновить
- сохранить
Иначе можно легко потерять данные, если например в будущем мы добавим новые поля в объект, но не добавим в форму.
> strval(trim
Лучше trim(strval()) иначе будет ошибка при передаче массива в $_POST['name'].
Регистрацию и обновление данных можно бы совместить, там много общего.
https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/controller/controller.php
Имена классов пишут с большой буквы.
> public function ValidateAll($student)
> $this->errors['name_error']=
Не лучше ли использовать просто переменную вместо поля?
> elseif($this->db->CheckEmail($email)){
> return "Такой E-mail уже сущестует";
При редактировании проблемы не будет?
> Вы не ввели свой пол
"Вы не указали свой пол". Или, что лучше, "Пожалуйста, укажите свой пол.".
> $this->male=1;
> $this->female=0;
Не очень понятно, почему тут 2 поля, а не одно поле с вариантами GENDER_MALE/GENDER_FEMALE.
> public function generateHash(){
В таких функциях нужна документация. Что за хеш? Зачем он нужен? Когда использовать эту функцию и для чего? Качество документирования кода пока что очень плохое. Представь, как неудобно будет другому человеку разбирать твой код.
> function __construct(){
> $config = require 'app/config/db.php';
> $this->db = new PDO('mysql:host='.$config['host'].';dbname='.$config['name'].';',$config['user'],$config['password']);
Параметры соединения лучше бы передавать в конструктор. А еще лучше - передавать объект PDO как зависимость. Иначе, у тебя каждый Gateway будет создавать свое отдельное соединение к БД.
Также, ты не включил для PDO режим выброса исключений. Также, стоит задать кодировку соединения и включить строгий режим MySQL.
Код надо форматировать. Второй раз я читать неформатированный код точно не буду.
> public function CheckEmail(string $email){
Эта функция, наверно, должна возвращать true/false?
> <input type="text" class="search" name="search" placeholder="Поиск по имени">
Сюда стоит подставлять введенное ключевое слово.
> <td class="px-5"> <?=$students[$key]['name']; ?></td>
А не лучше ли сюда передавать объекты, а не массив?
> href=<?="/?page=".$this->paginator->getPreviousPage();
Это тяжело читать. Надо сделать функцию или метод-помощник для формирования ссылок. Также, выводимые в HTML данные надо экранировать.
Если страниц 1 или менее, пагинацию можно не выводить.
> value="<?=$student['name'];?>">
Почитай урок про XSS: https://github.com/codedokode/pasta/blob/master/security/xss.md
> ><?= $_SESSION['errors']['name_error'];
View должен использовать переданные ему данные, а не лезть сам в глобальные переменные.
> <input id="inputLGEx"
id должны быть уникальны.
Для формы стоит добавить HTML5 валидацию.
https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/view/registration/registration.php
Здесь скопирована форма из профиля. Надо избавиться от дублирования кода.
Я наверно немного сумбурно все написал, задавай уточняющие вопросы, если что.
bump
Хелпаните нюфагу
Поставил MAMP на макось. Хотел включить отображение ошибок на в php. Сделал по гайду. Поставил в файле php.ini error_reporting = E_ALL и display_errors = On. Перезапуская серв и все равно при наличии ошибок пустая страница. И так и сяк делал. Не монимаю, в чем косяк. Мудрый анон, помоги
>Верстальщику - HTML/CSS, JS, jQuery. У нас в треде были люди, которые практически с нуля учились и смогли найти работу.
А в 2019 году есть шанс без реакта стать верстальщиком? Зная только js и jquery без реакта? Хочу задрачивать html, css, а не реакт. Я прошел 2 курса по реакту, примерно представляю как верстать под реакт, но я не готов заниматься программированием на реакте. Хочу верстать. Реально ли стать верстальщиком в 2019? (Мухосрань 300 тыс. людей)
Нашел в чем траблы.
Нужно сделать то же самое, еще раз, как и в Applications/MAMP/conf/php/, но в другом php.ini в Applications/MAMP/bin/php/
Вдруг кто-то такой же додик, как и я
Держу в курсе
Хуле там учить этот ебаный реакт, какой-то жалкий говнофреймворк блять, это тебе не c++ же.
Хуйня на полторы недели учебы.
Не скажи, если опыт прогинга есть - то конечно проще.
А вот если ноль - то прихуеет.
Аноны, я вкатываюсь в пхп. Знаю JS, SQL, питон все средненько естественно. С пхп по верхам разобрался.
У меня такая проблема - я решаю задачки, решаю задачки, решаю...
Но я нихуя не понимаю как написать полноценный сайт, пусть простой по сложности, но полноценный со стороны проектирования. Все что я писал - превращалось в кривую кучу говна, в которой я сам путался.
Что прошу - примеры структуры проектов, учебники по проектированию сайтов а не: "ребята - это функция, давайте познакомим ее с аргументами..." ,гайды на тему построения сайта не курильщика, может даже исходники какие нибудь.
Мне нужна основа что бы на ней закреплять свой говно код.
И еще - в JS подход когда страничка возвращается шаблоном - считается устаревшей хотя на Node я делал небольшой сервер с помощью шаблонов. Там модны SPA, изоморфные приложения, свитшоты, смузи и барбершопы, это понятно. Но вообще пхп хорошо дружит с реактом нахуя я его учил? или вью?
Берешь фреймворк любой, ларавель, йии или че там щас модно и ебашишь.
Ну и да, 2к18 на дворе, фронт давно разросся больше жопы твоей мамки и является отдельным полноценным приложением.
В целом, на сервере генеришь жсон любым говном, хоть пхп, хоть жс, хоть c++, далее его жрет фронтендовый барбершоп и показывает пользователю
А имеет смысл использовать
> фреймворк любой, ларавель, йии
если
> на сервере генеришь жсон
Как это выглядит? Вместо хтмла во вьюхи json ебашишь?
борисов объясняет в курсах, у котерова есть в книге примеры по архитектуре приложений
Ну как-то так, да
Чем он тебе не нравится-то? Если он тебе кажется переусложненным или непонятным, то это значит, что надо было сначала изучить тщательно JS, включая особенности новых версий.
Что-то ты слишком разборчивый, хочешь изучать только самое простое. Надо решать задачи клиента, если без реакта, то придумай какой-то другой способ.
> Там модны SPA, изоморфные приложения
Для разных ситуаций подходят разные способы. Ты же почему-то думаешь, что есть лишь "старые" и "новые" способы. Я, например, участвовал в написании SPA, когда не было ни реакта, ни ангулара, ни gulp. И в то же время, серверная генерация страниц никак не потеряла свою актуальность.
По проектированию - не хочешь почитать нашу задачу про студентов с комментариями и сделать её? Там много ценных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
> Но вообще пхп хорошо дружит с реактом нахуя я его учил? или вью?
PHP работает на сервере, а реакт - на клиенте. Они напрямую никак не связаны.
Понял, спасибо.
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i]=curl_init($url);
//тут много curl_setopt
curl_multi_add_handle ($mh,$conn[$i]);
}
do { curl_multi_exec($mh,$active); } while ($active);
for ($i = 0; $i < count($urls); $i++) {
$json = curl_multi_getcontent($conn[$i]);
$json = json_decode($json, 1);
if (isset($json['error_code'])) {
sleep($sl);
//????????
}
curl_multi_remove_handle($mh, $conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
Как в случае ошибки пробовать открыть ссылку снова, после небольшой паузы? curl_multi_getcontent($conn[$i]) возвращает старый результат, похоже.
1
http://jsfiddle.net/h7czk8yt/ - тут, сделал через border-box т.к. уже знал про него
2
http://jsfiddle.net/3h1z7gpb/
3
http://jsfiddle.net/2ojzpuxs/
4
http://jsfiddle.net/pwo5f04r/
5
http://jsfiddle.net/q2L0vr9w/
Я не осилил, но я еще учусь, ща верстку поделал, буду решать и банкомат параллельно. П.с. Что абу сделал с бордой? лагает и тупит все после обновы
Это задачи опа
есть установленная база данных MariaDB, есть установленный phpMyAdmin. Как мне связать базу и админа? В гугле ничего не нашел. Пытаюсь зайти с логином и паролем от базы - не заходит - не верные данные.
Ось debian 9.
Попробуй залогиниться в БД с теми же логином и паролем из консоли на сервере, где стоит MariaDB (если у тебя есть ssh-доступ к серверу или если сервер это твой компьютер):
mysql -uusername -p
Это поможет проверить правильность пароля. Также, в MySQL может стоять ограничение на доступ с внешних IP ир может быть разрешен вход только с того же компьютера.
Увидеть пользователей можно, зайдя под админом и сделав запрос SHOW GRANTS.
Все получилось. Я по недосыпу установил пароль 'password' вместо своего. Спасибо за помощь.
> 1 http://jsfiddle.net/h7czk8yt/ - тут, сделал через border-box т.к. уже знал про него
Ок, все верно.
> max-height: 250px;
> overflow: hidden;
А это делать не требовалось, и это вообще не очень хорошая идея делать текст недоступным. Как его прочесть тогда?
В остальном, хорошо.
Для обозначения угловой скобки лучше использовать < - это читабельнее. А для амперсанда &. В остальном, верно.
Все верно.
Всё правильно.
>>26026
Мы готовим полноценных разработчиков, а не просто писателей скриптов на PHP.
Вообще, код производит хорошее впечатление: комментарии, типизация.
Я не уверен насчет передачи компании в конструктор. Нужно ли ее хранить там постоянно? Не лучше ли передавать компанию в конкретный метод? А то у тебя получается, для каждой компании надо создавать новый объект Кризисных Мер, а так одним объектом можно было бы обработать кучу компаний.
> $department->getHead() !== $employee
Можно было, но необязательно, сделать у департамента метод isHead().
> $engineers[] = [$employee->getRank(), $employee];
Не требуется создавать массив, чтобы сортировать сотр. по ранку:
usort($engineers, function ($a, $b) {
return $a->getRank() <=> $b->getRank();
});
Если у тебя старый PHP < 7 без spaceship operator ( http://php.net/manual/ru/language.operators.comparison.php ), то используется пара тернарных операторов.
Для отбора сотрудников можно было использовать array_slice, но твой вариант тоже годится.
Для поиска сотрудников в департаменте по критерию можно было, но необязательно, сделать метод:
$people = $department->select(function ($e) { return $e->getRank() > 1; });
Заодно получил бы пример использования анонимных функций.
> Возвращает объект-хранилище департаментов
> @return SplObjectStorage
Можно еще сделать @return iterable чтобы не говорить конкретный тип возвращаемого объекта и можно было бы его поменять потом. Также, твой подход имеет небольшой недостаточек, что возвращаенный объект можно изменять (чем с радостью воспользуются криворукие разработчики). В этой программе это не критично и исправлять не надо, но я сталкивался с такими случаями, когда люди брали коллекциюи изменяли ее, нарушая принцип инкапсуляции.
> private function getAverageValue
> return round($value / $amount, 1)
Это не очень праивльно. Вот у нас есть задача: отобразить среднее по компании. Её можно разбить на 2 независимые части:
- получить среднее по компании (зона ответственности компании)
- вывести среднее в нужном формате (зона ответственности кода вывода данных)
Так как компания не знает, зачем у нее просят эти данные и как их будут использовать, она не должна их округлять, а должна предоставлять как есть. Возможно, ты не подумал о разделении ответственности и потому поместил код, меняющий представление данных, в компанию. В твоем подходе, когда тебе понадобится более точное значение, придется переделывать класс компании, и заодно переделывать вывод данных, чтобы они по-прежнему выводились с одним знаком после запятой.
> 'Удаление руководителя');
Лучше бы было сделать чуть более подробное сообщение, например "для удаления руководителя необходимо сначала назначить другого руководителя".
> Возвращает заработную плату
> public function getSalary(): int
Эта функция не проверяет, является ли человек руководителем и потому возвращает недостоверные данные. Исправить можно так:
1) переименовать функцию, запретить ее использовать и сделать в департаменте правильную функцию для получения зарплаты
2) сделать в работнике флаг, является ли он руководителем, автоматически обновлять его из департамента.
Ты сделал так, что ставка всего берется из объекта Profession. Это не позволяет, например, повысить зарплату только части сотрудников. Вроде как в задаче это и не требуется, но в дальнейшем это, может быть, потребуется переделать.
> @param Company $company
> function printCompany(Company $company)
На мой взгляд, этот комментарий не несет никакой новой информации и его не стоит добавлять. А то при редактировании придется больше кода исправлять.
> function printCompany(Company $company): void {
> // Добавление пробелов слева
> function padLeft($string, $length)
Не определяй именованные функции внутри другой функции, так как это не яваскрипт и второй вызов printCompany() вызовет ошибку. Сделай либо функции на верхнем уровне, либо анонимные.
> for ($i = $length - mb_strlen($string); $i > 0; $i--)
Есть str_repeat
В общем, сделано неплохо. Надеюсь, ты увидел преимущества ООП (если не увидел - попробуй решить задачу без классов). Если хочется еще попрактиковаться в ООП, поищи задачу про ООП-гостиницу или ООП-будильник на phpclub.tech.
Вообще, код производит хорошее впечатление: комментарии, типизация.
Я не уверен насчет передачи компании в конструктор. Нужно ли ее хранить там постоянно? Не лучше ли передавать компанию в конкретный метод? А то у тебя получается, для каждой компании надо создавать новый объект Кризисных Мер, а так одним объектом можно было бы обработать кучу компаний.
> $department->getHead() !== $employee
Можно было, но необязательно, сделать у департамента метод isHead().
> $engineers[] = [$employee->getRank(), $employee];
Не требуется создавать массив, чтобы сортировать сотр. по ранку:
usort($engineers, function ($a, $b) {
return $a->getRank() <=> $b->getRank();
});
Если у тебя старый PHP < 7 без spaceship operator ( http://php.net/manual/ru/language.operators.comparison.php ), то используется пара тернарных операторов.
Для отбора сотрудников можно было использовать array_slice, но твой вариант тоже годится.
Для поиска сотрудников в департаменте по критерию можно было, но необязательно, сделать метод:
$people = $department->select(function ($e) { return $e->getRank() > 1; });
Заодно получил бы пример использования анонимных функций.
> Возвращает объект-хранилище департаментов
> @return SplObjectStorage
Можно еще сделать @return iterable чтобы не говорить конкретный тип возвращаемого объекта и можно было бы его поменять потом. Также, твой подход имеет небольшой недостаточек, что возвращаенный объект можно изменять (чем с радостью воспользуются криворукие разработчики). В этой программе это не критично и исправлять не надо, но я сталкивался с такими случаями, когда люди брали коллекциюи изменяли ее, нарушая принцип инкапсуляции.
> private function getAverageValue
> return round($value / $amount, 1)
Это не очень праивльно. Вот у нас есть задача: отобразить среднее по компании. Её можно разбить на 2 независимые части:
- получить среднее по компании (зона ответственности компании)
- вывести среднее в нужном формате (зона ответственности кода вывода данных)
Так как компания не знает, зачем у нее просят эти данные и как их будут использовать, она не должна их округлять, а должна предоставлять как есть. Возможно, ты не подумал о разделении ответственности и потому поместил код, меняющий представление данных, в компанию. В твоем подходе, когда тебе понадобится более точное значение, придется переделывать класс компании, и заодно переделывать вывод данных, чтобы они по-прежнему выводились с одним знаком после запятой.
> 'Удаление руководителя');
Лучше бы было сделать чуть более подробное сообщение, например "для удаления руководителя необходимо сначала назначить другого руководителя".
> Возвращает заработную плату
> public function getSalary(): int
Эта функция не проверяет, является ли человек руководителем и потому возвращает недостоверные данные. Исправить можно так:
1) переименовать функцию, запретить ее использовать и сделать в департаменте правильную функцию для получения зарплаты
2) сделать в работнике флаг, является ли он руководителем, автоматически обновлять его из департамента.
Ты сделал так, что ставка всего берется из объекта Profession. Это не позволяет, например, повысить зарплату только части сотрудников. Вроде как в задаче это и не требуется, но в дальнейшем это, может быть, потребуется переделать.
> @param Company $company
> function printCompany(Company $company)
На мой взгляд, этот комментарий не несет никакой новой информации и его не стоит добавлять. А то при редактировании придется больше кода исправлять.
> function printCompany(Company $company): void {
> // Добавление пробелов слева
> function padLeft($string, $length)
Не определяй именованные функции внутри другой функции, так как это не яваскрипт и второй вызов printCompany() вызовет ошибку. Сделай либо функции на верхнем уровне, либо анонимные.
> for ($i = $length - mb_strlen($string); $i > 0; $i--)
Есть str_repeat
В общем, сделано неплохо. Надеюсь, ты увидел преимущества ООП (если не увидел - попробуй решить задачу без классов). Если хочется еще попрактиковаться в ООП, поищи задачу про ООП-гостиницу или ООП-будильник на phpclub.tech.
Я думаю, надо создать новый экземпляр curl. То есть один curl делает только один запрос. Также, работать напрямую с методами curl очень неудобно. Я бы советовал переделатьт это на объекты и промисы, например, так:
$manager = new CurlManager();
$manager->get('http://example.com')->then(function ($result) {
...;
}, function ($error) {
....;
});
$manager->get('http://other.example.com')->then(...);
И так далее.
Также, ты можешь взять готовую библиотеку Guzzle, где это уже сделано.
Паузу надо делать асинхронно (чтобы во время нее скачивание не прерывалось, просто sleep не годится). Опять же, это удобно делать на промисах. Тебе стоит их изучить.
В смысле останусь ли я к тому моменту макакой с веб головного мозга без возможности перекатиться в нормальный язык, или полученные знания в сфере веб дадут хорошую базу для освоения других инструментов под другие задачи?
мне 26, вкатывался в пыху два раза за два же года. Хочется взять себя в руки и зафорсить за короткий промежуток времени уровень ковыряния пет проектов по фану.
DELETE FROM table1 WHERE id=1
DELETE FROM table2 WHERE id=1
в одну строчку?
DELETE table1., table2.
FROM table1
LEFT JOIN table2
ON table1.id = table2.id
WHERE table1.id=1
А так лучше через ключи настроить каскадное удаление.
1000 строк, тысяча Карл! А что они делают? Подозреваю, что реальной логики там на 100 строчек, не больше. Все остальное тупой бойлерплейт aka ООП головного мозга.
>без лишних if-ов
Ифы не нужны https://ideone.com/fwg3K6
А лаконично это вот
for($i = 1; $i <= 100 and print(($i % 15 ? $i % 5 ? $i % 3 ? $i : 'Fizz' : 'Buzz' : 'FizzBuzz') . "\n"); ++$i);
Не понимаю, какое скачивание прерывается при sleep?
Где можно почитать про промисы на русском?
Сейчас нахожусь в процессе изучения PHP. Задача - как можно скорее начать зарабатывать, пусть и небольшие деньги.
Вопрос: для наискорейшего начала работы, мне стоит сконцентрироваться непосредственно на языке, фреймворках и инструментах или мне всё же критически необходимо изучить подобные книги - "Структура и интерпритация компьютерных программ", "Алгоритмы и структуры данных", "Архитектура компьютера"?
>Вопрос: для наискорейшего начала работы, мне стоит сконцентрироваться непосредственно на языке, фреймворках и инструментах или мне всё же критически необходимо изучить подобные книги - "Структура и интерпритация компьютерных программ", "Алгоритмы и структуры данных", "Архитектура компьютера"?
Каждый работодатель выдаёт свои требования. Если я правильно понимаю, что твоя задача как можно скорей найти работу, то советую сначала ознакомиться с их требованиями, чтобы самому определиться на чем тебе стоит сконцентрироваться.
Все языки следуют одним и тем же парадигмам программирования. То есть, если начать с веб разработки, то и в других сферах встретятся те же принципы.
Благодарю за отзыв.
> 1) переименовать функцию, запретить ее использовать и сделать в департаменте правильную функцию для получения зарплаты
Значит можно вычислять заработную плату сотрудников, а также остальные параметры в департаменте?
>сделать в департаменте правильную функцию
Что-то вроде этого?
private function getSalary(Employee $e): int;
private function getCoffeeVolume(Employee $e): int
private function getDocumentsCount(Employee $e): int
Получается, через объект сотрудника мы будем просто ретранслировать значения (ставка, кофе, документы) из объекта профессии или только объект профессии.
Иди на Хекслет hexlet.io, там специализируются на устройстве на работу таких как ты.
Честно говоря, я тут спарсил 2 ляма торрентов, а теперь мне нужно сделать такой поисковик по ним.
Не встечали такое готовое? Чтобы мышкой накидал в админке, что будем выбирать и готово? За 5 минут.
Решишь эту задачу без ООП и покажешь, как лучше сделать?
>>26413
А зачем? Это плохая идея. Если ты хочешь, чтобы они или оба выполнились, или не выполнились, заверни их в транзакцию.
>>26479
Тролли подъехали. Покажи, как это сделать без ООП. Задача из учебника в ОП-посте, глава про ООП, задача про "Вектор" и антикризисные меры.
В PHP код по умолчанию однопоточный. То есть команды выполняются одна за другой, без распараллеливания. На твоем же рисунке явно видно распараллеливание, где код выполняется в 3 параллельных потока.
Скчивание файла через HTTP-запрос - это многоступенчатый процесс. Он требует сделать несколько действий, каждое из которых может затянуться, так как передача данных по сети не мгновенная:
- определить IP адрес сервера по его имени (example.com -> 1.2.3.4). Для этого ты должен составить пакет с DNS-запросом и попросить ОС его отправить DNS-серверу
- затем ты ждешь получения ответа от DNS-сервера. Он может придти через 0,1с, а может через несколько секунд - все это время твой код стоит и ничего не делает, ждет прихода пакета
- получив IP, ты просишь ОС установить TCP-соединение с этим IP и ждешь подтверждения, что оно установлено
- если все ок, ты шлешь серверу HTTP-запрос. Опять же, ждешь подтверждения, что он дошел до сервера
- затем сервер обрабатывает твой запрос, ты ждешь
- затем он шлет тебе ответ, ты принимаешь его по частям и сохраняешь
- затем ты просишь ОС закрыть соединение и ждешь подтверждения
Каждое из этих действий по умолчанию блокирующее, то есть ОС останавливает твою программу до прихода ответа (иначе будет неудобно - ведь каждый следующий шаг зависит от предыдущего). Вот, например, такой код:
ид1 = установить_соединение('1.2.3.4');
отправить_запрос_в_соединение(ид1, запрос);
Здесь каждая функция возвращает управление только когда требуемая операция выполнена.
Очевидно, что с таким подходом нельзя выполнять параллельно более одного запроса. Потому для этого используют неблокирующие операции. Они выглядят примерно так. Допустим, тебе надо установить 2 TCP-соединения и отправить в них запросы параллельно. Ты просишь ОС установить соединение в неблокирующем режиме. Она запускает процесс установки соединения, и не дожидаясь результата, возвращает тебе его идентификатор. Так как соединение пока не установлено, то посылать данные в него нельзя:
ид1 = установить_соединение_без_блокировки('1.2.3.4');
Так как твоя программа не блокируется, то ты можешь сразу попросить ОС установить второе соединение:
ид2 = установить_соединение_без_блокировки('3.4.5.6');
Теперь у тебя есть 2 идентификатора, но отправлять запрос можно только когда соединение установится. Чтобы дождаться этого, ты просишь ОС заблокировать тебя до того момента, пока любое из соединений не будет готово к приему данных (или пока не обнаружится ошибка):
while (true) {
соединение = ждать_изменения_состояния([ид1, ид2]);
Как только с соединением что-то произойдет, ОС вернет тебе его идентификатор. И ты можешь слать запрос, так же, в неблокирующей манере:
если (соединение == ид1 && мы еще не отправили запрос в соединение 1) {
отправить_запрос_в_соединение(ид1, запрос1);
} иначе если (соединение == ид1 && мы отправили запрос в соединение 1) {
начать_прием_ответа(ид1, буфер_для_ответа_1);
} иначе, если (соединение == ид2 && мы не отправили запрос в соединение 2) {
....
}
}
Как видишь, здесь сделан цикл, который получает от ОС уведомление о том, что произошло какое-то событие и реагирует на него. Такой цикл позволяет параллельно обрабатывать множество соединений.
Курл прячет от тебя всю эту сложность, и этот цикл в нем спрятан в функции curl_multi_exec - она как раз и занимается тем, что запрашивает у ОС состояние соединений и реагирует на его изменения.
Если ты в своем коде вызовешь sleep() то все это время curl_multi_exec работать не будет и скачиваться ничего не будет. Потому тебе надо делать паузу в такой же асинхронной манере:
while (true) {
соединение = ждать_изменения_состояния_или_завершения_таймаута([ид1, ид2], 2 секунды);
если (прошло 2 секунды) {
запустить повторное соединение;
}
...
То есть, тебе надо вместо sleep сделать асинхронную проверку прошедшего времени вот в этом цикле: do { curl_multi_exec($mh,$active); } while ($active);
И как я написал выше, без объектов или каких-то других абстракций делать это будет крайне неудобно.
В общем, твой код очень примитивный и у тебя явно недостаточно знаний, потому я предлагаю учиться в таком порядке:
- изучить сокеты Беркли, сначала блокирующие, на функциях socket_create, socket_read, socket_write
- потом научиться писать неблокирующий код на функциях вроде socket_select как описано выше
- потом освоить ReactPHP и промисы
- и наконец с этими знаниями либо написать свой код, либо сделать свою задачу с использованием Guzzle
Без этого, даже если ты где-то найдешь готовый ответ, ты не сможешь работать с этим кодом, поддерживать его, дорабатывать итд. Если для тебя это слишком сложно, то можно сделать проще: на каждый URL запускать отдельный php-скрипт и в нем выполнять один запрос в блокирующей манере, на обычном курле, делая паузу с помощью sleep.
В PHP код по умолчанию однопоточный. То есть команды выполняются одна за другой, без распараллеливания. На твоем же рисунке явно видно распараллеливание, где код выполняется в 3 параллельных потока.
Скчивание файла через HTTP-запрос - это многоступенчатый процесс. Он требует сделать несколько действий, каждое из которых может затянуться, так как передача данных по сети не мгновенная:
- определить IP адрес сервера по его имени (example.com -> 1.2.3.4). Для этого ты должен составить пакет с DNS-запросом и попросить ОС его отправить DNS-серверу
- затем ты ждешь получения ответа от DNS-сервера. Он может придти через 0,1с, а может через несколько секунд - все это время твой код стоит и ничего не делает, ждет прихода пакета
- получив IP, ты просишь ОС установить TCP-соединение с этим IP и ждешь подтверждения, что оно установлено
- если все ок, ты шлешь серверу HTTP-запрос. Опять же, ждешь подтверждения, что он дошел до сервера
- затем сервер обрабатывает твой запрос, ты ждешь
- затем он шлет тебе ответ, ты принимаешь его по частям и сохраняешь
- затем ты просишь ОС закрыть соединение и ждешь подтверждения
Каждое из этих действий по умолчанию блокирующее, то есть ОС останавливает твою программу до прихода ответа (иначе будет неудобно - ведь каждый следующий шаг зависит от предыдущего). Вот, например, такой код:
ид1 = установить_соединение('1.2.3.4');
отправить_запрос_в_соединение(ид1, запрос);
Здесь каждая функция возвращает управление только когда требуемая операция выполнена.
Очевидно, что с таким подходом нельзя выполнять параллельно более одного запроса. Потому для этого используют неблокирующие операции. Они выглядят примерно так. Допустим, тебе надо установить 2 TCP-соединения и отправить в них запросы параллельно. Ты просишь ОС установить соединение в неблокирующем режиме. Она запускает процесс установки соединения, и не дожидаясь результата, возвращает тебе его идентификатор. Так как соединение пока не установлено, то посылать данные в него нельзя:
ид1 = установить_соединение_без_блокировки('1.2.3.4');
Так как твоя программа не блокируется, то ты можешь сразу попросить ОС установить второе соединение:
ид2 = установить_соединение_без_блокировки('3.4.5.6');
Теперь у тебя есть 2 идентификатора, но отправлять запрос можно только когда соединение установится. Чтобы дождаться этого, ты просишь ОС заблокировать тебя до того момента, пока любое из соединений не будет готово к приему данных (или пока не обнаружится ошибка):
while (true) {
соединение = ждать_изменения_состояния([ид1, ид2]);
Как только с соединением что-то произойдет, ОС вернет тебе его идентификатор. И ты можешь слать запрос, так же, в неблокирующей манере:
если (соединение == ид1 && мы еще не отправили запрос в соединение 1) {
отправить_запрос_в_соединение(ид1, запрос1);
} иначе если (соединение == ид1 && мы отправили запрос в соединение 1) {
начать_прием_ответа(ид1, буфер_для_ответа_1);
} иначе, если (соединение == ид2 && мы не отправили запрос в соединение 2) {
....
}
}
Как видишь, здесь сделан цикл, который получает от ОС уведомление о том, что произошло какое-то событие и реагирует на него. Такой цикл позволяет параллельно обрабатывать множество соединений.
Курл прячет от тебя всю эту сложность, и этот цикл в нем спрятан в функции curl_multi_exec - она как раз и занимается тем, что запрашивает у ОС состояние соединений и реагирует на его изменения.
Если ты в своем коде вызовешь sleep() то все это время curl_multi_exec работать не будет и скачиваться ничего не будет. Потому тебе надо делать паузу в такой же асинхронной манере:
while (true) {
соединение = ждать_изменения_состояния_или_завершения_таймаута([ид1, ид2], 2 секунды);
если (прошло 2 секунды) {
запустить повторное соединение;
}
...
То есть, тебе надо вместо sleep сделать асинхронную проверку прошедшего времени вот в этом цикле: do { curl_multi_exec($mh,$active); } while ($active);
И как я написал выше, без объектов или каких-то других абстракций делать это будет крайне неудобно.
В общем, твой код очень примитивный и у тебя явно недостаточно знаний, потому я предлагаю учиться в таком порядке:
- изучить сокеты Беркли, сначала блокирующие, на функциях socket_create, socket_read, socket_write
- потом научиться писать неблокирующий код на функциях вроде socket_select как описано выше
- потом освоить ReactPHP и промисы
- и наконец с этими знаниями либо написать свой код, либо сделать свою задачу с использованием Guzzle
Без этого, даже если ты где-то найдешь готовый ответ, ты не сможешь работать с этим кодом, поддерживать его, дорабатывать итд. Если для тебя это слишком сложно, то можно сделать проще: на каждый URL запускать отдельный php-скрипт и в нем выполнять один запрос в блокирующей манере, на обычном курле, делая паузу с помощью sleep.
Так зачем писать все одной длинной портянкой? Возможно, надо разбивать код на функции.
Ну и с промисами не должно быть большой вложенности, они обычно пишутся так же:
var result1 = someAsyncFunc();
var result2 = result1.then(function () {
return someOtherAsyncFunc();
});
var result3 = result2.then(function () {
return someOtherAsyncFunc();
});
(естественно, имена переменных надо делать нормальные и добавить обработку ошибок).
>>26678
> Значит можно вычислять заработную плату сотрудников, а также остальные параметры в департаменте?
Это один вариант. Другой - сделать, чтобы работник знал, босс он или нет.
> >сделать в департаменте правильную функцию
> Что-то вроде этого?
Я имел в виду, раз работник не знает, босс ли он, то он не может посчитать себе зарплату. Её должны посчитать в департаменте:
public function getEmployeeSalary(Employee $e): int
Так зачем писать все одной длинной портянкой? Возможно, надо разбивать код на функции.
Ну и с промисами не должно быть большой вложенности, они обычно пишутся так же:
var result1 = someAsyncFunc();
var result2 = result1.then(function () {
return someOtherAsyncFunc();
});
var result3 = result2.then(function () {
return someOtherAsyncFunc();
});
(естественно, имена переменных надо делать нормальные и добавить обработку ошибок).
>>26678
> Значит можно вычислять заработную плату сотрудников, а также остальные параметры в департаменте?
Это один вариант. Другой - сделать, чтобы работник знал, босс он или нет.
> >сделать в департаменте правильную функцию
> Что-то вроде этого?
Я имел в виду, раз работник не знает, босс ли он, то он не может посчитать себе зарплату. Её должны посчитать в департаменте:
public function getEmployeeSalary(Employee $e): int
Про безопасность можно бесплатный хостинг на клауде взять чтобы не было проблем с досом итд.
Про сложность, можно же научиться скриптовать запросы итд?
Объясните нубу плз?
>Разве нельзя разместить свой сервер на апаче или на никсе на ноуте и размещать там спокойно свой сайтец?
Можно, если у тебя белый ип, что очень врядли. И то домен ты все равно где-то покупать будешь.
Домен то ясное дело. Почитал на стаке об этом, челу сказали что ему придется сервера защищать, настраивать и поддерживать в рабочем состояний, мол это сложно, но сервера будут работать быстро, то что мне надо.
> если у тебя белый ип
Не в курсе темы, можно поподробнее? Имеется ввиду то, что айпишник должен быть напрямую в сеть, а не через провайдерские порты?
Я просто пробовал вывести свой сервер на публику, через особенный порт, перенаправил его внутри роутера на порт 80, вывело стартовую страницу Drupal спокойно в сеть, можно было войти на сайт, но пришлось отключить SELinux и поэтому я сайт положил, нехорошая практика, сейчас планирую сервер сделать на Debian, все хорошо пока что, но нужно все равно разбирать эту тему. Все будет локально как рекомендует сам дебиан и запросы будут брать данные с локальной базы данных. В общем пока разбираюсь.
Щас проверил, провайдер говорит что у меня белый адрес.
>распараллеливание, где код выполняется в 3 параллельных потока.
Так потому что multicurl, разве нет?
>Используя curl_multi_exec, мы можем выполнять все эти запросы параллельно, тем самым общее время запроса будет равно времени самого медленного из запросов.
>Если ты в своем коде вызовешь sleep() то все это время curl_multi_exec работать не будет и скачиваться ничего не будет.
Я правильно это изобразил? При условии, что у разных запросов разная продолжительность.
В очередной раз спасибо за помощь. Постараюсь всё изучить. Хотя, конечно, хотелось бы сначала как-нибудь доделать свой недокод, но ладно.
Есть вот такая вырванная из контекста строчка:
move_uploaded_file($_FILES['img']['tmp_name'], 'imgs/uploads/' . $_FILES['img']['name']);
Кому лень думать, она перехватывает заголовки, отправленные методом POST и перемещает картинку из временного каталога в uploads.
Где находится этот временный каталог?
Я играл с php.ini, с директивой upload_tmp_dir путь к этой временной директории, перезагружал апач. Phpinfo() говорит, что директория изменена.
Но код продолжает работать, что бы я ни написал в этой директиве.
Хорошо. Изменяю строчку на:
move_uploaded_file('путь/указанный/в/upload_tmp_dir' . $_FILES['img']['tmp_name'], 'imgs/uploads/' . $_FILES['img']['name']);
Но обработчик не загружает картинку.
По умолчанию эта директива в php.ini закомментирована, то есть есть какой-то путь по умолчанию, о котором я не знаю. Как его найти?
>Так зачем писать все одной длинной портянкой? Возможно, надо разбивать код на функции.
Так всё что можно разбить уже разбито. Валидация делается с помощью ORM библиотеки, на подобии того как это делается в Symfony. Работа с БД тоже выполнена с её помощью. Сравнение пароля с хешем и получение токена выполнены тоже с помощью сторонних библиотек. Остаётся только выдача ответа, которым должен заниматься сам контроллер.
Причина по которой я запостил свой код, это показать как асинхронный код становиться чище после применения async/await. Взгляните, ведь даже после рефакторинга во 2-ом примере, в котором вложенность стала чуть-чуть чище, в 3-ем примере код всё равно стал читаемей.
>Ну и с промисами не должно быть большой вложенности, они обычно пишутся так же:
Если это повсеместно рабочая практика, то у меня плохое предчувствие об этом.
В моём коде пришлось бы писать
let validatePromise...
let findPromise...
let compareHashPromise...
Это же выглядит уродливо. В каких проектах вам довелось это видеть?
Промисы для хипстеров.
Можно, но тут есть несколько проблем.
1) если твой провайдер использует NAT, то снаружи нельзя подсоединиться к твоему компьютеру, так как у него нет видимого снаружи адреса (он виден только в локалке провайдера). Тебе нужно в этом случае приобрести "белый внешний IP" у провайдера, это может стоить денег. Если ты используешь роутер, вдобавок надо пробросить порт на роутере, так как роутер это тот же NAT.
2) если у твоего провайдера динамические IP адреса, то адрес твоего сайта может меняться. Тебе надо либо приобрести фиксированный "белый IP", либо заморачиваться с динамическим DNS (это штука, которая обновляет адрес твоего сайта когда провайдер выдает тебе новый адрес, но она работает неидеально).
3) твой ноутбук должен быть подключен к сети постоянно. Ты не можешь его перезагрузить просто так. не говоря уж о том, чтобы взять куда-то с собой. Неудобно. Хотя, если у тебя есть второй ноутбук, то это не проблема.
4) за электричество от постоянно включенного ноутбука придется платить
5) если твой сайт станет очень популярен, и исчерпает лимит трафика, провайдер может потребовать перейти на тариф подороже
То есть получится неудобно и дорого. И VPS за 3 евро окажется дешевле. Но такая возможность есть, можешь попробовать. Плюсы тут тоже есть: в отличие от хостинга, никто не может залезть в твой компьютер и следить за твоими посетителями. Также, ты можешь поднять у себя свой джаббер-сервер и общаться приватно, не делясь ни с кем своими данными.
Да, sleep останавливает твою программу на 2 с и в этом время ничего не делается, данные не принимаются и не передаются.
Многопоточности там нет, мультикурл ее имитирует, используя неблокирующие операции и обрабатывая происходящие события по очереди.
>>27270
Ни в коем случае не пиши такой код, это просто открывает доступ к твоему серверу. Ты должен был сначала изучить безопасную загрузку файлов, а только потом ее делать.
$_FILES['img']['name'] предоставляет пользователь и он может вписать туда что угодно. Например, он тебе может загрузить файл с именем backdoor.php и вызвать его. Или .htaccess. Сделай исправления:
- проверяй расширение файла по белому списку, а лучше генерируй имя сам
- так как пользователь может использовать любые, в том числе нечитаемые символы в имени, фильтруй их по списку разрешенных символов или генерируй безопасное имя сам
- если вдруг файл не требуется отдавать наружу и показывать на сайте, то загружай его в непубличную папку, чтобы к нему нельзя было обратиться из браузера
- запрети выполнение php в папке с файлами с помощью htaccess
- если разрешено загружать только картинки, можно проверить ее тип и размеры с помощью http://php.net/manual/ru/function.getimagesize.php
- проверяй размер загружаемого файла
> Где находится этот временный каталог?
Сделай var_dump($_FILES); и смотри, что написано в tmp_name.
> ('путь/указанный/в/upload_tmp_dir' . $_FILES['img']['tmp_name'],
В tmp_name уже хранится полный путь и дописывать ничего не надо.
Если переменные на каждый шаг писать неохота, можно писать цепочкой (но я не вижу проблем в переменных и это по моему чище, чем цепочка):
var result = async1().then(function () {
return async2();
}).then(function () {
return async3();
})
async/await удобнее, да.
Где можно почитать о подобном? О принципах работы и внутреннем устройстве PHP? Разобраться, что под капотом и как работает? Что можешь посоветовать?
>Ни в коем случае не пиши такой код, это просто открывает доступ к твоему серверу. Ты должен был сначала изучить безопасную загрузку файлов, а только потом ее делать.
У тебя синдром учителя. Я же написал, что строчка вырвана из контекста. Не буду же я тонны проверок сюда копипастить, правильно?
>Сделай var_dump($_FILES); и смотри, что написано в tmp_name.
["tmp_name"]=> string(14) "/tmp/phpGQXuhf"
Я перепутал абсолютный каталог tmp в корне системы с относительным каталогом в корне сайта. Вот я дебич.
Что значит "спарсил"? Скачал себе на комп торрент-файлы? Залил ссылки на них в базу?
Тащемта, если поиск простой, допустим, если пользователь ищет что-то по имени торрент файла gta 5, то тут можно обойтись простой подстановкой значения из поиска в mysql запрос. Умеешь в такое?
Хотелось мы с ajax-подсказками, конечно. Вопрос немного не в этом: может кто видел готовую cms, ориентированную на большие массивы данных и чтобы там была уже пагинация, карта сайта, категори и т.п.?
Шобы оно не падало на нескольких миллионах записей.
Мне по сути нужен поиск и вывести несколько значений типа: тайтл, деск, торент файл, магнет - для каждого найденного.
Не, я с цмсками не связывался.
>Если переменные на каждый шаг писать неохота, можно писать цепочкой
Можно посмотреть в 1-ом примере к чему это привело - Promise Hell.
>но я не вижу проблем в переменных и это по моему чище, чем цепочка
Выходит переменные или цепочка, это дело вкуса. Но с async/await мы сходимся во мнениях, и значит нужно использовать это, чтобы это становилось общей рабочей практикой.
>1000
Пилите перекат, суки!
Какая блять разница как должно или положено? Одни блять стереотипы в кодировании. Сами ведь себе сложности хуярите. А ведь можно писать так, как реально удобно.
>Какая блять разница как должно или положено?
Языки программирования созданы чтобы переводить человекочитаемый формат в бинарные инструкции (машинный код). Но человекочитаемый формат, это относительное понятие. Чтобы это понятие стало объективным нужно прийти к своду правил, как это делается в естественных языках, посредством правил грамматики и пунктуации.
Иными словами, код пишется чтобы другие люди его понимали.
Написание кода упрощает IDE и прочий вспоможательный софт.
Фреймворки уменьшают время разработки из-за того, что некоторые частоиспользуемые программные модули там уже реализованы, причём часто довольно хорошо.
>>27510
>может кто видел готовую cms, ориентированную на большие массивы данных и чтобы там была уже пагинация, карта сайта, категори и т.п.?
Вукомерц для вордпресса смотрел? Это плагин электронного магазина. Должен подходить под твои нужды. Только подкрутить под задачу.
Вообще, что понимать под "большими массивами"? Ты собираешься весь миллион торрентов пользователю показывать сразу? Зачем? Он их всё равно не прочитает, и даже не оценит. А простой поиск по базе сделать недолго на чистом пхп.
>Одни блять стереотипы в кодировании.
Это хорошо.
Вот говоришь ты человеку - говно, и он понимает, что это такое. А вот если один говорит - студёная коричневая масса с неприятным запахом, второй - органические выделения, а третий вообще - сладкий деревенский хлебушек.
Вот пойди и разбери что там каждый имеет ввиду. Поэтому отсебятина в программировании там, где есть уже ставшее стандартом решение - плохо.
Спасибо.
Попробуй думать не стереотипами, а своей головой. Можно использовать ООП, но писать при этом компактно. Можно не использовать ООП, и писать еще компактней. Но для этого нужно думать, а не тупо копировать то что Гради Буч придумал.
И то и другое.
Не, вордпресс оче хуево работает на овер 30к записях - из-за замудренной структуры бд. Плюс там этот wp api еще - я буду добавлять в базу несколько лет.
Отличия в знаниях будут не значительными. Ты будешь знать лучше работу веба. Те кто на C/C++ будут лучше знать работу процессора. Если опыт одинаковый, то нельзя сказать кто из них лучше или хуже. Бывают крутые и PHP разработчики, которые всесторонне развиваются, решают сложные задачи.
Фреймворк это просто некоторый заранее написанный код. Он должен предоставлять необходимые штуки для решения задачи. Если это веб-фреймворк, то он должен решать задачу маршрутизации запросов, шаблонизации, иметь механизм миграций, и тому подобное.
>>27574
Я подозреваю, книги "Как делать асинхронные запросы с помощью multi curl в PHP" нету. Можно погуглить, вдруг есть, но я бы не надеялся. Можно почитать про сетевое программирование в linux (чтобы знать, как работают сокеты Беркли) и затем про асинхронное сетевое программирование в linux, мультиплексирование ввода-вывода:
- про сокеты Беркли https://rsdn.org/article/unix/sockets.xml (на примере языка Си, в PHP эти же функции доступны под именами вроде socket_create, socket_bind и тд, см. мануал PHP)
- http://php.net/manual/ru/book.sockets.php
- https://webonrails.ru/post/37878306439173678/ (там в коде есть ошибки)
- книга про сетевое программирование на linux "UNIX: разработка сетевых приложений" на примере Си: https://it.wikireading.ru/6936 Мультиплексирование ввода/вывода описано в главе 6.
А вот про реализацию мультиплексирования I/O уже в PHP:
- https://habr.com/ru/post/111357/
Одной теории, конечно, мало, потому я бы предложил тебе написать такие программки для закрепления:
- программа, которая в блокирующем режиме отправляет HTTP-запрос на заданный URL и приниаме ответ
- программа, которая в неблокирующем режиме, параллельно, отправляет HTTP-запросы на разные сервера. Добавить к ней ограничение частоты отправки запросов на один домен, а также повтор при временных ошибках (вроде 500 или ошибки установки соединения). Разрешение имени домена через DNS можно сделать блокирующим, хотя, если ты сможешь и это сделать асинхронно, это будет плюс.
Я могу проверить твой код и дать тебе советы и подсказки.
Буду писать что-то на laravel + vue.js специально для портфолио.
Может подкинете идей для проекта? Было бы неплохо, если бы он ещё и полезен был кому-то.
Не соглашусь полностью. Я написал, что промисы как раз позволяют избежать callback hell при правильном применении. И если в примере кода выше этот hell получается, то проблема, скорее всего, не в промисах.
Ну к примеру, возьмем этот код:
user.validate({ skip: ....}).then(() => {
return User.find({ where: ... }).then(u => {
...
return bcrypt.compare(...).then(r => {
...
});
});
}).catch(err => {
...
});
Первое, что бросается в глаза - многое можно вынести в отдельные функции. Например, поиск пользователя по логину и паролю - логично вынести в модуль авторизации:
userPromise = authService.findOneByLogin(email, password);
Я это и назвал "портянкой", то, что часть кода так и просит, чтобы его вынесли в отдельные функции.
Но, допустим, вынести код нельзя. Даже в этом случае его можно перестроить на последовательный, а не вложенный, код:
var skip = ...;
var userData = user.validate({ skip: skip }).then(function () {
return User.find({ where: email });
}).then(function (u) {
if (!u) {
// Это код 404, а не 204. 204 обозначает успех операции, а не ошибку.
throw new Http404Error(...);
}
return [u, authService.checkPassword(u, password)];
}).then(function (checkResult) {
[u, isPassValid] = checkResult;
if (!isPassValid) {
throw new Http403Error(...);
}
return [u, signUserTokenAsync(u)];
});
// Вся работа с res в одном месте, а не раскидана по коду
responsePromise.then(function (userData) {
[u, jwt] = userData;
res.status(200);
res.json(u.getPublic());
res.cookie(....);
}, function (err) {
if (err instanceof ValidationError) {
res.status(400);
} else if (err instance of HttpError) {
...
} else if (err instance of PasswordInvalidError) {
res.status(403);
} else {
console.error(err);
res.status(503);
}
});
Цепочка промисов - это процесс преобразования данных, где каждый коллбек делает одно преобразование:
данные из Request -> успешный результат валидации -> объект User -> User + результат проверки пароля -> User + токен
При использовании промисов мы сначала составляем цепочку преобразований, а потом реализуем ее в коде - и получается последовательный код.
Передача массивов выглядит немного коряво и намекает на неправильное использование промисов, потому я попробовал написать альтернативный вариант, без нее, где мы делаем независимые цепочки промисов для преобразования каждого значения отдельно:
Email -> валидированный Email -> объект User
Password, User -> результат проверки пароля
User -> подписанный токен
За счет этого мы даже можем выполнить 2 последних операции параллельно (проверка пароля и генерация токена), при условии что там асинхронный код и при условии, что это не создает нежелательных эффектов (например, лишние записи в БД):
var validatedUser = user.validate(...).then(function () {
return User.find(where);
});
var isPassValidPromise = validatedUser.then(function (u) {
return authService.checkPassword(u, password);
});
var signedTokenPromise = validatedUser.then(function (u) {
return signTokenAsync(u);
});
Promise.all([validatedUser, isPassValidPromise, signedTokenPromise]).then(function (all) {
[u, isPassValid, signedToken] = all;
res.send(...);
res.json(...);
res.cookie(...);
}).catch(function (err) {
// обработка ошибок
});
Мне кажется, так получается правильнее. Промис - это значение, к которому применяются преобразования, а не средство для создания лестниц из кода. Если нам нужно несколько значений, мы делаем несколько цепочек промисов.
Цепочки промисов удобно рисовать с помощью квадратиков и стрелочек на бумаге или с помощью утилиты Graphwiz: https://dreampuf.github.io/GraphvizOnline/#digraph Authorization { subgraph cluster_0 { validatedEmail -> User label = "Find User"; } subgraph cluster_1 { User -> isPassValid; label = "Check Pass"; } subgraph cluster_2 { label = "Sign Token"; User -> signedToken } email -> validatedEmail password -> isPassValid User -> successfulResponse isPassValid -> successfulResponse signedToken -> successfulResponse}
На графе узлы обозначают значения, а стрелочки - преобразования.
Разумеется, этот код можно переписать на await и он станет еще лучше. Но рисование цепочек поможет спроектировать код и в этом случае. Только после того, как я придумал эти цепочки, я увидел, что можно часть операций делать параллельно.
Использовать в цепочке промисов return res.status(...) тут не получится, так как оно продолжит выполнение цепочки и скорее всего вызовет ошибку. Потому я использовал исключения для прерывания цепочки (альтернативные идеи принимаются).
Также, в твоем коде бросается в глаза "проглатывание" ошибок: при возникновении ошибки в цепи промисов она не логгируется, а просто отдается ответ с кодом 500. Разработчик о ней не узнает, и никто не узнает. Это, на мой взгляд, неправильно, и усложняет поддержку кода. Должно быть так:
user.validate(...).then(function () {
....
}).catch(function (err) {
if (err instanceof ValidationError) {
// мы ловим исключение от user.validate(), хотя тут поймается и исключение
// от других элементов цепочки, и это плохо
return res.sendStatus(400);
}
// Логгируем ошибку
loggerSevrice.logError(err);
res.sendStatus(500);
});
Не соглашусь полностью. Я написал, что промисы как раз позволяют избежать callback hell при правильном применении. И если в примере кода выше этот hell получается, то проблема, скорее всего, не в промисах.
Ну к примеру, возьмем этот код:
user.validate({ skip: ....}).then(() => {
return User.find({ where: ... }).then(u => {
...
return bcrypt.compare(...).then(r => {
...
});
});
}).catch(err => {
...
});
Первое, что бросается в глаза - многое можно вынести в отдельные функции. Например, поиск пользователя по логину и паролю - логично вынести в модуль авторизации:
userPromise = authService.findOneByLogin(email, password);
Я это и назвал "портянкой", то, что часть кода так и просит, чтобы его вынесли в отдельные функции.
Но, допустим, вынести код нельзя. Даже в этом случае его можно перестроить на последовательный, а не вложенный, код:
var skip = ...;
var userData = user.validate({ skip: skip }).then(function () {
return User.find({ where: email });
}).then(function (u) {
if (!u) {
// Это код 404, а не 204. 204 обозначает успех операции, а не ошибку.
throw new Http404Error(...);
}
return [u, authService.checkPassword(u, password)];
}).then(function (checkResult) {
[u, isPassValid] = checkResult;
if (!isPassValid) {
throw new Http403Error(...);
}
return [u, signUserTokenAsync(u)];
});
// Вся работа с res в одном месте, а не раскидана по коду
responsePromise.then(function (userData) {
[u, jwt] = userData;
res.status(200);
res.json(u.getPublic());
res.cookie(....);
}, function (err) {
if (err instanceof ValidationError) {
res.status(400);
} else if (err instance of HttpError) {
...
} else if (err instance of PasswordInvalidError) {
res.status(403);
} else {
console.error(err);
res.status(503);
}
});
Цепочка промисов - это процесс преобразования данных, где каждый коллбек делает одно преобразование:
данные из Request -> успешный результат валидации -> объект User -> User + результат проверки пароля -> User + токен
При использовании промисов мы сначала составляем цепочку преобразований, а потом реализуем ее в коде - и получается последовательный код.
Передача массивов выглядит немного коряво и намекает на неправильное использование промисов, потому я попробовал написать альтернативный вариант, без нее, где мы делаем независимые цепочки промисов для преобразования каждого значения отдельно:
Email -> валидированный Email -> объект User
Password, User -> результат проверки пароля
User -> подписанный токен
За счет этого мы даже можем выполнить 2 последних операции параллельно (проверка пароля и генерация токена), при условии что там асинхронный код и при условии, что это не создает нежелательных эффектов (например, лишние записи в БД):
var validatedUser = user.validate(...).then(function () {
return User.find(where);
});
var isPassValidPromise = validatedUser.then(function (u) {
return authService.checkPassword(u, password);
});
var signedTokenPromise = validatedUser.then(function (u) {
return signTokenAsync(u);
});
Promise.all([validatedUser, isPassValidPromise, signedTokenPromise]).then(function (all) {
[u, isPassValid, signedToken] = all;
res.send(...);
res.json(...);
res.cookie(...);
}).catch(function (err) {
// обработка ошибок
});
Мне кажется, так получается правильнее. Промис - это значение, к которому применяются преобразования, а не средство для создания лестниц из кода. Если нам нужно несколько значений, мы делаем несколько цепочек промисов.
Цепочки промисов удобно рисовать с помощью квадратиков и стрелочек на бумаге или с помощью утилиты Graphwiz: https://dreampuf.github.io/GraphvizOnline/#digraph Authorization { subgraph cluster_0 { validatedEmail -> User label = "Find User"; } subgraph cluster_1 { User -> isPassValid; label = "Check Pass"; } subgraph cluster_2 { label = "Sign Token"; User -> signedToken } email -> validatedEmail password -> isPassValid User -> successfulResponse isPassValid -> successfulResponse signedToken -> successfulResponse}
На графе узлы обозначают значения, а стрелочки - преобразования.
Разумеется, этот код можно переписать на await и он станет еще лучше. Но рисование цепочек поможет спроектировать код и в этом случае. Только после того, как я придумал эти цепочки, я увидел, что можно часть операций делать параллельно.
Использовать в цепочке промисов return res.status(...) тут не получится, так как оно продолжит выполнение цепочки и скорее всего вызовет ошибку. Потому я использовал исключения для прерывания цепочки (альтернативные идеи принимаются).
Также, в твоем коде бросается в глаза "проглатывание" ошибок: при возникновении ошибки в цепи промисов она не логгируется, а просто отдается ответ с кодом 500. Разработчик о ней не узнает, и никто не узнает. Это, на мой взгляд, неправильно, и усложняет поддержку кода. Должно быть так:
user.validate(...).then(function () {
....
}).catch(function (err) {
if (err instanceof ValidationError) {
// мы ловим исключение от user.validate(), хотя тут поймается и исключение
// от других элементов цепочки, и это плохо
return res.sendStatus(400);
}
// Логгируем ошибку
loggerSevrice.logError(err);
res.sendStatus(500);
});
>>27618
В программировании используется инженерный подход: сравниваются разные варианты, их плюсы и минусы и выбирается выгоднейший. Как при проектировании моста или здания. Потому от программиста требуется понимание этих самых плюсов и минусов. Например, нет смысла проектировать архитектуру для скрипта на 200 строчек, который будет выполнен 1 раз. А для приложения на 100К строк, которое будет писать команда в течение нескольких лет - это необходимо.
>>27754
А есть что-то, что тебе интересно или нужно? Если не придумаешь, то в ОП-посте есть задача на SPA. Она сложная, если хочется что-то проще, сделай ленту новостей (вроде Хабра или Твиттера): есть бесконечная лента новостей, можно заходить в новость, можно читать только новости из определенной категории, можно писать комменты, можно добавлять в закладки и лайкать. В идеале все это динамически обновляется (например, число лайков), оптимально кешируется и работает при перебоях со связью. На любую страницу можно дать ссылку.
Ленту новостей можно будет показать на собеседовании.
С лентой отличная идея, анончик. Спасибо, если ничего лучше не придумаю - запилю.
Ещё можно создать джобы по парсингу каких-то новостных ресурсов, или мемов.
А в идеале сделать, чтобы можно было выбрать источники информации. Но это уже новостной портал, а не проектик для портфолио.
http://jsfiddle.net/4Ld60kht/ - думаю поля можно было через паддинг родителя, но я сделал так.
7
http://jsfiddle.net/avu90q3w/
8
http://jsfiddle.net/pvk2rf9a/ - не понял как тут применить отрицательный маргин и не уверен что * хорошо указывать
А так сделал эти задачи вроде.
Из-за этого код выглядит как говно и постоянно не вмещается в одну строку.
И если метод, принимающий несколько аргументов, еще можно красиво сформатировать, то принимающий 1 аргумент длинный метод всегда выглядит как говно.
Но я не могу называть переменные и методы короче, иначе потеряется понимание их смысла.
Я вижу метод sendTextMessageAndShowMenu
Во-первых, можно написать просто sendMessage.Во-вторых, а почему у тебя одна функция делает две задачи? Если они независимы, их можно сделать 2 функциями. Если же связаны, то объединить в одну функцию с названием просто sendMessage.
NOTES_SELECTED_CURRENT_MESSAGE_INDEX -> тут одно слово можно сократить, а при желании еще и INDEX убрать.
Лол, я такое встречал в реальной жизни, когда люди с джавы вкатывались в веб. Личный опыт. У джавистов приняты многосложные именования свойств и методов. Но есть в этом плюс, легко понимать, что человек написал. Правда если приходится парсить глазами длинную простыню, то это затянется надолго. Да и джава медленная, хоть и простая.
>Promise.all
Да, я видел и такой вариант обработки промисов. Но всё равно, как вы и сказали, с async/await код станет только лучше.
>// Это код 404, а не 204. 204 обозначает успех операции, а не ошибку.
404 означает ошибку, то есть когда приложение пытается обратиться к несуществующему ресурсу. А 204 означает, что операция прошла успешно, ничего не найдено (нет контента).
https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
>10.4.5 404 Not Found
>The server has not found anything matching the Request-URI.
>Также, в твоем коде бросается в глаза "проглатывание" ошибок: при возникновении ошибки в цепи промисов она не логгируется, а просто отдается ответ с кодом 500.
Спасибо за это замечание. Об этом я как раз и забыл.
Я думал, я уже достаточно сознателен чтобы писать код без ошибок, а всё таки совершил одну с логгированием.
Здоровья тебе, добрый человек
Есть у меня к примеру сущности "товары", "отзывы", "пользователи". И есть два способа проектирования.
1. создать для каждой сущности отдельную базу с небольшим количеством таблиц, например, база "товары", таблицы "все товары", "товары в корзине", "товары в 'понравилось'" и т. д.
Получится несколько баз с несколькими таблицами. При большой нагруженности, скорее всего общение сервера с базами будет происходить быстрее.
2. создать одну единую базу магазина с большим количеством таблиц всех сущностей. База "магазин", таблицы "товары", "товары в корзине", ... "отзывы", "ответы на отзывы", ... и т. д.
Как лучше и почему?
Знаю, что у опенкарт, например, база устроена по второму принципу. Но что-то мне подсказывает, что первый вариант удобнее.
> 404 означает ошибку, то есть когда приложение пытается обратиться к несуществующему ресурсу. А 204 означает, что операция прошла успешно, ничего не найдено (нет контента).
4xx обозначает ошибку клиента. Неправильный id пользователя - это явно ошибка клиента.
Предлагаю посмотреть RFC7231 (чуть более новый, чем устаревший 2616, это упомянуто тут: https://www.w3.org/Protocols/rfc2616/rfc2616.html ):
Код 204: https://tools.ietf.org/html/rfc7231#section-6.3.5
> The 204 (No Content) status code indicates that the server has
> successfully fulfilled the request and that there is no additional
> content to send in the response payload body.
Тут передан неверный email, и это явно не "успешный" результат, а ошибка. Тем более, что клиент, как я понимаю, рассчитывал получить токен.
> For example, a 204 status code is commonly used with document editing
> interfaces corresponding to a "save" action, such that the document
> being saved remains available to the user for editing.
204 обычно используется, когда запрос обработан (например, запрос на добавление товара в корзину), но в ответ посылать ничего не требуется.
Код 404: https://tools.ietf.org/html/rfc7231#section-6.5.4
> The 404 (Not Found) status code indicates that the origin server did
> not find a current representation for the target resource or is not
> willing to disclose that one exists.
Можно заметить, что тут убрано упоминание URI. Думаю, в RFC2616 авторы имели в виду запрос вида /user/12345 и в ответ на него предполагали отдавать 404 если id неправильный. Но по моему, его вполне логично отдавать, даже если id пользователя передан не через URI.
И тут: https://tools.ietf.org/html/rfc7231#section-6.5
> The 4xx (Client Error) class of status code indicates that the client
> seems to have erred. Except when responding to a HEAD request, the
> server SHOULD send a representation containing an explanation of the
> error situation, and whether it is a temporary or permanent
> condition.
> 404 означает ошибку, то есть когда приложение пытается обратиться к несуществующему ресурсу. А 204 означает, что операция прошла успешно, ничего не найдено (нет контента).
4xx обозначает ошибку клиента. Неправильный id пользователя - это явно ошибка клиента.
Предлагаю посмотреть RFC7231 (чуть более новый, чем устаревший 2616, это упомянуто тут: https://www.w3.org/Protocols/rfc2616/rfc2616.html ):
Код 204: https://tools.ietf.org/html/rfc7231#section-6.3.5
> The 204 (No Content) status code indicates that the server has
> successfully fulfilled the request and that there is no additional
> content to send in the response payload body.
Тут передан неверный email, и это явно не "успешный" результат, а ошибка. Тем более, что клиент, как я понимаю, рассчитывал получить токен.
> For example, a 204 status code is commonly used with document editing
> interfaces corresponding to a "save" action, such that the document
> being saved remains available to the user for editing.
204 обычно используется, когда запрос обработан (например, запрос на добавление товара в корзину), но в ответ посылать ничего не требуется.
Код 404: https://tools.ietf.org/html/rfc7231#section-6.5.4
> The 404 (Not Found) status code indicates that the origin server did
> not find a current representation for the target resource or is not
> willing to disclose that one exists.
Можно заметить, что тут убрано упоминание URI. Думаю, в RFC2616 авторы имели в виду запрос вида /user/12345 и в ответ на него предполагали отдавать 404 если id неправильный. Но по моему, его вполне логично отдавать, даже если id пользователя передан не через URI.
И тут: https://tools.ietf.org/html/rfc7231#section-6.5
> The 4xx (Client Error) class of status code indicates that the client
> seems to have erred. Except when responding to a HEAD request, the
> server SHOULD send a representation containing an explanation of the
> error situation, and whether it is a temporary or permanent
> condition.
Не сталкивался с первым подходом. Есть такой принцип, как нормализация БД: https://github.com/codedokode/pasta/blob/master/db/normalization.md и он явно с ним не сочетается.
Да, есть еще такие вещи, как денормализация, шардинг, кеширование, итд., но начинают все равно с нормализованной схемы.
>почему у тебя одна функция делает две задачи? Если они независимы, их можно сделать 2 функциями. Если же связаны, то объединить в одну функцию с названием просто sendMessage.
Есть и отдельный метод sendTextMessage(), без показа меню, который обычно и используется.
А зачем я сделал еще и sendTextMessageAndShowMenu(). Вот зачем.
Возвращаемое значение sendTextMessage() всегда используется как возвращаемое значение вышестоящего метода.
То есть, return sendTextMessage();
Есть метод showMenu(), он не возвращает нихуя.
То есть, если есть какое-то условие типа пикрила и мне надо еще и показать меню, то надо писать:
if (...) {
$result = sendTextMessage();
showMenu();
return $result;
}
Вместо того, чтобы написать:
if (...) {
return sendTextMessageAndShowMenu();
}
Это охуенно так упрощает понимание кода за счет снижения когнитивной нагрузки.
Можно было показ меню сделать опциональным аргументом.
Типа
sendTextMessage (string $msg, bool $isShowMenu = false);
В принципе, тож вариант, но есть 2 минуса, не знаю насколько они велики, но они есть:
1. Я не могу средствами IDE в целях рефакторинга найти все сотни мест, где используется показ меню.
2. Когнитивная нагрузка вырастает, мозгу надо парсить доп-аргумент, методы с показом меню и без показа меню слабо отличаются на вид.
Чет какой-то невротъебенный анализ тут привел, ну да ладно, а хуле поделать.
>почему у тебя одна функция делает две задачи? Если они независимы, их можно сделать 2 функциями. Если же связаны, то объединить в одну функцию с названием просто sendMessage.
Есть и отдельный метод sendTextMessage(), без показа меню, который обычно и используется.
А зачем я сделал еще и sendTextMessageAndShowMenu(). Вот зачем.
Возвращаемое значение sendTextMessage() всегда используется как возвращаемое значение вышестоящего метода.
То есть, return sendTextMessage();
Есть метод showMenu(), он не возвращает нихуя.
То есть, если есть какое-то условие типа пикрила и мне надо еще и показать меню, то надо писать:
if (...) {
$result = sendTextMessage();
showMenu();
return $result;
}
Вместо того, чтобы написать:
if (...) {
return sendTextMessageAndShowMenu();
}
Это охуенно так упрощает понимание кода за счет снижения когнитивной нагрузки.
Можно было показ меню сделать опциональным аргументом.
Типа
sendTextMessage (string $msg, bool $isShowMenu = false);
В принципе, тож вариант, но есть 2 минуса, не знаю насколько они велики, но они есть:
1. Я не могу средствами IDE в целях рефакторинга найти все сотни мест, где используется показ меню.
2. Когнитивная нагрузка вырастает, мозгу надо парсить доп-аргумент, методы с показом меню и без показа меню слабо отличаются на вид.
Чет какой-то невротъебенный анализ тут привел, ну да ладно, а хуле поделать.
Читай про шардинг, репликацию, и прочие способы разработки высоконагруженных БД.
Но в 99.99% приложений, с которыми ты когда-либо столкнешься, тебе это нахуй не понадобится.
А как понадобится - так изучишь.
Преждевременные оптимизации - зло, не надо пытаться строить архитектуру как у гугла, кода у тебя сайт на полтора человека.
https://github.com/asdasdasdasddasasdasdas/StudentList
Op я переделал свой список. Чкни.
>Ты прав, такое говно после java началось у меня, теперь ооп головного мозга и любой код превращается в ебаную простыню.
А я думал, что я один такой, который раз за разом перекатывается на новую технологию, так и не устроившись на работу.
Да я и не перекатывался, прост немного знаю джаву.
В яве я узнал, что такое настоящий объектно-ориентированный код, строгая типизация, коллекции и многопоточность.
После нее пых кажется очень ограниченным.
>В яве я узнал, что такое настоящий объектно-ориентированный код
>>28056
>Ты прав, такое говно после java началось у меня, теперь ооп головного мозга и любой код превращается в ебаную простыню.
Никакого ООП не существует. Были идеи, но их не поняли, и не реализовал на должном уровне. Никаких математических обоснований у ООП нет. Все что сейчас преподносится под видом ООП просто сектантство. Код ради кода. Полное отсутствие логики. Чем хуже тем лучше. Все это характеризует современное ООП.
>Ооп нужен для упрощения написания программ
>>28056
>у меня, теперь ооп головного мозга и любой код превращается в ебаную простыню
Типичный сектантский ответ без фактов. Большая часть кода в ООП стиле ничего не делает. Это просто тупой бойлерплейт. А если большая часть кода написана ради кода, а не для решения задачи, то какое может быть упрощение вообще?! Вопрос риторический.
Проблема объектно-ориентированных языков заключается во всей их неявной среде, которую они всегда тянут за собой. Вы хотели банан, а получили гориллу, держащую банан, вместе со всеми джунглями. (Джо Армстронг, создатель языка Эрланг).
Но больше никак не выходит, если бы люди придумали что-то лучше — все бы это и использовали.
Вот и пишем абстрактные фабрики медиаторов фасадов синглтонов.
>если бы люди придумали что-то лучше
Придумали еще в 30-е годы 20-го века, называется Лямбда-исчисление.
На любом Тьюринг-полном языке можно написать любую вычислимую программу. PHP естественно Тьюринг-полный, на нем можно написать компилятор к примеру.
Чувак, ты тредом ошибся. В этом треде никто не программирует. Веб 21 века это:
1. натягивание готовых шаблонов на cms
2. редактирование этих шаблонов под себя
3. подключение js-библиотек
4. php-шный/js-сный копипаст во фреймворках.
5. готовые решения sql/nosql
И все это тянется из проекта в проект на автомате. Не на автомате даже, а на пулемете. Как макаки-копирайтеры хуярят килознаки текста, так и веб-"программисты" копипастят свои сниппеты.
>компилятор на пхп
> oтсутствие многопоточности
> неполная поддержка ООП
> помойка в стандартной библиотеке
> нестрогая типизация
> утечки памяти, как сквозь сито
> очень много жрет памяти (в 3 раза больше, чем руби)
> нет классов, привязанных к типам данных
Как там в 2005м?
ОНИ МОГЛИ ДЕЛАТЬ ТАКОЕ В 2000 ГОДУ!?! АХУЕТЬ Я ДАУН!!!!
Ааа ну да эпоха FP же была... Сук мода же делать все с помощью CSS&HTML&JS только сейчас началась.
Все уговорил иду учить РУБИ! Хотя пихуй Руби я бы и так изучил.
Но подожди можно же без копипаста делать все, использовать библиотеки и CMS без копирования, а как все это делают, даже опытные, подстраивают под себя зная что делает код. Просто если ты будешь свой фрейм писать на это уйдет время и если ты захочешь разработать свой, мало того, что ты потратишь ресурсы и время, так еще и потом будут говорить, что твоя копипаста нам не нужна. У тебя есть какие то другие варианты?
Про копирование и бесконечное использование стака если ты не учишься то это конечно же, позор. Но ведь не все идут под эту дудку, есть люди которые пишут и свои библиотеки и развиваются в другой манере, я не из них, ибо ничего не умею.
Kernel is a core.
С самопознания, найти себя и свое дело надо (Секрет: Заниматься хобби, например это тред PHP хоббитов).
Благодарю! Я задал вопрос для разбавления атмосферы, но ты дал верный ответ. Всем добра.
Спасибо! Это имеет больше смысла!
Лучше файлообменник, ибо найдешь ответы на вопросы после процесса и поддержку быстрее получишь. Сначала сделай уже известное, а потом и проект посмотрим.
Ты говоришь, что все используют готовые библиотеки. Но забываешь, что эти библиотеки кто-то пишет. Есть путь использовать библиотеки, а есть путь писать их для других. Точно также с языками, кто-то их использует, а кто-то их пишет.
Так что не нужно обобщать. Не все занимаются инфраструктурными вещами, подключением и стыковкой библиотек, и тому подобным.
Многопоточность не равна параллелизму.
>Есть путь использовать библиотеки, а есть путь писать их для других.
Подозреваю, что путь тут только один - писать костыли, а как опыта прибудет - уже библиотеки, чтобы другие не писали костыли.
Само собой нужен опыт. Но если не начать это делать, то откуда опыт возьмется?! В 95% случаев все говорят, что СИКП не нужен из-за того, что сейчас все занимаются только состыковкой готовых библиотек. Если они сами себе поставили ограничение заниматься только состыковкой готовых либ, то опыта написания либ у них никогда не появится.
Можно пилить свой. Так даже интереснее. Но я советую почитать советы и примечания к задачам про студентов и файлообменник, так как они и к другим приложениям подойдут.
Пожалуйста, давай возьмем во внимание то, что это 2000 год. Их сайт выйграл номинацию как самый лучший на то время и видимо не просто так.
bump
Анонче, чем использование laravel принципиально отличается от нативной пыхи
Нужно сделать задание для компании,а я уже третий день ебусь со всякими композерами, хомстедами и прочим долбоеб щито поделать и даже не начинал писать, хотелось бы узнать заранее как отличается код и процесс написания
Погугли зачем вообще нужны фреймворки.
Вкратце:
1. Фреймворк задает тебе архитектуру приложения, у тебя гораздо меньше шансов написать откровенно хуевую архитектуру.
2. Фреймворк предоставляет тебе различные классы и библиотеки в добровольно-принудительном порядке, в итоге, опять же, у тебя меньше шансов использовать левые хуевые библиотеки для стандартных нужд.
3. Фреймворк знаешь не только ты, другим разработчиком написанное на фреймворке приложение гораздо ГОРАЗДО понятнее, чем самописный говнокод
Спасибо, понял
В плане разницы с нативным кодом пыха/ларавел можно сравнить с жс/jQuery?
Я про то что по сути это заранее запиленные за тебя классы/функции и тд
Скорее с реактом тогда.
Жс - просто набор хуйни, чтобы воротить хтмл-тегами.
Фреймворк это не какая-то сторонняя хуйня, которую ты используешь в своем приложении.
Ты пишешь приложение как бы ДЛЯ фреймворка.
Фреймворк есть база, на который на нанизываешь свое говно.
Он специально сделан умными людьми так, чтобы все это происходило легко и хорошо
Ставлю, через композер, например либу "a", которая зависит от либы "b" с версией 1.0.0, которую она очевидно подтягивает.
Но, также, необходимо поставить либу "b", но с версией 1.5.0.
Шо будет?
>у тебя гораздо меньше шансов написать откровенно хуевую архитектуру
Талантливых говнокодеров ничто не останавливает. Видел не раз использование фреймворков только для роутинга, мб еще какой-нибудь мелочи, и все остальное самописный пиздец. Зато кейвордик в резюме.
Оооооой пор пафор
Нельзя поставить 2 разных версии одной библиотеки. Если удовлетворить твои требования и требования библиотеки a одной версией b нельзя, будет выдана ошибка с разъяснением причин.
Хулеж они так криворуко сделали то
DataMapper - это по идее сложная система вроде Доктрины, которая мапит объекты на строки в БД. Там могут быть реализованы IdentityMap, UnitOfWork и прочие радости поклонников Фаулера. TableGateway - это просто класс, в котором собраны все операции с одной таблицей. Вообще, Gateway у Фаулера - это класс, который собирает в себе все действия с какой-то системой, например, внешней системой, БД и так далее и операции с этой системой нельзя делать в обход Gateway.
А так - можно использовать и другие паттерны, например, activeRecord.
Ты поздно спохватился. Надо было не спеша изучить и композер, и ларавель, и ООП, и нужные паттерны (наш тред готов в этом помогать). Мгновенно это не выучить (если ты конечно не специалист с кучей опыта и знанием кучи языков), и в лучшем случае ты сможешь сделать что-то полуработающее, накопипастив кода, но толком не поняв, как он работает.
Тестовое задание очевидно нужно для проверки твоих знаний фреймворка, и очевидно, что пока у тебя их нету.
Фреймворк - это каркас приложения, который избавляет от необходимости писать код, который есть в каждом приложении (роутинг, доступ к БД, валидация, шаблоны). Ты пишешь только то, что уникально для твоего приложения и экономишь время. Также, другим разработчикам проще разобраться в коде (проект на фреймворке с документацией понять проще, чем разбираться в полностью самописном коде без документации). Если ты сделал хотя бы 2-3 проекта, то наверняка прихоилось писать почти одинаковый код. Его и выносят во фреймворк.
Также, к фреймворку обычно есть куча других сторонних библиотек, которые можно использовать, например, для приема платежей, авторизации итд.
Хотя мне лично больше нравятся библиотеки, как компоненты Симфони, из которых можно собрать свой фреймворк.
Хомстед (вирутальная машина с линуксом) наверно не обязателен, но под Windows придется настроить все нужные инструменты, и это потребует еще время.
Чтобы понять, как происходит процесс написания, открой любой туториал по созданию сайта на фреймворке и прочти: https://laravel.com/docs/5.1/quickstart#building-layouts-and-views (не понимаешь английский - нагугли перевод или статью на русском). Устанавливаешь фреймворк, выполняешь комнады, пишешь код.
Опять же, тут нужно время, чтобы разобраться.
Я так и понял, что завысил планку, кинув резюме
Делал все по гайдам, но не работает нихуя, хомстед не видит команд
Опыт в пыхе был на уровне зарегаться-залогиниться-выйти и сохранить какие нибудь данные пользователя, чтобы их потом вывести в лк
Ну и работа с почтой
Спасибо, анон, значит не буду трогать пока пхп не очень то хотел, просто вакансия очень вкусная и опыт какой никакой уже получить пришлось, поработаю во фронте или бекенде на ноде, а там уже посмотрим
В композиторского автозагрузчика есть json, в который я пишу что-то типа { "Huita1\\Huita2": "huita/huita1/huita2" }
В классе Huita.php пишу:
namespace Huita1\Huita2
Class Huita
{
public static function getHuita()
{
return 'huita';
}
{
}
Теперь, чтобы обратиться к этому классу из каких-нибудь ебеней, я пишу в другом файле ebenya.php:
Huita1\Huita2\Huita::getHuita();
А теперь сам вопрос: если перед каждым классом писать его пространство имен, то выходит очень, очень много кода. Как современные фреймворки решают этот вопрос?
Сохраняют неймспейс в константу и подставляют, куда нужно?
>А теперь сам вопрос: если перед каждым классом писать его пространство имен, то выходит очень, очень много кода. Как современные фреймворки решают этот вопрос?
>Сохраняют неймспейс в константу и подставляют, куда нужно?
Не надо перед каждым классом писать полное имя. Достаточно импортировать его используя use.
В твоём случае это выглядело бы так:
Вначале ипортируешь пространство имён use Huita1/Huita2
А потом просто обращаешься к своему синглтону просто по имени Huita::getHuita() где надо.
Только загрузчик правильно напиши - по ПИЭСАР, или юзай композеровский.
Ты вообще хуйню написал.
>Huita1/Huita2
Надо Huita1\Huita2
>Huita::getHuita()
Надо Huita2\Huita::getHuita()
Еле разобрался.
И нормальной практикой считается более одного use?
И еще, причем тут синглтон? Разве только в сингтоне может быть статический метод, лол?
Пожалуйста прочитай сначала урок про неймспейсы, может быть, там есть ответ на вопрос: https://github.com/codedokode/pasta/blob/master/php/autoload.md
Конструкция use позволяет избежать длинных имен в коде.
Нормальной практикой считается не писать use руками, а поручить это редактору или IDE. Я видел файлы, где было до 30-40 строчек use, да и ты можешь сам увидеть такие файлы в коде Symfony:
https://github.com/symfony/symfony/blob/5aa0967f9f0ab803ededefb040d48a0ebc7a27a6/src/Symfony/Bundle/FrameworkBundle/Controller/AbstractController.php
https://github.com/symfony/symfony/blob/7cc7c716acd27d2245fa3365547484ade7695052/src/Symfony/Bundle/SecurityBundle/SecurityBundle.php
>Ты вообще хуйню написал.
>Еле разобрался.
Ну извини.
Надо документацию читать, а не детские вопросы в треде задавать. Есть IDE и подсветка, а я в рот ебал пляску с этими долбанными палками во все стороны. Объявлять - в одну сторону, использовать - в другую, а ещё эта хуйня иногда экранирует. И винда с линуксом их по разному воспринимают.
Это не я хуйню написал, а они хуйню сделали.
Тащемта, если ты не знаешь, как что-то написать вручную, то ты не про.
bump
ОП, чекни плиз, что-то я запутался в следующих заданиях.
Ребята, изучать php еще актуально.
Можно ли вкатиться в ДС, не имея опыт работы?
Node или python сильно жмут?
фреймворк предоставляет тебе готовые абстракции для создания приложения.
Тебе не придется занимаются таким количеством низкоуровнего говна.
Сравни - чтобы сделать пирог ты можешь взять коржи, сгуху, ягоды и запечь пирог.
А можешь пойти в лес, вырубить его, засеять пшеницей, вырастить её.. когда муку получишь, испекешь коржики, замутишь сгуху домашнюю.
Ну ты понял, короче. От низшего говна повыше поднимаемся.
>В большинстве случаев все переменные PHP имеют только одну область видимости. Эта единая область видимости охватывает также включаемые (include) и требуемые (require) файлы.
Короче, локальная область видимости генерируется только при объяве функции внутри ее тела.
А в твоем случае область видимости одна.
Локальная переменная видна внутри всей функции с момента создания. Блоки вроде if/while не ограничивают ее видимость.
Для разделения есть неймспейсы. Include и require ныне напрямую почти не используют.
есть ссылка типа <a href="add2basket.php/?id=<?= $item['id']?>"> В корзину</a> где$item['id'] это номер товара, но на странице куда должно передаваться нихуя не передается, как правильно то?
сорян братья, заработало, почему то как только напишу в тред все сразу сам решаю, чудеса
>>06284
> Может, хотя бы, получиться поддерживать старые браузеры. Нужно проводить тесты.
Для старых браузеров (если хочется поизвращаться) есть такие возможности хранения данных:
- document.cookie (ограничение порядка 2-4 Кб, только текст). Минус - куки будут отправляться на сервер при каждом запросе, что не очень безопасно. Также, пользователь может их очистить. Плюс - работает вообще везде, включая IE6 или Firefox 1.
- flash shared object - можно через флеш-приложение хранить данные в хранилище флеша. Доки по флешу (еле нашел такую древность) https://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7d80.html . Минус - нужен Adobe Flash. Но в старом браузере он скорее всего есть. Готовая JS библиотека для взаимодействия: https://github.com/nfriedly/Javascript-Flash-Cookies
Библиотека, которая поддерживает хранилища, о которых я даже не слышал (вроде userdata behaviour для IE 5.5+)
Еще статья по теме: https://developer.mozilla.org/ru/docs/Web/Guide/API/DOM/Storage
> Поэтому для express'а нет никакого смысла ставить обработчик на каждый роут. Как можно заметить роут для '/' и для '/somewhere' имеет абсолютно идентичный код. Так может для рендеринга просто поставить обработчик с регулярным выражением для всех роутов '/.*', а сверху перезаписать отдельные для POST (если такие потребуются) и для API?
Это схема, когда при HTTP-запросе сервер express рендерит HTML-страницу, отдает, и дальше клиент (если включен яваскрипт) на реакте инициализируется и прикрепляется к этой странице? Тогда да, можно поставить роут на звездочку. Только надо проверить, что он будет корректно отдавать код 404 для несуществующих страниц.
> Дизассемблированный код пихается в блок div у которого overflow-y: scroll
> Каждая строчка это div в котором ещё 5 дивов. Адрес, мнемоника и аргументы
Создавать 4 000 дивов - это плохая идея, будет тормозить. Надо либо использовать канвас, либо убирать невидимые /добавлять видимые дивы при прокрутке, либо просто вставлять текстом, а полоску сделать отдельным дивом.
> Это я нашёл. Но как вычислять чему этот scrollTop равен к примеру для 4 строчке.
Если высота одной строки известна, и нет переносов строк, то это не сложно.
> Главная функция эмулятора дёргается каждые 16мс. Если с таким интервалом менть css свойства браузер нормально будет отрабатывать?
Надо тестировать, но думаю, что не очень. Это будет отнимать больше времени, чем сама эмуляция. Перерисовка DOM - это ведь сложный процесс, там много тонкостей и сложностей. Тут можно было бы использовать канвас и самому вычислять, что надо перерисовать, но еще лучше будет снизить частоту обновления. Какой смысл обновлять код с такой скоростью, если человек не способен его читать? Я бы вообще отключил обновление кода во время выполнения.
В инструментах разработчика в браузере есть средство для профилирования кода - ты можешь сделать прототип и протестировать.
Также, если ты пишешь на JS, обрати внимание на WebAssembly. Это позволяет писать програмы на ассемблере (естественно, не руками, а используя высокоуровневый язык и компилятор). Это позволит достичь максимально возможной скорости эмуляции, быстрее чем JS.
Вот тут описан довольно простой способ сделать REST API на Yii, не подойдет? http://developer.uz/blog/restful-api-in-yii2/
>>07386
Неплохо, но выражение $creditItogo*$percent+$commision повторяется аж 3 раза, а можно без повторений сделать?
> $openSchetHomo=0;
> $percentHomo=1.04;
> $commisionHomo=500;
> $HomoCredit=calcIpadPrice($depositt,$paymentt,$percentHomo,$commisionHomo,$openSchetHomo);
Тут можно было не создавать переменные, а писать ... = calcIpadPrice($deposit, $payment, 1.04, 500, 0);
>>07732
MariaDb - это форк (ответвление) от MySQL, на 99% там все одинаково. Чем отличается, написано в Гугле: https://mariadb.com/kb/ru/mariadb-vs-mysql-features/
>>05368 (OP)
ПЕРЕКАТ
>>05368 (OP)
ПЕРЕКАТ
>>05368 (OP)
ПЕРЕКАТ
>>05368 (OP)
ПЕРЕКАТ
>>05368 (OP)
ПЕРЕКАТ
>>05368 (OP)
Туда барыжки загружают прайс листы, номенкалатуры,категори товаров, приходят чеки с онлаин касс и т.д
Нужно реализовать функционал СКИДОК на товар/категорию товаров/все товары. Но загвоздка вот в чем: СКИДКА ДОЛЖНА БЫТЬ ВРЕМЕННАЯ. Барыжка заходит в crm-> выбирает категорию пивко-> ставит скидку 5%-> Время валидности скидки 48 часов.
Цены хранятся в MySQL. Сделать доп. колонку time_sail и чекать каждый раз валидна ли скидка? Может есть более гибкое решение?
Для этого тред и создан
Рекурсивно
Двачую. Только я еще и на тостер свои говновопросы задаю, и почти сразу же, после того, как запощу и вдумчиво перечитаю свой вопрос, то в голову влетает идея, я ее пробую, и все начинает работать.
Очень плохое решение.
>и вдумчиво перечитаю свой вопрос
Я могу ебланиться несколько часов, а потом решусь где-то спросить. Начинаю писать вопрос и пока его составляю - обнаруживаю ошибку
Проекты, написанные до официального релиза 7.0 пока не решаются переходить на версии выше в силу сам понимаешь каких причин. Обратная совместимость и банальная лень - работает, и заебись. Поэтому 5.6 до сих пор обновляют и поддерживают.
Ну а если ты аццкий прогер на пхп, то юзай ту версию, какую хочешь. Большинству людей хватит 7.0. Если ты уже матерый прогмик, которому скучно писать на одной и той же версии каждый проект, то обновляйся, хули.
>пока не решаются переходить на версии выше в силу сам понимаешь каких причин. Обратная совместимость и банальная лень - работает, и заебись. Поэтому 5.6 до сих пор обновляют и поддерживают.
>Ну а если ты аццкий прогер на пхп, то юзай ту версию, какую хочешь. Большинству людей хватит 7.0. Если ты уже матерый прогмик, которому скучно писать на одной и той же версии каждый проект, то обновляйся, хули.
я не про это немного, а про фактическое обновление кем-либо из анонов. у нас на главноем проекте 7.1 и обновлять его на даже 7.2 никто просто так не даст.
я к тому что аноны писали, что 7.3 сегфолтится, интересуюсь поправили ли это. ну и захотелось попасть в прон-тред
>Поэтому 5.6 до сих пор обновляют и поддерживают
и кстати я тебя разочарую, бро
https://secure.php.net/supported-versions.php
5.6 уже два года не обновляют и с январая даже секьюрити апдейты не пилят. но ты не переживай, пхп-тред и создан для того, чтобы учиться новому
>проекте 7.1 и обновлять его на даже 7.2 никто просто так не даст
Почему? Он же стейбл. Я на следующей неделе буду древний кусок говна с 5.6 на 7.2 сразу переводить.
Не понял, а почему тогда я частенько вижу, когда захожу на php.net, наверху страницы, PHP 5.6.* Released!
К слову, если я пишу проект на пых-пых 7.0, а на серваке будет 7.3, код ведь будет работать?
Без понятия, 7.3 еще не пробовал. 7.2 у меня везде работал нормально, где был 7.0, но тоже не факт, что мне просто не повезло.
https://pastebin.com/xVatJU99 - форма и код.
Как исправить ошибку (или безграмотность, или и то, и другое)?
>зависит от количества кода и возраста проекта
Ну, там проект 5+ лет на херовой технологии. Посмотрим, что получится. Если что отпишусь.
Точнее, соединять.
поставил, 0 эмоций.
INSERT INTO `test` . `user`(user_name, e_mail) VALUES ($name, $email);
В sql запрос проходит, только вместо переменных строчные данные, заключенные в кавычки ' ' .
С переменными кавычки не прокатывают.
Зачем мне создавать объекты если я всегда могу обращаться к ним статически?
К классам, в смысле
Щас представил как купил утку и начал с ней разговаривать и задавать ей вопросы, интересно что обо мне подумают другие лол?
У меня был знакомый который утку с собой таскал, теперь я понял что он имел ввиду под фразой Думай о желтой резиновой утке и он говорил это в критические ситуации когда нужно отвлечься.
А зачем пробелы убирать? Это типа как в питоне работает?
Ты не правильно расположил аргументы в mysqli, лол.
Cначала идет хост, потом юзер с паролем, потом только база в конце.
Алсо, если у тебя в $user записано 'test', то и обращайся к тесту.
Или блять подставляй переменную вместо юзера.
А ОП пизданутый на всю башку идиот. Нахуя писать в ОП-посте, что пых простой? Вот поэтому у треда и репутация такая хуевая, и сидят тут одни вкатывальщики. Ну это блять анекдот натуральный. Собрал армию новичков, накидал для них задачек и сидит вечером после работы проверяет. Тебе делать нехуй? Найди себе девушку. Нормальным проггерам уже не продохнуть от количества людей, которые не могут прочесть матчасть или хотя бы установить IDE, которая все сделает за них.
На яркую жизнь php программистам хватает?
if (mysqli_connect_errno()) {
echo 'Что-то пошло не так... ' . 'Ошибка ' . mysqli_connect_errno() .
'. ' . mysqli_connect_error();
exit();
}
Вставь код после подключения к базе и посмотри, какую ошибку выводит.
Иди нахуй отсюда, сука.
Вполне. Если ты не обезьянка, то на хорошую зп тебя с руками отрывают.
Значит, подключился. У тебя неправильно сформировать SQL.
Надо так:
Insert into user (user_name, e_mail) values ($name, $email)
И точку с запятой убери после запроса перед закрывающей кавычкой, ее там не должно быть.
Test у тебя есть уже в первом аргументе, зачем его передавать снова через точку, ты вообще читал что-нибудь про этот метод, или от пизды пишешь?
бля, зашел на стак и увидел такую конструкцию в запросе при желании вставить переменную.
Оказалась рабочей, лол.
VALUES (' ".$name." ', ' ".$email." ')
А, ну да, точняк. Переменные нельзя напрямую вставлять в запрос, их надо сначала привести к строке.
Когда у тебя самого возникают проблемы с кодом, не работает одно выражение, и ты сидишь и думаешь над ней 4-5 часов, то потом решение само появляется. И ты уже автоматически видишь эти косяки у других.
Понятие объекта и класса немного разные. Объект это то, чем можно оперировать - положить куда-то, потом вернуть. А статический класс он как памятник - хер что с ним сделаешь. По сути это просто глобальная функция.
Ой, забыл тебе ответить.
Лично я все системные функции в своей стандартной библиотеке делаю статическими. То есть все, что должно что-то принять, обработать и вернуть я всегда делаю статическим.
А вот если нужно сделать много экземпляров чего-то, к примеру, много постов, товаров, категорий сделать, которые в свою очередь наследуются от абстрактов и интерфейсов, то тут объекты лучше использовать.
Конечно, можно полностью весь сайт сделать со статическим кодом на счетчиках, но это уже не ООП подход, а что-то из разряда лямбда-исчислений, которые постепенно вытесняют ООП. Но это всего лишь мои философствования. В любом случае, каждый пишет так, как он хочет.
>из разряда лямбда-исчислений, которые постепенно вытесняют ООП
Много ты коммерческого софта на том же Хаскеле видел? А теперь с одним лишь пхп сравни масштабы. Обычная хипстерская болтовня короче.
Хуево ты ООП выучил. Памятник это абстрактный класс, методы которого нельзя вызывать динамически. И экземпляр которого создать тоже нельзя. Статический класс (это класс, в котором нет ни одного не статического метода и свойства) в пыхе можно заэкземплярить и вызывать его методы динамически.
Кстати, очень хуевая реализация ООП в пыхе уже не раз критиковалась многими людьми, писали письма с просьбами исправить эту хуйню, но пока они только попивают коктейли на очередных конференциях.
То есть статический класс в пыхе это нихуя не памятник, он может сохранять в своих свойствах значения. Это его и отличает от обычного класса со своими объектами.
Да причем тут блять твой Хаскель. Я тебе не про реализацию говорю на конкретном языке, а про сам подход. ООП и лямбда это два разных подхода к одной и той же задаче - писать программы.
>доебался до неудачного сравнения
>указал на мутный костыль, который сам же и обосрал
Ну ты и говно.
Список коммерческого софта в студию. Пока что я вижу, что одни фанатики с этой хуйнёй носятся, а выхлоп околонулевой.
Ну или оставайтесь. Сами же знаете правила.
>а какие задачи решаешь с прмощью pthreads?
Многопоточный постинг в несколько соц-сетей с нескольких аккаунтов
Честно говоря, не совсем тебя понял.
Просто я пишу платформу и пришел к тому, что у меня объектами являются только какие-нибудь йоба-интерфейсы во фронте, которые связывают все остальные классы. Большинство - статика, в которых классы больше служат для разделения по функциональным группам и понятного чтения кода проекта. По сути объектом у меня является только маршрутизатор и страница, которая уже обращается к статическим методам и генерирует себя в зависимости от запроса. И пока писал это все задался вопросом - а какой толк то, собственно, от этих объектов? Я код пытался строить таким образом, чтобы можно было модернизировать каждый модуль по отдельности (без некоторых он даже работать будет, просто ругаться начнет) и чтобы все это было максимально читаемо, и вроде это и есть принцип ооп. Не знаю. Извиняюсь за такой глупый вопрос, но рил хочтся знать. Просто какой толк от объекта, если в конце построения страницы пыха сама себя убьет?
А, и еще пару вопросов сразу, скажите плз где взять норм инфу по паттернам. А то я тока MVC освоил, а остальное не понимаю как применить в своем коде, но задачу себе поставил не по уровню и знаний временами явно не хватает. И когда можно на работу подаваться, а то заебался в магазине батрачить? Хочется сменить сферу
задавал этот вопрос пьяный, потом пил еще 2 недели, в процессе написал себе кучу полезного софта (работающего) по старым принципам "никто не увидит, хуячь все в один файл и нахуй форматирование, ООП тоже нахуй".
Итоги: говнософт работает, в офис меня не возьмут (потому что я тупой и не смогу переучиться), самооценка упала еще ниже.
Сейчас почитаю скудные ответы, приятно что их 5 штук (думал, будет ноль). Спасибо, ребята, хотя и подозреваю что там ничего хорошего в ответах нету.
>Ты не напишешь ни одного более-менее толкового приложения меньше 1к строк. С нуля в смысле - без васянских либ. Но для школоскриптиков в 100 строчек это и правда - нахуй не надо. Тут ты прав.
Толковое приложение - это инстаграм или вакаба? Какая мне нахуй разница, сколько в проекте строк и как оно запускается, если оно быстро работает, не падает и делает свою работу? Я же не хайлоад пишу в 100500 рпс (как остальные в этом треде).
Я так понимаю, ты ОП этих тредов.
Спасибо за твой титанический труд, ты охуенен.
>Видимо ты не понял идею разбиения кода на функции. Суть в том, что длинный кусок кода, который делает несколько вещей, сложно понять. Его сложно править, в нем много переменных, и можно нечаянно что-то сломать. Ну и физически прочитать 1000 или 10 000 строк кода быстро невозможно. Поэтому код разбивают на отдельные действия и выносят эти действия в функции. Так, что мы можем вместо огромной портянки кода читать только небольшую функцию, которая нас интересует.
Разумеется, отдельные действия я выношу в отдельные функции, но зачем мне надо устраивать ООП и выносить простой код в 100500 файлов, где хуй потом разберешь что и где.
Я ПОНИМАЮ, что ты работаешь в команде, очевидно, где все погромисты должны читать код друг друга и тд, но я ведь один! Зачем мне самому устраивать в своей инфраструктуре хаос?
>То есть ты должен в идеале каждую функцию так описать.
Зачем мне ее описывать, если никто ее не увидит? Хороший тон?
>Насчет "нужно" - конечно, нужно, как другой человек будет разбирать твой код?
Я это и пытаюсь понять. Все преимущества твоих правил и рекомендаций - созданы для работы в коллективе. Если коллектива нет - эти правила нахуй не нужны, выходит. В последние дни я заметил что больше времени уделяю форматированию кода, чем собственно написанию, а большинство усилий должно уходить на алгоритмы.
И без обид, но я осмелюсь предположить - вам там про алгоритмы думать не сильно надо, надо сидеть и хуячить код. Грубо звучит, но все мои знакомые программисты так и работают.
>Не хочешь исследовать причины проблемы и исправить её?
Разумеется не хочу. Что npm, что composer - лютый пиздец. Сначала мы создаем проблему, а затем героически ее решаем костылями (безуспешно).
>Или, может, кто-то из анонов хочет помочь улучшить композер?
Сначала написал: "Убить разработчика?", но потом подумал, что и правда было бы интересно потрейсить, что там жрет 1гб озу. Попробую разобраться на днях, если не протрезвею.
Но смотри, куча народа со мной согласна https://github.com/composer/composer/issues/1898 (что характерно, они пишут про Это в 2013 году, а я в 2019, и ничего не изменилось! За 5, сука, лет).
>Yep, same here - have to increase memory limit to 1G. And indeed it eats up to 980M.
Гигабайт! Что оно делает с ним, грузит все в память одним куском, все скачанные пакеты?
>Для начала, ты бы мог дать пример composer.json и написать, что сделать, чтобы отъесть столько памяти.
https://gitlab.com/edgyemma/Postmill
inb4: написал composer update и ничего не жрет!
и не хочу портить ОП-у тред, но как ты объяснишь это?
https://stackoverflow.com/questions/33299302/composer-update-failed-out-of-memory
> Какая мне нахуй разница, сколько в проекте строк и как оно запускается, если оно быстро работает
Хочу объяснить этот момент.
Все люди, кто рассказывал мне про правильный код, синтаксис и хуё-моё - были максимум разработчиками сайтов визиток или кривых магазинов где даже 1 rps нет, зато у них композер, грунт, докер и красивое форматирование.
Когда пытаешься с ними обсудить свои текущие задачи ("ты ж девелопер, подскажи ебана"), впадают в ступор.
Я на 100% уверен, что все что я писал выше - бред нуба, но это настолько заебало, что пришел сюда выговориться. Извините за крик души, и удалите если посчитаете нужным.
ОПу респект, материалы хорошо написаны и читать интересно.
Или наоборот, когда ты уже решил для кого то проблему и она для тебя никогда не возникнет в будущем.
>Какая мне нахуй разница, сколько в проекте строк и как оно запускается, если оно быстро работает, не падает и делает свою работу?
Это заказчику похуй, а не разработчику - это твоё дело. Тебе похуй пока ничего более-менее большого не писал, да и разрабатывать удобно - работаешь с отдельным модулем, а не всю простыню правишь в пяти разных местах а потом всё падает потому, что ещё в трёх пропустил и надо искать полдня дырку в логике, в файле на 1.5к строк. П - продуктивность..
>>30538
>хуй потом разберешь что и где
>устраивать в своей инфраструктуре хаос
У тебя уровень проганья низковат для правильной оценки рекомендация PSR. Как начнёшь писать, как все нормальные кодеры пишут, так оценишь. Я тоже не сразу въехал во всё это, а теперь только так и делают. + ты начинаешь понимать что пишут другие, и другие тебя понимают. Но это уже промышленные стандарты.
И как понял что конкретно в php.ini ему не нравится
Выглядит это так (и с версией 56 стартует):
service apache24 start
Performing sanity check on apache24 configuration:
Syntax OK
Starting apache24.
kernel: pid 1902 (httpd), uid 0: exited on signal 11 (core dumped)
apachectl configtest
Performing sanity check on apache24 configuration:
Syntax OK
php -v
PHP 7.2.14 (cli) (built: Jan 15 2019 01:14:39) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.14, Copyright (c) 1999-2018, by Zend Technologies
ls -la /usr/local/libexec/apache24/
total 8524
drwxr-xr-x 2 www www 4608 Jan 20 00:16 .
drwxr-xr-x 10 root wheel 1024 Jan 20 00:36 ..
-rwxr-xr-x 1 www www 15727 Jan 19 21:13 httpd.exp
-rwxr-xr-x 1 www www 4976672 Jan 15 04:15 libphp7.so
И как понял что конкретно в php.ini ему не нравится
Выглядит это так (и с версией 56 стартует):
service apache24 start
Performing sanity check on apache24 configuration:
Syntax OK
Starting apache24.
kernel: pid 1902 (httpd), uid 0: exited on signal 11 (core dumped)
apachectl configtest
Performing sanity check on apache24 configuration:
Syntax OK
php -v
PHP 7.2.14 (cli) (built: Jan 15 2019 01:14:39) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
with Zend OPcache v7.2.14, Copyright (c) 1999-2018, by Zend Technologies
ls -la /usr/local/libexec/apache24/
total 8524
drwxr-xr-x 2 www www 4608 Jan 20 00:16 .
drwxr-xr-x 10 root wheel 1024 Jan 20 00:36 ..
-rwxr-xr-x 1 www www 15727 Jan 19 21:13 httpd.exp
-rwxr-xr-x 1 www www 4976672 Jan 15 04:15 libphp7.so
удалил расширения из /usr/local/etc/php
заработало, глючное расширение пока не нашёл, но думаю, что победил проблему
Работает всё, но меня смущает одно.
Смотрите.
echo "У анона выпало {$anonDice1} и {$anonDice2}\nУ компьютера {$compDice1} и {$compDice2}\n";
Зачем здесь нужны скобки у переменных? Если их убрать, то ничего не меняется.
Просто в уроке о переменных, когда через echo они выводились, там скобок не ставили.
То есть, если освоить MVC и делать проекты при помощи своего или стороннего фреймворка, то ты уже автоматически становишься лучше большинства?
>Зачем здесь нужны скобки у переменных? Если их убрать, то ничего не меняется.
Так не должно работать. У тебя какая версия пхп?
А, отбой вопроса, я спутал с другим языком. Просто ОП считает, что ставить вокруг переменной это правило хорошего тона.
Потому что если тебе нужно будет написать вот так:
"Хуй$pizdaджигурда ", то такая конструкция не отработает, потому что интерпретатор поймет, что есть некая переменная $pizdaджигурда, которой на самом деле нет.
Просто многие решения, особенно в e-commerce, растут еще из очень темных времен уровня php 4, а может и раньше. По инерции это легаси до сих пор существует, т.к. все еще остается рабочим. Есть подвижки к развитию, но это не слишком быстро движется. Ну а что-то новое нормальный разраб не станет делать по лет на 10 устаревшим подходам.
Фреймворки вообще не нужны, если ты не знаешь, как написать без них. Но с другой стороны, ты и не узнаешь, пока не поковыряешься с одним из них. Такое вот колесо сансары.
Я писал без них и с ними чуток для своих супер мелких проектов. Но на вопрос ответь плиз.
Шло время начали придумываться варианты для адаптивной верстки, так как разрешение экранов начало расти от 1024 до 1920 и все понимали, что прописывать маржины для каждого разрешения это не вариант и появился флоат, который дал возможность адаптивно верстать немного закрывая глаза на разрешение. И если ты входил в режим флоат, то добавляли в конце всех блоков ещё 1 с пустым содержанием, но с clear : both. Т.е. обнуление флоата. Затем прошло еще время. Страницы начали расти в объемах и кол-во этих пустых блоков тоже стало расти. И решили что можно сделать класс с ::after, который позволит избежать постоянного создания блока. И стали писать content : "." и там же следующей строчкой делать её невидимой. Ну и уже еще через какое-то время все пришло к пустой строке.
видосы зинченко. За два часа отлично поясняет как работает паттерн. Мозги на место становятся (при наличии оных). Лично я начал писать что то реально стоящее только после его объяснения.
Попробую, спасибо. А еще что то посоветуете? Кроме шапки? В свое время лучшим толчком мне были первые два видео зинченко и задачи из шапки. Причем это работало так, что основы я узнал из примерно половины текста шапки, после чего мне это все стало казаться ве глупым, и двух видео зинченко, после которых, опять же, мне все начало пахнуть говном. Просто подчерпнул свое и пиздец
> На вашем счету семьдесят миллионов_____восемь (70000008) рублей
Что-то пробелов дофига. Надо пропускать такие части числа, если они равны нулю.
> function getWordForm ($threeDigit, $selectName)
Можно было просто передавать сюда все формы слова и получилась бы универсальная функция, которая может выбирать любое слово. А то с номером получается, что это не отдельная функция, а продолжение функции spellNumber, в которой есть счетчик от 0 до 3.
Плюс, у тебюя слишком большая вложенность if. Вместо этого:
if (условие) {
много кода
} else {
return ...;
}
Лучше писать
if(!условие) {
return ...
}
много кода...
В остальном, сделано неплохо.
По калькулятору: сделано верно.
> кроме как условиями, возможно реализовать выполнение действий?
Нет, надо делать через if/elseif.
>>19485
> if($arrayRand == $arrayRand)
Ты сравниваешь переменную саму с собой. Естественно, значения будут равны. Чтобы выдавать предупреждение, надо либо сохранять в отдельной переменной предыдущее значение, либо вообще сделать массив и сохранять там все выпавшие ранее значения.
> На вашем счету семьдесят миллионов_____восемь (70000008) рублей
Что-то пробелов дофига. Надо пропускать такие части числа, если они равны нулю.
> function getWordForm ($threeDigit, $selectName)
Можно было просто передавать сюда все формы слова и получилась бы универсальная функция, которая может выбирать любое слово. А то с номером получается, что это не отдельная функция, а продолжение функции spellNumber, в которой есть счетчик от 0 до 3.
Плюс, у тебюя слишком большая вложенность if. Вместо этого:
if (условие) {
много кода
} else {
return ...;
}
Лучше писать
if(!условие) {
return ...
}
много кода...
В остальном, сделано неплохо.
По калькулятору: сделано верно.
> кроме как условиями, возможно реализовать выполнение действий?
Нет, надо делать через if/elseif.
>>19485
> if($arrayRand == $arrayRand)
Ты сравниваешь переменную саму с собой. Естественно, значения будут равны. Чтобы выдавать предупреждение, надо либо сохранять в отдельной переменной предыдущее значение, либо вообще сделать массив и сохранять там все выпавшие ранее значения.
> вот тут в условиях задачи про игру в кубики было сказано только про дубли, но одинаковая сумма может выпасть и при разных числах, правильно ли решена задача?
Да, правильно. Если одинаковая сумма при разных числах, то это просто ничья.
>>20461
Вполне допустимое решение, только в echo получилось слишком сложное выражение и стоило бы получение случайных слов вынести в отдельные переменные.
>>20625
> Как мне заставить регулярку искать только 10 цифр, а кол-во других символов не имеет значения?
Пишешь регулярку, которая ищет ровно 1 цифру, а за ней любое число других символов: xxx (напиши ее сам).
А затем пишешь, что это повторяется 10 раз: (xxx){10} . Круглые скобки значат, что {10} применено ко всему выражению.
> Пиши верно https://3v4l.org/UaM8i
> (?<=[.!?])+
Я думаю, + тут бессмысленнен, так как утверждения не поглощают символы при совпадении и не смещают позицию в строке и повторная применяется к тому же месту строки. То есть, выражение вида (?<=!){2} ищет один восклицательный знак (просто проверяет его наличие 2 раза), а не два: https://repl.it/repls/NaturalCalculatingProtocols
Чтобы искать 2 воскл. знака, надо писать {2} внутри утверждения.
Более того, плюс у тебя не очень и нужен, так как одной точки достаточно для
определения границы предложения.
А так, решено верно.
> Yoda Speak https://3v4l.org/coKeP
> /[.|!|?|;]
В квадратных скобках | обозначает символ вертикальной черты, а не "один из вариантов". Надо писать [.!?;].
В остальном, верно.
> Сумма прописью https://3v4l.org/NSeMe
> if (floor($number / 1000000) >= 1) {
Лучше if ($number >= 1000000)
> На вашем счету{$text1}
Лучше бы функция возвращала фразу без лишнего пробела в начале.
А так, верно.
> Калькулятор https://3v4l.org/n6fuv
> [+]|[-]|[=]
Можно просто [+-=...]
> [0-9]+[.]*
Надо [.]?
При наличии пробелов в строке считает неверно, хотя без них все правильно.
> Пиши верно https://3v4l.org/UaM8i
> (?<=[.!?])+
Я думаю, + тут бессмысленнен, так как утверждения не поглощают символы при совпадении и не смещают позицию в строке и повторная применяется к тому же месту строки. То есть, выражение вида (?<=!){2} ищет один восклицательный знак (просто проверяет его наличие 2 раза), а не два: https://repl.it/repls/NaturalCalculatingProtocols
Чтобы искать 2 воскл. знака, надо писать {2} внутри утверждения.
Более того, плюс у тебя не очень и нужен, так как одной точки достаточно для
определения границы предложения.
А так, решено верно.
> Yoda Speak https://3v4l.org/coKeP
> /[.|!|?|;]
В квадратных скобках | обозначает символ вертикальной черты, а не "один из вариантов". Надо писать [.!?;].
В остальном, верно.
> Сумма прописью https://3v4l.org/NSeMe
> if (floor($number / 1000000) >= 1) {
Лучше if ($number >= 1000000)
> На вашем счету{$text1}
Лучше бы функция возвращала фразу без лишнего пробела в начале.
А так, верно.
> Калькулятор https://3v4l.org/n6fuv
> [+]|[-]|[=]
Можно просто [+-=...]
> [0-9]+[.]*
Надо [.]?
При наличии пробелов в строке считает неверно, хотя без них все правильно.
label нужно указать при создании формы (читай мануал). Если ты сам хочешь выводить label, то надо либо отключить встроенный, либо самому выводить весь виджет, кроме label (то есть свой label, потом form_widget, потом область ошибок).
>>27398
Твой код может кто-то увидеть и скопировать. Нет, примеры кода должны быть безопасными.
>>27488
Плохой. Так как ты не решаешь конфликты. Банальный пример: сейчас в файле цифра 100. Первый скрипт запускается, читает "100". Параллельно работающий скрипт тоже читает 100. Первый меняет на 101. второй тоже. Один просмотр потерян. Еще хуже, если файл большой и 2 параллельно работающих скрипта перезапишут его одновременно, так что получится смесь из 2 кусков.
Используй sqlite - она тоже хранит данные в файле, только правильно и с блокировками.
>>27846
6 http://jsfiddle.net/4Ld60kht/ - думаю поля можно было через паддинг родителя, но я сделал так.
Ок, верно. Паддинг удобнее, если ты например захочешь фон добавить.
7 http://jsfiddle.net/avu90q3w/
Правильно.
8 http://jsfiddle.net/pvk2rf9a/ - не понял как тут применить отрицательный маргин и не уверен что * хорошо указывать
> p, ul, ol, h1, h2, h3, h4, h5, h6, img {
> margin-left: 110px;
Это, на мой взгляд, плохая идея и правильнее тут поставить padding на article. А то твое правило не применится к тексту без тегов.
> aside + * {
Это не очень праивльно, ты так можешь сбросить нужный оступ у абзаца (если он идет после aside), например. Зачем вообще это правило? На случай, когда в начале текста идет aside, а за ним p?
> article > *:first-child {
Это не очень правильно. Может, там вначале такой элемент, которому надо добавить маргин. Лучше явно указать, к каким тегами применено правило и сделать article > p:first-of-type
Вообще, если тебе не нравится лишний отступ сверху у первого абзаца/заголовка, надо придумать способ получше. Мне пришла в голову такая мысль:
- заменяем паддинг вверху article на див нулевой высоты с margin-bottom: 10px
- этот маргин будет коллапсировать с маргин-топ идущего далее элемента
- если у идущего далее элемента нет маргин-топ (например, картинка), то отступ все равно будет
Не хочешь проверить эту идею и поискать, есть ли у нее недостатки? Интересно, это я придумал или до меня уже кто-то?
label нужно указать при создании формы (читай мануал). Если ты сам хочешь выводить label, то надо либо отключить встроенный, либо самому выводить весь виджет, кроме label (то есть свой label, потом form_widget, потом область ошибок).
>>27398
Твой код может кто-то увидеть и скопировать. Нет, примеры кода должны быть безопасными.
>>27488
Плохой. Так как ты не решаешь конфликты. Банальный пример: сейчас в файле цифра 100. Первый скрипт запускается, читает "100". Параллельно работающий скрипт тоже читает 100. Первый меняет на 101. второй тоже. Один просмотр потерян. Еще хуже, если файл большой и 2 параллельно работающих скрипта перезапишут его одновременно, так что получится смесь из 2 кусков.
Используй sqlite - она тоже хранит данные в файле, только правильно и с блокировками.
>>27846
6 http://jsfiddle.net/4Ld60kht/ - думаю поля можно было через паддинг родителя, но я сделал так.
Ок, верно. Паддинг удобнее, если ты например захочешь фон добавить.
7 http://jsfiddle.net/avu90q3w/
Правильно.
8 http://jsfiddle.net/pvk2rf9a/ - не понял как тут применить отрицательный маргин и не уверен что * хорошо указывать
> p, ul, ol, h1, h2, h3, h4, h5, h6, img {
> margin-left: 110px;
Это, на мой взгляд, плохая идея и правильнее тут поставить padding на article. А то твое правило не применится к тексту без тегов.
> aside + * {
Это не очень праивльно, ты так можешь сбросить нужный оступ у абзаца (если он идет после aside), например. Зачем вообще это правило? На случай, когда в начале текста идет aside, а за ним p?
> article > *:first-child {
Это не очень правильно. Может, там вначале такой элемент, которому надо добавить маргин. Лучше явно указать, к каким тегами применено правило и сделать article > p:first-of-type
Вообще, если тебе не нравится лишний отступ сверху у первого абзаца/заголовка, надо придумать способ получше. Мне пришла в голову такая мысль:
- заменяем паддинг вверху article на див нулевой высоты с margin-bottom: 10px
- этот маргин будет коллапсировать с маргин-топ идущего далее элемента
- если у идущего далее элемента нет маргин-топ (например, картинка), то отступ все равно будет
Не хочешь проверить эту идею и поискать, есть ли у нее недостатки? Интересно, это я придумал или до меня уже кто-то?
Это неправильно. Функция должна выполнять одну задачу, а не две. Не надо объединять случайные функции только потому, что они пару раз используются вместе.
>>29885
Внешними утилитами, например в линуксе в командной строке скрипт можно запустить через time:
time php script.php
Также, есть функции microtime(true) и php_memory_get_usage(true) (или как-то так), которые позволяют мерять это внутри скрипта.
Также, можно с помощью Apache Benchmark или siege проверить, какую нагрузку выдерживает скрипт.
>>29928
Да, хранить дату окончания в БД.
>>30173
Ты данные экранируешь перед вставкой хоть?
Выучи сначала наизусть урок про SQL инъекции, а то взломают: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
Также, true это не строка, а булево значение и пишется без кавычек. Погугли про булевы значения.
При сравнении надо писать ==, а не =.
Далее, любой вызов mysqli может вернуть false при ошибке и ты должен проверять, и выводить сообщение с подробностями в этом случае. Тогда бы ты увидел причину ошибки, а сейчас ты вслепую отлаживаешь, что довольно глупо. Вот пример обработки ошибок: http://php.net/manual/ru/mysqli.quickstart.statements.php
Естественно, на продакшене ошибки должны идти в лог, а не на экран.
Если тебе надоело писать if после каждого вызова, то освой исключения и mysqli_report: http://php.net/manual/ru/mysqli-driver.report-mode.php
>>30181
>>30418
Ответный вопрос: зачем тебе нужны классы со статическими методами, если их можно заменить просто на набор функций? Зачем ты их вообще пишешь?
При статических методах у тебя появляется глобальное состояние, и вызываемые им побочные эффекты. То есть ты вызвал одну функцию, она поменяла какое-то статическое поле и это повлияет на результат вызова другой функции. Ты не можешь создать 2 экземпляра класса с разными настройками. Ты не можешь для тестирования создать объект, попользоваться и выкинуть, и у тебя тесты будут влиять один на другой. В общем, все будет плохо.
Плюс, ты не сможешь использовать DI и все классы будут жестко связаны друг с другом.
Ну и данные ведь все равно надо где-то хранить. Ты скорее всего хранишь и передаешь там массивы, а это делает код непонятным, нечитаемым и неподдерживаемым. Простой пример: тебе надо исправить баг в функции, а у нее такой код:
function registerUser(array $user)...
Вопрос: как ты определишь, какие поля в $user, какого типа, что они значат? В случае с объектами ты бы мог посмотреть код класса:
function registerUserWithOOP(User $user)
А так - не можешь. Надо разбирать весь код, тратить много времени, легко допустить ошибку. И в итоге может оказаться, что в одном случае там передается массив одного вида, а в другом - другого, и тебе надо еще и это исправлять. Массивы не типизированы, в них можно записать что угодно и ошибки выдано не будет.
ООП же позволяет документировать и описывать структуру данных, использовать инкапсуляцию для упрощения понимания кода и защиты от ошибок.
У тебя не ООП код, а код на массивах и функциях, в котором иногда для видимости добавлено слово class. Если ты хочешь изучить ООП, попробуй решить задачу про ООП-Гостиницу или ООП-будильник:
- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
Без ООП там будет довольно плохой код.
Выучи сначала наизусть урок про SQL инъекции, а то взломают: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
Также, true это не строка, а булево значение и пишется без кавычек. Погугли про булевы значения.
При сравнении надо писать ==, а не =.
Далее, любой вызов mysqli может вернуть false при ошибке и ты должен проверять, и выводить сообщение с подробностями в этом случае. Тогда бы ты увидел причину ошибки, а сейчас ты вслепую отлаживаешь, что довольно глупо. Вот пример обработки ошибок: http://php.net/manual/ru/mysqli.quickstart.statements.php
Естественно, на продакшене ошибки должны идти в лог, а не на экран.
Если тебе надоело писать if после каждого вызова, то освой исключения и mysqli_report: http://php.net/manual/ru/mysqli-driver.report-mode.php
>>30181
>>30418
Ответный вопрос: зачем тебе нужны классы со статическими методами, если их можно заменить просто на набор функций? Зачем ты их вообще пишешь?
При статических методах у тебя появляется глобальное состояние, и вызываемые им побочные эффекты. То есть ты вызвал одну функцию, она поменяла какое-то статическое поле и это повлияет на результат вызова другой функции. Ты не можешь создать 2 экземпляра класса с разными настройками. Ты не можешь для тестирования создать объект, попользоваться и выкинуть, и у тебя тесты будут влиять один на другой. В общем, все будет плохо.
Плюс, ты не сможешь использовать DI и все классы будут жестко связаны друг с другом.
Ну и данные ведь все равно надо где-то хранить. Ты скорее всего хранишь и передаешь там массивы, а это делает код непонятным, нечитаемым и неподдерживаемым. Простой пример: тебе надо исправить баг в функции, а у нее такой код:
function registerUser(array $user)...
Вопрос: как ты определишь, какие поля в $user, какого типа, что они значат? В случае с объектами ты бы мог посмотреть код класса:
function registerUserWithOOP(User $user)
А так - не можешь. Надо разбирать весь код, тратить много времени, легко допустить ошибку. И в итоге может оказаться, что в одном случае там передается массив одного вида, а в другом - другого, и тебе надо еще и это исправлять. Массивы не типизированы, в них можно записать что угодно и ошибки выдано не будет.
ООП же позволяет документировать и описывать структуру данных, использовать инкапсуляцию для упрощения понимания кода и защиты от ошибок.
У тебя не ООП код, а код на массивах и функциях, в котором иногда для видимости добавлено слово class. Если ты хочешь изучить ООП, попробуй решить задачу про ООП-Гостиницу или ООП-будильник:
- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078
Без ООП там будет довольно плохой код.
Поизучай код Симфони, например Symfony Forms, там есть и примеры ООП, и паттерны.
>>30538
Не хочешь развиваться - не развивайся, дело твое. Я, наоборот, не понимаю, зачем писать плохой код и самому от этого огорчаться. Да еще и ограничивать свою карьеру. Вам нравится меньше денег получать?
> и выносить простой код в 100500 файлов, где хуй потом разберешь что и где.
Если непонятно - значит, это как раз плохо сделано. Вот попробуй ООП-гостиницу или ООП-будильник без ООП решить - получится код хуже.
> вам там про алгоритмы думать не сильно надо
Если ты думаешь про алгоритмы 2 часа и 6 часов пишешь код, то как оформление кода тебе мешает думать?
> В последние дни я заметил что больше времени уделяю форматированию кода
Я вообще не понимаю, откуда здесь трата времени. Я с самого начала пишу код как надо, и не помню, чтобы на это тратилось дополнительное время. Плюс, IDE умеют форматировать код. Нажать пробел или перевод строки - требует одинаковое количество времени.
>>30539
> Сначала мы создаем проблему, а затем героически ее решаем
И как можно "не создавать" проблему зависимостей? Изобретать велосипед и тратить на это лишнее время?
> Что оно делает с ним, грузит все в память одним куском, все скачанные пакеты?
Ну вот выяснил бы.
Поизучай код Симфони, например Symfony Forms, там есть и примеры ООП, и паттерны.
>>30538
Не хочешь развиваться - не развивайся, дело твое. Я, наоборот, не понимаю, зачем писать плохой код и самому от этого огорчаться. Да еще и ограничивать свою карьеру. Вам нравится меньше денег получать?
> и выносить простой код в 100500 файлов, где хуй потом разберешь что и где.
Если непонятно - значит, это как раз плохо сделано. Вот попробуй ООП-гостиницу или ООП-будильник без ООП решить - получится код хуже.
> вам там про алгоритмы думать не сильно надо
Если ты думаешь про алгоритмы 2 часа и 6 часов пишешь код, то как оформление кода тебе мешает думать?
> В последние дни я заметил что больше времени уделяю форматированию кода
Я вообще не понимаю, откуда здесь трата времени. Я с самого начала пишу код как надо, и не помню, чтобы на это тратилось дополнительное время. Плюс, IDE умеют форматировать код. Нажать пробел или перевод строки - требует одинаковое количество времени.
>>30539
> Сначала мы создаем проблему, а затем героически ее решаем
И как можно "не создавать" проблему зависимостей? Изобретать велосипед и тратить на это лишнее время?
> Что оно делает с ним, грузит все в память одним куском, все скачанные пакеты?
Ну вот выяснил бы.
> Все люди, кто рассказывал мне про правильный код, синтаксис и хуё-моё - были максимум разработчиками сайтов визиток или кривых магазинов где даже 1 rps нет, зато у них композер, грунт, докер и красивое форматирование.
Одно к другому отношения не имеет. Как grunt (уже webpack) влияет на производительность PHP кода?
> сайтов визиток или кривых магазинов где даже 1 rps нет
Ты же не маленький и понимаешь, что важно не сколько rps, а сколько проект приносит прибыли (или хотя бы общественной пользы).
>>30663
> Анончики, милые помогите, не запускается apache24 с php72, как можно понять почему он не хочет работать с LoadModule
А там версии совместимые? Ты не пытаешься расширение к старой версии PHP загрузить? Вообще, Signal 11 = SIGSEGV - говорит о баге где-то в коде (не твоем), и может тебе стоит написать баг-репорт разработчикам дистрибутива. Только перед этим проверить, что у тебя актуальные и совместимые версии библиотек.
>>30877
Можно убрать, скобки нужны, если там вплотную идет текст.
>>31333
float придумывался для вставки иллюстраций в текст с обтеканием их текстом. Но оказался удобен и для других применений (рскладки частей страницы), хотя сейчас его будет постепенно вытеснять flexbox.
> Я хотел бы уточнить правильно ли я понял как работает clearfix.
clearfix заставляет контейнер растягиваться, чтобы вместить все флоаты. Свойство clear добавляет элементу margin сверху так, чтобы он оказался ниже всех флоатов в потоке. Спецификация: https://www.w3.org/TR/CSS2/visuren.html#floats
> Все люди, кто рассказывал мне про правильный код, синтаксис и хуё-моё - были максимум разработчиками сайтов визиток или кривых магазинов где даже 1 rps нет, зато у них композер, грунт, докер и красивое форматирование.
Одно к другому отношения не имеет. Как grunt (уже webpack) влияет на производительность PHP кода?
> сайтов визиток или кривых магазинов где даже 1 rps нет
Ты же не маленький и понимаешь, что важно не сколько rps, а сколько проект приносит прибыли (или хотя бы общественной пользы).
>>30663
> Анончики, милые помогите, не запускается apache24 с php72, как можно понять почему он не хочет работать с LoadModule
А там версии совместимые? Ты не пытаешься расширение к старой версии PHP загрузить? Вообще, Signal 11 = SIGSEGV - говорит о баге где-то в коде (не твоем), и может тебе стоит написать баг-репорт разработчикам дистрибутива. Только перед этим проверить, что у тебя актуальные и совместимые версии библиотек.
>>30877
Можно убрать, скобки нужны, если там вплотную идет текст.
>>31333
float придумывался для вставки иллюстраций в текст с обтеканием их текстом. Но оказался удобен и для других применений (рскладки частей страницы), хотя сейчас его будет постепенно вытеснять flexbox.
> Я хотел бы уточнить правильно ли я понял как работает clearfix.
clearfix заставляет контейнер растягиваться, чтобы вместить все флоаты. Свойство clear добавляет элементу margin сверху так, чтобы он оказался ниже всех флоатов в потоке. Спецификация: https://www.w3.org/TR/CSS2/visuren.html#floats
Это копия, сохраненная 22 января 2019 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.