М.Двач / Программирование

Этого треда уже нет.
Это копия, сохраненная 15 июня 2019 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.

Клуб изучающих PHP #109 /php/ 13 апр, 21:41 1380485 В конец треда | Веб

33 Кб, 500x500157 Кб, 1024x683194 Кб, 1024x76887 Кб, 1024x764

Здравствуй, заблудший анон. Заходи. Пока чьи-то ракеты бороздят просторы космоса и даже возвращаются обратно, мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет открыть стартап, кто-то заработать на лапшу быстрого приготовления, кому-то просто нечего делать.

В нашем треде отвечают почти на все вопросы, только бампайте каждые 5 дней. И не разводите флуд, если вам скучно, лучше сходите промочите ноги на улице, например.

Это тред и для начинающих. Слово "классы" у тебя ассоциируется только со школой, а в аттестате тройка по математике? Ты наш человек.

Предыдущий тред был тут: >>1353705 (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? — Да, однозначно. Посмотри любую вакансию.

Ответы381869393255394228394386395490395840396603397380400712413441415504

56 Кб, 500x644
Оформление кода 2 13 апр, 21:44 2 1380488

Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть. Если каждый будет оформлять код как хочет, будет бардак.

Если тебе лень выравнивать код руками, закачай его на 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

3 13 апр, 21:46 3 1380489

Аноны, я постараюсь в ближайшие пару дней проверить оставшиеся посты в прошлом треде >>1353705 (OP) но вы можете напомнить о себе тут, чтобы точно не забыть.

4 13 апр, 23:15 4 1380536

Как выглядит реальная работа мечты в нерезиновой для php программиста, уже не вкатывальшика? У меня после пары лет в мухосранской конторе php ассоциируется с переработками, вечным дедлайном, с заказчиками с которыми ты должен общаться лично, задержками микрозарплаты, древнем пека на селероне. Есть ли смузихлебные места в Москве для пыхарей?

Ответы381544381548

5 13 апр, 23:39 5 1380549

Решаю список студентов и возникли некоторые вопросы.

1. Будет ли хорошим решением получать объект студента статическим методом из класса-помощника?
Например:
$student = Utils::createStudentFromGlobals();

2. Хорошим ли решением будет хранить введенные студентом данные на стороне сервера, чтобы в случае вывода ошибки при валидации вставлять их в html-атрибут value?

3. Можно ли вызывать встроенные в php функции из логики шаблонов? Да и обычные функции, ведь они могут содержать в себе сложную логику.
Или всё что серьезнее if/else/for/foreach низяяя?

4. Я забрёл слишком далеко и начал тестировать с phpunit валидатор студента, а у меня в нём большинство методов защищенные. Пришлось использовать Reflectionclass для получения доступа к ним, это нормальная практика?

И про валидатор, в нём самые часто используемые конструкции по типу измерения длины строки/проверки на пустоту, я обобщил в отдельные методы. Как вам такое решение?

5. Вопрос по тестированию.

Например у меня есть метод валидации имени студента. Он умеет:

1. Проверять переданное значение на пустоту.
2. Проверять длину на min, max значения и возвращать соответствующие ошибки.
3. Проверять регуляркой на кириллические символы.

В конце возвращает массив с ошибками или null.

Для каждой способности этого метода писать отдельный тест-метод?

Надеюсь, не отнял много времени. Заранее спасибо!

5 13 апр, 23:39 5 1380549

Решаю список студентов и возникли некоторые вопросы.

1. Будет ли хорошим решением получать объект студента статическим методом из класса-помощника?
Например:
$student = Utils::createStudentFromGlobals();

2. Хорошим ли решением будет хранить введенные студентом данные на стороне сервера, чтобы в случае вывода ошибки при валидации вставлять их в html-атрибут value?

3. Можно ли вызывать встроенные в php функции из логики шаблонов? Да и обычные функции, ведь они могут содержать в себе сложную логику.
Или всё что серьезнее if/else/for/foreach низяяя?

4. Я забрёл слишком далеко и начал тестировать с phpunit валидатор студента, а у меня в нём большинство методов защищенные. Пришлось использовать Reflectionclass для получения доступа к ним, это нормальная практика?

И про валидатор, в нём самые часто используемые конструкции по типу измерения длины строки/проверки на пустоту, я обобщил в отдельные методы. Как вам такое решение?

5. Вопрос по тестированию.

Например у меня есть метод валидации имени студента. Он умеет:

1. Проверять переданное значение на пустоту.
2. Проверять длину на min, max значения и возвращать соответствующие ошибки.
3. Проверять регуляркой на кириллические символы.

В конце возвращает массив с ошибками или null.

Для каждой способности этого метода писать отдельный тест-метод?

Надеюсь, не отнял много времени. Заранее спасибо!

Показать весь текст
Ответы380793383810394736

6 14 апр, 01:50 6 1380575

Напоминаю ОП-у глянуть мое из прошлого треда.

> Оп, глянь, как будешь свободен, финальное задание по верстке твое "Webpaint". Остальные аноны тоже можете указать на ошибки.

https://codecoshauni.github.io - сама страница.
https://github.com/codecoshauni/codecoshauni.github.io - ну и код.

Ответы398384

someApprentice !EaaiHmIJms 7 14 апр, 11:07 7 1380679

Надеюсь мой ответ не потеряется >>1380677

125 Кб, 1173x382
8 14 апр, 11:29 8 1380690

Продублирую в новом ИТТ треде:

>>1380456
>У тебя как-то странно сделано, что параметры сохраняются в $this->get. Это значит, что если ты с помощью функции linkMaker() создашь 2 анонимных функции, то одна будет влиять на другую (параметры, переданные в одну, отобразятся в другой). Это неправильно.

>$this->get
Так ведь там весь массив гет из реквеста, а не просто место для сохранения. Параметры не столько сохраняются, сколько апдейтятся - меняется только один, за который отвечает ссылка, и она пересобирается с новым значением.
Ну и разные функции нет смысла создавать - всегда один гет-массив приходит в запросе и с ним работаем.
Вообще, задумка была такой, что замыкание передаётся в шаблон под каким-то именем, где просто вызывается как на пикрелейтед. Меняются только запрошенные параметры, остальные не остаются как были. Ну и пустой писанины чтоб поменьше.

Я тут не подумал сразу и вкинул эту функцию в тред, без комментов, без пояснений нормальных. Потом только дошло, что она не оформлена никак у меня.

>если мы меняем сортировку, то надо сбрасывать пагинацию
Зачем? Количество записей ведь не изменилось. Я вот со своей этой функцией поигрался - вполне юзабельно вроде. Страницы жмёшь - меняет страницы, сортировку меняешь - сортировка только и меняется, что нажали - то и выводит.

Ответы394737

9 14 апр, 13:56 9 1380793

>>1380549
>2. Хорошим ли решением будет хранить введенные студентом данные на стороне сервера, чтобы в случае вывода ошибки при валидации вставлять их в html-атрибут value?

Вот например ошибки из валидатора и данные введенные в форму я передаю в шаблон в виде двух массивов $errors, $formData.
В шаблоне к каждому полю где они будут выводиться, нужно прикручивать проверку на существование значения в массиве во избежании предупреждения об ошибке от пхп?

Есть несколько вариантов решения этой проблемы, какой бы лучше выбрать?
https://ideone.com/1B8bMH

Ответы380807394736

10 14 апр, 14:16 10 1380807

>>1380793
Дошло, что можно использовать в шаблоне объект студента
<input type="text" value="<?= $student->getFirstName()"?>

Ответы394735

11 14 апр, 23:14 11 1381544

>>1380536

есть:

badoo
yandex
avito
lamoda
8bit
travelata
tutu

и куча других менее известных, но тоже достойных контор

12 14 апр, 23:18 12 1381548

>>1380536

Возможность личного общения с заказчиком - на мой взгляд, это большой плюс. Разработчики, понимающие бизнес, обычно ценятся выше.

Ответы381592

13 15 апр, 01:13 13 1381592

>>1381548
>Разработчики, понимающие бизнес
Какой бизнес? По доставке еды, е-коммерце, грузоперевозки, Б2Б, сотни других?
Сам-то понял что сказал? У тебя жизни не хватит чтобы всё это понять.
Умей своё дело делать хорошо и не пытайся лезть в чужое.

14 15 апр, 13:12 14 1381736

Котаны, в документации, в примерах функции зачастую типа такая запись аргументво что идут в функцию:

public PDO::prepare ( string $statement [, array $driver_options = array() ] )
или
mail ( string $to , string $subject , string $message [, mixed $additional_headers [, string $additional_parameters ]] )

Почему тут конструкция типа '[,' - т.е. сначала скобка квадратная а потом запятая. Зачем квадратные скобки?

Ответы381737

15 15 апр, 13:15 15 1381737

>>1381736
Это значит, что аргументы в скобках не обязательны

Ответы381740

16 15 апр, 13:20 16 1381740

>>1381737
Спасибо.

А еще кстати подскажите порядок работы или где почитать по почте:
Я делаю форму с отправкой почты. Читал что правильнее это все реализовывать не просто через вызов mail() - но устанавливать отдельный почтовый сервер, и уже на него отправлять из пхп письма.

Ответы381833394735

17 15 апр, 14:33 17 1381775

Сап аноны, я тут новенький. Пару дней ковырял задачу на опечатки в регулярных выражениях были траблы с типами данных. Задачу решил, но хочется что-бы кто-нибудь оценил. Буду рад если скажете где и почему было написано хуёво и как сделать лучше. Алсо реквестирую каких-нибудь статей про типы данных в PHP.
Сама программа: https://ideone.com/rg3cAy
p.s. Старался в комментарии на английском. Может быть понятно, а может и нет.

Ответы381796394735

18 15 апр, 15:02 18 1381792

Как хранить длинную SQL комманду в классе работы с бд?

Ответы383121385180

19 15 апр, 15:16 19 1381796

>>1381775
Пиздец.

Ответы381814

20 15 апр, 15:24 20 1381799

так, при регистрации валидатор симфони ругается: data.passwordThis value should not be blank.
null
ConstraintViolation {#1123
-message: "This value should not be blank."
-messageTemplate: "This value should not be blank."
-parameters: []
-plural: null
-root: Form {#594 }
-propertyPath: "data.password"
-invalidValue: null
-constraint: NotBlank {#905 …}
-code: "c1051bb4-d103-4f74-8988-acbcafc7fdc3"
-cause: null
}

помогите пж нубасу)

Ответы381836

21 15 апр, 15:48 21 1381814

>>1381796
В смысле?

Ответы381815

22 15 апр, 15:57 22 1381815

>>1381814
Твои комментарии только мешают просмотру кода, для скриптов на 30 строк они точно не нужны, особенно на каждый пук. Плюс отделять нужно для лучшей читаемости кода пустыми строками блоки этого кода.
Какие вообще статьи про типа данных ты хочешь? Просто прочитай в пхп мануале про все типы существующие и результаты их сравнения.

Ответы381823

23 15 апр, 16:14 23 1381823

>>1381815
Спасибо. Со стороны на код не смотрел. Действительно пиздец.
Так лучше: https://ideone.com/mdzzN7
А по типам данных. Что-нибудь про массивы и их нюансы(многомерные, как лучше обращаться к данным внутри них и т.д.) + про конвертацию данных в слаботипизированных языках для лучшего понимания. Я читал официальные мануалы, но все равно ощущение что, что-то не догоняю.

Ответы381842

24 15 апр, 16:28 24 1381833

>>1381740
Свифтмайлер

Ответы382162

25 15 апр, 16:30 25 1381836

>>1381799
Тебе же прямым текстом написано, в чем проблема.

26 15 апр, 16:54 26 1381842

>>1381823
Сравнение разных типов и их преобразование я понял, просто написав все возможные варианты сравнения и операций с ними, потом смотрел, что выведет интерпретатор. Вообще в мануале хорошие таблицы есть,как будут сравниваться и преобразовываться типы.

27 15 апр, 17:00 27 1381844

>>1380459
>Есть очереди задач для этого.
Ты имеешь в виду какой-нибудь rabbitmq? Из пушки по воробьям же. Мне нужно просто отправить юзеру view сразу, до того как долгий таск завершится. Я до этого писал всякую шляпу на fat free framework и там есть функция abort, которая делает нужное
https://fatfreeframework.com/3.6/base#abort
Я вполне способен залезть в исходники и посмотреть, что она там делает и перенести это в симфони, но ведь скорее всего это уже там есть и мой велосипед всяко будет хуже.

28 15 апр, 17:49 28 1381869

>>1380485 (OP)
Говорю говорю и еще раз говорю. Пхп на уровне развития стремится стать жабой, когда сама жаба уже существует. С каждой версии все похожее и похожее.

Писать на этой ссанине - себя не уважать. Нормальные люди пишут на питоне\рельсах\жабе. Пхп - кусок дерьма.

У меня есть одногруппник который пытается еще алгоритмы на нем писать. Стоит ли рассказывать об его анальной ебле и рендере красивой хтлм странички?

Ответы381885381900382971

29 15 апр, 18:22 29 1381885

>>1381869

Что ты тогда забыл в нашем треде, болезный? Иди и пиши на том языке, который тебе нравится, только почитай сначала https://habr.com/ru/post/315152/

Ответы381912

30 15 апр, 19:02 30 1381900

>>1381869
Рыночек решает. На питоне юэкенд-вэба меньше во сколько раз? В 10? В 20?
Я сам терзался выбором между пхп и питоном. К питону естественно лежала душа. Но выбрал пхп потому что тут через месяц уже можно искать какую-нибудь удаленку и хоть по минимуму монетизировать свои знания.
А то вкатывальщики годами решают тестовые, и сосут хуи.
Пока ерохи организуют вэб-студии в которых херачат на джумле сайты и делают деньги, причем GET от POST запроса не отличают тру стори.
Лично я решил дрочить технологии бека на пхп. Синтаксис питона я знаю. Если вдруг вэб перевернется - перекачусь в питон. Или в JS на котором я тоже уже по мелочи зарабатываю. Клепая калькуляторы и прочее.

31 15 апр, 19:20 31 1381912

>>1381885
Действительно https://habr.com/en/post/315152/#7

32 16 апр, 02:13 32 1382113

Аноны, как можно сделать по другому?
http://sandbox.onlinephpfunctions.com/code/36216a124252e2f05ed9d0a55dd1238d7931c980: ошибка

http://sandbox.onlinephpfunctions.com/code/7ab17081d971e1361863d569f390cdd85a382b46: пофиксил добавлением пробелов в строках 7-20.

Есть вариант найти максимальное кол-во символов в строке (32) и дополнить все строки где кол-во символов <32 пробелами. Но мне кажется что можно сделать мудрее

Ответы394735

33 16 апр, 09:33 33 1382148

Анонче, подскажи, а то я застрял. Делаю грамматического нациста, хочу сделать проверку по отсутствию знака препинания. Идея такая я делаю preg match all с preg set order< затем дампую. 0й массив. Но как мне ограничить регулярку так, что бы выводилась вся фраза с ошибкой, а не кусок? Я думал таком варианте
'/s|^. - это либо символ начала строки либо ограничивающий пробел.
\.\S - условие замены
.\s|.*\. - ограничение по пробелу или концу строк
Я хочу что бы сделав дамп 0го массива вылезли все ошибки. Но почему - то даже правильные последовательности тоже выдаются. Где я перемудрил? По возможности намекните т к хочу допереть сам

Ответы394734

34 16 апр, 10:11 34 1382162

>>1381833
>>Свифтмайлер
В нем уже реализован SMTP транспорт? Или еще нужно ставить почтовый SMTP сервер?

405 Кб, 1610x862
35 16 апр, 15:54 35 1382304

Двач, как в Splunk'e составить поисковый запрос , результатом которого будет список уникальных заявок, заполнение которых было полностью завершено?

36 17 апр, 07:39 36 1382653

В задании про список студентов оп говорит, что валидатору инфы о студенте нужно в конструктор передавать объект tablegateway, чтобы валидатор мог, например, смотреть, есть ли а базе такой email. Контроллерам тоже нужно будет вызывать методы tablegateway, чтобы работать с базой. Значит в конструктор контроллера надо передавать тоже этот объект tablegateway? А если у меня объект контроллера в роутере создаётся, то сначала объект tablegateway нужно в роутер передавать прямо из index.php? Это и есть Di?

Ответы382741385181

37 17 апр, 12:33 37 1382741

>>1382653
>объект tablegateway нужно в роутер передавать
Классы получают только те зависимости, что нужны для их собственной работы и ничего лишнего. Если представить, что у тебя будет сотня сущностей то под каждую гейтвей в роутер передавать? Херня ведь получится.
DI - это класс-контейнер который содержит в себе все нужные зависимости соединение с БД, настройки нужные, гейтвей твой. Достаточно передать в роутере только его, а не целый список барахла. Уже в конструкторе контроллер сам берёт из контейнера нужные ему зависимости.

Но вообще гугл в этом деле очень помогает.

Ответы382746

38 17 апр, 12:42 38 1382746

>>1382741
Настройка и связь с бд у меня в bootstrap.php лежит, там же создаётся и объект tablegateway. Вопрос в том,правильно ли я понял, что контроллеру можно просто объект этот передать, как передал валидатору (по совету опа), или это разные вещи. Больше никакого барахла не будет, проект же небольшой(список студентов).
Походу я немного запутался уже в этих абстракциях.

Ответы382756

9 Кб, 311x350
39 17 апр, 12:45 39 1382747

Пых-удаленщики на месте?

40 17 апр, 13:10 40 1382756

>>1382746
>контроллеру можно просто объект этот передать
Конечно можно. Только, бога ради, не в роутере - ему вообще не положено знать о таких вещах.

Ответы382791

41 17 апр, 14:24 41 1382791

>>1382756
А как тогда? Роутер же создаёт контроллер нужный и запускает его метод начала работы.

Ответы382986382989

someApprentice !EaaiHmIJms 42 17 апр, 16:17 42 1382907

Ошибка постинга: В сообщении присутствует слово из спам листа.

https://pastebin.com/iPSf8D9z

Ответы388353388926

43 17 апр, 17:48 43 1382971

>>1381869
>Икспердное мнение
>У меня дногруппник...
Ну ты понял, да.

44 17 апр, 18:25 44 1382986

>>1382791
>Роутер же создаёт контроллер нужный
Вообще не его обязанность, как по мне. Можно роутер сделать конструктором объекта Route, т.е. настоящего маршрута, который отрабатывает в данный момент.
В него, например, передавать имя контроллера, метода, параметры вызова(гет\пост и тд), ну уже потом в него и передавать зависимости, Хотя тут контейнер тоже удобнее будет.
Ну а потом $Route->run(), который собирает всё это дело воедино и посылает на рендер.
Уж лучше так, чем в роутер гейтвей сущности пихать.

Ответы383031

45 17 апр, 18:29 45 1382988

Аноны, подскажите нубу, почему если у меня сервер nginx, то нужно ставить php-fpm, а если apache то просто php.
В чём между ними разница?

Ответы394734

46 17 апр, 18:29 46 1382989

>>1382791
А вообще, с таким подходом ты просто обречен убрать инициализацю gateway из bootstrap и запихнуть её в сам контроллер. Конструктор или прямо в методе.

Ответы383031

47 17 апр, 19:17 47 1383012

Аноны, сейчас нахожусь на испытательном в небольшой компании, php программист. Опыта в php только 2 месяца.
Мне кажется что я неправильно подхожу к процессу. Трачу много времени на задачи, в которых в итоге добавляю 5-10 строк. Как быстро читать код, понимать его логическую структуру и т.д. Когда только начинал, читал код тупо как текст, услышал, что так нельзя, а как правильно хз. Как быстро находить файлы и директории с нужными кусками кода в файловой структуре. Иногда с одной страницы отсылается форма на другую, или аякс, и приходится долго искать где происходит вся обработка. Так же чую что остановилось развитие. В метро читать что то без практики не вижу смысла, а дома уже нет сил после рабочего дня(как раз таки из за того что стопоришься на легкой хуйне и это изматывает и угнетает)

Ответы383016

48 17 апр, 19:18 48 1383014

Аноны, сейчас нахожусь на испытательном в небольшой компании, php программист. Опыта в php только 2 месяца.
Мне кажется что я неправильно подхожу к процессу. Трачу много времени на задачи, в которых в итоге добавляю 5-10 строк. Как быстро читать код, понимать его логическую структуру и т.д. Когда только начинал, читал код тупо как текст, услышал, что так нельзя, а как правильно хз. Как быстро находить файлы и директории с нужными кусками кода в файловой структуре. Иногда с одной страницы отсылается форма на другую, или аякс, и приходится долго искать где происходит вся обработка. Так же чую что остановилось развитие. В метро читать что то без практики не вижу смысла, а дома уже нет сил после рабочего дня(как раз таки из за того что стопоришься на легкой хуйне и это изматывает и угнетает)

Ответы387763388197

49 17 апр, 19:20 49 1383016

>>1383012
>Как быстро находить файлы и директории с нужными кусками кода в файловой структуре
Я пришел тупо к тому, что ищу через поиск.
В пых-шторме правый shift 2 раза тыкаешь и вводишь название файла.
Быстрее, чем мышкой крутить список файлов получается.

Ответы383018

50 17 апр, 19:23 50 1383018

>>1383016
Это то да, но например хочешь найти где задается какой нибудь класс, а имя файла не знаешь, я щас тупо git grep юзаю, но даже на это иногда уходит много времени

Ответы383029

51 17 апр, 19:42 51 1383029

>>1383018

В IDE обычно есть команда "перейти к классу". В Саблайме я жму Ctrl + Shift + R и набираю часть имени класса. Плюс, обычно файл должен называться так же, как и класс, потому я жму в Саблайме Ctrl + P (поиск файла по имени) и набираю часть имени класса и файл находится.

Изучай особенности редактора и IDE, иначе будешь очень медленно и неэффективно работать.

Если речь про то, что надо понять, кто обрабатывает запрос к странице /somepage, то тут надо смотреть, фреймворк там или что-то самописное:

- если фреймворк - читаем мануал про роутинг и идем в конфиг роутера или еще куда-то
- если самопис - то изучаем код, начиная с index.php и смотрим, как реализован роутинг.

В крайнем случае, можно сделать поиск по файлам (Ctrl + Shift + F) по регулярке "\bsomepage\b" и посмотреть, что найдется.

52 17 апр, 19:48 52 1383031

>>1382989
>>1382986
Вообще почитал я про контейнеры у опа и это не так уж и сложно, как я думал, сделаю через него лучше и объект контейнера запихну в роутер.

Ответы383060

53 17 апр, 19:54 53 1383037

https://ideone.com/N3PEgY

Не могу понять, как сделать, чтобы год человека перезаписывал себя в цикле и выдавал свежее значение.

Просто год задаётся понятно, а вот как сделать, чтобы переменная перестала постоянно считаться от 16 - не знаю. Если местами переставить, то сайт будет думать, что я к нулю прибавляю, а не к 16, если оставлять так, то он каждый раз заново берёт старое содержимое...

Ответы383040385180

54 17 апр, 20:00 54 1383040

>>1383037
Держи.
https://ideone.com/1tnKb1

Ответы383041383047

55 17 апр, 20:01 55 1383041

>>1383040
Бля, я идиот. Спасибо.

56 17 апр, 20:13 56 1383047

>>1383040
Там ещё убрать можно лишнюю переменную, просто оставить $oldDude++ в цикле, и её же выводить в строке.

Я просто почему-то не понял, что ++ будет перезаписывать функцию самую первую со значением в 16.

Ответы383281

57 17 апр, 20:42 57 1383060

>>1383031
>не так уж и сложно
Это ещё и удобно, уж поверь.

58 17 апр, 21:46 58 1383079

Чёт хз, задачка с айфоном пиздец какой-то. В программировании всё такое душное и непонятное?

Ответы383080383081385180

59 17 апр, 21:49 59 1383080

>>1383079
Всё же легко, ты чего? Там вообще учебник сделан так, что поймёт и умственно отсталый.

Ответы383083

60 17 апр, 21:49 60 1383081

>>1383079
Дайте решение хоть, посмотрю как это вообще решается, перед тем как забить.

Ответы383084

61 17 апр, 21:51 61 1383083

>>1383080
Ну я понимаю что написано в коде, но сам придумать и добавить что-то не могу.

62 17 апр, 21:56 62 1383084

>>1383081
Там ниже решение же. ты в глаза долбишься или что
http://codepad.org/nm9jPcpd

Ответы383090

63 17 апр, 22:07 63 1383090

>>1383084
Это не решение. Там же надо сделать так, чтобы сумма в минус не ушла, а в ноль, только остаток чтобы выплатился.

Ответы383106

64 17 апр, 22:55 64 1383106

>>1383090
http://sandbox.onlinephpfunctions.com/code/4e7f16a7f2b2d42fdd3f95ac47351360c148fda7

65 17 апр, 23:34 65 1383121

>>1381792
Константа класса или локальная переменная в методе

66 18 апр, 02:04 66 1383151

Может кто глянуть? Правильно ли
function checkTotalAnswers пытаться поместить в класс Questions?
https://github.com/Leorne/ClassLessons/blob/master/ClassLesson3.php

Ответы385179

67 18 апр, 07:43 67 1383193

Зачем оп с списке студентов советует создать константу пола (const GENDER_MALE) в модели студента, если мы и так в конструктор будем пол передавать и записывать его в обычное поле, как и все остальное?

Ответы383195383545385179

68 18 апр, 07:47 68 1383195

>>1383193
Шоб везде писать

$vasya->setGender(User::GENDER_MALE);

if ($vasia->getGender() === User::GENDER_MALE) {
...
}

Ответы383372383545

69 18 апр, 10:45 69 1383281

>>1383047
Да, можно. Я поправил именно то, что анон просил.

70 18 апр, 12:54 70 1383372

>>1383195
>$vasya->setGender
не скрепно как-то
вася должен быть сразу создан с правильным гендером безо всяких сеттеров

Ответы383408383858

71 18 апр, 13:39 71 1383408

>>1383372
Вот я и спросил, зачем тут const. Лишний код только придется писать,типа если переданный пол в конструктор == male, то $this->gender = GENDER_MALE.

Ответы383428385179

72 18 апр, 14:31 72 1383428

>>1383408
Это позволяет держать значение male только в одном месте. Из любого места кода я могу обратиться к константе Student::GENDER_MALE и мне не важно, что там за значение (m/male/man/muzhskoj что только не пишут). Не нужно бегать править контроллеры, сервисы, валидаторы, тесты только потому что приняли "архитектурное" решение сменить 'female' на 'f'.

73 18 апр, 18:30 73 1383545

>>1383193
>>1383195
Не читал ваш срач, но вам нужен https://github.com/myclabs/php-enum

Использую это говно во всех проектах, зависимость есть, брат жив.
Охуенная штука. Позволяет тайпхинтить енумы.

Ответы383546383602

74 18 апр, 18:35 74 1383546

>>1383545
Заибца подтащил. Крепкого тебе смузи.

75 18 апр, 19:50 75 1383602

>>1383545
Список студентов я хочу без всего со стороны написать, а так спасибо.

Ответы383611

76 18 апр, 20:00 76 1383611

>>1383602
>без всего со стороны написать
В чем сакральный смысол данной идеи?

Ответы383631385178

77 18 апр, 20:20 77 1383631

>>1383611
Ни в чем, просто хочу.

78 18 апр, 22:21 78 1383734

Аноны, подскажите можно ли делать так:
function __construct(int $countOfPerson,int $tier,int $leader){
$this->countOfPerson = $countOfPerson;
$this->tier =(!isset($tier))?0:$tier;
$this->leader =(!isset($leader))?0:1;
}
В конструкторе есть переменная $tier и $leader. Могу ли я сделать их необязательными?

Ответы383743385178

79 18 апр, 22:45 79 1383743

>>1383734
Используй значения по умолчанию.

80 19 апр, 02:58 80 1383810

>>1380549
1. Зависит от обстоятельств. Есть такие принципы, как SOLID.
S - единственности ответственности. Грубо говоря каждый класс отвечает за что-то свое. Поставь вопрос - за что отвечает как Utils ? Если ответ не слишком большой - норм.
4. Нет. Скорее всего ты пишешь юнит тесты. В них (да как и почти в любых тестах) ты тестируешь только открытый функционал. Тестировать закрытые функции = себя не уважать.
5. Тестируй по отдельности, тестируй как они работают вместе. Это нормально.

Ответы383813385178

81 19 апр, 03:30 81 1383813

>>1383810
>Есть такие принципы, как SOLID.

Book authors want to sell books

Ответы383838

82 19 апр, 06:47 82 1383838

>>1383813
Мы вам перезвоним

83 19 апр, 09:13 83 1383858

>>1383372

А если над персистентным Васей совершают операцию по смене пола?

Ответы383864

84 19 апр, 09:21 84 1383864

>>1383858
Тогда удаляем объект Вася из нашего консервативного ООП.

Ответы385178

85 19 апр, 09:28 85 1383866

Аноны, ну нахуя эта пидораха что запилила пхп сделала эти тупые
'->' вместо православной '.' ?
Я понимаю что это вкусовщина и в сущности ниче не решает. Просто мне никрасива.

Ответы383897

86 19 апр, 10:34 86 1383897

>>1383866
Точка - оператор конкатенации.
Вероятно, это говно еще с пыха 3 пошло.
Ставлю очко, что конкатенация появилась раньше ооп.

Ответы383992

400 Кб, 1242x1656
87 19 апр, 12:03 87 1383949

Привет треду и Опу.

Сидел с вами с 16 по 17 год, успел сделать список студентов, MVC сапера на JS и половину файлообменника. К несчастью, у меня начались проблемы с глазами – нечто похожее на синдром "сухого глаза". Работать с пекой стало сложно, особенно с текстом, глаза устают минут за 10, пришлось завязать с программированием. Капли, очки, и лазерная коррекция не помогли, как и разные жк мониторы и шрифты. Но ближе к сути.

Я хочу заказать e-ink монитор Dasung Paperlike HD 2019 из Китая за 60к (кому интересно вот пример работы модели 2018 года https://www.youtube.com/watch?v=vLhcM9gsOEU , моя модель с более низким инпут лагом), который должен помочь мне вернуться обратно к программированию и в этот тред. Я думаю, что он мне поможет, т.к. я могу пользоваться e-ink книгами без усталости. И мне стало интересно, какие у меня теперь будут проблемы непосредственно с программированием. У монитора частота экрана около 6гц и инпут лаг 100 мс. Пока вижу следующее:

– Тяжело будет работать с монохромной IDE без раскрашивания синтаксиса. Но, думаю привыкнуть можно будет;
– Монохромный фронтенд тоже настораживает. Вряд ли я смогу работать с фотошопом (или смогу?). Также тяжело будет работать с JS анимацией из-за инпут лага;
– Хотел параллельно с вебом изучить геймдев, но с такой частотой это, наверное, вряд ли возможно – нужно больше 6гц;

Вообще, у меня опасения в основном по фронтенду, но т.к. я его не успел достаточно изучить за 2 года вката (не успел сделать задание Опа на макет), возможные проблемы для меня найти сложно. Хотелось бы послушать анона, что он может придумать и добавить к минусам осознанного дальтонизма. Часто ли при работе бэкэндером приходится работать с фронтэндом, например? На этот монитор много положительных отзывов программистов, может все не так плохо, на самом деле.

Ответы383965383966383979383981384989385177

88 19 апр, 12:22 88 1383965

>>1383949
Ясен хуй во фронт путь заказан.
Твоя стезя теперь - это бек. Там вообще проблем быть не должно.

89 19 апр, 12:24 89 1383966

>>1383949
Ну и попробуй сидеть на минимальной яркости за обычным монитором.
Может, прокатит.

Ответы383972385178

90 19 апр, 12:30 90 1383972

>>1383966

Пробовал, не помогло. Вообще, я много чего перепробовал по советам отсюда https://forum.ixbt.com/topic.cgi?id=28:29319 (оказывается не я один такой), от старых мониторов с CCFL подсветкой до Mactype (рендеринг шрифтов как в маке на винду), все бесполезно, кроме электронных чернил.

91 19 апр, 12:49 91 1383979

>>1383949
>два года вката
>делает какие-то оп задания
ты это, не спеши

Ответы383985

92 19 апр, 12:52 92 1383981

>>1383949
Что за mvc сапёр? Или это не опа задача?

Ответы383985

93 19 апр, 12:57 93 1383985

>>1383979

Да ладно, неужели я самый долгий? По-моему были аноны, которые на калькуляторе столько же сидели.

>>1383981

Опа. https://gist.github.com/codedokode/ce30e7a036f18f416ae0#3-сапер

Ответы383986383991

94 19 апр, 12:59 94 1383986

>>1383985

Фикс ссылки https://github.com/codedokode/pasta/blob/master/js/minesweeper-mvc.md

95 19 апр, 13:07 95 1383991

помню я как-то написал калькулятор на джаваскрипте за несколько дней, там было под четыреста с лишним строк кода и куча корнер кейсов, ну и он работал примерно как виндовый с отслеживанием серии операций, никогда не думал калькуляторы оказывается сложнее простой игры

потом правда забил учить кодинг только недавно снова начал

>>1383985
а зачем тут мвк? да и вообще пхп, я такое за день или два напишу на джаваскрипте

Ответы384041385177

96 19 апр, 13:09 96 1383992

>>1383897
>>Точка - оператор конкатенации.
Ой спасибо что сказал.
Я просто ною на тему.

Ответы384044

97 19 апр, 14:10 97 1384041

>>1383991
>никогда не думал калькуляторы оказывается сложнее простой игры
Это еще че, попробуй напиши калькулятор, обрабатывающий серии операций, со скобками - еще и алгоритмы придется подтянуть и синтаксический анализатор написать, а там и до своего япа недалеко, лол.

Ответы384052

98 19 апр, 14:14 98 1384044

>>1383992
Ну ныл бы тогда хуле конкатенация точкой, а не плюсом, как во всех остальных языках.

55 Кб, 711x905
99 19 апр, 14:20 99 1384052

>>1384041
он у меня серии операций и обрабатывал но без скобок - как обычный виндовый же - заряжаешь серию не ограниченной длинны он её и посчитает
вот собственно скин с кодпена, он там до сих пор висит, сам кодпен не хочу постить там везде говнища

Ответы384086

100 19 апр, 14:50 100 1384086

>>1384052
Тупо в eval пихал ввод?

Ответы384102

101 19 апр, 14:52 101 1384090

Есть ли у этой параши будущее?
педалю ублюдочный проект на работе, без фреймворков и стандартов. Местами ссанина прямиком из 2005 где запросы в базу и html в одном цикле.
Новый код пишем нормально, но старое переписать не дают.
Думаю уволиться и искать новую работу, но не знаю на какой технологии.
Есть ли смысл искать работу ещё на рнр (аппелируя к тому, что у меня уже есть опыт), или лучше выкатываться куда подальше?
Алсо, ненавижу фронтенд и избегаю его всеми силами.

Ответы384098

102 19 апр, 14:59 102 1384098

>>1384090
Ищи работу пых+го с перекатом в го, базарю, еще захочешь.
Есть прям такие вакансии: "Ищем пыхарей с перекатом в го".
Когда есть проект на пыхе, а его перепердоливают на го.
Как раз шанс выучить го и съебать от пыха.

103 19 апр, 15:04 103 1384102

>>1384086
нет, строка сплитится по пробелам и парсится, т.к. проверки типа - нельзя ввести две точки подряд или два математических символа подряд и т.п. на уровне ввода то это безопасно, ну а потом результат округлялся до определенной точности чтобы он в экран влез (это только верхняя строчка могла как в виндовом скипаться влево со знаком <<) и т.п.

наверное можно было и в эвал скормить я что-то не подумал

Ответы385177

104 19 апр, 15:40 104 1384130

Опчик, можешь глянуть 1 задачу по ООП? 200 строк это нормально, или я его сильно раздул и нужно пытаться писать более сжато?
https://github.com/Leorne/VektorCompany/blob/master/Vektor.php
Почему когда я делаю свойства класса Position - private (33 строка), то методы которые должны возвращать эти значения возвращают 0? (Все кроме getTotalEmployees, с ним всё ок)

Ответы384135384216384401385176

105 19 апр, 15:51 105 1384135

>>1384130
У меня вектор с антикризисными в 700 вышел, лол, оп проверял, про размер ниче не сказал.

Ответы384176

106 19 апр, 16:49 106 1384176

>>1384135
А, там продолжение задачи по Вектору. Я, выходит, только 1 часть сделал.

107 19 апр, 17:50 107 1384216

>>1384130
Приватные поля не видны наследникам.

51 Кб, 920x203
108 19 апр, 21:26 108 1384401

>>1384130
>200 строк это нормально
Есть топовый хинт - каждый класс в свой файл класть.
Комментариев мало. Хотя бы 30% от кода - 50 строк, по паре рабочих на каждый класс и метод.
Пикрелейтед старайся избегать. Хорошо считается когда 1-3 параметра у метода\функции, больше - хуже.

Docker GooseBumps 109 20 апр, 02:55 109 1384524

Привет тред, есть вопрос по Docker + Symfony(сифон), в контейнеризации новичок. Вопрос следующий, у меня есть приложение на сифоне которое я хочу засунуть в докер. Прочитав большое кол-во статей, я не донца понял, как это реализовать. На многих бордах люди просто описывают как развернуть среду вокруг сифона(Apache,MySQL и тд), а потом просто загружают свою приложку. Меня интересует вопрос, можно ли создать образ в который будет сразу встроено мое приложение, чтобы я просто мог скачать образ и запустись его с уже готовым приложением. У меня была мысль создать докер файл в котором прописать команды на скачивание с гита моего проекта, но будет ли этот подход грамотный с точки зрения архитектуры и концепции докера?

Ответы385086385175

110 20 апр, 18:39 110 1384989

>>1383949

У нас на работе есть фронтендер. У него два моник: один для кода (е инк), второй для анимации (жк). Возможно, тебе тоже покатит писать код там, где комфортнее глазам, а на интерфейсы изредка поглядывать через стандартный монитор.

111 20 апр, 21:52 111 1385086

>>1384524
Короче, создай пару образов докера, пойми как это говно работает.
>как развернуть среду
Ну так так все и происходит. Записываешь команды в докерфайл на установку софта, как обычно на сервере.
Файлы можешь записать внутрь на постоянку или монтировать разделы во внешнюю систему.
В докера есть докерхаб для распространения + есть кубернетис, но до этого тебе пока далеко.

Сначала просто разверни все зависимости твоего приложения в докере

Ответы385164

112 21 апр, 02:13 112 1385164

>>1385086
Ок, спасибо за совет. Тогда отпишусь по итогу что получилось, быть может кому пригодится.

113 21 апр, 03:34 113 1385175

>>1384524

Докер часто используют для решения проблем с зависимостями. В Линуксе часто нельзя стандартными средствами установить несколько версий языка программирования или какой-то библиотеки, потому Докер используют, чтобы засунуть внутрь контейнера программу и ее зависимости, не влияя на окружающую ОС. То есть, тебе нужен PHP версии X с определенными зависимостями, и ты пишешь Докер-конфиг, который берет базовый образ ОС, скачивает исходники нужной версии PHP, компилирует их (либо устанавливает из репозитория ОС), ставит нужные расширения.

Для примера, вот конфиг из Dockerhub для PHP7.3 на основе минималистичного образа Alpine: https://github.com/docker-library/php/blob/a5c895da277a71578af9561b0e282e6cb0764434/7.3/alpine3.9/cli/Dockerfile

В нем скачивается исходный код PHP, устанавливается компилятор и производится сборка (подозреваю, что не быстро). Описание этого и похожих конфигов есть тут: https://hub.docker.com/_/php

То есть Докер тут используется для того, чтобы можно было установить PHP с зависимостями независимо от того, какая используется ОС. Стандартными средствами это часто сделать нельзя - в репозитории ОС может быть только одна версия PHP, и пакетный мемеджер не позволяет ставить несколько разных версий PHP одновременно.

В Windows для этого раньше использовались "портабельные" приложения, которые просто ставились в нужную папку со своими зависимостями, не влияя на систему, и наверно в Линуксе можно было бы сделать так же, используя хитрые bash-скрипты, но люди почему-то используют Докер.

После того, как ты сделал конфиги для PHP, MySQL, Nginx, ты используешь docker-compose для того, чтобы запускать контейнеры с ними и связывать между собой. Код приложения внутрь образа не помещается, а просто монтируется туда (в определенную папку). В итоге, разработчику надо лишь запустить Докер, чтобы поднять локальную копию приложения. Это в теории. На практике, тут куча подвохов:

- в Windows/Mac Докер работает в виртуальной машине, и возможно замедление работы в сравнении с нативными приложениями
- прокидывание папки с PHP-кодом в виртуальную машину тоже работает не так быстро
- часто разработчик настраивает конфиг, как ему удобнее, но при этом конфиг не работает у другого разработчика
- образы требуют места на диске, сборка занимает время
- демон Докера большой, сложный, и работает из-под рута

То есть Докер используют в dev-среде, в CI (для прогона тестов), а на продакшене часто админы не разрешают разворачивать Докер.

Теоретически Докер можно использовать и в продакшене, например, ты собираешь образ, выгружаешь его на продакшен. Но тут будут сложности:

- тратится лишнее время на сборку образа
- надо как-то решать задачу бесшовного деплоя. В мануале, например, https://docs.docker.com/compose/production/ дается вариант только деплоя с даунтаймом при переключении.

Что ты хочешь сделать, я не очень понимаю. Зачем тебе делать образ с кодом твоего приложения внутри? Ты его передаешь какому-то заказчику? Если нет, то непонятно, зачем это тебе нужно.

> У меня была мысль создать докер файл в котором прописать команды на скачивание с гита моего проекта, но будет ли этот подход грамотный с точки зрения архитектуры и концепции докера?

Это будет неудобно, так как при каждой правке кода тебе надо пересобирать образ и тратить время и место на диске, не очень понятно, ради чего. Процесс деплоя станет медленным.

Я должен сказать, что Докер ни разу не запускал, так что советую получше изучить документацию к нему.

113 21 апр, 03:34 113 1385175

>>1384524

Докер часто используют для решения проблем с зависимостями. В Линуксе часто нельзя стандартными средствами установить несколько версий языка программирования или какой-то библиотеки, потому Докер используют, чтобы засунуть внутрь контейнера программу и ее зависимости, не влияя на окружающую ОС. То есть, тебе нужен PHP версии X с определенными зависимостями, и ты пишешь Докер-конфиг, который берет базовый образ ОС, скачивает исходники нужной версии PHP, компилирует их (либо устанавливает из репозитория ОС), ставит нужные расширения.

Для примера, вот конфиг из Dockerhub для PHP7.3 на основе минималистичного образа Alpine: https://github.com/docker-library/php/blob/a5c895da277a71578af9561b0e282e6cb0764434/7.3/alpine3.9/cli/Dockerfile

В нем скачивается исходный код PHP, устанавливается компилятор и производится сборка (подозреваю, что не быстро). Описание этого и похожих конфигов есть тут: https://hub.docker.com/_/php

То есть Докер тут используется для того, чтобы можно было установить PHP с зависимостями независимо от того, какая используется ОС. Стандартными средствами это часто сделать нельзя - в репозитории ОС может быть только одна версия PHP, и пакетный мемеджер не позволяет ставить несколько разных версий PHP одновременно.

В Windows для этого раньше использовались "портабельные" приложения, которые просто ставились в нужную папку со своими зависимостями, не влияя на систему, и наверно в Линуксе можно было бы сделать так же, используя хитрые bash-скрипты, но люди почему-то используют Докер.

После того, как ты сделал конфиги для PHP, MySQL, Nginx, ты используешь docker-compose для того, чтобы запускать контейнеры с ними и связывать между собой. Код приложения внутрь образа не помещается, а просто монтируется туда (в определенную папку). В итоге, разработчику надо лишь запустить Докер, чтобы поднять локальную копию приложения. Это в теории. На практике, тут куча подвохов:

- в Windows/Mac Докер работает в виртуальной машине, и возможно замедление работы в сравнении с нативными приложениями
- прокидывание папки с PHP-кодом в виртуальную машину тоже работает не так быстро
- часто разработчик настраивает конфиг, как ему удобнее, но при этом конфиг не работает у другого разработчика
- образы требуют места на диске, сборка занимает время
- демон Докера большой, сложный, и работает из-под рута

То есть Докер используют в dev-среде, в CI (для прогона тестов), а на продакшене часто админы не разрешают разворачивать Докер.

Теоретически Докер можно использовать и в продакшене, например, ты собираешь образ, выгружаешь его на продакшен. Но тут будут сложности:

- тратится лишнее время на сборку образа
- надо как-то решать задачу бесшовного деплоя. В мануале, например, https://docs.docker.com/compose/production/ дается вариант только деплоя с даунтаймом при переключении.

Что ты хочешь сделать, я не очень понимаю. Зачем тебе делать образ с кодом твоего приложения внутри? Ты его передаешь какому-то заказчику? Если нет, то непонятно, зачем это тебе нужно.

> У меня была мысль создать докер файл в котором прописать команды на скачивание с гита моего проекта, но будет ли этот подход грамотный с точки зрения архитектуры и концепции докера?

Это будет неудобно, так как при каждой правке кода тебе надо пересобирать образ и тратить время и место на диске, не очень понятно, ради чего. Процесс деплоя станет медленным.

Я должен сказать, что Докер ни разу не запускал, так что советую получше изучить документацию к нему.

Показать весь текст
Ответы385184385265

114 21 апр, 03:35 114 1385176

>>1384130

Когда ты столкнешься с реальными проектами, ты поймешь, что 200 строк - это ерунда. На практике каждый класс помещают в отдельный файл.

Код у тебя по моему не соответствует форматированию PSR, например, пробелы вокруг "равно" хаотично расставлены. Если ты будешь использовать IDE, то там код форматируется одной кнопкой. Также, см. второй пост треда про другие способы отформатировать код.

> private $nameOfDepartment;
Достаточно просто $name. В данном случае удлинение имени переменной не дает никакой новой информации.

> public function setPosition(string $name,int $countOfPerson,int $tier =1,int $leader = 0){
Этот метод содержит захардкоженный список профессий и не позволит добавить новые, не меняя старый код. Лучше убрать создание работников из Департамента и принимать на вход уже созданного работника. Департамент ведь нанимает людей, а не создает.

Комментарии лучше писать сверху, а не справа, а то строки получаются длинные.

> abstract class Position{
>public $payment;
Лучше использовать protected, а то у тебя можно без всяких проверок записать что угодно в эти поля снаружи. То есть сделай инкапсуляцию: доступ к свойствам снаружи есть только через методы, которые не позволят задать некорректные значения.

> function __construct(int $countOfPerson,int $tier,int $leader){
У тебя один объект Position представляет целую группу работников. Это неудобно, так как ты не можешь одному из этой группы повысить ранг, например. В части задачи про кризис это тебе помешает.

> if ($tier != 1){
> $this->payment += ($this->payment($tier0.25-0.25));
Здесь ты смешал в одном поле 2 разных значения: базовую ставку и итоговую зарплату.

Также, у твоего объекта работника есть серьезный недостаток: зарплата считается только при создании. Если мы повысим работнику ранг, зарплата не обновится. А по идее зарплата должна обновляться при изменении любого влияющего на нее свойства (подсказка: проще всего ее вообще не хранить).

> public function getTotalPayment(){
Стоит указывать тип возвращаемого функцией значения.

> class Manager extends Position{
>public $payment = 500;
У тебя класс-наследник должен указать базовую ставку для профессии. Но это никак не описано в коде и никак не проверяется. Легко забыть это сделать. Лучше объявить абстрактные методы вроде getBaseSalary, тогда не определить их в наследнике не получится.

> $sellDepartment->setPosition('manager',12);
Вместо названия лучше было бы использовать встроенную константу, возвращающую имя класса: Marketer::class. Так при опечатке будет выдана ошибка. У тебя же опечатка будет молча проигнорирована, что очень плохо - это не позволяет сразу увидеть ошибку и придется потратить много времени на отладку.

114 21 апр, 03:35 114 1385176

>>1384130

Когда ты столкнешься с реальными проектами, ты поймешь, что 200 строк - это ерунда. На практике каждый класс помещают в отдельный файл.

Код у тебя по моему не соответствует форматированию PSR, например, пробелы вокруг "равно" хаотично расставлены. Если ты будешь использовать IDE, то там код форматируется одной кнопкой. Также, см. второй пост треда про другие способы отформатировать код.

> private $nameOfDepartment;
Достаточно просто $name. В данном случае удлинение имени переменной не дает никакой новой информации.

> public function setPosition(string $name,int $countOfPerson,int $tier =1,int $leader = 0){
Этот метод содержит захардкоженный список профессий и не позволит добавить новые, не меняя старый код. Лучше убрать создание работников из Департамента и принимать на вход уже созданного работника. Департамент ведь нанимает людей, а не создает.

Комментарии лучше писать сверху, а не справа, а то строки получаются длинные.

> abstract class Position{
>public $payment;
Лучше использовать protected, а то у тебя можно без всяких проверок записать что угодно в эти поля снаружи. То есть сделай инкапсуляцию: доступ к свойствам снаружи есть только через методы, которые не позволят задать некорректные значения.

> function __construct(int $countOfPerson,int $tier,int $leader){
У тебя один объект Position представляет целую группу работников. Это неудобно, так как ты не можешь одному из этой группы повысить ранг, например. В части задачи про кризис это тебе помешает.

> if ($tier != 1){
> $this->payment += ($this->payment($tier0.25-0.25));
Здесь ты смешал в одном поле 2 разных значения: базовую ставку и итоговую зарплату.

Также, у твоего объекта работника есть серьезный недостаток: зарплата считается только при создании. Если мы повысим работнику ранг, зарплата не обновится. А по идее зарплата должна обновляться при изменении любого влияющего на нее свойства (подсказка: проще всего ее вообще не хранить).

> public function getTotalPayment(){
Стоит указывать тип возвращаемого функцией значения.

> class Manager extends Position{
>public $payment = 500;
У тебя класс-наследник должен указать базовую ставку для профессии. Но это никак не описано в коде и никак не проверяется. Легко забыть это сделать. Лучше объявить абстрактные методы вроде getBaseSalary, тогда не определить их в наследнике не получится.

> $sellDepartment->setPosition('manager',12);
Вместо названия лучше было бы использовать встроенную константу, возвращающую имя класса: Marketer::class. Так при опечатке будет выдана ошибка. У тебя же опечатка будет молча проигнорирована, что очень плохо - это не позволяет сразу увидеть ошибку и придется потратить много времени на отладку.

Показать весь текст
Ответы387082

115 21 апр, 03:36 115 1385177

>>1384102

Лучше без eval. С ним код разбирать труднее.

>>1383991

MVC там чтобы изучить MVC и научиться отделять модель от представления, понять, какие есть подходы к реализации data-байндинга. Почитал бы комментарии к задаче. Так-то, конечно, саперу полноценный MVC не нужен.

>>1383949

Я думаю, что и фронтендом заниматься возможно, но тебе придется как-то компенсировать невозможность постоянно смотреть на экран. Ну, например, можно тщательно изучить CSS, чтобы в голове представлять, как будут выглядеть те или иные элементы и использовать обычный монитор только для проверки. В принципе, верстать можно, особо не глядя на экран большую часть времени.

На черно-белом мониторе главная проблема не в анимациях, а в маленьком кол-ве оттенков. Трудно на нем нарезать макет на картинки, не видны цвета. Также, бывают сайты с серым текстом на сером фоне.

Возможно, тебе еще подойдет вариант распечатывать какие-то материалы и читать с бумаги. Как плюс, можно делать пометки на них.

С играми да, тут сложнее. Обычно они довольно динамичные, если не считать каких-то стратегий.

> Часто ли при работе бэкэндером приходится работать с фронтэндом, например?

Бывает довольно часто надо что-то подправить/добавить на существующую страницу. Но если ты будешь работать со всякими бизнес-ориентированными приложениями, там обычно дизайн в стиле черные таблицы на белом фоне.

Монитор, если есть такая возможность, стоило бы посмотреть вживую перед покупкой.

116 21 апр, 03:37 116 1385178

>>1383864

В этой задаче редактирование предусмотрено на случай ошибок при вводе данных. Так что Васю все же надо оставить.

>>1383966

В некоторых ЖК мониторах минимальная яркость соответствует наибольшей амплитуде мерцаний подсветки.

>>1383810

> Тестировать закрытые функции = себя не уважать.

Дело тут не в уважении, а в том, что приватные функции - это деталь реализации. От класса требуется предоставлять выполнять определенные требования, а как он это делает - его личное дело. И если мы будем в тестах закладывать знание внутреннего устройства класса, то нам их придется переписывать при любых изменениях. А это неудобно.

>>1383734

..., int $tier = 1, ..

Это описано в мануале PHP.

>>1383611

Изучить, как устроено веб-приложение, а не изучить, как настроить фреймворк.

117 21 апр, 03:37 117 1385179

>>1383193
>>1383408

Для случаев, когда есть выбор из нескольких значений, эти значения принято обозначать константами. Плюсы: защита от опечаток; видно, какие есть вообще варианты значения; видно, что это не случайная строка; автодополнение в IDE.

То есть Student::GENDER_MALE говорит гораздо больше, чем просто строка 'male' или число 1.

И в конструктор ты будешь передавать сразу константу.

>>1383151

> if (($answer == $this->answer) || array_search($answer,$this->deviation) != FALSE){

Тут явно что-то неправильно сделано. Для ответа с погрешностью тебе надо лишь проверить, что ответ находится в диапазоне (правильный ответ - погрешность; ответ + погрешность). То есть обычные сравнения больше/меньше.

> if (property_exists($question,'options') == TRUE){
> echo "Варианты ответов:\n";

А вот это неправильно. Это какой-то костыль. Тут получается, если у нас есть 10 видов вопросов, мы должны написать 10 ифов. Правильнее было бы сделать так: сделать в вопросе метод printQuestion() и пусть каждый вопрос сам определяет, как его надо выводить. Так мы можем добавлять новые типы вопросов, не трогая старый код.

> Правильно ли
> function checkTotalAnswers пытаться поместить в класс Questions?

Думаю, что нет, так как Question представляет один вопрос, а функция работает со множеством вопросов.

Ответы385271

118 21 апр, 03:38 118 1385180

>>1381792

Просто как обычную строку. Я против констант для этого, так как:

- запрос выносится из кода, в котором он используется, код труднее читать
- непонятно, зачем это нужно: мы будем использовать этот запрос где-то еще?

>>1383079

Я сразу предупрежу, что у тебя какое-то неправильное отношение. Сложные задачи для программиста - это челлендж и возможность к развитию, возможность поломать голову и получить удовольствие, а не "душная" вещь.

Задачка решается примерно так:

- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.

>>1383037

Вообще, у тебя тут все очень просто. Возраст сейчас = начальный возраст + сколько прошло лет.

Что касается ++, это $x++ это короткая запись для $x += 1, а это короткая запись для $x = $x + 1. То есть мы вычисляем $x + 1 и записываем это назад в $x.

119 21 апр, 03:38 119 1385181

>>1382653

Если следовать принципу DI, то да, в контроллер надо передавать нужные ему объекты (зависимости) снаружи. Соответственно, создание контроллера мы поручаем DI контейнеру, который и передаст ему эти зависимости. Роутер берет контроллер из контейнера, а не создает сам.

Но на практике контроллеры часто исключают из DI, так как это все равно не повторно используемый код, и просто передают в конструктор контроллера только DI контейнер, а контроллер уже сам берет из него то, что ему нужно. Это отступление от принципов DI/IoC.

И роутер (который на самом деле Front Controller, а не просто роутер) можно исключить из DI по той же причине.

> А если у меня объект контроллера в роутере создаётся, то сначала объект tablegateway нужно в роутер передавать прямо из index.php? Это и есть Di?

В DI обычно объекты создает DI контейнер, а не роутер. В роутер проще передать DI контейнер и брать контроллеры из него. Хотя, если тебе очень хочется, можно и для роутера задействовать DI, передавая в него все объекты контроллеров снаружи, и сам роутер поместить в DI контейнер.

Ответы385271

120 21 апр, 06:10 120 1385184

>>1385175
В одном из тестовых заданий на стажировку была задача предоставить докер образ по окончанию работы, поэтому задался таким вопросом.

А насчёт prod версии и докера, то на мой взгляд довольно удобно поставлять докер образы, тк у кого то Postgre или sqlLite, а кому то нужен Nginx вместо Apache.

Спасибо за инфу, буду анализировать.

Ответы385293385809

121 21 апр, 11:45 121 1385265

>>1385175
В итоге удалось разобраться и составить свой Docker-compose файл для проекта(на Symfony). Ты оказался прав, это нелогично запихивать исходники в контейнер, гораздо проще таскать среду и подгружать все через гит и композер.

Если кому пригодится, то исходники на гите, стек - phpmyadmin, apache, php7.2, mariaDB.

https://github.com/GooseBumpsOS/docker-symfony

Ответы385875

122 21 апр, 11:47 122 1385271

>>1385181
>>1385179
Спасибо за ответ.

123 21 апр, 12:23 123 1385293

>>1385184
У обычного разработчика в общем случае будут установлены как postgres, так и sqlite.
ОП всё правильно расписал, для zero downtime деплоя в докере из коробки ничего нет, есть bash-костыли на гитхабе. Сервер нужно чистить от старых образов, как-то это всё хозяйство мониторить. В итоге ты будешь вынужден платить за kubernetes или за сервисы амазона. Мы через это прошли и в итоге избавились от докера везде, где возможно - проще один раз за 20-30 минут поднять проект, чем постоянно возиться с докером, ждать сборки образов. Как плюс - на всех проектах PHP самой новой версии, так как если локально обновили PHP c 7.1 на 7.2, то и все проекты нужно перевести на 7.2, иначе локально могут не работать. Ну и на маке докер работает очень медленно, нужны опять костыли вроде docker-sync.

Ответы385303

686 Кб, 1725x947
124 21 апр, 12:41 124 1385303

>>1385293
ахах, сейчас как раз смотрю общую лекцию по Kubernetes.

А как без докера решать такие проблемы?

Ответы385876

125 21 апр, 15:25 125 1385809

>>1385184

Я думаю, что там требовалось сделать именно Докер для dev-среды. То есть сделать образы с PHP, nginx, MySQL, PHP-FPM и связать их через docker-compose, чтобы все это можно было бы запустить одной командой.

Ответы388192

126 21 апр, 15:50 126 1385875

>>1385265

Обычно внутрь контейнера код никто не загружает, его просто примонтируют (то есть код лежит на хосте, а у контейнера есть доступ к этой папке). Папка задается командой VOLUME: https://docs.docker.com/engine/reference/builder/#volume

Если надо, можно почитать информацию на сайте dockerhub, там и по PHP, и по MySQL есть подробнейшие пояснения:

- https://hub.docker.com/_/mysql
- https://hub.docker.com/_/php

Зачем тебе apache, не очень понятно, использовал бы nginx сразу, раз у тебя php-fpm.

Ответы385920

127 21 апр, 15:53 127 1385876

>>1385303

Не всем требуется управлять десятками серверов. которые должны запускаться и останавливаться вслед за пиками нагрузки. Потому проблем, которые решают системы управления контейнерами, у них нету.

Если используется пара серверов (веб-сервер + сервер БД), то это все настраивается руками без докеров. Если потребуется переезд, то просто на новом месте разворачивается полный бекап.

128 21 апр, 16:44 128 1385920

>>1385875
>Зачем тебе apache, не очень понятно, использовал бы nginx сразу, раз у тебя php-fpm.

Мой косяк, не заметил, подправил.

129 22 апр, 07:47 129 1386332

Объясните долбоебу про front controller.

Ответы386341386423

130 22 апр, 08:38 130 1386341

>>1386332
В public лежит index.php и .htaccess. В последнем прописаны настройки апача - происходит редирект любых юрлов в index:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule .* index.php [L]

А index уже обрабатывает их как тебе надо, вызывая нужные контроллеры, например, вроде так.

131 22 апр, 11:13 131 1386423

>>1386332

http://design-pattern.ru/patterns/front-controller.html

132 22 апр, 16:16 132 1386695

Что за хуйня с этим ебучим Eloquent?

Пишу запрос через орм. Возвращается пустой массив.
Распечатал сформированный орм запрос:
select `type`, SUM(`duration`) AS `sum_duration` from `megafon_calls` where `telephony_id` = ? and `time` > NOW() - INTERVAL ? HOUR group by `telephony_id`, `type`
- Все нормально блять, если его вставить в пых-админ, он выполнится как надо.
Но в коде возвращается пустой массив.
Пиздец.
Тупо голый sql написать что ли? Заебался уже.

Ответы386920394734

133 22 апр, 21:51 133 1386920

>>1386695
Ты бы свой eloquent запрос что ли прислал

134 23 апр, 00:47 134 1387082

>>1385176
>Когда ты столкнешься с реальными проектами, ты поймешь, что 200 строк - это ерунда.

Да я спрашиваю к тому, чтобы знать: раздут мой код или нет. Если можно сделать в 100 строк, а я сделал в 400 - значит я написал не так хорошо как мог

>Лучше убрать создание работников из Департамента и принимать на вход уже созданного работника.Департамент ведь нанимает людей, а не создает.

Сделать в департаменте массив из работников, который будет содержать в себе все виды работников? Не совсем понял где тогда создавать работников, ведь я вызывал метод
setPosition и устанавливал все необходимые входные данные там. С названием "должности" я понял проблему, это можно починить передавая константы с именем класса. Если константы не существует - значит и класса такого нет, а значит и нет проблем.

>Лучше использовать protected, а то у тебя можно без всяких проверок записать что угодно в эти поля снаружи.

Правильно ли я понимаю, что желательно для всех свойств класса ставить protected/private, а для считывания/записи нужно делать public методы с проверкой и выдачей ошибки в случае чего?

>У тебя один объект Position представляет целую группу работников. Это неудобно, так как ты не можешь одному из этой группы повысить ранг, например. В части задачи про кризис это тебе помешает.

Неужели для каждого рабочего свой обьект создавать? Ранг повысить я смог, если нужно повысить 4 человека с 1 ранга до 2, то с группы людей 1 ранга(кол-ва человек) отнимаем 4, и создаем новый обьект в департаменте с рангом +1 (с кол-вом человек = 4 ).

>Вместо названия лучше было бы использовать встроенную константу, возвращающую имя класса: Marketer::class.

Не совсем понял. Обьявить в начале кода 4 константые Manager,Engineer и т.д?

>Здесь ты смешал в одном поле 2 разных значения: базовую ставку и итоговую зарплату.

Т.е базовая ставка у всех одинаковая, а итоговая зависит от ранга и является ли работник лидером?

Попробую все задание по новой переделать, ибо я задание с кризисом почти сделал, но код какой то мусорный и плохо читаемый.

ОП, спасибо тебе огромное что уделил время

134 23 апр, 00:47 134 1387082

>>1385176
>Когда ты столкнешься с реальными проектами, ты поймешь, что 200 строк - это ерунда.

Да я спрашиваю к тому, чтобы знать: раздут мой код или нет. Если можно сделать в 100 строк, а я сделал в 400 - значит я написал не так хорошо как мог

>Лучше убрать создание работников из Департамента и принимать на вход уже созданного работника.Департамент ведь нанимает людей, а не создает.

Сделать в департаменте массив из работников, который будет содержать в себе все виды работников? Не совсем понял где тогда создавать работников, ведь я вызывал метод
setPosition и устанавливал все необходимые входные данные там. С названием "должности" я понял проблему, это можно починить передавая константы с именем класса. Если константы не существует - значит и класса такого нет, а значит и нет проблем.

>Лучше использовать protected, а то у тебя можно без всяких проверок записать что угодно в эти поля снаружи.

Правильно ли я понимаю, что желательно для всех свойств класса ставить protected/private, а для считывания/записи нужно делать public методы с проверкой и выдачей ошибки в случае чего?

>У тебя один объект Position представляет целую группу работников. Это неудобно, так как ты не можешь одному из этой группы повысить ранг, например. В части задачи про кризис это тебе помешает.

Неужели для каждого рабочего свой обьект создавать? Ранг повысить я смог, если нужно повысить 4 человека с 1 ранга до 2, то с группы людей 1 ранга(кол-ва человек) отнимаем 4, и создаем новый обьект в департаменте с рангом +1 (с кол-вом человек = 4 ).

>Вместо названия лучше было бы использовать встроенную константу, возвращающую имя класса: Marketer::class.

Не совсем понял. Обьявить в начале кода 4 константые Manager,Engineer и т.д?

>Здесь ты смешал в одном поле 2 разных значения: базовую ставку и итоговую зарплату.

Т.е базовая ставка у всех одинаковая, а итоговая зависит от ранга и является ли работник лидером?

Попробую все задание по новой переделать, ибо я задание с кризисом почти сделал, но код какой то мусорный и плохо читаемый.

ОП, спасибо тебе огромное что уделил время

Показать весь текст
Ответы387094393246394576

135 23 апр, 01:12 135 1387094

>>1387082
>Если можно сделать в 100 строк, а я сделал в 400 - значит я написал не так хорошо как мог
главное какой вариант легче читать и поддерживать

136 23 апр, 17:29 136 1387384

Нихуя не понимаю mvc, помогите долбоёбу

Ответы387455387469388200394733

97 Кб, 259x194
137 23 апр, 20:22 137 1387455

>>1387384
Я вообще ничего не понимаю с этим долбанным SQL. Набираю уже где-то первую космическую на одной жопной тяге.

Правила меняются постоянно от запроса к запросу, от типа переменной к другому типу переменной. Заебало такое поведение уже. Где-то можно напрямую переменные в строку лепить - где-то нельзя.
С группировкой тоже возился долго и пришлось костыль писать, так потом выяснилось что мой костыль и не костыль вовсе. Оказывается в "GROUP BY" нельзя биндить переменную. Но везде можно. А тут нельзя - читайте документацию. Где-то там на триста-сраной странице пару строк написано про это. Или гугл доёбывайте, но на русском только шизики срут - трахайте по английский пожалуйста. Рады были вам помочь.
Ну охуеть теперь. И всем норм. Говноедство какое-то массовое.

Ответы387703394734

138 23 апр, 20:52 138 1387469

>>1387384
я тоже не совсем понимаю
модель ладно, это база данных
вью понятно, это фронт-энд
контроллер... щито такое контроллер? бэкэнд с роутингом и запросами к базе данных? вроде логично, но фронт-энд, бэк-энд и база данных есть у большинства приложух, а мвк считается специфической композицией

Ответы387476

139 23 апр, 20:57 139 1387476

>>1387469
>модель ладно, это база данных
Это бизнес-логика. То есть сама суть процесса, который ты программируешь. Там не только база данных.
>контроллер... щито такое контроллер?
То, что склеивает модель и представление. Она обычно трогает модель за разные места, а результат этого действия отдаёт представлению(вью).

Ответы387484

140 23 апр, 21:12 140 1387484

>>1387476
как все сложно
я рад что есть спы, вот они точно по мне

141 24 апр, 11:07 141 1387703

>>1387455
Ето и есть процесс обучения.

Ответы387794

142 24 апр, 13:07 142 1387763

>>1383014
Это что за компания, где берут с 2-мя месяцами опыта?
и сколько платят?

Ответы387771387786

143 24 апр, 13:27 143 1387771

>>1387763
Меня вообще без опыта взяли. Ебошу бэк для мобилочек теперь.

Ответы387915

144 24 апр, 13:40 144 1387775

Как начать отписываться по зказам на фрилансе? Не могу просто начать, боюсь что не справлюсь и испорчу профиль и все в этом духе. Хотя опыт есть, я сейчас работаю веб макакой, но тут все просто. Тебе выдают таск и знай делай, и с заказчиками тоже иногда общаюсь

Ответы388199

145 24 апр, 14:34 145 1387786

>>1387763
в смысле? все люди когда-то начинали свою первую работу не имея опыта

Ответы387915

146 24 апр, 14:46 146 1387792

Почему меня фолловят на гитхабе, если я ещё ничего не выкладывал? За звёзды другим проектам могут?

147 24 апр, 14:49 147 1387794

>>1387703
Да ето так.

Однако от этого не легче - довольно сложно работать с системой, в данном случае, MySQL, если она ведёт себя как девка на свидании и постоянно ломается и нарушает свои же правила.

148 24 апр, 14:53 148 1387796

Аноны, подскажите - разбиваю url строку в массив.
$url = "posts-new/test?page2=2&page3=3";
$params = explode('&', $url);

результат:
$params = Array
(
[0] => posts-new/test
[1] => page2=2
[2] => page3=3
)

Какого хрена? Я же в качестве разделителя амперсанд "&" использую?
И когда я просто печатаю url на страничке - "&" меняется на "?". почему так?

Ответы387823388194388284388288

149 24 апр, 15:51 149 1387823

>>1387796
У пыха встроенный функционал есть для разбора УРЛов. Не надо вручную всё это .

Ответы388239

150 24 апр, 18:32 150 1387915

>>1387786
>>1387771
Так он указывает что вообще в пыхе два месяца опыта.То что могут взять без опыта РАБОТЫ я понимаю, но ведь для этого нормально знать уже надо.
я так думаю

151 25 апр, 01:52 151 1388192

>>1385809
> сделать образы с PHP, nginx, MySQL, PHP-FPM и связать их через docker-compose, чтобы все это можно было бы запустить одной командой.
Но зачем? В репозиториях докера уже всё это есть.
А ещё есть уже даже собранное решение. Devilbox

Ответы388990

152 25 апр, 01:56 152 1388194

>>1387796
Как же ты так, функцию explode узнал, а про GET и POST запросы и суперглобальные переменные нет. Вот тебе наводка. Иди гугли. Найдёшь что ищешь.

Ответы388239

153 25 апр, 01:59 153 1388197

>>1383014
Забей, пока ты просто плохо знаешь проект, будешь тупить. Подольше его попердолишь, уловишь структуру и логику даже если её нет, лол, всё равно запомнишь где что и установишь закономерности и будешь уже по проекту хорошо ориентироваться.

154 25 апр, 02:01 154 1388199

>>1387775
В таком случае, голодать. Как поймёшь, что либо пишешь заказчику, либо завтра жрать нечего будет, страх уйдёт.

155 25 апр, 02:04 155 1388200

>>1387384
Model - тут логика, обработка данных, работа с БД.
View - всё просто. Шаблоны, вёрстка. В общем, всё что показывается пользователю тут.
Controller - звено между пользователем и логикой. Принимает данные, преобразует типа, собрать аргументы в массив и прочее по мелочи, передаёт в модель.

156 25 апр, 05:21 156 1388212

>>1380677

> Сообщение - это конкретная запись сообщения имеющая все данные о нём, от содержания до автора, id, даты публикации и т.д., а сообщения - это запись какие сообщения принадлежат какому пользователю и/или диалогу. Т.е. "сообщения" хранит ссылки для пользователя на id конкретного сообщения.

Это лучше назвать "message_to_user" или "user_message", как-то так. Тут https://www.sqlstyle.guide/ru/ советуют придумывать оригинальные имена, но в данном случае это трудно.

Твои названия сбили меня с толку, и скорее всего, собьют и других людей.

> Такая схема была предложена вами при обсуждении моей задачи чата на чистом JS:

Да, я имел в виду, что если мы делаем каждому пользователю свою копию сообщения, то хорошо бы эти копии связать с помощью какого-то id. Чтобы можно было например их редактировать или удалять все вместе.

И еще, у тебя в таблице "текстовое_сообщения" есть ссылка на диалог. Но ведь сообщение постится в один чат. Значит, у тебя для чата у каждого пользователя есть своя "копия" диалога со своим id? Вот такие вещи стоило бы пояснить заранее, увы, я этого не понял сразу.

Я уже не помню точно, что я раньше советовал, но тут стоило бы в идеале сравнить разные варианты реализации и найти их плюсы и минусы. Как лучше - делать при отправке сообщения каждому получателю свою копию или же делать одно сообщение, но с несколькими получателями. В случае шифрования, если мы для каждого пользователя делаем разный шифротекст (шифруем сообщение разными ключами), то придется делать несколько копий.

При таком подходе есть проблема - в огромных чатах при отправке накладно получается делать 1000 копий сообщения, и в плане загрузки CPU, и в плане хранения на сервере. Для таких случаев можно попробовать такую идею: есть создатель чата, он создает "ключ чата" и сохраняет на сервер (или же сервер сам его генерирует). Каждый подключающийся к чату получает этот ключ и может шифровать и расшифровывать сообщения. Минус - когда один ключ есть у кучи людей, это не очень-то надежно. Но если это публичный чат, то и так любой может подключиться к нему и читать его. Чтобы отключившиеся от чата не могли больше читать его, надо периодически обновлять ключ чата. Те, кто отключился, не получат новую версию ключа.

В общем, попробуй применить инженерный подход: сравнение разных схем, определение плюсов и минусов, проверка типовых сценариев (переписка между пользователями, между несколькими, большой чат, правка и удаление сообщений, бан пользователей, выборка последних N сообщений, выборка списка диалогов с числом непрочтенных сообщений). Я, увы, с ходу не могу предсказать, что тут лучше подойдет. Но могу прокомментировать и покритиковать предложенную схему.

> Я думал об этом и предполагал, что у psql есть встроенная поддержка этого, и как оказалось, действительно есть

Это хорошо, что там есть поддержка наследования, но стоило бы проверить, как это реализовано и нет ли там сильного замедления запросов при таком подходе. Если физически это сделано как одна большая таблица, то скорее всего все ок.

> Этот массив был бы объектом с одним свойством этого самого массива?

Зависит от ситуации, скорее всего объектом с полями. Ну например, у нас есть фильтр по товарам, который мы передаем в функции и получаем из функций, преобразуем. Логично делать его не массивом, а нормальным объектом с полями: мин. цена, макс. цена, категории, цвета, бренды, поиск по названию и тд. Я имел в виду, что в такой ситуации выгоднее использовать объект с методами, проверкой типов, чем просто непонятный массив, в котором непонятно даже какие поля есть.

156 25 апр, 05:21 156 1388212

>>1380677

> Сообщение - это конкретная запись сообщения имеющая все данные о нём, от содержания до автора, id, даты публикации и т.д., а сообщения - это запись какие сообщения принадлежат какому пользователю и/или диалогу. Т.е. "сообщения" хранит ссылки для пользователя на id конкретного сообщения.

Это лучше назвать "message_to_user" или "user_message", как-то так. Тут https://www.sqlstyle.guide/ru/ советуют придумывать оригинальные имена, но в данном случае это трудно.

Твои названия сбили меня с толку, и скорее всего, собьют и других людей.

> Такая схема была предложена вами при обсуждении моей задачи чата на чистом JS:

Да, я имел в виду, что если мы делаем каждому пользователю свою копию сообщения, то хорошо бы эти копии связать с помощью какого-то id. Чтобы можно было например их редактировать или удалять все вместе.

И еще, у тебя в таблице "текстовое_сообщения" есть ссылка на диалог. Но ведь сообщение постится в один чат. Значит, у тебя для чата у каждого пользователя есть своя "копия" диалога со своим id? Вот такие вещи стоило бы пояснить заранее, увы, я этого не понял сразу.

Я уже не помню точно, что я раньше советовал, но тут стоило бы в идеале сравнить разные варианты реализации и найти их плюсы и минусы. Как лучше - делать при отправке сообщения каждому получателю свою копию или же делать одно сообщение, но с несколькими получателями. В случае шифрования, если мы для каждого пользователя делаем разный шифротекст (шифруем сообщение разными ключами), то придется делать несколько копий.

При таком подходе есть проблема - в огромных чатах при отправке накладно получается делать 1000 копий сообщения, и в плане загрузки CPU, и в плане хранения на сервере. Для таких случаев можно попробовать такую идею: есть создатель чата, он создает "ключ чата" и сохраняет на сервер (или же сервер сам его генерирует). Каждый подключающийся к чату получает этот ключ и может шифровать и расшифровывать сообщения. Минус - когда один ключ есть у кучи людей, это не очень-то надежно. Но если это публичный чат, то и так любой может подключиться к нему и читать его. Чтобы отключившиеся от чата не могли больше читать его, надо периодически обновлять ключ чата. Те, кто отключился, не получат новую версию ключа.

В общем, попробуй применить инженерный подход: сравнение разных схем, определение плюсов и минусов, проверка типовых сценариев (переписка между пользователями, между несколькими, большой чат, правка и удаление сообщений, бан пользователей, выборка последних N сообщений, выборка списка диалогов с числом непрочтенных сообщений). Я, увы, с ходу не могу предсказать, что тут лучше подойдет. Но могу прокомментировать и покритиковать предложенную схему.

> Я думал об этом и предполагал, что у psql есть встроенная поддержка этого, и как оказалось, действительно есть

Это хорошо, что там есть поддержка наследования, но стоило бы проверить, как это реализовано и нет ли там сильного замедления запросов при таком подходе. Если физически это сделано как одна большая таблица, то скорее всего все ок.

> Этот массив был бы объектом с одним свойством этого самого массива?

Зависит от ситуации, скорее всего объектом с полями. Ну например, у нас есть фильтр по товарам, который мы передаем в функции и получаем из функций, преобразуем. Логично делать его не массивом, а нормальным объектом с полями: мин. цена, макс. цена, категории, цвета, бренды, поиск по названию и тд. Я имел в виду, что в такой ситуации выгоднее использовать объект с методами, проверкой типов, чем просто непонятный массив, в котором непонятно даже какие поля есть.

Показать весь текст
Ответы388352

157 25 апр, 05:21 157 1388213

>>1380688

> Ну и разные функции нет смысла создавать - всегда один гет-массив приходит в запросе и с ним работаем.

Суть не в том, что ты создаешь эту анонимную функцию всего один раз. Суть в том, что это можно было сделать нормально аж несколькими способами:

- не использовать анонимную функцию, а использовать объект, каждый генератор ссылок - это новый объект
- использовать анонимную функцию, но хранить данные в замыкании, а не в $this, так что каждая функция изолирована от других

Любой из этих вариантов решил бы проблему нарушения изоляции генераторов ссылок друг от друга. Ты же выбрал плохой вариант, который может вызвать баг, и вместо исправления пишешь о том, что ты создаешь всего лишь 1 генератор. Это так не делается. В реальном проекте завтра кто-то попробует создать второй генератор ссылок и получит баг. Не надо писать такой код, который легко использовать неправильно и получить баг.

>> если мы меняем сортировку, то надо сбрасывать пагинацию
> Зачем? Количество записей ведь не изменилось.

Обычно сортировку используют, чтобы показать, например, самые большие или самые маленькие баллы. Или первые фамилии по алфавиту. Для этого надо перейти на 1-ю страницу при смене сортировки. Если ты меняешь сортировку и оставляешь ту же страницу, то не очень понятно, для чего это нужно. Ты не получаешь ни самые большие, ни самые маленькие баллы, а что-то из середины списка.

Везде переключают на первую страницу при смене сортировки, насколько я знаю.

>>1381843

Этот подход довольно плохой. Он мне не нравится. Во-первых, не всегда это работает, зависит от конфигурации сервера, и может получиться, что у юзера будет крутиться кружок загрузки, пока твой скрипт что-то там считает якобы в фоне. Во-вторых, php-fpm на такое не рассчитан. Там может быть ограничено число рабочих процессов, и в неудачном случае они все могут оказаться заняты этими вычислениями и некому будет обслуживать другие запросы пользователей. В-третьих, тут нет обратной связи - ты запустил вычисление, а чем оно закончилось, неизвестно. Также, часто на php-fpm ставится таймаут на время работы скрипта.

Если у тебя какой-то простой случай, не требующий очереди задач, редко вызваемый (типа генерации какого-то отчета, который генерируется минуту), то проще просто сделать страницу с кнопкой и кнопкой запрашивать скрипт аяксом, а тот скрипт генерирует отчет и возвращает. Тут ты хотя бы в итоге либо получишь отчет, либо какую-то ошибку и можно будет нажать кнопку еще раз.

157 25 апр, 05:21 157 1388213

>>1380688

> Ну и разные функции нет смысла создавать - всегда один гет-массив приходит в запросе и с ним работаем.

Суть не в том, что ты создаешь эту анонимную функцию всего один раз. Суть в том, что это можно было сделать нормально аж несколькими способами:

- не использовать анонимную функцию, а использовать объект, каждый генератор ссылок - это новый объект
- использовать анонимную функцию, но хранить данные в замыкании, а не в $this, так что каждая функция изолирована от других

Любой из этих вариантов решил бы проблему нарушения изоляции генераторов ссылок друг от друга. Ты же выбрал плохой вариант, который может вызвать баг, и вместо исправления пишешь о том, что ты создаешь всего лишь 1 генератор. Это так не делается. В реальном проекте завтра кто-то попробует создать второй генератор ссылок и получит баг. Не надо писать такой код, который легко использовать неправильно и получить баг.

>> если мы меняем сортировку, то надо сбрасывать пагинацию
> Зачем? Количество записей ведь не изменилось.

Обычно сортировку используют, чтобы показать, например, самые большие или самые маленькие баллы. Или первые фамилии по алфавиту. Для этого надо перейти на 1-ю страницу при смене сортировки. Если ты меняешь сортировку и оставляешь ту же страницу, то не очень понятно, для чего это нужно. Ты не получаешь ни самые большие, ни самые маленькие баллы, а что-то из середины списка.

Везде переключают на первую страницу при смене сортировки, насколько я знаю.

>>1381843

Этот подход довольно плохой. Он мне не нравится. Во-первых, не всегда это работает, зависит от конфигурации сервера, и может получиться, что у юзера будет крутиться кружок загрузки, пока твой скрипт что-то там считает якобы в фоне. Во-вторых, php-fpm на такое не рассчитан. Там может быть ограничено число рабочих процессов, и в неудачном случае они все могут оказаться заняты этими вычислениями и некому будет обслуживать другие запросы пользователей. В-третьих, тут нет обратной связи - ты запустил вычисление, а чем оно закончилось, неизвестно. Также, часто на php-fpm ставится таймаут на время работы скрипта.

Если у тебя какой-то простой случай, не требующий очереди задач, редко вызваемый (типа генерации какого-то отчета, который генерируется минуту), то проще просто сделать страницу с кнопкой и кнопкой запрашивать скрипт аяксом, а тот скрипт генерирует отчет и возвращает. Тут ты хотя бы в итоге либо получишь отчет, либо какую-то ошибку и можно будет нажать кнопку еще раз.

Показать весь текст

158 25 апр, 05:22 158 1388214

>>1382020

> Делаю грамматического нациста, хочу сделать проверку по отсутствию знака препинания.

Проще всего искать так:

- в начале идет любая буква
- за ней пробелы
- за ней слово "а" или "но"
- за ним граница слова

>>1383863

Возможности очень хорошие, есть куча плагинов, но жрет память и проц. Если твое железо потянет, то неплохой вариант.

>>1383892

Я взял привычку всегда их ставить, и к таблицам, и к полям. Они отображаются во всяких визуальных программах для работы с БД вроде phpmyadmin.

159 25 апр, 05:31 159 1388216

>>1387125

> Можно вместо создания бесконечного количества ссылок создать поле с типом ARRAY и помещать в него все ссылки (UUID) на необходимые данные.

Можно, но это будет денормализация. Допустимо, но лучше сначала спроектировать нормализованную схему, а только потом денормализовать. И что там с внешними ключами?

> Participant:
> -messages UUID[] //массив из uuid сообщений

Это плохо масштабируется, так как у пользователя могут быть тысячи сообщений. И мы не можем быстренько выбрать часть из них. Хотя, тут стоило бы сделать микробенчмарк, а не гадать.

>>1388116

Я не вижу особой разницы. Возможно, нужен не абстрактный, а более реальный пример кода, тогда будет понятнее.

Во втором варианте можно считать результат, никуда его не сохраняя, в отличие от первого.

160 25 апр, 08:24 160 1388239

>>1388194
>>1387823
Блэт. Господа, не нужно тумана.
Почему "?" меняется на "&" просто скажите

Ответы388378

161 25 апр, 09:51 161 1388284

>>1387796
Только что переписал твой код себе и у меня как надо разбилось, на 2 строки до и после амперсанта.

Ответы388384

162 25 апр, 09:55 162 1388288

>>1387796
Попробовал и в интерпретаторе у себя и на онлайн сервисе на 5 и 6 пыхе, все работает как надо.

Ответы388289388384

163 25 апр, 09:56 163 1388289

>>1388288
7*

someApprentice !EaaiHmIJms 164 25 апр, 11:52 164 1388352

>>1388212
Ошибка постинга: В сообщении присутствует слово из спам листа.

https://pastebin.com/raw/yGsWM6BA

Ответы388928

someApprentice !EaaiHmIJms 165 25 апр, 11:58 165 1388353

Напомню посмотреть ещё этот вопрос, который мог быть не замечен из-за ошибки спам-листа >>1382907

Простите что так много вопросов, тяжело очень.

166 25 апр, 12:37 166 1388378

>>1388239

Попробуй запустить свой код на ideone и, если он работает, так как ты описал, то дай ссылку с подтверждением. Я думаю, что explode работает как надо, и ошибка в чем-то другом, или ты просто что-то перепутал.

Ответы388385

167 25 апр, 12:46 167 1388384

>>1388288
>>1388284
Такое случается если ты парсишь именно url, полученный например через $_SERVER['QUERY_STRING']

168 25 апр, 12:49 168 1388385

>>1388378
explode работает как нужно.
Это какая то особенность именно url возвращаемого $_SERVER['QUERY_STRING']
Более того - распечатай именно $_SERVER['QUERY_STRING'] на странице - и увидишь что "?" в нем заменен на "&"

Если просто строку парсить - то explode работает как нужно.

Ответы394733

169 25 апр, 15:06 169 1388460

Почему Symfony такой убогий фреймворк?

Ответы388994

170 26 апр, 05:38 170 1388926

>>1388324

> Однако, как бы подход с массивами не казался элегантным, у него есть один недостаток - для всех ORM можно переопределить условие для взаимоотношений между таблицами (прим. One-To-Many, Many-to-Many) для сущностей. В SQLAlchemy, похоже, такая возможность есть https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#specifying-alternate-join-conditions , а в Доктрине я такой возможности не нашел. Она есть?

Я думаю, что нету. Судя по https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/annotations-reference.html#annref_joincolumn там связь делается только через колонку с внешним ключом и никак иначе.

Я еще должен предупредить, что, может быть, где-то придется делать SQL-запросы напрямую, если это будет давать значительную разницу в времени выполнения запроса.

> // Получить все сообщения получателя

Вот такие запросы лучше даже не планировать. Сообщений может быть много, и все сразу получать невыгодно. Обычно сообщения всегда запрашивают какими-то кусочками, а когда пользователь прокручивает страницу, подгружают еще.

>>1382907

> Значит, нужно на серверной стороне написать такой клиент, который будет подписываться на все сообщения, валидировать их, сохранять в БД, а затем только перенаправлять клиенту пользователя.

Обычно WAMP и websocket используют как PubSub-брокер (про PubSub: http://design-pattern.ru/patterns/pubsub.html ). PubSub - это технология, когда есть программа-брокер, и к ней могут подсоединяться издатели и подписчики. Подписчики подключаются к брокеру и подписываются на интересующие их каналы или "топики". Издатели подключаются к брокеру и шлют сообщения в выбранные ими каналы. И брокер пересылает сообщения только тем подписчикам, кто подписан на канал. Список каналов нигде не хранится, это просто строка, которая позволяет отобрать получателей сообщения. Каналы/топики нужны для маршрутизации сообщений, чтобы клиенты получали только нужные им события, а не все подряд, что происходит в системе.

WAMP-сервер (программа, которая принимает вебсокет соединения на стороне сервера) обычно и служит брокером PubSub.

Это напоминает очередь сообщений вроде RabbitMQ, только без гарантий сохранности и доставки сообщений. Сообщения не сохраняются, как в очереди, в ожидании получателя, а передаются только тем, кто в данный момент подключен к брокеру. Если никто не подписан на канал, то сообщение от издателя просто отбрасывается.

Пример. Клиент (браузер) подсоединяется к WAMP-серверу. При этом код в браузере устанавливает постоянное веб-сокет соединение с WAMP-сервером, автоматически переподсоединяясь при обрыве. Используя функционал PubSub, он подписывается на канал msg-for-1234, где 1234 - это id залогиненного пользователя.

Когда кто-то шлет пользователю 1234 сообщение, серверный скрипт подсоединяется к WAMP-серверу и публикует это сообщение в канал msg-for-1234. WAMP-сервер передает это сообщение всем подписанным на канал msg-for-1234 клиентам. В данном случае это один браузер. Ему отправляется сообщение по вебсокет-соединению, и после получения браузер генерирует событие, и вызывается какой-то коллбек в JS коде. Таким образом JS код узнает о приходе нового сообщения, и отображает его на экране.

При этом обычно используются и обычные аякс-запросы, и вебсокет. Когда пользователь запускает клиент, тот получает список последних сообщений обычным АЯКС-запросом, а вебсокет используется только для получения новых сообщений с момента запуска клиента. Еще, иногда вебсокет используется только для уведомления о новых сообщениях, а само сообщение запрашивается АЯКС-запросом. Также, можно не полагаться только на вебсокет, а дополнительно раз в N минут делать классический АЯКС-запрос - на случай, если сообщение где-то потерялось, или на случай, если у нас был разрыв вебсокет-соединения и в этот момент пришло сообщение (так как WAMP вроде бы не гарантирует их сохранность и работает по принципу best effort).

Еще, тут надо помнить о безопасности: подключиться к каналу msg-for-1234 должен иметь возможность только пользователь 1234, а не кто угодно. То есть нужна какая-то авторизация на WAMP-сервере.

Так как pubSub - ненадежный механизм, использовать его для отправки сообщений с клиента не стоит. Тебе надо рассмотреть другие варианты:

- AJAX
- RPC в WAMP

RPC - это "удаленный вызов процедур". Ты с клиента делаешь вызов какой-то функции на сервере, передаешь ей параметры, а в ответ получаешь либо результат, либо ошибку. Это наверно подойдет для твоей задачи.

Плюс RPC в сравнении с аяксом - нет накладных расходов на создание соединения и на оборачивание данных в HTTP-запрос, на передачу HTTP-заголовков. Плюс аякса - больше старых браузеров его поддерживают.

Опять же, не забудь про авторизацию. А то кто угодно сможет отправлять сообщения от имени пользователя.

Вот пример вызова RPC из документации autobahn-js:

// 4) call a remote procedure
session.call('com.myapp.add2', [2, 3]).then(
function (res) {
console.log("Result:", res);
}
);

Можно сделать что-то вроде:

session.call('message.send', { to: 5678, cyphertext: 'zzzzzz', auth: 'xyz1234' }).then( ...);

На стороне сервера ты должен будешь "зарегистрировать" процедуру message.send и тогда брокер будет перенаправлять вызов от клиента твоему серверу, он обработает его и пошлет ответ, который брокер перешлет клиенту. Ты упоминаешь crossbar, и в нем есть пример "компонента", который регистрирует RPC и отвечает на вызовы:

https://github.com/crossbario/crossbar-examples/blob/master/getting-started/3.rpc/client_component_rpc_callee.py

Там есть функция utcnow(), и клиент (браузер) может ее вызывать удаленно, используя session.call().

callee в название файла обозначает "вызываемая сторона", в отличие от caller - "вызывающая сторона".

Тут конечно надо еще поподробнее изучить crossbar, если ты хочешь его использовать, чтобы понять, как он работает, как оптимальнее его настроить, итд. Нужно его потестировать, итд.

> Чтобы авторизовать публикации для клиентов напомню что они могут приходить только от сервера, нужно воспользоваться встроенным в роутер механизмом - функции динамической авторизации.

Да, наверно так. Хотя у меня ощущение, что в документации приведены примеры для небольшого числа пользователей. Например, когда ты используешь crossbar для обмена данными между несколькими устройствами, а не для многопользовательского веб-сервиса.

Потому, возможно, тебе придется делать дополнительную авторизацию на уровне RPC, например, передавать какой-то токен в RPC функцию отправки сообщения.

> // нужно проверить что это делает именно сервер
> // для этого я решил создать jwt со свойством isServer: true

Можно так, да. Хотя выглядит как усложение, конечно.

> Вопрос прост - Как вынести это n-ое количество проверок в отдельную архитектуру?

Там есть какие-то роли, может быть их можно использовать. Сделать роли "фронтенд/браузер" и "бекенд".

170 26 апр, 05:38 170 1388926

>>1388324

> Однако, как бы подход с массивами не казался элегантным, у него есть один недостаток - для всех ORM можно переопределить условие для взаимоотношений между таблицами (прим. One-To-Many, Many-to-Many) для сущностей. В SQLAlchemy, похоже, такая возможность есть https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#specifying-alternate-join-conditions , а в Доктрине я такой возможности не нашел. Она есть?

Я думаю, что нету. Судя по https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/annotations-reference.html#annref_joincolumn там связь делается только через колонку с внешним ключом и никак иначе.

Я еще должен предупредить, что, может быть, где-то придется делать SQL-запросы напрямую, если это будет давать значительную разницу в времени выполнения запроса.

> // Получить все сообщения получателя

Вот такие запросы лучше даже не планировать. Сообщений может быть много, и все сразу получать невыгодно. Обычно сообщения всегда запрашивают какими-то кусочками, а когда пользователь прокручивает страницу, подгружают еще.

>>1382907

> Значит, нужно на серверной стороне написать такой клиент, который будет подписываться на все сообщения, валидировать их, сохранять в БД, а затем только перенаправлять клиенту пользователя.

Обычно WAMP и websocket используют как PubSub-брокер (про PubSub: http://design-pattern.ru/patterns/pubsub.html ). PubSub - это технология, когда есть программа-брокер, и к ней могут подсоединяться издатели и подписчики. Подписчики подключаются к брокеру и подписываются на интересующие их каналы или "топики". Издатели подключаются к брокеру и шлют сообщения в выбранные ими каналы. И брокер пересылает сообщения только тем подписчикам, кто подписан на канал. Список каналов нигде не хранится, это просто строка, которая позволяет отобрать получателей сообщения. Каналы/топики нужны для маршрутизации сообщений, чтобы клиенты получали только нужные им события, а не все подряд, что происходит в системе.

WAMP-сервер (программа, которая принимает вебсокет соединения на стороне сервера) обычно и служит брокером PubSub.

Это напоминает очередь сообщений вроде RabbitMQ, только без гарантий сохранности и доставки сообщений. Сообщения не сохраняются, как в очереди, в ожидании получателя, а передаются только тем, кто в данный момент подключен к брокеру. Если никто не подписан на канал, то сообщение от издателя просто отбрасывается.

Пример. Клиент (браузер) подсоединяется к WAMP-серверу. При этом код в браузере устанавливает постоянное веб-сокет соединение с WAMP-сервером, автоматически переподсоединяясь при обрыве. Используя функционал PubSub, он подписывается на канал msg-for-1234, где 1234 - это id залогиненного пользователя.

Когда кто-то шлет пользователю 1234 сообщение, серверный скрипт подсоединяется к WAMP-серверу и публикует это сообщение в канал msg-for-1234. WAMP-сервер передает это сообщение всем подписанным на канал msg-for-1234 клиентам. В данном случае это один браузер. Ему отправляется сообщение по вебсокет-соединению, и после получения браузер генерирует событие, и вызывается какой-то коллбек в JS коде. Таким образом JS код узнает о приходе нового сообщения, и отображает его на экране.

При этом обычно используются и обычные аякс-запросы, и вебсокет. Когда пользователь запускает клиент, тот получает список последних сообщений обычным АЯКС-запросом, а вебсокет используется только для получения новых сообщений с момента запуска клиента. Еще, иногда вебсокет используется только для уведомления о новых сообщениях, а само сообщение запрашивается АЯКС-запросом. Также, можно не полагаться только на вебсокет, а дополнительно раз в N минут делать классический АЯКС-запрос - на случай, если сообщение где-то потерялось, или на случай, если у нас был разрыв вебсокет-соединения и в этот момент пришло сообщение (так как WAMP вроде бы не гарантирует их сохранность и работает по принципу best effort).

Еще, тут надо помнить о безопасности: подключиться к каналу msg-for-1234 должен иметь возможность только пользователь 1234, а не кто угодно. То есть нужна какая-то авторизация на WAMP-сервере.

Так как pubSub - ненадежный механизм, использовать его для отправки сообщений с клиента не стоит. Тебе надо рассмотреть другие варианты:

- AJAX
- RPC в WAMP

RPC - это "удаленный вызов процедур". Ты с клиента делаешь вызов какой-то функции на сервере, передаешь ей параметры, а в ответ получаешь либо результат, либо ошибку. Это наверно подойдет для твоей задачи.

Плюс RPC в сравнении с аяксом - нет накладных расходов на создание соединения и на оборачивание данных в HTTP-запрос, на передачу HTTP-заголовков. Плюс аякса - больше старых браузеров его поддерживают.

Опять же, не забудь про авторизацию. А то кто угодно сможет отправлять сообщения от имени пользователя.

Вот пример вызова RPC из документации autobahn-js:

// 4) call a remote procedure
session.call('com.myapp.add2', [2, 3]).then(
function (res) {
console.log("Result:", res);
}
);

Можно сделать что-то вроде:

session.call('message.send', { to: 5678, cyphertext: 'zzzzzz', auth: 'xyz1234' }).then( ...);

На стороне сервера ты должен будешь "зарегистрировать" процедуру message.send и тогда брокер будет перенаправлять вызов от клиента твоему серверу, он обработает его и пошлет ответ, который брокер перешлет клиенту. Ты упоминаешь crossbar, и в нем есть пример "компонента", который регистрирует RPC и отвечает на вызовы:

https://github.com/crossbario/crossbar-examples/blob/master/getting-started/3.rpc/client_component_rpc_callee.py

Там есть функция utcnow(), и клиент (браузер) может ее вызывать удаленно, используя session.call().

callee в название файла обозначает "вызываемая сторона", в отличие от caller - "вызывающая сторона".

Тут конечно надо еще поподробнее изучить crossbar, если ты хочешь его использовать, чтобы понять, как он работает, как оптимальнее его настроить, итд. Нужно его потестировать, итд.

> Чтобы авторизовать публикации для клиентов напомню что они могут приходить только от сервера, нужно воспользоваться встроенным в роутер механизмом - функции динамической авторизации.

Да, наверно так. Хотя у меня ощущение, что в документации приведены примеры для небольшого числа пользователей. Например, когда ты используешь crossbar для обмена данными между несколькими устройствами, а не для многопользовательского веб-сервиса.

Потому, возможно, тебе придется делать дополнительную авторизацию на уровне RPC, например, передавать какой-то токен в RPC функцию отправки сообщения.

> // нужно проверить что это делает именно сервер
> // для этого я решил создать jwt со свойством isServer: true

Можно так, да. Хотя выглядит как усложение, конечно.

> Вопрос прост - Как вынести это n-ое количество проверок в отдельную архитектуру?

Там есть какие-то роли, может быть их можно использовать. Сделать роли "фронтенд/браузер" и "бекенд".

Показать весь текст
Ответы393712

171 26 апр, 05:45 171 1388928

>>1388352

Упс, теперь и я не могу так просто постить этот текст: https://pastebin.com/J8ePkQCK

Подозреваю, это из-за слова на буквы "к", "о", "н", "ф".

Ответы389946

172 26 апр, 10:59 172 1388990

>>1388192
Чтобы разобраться как это работает

173 26 апр, 11:00 173 1388994

>>1388460А
Вынужден не согласится, пишу на нем около года, после того как понял логику разрабов, то все стало просто замечательно

someApprentice !EaaiHmIJms 174 27 апр, 09:29 174 1389598

Опять
Ошибка постинга: В сообщении присутствует слово из спам листа.

https://pastebin.com/raw/qDFCE7SL

Ответы393712394587

175 27 апр, 14:10 175 1389781

Если планируете перекатываьтся за границу, то забейте на пхп. он мертв в развитых странах.
Говорю на своем опыте. я перекатился в израиль и тут нет вакансий. нода в 2 раза востребованей. самые топовые языки тут это с#, питон и джава

Ответы389802

176 27 апр, 14:29 176 1389802

Аноны, какой редактор посоветуете?
Я пишу в VScode, но сейчас стал писать больше, и блядь VScode даже с плагинами не устраиваетили я его настроить не могу. Я хочу порядочные автодополнения, что бы редактор нормально искал методы используемого класса, что бы показывал нормально аргументы вызываемой функции.

>>1389781
У меня смутное ощущение что когда ты въедешь в саму сферу - выбор платформы это дело пятое. Какая разница на чем MVC реализовывать, если ты понимаешь как это делать. Не вижу особой разницы в этом случае между например пхп или питоном. Тем более пхп7 быстр. Думаю что он свои позиции отвоюет. JS до 2015 тоже был ссаниной, а сейчас развился и расхайпован что пиздец.
Если это не так - то уже разъясните иную точку зрения.

Ответы389813390167394587

177 27 апр, 14:40 177 1389813

>>1389802
П.С.
Я к чему - я сам выбирал в какой бекенд вкатываться, выбирал между пхп и питономи нодой. Я на тот момент знал только синтаксис этих ЯП.
По итогу порешал рыночек, и количество информации. На пхп проще заработать на первый доширак, если суетитьсяособенно удобно если у тебя уже есть работа и ты вкатываешься по вечерам. Сейчас пришел к выводу что понимание предметной области значит больше чем конретный ЯП.
Может я нуб, но я реально не понимаю какая разница между пхп и питоном в типовых задачах.

С нодой отдельная песня. У нее своя ниша, а за ее рамками не понятно зачем она нужна. Хотя и на ней можно магазины ебашить, ток нахуя.

Ответы389824

178 27 апр, 14:46 178 1389824

>>1389813
П.П.С
Вот что мне реально не нравится в пхп - то что он не создает процесса. Рожден что бы умереть короче. Ну и конфигурационные файлы сервера - то еще говно.
Но опять же, наверное пхп можно запустить как постоянный процесс, но про это я ничего не знаю пока что.

В ноде создал объект сервера http, поставил событие listening - это как то солиднее на мой взгляд.

Ответы394587

someApprentice !EaaiHmIJms 179 27 апр, 17:32 179 1389946

>>1388928
И как всегда

https://pastebin.com/raw/xeTL9JtV

Ответы394587

180 27 апр, 21:03 180 1390167

>>1389802
Пхпшторм ставь.

181 27 апр, 22:22 181 1390215

18 Кб, 265x5599 Кб, 1626x41

На собеседовании не сделал одно задание, подобное которому когда-то пытался сделать, но были проблемы.
Есть многомерный массив папок и файлов, вложенных в папки, пустые папки, либо просто файлы в корне.
$folders=array("Папка А"=>array("Папка B"=>array(), "Папка C"=>array("Файл 1", "Файл 2", "Файл 3"), "Файл 10", "Файл 11", "Файл 12"), "Файл 20", "Файл 21", "Файл 22", "Папка G"=>array());

Нужно вывести деревом как на пикрилейтед 1 с помощью функции рекурсии.

Проблемы возникают в том, что массив "Папка A" считается как ассоциативный и не идёт ключём [0], к примеру, в итоге возникают сложности с форичем. Пикрил 2.

Для начала пытался без рекурсии вывести. Более менее работает такой код, но по-ебаному совсем.

foreach ($folders as $key=>$value){
echo "$key - $value<br>";
if(is_array($value)&&count($value)>0) {
foreach ($value as $tmp=>$key2){
echo "$tmp - $key2<br>";
if(is_array($key2)&&count($key2)>0){
foreach ($key2 as $tmp2=>$key3){
echo "$tmp2 - $key3 <br>";
}
}
}
}
}

Ответы390217390238390358

182 27 апр, 22:24 182 1390217

>>1390215
https://pastebin.com/Y7WhNEjR
Код в более удобном виде.

183 27 апр, 23:03 183 1390238

>>1390215

Это решается элементарно. Обходим массив, если значение элемента это строка, то перед нами файл. Если значение - это массив - то перед нами папка, вызываем себя рекурсивно для вывода содержимого папки с отступом.

Если тебе не нравится рекурсия, можно сделать без нее, например используя стек, но будет в разы корявее.

Твой код никуда не годится, так как в нем заложена фиксированная глубина вложенности.

Ответы390365

184 28 апр, 01:23 184 1390358

>>1390215
https://ideone.com/xFFy4I
А ты не рано по вакансиям ходить начал?
Рекурсия это штука из основ проганья.

Ответы390365

185 28 апр, 01:39 185 1390365

>>1390238
Спасибо.
>>1390358
Да я уже успел поработать немного. Рекурсию я знаю, проблема была с деревом этим.
Что у тебя в $de должно идти в функцию?

Ответы390366

186 28 апр, 01:45 186 1390366

>>1390365
>Что у тебя в $de должно идти в функцию?
Глубина рекурсии.

187 29 апр, 16:04 187 1391581

Почему так много хейта в стороны пхп?

Ответы391583391618394579

188 29 апр, 16:08 188 1391583

>>1391581
>эти дебилы ITT
Сам-то как думаешь?

Ответы391585

189 29 апр, 16:10 189 1391585

>>1391583
Не знаю.
Начал учить жс, пхп, так везде натыкаюсь на хейт этого всего.
Какой-то абсурд.

Ответы391588

190 29 апр, 16:14 190 1391588

>>1391585
>Начал учить жс, пхп
Дебильными вопросами на мейлопараше срешь?
Олигофреном себя показываешь?

Ответы391591

191 29 апр, 16:17 191 1391591

>>1391588
Нет. Я вообще редко тут пишу что-то. В основном за ссылками из шапки захожу.
Почему ты такой агрессивный?

Ответы391592

192 29 апр, 16:20 192 1391592

>>1391591
>Нет.
Малаца, значит.
А вот большинство ИТТ (и, хаха, "комьюнити" говнопыхыпы) и срет и показывает - дебилы же.
Потому что подобное к подобному, уже который год.

Ответы391912

193 29 апр, 17:07 193 1391618

>>1391581
По наблюдениям могу сказать, что хейтят в основном посторонние диваны, которые услышали что-то такое от других диванов на заре своей голожопой юности. Так и продолжают крякать одно и то же чётко показывая свой уровень перед теми, кто в курсе дел.
Любому более-менее изучавшему ПХП обычно очевидно, что это вполне нормальный язык для веб-разработки со всеми современными фичами. Которой к тому же ещё и активно развивается.

Ответы391659

194 29 апр, 18:07 194 1391659

>>1391618
>нормальный язык
Что характерно, по поводу местного сборища имбецилов возражений нет.

Ответы391911391912

Аноним 195 30 апр, 08:25 195 1391911

>>1391659 Не ну тгхнн, але!

196 30 апр, 08:26 196 1391912

>>1391592
>>1391659
Перед вами пример типичной токсичной мрази, а по совместительству хейтера PHP.

197 30 апр, 09:00 197 1391936

Ого! АзиаткаПХП-кун всё ещё на дваче! Вот это поворот. Я думал ты уже - всё.

Алсо, собираюсь использовать пхп для системного скриптинга. Почему? Потому что я могу. По кр. мере пока мне так кажется. Сокеты есть. Птредс есть. Всякие fork есть. Что ещё нужно? Да вроде всё.

Какие подводные?

Ответы392059394579

25 Кб, 338x486
198 30 апр, 13:02 198 1392059

>>1391936
>пхп для системного скриптинга
С веб-мордой? Обязательно надо с веб мордой.

Ответы392438

199 1 мая, 07:30 199 1392401

Имеет смысл делать свой mvc или использовать фреймворки?

Ответы392404392451394579

200 1 мая, 07:39 200 1392404

>>1392401
Шел 2020 год. MVC все еще воспринимался пыхарями как килерфича.
У нас в Китае казнят за изобретение нового иероглифа, если ты не обяснишь зачем он нужен.

Ответы394579

201 1 мая, 10:15 201 1392437

есть хороший курс по ларе для новичка?

Ответы392608

202 1 мая, 10:17 202 1392438

>>1392059

Да, и что ты мне сделаешь? Это всё будет работать на локалхосте.

Хочу запилить сетевой демон, который будет выполнять как одноразовые, так и бесконечно выполняемые команды в виде дочерних процессов и осуществлять менеджмент этих процессов. Чтобы не заходить по ssh и не пердолиться в консоли и тмуксы, а хуяк и запустил всё одной кнопкой и сидишь, откинувшись на спинку кресла, и смотришь как всё работает.

Как тебе такое?

Ответы394579

203 1 мая, 11:17 203 1392451

>>1392401
Разобраться в любом случае придётся - все ходовые фреймворки работают по этому принципу. А лучший способ это сделать - собрать свой велосипед. Да и у ОПа есть по этой теме кое-что.

Ответы392460

204 1 мая, 11:43 204 1392460

>>1392451

Тут тебя ждет разочарование, потому что способов релизации MVC фреймворка столько, сколько понимания, что значит M, что V, а что C и что с чем "рационально" объединить и на сколько объединить.

Там болото, анон. Не лезь. Возьми какой-то один популярный фреймворк и тщательно разберись.

Ответы392626

205 1 мая, 16:15 205 1392608

>>1392437
laracasts

Ответы392664

206 1 мая, 16:46 206 1392626

>>1392460
>потому что способов релизации MVC фреймворка столько
Выбирай любой. Или три.

>Там болото, анон. Не лезь.
Да и вообще нахуй это надо. Сразу на завод - говно месить лопатой. Там разбираться не приходится.

А ещё руками иногда нагляднее получается попробовать.

Ответы392679

207 1 мая, 17:44 207 1392664

>>1392608
на слух английский не понимаю,че нибудь письменное есть?

Ответы392823

208 1 мая, 18:16 208 1392679

>>1392626
>Да и вообще нахуй это надо. Сразу на завод - говно месить лопатой. Там разбираться не приходится.
Самый годный совет

209 1 мая, 22:42 209 1392823

>>1392664
Можешь их на ютубе смотреть с субтитрами

210 2 мая, 06:39 210 1392888

Аноны, я выучил PHP со всеми этими ООП и теперь могу писать свои велосипедные сайты.

Скажите, изучать Laravel сложнее, чем всё то, что я уже изучил? Или будет проще?

Ответы392905393253394576

211 2 мая, 09:21 211 1392905

>>1392888
>Скажите, изучать чем всё то, что я уже изучил?
Откуда мы знаем что тебе будет проще? Это же всё индивидуально.

Берешь изучаешь. Если что-то не понятно сюда задаешь вопрос по языку, а не психологии.

>Или будет проще?
Будет проще, если начнешь изучать.

Вообще, вот тебе совет... (В информатике) первым шагом перед решением задачи, это сбор информации и оценка сил и времени на это задачу.

Поищи примеры/посмотри на ютюбе... Научись самостоятельно добывать информацию.

212 2 мая, 16:52 212 1393036

Аноны, есть вопрос. Допустим, я хочу агрегатор сделать. С самим сайтом понятно все - просто выдаёт все из базы. А как в общих чертах правильно делать часть, которая все тащить будет в базу с других ресурсов? Может за папкой проекта на сервере будет ещё одна со скриптами, которые cron будет запускать, например, каждые 5 минут. Они будут каждые 5 минут сгребать все базу?

Ответы393393394575

213 3 мая, 01:16 213 1393246

>>1387082
бамп

Ответы394576

214 3 мая, 02:17 214 1393253

>>1392888
>Аноны, я выучил PHP со всеми этими ООП
Это примерно несколько сотен строк достаточно примитивного кода в процедурном стиле из разряда сел и написал в один файл скрипт.

>Скажите, изучать Laravel сложнее, чем всё то, что я уже изучил? Или будет проще?
Это несколько тысяч строк достаточно нетривиального кода, размещенного в сотне взаимосвязанных файлов, архитектура mvc и паттерны проектирования.

Ответы393254

215 3 мая, 02:26 215 1393254

>>1393253
Благодарю за понятный мне ответ.

216 3 мая, 02:28 216 1393255

>>1380485 (OP)
140к на руки с опытом 2,5 года в дс на пыхе - это успех?

Ответы393265

217 3 мая, 04:17 217 1393265

>>1393255
Расскажи как устраивался на работу, какие вопросы были ? Что нужно знать/уметь делать чтоб устроиться ?

Ответы393335

218 3 мая, 11:23 218 1393335

>>1393265
Учил пыху в этом самом треде (тут всё ещё тот же помогающий ОП? не верится, что столько времени прошло).

Без задней мысли после полугода аутирования в треде пошёл на собесы, спрашивали базовые вещи, про ООП, наследование, типы данных, sql.
На джуна ничего не надо УМЕТЬ, но надо знать, и главное, показаться ТОЛКОВЫМ.
всё изи:
1) принципы ооп
2) solid
3) паттерны GoF
4) кто-нибудь спросит про сортировки, но хз, надо ли тебе в такую контору (мейлсру и прочие спросят 100%, рога и копыта нет)
5) новые фичи php7+
6) базовый sql, простые запросы и джоины, про индексы могут спросить

Ответы393338393353393358393392393400393402393456

219 3 мая, 11:28 219 1393338

>>1393335
А по верстке и js спрашивают?

Ответы393348

220 3 мая, 11:54 220 1393348

>>1393338
ну... если ты на бекендера идёшь, то нет. Если на фуллстек (не иди туда), то могут, а могут и не спросить.
Когда на первую устраивался, то js даже в глаза не видел. Взяли и в итоге ковырял всё, даже css, попутно научившись. Но это дно-места. В нормальных конторах такие вещи разделены между разными специалистами

221 3 мая, 12:04 221 1393353

>>1393335
>2) solid
>3) паттерны GoF
Ебать, в первый раз такое слышу.

Ответы393374

222 3 мая, 12:12 222 1393358

>>1393335
А надо свои проекты показывать ?

Ответы393360393362

223 3 мая, 12:15 223 1393360

>>1393358
При всех или наедине с эйчаркой?

224 3 мая, 12:21 224 1393362

>>1393358
меня не просили. Но в резюме прикреплял ссылку на гитхаб с выполненным заданием "кошки-мышки" (не знаю, есть ли оно ещё в шапке), лол. На одном собесе попросили про него рассказать даже.

Сейчас скажу, что большинство не смотрит гитхабы, но, если посмотрят, то это плюс и тебе, и конторе (тк адекваты).

225 3 мая, 12:52 225 1393374

>>1393353
>solid
Без этого твой код никому не нужен так как будет нечитаемой лапшой.
>паттерны GoF
Как-то сомнительно, что такое у джуна спрашивают. Нелогично это получается - про наследование спросили и тут же про паттерны? Это немного разные уровни ООП.

Ответы393376

226 3 мая, 12:54 226 1393376

>>1393374
>>solid
>Без этого твой код никому не нужен так как будет нечитаемой лапшой.
В смысле без полного набора: solid, kiss, dry

Ответы393384

227 3 мая, 13:11 227 1393384

>>1393376
Dry and kiss my solid yagni

Ответы393428

228 3 мая, 13:11 228 1393386

Объясните пожалуйста.
1) Как реализовать конструктор в классе, который реализует паттерн TableDataGateway? В примере ОП использует PDO и конструктор выглядит так:
public function __construct(PDO $pdo) { ... }
а я использую mysqli могу ли я написать
public function __construct($conn) { ... }?
Так же не понятно, что мне писать в самом конструкторе? Подключение к базе данных или что?
2)С исключениями я тоже не понял. Могу ли я их не использовать, а писать просто
$conn = new mysqli ($hn, $un, $pw, $db);
if($conn->connect_error) die($conn->connect_error);
?

Ответы393389393396393429394513

229 3 мая, 13:16 229 1393389

>>1393386
Насчет первого вопроса я просто не понял зачем оп написал PDO в функции, что это за уточнение?

Ответы393398394575

230 3 мая, 13:21 230 1393392

>>1393335
Какие вообще шаблоны проектирования ты использовал за это время в работе реальной?

Ответы393394

231 3 мая, 13:22 231 1393393

>>1393036
бамп

232 3 мая, 13:23 232 1393394

>>1393392
команда, фабричный метод, абстрактная фабрика, декоратор, фасад. Дохуя на самом деле, если ты не битриксовая шлюха, то без них никуда.

233 3 мая, 13:26 233 1393396

>>1393386
>а я использую mysqli
зачем? Юзай pdo
>Подключение к базе данных или что?
не смотрел пример ОПа, но в классе PDO коннекшн уже же будет установлен?
>С исключениями я тоже не понял. Могу ли я их не использовать, а писать просто
можешь. Зачем тебе только это? Твой die() выйдет из программы и всё, а исключение можно обработать и продолжать работать дальше.

Привыкай к ним, die и exit в реальном коде не встретишь

Ответы393514

234 3 мая, 13:34 234 1393398

>>1393389
>PDO в функции, что это за уточнение
гугли type hinting и вообще научись гуглить простые места, ебать, тебе весь php.net пересказывать?

235 3 мая, 13:40 235 1393400

>>1393335
А на 140 к какие вопросы на собесе были? Что по английскому у тебя?

Ответы393617

236 3 мая, 13:51 236 1393402

>>1393335
Как вообще рынок пыхи оцениваешь, свалить в другой стек не думал? Не надоело?

Ответы393617

237 3 мая, 14:44 237 1393428

>>1393384
Точно.

238 3 мая, 14:49 238 1393429

>>1393386
>а я использую mysqli могу ли я написать
>public function __construct($conn) { ... }?
Да просто оберни mysqli в класс и всё.
Я бы тогда ещё и интерфейс сделал, чтобы можно было как через ПДО ходить, так и через твою обёртку.

Ответы393514394575

239 3 мая, 16:01 239 1393456

>>1393335
160к за год (точнее 11 месяцев)

Ответы393617

240 3 мая, 16:50 240 1393471

Насколько плохо делать проверку на instanceof внутри класса-родителя? Типа

[CODE]class A {

function test() { if ($this instanceof B) doSomething(); }

}

class B extends A {}[/CODE]

Просто пришел к тому, что в функции test() класса А надо реализовать функционал, специфичный для класса B, при сохранении всего существующего функционала. Причем эта проверка будет запрятана на глубине одного цикла и try-catch, то есть нельзя выйти из ситуации кодом типа [CODE]class B extends A { function test() { parent::test(); doSomething(); } }.[/CODE]

Как выйти из ситуации, или такое норм?

Ответы394054394571

241 3 мая, 19:24 241 1393514

>>1393396
>>1393396
>Юзай pdo
В книге, которую я читаю, используют mysqli. Мне его использовать удобней.
>PDO коннекшн уже же будет установлен?
Не понял
>Зачем тебе только это?
Да вот собственно вопрос. Оп пишет что исключение сокращает код, только у меня чет наоборот. Ну и нигде нормального объяснения про исключения не могу найти.
Так же видел, что нельзя использовать класс Exception. С классом Exception вопросы. Мне нужно создать свой класс, который унаследует Exception? А что в нем писать?
Ну и не понятно зачем отлавливать ошибку если можно вместо die
отправить HTML страницу с ошибкой. Но в задании этого нет, так что делать я этого не буду.

>>1393429
Во во, тоже вопрос. ОП вроде тоже писал про обертку mysqli или не он. Что это значит? Зачем нужно? Как реализовать я даже не спрашиваю. И что так mysqli не любят?

Ответы393541393617394513394575

45 Кб, 532x495
242 3 мая, 19:31 242 1393518

привет,я снова вернулся в это тред,спустя стольких месяцев,чтобы вы порадовались
пхп гавно

243 3 мая, 20:21 243 1393541

>>1393514
>про обертку mysqli
>Что это значит?
То и значит - оберни в класс функционал mysqli, который тебе нужен.
>Зачем нужно?
Банально удобнее работать с такими вещами через объекты.
Ну и по ТЗ нужен ООП.
>Как реализовать я даже не спрашиваю
Объяснять дольше чем класс писать. С этой хренью любой ждун за 10 минут справится. Гугл подоёбывай по этой теме.

1,2 Мб, 1268x1446
244 3 мая, 21:05 244 1393551

Привет ребята, первый раз в треде. Что учить чтоб вкатиться в пхп?
На данный момент что я сделал:
-Самостоятельно написал на паттернах и ООП примитивную цмс.
-Калькулятор на джаваскрипте
-Лэндинги на ларавел
-Немного опыта коммерческого на вордпрессе когда-то был.
Одно собеседование провалил, спрашивали по бутстрапу и фронту, хотя шёл на ларавел-позицию.
Тестовое задание провалил на другую вакансию, реализация мини-гугла с 100.000 строками в БД, на jquery и пхп(завалил фронт)

В общем наверное буду дальше дрочить ларавел и попробую начать вью, если спрашивают и фронт, я правильно делаю? Не нужно идти в битриксы и подобное? Там вообще с улицы берут, а на иностранные фреймворки порог какой-то довольно высокий.

Ответы393553393560394575

245 3 мая, 21:11 245 1393553

>>1393551
>-Лэндинги на ларавел
Как ты их писал, если во фронт не можешь, а он там главное?

Ответы393556

246 3 мая, 21:21 246 1393556

>>1393553
Ну это просто примитив на ларке, шаблон скачал на хтмл, распилил блэйдом, красивых джквери-модулей прикрутил. Данные все через БД просто в учебных целях.

247 3 мая, 21:28 247 1393560

>>1393551
>На данный момент что я сделал:
И сколько времени ушло на поднятия скилла до уровня "я слелал" ?

Ответы393561

248 3 мая, 21:32 248 1393561

>>1393560
8 месяцев где-то.

Ответы393563

249 3 мая, 21:35 249 1393563

>>1393561
А такой результат за 8 мес это ок ли не ок ?

Ответы393564

250 3 мая, 21:41 250 1393564

>>1393563
А хрен его знает. С одной стороны я фундаментально готовился, с другой стороны я только окунулся в фреймворки, ведь никому чистый пхп не нужен.
Может и ок, учитывая что я сам без курсов и сам программу делал себе. Думаю на курсах это гораздо быстрее дело шло.

Ответы393566

251 3 мая, 21:46 251 1393566

>>1393564
Я в этом не шарю, просто смотрел зп джунов в ДС, и решил зебажать сюда.
ИМХО чет вам на джуне мало платят, Да, конечно, джун только начало и перспективы на 300к/сек, но в начале мало.

Ответы393568

7 Кб, 225x225
252 3 мая, 21:47 252 1393567

Есть тут вообще кто ларавел тоже изучает?

Ответы393569393583

253 3 мая, 21:51 253 1393568

>>1393566
Да и не на джуне тоже не много. Зарплаты из вакансий на собесах косят. Так что беги от сюда зайчик забегайчик.

254 3 мая, 21:53 254 1393569

>>1393567
как ты можешь изучать эту мерзость?

Ответы393570

255 3 мая, 21:56 255 1393570

>>1393569
Поясни

Ответы393571

256 3 мая, 21:57 256 1393571

>>1393570
тормознутый и на пхп

Ответы393572

257 3 мая, 21:58 257 1393572

>>1393571
И что ты на нём разрабатывал? Покажи.

Ответы393575

258 3 мая, 21:59 258 1393575

>>1393572
фейсбук

259 3 мая, 22:16 259 1393583

>>1393567
а че не симфони?

260 3 мая, 23:41 260 1393617

>>1393400
>Что по английскому у тебя
с англ ок, на русском тех литру не читаю в принципе
>А на 140 к какие вопросы на собесе были
очень много вопросов по sql и по безумным джоинам. В остальном вопросы разные, от логических задачек в яндексе (не взяли) до вопросов про то, как реализован массив в ядре пхп
>>1393402
>Как вообще рынок пыхи оцениваешь
в рашке большой, но разный, серьёзное погромирование только на симфони и немножко лара, его мало, в остальном пхп рынок это дно уровня вордпресса и битрикса, это путь в никуда и дерьмо полное, не тратьте время. В европе он побольше, но всё равно так себе, слишком дурная слава у пыхи. Хотя язык хороший
>>1393456
не понял

>>1393514
>которую я читаю, используют mysqli
и что блядь, я говорю тебе, это дерьмо в приличном обществе даже не упоминают, а ты
>Мне его использовать удобней.
Просто погугли mysqli vs pdo php и почитай тонны текста.
>Оп пишет что исключение сокращает код
оп всё правильно пишет, любой новичок поначалу не понимает, зачем нужны исключения. Я тебе дал пищу для размышлений по поводу того, что die безусловно заканчивает работу программы.
>Ну и нигде нормального объяснения про исключения не могу найти.
exception почти в неизменном виде есть в Java/Php/C++/C#/js, написаны килотонны паст и разбито много копий, а ты не можешь найти объяснения. Главное качество погромиста - умение гуглить, запомни.
>зачем отлавливать ошибку если можно вместо die
вот прям так и загугли. Только не на русском, конечно

Ответы393623393729394459394513

261 3 мая, 23:55 261 1393623

>>1393617
на чём пишешь? Перспективно учить ларавел сейчас для пыхи?

Ответы393628

262 4 мая, 00:06 262 1393628

>>1393623
пишу на симфони.
>Перспективно
да. Спрос есть и разработка на ларе зачастую попадает под категорию "серьёзное программирование". Но если есть выбор, делай в сторону симфони.

Ответы393714393724

263 4 мая, 00:19 263 1393636

Как выполняется код в пыхе при одновременном запросе? Представим ситуацию, что два пользователя(или больше) нажали одновременно одну кнопку, которая общается с базой данных. В этом запросе берётся ид последней записи(count всех записей), создаётся новая запись и берётся её ид. Возможно ли, что возьмётся ид второй созданной записи(тип сначала от первого юзера, потом от второго)? Или лучше самостоятельно присвоить ид +1 от последнего?

Ответы393656394575

264 4 мая, 01:07 264 1393656

>>1393636
Пых сам не обрабатывет http запросы. Запросы обрабатываются сервером (apache, nginx) затем на каждый запрос создается (гурбо говоря) отдельный процесс php, которому через стандартный ввод stdin и переменные окружения передаются параметры запроса. Данные попадают в массив $GLOBALS. Все запросы обрабатываются независимо.

Пых сам не обрабатывет SQL запросы. Он соеденяется с СУБД и передает через сокет запрос. СУБД выполняет запрос независимо от процесса PHP

id записи в базе данных обычно автоматически инкрементируется при создании новой записи. На момент выполнения запроса к СУБД таблица блокируется на запись для других запросов (грубо говоря). Все изменения с таблицей будут последовательны.

Ответы394166394573

someApprentice !EaaiHmIJms 265 4 мая, 09:49 265 1393712

>>1389598 -> >>1388926

>>1388926
>> // нужно проверить что это делает именно сервер
>> // для этого я решил создать jwt со свойством isServer: true
>
>Можно так, да. Хотя выглядит как усложение, конечно.
Мне хочется сделать проверку на сервер как проверку на обычного пользователя. То есть, при установки приложения сделать в БД первого пользователя с именем root, и дальше делать все проверки от него.

Это очень удобно:

def authenticate(token):
... return user

# if user.name == 'root':
if user.email == 'rKKDootANUScryptevucrPUNCTUMc*qjom' #понадёжней т.к. уникальный идентификатор
...

Следует сделать скрипт, который будет принимать все credentials, выполнять всю установку, а на выход выдавать все хэши и токены. Возможно генерировать сразу .env файл.

Как обычно делаются такие файлы? Через Докер (не разу с ним не знакомился)? Приложение становится всё больше мултиязычным и делать этот скрипт на каком-то из языков не логично. Лучше сделать это на системном языке и чтобы он был кроссплатформенный. Можете что-нибудь посоветовать пожалуйста?

Вопрос по синтаксису или скорее архитектуре Питона:

Я создавал модели в соответствии с задуманной схемы БД и из-за наследования в ней, мне пришлось делать наследования и в моделях - такое поддерживается и "приветствуется" в выбранной мной ORM.

Чтобы описать проблему, следует сперва показать код https://repl.it/repls/PoliteHappyScales

Как можно заметить, при инициализации приложения возникает ошибка в text_message.py. Поискав в интернете, я выяснил что это проблема называется cyclic dependency inheritance.

Чтобы решить её, я вынес все наследования в отдельный модуль: https://repl.it/repls/PowderblueInsidiousCubase

Я правильно поступил?

someApprentice !EaaiHmIJms 265 4 мая, 09:49 265 1393712

>>1389598 -> >>1388926

>>1388926
>> // нужно проверить что это делает именно сервер
>> // для этого я решил создать jwt со свойством isServer: true
>
>Можно так, да. Хотя выглядит как усложение, конечно.
Мне хочется сделать проверку на сервер как проверку на обычного пользователя. То есть, при установки приложения сделать в БД первого пользователя с именем root, и дальше делать все проверки от него.

Это очень удобно:

def authenticate(token):
... return user

# if user.name == 'root':
if user.email == 'rKKDootANUScryptevucrPUNCTUMc*qjom' #понадёжней т.к. уникальный идентификатор
...

Следует сделать скрипт, который будет принимать все credentials, выполнять всю установку, а на выход выдавать все хэши и токены. Возможно генерировать сразу .env файл.

Как обычно делаются такие файлы? Через Докер (не разу с ним не знакомился)? Приложение становится всё больше мултиязычным и делать этот скрипт на каком-то из языков не логично. Лучше сделать это на системном языке и чтобы он был кроссплатформенный. Можете что-нибудь посоветовать пожалуйста?

Вопрос по синтаксису или скорее архитектуре Питона:

Я создавал модели в соответствии с задуманной схемы БД и из-за наследования в ней, мне пришлось делать наследования и в моделях - такое поддерживается и "приветствуется" в выбранной мной ORM.

Чтобы описать проблему, следует сперва показать код https://repl.it/repls/PoliteHappyScales

Как можно заметить, при инициализации приложения возникает ошибка в text_message.py. Поискав в интернете, я выяснил что это проблема называется cyclic dependency inheritance.

Чтобы решить её, я вынес все наследования в отдельный модуль: https://repl.it/repls/PowderblueInsidiousCubase

Я правильно поступил?

Показать весь текст
Ответы394573

266 4 мая, 09:59 266 1393714

>>1393628
Сколько часов в неделю уходит на работу + обучение не считая обедов и прочего отдыха?

Ответы393737

157 Кб, 680x753
267 4 мая, 10:32 267 1393724

>>1393628
А какой фронт? Это нормально когда я пришёл на джуна по ларке, а меня спрашивают кроме ларки ещё по реакт/вью и бутстрап? Что бы ты посоветовал, углубляться в бэк или распыляться на фронт, чтобы найти работу?

Ответы393737

268 4 мая, 10:46 268 1393729

>>1393617
>от логических задачек в яндексе
Что за задачи хоть были? Такие которые не решаются обычными смертными без анало-математического мышления или все таки к ним можно было подготовиться?
Че вообще думаешь? Это же получается ты не попадешь на верхушку ITяндекса ЛОЛ, как переживешь?

Ответы393737394571

269 4 мая, 11:08 269 1393737

>>1393714
если интересный проект на работе, то работаю все рабочее время (7 часов примерно), а дома отдыхаю. Если проект так себе, то половину времени на работе прокрастинирую. Дома сейчас мини проект на расте пишу ради фана + один пупен-сорс на пыхе. Пару часов вечером, иногда 0.

>>1393724
>Это нормально
in the grand scheme of things это хуёво, тк нормально, когда есть деление: бекендеры, фронты (у нас есть алсо отдельные верстальщики, то есть фронты только js пилят). Я, например, вообще не разбираюсь в современном js и не особо хочу разбираться. И не страдаю.

Но очень часто (вот прям очень) конторы берут себе фуллстеков, и на дуде игрецов и жнецов и швецов (экономят). Ясное дело, что один человек не может (ну просто не хватит сил у него и нервов) разбираться хорошо и в беке, и в бд, и в продвинутом современном js. Так что экономия выходит боком.
Сам начинал в подобном месте. Начинать там нормально, но как решишься работу менять, уже ищи внимательнее. И всегда на собесах прямо спрашивай, не придётся ли ковырять фронт.

>Что бы ты посоветовал
только углубляться. Хороший фронт/бек всем нужен. Фуллстек - ни рыба ни мясо, нужен только рогам и копытам для экономии.

>>1393729
логические, не относящиеся к матеше. Чисто как из мы-вам-перезвоним-тредов про лампочки и переворачивания монеток.
>как переживешь?
ну сейчас не попал, но тоже оч хорошее место нашёл. Через год примерно снова буду искать и опять в яндех попробую, хули нет. Подготовлюсь получше, всё в наших руках

Ответы393751

270 4 мая, 12:04 270 1393751

>>1393737
Как раст?

Ответы393756

271 4 мая, 12:19 271 1393756

>>1393751
няшный

272 4 мая, 21:12 272 1394054

>>1393471
Бамп вопросу

14 Кб, 149x572
273 4 мая, 23:02 273 1394148

Антошки, памагите. Есть два массива, оба ассоциативные. Смысл таков, что значения первого и ключи второго идентичны. Как скрестить таким образом, чтобы получился массив с ключами первого и значениями второго массива? Разумеется все лишние варианты просто игнорить за ненадобностью.

Ответы394160394185394571

274 4 мая, 23:12 274 1394160

>>1394148
Тебе функций для работы с массивами что ли мало?

Ответы394162

275 4 мая, 23:13 275 1394162

>>1394160
Их дохуя и нет ни одной нужной. По крайней мере единственная, что по описанию подходит - требует равное количество элементов в обоих массивах.

Ответы394174394200

276 4 мая, 23:15 276 1394166

>>1393656
>Пых сам не обрабатывет http запросы. Запросы обрабатываются сервером (apache, nginx) затем на каждый запрос создается (гурбо говоря) отдельный процесс php, которому через стандартный ввод stdin и переменные окружения передаются параметры запроса.
Ваш пых совсем не умеет в демонизацию и асинхронность?

Ответы394178394181394569

277 4 мая, 23:23 277 1394174

>>1394162
Тогда ручками делай.

Ответы394179

278 4 мая, 23:25 278 1394178

>>1394166
А надо?

279 4 мая, 23:25 279 1394179

>>1394174
Ну, у меня только такой вариант в голову пришёл "Ну раз нет функции, которая могёт это ебануть сама. То юзать внутренний указатель массива и прогонять через цикл, брать значение элемента из первого массива и на его место подставлять значение элемента второго массива, после отправляя указатель на следующий элемент". Насколько это тупо?

280 4 мая, 23:26 280 1394181

>>1394166
Он же интерпретируемый.

Ответы394184

281 4 мая, 23:27 281 1394184

>>1394181
Что дальше?

20 Кб, 528x176
282 4 мая, 23:27 282 1394185

>>1394148
Вырезать значения из второго, создать третий массив и записать туда ключи первого, значения второго.

Ответы394197394218

283 4 мая, 23:33 283 1394197

>>1394185
А выборку нужных как делать? Мне же не рандомные нужны, а вполне конкретные. Значения первого = ключи второго. У меня в этом проблема, как эту выборку сделать, дабы ебануть третий массив.

Ответы394198394208

284 4 мая, 23:33 284 1394198

>>1394197
Значения перовго = ключи второго, значения которых и нужны.

285 4 мая, 23:33 285 1394200

>>1394162
Жопой прочитал документацию, ищи еще.
Даю подсказку: решение в одну строку, используется две функции, обе array_*. И ты близок к истине: твой вопрос задан верно, что есть 50% успеха — одна из функций именно скрещивает массивы.

Ответы394202394240

286 4 мая, 23:35 286 1394202

>>1394200
Удвою.
Я как минимум 3 способа увидел.

287 4 мая, 23:42 287 1394208

>>1394197
> Как скрестить таким образом, чтобы получился массив с ключами первого и значениями второго массива?
>Значения первого = ключи второго.
Ты сам определиться не можешь что тебе нужно? Научись для начала задачу описывать чётко.

Ответы394214

288 4 мая, 23:45 288 1394214

>>1394208
Второй для описания принципа скрещивания. То есть в первом массиве значение идентично нужному ключу второго массива, значение которого мне и требуется для получения массива аля:
ключ первого массива => значение второго массива.

Ответы394226

289 4 мая, 23:49 289 1394218

>>1394185
Ты специально так коряво написал?

290 4 мая, 23:55 290 1394226

>>1394214
То есть тебе нужны элементы второго массива с ключами 1,9, 17, 25, 33, 41, 49, а условие какие ключи задаётся первым массивом?

Ответы394227

291 4 мая, 23:56 291 1394227

>>1394226
Да.

292 4 мая, 23:58 292 1394228

>>1380485 (OP)
Читая коменты повышаю самооценку.

Ответы394233394569

293 5 мая, 00:03 293 1394233

>>1394228
Она у тебя настолько низкая, что ты на нубасах её повышаешь? Хуёво быть тобой.

294 5 мая, 00:13 294 1394240

>>1394200
Даже не приблизился. Что функции хоть делают? Мне даже приблизительно трудно представить как это действие на две части делить.

Ответы394245394248394261

295 5 мая, 00:17 295 1394245

>>1394240
Думаю, что надо взять значения одного массива и ключи другого, потом сделать схождение.

Ответы394247

296 5 мая, 00:17 296 1394247

>>1394245
Что такое схождение? Я заебался гуглить термины в этой документации. Нигде нет описания, что это такое. Только задачи мол сделай схождение.

Ответы394258394571

297 5 мая, 00:18 297 1394248

>>1394240
Можно ещё тупо фильтрануть.
Можно форичем сделать.

Кто больше?

298 5 мая, 00:26 298 1394258

>>1394247
А что у тебя там требовало одинаковых по длине массивов? Можно ведь и нулями недостающее заполнить. Хотя это не лучшее решение.

Какое раздолье бля.

299 5 мая, 00:28 299 1394261

>>1394240
Одна меняет местами ключи и значения, другая ищет пересечения ключей в двух массивах.

Ответы394267394269394283

300 5 мая, 00:34 300 1394267

>>1394261
А, ну и затем у тебя есть два одинаковых по длине массива. Далее применяешь ту самую функцию, которую ты уже нашел.

Ты главное, помни, потом этот код читать тебе и другим. Пиши так, чтоб понятно было, в том числе тебе. Поэтому можешь и foreach забомбить.

301 5 мая, 00:35 301 1394269

>>1394261
Ты лучше скажи, как удалить все значения массива после конкретного элемента? Ваще похуй, можно от ключей отказаться и перевести всё в обычный массив или ещё как. Главное оставить в массиве определённое количество значений, с первого и до определённого. Допустим, двадцатого.

Ответы394273394569

302 5 мая, 00:42 302 1394273

>>1394269
В документации всё есть.

303 5 мая, 00:55 303 1394283

>>1394261
Лол, получилось! Спасибо, антоша! Как тебя отблагодарить?

Ответы394286

304 5 мая, 00:58 304 1394286

>>1394283
Ты молодец. Можешь выпить чаю за мое здоровье.

Ответы394287

305 5 мая, 00:59 305 1394287

>>1394286
Обязательно.

306 5 мая, 03:47 306 1394323

На какой стул сесть? Linux или vagrant?
инфибо опенсервер

Ответы394377394386

307 5 мая, 10:50 307 1394377

>>1394323
Конечно LAMP, убунту ставь и учись.

308 5 мая, 11:14 308 1394386

52 Кб, 690x630105 Кб, 1193x693

>>1380485 (OP)
Помогите криворукому поставить тему на юйку (yii2)
делал по этому гайду https://medium.com/@jsnook_58598/how-to-use-a-bootstrap-4-theme-with-yii2-974a6dcca986
ошибка пик 1
бандл у меня пик 2
или отправьте читать тему в документации на которой я проебался
>>1394323
Да что удобнее то и ставь
вамп от лампа не прям чтоб особо отличается, по моему первому впечатлению по крайней мере

Ответы394569

102 Кб, 1064x569
309 5 мая, 14:12 309 1394459

>>1393617
Не хотел засорять, но с исключениями остались вопросы
>и что блядь, я говорю тебе, это дерьмо в приличном обществе даже не упоминают, а ты
Ну так я это прочитал в бестселлере, который имеет 4 издание. Тебя в яндекс не взяли так что не знаю про какое общество ты говоришь. Но так как я не считаю яндекс каким то топовым местом и перейти на PDO мне не трудно

>оп всё правильно пишет, любой новичок поначалу не понимает, зачем нужны исключения.
Вот смотри как выглядит задача, которую я программирую(задача ОПа). Есть список студентов в БД. Мы должны к нему подключится. Если подключение не удалось я НИЧЕГО НЕ ДЕЛАЮ. Все, прога завершает свою работу. Естественно на боевом сервере нужно было бы вывести красивую ошибку, но сейчас не про это. Мой вопрос заключается вот в чем. Зачем использовать исключения, если:
1) Этот код занимает больше места чем тот вариант который я написал;
Сравни
try {
$dbh = new PDO('mysql:host=localhost;dbname=""', $user, $pass);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}

и

$conn = new mysqli ($hn, $un, $pw, $db);
if($conn->connect_error) die($conn->connect_error);

Ну кстати первый вариант с pdo, а второй с mysqli. Я просто не знаю как можно сокращено написать с pdo. Где то их вооб
2) Так еще вместо die() если это нужно конечно можно было бы подключить файл с выводом той красочной страницы с ошибкой, мол НЕ УДАЛОСЬ ПОДКЛЮЧИТЬСЯ С БАЗОЙ ДАННЫХ, ПРИНОСИМ ИЗВИНЕНИЯ.

Короче, суть в этих словах: если не знаешь, как обрабатывать - не обрабатывай никак. РНР прекрасно справляется с базовой обработкой и сам.
Ловить исключение только ради того чтобы поймать - бессмысленно.
Поэтому лучше оставить всё как есть, а ловить исключение только тогда, когда точно знаешь, что хочешь сделать, поймав.

Я это все пишу не для того чтобы поспорить. Просто мне кажется так мы сокращаем строчки кода вроде бы без ущерба.

102 Кб, 1064x569
309 5 мая, 14:12 309 1394459

>>1393617
Не хотел засорять, но с исключениями остались вопросы
>и что блядь, я говорю тебе, это дерьмо в приличном обществе даже не упоминают, а ты
Ну так я это прочитал в бестселлере, который имеет 4 издание. Тебя в яндекс не взяли так что не знаю про какое общество ты говоришь. Но так как я не считаю яндекс каким то топовым местом и перейти на PDO мне не трудно

>оп всё правильно пишет, любой новичок поначалу не понимает, зачем нужны исключения.
Вот смотри как выглядит задача, которую я программирую(задача ОПа). Есть список студентов в БД. Мы должны к нему подключится. Если подключение не удалось я НИЧЕГО НЕ ДЕЛАЮ. Все, прога завершает свою работу. Естественно на боевом сервере нужно было бы вывести красивую ошибку, но сейчас не про это. Мой вопрос заключается вот в чем. Зачем использовать исключения, если:
1) Этот код занимает больше места чем тот вариант который я написал;
Сравни
try {
$dbh = new PDO('mysql:host=localhost;dbname=""', $user, $pass);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}

и

$conn = new mysqli ($hn, $un, $pw, $db);
if($conn->connect_error) die($conn->connect_error);

Ну кстати первый вариант с pdo, а второй с mysqli. Я просто не знаю как можно сокращено написать с pdo. Где то их вооб
2) Так еще вместо die() если это нужно конечно можно было бы подключить файл с выводом той красочной страницы с ошибкой, мол НЕ УДАЛОСЬ ПОДКЛЮЧИТЬСЯ С БАЗОЙ ДАННЫХ, ПРИНОСИМ ИЗВИНЕНИЯ.

Короче, суть в этих словах: если не знаешь, как обрабатывать - не обрабатывай никак. РНР прекрасно справляется с базовой обработкой и сам.
Ловить исключение только ради того чтобы поймать - бессмысленно.
Поэтому лучше оставить всё как есть, а ловить исключение только тогда, когда точно знаешь, что хочешь сделать, поймав.

Я это все пишу не для того чтобы поспорить. Просто мне кажется так мы сокращаем строчки кода вроде бы без ущерба.

Показать весь текст
Ответы394511394569

310 5 мая, 14:14 310 1394460

Анонасы, помогите советом нубу.

Как вообще в PHP отслеживать ошибки в коде?

У меня стоит nginx + php-fpm + mariadb.

При возникновении ошибки сервер выдают ошибку 500.

Сколько не гуглил, сколько не менял кофигурационный файлы - всё бестолку.

Что посоветуете?

Ответы394511

311 5 мая, 16:08 311 1394511

>>1394460

Ошибки должны писаться в логи, если только ты их не отключил. Логи в линуксе находятся в /var/log, а также читаются утилитой journalctl. Изучи, как устроено логгирование.

>>1394459

Можно использовать mysqli, она тоже поддерживает исключения, только их надо включить. Без них тебе придется после каждой команды ставить if и проверять результат, что утомляет. Про исключения у меня есть урок, прочти, если еще не читал: https://github.com/codedokode/pasta/blob/master/php/exceptions.md и после этого можешь задавать уточняющие вопросы.

Но я должен предупредить, в некоторых книгах эту библиотеку используют только потому, что она похожа на более старую библиотеку mysql, и авторы, чтобы не переделывать код, написанный для mysql, просто добавили в функции букву i (mysql_query -> mysqli_query). Но зачастую код, писавшийся для mysql, некачественный, и лучше бы они его переписали с нуля. Да и mysqli имеет некоторые отличия и авторам книг лучше было бы код переделать с нуля, а не механически заменить названия функций (например, mysqli поддерживает плейсхолдеры, а mysql - нет. И авторам стоило бы перевести свой код на их использование, а не подставлять данные в запрос вручную, как это делалось в mysql).

То есть, полезно пролистать официальный мануал по mysqli, чтобы правильно ее использовать.

> Я это все пишу не для того чтобы поспорить. Просто мне кажется так мы сокращаем строчки кода вроде бы без ущерба.

Как раз хорошо, что ты задаешь вопросы. В программировании, как и в других инженерных науках, все решения принято обосновывать. Что касается сокращения кода - я тут его не вижу. Выбросить исключение - это одна строчка. Написать свой класс исключений - 3 строки (class X extends \Exception {}).

Если библиотека поддерживает выброс исключений (mysqli и PDO поддерживают), то их использование экономит строчки, так как тебе не надо руками писать if() после каждой функции работы с БД, которая может вернуть ошибку. Это упомянуто в моем уроке.

312 5 мая, 16:09 312 1394513

>>1393386

> а я использую mysqli могу ли я написать
> public function __construct($conn) { ... }?

А ты читал урок про DI? Прочти, если не читал: https://github.com/codedokode/pasta/blob/master/arch/di.md А то я не вижу смысла пересказывать уже написанное там.

В ООП мы используем разделение ответственности, каждый класс отвечает за что-то свое. Соответственно, устанавливать соединение с БД - это не задача класса TableGateway, потому мы передаем ему уже готовое соединение в конструктор, примерно как ты написал, только стоит еще тайп-хинт добавить.

> С исключениями я тоже не понял. Могу ли я их не использовать, а писать просто
> $conn = new mysqli ($hn, $un, $pw, $db);
> if($conn->connect_error) die($conn->connect_error);

Прочти урок про исключения и там написано, чем это плохо. Ну как минимум у тебя проблема в том, что ты пользователю показываешь ошибку, которая ему нафиг не нужна, так как он не программист, при этом ты (разработчик) об этой ошибке не узнаешь, так как она не пишется в лог. Потому стоит почитать про существующие решения в моем уроке: https://github.com/codedokode/pasta/blob/master/php/exceptions.md

Альтернатива исключениям - это возвращать код ошибки. Его придется проверять после вызова каждой функции, где может произойти ошибка.

>>1393514

> Ну и не понятно зачем отлавливать ошибку

В случае выброса исключения тот, кто вызвал функцию, решает, что делать в случае исключения. В случае die() он решить ничего не может. Плюс, тут нарушается разделение ответственности. С какой стати класс для работы с БД может показывать HTML страницу? Ему никто этого не разрешал.

Если в программе есть разделение ответственности, то класс работы с БД лишь сообщает об ошибке, но не решает, как ее обрабатывать. Показ страницы ошибки - это не его зона ответственности. Ты пока воспринимаешь программу как одно целое и не разделяешь ее на слабосвязанные части.

>>1393617

В твоем посте избыток категоричности стоило бы заменить на изобильность пояснений.

312 5 мая, 16:09 312 1394513

>>1393386

> а я использую mysqli могу ли я написать
> public function __construct($conn) { ... }?

А ты читал урок про DI? Прочти, если не читал: https://github.com/codedokode/pasta/blob/master/arch/di.md А то я не вижу смысла пересказывать уже написанное там.

В ООП мы используем разделение ответственности, каждый класс отвечает за что-то свое. Соответственно, устанавливать соединение с БД - это не задача класса TableGateway, потому мы передаем ему уже готовое соединение в конструктор, примерно как ты написал, только стоит еще тайп-хинт добавить.

> С исключениями я тоже не понял. Могу ли я их не использовать, а писать просто
> $conn = new mysqli ($hn, $un, $pw, $db);
> if($conn->connect_error) die($conn->connect_error);

Прочти урок про исключения и там написано, чем это плохо. Ну как минимум у тебя проблема в том, что ты пользователю показываешь ошибку, которая ему нафиг не нужна, так как он не программист, при этом ты (разработчик) об этой ошибке не узнаешь, так как она не пишется в лог. Потому стоит почитать про существующие решения в моем уроке: https://github.com/codedokode/pasta/blob/master/php/exceptions.md

Альтернатива исключениям - это возвращать код ошибки. Его придется проверять после вызова каждой функции, где может произойти ошибка.

>>1393514

> Ну и не понятно зачем отлавливать ошибку

В случае выброса исключения тот, кто вызвал функцию, решает, что делать в случае исключения. В случае die() он решить ничего не может. Плюс, тут нарушается разделение ответственности. С какой стати класс для работы с БД может показывать HTML страницу? Ему никто этого не разрешал.

Если в программе есть разделение ответственности, то класс работы с БД лишь сообщает об ошибке, но не решает, как ее обрабатывать. Показ страницы ошибки - это не его зона ответственности. Ты пока воспринимаешь программу как одно целое и не разделяешь ее на слабосвязанные части.

>>1393617

В твоем посте избыток категоричности стоило бы заменить на изобильность пояснений.

Показать весь текст
Ответы394643

313 5 мая, 18:23 313 1394567

Помогите долбоёбу.
Вроде как основы php начал понимать ООП вроде как тоже понял, но когда дошёл до паттерных, фреймворков стал тупить пиздец. Где лучше всего их изучать ? Прошу скинуть каких-нибудь годных уроков.

Ответы394637

314 5 мая, 18:26 314 1394569

170-312

>>1394459

Твой код с try/catch написан неправильно. try/catch если и ставят, то только 1 раз, в самом начале программы, а не вокруг каждого вызова функции. Потому код там будет выглядеть так:

$dbh = new PDO('mysql:host=localhost;dbname=""', $user, $pass);

Что, очевидно, короче, чем если бы мы еще писали после него if с проверкой результата.

Глобальный обработчик исключений ставят либо с помощью set_exception_handler, либо с помощью try/catch в самом начале программы.

>>1394386

У тебя какая-то ошибка синтаксиса - какой-то лишний символ (например: неразрывный пробел), или какая-то слишком старая версия PHP, или какое-нибудь двоеточие вместо точки с запятой, или русская буква вместо латинской.

Попробуй этот файл вставить в ideone и проверить, будет такая же ошибка или же другая. Если такая же - то дело именно в символах.

>>1394269

array_slice. Не ленись, открой раздел про функции работы с массивами и прочитай список с краткими описаниями. Это все равно на собеседовании могут спросить.

Вот, читай список тут: https://www.php.net/manual/ru/ref.array.php

>>1394228

Так это учебный тред для начинающих с нуля. Ты подожди, пока анончик прочтет все уроки и решит все мои задачи, и твоя самооценка зашатается.

>>1394166

Для демонизации там есть php-fpm. Зачем нужна "асинхронность", если синхронный код писать проще и он понятнее, я не понял. Но если тебе хочется мучаться с промисами и евент-лупами, то ReactPHP к твоим услугам.

Синхронность это плюс: синхронный код проще. В отличие от языков вроде ноды, где код писать тяжело. То, что PHP умирает после каждого запроса, это плюс: у нас нет утечек памяти. В отличие от языков вроде ноды или руби, где (вроде бы) нет профайлеров памяти, по крайней мере бесплатных, и при утечке люди просто тупо прибивают приложение по крону, чтобы оно не отъедало всю память, так как не могут найти эту утечку.

Хотя есть ситуации, где нужен именно асинхронный код. Тут, конечно, все корявенько, но сама возможность есть.

И я не считаю, что нода это что-то плохое, но есть ситуации, где PHP просто удобнее использовать.

А еще, PHP хорошо оптимизирован, есть типизация и у нас готовят JIT.

314 5 мая, 18:26 314 1394569

170-312

>>1394459

Твой код с try/catch написан неправильно. try/catch если и ставят, то только 1 раз, в самом начале программы, а не вокруг каждого вызова функции. Потому код там будет выглядеть так:

$dbh = new PDO('mysql:host=localhost;dbname=""', $user, $pass);

Что, очевидно, короче, чем если бы мы еще писали после него if с проверкой результата.

Глобальный обработчик исключений ставят либо с помощью set_exception_handler, либо с помощью try/catch в самом начале программы.

>>1394386

У тебя какая-то ошибка синтаксиса - какой-то лишний символ (например: неразрывный пробел), или какая-то слишком старая версия PHP, или какое-нибудь двоеточие вместо точки с запятой, или русская буква вместо латинской.

Попробуй этот файл вставить в ideone и проверить, будет такая же ошибка или же другая. Если такая же - то дело именно в символах.

>>1394269

array_slice. Не ленись, открой раздел про функции работы с массивами и прочитай список с краткими описаниями. Это все равно на собеседовании могут спросить.

Вот, читай список тут: https://www.php.net/manual/ru/ref.array.php

>>1394228

Так это учебный тред для начинающих с нуля. Ты подожди, пока анончик прочтет все уроки и решит все мои задачи, и твоя самооценка зашатается.

>>1394166

Для демонизации там есть php-fpm. Зачем нужна "асинхронность", если синхронный код писать проще и он понятнее, я не понял. Но если тебе хочется мучаться с промисами и евент-лупами, то ReactPHP к твоим услугам.

Синхронность это плюс: синхронный код проще. В отличие от языков вроде ноды, где код писать тяжело. То, что PHP умирает после каждого запроса, это плюс: у нас нет утечек памяти. В отличие от языков вроде ноды или руби, где (вроде бы) нет профайлеров памяти, по крайней мере бесплатных, и при утечке люди просто тупо прибивают приложение по крону, чтобы оно не отъедало всю память, так как не могут найти эту утечку.

Хотя есть ситуации, где нужен именно асинхронный код. Тут, конечно, все корявенько, но сама возможность есть.

И я не считаю, что нода это что-то плохое, но есть ситуации, где PHP просто удобнее использовать.

А еще, PHP хорошо оптимизирован, есть типизация и у нас готовят JIT.

Показать весь текст
Ответы394581394643

315 5 мая, 18:28 315 1394571

>>1394247

Я тоже такой термин не слышал никогда.

>>1394148

Сделай foreach'ем либо через intersect_key.

>>1393471

Очень плохо. Идея ООП в том, что ты можешь в наследнике заменить или обернуть метод, а если тебе понадобился instanceof, то ты делаешь что-то неправильно. Плюс, предок не должен знать о своих наследниках. Как автор кода может знать, кто именно в будущем будет наследовать его класс, а? В ООП принцип открытости для расширения - любой может в будущем унаследовать твой класс и ты не знаешь даже, сколько у него будет наследников.

Ты в предке пишешь название класса-наследника. Это неправильно.

Тебе надо правильно проектировать классы, думать о том, какая у каждого зона ответственности. Конкретный совет дать не могу, так как пример у тебя абстрактный. Можно попробовать вынести дублирующийся код в отдельный метод.

>>1393729

Задачи из яндекса легко гуглятся. Мне в общем они нравятся, интересные и есть над чем поломать голову. Я вообще люблю задачи, которые не могу решить сразу.

Ответы394590

316 5 мая, 18:29 316 1394573

>>1393712

По поводу импортов: я не очень понимаю, зачем ты в model/message.py импортируешь наследников. Обычно импортируют только то, что нужно в данном файле. И обычно наследник импортирует предка, а не наоборот. Потому я думаю, эти импорты надо просто убрать:

# models/message.py
import text_message
import voice_message

Зачем они добавлены? Странно, что у тебя предок зависит от своих наследников (что они ему нужны).

Также, ты похоже выбрал Concrete Table Inheritance, возможно, что запросы к ней потребуют лишних UNION, судя по мануалу: https://docs.sqlalchemy.org/en/13/orm/inheritance.html#concrete-table-inheritance

> Следует сделать скрипт, который будет принимать все credentials, выполнять всю установку, а на выход выдавать все хэши и токены. Возможно генерировать сразу .env файл.

Я думаю, достаточно только сгенерировать токены. В .env может быть еще куча других параметров. Но можно, конечно, выдавать заготовку .env файла.

> Как обычно делаются такие файлы? Через Докер (не разу с ним не знакомился)?

В dev среде можно использовать docker-compose для оркестрации докеров с отдельными приложениями. Докер, как правило, используется чтобы упаковать в образ программу с нужными ей библиотеками, например, определенную версию Питона или Ноды, чтобы ее не надо было устанавливать в систему руками. Код твоего приложения в докер-образ не кладется, а подмонтируется в него как внешний раздел. docker-compose заниамется тем, что просто запускает несколько докеров (например: микросервис авторизации и основное приложение). На Винде и Маке Докер запускает код в виртуальной машине с линуксом, а файлы прокидываются через сетевую файловую систему со всеми вытекающими.

Ты можешь найти готовый пример приложения на PHP + nginx + mysql в докере и разберешься, я думаю.

> Лучше сделать это на системном языке и чтобы он был кроссплатформенный. Можете что-нибудь посоветовать пожалуйста?

Обычно используют Питон, bash для таких скриптов. Если у тебя код на Питоне, логично в нем сделать CLI скрипт для генерации токенов.

>>1393656

У тебя описан CGI, он не используется на практике, используется FastCGI, а там все посложнее, и один процесс php обрабатывает много запросов по очереди.

316 5 мая, 18:29 316 1394573

>>1393712

По поводу импортов: я не очень понимаю, зачем ты в model/message.py импортируешь наследников. Обычно импортируют только то, что нужно в данном файле. И обычно наследник импортирует предка, а не наоборот. Потому я думаю, эти импорты надо просто убрать:

# models/message.py
import text_message
import voice_message

Зачем они добавлены? Странно, что у тебя предок зависит от своих наследников (что они ему нужны).

Также, ты похоже выбрал Concrete Table Inheritance, возможно, что запросы к ней потребуют лишних UNION, судя по мануалу: https://docs.sqlalchemy.org/en/13/orm/inheritance.html#concrete-table-inheritance

> Следует сделать скрипт, который будет принимать все credentials, выполнять всю установку, а на выход выдавать все хэши и токены. Возможно генерировать сразу .env файл.

Я думаю, достаточно только сгенерировать токены. В .env может быть еще куча других параметров. Но можно, конечно, выдавать заготовку .env файла.

> Как обычно делаются такие файлы? Через Докер (не разу с ним не знакомился)?

В dev среде можно использовать docker-compose для оркестрации докеров с отдельными приложениями. Докер, как правило, используется чтобы упаковать в образ программу с нужными ей библиотеками, например, определенную версию Питона или Ноды, чтобы ее не надо было устанавливать в систему руками. Код твоего приложения в докер-образ не кладется, а подмонтируется в него как внешний раздел. docker-compose заниамется тем, что просто запускает несколько докеров (например: микросервис авторизации и основное приложение). На Винде и Маке Докер запускает код в виртуальной машине с линуксом, а файлы прокидываются через сетевую файловую систему со всеми вытекающими.

Ты можешь найти готовый пример приложения на PHP + nginx + mysql в докере и разберешься, я думаю.

> Лучше сделать это на системном языке и чтобы он был кроссплатформенный. Можете что-нибудь посоветовать пожалуйста?

Обычно используют Питон, bash для таких скриптов. Если у тебя код на Питоне, логично в нем сделать CLI скрипт для генерации токенов.

>>1393656

У тебя описан CGI, он не используется на практике, используется FastCGI, а там все посложнее, и один процесс php обрабатывает много запросов по очереди.

Показать весь текст
Ответы397648

317 5 мая, 18:31 317 1394575

>>1393636

Обычно есть несколько отдельных рабочих процессов PHP и оба запроса будут обрабатываться параллельно. Для получения id записи в MySQL надо использовать LAST_INSERT_ID() или одноименную функцию в PDO или mysqli, не надо делать кривой велосипед. В Postgres надо использовать сиквенсы (генераторы уникальных значений) для этого.

Описанные тобой способы неправильные и могут давать ошибки.

>>1393551

Подучи HTML/CSS/JS. Вряд ли ты сможешь осилить фронтенд-фреймворки не зная толком JS. Ну и мне кажется, тебе надо дальше проходить собеседования, есть шанс, что куда-нибудь возьмут.

Заодно можно поизучать теорию по БД, виды связей, нормализация, древовидные данные, индексы. оптимизация и тд.

>>1393514

Наследования исключения делается в простейшем варианте так:

class SomeException extends \Exception {}

Далее при желании можно добавлять поля и методы.

>>1393429

Я думаю, что если стоит задача сделать что-то более универсальное, то можно взять готовую библиотеку вроде Doctrine DBAL, где уже есть все нужные обертки.

>>1393389

Это тайп-хинт (контроль типов). Изучи его и используй по возможности везде.

>>1393036

Если твой скрипт может выполнить задачу за 5 минут, то да, можно так. Если не может, то надо запускать реже.

317 5 мая, 18:31 317 1394575

>>1393636

Обычно есть несколько отдельных рабочих процессов PHP и оба запроса будут обрабатываться параллельно. Для получения id записи в MySQL надо использовать LAST_INSERT_ID() или одноименную функцию в PDO или mysqli, не надо делать кривой велосипед. В Postgres надо использовать сиквенсы (генераторы уникальных значений) для этого.

Описанные тобой способы неправильные и могут давать ошибки.

>>1393551

Подучи HTML/CSS/JS. Вряд ли ты сможешь осилить фронтенд-фреймворки не зная толком JS. Ну и мне кажется, тебе надо дальше проходить собеседования, есть шанс, что куда-нибудь возьмут.

Заодно можно поизучать теорию по БД, виды связей, нормализация, древовидные данные, индексы. оптимизация и тд.

>>1393514

Наследования исключения делается в простейшем варианте так:

class SomeException extends \Exception {}

Далее при желании можно добавлять поля и методы.

>>1393429

Я думаю, что если стоит задача сделать что-то более универсальное, то можно взять готовую библиотеку вроде Doctrine DBAL, где уже есть все нужные обертки.

>>1393389

Это тайп-хинт (контроль типов). Изучи его и используй по возможности везде.

>>1393036

Если твой скрипт может выполнить задачу за 5 минут, то да, можно так. Если не может, то надо запускать реже.

Показать весь текст
Ответы394600

318 5 мая, 18:32 318 1394576

>>1392888

Будет сложнее, но я советовал бы поковырять код Ларавел, чтобы учиться дальше.

>>1393246
>>1387082

> раздут мой код или нет

Нет.

> Сделать в департаменте массив из работников, который будет содержать в себе все виды работников? Не совсем понял где тогда создавать работников, ведь я вызывал метод

Снаружи департамента. Удобно сделать метод найма работника в департамент и в него передавать созданных работников. При таком подходе, как создаются работники, департамент не волнует - он принимает уже готовых. Разделение ответственности.

$saleDep = new Department(..);
$ivan = new Engineer(...);
$saleDep->employ($ivan);

> Правильно ли я понимаю, что желательно для всех свойств класса ставить protected/private, а для считывания/записи нужно делать public методы с проверкой и выдачей ошибки в случае чего?

да, это называется "инкапсуляция". Паста:

=============

Суть инкапсуляции в том, что класс скрывает (инкапслирует) в себе логику работы с данными и сами данные, а наружу выставляет только методы. Пользователю этих методов не важно, как класс устроен внутри, как он хранит данные, какие у него есть поля, ему достаточно вызвать нужный метод чтобы получить результат.

Кроме нескольких публичных методов, остальные методы и свойства закрываются от доступа снаружи модификаторами private или protected. То есть с объектом снаружи ничего нельзя сделать, кроме вызова публичных методов.

Это упрощает понимание кода: тебе не надо читать и разбирать код класса, достаточно прочитать название публичных методов (и может быть комментарии к ним). Также, это упрощает изменение кода: если какое-то свойство имеет уровень private, то доступ к нему возможен только из того же класса и тебе не надо бегать по всему коду и смотреть что там с этим свойством делается, тебе достаточно просмотреть один файл с этим классом.

При инкапсуляции автор класса таким образом задает ограничения, что можно делать с объектом.

Как плюс, мы можем поставить какие-то проверки в методах, и запретить установку неправильных значений свойств. Таким образом, снаружи записать неправильное значение в объект будет нельзя и автор класса может гарантировать его корректную работу в любой ситуации. Если у нас есть публичные свойства, то в них можно записывать что угодно, а приватные свойства изменять снаружи нельзя, можно только вызвать методы, которые что-то делают.

Инкапсуляция это хорошо. Так как весь код, который занимается одной задачей, оказывается заключен внутри одного класса. Противоположный случай это когда код (или знание о его внутреннем устройстве) вылезает из класса и размазывается по всей программе.

Если проводить аналогии, то можно представить кофе-машину. Ты нажимаешь кнопку (=вызываешь публичный метод) и получаешь кофе (=результат вызова этого метода), при этом ты не видишь что происходит внутри нее и тебе не надо в этом разбираться.

Вот пример класса с использованием инкапсуляции:

// Объект представляет собой ломаную линию из нескольких сегментов
// Показаны только публичные методы, остальное скрыто
class PolyLine
{
public function __construct(float $x, float $y) { ... }

// Добавляет еще одну точку к ломаной
public function addPoint(float $x, float $y): void { ... }

// Посчитать общую длину линии
public function calculateLength(): float { ... }
...
}

В нем всего 3 публичных метода, включая конструктор, и мы видим, что с объектом можно сделать только три действия:

- создать ломаную, указав начальную точку
- добавить к ломаной еще одну точку
- посчитать длину ломаной

Вот пример использования этого класса:

$line = new PolyLine(1, 1);
$line->addPoint(2, 2);
$line->addPoint(4, 7);
echo $line->calculateLength();

При этом код может проверять передаваемые значения, например, не разрешать 2 раза добавлять одну и ту же точку. Здесь не приведен код методов и мы не видим приватные поля и методы, но нам это и не требуется - и так понятно, как использовать класс.

==================

> Неужели для каждого рабочего свой обьект создавать?

Это будет проще. Но ты можешь использовать и свой подход. Если у тебя реализована инкапсуляция, то по идее, коду снаружи неважно, как именно данные хранятся внутри - он вызывает метод, а дальше уже не его забота.

> Не совсем понял. Обьявить в начале кода 4 константые Manager,Engineer и т.д?

Они уже встроены в каждый класс, их объявлять не надо, можно сразу использовать: Manager::class. Прочти мануал https://www.php.net/manual/ru/language.oop5.constants.php

> Т.е базовая ставка у всех одинаковая, а итоговая зависит от ранга и является ли работник лидером?

Это 2 разные вещи. С одной стороны, если мы меняем ранг, то базовая ставка не меняется, а зарплата меняется. С другой стороны, мы можем повысить человеку базовую ставку и зарплата тоже поменяется.

318 5 мая, 18:32 318 1394576

>>1392888

Будет сложнее, но я советовал бы поковырять код Ларавел, чтобы учиться дальше.

>>1393246
>>1387082

> раздут мой код или нет

Нет.

> Сделать в департаменте массив из работников, который будет содержать в себе все виды работников? Не совсем понял где тогда создавать работников, ведь я вызывал метод

Снаружи департамента. Удобно сделать метод найма работника в департамент и в него передавать созданных работников. При таком подходе, как создаются работники, департамент не волнует - он принимает уже готовых. Разделение ответственности.

$saleDep = new Department(..);
$ivan = new Engineer(...);
$saleDep->employ($ivan);

> Правильно ли я понимаю, что желательно для всех свойств класса ставить protected/private, а для считывания/записи нужно делать public методы с проверкой и выдачей ошибки в случае чего?

да, это называется "инкапсуляция". Паста:

=============

Суть инкапсуляции в том, что класс скрывает (инкапслирует) в себе логику работы с данными и сами данные, а наружу выставляет только методы. Пользователю этих методов не важно, как класс устроен внутри, как он хранит данные, какие у него есть поля, ему достаточно вызвать нужный метод чтобы получить результат.

Кроме нескольких публичных методов, остальные методы и свойства закрываются от доступа снаружи модификаторами private или protected. То есть с объектом снаружи ничего нельзя сделать, кроме вызова публичных методов.

Это упрощает понимание кода: тебе не надо читать и разбирать код класса, достаточно прочитать название публичных методов (и может быть комментарии к ним). Также, это упрощает изменение кода: если какое-то свойство имеет уровень private, то доступ к нему возможен только из того же класса и тебе не надо бегать по всему коду и смотреть что там с этим свойством делается, тебе достаточно просмотреть один файл с этим классом.

При инкапсуляции автор класса таким образом задает ограничения, что можно делать с объектом.

Как плюс, мы можем поставить какие-то проверки в методах, и запретить установку неправильных значений свойств. Таким образом, снаружи записать неправильное значение в объект будет нельзя и автор класса может гарантировать его корректную работу в любой ситуации. Если у нас есть публичные свойства, то в них можно записывать что угодно, а приватные свойства изменять снаружи нельзя, можно только вызвать методы, которые что-то делают.

Инкапсуляция это хорошо. Так как весь код, который занимается одной задачей, оказывается заключен внутри одного класса. Противоположный случай это когда код (или знание о его внутреннем устройстве) вылезает из класса и размазывается по всей программе.

Если проводить аналогии, то можно представить кофе-машину. Ты нажимаешь кнопку (=вызываешь публичный метод) и получаешь кофе (=результат вызова этого метода), при этом ты не видишь что происходит внутри нее и тебе не надо в этом разбираться.

Вот пример класса с использованием инкапсуляции:

// Объект представляет собой ломаную линию из нескольких сегментов
// Показаны только публичные методы, остальное скрыто
class PolyLine
{
public function __construct(float $x, float $y) { ... }

// Добавляет еще одну точку к ломаной
public function addPoint(float $x, float $y): void { ... }

// Посчитать общую длину линии
public function calculateLength(): float { ... }
...
}

В нем всего 3 публичных метода, включая конструктор, и мы видим, что с объектом можно сделать только три действия:

- создать ломаную, указав начальную точку
- добавить к ломаной еще одну точку
- посчитать длину ломаной

Вот пример использования этого класса:

$line = new PolyLine(1, 1);
$line->addPoint(2, 2);
$line->addPoint(4, 7);
echo $line->calculateLength();

При этом код может проверять передаваемые значения, например, не разрешать 2 раза добавлять одну и ту же точку. Здесь не приведен код методов и мы не видим приватные поля и методы, но нам это и не требуется - и так понятно, как использовать класс.

==================

> Неужели для каждого рабочего свой обьект создавать?

Это будет проще. Но ты можешь использовать и свой подход. Если у тебя реализована инкапсуляция, то по идее, коду снаружи неважно, как именно данные хранятся внутри - он вызывает метод, а дальше уже не его забота.

> Не совсем понял. Обьявить в начале кода 4 константые Manager,Engineer и т.д?

Они уже встроены в каждый класс, их объявлять не надо, можно сразу использовать: Manager::class. Прочти мануал https://www.php.net/manual/ru/language.oop5.constants.php

> Т.е базовая ставка у всех одинаковая, а итоговая зависит от ранга и является ли работник лидером?

Это 2 разные вещи. С одной стороны, если мы меняем ранг, то базовая ставка не меняется, а зарплата меняется. С другой стороны, мы можем повысить человеку базовую ставку и зарплата тоже поменяется.

Показать весь текст

319 5 мая, 18:34 319 1394579

>>1392401

Не знаю, наверно лучше брать фреймворки. Но могу дать урок про MVC: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

>>1392438

Пожалуйста, Symfony Process для запуска процессов в блокирующем режиме, ReactPHP process для асинхронного управления (будет немного больно).

Но, возможно, тебе проще будет написать bash скрипт.

>>1392404

MVC это не "фича" (особенность) чего-то. А архитектурный паттерн.

>>1391936

PHP на всяких хостингах используется в панели управления для управления кронами, пользователями, установки пакетов итд.

>>1391581

Это делают те, кто не осилил прочесть https://habr.com/ru/post/315152/

А вообще, я проблемы не вижу, не нравится - не пиши. Может у них проблемы какие-то, или их на работу не берут, или им просто скучно и они пытаются флуд развести, или это проявляется эффект Даннинга-Крюгера.

320 5 мая, 18:37 320 1394581

>>1394569
>Твой код с try/catch написан неправильно. try/catch если и ставят, то только 1 раз, в самом начале программы, а не вокруг каждого вызова функции. Потому код там будет выглядеть так:
ну, кстати, тут я бы поспорил. Разные мнения на этот счёт, моё таково, что в try catch надо оборачивать каждый (в разумных пределах) вызов функции, где возможен выброс исключения, и которое ты планируешь обработать.

Ответы394582394733

321 5 мая, 18:38 321 1394582

>>1394581
то есть несколько try/catch в одном коде это ок, особенно если разные исключения ловятся и они в разных местах возникают

Ответы394733

322 5 мая, 18:43 322 1394587

>>1389946

> Для этого нужно проверить, что конференции между этими пользователями не существует. То есть нужно найти двух Получателей с одинаковым Диалогом и чтобы этот Диалог был приватным.

Такие запросы с джойнами будут плохо работать на больших нагрузках. Они же почти не оптимизируются индексами никак и требуют перебор строк. Возможно, тут придется сделать денормализацию, например, добавить в Dialog либо в Participant дополнительные поля. Чтобы, например, запрос бы имел вид

SELECT FROM Participant WHERE user = ? AND partner = ? AND private =1

Это ложится на индексы. Но, конечно, денормализацию стоит делать во вторую очередь.

> Можно я оптимизацию БД оставлю на последнее?

Можно. Но я просто хотел подчеркнуть, что мессенджеры это высоконагруженные штуки и там приходится об этом думать. И о шардинге, если ты хочешь, чтобы проект расширялся. Потому мы сначала проектируем нормализованную схему, а потом смотрим на типичные запросы и оптимизируем схему для них.

Более того, часто под мессенджеры даже пишутся специализированные хранилища.

Насчет reply - а недостаточно тут просто сделать поле в сообщении "replyToUuid" со ссылкой на исходное сообщение? Без вложений.

Так, схема выглядит хорошо. Позже стоит продумать операции, которые будут выполняться (их явно будет больше, например, может понадобиться постраничное получение участников огромного чата). И как их оптимизировать.

Также, в таблицах вроде Conference_Reference можно не вводить отдельный uuid, а использовать например составной ключ (uuid конференции + id юзера). Возможно, так будет проще. А может и нет.

>>1389824

То, что он умирает, во-первых, делает его stateless, во-вторых, исключает утечки памяти, которые возможны в node-приложениях. Это зачастую плюс, а не минус. Ты знаешь, как в ноде искать утечку памяти, есть ли для нее бесплатные профайлеры памяти?

>>1389802

По идее в VSCode умное дополнение есть, оно называется intellisense или как-то так и его надо ставить отдельно для каждого языка.

>>1389598

> Я думаю, что пока подходы к авторизации методов WAMP не изучены, следует писать сырой код на if'ах, а подход с роутингом взять на заметку и держать в уме. А как думаете вы?

Я, увы, так хорошо авторизацию в WAMP не знаю и сейчас не могу подсказать. Разделение прав нам обязательно нужно будет при подписке, чтобы клиент не мог подписаться на чужие сообщения (кстати, я сейчас себя поймал на мысли, что возможно, другие разработчики этим не озаботились и в интернете куча уязвимых WAMP-серверов).

Возможно, придется использовать роутер и в нем проверять переданный клиентом токен. Или вместо id пользователя в идентификаторах каналов использовать трудноподбираемый токен (new-msgs-for-112345678765432) - тогда может быть, авторизация для подписки не потребуется.

322 5 мая, 18:43 322 1394587

>>1389946

> Для этого нужно проверить, что конференции между этими пользователями не существует. То есть нужно найти двух Получателей с одинаковым Диалогом и чтобы этот Диалог был приватным.

Такие запросы с джойнами будут плохо работать на больших нагрузках. Они же почти не оптимизируются индексами никак и требуют перебор строк. Возможно, тут придется сделать денормализацию, например, добавить в Dialog либо в Participant дополнительные поля. Чтобы, например, запрос бы имел вид

SELECT FROM Participant WHERE user = ? AND partner = ? AND private =1

Это ложится на индексы. Но, конечно, денормализацию стоит делать во вторую очередь.

> Можно я оптимизацию БД оставлю на последнее?

Можно. Но я просто хотел подчеркнуть, что мессенджеры это высоконагруженные штуки и там приходится об этом думать. И о шардинге, если ты хочешь, чтобы проект расширялся. Потому мы сначала проектируем нормализованную схему, а потом смотрим на типичные запросы и оптимизируем схему для них.

Более того, часто под мессенджеры даже пишутся специализированные хранилища.

Насчет reply - а недостаточно тут просто сделать поле в сообщении "replyToUuid" со ссылкой на исходное сообщение? Без вложений.

Так, схема выглядит хорошо. Позже стоит продумать операции, которые будут выполняться (их явно будет больше, например, может понадобиться постраничное получение участников огромного чата). И как их оптимизировать.

Также, в таблицах вроде Conference_Reference можно не вводить отдельный uuid, а использовать например составной ключ (uuid конференции + id юзера). Возможно, так будет проще. А может и нет.

>>1389824

То, что он умирает, во-первых, делает его stateless, во-вторых, исключает утечки памяти, которые возможны в node-приложениях. Это зачастую плюс, а не минус. Ты знаешь, как в ноде искать утечку памяти, есть ли для нее бесплатные профайлеры памяти?

>>1389802

По идее в VSCode умное дополнение есть, оно называется intellisense или как-то так и его надо ставить отдельно для каждого языка.

>>1389598

> Я думаю, что пока подходы к авторизации методов WAMP не изучены, следует писать сырой код на if'ах, а подход с роутингом взять на заметку и держать в уме. А как думаете вы?

Я, увы, так хорошо авторизацию в WAMP не знаю и сейчас не могу подсказать. Разделение прав нам обязательно нужно будет при подписке, чтобы клиент не мог подписаться на чужие сообщения (кстати, я сейчас себя поймал на мысли, что возможно, другие разработчики этим не озаботились и в интернете куча уязвимых WAMP-серверов).

Возможно, придется использовать роутер и в нем проверять переданный клиентом токен. Или вместо id пользователя в идентификаторах каналов использовать трудноподбираемый токен (new-msgs-for-112345678765432) - тогда может быть, авторизация для подписки не потребуется.

Показать весь текст
Ответы397648

323 5 мая, 18:50 323 1394590

>>1394571
> Конкретный совет дать не могу, так как пример у тебя абстрактный.
Спасибо за ответ. Всегда приятно читать твои объяснения.

Реальный код такой. Есть класс WebReader, который удобная для меня обертка над file_get_contents, контекстами стримов и $http_response_header.
В нем есть метод doRequest(), внутри которого while и try-catch, и идет запрос через file_get_contents, собственно. В catch обрабатываются исключения, которые кидает file_get_contents. Если исключение такое, что это просто сбой http-запроса - крутим while снова (отправляем новый запрос). Если что-то другое, пробрасываем исключение наружу, конец.
Он не абстрактный, готовый класс для запрос в интернет. Но от него я наследуюсь, если конкретному сайту нужны специфические заголовки, или сохранить-отдать специфические куки. TheSiteWebReader, например. Я все это закладывал при проектировании, поэтому работает замечательно.

И вот пришла беда: на одном из сайтов, на который я лезу через TheSiteWebReader, file_get_contents выдает такую ошибку, которую я могу починить немного починив запрос конкретно для этого сайта, но ни для какого другого. Единственное место, где я могу это починить - глубокие кишки WebReader->doRequest(). И мне нужно проверять, что я TheSiteWebReader, потому что для других сайтов чинить эту ошибку нельзя.

Что делать? Выделить содержимое catch во вспомогательный метод типа WebReader->tryToRepairTheRequest(), а затем при необходимости переопределять этот метод в классах-наследниках? Это будет нормально - передать ему исключение, на основе которого он либо изменит свойства класса (модифицирует запрос), либо кинется переданным исключением, если он не может починить запрос?

Ответы394733

324 5 мая, 19:15 324 1394600

>>1394575
Просто сразу не мог додуматься до того, что в ларавеле после $var->save(), смогу взять из неё же id =)

325 5 мая, 19:29 325 1394604

сколько лара выдерживает запросов?

Ответы394732

326 5 мая, 19:32 326 1394606

зашел сюда а тут все то же что и года 3 назад, ничего не меняется, анончик учи жс пока не поздно

327 5 мая, 19:37 327 1394607

Привет ОП, у меня возникли вопросы:

1. Хелперы/Сервисы это место куда мы выносим бизнес-логику, что-то вроде внутреннего api приложения? Это нужно чтобы наш контроллер оставался тонким, так?

2. Утилиты это классы со статик методами, служащими аналогом обычных функций? Я так понял их используют потому-что для функций нельзя использовать автозагрузку.

3. Стоит ли делать отдельный класс роутера для списка студентов?

Ответы394656394659394730

328 5 мая, 21:01 328 1394637

>>1394567
Можешь написать CMS свою по уроку Зинченко на ютубе, тогда вклинишься в настоящий ООП, а если фреймворк, то какой тебе нужен?

Ответы394707394708394709394877

329 5 мая, 21:32 329 1394643

>>1394569
>Твой код с try/catch написан неправильно. try/catch если и ставят, то только 1 раз, в самом начале программы, а не вокруг каждого вызова функции. Потому код там будет выглядеть так:
Так стойте, что это значит? А что тогда должен ловить try/catch?

>>1394513
Вот посмотри мой код, пожалуйста. Где тут ошибки. Мне нужно оборачивать запрос $dbh->query($query); в try/catch? Если да, то какую ошибку функция query() может выбрасывать? Тоже PDOException?

<?php
require_once __DIR__ . '/login.php';
try {
$dbh = new PDO('mysql:host=localhost;dbname=', $un, $pw);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Подключение не удалось: ' . $e->getMessage(); //$e->getMessage() не нужно писать, получается?
}

$query = "CREATE TABLE student (
id SMALLINT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
surname VARCHAR(50) NOT NULL,
gender ENUM('male', 'female') NOT NULL,
groupNumber VARCHAR(5) NOT NULL,
email VARCHAR(30) NOT NULL UNIQUE,
totalPoints SMALLINT UNSIGNED NOT NULL,
yearOfBirth YEAR NOT NULL,
localOrNonresident ENUM('local', 'nonresident') NOT NULL,
PRIMARY KEY (id)
)";

$dbh->query($query);
$dbh = null;
?>

329 5 мая, 21:32 329 1394643

>>1394569
>Твой код с try/catch написан неправильно. try/catch если и ставят, то только 1 раз, в самом начале программы, а не вокруг каждого вызова функции. Потому код там будет выглядеть так:
Так стойте, что это значит? А что тогда должен ловить try/catch?

>>1394513
Вот посмотри мой код, пожалуйста. Где тут ошибки. Мне нужно оборачивать запрос $dbh->query($query); в try/catch? Если да, то какую ошибку функция query() может выбрасывать? Тоже PDOException?

<?php
require_once __DIR__ . '/login.php';
try {
$dbh = new PDO('mysql:host=localhost;dbname=', $un, $pw);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
echo 'Подключение не удалось: ' . $e->getMessage(); //$e->getMessage() не нужно писать, получается?
}

$query = "CREATE TABLE student (
id SMALLINT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
surname VARCHAR(50) NOT NULL,
gender ENUM('male', 'female') NOT NULL,
groupNumber VARCHAR(5) NOT NULL,
email VARCHAR(30) NOT NULL UNIQUE,
totalPoints SMALLINT UNSIGNED NOT NULL,
yearOfBirth YEAR NOT NULL,
localOrNonresident ENUM('local', 'nonresident') NOT NULL,
PRIMARY KEY (id)
)";

$dbh->query($query);
$dbh = null;
?>

Показать весь текст
Ответы394656394732

330 5 мая, 22:01 330 1394647

были такие кто уже на 2 задании застряли?

331 5 мая, 22:41 331 1394656

>>1394643
Я не оп.
Популярное решение - это централизованный обработчик исключений в ядре твоего фреймворка, как можно ближе к точке входа. В зависимости от режима DEVELOPMENT/ PRODUCTION ты можешь выводить ошибки на экран или молча логировать в файл Собственно единая точка входа и для этого тоже нужна.
>>1394607
Я не оп.
Под хелперами обычно понимают методы/функции шаблонизатора, хотя зависит о терминологии конкретного фремворка.

Сервисы обычно имеют отношения к Dependency Inversion https://ru.wikipedia.org/wiki/Принцип_инверсии_зависимостей фреймворка. Предполанается что ты пишешь в ооп стиле. У тебя куча классов зависящих друг от друга наследованием и композицией (когда один инстанс класса содержит ссылку на инстанс другого класса). Чтобы инстанцировать класс тебе нужно, предварительно инстанцировать кучу других классов, от которых он зависит путем композиции. DI во фреймворке:
1 позволяет обобщеным образом описать зависимости между классами (иногда автоматически интроспекцией получается инстанцировать класс)
2 позволяет осуществлять замену классов зависящих от друг друга наследованием или наследующих один интерфейс

Ты дожен понять что DI это не дополнительный улучшизм, а основной метод содания объектов во фрейймворке. Сервисы это классы твоей бизнес модели как ты выразился. Если твой класс ниотчего не зависит то тебе ненужно вставлять его в DI Собственно ты приходишь к утилитам.

332 5 мая, 22:57 332 1394659

>>1394607
Смотри, тут такая штука. Во-первых, ООП и MVC-фреймворки используются повсеместно, потому вопрос, надо ли их знать, по моему, лишний, если только ты не мечтаешь копаться в старом-престаром давно написанном быдлокоде. ООП — не новомодное изобретение, его используют в коммерческой разработке с 80-х годов, кстати, так что это вполне проверенный временем подход. MVC тоже появился (правда немного не такой, как в вебе) как способ упростить разработку десктопных приложений с окошечками примерно в то же время.

Чем ООП помогает в разработке? Тем, что позволяет не свалить код в одну кучу из функций и переменных, а разложить по отдельным классам. Очевидно, что чем больше объем кода, тем больше должно быть порядка и организации, иначе все спутывается, код становится труднее понять (то есть он становится менее качественным), из-за этого появляются баги, и в итоге на борьбу с ними уходит чуть ли не больше времени чем на разработку.

И ООП и MVC пытаются сделать код лучше за счет разделения его на части. В случае ООП, мы делаем каждую сущность отдельным классом и помещаем в него код для работы с ней. Например, в случае файлообменника, очевидно, что там будут объекты «файл», у них будут свойства типа имя, дата загрузки, может быть еще что-то.

При правильном проектировании каждый класс занимается своей задачей, в них есть инкапсуляция (возможность закрывать доступ к свойствам и методам с помощью private/protected), и потому часто тебе не надо лазать по всему коду, а достаточно изучить и подправить только один класс. Это очевидно упрощает разработку и жизнь программиста.

В ООП есть наследование. Это позволяет модифицировать поведение какого-то класса из сторонней библиотеки, не меняя его код. На функциях ты такое вряд ли сделаешь без костылей (пример - Друпал, там сделано но на костылях).

При использовании MVC, мы тоже разделяем код на части: код для отображения данных (View), код для хранения и изменения данных (Model) и код для приема команд от пользователя и управления view и model (Controller).

Наконец, есть еще один момент. Программисты обычно не работают в одиночку, а вместе. Если это не коммерческая разработка, а Open Source, все равно, кто-то присылает патчи, кто-то захочет форкнуть твой проект и добавить в него новые фичи. ООП и MVC - общепринятый подход. Везде ты будешь видеть такой код (все популярные фреймворки используют ООП), и если сам пишешь в таком стиле, твой код будет тоже понятен. А если ты начнешь изобретать что-то свое, то многие люди просто не захотят разбираться в твоем велосипеде. Зачем тратить на это время?

Про фреймворки. Из используют по тем же причинам: 1) чтобы в приложении был стандартный понятный каркас 2) чтобы экономить время на написании того, что можно взять гтовое. Из Slim в принципе мы используем в первую очередь роутер, это штука которая умеет из URL вроде /file/123 извлечь id файла и выбрать действие, котлрое надо выполнить. Конечно, можно вместо Slim написать свой роутер, на if и регулярках, но зачем? Время уйдет, а какая от этого выгода?

Ты говоришь, что не видишь преимуществ ООП. Хорошо, а ты пробовал решать задачи из последней главы (задача про корпорацию и кошки-мышки)? По моему в них преимущества ООП-подхода довольно-таки хорошо видны: если пытаться решать их без ООП, получается та еще лапша из функций и массивов. Ты их решал? Если ты так уверен что ООП не нужен и без него все проще, почему бы тебе не попробовать решить эти задачи без ООП и посмотреть самому?

Теперь про файлообменник. Можно ли сделать клон ргхоста без ООП? Да, можно. Но вопрос, а зачем? Из твоего вопроса видно, ты считаешь ООП и фреймворки чем-то сложным, и думаешь зачем для простой задачи использовать сложные вещи. Это понятно, что для начинающего они могут показаться сложными, но только потому что ты в них плохо разбираешься. У меня например, наоборот, ощущение что без ООП выйдет менее понятный, более запутанный код.

Ну и наконец, задача про ргхост имеет целью не «сделать побыстрее клон файлообменника и заработать денег», а «изучить основы разработки веб-приложений, ООП и MVC».

Я привожу в пример тот же Друпал. Сейчас там вроде стало больше ООП-кода, но раньше он был целиком написан на функциях и массивах, и поверь это был очень запутанный код, при работе с которым приходилось постоянно держать документацию открытой и все перепроверять, а на это между прочим уходит время, которое можно потратить с большей пользой.

> По учебнику я учился какой-то процедурной ерунде,
Это потому, что кто-то так толком и не дописал все, что собирался. Но одна глава про ООП там все-таки есть. в самом конце.

В обещм, если у тебя есть еще какие-то сомнения, то пиши. Но мне кажется, что ты пропустил задачи из главы про ООП и потому толком в нем не разобрался.

332 5 мая, 22:57 332 1394659

>>1394607
Смотри, тут такая штука. Во-первых, ООП и MVC-фреймворки используются повсеместно, потому вопрос, надо ли их знать, по моему, лишний, если только ты не мечтаешь копаться в старом-престаром давно написанном быдлокоде. ООП — не новомодное изобретение, его используют в коммерческой разработке с 80-х годов, кстати, так что это вполне проверенный временем подход. MVC тоже появился (правда немного не такой, как в вебе) как способ упростить разработку десктопных приложений с окошечками примерно в то же время.

Чем ООП помогает в разработке? Тем, что позволяет не свалить код в одну кучу из функций и переменных, а разложить по отдельным классам. Очевидно, что чем больше объем кода, тем больше должно быть порядка и организации, иначе все спутывается, код становится труднее понять (то есть он становится менее качественным), из-за этого появляются баги, и в итоге на борьбу с ними уходит чуть ли не больше времени чем на разработку.

И ООП и MVC пытаются сделать код лучше за счет разделения его на части. В случае ООП, мы делаем каждую сущность отдельным классом и помещаем в него код для работы с ней. Например, в случае файлообменника, очевидно, что там будут объекты «файл», у них будут свойства типа имя, дата загрузки, может быть еще что-то.

При правильном проектировании каждый класс занимается своей задачей, в них есть инкапсуляция (возможность закрывать доступ к свойствам и методам с помощью private/protected), и потому часто тебе не надо лазать по всему коду, а достаточно изучить и подправить только один класс. Это очевидно упрощает разработку и жизнь программиста.

В ООП есть наследование. Это позволяет модифицировать поведение какого-то класса из сторонней библиотеки, не меняя его код. На функциях ты такое вряд ли сделаешь без костылей (пример - Друпал, там сделано но на костылях).

При использовании MVC, мы тоже разделяем код на части: код для отображения данных (View), код для хранения и изменения данных (Model) и код для приема команд от пользователя и управления view и model (Controller).

Наконец, есть еще один момент. Программисты обычно не работают в одиночку, а вместе. Если это не коммерческая разработка, а Open Source, все равно, кто-то присылает патчи, кто-то захочет форкнуть твой проект и добавить в него новые фичи. ООП и MVC - общепринятый подход. Везде ты будешь видеть такой код (все популярные фреймворки используют ООП), и если сам пишешь в таком стиле, твой код будет тоже понятен. А если ты начнешь изобретать что-то свое, то многие люди просто не захотят разбираться в твоем велосипеде. Зачем тратить на это время?

Про фреймворки. Из используют по тем же причинам: 1) чтобы в приложении был стандартный понятный каркас 2) чтобы экономить время на написании того, что можно взять гтовое. Из Slim в принципе мы используем в первую очередь роутер, это штука которая умеет из URL вроде /file/123 извлечь id файла и выбрать действие, котлрое надо выполнить. Конечно, можно вместо Slim написать свой роутер, на if и регулярках, но зачем? Время уйдет, а какая от этого выгода?

Ты говоришь, что не видишь преимуществ ООП. Хорошо, а ты пробовал решать задачи из последней главы (задача про корпорацию и кошки-мышки)? По моему в них преимущества ООП-подхода довольно-таки хорошо видны: если пытаться решать их без ООП, получается та еще лапша из функций и массивов. Ты их решал? Если ты так уверен что ООП не нужен и без него все проще, почему бы тебе не попробовать решить эти задачи без ООП и посмотреть самому?

Теперь про файлообменник. Можно ли сделать клон ргхоста без ООП? Да, можно. Но вопрос, а зачем? Из твоего вопроса видно, ты считаешь ООП и фреймворки чем-то сложным, и думаешь зачем для простой задачи использовать сложные вещи. Это понятно, что для начинающего они могут показаться сложными, но только потому что ты в них плохо разбираешься. У меня например, наоборот, ощущение что без ООП выйдет менее понятный, более запутанный код.

Ну и наконец, задача про ргхост имеет целью не «сделать побыстрее клон файлообменника и заработать денег», а «изучить основы разработки веб-приложений, ООП и MVC».

Я привожу в пример тот же Друпал. Сейчас там вроде стало больше ООП-кода, но раньше он был целиком написан на функциях и массивах, и поверь это был очень запутанный код, при работе с которым приходилось постоянно держать документацию открытой и все перепроверять, а на это между прочим уходит время, которое можно потратить с большей пользой.

> По учебнику я учился какой-то процедурной ерунде,
Это потому, что кто-то так толком и не дописал все, что собирался. Но одна глава про ООП там все-таки есть. в самом конце.

В обещм, если у тебя есть еще какие-то сомнения, то пиши. Но мне кажется, что ты пропустил задачи из главы про ООП и потому толком в нем не разобрался.

Показать весь текст

333 6 мая, 00:44 333 1394687

Вообще как происходит разработка приложения в норме? Понятно, что не вручную всё пишется.
Я сейчас бросаю композер в папку, там зависимости прописываю и ставлю, потом собираю это долго и нудно во что-то работающее.

Ответы394730

334 6 мая, 04:50 334 1394707

>>1394637
Я другой анон.
Сам учу PHP по урокам Виктора Зинченко. Он лучший из всего на YouTube. У парня талант обучать других людей.

335 6 мая, 04:52 335 1394708

>>1394637

Я другой анон.

Сам учу PHP по урокам Виктора Зинченко.

Он лучший из всего на YouTube. У парня талант обучать других людей.

336 6 мая, 05:33 336 1394709

>>1394637
А в чём разница между фрейморками ? Я в этом теме вообще ничего не понимаю. Может посоветуешь ?

8-170 337 6 мая, 08:50 337 1394730

8-170

>>1394687

Что значит "не вручную"? Код пока пишут вручную.

>>1394607

Сервисы - это и есть ядро приложения без пользовательского интерфейса, бизнес-логика. Подход описан например у Фаулера:

- https://martinfowler.com/eaaCatalog/serviceLayer.html
- http://design-pattern.ru/patterns/service-layer.html

Ну например, если у тебя есть приложение-файлообменник, ты можешь сделать сервис загрузки файлов и в нем метод "добавить файл". Это позволяет тебе добавить файл не только вручную через сайт, но и программно, из кода. Это может пригодиться, если ты например будешь делать API, при тестировании, да и просто делает код аккуратнее.

У меня возникает другой вопрос, а как можно писать код без сервисов? Лапша же получается с толстыми контроллерами.

Код в контроллере нельзя повторно использовать, в отличие от сервиса. Ну и в MVC роль контроллера в интерпретации команд пользователя.

> Утилиты это классы со статик методами, служащими аналогом обычных функций?

Да. Паттерн Utility Class.

> Стоит ли делать отдельный класс роутера для списка студентов?

Можно сделать. Стоит или не стоит - думай сам.

338 6 мая, 08:52 338 1394732

>>1394643

> А что тогда должен ловить try/catch?

Ты урок про исключения прочел? Смысл исключений как раз в том, чтобы не писать кучу if или кучу try/catch.

> Вот посмотри мой код, пожалуйста. Где тут ошибки

- пользователю не показывается красивая страница ошибки
- информация об ошибке не попадает в лог ошибок
- для показа страницы ошибки try/catch пишут один раз в начале программы, а не вокруг каждого вызова функции

В твоем случае надо либо использовать set_exception_handler, либо оборачивать все в огромный try/catch.

> Если да, то какую ошибку функция query() может выбрасывать? Тоже PDOException?

А в мануале ответа нету? Тут например: https://www.php.net/manual/ru/pdo.error-handling.php

Ошибки естественно могут быть: ошибка в SQL-запросе, ошибка связи с БД.

> Мне нужно оборачивать запрос $dbh->query($query); в try/catch?

Не нужно.

Что использовать: PDO или mysqli - не принципиально, они оба поддерживают исключения.

>>1394604

Померяй или погугли тесты.

338 6 мая, 08:52 338 1394732

>>1394643

> А что тогда должен ловить try/catch?

Ты урок про исключения прочел? Смысл исключений как раз в том, чтобы не писать кучу if или кучу try/catch.

> Вот посмотри мой код, пожалуйста. Где тут ошибки

- пользователю не показывается красивая страница ошибки
- информация об ошибке не попадает в лог ошибок
- для показа страницы ошибки try/catch пишут один раз в начале программы, а не вокруг каждого вызова функции

В твоем случае надо либо использовать set_exception_handler, либо оборачивать все в огромный try/catch.

> Если да, то какую ошибку функция query() может выбрасывать? Тоже PDOException?

А в мануале ответа нету? Тут например: https://www.php.net/manual/ru/pdo.error-handling.php

Ошибки естественно могут быть: ошибка в SQL-запросе, ошибка связи с БД.

> Мне нужно оборачивать запрос $dbh->query($query); в try/catch?

Не нужно.

Что использовать: PDO или mysqli - не принципиально, они оба поддерживают исключения.

>>1394604

Померяй или погугли тесты.

Показать весь текст
Ответы394743

339 6 мая, 08:54 339 1394733

>>1394590

> Есть класс WebReader

Это называется обычно HttpClient. И есть уже готовые клиенты, например, Guzzle.

Тебе надо переделать архитектуру и выбрасывать исключение наверх, а в классе-наследнике ловить его и обрабатывать как нужно, либо сделать в базовом классе опцию для включения этого кода, и выставлять ее в true в наследнике, либо вынести решение вопроса "что делать при ошибке" в отдельный метод, и тогда наследник может его переопределить.

А вообще, если речь идет о сккрейпинге, там не стоит сильно заморачиваться с архитектурой, это обычно одноразовые скрипты, которые постепенно приходят в негодность и переписывают или выкидывают.

> Это будет нормально - передать ему исключение, на основе которого он либо изменит свойства класса (модифицирует запрос)

Непонятно, кстати, почему у тебя параметры запроса хранятся в свойствах класса. У тебя объект представляет один запрос и для нового запроса создается новый объект? Если нет, то это может быть ошибкой в архитектуре. Ну например: что, если ты в процессе обработки одного запроса попытаешься через этот класс сделать другой? Свойства второго запроса затрут первый?

>>1394581

Он не может обработать ошибку соединения с БД. У него нет резервной БД или чего-то такого. Потому ему не нужен отдельный обработчик для именно этой ошибки, а нужен один общий обработчик для любых ошибок и для показа страницы ошибки.

>>1394582

Несколько try/catch пишется, если ты знаешь, как обработать конкретную ошибку. Иначе пишется один общий обработчик ошибок на все случаи жизни.

>>1388385

В нем ничего не заменено, просто QUERY_STRING - это то, что идет ПОСЛЕ знака вопроса в URL (потому знака вопроса в ней нету) и она вообще может отсутствовать. Открой мануал и проверь: https://www.php.net/manual/ru/reserved.variables.server.php

Также, можешь прочитать урок про структуру URL на всякий случай: https://github.com/codedokode/pasta/blob/master/network/urls.md - там написано, что такое query string

>>1387384

Урок по MVC https://github.com/codedokode/pasta/blob/master/arch/mvc.md

339 6 мая, 08:54 339 1394733

>>1394590

> Есть класс WebReader

Это называется обычно HttpClient. И есть уже готовые клиенты, например, Guzzle.

Тебе надо переделать архитектуру и выбрасывать исключение наверх, а в классе-наследнике ловить его и обрабатывать как нужно, либо сделать в базовом классе опцию для включения этого кода, и выставлять ее в true в наследнике, либо вынести решение вопроса "что делать при ошибке" в отдельный метод, и тогда наследник может его переопределить.

А вообще, если речь идет о сккрейпинге, там не стоит сильно заморачиваться с архитектурой, это обычно одноразовые скрипты, которые постепенно приходят в негодность и переписывают или выкидывают.

> Это будет нормально - передать ему исключение, на основе которого он либо изменит свойства класса (модифицирует запрос)

Непонятно, кстати, почему у тебя параметры запроса хранятся в свойствах класса. У тебя объект представляет один запрос и для нового запроса создается новый объект? Если нет, то это может быть ошибкой в архитектуре. Ну например: что, если ты в процессе обработки одного запроса попытаешься через этот класс сделать другой? Свойства второго запроса затрут первый?

>>1394581

Он не может обработать ошибку соединения с БД. У него нет резервной БД или чего-то такого. Потому ему не нужен отдельный обработчик для именно этой ошибки, а нужен один общий обработчик для любых ошибок и для показа страницы ошибки.

>>1394582

Несколько try/catch пишется, если ты знаешь, как обработать конкретную ошибку. Иначе пишется один общий обработчик ошибок на все случаи жизни.

>>1388385

В нем ничего не заменено, просто QUERY_STRING - это то, что идет ПОСЛЕ знака вопроса в URL (потому знака вопроса в ней нету) и она вообще может отсутствовать. Открой мануал и проверь: https://www.php.net/manual/ru/reserved.variables.server.php

Также, можешь прочитать урок про структуру URL на всякий случай: https://github.com/codedokode/pasta/blob/master/network/urls.md - там написано, что такое query string

>>1387384

Урок по MVC https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Показать весь текст
Ответы394909

340 6 мая, 08:56 340 1394734

>>1387455

Я думаю, все проще. Подстановка через плейсхолдеры работает только для значений (чисел и строк), но не для идентификаторов (имен полей и таблиц). Ну и да, мануал на английском, это опен сурс, если никто не будет его переводить, то версии на русском не будет.

Для Постгреса, кстати, есть русский перевод мануала.

>>1386695

Ты передаешь неправильные параметры наверно, либо не тот ид телефонии, либо не то число часов. Или передаешь его строкой может быть.

>>1382988

php-fpm это менеджер процессов PHP, к которому nginx обращается по протоколу FastCGI. Он запускается как отдельная от nginx программа. Apache тоже поддерживает FastCGI и может с ним взаимодействовать.

Обычно схема такая: запросы идут на нгинкс, статические файлы он отдает сам, динамические запросы к страницам сайта передает в php-fpm, который выполняет php-скрипт.

mod_php - это интерпретатор PHP, оформленный в виде модуля к Апачу. Он загружается внутрь Апача и естественно, без Апача работать не может.

>>1382148

Это можно сделать, но тут сложность в том, что он не будет искать ошибки в захваченной фразе. Ну, например, если мы хотим захватить ближайшее слово справа и слева, то можем написать:

\S+\s＊...\s＊\S+

Но тогда в захваченном слове не будут искаться ошибки, так как preg_match_all() не проходится повторно по уже найденной подстроке.

Другой вариант - использовать опцию PREG_MATCH_OFFSET_CAPTURE, которая сохраняет для каждого найденного вхождения позицию в байтах от начала строки. Эту позицию преобразовываем в символы и берем например текст, по 20 символов в обе стороны от места ошибки.

Ну и покажи код, чтобы было можно что-то еще добавить.

340 6 мая, 08:56 340 1394734

>>1387455

Я думаю, все проще. Подстановка через плейсхолдеры работает только для значений (чисел и строк), но не для идентификаторов (имен полей и таблиц). Ну и да, мануал на английском, это опен сурс, если никто не будет его переводить, то версии на русском не будет.

Для Постгреса, кстати, есть русский перевод мануала.

>>1386695

Ты передаешь неправильные параметры наверно, либо не тот ид телефонии, либо не то число часов. Или передаешь его строкой может быть.

>>1382988

php-fpm это менеджер процессов PHP, к которому nginx обращается по протоколу FastCGI. Он запускается как отдельная от nginx программа. Apache тоже поддерживает FastCGI и может с ним взаимодействовать.

Обычно схема такая: запросы идут на нгинкс, статические файлы он отдает сам, динамические запросы к страницам сайта передает в php-fpm, который выполняет php-скрипт.

mod_php - это интерпретатор PHP, оформленный в виде модуля к Апачу. Он загружается внутрь Апача и естественно, без Апача работать не может.

>>1382148

Это можно сделать, но тут сложность в том, что он не будет искать ошибки в захваченной фразе. Ну, например, если мы хотим захватить ближайшее слово справа и слева, то можем написать:

\S+\s＊...\s＊\S+

Но тогда в захваченном слове не будут искаться ошибки, так как preg_match_all() не проходится повторно по уже найденной подстроке.

Другой вариант - использовать опцию PREG_MATCH_OFFSET_CAPTURE, которая сохраняет для каждого найденного вхождения позицию в байтах от начала строки. Эту позицию преобразовываем в символы и берем например текст, по 20 символов в обе стороны от места ошибки.

Ну и покажи код, чтобы было можно что-то еще добавить.

Показать весь текст

341 6 мая, 08:58 341 1394735

>>1382113

Для разбиения на строки хватило бы explode().

Переменные можно назвать лучше: afterSplit -> lines, stringAfter -> line, text1 -> characters

> $i<34

Это лучше бы вычислять, например, как макс. из длины строк, одной строкой, используя array_map() и max().

> $text1[$k][$i] != "\0"

В реальном тексте там нет символа с нулевым кодом и твоя проверка не имеет смысла.

Ты тут обращаешься к несуществующим элементам массива и это вызвает ошибки. Тебе стоило бы сделать проверку, что $k меньше чем число символов в текущей строке. У тебя есть проверка, но она некорректная (она сравнивает не с числом символов в текущей строке, а с числом в последней).

То есть тебе стоит сделать так:

если (k меньше чем число символов в данной строке) то вывести пробел.

>>1381775

Комментарии лучше писать над строкой, а не справа, а то слишком длинные строки выходят.

ё не входит в диапазон а-я и её надо писать отдельно.

> for ($i=(count($matches)-1); $i>=0; $i--) {

Не стоит заниматься такими микрооптимизациями, они ухудшают читабельность. Также, для обхода массива стоит использовать foreach().

> like in 20 line

Не стоит ссылаться на номера строк, так как они меняются при доработке кода.

Для замены букв по массиву замен есть функция strtr().

Ты считаешь все латинские буквы неправильными, но могут быть и латинские слова с русскими буквами - лучше проверять по первой букве или как-то еще.

Про преобразования типов: https://www.php.net/manual/ru/language.types.type-juggling.php

>>1381740

Отдельный сервер нужен для больших объемов отправки.

>>1380807

Добавь еще экранирование выводимых данных.

341 6 мая, 08:58 341 1394735

>>1382113

Для разбиения на строки хватило бы explode().

Переменные можно назвать лучше: afterSplit -> lines, stringAfter -> line, text1 -> characters

> $i<34

Это лучше бы вычислять, например, как макс. из длины строк, одной строкой, используя array_map() и max().

> $text1[$k][$i] != "\0"

В реальном тексте там нет символа с нулевым кодом и твоя проверка не имеет смысла.

Ты тут обращаешься к несуществующим элементам массива и это вызвает ошибки. Тебе стоило бы сделать проверку, что $k меньше чем число символов в текущей строке. У тебя есть проверка, но она некорректная (она сравнивает не с числом символов в текущей строке, а с числом в последней).

То есть тебе стоит сделать так:

если (k меньше чем число символов в данной строке) то вывести пробел.

>>1381775

Комментарии лучше писать над строкой, а не справа, а то слишком длинные строки выходят.

ё не входит в диапазон а-я и её надо писать отдельно.

> for ($i=(count($matches)-1); $i>=0; $i--) {

Не стоит заниматься такими микрооптимизациями, они ухудшают читабельность. Также, для обхода массива стоит использовать foreach().

> like in 20 line

Не стоит ссылаться на номера строк, так как они меняются при доработке кода.

Для замены букв по массиву замен есть функция strtr().

Ты считаешь все латинские буквы неправильными, но могут быть и латинские слова с русскими буквами - лучше проверять по первой букве или как-то еще.

Про преобразования типов: https://www.php.net/manual/ru/language.types.type-juggling.php

>>1381740

Отдельный сервер нужен для больших объемов отправки.

>>1380807

Добавь еще экранирование выводимых данных.

Показать весь текст
Ответы395036

342 6 мая, 09:01 342 1394736

>>1380549

> 1. Будет ли хорошим решением получать объект студента статическим методом из класса-помощника?

Нет. Вообще, зачем тебе создавать объек студента из глобальных переменных? Ты обычно просто обновляешь его свойства из глобальных переменных. Обычно делают в самом объекте метод вроде updateAttributes, который принимает произвольный массив, тщательно все проверяет и обновляет свойства.

> 2. Хорошим ли решением будет хранить введенные студентом данные на стороне сервера, чтобы в случае вывода ошибки при валидации вставлять их в html-атрибут value?

Как это делать, описано в моем уроке про формы и в комментариях к задаче: https://github.com/codedokode/pasta/blob/master/forms.md

> 3. Можно ли вызывать встроенные в php функции из логики шаблонов? Да и обычные функции, ведь они могут содержать в себе сложную логику.

Можно для оформления вывода, чтобы например, как-то отформатировать число, итд.

> 4. Я забрёл слишком далеко и начал тестировать с phpunit валидатор студента, а у меня в нём большинство методов защищенные. Пришлось использовать Reflectionclass для получения доступа к ним, это нормальная практика?

Это неправильно. Ты не должен при тестировании "знать", как устроен тестируемый класс. Ты тестируешь только публичные методы, те же, что использует программа. Ты используешь класс так же, как программа, не имея каких-то тайных дверей внутрь него. При таком подходе мы можем менять содержимое класса, не трогая тесты. А также, тесты получаются ближе к тому, что делает программа.

При твоем же подходе тебе придется постоянно переделывать тесты при рефакторингах, что замедляет разработку.

> И про валидатор, в нём самые часто используемые конструкции по типу измерения длины строки/проверки на пустоту, я обобщил в отдельные методы. Как вам такое решение?

Нормально.

> Для каждой способности этого метода писать отдельный тест-метод?

Обычно тестируют выполнение "требований". Что должен делать метод? В простейшем случае: 1) пропускать правильные значения 2) не пропускать неправильные. Значит, пишем 2 теста. Это еще назвыают "позитивный" и "негативный" сценарий.

У тебя требований несколько, и логично каждое проверять отдельным тестом. Тогда при поломке мы сразу увидим, что именно не работает.

Но на практике это может раздувать объем тестов, и тогда можно негативные тесты собрать вместе в один тест, проверяющий разные значения.

>>1380793

В шаблон удобнее передать объект студента.

342 6 мая, 09:01 342 1394736

>>1380549

> 1. Будет ли хорошим решением получать объект студента статическим методом из класса-помощника?

Нет. Вообще, зачем тебе создавать объек студента из глобальных переменных? Ты обычно просто обновляешь его свойства из глобальных переменных. Обычно делают в самом объекте метод вроде updateAttributes, который принимает произвольный массив, тщательно все проверяет и обновляет свойства.

> 2. Хорошим ли решением будет хранить введенные студентом данные на стороне сервера, чтобы в случае вывода ошибки при валидации вставлять их в html-атрибут value?

Как это делать, описано в моем уроке про формы и в комментариях к задаче: https://github.com/codedokode/pasta/blob/master/forms.md

> 3. Можно ли вызывать встроенные в php функции из логики шаблонов? Да и обычные функции, ведь они могут содержать в себе сложную логику.

Можно для оформления вывода, чтобы например, как-то отформатировать число, итд.

> 4. Я забрёл слишком далеко и начал тестировать с phpunit валидатор студента, а у меня в нём большинство методов защищенные. Пришлось использовать Reflectionclass для получения доступа к ним, это нормальная практика?

Это неправильно. Ты не должен при тестировании "знать", как устроен тестируемый класс. Ты тестируешь только публичные методы, те же, что использует программа. Ты используешь класс так же, как программа, не имея каких-то тайных дверей внутрь него. При таком подходе мы можем менять содержимое класса, не трогая тесты. А также, тесты получаются ближе к тому, что делает программа.

При твоем же подходе тебе придется постоянно переделывать тесты при рефакторингах, что замедляет разработку.

> И про валидатор, в нём самые часто используемые конструкции по типу измерения длины строки/проверки на пустоту, я обобщил в отдельные методы. Как вам такое решение?

Нормально.

> Для каждой способности этого метода писать отдельный тест-метод?

Обычно тестируют выполнение "требований". Что должен делать метод? В простейшем случае: 1) пропускать правильные значения 2) не пропускать неправильные. Значит, пишем 2 теста. Это еще назвыают "позитивный" и "негативный" сценарий.

У тебя требований несколько, и логично каждое проверять отдельным тестом. Тогда при поломке мы сразу увидим, что именно не работает.

Но на практике это может раздувать объем тестов, и тогда можно негативные тесты собрать вместе в один тест, проверяющий разные значения.

>>1380793

В шаблон удобнее передать объект студента.

Показать весь текст

343 6 мая, 09:02 343 1394737

>>1380690

> Так ведь там весь массив гет из реквеста, а не просто место для сохранения.

А это неправильно и говорит о том, что ты не понимаешь разделение ответственности. Задача генератора ссылок - генерировать ссылки, а откуда пришли данные, из GET или из базы данных, или еще откуда-то - он знать не должен. Потому в нем не должно быть упоминания массива GET. Ты не разделяешь зоны ответственности в коде.

> Вообще, задумка была такой, что замыкание передаётся в шаблон под каким-то именем, где просто вызывается как на пикрелейтед. Меняются только запрошенные параметры, остальные не остаются как были. Ну и пустой писанины чтоб поменьше.

Ну так можно сделать нормально, так что можно сделать несколько анонимных функций и они не влияют друг на друга.

> Зачем? Количество записей ведь не изменилось.

Я вроде писал, так везде делают. Когда ты жмешь сортировку, ты хочешь увидеть САМЫЕ большие или маленькие значения, а для этого надо перейти на первую страницу. Иначе ты оказываешься где-то в середине.

119 Кб, 1250x796
344 6 мая, 09:46 344 1394743

>>1394732
>чтобы не писать кучу if или кучу try/catch.
В смысле? На той же яве и в C++ try/catch нужно было на каждый чих ОТДЕЛЬНО устанавливать, а в PHP он как то по другому действует? Тип как try/catch может выглядеть ОДИН на всю программу?

>В твоем случае надо либо использовать set_exception_handler, либо оборачивать все в огромный try/catch
Я чет не понимаю. try/catch должен оборачивать что? ??

>А в мануале ответа нету? Тут например
Там написано, для того чтобы получить ошибку нужно вызвать какую то функцию. И я не увидел какую именно ошибку выбрасывает запрос. Мне же нужно знать, какую именно ошибку выбрасывает запрос, чтобы поймать ее.

Ответы394746394747

345 6 мая, 10:01 345 1394746

>>1394743
Короче, вот если так сделать, то что будет. Это кстати разработка БД, мне не нужно выдавать ошибку

<?php
set_exception_handler(function (Throwable $exception) {
//Код из мануала ОПа
error_log($e->__toString());

header("HTTP/1.0 503 Temporary unavailable");
header("Content-type: text/plain; charset=utf-8");

});
require_once __DIR__ . '/login.php';

$dbh = new PDO('mysql:host=localhost;dbname=', $un, $pw);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //И куда теперь эту штуку девать?
$query = "CREATE TABLE student (
id SMALLINT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
surname VARCHAR(50) NOT NULL,
gender ENUM('male', 'female') NOT NULL,
groupNumber VARCHAR(5) NOT NULL,
email VARCHAR(30) NOT NULL UNIQUE,
totalPoints SMALLINT UNSIGNED NOT NULL,
yearOfBirth YEAR NOT NULL,
localOrNonresident ENUM('local', 'nonresident') NOT NULL,
PRIMARY KEY (id)
)";

$dbh->query($query);
$dbh

345 6 мая, 10:01 345 1394746

>>1394743
Короче, вот если так сделать, то что будет. Это кстати разработка БД, мне не нужно выдавать ошибку

<?php
set_exception_handler(function (Throwable $exception) {
//Код из мануала ОПа
error_log($e->__toString());

header("HTTP/1.0 503 Temporary unavailable");
header("Content-type: text/plain; charset=utf-8");

});
require_once __DIR__ . '/login.php';

$dbh = new PDO('mysql:host=localhost;dbname=', $un, $pw);
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //И куда теперь эту штуку девать?
$query = "CREATE TABLE student (
id SMALLINT NOT NULL AUTO_INCREMENT,
name VARCHAR(50) NOT NULL,
surname VARCHAR(50) NOT NULL,
gender ENUM('male', 'female') NOT NULL,
groupNumber VARCHAR(5) NOT NULL,
email VARCHAR(30) NOT NULL UNIQUE,
totalPoints SMALLINT UNSIGNED NOT NULL,
yearOfBirth YEAR NOT NULL,
localOrNonresident ENUM('local', 'nonresident') NOT NULL,
PRIMARY KEY (id)
)";

$dbh->query($query);
$dbh

Показать весь текст
Ответы394749

346 6 мая, 10:01 346 1394747

>>1394743

Пусть у тебя все запросы идут через index.php. Тогда можно написать в нем:

require_once '....error_handler.php';
initErrorHandler();

try {
require_once 'bootstrap.php';
$fc = new FrontContrller();
$fc->handleRequest();
} catch (Throwable $e) {
handleException($e);
}

Альтернатива:

require_once '....error_handler.php';
initErrorHandler();
set_exception_handler('handleException');
$fc = new FrontContrller();
$fc->handleRequest();

Соответственно, во всех остальных местах кода try/catch не нужен, так как исключение будет поймано в index.php. Объясни теперь, откуда у тебя идея, что его надо писать много раз?

В мануале специально дан такой пример, чтобы с помощью расположения try/catch показать, в каком месте выбрасывается исключение. Это не значит, что ты его должен копировать строка в строку. Более того, там объясняется, как отключить выброс исключений и использовать ERRMODE_WARNING, потому и try/catch так поставлен, чтобы исключение не вылетело наружу из кода. А у тебя цели "отключать" исключения нету. То есть ты нашел в мануале пример, который вообще отношения к твоей ситуации не имеет.

В яве и Си++ то же самое, не требуется везде ставить try/catch.

Видимо, я плохо в уроке про исключения это объясняю. Но тебе определенно надо изучить исключения получше.

346 6 мая, 10:01 346 1394747

>>1394743

Пусть у тебя все запросы идут через index.php. Тогда можно написать в нем:

require_once '....error_handler.php';
initErrorHandler();

try {
require_once 'bootstrap.php';
$fc = new FrontContrller();
$fc->handleRequest();
} catch (Throwable $e) {
handleException($e);
}

Альтернатива:

require_once '....error_handler.php';
initErrorHandler();
set_exception_handler('handleException');
$fc = new FrontContrller();
$fc->handleRequest();

Соответственно, во всех остальных местах кода try/catch не нужен, так как исключение будет поймано в index.php. Объясни теперь, откуда у тебя идея, что его надо писать много раз?

В мануале специально дан такой пример, чтобы с помощью расположения try/catch показать, в каком месте выбрасывается исключение. Это не значит, что ты его должен копировать строка в строку. Более того, там объясняется, как отключить выброс исключений и использовать ERRMODE_WARNING, потому и try/catch так поставлен, чтобы исключение не вылетело наружу из кода. А у тебя цели "отключать" исключения нету. То есть ты нашел в мануале пример, который вообще отношения к твоей ситуации не имеет.

В яве и Си++ то же самое, не требуется везде ставить try/catch.

Видимо, я плохо в уроке про исключения это объясняю. Но тебе определенно надо изучить исключения получше.

Показать весь текст
Ответы394765

347 6 мая, 10:04 347 1394749

>>1394746

Если это скрипт, который запускается вручную из консоли (командной строки), то вообще писать try/catch не нужно, так как PHP в этой ситуации при исключении выведет информацию о нем и завершит скрипт. И соответственно, header в консоли не имеет никакого смысла.

Если это не скрипт в консоли, а для веба, то надо делать, как я описал выше, либо set_exception_handler, либо все завернуть в единственный try/catch.

Ответы394772

348 6 мая, 11:09 348 1394765

>>1394747
Еще больше запутался.
require_once '....error_handler.php';
Что это за многоточие и что это подключаем тут?

initErrorHandler();
И эта функция что делает?? Не гуглится

Скажи я правильно понял или нет, пожалуйста.
Берем главный файл index.php. В него входят две первые строчки, которые я не понял и дальше включаем try. В try идет подключение файла bootstrap. А bootstrap это толи модель, толи просто инициализатор в MVC. Там хранятся файлы:
1) Класс, который описывает сущность студент
2) Класс, который работает с базой данных(паттерн TableDataGateway)
3) Класс, который проверяет правильность ввода данных.
Так вот в тех классах исключения писать не надо? Мне не нужно в классе, который реализует паттерн TableDataGateway использовать отлов ошибок/исключение/try/catch?
Подключение к БД в каком месте идет? В TableDataGateway или в index?
Просто если в index, то что мне делать в конструкторе public function __construct(PDO $pdo) { ... } класса TableDataGateway? Взять данные из базы данных в массив?
И где мне тогда подключаться к базе данных? В try/catch до bootstrap?

$fc = new FrontContrller();
$fc->handleRequest();
Это я тоже не понял. Это шаблоны?

И почему в альтернативе не описана функция set_exception_handler('handleException')? Ты подразумевал, что она где то описана?

Ответы394771415600

349 6 мая, 11:26 349 1394771

>>1394765
>А bootstrap это толи модель, толи просто инициализатор в MVC.
Это прелоадер называется. Там инициализируются зависимости, окружение и тд.

350 6 мая, 11:32 350 1394772

>>1394749
Кстати я подразумевал, что этот скриgn будет использован один раз. То есть он нужен был для GITHub, чтобы можно было включить один раз и все. Он создал бы базу данных и больше не понадобился.

Ответы394785

351 6 мая, 12:05 351 1394785

>>1394772

Лучше использовать для этого SQL-дамп. Просто создаем файл с расширением .sql и в него пишем нужные SQL-команды, с точкой с запятой в конце каждой. Дампы можно генерировать программами вроде mysqldump или phpmyadmin, но можно и писать руками (заодно поучишься SQL).

Загружается дамп через программу-клиент БД или через командную строку.

- http://www.mysql.ru/docs/man/mysqldump.html
- пример первого попавшегося, найденного в гугле, дампа: https://github.com/cymitty/Student-list/blob/master/studentlist.sql

Полезно писать дамп руками, чтобы освоить SQL и работу с дампами из командной строки.

Если же тебе надо что-то посложнее загрузки дампа, то надо сделать скрипт для командной строки. При этом делать страницу ошибки не требуется, и писать try/catch тоже, так как по умолчанию PHP выведет подробности ошибки сам.

Почитать про командную строку простыми словами: https://github.com/codedokode/pasta/blob/master/soft/cli.md

352 6 мая, 16:10 352 1394818

112 Кб, 1044x80535 Кб, 824x569

Циферки у меня выводятся, но не умножаются. Тыкните носом, уже и так и сяк пробовал. Да, тупой, не бейте

Ответы394839

353 6 мая, 18:56 353 1394839

>>1394818
Все действия убирай из ковычек. Ковычки = текст. Сделай конкатенацию. типо - echo "$x $x = " . $x $x

Ответы394840395041

187x19
354 6 мая, 18:57 354 1394840

>>1394839
знака умножения нет :(

Ответы395041

355 6 мая, 20:52 355 1394877

>>1394637
>Зинченко
никогда ничего не учи по-русски

356 6 мая, 22:18 356 1394909

>>1394733
> вынести решение вопроса "что делать при ошибке" в отдельный метод
Вот это мне нравится. Вытащу тогда содержимое catch во вспомогательный метод типа tryToRepairTheRequest().
В родителе будет
protected function tryToRepairTheRequest(\ErrorException $e) {
// можем что-то сделать? если нет, throw $e;
}
В наследниках буду делать
private function tryToRepairTheRequest(\ErrorException $e) {
try { parent::tryToRepairTheRequest($e); }
catch (\ErrorException $e) { // специальный код для наследника, а если не вышло то опять же throw $e; }
}

>У тебя объект представляет один запрос и для нового запроса создается новый объект?
Нет. Запросы могут идти через один объект, а вот ответы - уже новые объекты.
$reader = new WebReader($defaultStreamContext, $maxQtyAttempts); // контекст стрима, который будет использован, если в get() никакой не указан, и кол-во попыток перезапросить при сбоях
$response = $reader->get('https://google.com'[, $streamContext]); // $response - объект класса WebResponse, содержащий ответ
$response2 = $reader->get('https://yandex.ru');

> что, если ты в процессе обработки одного запроса попытаешься через этот класс сделать другой?
Не понял. У меня нет никакой асинхронности и тредов. Вызвал get() - получи WebResponse или эксепшен.
>Свойства второго запроса затрут первый?
Ну, каждый запрос плодит по совершенно независимому WebResponse. WebReader при этом может оставаться один. Все, что он знает - какие хттп-заголовки и параметры стрима выставлять. $url нигде не запоминается и живет только внутри get(), который под капотом вызывает return $this->doRequest($url, $streamContext, $this->qtyAttempts), если ему нравятся переданные параметры. А doRequest() возвращает new WebResponse($http_response_header, $content), куда кладет всё полученное, если запрос удался.

Ответы398391402423402834

357 7 мая, 01:41 357 1394979

ОП, глянешь список студентов?

https://github.com/codecoshauni/student-list
http://b29825zy.beget.tech/ - на хостинге

Ответы395444411268413645

358 7 мая, 09:32 358 1395036

>>1394735
>Отдельный сервер нужен для больших объемов отправки
Большой объём -- это сколько? Есть какое-то правило или просто "не работает в лоб -- поднимай сервер"?
Если я раз в два месяца отправляю пачку около 150 писем, нужен сервер?

Ответы395044

12 Кб, 259x120
359 7 мая, 09:48 359 1395041

>>1394839
>>1394840
Зачем там точка?
Принцип я понял, но теперь не хочет принимать равно.

Ответы395048

360 7 мая, 09:51 360 1395044

>>1395036

По идее, если ты правильно настроил sendmail на своем сервере (а также, возможно, всякие антиспам меры вроде SPF итд, которые описываются в статьях по теме), то все должно работать. Антиспам нужен для массовых рассылок.

Отдельный сервер, как я понимаю, тоже нужен для массовых рассылок, чтобы ты не запускал бы у себя на сервере экземпляр sendmail на каждую отправку письма, а например слал бы их по SMTP на отдельный сервер и с него рассылал. Возможно, это позволяет ускорить передачу писем на рассылку. Соответственно, "массовые" здесь начинается с десятков-сотен тысяч писем и нужно, когда стандартная конфигурация не работает или работает недостаточно быстро.

Или, возможно, ты увлекся микросервисами и хочешь усложнить себе жизнь на ровном месте. Тогда тоже можно сделать отдельный сервер.

Соответственно, у меня ощущение, что ты либо неправильно понял статью, либо в ней ошибки.

Ответы395430

361 7 мая, 10:10 361 1395048

>>1395041

У меня ощущение, что ты просто пробуешь переставлять символы наугад, а надо разобраться и писать код осознанно, понимая каждый символ в нем.

Программа составляется по определенным правилам, которые называются грамматикой. В грамматике определено, из каких частей может состоять текст программы и точный синтаксис каждого варианта. Описание грамматики раскидано по разным частям мануала.

Если твой текст программы не соответствует грамматике, то выдается синтаксическая ошибка (ошибка разбора) и программа не выполняется. Ну например, число должно состоять только из цифр. Если ты попытаешься написать в коде число вида 123xyz, то произойдет ошибка разбора.

Кроме синтаксических бывают и другие ошибки, но другие ошибки возможны только при выполнении программы и при отсутствии синтаксических.

Для начала, пролистай мануал по echo: https://php.net/manual/ru/function.echo.php

Посмотри на синтаксис echo из мануала (скобки я убрал):

echo string $arg1 [, string $... ] ;

Эта строка описывает, что в грамматике разрешено использовать после ключевого слова echo.

После echo можно указать 1 или несколько аргументов через запятую. echo выводит только строки и числа, потому если ты укажешь аргументы другого типа, то он их преобразует в строки или числа.

Теперь посмотри на свой код:

echo "....." = $x * $x\n;

ты пытаешься передать в echo сложную составную конструкцию как один аргумент. Давай её разберем:

"какая-то строка" = какое-то матем. выражение \n ;

Оператор = сохраняет в переменную слева от него значение, записанное справа от него, например:

$a = 2 + 2;

Ты же слева от оператора равно написал строку. В строку, естественно, сохранить ничего нельзя, так как это не переменная. Получается - ошибка синтаксиса, так как слева от знака равно может идти только переменная или похожее на переменную выражение.

Вторая ошибка - это использование \n. Ты его используешь вне строки, и вне строки это просто набор символов, не имеющий смысла и вызывающий ошибку разбора. Символы \n имеют специальный смысл (вставка в строку символа перевода строки) внутри двойных кавычек, но снаружи них это просто ошибка синтаксиса. Про это написано тут: https://www.php.net/manual/ru/language.types.string.php

Далее, прочитай про точку: https://www.php.net/manual/ru/language.operators.string.php - это оператор, работающий со строками. Справа и слева от него указывается строка или выражение, дающее строку, или что-то, что можно преобразовать в строку, и он склеивает строки справа и слева и возвращает результат. То есть точка - это как плюс из математики, только для строк.

Не поленись прочитать ссылки на мануал, которые я дал, можешь уточнять, если что-то непонятно. Если ты хочешь быть программистом, то мануалы тебе придется читать постоянно.

Про поводу того, что надо сделать, есть такие варианты:

- сделать переменную, поместить в нее результат умножения, а эту переменную подставить внутрь выводимой строки
- сделать переменную, поместить в нее результат умножения, и склеить строку с переменной с помощью точки
- склеить выводимую строку с результатом умножения без использования промежуточной переменной

Осмыслив все это, попробуй предложить правильный код, не подбирая ничего наугад. Или задавай вопросы.

361 7 мая, 10:10 361 1395048

>>1395041

У меня ощущение, что ты просто пробуешь переставлять символы наугад, а надо разобраться и писать код осознанно, понимая каждый символ в нем.

Программа составляется по определенным правилам, которые называются грамматикой. В грамматике определено, из каких частей может состоять текст программы и точный синтаксис каждого варианта. Описание грамматики раскидано по разным частям мануала.

Если твой текст программы не соответствует грамматике, то выдается синтаксическая ошибка (ошибка разбора) и программа не выполняется. Ну например, число должно состоять только из цифр. Если ты попытаешься написать в коде число вида 123xyz, то произойдет ошибка разбора.

Кроме синтаксических бывают и другие ошибки, но другие ошибки возможны только при выполнении программы и при отсутствии синтаксических.

Для начала, пролистай мануал по echo: https://php.net/manual/ru/function.echo.php

Посмотри на синтаксис echo из мануала (скобки я убрал):

echo string $arg1 [, string $... ] ;

Эта строка описывает, что в грамматике разрешено использовать после ключевого слова echo.

После echo можно указать 1 или несколько аргументов через запятую. echo выводит только строки и числа, потому если ты укажешь аргументы другого типа, то он их преобразует в строки или числа.

Теперь посмотри на свой код:

echo "....." = $x * $x\n;

ты пытаешься передать в echo сложную составную конструкцию как один аргумент. Давай её разберем:

"какая-то строка" = какое-то матем. выражение \n ;

Оператор = сохраняет в переменную слева от него значение, записанное справа от него, например:

$a = 2 + 2;

Ты же слева от оператора равно написал строку. В строку, естественно, сохранить ничего нельзя, так как это не переменная. Получается - ошибка синтаксиса, так как слева от знака равно может идти только переменная или похожее на переменную выражение.

Вторая ошибка - это использование \n. Ты его используешь вне строки, и вне строки это просто набор символов, не имеющий смысла и вызывающий ошибку разбора. Символы \n имеют специальный смысл (вставка в строку символа перевода строки) внутри двойных кавычек, но снаружи них это просто ошибка синтаксиса. Про это написано тут: https://www.php.net/manual/ru/language.types.string.php

Далее, прочитай про точку: https://www.php.net/manual/ru/language.operators.string.php - это оператор, работающий со строками. Справа и слева от него указывается строка или выражение, дающее строку, или что-то, что можно преобразовать в строку, и он склеивает строки справа и слева и возвращает результат. То есть точка - это как плюс из математики, только для строк.

Не поленись прочитать ссылки на мануал, которые я дал, можешь уточнять, если что-то непонятно. Если ты хочешь быть программистом, то мануалы тебе придется читать постоянно.

Про поводу того, что надо сделать, есть такие варианты:

- сделать переменную, поместить в нее результат умножения, а эту переменную подставить внутрь выводимой строки
- сделать переменную, поместить в нее результат умножения, и склеить строку с переменной с помощью точки
- склеить выводимую строку с результатом умножения без использования промежуточной переменной

Осмыслив все это, попробуй предложить правильный код, не подбирая ничего наугад. Или задавай вопросы.

Показать весь текст
Ответы395076

362 7 мая, 11:16 362 1395076

>>1395048
Пока вопрос один. В обучалке этого обьёма информации нет. Её надо в мануалах искать самому и дальше?

Ответы395080

363 7 мая, 11:21 363 1395080

>>1395076

Согласен, в учебнике есть что дорабатывать. Пока что можно параллельно с учебником искать в мануале описанные там функции и читать дополнительно. Учебник помогает тем, что тебе не надо читать весь мануал, он показывает, на что именно обратить внимание и дает пример использования функций.

Ответы395208

364 7 мая, 14:14 364 1395208

>>1395080
В учебнике ОПа хотелось бы больше примеров. Всё таки иногда понятнее посмотреть с небольшими пояснениями, чем прочитать смутные отсылки и попытки "объяснить на пальцах". Абстракции и шаблоны одними словами лучше даже не объяснять.
К тому же новичкам необходимо первое время больше читать, чем писать, как я думаю.

Понятно, что ОП даёт названия и отсылки, и можно посмотреть в гугле. Но гугл на то и гугл, что там до сих пор встречается код на том же mysql), или просто школьники с хабра - он на ранжирует качество написанного.

365 7 мая, 21:47 365 1395418

объясните мне хрень про стрелочку и this

Ответы395431395433

366 7 мая, 22:26 366 1395430

>>1395044
Статью не читал, просто в своё время делали с корешем прогу на питоне для рассылки оценок и прочей инфы, чтобы сократить ёблю единственной девочке из учебного офиса нашего института, которая всем этим занималась. Тогда мы поднимали smtp-сервер, потому что вроде как других способов не нашли, а сейчас мне просто интересно, как это можно было бы сделать на пхп

Ответы395435

367 7 мая, 22:31 367 1395431

>>1395418
Прочитай еще пару раз гайд от ОПа, там вроде предельно ясно обьяснено что это и зачем нужно

368 7 мая, 22:34 368 1395433

>>1395418
Иди нахуй.

Ответы395551

369 7 мая, 22:36 369 1395435

>>1395430
>в своё время делали с корешем прогу на питоне для рассылки оценок и прочей инфы, чтобы сократить ёблю единственной девочке из учебного офиса нашего института, которая всем этим занималась
м-м-максимум куколдизм

Ответы395778

79 Кб, 1280x720
370 7 мая, 23:07 370 1395444

>>1394979
Анон, через 'е' пишется. Ты из js-треда к нам?

Ответы395446

371 7 мая, 23:18 371 1395446

>>1395444
Если что, это я к анону, который зарегался, а не к создателю студентов.

Ответы395451

372 7 мая, 23:28 372 1395451

>>1395446
Ща я тож зарегаюсь.

Ответы395461

373 8 мая, 00:04 373 1395461

>>1395451
Пацаны, не вынуждайте меня искать вас по ip из логов.

Ответы395463395478

374 8 мая, 00:13 374 1395463

>>1395461
Хуй соси
Губой тряси

375 8 мая, 01:08 375 1395478

>>1395461
Ты удолил запись что ли? У меня пусто в профиле, да и в таблице тож.

Ответы395495

376 8 мая, 01:15 376 1395479

Не тратте время на изучение пыхи, это умирающая технология. Ничего нового на ней не пишут. Вакансий все меньше и смотреть на вас будут как на говно даже фронтендеры.

Ответы395480

377 8 мая, 01:19 377 1395480

>>1395479
А что учить?

Ответы395481

378 8 мая, 01:24 378 1395481

>>1395480
Java/C#/Python/Node.js - все что угодно из этого, только не пыху

Ответы395482395507

379 8 мая, 01:28 379 1395482

>>1395481
А что, по ноде вакансий больше?

Ответы395484

380 8 мая, 01:31 380 1395484

>>1395482
в развитых странах он уже обогнал пыху по вакансиям. а все тренды рано или поздно проявляются в снг

Ответы395485395498

381 8 мая, 01:33 381 1395485

>>1395484
Пруф есть, или бабка нашептала?

Ответы395487

382 8 мая, 01:37 382 1395487

17 Кб, 611x20017 Кб, 563x187

>>1395485

Ответы395488

383 8 мая, 01:44 383 1395488

>>1395487
А в штатах чё? Нах ты один Израиль принёс, мы что, евреи?

Ответы395489

384 8 мая, 01:45 384 1395489

>>1395488
хз, что в штатах. я там не живу, но подозреваю, что пыха там еще менее популярна, чем в израиле

Ответы395496

385 8 мая, 01:45 385 1395490

>>1380485 (OP)
Сап, пхп тред.
Дело такое, есть вероятность перекатиться на вакансию на бек php/java, а проблема в том, что не шарю за php почти никак. Делал круд в шарагу, но я думаю этого не хватит. На джаве писал на спринговом стеке, даже на котле писал чутка. Так вот, есть ли у вас какая нить годная книга чтобы без ЕХО "ХЕЛО ВРОЛД", а сразу четенько и по делу.
Олсо, может кто так же перекатывался с джавы, отпишитесь как и что.

Ответы395492

386 8 мая, 01:47 386 1395492

>>1395490
главное это пройти собеседование, а там легко перекатишся с джавы.
вот у меня всегда проблема решить задание на месте, потому-что мне надо думать в спокойной обстановке

Ответы395505

387 8 мая, 01:57 387 1395495

>>1395478
Да, лучше бы код мой засрали на гите, а не базу.

Ответы395497

388 8 мая, 01:58 388 1395496

>>1395489
А мы в Израиле не живем - нафига ты его принёс я понять не могу. Подозрения свои при себе оставь - ЖС сейчас на хайпе, вот и результат. Потом попустит.

С другой стороны нубы, вроде тебя, не понимают, что если ты учил программирование, а не язык, то освоение другого языка - не проблема. ЯП всего лишь инструмент.

Ответы395498

389 8 мая, 01:59 389 1395497

>>1395495
А что так? Ну написали тебе там ерунды, так ононы же всегда ерунду пишут.

Ответы395502

390 8 мая, 02:04 390 1395498

>>1395496
>ты учил программирование, а не язык
то ты обосрешся на собеседовании, когда не сможешь пояснить за конкретные технологии

>нафига ты его принёс я понять не могу
>>1395484

>ЖС сейчас на хайпе
сейчас это с 2011 года?

Ответы395499

391 8 мая, 02:07 391 1395499

>>1395498
Ты пруфов толком так и не принёс, толстяк.

Ответы395501

392 8 мая, 02:10 392 1395501

>>1395499
если ты фрилансер или живешь в снг и собираешся там дальше жить, то пыха норм - еще лет 15 протянет
Я лишь хотел дать рекомендацию тем, кто планирует свалить в развитые страны

Ответы395503

393 8 мая, 02:12 393 1395502

>>1395497
Испанский стыд был, как будто ребенок отсталый двачер писал. А так похер вообще, что в моем круде напишете.

394 8 мая, 02:14 394 1395503

>>1395501
>еще лет 15 протянет
Слишком смелое заявление для того, кто пруфов не принёс.

Ответы395504

395 8 мая, 02:16 395 1395504

>>1395503
я принес тебе пруф рынка труда в стране которая точно входит в 10-ку по передовым технологиям в мире

сразу отвечу, что мне похуй пруф для тебя это или нет, путь каждый сам решит

Ответы395508

396 8 мая, 02:17 396 1395505

>>1395492
ну мне фактически не нужно прям с головой в пыху залезть, мне нужно просто понять что почем, просто я работал на жабке и когда сел за пыху первый(единственный, лол) раз меня прям нормально так колдоёбило, вообще блять как другой мир

Ответы395506395511

397 8 мая, 02:19 397 1395506

>>1395505
я делал файлообменник из ОП-поста на Джаве и было труднее, чем на пхп

398 8 мая, 02:20 398 1395507

>>1395481
>>смотреть на вас будут как на говно даже фронтендеры
>советует учить ноду
ну ты же понимаешь кем становится человек который учит ноду

Ответы395510

399 8 мая, 02:20 399 1395508

>>1395504
Ты вполне мог избирательно пруф принести. Я тебе не верю.
Речь шла о развитых странах, а не только Израиле.

С другой стороны мне просто насрать на твоё мнение. Будем уж честны.

Ответы395509

400 8 мая, 02:22 400 1395509

>>1395508
тогда чего ты мне отвечаешь, шизик?

Ответы395512

401 8 мая, 02:22 401 1395510

>>1395507
успешным девелопером на острие веба?

Ответы395514

402 8 мая, 02:23 402 1395511

>>1395505
Я сейчас вот жабку изучаю после пыха. Поначалу тож колдоёбило бурно.

403 8 мая, 02:24 403 1395512

>>1395509
Так у нас тут еженедельно ебанашка с откровениями залетает. Просто посмотрел что у тебя в башке насрано.

Ответы395513

404 8 мая, 02:24 404 1395513

>>1395512
жаль ни одного аргумента за изучение пыхи не привел

Ответы395515

405 8 мая, 02:27 405 1395514

>>1395510
а еще фронтэндером

406 8 мая, 02:30 406 1395515

>>1395513
И не собираюсь.

Ответы395516

48 Кб, 524x556
407 8 мая, 02:35 407 1395516

>>1395515
Короче вот ситуация по США. Пока еще нода не обогнала пыху, но это случится очень скоро.

Ответы395517395548

408 8 мая, 02:36 408 1395517

>>1395516
Ну вот как перегонит, так и приходи.

Ответы395519

409 8 мая, 02:36 409 1395518

Если про backend, то у меня в Минске по ноде, руби совсем мало вакансий, питона норм, но, везде почти надо с опытом, знакомый вкатывался в питон и сейчас после десятков собесов нихуя, по c# и java по-моему надо знать намного больше, чем по пыхе и найти работу без опыта сложно. Так что пыха неплохой вариант, потом можно и куда ещё, не сидеть же на ней всю жизнь.

Ответы395521

410 8 мая, 02:37 410 1395519

>>1395517
но учить нужно уже сейчас

Ответы395520

411 8 мая, 02:40 411 1395520

>>1395519
Что учить? Многие пхп-кодеры это фуллстаки. Подтянуть нодку - дело недели-месяца.

Ответы395523

412 8 мая, 02:40 412 1395521

>>1395518
клепая сайтики ты не выучишь ООП, многопоточность и базы данных на нормальном уровне

Ответы395522395529

413 8 мая, 02:42 413 1395522

>>1395521
А что на пыхе этого нет?

414 8 мая, 02:43 414 1395523

>>1395520
короче я надеялся на конструктив, а тут "всяк кулик своё болото хвалит".

Ответы395524

415 8 мая, 02:46 415 1395524

>>1395523
Хорошо, что ты хочешь услышать? Мы раскаиваемся, бросаем пхп и идём учить то, что скажет нам залетевший еженедельный васян без каких-то конкретных знаний?
Прости нас о великий мимохуй. Мы не ведали что творили!

416 8 мая, 03:09 416 1395529

>>1395521
смотря какие сайтики

417 8 мая, 08:09 417 1395548

>>1395516
нода это еще хуже,чем пых

Ответы395552

418 8 мая, 08:39 418 1395551

>>1395433
че ты порвался так?

Ответы395612

419 8 мая, 08:39 419 1395552

>>1395548
ок если не использовать коллбеки
async/await и просто конфетка

420 8 мая, 09:55 420 1395576

Кто-нибудь работал с Joomla? Выполняю заказ на создание андроид приложения под сайт и делаю щас авторизацию. Хочу сделать хеширование введеного пароля, его сравнение с паролем из бд и по результатам авторизация или нет. Как Joomla хеширует пароли? Как я понял через bcrypt, но на сайте соль в бд не сохраняется

Ответы395583

421 8 мая, 10:26 421 1395583

>>1395576
Те сделать скрипт на php который хешировпл и проверял пароль. Сам сайт написан на Joomla

Ответы395613

422 8 мая, 11:54 422 1395612

>>1395551
Смысл на всякое говно время тратить, если оно не в состоянии найти инфу по базовым вещами? Сам не хочет - идёт нахуй.

423 8 мая, 11:59 423 1395613

>>1395583
Ну так сделай. Делов на пару строк.

Ответы395615

424 8 мая, 12:01 424 1395615

>>1395613
Как мне кэшировать пароль если я не знаю соль? Или это не так работает?

Ответы395629

425 8 мая, 12:48 425 1395629

>>1395615
Как сама джумла это делает? Доки смотрел? ИТТ всё больше по Ларавелям и Симфоням сидят.

Ответы395630

426 8 мая, 13:11 426 1395630

>>1395629
Она делает это через bcrypt. Щас кстати попробовал сделать проверку через стандартную функцию password_verify и оно выдает, что совпадает, хотя вчера вроде бы выдавала что нет. Как вообще bcrypt работает? Как, генерируя каждый раз новый хеш, оно может проверять на совпадение? Не разбираюсь в криптографии

Ответы395634395646

427 8 мая, 13:15 427 1395634

>>1395630
>генерируя каждый раз новый хеш
Хэш не должен быть каждый раз новым с одними и теми же входящими данными. Как ты его тогда сравнивать будешь?

>bcrypt
Может она там сама солит его?

428 8 мая, 13:34 428 1395643

Котаны, подскажите - есть экшен у контроллера, он обрабатывает два вида запросов - обычный и асинхронный.
public function testAction(){
if($this->isAjax()){ //если отправленный запрос AJAX
$postData = file_get_contents('php://input');
$res = json_decode($postData, true);
$this->loadView('_test', $res);
die;
}else{
$vars = [
'posts' => ['Test' => 'TestValue'],
];
}
$this->setVars($vars);

}

Ответы395645395658

429 8 мая, 13:35 429 1395645

>>1395643
Черт, случайно отправил недописанный пост. Фейспалм.jpg

430 8 мая, 13:36 430 1395646

>>1395630

Часто в выдаваемом "хеше" закодированы:

- сам хеш
- соль
- алгоритм получения хеша

Например, стандартная функция password_hash возвращает такой составной хеш, а password_verify разбирает его на части и проверяет по ним пароль.

431 8 мая, 13:47 431 1395650

в пхп фреймворках есть аналоги батареек джанги?

Ответы415601

432 8 мая, 13:57 432 1395658

>>1395643
Вопрос-то где?

433 8 мая, 14:00 433 1395661

Котаны, подскажите - есть экшен у контроллера, он обрабатывает два вида запросов - обычный и асинхронный.

public function testAction(){

if($this->isAjax()){ //если отправленный запрос AJAX то должен отрисовать ту же самую стандартную страницу, но с данными из AJAX запроса
$postData = file_get_contents('php://input');
$res = json_decode($postData, true); //данные из AJAX запроса
$this->loadView($res); //метод который должен перерисовать шаблон но уже с новыми данными но не перерисовывает
die;

}else{ //если не AJAX // то отрисовываем стандартную страницу
$res = "другие данные";
}
$this->loadView($res); //отриcовка шаблона по умолчанию

}

Короче суть проблемы вот в чем - отрисовываю шаблон, далее по нажатию на кнопку выполняется асинхронный запрос, и по моему плану сервер должен перерисовать шаблон но уже с данными из AJAX. Для этого я вызываю метод $this->loadView($res) который содержит require на тот же самый шаблон. Но нихрена не перерисовывается. Если в средствах разработчика в браузере посмотреть - то видно что ответом на запрос приходит шаблон с данными AJAX.

Понятно что можно с помощью JS вставить асинхронные данные - тут все работает отлично.

Ответы395662395667395772395774

434 8 мая, 14:02 434 1395662

>>1395661
А по заголовкам там чё?

Ответы395672

435 8 мая, 14:07 435 1395666

Анонычи, может кто сталкивался и подскажет, как в amoCRM по средствам api в php достать массив с id сделок?
Вроде сделал подключение, всё заебись, а id сделок достать не могу =(

Ответы415601

436 8 мая, 14:10 436 1395667

>>1395661

Функцию isAjax() ты протестировал, что она корректно работает?

Ответы395672

437 8 мая, 14:22 437 1395672

>>1395662
аякс запрос идет с двумя заголовками:
{ 'Content-Type': 'application/json' , 'X-Requested-With':'XMLHttpRequest' }

>>1395667
>Функцию isAjax() ты протестировал, что она корректно работает?

Да все работает. И сам аякс запрос работает корректно.
По факту нужно отрисовать один и тот же шаблон, но второй раз с новыми данными.

108 Кб, 1366x768
438 8 мая, 14:42 438 1395679

полчаса и вуаля

Ответы395684

459 Кб, 700x700
439 8 мая, 14:59 439 1395684

>>1395679
>поисковая строка принскрин экрана

Ответы395721

440 8 мая, 16:05 440 1395721

>>1395684
ну я же нуб

441 8 мая, 16:13 441 1395725

10 Кб, 334x994 Кб, 263x44

Господа, помогите в нелепой ситуации. Php никогда не изучал , захотел всего лишь изменить 1 css файл . 1ый пикрелейтед уже файл на хостинге (измененный). 2ой пикрелейтед, что приходит в браузер из этого файла. Сервер ребутал. Что еще нужно сделать, чтобы он подсосал изменения css?

Ответы395760395761415601

442 8 мая, 17:33 442 1395760

>>1395725
Смотри в коде страницы откуда именно сосутся css. Возможно ты изменил только исходник, а стили тянутся из компилированого файла и нужно его обновить. Ну и кеш сбрось.

443 8 мая, 17:34 443 1395761

>>1395725
У тебя страница просто в закэшилась. Контрол+R нажми в ней.

444 8 мая, 17:48 444 1395772

>>1395661
Страницу рисует браузер. Экшен у контроллера просто выдает данные которые нужно отрисовать. Когда ты дергаешь контроллер аяксом, соотвествующий акшон честно отдает все данные. Но браузеру на них похуй - лично к нему никто не обращался нарисовать что-то новое. Тут только с помощью JS вставлять асинхронные данные.

Ответы398828

445 8 мая, 17:50 445 1395774

>>1395661
какой уебищный синтаксис

446 8 мая, 17:59 446 1395778

>>1395435
Да, нам действительно нечем было заняться. До сих пор с болью вспоминаю, как мы пытались всё собрать в ехе-шник.

191 Кб, 512x512
447 8 мая, 20:00 447 1395825

Написал решение к классической задаче с собесов про
> Есть продукты A, B, C, D, E, F, G, H, I, J, K, L, M. Каждый продукт стоит определенную сумму.
> Есть набор правил расчета итоговой суммы:
> 1. Если одновременно выбраны А и B, то их суммарная стоимость уменьшается на 10% (для каждой пары А и B)
> 2. Если одновременно выбраны D и E, то их суммарная стоимость уменьшается на 6% (для каждой пары D и E)
> ...
Хочу, чтобы меня похуесосили. Если вам несложно, конечно ^_^
bit-ly/2Wyh0iX

Ответы395843396270396278

448 8 мая, 20:13 448 1395840

>>1380485 (OP)
Чекните, но не бейте.
https://github.com/artMonkey1/Students

Ответы395843395866396745399017413646

449 8 мая, 20:17 449 1395843

>>1395825
>>1395840
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

450 8 мая, 20:51 450 1395866

>>1395840
какой же ты несмешной, пиздец просто

451 9 мая, 10:50 451 1396270

>>1395825
> комментарии на кириллице
Надеюсь, ты уже уволен.

Ответы396386

452 9 мая, 11:25 452 1396278

>>1395825
Ты не понял задачу. Это не правила фильтра с исключением сработавших элементов из множества, на что намекает "странный" порядок правил. К множеству поочередно применяется каждое правило, затем из сработавших правил для каждого товара выбирается то правило, что даст наибольшую скидку на сумму стоимости корзины в целом.

453 9 мая, 14:48 453 1396386

>>1396270
Ты у Абу код посмотри.

454 9 мая, 17:46 454 1396476

что такое сессии?

Ответы396505

455 9 мая, 18:26 455 1396505

>>1396476
Это типа школьного экзамена

456 9 мая, 20:57 456 1396553

Не могу понять, как в самом свежем Slim'е куки установить.

Пробовал и внутри метода установить и снаружи, конструкция
$app->setCookie('user', uniqid('id'), '365 days');
возвращает исключение BadMethodCallException с текстом Method setCookie is not a valid method. Гуглил и ничего не нашел по теме.
На гитхабе вроде был вопрос о том, как установить куки в их фреймворке, на что создатели посоветовали юзать сторонние библиотеки для этого. Вопрос датируется 15 годом. Но сейчас в доке появилась инфа о том, что куки можно установить, но у меня не получается. Я делаю точно так же, как и в доке.

Кто-нибудь сталкивался с этим?

Ответы396562

457 9 мая, 21:16 457 1396562

>>1396553
Видимо, такого метода просто нет. Придется написать в службу поддержки, посмотрим, что скажут.

Ответы396578

458 9 мая, 22:10 458 1396578

>>1396562
Да, он был удален из Slim 3. Теперь нужно использовать родной setcookie(), либо юзать сторонние PSR-7 либы.

Ответы396726

459 9 мая, 23:24 459 1396603

>>1380485 (OP)
Аноны, вопрос по спискам студентов.
Где ведется подключение к базе данных?
В начале нужно подключить базу данных, а потом вызвать конструктор класса, которая реализует Table Data Gateway, и передать в конструктор переменную или подключение ведется в конструкторе класса, который реализует Table Data Gateway?

Ответы396642

460 10 мая, 01:27 460 1396642

>>1396603
Почитай у опа про DI. Ты заранее регистрируешь в контейнере, как подключение создаётся и как создаётся tablegateway. Потом можно этот контейнер передавать куда угодно и, например, из контроллера создавать твой tablegateway. А вообще подключение должно передаваться готовое уже, tablegateway этим заниматься не должен.

461 10 мая, 04:14 461 1396678

Анонычи, как хорошо усвоить ооп к собеседованию? На практикес гуглом всё понимаю, а вот боюсь в теории проебаться, я пока только начинаю, так что не думаю что будут прямо топить. Подкиньте гайдов каких-нибудь что-ли или толковой инфы, чтобы легко воспринималось и по базовом ооп

Ответы396728

462 10 мая, 10:17 462 1396726

>>1396578
Так-то логично сделали. Нинужно это Слиму.

463 10 мая, 10:22 463 1396728

>>1396678
Задачи ОПа делай, которые на ООП,

464 10 мая, 10:59 464 1396745

>>1395840
Я так и не понял, нормально я выполнил эту задачу или нет. Вопрос такой: Я попытался сделать сущность пользователя и разделить обязанность обращения к таблице и сделал, как я понимаю, TableDataGateway, получилось ли? И то, что я все файлы с видом создал в формате ".php", а не ".html" приемлемо?

127 Кб, 1366x768
465 10 мая, 17:40 465 1397075

бляяяя,заработало методом тыка,я рот имел всех авторов уроков

Ответы397206397210

466 10 мая, 17:58 466 1397095

Тем кто только вкатывается советую не ебланить с чтением литературы, просмотром дополнительных гайдосов и прочим обучением. Лучше учитесь сразу писать правильно на ооп с неймспейсами и прочей шалупонью. Уже 3 года работаю, а до сих пор не знаю как написать нормально с 0 апи на ООП. Так что ПРОСТО ПИШИ КОД И ВСЕ СО ВРЕМЕНЕМ ПРИДЕТ САМО - это не то что вам нужно, поверьте.

Ответы397100397112397153397246

467 10 мая, 18:02 467 1397100

>>1397095
поясни вкатывальщику
что это

Ответы397105397106

468 10 мая, 18:05 468 1397105

>>1397100
вот это Route::get('/user', 'UserController@index');
я понял что это связано с контроллерами,но не понял как работает

Ответы397108

469 10 мая, 18:05 469 1397106

>>1397100
-Пацаны читайте литературу и смотрете больше обучающих видосов
-поясни вкатывальщику что это
-Знаешь, иди ка нахуй, дебил ебаный...

Ответы397108

470 10 мая, 18:07 470 1397108

>>1397106
я не успел прост дописать вот это >>1397105
а ты сразу нахуй

471 10 мая, 18:11 471 1397112

>>1397095
Двачую.

разработчик со времён PHP 4, никак не могу переучиться на ООП

Ответы397117397118397478

472 10 мая, 18:14 472 1397117

>>1397112
Это у тебя сколько стажа получается? Где работаешь и сколько зарабатываешь?

Ответы397123

473 10 мая, 18:15 473 1397118

>>1397112
>>ПРИДЕТ САМО
>>3 года
>>никак не могу научиться
>>двочую

Ответы397121

474 10 мая, 18:19 474 1397121

>>1397118
не уловил смысл твоего поста

Ответы397123

475 10 мая, 18:19 475 1397123

>>1397117
Стажа лет 10, чисто как хобби.
С ходу взяли миддлом, но я поработал два месяца и ушел - тупо перегорел. Программирование это не так романтично, как кажется, когда ты за камплюктером 5/2 по 7 часов.
З/п была 70к.

>>1397121
Он жопочтец.

Ответы397125397129

476 10 мая, 18:26 476 1397125

>>1397123
Ты если адмен или прочий автоматизатор то тебе можно в принципе, ведь голова не резиновая что бы в неё знания из смежных областей складывать. А то что не роматнтично - так это наверное прост не повезло. Я на разные работы уже повкатывался и везде нагрузка разная, где-то за 30к приходилось впахивать по 10 часов в день (досвиданья через 2 месяца, ага), а где-то по 7 часов ненапряжно сиди да пиши без нервов и неадекватных дедлайнов за 70к, прост наверное нужно тебе еще попробоваться куда-то.

Ответы397132

477 10 мая, 18:31 477 1397129

>>1397123
Ты три года читаешь теорию и ни строки не написал? Или три года пишешь. Почему не пришло само? У тебя взаимоисключающие параграфы.

Ответы397132

478 10 мая, 18:35 478 1397132

>>1397125
> то тебе можно в принципе
Да нихрена. Любой проект свыше ста строк, написанный без ООП, приносит страдания каждому, кто будет его дописывать и переписывать.
Я вот на свои пет-проджекты без слез смотреть не могу.
На той работе тоже было куча легаси-кода и хреновая его документация. И еще тикеты типа "сделай такую-то фишечку", в ходе которого ты ломаешь еще три фишечки, потому что взаимосвязь всякой хрени внутри хранится в основном в голове у тимлидера и аксакалов.

>>1397129
Если ты прочтешь внимательнее, то увидишь, что он опровергает написанное болдом, а не подводит итог жирненьким.

Ответы397163

479 10 мая, 19:03 479 1397153

>>1397095
> Лучше учитесь сразу писать правильно на ооп с неймспейсами и прочей шалупонью
это так не работает. программисты всегда идут по кратчайшему пути. И никто не будет учиться писать "правильно", без мотивации. Могу посоветовать новичкам почитать "Чистый Код" от Мартина, там есть и советы и мотивационка

Ответы397159

480 10 мая, 19:30 480 1397159

>>1397153
Чистый код Мартина годно.
мимо-джавист

Ответы397163

481 10 мая, 19:41 481 1397163

>>1397132
Работаю в легаси проекте который начинался еще как раз на старте пхп5, в "ядре" системы такой код прикольный который как бы формально и оор, но по факту просто тематически скомпанованные функции по группкам и у большинства объектов можно только вызывать методы и все, а сам объект никуда не засунуть ни присунуть. Управляет всем этим файлы по 2к строк где изи может быть цикл с телом в 1к и сиди ковыряй. В целом большим плюсьм на проекте является то, что все как раз понимают что в нем никто нихуя не понимает, и никто не ебет мозги на тему "чего так долго", а наоборот по возможности все стараются помочь если не можешь разобраться.

>>1397159
Что жавист читает в пхп-тредисе?

Ответы397273

482 10 мая, 21:19 482 1397206

>>1397075
laracast попробуй, чтобы не иметь всех авторов

Ответы397208

483 10 мая, 21:21 483 1397208

>>1397206
плохо воспринимаю на слух и неудобно пользоваться субтитрами
уверен скажешь страдай сука
ща

Ответы397209397212

484 10 мая, 21:22 484 1397209

>>1397208
щас осилил базу по контролерам и видам,встал на миддл веар

485 10 мая, 21:24 485 1397210

>>1397075
На скрине в шторме снизу нашел ошибку отсутствия PagesController. Вот ты пытаешься получить к нему доступ,а ты его создал? php artisan make:controller PagesController

Ответы397211397214

486 10 мая, 21:26 486 1397211

>>1397210
это старый скрин,щас доперло

487 10 мая, 21:27 487 1397212

>>1397208
Пока ты не будешь даже пытаться осилить, ты никогда не начнешь воспринимать. Скажи спасибо, что у тебя есть нормальная мотивация учить ангельский, без задрачивания специальной скучной хуйни, как это делают разные неайтишники и гуманитарии.

мимо

Ответы397213

488 10 мая, 21:28 488 1397213

>>1397212
я только хоть как то воспринимаю печатный текст,англ учу уже 3 месяца

489 10 мая, 21:31 489 1397214

>>1397210
так в этом варианте можно и без контроллера страницу вывести

490 10 мая, 22:44 490 1397246

>>1397095
ООП это где проектирование. Писать легче и интереснее, если правильно классы сделал.
А вообще тема довольно простая - сложно переучиться, в смысле надо следить за тем как пишешь. Я сегодня вот увидел, что у меня парсер на статиках одних, весь вечер переписывал на ООП. Вроде вышло.

491 10 мая, 23:08 491 1397254

Я тут сериализовал массив в файл - он сохранялся в текстовом формате.
Потом я из этого массива объект сделал - он сериализовался в двоичный файл. Пробовал через __sleep возвращать поля, но там вообще чушь какая-то получается.
Что я делаю не так? Как сериализовать объект в текстовом виде? Это возможно?

Ответы397516397801398325

13 Кб, 700x208
492 10 мая, 23:15 492 1397259

Помогите решить задачу по SQL нубу.

493 10 мая, 23:44 493 1397273

>>1397163
Выше писал, что есть вероятность вкатиться на вакансию бек php/java с java бека, но нет знаний php, просил книгу подсказать
Прост захаживаю мало ли кто нить еще отпишет или что интересного найду

494 11 мая, 07:30 494 1397373

Аноны, в чем сейчас принято вести разработку? Docker, wsl, просто lemp или lamp на убунте родной, либо на виртуалке, либо на купленном vps, vargant, wamp? Чем вы пользуетесь? Если оп жив, то что ты посоветуешь?

Ответы397401397402397406

495 11 мая, 08:29 495 1397380

>>1380485 (OP)
>Кто-то хочет открыть стартап
на пхп???

496 11 мая, 10:36 496 1397401

>>1397373
Разработку или деплоймент?

Ответы397404

497 11 мая, 10:38 497 1397402

>>1397373
Разработку или деплоймент?

498 11 мая, 10:55 498 1397404

>>1397401
Разработку.

499 11 мая, 10:59 499 1397406

>>1397373
Разработка win10 + ospanel

500 11 мая, 12:44 500 1397478

>>1397112
вон из моей профессии

501 11 мая, 13:27 501 1397516

>>1397254
> Потом я из этого массива объект сделал - он сериализовался в двоичный файл
шта?

Ответы397612

502 11 мая, 14:19 502 1397571

>>1397559
причём этот фрилансер не знает как правильно сравнивать хеш. Мартышка, короче

Ответы397574

503 11 мая, 14:24 503 1397574

>>1397571
Что здесь не так? md5 дважды, чтобы хэш не нашелся по радужным таблицам. Сам md5 всегда возвращает string, поэтому нестрогое сравнение тут не влияет на результат.

Ответы397576397579397611

504 11 мая, 14:25 504 1397576

>>1397574
Он походу про password_verify.

505 11 мая, 14:30 505 1397579

>>1397574

Радужные таблицы как раз и позволяют восстановить многократно обработанный хеш.

Ответы397582

506 11 мая, 14:35 506 1397582

>>1397579
Как? В такой таблице должно быть 16^32 строк.

Ответы415601

Ecce PHP 507 11 мая, 15:31 507 1397611

635 Кб, webm,
1280x720, 0:0917 Кб, 922x495

>>1397574
Ту да, в стойбище, к другому животному
https://3v4l.org/13VFJ

Ответы397626

250 Кб, 1050x624
508 11 мая, 15:35 508 1397612

>>1397516
Чего не понятного? Берёшь класс, там объявляешь приватное хранилище, в хранилище - этот массив на самом деле этот класс тоже хранится в массиве. На выходе у тебя не сериализованный многомерный массив, а пикрелейтед. Но если сериализовать массивом, то там читабельный формат.
В принципе всё нормально работает. Но я чёта не понимаю - как так.

Ответы397614

Ecce PHP 509 11 мая, 15:38 509 1397614

>>1397612
лол, чем ты сериализацию проводишь?

Ответы397625

510 11 мая, 15:46 510 1397623

как группировать роуты в ларавеле?

Ответы397639397640

511 11 мая, 15:49 511 1397624

>>1397559
>фрилансер решил себе бекдор сделать
Защита от кидка заказчика, не?

512 11 мая, 15:51 512 1397625

>>1397614
Щекой твоей надо?

Ответы397636

513 11 мая, 15:51 513 1397626

>>1397611
А вместо боевых видео ты этот конкретный пример сломать можешь?
Коллизии в md5 есть, но ты мне найди пароль от конкретного примера.
А в примере по ссылке строки кастуются в числа из-за 0e, но только хэш из примера начинается с 36, и поэтому не скастуется в число никогда, даже если с другой стороны будет хэш, начинающийся с 0e.

Ответы397634

514 11 мая, 16:03 514 1397634

>>1397626
> строки кастуются в числа из-за 0e
> поэтому не скастуется в число никогда, даже если с другой стороны будет хэш, начинающийся с 0e
Да, и всё это знает обезьяна со скриншота из >>1397559 , и именно поэтому пишет нестрогое сравнение, а не потому что она обезьяна и до сих пор не выработала рефлекс писать строгое сравнение во время компарации хешей

515 11 мая, 16:03 515 1397636

>>1397625
Для начала попробуй json_encode. На мою щёку у тебя денег не хватит

Ответы397643

516 11 мая, 16:06 516 1397639

>>1397623
Насколько я знаю, можешь прописать Route::resource() https://laravel.com/docs/5.8/controllers#resource-controllers. Ну или самостоятельно их прописывать Route::get('/', 'PagesController@index')

Ответы397645

517 11 мая, 16:08 517 1397640

>>1397623
ок тогда объясните эту конструкцию
>Route::group([], function () {
Route::get('hello', function () {
return 'Hello';
});
Route::get('world', function () {
return 'World';
});
});
и эту
>Route::group(['prefix']=>'home', function()
{
Route::get('/', 'HomeController@showIndex');
Route::get('/about', 'HomeController@About');
Route::get('/contact',
'HomeController@showContact');
});
вменяемого объяснения нет

Ответы397829398073

518 11 мая, 16:09 518 1397643

>>1397636
Для начала научись не раздавать советы, которых у тебя не спрашивали, хамло неймфажное.

Ответы397644

519 11 мая, 16:10 519 1397644

>>1397643
Ты вообще ретард? Где во фразе "лол, чем ты сериализацию проводишь?" советы? Блядь, пиздуй вон, дворы подменять

Ответы397653

520 11 мая, 16:11 520 1397645

>>1397639
в одном сука месте видел
Route::resource('home', 'HomeController')
это типа хоум корень страницы и общий контроллер.
те все страницы после хоум и имеющие общий такой контроллер выполняются,так?

Ответы397647398325

521 11 мая, 16:12 521 1397647

>>1397645
Можешь проверить что будет работать через php artisan route:list

Ответы397650

someApprentice !EaaiHmIJms 522 11 мая, 16:13 522 1397648

249 Кб, 1920x1080276 Кб, 1920x1080356 Кб, 1920x1080290 Кб, 1920x1080

>>1394573
>По поводу импортов: я не очень понимаю, зачем ты в model/message.py импортируешь наследников. Обычно импортируют только то, что нужно в данном файле. И обычно наследник импортирует предка, а не наоборот. Потому я думаю, эти импорты надо просто убрать:
>
># models/message.py
>import text_message
>import voice_message
>
>Зачем они добавлены? Странно, что у тебя предок зависит от своих наследников (что они ему нужны).
Я понял свою ошибку. Я когда пытался получить все сообщения я использовал команду вида session.query(Message).join(Message_Reference).filter(Message_Reference.user == self.user).all() и получал только сущности родительского класса Message, и я подумал что родителю необходимо знать о детях чтобы получить их всех.
Я теперь понял, что импорты должны выполнятся там где выполняется этот запрос - это работает.

>Также, ты похоже выбрал Concrete Table Inheritance, возможно, что запросы к ней потребуют лишних UNION, судя по мануалу: https://docs.sqlalchemy.org/en/13/orm/inheritance.html#concrete-table-inheritance
К сожалению, мне не удалось найти какой паттерн наследования использует psql. Я косвенно предположил, что это именно он.pic-1

Использование UNION приводит к нагрузке?

Вообще, ORM не очень дружат с наследованием, как я могу посудить. Отношения между сущностями тяжело совершить с помощью встроенных инструментов и приходится делать метод для совершения запроса в ручную.pic-2 При получении сущностей выдается массив из сначала сущностей родителя, затем сущности ребёнка.pic-3 Я не знаю должно ли быть такое поведение. Хочется самому отсортировать только сущности детей и возвращать этот массив.

>> Следует сделать скрипт, который будет принимать все credentials, выполнять всю установку, а на выход выдавать все хэши и токены. Возможно генерировать сразу .env файл.
>
>Я думаю, достаточно только сгенерировать токены. В .env может быть еще куча других параметров. Но можно, конечно, выдавать заготовку .env файла.
>
>> Как обычно делаются такие файлы? Через Докер (не разу с ним не знакомился)?
>
>В dev среде можно использовать docker-compose для оркестрации докеров с отдельными приложениями. Докер, как правило, используется чтобы упаковать в образ программу с нужными ей библиотеками, например, определенную версию Питона или Ноды, чтобы ее не надо было устанавливать в систему руками. Код твоего приложения в докер-образ не кладется, а подмонтируется в него как внешний раздел. docker-compose заниамется тем, что просто запускает несколько докеров (например: микросервис авторизации и основное приложение). На Винде и Маке Докер запускает код в виртуальной машине с линуксом, а файлы прокидываются через сетевую файловую систему со всеми вытекающими.
>
>Ты можешь найти готовый пример приложения на PHP + nginx + mysql в докере и разберешься, я думаю.
Я ошибся когда писал, что у разных ролей wamp'а разные uri. Сейчас я сделал авторизацию действий засчет ролей и даже для сервера не нужно применять динамическую авторизацию.pic-4

...я когда придумывал архитектуру мне сразу приходил в голову такой подход, но я тестировал и ничего не вышло. Я не помню при каких настройках это было, возможно я что-то не так указал. Тяжело на ходу держать всё в уме.

>> Лучше сделать это на системном языке и чтобы он был кроссплатформенный. Можете что-нибудь посоветовать пожалуйста?
>
>Обычно используют Питон, bash для таких скриптов. Если у тебя код на Питоне, логично в нем сделать CLI скрипт для генерации токенов.
>Если у тебя код на Питоне
Страница выдаётся из Ноды, API я собираюсь переписать на PHP, а код wamp'а на Питоне.

>>1394587
>Такие запросы с джойнами будут плохо работать на больших нагрузках. Они же почти не оптимизируются индексами никак и требуют перебор строк. Возможно, тут придется сделать денормализацию, например, добавить в Dialog либо в Participant дополнительные поля. Чтобы, например, запрос бы имел вид
>
>SELECT FROM Participant WHERE user = ? AND partner = ? AND private =1
>
>Это ложится на индексы. Но, конечно, денормализацию стоит делать во вторую очередь.
Я думаю, что партнер должен добавляться скорее в ссылку на конференцию, потому что получатель это отдельная сущность, которая не отвечает за то с кем она должна вести диалог. А если партнёров будет много (публичная конференция)? Конечно тут можно прийти к созданию отдельной таблицы Partners... не будет ли и здесь плохо работать запрос с джоинами на больших нагрузках?

Далее, даже учитывая что мы создадим поле partner в Conference_Reference, это создаст запрос для получения вида:

// неизвестно какой пользователь сначала "создал" конференцию,
// а какой оказался получателем (партнёром)
SELECT FROM Conference_Reference WHERE (user = sender.id OR user = receiver.id) AND (partner = receiver.id OR partner = sender.id)

Такой запрос может вернуть две записи и сама его форма не элегантна.

Я предлагаю вернуться к идеи выше с массивами >>1387125

SELECT FROM Conference WHERE private = true AND (sender.id = ANY(participants) AND receiver.id = ANY(participants));

Как писалось выше такой запрос использует индексы (https://stackoverflow.com/questions/4058731/can-postgresql-index-array-columns).

У вас есть опыт с работой с индексами. Как вам кажется, индексирование массивов приведёт к желаемому повышению производительности?

>> Можно я оптимизацию БД оставлю на последнее?
>
>Можно. Но я просто хотел подчеркнуть, что мессенджеры это высоконагруженные штуки и там приходится об этом думать. И о шардинге, если ты хочешь, чтобы проект расширялся. Потому мы сначала проектируем нормализованную схему, а потом смотрим на типичные запросы и оптимизируем схему для них.
>
>Более того, часто под мессенджеры даже пишутся специализированные хранилища.
Я это прекрасно понимаю..

>Насчет reply - а недостаточно тут просто сделать поле в сообщении "replyToUuid" со ссылкой на исходное сообщение? Без вложений.
Судя по API телеграма там используется как раз такой подход ( https://core.telegram.org/bots/api#message ), но мне никогда не было понятно почему только можно ответить на одно сообщение, мне иногда хочется ответить на несколько сразу, да и выглядит это как прикрепление к сообщению.

>Так, схема выглядит хорошо. Позже стоит продумать операции, которые будут выполняться (их явно будет больше, например, может понадобиться постраничное получение участников огромного чата). И как их оптимизировать.
Опять же с массивами это тоже делается очень просто

SELECT participants[offset:limit] FROM Conference WHERE id = conference.id;

Мне хочется сделать, так же, и наследование и в конференциях, чтобы была отдельно приватная конференция и отдельно публичная. Публичная будет иметь свой приватный ключ (иначе шифровать сообщения для каждого отдельного пользователя будет затратно).

Также, я озаботился вопросом как работает с ключами protonmail, и оказалось, что он хранит их на сервере зашифрованные паролем пользователя, как я изначально и собирался это и делать. Я считал, что ключи должны храниться только у пользователя, но подход с генерацией ключей для каждого клиента пользователя создаёт только больше проблем - если пользователь часто меняет клиент (чистит кэш браузера/удаляет приложения/использует несколько устройств), это может превратиться в кошмарный список ключей и при зашифровки сообщения для них всех будет требовать всё больше и больше ресурсов.
Вынуждать пользователя самому заниматься менеджментом своих ключей было бы отталкивающе и тяжело доступно для понимания.

https://protonmail.com/support/knowledge-base/how-is-the-private-key-stored/

Я собираюсь повторить эту практику.

Такой подход вновь открывает возможность создания NoJS версии, но тратить время на это нужно только в случае, если за это можно выиграть лакомый кусочек пользователей. Или для надёжности, которые будут требовать текущие пользователи.

>> Я думаю, что пока подходы к авторизации методов WAMP не изучены, следует писать сырой код на if'ах, а подход с роутингом взять на заметку и держать в уме. А как думаете вы?
>
>Я, увы, так хорошо авторизацию в WAMP не знаю и сейчас не могу подсказать.
Рано или поздно мы разберёмся какая архитектура будет лучше.

P.S.
Я понимаю, что ваши советы по архитектуры базы данных содержат опыт, и я парой прихожу к тому что ваш совет, в конечном итоге, оказывается проще, но я всё равно нахожу либо ошибку в своих действиях в применении новых технологий, либо решение появляйщейся проблеме. Я чувствую, что я на правильном пути применяя новые технологии и идеи. В конечном итоге, это кристаллизуется в опыт и можно будет сравнить плюсы или минусы того или иного подхода.

someApprentice !EaaiHmIJms 522 11 мая, 16:13 522 1397648

249 Кб, 1920x1080276 Кб, 1920x1080356 Кб, 1920x1080290 Кб, 1920x1080

>>1394573
>По поводу импортов: я не очень понимаю, зачем ты в model/message.py импортируешь наследников. Обычно импортируют только то, что нужно в данном файле. И обычно наследник импортирует предка, а не наоборот. Потому я думаю, эти импорты надо просто убрать:
>
># models/message.py
>import text_message
>import voice_message
>
>Зачем они добавлены? Странно, что у тебя предок зависит от своих наследников (что они ему нужны).
Я понял свою ошибку. Я когда пытался получить все сообщения я использовал команду вида session.query(Message).join(Message_Reference).filter(Message_Reference.user == self.user).all() и получал только сущности родительского класса Message, и я подумал что родителю необходимо знать о детях чтобы получить их всех.
Я теперь понял, что импорты должны выполнятся там где выполняется этот запрос - это работает.

>Также, ты похоже выбрал Concrete Table Inheritance, возможно, что запросы к ней потребуют лишних UNION, судя по мануалу: https://docs.sqlalchemy.org/en/13/orm/inheritance.html#concrete-table-inheritance
К сожалению, мне не удалось найти какой паттерн наследования использует psql. Я косвенно предположил, что это именно он.pic-1

Использование UNION приводит к нагрузке?

Вообще, ORM не очень дружат с наследованием, как я могу посудить. Отношения между сущностями тяжело совершить с помощью встроенных инструментов и приходится делать метод для совершения запроса в ручную.pic-2 При получении сущностей выдается массив из сначала сущностей родителя, затем сущности ребёнка.pic-3 Я не знаю должно ли быть такое поведение. Хочется самому отсортировать только сущности детей и возвращать этот массив.

>> Следует сделать скрипт, который будет принимать все credentials, выполнять всю установку, а на выход выдавать все хэши и токены. Возможно генерировать сразу .env файл.
>
>Я думаю, достаточно только сгенерировать токены. В .env может быть еще куча других параметров. Но можно, конечно, выдавать заготовку .env файла.
>
>> Как обычно делаются такие файлы? Через Докер (не разу с ним не знакомился)?
>
>В dev среде можно использовать docker-compose для оркестрации докеров с отдельными приложениями. Докер, как правило, используется чтобы упаковать в образ программу с нужными ей библиотеками, например, определенную версию Питона или Ноды, чтобы ее не надо было устанавливать в систему руками. Код твоего приложения в докер-образ не кладется, а подмонтируется в него как внешний раздел. docker-compose заниамется тем, что просто запускает несколько докеров (например: микросервис авторизации и основное приложение). На Винде и Маке Докер запускает код в виртуальной машине с линуксом, а файлы прокидываются через сетевую файловую систему со всеми вытекающими.
>
>Ты можешь найти готовый пример приложения на PHP + nginx + mysql в докере и разберешься, я думаю.
Я ошибся когда писал, что у разных ролей wamp'а разные uri. Сейчас я сделал авторизацию действий засчет ролей и даже для сервера не нужно применять динамическую авторизацию.pic-4

...я когда придумывал архитектуру мне сразу приходил в голову такой подход, но я тестировал и ничего не вышло. Я не помню при каких настройках это было, возможно я что-то не так указал. Тяжело на ходу держать всё в уме.

>> Лучше сделать это на системном языке и чтобы он был кроссплатформенный. Можете что-нибудь посоветовать пожалуйста?
>
>Обычно используют Питон, bash для таких скриптов. Если у тебя код на Питоне, логично в нем сделать CLI скрипт для генерации токенов.
>Если у тебя код на Питоне
Страница выдаётся из Ноды, API я собираюсь переписать на PHP, а код wamp'а на Питоне.

>>1394587
>Такие запросы с джойнами будут плохо работать на больших нагрузках. Они же почти не оптимизируются индексами никак и требуют перебор строк. Возможно, тут придется сделать денормализацию, например, добавить в Dialog либо в Participant дополнительные поля. Чтобы, например, запрос бы имел вид
>
>SELECT FROM Participant WHERE user = ? AND partner = ? AND private =1
>
>Это ложится на индексы. Но, конечно, денормализацию стоит делать во вторую очередь.
Я думаю, что партнер должен добавляться скорее в ссылку на конференцию, потому что получатель это отдельная сущность, которая не отвечает за то с кем она должна вести диалог. А если партнёров будет много (публичная конференция)? Конечно тут можно прийти к созданию отдельной таблицы Partners... не будет ли и здесь плохо работать запрос с джоинами на больших нагрузках?

Далее, даже учитывая что мы создадим поле partner в Conference_Reference, это создаст запрос для получения вида:

// неизвестно какой пользователь сначала "создал" конференцию,
// а какой оказался получателем (партнёром)
SELECT FROM Conference_Reference WHERE (user = sender.id OR user = receiver.id) AND (partner = receiver.id OR partner = sender.id)

Такой запрос может вернуть две записи и сама его форма не элегантна.

Я предлагаю вернуться к идеи выше с массивами >>1387125

SELECT FROM Conference WHERE private = true AND (sender.id = ANY(participants) AND receiver.id = ANY(participants));

Как писалось выше такой запрос использует индексы (https://stackoverflow.com/questions/4058731/can-postgresql-index-array-columns).

У вас есть опыт с работой с индексами. Как вам кажется, индексирование массивов приведёт к желаемому повышению производительности?

>> Можно я оптимизацию БД оставлю на последнее?
>
>Можно. Но я просто хотел подчеркнуть, что мессенджеры это высоконагруженные штуки и там приходится об этом думать. И о шардинге, если ты хочешь, чтобы проект расширялся. Потому мы сначала проектируем нормализованную схему, а потом смотрим на типичные запросы и оптимизируем схему для них.
>
>Более того, часто под мессенджеры даже пишутся специализированные хранилища.
Я это прекрасно понимаю..

>Насчет reply - а недостаточно тут просто сделать поле в сообщении "replyToUuid" со ссылкой на исходное сообщение? Без вложений.
Судя по API телеграма там используется как раз такой подход ( https://core.telegram.org/bots/api#message ), но мне никогда не было понятно почему только можно ответить на одно сообщение, мне иногда хочется ответить на несколько сразу, да и выглядит это как прикрепление к сообщению.

>Так, схема выглядит хорошо. Позже стоит продумать операции, которые будут выполняться (их явно будет больше, например, может понадобиться постраничное получение участников огромного чата). И как их оптимизировать.
Опять же с массивами это тоже делается очень просто

SELECT participants[offset:limit] FROM Conference WHERE id = conference.id;

Мне хочется сделать, так же, и наследование и в конференциях, чтобы была отдельно приватная конференция и отдельно публичная. Публичная будет иметь свой приватный ключ (иначе шифровать сообщения для каждого отдельного пользователя будет затратно).

Также, я озаботился вопросом как работает с ключами protonmail, и оказалось, что он хранит их на сервере зашифрованные паролем пользователя, как я изначально и собирался это и делать. Я считал, что ключи должны храниться только у пользователя, но подход с генерацией ключей для каждого клиента пользователя создаёт только больше проблем - если пользователь часто меняет клиент (чистит кэш браузера/удаляет приложения/использует несколько устройств), это может превратиться в кошмарный список ключей и при зашифровки сообщения для них всех будет требовать всё больше и больше ресурсов.
Вынуждать пользователя самому заниматься менеджментом своих ключей было бы отталкивающе и тяжело доступно для понимания.

https://protonmail.com/support/knowledge-base/how-is-the-private-key-stored/

Я собираюсь повторить эту практику.

Такой подход вновь открывает возможность создания NoJS версии, но тратить время на это нужно только в случае, если за это можно выиграть лакомый кусочек пользователей. Или для надёжности, которые будут требовать текущие пользователи.

>> Я думаю, что пока подходы к авторизации методов WAMP не изучены, следует писать сырой код на if'ах, а подход с роутингом взять на заметку и держать в уме. А как думаете вы?
>
>Я, увы, так хорошо авторизацию в WAMP не знаю и сейчас не могу подсказать.
Рано или поздно мы разберёмся какая архитектура будет лучше.

P.S.
Я понимаю, что ваши советы по архитектуры базы данных содержат опыт, и я парой прихожу к тому что ваш совет, в конечном итоге, оказывается проще, но я всё равно нахожу либо ошибку в своих действиях в применении новых технологий, либо решение появляйщейся проблеме. Я чувствую, что я на правильном пути применяя новые технологии и идеи. В конечном итоге, это кристаллизуется в опыт и можно будет сравнить плюсы или минусы того или иного подхода.

Показать весь текст
Ответы397655398326

523 11 мая, 16:15 523 1397650

>>1397647
а объяснить просто принцип не судьба?
да,я тупой

Ответы397652

524 11 мая, 16:16 524 1397652

>>1397650
лол, думаешь я умный :) просто что сам знаю, тебе написа

525 11 мая, 16:16 525 1397653

>>1397644
Я не спрашивал как мне сохранять объекты, даун. Вопрос был о странном поведении встроенной функции.

Дворы подметать - твоя работа, судя по постам.

Ответы397657

526 11 мая, 16:16 526 1397655

>>1397648
Илюша,ты когда трезвый,такой добрый! кек

527 11 мая, 16:17 527 1397657

>>1397653
> Я не спрашивал как мне сохранять объекты
А я тебе и не отвечал

> даун
На этом сайте подпись ставят в самом низу сообщения. Ну это так, на будущее

528 11 мая, 19:18 528 1397801

А вот на серваке с убунтой через консольный PHP сериализует нормально - в текстовый вид. Только что проверил.
Хз что с ней не так.

>>1397254-кун

Ответы398372

41 Кб, 900x900
529 11 мая, 19:34 529 1397816

как мне сука горит от того что приходится собирать инфу по частям среди тонны воды и кучи статей,где писали как бы для начинающих,а по факту нихуя не объяснив как это работает и как все это связано между собой,а в треде хуй кто поможет

Ответы397822

530 11 мая, 19:47 530 1397822

>>1397816
А что у тебя?

Ответы397829

531 11 мая, 19:54 531 1397829

>>1397822
допустим это
>>1397640
и таких примеров дохера.
или это

Ответы397830397834

532 11 мая, 19:55 532 1397830

>>1397829

Ответы397831

533 11 мая, 19:55 533 1397831

>>1397830
>

534 11 мая, 19:58 534 1397834

>>1397829
А что тебе именно не понятно? Там вполне нормальный код.
Маршруту даётся замыкание, которое либо возвращает какое-то значение, либо отрабатывает контроллер.

Ответы397837

535 11 мая, 20:00 535 1397837

>>1397834
для тебя нормальный,а я понял что это группировка роутеров.но я не догоняю что значат массивы с ключами и значениями

Ответы397839397844

536 11 мая, 20:02 536 1397839

>>1397837
http://laravel.su/docs/5.0/routing#route-groups
Обязан понять

Ответы397846

537 11 мая, 20:04 537 1397844

>>1397837
Просто группировка чтобы удобней было прописывать. Можно, например, определить в одном файле, подключить его и указать в маршрутизаторе что там написали.

Ответы397855

538 11 мая, 20:05 538 1397846

>>1397839
а тот массив в адресе что значит?

Ответы397856

539 11 мая, 20:11 539 1397855

>>1397844
сгруппируй
>

Ответы397858

540 11 мая, 20:11 540 1397856

>>1397846
У тебя базы нет. Задачи ОПа делал? Ты так долго копаться будешь, задолбаешься и бросишь.
Учи матчасть сперва.

Ответы397861

541 11 мая, 20:11 541 1397858

>>1397855
отклеилось
Route::get('home/index', 'HomeController@showIndex');
Route::get('home/about', 'HomeController@About')

542 11 мая, 20:13 542 1397861

>>1397856
нет,не делал.зато на чистом пхп делал сайт с сессиями,регистрацией и пр.тот еще ад был

Ответы397868

543 11 мая, 20:15 543 1397862

Пробовал кто пройти данную игру?

где вам необходимо при помощи знаний php пройти ряд испытаний!
https://pikabu.ru/page/interview/jobseeker/?t=backend

Ответы397878397886397889398022398143

544 11 мая, 20:22 544 1397868

>>1397861
ООП знаешь?

Ответы397870

545 11 мая, 20:26 545 1397870

>>1397868
основы,понимаю где публичные и прайват методы,наследование,и пр по мелочи

546 11 мая, 20:32 546 1397878

>>1397862
Если без гугла и подсказок, то моя остановочка на третьей же задаче - date("\\i\u{0074}", 0x1953ad7fd).
Калькулятор говорит, что это 6798628861, что больше допустимого для unixtime. Не знаю, что произойдет.

Ответы397884397903

547 11 мая, 20:35 547 1397884

>>1397878
А я на getFibonacci встрял

548 11 мая, 20:37 548 1397886

>>1397862
https://s.pikabu.ru/page/interview/jobseeker/index.js?5
Похоже, на вакансию яваскриптера случайно приняли просто ява-программиста.

Ответы397887

549 11 мая, 20:39 549 1397887

>>1397886
ответом ты там не найдешь

Ответы397890

550 11 мая, 20:41 550 1397889

>>1397862
Какой смысл на эту переусложнённую херню время тратить? Синьорам ваш пикабу не сдался, а джуны не решат.

Ответы397897

551 11 мая, 20:41 551 1397890

>>1397887
Зачем нужны ответы, если там сразу форма отправки резюме?
Впрочем, она отправляет ответы тоже.

552 11 мая, 20:48 552 1397897

>>1397889
> а джуны не решат
А вдруг с помощью гугла.

Ответы397899

553 11 мая, 20:51 553 1397899

>>1397897
Работать они тоже с помощью гугла будут? Результатов только внуки дождутся.

Ответы397942

554 11 мая, 20:55 554 1397903

>>1397878
0x1953ad7fd

GMT: Thu, 09 Jun 2185 20:01:01 GMT
Ваша временная зона: 09.06.2185, 23:01:01

Ответы397906

555 11 мая, 20:59 555 1397906

>>1397903
Да ладно!

>The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer).

Ответы397912

556 11 мая, 21:03 556 1397912

>>1397906
Но это 32-разрядного целого
Для 64-разрядного таких ограничений нет

Ответы397921

557 11 мая, 21:07 557 1397921

>>1397912
Да ладно, я чую, что таймстамп там вообще роли не играет.
Там на выходе должно быть просто два символа: i и символ с кодом 74.
Мне просто все это гуглить и решать.

Ответы397922397928

558 11 мая, 21:08 558 1397922

>>1397921
*лень

559 11 мая, 21:11 559 1397928

>>1397921
это имя переменной i30

560 11 мая, 21:16 560 1397942

>>1397899
>Работать они тоже с помощью гугла будут?
Да это не ради трудоустройства, а так, поиграться.

561 11 мая, 22:47 561 1398022

>>1397862
Ну уж нет, говнокода на трейтах и статиках мне и на работе хватает, только там хотя бы деньги платят за ковыряние в этом. Не хочется попасть в команду, где такой код считается нормой, сразу настраивают на то, чем придётся заниматься разработчику после выхода работу.

Ответы398026

562 11 мая, 22:54 562 1398026

>>1398022
Как победить getFibonacci($n)
Что за оператор туда надо вставить?

563 11 мая, 23:59 563 1398073

>>1397640

На мой субъективный взгляд, тут почти все понятно. Мы задаем функции-обработчики, которые вызываются при поступлении HTTP-запроса с определенным URL.

Если вопрос был про группировку, то гугление официального мануала дает такую ссылку: https://laravel.com/docs/5.8/routing#route-groups

> Route groups allow you to share route attributes, such as middleware or namespaces, across a large number of routes without needing to define those attributes on each individual route. Shared attributes are specified in an array format as the first parameter to the Route::group method.

Далее, ты пишешь ниже:

> но я не догоняю что значат массивы с ключами и значениями

Это атрибуты, правда какие именно атрибуты доступны, в документации пояснения нет. Но, может мы не все прочли? Если пролистать страницу до конца, то там есть приписочка:

> Refer to the API documentation for both the underlying class of the Route facade and Route instance to review all accessible methods.

Идем по ссылке в API docs - это документация, генерируемая из комментариев в исходном коде. К сожалению, и там не перечислен список доступных атрибутов. Значит, остается вспомнить принцип "код - лучшая документация" - открываем исходный код класса Router, метод group() и смотрим код:

https://github.com/laravel/framework/blob/5.8/src/Illuminate/Routing/Router.php#L366

Идем по функциями в таком порядке: group() -> updateGroupStack() -> loadRoutes(). Тут путь заканчивается вызовом коллбека, внутри которого делается get(), и потому изучим, что происходит при его вызове: get() -> addRoute() -> createRoute() -> mergeGroupAttributesIntoRoute() -> mergeWithLastGroup().

Мы видим, что эти атрибуты идут в метод setAction() класса Route, потому глянем и его. В методе setAction() ничего интересного нет, но зато в конструкторе мы видим вызов parseAction() с многообещающим комментарием:

> Parse the route action into a standard array.

В нем, правда, тоже ничего нет. Тогда делаем поиск по выражению "->action[" и находим названия всех атрибутов. И замечаем, что в общем-то использовать этот массив особой нужды нет, так как для задания всех этих атрибутов есть готовые методы с такими же названиями.

В общем, поиск делается примерно в таком порядке:

- официальная документация
- API docs
- исходный код

По исходному коду, конечно, удобно перемещаться с помощью IDE. Привыкай, деды исходный код разбирали и ты справишься.

Если же ты вместо этого лазаешь по каким-то неофициальным, некачественным статьям или пиратским видео, то, пожалуйста, предъявляй претензии их авторам. Также, напомню, что Ларавель - открытый проект и если тебе хочется помочь другим разработчикам, то ты вполне можешь добавить информацию в документацию и в API docs.

563 11 мая, 23:59 563 1398073

>>1397640

На мой субъективный взгляд, тут почти все понятно. Мы задаем функции-обработчики, которые вызываются при поступлении HTTP-запроса с определенным URL.

Если вопрос был про группировку, то гугление официального мануала дает такую ссылку: https://laravel.com/docs/5.8/routing#route-groups

> Route groups allow you to share route attributes, such as middleware or namespaces, across a large number of routes without needing to define those attributes on each individual route. Shared attributes are specified in an array format as the first parameter to the Route::group method.

Далее, ты пишешь ниже:

> но я не догоняю что значат массивы с ключами и значениями

Это атрибуты, правда какие именно атрибуты доступны, в документации пояснения нет. Но, может мы не все прочли? Если пролистать страницу до конца, то там есть приписочка:

> Refer to the API documentation for both the underlying class of the Route facade and Route instance to review all accessible methods.

Идем по ссылке в API docs - это документация, генерируемая из комментариев в исходном коде. К сожалению, и там не перечислен список доступных атрибутов. Значит, остается вспомнить принцип "код - лучшая документация" - открываем исходный код класса Router, метод group() и смотрим код:

https://github.com/laravel/framework/blob/5.8/src/Illuminate/Routing/Router.php#L366

Идем по функциями в таком порядке: group() -> updateGroupStack() -> loadRoutes(). Тут путь заканчивается вызовом коллбека, внутри которого делается get(), и потому изучим, что происходит при его вызове: get() -> addRoute() -> createRoute() -> mergeGroupAttributesIntoRoute() -> mergeWithLastGroup().

Мы видим, что эти атрибуты идут в метод setAction() класса Route, потому глянем и его. В методе setAction() ничего интересного нет, но зато в конструкторе мы видим вызов parseAction() с многообещающим комментарием:

> Parse the route action into a standard array.

В нем, правда, тоже ничего нет. Тогда делаем поиск по выражению "->action[" и находим названия всех атрибутов. И замечаем, что в общем-то использовать этот массив особой нужды нет, так как для задания всех этих атрибутов есть готовые методы с такими же названиями.

В общем, поиск делается примерно в таком порядке:

- официальная документация
- API docs
- исходный код

По исходному коду, конечно, удобно перемещаться с помощью IDE. Привыкай, деды исходный код разбирали и ты справишься.

Если же ты вместо этого лазаешь по каким-то неофициальным, некачественным статьям или пиратским видео, то, пожалуйста, предъявляй претензии их авторам. Также, напомню, что Ларавель - открытый проект и если тебе хочется помочь другим разработчикам, то ты вполне можешь добавить информацию в документацию и в API docs.

Показать весь текст
Ответы398192

564 12 мая, 04:09 564 1398143

>>1397862
Чмошный тест. Оформление дебильное.
Вопросы либо нулевого уровня либо с понтом каверзные, в основном по сути теже что и в прошлый раз.
Только теперь почти все можно еще от пизды дописать по сигнатурам.
Более-менее полезных вещей пару штук но и те по сути справочные знания.

Еще такие "подвохи" типа нехватки ассертов и следовательно потенциал сделать не полностью верное решение лол...

48 Кб, 529x391
565 12 мая, 04:37 565 1398146

Wget выполняется только один раз.
На винде надо запускать один удаленный скрипт который ничего не возвращает, главное обратиться к адресу. Неважно, сколько он длится. Запуски должны быть каждые 5 минут бесконечное кол-во раз.
Использую WinWGet (wget с гуем). Он выполняет задание и пишет Finished. Не врубаюсь, как настроить правильно. Гайды прочитал.
tries выставлял в 0 - бесполезно.
Кеш отключен. Лимит на ожидание ответа выставил в 0, ибо неизвестно, через сколько минут/часов будет получен ответ от сервера.
Вся команда: "http://lolicap.ls/" -P "" -w 300 -t 9999999999 -T 0 -C off

Ответы398147

566 12 мая, 04:49 566 1398147

>>1398146
Так. wait мне не нужен, как я понял. он для загрузки цельных страниц нужен.
Походу, эта штука не то, что мне нужно. Она просто не умеет в повторения из гуя. Сделаю на автоите скрипт чтоб запускал команду wget через равный промежуток и норм.
Всем спасибо.

567 12 мая, 07:25 567 1398192

>>1398073
>>1398073
вот этого я и горю,что инфу приходиться собирать по крупицам,а оф доки не всегда очевидны.тебе со своей колокольни конечно же виднее

Ответы398228398325

568 12 мая, 11:27 568 1398228

>>1398192
>инфу приходиться собирать по крупицам
Каким ещё крупицам?
>оф доки не всегда очевидны
Там настолько всё разжёвывают и показывают, что только в задницу не целют и сказку на ночь не рассказывают. А если учесть видеокурсы и другие ресурсы, то можно считать, что и в задницу, и в сказку.

Скорее всего просто не твоё это погроммирование, раз ты настолько не можешь в документацию.

Ответы398229

569 12 мая, 11:32 569 1398229

>>1398228
>Там настолько всё разжёвывают и показывают
нифига,постоянно гуглю,как это работает. их доки скорее справочник,а не учебник

Ответы398230

570 12 мая, 11:39 570 1398230

>>1398229
>постоянно гуглю,как это работает
Так-то ты нативно в общих чертах понимать это должен - где там роуты, куда сервисы, как контроллеры.

Ответы398233

571 12 мая, 11:43 571 1398233

>>1398230
я уже с примитивной фигней то разобрался,че писать в роуте,в контроллере и виде.но что касается доп параметров-швах.все примеры обычно даются в отрыве от работающего примера,накидают примеров по роутингу,например параметры и как я должен понять,что писать в контроллере?

Ответы398240398384

572 12 мая, 12:05 572 1398240

>>1398233
пока почитаю про миграции и БД

573 12 мая, 14:52 573 1398325

>>1398192

Сколько я помню, так было всегда. Так что привыкай заглядывать в код, благо он открытый.

>>1397254

Сериализация не предназначена для просмотра содержимого человеком. Она нужна для того, чтобы потом восстановить объект обратно. Если тебе нужен человекочитаемый формат, то используй: var_dump, print_r. Или JSON.

Что касается текстового/бинарного вида, подозреваю, это просто текстовый редактор неправильно распознает тип файла. Там на скриншоте явно hex-коды букв.

>>1397645

resource() описан в документации: https://laravel.com/docs/5.8/controllers#resource-controllers

> This single route declaration creates multiple routes to handle a variety of actions on the resource. The generated controller will already have methods stubbed for each of these actions, including notes informing you of the HTTP verbs and URIs they handle.

Я подозреваю, он просто ищет в контроллере метод с именем, которое идет в URL после префикса, но это стоило бы уточнить в документации или коде.

Ответы398372

574 12 мая, 14:52 574 1398326

>>1397648

> Я теперь понял, что импорты должны выполнятся там где выполняется этот запрос - это работает.

Общий принцип такой, что ты импортируешь только то, что как-то используешь именно в этом файле (вызываешь, создаешь объекты этого класса итд). Если не используешь - то не импортируешь.

> К сожалению, мне не удалось найти какой паттерн наследования использует psql

Эти паттерны наследования реализуются не на уровне Postgres, а на уровне ORM. И там в документации к SQLAlchemy перечислено несколько вариантов на выбор.

> Я косвенно предположил, что это именно он

Это Concrete TI, так как при STI таблица одна, а при Class TI в text_message были бы только те поля, которые отсутствуют в message.

> Использование UNION приводит к нагрузке?

Это надо смотреть EXPLAIN-ом и делать тесты, но скорее всего, да. Представь, что ты хочешь получить последние 10 сообщений: самый быстрый способ сделать это - это пройтись по индексу (где сообщения отсортированы по времени) и взять первые 10 записей из единственной общей таблицы. В случае с UNION нам надо брать по несколько сообщений из каждой таблицы и как-то объединять списки. Это в случае, если СУБД будет работать максимально оптимально, а это не факт.

Но вообще, выбор схемы наследования зависит от того, какие мы запросы делаем и какие у нас данные.

> Отношения между сущностями тяжело совершить с помощью встроенных инструментов и приходится делать метод для совершения запроса в ручную

Вообще, в документации есть похожий пример и там используются дополнительные параметры (foreign_keys): https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#creating-custom-foreign-conditions

Может, в этом проблема?

Ведь ORM надо знать, как связывать объекты между собой. Допустим, у тебя есть объект класса A, и он связан отношением с объектом класса B. Если ты создаешь несколько объектов класса B, добавишь их в класс A, и попробуешь сбросить данные в БД, то ORM должен понять: как сохранить в БД связь между объектами?

Думаю, явное указание foreign_keys и remote_side как раз говорит ORM, что надо взять id из одного поля объекта и прописать его в поле другого объекта.

Но я могу ошибаться, так как лишь бегло пролистал документацию.

> При получении сущностей выдается массив из сначала сущностей родителя, затем сущности ребёнка.

Если ты используешь наследование, то Text_Message - это наследник Message, в соответствие с принципом Лисков наследник можно использовать вместо предка, и когда ты запрашиваешь список Message, то в нем будут и объекты Text_Message. Если ты это не хочешь, то тебе надо указать дополнительное условие (например: искать только Text_Message).

> Сейчас я сделал авторизацию действий засчет ролей и даже для сервера не нужно применять динамическую авторизацию

Только не забудь, что надо использовать принцип "белого списка" и все, что не указано явно - запрещается.

> Лучше сделать это на системном языке и чтобы он был кроссплатформенный

Вообще, "системное программирование" - это написание всяких модулей ядра, драйверов на языках вроде Си. А так, пиши на чем удобнее - на Питоне, JS или bash.

> А если партнёров будет много (публичная конференция)?

Часто в больших публичных конференциях список участников не показывают, пока ты не нажмешь какую-то кнопку. Потому, тут стоит учесть только такие варианты:

- получить полный список для маленькой конференции
- получить (по запросу пользователя) полный список для средней конференции
- если у тебя есть большие конференции (> 1000 - 5000 - 10000 польз.), то там может потребоваться получать список постранично

> не будет ли и здесь плохо работать запрос с джоинами на больших нагрузках?

Это зависит от того, как выглядит запрос. Одно дело - приджойнить 1 запись по ключу, другое дело - сджойнить два больших списка, к каждому из которых применяется какое-то условие.

> // неизвестно какой пользователь сначала "создал" конференцию,

Я думал, что у тебя там у каждого пользователя есть своя запись для конференции (со своим числом непрочитанных сообщений), и потому такой сложный запрос не нужен: мы ищем именно свою запись, а не любую.

> Как вам кажется, индексирование массивов приведёт к желаемому повышению производительности?

Без индексов тут нельзя - это я точно могу сказать. Но вид запроса очень неудачный, и скорее всего будет плохо индексироваться. Вот пример хорошего запроса:

SELECT WHERE a = 1 AND b = 2

Такой запрос при использовании UNIQUE INDEX (a, b) будет искать в индексе пару (1; 2) и будет оптимальным. Индекс выглядит так:

(a, b -> id)

Он отсортирован по возрастанию пар значений a; b.

А как выглядит индекс в твоем случае? Скорее всего, как отсортированный список (participant -> id). И как в нем найти соответствующие условию записи? Ищем по participant = sender, получаем большой список id, ищем по participant = receiver, получаем большой список id, ищем в 2 списках одинаковые id.

Твой запрос эквивалентен такому:

SELECT a.id FROM table AS a, table AS b WHERE a.participant = :sender AND b.participant = :receiver AND a.id = b.id

То есть, попробуй этот индекс нарисовать и придумать, как вообще в теории в нем найти нужную запись, и ты возможно увидишь, какие запросы будут работать быстро, а какие - в принципе не могут работать быстро.

Потому я и советовал поступать так:

- сделать нормализованную, не оптимальную схему
- сделать список запросов, которые будут выполняться
- оптимизировать схему под них

> но мне никогда не было понятно почему только можно ответить на одно сообщение,

Потому что это упрощает пользовательский интерфейс, наверно. Но твой подход тоже имеет право на жизнь. Кто знает, может это будет как раз преимуществом в сравнении с другими мессенджерами.

> Опять же с массивами это тоже делается очень просто

Только там происходит полная выборка списка в память. Если участников очень много (десятки тысяч), кто знает, может это неэффективно (нужно мерять).

> Я считал, что ключи должны храниться только у пользователя, но подход с генерацией ключей для каждого клиента пользователя создаёт только больше проблем

Это решается, если делать клиентское приложение на Electron (или на любой другой технологии) - оно работает на стороне пользователя и может хранить что угодно, при этом очистка кук ему не грозит. Но с синхронизацией да, придется помучаться.

Шифрование ключа паролем - это симметричное шифрование. Пароль относительно короткий и владелец сервера может попытаться его сбрутфорсить. Особенно, если у него есть "друзья" из NSA с дата-центрами, построенными специально для брутфорса паролей. Но можно придумать более интересные схемы синхронизации: 2 устройства одного пользователя одновременно выходят в сеть и передают ключ друг другу с использованием асимметричного шифрования, так, что сервер не может увидеть передаваемый ключ (т.к. при асиметричном шифровании используется случайный очень длинный ключ, как в HTTPS).

Это просто рассуждения на тему того, что тут можно сделать в теории.

574 12 мая, 14:52 574 1398326

>>1397648

> Я теперь понял, что импорты должны выполнятся там где выполняется этот запрос - это работает.

Общий принцип такой, что ты импортируешь только то, что как-то используешь именно в этом файле (вызываешь, создаешь объекты этого класса итд). Если не используешь - то не импортируешь.

> К сожалению, мне не удалось найти какой паттерн наследования использует psql

Эти паттерны наследования реализуются не на уровне Postgres, а на уровне ORM. И там в документации к SQLAlchemy перечислено несколько вариантов на выбор.

> Я косвенно предположил, что это именно он

Это Concrete TI, так как при STI таблица одна, а при Class TI в text_message были бы только те поля, которые отсутствуют в message.

> Использование UNION приводит к нагрузке?

Это надо смотреть EXPLAIN-ом и делать тесты, но скорее всего, да. Представь, что ты хочешь получить последние 10 сообщений: самый быстрый способ сделать это - это пройтись по индексу (где сообщения отсортированы по времени) и взять первые 10 записей из единственной общей таблицы. В случае с UNION нам надо брать по несколько сообщений из каждой таблицы и как-то объединять списки. Это в случае, если СУБД будет работать максимально оптимально, а это не факт.

Но вообще, выбор схемы наследования зависит от того, какие мы запросы делаем и какие у нас данные.

> Отношения между сущностями тяжело совершить с помощью встроенных инструментов и приходится делать метод для совершения запроса в ручную

Вообще, в документации есть похожий пример и там используются дополнительные параметры (foreign_keys): https://docs.sqlalchemy.org/en/13/orm/join_conditions.html#creating-custom-foreign-conditions

Может, в этом проблема?

Ведь ORM надо знать, как связывать объекты между собой. Допустим, у тебя есть объект класса A, и он связан отношением с объектом класса B. Если ты создаешь несколько объектов класса B, добавишь их в класс A, и попробуешь сбросить данные в БД, то ORM должен понять: как сохранить в БД связь между объектами?

Думаю, явное указание foreign_keys и remote_side как раз говорит ORM, что надо взять id из одного поля объекта и прописать его в поле другого объекта.

Но я могу ошибаться, так как лишь бегло пролистал документацию.

> При получении сущностей выдается массив из сначала сущностей родителя, затем сущности ребёнка.

Если ты используешь наследование, то Text_Message - это наследник Message, в соответствие с принципом Лисков наследник можно использовать вместо предка, и когда ты запрашиваешь список Message, то в нем будут и объекты Text_Message. Если ты это не хочешь, то тебе надо указать дополнительное условие (например: искать только Text_Message).

> Сейчас я сделал авторизацию действий засчет ролей и даже для сервера не нужно применять динамическую авторизацию

Только не забудь, что надо использовать принцип "белого списка" и все, что не указано явно - запрещается.

> Лучше сделать это на системном языке и чтобы он был кроссплатформенный

Вообще, "системное программирование" - это написание всяких модулей ядра, драйверов на языках вроде Си. А так, пиши на чем удобнее - на Питоне, JS или bash.

> А если партнёров будет много (публичная конференция)?

Часто в больших публичных конференциях список участников не показывают, пока ты не нажмешь какую-то кнопку. Потому, тут стоит учесть только такие варианты:

- получить полный список для маленькой конференции
- получить (по запросу пользователя) полный список для средней конференции
- если у тебя есть большие конференции (> 1000 - 5000 - 10000 польз.), то там может потребоваться получать список постранично

> не будет ли и здесь плохо работать запрос с джоинами на больших нагрузках?

Это зависит от того, как выглядит запрос. Одно дело - приджойнить 1 запись по ключу, другое дело - сджойнить два больших списка, к каждому из которых применяется какое-то условие.

> // неизвестно какой пользователь сначала "создал" конференцию,

Я думал, что у тебя там у каждого пользователя есть своя запись для конференции (со своим числом непрочитанных сообщений), и потому такой сложный запрос не нужен: мы ищем именно свою запись, а не любую.

> Как вам кажется, индексирование массивов приведёт к желаемому повышению производительности?

Без индексов тут нельзя - это я точно могу сказать. Но вид запроса очень неудачный, и скорее всего будет плохо индексироваться. Вот пример хорошего запроса:

SELECT WHERE a = 1 AND b = 2

Такой запрос при использовании UNIQUE INDEX (a, b) будет искать в индексе пару (1; 2) и будет оптимальным. Индекс выглядит так:

(a, b -> id)

Он отсортирован по возрастанию пар значений a; b.

А как выглядит индекс в твоем случае? Скорее всего, как отсортированный список (participant -> id). И как в нем найти соответствующие условию записи? Ищем по participant = sender, получаем большой список id, ищем по participant = receiver, получаем большой список id, ищем в 2 списках одинаковые id.

Твой запрос эквивалентен такому:

SELECT a.id FROM table AS a, table AS b WHERE a.participant = :sender AND b.participant = :receiver AND a.id = b.id

То есть, попробуй этот индекс нарисовать и придумать, как вообще в теории в нем найти нужную запись, и ты возможно увидишь, какие запросы будут работать быстро, а какие - в принципе не могут работать быстро.

Потому я и советовал поступать так:

- сделать нормализованную, не оптимальную схему
- сделать список запросов, которые будут выполняться
- оптимизировать схему под них

> но мне никогда не было понятно почему только можно ответить на одно сообщение,

Потому что это упрощает пользовательский интерфейс, наверно. Но твой подход тоже имеет право на жизнь. Кто знает, может это будет как раз преимуществом в сравнении с другими мессенджерами.

> Опять же с массивами это тоже делается очень просто

Только там происходит полная выборка списка в память. Если участников очень много (десятки тысяч), кто знает, может это неэффективно (нужно мерять).

> Я считал, что ключи должны храниться только у пользователя, но подход с генерацией ключей для каждого клиента пользователя создаёт только больше проблем

Это решается, если делать клиентское приложение на Electron (или на любой другой технологии) - оно работает на стороне пользователя и может хранить что угодно, при этом очистка кук ему не грозит. Но с синхронизацией да, придется помучаться.

Шифрование ключа паролем - это симметричное шифрование. Пароль относительно короткий и владелец сервера может попытаться его сбрутфорсить. Особенно, если у него есть "друзья" из NSA с дата-центрами, построенными специально для брутфорса паролей. Но можно придумать более интересные схемы синхронизации: 2 устройства одного пользователя одновременно выходят в сеть и передают ключ друг другу с использованием асимметричного шифрования, так, что сервер не может увидеть передаваемый ключ (т.к. при асиметричном шифровании используется случайный очень длинный ключ, как в HTTPS).

Это просто рассуждения на тему того, что тут можно сделать в теории.

Показать весь текст

575 12 мая, 15:52 575 1398372

>>1398325
>Что касается текстового/бинарного вида, подозреваю, это просто текстовый редактор неправильно распознает тип файла. Там на скриншоте явно hex-коды букв.
А вот тут и правда я не подумол. >>1397801 - вот здесь смотрел через другой редактор и видел что надо.

https://codecoshauni.github.io 576 12 мая, 16:18 576 1398384

>>1398233

Почитай про MVC, например у меня в уроке: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

>>1380575

https://codecoshauni.github.io

Первое, что сразу бросается в глаза: буквы в слове "We are" у тебя значительно толще, чем на макете. Конечно, бывают различия в рендеринге на разных платформах, но не до такой же степени. Проверка показала, что у тебя в h1 используется шрифт в полужирном (font-weight: bold) начертании, а должно использоваться тонкое начертание. Также, в слове Webpaint жирный шрифт искуственно ужирняется сверх нормы. Ну и еще, если присомтреться, то на макете чуть больше межбуквенное расстояние, чем у тебя.

Отступ между надписью "into berautiful things" и кнопкой ниже в полтора раза больше, чем должен быть. Заголовков Consectetur, Tristiquet у тебя вообще нет.

Надпись digital & branding имеет слишком сильный наклон букв. Ты взял шрифт в курсивном начертании и добавил к нему искуственный наклон за счет font-style: italic.

Ну это же грубейшие ошибки, которые сразу видны, если просто открыть рядом макет и твою верстку. Это никуда не годится. Нужно тщательнее проверять свою работу. Есть расширения к браузеру (вроде pixel perfect), которые позволяют накладывать изображение поверх страницы, они могут тебе помочь.

Сами шрифт подключен неправильно. Там используется один шрифт Lato, в разных начертаниях и стилях (font-weight, font-style), а не несколько разных шрифтов. Если делать правильно, то, когда мы используем тег strong, браузер будет автоматически выбирать более жирное начертание. В твоем же случае, он будет искуственно ужирнять буквы. Если правильно подключить шрифт, многие проблемы исправятся сами собой. Почитай про @font-face и про использование font-weight/font-style внутри. Если ты любишь длинные спецификации, то пожалуйста: https://drafts.csswg.org/css-fonts-4/#font-face-rule Если нет, то поищи какой-нибудь другой мануал.

Также, твой способ подключения не позволяет использовать локально установленную версию шрифта Lato.

Тебе нужно тщательно сравнить макет и свою верстку и исправить расхождения. В блоке Consectetur обрати внимание на межстрочный интервал.

Адаптивность требует доработки, а именно:

- блок с заголовками вроде Consectetur просто смотрится плохо на ширине 810 px. Он слишком широкий. Тут было бы логичнее либо сделать их в 2 колонки, либо сделать вертикальным списком для узких экранов, а иконку попробовать вынести вбок. А на маленькой ширине вообще убрать иконку или уменьшить ее размер.
- меню смотрится странно на ширине 810px, оно выстроено вертикально и слева от него огромное пустое место. Можно попробовать поэкспериментировать, выстроив его в 2-3 колонки, или попробовать поместить справа от надписи "We are Webpaint".
- Кнопки All/Graphic на ширине 810 px, наверно, лучше смотрятся в горизонтальном расположении
- В подвале на ширине 810px иконки места и телефона вываливаются на отдельную строку
- На ширине 338px надпись на кнопке See portfolio сдвинута вниз
- На ширине 352px в портфолио очень большие поля слева и справа, лучше их уменьшить и увеличить картинки портфолио. Более того, возможно, на такой маленькой ширине их стоит выводить в 1 колонку.

Заглавные буквы в меню делать лучше за счет CSS свойств. Имена лучше выбирать более осмысленно, не button1, а button-all.

У тебя есть правило:

> font-display: swap;

но оно вроде бы указывается внутри @font-face: https://drafts.csswg.org/css-fonts-4/#font-display-desc

https://codecoshauni.github.io 576 12 мая, 16:18 576 1398384

>>1398233

Почитай про MVC, например у меня в уроке: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

>>1380575

https://codecoshauni.github.io

Первое, что сразу бросается в глаза: буквы в слове "We are" у тебя значительно толще, чем на макете. Конечно, бывают различия в рендеринге на разных платформах, но не до такой же степени. Проверка показала, что у тебя в h1 используется шрифт в полужирном (font-weight: bold) начертании, а должно использоваться тонкое начертание. Также, в слове Webpaint жирный шрифт искуственно ужирняется сверх нормы. Ну и еще, если присомтреться, то на макете чуть больше межбуквенное расстояние, чем у тебя.

Отступ между надписью "into berautiful things" и кнопкой ниже в полтора раза больше, чем должен быть. Заголовков Consectetur, Tristiquet у тебя вообще нет.

Надпись digital & branding имеет слишком сильный наклон букв. Ты взял шрифт в курсивном начертании и добавил к нему искуственный наклон за счет font-style: italic.

Ну это же грубейшие ошибки, которые сразу видны, если просто открыть рядом макет и твою верстку. Это никуда не годится. Нужно тщательнее проверять свою работу. Есть расширения к браузеру (вроде pixel perfect), которые позволяют накладывать изображение поверх страницы, они могут тебе помочь.

Сами шрифт подключен неправильно. Там используется один шрифт Lato, в разных начертаниях и стилях (font-weight, font-style), а не несколько разных шрифтов. Если делать правильно, то, когда мы используем тег strong, браузер будет автоматически выбирать более жирное начертание. В твоем же случае, он будет искуственно ужирнять буквы. Если правильно подключить шрифт, многие проблемы исправятся сами собой. Почитай про @font-face и про использование font-weight/font-style внутри. Если ты любишь длинные спецификации, то пожалуйста: https://drafts.csswg.org/css-fonts-4/#font-face-rule Если нет, то поищи какой-нибудь другой мануал.

Также, твой способ подключения не позволяет использовать локально установленную версию шрифта Lato.

Тебе нужно тщательно сравнить макет и свою верстку и исправить расхождения. В блоке Consectetur обрати внимание на межстрочный интервал.

Адаптивность требует доработки, а именно:

- блок с заголовками вроде Consectetur просто смотрится плохо на ширине 810 px. Он слишком широкий. Тут было бы логичнее либо сделать их в 2 колонки, либо сделать вертикальным списком для узких экранов, а иконку попробовать вынести вбок. А на маленькой ширине вообще убрать иконку или уменьшить ее размер.
- меню смотрится странно на ширине 810px, оно выстроено вертикально и слева от него огромное пустое место. Можно попробовать поэкспериментировать, выстроив его в 2-3 колонки, или попробовать поместить справа от надписи "We are Webpaint".
- Кнопки All/Graphic на ширине 810 px, наверно, лучше смотрятся в горизонтальном расположении
- В подвале на ширине 810px иконки места и телефона вываливаются на отдельную строку
- На ширине 338px надпись на кнопке See portfolio сдвинута вниз
- На ширине 352px в портфолио очень большие поля слева и справа, лучше их уменьшить и увеличить картинки портфолио. Более того, возможно, на такой маленькой ширине их стоит выводить в 1 колонку.

Заглавные буквы в меню делать лучше за счет CSS свойств. Имена лучше выбирать более осмысленно, не button1, а button-all.

У тебя есть правило:

> font-display: swap;

но оно вроде бы указывается внутри @font-face: https://drafts.csswg.org/css-fonts-4/#font-display-desc

Показать весь текст

577 12 мая, 16:29 577 1398391

ОПчик, ответь, пожалуйста, нормальная ли архетиктура в >>1394909

578 12 мая, 17:33 578 1398430

это снова я.вопрос теперь по фабрике в ларе.как размножить одну модель?

Ответы398506

579 12 мая, 19:25 579 1398506

>>1398430
это хрень только для тестов?

580 12 мая, 20:38 580 1398596

Привет, антошки.
В шапке есть ссылка на задание по созданию SPA.
https://github.com/codedokode/pasta/blob/master/js/spa.md
И там в самом конце есть такие строки:
>Хорошо бы покрыть приложение или его компоненты автоматическими тестами
И тут мне стало очень интересно, что это за автоматические тесты такие. Саму концепцию я более-менее представляю, но, тем не менее, совершенно не понимаю следующее:
1) Как, собственно, эти автоматические тесты делать/писать? Вот написал я код, хочу его протестировать этими автотестами - как и с чего начинать?
2) В вакансиях иногда встречаю фразы типа "у нас хорошее покрытие кода автоматическими тестами". Может кто-нибудь рассказать, как именно это происходит в таких компаниях?

Буду благодарен за информацию.

Ответы398613

581 12 мая, 20:52 581 1398613

>>1398596
бездумно даю тебе ссылку из шапки - https://gist.github.com/codedokode/a455bde7d0748c0a351a

Ответы398827

582 12 мая, 23:04 582 1398700

Аноны помогите написать регулярку чтобы
из строки "@a @ab @abc a@xyz !@ijmn,@123 0@321 @1a2b @qwerty @abc.a @stu..test _@nmp @x.yz.@klm @.1a2b .@2c3d."
выбирало
["@abc", "@ijmn", "@123", "@1a2b","@abc.a", "@stu", "@x.yz", "@klm", "@2c3d"]

Ответы398715398730398813398815398837

583 12 мая, 23:35 583 1398715

>>1398700
Я логики в упор не вижу.

Ответы398813

584 12 мая, 23:44 584 1398730

>>1398700
Написал: @[1-3a-di-ns-ux-z.]{3,5}[\s]
https://regex101.com/r/YFPlPz/1

Самая чокнутая регулярка на моей памяти.

Ответы398813

585 13 мая, 01:52 585 1398804

Нид хелп с функциями.
Есть код: function rand_float($st_num=0,$end_num=1,$mul=1000000)
{
if ($st_num>$end_num) return false;
return mt_rand($st_num$mul,$end_num$mul)/$mul;
}

$num= rand(1,3);
include_once('db_connect.php');
for ($i = 0; $i < $num; $i++) {
$req = $mysqli->query("SELECT FROM `coinInfo` WHERE coinName = 'BTC'");
while($row = $req->fetch_assoc()) {
$ask = $row["ask"]/100000000;
$bid = $row["bid"]/100000000;
}
$operation = array("BUY", "SELL");
$rand_keys = array_rand($operation);

//

$int = mt_rand(1,4)/10000;
$fractional = mt_rand(1,99) / 10000;
$float = $int + $fractional;

$price = rand_float($bid,$ask);
$amount = $float;
$type_operation = $operation[$rand_keys];

$Responce=create_orders($mysqli,$sesion_id = 299,$contest_id = 1,$price,$amount,$name_val = 'USD',$name_prod = 'BTC',$type_operation);
По итогу он создает ордера(от 1 до 3) на продажу и покупку. Мне нужно продублировать его для нескольких $name_prod(их будет штук 20). И я хочу написать функцию, которая будет иметь единственный аргумент coinName, используется в запросе $req = $mysqli->query("SELECT FROMcoinInfoWHERE coinName = 'BTC'"); и эта новая функция будет возвращать весь набор необходимых переменных для create_orders. По идее должно вызов должен выглядеть как-то так: create_orders(data(btc))(если такое возможно вообще).
}

585 13 мая, 01:52 585 1398804

Нид хелп с функциями.
Есть код: function rand_float($st_num=0,$end_num=1,$mul=1000000)
{
if ($st_num>$end_num) return false;
return mt_rand($st_num$mul,$end_num$mul)/$mul;
}

$num= rand(1,3);
include_once('db_connect.php');
for ($i = 0; $i < $num; $i++) {
$req = $mysqli->query("SELECT FROM `coinInfo` WHERE coinName = 'BTC'");
while($row = $req->fetch_assoc()) {
$ask = $row["ask"]/100000000;
$bid = $row["bid"]/100000000;
}
$operation = array("BUY", "SELL");
$rand_keys = array_rand($operation);

//

$int = mt_rand(1,4)/10000;
$fractional = mt_rand(1,99) / 10000;
$float = $int + $fractional;

$price = rand_float($bid,$ask);
$amount = $float;
$type_operation = $operation[$rand_keys];

$Responce=create_orders($mysqli,$sesion_id = 299,$contest_id = 1,$price,$amount,$name_val = 'USD',$name_prod = 'BTC',$type_operation);
По итогу он создает ордера(от 1 до 3) на продажу и покупку. Мне нужно продублировать его для нескольких $name_prod(их будет штук 20). И я хочу написать функцию, которая будет иметь единственный аргумент coinName, используется в запросе $req = $mysqli->query("SELECT FROMcoinInfoWHERE coinName = 'BTC'"); и эта новая функция будет возвращать весь набор необходимых переменных для create_orders. По идее должно вызов должен выглядеть как-то так: create_orders(data(btc))(если такое возможно вообще).
}

Показать весь текст
Ответы415601

586 13 мая, 02:46 586 1398813

>>1398715
>>1398730

ему для теста пикабу. решение очевидно не верное ведь он не целиком перепостил

>>1398700

начни с простейшего
> \B@[a-z\d.]{3,5}\b

\B в начале исключить варианты вроде a@aaa
\b в конце это границы слова, помогает не матчить подстроку "@aaaaa" из "@aaaaab" к примеру

потом чтобы исключить варианты с многими точками в середине "@a..aa" можно добавить "позитив лукахед" после @
Обрати внимание, что в задании в комменатрии указано - не более одной точки, но в ассерте нет подходящего теста
> \B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}\b

> (?=[a-z\d]+\.?[a-z\d]+)
Вот этот кусок означает что следующее выражение после скобок будет также матчиться с ним, а сам он матчит допустимые символы плюс максимум одну точку где-то между ними. Короткий туториал:
?= - positive lookahead
?!
([выражение])[следующее выражение] - positive lookahead -
([выражение])[следующее выражение] - negative lookahead
(?<=[выражение])[следующее выражение] - positive lookback
(?<![выражение])[следующее выражение] - positive lookback

Теперь чтобы не матчить с точкой в конце добавим ка негатив лукбек..
\B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}(?<!\.)\b
Вот эта хуйня смотрит "назад" и удостоверяется что там нет ровно одной точки.

В качестве альтернативы можно сделать так:
\B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{2,4}[a-z\d]\b

586 13 мая, 02:46 586 1398813

>>1398715
>>1398730

ему для теста пикабу. решение очевидно не верное ведь он не целиком перепостил

>>1398700

начни с простейшего
> \B@[a-z\d.]{3,5}\b

\B в начале исключить варианты вроде a@aaa
\b в конце это границы слова, помогает не матчить подстроку "@aaaaa" из "@aaaaab" к примеру

потом чтобы исключить варианты с многими точками в середине "@a..aa" можно добавить "позитив лукахед" после @
Обрати внимание, что в задании в комменатрии указано - не более одной точки, но в ассерте нет подходящего теста
> \B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}\b

> (?=[a-z\d]+\.?[a-z\d]+)
Вот этот кусок означает что следующее выражение после скобок будет также матчиться с ним, а сам он матчит допустимые символы плюс максимум одну точку где-то между ними. Короткий туториал:
?= - positive lookahead
?!
([выражение])[следующее выражение] - positive lookahead -
([выражение])[следующее выражение] - negative lookahead
(?<=[выражение])[следующее выражение] - positive lookback
(?<![выражение])[следующее выражение] - positive lookback

Теперь чтобы не матчить с точкой в конце добавим ка негатив лукбек..
\B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}(?<!\.)\b
Вот эта хуйня смотрит "назад" и удостоверяется что там нет ровно одной точки.

В качестве альтернативы можно сделать так:
\B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{2,4}[a-z\d]\b

Показать весь текст
Ответы398815

587 13 мая, 02:53 587 1398815

>>1398813

я ебал этот редактор какого то хуя запостило посреди поста

>>1398700

начни с простейшего
> \B@[a-z\d.]{3,5}\b

\B в начале исключить варианты вроде a@aaa
\b в конце это границы слова, помогает не матчить подстроку "@aaaaa" из "@aaaaab" к примеру

потом чтобы исключить варианты с многими точками в середине "@a..aa" можно добавить "позитив лукахед" после @
Обрати внимание, что в задании в комменатрии указано - не более одной точки, но в ассерте нет подходящего теста
> \B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}\b

> (?=[a-z\d]+\.?[a-z\d]+)
Вот этот кусок означает что следующее выражение после скобок будет также матчиться с ним, а сам он матчит допустимые символы плюс максимум одну точку где-то между ними. Базовый туториал: https://www.regular-expressions.info/lookaround.html

Теперь чтобы не матчить с точкой в конце добавим ка "негатив лукбек"
> \B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}(?<!\.)\b
Вот эта хуйня смотрит "назад" и удостоверяется что там нет ровно одной точки.

В качестве альтернативы можно сделать так:
> \B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{2,4}[a-z\d]\b

Это возможно эффективнее работает по производительности но как по мне становится менее очевидно условие что символов от 3 до 5

И в конце концов тебе нужно почти целиком это завернуть в именованную группу, т.к. в коде теста это все потом вытаскивается из неё
тутс: https://www.regular-expressions.info/named.html

> \B(?<name>@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5})(?<!\.)\b

хотя вообще можно было бы и целиком:
> (?<name>\B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}(?<!\.)\b)

но как по мне всегда лучше захватывать необходимый минимум

587 13 мая, 02:53 587 1398815

>>1398813

я ебал этот редактор какого то хуя запостило посреди поста

>>1398700

начни с простейшего
> \B@[a-z\d.]{3,5}\b

\B в начале исключить варианты вроде a@aaa
\b в конце это границы слова, помогает не матчить подстроку "@aaaaa" из "@aaaaab" к примеру

потом чтобы исключить варианты с многими точками в середине "@a..aa" можно добавить "позитив лукахед" после @
Обрати внимание, что в задании в комменатрии указано - не более одной точки, но в ассерте нет подходящего теста
> \B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}\b

> (?=[a-z\d]+\.?[a-z\d]+)
Вот этот кусок означает что следующее выражение после скобок будет также матчиться с ним, а сам он матчит допустимые символы плюс максимум одну точку где-то между ними. Базовый туториал: https://www.regular-expressions.info/lookaround.html

Теперь чтобы не матчить с точкой в конце добавим ка "негатив лукбек"
> \B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}(?<!\.)\b
Вот эта хуйня смотрит "назад" и удостоверяется что там нет ровно одной точки.

В качестве альтернативы можно сделать так:
> \B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{2,4}[a-z\d]\b

Это возможно эффективнее работает по производительности но как по мне становится менее очевидно условие что символов от 3 до 5

И в конце концов тебе нужно почти целиком это завернуть в именованную группу, т.к. в коде теста это все потом вытаскивается из неё
тутс: https://www.regular-expressions.info/named.html

> \B(?<name>@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5})(?<!\.)\b

хотя вообще можно было бы и целиком:
> (?<name>\B@(?=[a-z\d]+\.?[a-z\d]+)[a-z\d.]{3,5}(?<!\.)\b)

но как по мне всегда лучше захватывать необходимый минимум

Показать весь текст

588 13 мая, 07:52 588 1398827

>>1398613
О, блин, вот это я даун, тупо не заметил ее.
Спасибо.

589 13 мая, 07:55 589 1398828

>>1395772
А как тогда принудительно заставить браузер перерисовать страницу в моем случае?
Вообще как заставить браузер перерисовать страничку из пхп?

Ответы413647

590 13 мая, 09:01 590 1398837

>>1398700
Как ты победил Фибоначчи?
Я уже ночью спать не могу.

Ответы399053

591 13 мая, 13:21 591 1398962

Гайс, попробовал запустить встроенный веб-сервер php. Через curl запросы отправляются и index.php возвращается, но браузер firefox выдает мне connection blocked. Как фиксить?
Второй вопрос. Как запускать апач для текущего каталога?
Сейчас могу смотреть только на те страницы, которые лежат в папке /var/www/html. Но если я например создал на рабочем столе папку и накидал туда php-файлов. Как мне их посмотреть в браузере через апач?

Ответы399006399007

592 13 мая, 14:02 592 1398983

я не понял,а Eloquent может в существ таблицу с пустыми колонками вписывать данные,типа имя юзера,логин и пароль?может я хреново понял документацию на англ?

Ответы399011

593 13 мая, 14:04 593 1398984

Бросайте свои регулярки и пиздуйте уже на Хекслет.
Пока вы полгода пытаетесь сделать задачу, сын маминой подруги устраивается на работу с 300кк в наносекунду.

Ответы398989399007399072399077

594 13 мая, 14:06 594 1398989

>>1398984
>300кк в наносекунду.
300 нанорублей за 1 сек
поправил

595 13 мая, 14:30 595 1399006

>>1398962
В конфиге апача параметр document root

596 13 мая, 14:32 596 1399007

>>1398962

Какой порт ты используешь для веб-сервера? Что пишешь в адресной строке браузера? Не ругается ли антивирус? Есть ли какие-то подробности на странице ошибки браузера? Если открыть консоль Firefox клавишами Ctrl + Shift + J или devTools клавишей F12, есть ли там какие-то относящиеся к проблеме сообщения?

>>1398984

Без аргументации это выглядит как грубо сделанная реклама.

597 13 мая, 14:34 597 1399011

>>1398983
как я понял, ты хочешь заполнять пустые.
Если ты сам хочешь своими данными заполнить, то ищешь как обычно, например Projects::all()->first(), присвоив её, и как при создании новой вставлять $projects->name = 123; $projects->save();
Если чтобы он сам заполнил, то прочитай про faker

Ответы399016

598 13 мая, 14:37 598 1399016

>>1399011
> про faker
читал,но так понял что это для тестирования.на практике не пробывал
ну таблица есть есть с именованными колонками.их должен заполнить юзер.
где можно нормально почитать для нуба?

Ответы399018

599 13 мая, 14:38 599 1399017

>>1395840
бамп

Ответы399052413646

600 13 мая, 14:38 600 1399018

>>1399016
по этой статье руководствоваться мне?
https://laravel.com/docs/5.8/eloquent#inserting-and-updating-models

601 13 мая, 15:08 601 1399052

>>1399017
Код вообще без комментариев. Садись - 2.

Хотя бы по строчке каждому методу и классу добавь.
В индексе тож напиши - что там просисходит в общих чертах.

Телепаты в вечном отпуске, а по коду разбирать - долго, нудно и нафиг надо.

Ответы399112

602 13 мая, 15:10 602 1399053

>>1398837
Я подскажу. Однако этот факт говорит о том что у тебя не хватает знаний о пхп.
В самом ассерте подсказка - твоя функция возвращает что-то, что является Iterable и приводится к массиву.

Скорее всего, функция является генератором...

Читаем про генераторы в пхп. Чтобы функция стала им в ней должен быть либо yield либо yield from - вот по сути и ответ.
В данном случае нужен yield from чтобы вернуть массивчик как пару ключ -> значение, просто yield вернет его целиком как значение.

Далее ты можешь посмотреть на состав функции - там, например есть return - это такой типо хитрожопый обман, на самом деле он там вообще ничего не делает. И еще пара таких вещей.

Ответы399167

603 13 мая, 15:54 603 1399072

>>1398984
Секта уровня бизнес-молодости, но лошкам хоть в глаза ссы.

ЧТО ТАКОЕ ООП, СУКА?

604 13 мая, 16:05 604 1399077

>>1398984
>> устраивается на работу с 300кк в наносекунду.
Нахрен иди со своими курсами.
Устраивается тот, кто подскакивает кабанчиком и ищет.

Толковый совет - активно искать подработку на свой уровень, даже на совсем нуба найдется свой купец. Мне недавно чел знакомый рассказывал как он переделывалсделал новый нахрен одной женщине ее лэндинг. Этот лэндинг ей кто то склепал за 5 тыс рублей - там дичайшая деревянная верстка табличная была, рили уровень первокурсника. Однако же 5 тыс.

Ответы399152

605 13 мая, 17:23 605 1399112

>>1399052
Принял

606 13 мая, 18:22 606 1399152

>>1399077
Самое стрёмное, что свой уровень не считаешь уровнем - думаешь, что такое же говно, и тебя любой мимокрок насквозь видит.

607 13 мая, 18:48 607 1399167

>>1399053
Спасибо тебе добрый человек.

> твоя функция возвращает что-то, что является Iterable
Да это было понятно и также было понятно, что !!![$n + 1 => $n1];
не подразумевает использование какой-либо функции.

> о том что у тебя не хватает знаний о пхп
У меня их вообще нет. Я просто мимо проходил и почему то зацепила эта игра.

> генератором, yield
Да я был близок.

В реальных проектах неужели используют такие странный конструкции с and и or?
$r = $n1 += $n2 and 0 or !!![$n + 1 => $n1];

Ответы399311399399399995

608 13 мая, 22:22 608 1399311

>>1399167
>В реальных проектах неужели используют такие
Там эталон поехавшего говнокода.

609 13 мая, 22:42 609 1399327

Здравствуйте, правильно ли я понимаю, что языка программирования, наиболее подходящего для скорейшего поиска хоть какой-то работы, пусть даже за еду, и при этом наиболее простого в изучении, с самым низким порогом вхождения, чем php, нет?

Ответы399332399333

610 13 мая, 22:53 610 1399332

>>1399327
Не правильно.

Ответы399339

611 13 мая, 22:54 611 1399333

>>1399327
Устаревший стериотип, так же как и то, что пхп - хуевый язык для макак. Для быстрого вката на работу пиздуй в js тред.

Ответы399342

42 Кб, 600x340
612 13 мая, 22:55 612 1399337

Ребята, подскажите как в nginx включить вывод ошибок php в браузере?

Все инструкции, что нагуглил - ничего не делают!

В Apache, при ошибке в коде - выводились сообщения об этом.

В nginx - или белая страница или 500я ошибка. Шо делать, хлопцы? Не лазить же каждый раз в папку с логами.

Ответы406548

613 13 мая, 22:55 613 1399339

>>1399332
Под php я подразумеваю также знания html+css и каких-то основ по javascript, т.к. они вроде бы сами собой подразумеваются в довесок к php.
И всё-таки, если не php, то что?

Ответы399356

614 13 мая, 22:57 614 1399342

>>1399333
> пиздуй в js тред

Благодарю!

615 13 мая, 23:22 615 1399356

>>1399339
Для "быстрого вката" на пхп скорее всего придется выучить на базовом уровне стэк из из php+mysql+html+js+css и идти ковырять магазины за 30к на каких-нибудь джумловордпрессах набираться опыта (эта низша вроде еще жива и будет жить, но там угнетение, очень много нужно знать и задротить ненужной хуйни время которой по сути уже проходит, там можно залететь в контору в которой хуярят на каком-нибудь MODX если ты в мухосрани, где на самом пхп то и кодить по сути не придется, сиди хуйню вызывай шаблонную и депрессуй), либо я даже не знаю, потому что тренд "ебанем фастиком на пхп и вываливаем на рыночек" имхо прошел. Новые проекты уже не так часто будут начинаться на пыхе. Стартапы-хуяпы вроде на ноде сейчас будут. Джуны судя по объявлениям не нужны, нужны опытные писаки с набитой рукой которые могут либо решать сложные задачи, либо любое самое всратое легаси поковыряют так что оно не сломается, поэтому как вкатиться в нормальную контору без опыта я понятия не имею сейчас.

С другой стороны если взять тех же фронт-энд разрабов то там сейчас большой кадровый голод и готовы даже ОБУЧАТЬ! С пхп я такое видел 5-6 лет назад, когда сам вкатывался, в последствии же это сошло на нет. Далее если например просто вбить на хэдхантере php, то будет 200 вакансий, а если js, то 400. По таким вот простейшим наблюдениям делаю вывод что в js куда проще вкатиться на данном этапе.

Ответы399359399360399579399596

616 13 мая, 23:23 616 1399359

>>1399356
>php+mysql+html+js+css
linux еще забыл.

Ответы399860

617 13 мая, 23:25 617 1399360

>>1399356
Большое спасибо за развернутый ответ!

618 14 мая, 00:12 618 1399399

>>1399167
Это один из "запутывающих" моментов. "and 0 or" по сути вообще ничего не делает и аналогично ";"

619 14 мая, 10:22 619 1399579

>>1399356
>По таким вот простейшим наблюдениям делаю вывод что в js куда проще вкатиться на данном этапе.
Сейчас бы вкатываться туда, куда проще, а не туда, куда сердце лежит.

Я вот линуксы знаю, немножко кодить умею на других языках. Зачем мне ваш жаваскрипт с раскраской формочек и событиями, если мне просто ближе бэкэнд? Мне и учить его легче и отторжения не вызывает, как фронтеэнд. И вчерашних школьников тут поменьше.

Ответы399596399721

620 14 мая, 11:05 620 1399596

>>1399356
>поэтому как вкатиться в нормальную контору без опыта я понятия не имею сейчас
3 человека знаю, кто за последние пол года вкатились. 1 в Питере 2 в Москве.
Всех брали на вакансии "1+ года опыта",
Но они и знали прилично (теоретическая база на слабенького мидла) + свои пет проекты вроде оповского тест-хаба. На гостевухе и одной книжке "Как слабать гостевуху на php" далеко не уедешь.
Сладкие времена, когда брали всех кто мог комп включить на обучение, прошли после кризиса 2008 и крым-наша, как в php так и в java c .net.

>>1399579
true

Ответы399721

621 14 мая, 15:01 621 1399721

>>1399579
речь шла о:
>для скорейшего поиска хоть какой-то работы
>с самым низким порогом вхождения

>>1399596
>1 в Питере 2 в Москве.
>Но они и знали прилично
Хз где противоречия? Я и написал что нельзя сейчас прийти просто так и сказать что платите мне 20к, а я буду учиться типа.

Ответы399759

622 14 мая, 16:16 622 1399759

>>1399721
>>для скорейшего поиска хоть какой-то работы
>>с самым низким порогом вхождения
Для скорейшего поиска работы можно просто пойти на завод. Нафига ещё что-то левое учить?
А самый низкий порог вхождения подразумевает работу с соседом-зумером, срущим мемасами по поводу и без.

623 14 мая, 18:37 623 1399860

>>1399359
Все тру пацаны на линуксе сидят? Может кто в двух словах обьяснить чем он лучше для разработчика?

Ответы399880

624 14 мая, 19:04 624 1399880

>>1399860
Он для серверов лучше винды. Так исторически сложилось.

Ответы399895

625 14 мая, 19:20 625 1399895

>>1399880
На винде нельзя сделать то, чего можно на линуксе? Или это будет не так эффективно?

Ответы399902399920

626 14 мая, 19:30 626 1399902

>>1399895
Все можно делать везде если ты обычный чел, хоть на маке хуярь, но наверное 90% веб-ресурсов крутится на линуксе. Сам если захочешь что-то свое поднять то придется учиться запускать и разворачивать это дело. В крупных конторах тоже исторически все хуярят на убунтах всяких и придешь туда, тебя посадят просто на готовую машину, на которой уже поставлены инструментами с которыми ты должен уметь работать, а если не умеешь то тебя еще на этапе собеседования перезвонят. Это не значит совсем что вся разработка тоже ведется на линуксах. В тех местах где я работал и работаю сейчас спокойно хуярят на локалке через ospanel и вперед, похуй что на продакшенах линуксы, все предварительно тестируется на тест-полигонах.

627 14 мая, 19:52 627 1399920

>>1399895
Пиши хоть на Вин 3.11, для рабочих групп которая.
А Макрософтам слишком жирно будет за каждый сервак в интернетах платить - жопа треснет.

628 14 мая, 21:18 628 1399995

>>1399167
В рот ебал это пикабу.
У меня опыта больше 7ми лет работал в разных крупных компаниях.
Проебался с этим заданием чуть не целый день, но сделал.
Мне ничего не ответили, ни письма ничего вообще, просто поссали мне в на лицо, потому что таких хомяков как я пол интернета.

Задачи к реальности отношение имеют весьма опосредованное.
Никогда не приходилось мастерски владеть функцией sscanf.
Ни на одном живом проекте я нигде не видел ни одного __invoke
И более того что если кто-то вздумает писать такое как вот у них в задании то это блять никогда не пройдет кодревью.

Задачи лишь для того чтобы ты показал им что ты терпеливое чмо согласное на любые унижения.

Ответы400017400026

629 14 мая, 21:44 629 1400017

>>1399995

Почему бы тебе не умерить свой гнев? Судя по тому, что я видел в треде (примеры вида !!![....]), это какой-то действительно неадекватный код, который нельзя писать в реальной жизни. Я бы был категорически против такого кода в проектах, над которыми работаю.

Но не надо сразу искать злой умысел. Возможно, они просто не смогли придумать более хорошее задание. Попробуй сам придумай, как толпы всяких менеджеров, прошедших курсы от мейл-ру (которые намекают на зарплату > 100 000 после их прохождения), и школьников, принципиально учащихся только по видео на Ютубе, отобрать настоящих разработчиков?

Я сам составлял как-то задачи для собеседований, и поверь, это очень непросто.

630 14 мая, 21:57 630 1400026

>>1399995
Сами задачи не несут никакого полезного знания, кроме траты времени. Лучше нормальное что почитать за это время, или глянуть что по той же теме. А какой смысл говнокод распутывать? Просто время жалко.

>Попробуй сам придумай, как толпы всяких менеджеров, прошедших курсы от мейл-ру (которые намекают на зарплату > 100 000 после их прохождения), и школьников, принципиально учащихся только по видео на Ютубе, отобрать настоящих разработчиков?
Классику с задачками на простые алгоритмы, вопросами на тему структур данных\фреймворки, код посмотреть - что сам вообще пишет?
Лучше эту шизофрению им подавать, выступая в роли ебанутого работодателя?

Ответы400346

631 15 мая, 02:23 631 1400219

Зашел посмотреть требования для джунов. Первой же ссылкой выдало: https://kiev.hh.ua/vacancy/31217687?query=PHP+junior&customDomain=1

Такие вакансии действительно существуют? Или тебя забирают в рабство обслуживать местных татаров? что то даже грустно стало

Ответы400294

632 15 мая, 09:09 632 1400269

Котаны, подскажите нубу, в методе устанавливающем обработчик при фатальной ошибке увидел такую конструкцию:

if(!empty($error) && $error['type'] & ( E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR) ){
//тут код
}

С первым '&&' ясно все - это AND

А вот в этой конструкции

$error['type'] & ( E_ERROR | E_PARSE | E_COMPILE_ERROR | E_CORE_ERROR)

& - что делает?

Ответы400294

633 15 мая, 10:29 633 1400294

>>1400269
Это побитовые операции, у ОПа есть теория и задачи на эту тему: https://phpclub.tech/pr/res/1019301.html#1027969
Ещё теории: https://learn.javascript.ru/bitwise-operators

>>1400219
Что не так? Обычная вакансия. Тебе в перезвоним тред, тут обсуждают программирование.

634 15 мая, 12:04 634 1400346

>>1400026
Самая большая ошибка, это никак не отреагировать на то что человек прошел тест, ни написать письмо, ни ачивку там выдать ни сказать "Сорян чувак мы уже нашли программиста". Достаточно просто было шаблонное письмо разослать хотя бы.

Ты чувствуешь себя обманутым потому что ты день плясал ради того чтобы на тебя никак не отреагировали.

Рейтинг конторы портится, ощущение что они считают что им все должны просто потому что у них огромная аудитория они могут зачерпнуть с этой аудитории программистов, например, а часть аудитории просто нахуй послать, потому что аудитория настолько большая что им похуй что она станет немношк меньше.

Ответы400378400891

635 15 мая, 12:49 635 1400378

>>1400346
Ну да, могли бы даже лычку на аккаунт повесить - типа уважаемый господин пхпшник. А так это что-то вроде разгадывания кроссворда получается - беспрофитное занятие для пенсионеров.

636 15 мая, 18:22 636 1400712

>>1380485 (OP)
хочу поставить на сайт вот это https://www.webslesson.info/2017/09/how-to-insert-xml-data-into-mysql-table-using-php.html
на простом пхп работает, а на yii нет
просто копирую код в виев
ошибка что сервер не может обработать запрос вроде
как это можно прикрутить к сайту на yii

Ответы402303

637 15 мая, 19:07 637 1400731

Где начало обсуждения пикабу? Я чет вроде в треде уже неделю мониторю, а не увидел начало. Только раздосадованных ананасиков о том как все хуево. А вообще чем распиаренне контора тем выше конкуренция очевидно. Тот же яндекс с зп ниже рынка тому подтверждение.

638 16 мая, 00:09 638 1400885

Подаюсь на стажировку в php-контору, решил тестовое задание. Прошу вашей помощи, а именно код-ревью хочется. Задача про книги:
>Требуется создать базу данных с книгами на складе книжного магазина и вывести список книг в виде таблицы.
>Для решения этой задачи был подготовлен небольшой скрипт, который создает структуру базы данных.
>Необходимо дописать получение книг из базы и вывод соответствующего списку книг html, используя php и mysql.
>Допускаются любые изменения в скрипте, но не в структуре базы данных, которая задается изначальными запросами.

Комментарии стараюсь не писать принципиально, т.к. считаю меня так научили что код должен быть самоочевиден. Посоветуйте, как сделать код ещё более очевидным, в частности, как можно получше переписать функцию getAuthorNameById. Вообще буду рад любым советам.

bit-ly/2HmT3Gb

Ответы400889401393402303

639 16 мая, 00:18 639 1400889

>>1400885
Я бы тебя не взял и считаю некультурным тебе помогать.
Работодатель должен увидеть твой уровень, а не анонимусов из интернета.

Ответы400892

640 16 мая, 00:19 640 1400891

>>1400346
Недавно говорил на эту тему с HR-ом с опытом работы 20+ лет. По её словам -- люди просто боятся писать письма. Дело не в их статусе или в чём-то ещё, просто так исторически сложилось, что в лицо тебе могут сказать что угодно, а по мылу почему-то боятся. Просто вот культура такая у людей, боятся они, что их захуесосят.
От неё же получил лайфхак такой: если пишешь письмо, на которое могут дать отказ или вообще проигнорировать, можно писать что-то вроде "Буду вам признателен, если вы сообщите любое ваше решение". Суть короче в том, чтобы показать людям, что ты не боишься получить отказ, тогда они может даже проявят интерес. Ну или как минимум не проигнорят.

641 16 мая, 00:21 641 1400892

>>1400889
А я вот думаю, что код-ревью -- это здорово, и неважно, от кого он получен, от двачера или от коллеги на месте работы. Я же не прошу решить за меня задачу, я просто прошу прочитать мой код и высказать своё мнение относительно стиля. Что в этом плохого?

Ответы400897400901402303

642 16 мая, 00:32 642 1400897

>>1400892
Сначала отправь это работодателю, затем приходи за ревью.

643 16 мая, 00:36 643 1400901

>>1400892
Впрочем, могу только сказать, что код плохой, уровня начинающего джуниора, над которым нужно будет ставить няньку-учителя, а не тимлидера.
Поэтому, повторюсь, не взял бы. На данном уровне не тебе надо платить зарплату, а ты должен платить за знания. Либо учиться сам.

Ответы400910400915

644 16 мая, 01:02 644 1400910

>>1400901
>код плохой
Что именно не так? Что выдаёт во мне джуна, который сел учить пхп 2 недели назад? Если что, мой код в отдельном блоке на строках 65-95, всё остальное уже было.
>нужно будет ставить няньку-учителя
Стажировка конкретно в этой компании вроде как это и подразумевает.

Ответы400911

645 16 мая, 01:10 645 1400911

>>1400910
Хочешь сказать, твой работодатель сам написал среди html-кода echoTableRows($dbh, $booksTableName, $authorsTableName) и сам написал кейворды в SQL маленькими буквами? И при этом копипастом везде всадил хвост с праймари кей, где кейворды написаны нормально капсом? А еще добавил в книги Зеленого слоника.
Тогда ничему хорошему ты там не научишься.

Впрочем, твой код хуже.

Ответы400920401231402303

646 16 мая, 01:17 646 1400915

>>1400901
Его, если судить по тому, что ему выдали, на битрикс или вордпресс поставят - там весь код такой. Он справится. Там даже слабоумный справится.
Самое главное в этой работе - софт скиллы.

Ответы400918400923

647 16 мая, 01:22 647 1400918

>>1400915
Он даже джойнов не знает, не справится.

Ответы400919

648 16 мая, 01:23 648 1400919

>>1400918
В процессе выучит. Это не ядерная физика.

649 16 мая, 01:25 649 1400920

>>1400911
Зелёного слоника я добавил для теста как книгу без автора. А так да, кейворды до 65 строки я не трогал: какие были, такие и есть. Возможно это такая вот подъёбка, которую я должен был исправить.
В любом случае спасибо, ты мне помог. Постараюсь за оставшееся время в остальном разобраться.

Ответы400925

650 16 мая, 01:29 650 1400923

>>1400915
А вот этот ответ меня воодушевляет: на битрикс меня скорее всего посадят, а софт-скиллы у меня есть.

651 16 мая, 01:31 651 1400925

>>1400920
>Возможно это такая вот подъёбка, которую я должен был исправить.
Я бы не стал - нет задачи править чужой скрипт если он нормально работает. Работай только по ТЗ, максимально ёмко и быстро.

И echo убери с глаз долой из функции - пиздец же. Используй фаст эхо, а в самой функции формируй строку для вывода.

Ответы401231

652 16 мая, 16:01 652 1401189

Возник тут вопрос, как в софте организовывать передачу объекта, который во многих глассах должен быть доступен и не надо его инстанциировать каждый раз? Например объект вывода данных. Просто передавать везде по dependency injection? Но тогда придется во всех классах его внедрять. Юзать синглтоны? Получится тесная связь классов, нетестируемость и сложности с расширением софта. Юзать DI container везде, передавая его в классы? Вроде лучше, но не хватает интерфейсов. Хотелось бы какой-то универсальный способ, которым классы могут связываться с одним объектом и при этом юзать что-то вроде интерфейсов, но при этом не возникала тесная связь с самим объектом. Как фреймворки решают подобные проблемы?

Ответы401250401271401307402301

653 16 мая, 16:44 653 1401231

>>1400911
>>1400925
bit-ly/2Q5FWMo
Вот вторая версия: теперь я выучил джойны, убрал всратые конкатенации и зеленого слоника и echo в функциях. Стало хоть немного лучше?

Ответы401244401250401259

654 16 мая, 17:06 654 1401244

>>1401231
Мимо такой же вкатывальщик на связи, мб я и не прав.
У тебя функция перегружена всяким говном, функции и методы должны отвечать за что-то одно, у тебя делает всё и сразу.
В mysql вроде есть функция встроенная if(), чтобы сразу в select определить наличие книг.
Зачем ты вынес html за свой шаблон? Я бы заносил результаты запроса в массив с помощью fetchall в коде логики, а уже в шаблоне итерацией выводил бы все, что надо через <?= ?>

Ответы401250

655 16 мая, 17:17 655 1401250

>>1401189
Н - наследование.
Объяви общего предка, добавь ему эту свою зависимость и просто наследуйся от него остальными - она там уже будет.

>>1401231
Вполне норм, но этот прав >>1401244
У тебя функция и швец и жнец - и в базу ходит, и вывод формирует. Так не стоит делать. Это разные задачи.

Ответы401329402301

656 16 мая, 17:36 656 1401259

>>1401231
Познай сразу альтернативный синтаксис для шаблонов
https://www.php.net/manual/ru/control-structures.alternative-syntax.php
Потом себе спасибо скажешь.

657 16 мая, 17:54 657 1401271

>>1401189
>Просто передавать везде по dependency injection? Но тогда придется во всех классах его внедрять.
Вспомнил тут ещё.
Я как-то фабричным методом делал. Пишешь лоадер для этого дела, который сам уже пихает всё что нужно в конструктор по шаблону. А сами объекты инстанцируешь через него.

658 16 мая, 18:33 658 1401307

>>1401189
>Как фреймворки решают подобные проблемы?
Контейнерами

Ответы401347

659 16 мая, 18:55 659 1401329

>>1401250
>Н - наследование.
>Объяви общего предка, добавь ему эту свою зависимость и просто наследуйся от него остальными - она там уже будет.
Неплохо придумано, но это нарушит single responsibility принцип. Другие классы будут заниматься делами, которые им по роли не положены.

Ответы401337

660 16 мая, 19:05 660 1401337

>>1401329
>Другие классы будут заниматься делами, которые им по роли не положены.
Это какие классы? У тебя классы одного типа имеют одинаковое поведение - заведи им общую абстракцию. Ну или собирай на фабрике. В обоих случая ещё один класс писать.

Ответы401340

661 16 мая, 19:09 661 1401340

>>1401337
Объект не должен заниматься деятельностью, которая по роли ему не положена. Если ты в общего предка суешь метод от класса с другими ролями, это нарушение SRP.

Ответы401345

662 16 мая, 19:21 662 1401345

>>1401340
>Объект не должен заниматься деятельностью, которая по роли ему не положена.
А это и не объект, это абстракция. Абстрактный класс называется.
У него и есть вся деятельность - реализовывать общее поведение для потомков.

>Если ты в общего предка суешь метод от класса с другими ролями
Вот тут поподробнее - боюсь не въехать сразу.

Ответы401348402303

663 16 мая, 19:28 663 1401347

>>1401307
Вообще я подумал о чем-то вроде системы сообщений между объектами. Допустим кладем все объекты разных классов в общий объект-реестр, он регулярно чекает все классы например используя метод getUpdates() который внедрен во все классы через общий интерфейс + трейт. getUpdates() содержит код что-то вроде:
foreach ($this->updates as $update) {
if ($update['type'] == self::OUTPUT_UPDATE)
return $this->factory->getOutputUpdateMessage($update);
}
Фабрика возвращает тогда инстанс \OutputUpdateMessage

Класс Printer, который на всю программу один, тогда будет содержать метод receiveUpdates($message), в котором будет что-то вроде:
if ($message instanceof \OutputUpdateMessage)
{
$this->outputUpdate($message);
}
Получится наши объекты не знают ничего про объект Printer, синглтон тоже не используется, на сообщениях есть интерфейс, т.е. сообщения всегда остаются одними и теми же вне зависимости от особенностей реализации Printer. Минусов пока не вижу, но может кто заметит.

Ответы401349402301

664 16 мая, 19:32 664 1401348

>>1401345
>А это и не объект, это абстракция. Абстрактный класс называется.
Сути не меняет, нарушение SRP есть нарушение SRP, хоть ты его через абстрактный класс запихни, хоть через трейт.

>Вот тут поподробнее - боюсь не въехать сразу.
https://habr.com/ru/company/mailru/blog/412699/
Принципы SOLID посмотри, в частности принцип единой ответственности гласит, что класс не может заниматья левой деятельностью, у него должна быть четко обозначенная роль, в рамках которой он только и функционирует. Если ты через абстрактный класс ему навязываешь действия от другой роли, то это нарушение SRP, и твой код больше не SOLID.

Ответы401355

665 16 мая, 19:33 665 1401349

>>1401347
Алсо, может кто знает, есть ли подобный паттерн? гуглением не нашел

Ответы401355

666 16 мая, 19:41 666 1401355

>>1401348
Зачем ты мне про солид рассказываешь? Ни слова о том, что сам там пилишь не сказал - только про общую инициализацию и всё.
Я похож на телепата?

>>1401349
>гуглением не нашел
Плохо искал.
https://refactoring.guru/ru/design-patterns/observer
В ПХП есть встроенный SplObserver вроде.

Ответы401356401357

667 16 мая, 19:43 667 1401356

>>1401355
>Ни слова о том, что сам там пилишь не сказал - только про общую инициализацию и всё. Я похож на телепата?
Выше написал же, один объект на весь проект, как синглтон, но без использования синглтона и dependency injection. Задача поменьше зависимостей, отсутствие тесной связи между классами и заюзать интерфейсы, чтобы больше гибкость была.

Ответы401358

668 16 мая, 19:44 668 1401357

>>1401355
>https://refactoring.guru/ru/design-patterns/observer
>В ПХП есть встроенный SplObserver вроде.
Спасибо, изучу, вроде что-то похожее.

669 16 мая, 19:47 669 1401358

>>1401356
Что пишешь?

670 16 мая, 20:44 670 1401393

>>1400885
Я сделал тебе кодревью и ты молодец что ты просишь его - так быстрее научишься.
Но твой код очень плох. Я бы не взял тебя на работу даже за бесплатно.
Старайся еще.

Ответы401464

671 16 мая, 22:02 671 1401464

>>1401393
Да, увидел, спасибо. Примерно половина из того, что ты написал, относится к коду, который уже был. Я просто решил его не трогать, как мне выше посоветовали, кроме той части, где TRUNCATE TABLE и auto_increment. Без этого просто работало очень криво и таблицы не джойнились.

Ответы401647

672 17 мая, 07:14 672 1401647

>>1401464
Делай ветки и пуллреквесты, чтобы было понятно куда писать ревью

60 Кб, 500x598
673 17 мая, 19:16 673 1401959

Middleware -что это простым языком и теоритический пример пожалуста.

Ответы401988402300

674 17 мая, 19:53 674 1401973

и можно ли работать без Eloquent?

Ответы402301

272 Кб, 988x627
675 17 мая, 20:07 675 1401988

>>1401959
Я не особо опытный, но после отправки запроса, выполняется мидлвейр, например проверка аутентификации, установка типа запроса ну и подобное, есть же выход в интернеты. Вот тип принцип на картинке => Запрос - обработка мидлвейр (например проверить csrf токен) - выдача кода.

Ответы402000402003

676 17 мая, 20:20 676 1402000

>>1401988
Т.е. мидлвейр это вроде как прослойка между какими-то контрольными точками, которую можно ручками назначать как угодно?

677 17 мая, 20:22 677 1402003

>>1401988
так вроде он контролирует запросы до выполнения осн приложения

678 17 мая, 21:58 678 1402069

Приветствую. У меня такая дилемма: хочу вкатиться в веб, познакомился с html/css, вот щас пытаюсь продвигаться по frontend траектории. Она легче чем backend, но я недавно понял что верстка - это самое стремное занятие, что-то на уровне мытья полов, однообразно и бессмысленно, но при этом чтобы научиться верстать сайты нормально, нужно дохуя практики!
Еще не поздно свернуть на php бекендера. Скажите, какой из двух путей короче по времени, чтобы попасть хоть на какую-то стажировку? Я вот видел несколько вакансий, где кроме php, js и mysql ничего и не нужно. Даже портфолио не надо. А на фронт нужно дохуя всего знать, по сути весь стек, и еще и портфолио обязательно.
Вы скажите, да выбери что больше по душе, а я вот еще не знаю что больше нравится, потому что знаний 0. В общем дайте совет. Хочу уже поскорей заняться чем-то реальным, и чтоб меня заставляли, а самому хуйней маяться справочники листать уже доёбывает потихоньку.

Ответы402101402106402149402300

679 17 мая, 22:27 679 1402101

>>1402069
>ничего не умею
>задрачивать не хочу
>чего хочу сам - не знаю
>хочу побыстрее денег
>там где полегче и нескучно
>и чтобы меня ещё и подгоняли
>дайте совет
Даю: иди нахуй.

Ответы402120

680 17 мая, 22:30 680 1402106

>>1402069
Алсо, там где портфолио не спрашивают - дают тестовое, которое ты не сдашь. Губу закатай, вкатывальщик.

Ответы402126

681 17 мая, 22:45 681 1402120

>>1402101
это не совет

Ответы402124

682 17 мая, 22:49 682 1402124

>>1402120
Вполне совет. Здесь тебе не место - тут начинающие кодеры, которые определились и не ищут халявы. А ты просто очередной вайтишник с нулевым скиллом и хотелками.
Можешь на курсы гикбрейнс ещё сходить - там таких много.

Ответы402129

683 17 мая, 22:52 683 1402126

>>1402106
Да в том то и дело, что тестовые там простые достаточно, мне одно присылали, но мне тогда надо было ехать лечиться, да и я на джаву пробовался. Я точно знаю, что с минимумом знаний на php можно уже какие-то мелочи делать: что-то в базе данных подправить, кнопочку добавить, и тд. А джун фронтендер уже должен быть нихуевым верстальщиком

Ответы402133

684 17 мая, 22:56 684 1402129

>>1402124
нет у меня никаких хотелок, я мечтаю за бесплатно поработать.
Какая нахер халява, о чем ты говоришь? В программировании нигде нет халявы.
То есть единственный совет, который ты мне дал - проебать деньги на курсы, спасибо

Ответы402148

685 17 мая, 23:02 685 1402133

>>1402126
Ты ещё ничего не изучал нормально, но уверенности у тебя больше чем у некоторых синьеров, как я посмотрю.

Ответы402145

686 17 мая, 23:22 686 1402145

>>1402133
Я уверен только в том, что ничего не умею. У меня есть только небольшой бекграунд, который ничего не дает

687 17 мая, 23:25 687 1402148

>>1402129
> я мечтаю за бесплатно поработать
Так работай, кто тебе мешает? Но ты говоришь, что тебя доёбывает этим заниматься. С чего ты взял, что тебя кто-то тащить должен? Заебался в парадной от хтмл и цсс, лол значит не твое. Может нам ИТТ ещё тебя уговаривать начать?
Как ты вообще планируешь этим по 8 часов в день заниматься?

Ответы402171

688 17 мая, 23:26 688 1402149

>>1402069
В вебе всем надо вёрстку и js основы знать, выбери себе задачу и учи то, что поможет ее сделать, у опа посмотри задачи вроде файлообменника.

689 17 мая, 23:49 689 1402171

>>1402148
Меня доебывает делать бессмысленные вещи, не приносящие ни мне денег, ни другим пользы - хотя это и есть тренировка. Вот в вузе я когда проект делал с однокурсником или на летней школе утилиту пилил, мне нравилось, потому что это уже серьезные дела, и у меня неплохо получалось. А учить языки для языков, фреймворки для фреймворков, делать макеты ради делания макетов, наскучивает.
Да, глупая ситуация, просто у меня видимо сейчас очередная просадка мотивации. Сейчас мне нужно определиться, в бекенд идти или фронтенд продолжать, я соберусь с мыслями и продолжу плодотворно учиться

Ответы402216

690 18 мая, 00:41 690 1402216

>>1402171
Делай что по кайфу, хули ты в треде хочешь узнать то? Куда легче вкатиться? Думаю, на завод. Там и вещи полезные, и научат всему. Я вот сам только вкатываюсь, хотя и понимаю что в своем городе/области я работу не найду. Но делаю че по кайфу, рано или поздно дорасту до того уровня крепкого джуна, а там уже работа сама найдется

Ответы402290

691 18 мая, 02:48 691 1402290

>>1402216
Да все, я пришел в себя, понял что бекендеру учить надо раза в 2-3 больше, чем фронтендеру. В связи с этим вопрос: почему тогда они получают одинаково?

Ответы402344

634-691 692 18 мая, 04:16 692 1402300

>>1402069

Верстка это точно не бессмысленное занятие, это часть разработки сайта, и в CSS есть немало интересного. С таким отношением, когда ты не хочешь учиться, а торопишься, ты можешь рассчитывать как раз на "однообразную и бессмысленную" работу, не требующую особых навыков.

Также, в любом случае человеку с нулевым опытом вряд ли поручат что-то сложное и интересное, сначала надо опыт набирать. Не думаю, что тут есть принципиальное различие между фронтендом или бекендом. И там, и там есть вакансии разных уровней сложности.

Ну и я не сказал бы, что HTML/CSS это что-то сложное и требует много времени. Это лишь малая часть того, что надо знать. Не требуется "сделать много макетов", чтобы в этом разобраться. Хватит и одного-двух, но качественно сделанных.

В ОП-посте есть простой набор задач по верстке, заканчивающийся версткой макета, но тебе наверно неинтересно будет их решать.

>>1401959

Middleware - это функция или класс, который "оборачивает" приложение, то есть может что-то сделать с запросом до выполнения прилоежния и что-то сделать с ответом до его отдачи с сервера. Выглядеть оно может так, если сделать в виде функции:

function example_middleware(Request $req, callable $next)
{
// делаем что-то с запросом
// вызываем нижележащий слой приложения
$response = next($req);
// делаем что-то с ответом
return $response;
}

Обычно оно используется, чтобы сделать что-то на уровне HTTP протокола:

- шифрование/расшифровка кук
- защита от CSRF
- авторизация
- сжатие тела HTTP-ответа
- вырезание пробелов из HTML документа
- логгирование

634-691 692 18 мая, 04:16 692 1402300

>>1402069

Верстка это точно не бессмысленное занятие, это часть разработки сайта, и в CSS есть немало интересного. С таким отношением, когда ты не хочешь учиться, а торопишься, ты можешь рассчитывать как раз на "однообразную и бессмысленную" работу, не требующую особых навыков.

Также, в любом случае человеку с нулевым опытом вряд ли поручат что-то сложное и интересное, сначала надо опыт набирать. Не думаю, что тут есть принципиальное различие между фронтендом или бекендом. И там, и там есть вакансии разных уровней сложности.

Ну и я не сказал бы, что HTML/CSS это что-то сложное и требует много времени. Это лишь малая часть того, что надо знать. Не требуется "сделать много макетов", чтобы в этом разобраться. Хватит и одного-двух, но качественно сделанных.

В ОП-посте есть простой набор задач по верстке, заканчивающийся версткой макета, но тебе наверно неинтересно будет их решать.

>>1401959

Middleware - это функция или класс, который "оборачивает" приложение, то есть может что-то сделать с запросом до выполнения прилоежния и что-то сделать с ответом до его отдачи с сервера. Выглядеть оно может так, если сделать в виде функции:

function example_middleware(Request $req, callable $next)
{
// делаем что-то с запросом
// вызываем нижележащий слой приложения
$response = next($req);
// делаем что-то с ответом
return $response;
}

Обычно оно используется, чтобы сделать что-то на уровне HTTP протокола:

- шифрование/расшифровка кук
- защита от CSRF
- авторизация
- сжатие тела HTTP-ответа
- вырезание пробелов из HTML документа
- логгирование

Показать весь текст
Ответы402315402395

693 18 мая, 04:18 693 1402301

>>1401973

Можно попробовать, но сторонние библиотеки и некоторые компоненты все равно будут его использовать.

>>1401189

Для этого есть DI: https://github.com/codedokode/pasta/blob/master/arch/di.md

> Например объект вывода данных.

А зачем тебе везде нужно выводить данные? Если временно для отладки, то проще это делать через echo/var_dump.

> Просто передавать везде по dependency injection?

Да.

> Юзать DI container везде, передавая его в классы?

Это будет не dependency injection. Разберись получше в принципе DI/IoC. Идея в том, что объект получает свои зависимости снаружи, а не ищет их в контейнере.

>>1401250

Это неправильно. Наследование используют для однотипных классов (вроде "Юрлицо" наследует "Субъект"). Нельзя наследовать класс просто ради получения какого-то объекта.

>>1401347

Как в таком коде разбираться? Ты усложняешь архитектуру без причины. Невозможно понять, как передается управление. Надо писать код как можно проще, в стиле:

- сделать одно
- сделать другое
- сделать третье

Тебе лучше задать вопрос, а почему тебе надо что-то выводить из кучи классов. Почему вывод не может делаться в одном месте.

Также, почитай статью про хлеб: https://habr.com/ru/post/153225/

693 18 мая, 04:18 693 1402301

>>1401973

Можно попробовать, но сторонние библиотеки и некоторые компоненты все равно будут его использовать.

>>1401189

Для этого есть DI: https://github.com/codedokode/pasta/blob/master/arch/di.md

> Например объект вывода данных.

А зачем тебе везде нужно выводить данные? Если временно для отладки, то проще это делать через echo/var_dump.

> Просто передавать везде по dependency injection?

Да.

> Юзать DI container везде, передавая его в классы?

Это будет не dependency injection. Разберись получше в принципе DI/IoC. Идея в том, что объект получает свои зависимости снаружи, а не ищет их в контейнере.

>>1401250

Это неправильно. Наследование используют для однотипных классов (вроде "Юрлицо" наследует "Субъект"). Нельзя наследовать класс просто ради получения какого-то объекта.

>>1401347

Как в таком коде разбираться? Ты усложняешь архитектуру без причины. Невозможно понять, как передается управление. Надо писать код как можно проще, в стиле:

- сделать одно
- сделать другое
- сделать третье

Тебе лучше задать вопрос, а почему тебе надо что-то выводить из кучи классов. Почему вывод не может делаться в одном месте.

Также, почитай статью про хлеб: https://habr.com/ru/post/153225/

Показать весь текст
Ответы405448

694 18 мая, 04:20 694 1402303

>>1401345

"Реализовывать общее поведение" - это не четко поставленная задача. Это просто пустые слова.

Это типичная ошибка, когда в приложении все классы наследуются от одного и в него пихают все подряд вместо использования разграничения ответственности.

ну и это неудобно, так как класс X может быть и не использует зависимость Y, но ее придется передать, так как его базовый класс ее требует. Маразм же.

>>1400911

Зачем вы вообще имена таблиц передаете в переменных?

>>1400892

Плохо то, что ты пытаешься решать задачу для проверки твоих знаний коллективно. Если компания нормальная, они тебя все равно раскусят на собеседовании, а если не раскусят - то, видимо, вы друг другу подходите.

>>1400885

> код должен быть самоочевиден

Кроме простейших примеров, так не бывает.

>>1400712

Не знаю, сразу не ответить, а читать лень. Но думаю, что код нельзя просто скопировать, а надо разбираться в устройстве Yii. Также, я не вижу тут никакой защиты, что если злоумышленник этим воспользуется? Что, если в коде уязвимости?

Если ты не разбираешься в Юи, то придется отвлечься на его освоение.

694 18 мая, 04:20 694 1402303

>>1401345

"Реализовывать общее поведение" - это не четко поставленная задача. Это просто пустые слова.

Это типичная ошибка, когда в приложении все классы наследуются от одного и в него пихают все подряд вместо использования разграничения ответственности.

ну и это неудобно, так как класс X может быть и не использует зависимость Y, но ее придется передать, так как его базовый класс ее требует. Маразм же.

>>1400911

Зачем вы вообще имена таблиц передаете в переменных?

>>1400892

Плохо то, что ты пытаешься решать задачу для проверки твоих знаний коллективно. Если компания нормальная, они тебя все равно раскусят на собеседовании, а если не раскусят - то, видимо, вы друг другу подходите.

>>1400885

> код должен быть самоочевиден

Кроме простейших примеров, так не бывает.

>>1400712

Не знаю, сразу не ответить, а читать лень. Но думаю, что код нельзя просто скопировать, а надо разбираться в устройстве Yii. Также, я не вижу тут никакой защиты, что если злоумышленник этим воспользуется? Что, если в коде уязвимости?

Если ты не разбираешься в Юи, то придется отвлечься на его освоение.

Показать весь текст
Ответы402346

695 18 мая, 05:32 695 1402315

>>1402300
Интересно-интересно, буду решать!
>Это лишь малая часть того, что надо знать
А разве для стажера - не большая?
Что там еще, научиться хоть как-то применять js, познакомиться с jQuery, js-фреймворком, препроцессором и сборщиком. Все

696 18 мая, 10:32 696 1402344

>>1402290
Хорошему фронтендеру тоже учить нормально придётся.
Вообще не советовал бы вкатываться туда, где легче - хайп пройдёт, а работать надо. Надо туда, где нравится - для этого надо всего понемногу попробовать.

697 18 мая, 10:36 697 1402346

>>1402303
>"Реализовывать общее поведение" - это не четко поставленная задача. Это просто пустые слова.
Википедия с тобой не согласна:
Наследование (англ. inheritance) — концепция объектно-ориентированного программирования, согласно которой абстрактный тип данных может наследовать данные и функциональность некоторого существующего типа, способствуя повторному использованию компонентов программного обеспечения.

К тому же человек просто экспериментирует, что хорошо. Я сам любитель заморочиться на такое.

Ответы402347402835

698 18 мая, 10:38 698 1402347

>>1402346
Хотя я тоже считаю, что у него не правильное архитектурное решение с Обсервером - там обычный Сервис Локатор был бы к месту.

699 18 мая, 13:23 699 1402395

>>1402300
Ой-вей, ОП, а ты ответишь на то, что выше 634 поста?

Ответы402419

700 18 мая, 13:38 700 1402419

>>1402395
А что там?

Ответы402423

701 18 мая, 13:41 701 1402423

>>1402419
Хочу узнать, нормальное ли у меня ООП в >>1394909

702 18 мая, 22:56 702 1402686

Допустим у меня в композере есть скрипт, который выполняется после каждого обновления проекта.

"scripts": {
"post-update-cmd": [
"rm -rf public/bootstrap",
"cp -R vendor/twbs/bootstrap/dist public/bootstrap"
]
}

Как привязать его к установке определенного пакета?

Ответы402834

703 19 мая, 06:51 703 1402834

>>1402686

Вообще, проще оставить все как есть, так как установка делается не так часто. Но если тебе хочется to go deeper ....

В composer на события можно повесить вызов функции или статического метода: https://getcomposer.org/doc/articles/scripts.md#package-events

При этом он получит объект события. Из него как-то можно попробовать выковырять название пакета: https://getcomposer.org/doc/articles/scripts.md#event-classes

Подробности придется искать в коде композера или в Гугле.

Также, хочу заметить, что твои скрипт не кросс-платформенны и работают только под Linux/Mac. Правильнее было бы повесить кроссплатформенный PHP-скрипт.

>>1394909

Ты как-то что-то усложнил. Давай спроектируем все с нуля:

Задача: дать возможность при ошибке поменять реквест и отправить запрос заново. Значит, нужна функция. Она может получать объект ошибки (не ErrorException, который соответствует PHP-ошибке, а например, HttpException) и объект Request. Она может вернуть либо null - не повторять запрос, либо вернуть тот же или модифицированный Request для повтора запроса, либо выбросить какое-то новое исключение:

function handleError(HttpException $e, Request $r): ?Response { ... }

Реализация по умолчанию, естественно, будет возвращать null.

Но тут есть подвох. Что, если мы хотим, например, в ответ на ошибку 503 сделать паузу в 5 секунд и сделать до 3 повторов запроса? Как нам хранить счетчик запросов? В данном случае - хранить его негде (если мы только не предусмотрели это в базовом классе).

Потому можно попробовать другой подход. Делаем переопределяемым сам метод отправки запроса - sendRequest(Request $req): Response. В наследнике просто оборачиваем его:

function sendRequest(...): ...
{
// любой код
parent::sendRequest()
// любой код
}

Это получается более универсальным подходом, как мне кажется.

А еще более универсально будет обернуть выполнение запроса без наследования, обернув вызов метода get().

Также, можно посмотреть на архитектуру питоновской библиотеки urllib, где есть плагины (openers), но она наверно сложновата для твоего случая: https://docs.python.org/3/library/urllib.request.html#module-urllib.request

У тебя в коде ошибки:

- указан слишком общий класс для отлова исключений
- нет реализации по умолчанию

Вообще, подход с оборачиванием проще, чем с обработчиком ошибок, как мне кажется.

703 19 мая, 06:51 703 1402834

>>1402686

Вообще, проще оставить все как есть, так как установка делается не так часто. Но если тебе хочется to go deeper ....

В composer на события можно повесить вызов функции или статического метода: https://getcomposer.org/doc/articles/scripts.md#package-events

При этом он получит объект события. Из него как-то можно попробовать выковырять название пакета: https://getcomposer.org/doc/articles/scripts.md#event-classes

Подробности придется искать в коде композера или в Гугле.

Также, хочу заметить, что твои скрипт не кросс-платформенны и работают только под Linux/Mac. Правильнее было бы повесить кроссплатформенный PHP-скрипт.

>>1394909

Ты как-то что-то усложнил. Давай спроектируем все с нуля:

Задача: дать возможность при ошибке поменять реквест и отправить запрос заново. Значит, нужна функция. Она может получать объект ошибки (не ErrorException, который соответствует PHP-ошибке, а например, HttpException) и объект Request. Она может вернуть либо null - не повторять запрос, либо вернуть тот же или модифицированный Request для повтора запроса, либо выбросить какое-то новое исключение:

function handleError(HttpException $e, Request $r): ?Response { ... }

Реализация по умолчанию, естественно, будет возвращать null.

Но тут есть подвох. Что, если мы хотим, например, в ответ на ошибку 503 сделать паузу в 5 секунд и сделать до 3 повторов запроса? Как нам хранить счетчик запросов? В данном случае - хранить его негде (если мы только не предусмотрели это в базовом классе).

Потому можно попробовать другой подход. Делаем переопределяемым сам метод отправки запроса - sendRequest(Request $req): Response. В наследнике просто оборачиваем его:

function sendRequest(...): ...
{
// любой код
parent::sendRequest()
// любой код
}

Это получается более универсальным подходом, как мне кажется.

А еще более универсально будет обернуть выполнение запроса без наследования, обернув вызов метода get().

Также, можно посмотреть на архитектуру питоновской библиотеки urllib, где есть плагины (openers), но она наверно сложновата для твоего случая: https://docs.python.org/3/library/urllib.request.html#module-urllib.request

У тебя в коде ошибки:

- указан слишком общий класс для отлова исключений
- нет реализации по умолчанию

Вообще, подход с оборачиванием проще, чем с обработчиком ошибок, как мне кажется.

Показать весь текст
Ответы402868

704 19 мая, 06:52 704 1402835

>>1402346

Нет, не согласен. Четко поставленная задача, это:

- базовый класс для любой перемещающейся по карте техники с функционалом: ездить, перевозить вещи или юнитов
- базовый класс для создания элементов форм

Твое же "базовый класс для всего, что мы хотим поместить в несколько классов", "базовый класс для всех классов приложения" - это не четко поставленная задача, и неправильное (имхо) использование наследования. Не нужно делать классы вроде BaseObject. Используй для таких функций, которые надо вызывать во многих местах: utility class, функции, другие классы, трейты.

В помещении функций в базовый класс или трейт вместо выделенного класса есть недостаток: состояние (поля) оказываются раскиданы по куче объектов. В то время, как если мы сделаем выделенный объект, то состояние будет только в нем. Пример: ты хочешь сделать метод для раскраски текста в консоли. Если ты делаешь его через отдельный объект, то ты можешь хранить в нем текущий цвет. В случае трейта или базового класса, поле "цвет" будет существовать в куче экземпляров и у каждого класса будет свой "текущий цвет" и из-за этого могут быть баги.

705 19 мая, 10:21 705 1402868

>>1402834
> скрипт не кросс-платформенны и работают только под Linux/Mac.
Я не автор того скрипта, но не понял зачем давать такой совет. Под виндой бекенд обычно не разрабатывают, во многих компаниях наоборот распространена практика пересаживания всех на мак/убунту, чтобы проекты можно было быстрее поднимать по инструкции. Никогда не видел, чтобы в проекте было несколько параллельных инструкций для разных ОС. Зато часто видел древние проекты, которые не то что на винде запустить нельзя, их нужно запускать только под определённой версией PHP и только под апачем, так как на его rewrite правилах и includ'ах завязан весь код.

Ответы402920405044

706 19 мая, 12:35 706 1402920

>>1402868
> бекенд обычно не разрабатывают
Net Core

707 20 мая, 11:40 707 1403678

А нет ли у кого-нибудь ссылок на годные опенсорс проекты на пыхе? Хочется посмотреть как умные люди код пишут. Только не фреймворки всякие, а вот уже то что на них сделано, конечный продукт, так сказать.

Ответы403698405044

708 20 мая, 12:20 708 1403698

>>1403678
Гитхаб чем тебе не нравится?

Ответы403706

709 20 мая, 12:38 709 1403706

>>1403698
Всем нравится, но может кто-то конкретные ссылки может дать, чтоб не лопатить самостоятельно всё подряд

Ответы403712403716403833

710 20 мая, 12:50 710 1403712

>>1403706
Берёшь, например, любую распротранённую либу, пускай гугл посоветует по твоей теме, идёшь по ссылке и смотришь что там и как.

711 20 мая, 12:53 711 1403716

>>1403706
Можешь тех же студентов от ОПа там погуглить - разные люди пишут с разным уровнем, обычно это заметно.
Ну и вообще лопатить самостоятельно гитхаб - хорошая годная практика.

712 20 мая, 15:57 712 1403833

>>1403706
https://yiipowered.com/ru например вот

9 Кб, 408x288
713 20 мая, 21:57 713 1403996

Аноны, подскажите кто нибудь пожалуйста:
http://jsfiddle.net/xyerd9zt/7/
Почему у меня не работают marign-left/right: 34%-10px;?
Просто 34% работает

Ответы403999405044

714 20 мая, 22:01 714 1403999

>>1403996
margin-left: calc(34% - 10px) попробуй

Ответы404007

715 20 мая, 22:27 715 1404007

>>1403999
работает, спасибо!

716 21 мая, 02:22 716 1404085

Не знаю, насколько понятно объяснил, вот демонстрационный код с комментариями:
http://sandbox.onlinephpfunctions.com/code/b26d6d8d3758ff649f4a41ffd324a7508f383106

Аноны, подскажите пожалуйста, как правильно решить следующую задачу.

Есть класс, который содержит основной публичный метод `me`. Внутри этого метода дёргается несколько сторонних API. Каждый из API может как корректно отработать, так и выдать ошибку. В случае возникновения ошибки этот класс (ну, вернее, его экземпляр) должен сформировать отчёт и отправить его в другой скрипт-логер.

Это самое формирование ошибки вынесено в отдельный метод `ex`. Этот метод, по сути, является методом завершающим выполнение скрипта. То есть, если, например, в `apiOne` произошла ошибка, объект класса `cl` должен сформировать отчёт и прекратить работу не вызывая далее `apiTwo` и т. д.

Собственно, вопрос: каким образом я мог бы это реализовать? Если я сделаю `return` внутри `ex`, то я выйду из `ex`, а метод `me`, соответственно, будет работать дальше. Если я сделаю (exit), то я полностью прибью выполнение скрипта, хотя мне нужно "выйти только из класса cl". Как это сделать?

В голове такие мысли:

Во-первых, конечно же, я могу каждый раз после вызова `$this->ex();` писать `return`, но это не очень удобно, потому что в случае 10 проверок у меня появляется 10 лишних строк.

Во-вторых (на этом варианте я остановился), я могу внутри метода `ex` бросать исключение и, соответственно, вызов основного метода `$obj->me();` оборачивать в `try{}`. Вроде бы всё работает как мне надо: исключение внутри `ex` полностью прибивает дальнейшую работу объекта, но при этом код следующий за `try{}` продолжает работать как мне нужно. Но я не уверен, что с архитектурной точки зрения это адекватное решение.

Ответы404168404172405043

717 21 мая, 11:52 717 1404168

>>1404085
Всё правильно с исключениями. Теперь заведи обработчик ошибок, куда будут сыпаться эти исключения, и который, вместо метода `ex`, будет формировать отчёт об ошибке согласно попавшей ошибке думаю, что не надо обрабатывать ошибки как обычный код - в методах.

Ответы404547

718 21 мая, 11:55 718 1404172

>>1404085
Вот, если что:
https://github.com/codedokode/pasta/blob/master/php/exceptions.md

719 22 мая, 10:35 719 1404547

>>1404168
>Всё правильно с исключениями.
Ого, я не так безнадёжен, спасибо.

> Теперь заведи обработчик ошибок, куда будут сыпаться эти исключения, и который, вместо метода `ex`
Ты, кажется, не совсем верно понял. Там не отчёт об ошибке, а отчёт о работе. Он посылается даже в случае успешного выполнения. Потому что скрипт-логер реагирует не на наличие ошибок, а на отсутствие данных о том, что последний запуск был удачным.

Ответы404549

720 22 мая, 10:37 720 1404549

>>1404547
>В случае возникновения ошибки этот класс (ну, вернее, его экземпляр) должен сформировать отчёт и отправить его в другой скрипт-логер.

А, ну это я хуйню сказал на сонную голову, если точнее.

7 Кб, 546x116
721 22 мая, 14:51 721 1404684

Эй, хакеры.
Есть пикрелейтед.
$_POST['tempname'] = 'qwerty';
$_POST['truename'] = 'sasai.php';

copy() должна скопировать мой текстовый файл как .php файл и после readfile() удалить его.
Я пытаюсь поймать момент копирования файла, чтоб запросить его и выполнить из него код.
Делаю башем в линуксе в 100 параллельных запросов. 100 запросов на пикрелейтед и 100 запросов на /sasai.php (который должен прописать код в новый файл), но новый файл не создаётся.
Размер файла "qwerty" 1 мегабайт. Больше залить нельзя.
Насколько быстро выполняется readfile()?
Или у меня нет шансов?

Ответы405015405043

722 23 мая, 00:49 722 1405015

>>1404684
Херня - файл блокируется для других подключений пока код не отработает.

Ответы405089

723 23 мая, 02:50 723 1405043

>>1404684

Это же жесть, этим кодом можно вообще перезаписать любой файл на сервере, на который хватит прав доступа, в том числе код приложения.

Так как у нас образовательный тред, предлагаю мимопроходящим анонам подумать, какие тут есть уязвимости и как надо переделать код.

>>1404085

Самое простое - вообще не использовать тут исключения, а возвращать false или true:

$result = apiOne();
if ($result == "error") {
$this->logError('api1', ....);
return false;
}

$result = apiTwo();
if ($result == "error") {
$this->logError('api2', ....);
return false;
}

return true;

Минус в том, что вызвыающий код не получает подробности ошибки - а просто false. Соответственно, второй вариант - сделать кастомный класс-исключение, описывающий ошибку и подробности. Его можно использовать и для логгирования, и для возврата:

$result = apiOne();
if ($result == "error") {
$e = new OperationFailedException("api1", подробности);
$this->logError($e);
return $e;
}

Наконец, третий вариант - выбрасывать исключение, просто меняем return на throw:

$result = apiOne();
if ($result == "error") {
$e = new OperationFailedException("api1", подробности);
$this->logError($e);
throw $e;
}

Четвертый вариант - пусть функция работы с API бросает исключение, а мы его ловим и преобразовываем:

try {
$result = apiOne();
} catch (ApiException $inner) {
$e = OperationFailedException::forApiError($inner);
$this->logError($e);
throw $e;
}

Если для разных ошибок нужны разные наборы параметров, то можно сделать в исключении статические конструкторы:

OperationFailedException::forApi1Error(...);
OperationFailedException::forApi2Error(...);

Если тебе надо выполнить функцию и в любом случае послать отчет о работе, то в случае использования кода возврата true/false все очевидно, в случае использования исключений мы можем попробовать ловить вообще все исключения:

try {
$this->doSomething();
} catch (\Throwable $e) {
$this->sendFailedReport($e);
throw $e; // Обязательно прокидываем исключение дальше, чтобы не потерять
}

$this->sendSuccessReport(...);

Минус использования Throwable в том, что отчет будет посылаться вообще при любых ошибках, вроде синтаксической ошибки в коде. Если это не желательно, то Throwable надо заменить на OperationFailedException. Плюс этого в том, что ты всегда знаешь, с каким исключением работаешь, какие в нем есть методы, поля и тд. Ну например, в твоем кастомном исключении может быть записано, на каком шаге произошла ошибка, какой запрос выполнялся, какой ответ получен итд.

Ты пытаешься найти какое-то сложное решение там, где работает простое. Если у тебя в коде 10 блоков if, от добавления 10 return или throw коду хуже не станет. Тут не нужны какие-то паттерны или что-то нестандартное.

Проблемы в твоем коде:

- Если ты ловишь исключения, то надо создавать кастомный класс, а не ловить вообще любые исключения. Кто тебе сказал, что исключения могут бросать только твои функции? Есть исключения от библиотек и фреймворков, есть исключения от самого PHP.

- короткие названия функций

- функция ex() без аргументов, которая каким-то магическим образом должна получать подробности ошибки

723 23 мая, 02:50 723 1405043

>>1404684

Это же жесть, этим кодом можно вообще перезаписать любой файл на сервере, на который хватит прав доступа, в том числе код приложения.

Так как у нас образовательный тред, предлагаю мимопроходящим анонам подумать, какие тут есть уязвимости и как надо переделать код.

>>1404085

Самое простое - вообще не использовать тут исключения, а возвращать false или true:

$result = apiOne();
if ($result == "error") {
$this->logError('api1', ....);
return false;
}

$result = apiTwo();
if ($result == "error") {
$this->logError('api2', ....);
return false;
}

return true;

Минус в том, что вызвыающий код не получает подробности ошибки - а просто false. Соответственно, второй вариант - сделать кастомный класс-исключение, описывающий ошибку и подробности. Его можно использовать и для логгирования, и для возврата:

$result = apiOne();
if ($result == "error") {
$e = new OperationFailedException("api1", подробности);
$this->logError($e);
return $e;
}

Наконец, третий вариант - выбрасывать исключение, просто меняем return на throw:

$result = apiOne();
if ($result == "error") {
$e = new OperationFailedException("api1", подробности);
$this->logError($e);
throw $e;
}

Четвертый вариант - пусть функция работы с API бросает исключение, а мы его ловим и преобразовываем:

try {
$result = apiOne();
} catch (ApiException $inner) {
$e = OperationFailedException::forApiError($inner);
$this->logError($e);
throw $e;
}

Если для разных ошибок нужны разные наборы параметров, то можно сделать в исключении статические конструкторы:

OperationFailedException::forApi1Error(...);
OperationFailedException::forApi2Error(...);

Если тебе надо выполнить функцию и в любом случае послать отчет о работе, то в случае использования кода возврата true/false все очевидно, в случае использования исключений мы можем попробовать ловить вообще все исключения:

try {
$this->doSomething();
} catch (\Throwable $e) {
$this->sendFailedReport($e);
throw $e; // Обязательно прокидываем исключение дальше, чтобы не потерять
}

$this->sendSuccessReport(...);

Минус использования Throwable в том, что отчет будет посылаться вообще при любых ошибках, вроде синтаксической ошибки в коде. Если это не желательно, то Throwable надо заменить на OperationFailedException. Плюс этого в том, что ты всегда знаешь, с каким исключением работаешь, какие в нем есть методы, поля и тд. Ну например, в твоем кастомном исключении может быть записано, на каком шаге произошла ошибка, какой запрос выполнялся, какой ответ получен итд.

Ты пытаешься найти какое-то сложное решение там, где работает простое. Если у тебя в коде 10 блоков if, от добавления 10 return или throw коду хуже не станет. Тут не нужны какие-то паттерны или что-то нестандартное.

Проблемы в твоем коде:

- Если ты ловишь исключения, то надо создавать кастомный класс, а не ловить вообще любые исключения. Кто тебе сказал, что исключения могут бросать только твои функции? Есть исключения от библиотек и фреймворков, есть исключения от самого PHP.

- короткие названия функций

- функция ex() без аргументов, которая каким-то магическим образом должна получать подробности ошибки

Показать весь текст
Ответы405089

724 23 мая, 02:52 724 1405044

>>1403996

Ты ищешь сложное решение вместо простого. В случае использования элемента display: block и задания ему ширины, маргины вычисляются автоматически. Достаточно задать левый маргин, ширину и поставить auto для правого маргина.

Как плюс, это работает вообще во всех браузерах, в отличие от calc(), который пришел только с CSS3 и внедрен с ~2013 года: https://caniuse.com/#feat=calc

Обрати также внимание, что в части старых бразеров calc доступен только с вендорным префиксом. Изучи эту тему, и добавь нужные префиксы, если ты хочешь использовать calc(). Также, добавь в закладки или запомни сайт caniuse, он наверняка еще пригодится.

В CSS полезно знать, как работают значения по умолчанию, чтобы меньше писать кода и меньше менять при правках.

>>1403678

Вообще, я бы советовал просто прочитать цикл статей "создаем приложение на фреймворке X". Вот, например, например, первый попавшийся туториал по Symfony: https://auth0.com/blog/symfony-tutorial-building-a-blog-part-1/

А так, пожалуйста, сложное облачное хранилище файлов nextcloud: https://github.com/nextcloud/server

CMS Интернет-магазина Magento: https://github.com/magento/magento2

>>1402868

Я довольно долгое время под виндой работал, PHP и Апач там вполне работают.

На винду поставить несколько версий PHP проще простого - скачиваем zip-архивы и распаковываем в разные папки. А под линукс? Либо заморачиваться со сторонними репозиториями, которые перезапишут тебе libssl, либо использовать работающие с переменныем успехом скрипты вроде phpenv.

725 23 мая, 09:22 725 1405089

>>1405015
Ну йобана.
>>1405043
>Это же жесть, этим кодом можно вообще перезаписать любой файл на сервере
Ещё и читать.
$_POST['truename'] = '../index.php'; и он его выдал, но не перезаписал. Видимо прав нет.
А в config.php пароль от базы у него "1". Но 3306 закрыт от мира и пхпмуадмина нет.
Ну и ладно.

12 Кб, 180x280
726 23 мая, 15:33 726 1405188

Тут кто-нибудь пробовал подружить сфинкс с постгрескьюэль?
Не покажите, как конфиг выглядит и как сфинкс вообще юзать в контексте постгреса?

Ответы405476406600

727 23 мая, 16:28 727 1405244

Сап, аноны, дайте подсказку.
Есть ДБ с тремя таблицами: "Юзеры", "Фильмы", "ЮзерыФильмы".
В таблице "ЮзерыФильмы" очевидно идет айди Юзера и Фильма, а также оценка.
В таблице "Фильмы" есть столбец с инфой "Средняя оценка", как мне таскать инфу для этой средней оценки?
Мониторить каждое изменение "ЮзерыФильмы" и апдейтить столбец "Средняя оценка"? Или есть более умные возможности?
П.С, пишу в Ларавеле если это вообще имеет смысл.

Ответы406548

728 23 мая, 23:26 728 1405448

>>1402301
Спасибо, хорошо объяснил. Про хлеб тоже понятно, что лучше проще архитектуру держать, чем сложнее. Меня в dependency injection смущает, что кучу классов надо в конструктор передавать, а если таких классов по всему проекту много, куда кучу других передавать, то конструкторы сильно заросшие получаются, и сложно потом что-то менять. Может это вопрос неправильной архитектуры, но когда классы начинаешь на роли делить, а не все подряд в пару god классов пихать, то выходит очень много всего по DI передавать становится.

Ответы406548

729 24 мая, 00:27 729 1405476

>>1405188
Подружил, отбой вопроса.

Бот Кoльчyгинa !lnkYxlAbaw 730 24 мая, 02:20 730 1405492

Дали странную задачу. Имитировать работу require_once используя require и возможности констант класса. Вроде просто — нужно проверять константу на отсутствие, ибо если её нет, то реквайр можно вставить, но если она есть, то нет. Однако предполагается, что этот самый require на один и тот же файл может быть вписан в код хоть 500 раз и каким образом сделать такую проверку на лету? Это на РНР вообще возможно, он же интерпретируемый?

Ответы405493

731 24 мая, 02:26 731 1405493

>>1405492
Допускаю, что знаю хуёво логику работы этих языковых конструкций и возможно ответ скрыт на поверхности, но я всё равно не понимаю как можно залочить команду по условию.

Ответы405494

732 24 мая, 02:32 732 1405494

>>1405493
Хмм... А если ебануть проверку условия существования константы прямо в файле класса.

Ответы405496

733 24 мая, 02:34 733 1405495

Как передавать класс пагинатор в тот же контроллер? По IoC - в конструктор\метод или уже внутри создавать, нарушая принципы?
Ну и вообще про такие вот утилитарные классы вопрос.

Ответы406547

734 24 мая, 02:35 734 1405496

>>1405494
Синглтон штоле?

Ответы405497406547

735 24 мая, 02:38 735 1405497

>>1405496
Похоже на то.

Ответы405498405501

736 24 мая, 02:42 736 1405498

>>1405497
Сомневаюсь что так надо - при синглтоне у тебя только один экземпляр класса, тогда как require_once просто подключает файл один раз, а вот количество объектов может быть любое.

Ответы405500

44 Кб, 871x125
737 24 мая, 02:43 737 1405500

>>1405498
Я хуй знает про логику на этом фоне.

Ответы405502406547

738 24 мая, 02:44 738 1405501

>>1405497
Я придумал: заведи себе массив подключенных файлов и при очередном запросе на подключение проверяй сперва этот массив.

Ответы405502

739 24 мая, 02:45 739 1405502

>>1405501
>>1405500
Только эту хуйню. То есть requre и константы класса.

Ответы405505

76 Кб, 918x622
740 24 мая, 02:48 740 1405503

Эх, не работает.

Ответы405504405722

741 24 мая, 02:49 741 1405504

>>1405503
А всё, заработало. Скобку забыл.

742 24 мая, 02:51 742 1405505

>>1405502
Ну попробуй что-то вроде define(ClassName::class, $путь к файлу) и проверяй эту константу перед подключением.

Ответы405506

743 24 мая, 02:52 743 1405506

>>1405505
Я это и сделол.

744 24 мая, 13:46 744 1405678

Посоны, вот это говно по зависимостям не читайте:
https://designpatternsphp.readthedocs.io/ru/latest/Structural/DependencyInjection/README.html
Там левая параша, которая к DI не имеет отношения почти полностью, кроме первого и второго абзаца. UML-диаграмма вообще какая-то левая - про конфиг и ДБ. Надо с контейнера начинать показывать, а они куда-то в кусты полезли.
По факту там просто показывается как передавать класс в конструктор через параметры какая великая наука. Тупее объяснения я ещё не видел, а поначалу вообще не врубался в то, о чём они там говорят.

Ответы406547

745 24 мая, 14:50 745 1405722

>>1405503
МОжет кто пояснить насколько это тупо?

Ответы405877

746 24 мая, 20:10 746 1405877

>>1405722
Нахуя ты паришься? Реквайр уанс подключит файл только единожды, то есть встретив инструкцию подключить тот же файл, то скрипт упадет. Сделай счетчик, который выкинет ошибку при повторном подключении файла, и все.

Ответы405930406427

747 24 мая, 21:51 747 1405930

>>1405877
>то есть встретив инструкцию подключить тот же файл, то скрипт упадет.
Щито? Документацию пускай дураки читают?
Ничего там не упадёт.

748 25 мая, 20:50 748 1406427

>>1405877
Ну дык я сделал таким образом, что скрипт прогоняет простое условие при каждом добавлении файла. Допускаю, что это тяжеловато, но вроде работает.

705-748 749 26 мая, 06:17 749 1406547

>>1405678

Вообще, DI контейнер это исключительно вспомогательная вещь, для удобства, и сам принцип DI не требует его наличия, а лишь говорит о том, что зависимости передаются снаружи. Принцип DI подробно описан в моем уроке: https://github.com/codedokode/pasta/blob/master/arch/di.md

>>1405500

Задача плохо сформулирована. Например, не очень понятно, что тут можно менять, а что нельзя.

>>1405496

Это не синглтон. Синглтон - это когда нельзя создать более 1 объекта какого-то класса.

>>1405495

Необязательно все передавать снаружи. Обычно снаружи передаются сервисы - классы, которые, как правило, существуют в одном экземпляре и не имеют состояния и параметры конфигурации. И, как правило, кроме как снаружи, взять их неоткуда, потому вариантов, кроме DI, нету.

Но это не значит, что твой класс не может сам создавать объекты. Конечно, может. Например, если твой класс работает с БД, то он вполне может создавать и возвращать объекты, соответствующие записям в БД.

Если пагинатор не имеет зависимостей, то можно просто создать его внутри контроллера. Если же у пагинатора есть зависимости (что вызывает вопросы к архитектуре), то есть такие варианты:

- внедрить зависимости в контроллер, а он их передаст пагинатору
- сделать фабрику, которая умеет создавать пагинаторы, и внедрить фабрику в контроллер. Переусложняем код на ровном месте.

750 26 мая, 06:19 750 1406548

>>1405448

Указание зависимостей в конструкторе это скорее плюс, так как зависимости явно видны и описаны. Не надо искать по всему телу класса, что ему нужно для работы.

Если зависимостей очень много, то это вызывает вопрос к архитектуре: а не создаешь ли ты God Object, который нарушает принцип единой ответственности? Обычно зависимостей не так много, порядка 3-6.

Ну и такие классы обычно никто руками не создает, используют DI контейнер, и получают объекты из него:

$auth = $container->get(AuthManager::class);

>>1405244

Да, либо обновлять при любом добавлении оценки, либо не хранить в БД и вычислять при обращении (может быть медленно).

>>1399337

Они настраиваются в конфиге PHP с названием php.ini (параметр display_errors) или в конфиге php-fpm, если ты его используешь: https://www.php.net/manual/ru/install.fpm.configuration.php

Не включай отображение ошибок на продакшене.

Для постоянного просмотра лога ошибок можно просто использовать команду tail -f в консоли.

751 26 мая, 11:32 751 1406600

>>1405188
Анша пхп!

752 26 мая, 20:42 752 1407003

Подскажите пожалуйста, как можно сделать кнопки сортировки по заголовкам таблицы?

Ответы407083407087411154

753 26 мая, 22:56 753 1407083

>>1407003
В гет-параметры ставишь сортировку, на странице таблицы получаешь эту сортировку, подставляешь в SQL-запрос и отправляешь в базу.
Посмотри как у других сделано - на гитхабе набери student-list, там выдаст с десяток разных. Вообще подглядывать тут не стыдно.

Ответы407119

754 26 мая, 23:08 754 1407087

>>1407003
Ссылкой.

Ответы407119

755 27 мая, 00:37 755 1407119

>>1407083
>>1407087
Простите, я плохо выразил свои мысли. У меня в основном проблемы с версткой. У меня в основном проблема с версткой. Мне заголовки в кнопки поместить? гуглил, там примеры с radio, я думаю сделать submit для каждого заголовка, но ощущение что это совсем не правильно будет. Я, кстати, с post делаю. Страницы и поиск сделал уже, осталась сортировка.

Ответы407133407311

756 27 мая, 01:17 756 1407133

>>1407119
Я просто заголовки таблицы делал ссылками с параметрами, ссылки эти функцией создаются, чтобы в шаблоне логики не было, параметры такие; по какому столбцу сортирую и в каком порядке, если не выбран никакой или выбран другой заголовок, то asc, если этот выбран был уже, то desc. Ну и поиск текущий тоже в параметры надо вставить, чтобы сортировка не дропалась.

Ответы407312

757 27 мая, 11:56 757 1407258

Где перекат, ленивые задницы?

758 27 мая, 13:44 758 1407311

>>1407119
>проблемы с версткой
Тогда вёрстку подтягивай. Неправильно лепить велосипеды там, где что-то не умеешь - надо значит учиться. Да и работать ты не сможешь, не зная азов. Ни спарсить ничего, ни сайт подправить.

>я думаю сделать submit для каждого заголовка, но ощущение что это совсем не правильно будет
Вообще не правильно. В таблице данные у тебя запрашиваются, просто в определённом порядке, а это именно GET-параметры. POST данные отдаёт на запись в базу например, а не запрашивает. Это вроде как SELECT и UPDATE в SQL. Желательно разделять и понимать эти вещи.

Ответы407629

759 27 мая, 13:47 759 1407312

>>1407133
>чтобы в шаблоне логики не было
Она там должна быть. Просто надо разделять на логику получения данных и логику их отображения. В обоих случаях она присутствует, но выполняет сугубо конкретные цели.

Ответы407336

760 27 мая, 14:30 760 1407336

>>1407312
Это и имелось ввиду.

761 27 мая, 22:07 761 1407629

>>1407311
>Вообще не правильно. В таблице данные у тебя запрашиваются, просто в определённом порядке, а это именно GET-параметры.
Тогда ссылки будут некрасивыми. Неужели даже если с POST сделаю - будет не правильно?

Ответы407708407807408166

762 28 мая, 01:45 762 1407708

>>1407629
Что значит некрасивые? Эта ссылка представляет состояние твоего приложения в одну единицу времени, иначе пропадает вообще смысл в ссылках. Ты её можешь скопировать и кому-то отправить, этот кто-то её откроет и увидит тоже что и ты, если конечно состояние не поменялось. В гет запросе тоже можно параметры в теле отправлять, но зачем? Если тебя смущают квери параметры то можешь яндекс браузер скачать, он отрезает весь текст в урле после ? пока на него мышкой не нажмешь для выделения

Ответы407807407974

763 28 мая, 10:18 763 1407807

>>1407629
>ссылки будут некрасивыми
Кто на них вообще смотрит? Ты лучше код внутри приложения красиво сделай, а не ссылки.

>>1407708
Двачую.
Не думал о ссылках как о глобальном сохраняемом состоянии приложения - интересная мысль.

395 Кб, 1037x1319
flock 764 28 мая, 11:45 764 1407842

Лочу и пишу в файл так:
$f = fopen('file.txt', 'cb');
flock($f, LOCK_EX|LOCK_NB);
ftruncate($f, 0);
fwrite($f, 'lalala');

далее скрипт продолжает работать, а в это время, читаю содержимое файла из другого скрипта:

$t = file_get_contents('file.txt');

В итоге, в переменной $t - пустая строка, хотя если открыть файл блокнотом, то в нем имеется запись. При этом проблема эта возникает только на винде, в линупсе работает как положено. почему так? Пробовал открывать на чтение fopen() и читать через fread() - та же история

Ответы408140408169408175

765 28 мая, 13:57 765 1407914

Опушка, добрый день! Занимаюсь по твоим урок уж который месяц, впервые решил поделиться. Уроки крутые.
Глянь пожалуйста задачку про ООО Вектор (до антикризисных),
что думаешь?
https://github.com/superhorsy/share/blob/master/oop_vector2.php

Ответы408554411152

766 28 мая, 15:27 766 1407974

>>1407708
> состояние твоего приложения в одну единицу времени
Не подумал об этом, спасибо.

767 28 мая, 19:17 767 1408140

>>1407842
Попробуй после записи
https://www.php.net/manual/ru/function.fflush.php
А так хуй знает.

Ответы408153

768 28 мая, 19:41 768 1408153

>>1408140
Не помогло

769 28 мая, 19:53 769 1408166

>>1407629

А ты вообще понимаешь, чем POST отличается от GET? Формально методы определены в одном из RFC: https://tools.ietf.org/html/rfc7231#section-4

> The GET method requests transfer of a current selected representation for the target resource. GET is the primary mechanism of information retrieval and the focus of almost all performance optimizations.
Hence, when people speak of retrieving some identifiable information via HTTP, they are generally referring to making a GET request.

> The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics.

Обычно GET используется для получения каких-то данных, а POST - для сохранения каких-то изменений на сервер. Очевидно, что для получения списка логичнее всего использовать именно GET. Например:

/students?search=Ivan&sort=-name&page=2

Я не очень понимаю, зачем тут POST вообще. Если ты хочешь использовать форму, то формы можно отправлять методом GET.

Как написали выше, GET имеет другие преимущества:

- возможность сохранить или переслать ссылку на результат
- возможность перемещаться назад/вперед по истории
- возможность кешировать ответ (тут, впрочем, это вряд ли нужно)

Обычно сортировку просто делают через ссылки в заголовке. Но, конечно, возможны другие варианты, например:

- яваскрипт перехватывает клик по заголовку и формирует ссылку нужного вида (минус: у обычных ссылок есть опции вроде "открыть в новой вкладке", "скопировать ссылку", а у кнопки - нет)
- яваскрипт перехватывает клик по заголовку, аяксом запрашивает данные и вставляет на страницу без перезагрузки. Минус - перестают работать многие из возможностей выше.
- использовать традиционные ссылки, сохраняя все их преимущества, но добавить библиотеку pajax, которая позволит подгружать данные аяксом

770 28 мая, 20:00 770 1408169

>>1407842

По идее ты должен сделать fclose() или хотя бы fflush(), чтобы сбросить изменения в файл. До fclose данные могут быть где-то в буфере внутри PHP или в буфере ОС.

Также, обрати внимание на мануал: https://www.php.net/manual/ru/function.flock.php

> PHP поддерживает портируемый способ консультативной блокировки (advisory locking) полностью всего файла (что означает, что все программы, осуществляющие доступ к файлу, должны использовать один и тот же способ блокировки, иначе блокировка не будет работать).

Я думаю, что ты должен при чтении также использовать flock(). Так как это добровольная (advisory), а не принудительная (mandatory) блокировка.

Также, если ты используешь LOCK_NB, то ты должен проверять, что блокировка получена, смотря на результат flock(). Для начала прочитай мануал и посмотри примеры кода в нем.

У file_get_contents, кстати, тоже есть флаги для блокировки.

Ответы408216

771 28 мая, 20:06 771 1408175

>>1407842

Ну и если у тебя есть конкретные вопросы по блокировкам, работе с файлами, не описанные в мануале, то тоже можешь задавать, так как возможно ты не очень понял, как оно все работает.

772 28 мая, 20:52 772 1408216

>>1408169
мне надо чтобы файл был залочен, в то время как я ег очитаю дургим скриптом. Т.е. заюзать fclose - нельзя.

fflush() не помогает.

Пробовал открывать по всякому, включая все способы что ты перечислил - не работает.

Пробовал в первом скрипте, псоле записи сделать fclose, а потом опять залочить - всеравно читет как пустую строку, до тех пор пока я не убью первый скрипт (или он сам не завершится)

Ответы408971

773 28 мая, 21:01 773 1408224

56 Кб, 1001x41710 Кб, 685x188

Всем привет. Делаю файлообменник и когда доходит до скачивания, то скачивается файл размером с 60-80 байт вместо 80кб к примеру. На первом скрине функция скачивания файла, что передается туда на втором скрине. Где я мог накосячить?

Ответы408244411154

774 28 мая, 21:21 774 1408244

>>1408224
какой убогий синтаксис

Ответы408250

775 28 мая, 21:25 775 1408250

>>1408244
Синтаксис то нормальный, только ничего не понятно что там происходит.
Да и вообще если он такой код написал, мог бы уже и сам разобраться что там на самом деле клиенту отправляется и где ошибка.
Ходит хвастается как он в ООП умеет.

Ответы408253408416410656411154

776 28 мая, 21:30 776 1408253

>>1408250
Не хвастаюсь, я очень много кода скопировал у кого-то кто это сделал и пытаюсь его разобрать.

Ответы408270

777 28 мая, 21:41 777 1408270

>>1408253
Ну йобана, ты текстовиком хоть файл скачанный открывал? Наверняка там ошибка лежит.

Ответы408274

778 28 мая, 21:46 778 1408274

>>1408270
Открыл блокнотом, там только путь до файла на локалке

Ответы408276408279

779 28 мая, 21:49 779 1408276

>>1408274
Ну. А должен быть сам файл.
Значит вместо echo $file; делай readfile($file);

780 28 мая, 21:54 780 1408279

>>1408274
Кажись понял.
В 7й строке вместо
->write($file->path_to_file)
делай
->write(file_get_contents($file->path_to_file))

Ответы408282

781 28 мая, 21:57 781 1408282

>>1408279
Помогло, спасибо большое!

782 29 мая, 01:19 782 1408416

>>1408250
>ничего не понятно что там происходит
$файл = получитьИлиОбломаться(бла-бла);

если (в апаче НЕ установлен мод для отсылки файлов)
{
$ответ = $ответ->добавитьЗаголовок(бла-бла, инфа-по-файлу)
->добавитьЗаголовок(бла-бла, инфа-по-файлу)
->добавитьЗаголовок(бла-бла, инфа-по-файлу)
->контентНаВыдачу($файл->путь)
}
иначе
{
$ответ = $ответ->добавитьЗаголовок(натравили мод на файл, инфа-по-файлу)
->добавитьЗаголовок(бла-бла, инфа-по-файлу)
->добавитьЗаголовок(бла-бла, инфа-по-файлу)
}
сделано на цепочках

$файл->сохранить(); нафига?
вернуть $ответ

ООП код гораздо легче процедурной лапши обычно читается.

783 29 мая, 10:13 783 1408552

Онтоны, есть у меня phpStorm и есть у меня развернутый проект на тестовом сервере. Я могу как-то подключить шторм к файлам на сервере, сразу увидеть в шторме структуру каталогов проекта и в реалтайме редактировать файлы, которые мне нужно отредактировать?

Ответы408553

784 29 мая, 10:16 784 1408553

>>1408552
Вот я долбоеб! Даже шторм предлагает сделать так.
Жаль только нет просто SSH/SPC
Может есть плагин? Лень поднимать SFTP на сервере

Ответы408621

785 29 мая, 10:17 785 1408554

>>1407914
Посоны, посмотрите пожалуйста кто нибудь, очень интересно мнение

Ответы411152

786 29 мая, 12:39 786 1408621

>>1408553

А там разве нет SCP, SFTP или чего-то похожего? Он через SSH работает.

787 30 мая, 02:03 787 1408971

>>1408216

Ты проверяешь, что возвращает flock()? Так как ты не написал об этом в своем посте, потому я предполагаю, что не проверяешь. Покажи текущую версию кода на всякий случай, и проверь, что в ней учтено то, что написано в мануале.

Ответы409026

788 30 мая, 08:40 788 1409026

>>1408971
Вопрос снят.
На винде нельзя блокировать тем типом блокировки, который происходит в линуксе (названий не помню).

На винде файл лочится таким образом, что его невозможно читать. Вся магия винды заключается в том, что файл всетаки читается дефолтным блокнотом (почему так - никто не знает), однако никакими другими средтвами его прочитать нельзя, включа коммандную строку, саблайм, даже браузер.

Ответы409168

789 30 мая, 09:04 789 1409035

Здесь можно найти людей для конфы вк для пхп мидлов, что стремятся стать сеньерами? ) https://vk.com/phpquestion

790 30 мая, 13:52 790 1409168

>>1409026

> Вся магия винды заключается в том, что файл всетаки читается дефолтным блокнотом (почему так - никто не знает),

Может, блокнот просто игнорирует ошибку доступа к файлу и притворяется, что все ок?

То есть, получается в итоге, что flock() работает, как описано в документации? Там упомянуто про использование принудительной блокировки на винде.

Ответы409217

791 30 мая, 14:39 791 1409217

>>1409168
Я не шибко знаком с возможными блокировками. но как я понял, если 2 типа:
1. Лочится так, что читать нельзя;
2. Лочится так, что читать можно.

По дефолту в линуксе используется второй способ, а на винде так сделать невозможно, поэтому используется первый

Ответы409221409222

792 30 мая, 14:42 792 1409221

>>1409217
есть 2 типа
фикс

793 30 мая, 14:42 793 1409222

>>1409217

Да, блокировки бывают разные: shared (на чтение, другие могут читать, но не могут писать) и exclusive (владелец может читать и писать, другие ничего не могут).

Но это тут, я думаю, не при чем. Просто в Линукс это реализовано как добровольная блокировка, то есть ты перед обращением к файлу сам должен убедиться, что он не заблокирован.

794 1 июня, 12:39 794 1410233

200 Кб, 1904x70481 Кб, 1788x934

Как же у меня бомбит.
Начал осваивать ларавел.
Сконфигурировал Ларавел, Композер, Вагрант, Хомстед, SQL.
Вчера всё работало норм.
Сегодня первый пик при запуске сайта через Хомстед.
При том что через php artisan serve - 127.0.0.1:8000 всё работает нормально.
Начал разбираться - проблема не гуглится.
Продолжил разбираться, пик2.
Даже артисан в хомстеде ругается на loadconfiguration.php
Начал смотреть туда.
protected function loadConfigurationFiles(Application $app, RepositoryContract $repository) не получает список php файлов, проблема в getConfigurationFiles.
Смотрю getConfigurationFiles. Finder::create()->files()->name('*.php')->in($configPath) не находит файлы.

$files11 = scandir('/home/vagrant/code');
Находит всё что нужно

$finder2->in('/home');
находит 2 папки.
-home/vagrant/code
-home/vagrant

$finder2->in('/home/vagrant');
находит 1 папку
- /home/vagrant/code

Пробую написать с нуля.
$finder2 = new Finder();
$finder2->in('/home/vagrant/code');
находит нихуя

Что делать то?

794 1 июня, 12:39 794 1410233

200 Кб, 1904x70481 Кб, 1788x934

Как же у меня бомбит.
Начал осваивать ларавел.
Сконфигурировал Ларавел, Композер, Вагрант, Хомстед, SQL.
Вчера всё работало норм.
Сегодня первый пик при запуске сайта через Хомстед.
При том что через php artisan serve - 127.0.0.1:8000 всё работает нормально.
Начал разбираться - проблема не гуглится.
Продолжил разбираться, пик2.
Даже артисан в хомстеде ругается на loadconfiguration.php
Начал смотреть туда.
protected function loadConfigurationFiles(Application $app, RepositoryContract $repository) не получает список php файлов, проблема в getConfigurationFiles.
Смотрю getConfigurationFiles. Finder::create()->files()->name('*.php')->in($configPath) не находит файлы.

$files11 = scandir('/home/vagrant/code');
Находит всё что нужно

$finder2->in('/home');
находит 2 папки.
-home/vagrant/code
-home/vagrant

$finder2->in('/home/vagrant');
находит 1 папку
- /home/vagrant/code

Пробую написать с нуля.
$finder2 = new Finder();
$finder2->in('/home/vagrant/code');
находит нихуя

Что делать то?

Показать весь текст
Ответы410442

795 1 июня, 20:00 795 1410442

>>1410233

> Смотрю getConfigurationFiles. Finder::create()->files()->name('*.php')->in($configPath) не находит файлы.

А ты сдампил, что там передается в $configPath? Может там путь не тот?

Также, ты можешь проверить наличие файлов командой вроде

ls -la /home/vagrant/code/

в консоли, в которой ты логинишься через ssh.

Также, ты не написал, как у тебя сделан маппинг файлов с хоста в виртуальную машину. Ты показываешь скриншот Far на твоем хосте, но Ларавель работает в виртуальной машине и возможно в ней этих файлов нет (что я тебе и предлагаю проверить с помощью команды ls).

Информация о команде: https://pingvinus.ru/note/cmd-ls

Также, увидеть текущий каталог в линуксе можно командой pwd.

Урок по командной строке: https://github.com/codedokode/pasta/blob/master/soft/cli.md

Ответы410465

796 1 июня, 20:45 796 1410465

>>1410442
>А ты сдампил, что там передается в $configPath? Может там путь не тот?
Сдампил ессно, путь корректен.

>ls -la /home/vagrant/code/
Тоже делал, файлы в наличии, ls -a в консоли и scandir('/home/vagrant/code') в коде их показывают.

>маппинг файлов с хоста в виртуальную машину
В конфиге homestead
folders:
- map: C:/Users/SRG/qwe (папка тестового проекта)
to: /home/vagrant/code

Проблема появилась после перезагрузки, до этого всё работало нормально. php artisan serve на хосте, а не в виртуалке отрабатывает нормально.

Ответы411151411152

797 1 июня, 22:04 797 1410492

Анончики, помогите понять. Делаю задачу про список студентов. Не могу разобраться в том как именно должно всё работать.
Вот есть страница, с неё посылается запрос на контроллер, он запускает модель, модель отдаёт данные обратно, контроллер передаёт данные на страницу. Так?
Как должно всё это взаимодействовать, если везде классы?

Ответы410520

798 1 июня, 23:00 798 1410520

>>1410492
Слишком общий вопрос.

Ответы410528

799 1 июня, 23:24 799 1410528

>>1410520
Если контроллер это класс, но как я должен его запускать? Прочитал про роутинг, но не понял. Вот есть страница с функциями вывода и поиска. Со страницы происходит запрос на файл роутер и в зависимости от того, что нужно сделать вывести или искать файл-роутер создаёт экземпляр нужного контроллера, запускает метод и возвращает данные на страницу. Так должно работать или я ошибаюсь?

Ответы410555410628410868411151

800 2 июня, 01:55 800 1410555

>>1410528
https://www.youtube.com/channel/UCQTlLk8CI8GDUPsz21uwjOQ
Я у этого парня смотрел по MVC урок. Не знаю грамотно ли он обьясняет, но на первое время точно пойдет

801 2 июня, 11:53 801 1410628

>>1410528
>Если контроллер это класс, но как я должен его запускать?
Как хочешь. Можно через конструктор, можно метод вызывать.

>Прочитал про роутинг, но не понял.
Читай и сам пробуй написать. Одного чтения мало, тем более если не понимаешь.

>происходит запрос на файл роутер
Сейчас все делают через фронт-контроллер. Никаких прямых запросов на php-файл извне - это небезопасно.

>Так должно работать или я ошибаюсь?
Нет, не так. Функция поиска - часть твоей страницы вывода. Это тот же список студентов, но только с критериями вывода, а значит контроллер тот же, что и в обычной таблице, только метод поиска, а не просто вывода.

Ответы411151

20 Кб, 500x212
802 2 июня, 13:02 802 1410656

>>1408250
>Синтаксис то нормальный

Ответы410660

803 2 июня, 13:13 803 1410660

>>1410656
Чёт тоже проиграл.

804 2 июня, 18:15 804 1410868

>>1410528
Найди на торрентах вот https://pr-of-it.ru/courses/php-2.html, в нём почти каждый урок обсасывают эту тему.

749 - 804 805 3 июня, 08:48 805 1411151

Перекат сделаем через день-два, там по моему еще у кого-то гитхаб непроверенный остался, а это плохо.

>>1410528

Для начала можно почитать урок про MVC c примером кода: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Там никакого роутера вообще нет, и ничего.

Самый простой способ "запускать" контроллер - просто создать его и вызвать метод:

$ctrl = new ListController;
$ctrl->indexAction();

Если ты хочешь красивые URL, то можно сделать роутер, как ты описал. Вот пример простейшего роутера:

if ($url == '/list') {
$ctrl = new ListController;
$ctrl->indexAction();
} else {
$this->show404Page();
}

Когда у тебя много классов, у тебя появятся зависимости между ними, чтобы их передавать, придумано DI, которое описано в этом уроке: https://github.com/codedokode/pasta/blob/master/arch/di.md

>>1410628

> Никаких прямых запросов на php-файл извне - это небезопасно.

Тут хорошо бы пояснить, чем именно небезопасно. А то я не понимаю.

>>1410465

По описанию напоминает что-то, связанное именно с тем, что файлы не видны в виртуальной машине. То есть ты редактируешь код на хосте, но в вирт. машине запускается старая версия кода. Ты можешь для проверки вывести содержимое файла в виртуальной машине командой вроде cat /home/vagrant/code/file.php

Также, когда ты в консоли запускаешь команды вроде php artisan ... - у тебя правильная текущая директория выбрана? (проверить можно командой pwd)

Попробуй почистить кеш командой php artisan cache:clear. Можно также вызвать composer install, который скорее всего очистит кеш.

Также, не может ли быть дело в правах, раньше ты логинился под одним пользователем по ssh, а сейчас под другим. И из-за этого у тебя нет доступа к файлам. Команда id или whoami показывает текущего пользователя, а команда ls -l показывает владельца файла и права доступа к нему.

Также, попробуй проверить класс Finder на какой-то незамапленной с хоста папке, например, на /etc или /usr.

749 - 804 805 3 июня, 08:48 805 1411151

Перекат сделаем через день-два, там по моему еще у кого-то гитхаб непроверенный остался, а это плохо.

>>1410528

Для начала можно почитать урок про MVC c примером кода: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Там никакого роутера вообще нет, и ничего.

Самый простой способ "запускать" контроллер - просто создать его и вызвать метод:

$ctrl = new ListController;
$ctrl->indexAction();

Если ты хочешь красивые URL, то можно сделать роутер, как ты описал. Вот пример простейшего роутера:

if ($url == '/list') {
$ctrl = new ListController;
$ctrl->indexAction();
} else {
$this->show404Page();
}

Когда у тебя много классов, у тебя появятся зависимости между ними, чтобы их передавать, придумано DI, которое описано в этом уроке: https://github.com/codedokode/pasta/blob/master/arch/di.md

>>1410628

> Никаких прямых запросов на php-файл извне - это небезопасно.

Тут хорошо бы пояснить, чем именно небезопасно. А то я не понимаю.

>>1410465

По описанию напоминает что-то, связанное именно с тем, что файлы не видны в виртуальной машине. То есть ты редактируешь код на хосте, но в вирт. машине запускается старая версия кода. Ты можешь для проверки вывести содержимое файла в виртуальной машине командой вроде cat /home/vagrant/code/file.php

Также, когда ты в консоли запускаешь команды вроде php artisan ... - у тебя правильная текущая директория выбрана? (проверить можно командой pwd)

Попробуй почистить кеш командой php artisan cache:clear. Можно также вызвать composer install, который скорее всего очистит кеш.

Также, не может ли быть дело в правах, раньше ты логинился под одним пользователем по ssh, а сейчас под другим. И из-за этого у тебя нет доступа к файлам. Команда id или whoami показывает текущего пользователя, а команда ls -l показывает владельца файла и права доступа к нему.

Также, попробуй проверить класс Finder на какой-то незамапленной с хоста папке, например, на /etc или /usr.

Показать весь текст

806 3 июня, 08:49 806 1411152

>>1410465

По описанию напоминает что-то, связанное именно с тем, что файлы не видны в виртуальной машине. То есть ты редактируешь код на хосте, но в вирт. машине запускается старая версия кода. Ты можешь для проверки вывести содержимое файла в виртуальной машине командой вроде cat /home/vagrant/code/file.php

Также, когда ты в консоли запускаешь команды вроде php artisan ... - у тебя правильная текущая директория выбрана? (проверить можно командой pwd)

Попробуй почистить кеш командой php artisan cache:clear. Можно также вызвать composer install, который скорее всего очистит кеш.

Также, не может ли быть дело в правах, раньше ты логинился под одним пользователем по ssh, а сейчас под другим. И из-за этого у тебя нет доступа к файлам. Команда id или whoami показывает текущего пользователя, а команда ls -l показывает владельца файла и права доступа к нему.

Также, попробуй проверить класс Finder на какой-то незамапленной с хоста папке, например, на /etc или /usr.

>>1407914
>>1408554

> public static function recursive_change_key($arr, $set)
Выглядит довольно сложно. Точно ли она тут нужна?

> @return array
Это не соотв. действительности, так как если передать не-массив, то функция его же и вернет обратно.

У тебя выбрана сложная схема хранения сотрудников в департаменте в виде многомерного массива, с которым сложно работать. Она не описана, я смотрю на код и вижу, что тут надо долго разбираться, чтобы понять, как это работает. Это никуда не годится, так как такой код будет тяжело поддерживать, и легко будет сделать в нем ошибку и не заметить.

Ну например, ты зачем-то хранишь количество в виде ключа. Но ведь ключ в массиве очень неудобно менять, это просто идентификатор элемента, он используется, чтобы найти элемент, его неудобно менять. Да и получать количество в твоей схеме неудобно. И в массиве не может быть 2 элементов с одинаковым ключом. Количество логичнее хранить как значение.

Вообще, ассоциативный массив предназначен в первую очередь для хранения соответствия чего-то чему-то, вроде "день => температура":

[ 1 => 8, 2 => -3, 4 => -5 ]

Соответствие "количество => тип работника" смотрится как-то странно.

Ты бы мог хранить данные, например, в таком виде:

$staff = [
['employee' => $emp, 'count' => 10],
['employee' => $emp2, 'count' => 1]
]

Но тут тоже возникает вопрос: это задача на ООП, почему мы тут объекты пытаемся имитировать с помощью массива? Логично поступить одним из 3 вариантов:

- либо переименовать Employee в EmployeeGroup и сделать в нем поле count
- либо сделать новый класс EmployeeGroup с полями employee и count
- либо отказаться от count и просто создавать каждого сотрудника как отдельный объект

Любой из этих вариантов, включая вариант с массивом массивов, на мой взгляд, в плане понятности кода и удобства работы будет лучше твоего массива-монстра.

То есть, схема хранения данных выбрана неудачно.

> private function isInStaff($item)
Где тайп-хинты? Как тут понять тип $item?

> if ($item == $employee) {
Это не очень хорошая идея, сравнивать объекты по значению полей, так как мы можем добавить какое-то новое поле (например: время создания объекта или кто его создал), и объекты с одной профессией, но разным временем, не будут более совпадать. То есть кто-то просто добавляет поле в объект (что по идее ничего не должно ломать), но старый код начинает работать по-другому. Это получается мина замедленного действия, и людям придется тратить кучу времени, чтобы найти и исправить причину ошибки.

Я бы лучше сделал метод isSameType(Employee $other): bool у работника с явным сравнением.

> private function isInStaff($item) //поиск сотрудника, возвращает ключи + работников или false
Он вернет массив с одним элементом или их может быть несколько? Ну и странный формат возвращаемого значения.

Класс Employee возможно логичнее назвать EmployeeType или как-то так.

> try {
> throw new Exception(
Нелогично в одной функции выбрасывать и ловить исключение - тут проще использовать if. Также, если ты ловишь исключение, то надо создавать свой класс, иначе ты можешь поймать например исключение, выброшенное самим PHP или какой-то другой функцией.

Ну и вообще, обычно функция просто выбрасывает исключение как признак ошибки, а ловит и обрабатывает тот, кто ее использовал. Или не обрабатывает, если он сделать с этим ничего не может. В твоем случае при ошибке исправить ее никак нельзя (только исправить код) и ловить исключение вообще смысла нет.

> public function addDepartment(array $stuff, $name)
На практике может быть удобнее принимать готовый объект департамента, а не создавать его самому.

Ждем еще версию с антикризисом. Если что-то непонятно, спрашивай.

806 3 июня, 08:49 806 1411152

>>1410465

По описанию напоминает что-то, связанное именно с тем, что файлы не видны в виртуальной машине. То есть ты редактируешь код на хосте, но в вирт. машине запускается старая версия кода. Ты можешь для проверки вывести содержимое файла в виртуальной машине командой вроде cat /home/vagrant/code/file.php

Также, когда ты в консоли запускаешь команды вроде php artisan ... - у тебя правильная текущая директория выбрана? (проверить можно командой pwd)

Попробуй почистить кеш командой php artisan cache:clear. Можно также вызвать composer install, который скорее всего очистит кеш.

Также, не может ли быть дело в правах, раньше ты логинился под одним пользователем по ssh, а сейчас под другим. И из-за этого у тебя нет доступа к файлам. Команда id или whoami показывает текущего пользователя, а команда ls -l показывает владельца файла и права доступа к нему.

Также, попробуй проверить класс Finder на какой-то незамапленной с хоста папке, например, на /etc или /usr.

>>1407914
>>1408554

> public static function recursive_change_key($arr, $set)
Выглядит довольно сложно. Точно ли она тут нужна?

> @return array
Это не соотв. действительности, так как если передать не-массив, то функция его же и вернет обратно.

У тебя выбрана сложная схема хранения сотрудников в департаменте в виде многомерного массива, с которым сложно работать. Она не описана, я смотрю на код и вижу, что тут надо долго разбираться, чтобы понять, как это работает. Это никуда не годится, так как такой код будет тяжело поддерживать, и легко будет сделать в нем ошибку и не заметить.

Ну например, ты зачем-то хранишь количество в виде ключа. Но ведь ключ в массиве очень неудобно менять, это просто идентификатор элемента, он используется, чтобы найти элемент, его неудобно менять. Да и получать количество в твоей схеме неудобно. И в массиве не может быть 2 элементов с одинаковым ключом. Количество логичнее хранить как значение.

Вообще, ассоциативный массив предназначен в первую очередь для хранения соответствия чего-то чему-то, вроде "день => температура":

[ 1 => 8, 2 => -3, 4 => -5 ]

Соответствие "количество => тип работника" смотрится как-то странно.

Ты бы мог хранить данные, например, в таком виде:

$staff = [
['employee' => $emp, 'count' => 10],
['employee' => $emp2, 'count' => 1]
]

Но тут тоже возникает вопрос: это задача на ООП, почему мы тут объекты пытаемся имитировать с помощью массива? Логично поступить одним из 3 вариантов:

- либо переименовать Employee в EmployeeGroup и сделать в нем поле count
- либо сделать новый класс EmployeeGroup с полями employee и count
- либо отказаться от count и просто создавать каждого сотрудника как отдельный объект

Любой из этих вариантов, включая вариант с массивом массивов, на мой взгляд, в плане понятности кода и удобства работы будет лучше твоего массива-монстра.

То есть, схема хранения данных выбрана неудачно.

> private function isInStaff($item)
Где тайп-хинты? Как тут понять тип $item?

> if ($item == $employee) {
Это не очень хорошая идея, сравнивать объекты по значению полей, так как мы можем добавить какое-то новое поле (например: время создания объекта или кто его создал), и объекты с одной профессией, но разным временем, не будут более совпадать. То есть кто-то просто добавляет поле в объект (что по идее ничего не должно ломать), но старый код начинает работать по-другому. Это получается мина замедленного действия, и людям придется тратить кучу времени, чтобы найти и исправить причину ошибки.

Я бы лучше сделал метод isSameType(Employee $other): bool у работника с явным сравнением.

> private function isInStaff($item) //поиск сотрудника, возвращает ключи + работников или false
Он вернет массив с одним элементом или их может быть несколько? Ну и странный формат возвращаемого значения.

Класс Employee возможно логичнее назвать EmployeeType или как-то так.

> try {
> throw new Exception(
Нелогично в одной функции выбрасывать и ловить исключение - тут проще использовать if. Также, если ты ловишь исключение, то надо создавать свой класс, иначе ты можешь поймать например исключение, выброшенное самим PHP или какой-то другой функцией.

Ну и вообще, обычно функция просто выбрасывает исключение как признак ошибки, а ловит и обрабатывает тот, кто ее использовал. Или не обрабатывает, если он сделать с этим ничего не может. В твоем случае при ошибке исправить ее никак нельзя (только исправить код) и ловить исключение вообще смысла нет.

> public function addDepartment(array $stuff, $name)
На практике может быть удобнее принимать готовый объект департамента, а не создавать его самому.

Ждем еще версию с антикризисом. Если что-то непонятно, спрашивай.

Показать весь текст
Ответы412337

807 3 июня, 08:50 807 1411154

>>1408224

По моему, ты вместо содержимого файла отдаешь просто его название в теле ответа. А надо отдавать содержимое.

Если ты используешь класс ответа из PSR-7, то там есть метод withBody, в который передается "поток", соответствующий файлу.

Также, обрати внимание на то, что надо передавать имена и пути к файлам по-разному:

- в заголовок Content-Disposition - только имя и символы ASCII без кириллицы. Есть также новый стандарт, который позволяет дополнительно к латинице передавать имя в utf-8 для новых браузеров. Изучить его было бы полезно.
- в X-Send-File - надо смотреть документацию, может полный путь от корня, а может относительно какой-то папки

Также, я не понял, зачем ты вызываешь $file->save(). Что ты хочешь сохранить в БД?

Синтаксис у тебя нормальный. Но я бы добавил отступ там, где длинная колбаса вызовов переносится. Я сам не очень люблю method chaining и предпочитаю обычный вызов методов.

>>1408250

Там скорее всего используется PSR-7, с которым ты можешь ознакомиться, если названия методов тебе ничего не говорят.

>>1407003

Сортировку проще всего сделать ссылкой. Например, ссылкой вида:

/list?search=Ivan&sort=-name&page=3

Про генерацию таких ссылок было написано в старых тредах, например:

- https://phpclub.tech/pr/res/1331378.html#1351739

807 3 июня, 08:50 807 1411154

>>1408224

По моему, ты вместо содержимого файла отдаешь просто его название в теле ответа. А надо отдавать содержимое.

Если ты используешь класс ответа из PSR-7, то там есть метод withBody, в который передается "поток", соответствующий файлу.

Также, обрати внимание на то, что надо передавать имена и пути к файлам по-разному:

- в заголовок Content-Disposition - только имя и символы ASCII без кириллицы. Есть также новый стандарт, который позволяет дополнительно к латинице передавать имя в utf-8 для новых браузеров. Изучить его было бы полезно.
- в X-Send-File - надо смотреть документацию, может полный путь от корня, а может относительно какой-то папки

Также, я не понял, зачем ты вызываешь $file->save(). Что ты хочешь сохранить в БД?

Синтаксис у тебя нормальный. Но я бы добавил отступ там, где длинная колбаса вызовов переносится. Я сам не очень люблю method chaining и предпочитаю обычный вызов методов.

>>1408250

Там скорее всего используется PSR-7, с которым ты можешь ознакомиться, если названия методов тебе ничего не говорят.

>>1407003

Сортировку проще всего сделать ссылкой. Например, ссылкой вида:

/list?search=Ivan&sort=-name&page=3

Про генерацию таких ссылок было написано в старых тредах, например:

- https://phpclub.tech/pr/res/1331378.html#1351739

Показать весь текст

808 3 июня, 12:35 808 1411227

Подкиньте, пожалуйста, ссылку на какой нибудь короткий видео урок, где пишут приложение на php, соблюдая хороший тон программирования. Заранее спасибо.

809 3 июня, 14:58 809 1411268

>>1394979
ОП, сможешь посмотреть всё-таки студентов моих?

Ответы413645

810 3 июня, 20:06 810 1411376

если на сайт нак ларавеле зайдет 10к челолвек разом-сайту каюк?

Ответы413644

811 3 июня, 21:02 811 1411406

Синьоры, я слышал, что внешние библиотеки в свой проект лучше интегрировать через свой объект, который работает с этой библиотекой, ну и интерфейс под него сделать.
Мне думается, что тут есть смысл, так как библиотеки могут иметь разный АПИ и задолбаешься по коду менять эти методы.

Так вот этот вот объект-обёртка над либой это что за паттерн?

Ответы411622413644

PHP 7.4. 812 3 июня, 21:22 812 1411411

Ну че посоны, много новой годноты обещают:
https://gtxtymt.xyz/blog/php-74-whats-new-release-date

сука, только я собираюсь съебаться с пыхи, как они выпускают новую версию с годнотой и я залипаю опять(((

Ответы411531

813 4 июня, 05:59 813 1411531

>>1411411
ничего интересного

Ответы411552

814 4 июня, 08:21 814 1411552

>>1411531
Ну для вкатывальщика, да.
А мне вот очень не хватало типизации свойств

Ответы411597

815 4 июня, 10:17 815 1411597

>>1411552
>Ну для вкатывальщика
Ты и есть вкатывальщик.

Ответы411605

816 4 июня, 10:58 816 1411605

>>1411597
Ой, пиздуй дальше говнокодь в процедурном стиле

817 4 июня, 11:55 817 1411622

>>1411406
>объект-обёртка
Ты не поверишь - Wrapper. Более известен как Adapter.

Ответы411732

818 4 июня, 15:05 818 1411732

>>1411622
>Adapter
Спасибо.

Отправка письма с сайта на почту с помощью функции PHP Аноним 819 4 июня, 17:56 819 1411828

Использовал эту функцию ранее, она работала, все отправлялось. Теперь данные с формы отправляются куда-то, но сообщение не приходит. Не могу понять, почему.

ФОРМА:

<?if(isset($_POST["sub"])) {
include "confirm_form.php";
} else {
?>
<form action="" method="POST">
<div class='inp_user_data'><input type="text" name="fio" value="" placeholder="ФИО"></div>
<div class='inp_user_data'><input type="text" name="email" value="" placeholder="E-mail"></div>
<div class='inp_user_data'><input type="text" name="phone" value="" placeholder="Номер телефона"></div>
<div class='inp_ps'><input type="checkbox" name="a" value="" checked> <a href='/privacy.php'> я принимаю пользовательское соглашение и политику конфиденциальности</a></div>
<div class='sub_user_data'><input type="submit" name="sub" value="ЗАКАЗАТЬ"></div>
</form>
<?}?>

ФУНКЦИЯ:

<?php
$error = array();
if(!empty($_POST['fio'])) {
$fio = $_POST["fio"];
} else {
$error[] = 'Введите ФИО';
}
if(!empty($_POST['email'])) {
$email = $_POST["email"];
} else {
$error[] = 'Введите E-mail';
}
if(!empty($_POST['phone'])) {
$phone = $_POST["phone"];
} else {
$error[] = 'Введите телефон';
}

if($error == array()) {
//Ошибок нет! Отправляем письмо.
$to = "указываю свою почту"; //Адрес получателя
$subject = "Пользователь заказал обратный звонок!"; //Тема письма
$message = "
Пользователь заказал обратный звонок!<br>
ФИО:" . $_POST["fio"] . "<br>
E-mail:" . $_POST["email"] . "<br>
Номер телефона:" . $_POST["phone"]
; //Текст письма
$email = $_POST["mail"]; //Адрес отправителя
$header = "From: " . $email . "\r\n"."Reply-To: " . $email . "\r\n"."X-Mailer: PHP/" . phpversion();
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-type: text/html; charset=utf-8\r\n";

$send = mail($to,$subject,$message,$header);

if($send == true) {
echo "<div style='color:#3d8873;'> Вы заказали обратный звонок!</div>";
}
} else {
//Ошибки есть! Выводим ошибки.?>
<?foreach($error as $v):?>
<div style='color:red;'><?=$v;?></div>
<?endforeach?>
<?}?>

Отправка письма с сайта на почту с помощью функции PHP Аноним 819 4 июня, 17:56 819 1411828

Использовал эту функцию ранее, она работала, все отправлялось. Теперь данные с формы отправляются куда-то, но сообщение не приходит. Не могу понять, почему.

ФОРМА:

<?if(isset($_POST["sub"])) {
include "confirm_form.php";
} else {
?>
<form action="" method="POST">
<div class='inp_user_data'><input type="text" name="fio" value="" placeholder="ФИО"></div>
<div class='inp_user_data'><input type="text" name="email" value="" placeholder="E-mail"></div>
<div class='inp_user_data'><input type="text" name="phone" value="" placeholder="Номер телефона"></div>
<div class='inp_ps'><input type="checkbox" name="a" value="" checked> <a href='/privacy.php'> я принимаю пользовательское соглашение и политику конфиденциальности</a></div>
<div class='sub_user_data'><input type="submit" name="sub" value="ЗАКАЗАТЬ"></div>
</form>
<?}?>

ФУНКЦИЯ:

<?php
$error = array();
if(!empty($_POST['fio'])) {
$fio = $_POST["fio"];
} else {
$error[] = 'Введите ФИО';
}
if(!empty($_POST['email'])) {
$email = $_POST["email"];
} else {
$error[] = 'Введите E-mail';
}
if(!empty($_POST['phone'])) {
$phone = $_POST["phone"];
} else {
$error[] = 'Введите телефон';
}

if($error == array()) {
//Ошибок нет! Отправляем письмо.
$to = "указываю свою почту"; //Адрес получателя
$subject = "Пользователь заказал обратный звонок!"; //Тема письма
$message = "
Пользователь заказал обратный звонок!<br>
ФИО:" . $_POST["fio"] . "<br>
E-mail:" . $_POST["email"] . "<br>
Номер телефона:" . $_POST["phone"]
; //Текст письма
$email = $_POST["mail"]; //Адрес отправителя
$header = "From: " . $email . "\r\n"."Reply-To: " . $email . "\r\n"."X-Mailer: PHP/" . phpversion();
$header .= "MIME-Version: 1.0\r\n";
$header .= "Content-type: text/html; charset=utf-8\r\n";

$send = mail($to,$subject,$message,$header);

if($send == true) {
echo "<div style='color:#3d8873;'> Вы заказали обратный звонок!</div>";
}
} else {
//Ошибки есть! Выводим ошибки.?>
<?foreach($error as $v):?>
<div style='color:red;'><?=$v;?></div>
<?endforeach?>
<?}?>

Показать весь текст
Ответы411868

820 4 июня, 19:34 820 1411868

>>1411828
sendmail настроен то на сервере?

Ответы411969

821 4 июня, 21:47 821 1411969

>>1411868
А как проверить, настроен или нет? Я просто скидываю файлы на сервер с помощью ftp-клиента и всё как бы

Ответы411981413644

822 4 июня, 22:40 822 1411981

>>1411969
Ну спроси у владельца сервера/хостинга если это не твой.
Или если у тебя какая-нибудь cPanel, попробуй там поискать.

823 5 июня, 02:55 823 1412025

где можно скачать курс php от лаврика?

824 5 июня, 10:29 824 1412096

Добрый день! Вопрос по выбору CMS: есть вариативные товары в виде кроватей, у которых, помимо обычных выборочных свойств (размер), есть опции с фиксированной ценной – дополнительные ящики, нестандартные основания и т.п. Как задать опциям цену, иначе очень много вариаций получается и цены каждой очень неудобно задавать? Например, как здесь: http://архитектория.рф/krovati/atrium. Плюс цвет тоже идет по ценновым категориям, а опции бывают взаимоисключающими.
Пробовал Prestashop и WooCommerce различными плагинами, но не все не то.

Ответы413644

825 5 июня, 12:33 825 1412173

Пиздос. Какой же всратый в .htaccess синтаксис.

826 5 июня, 18:39 826 1412337

>>1411152
Спасибо за проверку, вот версия с учетом ошибок плюс антикризис.
Посмотри пожалуйста.
https://github.com/superhorsy/share/blob/master/oop_vector2.php

Ответы413642

827 5 июня, 21:56 827 1412595

Что-то я нихера не вдупляю по поводу composer psr-4 autoloader. Кто-нибудь может пояснить?

Допустим, я имею следующую структуру файлов:

```
- src
-- ns1
--- firstClass.php
--- conflictClass.php
-- ns2
--- secondClass.php
--- conflictClass.php
```

Все php-файлы содержат в себе объявление класса и одного публичного метода, который выводит сообщение на экран. namespace в них не указан.

Я пишу в composer.json

```
"autoload": {
"psr-4": {
"": "classes/"
}
}
```

Выполняю `composer dump-autoload`, composer в консоль ругается, что у меня имеется два класса с названием conflictClass. Значит, структура каталогов может быть любой, вопрос в том, какие namespace я укажу у файлов? Просто на первый взгляд мне показалось, что использование composer psr-4 autoload приведёт к тому, что файл, который находится по пути /src/ns1/conflictClass.php при таких настройках станет доступен как \ns1\conflictClass.

Тогда мне не очень понятно, чем является ключ в паре `"": "classes/"`.

Допустим, я задам файлам из ns1 `namespace ns1`, из ns2 `namespace ns2` соответственно. После этого всё становится нормально. Например, класс firstClass становится доступен как \ns1\firstClass. Но если я в composer.json изменю ключ и приведу файл, например, к такому виду:

```
"autoload": {
"psr-4": {
"app\\": "classes/"
}
}
```

То попытка вызвать \ns1\firstClass вернёт ошибку. Попытка вызвать \app\ns1\firstClass тоже вернёт ошибку, попытка вызвать \app\firstClass аналогично.

Итого: я нихуя не понял. Если попытаться сформулировать чёткие вопросы, то они будут примерно следующими:

1. Влияет ли на что-нибудь файловая структура? Допустим, у меня есть два файла: classes/firstClass.php и classes/foo/bar/baz/secondClass.php. Обязывает ли данная файловая структура к тому, что firstClass.php будет доступен как firstClass, а secondClass.php как \foo\bar\baz\secondClass? Или это соглашение о структуре имён файлов (каждый уровень namespace = папка, имя файла = имя_класса.php) является скорее организационным моментом и на загрузку файлов никак не влияет?

2. Чем, всё-таки, является ключ в конфиге psr-4? Пока я писал это полотно в голове всё немного упорядочилось, я еще раз прочитал доки и появилась вот какая мысль.

Допустим:

"psr-4": {
"app\\": "classes/",
"another\\": "source/"
}

Приведёт к тому, что классы, полный путь к которым (то есть, с namespace) начинается с `app` будут искаться в папке `classes`, а те, которые начинаются с `another` будут искаться в `source/`.

Например, если я в своём index.php попробую обратиться к классу `\app\some\firstClass`, этот класс будет первым делом искаться в `classes/some/firstClass.php`? При этом, следующая конструкция в composer.json:

```
"psr-4": {
"": "classes/"
}
```

Является эдаким аналогом фразы "любые классы из любых неймспейсов ищи в папке classes" (конечно, библиотек загруженных через composer это не касается). То есть, эта конструкция

```
"autoload": {
"psr-4": {
"": "classes/"
}
}
```

Является универсальной и заменяет собой все остальные? То есть, если мне нужно для каждого namespace указать свою папку, то можно изъебываться и указывать их. Но если мне просто нужно подключить все файлы из папки classes, то я могу написать так. И структура пути будет зависить не от файловой структуры, а от того, что я напишу в namespace файла.

Например, файл classes/foo/bar/buzz/user.php у которого указан `namespace \project\foo\user.php` будет доступен как, собственно, \project\foo\user.php и файловая структура не играет роли с технической точки зрения (но играет с точки зрения адекватности архитектуры проекта, так сказать, и за такие фокусы мне должны нассать на лицо и заставить переложить этот файл по пути /classes/project/foo/user.php). Верно?

827 5 июня, 21:56 827 1412595

Что-то я нихера не вдупляю по поводу composer psr-4 autoloader. Кто-нибудь может пояснить?

Допустим, я имею следующую структуру файлов:

```
- src
-- ns1
--- firstClass.php
--- conflictClass.php
-- ns2
--- secondClass.php
--- conflictClass.php
```

Все php-файлы содержат в себе объявление класса и одного публичного метода, который выводит сообщение на экран. namespace в них не указан.

Я пишу в composer.json

```
"autoload": {
"psr-4": {
"": "classes/"
}
}
```

Выполняю `composer dump-autoload`, composer в консоль ругается, что у меня имеется два класса с названием conflictClass. Значит, структура каталогов может быть любой, вопрос в том, какие namespace я укажу у файлов? Просто на первый взгляд мне показалось, что использование composer psr-4 autoload приведёт к тому, что файл, который находится по пути /src/ns1/conflictClass.php при таких настройках станет доступен как \ns1\conflictClass.

Тогда мне не очень понятно, чем является ключ в паре `"": "classes/"`.

Допустим, я задам файлам из ns1 `namespace ns1`, из ns2 `namespace ns2` соответственно. После этого всё становится нормально. Например, класс firstClass становится доступен как \ns1\firstClass. Но если я в composer.json изменю ключ и приведу файл, например, к такому виду:

```
"autoload": {
"psr-4": {
"app\\": "classes/"
}
}
```

То попытка вызвать \ns1\firstClass вернёт ошибку. Попытка вызвать \app\ns1\firstClass тоже вернёт ошибку, попытка вызвать \app\firstClass аналогично.

Итого: я нихуя не понял. Если попытаться сформулировать чёткие вопросы, то они будут примерно следующими:

1. Влияет ли на что-нибудь файловая структура? Допустим, у меня есть два файла: classes/firstClass.php и classes/foo/bar/baz/secondClass.php. Обязывает ли данная файловая структура к тому, что firstClass.php будет доступен как firstClass, а secondClass.php как \foo\bar\baz\secondClass? Или это соглашение о структуре имён файлов (каждый уровень namespace = папка, имя файла = имя_класса.php) является скорее организационным моментом и на загрузку файлов никак не влияет?

2. Чем, всё-таки, является ключ в конфиге psr-4? Пока я писал это полотно в голове всё немного упорядочилось, я еще раз прочитал доки и появилась вот какая мысль.

Допустим:

"psr-4": {
"app\\": "classes/",
"another\\": "source/"
}

Приведёт к тому, что классы, полный путь к которым (то есть, с namespace) начинается с `app` будут искаться в папке `classes`, а те, которые начинаются с `another` будут искаться в `source/`.

Например, если я в своём index.php попробую обратиться к классу `\app\some\firstClass`, этот класс будет первым делом искаться в `classes/some/firstClass.php`? При этом, следующая конструкция в composer.json:

```
"psr-4": {
"": "classes/"
}
```

Является эдаким аналогом фразы "любые классы из любых неймспейсов ищи в папке classes" (конечно, библиотек загруженных через composer это не касается). То есть, эта конструкция

```
"autoload": {
"psr-4": {
"": "classes/"
}
}
```

Является универсальной и заменяет собой все остальные? То есть, если мне нужно для каждого namespace указать свою папку, то можно изъебываться и указывать их. Но если мне просто нужно подключить все файлы из папки classes, то я могу написать так. И структура пути будет зависить не от файловой структуры, а от того, что я напишу в namespace файла.

Например, файл classes/foo/bar/buzz/user.php у которого указан `namespace \project\foo\user.php` будет доступен как, собственно, \project\foo\user.php и файловая структура не играет роли с технической точки зрения (но играет с точки зрения адекватности архитектуры проекта, так сказать, и за такие фокусы мне должны нассать на лицо и заставить переложить этот файл по пути /classes/project/foo/user.php). Верно?

Показать весь текст
Ответы412596412609413150413640

828 5 июня, 21:56 828 1412596

>>1412595
Для тех, у кого из глаз пойдёт кровь - ссылка на markdown-версию (домен, разумеется, нужно заменить).

https://тиниюрл.com/y2gdfo3x

829 5 июня, 22:38 829 1412609

>>1412595
Ну и простыня. Твои вопросы просто теряются в ней. Учись краткости - программисту не лишним будет.

Ответы412666

830 6 июня, 00:17 830 1412658

Можно ли сравнивать ('11' == 11) ? Есть ли какие то подводные камни?

Ответы412685412747413639

831 6 июня, 00:52 831 1412666

>>1412609
Я постарался к концу конкретизировать.

Ответы412687

832 6 июня, 02:36 832 1412685

>>1412658
В документации что говорят по этому поводу?

833 6 июня, 02:39 833 1412687

>>1412666
Да просто пиши как все, по PSR - потом само всё дойдёт.

834 6 июня, 10:50 834 1412747

>>1412658
https://habr.com/ru/post/259497/

835 6 июня, 12:13 835 1412774

Скачал Imagick отсюда http://pecl.php.net/package/imagick/3.4.1/windows. Из архива dll поместил в раздел ext в папке с пхп. В конфиг добавил строчку extension=php_imagick.dll. Запускаю пхп, а он мне говорит unable to load dynamic library. ЧЯДНТ?

Ответы412796

836 6 июня, 13:15 836 1412796

>>1412774

А ты не из под Апача случайно PHP запускаешь? Попробуй сделать php -m из командной строки, если ошибки не будет, а при запуске из-под Апача ошибка есть, то скорее всего проблема в ниже описанном.

Дело скорее всего в пути поиска dll. Путь к php_imagick.dll известен полностью - он собирается из пути к папке ext, который записан где-то в конфиге и имени файла. То есть PHP знает полный путь к ней и загружает без проблем. Но возможно, что у php_imagick.dll есть какие-то зависимости, то есть ей нужна еще какая-то dll. И полный путь к этой dll нигде не записан, только имя файла. Потому при его поиске применяется стандартный алгоритм Windows, описанный тут: https://docs.microsoft.com/en-us/windows/desktop/dlls/dynamic-link-library-search-order

И возможно что нужная dll не находится.

Я скачал для примера архив http://windows.php.net/downloads/pecl/snaps/imagick/3.4.3/php_imagick-3.4.3-7.3-ts-vc15-x86.zip и посмотрел на зависимости у php_imagick.dll из него. И вот какие dll ей нужны:

- php7ts.dll
- CORE_RL_MagickWand_.dll
- VCRUNTIME140.dll
- CORE_RL_MagickCore_.dll

То есть php-расширению imagick нужны dll из библиотеки imagick, библиотека Visual C Runtime и библиотека из состава PHP.

Возможно, что-то из этого не находится. Как отлаживать такие ситуации? Тут есть разные подходы. Есть утилиты вроде Dependency Walker, которые показывают зависимости DLL и возможные проблемы. Другой, более надежный, вариант - мониторить запуск программой вроде procmon, которая показывает, какие действия делает программа, к каким файлам обращается (это очень полезная утилита, которую тебе вполне стоит освоить). Там ты увидишь, что именно не удается найти.

Как решить проблему? Если не находится VC runtime - скачать ее с сайта майкрософт. Если не находится imagick - то надо поместить их либо в одну папку с запускаемой программой (например, Апачом), либо добавить папку с ними в PATH, либо поместить библиотеки в папку, которая есть в PATH.

Задавай вопросы, если что-то непонятно.

Ответы413159

837 6 июня, 16:15 837 1412872

Ребят, некст ситуэйшн: имею дома мак (стоит пылится). Можете внятно пояснить, какая польза от разработки на маке вместо Win? Только от того что серверное окружение тоже unix? Или есть еще плюсы?

Ответы413151413348

838 6 июня, 19:50 838 1412984

Сап программач. Полез в пхп. Собственно проблема: создаю форму с помощью echo '<form ... и т.д. Проблема в том, что если я этой форме хочу прописать в action php-скрипт с параметром, выраженным перменной (action="/test.php?get=$test"), то в случае если я ставлю двойные кавычки в action, то передачи парметра на происходит и открывается просто test.php, а если ставлю одинарные, то ломается и выводится пустой вообще вся страница на которой форма. Что я делаю не так?

Ответы413153413639

839 7 июня, 07:25 839 1413150

>>1412595
>```
>- src
>-- ns1
>--- firstClass.php
>--- conflictClass.php
>-- ns2
>--- secondClass.php
>--- conflictClass.php
>```
>
>```
>"autoload": {
>"psr-4": {
>"": "classes/"
>}
>}
>```
Почему у тебя в структуре файлов корневая директория `src`, а в composer.json указана `classes`? Опечатка?

>Выполняю `composer dump-autoload`, composer в консоль ругается, что у меня имеется два класса с названием conflictClass. Значит, структура каталогов может быть любой, вопрос в том, какие namespace я укажу у файлов?
namespace Ключ\Путь\К\Файлу;

>1. Влияет ли на что-нибудь файловая структура?
На определение namespace'ов.

>Допустим, у меня есть два файла: classes/firstClass.php и classes/foo/bar/baz/secondClass.php. Обязывает ли данная файловая структура к тому, что firstClass.php будет доступен как firstClass, а secondClass.php как \foo\bar\baz\secondClass?
Да, нужно указывать полный путь к файлу начиная с корневой директории (ключа) указанной в composer.json.

>Или это соглашение о структуре имён файлов (каждый уровень namespace = папка, имя файла = имя_класса.php) является скорее организационным моментом и на загрузку файлов никак не влияет?
Нет, это соглашение о структуре имён файлов не является скорее организационным моментом, и влияет на загрузку файлов.

>2. Чем, всё-таки, является ключ в конфиге psr-4?

https://getcomposer.org/doc/04-schema.md#psr-4
>Under the psr-4 key you define a mapping from namespaces to paths, relative to the package root.

>Например, если я в своём index.php попробую обратиться к классу `\app\some\firstClass`, этот класс будет первым делом искаться в `classes/some/firstClass.php`?
Да.

>То есть, эта конструкция
>
>```
>"autoload": {
>"psr-4": {
>"": "classes/"
>}
>}
>```
>
>Является универсальной и заменяет собой все остальные?
Да.

>То есть, если мне нужно для каждого namespace указать свою папку, то можно изъебываться и указывать их. Но если мне просто нужно подключить все файлы из папки classes, то я могу написать так. И структура пути будет зависить не от файловой структуры, а от того, что я напишу в namespace файла.
>
>Например, файл classes/foo/bar/buzz/user.php у которого указан `namespace \project\foo\user.php` будет доступен как, собственно, \project\foo\user.php и файловая структура не играет роли с технической точки зрения (но играет с точки зрения адекватности архитектуры проекта, так сказать, и за такие фокусы мне должны нассать на лицо и заставить переложить этот файл по пути /classes/project/foo/user.php). Верно?
Нет, не верно. Для каждого namespace нужно указывать свою папку. Например, файл classes/foo/bar/buzz/user.php у которого указан `namespace \project\foo\user.php` не будет доступен как, собственно, \project\foo\user.php и файловая структура играет роль с технической точки зрения (и играет с точки зрения адекватности архитектуры проекта).

839 7 июня, 07:25 839 1413150

>>1412595
>```
>- src
>-- ns1
>--- firstClass.php
>--- conflictClass.php
>-- ns2
>--- secondClass.php
>--- conflictClass.php
>```
>
>```
>"autoload": {
>"psr-4": {
>"": "classes/"
>}
>}
>```
Почему у тебя в структуре файлов корневая директория `src`, а в composer.json указана `classes`? Опечатка?

>Выполняю `composer dump-autoload`, composer в консоль ругается, что у меня имеется два класса с названием conflictClass. Значит, структура каталогов может быть любой, вопрос в том, какие namespace я укажу у файлов?
namespace Ключ\Путь\К\Файлу;

>1. Влияет ли на что-нибудь файловая структура?
На определение namespace'ов.

>Допустим, у меня есть два файла: classes/firstClass.php и classes/foo/bar/baz/secondClass.php. Обязывает ли данная файловая структура к тому, что firstClass.php будет доступен как firstClass, а secondClass.php как \foo\bar\baz\secondClass?
Да, нужно указывать полный путь к файлу начиная с корневой директории (ключа) указанной в composer.json.

>Или это соглашение о структуре имён файлов (каждый уровень namespace = папка, имя файла = имя_класса.php) является скорее организационным моментом и на загрузку файлов никак не влияет?
Нет, это соглашение о структуре имён файлов не является скорее организационным моментом, и влияет на загрузку файлов.

>2. Чем, всё-таки, является ключ в конфиге psr-4?

https://getcomposer.org/doc/04-schema.md#psr-4
>Under the psr-4 key you define a mapping from namespaces to paths, relative to the package root.

>Например, если я в своём index.php попробую обратиться к классу `\app\some\firstClass`, этот класс будет первым делом искаться в `classes/some/firstClass.php`?
Да.

>То есть, эта конструкция
>
>```
>"autoload": {
>"psr-4": {
>"": "classes/"
>}
>}
>```
>
>Является универсальной и заменяет собой все остальные?
Да.

>То есть, если мне нужно для каждого namespace указать свою папку, то можно изъебываться и указывать их. Но если мне просто нужно подключить все файлы из папки classes, то я могу написать так. И структура пути будет зависить не от файловой структуры, а от того, что я напишу в namespace файла.
>
>Например, файл classes/foo/bar/buzz/user.php у которого указан `namespace \project\foo\user.php` будет доступен как, собственно, \project\foo\user.php и файловая структура не играет роли с технической точки зрения (но играет с точки зрения адекватности архитектуры проекта, так сказать, и за такие фокусы мне должны нассать на лицо и заставить переложить этот файл по пути /classes/project/foo/user.php). Верно?
Нет, не верно. Для каждого namespace нужно указывать свою папку. Например, файл classes/foo/bar/buzz/user.php у которого указан `namespace \project\foo\user.php` не будет доступен как, собственно, \project\foo\user.php и файловая структура играет роль с технической точки зрения (и играет с точки зрения адекватности архитектуры проекта).

Показать весь текст

840 7 июня, 07:32 840 1413151

>>1412872
Твоя разработка зависит от твоих личных предпочтений и удобств.

841 7 июня, 07:39 841 1413153

>>1412984
https://github.com/codedokode/pasta/blob/master/php/templates.md

842 7 июня, 08:15 842 1413159

>>1412796
Ну я потыкал php.exe и php-win.exe. В php-win.exe мне сказали, что не хватает библиотеки dll. Тогда я все что было с имэджиком поместил в корень папки php. Ошибки при запуске теперь нет, но и в phpinfo я подключенной библиотеки не вижу. Сайт ее не находит, значит точно не подключилась.

Ответы413639

843 7 июня, 10:15 843 1413188

Аноны, подскажите IDE или продвинутый редактор, основное что нужно кроме того что бы он дополнял структурами самого языка это то, что бы редактор нормально видел методы класса, в том числе и наследуемые от родителя. Или если вызывается новый класс - что бы его методы так же определялись корректно. Ну и конечно было бы здорово что бы редактор видел тип, количество аргументов в метод, ну и тому подобное.
Сейчас использую visual studo code, но так и не нашел для него php - дополнения что эту функциональность дает.
PHPStorm - понятная тема, но он 200 стоит. ЩА триал качаю. Но может есть бесплатные аналоги с подобным функционалом.

Ответы413351413399413545413638

844 7 июня, 16:52 844 1413348

>>1412872
С маком можешь смело ходить в гей-бары. С ним ты настоящий программист.

845 7 июня, 17:03 845 1413351

>>1413188
Я на Саблайме пишу - мне норм.

846 7 июня, 20:17 846 1413399

>>1413188
Пирать шторм и не выебывайся.

Ответы413545

847 7 июня, 21:49 847 1413433

писать проэкт с нуля ,на пхп-стильно и молодежно?

Ответы413638

90 Кб, 1290x712
848 7 июня, 22:21 848 1413441

>>1380485 (OP)
Драститя. Первый день изучаю ПХП по мануалу от анончика.
Поясните, зачем в поле вывода, в данном примере после echo значения заключаются в фигурные скобки?

При выполнении задания, я пробовал и так и эдак - разницы никакой. Но подозреваю, что разница есть. Хочу понять какая?
Как ни странно гугл не помог, или я туповат

Ответы413472413638

849 7 июня, 22:50 849 1413465

После вашего учебника-сайта куда двигаться? Прочитать статью про сервер, введение в sql и делать круд студентов?

Ответы413472413638

850 7 июня, 23:11 850 1413472

>>1413441
Чисто визуальная составляющая для выделения подстановки переменной - её так видно лучше и редакторы часто подсвечивают. Просто хороший способ не проебать переменную в куче кода, особенно поначалу.

>>1413465
Да. Можешь, конечно, в яндекс попроситься, но тебя пошлют скорее всего.

Ответы413976

851 8 июня, 06:05 851 1413530

Я не понимаю, объясните архитектуру solid, как она работает ? И имеет смысл учить это ?

Ответы413569413638

852 8 июня, 10:07 852 1413545

>>1413188
Ты не туда смотришь, PHPStorm для персонального использования стоит 89$ первый год, потом меньше: https://www.jetbrains.com/phpstorm/buy/#edition=personal
Сейчас PHPStorm де-факто стандарт для PHP разработки, а навыки работы с этой IDE часто указывают как обязательные требования в вакансиях. Если ты студент - то можешь получить бесплатную лицензию на всё время обучения. Вообще у них целый список из special offers: https://www.jetbrains.com/phpstorm/buy/#edition=discounts

>>1413399
Много офисов JetBrains находятся в РФ. Не жадничай на поддержу отечественного производителя, если благодаря их продукту зарабатываешь деньги.

Ответы413609

853 8 июня, 12:03 853 1413569

>>1413530
Она нужна когда на ООП пишешь.

854 8 июня, 14:05 854 1413609

>>1413545
А если человек просто вкатывается, а не зарабатывает? И для меня это не отечественный производитель, я не из РФ.

805 - 852, 590 - 634 855 8 июня, 14:52 855 1413638

>>1413530

SOLID - это не архитектура, а набор принципов, которым стоит следовать при использовании ООП, каждая буква обозначает отдельный принцип. Например, S значит Single Responsibility, то есть у каждого класса есть строго определенная зона ответственности, за которую он отвечает и он не занимается ничем другим. Расшифровку букв и пояснения к ним можно нагуглить, не все статьи понятные, но если поискать, то можно найти информацию.

Если у тебя есть какой-то более конкретный вопрос, то уточняй.

>>1413441

Скобки нужны на случай, если например прямо к переменной приклеен какой-то текст, чтобы его не воспринимало как часть переменной: {$size}Mb. Остально описано в мануале: https://www.php.net/manual/ru/language.types.string.php#language.types.string.parsing

>>1413465

Делать студентов и более сложные задачи. После учить фреймворки, например, Slim, Symfony, Laravel. Мало уметь решать задачки про выдачу кредита, надо учиться разрабатывать сайт целиком.

>>1413433

Обычно пишут на фреймворках.

>>1413188

Плохо искал. У VS code есть расширения вроде PHP intellisense: https://code.visualstudio.com/docs/languages/php

Еще есть Netbeans и Eclipse for PHP, но не знаю, как с ними дело.

Ответы413953413976

856 8 июня, 14:53 856 1413639

>>1413159

"Потыкал" - значит, запустил в командной строке? Или не запускал? Что показывает php -m?

И надо не "тыкать", а разобраться, как в Windows ищутся DLL. Например, в случае использования с Апачом (а ты, кстати, так и не написал, что у тебя в качестве сервера: Апач, php-fpm, встроенный сервер) порядок зависимостей такой:

httpd.exe (Апач) -> подключает по абс. пути php7apache2_4.dll -> она подключает по абс. пути php_imagick.dll -> она подключает dll-ки imagick, к которым путь не указан.

Если ты это сопоставишь с описанным на сайте Майкрософт (почему не сопоставил?), то увидишь, что в таком сценарии библиотеки imagick должны находиться либо в папке Апача, либо в PATH. Чтобы не разводить помойку, логично сделать для библиотеки imagick отдельную папку, положить туда все dll-ки и добавить путь к ней в переменную окружения PATH, и перезагрузить компьютер.

Ты зря ленишься разобраться в проблеме. Если ты с поиском DLL не можешь разобраться, как ты будешь более сложные проблемы решать?

>>1412984

Разберись с синтаксисом строк и экранированием: https://www.php.net/manual/ru/language.types.string.php

Нельзя просто так использовать кавычки внутри кавычек. Ну или, как тебе советуют, освой шаблоны.

>>1412658

Конечно, есть. Например, может оказаться, что '11apples' == 11. Читай документацию: https://www.php.net/manual/ru/language.operators.comparison.php

857 8 июня, 14:54 857 1413640

>>1412595

А ты читал мой урок по PSR-4? https://github.com/codedokode/pasta/blob/master/php/autoload.md

Также, прочти документацию в композере, а то я не хочу ее пересказывать: https://getcomposer.org/doc/04-schema.md#autoload

> Допустим, я имею следующую структуру файлов:
> firstClass.php

Обычно имена классов пишут с большой буквы без слова Class.

> Все php-файлы содержат в себе объявление класса и одного публичного метода, который выводит сообщение на экран. namespace в них не указан.

Тогда эти классы находятся в корневом неймспейсе. В какой папке они лежат, не важно.

> Я пишу в composer.json
> "psr-4":

Ты хочешь использовать PSR-4, но твой код не соответствует стандарту. Неудивительно, что оно не работает. Прочти мой урок для начала. Либо сам стандарт.

> Значит, структура каталогов может быть любой, вопрос в том, какие namespace я укажу у файлов?

Да, неймспейс задается словом namespace и не зависит от имени файла или папки. Но PSR-4 предлагает не раскидывать файлы как попало, а сделать структуру папок, соответствующую неймспейсам для облегчения поиска нужного файла. Автозагрузчик полагается на то, что ты следуешь PSR-4. Если ты не следуешь PSR-4, то ты должен либо писать свой автозагрузчик, либо попросить композер составить список твоих классов и пути к ним и использовать этот список (classmap).

> Просто на первый взгляд мне показалось, что использование composer psr-4 autoload приведёт к тому, что файл, который находится по пути /src/ns1/conflictClass.php при таких настройках станет доступен как \ns1\conflictClass.

Нет, неймспейс задается в самом файле и не зависит от пути к нему. Пути в composer.json настраивают автозагрузчик и говорят, где искать файлы с данным классом, но не задают неймспейс для него.

> Тогда мне не очень понятно, чем является ключ в паре "": "classes/"

Префиксом полного имени класса. Документация: https://getcomposer.org/doc/04-schema.md#autoload

> Но если я в composer.json изменю ключ и приведу файл, например, к такому виду:
> То попытка вызвать \ns1\firstClass вернёт ошибку. Попытка вызвать \app\ns1\firstClass тоже вернёт ошибку, попытка вызвать \app\firstClass аналогично.

Ты сказал, что классы, чье имя начинается с app, надо искать в папке classes. Автозагрузчик следует твоему указанию.

> Влияет ли на что-нибудь файловая структура?

Она влияет на работу автозагрузчика, так как он полагается на стандарт PSR-4, а тот рекомендует использовать определенную структуру, где путь к файлу выводится из полного имени класса. И при нарушении правил автозагрузчик не найдет классы.

> Чем, всё-таки, является ключ в конфиге psr-4?

Префиксом полного имени класса.

> Является эдаким аналогом фразы "любые классы из любых неймспейсов ищи в папке classes" (конечно, библиотек загруженных через composer это не касается).

Это значит, что если более конкретным правилом найти класс не удалось, использовать этот вариант как запасной.

> Например, файл classes/foo/bar/buzz/user.php у которого указан namespace \project\foo\user.php будет доступен как, собственно, \project\foo\user.php

В имени класса не может быть точки. Ты не можешь назвать класс или неймспейс user.php. Прочти мой урок сначала.

Если после этого есть еще вопросы, то задавай. Кстати, твой пост довольно понятен, если читать его последовательно.

857 8 июня, 14:54 857 1413640

>>1412595

А ты читал мой урок по PSR-4? https://github.com/codedokode/pasta/blob/master/php/autoload.md

Также, прочти документацию в композере, а то я не хочу ее пересказывать: https://getcomposer.org/doc/04-schema.md#autoload

> Допустим, я имею следующую структуру файлов:
> firstClass.php

Обычно имена классов пишут с большой буквы без слова Class.

> Все php-файлы содержат в себе объявление класса и одного публичного метода, который выводит сообщение на экран. namespace в них не указан.

Тогда эти классы находятся в корневом неймспейсе. В какой папке они лежат, не важно.

> Я пишу в composer.json
> "psr-4":

Ты хочешь использовать PSR-4, но твой код не соответствует стандарту. Неудивительно, что оно не работает. Прочти мой урок для начала. Либо сам стандарт.

> Значит, структура каталогов может быть любой, вопрос в том, какие namespace я укажу у файлов?

Да, неймспейс задается словом namespace и не зависит от имени файла или папки. Но PSR-4 предлагает не раскидывать файлы как попало, а сделать структуру папок, соответствующую неймспейсам для облегчения поиска нужного файла. Автозагрузчик полагается на то, что ты следуешь PSR-4. Если ты не следуешь PSR-4, то ты должен либо писать свой автозагрузчик, либо попросить композер составить список твоих классов и пути к ним и использовать этот список (classmap).

> Просто на первый взгляд мне показалось, что использование composer psr-4 autoload приведёт к тому, что файл, который находится по пути /src/ns1/conflictClass.php при таких настройках станет доступен как \ns1\conflictClass.

Нет, неймспейс задается в самом файле и не зависит от пути к нему. Пути в composer.json настраивают автозагрузчик и говорят, где искать файлы с данным классом, но не задают неймспейс для него.

> Тогда мне не очень понятно, чем является ключ в паре "": "classes/"

Префиксом полного имени класса. Документация: https://getcomposer.org/doc/04-schema.md#autoload

> Но если я в composer.json изменю ключ и приведу файл, например, к такому виду:
> То попытка вызвать \ns1\firstClass вернёт ошибку. Попытка вызвать \app\ns1\firstClass тоже вернёт ошибку, попытка вызвать \app\firstClass аналогично.

Ты сказал, что классы, чье имя начинается с app, надо искать в папке classes. Автозагрузчик следует твоему указанию.

> Влияет ли на что-нибудь файловая структура?

Она влияет на работу автозагрузчика, так как он полагается на стандарт PSR-4, а тот рекомендует использовать определенную структуру, где путь к файлу выводится из полного имени класса. И при нарушении правил автозагрузчик не найдет классы.

> Чем, всё-таки, является ключ в конфиге psr-4?

Префиксом полного имени класса.

> Является эдаким аналогом фразы "любые классы из любых неймспейсов ищи в папке classes" (конечно, библиотек загруженных через composer это не касается).

Это значит, что если более конкретным правилом найти класс не удалось, использовать этот вариант как запасной.

> Например, файл classes/foo/bar/buzz/user.php у которого указан namespace \project\foo\user.php будет доступен как, собственно, \project\foo\user.php

В имени класса не может быть точки. Ты не можешь назвать класс или неймспейс user.php. Прочти мой урок сначала.

Если после этого есть еще вопросы, то задавай. Кстати, твой пост довольно понятен, если читать его последовательно.

Показать весь текст

858 8 июня, 14:55 858 1413642

>>1412337

> self::padLeft($department->getSalary() / $department->getProduction()
Если по какой-то причине production равен нулю, то будет фатальная ошибка деления на ноль. Везде, где ты видишь деление, ты должен гарантировать, что там никогда не будет деления на ноль.

> $pad = str_repeat(' ', $columnWidth - $nameWidth);

Если здесь число пробелов будет отрицательным, то произойдет ошибка.

> echo $name . $pad;

Разве функция не должна просто возвращать строку, а не выводить ее?

> public $stuff = array(); // перечень сотрудников

Это позволяет любому снаружи менять список сотрудников и даже записывать туда всякий мусор. Надежднее было бы применить инкапсуляцию и сделать свойства закрытыми, разрешив менять их только через методы.

А так у тебя, например, можно присвоить работнику любой ранг, хоть 9999, и это никак не проверяется.

> public function __construct($name)
Здесь нужен тайп-хинт string: https://www.php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration

Также желательно указать тип возвращаемого значения там, где это уместно.

> public function addEmployees(Employee $employee, $count = 1)
> for ($i = 1; $i <= $count; $i++) {
> $this->stuff[] = $employee;

Разберись, как работает передача объектов: https://www.php.net/manual/ru/language.oop5.references.php

Это очень важный момент.

Ты здесь не создаешь несколько независимых копий объектов, а кладешь в массив несколько указателей на один и тот же объект. Для простоты представь, что $employee хранит не сам объект, а лишь его уникальный номер, а сам объект расположен где-то в другой области памяти. Ты просто кладешь много раз в массив один и тот же номер, ссылающийся на один и тот же объект. И если ты что-то поменяешь в одном работнике, то это же поменяется и у других.

Новый экземпляр объекта создается только двумя операторами: new или clone. В остальных случаях просто копируется указатель (идентификатор) на существующий объект. Это в большинстве случаев и требуется, но когда ты добавляешь работников, тебе нужно именно несколько независимых объектов. А у тебя, получается, ты одного человека на несколько должностей назначил.

> static function anticrisis1(Company $company)

Имена функций принято начинать с глагола в стиле сделатьЧтоТо().

> global $engineer;

Это не годится, глобальные переменные это зло (например: представь, что у тебя 2 компании и в них разные условия для инженеров). Тебе правильнее было бы сделать в компании "справочник профессий" и брать данные о профессии оттуда. Либо же сделать константы для типов профессий и проверку вида $profession->getType() === TYPE_ENGINEER.

> unset($department->stuff[$j]);

Вот здесь нарушается принцип единой ответственности. Каждый класс отвечает за что-то свое, и не лезет в зону ответственности других классов. Получается логичная схема. Кто отвечает за ведение списка сотрудников, прием и увольнение? Очевидно, департамент. Ты же размазываешь ответственность за это по всему коду: у тебя антикризисный класс решает, какой порядок увольнения работника и откуда его надо удалять.

Чем это плохо? Это усложняет разбор кода (в случае единой ответственности, тебе достаточно изучить один класс, чтобы понять как ведется список сотрудников, в твоем случае - надо изучать весь код), усложняет модификацию (если ты захочешь поменять формат хранения списка, тебе придется обойти весь код и везде его исправлять). У тебя всего 5 классов, а представь, если бы их было 1000 и работа с сотрудниками была бы по ним всем размазана. Как такой код разбирать?

Правильно закрыть свойство staff от шаловливых ручек, а в Департаменте сделать методы для приема на работу, увольнения, поиска сотрудников, выдачи информации о них. То же касается смены лидера: лучше делать это в депертаменте специальным методом, который гарантирует корректность.

Вот тут есть паста про инкапсуляцию: https://github.com/codedokode/pasta/blob/master/php/encapsulation.md

> $analyticUpgrade = new Profession(75, 1100, 5);

Здесь появляется проблема, что у тебя теперь получается две профессии аналитика, хотя по факту профессия одна, просто человеку повысили зарплату. Как теперь определять, что человек - аналитик? Возможно, правильнее в объекте профессии хранить только зарплату по умолчанию, а фактическую - в работнике. Или вообще не хранить ее в профессии.

Отбор работников на увольнение проще делать так: собрать массив кандидатов, отсортировать по приоритету, взять часть функцией array_slice().

> } elseif ($employee->isLeader === 1 and $employee->profession != $analytic) {

Здесь нестрогое сравнение объектов.

> $department->stuff[$managers[$i]]->level = $lev + 1;

Тут тоже похоже на нарушение инкапсуляции.

858 8 июня, 14:55 858 1413642

>>1412337

> self::padLeft($department->getSalary() / $department->getProduction()
Если по какой-то причине production равен нулю, то будет фатальная ошибка деления на ноль. Везде, где ты видишь деление, ты должен гарантировать, что там никогда не будет деления на ноль.

> $pad = str_repeat(' ', $columnWidth - $nameWidth);

Если здесь число пробелов будет отрицательным, то произойдет ошибка.

> echo $name . $pad;

Разве функция не должна просто возвращать строку, а не выводить ее?

> public $stuff = array(); // перечень сотрудников

Это позволяет любому снаружи менять список сотрудников и даже записывать туда всякий мусор. Надежднее было бы применить инкапсуляцию и сделать свойства закрытыми, разрешив менять их только через методы.

А так у тебя, например, можно присвоить работнику любой ранг, хоть 9999, и это никак не проверяется.

> public function __construct($name)
Здесь нужен тайп-хинт string: https://www.php.net/manual/ru/functions.arguments.php#functions.arguments.type-declaration

Также желательно указать тип возвращаемого значения там, где это уместно.

> public function addEmployees(Employee $employee, $count = 1)
> for ($i = 1; $i <= $count; $i++) {
> $this->stuff[] = $employee;

Разберись, как работает передача объектов: https://www.php.net/manual/ru/language.oop5.references.php

Это очень важный момент.

Ты здесь не создаешь несколько независимых копий объектов, а кладешь в массив несколько указателей на один и тот же объект. Для простоты представь, что $employee хранит не сам объект, а лишь его уникальный номер, а сам объект расположен где-то в другой области памяти. Ты просто кладешь много раз в массив один и тот же номер, ссылающийся на один и тот же объект. И если ты что-то поменяешь в одном работнике, то это же поменяется и у других.

Новый экземпляр объекта создается только двумя операторами: new или clone. В остальных случаях просто копируется указатель (идентификатор) на существующий объект. Это в большинстве случаев и требуется, но когда ты добавляешь работников, тебе нужно именно несколько независимых объектов. А у тебя, получается, ты одного человека на несколько должностей назначил.

> static function anticrisis1(Company $company)

Имена функций принято начинать с глагола в стиле сделатьЧтоТо().

> global $engineer;

Это не годится, глобальные переменные это зло (например: представь, что у тебя 2 компании и в них разные условия для инженеров). Тебе правильнее было бы сделать в компании "справочник профессий" и брать данные о профессии оттуда. Либо же сделать константы для типов профессий и проверку вида $profession->getType() === TYPE_ENGINEER.

> unset($department->stuff[$j]);

Вот здесь нарушается принцип единой ответственности. Каждый класс отвечает за что-то свое, и не лезет в зону ответственности других классов. Получается логичная схема. Кто отвечает за ведение списка сотрудников, прием и увольнение? Очевидно, департамент. Ты же размазываешь ответственность за это по всему коду: у тебя антикризисный класс решает, какой порядок увольнения работника и откуда его надо удалять.

Чем это плохо? Это усложняет разбор кода (в случае единой ответственности, тебе достаточно изучить один класс, чтобы понять как ведется список сотрудников, в твоем случае - надо изучать весь код), усложняет модификацию (если ты захочешь поменять формат хранения списка, тебе придется обойти весь код и везде его исправлять). У тебя всего 5 классов, а представь, если бы их было 1000 и работа с сотрудниками была бы по ним всем размазана. Как такой код разбирать?

Правильно закрыть свойство staff от шаловливых ручек, а в Департаменте сделать методы для приема на работу, увольнения, поиска сотрудников, выдачи информации о них. То же касается смены лидера: лучше делать это в депертаменте специальным методом, который гарантирует корректность.

Вот тут есть паста про инкапсуляцию: https://github.com/codedokode/pasta/blob/master/php/encapsulation.md

> $analyticUpgrade = new Profession(75, 1100, 5);

Здесь появляется проблема, что у тебя теперь получается две профессии аналитика, хотя по факту профессия одна, просто человеку повысили зарплату. Как теперь определять, что человек - аналитик? Возможно, правильнее в объекте профессии хранить только зарплату по умолчанию, а фактическую - в работнике. Или вообще не хранить ее в профессии.

Отбор работников на увольнение проще делать так: собрать массив кандидатов, отсортировать по приоритету, взять часть функцией array_slice().

> } elseif ($employee->isLeader === 1 and $employee->profession != $analytic) {

Здесь нестрогое сравнение объектов.

> $department->stuff[$managers[$i]]->level = $lev + 1;

Тут тоже похоже на нарушение инкапсуляции.

Показать весь текст
Ответы414782

859 8 июня, 14:56 859 1413644

>>1412096

Не знаю, увы. Может быть, надо написать свой плагин или как-то настроить свойства товаров в CMS?

>>1411969

Найди логи веб-сервера и/или логи PHP и посмотри, нет ли там ошибок.

>>1411406

Адаптеры используют, если у тебя есть код, который, например, работает с несколькими библиотеками: адаптеры помогают "адаптировать" их под единый интерфейс. Если это не так, то лучше использовать библиотеку напрямую и не заниматься оверинжинирингом.

>>1411376

Зависит от железа и конфигурации. Протестируй. Утилиты для тестирования, по возрастанию возможностей: Apache Benchmark, siege, Яндекс-танк.

Ответы413895

860 8 июня, 14:57 860 1413645

>>1394979
>>1411268

> `token` varchar(64) NOT NULL,
> `points` smallint(6) NOT NULL,

тут хорошо бы добавить комментарий к полю словом COMMENT с пояснением.

> $class = str_replace('Students\\', '', $class);
Лучше использовать регулярку, так как Students может быть где-то в середине имени класса, а не только в начале.

> return '/' . ltrim(str_replace('index.php', '', $path), '/');

Та же проблема.

> $charset = $config['charset'];

Я не уверен, что есть смысл в этом параметре конфига. Это ведь кодировка соединения, в который твой код передает данные в БД (а не кодировка таблиц). Следовательно, чтобы ее поменять, надо добавлять перекодировку данных еще и во все функции, работающие с БД. Следовательно, этот параметр не работает и только вводит пользователя в заблуждение.

> $container->register('studentsDataGateway',

Кстати, сейчас модно использовать имя класса (StudentsDataGateway::class) как имя сервиса. Автодополнение работает, плюс защита от опечаток.

Router тоже можно было поместить в контейнер.

> https://github.com/codecoshauni/student-list/blob/master/src/Controllers/ProfileController.php#L30

Для вывода страницы ошибки лучше сделать метод, а не копипастить везде одинаковый код.

> if ($_GET['notice'] == 'reg') $notice = self::NOTICE_REG;

Лучше было сделать константу NOTICE_REG, равную 'reg', и отдельно - константу-массив с расшифровкой сообщений [self::NOTICE_REG => '....', ...]. А сейчас у тебя непонятно, какие вообще notice бывают и нет защиты от опечатки.

> $student = $this->createStudentFromPost();

При редактировании обычно загружают объект из БД и редактируют его, а после сохраняют. Так надежнее, так как в форме может быть меньше полей, чем в самом объекте, и в этом случае у тебя могут теряться значения полей.

> do {
> $token = bin2hex(random_bytes(32));
> } while($this->studentsDataGateway->isTokenExist($token));

Это стоит вынести в отдельный метод и добавить ограничение на число попыток для защиты от бесконечного цикла.

> $studentData['name'] = $student->getName();
> $studentData['surname'] = $student->getSurname();

Удобнее просто передать в шаблон сам объект студента.

Также, не вижу в коде проверки на то, что email уже используется. Обрати внимание, что при редактировании надо не выдавать ошибку на свой собственный email.

> strval($_POST['name']) ?? '';

Не выдаст ли это ошибку при отсутствии поля? Может быть ?? должен быть внутри скобок?

> $student = new \Students\Model\Student($name, $surname, $sex, $group_number, $email, $points, $birth_year, $habitation);

Удобнее либо задавать поля по одному, либо сделать метод вроде setAttributes, принимающий массив, либо принимать массив в конструкторе. Плохо делать конструктор с 8 аргументами.

> $offset = (($page - 1) * $this->studentsDataGateway::LIMIT);
Обычно перед константой пишут имя класса.

> if (is_null($limit)) $limit = StudentsDataGateway::LIMIT;
В if принято, вроде бы в каком-то PSR, всегда использовать фигурные скобки. Иначе проще допустить ошибку.

> public function markSearchValue($tablevalue)
Здесь есть риск, что поисковое слово поломает HTML-разметку. Допустим, $tablevalue = 'Ivan', $this->search = 'van mark'. Первая замена даст I<mark>van</mark>, вторая поломает HTML-тег.

Можно вместо этого разбить текст на массив совпадений/несовпадений, и делать повторную замену только внутри несовпадений. А после преобразовать массив в размеченный HTML.

Другой вариант - сделать замену через preg_replace_callback с хитрой регуляркой, собранной из поисковых слов.

> $searchValues = explode(' ', $this->search);

А что, если в поисковой фразе идет несколько пробелов подряд? Тогда в массиве будут пустые строки и они конечно найдутся в тексте.

> if (!$this->search) return $tablevalue;

Нет экранирования.

> return (implode('', $this->errors) == '') ? [] : $this->errors;
Убрать пустые элементы можно array_filter().

> [a-zA-Zа-яА-Я

Букву ё надо указать отдельно, она не входит внутрь [а-я] в кодировке utf-8, убедись сам: https://unicode-table.com/ru/#cyrillic

> "Sorry, but you ({$habitation}) is non-existent";

Лучше писать что-то вроде "Вы не указали место проживания".

> public function __construct($pdo)
Нужен тайп-хинт.

> public function getStudentsCount($searchValue = '')

Здесь SQL инъекция в параметре $searchValue. Надо использовать плейсхолдер.

Также, в поисковой фразе хорошо бы заменять пробелы на %.

https://github.com/codecoshauni/student-list/blob/master/src/Model/StudentsDataGateway.php#L121

Здесь SQL инъекция в параметре order. Надо проверять его по белому списку разрешенных значений. Урок по инъекциям: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

> <input class='field write' type="text" name="name" maxlength="20" placeholder="less than 21 letters"
> pattern="[A-Za-zА-Яа-яЁё]+$"
Паттерн не соответствует паттерну в серверном валидаторе. Хорошо бы, конечно, держать эти паттерны рядом.

> <label for='ml'>Male</label>
Чтобы не писать for, можно просто обернуть input в label.

> https://github.com/codecoshauni/student-list/blob/master/templates/students-list.php

Не надо копипастить шапку и подвал в каждом шаблоне. То же касается CSS.

> <?php if ($listOutputHelper->getOrderBy() == 'name') echo

Тут лучше использовать специальный if с двоеточием для шаблонов. Писать внутри кавычек HTML очень неудобно.

> https://github.com/codecoshauni/student-list/blob/master/public/css/fontstyle.css#L12
> font-family: 'Roboto Mono Bold';

Это семейство Roboto Mono, просто с жирным весом, надо было указать в определении font-weight: bold. А из-за твоего определения, во-первых, не подхватится установленный на компьютере шрифт, во-вторых, если ты в тексте с Roboto Mono Regular добавишь тег strong, браузер будет использовать искуственную жирность вместо нужного начертания.

Посмотри, как шрифт определен в Google Fonts: https://fonts.google.com/specimen/Roboto+Mono?selection.family=Roboto+Mono

Там жмем use this font, затем копируем ссылку на CSS: https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap и смотрим этот CSS. У них, правда, почему-то для IE ничего не предлагается, и версия только woff2, что мне не нравится. Но ты все равно посмотри.

> header a {

это в общем плохая идея, так как завтра кто-то захочет добавить в заголовок ссылку в другом стиле и правила будут ему мешать. Лучше использовать класс для ссылки или класс для меню со ссылками.

Еще плохо, что при наведении на номер страницы все номера справа сдвигаются.

Также, проверь, подвержен ли твой сайт уязвимости XSRF: https://github.com/codedokode/pasta/blob/master/security/xsrf.md

Так, если бы не SQL-инъекции, я бы сказал, что хорошая работа, но уязвимости в коде оставлять - это плохо.

860 8 июня, 14:57 860 1413645

>>1394979
>>1411268

> `token` varchar(64) NOT NULL,
> `points` smallint(6) NOT NULL,

тут хорошо бы добавить комментарий к полю словом COMMENT с пояснением.

> $class = str_replace('Students\\', '', $class);
Лучше использовать регулярку, так как Students может быть где-то в середине имени класса, а не только в начале.

> return '/' . ltrim(str_replace('index.php', '', $path), '/');

Та же проблема.

> $charset = $config['charset'];

Я не уверен, что есть смысл в этом параметре конфига. Это ведь кодировка соединения, в который твой код передает данные в БД (а не кодировка таблиц). Следовательно, чтобы ее поменять, надо добавлять перекодировку данных еще и во все функции, работающие с БД. Следовательно, этот параметр не работает и только вводит пользователя в заблуждение.

> $container->register('studentsDataGateway',

Кстати, сейчас модно использовать имя класса (StudentsDataGateway::class) как имя сервиса. Автодополнение работает, плюс защита от опечаток.

Router тоже можно было поместить в контейнер.

> https://github.com/codecoshauni/student-list/blob/master/src/Controllers/ProfileController.php#L30

Для вывода страницы ошибки лучше сделать метод, а не копипастить везде одинаковый код.

> if ($_GET['notice'] == 'reg') $notice = self::NOTICE_REG;

Лучше было сделать константу NOTICE_REG, равную 'reg', и отдельно - константу-массив с расшифровкой сообщений [self::NOTICE_REG => '....', ...]. А сейчас у тебя непонятно, какие вообще notice бывают и нет защиты от опечатки.

> $student = $this->createStudentFromPost();

При редактировании обычно загружают объект из БД и редактируют его, а после сохраняют. Так надежнее, так как в форме может быть меньше полей, чем в самом объекте, и в этом случае у тебя могут теряться значения полей.

> do {
> $token = bin2hex(random_bytes(32));
> } while($this->studentsDataGateway->isTokenExist($token));

Это стоит вынести в отдельный метод и добавить ограничение на число попыток для защиты от бесконечного цикла.

> $studentData['name'] = $student->getName();
> $studentData['surname'] = $student->getSurname();

Удобнее просто передать в шаблон сам объект студента.

Также, не вижу в коде проверки на то, что email уже используется. Обрати внимание, что при редактировании надо не выдавать ошибку на свой собственный email.

> strval($_POST['name']) ?? '';

Не выдаст ли это ошибку при отсутствии поля? Может быть ?? должен быть внутри скобок?

> $student = new \Students\Model\Student($name, $surname, $sex, $group_number, $email, $points, $birth_year, $habitation);

Удобнее либо задавать поля по одному, либо сделать метод вроде setAttributes, принимающий массив, либо принимать массив в конструкторе. Плохо делать конструктор с 8 аргументами.

> $offset = (($page - 1) * $this->studentsDataGateway::LIMIT);
Обычно перед константой пишут имя класса.

> if (is_null($limit)) $limit = StudentsDataGateway::LIMIT;
В if принято, вроде бы в каком-то PSR, всегда использовать фигурные скобки. Иначе проще допустить ошибку.

> public function markSearchValue($tablevalue)
Здесь есть риск, что поисковое слово поломает HTML-разметку. Допустим, $tablevalue = 'Ivan', $this->search = 'van mark'. Первая замена даст I<mark>van</mark>, вторая поломает HTML-тег.

Можно вместо этого разбить текст на массив совпадений/несовпадений, и делать повторную замену только внутри несовпадений. А после преобразовать массив в размеченный HTML.

Другой вариант - сделать замену через preg_replace_callback с хитрой регуляркой, собранной из поисковых слов.

> $searchValues = explode(' ', $this->search);

А что, если в поисковой фразе идет несколько пробелов подряд? Тогда в массиве будут пустые строки и они конечно найдутся в тексте.

> if (!$this->search) return $tablevalue;

Нет экранирования.

> return (implode('', $this->errors) == '') ? [] : $this->errors;
Убрать пустые элементы можно array_filter().

> [a-zA-Zа-яА-Я

Букву ё надо указать отдельно, она не входит внутрь [а-я] в кодировке utf-8, убедись сам: https://unicode-table.com/ru/#cyrillic

> "Sorry, but you ({$habitation}) is non-existent";

Лучше писать что-то вроде "Вы не указали место проживания".

> public function __construct($pdo)
Нужен тайп-хинт.

> public function getStudentsCount($searchValue = '')

Здесь SQL инъекция в параметре $searchValue. Надо использовать плейсхолдер.

Также, в поисковой фразе хорошо бы заменять пробелы на %.

https://github.com/codecoshauni/student-list/blob/master/src/Model/StudentsDataGateway.php#L121

Здесь SQL инъекция в параметре order. Надо проверять его по белому списку разрешенных значений. Урок по инъекциям: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

> <input class='field write' type="text" name="name" maxlength="20" placeholder="less than 21 letters"
> pattern="[A-Za-zА-Яа-яЁё]+$"
Паттерн не соответствует паттерну в серверном валидаторе. Хорошо бы, конечно, держать эти паттерны рядом.

> <label for='ml'>Male</label>
Чтобы не писать for, можно просто обернуть input в label.

> https://github.com/codecoshauni/student-list/blob/master/templates/students-list.php

Не надо копипастить шапку и подвал в каждом шаблоне. То же касается CSS.

> <?php if ($listOutputHelper->getOrderBy() == 'name') echo

Тут лучше использовать специальный if с двоеточием для шаблонов. Писать внутри кавычек HTML очень неудобно.

> https://github.com/codecoshauni/student-list/blob/master/public/css/fontstyle.css#L12
> font-family: 'Roboto Mono Bold';

Это семейство Roboto Mono, просто с жирным весом, надо было указать в определении font-weight: bold. А из-за твоего определения, во-первых, не подхватится установленный на компьютере шрифт, во-вторых, если ты в тексте с Roboto Mono Regular добавишь тег strong, браузер будет использовать искуственную жирность вместо нужного начертания.

Посмотри, как шрифт определен в Google Fonts: https://fonts.google.com/specimen/Roboto+Mono?selection.family=Roboto+Mono

Там жмем use this font, затем копируем ссылку на CSS: https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap и смотрим этот CSS. У них, правда, почему-то для IE ничего не предлагается, и версия только woff2, что мне не нравится. Но ты все равно посмотри.

> header a {

это в общем плохая идея, так как завтра кто-то захочет добавить в заголовок ссылку в другом стиле и правила будут ему мешать. Лучше использовать класс для ссылки или класс для меню со ссылками.

Еще плохо, что при наведении на номер страницы все номера справа сдвигаются.

Также, проверь, подвержен ли твой сайт уязвимости XSRF: https://github.com/codedokode/pasta/blob/master/security/xsrf.md

Так, если бы не SQL-инъекции, я бы сказал, что хорошая работа, но уязвимости в коде оставлять - это плохо.

Показать весь текст

https://github.com/artMonkey1/Students/ 861 8 июня, 14:58 861 1413646

>>1395840
>>1399017

> `password` varchar(255) DEFAULT NULL
Тут не помешал бы комментарий к колонке со словом COMMENT, что там хранится.

> `gender` varchar(15) NOT NULL
Тут лучше использовать ENUM.

Стоит добавить уникальный ключ по email.

Стоит добавить README.

> ini_set('display_errors',1);

Это неудобно тем, что непонятно, как его выключать при выгрузке на продакшен. Лучше менять настройку в php.ini или хотя бы в конфиге.

> if($router->run() != true){
> include ROOT . 'public/views/404.php';

Мало показать страницу, надо еще выставить HTTP-код ответа (код состояния) в 404.

> https://github.com/artMonkey1/Students/blob/master/app/components/Autoloader.php

Надо проверять, что файл существует, перед подключением. А то у тебя код вроде if (class_exists('ssss')) вызовет ошибку.

Вместо возврата true/false удобнее выбрасывать исключение при 404 и ловить его, либо самостоятельно из контроллера вызывать функцию вывода страницы ошибки.

> $page = $_GET['page'] ? $_GET['page'] : 1;

Если в GET нет элемента page, тут будет notice. Ты его не видел? Либо у тебя отключен показ ошибок, либо включено игнорирование нотисов. Лучше всего превращать любые ошибки в исключения через set_error_handler, пример кода есть в мануале, тогда не заметить их не получится.

> header("Location: /list/?&page=1");
А зачем амперсанд? И параметр page?

Функция регистрации и редактирования профиля очень похожи. Надо посмотреть, можно ли избежать копипаста кода и шаблонов для них. Незачем два раза писать почти одинаковый код.

При регистрации gender почему-то не передается в валидатор.

Удобнее сделать модель студента (информацию о студенте) объектом, а не массивом. Сейчас у тебя есть куча функций, куда передается этот массив, и его формат даже не описан в комментариях. Как работать с таким кодом? Как понять, какие поля есть в массиве и какого они типа? Ключевой объект лучше сделать строго типизированным объектом со строго определенными полями. У нас же ООП, а не массиво-ориентированное программирование.

> public static function registration($user = array())

Зачем тут возможность передать пустой массив? Чтобы зарегистрировать пустого пользователя?

> public static function getStudentsList($page, $orderBy, $dir)

Здесь стоит использовать тайп-хинты вроде int, и тайп-хинт на возвращаемое значение.

Функции getStudentsList и getStudentsListFromSearch очень похожи и их стоит объединить.

При ошибке работы с БД ты возвращаешь false, но при режиме выброса исключеий в PDO он не вернет false. Нет смысла проверять это значение.

Код станет чище, если вместо статических методов и синглтонов ты будешь исплоьзовать DI для связи классов, урок: https://github.com/codedokode/pasta/blob/master/arch/di.md

При проверке существования email правильнее использовать SELECT COUNT(...)...

> https://github.com/artMonkey1/Students/blob/e4d4b2d66cd8f481d0a1681cd5b4a141ebd0fa18/app/controllers/CabinetController.php#L31

Здесь функция checkLogged() может сделать редирект, но ты даже в этом случае выполняешь код и выводишь страницу, которую никто не увидит.

Класс User правильнее было бы назвать AuthHelper. Он не представляет объект пользователя.

Вместо сессии, возможно, лучше было бы использовать куки. Сессия умирает по умолчанию после 30 минут неактивности, если не путаю. Можно повысить время, но это приведет к накоплению файлов сессий.

При удалении пользователя, у тебя остается его id в сессии и он вроде как считается залогиненным, хотя данные уже удалены. Не вызовет ли это ошибки?

При разлогинивании, возможно, лучше полностью уничтожать сессию, вдруг потом в нее добавят еще какие-то элементы и они будут оставаться после разлогинивания. А возможно, и не стоит уничтожать.

Параметр charset в конфиге не имеет смысла, так как это кодировка соединения, и при ее смене надо также поменять весь код, который передает данные в БД.

Также, вместо utf8 лучше использовать utf8mb4, который является полноценной версией UTF-8.

Также, надо более тщательно проверять URL, чтобы нельзя было дописать мусор в конец URL и получить ту же страницу (по типу http://example.com/cabinet/index/1456789). Это как минимум повредит поисковой оптимизации.

views не должны быть в public, так как их бессмысленно вызывать напрямую и они содержат код приложения.

> <p>Email: <?php echo $user['email']; ?></p>
при выводе надо экранировать данные htmlspecialchars(), читай урок https://github.com/codedokode/pasta/blob/master/security/xss.md

> https://github.com/artMonkey1/Students/blob/master/public/views/cabinet/delete.php
Тут узявимость CSRF: https://github.com/codedokode/pasta/blob/master/security/xsrf.md

> https://github.com/artMonkey1/Students/blob/master/public/views/cabinet/edit.php#L19
Здесь уязвимость XSS в инпутах.

> https://github.com/artMonkey1/Students/blob/master/public/views/site/error.php#L7
И здесь, по-моему, тоже.

При показе результатов поиска хорошо бы сохранять в инпуте введенное значение.

> https://github.com/artMonkey1/Students/blob/master/public/views/user/registration.php
Здесь стоит добавить HTML5 валидацию в форму.

https://github.com/artMonkey1/Students/blob/master/app/components/Linker.php
Тут лучше бы не использовать доступ к GET, а получать параметры отображения при создании. Чтобы было разделение ответственности, и класс не определял эти параметры сам. То есть, это задача контроллера разобрать параметры сортировки.

> https://github.com/artMonkey1/Students/blob/master/app/components/Pagination.php#L65
HTML-код луше помещать в шаблон.

> self::validEmail();
Нестатические методы надо вызывать через $this.

> if (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
> $this->errors[] = 'Имя больше 50 символов!';
По моему, текст неправильный.

> if (!strlen($this->password) > 8) {
strlen неправильно считает длину строки в utf-8. Попробуй вывести, что вернет strlen("привет")

> foreach($validParams as $property => $value){
> $this->$property = $value;
Так можно добавить в объект поля, которых в нем изначально не было.

> if(!preg_match("/[а-яёА-ЯЁa-zA-Z]{2,50}/u", $this->firstName)){
Нет привязки к краям строки. То есть строка "&&&&&&&имя???" пройдет тест.

> if(0 > $this->totalPoints && 300 > $this->totalPoints){
Это точно не ошибка?

В общем, пока много чего стоит исправить. Задавай вопросы, если что-то непонятно. Я бы также советовал перечитать комментарии к задаче, там много полезных советов.

https://github.com/artMonkey1/Students/ 861 8 июня, 14:58 861 1413646

>>1395840
>>1399017

> `password` varchar(255) DEFAULT NULL
Тут не помешал бы комментарий к колонке со словом COMMENT, что там хранится.

> `gender` varchar(15) NOT NULL
Тут лучше использовать ENUM.

Стоит добавить уникальный ключ по email.

Стоит добавить README.

> ini_set('display_errors',1);

Это неудобно тем, что непонятно, как его выключать при выгрузке на продакшен. Лучше менять настройку в php.ini или хотя бы в конфиге.

> if($router->run() != true){
> include ROOT . 'public/views/404.php';

Мало показать страницу, надо еще выставить HTTP-код ответа (код состояния) в 404.

> https://github.com/artMonkey1/Students/blob/master/app/components/Autoloader.php

Надо проверять, что файл существует, перед подключением. А то у тебя код вроде if (class_exists('ssss')) вызовет ошибку.

Вместо возврата true/false удобнее выбрасывать исключение при 404 и ловить его, либо самостоятельно из контроллера вызывать функцию вывода страницы ошибки.

> $page = $_GET['page'] ? $_GET['page'] : 1;

Если в GET нет элемента page, тут будет notice. Ты его не видел? Либо у тебя отключен показ ошибок, либо включено игнорирование нотисов. Лучше всего превращать любые ошибки в исключения через set_error_handler, пример кода есть в мануале, тогда не заметить их не получится.

> header("Location: /list/?&page=1");
А зачем амперсанд? И параметр page?

Функция регистрации и редактирования профиля очень похожи. Надо посмотреть, можно ли избежать копипаста кода и шаблонов для них. Незачем два раза писать почти одинаковый код.

При регистрации gender почему-то не передается в валидатор.

Удобнее сделать модель студента (информацию о студенте) объектом, а не массивом. Сейчас у тебя есть куча функций, куда передается этот массив, и его формат даже не описан в комментариях. Как работать с таким кодом? Как понять, какие поля есть в массиве и какого они типа? Ключевой объект лучше сделать строго типизированным объектом со строго определенными полями. У нас же ООП, а не массиво-ориентированное программирование.

> public static function registration($user = array())

Зачем тут возможность передать пустой массив? Чтобы зарегистрировать пустого пользователя?

> public static function getStudentsList($page, $orderBy, $dir)

Здесь стоит использовать тайп-хинты вроде int, и тайп-хинт на возвращаемое значение.

Функции getStudentsList и getStudentsListFromSearch очень похожи и их стоит объединить.

При ошибке работы с БД ты возвращаешь false, но при режиме выброса исключеий в PDO он не вернет false. Нет смысла проверять это значение.

Код станет чище, если вместо статических методов и синглтонов ты будешь исплоьзовать DI для связи классов, урок: https://github.com/codedokode/pasta/blob/master/arch/di.md

При проверке существования email правильнее использовать SELECT COUNT(...)...

> https://github.com/artMonkey1/Students/blob/e4d4b2d66cd8f481d0a1681cd5b4a141ebd0fa18/app/controllers/CabinetController.php#L31

Здесь функция checkLogged() может сделать редирект, но ты даже в этом случае выполняешь код и выводишь страницу, которую никто не увидит.

Класс User правильнее было бы назвать AuthHelper. Он не представляет объект пользователя.

Вместо сессии, возможно, лучше было бы использовать куки. Сессия умирает по умолчанию после 30 минут неактивности, если не путаю. Можно повысить время, но это приведет к накоплению файлов сессий.

При удалении пользователя, у тебя остается его id в сессии и он вроде как считается залогиненным, хотя данные уже удалены. Не вызовет ли это ошибки?

При разлогинивании, возможно, лучше полностью уничтожать сессию, вдруг потом в нее добавят еще какие-то элементы и они будут оставаться после разлогинивания. А возможно, и не стоит уничтожать.

Параметр charset в конфиге не имеет смысла, так как это кодировка соединения, и при ее смене надо также поменять весь код, который передает данные в БД.

Также, вместо utf8 лучше использовать utf8mb4, который является полноценной версией UTF-8.

Также, надо более тщательно проверять URL, чтобы нельзя было дописать мусор в конец URL и получить ту же страницу (по типу http://example.com/cabinet/index/1456789). Это как минимум повредит поисковой оптимизации.

views не должны быть в public, так как их бессмысленно вызывать напрямую и они содержат код приложения.

> <p>Email: <?php echo $user['email']; ?></p>
при выводе надо экранировать данные htmlspecialchars(), читай урок https://github.com/codedokode/pasta/blob/master/security/xss.md

> https://github.com/artMonkey1/Students/blob/master/public/views/cabinet/delete.php
Тут узявимость CSRF: https://github.com/codedokode/pasta/blob/master/security/xsrf.md

> https://github.com/artMonkey1/Students/blob/master/public/views/cabinet/edit.php#L19
Здесь уязвимость XSS в инпутах.

> https://github.com/artMonkey1/Students/blob/master/public/views/site/error.php#L7
И здесь, по-моему, тоже.

При показе результатов поиска хорошо бы сохранять в инпуте введенное значение.

> https://github.com/artMonkey1/Students/blob/master/public/views/user/registration.php
Здесь стоит добавить HTML5 валидацию в форму.

https://github.com/artMonkey1/Students/blob/master/app/components/Linker.php
Тут лучше бы не использовать доступ к GET, а получать параметры отображения при создании. Чтобы было разделение ответственности, и класс не определял эти параметры сам. То есть, это задача контроллера разобрать параметры сортировки.

> https://github.com/artMonkey1/Students/blob/master/app/components/Pagination.php#L65
HTML-код луше помещать в шаблон.

> self::validEmail();
Нестатические методы надо вызывать через $this.

> if (!filter_var($this->email, FILTER_VALIDATE_EMAIL)) {
> $this->errors[] = 'Имя больше 50 символов!';
По моему, текст неправильный.

> if (!strlen($this->password) > 8) {
strlen неправильно считает длину строки в utf-8. Попробуй вывести, что вернет strlen("привет")

> foreach($validParams as $property => $value){
> $this->$property = $value;
Так можно добавить в объект поля, которых в нем изначально не было.

> if(!preg_match("/[а-яёА-ЯЁa-zA-Z]{2,50}/u", $this->firstName)){
Нет привязки к краям строки. То есть строка "&&&&&&&имя???" пройдет тест.

> if(0 > $this->totalPoints && 300 > $this->totalPoints){
Это точно не ошибка?

В общем, пока много чего стоит исправить. Задавай вопросы, если что-то непонятно. Я бы также советовал перечитать комментарии к задаче, там много полезных советов.

Показать весь текст

862 8 июня, 14:59 862 1413647

>>1398828

Если твой PHP скрипт вызывается в ответ на аякс-запрос, то PHP вообще ничего вывести не может. Результат его работы передается яваскрипту, и тут решает, что с ним делать - вставить на страницу или выкинуть. В этом смысл аякса.

863 8 июня, 15:17 863 1413654

Очень понравилась трава в учебнике по пхп. Спасибо, ОП!

864 8 июня, 23:47 864 1413895

>>1413644
>Адаптеры используют, если у тебя есть код, который, например, работает с несколькими библиотеками
В нескольких местах использовался. Потому и спрашивал - что подозрения появились.

865 9 июня, 09:01 865 1413953

>>1413638
>Обычно пишут на фреймворках.
А если фреймворк не может решит определённую задачу, то что тогда делать ?

Ответы413993

866 9 июня, 10:49 866 1413976

>>1413638
>>1413472
Спасибо, няши.
Добра вам.

Скобки-кун

867 9 июня, 11:48 867 1413985

ебать я тупой, не могу понять, что делать дальше после создания формы заполнения для студентов, пержу пару дней уже

Ответы413990414013

868 9 июня, 12:02 868 1413990

>>1413985
У меня тоже такое долго шло. Это от недостатка опыта наверное.
Попробуй сперва расписать обычными словами алгоритм.

869 9 июня, 12:06 869 1413993

>>1413953
Они под неопределённые задачи и используются, а на типовую штамповку есть разные CMS.

870 9 июня, 13:17 870 1414013

>>1413985

А тут не смотрел алгоритм работы с формами? https://github.com/codedokode/pasta/blob/master/forms.md

Это не поможет?

871 9 июня, 14:07 871 1414039

>Обычно пишут на фреймворках.
вопрос был о целесообразности использовать пыху вообще в 2019г

872 9 июня, 14:46 872 1414054

Йоу, что можно прочитать про CURL, чтобы прям для дебилов

Ответы414156

873 9 июня, 14:50 873 1414055

Изучил ооп и архитектуру mvc, куда двигаться дальше?

874 9 июня, 15:23 874 1414064

https://ideone.com/cYEU4u#stdin
Не могу понять как вывести слова в соответствии стиху

Ответы414105

875 9 июня, 16:43 875 1414105

>>1414064
https://ideone.com/cYEU4u#stdin
сделал какой-то ужасный костыль

876 9 июня, 16:55 876 1414111

как же тянет блевать от пхп...

Ответы414122

18 Кб, 288x399
sage 877 9 июня, 17:06 877 1414122

>>1414111
А почему рот в говне

Ответы414129

878 9 июня, 17:27 878 1414129

>>1414122
издержки профессии

sage 879 9 июня, 18:08 879 1414150

Щито я делаю не так, эксперты?
Можно ли как-то обойтись без этого "Итога"?
Чтобы, например, если я ввожу зашифрованный текст, он отображался в "Оригинале", потом расшифровывался и этот расшифрованный текст отображался в "Шифровке".
А если я ввожу текст, чтобы его зашифровать, он тоже отображался в "Оригинале", и он в зашифрованном виде отображался в "Шифровке"?
https://ideone.com/mYR9Ae

Ответы414151414160

880 9 июня, 18:09 880 1414151

>>1414150
Сорян, сажа прилипла

881 9 июня, 18:29 881 1414156

>>1414054
Документацию.

882 9 июня, 18:33 882 1414160

>>1414150
Да, конечно можно. Думаю, что ты и сам способен переделать как надо.

Ответы414165

883 9 июня, 18:38 883 1414165

>>1414160
Ладно, спасибо
Щас буду траить

Ответы414180

884 9 июня, 19:02 884 1414180

>>1414165
Ну вот так вроде норм

Ответы414182

885 9 июня, 19:02 885 1414182

>>1414180
https://ideone.com/WALkhq

886 9 июня, 21:59 886 1414240

В самом начале пути.
Помогайте и добро вернется добром

В задаче от анона, нужно вычислить за сколько лет накопится миллион если откладывать по 10тыс.

В цикл for нужно подставлять годы или потоянный платеж++ ?

Понятное дело, меня подмывает вставить просто формулу сложных процентов, но смысл в том, чтобы использовать циклы, как я понимаю, и написать код в несколько строчек

Ответы414243414306

887 9 июня, 22:17 887 1414243

>>1414240
>Помогайте
Бох в помощь.

888 10 июня, 00:48 888 1414306

>>1414240
Попробуй в уме посчитать, получишь алгоритм. Или на листике

39 Кб, 720x405
889 10 июня, 05:28 889 1414333

В интернете столько материала, что не знаю с чего начать. Я изучил ООП на php, что дальше ? Хотелось бы найти полный курс с последовательными темами.

Ответы414373

890 10 июня, 08:50 890 1414373

>>1414333
пили свой двач

891 10 июня, 15:39 891 1414520

https://habr.com/ru/post/348234/
Можете мне коротко расписать, как реализовать это на php (без библиотек)? Не понимаю, как он взаимодействует с "агентом".
Вот есть у меня ссылка на файл, который я гружу на сервер телеграма через API и работаю уже с полученным file id. Ограничение на ссылки даже не 50, а 20 мб - беда. Как мне взаимодействовать с зарегистрированным приложением, чтобы грузить файлы больше 20 и 50 мб, имея только ссылку?

Ответы414548414756

892 10 июня, 16:53 892 1414548

>>1414520
Или, может, есть подходящая библиотека для работы с api приложения. Потому что я пока не понимаю, как работать с теми методами.

Ответы414756

893 10 июня, 18:13 893 1414574

Пиздос, в ваш тред зайти невозможно, прогружается 2 часа. Пилите перекат уже, что ли. Или я запилю.

Ответы414584

894 10 июня, 18:55 894 1414584

>>1414574

Погоди немножечко, скоро сделаем.

895 11 июня, 02:33 895 1414717

Поржать принес
https://www.youtube.com/watch?v=VlN_8O2_ZkE

Ответы414740

896 11 июня, 03:07 896 1414722

Чуть не сошел с ума, пока решал задачи про регулярные выражения.
Как же хорошо, что все позади.

897 11 июня, 05:24 897 1414740

>>1414717
А в чём комичность ?

Ответы414798

898 11 июня, 07:48 898 1414756

>>1414520
> как реализовать это на php (без библиотек)?
Никак. Для общения с серверами телеграма нужно использовать их протокол - mtproto, у телеграма нет REST API как у других сервисов. Нужна библиотека, которая умеет по этому протоколу общаться, например: https://github.com/danog/MadelineProto
По моему опыту библиотека просто отвратительная, постоянно ломают API, всё на магических методах, запутанный код внутри: https://github.com/danog/MadelineProto/blob/master/src/danog/MadelineProto/TL/TL.php

>>1414548
Алгоритм простой - регистрируешь приложение на сайте телеграма, получаешь ключи и с этими ключами логинишься в скрипте, у MadelineProto есть готовый скрипт, нужно будет ввести номер и дальше можно пользоваться API пользователя (не бота).

Ответы414799414802415145

899 11 июня, 10:44 899 1414782

>>1413642
Большое спасибо за разбор! Принимаюсь за список студентов

900 11 июня, 12:29 900 1414798

>>1414740
Ну что она называет язык ПэХэПэ,
А еще когда выбирает имя хоста ,рекомендует локалхост потому что это "оптимальный вариант" и скорее всего не понимает зачем это ваще.

Ответы414801

sage 901 11 июня, 12:29 901 1414799

>>1414756
>Никак.
>у телеграма нет REST API
Так-то всё есть - и АПИ, и библиотеки. Я и на чистом писал, было дело.

Ответы414801414802

902 11 июня, 12:33 902 1414801

>>1414798
Ничего смешного в этом нету, скорее грустое - за обучение берутся те, кто сам ничего не понимает.

>>1414799
Сажа прилипла.

Ответы414804

903 11 июня, 12:35 903 1414802

>>1414756
Спасибо. Наверное, загрузка по ссылке там не работает и нужно работать только с файлами?
>>1414799
Это про апи приложения, а не апи бота.

904 11 июня, 12:42 904 1414804

>>1414801
Обоже смотрите какие мы интелегенты, совсем не смеемся над обычными шутками. .. ищем трагичность

Ответы414805

905 11 июня, 12:45 905 1414805

>>1414804
Над таким обычно смеются только те, кто сами не далеко ушли по уровню знаний.

Ответы414857

906 11 июня, 16:29 906 1414857

>>1414805
Гении вообще не смеются, да?

6 Кб, 519x116
907 12 июня, 09:58 907 1415096

Объясните что делает этот код

Ответы415105

908 12 июня, 10:29 908 1415105

>>1415096
Запрос к бд с выборкой по полям

Ответы415180

909 12 июня, 11:48 909 1415145

>>1414756
Так и не проверил, работает ли отправка файла со ссылки. Но обнаружил проблему при использовании бот апи. Долго искал, в чем проблема - ошибку не возвращал ни телеграм, ни curl - ссылка просто не открывалась. Обнаружил, что дело в описании файла, которое парсится, как и сама ссылка на файл. Curl только пару раз (во время экспериментов) возвращал ошибку "Curl option contains invalid characters (\0)", но обычно молча отказывался открывать ссылку. Описание, на вид, на латинице. Кодировка utf-8. Но в чём же проблема? Постоянно какая-то хуйня с этими кодировками. Я просто уже не знаю, как мне обрабатывать строку, чтобы с ней не было проблем. Хелп ми!

Ответы415175

77 Кб, 1397x87
910 12 июня, 12:48 910 1415175

>>1415145
Попробовал оставить только латиницу, даже пробелы с цифрами убрал, но всё равно именно эта строка не работает. Я уже вообще не понимаю, как такое может быть. Вот, заскринил, работает только последняя строка, а предыдущие 2 не возвращают ничего - ни ошибки curl, ни ошибки телеграм api. Как так? Таких 2 описания из 30 где-то.

Ответы415191

911 12 июня, 12:57 911 1415180

>>1415105
А возможно это сделать через foreach ?

912 12 июня, 13:24 912 1415191

>>1415175
>curl_get_contents
Что за параша? Ты нам васянские говнолибы разбирать предлагаешь?

Ответы415215

913 12 июня, 13:40 913 1415215

>>1415191
Там простейшая функция, никаких говнолиб.
$curl = curl_init();
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_AUTOREFERER, 1);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_HEADER, 0);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 120);
curl_setopt($curl, CURLOPT_CAINFO, __DIR__ . '/cacert.pem');
curl_setopt($curl, CURLOPT_USERAGENT, $ua);
curl_setopt($curl, CURLOPT_URL, $page_url);
$curlname = curl_exec($curl);

if($errno = curl_errno($curl)) {
$error_message = curl_strerror($errno);
return "Error: ($errno): $error_message ";
} else { return $curlname; }

11 Кб, 621x117
914 12 июня, 14:33 914 1415251

for ($i=10000; $i<1000000; $i=$i+$i*0.1) {
echo "На счету в банке $i рублей\n";
}

Я выполнить задачу

Ответы415253415260415576

915 12 июня, 14:33 915 1415253

>>1415251
*выполнил задачу?

916 12 июня, 15:01 916 1415260

>>1415251
Ну и где в твоём решении выполненые остальные условия?

Ответы415273

917 12 июня, 15:16 917 1415273

>>1415260
Тогда я не знаю как. Помоги, пожалуйста :\

Ответы415277

918 12 июня, 15:17 918 1415277

>>1415273
На работе так же будешь просить за тебя доделать? Пока не поздно выбери другую профессию. Программирование это не твоё.

Ответы415279

919 12 июня, 15:19 919 1415279

>>1415277
Чего?

Ответы415362

920 12 июня, 16:42 920 1415362

>>1415279
Тут азы не расжёвывают - всё самому надо делать. Тут бесплатная школа программирования, а просто тусовочка пхпшников. Обкашлять паттерны, архитектурку и т.д. это запросто, но не сраные азы, которые дрочит каждый сам. Не можешь сам - никто тебе не поможет.

Ответы415363415393

921 12 июня, 16:42 921 1415363

>>1415362
>Тут бесплатная школа программирования
не бесплатная

922 12 июня, 17:24 922 1415376

Когда с фронтенда отправляю POST через джейквери, на сервер-сайде все бывшие булевыми поля в $_POST появляются в виде строк "true" и "false". Что за хуйня, оно так и должно быть? Это можно исправить?

Ответы415409

923 12 июня, 17:49 923 1415393

>>1415362
Тогда понятно

924 12 июня, 18:37 924 1415409

>>1415376
Если они отправляются, то значит так и должно быть.

Ответы415439

925 12 июня, 19:35 925 1415438

Как думаете если держать сайт с картинками в хайрезе, при каком количестве посетителей все начнет падать? Какие решения нужно принять на этапе написания что бы в самом начале подстелить соломку на случай популярности?

926 12 июня, 19:36 926 1415439

>>1415409
Почему джаваскриптовое false на пыховой стороне после распаршивания джейсона должно стать строкой "false", а не константой false? Не понимат.

Ответы415447

927 12 июня, 19:50 927 1415447

>>1415439
https://ideone.com/5fdZv0

потому что у тебя в jsone в пхп прилетает "false" в кавычках вместо простого false?

Консоль логай свой json на стороне js'a прежде чем отправляешь запрос на сервер.

Если честно то это тупой вуопрос для этого треда, в гугле бы быстрее нашел чем тут.

5

Ответы415469415476

928 12 июня, 20:41 928 1415469

>>1415447
Жсон всегда надо прогонять через преобразование типов на входе?

мимо

929 12 июня, 21:02 929 1415476

>>1415447
Хотел ещё раз объяснить, в чём проблема, но передумал. Будь так добр, в следующий раз, когда тебе захочется читать посты жопой, не отвечай на них вообще.

Ответы415644415945

930 12 июня, 22:08 930 1415504

>>1380485 (OP)
>Почему PHP? Потому что вакансий море, и учить легко.
Ситуация на рынке не изменилась? Javascript или python в этом вопросе по-прежнему не конкуренты php?

931 13 июня, 02:10 931 1415576

>>1415251

Почти. Но после того, как ты написал код, прочти еще раз внимательно условие задачи (это полезный навык, который пригодится и на работе). Там сказано: "напиши программу, считающую через сколько лет...". Где количество прошедших лет?

170 - 590 932 13 июня, 07:11 932 1415600

>>1394765

> require_once '....error_handler.php';
> Что это за многоточие и что это подключаем тут?

Многоточие - это путь к файлу, если он в какой-то папке. Файл содержит обработчик ошибок.

> initErrorHandler();
> И эта функция что делает??

Ее надо написать самому, это функция из error_handler.php. Она, как следует из названия, задает обработчик ошибок.

> А bootstrap это толи модель, толи просто инициализатор в MVC.

Это файл, который подготавливает код: например, задает автозагрузчик, создает нужные объекты (или описывает из в DI контейнере). Если он тебе не нужен, то можно его не использовать.

> Так вот в тех классах исключения писать не надо? Мне не нужно в классе, который реализует паттерн TableDataGateway использовать отлов ошибок/исключение/try/catch?

Да, не надо.

> Подключение к БД в каком месте идет? В TableDataGateway или в index?

Можно создавать объект PDO в bootstrap.php, можно в index. Это не очень важно, где именно. Объект PDO создается там же, где и другие нужные для работы кода объекты.

> Просто если в index, то что мне делать в конструкторе public function __construct(PDO $pdo) { ... } класса TableDataGateway? Взять данные из базы данных в массив?

Это DI. Прочитай урок по DI: https://github.com/codedokode/pasta/blob/master/arch/di.md

> Это я тоже не понял. Это шаблоны?

Это Front Controlller, погугли.

> Ты подразумевал, что она где то описана?

В мануале.

Если есть еще какие-то вопросы, уточняй.

170 - 590 932 13 июня, 07:11 932 1415600

>>1394765

> require_once '....error_handler.php';
> Что это за многоточие и что это подключаем тут?

Многоточие - это путь к файлу, если он в какой-то папке. Файл содержит обработчик ошибок.

> initErrorHandler();
> И эта функция что делает??

Ее надо написать самому, это функция из error_handler.php. Она, как следует из названия, задает обработчик ошибок.

> А bootstrap это толи модель, толи просто инициализатор в MVC.

Это файл, который подготавливает код: например, задает автозагрузчик, создает нужные объекты (или описывает из в DI контейнере). Если он тебе не нужен, то можно его не использовать.

> Так вот в тех классах исключения писать не надо? Мне не нужно в классе, который реализует паттерн TableDataGateway использовать отлов ошибок/исключение/try/catch?

Да, не надо.

> Подключение к БД в каком месте идет? В TableDataGateway или в index?

Можно создавать объект PDO в bootstrap.php, можно в index. Это не очень важно, где именно. Объект PDO создается там же, где и другие нужные для работы кода объекты.

> Просто если в index, то что мне делать в конструкторе public function __construct(PDO $pdo) { ... } класса TableDataGateway? Взять данные из базы данных в массив?

Это DI. Прочитай урок по DI: https://github.com/codedokode/pasta/blob/master/arch/di.md

> Это я тоже не понял. Это шаблоны?

Это Front Controlller, погугли.

> Ты подразумевал, что она где то описана?

В мануале.

Если есть еще какие-то вопросы, уточняй.

Показать весь текст

933 13 июня, 07:12 933 1415601

>>1395650

У Симфони есть бандлы. Хотя в 4 версии они от них отказываются в пользу композер-библиотек. Вообще, как я понял, "батарейки" это просто сторонние библиотеки, а они точно есть в PHP.

>>1395666

Надо смотреть документацию, так не скажу.

>>1395725

Ctrl + Shift + Del во многих браузерах открывает диалог очистки кеша.

>>1397582

Действительно, что-то я напутал. Но так много строк вообще-то в таблице быть не должно, смысл радужных таблиц как раз в сокращении объема таблицы за счет многократного вычисления и развычисления хеша.

>>1398804

Боюсь, я не готов писать тебе код.

Ответы415640

934 13 июня, 07:40 934 1415607

Этот тред закрыт, переходите в новый тред: >>1415604 (OP)

Если я кого-то пропустил, напомните о себе в новом треде. Здесь больше писать не надо.

935 13 июня, 10:28 935 1415640

>>1415601
>У Симфони есть бандлы. Хотя в 4 версии они от них отказываются в пользу композер-библиотек. Вообще, как я понял, "батарейки" это просто сторонние библиотеки, а они точно есть в PHP.
а что насчет Ларки?

936 13 июня, 10:33 936 1415644

>>1415476
Нихуя ты свинья - не смог нормально проблему рассказать, и тот, кто на тебя внимание обратил получил говна за щёку.

мимо

937 13 июня, 18:05 937 1415945

>>1415476
Очередной раз пытаешься помочь безработному тупому уебищу итт и очередной раз понимаешь насколько же я теперь понимаю тех, кто хоть с парой лет опыта смотрит на такой мусор как на говно в этом разделе...

Тред утонул или удален.
Это копия, сохраненная 15 июня 2019 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.

« /pr/В начало тредаВеб-версияНастройки/a//b//mu//s//vg/Все доски

Пользуетесь скринридером — пишите, что можно улучшить.
Host-Food.ru — надёжный хостинг от 12 руб/мес | Free DNS
Зеркала М.Двача: m2ch.hk, m2ch.lib, m2chfapiswfw2wcakptqp4o6ltgchvjuxfab7urxlduraomtlnhw5xad.onion