Программирование


Ответить в тред Ответить в тред

<<
Назад | Вниз | Каталог | Обновить тред | Автообновление
913 101 281

Клуб изучающих PHP #108 /php/ Аноним 24/02/19 Вск 06:08:49 13537051
php-noob-1.png (33Кб, 500x500)
500x500
cat-cafe-osaka.jpg (157Кб, 1024x683)
1024x683
l0-sensei.jpg (34Кб, 650x384)
650x384
mori-1.jpg (359Кб, 900x600)
900x600
Ну что же, зима заканчивается, и это хорошо. А мы по-прежнему изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки, печем печенье и даже делаем простые сайты! Зачем? Кто-то хочет открыть стартап, кто-то заработать на лапшу быстрого приготовления, кому-то просто нечего делать.

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

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

Предыдущий тред был тут: >>1331378 (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? — Да, однозначно. Посмотри любую вакансию.
Оформляйте код Аноним 24/02/19 Вск 06:10:34 13537062
grammar.png (56Кб, 500x644)
500x644
Не знаю, читает ли кто-то этот пост, но все равно напишу. Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть. Если каждый будет оформлять код как хочет, будет бардак.

Если тебе лень выравнивать код руками, закачай его на 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
Аноним 24/02/19 Вск 06:11:13 13537073
Если я кому-то не ответил в прошлом треде, то постараюсь ответить сегодня-завтра. Но вы можете напомнить о себе в этом треде.
ХАЦКЕР Аноним 24/02/19 Вск 11:02:19 13537424
Screenshot1блоо.png (175Кб, 1913x938)
1913x938
Анон помоги. Можно ли как-то заполучить доступ к полному номеру телефона на сайте, если он зашифрован звездочками? Я неумею немножко читать код, но не разобралсс(.
Аноним 24/02/19 Вск 11:07:41 13537435
>>1353742
Нет, сори. Я умею ток взламывать вк.
Аноним 24/02/19 Вск 11:10:23 13537456
Пхп вообще параша. Кто будет этим всем заниматься? Язык постоянно пытается стать жабой, когда сама жаба уже существует и просто плюет в сторону этого треда. Я уже не говорю про бек на питоне или голанге, где это дело более успешней, чем перебирать говнокод 10летней давности здесь.

Подумайте об этом.
Аноним 24/02/19 Вск 11:11:59 13537497
>>1353742
Смотри через Network, что сервер тебе присылал. Если присылал уже со звездочками, то ничего.
Аноним 24/02/19 Вск 11:17:46 13537568
Аноним 24/02/19 Вск 11:39:25 13537779
>>1353745
Количество вакансий и фирм глянь, где используется. Пхп очень популярен, прост в осовении и гибок, инструменты все современные есть, по скорости щас тоже отдалили. С жабой имеет смысл начинать, если есть огромный энтерпрайз, где кучи сервисов друг с другом коммуницируют. Жаба в крайне малом количестве стартапов сейчас используется, проще и быстрее все на пхп бывает написать и инвесторам результаты показать, чтобы получить дальнейшее финансирование.
Аноним 24/02/19 Вск 11:49:45 135378610
>>1353749
Облом. Приходит со звездюльками( Спасиб всеж.

Аноним 24/02/19 Вск 12:18:05 135380311
>>1353777
Проще и быстрее писать на рельсах, если ты очередной манястартапер. Если же хочешь в норм контору - то тут уже юзается питчон, а если прям охуеваешь от своей тормознутости - присыпается голанг для убер маня хайлода.

>чтобы получить дальнейший говнокод.
Подправил.
Аноним 24/02/19 Вск 12:33:31 135381012
>>1353803
Как ни грустно это осозновать, но двачую.
Аноним 24/02/19 Вск 13:08:30 135382713
>>1353803

Какие плюсы у Питона? Это же по сути и по синтаксису почти тот же Яваскрипт, нет даже тайп-хинтов. В Руби та же ерунда. В PHP больше возможностей статической типизации, есть фреймворки, ORM. И разработчиков найти проще.
Аноним 24/02/19 Вск 13:10:42 135383114
>>1353803

И, конечно, непонятно, как просто использование Питона или Руби повышает качество кода. С чего бы вдруг? Что, менеджер по продажам, прошедший экспресс-курсы по Питону, будет писать более качественный код, чем после курсов по PHP? Вы, товарищи, просто распространяете очень далекие от реальности стереотипы.
Аноним 24/02/19 Вск 14:00:51 135388415
>>1353827
>В PHP больше возможностей статической типизации, есть фреймворки, ORM. И разработчиков найти проще.
Это все нивелируется с существование жабы. Если бы ее не было, возможно пхп был бы еще уебищней.

>>1353831
Качественный код может написать любой человек который умеет читать доки.

Какую-то хуйню не аргументированную спизданул.
Аноним 24/02/19 Вск 14:12:24 135390116
pyha.png (7Кб, 799x506)
799x506
>>1353884
>Это все нивелируется с существование жабы.
Ну так и есть, пхп второй после жабы, пикрелейтед. Где жабу поднимать геморно, но удобство и функциональность жабы нужна, поднимают пхп.
Аноним 24/02/19 Вск 14:50:51 135394217
ОП, я сделал все задания из твоего поста и прочитал все книги из оп-поста + некоторые проскакивающие в обсуждении про шаблоны. Что мне делать дальше?
Аноним 24/02/19 Вск 14:54:53 135394618
Аноним 24/02/19 Вск 15:32:36 135399219
>>1353901
>бекенд
>мочаскрипт

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

>>1353942
>Что мне делать дальше?
Делать сайты. Магазины, склады, игровые сайты, фильмы и т.д. Но мне тебя жаль.
Аноним 24/02/19 Вск 17:23:40 135411120
А объясните на пальцах, какую проблему решает DI?
Аноним 24/02/19 Вск 18:01:23 135412921
Вопрос на засыпку:
есть два скрипта. В одном весь код поделен на методы вплоть до абсурда, например, метод hasProperty имеет всего лишь одну строчку кода return isset(prop); и методов очень много, сами понимаете, код раздут, код ради кода. В другом все написано в одном методе. Какой из этих скриптов отработает быстрее?
Аноним 24/02/19 Вск 19:16:22 135420622
Аноним 24/02/19 Вск 19:21:33 135421523
Спрашивал в JS-треде, но там молчат
Помогите изменить скрипт, пожалуйста.

Логика такая: при загрузке страницы срабатывает скрипт, считывает значение поля amount, отправляет его аяксом в requestUrl.php, принимает ответ и ждёт, пока человек не нажмёт кнопку payButtonId. Нажал - данные улетают в https://pay.realexpayments.com/pay

Проблема в том, что кроме amount нужны дополнительные поля, но пользователь заполняет их уже на странице. То есть, нужно, чтобы он сначала заполнил их, и только потом срабатывала их отправка в requestUrl.php

У меня не получается так сделать. Даже если ввести ещё одну кнопку и повесить на неё скрипт отправки в requestUrl.php, а на вторую отправку в платёжку, то отправка в платёжку не срабатывает. Работает только по $(document).ready

Вот код:
https://jsfiddle.net/tw6f7y2b/
Аноним 24/02/19 Вск 19:43:04 135423224
>>1353992
всмысле жаль? ты охуел?
Аноним 24/02/19 Вск 21:03:12 135430525
>>1354232
Да. Если бы я был бы тобой и только закончил бы опа таски - то я бы сменил род деятельности ( в програмаче ). Явно не жаба, там слишком много писать. Пошел бы в питон, если бы ничего больше не знал. А если бы я делал выбор сейчас - то остался бы в мобилках. Тут языки не нужно придумывать. Все стандартно. Но для бека я бы выбрал голанг или рельсы.
Аноним 24/02/19 Вск 21:33:53 135434226
>>1354305
Вот этот дело говорит.
мимо-как-год-перекатился-в-божественный-руби
Аноним 24/02/19 Вск 21:38:55 135434827
>>1354305
а если в системное програмирование?
Аноним 24/02/19 Вск 21:49:20 135435828
>>1354342
>как-год-перекатился-в-божественный-руби
А я вот выбирал между гошкой и руби. Не понравилась мне динамика. Поэтому делаю внутрипроекты на гошке.
Аноним 24/02/19 Вск 22:04:35 135437929
Добрый вечер, задался вопросом как вообще устроены большие парсеры, есть ли какое-то название у этого и какие технологии используются? Например если есть какой-то агрегатор - на чем именно пишут парсеры для него?
Аноним 25/02/19 Пнд 00:09:34 135449430
>>1354219

Смысл сервис-контейнера в том, что он может создавать сервисы с зависимостями, не заставляя нас делать это вручную. Принцип DI (внедрение зависимостей) обычно требует передавать зависимости в сервис снаружи. Вручную это выглядит так. Допустим, нам нужен сервис C, который зависит от A и B:

$a = new A;
$b = new B;
$c = new C($a, $b);

С контейнером:

$c = $container->get('C'); // Или $app->make('C') в Laravel

Если что, DI и контейнеры я попытался, как мог, описать в своем уроке: https://github.com/codedokode/pasta/blob/master/arch/di.md - без теории по DI трудно понять, зачем нужен контейнер.

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

Далее, ты упомянул "сервис-провайдеры". Это немного другая штука. Они используются, чтобы пачкой зарегистрировать несколько сервисов. Ты мог бы обойтись и без провайдера, и просто зарегистрировать сервисы в контейнере руками, но если ты, например, делаешь библиотеку, то логично объединить предоставляемые ей сервисы в провайдер, чтобы можно было зарегистрировать их одним действием.

> Заодно вопрос какая структура папок должна быть для контрактов и их реализации.

Не знаю, в документации Ларавел не описано?

> Если бороться с жирными контроллерами через сервисный слой то какую выбрать структуру папок чтоб можно было вернуться к проекту через месяц?

А ты разобрался, что такое сервисы? Проблема "толстых контроллеров" в том, что код в них нельзя повторно использовать. Ты описал, например, код регистрации пользователя в контроллере и после этого ты не можешь создать пользователя программно из другого места кода. Сервисы решают эту проблему.

Если у тебя маленький проект, то ты просто кладешь сервисы в одну папку. В простейшем случае можно для каждой сущности сделать свой сервис (сервис для работы с постами, с комментариями, с пользователями). Если большой - то делаешь, например, подпапки, а сами сервисы разделяешь по задачам: сервисы приема платежей, сервисы для подсчета статистики, итд.
Аноним 25/02/19 Пнд 00:10:06 135449531
>>1354379

Это правильно называется "скрейперы", и как правило, абсолютно ничего сложного там нет, все элементарно:

- загружаем HTML код
- выделяем куски страницы с помощью какой-нибудь DOM-библиотеки, по имени CSS-класса, по тексту, по еще каким-то HTML-атрибутам
- выводим собранные данные в каком-нибудь формате

Если ты знаешь HTML и DOM, то это обычно элементарная задача.

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

Еще можно, как Телеграм, объявить конкурс и выбрать лучшее решение: https://habr.com/ru/post/438926/

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

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

http://xgu.ru/wiki/HTML_scraping

>>1354305

Какой смысл выучить один язык, забросить, и учить другой? Никакого.

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

Но учить язык только потому, что анонимные эксперты с двача называют его "боежственным", довольно глупо. Есть такие люди, которым в принципе работать не интересно, они весь день сидят, пишут код на Си, PHP, C# или Яве, страдают, а тут рассуждают про "божественные" языки (которые точно так же им наскучат через неделю, если попросить их поучаствовать в большом, реальном проекте на них в команде, с реальным кодом, а не задачками на 500 строк).
Аноним 25/02/19 Пнд 00:13:46 135450032
>>1354305

В Питоне нет тайп-хинтов, приватных полей. Там везде костыли вроде virtualenv (так как Питон и его окружение по умолчанию пытается устанавливать пакеты в системные директории, что не всегда хорошо). Несколько менеджеров пакетов, причем часто один менеджер используется только для установки другого. Ужасные сокращения, часто нелогичные (например: в matplotlib есть метод set_xlim, а не set_x_limit, но при этом есть set_xscale). Вообще, если брать библиотеки вроде numpy или matplotlib, то нелогичность названий и интерфейса там вполне сопоставима с таковой же в стандартной библиотеке PHP. matplotlib это вообще жесть. Хотя богатство возможностей, конечно, радует.

Расширять библиотеки часто сложно. Например, попробуйте прикрутить DNS-кеш или подменить DNS-резолвер в стандартной библиотеке urllib. Придется поломать голову.

Часто используются глобальные переменные, глобальное состояние, или статические методы. Например: в urllib3 для настройки логгирования вместо DI (создать логгер и передать в urllib3) предлагают использовать код:

logging.getLogger("urllib3").setLevel(logging.WARNING)

А для замены компонента SSL предлагают:

urllib3.contrib.pyopenssl.inject_into_urllib3()

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

То же самое в urllib.requests:

> urllib.request.install_opener(opener)
> Install an OpenerDirector instance as the default global opener.

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

Обратите внимание на стиль написания функций:

> urllib.request.build_opener()
> urllib.request.getproxies()

Я не уверен, есть ли бесплатные IDE с анализом кода, показом определений для Питон. Ну и вакансий вроде меньше.
Аноним 25/02/19 Пнд 00:14:15 135450233
>>1353705 (OP)
как пересесть с PHP на иглу мужского одобрения?
Аноним 25/02/19 Пнд 00:14:16 135450334
>>1354129

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

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

>>1353992

Человек, обзывающий других дегенератом, хорошего впечатления не производит.

>>1353942

А что ты хочешь делать? Устроиться на работу, сделать свой проект, сдать сессию, какая у тебя цель?

Если на работу - то с задачами про студентов и файлообменник, навыками верстки, SQL, JS вполне может быть достаточно знаний. Можно, конечно, дополнительно освоить какой-нибудь фреймворк вроде Симфони или Ларавель, или посмотреть какую-то популярную CMS. Вроде как у нас были люди, которые послет студентов или файлообменника устраивались на работу и дальше задачи не делали.
Аноним 25/02/19 Пнд 00:15:31 135450635
>>1353884

> Качественный код может написать любой человек который умеет читать доки.

Неверно. Вот, допустим, человек прочитал документацию по Питону - станет ли он писать качественный код? Да не факт, Питон очень провоцирует городить списки из словарей, называть переменные непонятно итд. Будет ли этот человек знать MVC, ООП, паттерны? Вряд ли.

Вот посмотри библиотеки matplotlib или urllib. Их, наверно, писали люди, читавшие доки, но качество кода очень страдает, мягко говоря. Они даже функции назвать единообразно не смогли, не говоря уж про такие вещи, как DI. Я не вижу особого различия в качестве между PHP- и Питон-библиотеками.

>>1353745

Тогда что ты, болезный, забыл в нашем треде? Выкатывайся в свой тред и нахваливайте друг друга петухами и кукушками. У нас тут учебный тред, а не тред для самоубеждения, что у нас самый лучший язык.
Аноним 25/02/19 Пнд 00:22:26 135451136
15324579917250.mp4 (2249Кб, 854x480, 00:00:17)
854x480

>...использование Питона или Руби повышает качество кода
день 00:20 вот-вот начался, а ты уже сделал его
Аноним 25/02/19 Пнд 00:28:42 135451737
Шаблон Реестр и класс DI дублируют друг друга? Я смотрю, у них одна и та же структура. Геттер, сеттер и контейнер. Разница между ними лишь идеологическая?
Аноним 25/02/19 Пнд 00:32:42 135452038
>>1354517

Реестр обычно это глобальное хранилище и он может быть только один. А если ты сделаешь Реестр на нестатических методах как объект, то он от DI контейнера будет не отличим.
Аноним 25/02/19 Пнд 00:38:23 135452639
>>1354503
>А что ты хочешь делать? Устроиться на работу, сделать свой проект, сдать сессию, какая у тебя цель? Если на работу - то с задачами про студентов и файлообменник, навыками верстки, SQL, JS вполне может быть достаточно знаний. Можно, конечно, дополнительно освоить какой-нибудь фреймворк вроде Симфони или Ларавель, или посмотреть какую-то популярную CMS. Вроде как у нас были люди, которые послет студентов или файлообменника устраивались на работу и дальше задачи не делали.


Я хочу устроиться на работу, но не абы куда, студии мимо, хочу заняться серьезным серверным программированием. Мне в вузе очень нравилось проектировать базы данных, вследствие этого за мной тянется фундаментальный багаж знаний о реляционных и нереляционных баз данных. Здесь я только пхп учил. Смотрел, кто из знакомых по вузу где зацепился, большинство не работает по профессии, некоторые админят (тоже не по профессии), некоторые пашут на мобилках, делают приложения, один ушел в 1С. Говно, в общем. Что делать, куда идти? Может свой проект сначала написать какой-то, чтобы крупные компании на меня обратили внимание?
Аноним 25/02/19 Пнд 00:45:57 135453140
Аноним 25/02/19 Пнд 00:47:37 135453241
Аноним 25/02/19 Пнд 01:12:40 135454942
>>1354526
В стартап либо компашку поменьше иди джуном. На собесе задавай вопросы, что они там пилят, если какой свой проект и начинают про архитектуру рассказывать, то круто, если про 100500 клиентов и как они им один и тот же фреймворк или цмс фигачат, то не очень. Можно в принципе и в студии свой уровень подтянуть, если по ходу дела книгу вроде зандстры осваивать и кусками паттерны и нормальный код стараться организовывать, но это дольше. Свой проект на гитхабе конечно лучше сразу, если еще и ООП нормальный там будет, то на собеседовании тебя уже будут нормально воспринимать, и будет о чем рассказать.
Аноним 25/02/19 Пнд 06:51:48 135457543
>>1354494
резюмируя - в сервис контейнер я пихаю только если у меня присутствует необходимость в зависимости? если у меня просто вспомогательный класс (сервисного слоя) без зависимостей для контроллера я его просто делаю use и использую.
>Не знаю, в документации Ларавел не описано?
контракты в /app/Contracts а реализации их неизвестено где
Аноним 25/02/19 Пнд 09:01:38 135460444
сап, подскажет мб кто.
В общем у меня есть скрипт пхп вывода значений из mysql, как его засунуть в таблицу на сайте хтмл?
Аноним 25/02/19 Пнд 09:21:32 135460845
Пиздон или Джава? На чей хуй пересесть? Что анон посоветует?
Аноним 25/02/19 Пнд 14:19:03 135477746
>>1354495
>Это правильно называется "скрейперы"
Да нет, проблем с написанием его нет. Меня интересует как и на каких технологиях разворачивают крупные скрейперы а-ля momondo или другие агрегаторы. Вот допустим есть агрегатор который должен содержать актуальную информацию, то-есть нужен не только первоначальный сбор инфы с сайта но и постоянный перепарсинг сайта (не учитываем тут защиту сайтов, считаем что её нет и принимаем работу что не все сайты нужно парсить, у некоторых есть удобное API).
Можно ли использовать Apache Beam для таких целей или что-нибудь подобное? Или как вообще они устроены? Докеризированные контейнеры которые разворачиваются on purpose? Меня не сам процесс парсинга интересует (тут я имею немного опыта, писал как PHP-парсеры так и мультипоточные парсеры на selenium-js) а вот та инфраструктура которая позволяет поддерживать беспрерывную работу парсеров под большой нагрузкой и в автоматическом режиме.
Аноним 25/02/19 Пнд 14:30:58 135478647
>>1354608
Джава, если объект-ориентированный php освоил, то будет минимум отличий и без усилий перейдешь, все довольно похоже. К тому же вакансий на ней поболее и платят там лучше, ну и в джаве более серьезно к качеству кода относятся, чем в питонах.
Аноним 25/02/19 Пнд 14:35:57 135479448
>>1354786
Тханкс. По пых я всю доку от корки до корки перечитал, долго работал пыхокодером. Хотет перекатиться во чтото для взрослых людей, чтобы быть уважаемым господином.

Т.е. хочу выбрать язык которому я мог бы посвятить жизнь без всяких сомнений, изучать каждый пук. Удачным ли выбором для таких целей является джава?
Аноним 25/02/19 Пнд 14:48:22 135480349
>>1354777
У нас в шараге под подобное были докеры на амазоне, запускались по таймеру из дженкинс, результаты потом дампом БД пересылались в основную базу. Платили только за время работы парсеров. Но наверняка есть лучшие методы.
Аноним 25/02/19 Пнд 15:19:58 135482750
>>1354803
То-есть в докере генерились дампы, не было прямого взаимодействия с бд? Был какой-то микросервис отдельный который принимал дампы на импорт? Немного подробнее пожалуйста этот момент объясни.
Аноним 25/02/19 Пнд 15:23:07 135482951
>>1354794
Питон по синтаксису на мой взгляд посасывает современному PHP, нет неймспейсов как у PHP, там интерпретатор ищет файлы сперва в локальной области видимости, потом в PYTHON_PATH и тд, есть конечно импорт директорий но это на мой взгляд не так удобно как с нейспейсами в PHP, нет тайпхинтов. Есть генераторы списков (удобная хрень) и есть многопоточность
мимо начал изучать python параллельно с основной работой на PHP
Аноним 25/02/19 Пнд 15:36:21 135483852
>>1354829
Да, тоже пытался питон учить, но подгорел от нитакогокаквсе синтаксиса
Crypter someApprentice !EaaiHmIJms 25/02/19 Пнд 17:14:56 135491053
https://github.com/someApprentice/Crypter

Для начала реализовал сервис авторизации. Можно сказать, что это выполненная задача Студентов https://github.com/codedokode/pasta/blob/master/student-list.md выполненная на JavaScript, с Server Side Rendering и SPA, поэтому если новичкам интересно они могут что-то подсмотреть.

Если у новичков есть какие-то вопросы - чувствуйте себя свободно задавать их.


Всё сделано "как по учебнику" и интересного здесь мало чего, за исключением пару вещей.

1. При первом заходе на сайт, пользователя встречает форма Приветствия, в которую нужно заполнить email и, в зависимости от того зарегистрирован ли пользователь или нет, перенаправляет на страницу регистрации или логина, а соответствующий импут email'а автозаполняется.

Это реализовано с помощью пары строчек, которые добавляют для определенного роута поле data с этим email'ом:

https://github.com/someApprentice/Crypter/blob/master/src/app/auth/welcome/welcome.component.ts#L46-L49

https://github.com/someApprentice/Crypter/blob/master/src/app/auth/registration/registration.component.ts#L75-L77
https://github.com/someApprentice/Crypter/blob/master/src/app/auth/login/login.component.ts#L35-L37

Но получив некий опыт на Ангуляре, я понял что более шаблонным и следовательно простым для понимания было бы обернуть все эти компоненты в отдельный компонент AuthComponent и в нём уже сделать свойство email (а лучше объект user/form) и передавать это значение с помощью "Взаимодействий Компонентов" https://angular.io/guide/component-interaction.

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

https://github.com/someApprentice/Crypter/blob/master/src/app/storage.service.ts#L18-L20
https://github.com/someApprentice/Crypter/blob/master/src/app/storage.service.ts#L22-L26

https://github.com/someApprentice/Crypter/blob/master/src/app/models/StorageWrapper.ts


Небольшие вопросы, которые не критичны, но всё же знать их следует чтобы довести до идеала:

https://github.com/someApprentice/Crypter/blob/master/api/api.ts#L31
Позволяет ли Bearer token защититься от XSRF?

Я детально изучил эту уязвимость и касаемо этого вопроса, критический момент зависит от того, что может ли злоумышленник "обмануть" браузер отправить автоматически запрос с этим токеном. Он может, например, сделать XMLHttpRequests с ним (со своего сайта), но для начала ему нужно узнать этот токен, что практически тоже самое что добавлять csrf-token, чтобы бороться с этой уязвимостью.

Способ с Bearer token'ом технически идентичен с методом Cookie-to-header token ( https://en.wikipedia.org/wiki/Cross-site_request_forgery#Cookie-to-header_token ) за исключением семантики заголовка X-Csrf-Token заменённого на Bearer token.
И в моём случае, токен хранится в Кукисах, которые защищены с помощью HttpOnly и Secure флагов и в localStorage.

Приходит ли вам на ум какая-нибудь слабая точка которую можно эксплуатировать?

https://github.com/someApprentice/Crypter/blob/master/src/app/storage.service.spec.ts#L32-L33
Достаточно ли это строгая проверка на то является ли сущность экземпляром объекта localStorage?

https://github.com/someApprentice/Crypter/blob/master/src/app/models/StorageWrapper.ts
В правильной ли директории находится эта обёртка? Это не совсем сущность, например как User, но места по лучше я не могу придумать для неё. Куда следует помещать обёртки?

https://github.com/someApprentice/Crypter/blob/master/src/app/auth/registration/registration.component.spec.ts#L67
https://github.com/someApprentice/Crypter/blob/master/src/app/auth/login/login.component.spec.ts#L66
Нужно ли делать проверку на каждую валидацию? Например на встроенные в Ангуляр валидаторы или на валидацию по регулярному выражению? https://github.com/someApprentice/Crypter/blob/master/src/app/auth/registration/registration.component.ts#L21-L24


Следующий шаг написания сервиса сообщений.

Он будет реализован с помощь протокола WAMP и на платформе от https://crossbar.io/ , которая написана на Питоне, и для которой для аутентификации клиентов нужно тоже написать код на нём.

https://github.com/crossbario/crossbar-examples/blob/master/authentication/ticket/dynamic/authenticator.py

Поэтому я сейчас буду изучать его, и возможно у меня появиться небольшие вопросы по нему. Могу я задать их в этом треде?

Заодно и реактивное программирование подучу.


Буду признателен за проверку моего завершающего задания на JavaScript.

Это очень много значит для меня. Большое спасибо.
Аноним 25/02/19 Пнд 18:46:55 135500054
15510076739240.jpg (59Кб, 1200x630)
1200x630
Аноны, меня из фронт-энд треда послали к вам.
Меня интересует возможность удаленного заработка в пределах 40к. Сейчас начал изучать HTMl 5.

И появилась парочка вопросов:
1) Реально ли работая на фрилансе 8-10 часов в день поднимать 40к для среднестатистического человека?
2) Не покажется ли такая работа скучной, через чур сидячей или все зависит от организации раб. места?

Если это реально, то с такой зарплатой в 40к, в своем м-сраснке с населением 150к я буду полубогом.
В принципе, верстать нравится, сейчас пилю нубский сайт по Бри Ларсон.
Аноним 25/02/19 Пнд 19:15:51 135502955
>>1354827
Да, докер ставился на паузу через дженкинс с внешнего сервера, так что процессорное время не тратилось, когда там ничего не обрабатывалось. Парсеры забирали данные с внешних сайтов, у себя обрабатывали, во время работы на amazon aurora все промежуточные результаты хранили. В конце дамп с авроры делался и копировался на продакшн сервак и микросервис там висел, чтобы внешние парсеры запускать импорт дампов могли. Единственные сложности были с ключами в БД, которые между собой конфликтовали, но мы там потом все составные сделали основной ключ + номер парсера.
Аноним 25/02/19 Пнд 19:28:41 135504656
>>1355000
На одном html сложновато на фрилансе поднять, обычно клиенты хотят сразу и верстку и фронтенд js и бэкенд на php, за фуллстэк работы в основном платят. Если еще в английский можешь, то 40к самый минимум, обычно больше. Делай задания из шапки, там все есть чтобы на нужный уровень выйти.
Аноним 25/02/19 Пнд 19:38:09 135504957
>>1355046
Спасибо анон. Я за верстку и считал html, css, js. Только про php узнал сейчас.
И сколько в среднем стоит обычный проект для новичка? И за какое время, например ты сам в начале пути делал верстку
Аноним 25/02/19 Пнд 19:39:13 135505158
>>1355029
Благодарю, буду разбираться, ну хоть направление есть теперь
Аноним 25/02/19 Пнд 20:02:17 135506759
Аноны, ответьте новичку.

Не могу понять, как работает "поддержка" авторизации на сайтах. Взять тот же ВК. Просмотр страниц доступен только после входа.

Но как потом страницы определяют, что пользователь авторизирован?

Сессии? А в сессии сохранён параметр входа, типа AUTH = TRUE? Что будет, если я скопирую себе COOKIE с id сессии у другого пользователя? Получается, так я могу получить доступ к чужому аккаунту?

Хранение хэшей паролей и проверка на каждой странице мне кажется бредовым решением.

Подскажите, опытные аноны.
Аноним 25/02/19 Пнд 20:57:27 135510460
>>1355067
>Получается, так я могу получить доступ к чужому аккаунту?
Да
Аноним 25/02/19 Пнд 21:11:57 135511061
Сап! Давно тут сидел, сделал студентов и файлообменник. Потом был очень занят по работе (с кодингом совсем не связано) и где-то год ничего не делал. Теперь снова появилось свободное время и я вкатился в тред. Какую задачу посоветуете, чтобы снова все вспомнить?
Аноним 25/02/19 Пнд 21:15:50 135511162
15500333745312.webm (3225Кб, 640x744, 00:00:11)
640x744
>>1353705 (OP)
ого, эти треды еще живы
года 2 назад вкатился благодаря им и опу, за что ему мое увожение
Аноним 25/02/19 Пнд 21:19:00 135511363
>>1355111
Чем занимаешься сейчас?
Аноним 25/02/19 Пнд 21:19:11 135511464
>>1355111
скока щас получаешь?
Аноним 25/02/19 Пнд 21:49:03 135514065
Написал я к примеру файл с созданием сервис провайдера и кинул его в папку с сервисами. А реализация сервиса (ну например "соединение с бд" должна в этом же каталоге лежать или где угодно?
Аноним 25/02/19 Пнд 21:49:19 135514166
Аноним 25/02/19 Пнд 21:49:41 135514267
15510768244100.jpg (148Кб, 700x875)
700x875
>>1355113
перекатился на голенг, неспешно ищу удаленку, но видимо придется ехать в дс
>>1355114
около 90к
Аноним 25/02/19 Пнд 21:54:04 135515168
15503794278460.jpg (109Кб, 861x807)
861x807
>>1355141
ну а чо пилить то
надоело говно вилкой чистить за 18к, вот и решил в ваше айти вкатиться
почти год после работы читал/писал и взяли меня на галеру
поработал там 2 года, понял что на этой галере больше ничему не научиться и теперь пора следующий шаг делать
Аноним 25/02/19 Пнд 22:23:31 135518669
>>1355151
Фига ты успешный. Чем занимался до этого? Тяжело вкатываться? Сам из м-сранска, зп 15-20к.
Аноним 25/02/19 Пнд 22:47:39 135520770
Нужно ли делать ячейку DI-контейнера одиночкой, если она нуждается в этом? Понятно, что содержимое ячейки будет возвращаться одно и то же, но ведь можно будет создать экземпляр и не через сервис, а вручную, поэтому я хочу дополнительно обезопасить код. Правильно мыслю?
Аноним 25/02/19 Пнд 22:49:44 135521071
Аноним 25/02/19 Пнд 23:09:53 135523472
Сука, уже целый день пытаюсь включить Xdebug в VS Сode. И нихера короче. Чеж так сложно-то? Пипец, пол-интерннета таких же мученников и у всех разные решения везде. Не подхватывает и всё тут.

Может netbeans поставить, а? Может там все из коробки нормально, как думаете?
Аноним 26/02/19 Втр 07:16:17 135541873
15510108182730.jpg (71Кб, 811x1081)
811x1081
>>1355186
До этого был петухом в госшараге и всю жизнь руками работал. Ну а вкатываться конечно тяжело. У меня вон почти год это дело заняло, ну и заставлять же себя надо. После работы пришел заебаный - будь добр пиши код, иначе так говно и будешь чистить.
>>1355210
28
Аноним 26/02/19 Втр 10:24:25 135550074
>>1355067
>Сессии? А в сессии сохранён параметр входа, типа AUTH = TRUE? Что будет, если я скопирую себе COOKIE с id сессии у другого пользователя? Получается, так я могу получить доступ к чужому аккаунту?
Концептуально так и есть, но если взять пример ВК, то там, возможно, есть какие то Cookie с хэшем которые высчитываются из ip-адреса, поэтому просто своровать их чтобы получить доступ к чужому аккаунту, скорее всего не получиться.
Аноним 26/02/19 Втр 10:36:58 135550875
Screenshot20190[...].png (31Кб, 478x287)
478x287
Screenshot20190[...].png (49Кб, 1088x693)
1088x693
Аноним 26/02/19 Втр 11:27:12 135553376
>>1355508
Попробуй другой порт например. (я по привычке ставлю 9005)
Если у тебя хост на виртуалке - remote_host будет не 127.0.0.1 а 192.168.1.Х (открываешь свойства сети на компе и смотришь свой IP в локалке)
profiler_enable - тебе вряд ли нужен, но будет дико замедлять работу скриптов (будет писаться файловый лог работы скрипта), лучше поставить чтобы по GET-параметру XDEBUG_PROFILER=1 срабатывал профайлер.
Аноним 26/02/19 Втр 11:35:35 135553677
>>1355533
Алсо, если у тебя php-fpm не забывай и его перезагружать после изменений в php.ini
Аноним 26/02/19 Втр 12:15:23 135555778
>>1355533
Що ты кажешь? Я наоборот скинул анону, чтобы он увидел как у меня настроено и все работает
Аноним 26/02/19 Втр 12:26:34 135556579
>>1355557
А, извини, но я не говорил, что у тебя неправильно настроено, я просто уточнил по некоторым пунктам для него из твоего скрина.
Аноним 26/02/19 Втр 14:38:30 135566980
Посоветуйте бесплатную и без необходимости где-то регаться и не веб страничку блядь клиентскую софтину для redis на линупс
Аноним 26/02/19 Втр 14:49:46 135568681
Аноним 26/02/19 Втр 15:48:34 135573382
>>1355686
ахаха, ну ты мочишь чувак, пошути про программирование на html, плз
Какие различия между пхп 5.5 и 7 ? Аноним 26/02/19 Втр 16:40:19 135576283
PHP-5-vs-PHP-7.jpg (71Кб, 750x425)
750x425
Какие различия между пхп 5.5 и 7 ?
Аноним 26/02/19 Втр 16:46:01 135576684
MVC без шаблонизатора Аноним 26/02/19 Втр 17:26:42 135579885
Верно ли утверждение, что без шаблонизатора мы не можем создать полноценную MVC на пхп, ведь шаблонизатор не убирает скрипты пхп из HTML, а заменяет его код на свой синтаксис, т.е. все скрипты их штмл никуда не деваются. Главная задача MVC отделить логику от представления, разве обязательно юзать шаблонизатор?
Аноним 26/02/19 Втр 20:40:44 135589886
>>1355508

https://www.youtube.com/watch?v=k1CN4YVcbHo

Спасибо, бро. Но я скачал нетбинс и охуел от его аскетичности чтоли:
- нет дерева файлов слева, не понял нихуя, наверное, я тупой, предлагает зачем-то импортировать из zip. А не из zip???
- предлагает создать проект html файл. Нахуя мне html? Я же скачал специально php edition...
- старые плагины 2014 года выпуска, например, Emmet вообще нет, он называется по-старому - Zen coding

Чет мне кажется, я говна поем с этой IDE.

Оууукей. скачал Codelobster - там конечно полный фарш по поддержке фреймворков и cms, смотрите сами, НО! Сука дебагер не пашет на php7, хотя вроде поддержка есть. Ладно, пока попишу на php5 свою херню, хотя странно.

Бля как же сложно, я просто хочу писать и отлаживать удобно код, как раньше в дельфи, неужели я многого прошу?

Алсо видео стронгли рилейтед.
Аноним 26/02/19 Втр 21:30:28 135592887
>>1355898
шо? В нетбинсе все это есть. Это раз.
Два. Это вторая по популярности ИДЕ после пхпшторма. Три - коделобстер - кусок говна по функционалу, даже если сравнить с обычным блокнотом
Аноним 26/02/19 Втр 21:40:48 135593088
>>1355928
По какому функционалу он кусок говна? Поясни-ка, если не трудно.
Аноним 26/02/19 Втр 21:51:14 135593889
>>1355930
Я его пробовал несколько лет назад, поэтому точно не помню. Помню что жопа горела дико.

Там какая-то перда была с тем что внутренние окна меняли свой размер, он лагал. Там ты ничего толком не настроишь, он платный. Я уже не помню есть там поддержка композера, гита и пр штук? Терминал имеется? Возможность работать с сервером удаленно?
Аноним 26/02/19 Втр 22:15:59 135595390
2019-02-2622-11[...].png (32Кб, 625x605)
625x605
>>1355938
Терминала нету. А что ты запускаешь в терминале? Artisan?

А что значит - поддерка компоузера?

Удаленный сервер - всё это есть, конечно.
Аноним 26/02/19 Втр 22:50:30 135597291
народ, если тут не отвечают на ваши вопросы, можете вкатиться в телегу к нам в конфу (25 чел). Тут есть как и опытные, уже работающие люди так и новички, которые хотят вкатиться и спрашивают свои ответы. Пишите почту/телегу.
Аноним 26/02/19 Втр 23:06:19 135598892
>>1355972
Вы еще где-то есть? Не охота с телегой ебаться.
Аноним 27/02/19 Срд 00:15:04 135603693
Laravel
1. Не понимаю в чем профит сервис контейнера? Уже пересмотрел много видео и статей и примеры. Но я не понимаю через сервис провайдеры мы как бе можем подменять реализации интерфейсов того что будет храниться в сервис контейнере, но мы как бы можем сделать это и без него в чем профит использовать именно его? Да реализация через него синглтона довольна удобно и ясна, но она не так часто нужна, так для чего еще?. Так что вопрос зачем?
2. Заодно вопрос какая структура папок должна быть для контрактов и их реализации.
3. Если бороться с жирными контроллерами через сервисный слой то какую выбрать структуру папок чтоб можно было вернуться к проекту через месяц?
Аноним 27/02/19 Срд 00:30:03 135604094
>>1356036
У меня дежа вю от твоего поста.
Аноним 27/02/19 Срд 01:03:58 135605595
Аноним 27/02/19 Срд 01:37:51 135607196
>>1355972
Добавьте меня @PsychoSion
someApprentice !EaaiHmIJms 27/02/19 Срд 10:32:12 135614997
>>1354910
>Но получив некий опыт на Ангуляре, я понял что более шаблонным и следовательно простым для понимания было бы обернуть все эти компоненты в отдельный компонент AuthComponent и в нём уже сделать свойство email (а лучше объект user/form) и передавать это значение с помощью "Взаимодействий Компонентов" https://angular.io/guide/component-interaction.

Здесь не получится реализовать "Взаимодействие Компонентов" потому что, всё равно, придется размещать не сами компоненты, а <router-outlet>.
Аноним 27/02/19 Срд 16:56:25 135628098
>>1355418
А что из заданий опа (студенты, файлообменник) успел сделать за год?
Аноним 27/02/19 Срд 18:48:58 135632999
15478515464620.webm (15572Кб, 816x592, 00:01:03)
816x592
Анончики, помогите найти закавыку:

Допустим, массив всех строк из файла ложится в $key и я хочу организовать поиск по нему.


Дальше такой код: https://ideone.com/PKbkZz


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

2. Как мне вывестив результате номер строки именно найденного результата?

Спасибо вам.
Аноним 27/02/19 Срд 19:33:54 1356353100
Аноним 27/02/19 Срд 19:36:28 1356357101
>>1355972
Напиши пожалуйста название конфы
Аноним 27/02/19 Срд 19:42:56 1356364102
>>1356329
Strpos возвращает первое вхождение. Он может тебе вернуть 0 т.к нашел с индекса ноль а у тебя true стоит может быть поэтому у тебя не сходится. Мне кажется тебе надо.жестко проверить strpos() !== false
Аноним 27/02/19 Срд 22:55:19 1356479103
15511139949370.mp4 (7298Кб, 1280x720, 00:00:27)
1280x720
>>1356280
За студентов не скажу, потому что не помню, а вот файлообменник кинул на гитхаб как пример того чо могу(ничего). Ну там еще было задание после файлообменника, но его я не делал. К слову по жс я не умел вообще ничего, даже json запрос написать не мог. Ну и вообще, то что я там пыхтел год можно реально выучить за месяц максимум на реальных проектах, так что чем скорее попадете на вашу первую ламповую галеру за еду, тем быстрее пойдет скилл.
Аноним 28/02/19 Чтв 19:53:26 1356794104
841bd-clip-32kb.png (32Кб, 556x362)
556x362
Проверьте код, пожалуйста, господа. https://ideone.com/XUZklL
Задачка про вопросы из раздела про ООП.
Аноним 28/02/19 Чтв 20:13:20 1356827105
>>1356794
Почему конструктор не используешь?
Аноним 28/02/19 Чтв 20:47:15 1356873106
Аноним 28/02/19 Чтв 20:57:11 1356877107
>>1356873
Ты поля из вне задаешь. Я против такого подхода потому что создается не валидный обьект. Ты через new его создаешь а потом туда пихаешь значения.
Аноним 28/02/19 Чтв 20:59:48 1356879108
>>1356873
Я как клиент твоего класса должен знать , что после new надо в поля записать. А я не хочу)
Аноним 28/02/19 Чтв 22:48:31 1356943109
>>1356877
>>1356879
честно говоря, не особо понял в чем моя ошибка. Скажи,пожалуйста, что мне конкретно нужно переделать?
Аноним 28/02/19 Чтв 23:07:50 1356963110
+ спасибо
Аноним 28/02/19 Чтв 23:23:18 1356973111
Котаны, совета прошу. Я нуб, пхп осваиваю понемногу. В общем сейчас свое приложение делаю, MVС, на классах, содрал структуру с сети, запросы в базу писать уже научился( с помощью PDO), sql знаю. Суть туда/сюда понимаю. Короче зайчатки разума есть.
На работе появилась задача, которую мне нужно по итогу реализовать, сроки совсем не сжатые, но работу веду по факту ежедневно. Думаю что мой MVC шаблон и станет основой будещего приложения.
Суть приложения проста - сотрудники заходят на сервер и получают перечень доступных им запросов в базу, которые могут использовать.
Какие проблемы для себя я вижу:
1. Как сделать авторизацию в MVC?
2. Как делать права доступа? Т.е. сотруднику №1 доступны все отчеты, а сотруднику №2 только один.
sql-отчетов гипотетически будет много разных.
Делаю это для удобства всех вообще, потому как на данный момент отчеты я ручками пилю при необходимости.
Такой вот учебно-практичный проект возникает.
Где почитать годноты, котаны?



Аноним 01/03/19 Птн 01:36:09 1357016112
>>1356973
1. В бд есть таблица с логинами и паролями (хешами с солью). Показываешь страницу логина с полями для входа. Если пароль не подходит - посылаешь нахер. Если подходит - в сесию пишешь токен (очень длинную случайную строку). С этим токеном пользователь может лазить по сайту. Без токена - посылаешь на страницу логина. Токен проверяешь в каждом контроллере.
2. В бд есть таблица с правами пользователей. В контроллере проверяешь права - в зависимости от прав выводишь нужную инфу, или вообще посылаешь нахер на первую страницу если пользователь ломиться куда не положено.
Вообще лучше фрейморк какой-то взять (Yii2 или Laravel) - там эта вся хуйня сделана изначально (по крайней мере в Yii2).
Аноним 01/03/19 Птн 08:26:32 1357054113
>>1356943
$q1 = new ChoiceQuestion("Какая планета располагается четвертой по счету от Солнца?", 'b');
$q1->options = array('a' => 'Венера', 'b' => 'Марс', 'c' => 'Юпитер', 'd' => 'Меркурий');
$q2 = new NumericQuestion("Чему равна скорость света в км/с?", 300000, 20);
$q2->deviation = 20000;

Поля $q1->options и $q2->deviation = 20000 ты все так же задаешь из вне.
Аноним 01/03/19 Птн 08:35:14 1357057114
>>1356873
И еще мне кажется что делать echo в методе не совсем верно, лучше возвращать строки и пусть кто вызывал твой метод разбирается что с ней делать.
echo " {$key}. {$option}\n"; заменить на return " {$key}.{$option}";
Аноним 01/03/19 Птн 11:39:27 1357116115
Аноним 01/03/19 Птн 12:17:18 1357138116
>>1357054
>>1357057
Переделал вот: https://ideone.com/Lb6iG1.
Если я правильно понял, то переопределить метод изменив количество параметров не получится. Поэтому я в каждый дочерний класс запихнул конструктор. Верно или я ошибаюсь?
Аноним 01/03/19 Птн 12:18:17 1357141117
Аноним 01/03/19 Птн 15:19:00 1357205118
>>1357141
Да норм. Конструктор часть конкретного класса. Я бы не рассматривал его как часть интерфейса
Аноним 01/03/19 Птн 18:59:46 1357310119
>>1356479
Ого. Я тоже сделал только файлобменник. Учу шаблоны, дабы приступить к изучению Laravel.

Предлагаешь с такими околонулевыми знаниями уже подыскивать галеру?
Аноним 01/03/19 Птн 21:51:12 1357424120
>>1357310
Ничего себе околонулевые. Сколько учишь уже?
Аноним 01/03/19 Птн 22:14:50 1357438121
>>1357424
Двачую. Тут люди с одним файлообменником на работу устраивались.
Аноним 01/03/19 Птн 22:32:23 1357456122
15473166366290.jpg (183Кб, 550x550)
550x550
>>1357310
Хз, пробуй. Если в дс то изи, если нет, то не очень. Ну от бомжа и не ждут, что он процесс от потока отличает и знает чтото про уровни изоляции транзакций.
лучше поздно чем никогда Аноним 02/03/19 Суб 00:44:41 1357490123
Аноним 02/03/19 Суб 03:01:43 1357536124
Правильно ли идеалогически подключать несколько View в один шаблон?
Аноним 02/03/19 Суб 03:41:47 1357540125
>>1353745
Быстро мне накидал CMS с плугами под нормальные языки!
Знаю что напсавший уже и забыл о том что писал, ведь в школе каждый день кипит событиями
Аноним 02/03/19 Суб 04:09:23 1357547126
>>1357536
Я не понимаю, мои посты скрываются каким-то специальным скриптом? На них никто не знает ответ? Вопросы дурацкие? Или просто лень отвечать?

>>1355207
>>1355140
>>1354531
>>1355798

И в предыдущем треде дохуя.
Аноним 02/03/19 Суб 05:36:51 1357562127
>>1357547
Да просто не знают ответа ибо только учатся или посрать пришли
Аноним 02/03/19 Суб 07:47:24 1357584128
>>1357536
Это что бы изменение 1 вьюшки были отображены в другой?например я обычно общие куски делаю в partial и их уже где надо подключаю. Какой результвт ты хотел бы получить?
Аноним 02/03/19 Суб 14:22:14 1357720129
2819ad17a291d86[...].png (143Кб, 227x262)
227x262
Аноним 02/03/19 Суб 14:29:40 1357722130
пакетик 02/03/19 Суб 14:51:54 1357727131
>>1357720
Что значит проверить?
Аноним 02/03/19 Суб 15:13:14 1357736132
>>1357720
Хорошо. Лучше чем большинство делает в этот ITT треде, обычно пытаются все логические действия впихнуть в одну строку и косячат. Учись дальше.
Аноним 02/03/19 Суб 15:55:22 1357756133
Clip2net1903021[...].png (13Кб, 612x145)
612x145
>>1353705 (OP)
Есть вопрос по "Вектору".
Правильно ли я понимаю что создание всех этих объектов работников надо как то автоматизировать? Или втупую ручками создавать каждый объект?
Аноним 02/03/19 Суб 16:00:24 1357759134
>>1357756
Сначала ручками, потом автоматизируешь, протом сравниваешь ощущения.
Аноним 02/03/19 Суб 17:14:51 1357797135
>>1357756
Ну я когда делал, то парсил из текста с твоей картинки, только там тогда были буквы из латиницы и из кириллицы намешаны, что добавило анальных болей, не знаю было ли это исправлено.
Аноним 02/03/19 Суб 20:32:26 1357898136
>>1357759
будет правильным создавать объекты сотрудников с помощью clone?
Аноним 02/03/19 Суб 20:49:18 1357904137
>>1357898
Чому бы и нет? Паттерн прототип сам просится
Аноним 02/03/19 Суб 20:56:08 1357908138
>>1357898
Нет. Делай нормальные конструкторы. По факту там и ватоматизировать мало чего. В циклах создаешь объекты и все. Инициализации все равно много будет.
Аноним 02/03/19 Суб 21:04:31 1357918139
>>1357584
Я просто еще с фреймворками не работал, так что хз, как оно там везде работает. Есть вот шаблон, куда я подключаю вид, считай, вызываю функцию getView(), которая подключает текущий вид. Например, это список товаров. А еще у меня в каждом виде меняется, к примеру, шапка. Там title разный на каждой вьюхе. И как мне его там менять? Инклюдить всю шапку как виджет в каждый вид, туда передавать параметры для title и потом выводить все вместе или еще как-то можно?
Аноним 02/03/19 Суб 21:38:13 1357938140
>>1357918
Напрмиер, в шаблоне также как подключаешь вью с товарами, также подключашь нужную шапку. Виджет норм идея, если сможешь сделать его более-менее универсальным (тоесть можно будет использовать больше чем в одном проекте). А если придется допиливать под каждый конкретный проект то лучше всетаки как отдельное вью или типа того оформить.
Аноним 02/03/19 Суб 22:28:34 1357975141
Аноним 03/03/19 Вск 11:57:53 1358201142
rj8raf1riyny.png (301Кб, 1250x811)
1250x811
Аноним 03/03/19 Вск 12:52:48 1358261143
Аноним 03/03/19 Вск 12:52:51 1358262144
Аноним 03/03/19 Вск 14:17:19 1358314145
>>1358261
Для начала сделай нормальную автозагрузку
Аноним 03/03/19 Вск 14:18:03 1358316146
Расскажите нуфагу.
Почему \n работает только на сайте ideone com, а человеческий '<br>', который работает везде, сайт тупо принимает за текст?
Аноним 03/03/19 Вск 14:20:39 1358320147
>>1358262
Чому тайп хинтинг не используешь? Захардкоженные названия профессий тоже не оч хорошо
Аноним 03/03/19 Вск 15:14:19 1358368148
>>1358316
Потому что там вывод скрипта используется как простой текст, а не html разметка.
Аноним 03/03/19 Вск 16:01:30 1358386149
>>1358320
по поводу тайп хинта понял, а что с названиями не так?
Аноним 03/03/19 Вск 16:11:59 1358393150
>>1356479
>>1357310
Вкатился на python галеру после задачи с файлообмненником, работаю уже два месяца. Самое забавное, что набирают людей с куда меньшими чем у меня знаниями, так что вкатывайтесь чем раньше, тем лучше. Кстати, огромное спасибо опу за задачки, я, правда, учился в основном, не на его уроках, но все-равно материалы из этого треда были очень полезны.
>>1357424
Аноним 03/03/19 Вск 17:07:05 1358490151
>>1358386
Я бы добавил константы и в свитчах использовал бы их
switch($this->profession) {
case self::MANAGER итд
Аноним 03/03/19 Вск 17:36:05 1358506152
Анон, я хохол. Хочу понаехать в МСК.
Насколько будет проблемно найти работку в МСК пхп кодеру?
Имеется опыт работы 3+ года, знаю ООП, фреймворки и пр. Хуйов в верстке еще немношк знаю джаву и планирую в нее перекатиться.

Будут ли меня обссыкать за то что я шокаю и гакаю?
Аноним 03/03/19 Вск 17:42:25 1358509153
Screenshot351.png (36Кб, 847x540)
847x540
Screenshot352.png (34Кб, 769x542)
769x542
Анон. Чому он иногда выдает пустоту вместо вопроса?
Аноним 03/03/19 Вск 17:52:04 1358514154
>>1358509
Потому что количество элементов массива 4 а последний индекс 3. Происходит обращение к несуществующему элементу.
Аноним 03/03/19 Вск 17:59:16 1358522155
>>1358514
И правда. Спасибо, теперь все норм.
Аноним 03/03/19 Вск 18:22:54 1358534156
image.png (216Кб, 1920x1080)
1920x1080
Первый верхний вариант функции работает, а второй нижний нет! Что делать??? В чём причина?

(При вызове функции посередине)
Аноним 03/03/19 Вск 18:33:23 1358539157
>>1358534
В первом случае инфо это массивчик, а во втором объект?
Аноним 03/03/19 Вск 18:38:05 1358542158
>>1358539
хмм, походу на то.

Но тогда получается у меня $data - объект, а не в коим случае не объект?

В связи с этим, правильно ли я думаю, что если считывать json файл где всё сосредоточено в
{
//что то
}
то это объект, а если
[
// что то
]
то это массив?
Аноним 03/03/19 Вск 18:42:43 1358547159
>>1358542
fix:

не объект не массив
Аноним 03/03/19 Вск 19:02:37 1358554160
Аноним 03/03/19 Вск 19:16:56 1358561161
>>1358542
Ну если ты обращаешься к данным через ->, то это признак того, что ты обращаешься к объекту.

В javascript можно обращаться к пустому объекту, просто создав его через {}. В PHP так делать нельзя, объект нужно создать через new, поэтому твой json (ты ведь его получаешь?) сначала нужно распарсить (превратить в массив) и потом уже только обращаться к нему.
Аноним 03/03/19 Вск 20:01:48 1358583162
14188451148390.jpg (56Кб, 597x800)
597x800
На пхп вообще есть работа?
В смысле не ковыряние какой-то ублюдской параши с ключевыми словами "битрикс джумла вордпресс", а создание каких-то систем с нуля там, на фреймворках?
03/03/19 Вск 20:16:03 1358591163
>>1358583
Нет. Это фантастика, сынок. А фреймворки это так, хуйня. Фабьен с Тейлором их по приколу напейсали. Вкатывайся лучше в руби
Аноним 03/03/19 Вск 20:47:05 1358608164
>>1358583
Работа есть, но только как ты выразился ковыряние cmsок в студиях, потому что дешево и быстро.
Аноним 03/03/19 Вск 21:27:00 1358638165
А вот такое знает кто?
Есть у меня к примеру экшен, который вызывается один раз по умолчанию, когда юзверь заходит на страниц. Потом, когда программа юзверя запомнила, она будет вызывать другой экшен, при заходе на эту же страницу по умолчанию.
Можно ли сделать вот так?

методПоУмолчанию {
if (тутБылЮзверь) {
методПослеПосещения()
}
"Юзверь, зарегистрируйся!"
}

методПослеПосещения {
выводимИнфу()
}

То есть я понимаю, что чисто физически я могу вызвать один метод в другом, но можно ли так делать в MVC шаблоне?
Аноним 03/03/19 Вск 21:31:06 1358643166
>>1358638
Почему нет? Только если у тебя фрейморк какой-то то там скорее всего лучше не напрямую вызывать другой экшен, а сделать редирект.
Аноним 03/03/19 Вск 21:34:13 1358645167
>>1358643
Ага, спасибо. Почему нет, я не знаю, поэтому и спрашиваю, лол. С фреймами пока не работал, на вольных хлебах пока что. Что хочу, то и ворочу.
Аноним 04/03/19 Пнд 12:34:47 1358927168
Короче, аноны.
Решил написать простенький калькулятор, но после проверки, является ли введенные значения целыми числами, но жидко обсераюсь и ловлю сообщение о том, что там не числа (хотя там числа).

Посмотрите, пожалуйста, где я не прав.
https://ideone.com/gwTPUt
Аноним 04/03/19 Пнд 12:49:28 1358932169
Аноним 04/03/19 Пнд 12:51:35 1358934170
>>1358932
Спасибо. Сейчас разберемся.
Аноним 04/03/19 Пнд 16:08:18 1359022171
Создал я, значит, сущность юзер, к нему маппер, базу ещё. Заполнился юзер данными, но вот только одна беда, некому оперировать этой сущностью. Какой слой модели вызывает методы этой сущности и возвращает результат контроллеру? Или может контроллер сам это делает?
Аноним 04/03/19 Пнд 17:16:23 1359047172
>>1358591
на руби ноль работы, умирает язык
Аноним 04/03/19 Пнд 18:04:44 1359071173
e2a9d-clip-28kb.png (28Кб, 631x226)
631x226
Господа, подскажите как реализовывать " антикризисные меры" в задачке "Вектор"? Это должна быть отдельная функция на каждое антикризисное решение или это должны быть три разные программы на каждый случай?
пакетик 04/03/19 Пнд 20:44:47 1359196174
>>1359022
В операциях чтения ни чего такого нету. Можешь вызывать из контроллера
пакетик 04/03/19 Пнд 20:47:24 1359198175
>>1359047
Работа тебе нужна только 1.И на руби можно найти ее
Аноним 05/03/19 Втр 00:53:32 1359348176
Думаю вопрос поднимался миллион раз, посоветуйте годной advanced литературы/видеокурсов.
Аноним 05/03/19 Втр 03:08:43 1359366177
>>1359196
Мне кажется, хуевый план. А если мне нужно будет этих юзеров рассортировать, пропустить их через валидатор, то где мне это делать? Явно не в контроллере. Опчик, ты ведь знаешь ответ? Взываю к тебе!
Аноним 05/03/19 Втр 08:35:49 1359390178
Аноним 05/03/19 Втр 08:37:07 1359392179
>>1359366
Операции чтения стейт приложения не меняют.
Поэтому их может быть очень много.
Аноним 05/03/19 Втр 08:44:26 1359394180
>>1359366
что тебя смущает я не понимаю.
class Controller
{
private $search;
public function __construct(Search $search)
{
$this->search = $search;
}

public function index()
{
$result = $this->search->search();
}

}
Аноним 05/03/19 Втр 15:52:48 1359591181
Аноним 05/03/19 Втр 17:24:07 1359625182
$a='2';
test($a);
public function test($a) :int
{
return $a;
}

вернет ли в данном случае int или же string?
Аноним 05/03/19 Втр 17:29:49 1359634183
>>1359625
Зависит от strict_types. Или сделает приведение типов и вернет число, или при strict_types=1 будет ошибка
Аноним 05/03/19 Втр 17:36:40 1359640184
>>1359634
да, уже потестил в песочницах.
Но в проекте просто втихую возвращает стринг и никаких ворнингов, ошибок, поэтому и пришел с этим вопросом.
Аноним 05/03/19 Втр 17:43:12 1359645185
>>1359640
нвм, я дегенерат, дампил значение до его возвращения, а приведение типов работает во время возвращения.
Аноним 05/03/19 Втр 21:34:22 1359816186
Есть ли шанс найти галеру если нет технической вышки?
Аноним 05/03/19 Втр 21:40:01 1359817187
>>1359816
Всем плевать на вышку если ты сильный кандидат (немного похуже в Украине, у них странноватый рынок труда в IT). Больше интересует что бы в армию не ушел прямо с работы или в запой.
1-52 Аноним 06/03/19 Срд 05:31:41 1359945188
>>1354215

Вообще, это неудобно. Что, если пользователь нажал кнопку, а данные еще не пришли?

Сначала лучше сделать так: пользователь заполняет все поля и жмет кнопку. Отправляются по очереди все нужные запросы.

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

Если у тебя нет понимания, как это делать, то скорее всего ты пока плохо знаешь Яваскрипт. Пройди учебник http://learn.javascript.ru/ и обрати особое внимание на события, анонимные функции (коллбеки), почитай про промисы.

>>1354526

Часто, чтобы попасть в "серьезную" компанию, надо сначала где-то приобрести опыт, возможно, что в веб-студии, в аутсорсере или где-то еще, где берут джуниоров. Ты можешь сам посмотреть вакансии компании, которая тебе нравится, на hh.ru и оценить требования.

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

>>1354531

Реестр - это паттерн, который описывает объект, в который можно класть и получать данные ( https://martinfowler.com/eaaCatalog/registry.html ). Часто он реализуется на статических методах:

ServiceRegistry::set(ServiceA::class, new ServiceA);
...
$srvA = ServiceRegistry::get(ServiceA::class);

Но это не обязательно. Как я помню, в той же Симфони есть такие реестры:

- реестр кастомных (добавленных пользователем) типов полей Доктрины
- реестр типов элементов форм

Там, где Реестр противопоставляется DI контейнеру - противопоставляется, наверно, статическая версия реестра. То есть подход

ServiceRegistry::get('ServiceA')

и

$container->get('ServiceA');

У Реестра и Контейнера могут быть такие отличия:

- Реестр часто бывает статический, а контейнер - нет
- Реестр не создает объекты: он хранит то, что в него положат. DI контейнер может создавать объекты, если ему дать описание, как это делается (например, описать, что надо передавать в конструктор, или позволить ему самому это понять анализом аргументов в конструкторе).
- Реестр может хранить что угодно, например, числа какие-нибудь или настройки. DI контейнер, как правило, хранит объекты-сервисы. Хотя в Симфони он хранит и настройки.

Аноним 06/03/19 Срд 05:32:18 1359946189
>>1357547

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

>>1355207

> Нужно ли делать ячейку DI-контейнера одиночкой, если она нуждается в этом?

Ни в коем случае. Идея DI контейнера - IoC - предполагает, что жизнью объекта (когда его создать, когда уничтожить, что передать в зависимости) управляют снаружи, что это не его зона ответственности. Это не дело объекта-сервиса знать, сколько экземпляров сейчас создано. Дело сервиса - указать свои зависимости, например, в конструкторе или в методах.

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

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

Потому синглтон - это почти всегда антипаттерн. Не стоит его использовать.

>>1355140

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

- если классов мало (< 10), их можно класть в одну папку
- можно делать папки по типам классов: папка для сервисов, для контроллеров, для представлений, для моделек, для классов работы с БД, для вспомогательных утилит. Этот подход начинает фейлиться, когда у тебя становится огромное приложение с сотнями серисов и моделей.
- можно взять предыдущий подход и добавлять подпапки внутри папок. Ну например, папка модели, а в ней: папка пользователи, папка товары, папка статистика итд.
- а можно поступить по-другому, и разбить приложение на "части". Для каждой "части" создаем свою папку, а в ней подпапки: сервисы, модели, контроллеры, утилиты и тд. То есть будет папка "пользователи", а в ней подпапки с моделями пользователей, контроллерами раздела работы с пользователями итд.

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

То есть для огромного магазина, например, можно сделать так:

CommonBundle - общий код, который используется всеми бандлами (не контроллеры или модели, а например, сервисы, утилиты, расширения фреймворка итд)
UsersBundle - управление пользователями, регистрация, личный кабинет
StoreBundle - витрина, вывод товаров, оформление заказа
FinanceBundle - оплата, бонусы
SupportBundle - раздел техподдержки
ForumBundle - форум
AnalyticBundle - аналитика
AdminBundle - админка
Аноним 06/03/19 Срд 05:32:48 1359947190
>>1355798

> что без шаблонизатора мы не можем создать полноценную MVC на пхп

В теории - можем. Например, если мы делаем сервер API, который отдает не HTML-страницы, а данные в формате JSON, то шаблоны нам не нужны. Ну и в теории, опять же, мы можем без шаблонов сделать вывод HTML кода кучей операторов echo.

То есть, шаблон - это лишь один из вариантов реализации View.

Я думаю, ты хотел спросить, "можно ли вместо стороннего шаблонизатора использовать встроенный в PHP?" - да, можно, но неудобно на больших проектах.

Урок про шаблонизаторы: https://github.com/codedokode/pasta/blob/master/php/templates.md

>>1354575

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

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

> если у меня просто вспомогательный класс (сервисного слоя) без зависимостей для контроллера я его просто делаю use и использую.

Для вспомогательных классов можно использовать паттерн Utility Class (класс со статичесикими методами).

> контракты в /app/Contracts а реализации их неизвестено где

Их реализации там, где уместно. Естественно, не в папке Contracts. Вообще, ты можешь посмотреть, как код организован в самом Laravel или стандартных библиотеках к нему.

Если у тебя мало сервисов, можно просто сделать папку App/Services. Если много - то думать, как дробить на части. Можно как-то по смыслу их группировать, по разделу сайта, по компоненту приложения.

>>1354604

По идее так: http://php.net/manual/ru/language.basic-syntax.phpmode.php

Но это даст низкокачественный код, потому читай https://github.com/codedokode/pasta/blob/master/php/templates.md
Аноним 06/03/19 Срд 05:33:28 1359948191
>>1354838

Он зато лаконичный. И там есть IPython Notebook - отличнейшая штука. Но отсутствие тайп-хинтов, конечно, убивает.

>>1359625

Вернет в любом случае то, что указано в тайп-хинте, в нестрогом режиме при этом допускает автоматическую конвертацию в int.

>>1359071

Можно как 3 функции, можно как 3 класса, можно как 3 метода в одном классе. Метод может принимать экземпляр Компании и делать с ней какие-то операции.

>>1359022

Зависит от того, как сделана работа с БД. Если у тебя используется дата маппер, то в нем и будет метод для загрузки моделек из БД.

> Какой слой модели вызывает методы этой сущности и возвращает результат контроллеру? Или может контроллер сам это делает?

Вызывать метод загрузки данных может контроллер. Либо сервис, который загружает данные из БД и делает какие-то еще преобразования.
Аноним 06/03/19 Срд 05:33:51 1359949192
>>1359366

Зависит от ситуации. Контроллер должен быть тонким, то есть в основном в нем вызовы разных сервисов (тех же мапперов) для получения разных данных и передача их во View. Для валидации можно сделать отдельный класс-валидатор. Для сортировки - если это что-то простое, нужно только для вывода и не повторно используемое, то делаем в контроллере. В задаче про студентов сортировку логично сделать аргументом в методе для получения студентов:

findStudents($searchBy, $orderBy, $orderDir, $offset, $limit): iterable

Этот метод может быть в маппере для работы с БД.

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

Контроллер отвечает за управление процессом обработки запроса, за интерпретацию команд пользователя. То есть контроллер как-то (например, из $_GET) определяет, какая сортировка нужна пользователю, и вызывает метод для загрузки студентов с сортировкой по данному полю. А затем передает найденных студентов во View и отдает пользователю сгенерированную HTML страницу.

>>1358638

Обычно это делают так:

class Controller
{
public function indexAction(Request $req)
{
if (!$this->isLoggedIn($req)) {
return $this->redirectTo(...);
}

...
}
}

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

В твоем варианте пользователь может попробовать обойти авторизацию, вызвав напрямую метод "методПослеПосещения".
Аноним 06/03/19 Срд 05:34:13 1359950193
>>1358534

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

>>1358542

Прочти также целиком мануал по json_decode. Там написано, когда получается объект класса stdClass, а когда массив.

>>1358506

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

>>1358393

Не думал, что у файлообменника такая сила. Сейчас, вроде начинающие разработчики делают сокращатели ссылок, но это уже неприлично просто.

>>1358316

<br> это тег языка HTML. Он работает только там, где данные интерпретируются как HTML-код (в браузере). А \n браузер воспринимает просто как разделитель слов и непереносит строку.

На ideone и в консоли данные просто выводятся как текст. Если там будут теги - они выведутся как есть.

Это не единственное отличие. Например, & lt ; в браузере выводится как знак "меньше", а в консоли - как есть.

То есть различай "просто текст" и "HTML текст с тегами".

Если добавить в начало header("Content-Type: text/plain; charset=utf-8"); то браузер перестанет воспринимать данные как HTML и \n начнет работать.
Аноним 06/03/19 Срд 05:35:11 1359951194
>>1357898

Если они совсем однотипные то можно, но проще наверно через new.

>>1357918

Обычно делают отдельно шаблон для "лейаута" (шапка/подвал) и "контента". Лейаутов может быть несколько - например, один для морды, другой для админки. Как передавать параметры для лейаута? Тут есть варианты:

- руками копипастить их в каждый метод каждого контроллера (боль)
- наследовать контроллеры от базового класса и в нем формировать данные. У базового класса может быть метод вроде "поменять тайтл текущей страницы". Плюс - инкапсуляция, трудно передать что-то неправильное, например, не-строку.
- передать эти данные во вью до или после выполнения контроллера, без использования наследования. Или передать в контроллер.
- сделать "контроллер для лейаута" и в нем формировать данные для лейаута. У "контроллера лейаута" могут быть вспомогательные методы вроде "поменять тайтл текущей страницы".

В фреймворках готового решения нет. Каждый изобретает сам.

>>1357536

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

>>1357016

В сессию токен писать нет смысла. Данные сессии хранятся на сервере и недоступны пользователю, потому можно просто писать туда userId = 123. Это безопасно.

Токен нужен, если используется не сессия, а куки. Тогда писать userId = 123 нельзя, так как пользователь может их подделать. Также, некоторые шифруют и/или подписывают куки для защиты от чтения и/или модификации их пользователем. Плюс: сессии не требуется хранить.
Аноним 06/03/19 Срд 05:35:32 1359952195
>>1356973

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

Советую реализовать RBAC, в общем.

Статья в википедии про RBAC трудночитаема.

> 1. Как сделать авторизацию в MVC?

В твоем случае:

if (!$this->hasRole(Roles::ROLE_BUH)) {
редиректим на форму логина, либо показываем ошибку нехватки прав;
}
Аноним 06/03/19 Срд 14:03:53 1360106196
Я не понял, а где море вакансий для PHP? На ХХ вижу только 20 вакансий PHP Junior.
Аноним 06/03/19 Срд 14:26:36 1360115197
Аноним 06/03/19 Срд 17:30:52 1360209198
Господа, вопросик.
Клонирую объект в свойстве которого лежит массив объектов. Правильно я понимаю, что объекты в массиве тож надо клонировать с помощью __clone()? Если да, то правильной ли будет вот такая функция:

function __clone()
{
foreach ($this->arrayWithObjects as $key => $object)
{
$this->arrayWithObjects[$key] = clone $object;
}
}
Аноним 06/03/19 Срд 17:38:41 1360214199
>>1360209
Ты ведь просто перезаписываешь объект, клонируя его. Какой смысл?
Аноним 06/03/19 Срд 17:45:23 1360216200
>>1360214
Потом мне нужно работать с этими объектами в массиве и изменять их, но так чтобы оригинальные не поменялись.
Аноним 06/03/19 Срд 20:12:25 1360320201
Screenshot361.png (36Кб, 1081x418)
1081x418
Аноны, где я не прав?
Аноним 06/03/19 Срд 20:19:32 1360327202
Screenshot365.png (39Кб, 952x520)
952x520
Screenshot363.png (39Кб, 971x524)
971x524
Screenshot362.png (39Кб, 986x493)
986x493
>>1360320
Так сделал, вроде работает.
Или можно было как- то короче?
Тут я сравнивал не по половинам, а целую строку. Потому что я тупой и не придумал, как сравнить одну половину со второй.
Аноним 06/03/19 Срд 21:08:04 1360353203
>>1360216
Ты в тот же самый массив записываешь тот же самый объект с тем же ключом. Какой смысл? Массив у тебя как был один, так и будет. Или ты все-таки в другой клонируешь?
Аноним 06/03/19 Срд 22:10:15 1360386204
reddit.png (48Кб, 1012x616)
1012x616
Аноны, нужен совет.

Одна из моих проблем заключается в том, что я не могу в базовую терминологию, поэтому часто приходится изъяснятся как ретард. Подскажите, как можно обозначить вот эти элементы страницы любого саба на Reddit (pic related)?

Хочу построить простой сайт (на локальном сервере, просто ради практики), который будет что-то листить. Людей, бананы - без разницы. Я просто селебрити выбрал. Сейчас сделал простую html форму для добавления новых записей в базу данных, на той же странице написал PHP скрипт, который пользуется переменными из $_GET для составления SQL INSERT INTO. Всё ок, только теперь не могу понять, каким образом написать скрипт для генерации html файла для каждого добавления в базу данных. То есть, у каждого селеба должен генерероваться свой профиль на основе страницы-шаблона.

Затем будет стоять задача построить механизм фильтрации по атрибутам (first_name, last_name, occupation, location, etc.) при поиске на сайте. Пока не могу даже в гугле толком вопрос сформировать, чтобы найти, что нужно. То есть, как реализовать фильтрацию по базе данных на странице html?

Подскажите, пожалуйста.
Аноним 06/03/19 Срд 22:59:23 1360452205
>>1360353
В тот же массив я записываю клоны объектов, чтобы потом их изменять, без изменения оригинальных объектов.
Аноним 06/03/19 Срд 23:14:33 1360464206
>>1360386
> теперь не могу понять
1. Пишешь скрипт который просто генерирует статический профиль.
2. Находишь в профиле всю инфу которая должна тянуться с базы.
3. Выделяешь эту инфу в переменные. Тоесть при генерации профиля инфа не захаркоджена а берется из переменных. Переменные ты инициализируешь перед скриптом генерации.
4. Придумываешь способ заполнить эти переменные инфой из бд.
5. .....
6. профит
Аноним 07/03/19 Чтв 01:41:38 1360493207
>>1360452
Ты берешь и перезаписываешь оригинал его клонированной копией. Так понятно?

function __clone()
{
foreach (твойМассив как $ключ => $значение) {
твойМассив[$ключ] (текущий ключ форыча, - прим. автора) = clone $объект
}
}

Это равноценно такому

$arr = [0 => 'a', 1 => 'b'];
//первая итерация
foreach ($arr as 0 => 'a') {
$arr[0] = 'a';
}

То есть форыч берет и перезаписывает значение на то же самое. Чтобы работать с копиями, тебе необходимо положить их в новый массив.
Аноним 07/03/19 Чтв 03:13:51 1360508208
>>1359945
>Реестр - это паттерн, который описыв
Спасибо, исчерпывающий ответ. Написал бы ты всеобъемлющую книгу по всем этим аспектам. Они ведь не устаревают. Будет пользоваться популярностью.

>>1359946
>У меня просто времени иногда нет, последние пару недель адски загружен.

А можно узнать, чем ты занимаешься? В студии трудишься или в каком-нибудь банке софт ваяешь?

>Ни в коем случае. Идея DI контейнера - IoC - предполагает
Хорошо, проблему синглтона контейнер решает.
А вот еще вопрос. Создал я класс подключения к мускулу, сделал для него сервис-провайдер, где он создается, а потом внедряю его, куда нужно.

А вот, скажем, мне нужен не один объект, а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?

>Я думаю, сервис провайдеры и сервисы хранятся в отдельных папках.

Спасибо, теперь все понятно.

>>1359948
Если у тебя используется дата маппер, то в нем и будет метод для загрузки моделек из БД.

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

>>1359949
> В задаче про студентов сортировку логично сделать аргументом в методе для получения студентов:

Спасибо за разъяснение особенно за последний абзац и за метод, ты сэкономил мне кучу времени.

>То есть перед выполнением нужных действий проверяем наличие логина. При отсутствии - редирект на форму логина с передачей текущего URL

А можно такую проверку делать в конструкторах? Например, в общий абстрактный контроллер засунуть. А то не делать же ее в каждом методе (боль, лол). И если юзверь не залогинен, то просто будет редирект на контроллер залогинивания, который этот конструктор не наследует.

>В твоем варианте пользователь может попробовать обойти авторизацию, вызвав напрямую метод "методПослеПосещения".

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

>Не думал, что у файлообменника такая сила. Сейчас, вроде начинающие разработчики делают сокращатели ссылок, но это уже неприлично просто.

А это разве не проще, чем файлообменник? Там ведь просто идет редирект на реальный URI при обращении к твоей ссылке. За вечер-другой можно сделать.

>>1359951
>Обычно делают отдельно шаблон для "лейаута" (шапка/подвал) и "контента". Лейаутов может быть несколько - например, один для морды, другой для админки. Как передавать параметры для лейаута? Тут есть варианты:


Я придумал вот что. Я в контроллере общем создал контейнер обычный массив data, куда записываю данные со всех уголков контроллеров и приходящие данные из моделей. В контроллерах-родителях задаю общие данные, в контроллерах специфичные, в методах контроллеров данные еще специфичнее. Данные записываются не через переопределение свойств, а через методы суперкласса.
Потом этот контейнер передаю в вид и обращаюсь к нему из шаблонов типа $data['title'], foreach($data['posts'] as $key => $post) {}, ну и все в таком духе. То есть "лейаут" и "контент" получаются данные из одного глобального массива data, переданного в вид. Так нормально?

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

Ну я имел ввиду, можно ли несколько "контентов" подключать в "лейаут".

Спасибо за ответы, ты будто чистое знание вливаешь мне прямо в мозг. Я, бывает, что-то очень долго ищу, бывает, несколько дней занимает поиск ответа на какой-то вопрос, иногда бывает сам додумываюсь до ответа, но проблема в том, что я не знаю, правильный он или нет. Но вот так очень круто зайти сюда и прочитать ответы на все, что я задавал. Пасиба.
Аноним 07/03/19 Чтв 03:15:56 1360509209
>>1360508
>а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?
Хранить в контейнере factory, через нее создавать объекты.
Аноним 07/03/19 Чтв 03:35:41 1360515210
>>1360509
Еще до фабрик не дошел, сейчас самое время, спасибо, анонче.
Аноним 07/03/19 Чтв 03:52:12 1360517211
А что лучше AIMPP или XAMPP?
Аноним 07/03/19 Чтв 03:56:55 1360518212
Аноним 07/03/19 Чтв 04:47:19 1360520213
На чем в 2019 Rest сервисы на пыхе пишут? Надо бы с автодокументацией какой, как в soap, с нормальной структурой и клиентами. Есть что удобное или все свои велосипеды городят? Пока нашел swagger + swagger-php + jane openapi, может еще кто на чем делал?
Аноним 07/03/19 Чтв 06:57:39 1360530214
>>1360209

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

>>1360214

Смысл в том, что когда мы клонируем объект и у него есть поле с массивом объектов, мы хотим сделать независимые копии этих объектов.

>>1360386

Тут есть 2 подхода. Статический и динамический.

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

Их можно генерировать 2 способами:

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

- можно при добавлении знаменитости генерировать страницу с ней и класть в папку, а также перегенерировать оглавление. Это должно быть недолго, и это можно сделать в скрипте обновления БД, только вынеси это в отдельные функции.

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

Есть и другой подход - динамический. При нем мы не храним HTML на диске вообще. Мы генерируем HTML-страницу знаменитости или оглавление на лету, когда пользователь ее попросит, и не сохраняем ее никуда. То есть когда пользователь заходит по адресу /celeb.php?id=123 (адрес можно будет поменять), то запускается скрипт, берет информацию о знаменитости 123, подставляет ее в шаблон и отдает получившийся HTML пользователю. Аналогично делается оглавление.

Плюс динамического сайта - то, что не надо ничего обновлять при добавлении или изменении информации, и что изменения в БД мгновенно отображаются на сайте. Плюс статического сайта - скорость работы, в десятки-сотни раз выше, чем у динамического. Минус статического сайта - по мере роста объема информации обновление занимает больше времени. Представь, что у тебя оглавление содержит 20 знаменитостей на страницу, а всего знаменитостей миллион. При добавлении новой тебе придется обновлять все 50 000 страниц оглавления.

Почитать про шаблоны можно тут: https://github.com/codedokode/pasta/blob/master/php/templates.md

Почитать про архитектуру MVC (для динамической генерации страниц) можно тут: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Наконец, у нас есть задача сделать список студентов - и в ней есть очень много комментариев, которые подойдут и тебе: https://github.com/codedokode/pasta/blob/master/student-list.md

> Подскажите, как можно обозначить вот эти элементы страницы любого саба на Reddit (pic related)?

Посты, записи.

> на той же странице написал PHP скрипт, который пользуется переменными из $_GET для составления SQL INSERT INTO.

Прочитай обязательно про инъекции: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

> Затем будет стоять задача построить механизм фильтрации по атрибутам (first_name, last_name, occupation, location, etc.) при поиске на сайте.

Это надо делать динамически, то есть при получении запроса из формы поиска ты должен сформулировать SQL запрос с условиями, выбрать знаменитостей из БД, сформировать HTML страницу и отправить пользователю.

Со статическим подходом это сделать вряд ли получится, так как фильтры дают огромное количество комбинаций и ты замучаешься генерировать заранее HTML страницу под каждую комбинацию.
Аноним 07/03/19 Чтв 07:06:14 1360531215
>>1360386

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

То есть HTML код будет генерироваться прямо в браузере, а сервер по сути будет просто предоставлять данные о знаменитостях в виде того же JSON.

Более того, если знаменитостей ограниченное кол-во (не более нескольких тысяч), можно просто информацию о них сложить в файл JSON (или CSV, XML) на сервере, программа на JS будет скачивать этот файл, и использовать информацию из него. В таком случае нам не придется писать PHP-код, который будет выдавать информацию о знаменитостях.

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

На практике, правда, когда пытаются реализовать этот подход, получается тормозной, глючный, плохо работающий, дергающийся сайт. Потому что этот подход сложный и не всем по плечу. Люди бездумно используют готовые библиотеки и подходы, даже не понимая толком, как они работают, какие у них ограничения.
PostgreSQL Аноним 07/03/19 Чтв 10:34:51 1360565216
Все чаще встречаю PostgreSQL. Хочу освоить.
MySQL знаю хорошо, сильны ли различия?
Где что можно посмотреть/почитать на русском, дабы обуздать PostgreSQL для людей знакомых с мускулем?
Аноним 07/03/19 Чтв 10:45:10 1360568217
>>1360565
>MySQL знаю хорошо
Кому ты пиздишь?
Аноним 07/03/19 Чтв 18:21:34 1360712218
>>1360565
Смысла по-моему не особо, mysql по уши хватает на задачи реляционных БД. Зато nosql решения часто в добавок к mysql на фирмах требуются, так что полезнее будет их поизучать, mongodb c редисами, elasticsearch.
Аноним 07/03/19 Чтв 19:05:39 1360726219
>>1360712
с редиской знаком, а монго давно как-то мельком юзал. Есть чето на русском годное и исчерпывающее?

И всетаки интересно именно по postgre
Аноним 07/03/19 Чтв 20:25:07 1360752220
>>1360531
Ого! Thanks for guidance. Буду разбираться.
Аноним 07/03/19 Чтв 22:33:15 1360792221
Аноним 08/03/19 Птн 00:06:51 1360810222
>>1360792
Спасиб. Но 5к страниц...
Аноним 08/03/19 Птн 05:20:14 1360840223
>>1353705 (OP)
Почему в экосистеме PHP такая чудовищно всратая ситуация с поднятием локального сервера?

Вот есть Нода. Спокойно запускает процесс сервера из любого каталога, лишь бы там были нужные файлы и всех пакетов хватало.
То же самое у Питона, но только надо с виртуальной средой чуть заморочиться.
ASP.Net? Да тоже в общем-то обычным процессом запускается, ещё и с exe-шников.
Да что там, даже Хаскель компилится в нормально исполняемый из любого каталога сервер.

И тут я прихожу в мир PHP. И наблюдаю удивительнейшие истории когда для запуска проекта нужно зачем-то пихать его в какую-то папку апача\нгинкса и смотреть как это чудовище пытается запускаться на 80м порту. При этом ещё по дефолту будет как-то странно всё отображать. Ещё и лагать может только в путь.
Блять, ну почему осталось именно так? Почему в 2к19 приходится наблюдать эти 90е?
Я прекрасно понимаю насколько это удачный подход относительно продакшн-сервера уже на готовом хосте, но для локальной работы, ещё и с несколькими проектами это какой-то ужас.
Аноним 08/03/19 Птн 08:12:02 1360858224
Аноним 08/03/19 Птн 08:22:28 1360865225
>>1360840
Даун, блядь
php -S localhost:8000
Аноним 08/03/19 Птн 10:36:47 1360880226
>>1360858
>>1360865
Надо же, не думал что буду так благодарен за струю мочи в мою сторону.
Работает прекраснейшим образом, без лагов и даже настраивать ничего не понадобилось.

Но почему тогда мне отовсюду XAMPP, LAMP, WAMP советуют ставить чтобы хоть что-то запустить?
Я в своё время по сути только из-за этого php и не трогал, что он целенаправленно MySQL пропагандирует с которым я не в ладах. А тут, получается, можно и без этого тоже чтоли?
Аноним 08/03/19 Птн 10:48:27 1360887227
>>1360880
> XAMPP, LAMP, WAMP советуют
Они желают тебе зла. Если собираешься серьезно погружаться в тему, то только php_fpm + nginx, а по мелочам и встроенного хватит.

>php и не трогал, что он целенаправленно MySQL пропагандирует
Ты шутишь?
Аноним 08/03/19 Птн 10:55:28 1360890228
>>1360887
>Если собираешься серьезно погружаться в тему, то только php_fpm + nginx, а по мелочам и встроенного хватит.
Что-то с nginx по-моему ебли и допотопности было не сильно меньше чем с Апачем.
>Ты шутишь?
Да не особо. По тем же хостингам если из БД предлагают только MySQL, то уже ясно что хостинг заточен на php. Те же стандартные стаки и почти все гайды - отовсюду предлагают именно MySQL.
Аноним 08/03/19 Птн 11:25:36 1360904229
>>1360890
Написал большую телегу, но стер все нахуй. Не в коня корм
Аноним 08/03/19 Птн 12:26:06 1360919230
Screenshot372.png (69Кб, 785x766)
785x766
Хочу немного прояснить за регулярные выражения.

Если мне нужно будет найти определенные буквы, то я могу написать:
[а-жк-у] (от А до Ж, от К до У), то код не слепит вместе Ж и К?
Есть ли какой- то символ, который можно ставить, чтоб чисто визуально видеть, что они (Ж и К) будут врознь?
Аноним 08/03/19 Птн 12:50:21 1360926231
SPA Аноним 08/03/19 Птн 14:35:54 1360970232
Смотрю вакансии фронтенда и везде нужен какой-то из spa фреймворков, что намекает что все хотят полностью перейти на гоняние jsona между еедпоинтами api
Вопрос:"Есть ли тут место php?"
Аноним 08/03/19 Птн 15:22:11 1360991233
>>1360970
Ну да. А что тебя смущает?
Аноним 10/03/19 Вск 01:09:41 1361764234
Аноним 10/03/19 Вск 01:43:06 1361773235
Няши, посмотрите верстку по макету, дайте советов мудрых и ответьте на некоторые вопросы. https://jsbin.com/pofasoviqa/edit?html,css,output
Знаю, код очень корявый, но я хочу стать лучше, потому мне нужны ваши ответа
Можно ли сделать плавный переход по якорям без JS?
Можно ли задать плавное всплывание картинок по нажатию на какую-либо из кнопок?
Копирайт всегда должен быть в футере, можно ли их разделить и будет ли это правильно? Я разделил, потому что так в PSD было. С шапкой также сделал.
Подписи к заголовкам обрамлять в <h> на пункт меньше или <p>?
Почему "margin: 0;" в body не работал и мне приходилось подписывать его к каждому элементу?
Аноним 10/03/19 Вск 01:45:54 1361774236
.jpg (131Кб, 568x895)
568x895
>>1361773
А, и что еще со значками соц.сетей мне делать нужно было? Я фигурку внутри кружка скачал, а она битая получилась, но я вставил все равно.
Аноним 10/03/19 Вск 09:00:32 1361814237
>>1354910

Вот что мне в ноде кажется неудобным - так это то, что каждый в Node.JS организует код как хочет. Вот, например, код: bodyParser.json() - непонятно, почему он сделан в виде вызова функции? Если он есть в единственном экземпляре, можно просто было бы использовать свойство bodyParser.jsonParser. Если там каждый раз надо создавать новый объект, можно было бы экспортировать класс: new bodyParser.JsonParser. А тут надо вызвать функцию, причем в ее названии нет ни малейшего намека на то, что это функция-конструктор (хоть бы createJsonParser ее назвали). Понятно, что это сторонняя библиотека, но все же не привычно.

А еще я открыл для себя, что в Express функция get() делает 2 разных вещи, в зависимости от числа аргументов: http://expressjs.com/ru/api.html#app . Кажется, разработчики Ноды решили пройтись по тем же граблям, которые проходили разработчики PHP.

Но в общем-то, я довольно плохо знаком с Нодой. Потому перейдем к коду.

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

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

https://github.com/someApprentice/Crypter/blob/master/server.ts#L30
> const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.js');

Это место очень трудно понять. Мне пришлось открыть вопрос по ссылке из комментария и прочесть его:

> // https://stackoverflow.com/a/51391081
> const asyncHandler = fn => (req, res, next) => {

И проблема тут в плохом названии и отсутствии комментариев. Нужно было назвать функцию, например, promiseToCallback, handlePromise или adaptPromise и снабдить комментарием (я еще убрал стрелки так как на мой личный вкус, они плохо читаемы):

// Комментарий
function wrapPromise(asyncFn) {
return function(req, res, next) {
return Promise....;
}
}

Еще я не очень понял:

1) зачем там нужен Promise.resolve(), если асинхронная функция при вызове и так возвращает нам промис.
2) зачем использовать return

Я бы тогда написал так:

// Принимает на вход асинхронный обработчик, и возвращает
// новый обработчик, который отлавливает выброшенные
// в нем асинхронно исключения, передавая их в next().
//
// ссылка на SO
function adaptPromise(asyncFn) {
return function (req, res, next) {
asyncFn(req, res, next).catch(next);
}

}

> Does Bearer token provide XSRF protection?

Я думаю, да, тут XSRF не пройдет, так как браузер автоматически добавляет к отправляемым запросам куки или заголовок Authorization для традиционной авторизации по логину-паролю (на чем и основана уязвимость), но не добавляет его для типа Bearer.

> if (err) throw new err;

А не throw err? err - это функция-констуктор или объект исключения?

> res.cookie('uuid', uuid, ...
> res.cookie('email', email, ...
> res.cookie('name', name, ...

А зачем тут столько кук? Они же уже содержатся внутри токена. А в твоем варианте пользователь может их подменить, и если ты доверяешь им на сервере, то получается уязвимость. Ну и вообще, нужно ли ставить куки в SPA? Это же серверное API, оно наверно не должно ставить куки. А должно отдавать JSON с токеном.

> json(<U> { uuid, email, name, jwt });

Не очень понятно, зачем здесь влеплен Type Assertion? Функции json() он не нужен, это для проверки, что объект соответствует интерфейсу User?

Еще, кстати, вопрос: а при регистрации проверяется уникальность email? Также, я подозреваю, что удобнее может быть сделать отдельную функцию для валидации, чем использовать только встроенные возможности sequelize.

По поводу JWT - я с ним не работал (но с интересом прочитал про него), но у меня уже есть сомнения: почему при подписании токена мы передаем все значения из модели? Получается, что токен перестанет работать в следующих ситуациях:

- пользователь меняет имя
- пользователь меняет email
- пользователь меняет пароль
- мы добавили новые поля в модель пользователя

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

И, кстати, а почему был выбран JWT? Какие-то еще варианты рассматривались?

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

async function createToken(u: User): Promise<string>

Чтобы мы могли бы создавать токены в любом месте API?

> let user = new User({ email });
> await user.validate({ skip: difference(Object.keys(User.rawAttributes), ['email']) });

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

> router.get('/email/:email'

Это не очень соответствует REST, так как URL в нем это указатель на "ресурс" (какую-то сущность), и при отсутствии ресурса ты должен отдавать 404. А ты всегда отдаешь 200. Я бы сделал тогда просто /email-exists?email=....

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

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

В наши дни наверно самый популярный формат документирования - это OpenAPI 3.0 (бывший Swagger). Ты описываешь свое API в виде YAML файла, и получаешь на выходе такую красивую штуку: https://petstore.swagger.io/ или такую: https://docs.discourse.org/

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

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

Аноним 10/03/19 Вск 09:03:16 1361815238
>>1354910

По тесту:

https://github.com/someApprentice/Crypter/blob/master/api/api.test.ts#L31

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

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

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

Для каждого требования мы придумываем свой способ проверки. Создание аккаунта на сервере можно проверить, попробовав залогиниться в него. Токен можно проверить, попробовав вызвать защищенное API, например "получить сведения о себе".

В общем, тесты пока сделаны неправильно.

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

На практике, может быть полезно разместить тестовую БД на ramfs, чтобы избежать вообще обращений к диску и ускорить прогон тестов.

Можно также попробовать добавить тест для обработчика ошибок (вызвать специальный URL, который выбрасывает исключение). Иначе ты можешь его отключить/сломать и не заметить.

> Is there any way to declare all classes at once for a webpack output file?

Я думаю, это не имеет отношения к webpack, так как ты должен в sequelize передать список классов. А для этого их надо импортировать. И вебпак увидит импорты.

По клиентской стороне:

Ты в API при логине ставишь куки вручную, но разве это правильно? По идее, это должно работать так:

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

Если ты сделал куки аналогом localStorage для серверного рендеринга, то, наверно, логично абстрагировать это от приложения. Оно работает с StorageService, а куда потом сохраняются данные - не его забота.

Тут конечно мы упираемся в проблему, что объем кук ограничен, в то время как в браузере мы можем кучу информации сохранить в localStorage. Решением наверно тут будет как можно меньше сохранять в storage, когда мы выполняемся в режиме рендера на сервере. В идеале - хранить там только JWT.

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

interface Storage {
getJwtToken(): Promise<string>
setJwtToken(token)
getUserData(): Promise<User>
setUserData()
}

И 2 реализации: клиентская берет данные из localStorage, а серверная - берет из БД или кук. Но это, конечно, требует писать два варианта кода.

Есть еще альтернатива, но она довольно сложная. Мы могли бы сделать что-то вроде "сессий" и делать для каждой "сессии" свой серверный аналог localStorage. То есть пользователь заходит на сайт, на сервере создается некий serverStorage, который не очищается между запросами. И приложение Angular, работая на сервере, работает с ним, как будто это localStorage. Ключом сессии может быть токен JWT. Данные serverStorage могут храниться в памяти Node-приложения или сбрасываться в HASH внутри редис.

То есть, когда приложение работает на сервере, в итоге данные пишутся в redis с ключом на основе JWT. Там конечно еще можно подумать над оптимальным по производительности алгоримом. И опять же, стараться при работе на сервере меньше сохранять данные в serverStorage, если они есть в БД.

https://github.com/someApprentice/Crypter/blob/master/src/app/app.component.html

Тут мне не кажется 100% надежной проверка залогиненности. Тут же нет проверки, что это валидный токен.

И еще, я не очень понял, как будет работать форма регистрации в режиме серверного рендеринга. Как и куда она будет отправлять свои данные?

> let route = this.router.config.find(r => r.path === redirect);
> route.data['email'] = email;

А это передает email только один раз, или ты этот email навсегда в конфиг роутинга вписал? По моем, не очень красиво получается. Разве нельзя передавать email внутри route parameters: https://angular.io/guide/router#route-parameters

Тогда можно сделать так: router.navigate(['/register', { email: email }])

Причем, я бы хранил email не в path, а в query: /register?email=xyz@example.com

> Позволяет ли Bearer token защититься от XSRF?
> Приходит ли вам на ум какая-нибудь слабая точка которую можно эксплуатировать?

Да. У тебя используются куки, и в них тоже есть токен. Предположим, у нас есть HTML версия, работающая без ангулара. Не получится ли, что злоумышленник сделает форму, которая будет имитировать отправку запроса этой HTML версией, и возникнет XSRF?

> Достаточно ли это строгая проверка на то является ли сущность экземпляром объекта localStorage?

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

> В правильной ли директории находится эта обёртка? Это не совсем сущность, например как User, но места по лучше я не могу придумать для неё. Куда следует помещать обёртки?

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

> Нужно ли делать проверку на каждую валидацию? Например на встроенные в Ангуляр валидаторы или на валидацию по регулярному выражению?

Нет смысла тестировать протестированное. Валидатор если и тестировать, то юнит-тестами, и они уже есть в сторонней библиотеке. Но надо протестировать, что:

- эти валидаторы действительно вызываются и проверяют данные
- их результат работы отображается

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

> Следующий шаг написания сервиса сообщений.

> Он будет реализован с помощь протокола WAMP и на платформе от https://crossbar.io/ , которая написана на Питоне, и для которой для аутентификации клиентов нужно тоже написать код на нём.

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

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

> Заодно и реактивное программирование подучу.

Конечно. Только пиши тогда, что именно ты добавил в проект и на что стоит посмотреть, а то он большой и с ходу это будет не очевидно.

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

Аноним 10/03/19 Вск 09:05:43 1361816239
>>1355067

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

Дополнительно да, сайт может смотреть, с какого IP ты зашел, и если он сильно поменялся, то попросить подтвердить вход ссылкой на email или SMS.
Аноним 10/03/19 Вск 09:09:41 1361817240
>>1355110

ТестХаб или задачу на SPA, но ты от нее умрешь, ее пока никто не решил. Можешь попробовать сделать SPA, но попроще, чем описанный в ней, например: сайт, показывающий новости (наподобие мобильной версии Хабра). Можно смотреть список новостей, можно смотреть новости из какого-то хаба, можно читать новость, лайкать и добавлять в закладки. Все это в виде SPA, с умным кешированием, автоматическим обновлением и способностью временно работать без Интернета на кешированных данных. То есть Интернета нет, ты жмешь лайк, он запоминается и при появлении связи отправляется. Или ты жмешь новость, и если она есть в кеше, она открывается. Обновления отслеживаются, если появились новые новости, то ввеху появляется плашка с предложением обновить список и загрузить их. Число лайков обновляется если кто-то жмет лайк. Как тебе идея?


Аноним 10/03/19 Вск 09:19:53 1361818241
>>1360508

> А можно узнать, чем ты занимаешься?

Просто обычная удаленная работа.

> А вот, скажем, мне нужен не один объект, а нужно итеративно и с условиями получить много, тогда что? Нужно будет в контейнере хранить не объект, а класс, а потом внедрять этот класс и там создавать через new?

Можно хранить фабрику (класс, создающий нужные объекты), можно в контейнере сделать метод, который позволяет создавать объекты с параметрами. Но вообще, надо подумать, а нужны ли в таких объектах зависимости? Обычно, если это объект типа "Пользователь", у них нет зависимостей и их можно просто создавать через new. То есть такие "сущности" обычно в контейнер не кладут.

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

Если ты читал мой урок https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md то знаешь, что есть ACtiveRecord, где сущности умеют сами себя сохранять в БД и Data Mapper, где они не умеют.

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

> А можно такую проверку делать в конструкторах?

Плохая идея, из конструктора нельзя возвращать значения, да и он не для этого. Но ты можешь сделать метод вроде beforeRequest() и обязательно его вызывать из фронт-контроллера.

> Я придумал вот что. Я в контроллере общем создал контейнер обычный массив data, куда записываю данные со всех уголков контроллеров и приходящие данные из моделей. В контроллерах-родителях задаю общие данные, в контроллерах специфичные, в методах контроллеров данные еще специфичнее. Данные записываются не через переопределение свойств, а через методы суперкласса.

Это плохо для чтения кода, так как чтобы понять, что передается в шаблон, надо изучать все эти места кода. Удобнее, когда передаваемые данные формируются в одном месте одним массивом.
Аноним 10/03/19 Вск 13:29:13 1361901242
Kotlin - это параша.
Аноним 10/03/19 Вск 20:47:23 1362166243
>>1361901
К чему ты это высрал?
Аноним 11/03/19 Пнд 16:46:44 1362488244
Господа, а есть какой нибудь хороший ресурс (желательно с практическими заданиями) для изучения sql?
Аноним 11/03/19 Пнд 20:52:47 1362602245
>>1361773
>Почему "margin: 0;"

Выбирай не через body, а через .

{margin: 0; padding: 0;}

>Подписи к заголовкам

В <p>. Our Featured Works и Get in Touch это будет h2.

>Копирайт всегда

@ 2013 Webpaint. All Rights Reserved. - у тебя в футере будет, а область выше это секция (section).

>со значками соц.сетей

У тебя на фото 5 значков, полностью их вырезай из макета, прямо с кружком. Вставляешь каждую по очереди и делаешь их ссылкой. Помести их в блок div.soc-but или типа того, сделай его display:flex и justify-content: space-between.

>плавное всплывание

webref.ru/css/transition

>плавный переход

webref.ru/css/scroll-behavior



Аноним 11/03/19 Пнд 20:58:45 1362606246
Аноним 12/03/19 Втр 11:00:20 1362894247
сап, анонесы, подскажите с чего начать, попал в небольшую стагнацию, освоил процедурный код пхп и дальше никак. Пытаюсь в ооп, но всегда есть какое-то непонимание, нахуя и почему так. Заебался уже читать эти тонны текста по нему, может кто-нибудь подкинет какой-нибудь легкий на подъем гайд с задачками? Чтобы поменьше воды и практикапрактикапрактика, или я не верный вектор взял и нужно не ооп дрочить, а какой-нибудь фрейм/мвц и т.д?
из того в чем разбираюсь норм это sql, pdo, html/css. А куда дальше ковырять не понимаю.
Аноним 12/03/19 Втр 12:33:07 1362922248
>>1362894
ООП раскрывается на больших проектах которые разрабатываются большими группами людей.
Самому понять трудно нахуя вообще нужны интерфейсы, и зачем по десять раз писать сначала обьвление в интерфейсе методов, потом их реализация. И другие вещи связанные в ООП.
Но на больших проектах оказывается что это наоборот экономит время и позволяет не повторять функционал по сто раз, передавать экземпляры класса как аргумент итд.
Аноним 12/03/19 Втр 13:52:29 1362954249
>>1362922
вот, и я нихуя не понимаю как мне это учить блждат.
Или ты хочешь сказать забить на ооп и только в теории понимание этого достаточно, пока не началась работа в сфере.
Аноним 12/03/19 Втр 14:15:31 1362965250
Разработчики, поясните в каких случаях стоит отделять mysql от сайта, а когда нет
Насколько нормально держать сайт и базу данных на одном сервере, при условии, что у бд указан локалхост вместо интерфейса
Аноним 12/03/19 Втр 15:02:08 1362992251
>>1362894

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

Если хочешь что-то посложнее, то к твоим услугам задача про ООП-гостинцу и ООП-будильник тут:

- ООП-Будильник: https://phpclub.tech/pr/res/1232710.html#1263399
- ООП-Гостиница: https://phpclub.tech/pr/res/1082507.html#1097078

Дальше, если ты все это сделал или все идеально знаешь, гугли и изучай инкапсуляцию, SOLID, DI. Кстати, у меня есть понятный урок по DI: https://github.com/codedokode/pasta/blob/master/arch/di.md

А еще по интерфейсам: https://github.com/codedokode/pasta/blob/master/php/interfaces.md

Ну и если есть желание, почитай другие уроки тут: https://github.com/codedokode/pasta/ - там есть и про MVC и про другие трендовые слова.

Ну и заодно почитай статью про выпечку хлеба: https://habr.com/ru/post/153225/

Если захочется увидеть применение ООП на практике, изучи библиотеку Symfony forms, разбери ее код и нарисуй диаграмму классов и связей между ними (кто кого наследует, кто кого создает).

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

Изучать ООП надо с основ. Если ты их не освоил, а берешься за паттерны, фреймворки, то конечно ты будешь путаться.
Аноним 12/03/19 Втр 15:54:13 1363007252
>>1362992
о, спасибо большое анон, отлично все расписал. Займусь сегодня, благодарю, буду вкидывать решения. Еще раз спасибо.
Аноним 12/03/19 Втр 16:31:25 1363025253
>>1353705 (OP)
не могу вывести названия элементов из дб в список в php файл
http://beta.phpformatter.com#.XIex79kY6AQ.link

выдает ошибку
Warning: mysqli_fetch_assoc() expects parameter 1 to be mysqli_result, null given in мой путь до файла

файл у меня на сайте на локалхосте через апач (опенсервер)
Аноним 12/03/19 Втр 16:35:23 1363027254
Аноним 12/03/19 Втр 17:01:11 1363045255
Имеет ли смысл использовать в студентах подобную систему валидации https://3v4l.org/gfBAC? Накидал на скорую руку, получился какой-то карго-культ на валидацию из симфони.

Кстати про симфони, в объектах-наследниках Constraint открытые публичные свойства. Получается бывают ситуации, когда инкапсуляцией можно пренебречь?
https://github.com/symfony/symfony/blob/4.2/src/Symfony/Component/Validator/Constraints/Length.php
Аноним 12/03/19 Втр 17:29:53 1363056256
Screenshot1.png (37Кб, 773x418)
773x418
Screenshot8.png (34Кб, 671x680)
671x680
Анон, поясни, чому он не печатает номера и почему пишет, что они неправильные все.
Аноним 12/03/19 Втр 17:52:49 1363067257
Screenshot376.png (33Кб, 546x685)
546x685
>>1363056
Чуть поправил, но эффекта не дало. Блэт.
Аноним 12/03/19 Втр 20:25:31 1363131258
image.png (13Кб, 577x204)
577x204
image.png (13Кб, 503x191)
503x191
>>1363027
я дебич

короче вот на пиках
первый пик подключение к дб
второй пик это я так пытался вывести тайтлы из дб в столбик
Аноним 13/03/19 Срд 06:57:42 1363279259
Аноним 13/03/19 Срд 07:30:27 1363281260
>>1363067
У тебя регулярка неправильная, [ ] задают список возможных символов, там не работают всякие | и &. Если тебе нужно условие "+7 или 8", то будет `(\+7|8)`.
Аноним 13/03/19 Срд 08:22:00 1363289261
А как по нормальному деплоятся сайты которые больше визиток? К примеру у меня небольшой веб-магазин, тысяч 60 товаров, 40 гигов фоток к товарам. И я хочу чтобы была возможность одной кнопкой переместить это все на другой сервак. С визиткой скажем понятно. Засунул в докер, где надо запустил с образа. С большими сайтами как-то не ок, так как на стайте каждый день что-то меняют (фотки к товарам + новые товары). Тоесть просто копировать образ докера не получится (если не пересобирать его после каждой новой фотки). Ну и база еще.
Аноним 13/03/19 Срд 11:08:34 1363338262
>>1363281
Спасибо.
Так и думал, что с "+7 или 8" будут проблемы.
Аноним 13/03/19 Срд 11:48:18 1363352263
Аноны, у меня такой вопрос, возможно ли каким-то образом параллельно запустить PHP для обработки данных с Mysql. Т.е. из БД я к примеру делаю запрос вида: SELECT * FROM `table` WHERE ... LIMIT 1000. А затем первые 500 строк обрабатываю в одном потоке, а остальные строки во втором потоке. Сейчас скрипт, который реализует этот функционал выполняется около 10 мин. Вся проблема в том, что записи связаны с другими таблицами, и одна запись из извлекаемой таблицы, может иметь несколько записей из других таблиц. Сам скрипт вносит определнные изменения в эти данные, т.е. вызывается UPDATE.
Аноним 13/03/19 Срд 14:02:56 1363410264
Если в StudentDataGateway объединить методы add и update в save() + добавить логику определения существования студента, то этот класс можно переименовывать в StudentMapper?

И ещё, в классе работы с БД очевидно нужна функция поиска студентов. Например $studentMapper->find($searchQuery, $orderBy, $orderDir, $offset, $limit);
Что если в find() передавать не кучу параметров, а объект с параметрами класса SearchOptions? Узнал о таком способе решения тут https://www.refactoring.com/catalog/introduceParameterObject.html
Аноним 13/03/19 Срд 15:07:09 1363443265
Есть вопрос насчёт цепочки исключений.
Вот такая функция:

[code lang="php"] %
public function func1()
{
$x = 0;
try {
///
}
catch(SomeException $e) {
switch ($e->getCode()) {
case 1:
throw new SomeException("message_1", 11, $e);
break;
case 2:
throw new SomeException("message_2", 22, $e);
break;
case 3:
try {
///
}
catch (SomeException $g) {
// brainfuck
$g->previous = $e;
throw new SomeException('message_5', 55, $g);
}
throw new SomeException('message_3', 33, $e);
break;
case 4:
///
break;
}
}
return $x;
}
% [/code]

Сложность в блоке с brainfuck. Так как написано - не получится хотя бы потому что и поля previous нету. Создать копию $g вроде как нельзя - перенесётся message и code, но не trace и остальное.
Как же сцепить исключения таким образом чтобы все данные нормально сохранились? Может тут какая-то стилистическая или структурная ошибка?
Аноним 13/03/19 Срд 15:36:57 1363467266
>>1363443

Код довольно большой, и не очень понятно, что ты хочешь сделать.

Связь исключений используется. чтобы показать, что одно исключение было вызвано другим. Ну например, чтобы показать, что исключение DataLoadException вызвано исключнием HTTPConnectException (мы не смогли загрузить данные, так как в ходе их получения не удалось соединиться с удаленным сервером). Пример:

function getData($x)
{
try {
$a = loadDataFrom('https://a.example.com/1');
$b = loadDataFrom('https://b.example.com/1');
return $a + $b;
} catch (HTTPConnectException $e) {
throw new DataLoadException("Не удалось загрузить данные из-за проблем связи с сервером", 0, $e);
} catch (AccessDeniedException $e) {
throw new DataLoadException("Не удалось загрузить данные из-за того, что доступ к ним запрещен", 0, $e);

}

Ты же в коде ловишь одно исключение. и создаешь на его основе исключение того же класса. Это выглядит как минимум странно.
Аноним 13/03/19 Срд 19:14:36 1363604267
Screenshot378.png (18Кб, 998x413)
998x413
Screenshot377.png (76Кб, 1643x639)
1643x639
Не могу понять, где ставить поиск символов, которые могут быть посреди номера.

Я пробую:
([0-9]{10}) ([\w]{0,}) - цифры и знаки в разных скобках.
([0-9]{10} [\w]{0,}) - цифры и знаки в одних скобках.
[0-9 [\w]{0,} ]{10} - знаки внутри скобок с цифрами.

Как я понял, то, что внутри (этих) скобок считается отдельным блоком, куда можно накидать кучу параметров, написанных [тут].
Но почему- то у меня не работает это никак.

Объясните, как, блять, тут делать, чтоб нормально было.
Аноним 13/03/19 Срд 20:20:14 1363624268
>>1363604
Читать нормальные статьи где объясняют регулярки.

>>1353705 (OP)
Вы все еще так же сидите на РПР? Это же каким дегенератом нужно быть.
Аноним 13/03/19 Срд 21:32:23 1363656269
Screenshot11.png (42Кб, 644x784)
644x784
Я все, я нихуя не понимаю.
Аноним 13/03/19 Срд 21:59:44 1363679270
wallhaven-36310.jpg (498Кб, 1920x1080)
1920x1080
сап програмач, хочу написать скрипт для регистрации на сайте, что нужно знать для этого, знаю кто то использует API с сайтов с смсками, хелпаните инфой кто какой обладает
Аноним 13/03/19 Срд 22:04:37 1363682271
>>1363679
для начала хочу каким образом он реализуется
Аноним 13/03/19 Срд 22:05:01 1363683272
>>1363682
образом* всё я плывву
Аноним 13/03/19 Срд 22:05:18 1363684273
>>1363683
всё мне пизда пора спать идти
Аноним 14/03/19 Чтв 06:29:35 1363959274
>>1363679
гугли скрипты для регистрации и делай для своей бд где у тебя юзеры будут храниться
если я правильно понял что тебе нужно

>>1363131
вот тут я просто поменял assoc на array и дописал запрос
кому интересно могу показать

Аноним 14/03/19 Чтв 11:48:16 1364043275
У вас тут так уютно, можно присоединиться из frontend треда?
Аноним 14/03/19 Чтв 13:27:06 1364097276
Screenshot379.png (26Кб, 614x554)
614x554
Всем приветик в этом чатике, это снова я.
Подскажите, блять, наконец уже, как сделать поиск символов между цифр.

Есть охуенная идея:
Накопипастить ([\W]{0,})([0-9]) десять раз, но это же пиздец как тупо. Уверен, есть другой способ, просто я слишком туп, чтоб его найти.


Подскажите, блэт.
Аноним 14/03/19 Чтв 13:33:17 1364102277
>>1364097
У программиста была проблема которую он предпочел решить регулярными выражениями.
Теперь у него две проблемы.
Аноним 14/03/19 Чтв 13:36:19 1364106278
>>1364102
Так же написано в учебнике, в котором дана эта задачка.
Аноним 14/03/19 Чтв 13:36:53 1364107279
>>1364106
Как думаешь для чего?
Аноним 14/03/19 Чтв 13:38:06 1364108280
>>1364097

- напиши выражение, которое находит ровно 1 цифру и любое число доп. символов за ней
- возьми его в круглые скобки и поставь после них {x}
Аноним 14/03/19 Чтв 13:38:28 1364109281
>>1364107
Чтоб не тратить время на изучение регулярок?
Аноним 14/03/19 Чтв 13:41:45 1364116282
Screenshot380.png (21Кб, 479x498)
479x498
>>1364108
Чот вообще не то. И неверные номера тоже зацепило.
Аноним 14/03/19 Чтв 13:45:29 1364120283
Screenshot381.png (25Кб, 639x463)
639x463
Такс.
Мы развиваемся и эволюционируем. Осталось понять, как искать символы между цифрами.
Аноним 14/03/19 Чтв 13:49:14 1364123284
>>1364120
Чот я прикола не понял.
Чому он пропускает некоторые номера? Не могу понять, по какому признаку он их выбирает.
В чем причина моих мозгах, аноны?
Аноним 14/03/19 Чтв 13:53:58 1364125285
>>1364123

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

Также, вместо {0,} можно писать просто звездочку.

Также, вместо \W лучше писать конкретные символы - минусы, скобки, пробелы, а то он что угодно под это выражение подгонит.


Аноним 14/03/19 Чтв 14:18:39 1364131286
Аноним 14/03/19 Чтв 14:21:39 1364135287
Screenshot384.png (36Кб, 998x506)
998x506
>>1364125
Спасибо тебе, помог очень сильно. Долго думал, как быть с пробелом между + и 7, но догадался(!) сделать там просто пробел.

> Также, вместо {0,} можно писать просто звездочку.
> Также, вместо \W лучше писать конкретные символы - минусы, скобки, пробелы, а то он что угодно под это выражение подгонит.

За вот эти советы отдельное спасибо, буду знать и применять.
Аноним 14/03/19 Чтв 15:31:23 1364171288
Аноны, привет, я нуб. Я тут валандаюсь с своим MVC, сейчас озадачен админкой и ролями и прочим.
Сейчас я очевидно горожу свои костыльные недо-велосипеды.
Может стоит взять какой нибудь фреймворк за основу? Сразу начинать с большого, я думаю о laravel. Или все таки какой то мини-фреймворк? Я правда о таких не знаю.
Основная задача все таки - посмотреть как это должно быть реализованно.
MVC для меня сейчас обязательно, так как я с начала изучения пишу классами на MVC.
Аноним 14/03/19 Чтв 16:40:28 1364223289
>>1364171
Рекомендую 2й уровень курса профит, там как раз про mvc. Очень доступно объясняет.
Аноним 14/03/19 Чтв 17:14:20 1364246290
>>1364171

Могу предложить простой урок про основы MVC: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Затем можно посмотреть какой-нибудь фреймворк вроде Yii2 (попроще) или Laravel, Symfony (посложнее). Это как раз подходит для варианта "посмотреть, как реализовано".

Для ролей обычно принято использовать RBAC.
Аноним 14/03/19 Чтв 17:35:20 1364272291
>>1364097
Бля, анон, как же хочется помочь тебе, но мне пиздец как впадлу даже твой скрин смотреть(

Гугли уроки по регуляркам от WebForMySelf

мимо бог регулярок
Аноним 14/03/19 Чтв 18:37:26 1364307292
>>1364272
> WebForMySelf
И на этом спасибо. Чем больше материалов, тем лучше. Где- то одни фичи рассказывают, где- то - другие.
Аноним 14/03/19 Чтв 19:17:14 1364338293
>>1364307
Там все рассказывают по регуляркам, больше тебе нихуя не надо
Аноним 14/03/19 Чтв 21:00:13 1364387294
В чем разница и какие преимущества между join и выборкой из двух таблиц?
Аноним 14/03/19 Чтв 21:04:38 1364393295
>>1364387
Технически никакой и на скорость выполнения не влияет, просто синтаксически наглядней, особенно если будет огромный запрос, то сразу видно будет какие таблицы юзаются, а в условии будут примитивные конструкции
Аноним 15/03/19 Птн 12:45:10 1364666296
>>1364387
Выборка из двух таблиц === inner join.
Есть ещё outer join (с пустыми клеточками) и редко бывает нужен self join (поиск совпадений в таблицах).
Алсо, не забываем о том, что в джойнах есть ключевое слово "ON", с ним код легче читать.
Аноним 15/03/19 Птн 13:08:49 1364678297
Многоуважаемые братья пхп-шники, подскажите пожалуйста. Задачка по проверке номера по регуляркам. Как написать регулярку которая: сначала идет +7 или 8, за ними ровно 10 цифр, между которыми может быть любое число скобок, минусов, пробелов
Я сделал как ^(\+?(8|7)\d{10})$ Но как сделать так, чтобы между цифрами могли быть пробелы, или другие символы?
Аноним 15/03/19 Птн 14:00:37 1364697298
>>1364678
(\+?7|8)([()\-\s]\d[()\-\s]){10}

([()\-\s]\d[()\-\s]){10}
Обязательно одно число от 0 до 9 (\d). Вокруг него может быть, а может и не быть любое количество пробелов, тире, скобок.

Помог как смог.
Аноним 15/03/19 Птн 14:02:27 1364698299
Аноним 15/03/19 Птн 14:39:27 1364712300
1
Аноним 15/03/19 Птн 15:08:02 1364724301
>>1364697
Я въехал в регулярку, спасибо!, как сам не допер до этого...
Аноним 15/03/19 Птн 19:19:06 1364877302
Аноним 15/03/19 Птн 20:02:53 1364906303
>>1364246
>Могу предложить простой урок про основы MVC: https://github.com/codedokode/pasta/blob/master/arch/mvc.md
К сожалению, там упущен один очень важный момент, а именно по поводу тонкого контроллера и толстой модели.
Аноним 15/03/19 Птн 21:02:39 1364946304
DvsPcVcWkAEPc90.jpg (180Кб, 930x1140)
930x1140
Недавно начал осваивать Linux (Lubuntu), поэтому никак не могу настроить apache2, чтобы он корректно отображал PHP скрипты.

Все установил через консоль, как описано здесь: https://howtoubuntu.org/how-to-install-lamp-on-ubuntu

Однако когда закидываю свой test.php в /var/www/html, то в результате браузер открывает пустую страницу. Смотрел туториалы рандомных индусов - у них всё отображается.

HTML файлы отображаются без проблем.

В чём может быть проблема? Выручьте идеями, пожалуйста.
Аноним 15/03/19 Птн 21:34:38 1364960305
>>1364946
/etc/php/<версия>/apache2/php.ini

display_errors = on

как минимум
Аноним 15/03/19 Птн 21:35:00 1364961306
Ребята, подскажите проект php на github-е, желательно e-commerce, в котором применяется DDD и код придерживается принципам SOLID?
Вроде теорию прочитал - понял, но на практике не могу применять, что касаемо DDD.
Аноним 15/03/19 Птн 21:49:09 1364964307
>>1364960
Спасибо за вариант! Изменил файл, проблема осталась, к сожалению.
Выходит абсолютно пустая страница.
Аноним 15/03/19 Птн 21:55:37 1364968308
>>1364964
Что ты изменил :) ?
Какая версия пхп у тебя под апачем работает?
Покажи свой test.php
Что ты в адресной строке набираешь?
Не заставляй ванговать
Аноним 15/03/19 Птн 21:58:48 1364972309
>>1364964
Еще ты забыл сделать sudo service apache2 restart
Аноним 15/03/19 Птн 22:12:28 1364981310
>>1364968
Окей, вот порядок моих действий:
1) sudo vim /etc/php/7.2/apache2/php.ini
2) нашёл строчку display_errors = Off, поменял на On (:wq, конечно же);
3) sudo service apache2 restart

Скрипт простой:

<?php

echo "This is supposed to be displayed!";

?>

Просто без задней мысли вбиваю:
file:///var/www/html/test.php
Аноним 15/03/19 Птн 22:28:39 1364990311
Аноним 15/03/19 Птн 22:44:37 1365006312
>>1364990
Я просто очень большой нуб, поэтому я просто создал HTML файл в /var/www/html
Назвал его test.html, положил туда простой контент и кликнул дважды. Затем поменял test.html в строке на test.php и ничего не получил.

Почему я так сделал? Потому что на винде localhost/myfolder выводит список файлов, которые без проблем запускаются по нажатию. Тут такое не работает.

Моя логика действий само собой вызывает улыбку, но вот как-то так.

Анон, большое тебе спасибо. Я не перестаю удивляться, как этот тред умудряется привлекать столько отзывчивых анонов.
Аноним 15/03/19 Птн 23:58:57 1365040313
Ребята, существует ли в пхп какой-то встроенный класс который содержит данные запроса?
Аноним 16/03/19 Суб 01:50:27 1365101314
>>1365040
Есть переменная (массив) $_REQUEST
Аноним 16/03/19 Суб 07:49:19 1365221315
Знаю петон, как быстро смогу перекатиться в ваш пхп?
Привет пхпешникам! Аноним 16/03/19 Суб 09:38:08 1365245316
Сам то я вкатился в бэкэнд яву, но желаю вам всем найти работку за деньги!
Аноним 16/03/19 Суб 10:46:04 1365254317
>>1365221
Довольно быстро. Но буден непривычно выделять переменные и ставить ; в конце команд.
А так - такой же простой язык, как и питхон.

поначалу орал люто, потому что вместо echo писал print().
Аноним 16/03/19 Суб 12:04:25 1365283318
image.png (21Кб, 543x218)
543x218
>>1353705 (OP)
Какую функцию использовать чтобы в zakaz.php отображался свой элемент из моей бд для каждого элемента цикла?
Аноним 16/03/19 Суб 12:33:43 1365292319
Аноним 16/03/19 Суб 16:39:52 1365456320
image.png (264Кб, 1920x1080)
1920x1080
syntax error, unexpected ';'

Что мне делать? :((
Аноним 16/03/19 Суб 17:35:06 1365486321
>>1365456
> syntax error, unexpected ';'
В 577 строке? Проверь предыдущие.
Аноним 16/03/19 Суб 20:07:12 1365553322
>>1365486

Хммм, удивительно, но твой способ магическим образом помог
Аноним 16/03/19 Суб 23:20:55 1365708323
1212.JPG (69Кб, 1180x626)
1180x626
аноны. хочу сделать ооп ферму. создал классы для 2-х типов животныых. Как мне описать ферму, чтобы она могла добавлять N животных, доить их и вытаскивать продукцию? опиши словесно
Аноним 16/03/19 Суб 23:43:50 1365742324
>>1365708
Следующие советы подразумевают что ты хочешь поебаться с ООП.
Рефакторишь своих животных чтобы они наследовались от общего базового класса. В базовом классе реализешь генерацию id, а также метод getYeld() - этот метод возвращает массив с дневными профитами с животного, в твоем случае это будет что-то типа ['milk' => 8] с коровы и ['egg' => 1] с курицы. В массиве можно возвращать несколько разных продуктов (если ты хардкорный фермер можно еще навоз например добавить - это важный ресурс). Ключи массива сделать костантами.
В классе фермы делаешь массив для животных. Для добавления животных делаешь метод addAnimal($class, $count) - указываешь класс животного и количество, ферма добавляет нужное количество в массив животных. Делаешь массив для хранения ресурсов. Добавляешь к ферме метод getYeld() который проходит по массиву животных, вызывает у каждого животного getYeld(), полученые результаты суммирует с массивом с ресурсами - тут нужно внимательно проследить чтобы результаты для каждого ключа суммировались с теми что уже есть в массиве, а не перезаписывались новыми.
Аноним 17/03/19 Вск 01:18:41 1365791325
>>1365283
пиши в sql запрос SELECT*FROM stor WHERE 'столбец цена' AS price AND 'столбец количество' AS quan и т.д , все отсально кроме запроса вроде корректное
Аноним 17/03/19 Вск 01:22:32 1365792326
>>1365742
геттеры и сеттеры - антипаттерн.

мимо Егор Бугаенко
Аноним 17/03/19 Вск 01:29:58 1365795327
>>1365792
Слушать Бугаенко - антипаттерн
Аноним 17/03/19 Вск 03:58:31 1365835328
>>1365792
Там нет геттеров и сеттеров.
Аноним 17/03/19 Вск 10:07:34 1365890329
Аноним 17/03/19 Вск 11:09:20 1365937330
image.png (212Кб, 1920x1080)
1920x1080
image.png (281Кб, 1920x1080)
1920x1080
функция json_decode() не работает к этой строке, json parser-ы и decode-ры говорят что всё ок, но вот json_decode() жалуется

помогите пожайлуста
Аноним 17/03/19 Вск 11:11:15 1365938331
>>1365937
забыл сказать:

$people получает значение null, а Sssend просто работающий аналог echo
Аноним 17/03/19 Вск 12:01:49 1365957332
>>1365245
Стоит ли укатываться в яву?
Аноним 17/03/19 Вск 12:25:42 1365974333
>>1353705 (OP)
Аноы, чет туплю.
Есть у меня класс Klass, у этого класса есть статический метод Start(){...}

создаю новый объект $obj = new Klass();
И вызываю статический метод из объекта не статическим способом:
$obj->Start(); и так работает
Какой жопой я читал документацию? Разве так можно?


Аноним 17/03/19 Вск 12:36:20 1365979334
>>1365974
Объявление свойств и методов класса статическими позволяет обращаться к ним без создания экземпляра класса. Свойство класса, объявленное как статическое, не может быть доступно посредством экземпляра класса (но статический метод может быть вызван).

http://php.net/manual/ru/language.oop5.static.php
Аноним 17/03/19 Вск 12:38:29 1365980335
Аноним 17/03/19 Вск 13:16:42 1365994336
>>1365937
Снкачала убедись что file_get_contents правильно читает файл, потом разбивай джон на части пока не найдешь строчку с проблемой
Аноним 17/03/19 Вск 15:22:51 1366045337
>>1365957
Хз что сказать.
Имей ввиду что йава ждуниоров фильтруют сложностью тестового.
Это ёба задание на 3-х листах английского текста на неделю, где специально выбирают ёба технологии про которые никто не знает (сразу отваливаются вкатальщики по роликам с ютуба и остаются тру пацаны которые умеют читать доки по английски и гуглить в стековерфлоу)
Если у тебя есть зелёный гит и что нить в сети на пхп то ты уже молодец.

someApprentice !EaaiHmIJms 17/03/19 Вск 17:55:24 1366102338
>>1361814
>Вот что мне в ноде кажется неудобным - так это то, что каждый в Node.JS организует код как хочет. Вот, например, код: bodyParser.json() - непонятно, почему он сделан в виде вызова функции? Если он есть в единственном экземпляре, можно просто было бы использовать свойство bodyParser.jsonParser. Если там каждый раз надо создавать новый объект, можно было бы экспортировать класс: new bodyParser.JsonParser. А тут надо вызвать функцию, причем в ее названии нет ни малейшего намека на то, что это функция-конструктор (хоть бы createJsonParser ее назвали). Понятно, что это сторонняя библиотека, но все же не привычно.
А ещё с TypeScript некоторые возможности теряются https://github.com/someApprentice/Crypter/blob/master/api/api.ts#L8-L9

Моё мнение что на JS не должно быть никакого кода, кроме браузерного, и максимум выдаваться SSR страницы. А серверный код должен написан на языках получше, например PHP.


>Комментариев, конечно мало. Наверно стоило бы хотя бы в начале файла писать, что это за модуль и для чего.
Ой-ой. Ошибка. Нужно было предупредить, что я комментарии оставлял "для себя" чтобы понимать что это и откуда взялось, и что это скорее всего нужно исправить.
К сожалению, инструменты для написания кода на JS ещё не совершены, и не справляются с тривиальными задачами, по моему приземлённому мнению.
Я перенёс эти проблемы в issues задачи https://github.com/someApprentice/Crypter/issues проверять это не нужно, но если у вас есть подсказка, то я с радостью её приму

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

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


>Тут ссылка на отсутствующий в репозитории файл - это нормально? Этот файл ведь из чего-то генерируется, и нельзя ли тут подключать исходный файл. Или хотя бы комментарий написать:
>
>https://github.com/someApprentice/Crypter/blob/master/server.ts#L30
>> const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main.js');
>
Да, эта папка генерируется после сборки приложения npm run build. Думаю тут тоже можно добавить комментарий.


>И проблема тут в плохом названии и отсутствии комментариев. Нужно было назвать функцию, например, promiseToCallback, handlePromise или adaptPromise и снабдить комментарием
Насчет комментария это да, их стоит добавить. Но я не понимаю почему вы пишите, что эта функция для того чтобы обрабатывать промисы, это не так. Эта функция нужна, чтобы обработать асинхронный обработчик запросов, который Эксрпресс не поддерживает (пока что?).

// Это не сработает
express.get('/route', async (...) => {
await promise = ...
});

https://github.com/someApprentice/Crypter/issues/12


>> if (err) throw new err;
>
>А не throw err? err - это функция-констуктор или объект исключения?
Объект исключения. Исправлю.


>> res.cookie('uuid', uuid, ...
>> res.cookie('email', email, ...
>> res.cookie('name', name, ...
>
>А зачем тут столько кук? Они же уже содержатся внутри токена. А в твоем варианте пользователь может их подменить, и если ты доверяешь им на сервере, то получается уязвимость. Ну и вообще, нужно ли ставить куки в SPA? Это же серверное API, оно наверно не должно ставить куки. А должно отдавать JSON с токеном.
Они нужны для отрисовки данных при серверном рендеренге. Как я уже писал, куки нужны только для условий отображений https://github.com/someApprentice/Crypter/blob/master/src/app/main/main.component.html#L3 . Возможно uuid можно убрать, но почему нет?

Здесь нет уязвимости, т.к. сервер (API) не использует куки.

Сделать приложение работающие без поддержки JS - я отказываюсь от этой идеи.


>> json(<U> { uuid, email, name, jwt });
>
>Не очень понятно, зачем здесь влеплен Type Assertion? Функции json() он не нужен, это для проверки, что объект соответствует интерфейсу User?
Да, именно так. Это лишнее?

>Еще, кстати, вопрос: а при регистрации проверяется уникальность email?
Нет, я забыл её сделать. Исправлю. И наверно нужно ещё это в схему БД добавить.

>Также, я подозреваю, что удобнее может быть сделать отдельную функцию для валидации, чем использовать только встроенные возможности sequelize.
Почему нужно отдельную функцию валидации? Всё же и так в одну строчку делается. https://github.com/someApprentice/Crypter/blob/master/api/api.ts#L50



>По поводу JWT - я с ним не работал (но с интересом прочитал про него), но у меня уже есть сомнения: почему при подписании токена мы передаем все значения из модели? Получается, что токен перестанет работать в следующих ситуациях:
>
>- пользователь меняет имя
>- пользователь меняет email
>- пользователь меняет пароль
>- мы добавили новые поля в модель пользователя
>
>На мой взгляд, токен должен переставать работать только при смене пароля (на случай, если пользователь боится, что у него украли токен и меняет пароль, старый токен должен перестать действовать). Соответственно, в подписи должны участвовать только uuid и хеш пароля. Или я ошибаюсь?
>
>И, кстати, а почему был выбран JWT? Какие-то еще варианты рассматривались?
>
>Также, я не уверен, а правильно ли токен создавать прямо в обработчике? Не логичнее ли сделать функцию такого вида:
>
>async function createToken(u: User): Promise<string>
>
>Чтобы мы могли бы создавать токены в любом месте API?

>почему при подписании токена мы передаем все значения из модели?
Да, я понимаю этот вопрос. Я думал, что можно сделать так, получать из Bearer token этот токен, и получать из него всё что нужно (имейл/что-нибудь ещё), но это, скорее всего нигде не пригодиться, так что это ошибка. Я согласен что достаточно хранить в нём только uuid и хэш.

>И, кстати, а почему был выбран JWT? Какие-то еще варианты рассматривались?
Он популярен. Чем популярнее технология, тем больше решений вопросов связанной с ней. В прочитанных мной статьях по JS приводят примеры именно с ним.


>Также, я не уверен, а правильно ли токен создавать прямо в обработчике? Не логичнее ли сделать функцию такого вида:
>
>async function createToken(u: User): Promise<string>
>
>Чтобы мы могли бы создавать токены в любом месте API?
Я скажу на чистоту мой взгляд на это - Я не понимаю зачем нужно выносить такие функции в отдельные. Это функция понятна любому разработчику и он с первого взгляда поймет что происходит в ней. Почему нужно делать обёртку ради человекопонятного названия функции?

Я правда не понимаю, вот как эта функция будет выглядеть (она кстати не работает на промисах):

function createToken(u: User, cb) {
token.sign(u.dataValues, JWT_SECRET, cb(...))
}

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


>> let user = new User({ email });
>> await user.validate({ skip: difference(Object.keys(User.rawAttributes), ['email']) });
>
>Это, конечно, выглядит немного корявым способом проверить email. Наверно, можно как-то получить функцию валидации отдельного поля?
Это баг библиотеки sequelize-typescript. Чтобы получить валидацию отдельного поля нужно вместо опции skip добавить fields.


>> router.get('/email/:email'
>
>Это не очень соответствует REST, так как URL в нем это указатель на "ресурс" (какую-то сущность), и при отсутствии ресурса ты должен отдавать 404. А ты всегда отдаешь 200. Я бы сделал тогда просто /email-exists?email=....
>Я бы сделал тогда просто /email-exists?email=....
Всё исправлю. Здесь тоже в случае отсутствия нужно отдавать 404?

>Не очень понятно, зачем ты тут вызвал валидацию и не использовал результат.
Хм, возможно валидацию и не стоило вызывать. Почему нет?

>и не использовал результат
Результат валидации либо вбрасывает ошибку, либо возвращает null(?). Эта ошибка обрабатывается в обработчике ошибок https://github.com/someApprentice/Crypter/blob/master/api/errorHandler.ts#L8-L10



>И еще важный момент. У тебя нет документации по API, а это плохо. Если фронтенд-разработчик хочет использовать твое API, где он прочтет документацию? Код что ли разбирать?
>
>В наши дни наверно самый популярный формат документирования - это OpenAPI 3.0 (бывший Swagger). Ты описываешь свое API в виде YAML файла, и получаешь на выходе такую красивую штуку: https://petstore.swagger.io/ или такую: https://docs.discourse.org/
>
>Естественно, логично не писать YAML руками, а генерировать его из комментариев в коде. Так ты получишь и комментированный код, и документацию для разработчиков.
Понял, буду работать над этим. Написать комментарии для документации API мне кажется более понятной задачей, чем писать комментарии для бушующих разроботчиков.

Так вы имели ввиду комментраии для модулей API, а не фронтенд приложения?
someApprentice !EaaiHmIJms 17/03/19 Вск 17:55:51 1366103339
>>1361814
>Еще, кстати, мне интересно, можно ли как-то использовать описания моделей (например, User) для автоматической генерации документации о формате JSON-ответа, и можно ли использовать описания для автоматического тестирования (тест берет Swagger-описание, проходится по всем методам и пробует их вызывать и проверяет, что ответ соответствует описанию).
Я ничего из этого не знаю, но постараюсь разобраться.


>>1361815
>Тут код теста почти повторяет код обработчика. Это не годится, так как ты можешь сделать одинаковые ошибки и там, и там.
А где у меня код повторяется? То что я токен генерирую? А как я узнаю какой токен будет иначе?

>Если мы тестируем функцию вычисления корня, то ее проверяют возведением в квадрат, а не аналогичным вычислением.
Не понимаю сравнение.

var n = 5
expect(sqrt(n^2)).toEqual(n)

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

var user = { ... }
token(user, (jwt) => {
expect(cookies['jwt']).toEqual(jwt)
});

Ну да, теперь вижу причину. Нужно проверить что пришедший токен в дешифрованном виде равен данным пользователя?

>В твоем случае надо сформулировать требования к функции регистрации. На мой взгляд, они такие:
>
>- она должна создавать аккаунт на сервере, под которым можно залогиниться
Я забыл сделать проверку, что пользователь добавился в БД и данные правильные. Это достаточное условие? Залогинивание проверяется в предназначенном для неё тесте, и там как раз сначала заполняется запись в БД.

>- она должна возвращать токен, с которым можно использовать защищенное API
Нужно сделать проверку как я писал выше, что пришедший токен в дешифрованном виде равен данным пользователя или действительно нужно проверять каким-то методом API?

>- нельзя дважды зарегистрироваться с одинаковым email
Сделаю. то нужно сделать прописав ассоциацию Sequelize на уникальность emai'а. Тогда при повтороном имейле будет вбрасываться ошибка и тест провалится.

>- нельзя регистрироваться без указания обязательных аргументов
Сделаю.

>- и, может, еще какие-то требования по валидации. Например, что при ошибке возвращается объект определенного вида
Сделаю.


>Для каждого требования мы придумываем свой способ проверки. Создание аккаунта на сервере можно проверить, попробовав залогиниться в него. Токен можно проверить, попробовав вызвать защищенное API, например "получить сведения о себе".
>Создание аккаунта на сервере можно проверить, попробовав залогиниться в него.
>Токен можно проверить, попробовав вызвать защищенное API, например "получить сведения о себе".
Почему? Разве не достаточно проверить что запись добавилась в базу? Разве не залогинивание не должно проверяться в своём собственном тесте?
А токен не достаточно проверить просто дешифровав его (как раз метод и называется verify(token))?


>Так как ты тестируешь код, использующий БД, тебе надо предусмотреть, чтобы база была перед тестом в каком-то определенном состоянии (полностью пустая, например, или с какими-то тестовыми данными). Один из вариантов - в самом начале почистить БД/загрузить дамп, а каждый тест обернуть в транзакцию, которая откатывается. Это может быть быстрее, чем загружать дамп каждый раз.
В данный момент для каждого теста БД должна быть в чистом состоянии и после каждого теста база очищается это можно улучшить добавив перед каждым тестом очистку (методо beforeEach()).

>На практике, может быть полезно разместить тестовую БД на ramfs, чтобы избежать вообще обращений к диску и ускорить прогон тестов.
Тяжело понять. Я с таким не сталкивался. Вижу что это как бы "эмулирует" жесткий диск в оперативной памяти. Как для этого настроить psql? Как нужно будет для это настраивать найстройки соеденения к БД в Ноде? Слишком много вопросов для такой маленькой задачи. Возможно позже, с ростом приложения это будет актуально. Если что взял этот подход на вооружение и вернусь к нему, когда тесты будут делаться медленно.


>Можно также попробовать добавить тест для обработчика ошибок (вызвать специальный URL, который выбрасывает исключение). Иначе ты можешь его отключить/сломать и не заметить.
Сделаю.

>> Is there any way to declare all classes at once for a webpack output file?
>
>Я думаю, это не имеет отношения к webpack, так как ты должен в sequelize передать список классов. А для этого их надо импортировать. И вебпак увидит импорты.
В sequlize-typescript можно указать директорию с моделями, но webpack транспилирует всё в один файл, и это ломается.

https://www.npmjs.com/package/sequelize-typescript#configuration
https://github.com/someApprentice/Crypter/issues/7


>По клиентской стороне:
>
>Ты в API при логине ставишь куки вручную, но разве это правильно? По идее, это должно работать так:
Ставлю куки вручную в клиентской стороне? Нет, у меня такого нет. В клиентской стороне куки только берутся из реквеста, чтобы пререндерить страницу с залогиненым пользователем или нет. Для этого они и нужны. localStorage ставиться в ручную(?) в клиентской стороне при залогинивании https://github.com/someApprentice/Crypter/blob/master/src/app/auth/login/login.component.ts#L48-L51 . Не могли бы вы уточнить строку где я это делаю, я не могу понять последующие описание проблемы.


>https://github.com/someApprentice/Crypter/blob/master/src/app/app.component.html
>
>Тут мне не кажется 100% надежной проверка залогиненности. Тут же нет проверки, что это валидный токен.
Так это же отображение. Если что-то не так, то при запросе к API выдастся соответствующая ошибка. Вряд ли, пользователь сможет что-то сломать не лазия в хранилище.


>И еще, я не очень понял, как будет работать форма регистрации в режиме серверного рендеринга. Как и куда она будет отправлять свои данные?
>
>> let route = this.router.config.find(r => r.path === redirect);
>> route.data['email'] = email;
Имеете ввиду версию страницы работающей с отключенным JS? Я решил отказаться от этой идеи. Она бесполезная, по крайней мере для части чата, потому что сообщения будут шифроваться на стороне клиента. Может быть позже можно что-то с этим придумать, но пока этого не будет. Я считаю, что это вопрос доверия пользователя, оно есть в каких-то границах, и эти границы могут как и широки так и малы, т.е. я пытаюсь сказать что зависит от пользователя и его доверия. Я думаю, что для приложения с открытом кодом можно даже задуматься и о вайтлисте js.

>А это передает email только один раз, или ты этот email навсегда в конфиг роутинга вписал? По моем, не очень красиво получается. Разве нельзя передавать email внутри route parameters: https://angular.io/guide/router#route-parameters
>
>Тогда можно сделать так: router.navigate(['/register', { email: email }])
>
>Причем, я бы хранил email не в path, а в query: /register?email=xyz@example.com
Можно, но мне наоборот кажется это не очень красивым, когда в URL что-то появляется. Хочу чтобы было так.
Этот email удаляется из роутинга после уничтожения связанного компонента:

https://github.com/someApprentice/Crypter/blob/master/src/app/auth/login/login.component.ts#L63-L68


>> Позволяет ли Bearer token защититься от XSRF?
>> Приходит ли вам на ум какая-нибудь слабая точка которую можно эксплуатировать?
>
>Да. У тебя используются куки, и в них тоже есть токен. Предположим, у нас есть HTML версия, работающая без ангулара. Не получится ли, что злоумышленник сделает форму, которая будет имитировать отправку запроса этой HTML версией, и возникнет XSRF?
Как я говорил ранее, я принял решение отказаться от версии без ангуляра, что значит что не будет такого обработчика запроса, который будет работать с куками повторюсь в очередной раз, что они нужны только для условий в отоброжении (токен наверно и удалить из кук)


>> Достаточно ли это строгая проверка на то является ли сущность экземпляром объекта localStorage?
>
>Проверка достаточная, но непонятен ее смысл. Тест по идее должен проверять, что данные сохраняются и загружаются, а не какой именно класс там испольуется для хранения.
Проверить... что, например, вот для серверной части есть проверка, что вернулся StorageWrapper и всё работает, а для браузерной тоже аналогично. Это не нужно?
someApprentice !EaaiHmIJms 17/03/19 Вск 17:56:40 1366104340
>>1361815
>> Следующий шаг написания сервиса сообщений.
>
>> Он будет реализован с помощь протокола WAMP и на платформе от https://crossbar.io/ , которая написана на Питоне, и для которой для аутентификации клиентов нужно тоже написать код на нём.
>
>А чем Node не годится, кстати? Или ты решил изучить Питон и микросервисы? Ок, но на практике такой маленький проект может быть невыгодно разбивать на микросервисы - у них ведь есть и накладные расходы.
У роутеров WAMP'а на Node, нету возможностей для аутентифекации и авторизации соединения, и документации. Вышеупомянутая платформа развита лучше других.


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


>Я пока все не успел проверить, увы, давай сначала с тем, что я написал, разберемся, а потом остальное глянем.
Хорошо, спасибо большое! Я не успеваю ответить в тот же день. Не понимаю почему - занимаюсь каждый день, и всё больше и больше нужно изучить. Я так хочу просто писать код. Я никогда не знал что разработка на JS может быть такой сложной, и приложений вообще.
Я ещё серьёзно задумываюсь о приложениях для устройств, а там либо медленный и кривой JS, либо изучать Java/Swift.

Я так хочу хотя бы браузернное приложение к лету закончить, а приложения к осени.


Спасибо большое, у меня нет слов как мне всё это важно.
Аноним 17/03/19 Вск 21:56:54 1366247341
Screenshot2019-[...].png (64Кб, 591x758)
591x758
Привет ананасы. Как-то давно начинал делать тестхаб на симфони, потом забил и сейчас опять решил, но уже на ларавель. Я уже даже немного смирился с евойной орм, пока решил не инсертить данные в таблицу. Тут просто ужасно всё, из-за архитектуры орм нельзя как в доктрине без записи в бд привязать определенные вопросы к тесту например, есть метод saveMany, думаешь что он может заинсертить всё одним запросом? он в цикле просто вызывает свой же save() метод, в итоге получается что на каждый объект идет запрос к бд, если у меня 50 вопросов и у каждого по 4 ответа то это получается 200 запросов к базе просто для сохранения. Помню в доктрине можно было банально через сеттер сначала сохранить всё как ты хочешь, а если еще и cascade: persist стоит то вообще можно не напрягаться. Читал что как вариант можно использовать DB::insert( array ), вручную расставлять внешние ключи и вот это всё. А вот та же валидация реквеста намного больше понравилась чем формы в симфони
Аноним 17/03/19 Вск 23:48:58 1366308342
>>1365937
Чекай
json_last_error,
невидимые символы,
кодировка без BOM
Аноним 18/03/19 Пнд 10:16:34 1366399343
>>1366247
>валидация реквеста намного больше понравилась чем формы в симфони
Тебе никто не запрещает запилить аргумент ресолвер в симфе и тоже валидировать реквест.
Аноним 18/03/19 Пнд 10:36:26 1366408344
>>1366247
в чём проблема использовать лару с доктриной ?
Аноним 18/03/19 Пнд 10:37:37 1366410345
>>1366045
Вот инглиш ща взялся поттягивать. С пыхой на "ты", опыт работы и гитхаб имеется.

С пыхи вообще укатиться сложно? Насколько это будет плюсом при приеме на работу? Или меня джависты будут обоссывать?
Аноним 18/03/19 Пнд 12:10:31 1366427346
>>1353705 (OP)
Вопросы по задаче про список студентов
1)Где нужно создавать базу данны=х? В командной строке(КС), в самом PHP или в PHPadmin?
Если использовать КС или админку, то как сохранять ... код на Git?
2) Так же не понял с, что делать с организацией доступа пользователей. Мне нужно через GRANT создать пользователя и или можно предоставить привилегированный доступ (root)? Я просто не понял, как люди проверяют работу через Git. Им же все равно нужно выгрузить весь код на свой компьютер и потом запустить у себя? Значит не нужно создавать пользователя или все таки нужно?
3) Зачем в этом задании использовать классы? Разве нельзя обойтись без них? Особенно не понял, зачем нужен "класс-помощник". Раз у него отсутствуют свойства, почему бы не использовать обычные функции?
Аноним 18/03/19 Пнд 15:03:57 1366516347
>>1366427
4)Также вопрос про экранирование. В уроке про шаблоны говорилось, что "данные лучше форматировать не в php-скрипте, а в шаблоне. Причина тому в том, что форматов вывода данных может быть много, а php-скрипт, получающий данные из базы, как правило один общий". Да, вроде бы логично, но неужели не правильней будет дать базе данных уже экранированную строку, а не повторять эти действия вновь и вновь в шаблоне?
Аноним 18/03/19 Пнд 15:06:27 1366520348
>>1366410
что в пхп не устраивает?
Аноним 18/03/19 Пнд 15:43:59 1366541349
>>1366427
1) В mysql или какой-то другой БД. У mysql есть удобный интерфейс phpmyadmin, также можно работать через КС.

2) Короче говоря, ты ставишь регистрирующемуся студенту куки которые записываются в том числе в базу данных.
Потом каждого пользователя подключающегося к нашему приложению проверяем на наличие кук. Если они есть, проверяем их на сущестование в БД. При положительном результате производим нужные нам действия, например вывод ФИО данного студента.

3.) Так надо

мимо сам делаю эту задачу
Аноним 18/03/19 Пнд 15:50:30 1366549350
Аноны, где у вас в wamp лежит ваш проект? Просто по стандарту в апач/htdocs и дальше там внутри сам проект, а базу создаёте отдельно где-то на с:/data/db допустим?
Аноним 18/03/19 Пнд 15:57:59 1366559351
>>1366520
1. Хочу больше денех;
2. Хочу глубоко изучать язык, жить этим, хотелось бы выбрать что-то более серьезное, на что не жалко тратить жизнь.
Аноним 18/03/19 Пнд 16:07:27 1366568352
>>1366410
>Насколько это будет плюсом при приеме на работу? Или меня джависты будут обоссывать?
Ты идёшь на ждуна, но ты с опытом чувак, это большой плюс!
Аноним 18/03/19 Пнд 16:34:18 1366599353
>>1366541
1)Ну про mysql понятно. А как мне создать БД, чтобы записать код в Git?
2)Тоже не то. Есть команда GRANT, управляет доступом БД. Когда я читал, про эту команду, говорилось, что лучше создать через эту команду пользователя(одного), чтобы не входить в БД через root. Вот я и спрашиваю, а оно надо? Как это будет работать, если код будет запущен на другом компе?
3)Ну тут можно было бы сказать, что это сделано для удобства. Но создавать массив объектов Student не затратно по памяти?
Аноним 18/03/19 Пнд 16:36:08 1366602354
>>1366599
>А как мне создать БД, чтобы записать код в Git?
Гугли про миграции и фикстуры.
Аноним 18/03/19 Пнд 16:47:00 1366610355
>>1366599
>1)Ну про mysql понятно. А как мне создать БД, чтобы записать код в Git?
Может сделать дамп базы (только структура, без данных студентов), например students_list.sql и добавить его в репозиторий? Учитель кажется писал об этом в конце задания.

2.) Понял тебя, довольно интересный вопрос. Я работаю со своей БД через root и даже не задумывался об этом, будем ждать что скажет ОП или другие опытные ребята.

3.) Нужно посмотреть как делают в фреймворках и сделать выводы.
Аноним 18/03/19 Пнд 17:51:11 1366652356
>>1366427

Ты можешь создавать у себя БД любым способом, но я бы советовал попробовать описать структуру руками в формате SQL (CREATE TABLE ...). Это поможет тебе вспомнить этот язык. Затем сделай дамп БД в формате .sql и положи в репозиторий, чтобы другие люди могли бы себе развернуть этот дамп. Не включай в дамп команды создания самой БД или пользователя, только команды создания таблиц и вставки данных. Так как у людей могут быть другие названия БД и имя пользователя.

Пользователя люди создадут сами, просто опиши в README, в какой файл надо прописать параметры соединения с БД и где лежит дамп.

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

>>1366516

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

А это создает сложности. Где должны экранироваться пришедшие от пользователя данные - в контроллере или в коде сохранения в БД? Функция валидации данных пользователя - что она принимает на вход, экранированные или неэкранированные данные? Функция, ищущая пользователя по id - в каком виде она вернет результат? Тебе надо по всему коду как-то расставлять комментарии, и тщательно проверять, что везде данные правильно преобразуются. Если где-то программист ошибся, то программа будет либо корежить данные, либо в ней появится уязвимость XSS.

Вторая проблема - если мы посмотрим на шаблон, то там нет команд экранирования. Как понять, что тут нет уязвимости? Изучать весь код и все пути, по которым могут передаваться данные? А если завтра новый разработчик добавит новый код, и забудет там поставить экранирование? Глядя на шаблон, мы это не увидим.

Хотя, эти проблемы мы могли бы решить с помощью ООП. Мы бы могли сделать объект SafeString, и у него несколько методов: getRaw(), getHtmlEscaped(), итд, возвращающих данные в нужном формате (и несколько статических конструкторов, позволяющий создать объект из обычной или экранированной строки). Это защитило бы нас от ошибок, так как мы сразу бы видели, какие данные получаются. Но это получается усложнение кода.
Аноним 18/03/19 Пнд 19:53:29 1366706357
>>1366559
плиз ответь на вопрос,
т.к я обычный вкатывальщик, меня интересует 1 вопрос, твои ожидания по увеличению зп с переходом пхп на яву, на сколько %.
Аноним 18/03/19 Пнд 20:17:59 1366719358
>>1366706
По первой может и меньше быть, но в ближайшей перспективе год-два хотябы в 2-3 раза
Аноним 18/03/19 Пнд 20:33:00 1366730359
>>1366247

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

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

В твоем варианте, вместо ручной расстановки startTranscation/commit лучше использовать готовый метод: https://laravel.com/docs/5.8/database#database-transactions

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

В твоем коде, тут 'body' => $question['body'] нет проверки, что $question это массив и там есть такой элемент. Не лучше ли использовать получение элемента по пути, как описано тут: https://laravel.com/docs/5.8/requests#retrieving-input или сделать проверку на наличие ключей?

> Помню в доктрине можно было банально через сеттер сначала сохранить всё как ты хочешь, а если еще и cascade: persist стоит то вообще можно не напрягаться

persist() ничего не сохраняет. Она лишь передает сущность под управление Доктрины. Сохранение происходит по flush(): Доктрина сравнивает данные в управляемых сущностях с теми, что были загружены из БД, и формирует запросы INSERT/UPDATE/DELETE, выполняя их в одной транзакции.

Вообще, я бы тебе советовал детально изучить ORM в Laravel, и в коде немного поковыряться, чтобы ты мог сравнивать Доктрину vs Eloquent и видеть плюсы/минусы.
Аноним 18/03/19 Пнд 20:34:08 1366731360
>>1366102

А напомни пожалуйста, зачем ты решил делать server-side rendering, если ты все равно поддерживаешь только браузеры с JS? Для изучения SSR?

Просто обычно SSR используется либо для поддержки поисковых ботов, либо для пользователей без JS или для создания "облегченной" версии. У тебя же ситуация усложняется тем, что ты пытаешься на сервере имитировать localStorage. Если бы у тебя был сайт вроде инстаграма или твиттера, то там можно было бы сделать SSR для поисковиков, и не было бы никаких сложностей. А для страниц с авторизацией делать SSR чуть сложнее.

То есть, я хочу понять, зачем и как используется SSR и что в этом случае можно сделать с хранилищем для сервера. Идея передавать кучу данных в куках мне не особо нравится.

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

Да, комментарии нужны там, где назначение модуля не очевидно.

> https://github.com/someApprentice/Crypter/issues/1

Тут я кстати обратил внимание, что у тебя в стектрейсе обфусцированные имена функций. Лучше было бы в dev использовать неминифицированные файлы, с исходными названиями функций, а то сложно разбираться в функции с именем t._e(). Не знаю, где это настраивается, может быть, в angular.json (но я не уверен).

Вообще, по моему мнению, в dev удобнее не склеивать файлы, а подгружать динамически (через что-нибудь вроде require.js или загрузчик для модулей ES6). Тогда в dev tools и в стек трейсах ты видишь файлы с теми же именами, как в оригинале, а не огромный main.js. Но я, увы, не знаю, легко ли это сделать в твоем случае.

> У меня плохо с английским и написание комментариев утяжелит и замедлил разработку. Насколько важно их писать?

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

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

> Эта функция нужна, чтобы обработать асинхронный обработчик запросов, который Эксрпресс не поддерживает (пока что?).

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

> Как я уже писал, куки нужны только для условий отображений

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

>> Функции json() он не нужен, это для проверки, что объект соответствует интерфейсу User?
> Да, именно так. Это лишнее?

Нет, я просто хотел спросить, зачем так сделано.

> Почему нужно отдельную функцию валидации? Всё же и так в одну строчку делается. https://github.com/someApprentice/Crypter/blob/master/api/api.ts#L50

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

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

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

> Я правда не понимаю, вот как эта функция будет выглядеть

function createToken(u: User): Promise<string> - наверно так?

> Всё исправлю. Здесь тоже в случае отсутствия нужно отдавать 404?

По идее, да, можно так, если ты хочешь следовать идеям из REST. Либо можно возвращать JSON с true/false, если не хочешь.

В идеологии REST (да и в стандартах HTTP что-то может быть), как я помню, URL соответствуют ресурсам, по типу:

/user/123 - пользователь 123
/book/some-book - какая-то книга

И ты можешь слать к этим ресурсам запросы GET/POST/PUT/DELETE. Такая схема очень хорошо работает с кешем - ты можешь просто использовать URL ресурса в качестве ключа кеша. У REST могут быть и минусы, например, может потребоваться делать много запросов для получения всех данных (хотя это зависит от того, как спроектировано API).

Потому не все используют REST. Например, у Ютуба в API для получения списка видео и одного видео используется один и тот же эндпойнт, просто с разными параметрами: https://developers.google.com/youtube/v3/docs/videos/list

> Результат валидации либо вбрасывает ошибку, либо возвращает null(?). Эта ошибка обрабатывается в обработчике ошибок

Там теряются подробности ошибки:

if (err instanceof ValidationError) {
return res.sendStatus(400);
}

Ну и довольно неочевидная штука, я бы не додумался лезть в обработчик ошибок смотреть код.
Аноним 18/03/19 Пнд 20:36:18 1366734361
>>1366102

> Так вы имели ввиду комментраии для модулей API, а не фронтенд приложения?

Главное, чтобы в коде было проще разбираться.

> Я же тоже "возвожу" данные пользователя в токен и проверяю совпадает ли возвращённый ответ, а именно кукисы, с ним.

Ты в тесте просто скопировал код из серверного API. Если ты его неправильно написал, то ты мог сделать одинаковую ошибку и в серверном коде, и в тесте. Потому проверять работу функции нужно другим кодом, другим алгоритмом, а не тем же самым.

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

Да и это нелогично, получатель токена ведь не должен знать, как он устроен внутри. Ему достаточно того, что этот токен дает доступк API, а как он устроен - не его дело.

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

Тесты проверяют требования (ТЗ) для API. У тебя в требованиях (если их сформулировать и записать пиьменно) вряд ли сказано, что "функция регистрации возвращает токен JWT такой-то структуры, зашифрованный таким-то ключом". Она возвращает просто токен, неважно какой. Знание о том, как он устроен, должно быть сконцентрировано в модуле для генерации и проверки токена, а остальным знать это не важно. Потому я и советовал вынести функции генерации и проверки токена в отдельный модуль авторизации.

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

> Ну да, теперь вижу причину. Нужно проверить что пришедший токен в дешифрованном виде равен данным пользователя?

Мне кажется, это будет плохая идея. Получатель токена не должен знать, как он устроен.

> Я забыл сделать проверку, что пользователь добавился в БД и данные правильные. Это достаточное условие? Залогинивание проверяется в предназначенном для неё тесте, и там как раз сначала заполняется запись в БД.

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

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

> Тяжело понять. Я с таким не сталкивался. Вижу что это как бы "эмулирует" жесткий диск в оперативной памяти. Как для этого настроить psql?

Я почитал тут:

- https://ru.wikipedia.org/wiki/Tmpfs
- http://www.k-max.name/linux/ramdisk-ramfs-tmpfs-in-linux/

Лучше использовать tmpfs. По идее, ты создаешь диск и монтируешь его в папку одной командой (могут понадобиться права рута, но можно прописать этот диск в /etc/fstab с опцией монтирования пользователем). tmpfs не тратит память, если на виртуальном диске нет данных, более того, она по моему не создает структуру каталогов и служебные области, а как-то хранит файлы напрямую в памяти.

После этого ты как-то настраиваешь psql, чтобы данные для тестовой базы хранились бы в папке с tmpfs. Я не знаю, как это сделать, но гугление выдает статьи вроде такой https://www.manniwood.com/postgresql_94_in_ram которая описывает создание отдельного инстанса Postgres с данными в tmpfs.

> В sequlize-typescript можно указать директорию с моделями, но webpack транспилирует всё в один файл, и это ломается.

Можно придумать какой-то костыль, например, читать список файлов и создавать файл "models.js", импортирующий все эти модели. Пока моделей мало, проще просто вручную перечислить.

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

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

> Можно, но мне наоборот кажется это не очень красивым, когда в URL что-то появляется. Хочу чтобы было так.

Так это не сохраняет состояние. Если мы обновим страницу, или используем навигацию в браузере (вперед/назад), то email потеряется. Потому аргументы и хранят в URL.

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

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

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

> У роутеров WAMP'а на Node, нету возможностей для аутентифекации и авторизации соединения, и документации. Вышеупомянутая платформа развита лучше других.

Да, но это можно добавить. А в случае с Питоном, ты не сможешь вызывать функции из приложения Node, тебе придется возможно дублировать их, или настраивать взаимодействие. Я не против такого варианта, но готовься к сложностям. И надо правильно спроектировать взаимодействие между питоновским и нодовским приложениями. Это уже почти микросервисы получаются со всеми их плюсами и минусами.
Аноним 18/03/19 Пнд 23:10:49 1366798362
reg.png (12Кб, 439x506)
439x506
Сап двощь, как сделать так чтобы между словами всегда оставался один символ замены, в данном случае | ? Ищу пробелы или % и хочу их поменять на один пробел, чтобы потом удобно было разбить массив по этому пробелу, в регулярках не силен
Аноним 19/03/19 Втр 00:55:17 1366855363
Untitled.png (66Кб, 606x576)
606x576
>>1366730
Привет ОП. В ларавеле я пока не особо хорошо разбираюсь, складывается ощущение что всё почти идеально пока у тебя какая-то типичная веб-задача, немного навязывается стиль написания кода, но мне как бы и норм, пока что хз какие бест практис и можно доверять фреймворку. Готовый метод транзакции кстати делает абсолютно тоже самое что и у меня, только через анонимную функцию. Не раз замечаю что на одну функцию может идти несколько алиасов, просто чтобы было чуть более интуитивно. А граф объектов у меня уже провалидирован, на том скрине не видно, но это не обычный Request, а ларкин FormRequest, обёртка, которая при создании валидирует входные данные на правила, как на скрине, и если валидация фейлится то в контроллер даже не пускает. Я её еще не доделал правда.
Я сделал объект Attempt, который представляет собой попытку прохождения теста, у него может быть два глобальных состояния, в процессе прохождения и завершен. Так вот я пока что не уверен что делать, когда клиент пытается завершить прохождение теста, но при этом присылает неправильные данные, например входной массив будет иметь вид [ключ_вопроса => ключ_варианта_ответа], клиент присылает свои варианты, но оказывается что указанный вопрос не имеет такого ответа, он относится или к другому вопросу, или его вообще не существует, айди ответа какой-то левый. Мне в таких случаях отправлять обратно что-то в стиле "Вы там у себя разберитесь, а потом перезвоните" и на этом всё или сразу завершать прохождение, помечать как зафейленное, при счете баллов можно например просто притвориться что пользователь банально не ответил на вопрос? То же относится и к отношению Тест -> вопросы в принципе.
Аноним 19/03/19 Втр 01:09:54 1366861364
>>1366798
Покажи для начала, что ты уже сделал. Потому что твой скрин говорит о том, что ты ленивая хуйлуша.
Аноним 19/03/19 Втр 02:11:55 1366870365
reg.png (18Кб, 517x499)
517x499
>>1366861
Мне после твоих слов прям обидно стало и я разобрался без понятия как это работает
Аноним 19/03/19 Втр 03:10:46 1366879366
Аноны, решаю задачу про проверку телефонов из учебника. Объясните мне пжалста, почему номера со скобками с пробелами рядом (вроде 8 (800) ...) определяются как неправильные? При этом просто с пробелами (8 8 00..) или со скобками (8(800)...) или даже со скобками и пробелами но не рядом (8 8(0)0 ...) - все нормально?

https://ideone.com/2ro2xS
Аноним 19/03/19 Втр 21:59:23 1367239367
>>1353705 (OP)
Антоны, мне нужно написать веб-морду для управления кое-каким сервисом. Основная функциональность - это внесение правок в конфиги, которые лежат на сервере, перезапуск этого сервиса ну и снятие парочки метрик с него.
Сейчас это делают написанные мной скрипты на баше, но хочу чего-то более юзер-френдли для других юзеров.
Ну и с авторизацией и разграничением прав, конечно (почти наверняка это будет в виде ldap учеток)

С программизмом я никак не связан, писал только скрипты на баше. Питон не знаю, да. Посоветуйте какую-нибудь книжку (а лучше видеокурс), чтобы быстро вкатиться в какой-нибудь простой пэхапэ-фреймворк. Думаю, что идеально было бы, если б учили сразу пилить какую-нибудь веб-морду/cms.
247-340 Аноним 19/03/19 Втр 22:28:49 1367259368
247-340

>>1366549

На линуксе обычно проекты кладут в /var/www/название. На windows - можно сделать отдельную папку на каком-нибудь диске. Например, c:\projects\. В apache/htdocs обычно лежит тестовая страница самого апача.

>>1366879

Если посмотреть на твою регулярку, то она написана примерно так:

- сначала идет 8
- затем 1 или больше скобок
- затем 1 или больше пробелов
- затем цифра

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

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

>>1366855

> Так вот я пока что не уверен что делать, когда клиент пытается завершить прохождение теста, но при этом присылает неправильные данные, например входной массив будет иметь вид [ключ_вопроса => ключ_варианта_ответа], клиент присылает свои варианты, но оказывается что указанный вопрос не имеет такого ответа, он относится или к другому вопросу, или его вообще не существует,

Проще всего приравнять это к отсутствию ответа (отстутствию ключа в массиве). Можно еще в лог варнинг писать, вдруг это фронтенд-специалист накосячил и не те данные шлет.
Аноним 19/03/19 Втр 22:29:36 1367261369
>>1363045

Вообще, проще наверно было бы совместить Constraint и ConstraintValidator. Не очень понятно, зачем делать 2 отдельных класса. В Симфони одна из причин - это использование аннотаций, Constraint это аннотация, потому оно сделано отдельным классом. В более простой системе разделять здесь код на 2 класса может быть, нет необходимости.

Код в классе Constraint в конструкторе немного усложнен. Не очень понятно, зачем присваивать свойствам значения из массива, если значения по умолчанию можно просто прописать при объявлении свойства.

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

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

>>1363410

Наверно можно переименовать.

> Что если в find() передавать не кучу параметров, а объект с параметрами класса SearchOptions?

Вполне хорошая идея. Я думаю, что этот объект может пригодиться и в других местах, например, при генерации ссылок для пагинации.

>>1364961

Я не знаю, есть ли там DDD или нет, но есть Magento - это e-commerce проект.
Аноним 19/03/19 Втр 22:30:07 1367263370
>>1363656

У тебя в регулярке написано [0-9]{10}, а это значит "10 идущих подряд цифр", без каких-то символов между ними.

> Как я понял, то, что внутри (этих) скобок считается отдельным блоком, куда можно накидать кучу параметров, написанных [тут].

Квадратные скобки [abc] - обозначают "ровно один любой символ из набора a, b или c"

Круглые скобки () используются для группировки, и позволяют применять квантификаторы ко всей группе. Сравни: abc+ - здесь плюс применяется только к букве c и регулярка ищет строки abc, abccc, abcccc. a(bc)+ - здесь плюс применяется к группе (bc) и регулярка ищет строки abc, abcbc, abcbcbcbc.

>>1363352

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

php script.php 1 199 &
php script.php 200 399 &
php script.php 400 1000 &
wait

Здесь & - это синтаксис линуксовой оболочки bash, который запускает команду в фоновом режиме. А команда wait ждет завершения всех фоновых программ.

Но здесь может быть проблема. Если ты используешь транзакции (а их стоит использовать) , то они блокируют данные, с которыми работают, и если нескольким скриптам надо работать с одними и теми же данными, то может так получиться, что работать будет только один скрипт, а другие будут ждать освобождения блокировки.
Аноним 19/03/19 Втр 22:30:31 1367264371
>>1363289

В случае докера, данные обычно не помещают внутрь образа. Докер часто используют только для того, чтобы засунуть программу + ее конфиг + зависимости (библиотеки) внутрь контейнера. То есть у тебя будет контейнер с nginx, с php-fpm, с mysql и docker-compose, чтобы их всех одновременно запускать. Но картинки и файлы таблиц базы данных не хранятся в этих контейнерах.

Более того, если у тебя есть dev сервер, тебе не требуется на нем держать все картинки с продакшена. Зачем? Пусть они на продакшене и лежат.

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

По поводу деплоя. Самый простой вариант, для простых сайтов - это деплой через rsync (команда копирования файлов) или git. То есть ты просто обновляешь скриптом файлы на сервере. Минус - в процессе деплоя есть момент, когда часть файлов уже обновлена, а часть еще нет и в этот момент сайт может выдавать ошибки.

Сине-зеленый деплой ( https://habr.com/ru/post/309832/ ) - это когда у тебя 2 папки для сайта. Сайт работает из первой папки, а деплой ты делаешь во вторую папку, и после завершения переключаешь настройку на веб-сервере, чтобы сайт отдавался теперь из второй папки. А следующий деплой делаешь в первую папку.

В случае с докерами и сине-зеленым деплоем, ты можешь сделать деплой кода в новую папку. Поднять там все докеры, используя другие номера портов (php-fpm, mysql). И затем переключить нгинкс на использование кода из новой папки. А старые докеры остановить.

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

Единственная проблема может быть с долгоживущими cli-скриптами (за время их жизни код в папке, из которой они запущены, мог обновиться), хотя на практике это маловероятно.
Аноним 19/03/19 Втр 22:30:52 1367265372
>>1363131

Скорее всего ошибка при выборке данных, например в SQL запросе. Ты должен после каждой команды работы с mysqli проверять, что она не вернула null или false. Или же настроить выброс исключений при ошибке и тогда проверять не придется.

Также, почитай про шаблоны и про XSS:

- https://github.com/codedokode/pasta/blob/master/php/templates.md
- https://github.com/codedokode/pasta/blob/master/security/xss.md

>>1363056

[+7|8] значит "ровно один любой символ из набора: +, 7, | или 8"

>>1362965

Если ресурсов сервера хватает, то можно держать на одном сервере. Разносят, чтобы например можно было запустить несколько отдельных php-серверов, и они бы не отъедали CPU у базы данных.
Аноним 19/03/19 Втр 22:55:14 1367276373
Свежее интервью с сore-разработчиком Yii - Александром Макаровым: https://youtu.be/uHHfnZDRHs8?t=109
Слушать всем, кто сомневается брать ли PHP сейчас, полезно послушать.
Аноним 19/03/19 Втр 23:19:12 1367290374
Аноним 20/03/19 Срд 07:16:58 1367370375
Задача "Grammar Nazi"
$text = "Жырный тролль сдесь.зделал координально срач а модеры?смотрят но всем плевать";
$regexp = '/([.,;:!?](\\S))|жы|шы|координально|сдесь|зделал|([^,] (а|но) )/ui';
$match = [];
if (preg_match_all($regexp, $text, $match) > 0) {
foreach ($match[0] as $number => $mistake) {
$number++;
echo "{$number}-я ашипка - {$mistake}\n";}}
выводит
1-я ашипка - Жы
2-я ашипка - сдесь
3-я ашипка - .з
4-я ашипка - координально
5-я ашипка - ч а
6-я ашипка - ?с
7-я ашипка - т но
Объясните мне, почему не видит слово "зделал"?
Аноним 20/03/19 Срд 12:33:55 1367463376
Картинка для пр[...].jpg (42Кб, 750x600)
750x600
В прошлый раз никого не нашел, репост. Нужен толковый чувак, веб-разработчик широкого профиля (фуллстак).

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

Языки программирования: PHP (на сервере 7.2), JS, HTML/CSS, SQL (на сервере MySQL или MariaDB).
Фреймворки: Yii, jQuery.
Технологии и инструменты: scss(sass), gulp, git, PHPStorm.
Нужен опыт работы над крупными yii-проектами (крупнее лаба10.пхп и сокращателя ссылок).

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

Задачи: доработка существующего продукта, который, по идее, написан неплохо (MVC, вся фигня), с нынешним разработчиком познакомлю, введем в курс дела.

dvachheadhunting@yandex.ru
Аноним 20/03/19 Срд 13:09:52 1367474377
>>1367463
без уи вобще никак? если симфоня есть например? если ванильное мвц есть например?
Аноним 20/03/19 Срд 13:26:20 1367478378
>>1367474
Вряд ли, проект уже имеющийся на yii написан, там куча строк кода, и его надо развивать, дорабатывать, фреймворк активно используется. Если ты сможешь быстро вкатиться в йиишные фичи (всякие там актив рекордс, актив форм, гридвью, контроль доступа, миграции) - то в принципе вариант.
Аноним 20/03/19 Срд 14:43:43 1367502379
>>1367463
Начинаю джун на подсосе случайно не нужен?
Аноним 20/03/19 Срд 14:44:02 1367503380
Аноним 20/03/19 Срд 15:36:52 1367536381
>>1367502
Возможно будет нужен через пару месяцев, пока ищу основного разраба в проект.
Аноним 20/03/19 Срд 17:23:05 1367587382
Аноны, почему, черт возьми, этот код на идеоне не запускается?!!! https://ideone.com/Nl5UmE
Я, блядь, полночи бился, выискивая ошибку в каждой букве, только чтобы обнаружить, что на phptester.net или на runphponline.com он прекрасно работает! Какого хрена?! Ну и проверьте, что ли, как я вообще решил эту задачу про палиндромы. Нормальный код?
someApprentice !EaaiHmIJms 20/03/19 Срд 17:41:30 1367597383
download.png (113Кб, 1920x1051)
1920x1051
>>1366731
>А напомни пожалуйста, зачем ты решил делать server-side rendering, если ты все равно поддерживаешь только браузеры с JS? Для изучения SSR?
>
>Просто обычно SSR используется либо для поддержки поисковых ботов, либо для пользователей без JS или для создания "облегченной" версии. У тебя же ситуация усложняется тем, что ты пытаешься на сервере имитировать localStorage. Если бы у тебя был сайт вроде инстаграма или твиттера, то там можно было бы сделать SSR для поисковиков, и не было бы никаких сложностей. А для страниц с авторизацией делать SSR чуть сложнее.
>
>То есть, я хочу понять, зачем и как используется SSR и что в этом случае можно сделать с хранилищем для сервера. Идея передавать кучу данных в куках мне не особо нравится.

>А напомни пожалуйста, зачем ты решил делать server-side rendering, если ты все равно поддерживаешь только браузеры с JS? Для изучения SSR?
Для ускорения загрузки приложения. И для поддержки поисковых ботов, конечно.

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


>> https://github.com/someApprentice/Crypter/issues/1
>
>Тут я кстати обратил внимание, что у тебя в стектрейсе обфусцированные имена функций. Лучше было бы в dev использовать неминифицированные файлы, с исходными названиями функций, а то сложно разбираться в функции с именем t._e(). Не знаю, где это настраивается, может быть, в angular.json (но я не уверен).
>
>Вообще, по моему мнению, в dev удобнее не склеивать файлы, а подгружать динамически (через что-нибудь вроде require.js или загрузчик для модулей ES6). Тогда в dev tools и в стек трейсах ты видишь файлы с теми же именами, как в оригинале, а не огромный main.js. Но я, увы, не знаю, легко ли это сделать в твоем случае.
У меня сейчас получилось сгенерировать не минифицированные файлы, убрав просто флаг --prod из команды сборки ng build --prod && ng run Crypter:server && webpack --config webpack.server.config.js

Добавил новый стактрейс: https://github.com/someApprentice/Crypter/issues/1#issuecomment-474728547

>Тогда в dev tools и в стек трейсах ты видишь файлы с теми же именами, как в оригинале, а не огромный main.js.
Разве и так в dev tools нельзя посмотреть все файлы даже после компиляции webpack'ом?pic-1


>> У меня плохо с английским и написание комментариев утяжелит и замедлил разработку. Насколько важно их писать?
>
>Там, где я работаю, проблему решили написанием комментариев на русском языке. А так, я думаю, что важно. Пока ты работаешь один, ты многое можешь держать в голове. Но что, если придет новый человек, и ему надо разобраться с кодом? Тут важно не количество комментариев, а насколько легко разобраться в проекте.
>
>У тебя в README даже не описана общая архитектура, как все связано. Я не очень хорошо знаком со всеми этими компиляторами и средствами сборки, и я путаюсь от того, что там в корне лежит куча разных конфигов. Если бы в README было описано, как происходит процесс сборки и какой конфиг за что отвечает, думаю, было бы понятнее.
Если честно, я сам путаюсь от такого количества конфигов, и я сам первый раз сталкиваюсь с этими всеми компиляторами и средствами сборки. Это бесконечная яма если я буду и это ещё изучать во всех тонкостях. Мне нужно изучить Python, мне нужно изучить crossbar.io (сегодня собираюсь писать действительный код), мне нужно изучить реактивное программирование, мне нужно написать само приложение, и на каждом шажке всплывает ещё 1000 подводных камней, которые нужно изучать. Я так никогда не закончу эту приложение.

Простите, что противлюсь вашим наставлениям - я исправлю это после всего... А пока, всё что нужно знать о сборке, тому кто хочет протестировать приложение, нужно всего лишь набрать npm run build.

Комментарии в коде для обёртки я обязательно добавлю.


>> Эта функция нужна, чтобы обработать асинхронный обработчик запросов, который Эксрпресс не поддерживает (пока что?).
>
>Я имею в виду, что когда смотришь на код, абсолютно непонятно, зачем эта функция и что за магию она делает. Я не знал, поддерживает ли express возврат промисов из обработчиков (теперь знаю, что нет). А если бы там был комментарий - было бы понятнее. Ну и мне кажется, функцию, которая адаптирует асинх. функцию к использованию в express вполне можно называть адаптером.
Хорошо, я переменную функцию и добавлю к ней более вразумительный комментарий.


>> Как я уже писал, куки нужны только для условий отображений
>
>По идее, эти данные на сервере проще получить из БД по токену авторизации. Значит, куки можно было бы не делать. То есть тут получается избыточность, как мне кажется.
Да, можно написать и серверный код в Angular-приложении за счет проверки на isPlatformServer(), но для этого нужно будет... хм, внутри этой проверки делать отдельные импорты библиотек (sequelize, dotenv, весь серверный код) чтобы они не тянулись в браузерной части. Мне не нравится этот стиль написания кода, так ещё не понятней будет, и к тому же нужно будет писать другую абстракцию - ничего от этого не выигрывается и только теряется время на написание дополнительных комментариев, увеличения кода, роста количества файлов, и что значит сложности в изучении проекта.

Я вижу вашу мысль об избыточности и понимаю, что это связанно с тем что есть и localStorage и кукисы, но почему бы и нет? Это нормально использовать и кукисы и localStorage. Что мешает этому? Это же машинное хранилище, и им нужно пользоваться.
Можно посмотреть на это так - сервер рендерит страницу с помощью кук, а js приложение подхватывает полученную страницу и уже работает с localStorage. То с чем и должен работать js, не получая доступ к кукам. Разве это не плохо что js имеет доступ к кукам?


>> Почему нужно отдельную функцию валидации? Всё же и так в одну строчку делается. https://github.com/someApprentice/Crypter/blob/master/api/api.ts#L50
>
>Пока это не требуется, но если ты захочешь сделать проверку уникальности или другую проверку, требующую обращения к БД или сервисам, то из модели ты не сможешь это сделать, так как у нее нет ссылок на эти сервисы. И тебе понадобится внешняя функция валидации.
А, хорошо. Конечно, для таких случаев я бы написал сервис валидации.

>Чтобы избежать дублирования кода. Чтобы не надо было в нескольких местах править одинаковый код. Ну и чтобы не писать код длинной портянкой, а разделять на отдельные части.
В данный момент тогда лучше сделать сервис с методом .login(...), потому что, пока что, код дублируется в двух местах и нужен как раз для залогинивания. Думаю, всё таки нужно написать сервис Authorizer.


>> Я правда не понимаю, вот как эта функция будет выглядеть
>
>function createToken(u: User): Promise<string> - наверно так?
Я выше написал, что для этой функции нужно передать коллбэк и в итоге получится тоже самое, либо нужно делать отдельную функцию для каждого случая createTokenForLogin(u: User) Promise<string>, createTokenForSomething(smth: any) Promise<string>... Может правда лучше разбить сам код на функции, и там пользоваться функцией создания токена как есть?


>> Результат валидации либо вбрасывает ошибку, либо возвращает null(?). Эта ошибка обрабатывается в обработчике ошибок
>
>Там теряются подробности ошибки:
>
>if (err instanceof ValidationError) {
>return res.sendStatus(400);
>}
>
>Ну и довольно неочевидная штука, я бы не додумался лезть в обработчик ошибок смотреть код.
А как иначе нужно делать? Делать блоки try/catch каждый раз и каждый раз повторять один и тот же код? Разве в PHP на Slim'е не была такая логика обработки ошибки?
someApprentice !EaaiHmIJms 20/03/19 Срд 17:41:54 1367598384
>>1366734
>> Я же тоже "возвожу" данные пользователя в токен и проверяю совпадает ли возвращённый ответ, а именно кукисы, с ним.
>
>Ты в тесте просто скопировал код из серверного API. Если ты его неправильно написал, то ты мог сделать одинаковую ошибку и в серверном коде, и в тесте. Потому проверять работу функции нужно другим кодом, другим алгоритмом, а не тем же самым.
>
>Плюс, второй недостаток теста - ты в нем используешь знание о том, как устроена функция регистрации, как она генерирует токен. Если в алгоритме генерации токена что-то поменяется, тебе придется преределывать тест.
>
>Да и это нелогично, получатель токена ведь не должен знать, как он устроен внутри. Ему достаточно того, что этот токен дает доступк API, а как он устроен - не его дело.
>
>В твоем случае, если ты вызываешь API регистрации, логичнее всего проверить, что полученный токен можно использовать для доступа к защищенному API. Или хотя бы вызвать функцию проверки токена.
>
>Тесты проверяют требования (ТЗ) для API. У тебя в требованиях (если их сформулировать и записать пиьменно) вряд ли сказано, что "функция регистрации возвращает токен JWT такой-то структуры, зашифрованный таким-то ключом". Она возвращает просто токен, неважно какой. Знание о том, как он устроен, должно быть сконцентрировано в модуле для генерации и проверки токена, а остальным знать это не важно. Потому я и советовал вынести функции генерации и проверки токена в отдельный модуль авторизации.
>
>Принцип разделения ответственности здесь нарушается. Это легко видеть по тому, что код теста использует секрет, который нужен для генерации токена. Тесты ведь имитируют поведение пользователя API. А у него нет этого секрета.

>Плюс, второй недостаток теста - ты в нем используешь знание о том, как устроена функция регистрации, как она генерирует токен. Если в алгоритме генерации токена что-то поменяется, тебе придется преределывать тест.
У меня в тесте с логином, я сначала добавляю пользователя в БД, а потом проверяю само залогиневание. То есть я здесь тоже использую знание о том как устроенна функция. А что если алгоритм сохранения пользователя тоже поменяется? Здесь тоже ошибка? Как тогда быть? Нужно писать какую-то абстракцию над БД во время тестов? Значит, нужно сначала вызвать функцию регистрации?

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

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

Всё исправлю.

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


>> В sequlize-typescript можно указать директорию с моделями, но webpack транспилирует всё в один файл, и это ломается.
>
>Можно придумать какой-то костыль, например, читать список файлов и создавать файл "models.js", импортирующий все эти модели. Пока моделей мало, проще просто вручную перечислить.
Я плохо разбираюсь как настраивать webpack. В проблемах этой библиотеке, мне сказали, что нужно написать плагин для этого.
Буду пока вручную перечислять, хоть и знаю что это плохо.


>> Я считаю, что это вопрос доверия пользователя, оно есть в каких-то границах, и эти границы могут как и широки так и малы, т.е. я пытаюсь сказать что зависит от пользователя и его доверия. Я думаю, что для приложения с открытом кодом можно даже задуматься и о вайтлисте js.
>
>Проблему можно решить, выложив клиентский код в открытый доступ и собрав из него electron-приложение. Если мы сами собрали его из проверенных исходников, то никто не сможет подменить код клиента.
Вот именно. Код и так будет в открытом доступе. Только, к сожалению, не каждый пользователь сможет сделать это самостоятельно. Даже я думаю, что это не так просто, как вы говорите.

Что вы знаете о других инструментах созданий приложений? Я знаю о таком инструменте как React Native и нагуглить NativeScript, но учитывая свой печальный опыт с React'ом, я боюсь что с ним тоже будет не всё так гладко. Ну конечно же, это ни секрет что JS медленный.
Вы знаете что-нибудь об их этих инструментах и как легко с ними будет работать? После ваших слов, создаётся ощущение, что в случае с Electorn'ом это действительно будет достаточно склонировать репозитирий и собрать из него десктопное приложение - и мне интересно, будет ли здесь всё так же просто?


>> Можно, но мне наоборот кажется это не очень красивым, когда в URL что-то появляется. Хочу чтобы было так.
>
>Так это не сохраняет состояние. Если мы обновим страницу, или используем навигацию в браузере (вперед/назад), то email потеряется. Потому аргументы и хранят в URL.
>
>Тут тогда логичнее было просто сделать единую страницу регистрации/логина на одном роуте с двумя формами и скрывать одну из них. А email хранить в обычной переменной. И не понадобятся такие явно ненадежные костыли.
Мне кажется так удобно будет для каждого пользователя. Например, мы же не можем знать заранее зарегистрирован человек или только хочет зарегистрироваться, и всё что ему нужно это просто ввести свой email и дальше система определит, что он хочет сделать. Я такое видел только в моей бывшей любимой соц.сети - tumblr'е, но сейчас они убрали эту функцию. Я считаю это очень удобным и типо приветливым.


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


>> У роутеров WAMP'а на Node, нету возможностей для аутентифекации и авторизации соединения, и документации. Вышеупомянутая платформа развита лучше других.
>
>Да, но это можно добавить. А в случае с Питоном, ты не сможешь вызывать функции из приложения Node, тебе придется возможно дублировать их, или настраивать взаимодействие. Я не против такого варианта, но готовься к сложностям. И надо правильно спроектировать взаимодействие между питоновским и нодовским приложениями. Это уже почти микросервисы получаются со всеми их плюсами и минусами.
Можно вызывать функции приложения из Node с помощью Remote Procedure Calls паттерна реализуемым WAMP.

Я не знаю, о каких функциях приложения Node вы говорили, но у crossbar.io есть возможность сделать компонент(?) и на другом языке https://crossbar.io/docs/Guest-Configuration/?highlight=node.js
Аноним 20/03/19 Срд 17:41:58 1367599385
>>1367587
Что ты там выискивал, если тебе прямым текстом говорится, в чем ошибка? Похоже, что у них похапе без расширения ext-mbstring
Аноним 20/03/19 Срд 17:59:04 1367607386
>>1367599
>расширения ext-mbstring
А что это вообще?
Аноним 20/03/19 Срд 18:23:55 1367619387
>>1367607
Не работают там функции с приставкой mb_ , твёрдо и чётко.
Аноним 20/03/19 Срд 18:27:47 1367622388
>>1367607
Расширение, которое добавляет в пхп функции с приставкой mb_
Ну например mb_strlen().
Аноним 20/03/19 Срд 19:46:39 1367643389
>>1367607

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

Увидеть список основных расширений, и какие в них есть функции, можно в мануале: http://php.net/manual/ru/funcref.php

Кроме них, бывают еще сторонние расширения.

Про установку расширений можно почитать тут: http://php.net/manual/ru/install.pecl.php Под Windows обычно ты просто скачиваешь расширение, кладешь в папку и указываешь его в конфиге.
Аноним 20/03/19 Срд 20:06:02 1367648390
>>1367239
Короче нихуя не ответили - говно, а не доска
Аноним 20/03/19 Срд 20:14:33 1367653391
>>1367648
Народ по полгода вкатывается, а тут Васян пришёл - быстренько подайте ему супер-курс по двухдневному вкату.
Прост нахуй иди.
Аноним 20/03/19 Срд 20:19:06 1367654392
2019-03-2020-17[...].png (10Кб, 366x562)
366x562
Привет, анончики, на связи вкатывальщик. Желаю задачи из учебника в шапке, почему-то залип на первой же, связанной с циклами.
Неожиданно нашел решение, но мне кажется оно какое-то... Ну не то оно какое-то. Пните, скажите как надо было сделать красивее.
https://ideone.com/N2Zr7R
Аноним 20/03/19 Срд 20:19:20 1367655393
>>1367239
Курс с символичным названием "$Профит$". Найдешь на торрентах
Аноним 20/03/19 Срд 20:22:00 1367657394
>>1367654
Всё правильно, с почином!
Аноним 20/03/19 Срд 20:23:24 1367658395
>>1367657
Благодарю! Пока что эта больше всего времени заняла, хотя решалась в одно действие, но тем приятнее все же было победить.
Аноним 20/03/19 Срд 20:26:38 1367662396
>>1367239
>Посоветуйте какую-нибудь книжку (а лучше видеокурс), чтобы быстро вкатиться в какой-нибудь простой пэхапэ-фреймворк
Документация к Laravel\Symphony\etc.

Следующий.
Аноним 20/03/19 Срд 20:33:30 1367668397
>>1367653
>супер-курс по двухдневному вкату
Кто тебе сказал, что по двухдневному?

>Народ по полгода вкатывается
Полгода вкатывается во что? В запись файлов на пхп? Соболезную

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

>>1367662
>Документация к Laravel\Symphony\etc.
Документация == видеокурс? Похоже, у тебя с восприятием еще хуже, чем у антона выше, лол или ты просто хреново умеешь читать представляю, какой у тебя код

>>1367655
Тосто и тупо тут, видимо, все аноны такие же тупые?
Аноним 20/03/19 Срд 20:37:59 1367673398
>>1367668
Тебе тут никто уже не поможет.
Аноним 20/03/19 Срд 20:39:23 1367675399
>>1367673
Ага, я понял, поэтому сменил тему разговора со своего реквеста на обсуждение тупости местных анонов
Аноним 20/03/19 Срд 20:44:11 1367679400
>>1367675
>запись файлов на пхп
>видеокурс
>...
>называет кого-то тупым
Давай дальше развлекай.
Аноним 20/03/19 Срд 20:52:41 1367685401
>>1367679
>Давай дальше развлекай.
Хорошо

>запись файлов на пхп
А ты в своих проектах на пхп запись в файл, видимо, не используешь, дегрод? Но я не удивлюсь, если ты еще и чтение из файла не осилил.

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

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

Пиши, если тебя что-нибудь еще заинтересует
Аноним 20/03/19 Срд 20:57:04 1367690402
>>1367685
Парни, подгоните этому гению 15 часовой курс лекций по конкатенации строк в пыхе, у кого есть.
А ещё тут где-то анон ходил, с 9 часовым курсом по регуляркам.
Аноним 20/03/19 Срд 21:04:42 1367697403
>>1367690
>Парни, подгоните этому гению 15 часовой курс лекций по конкатенации строк в пыхе, у кого есть.
Опять сказал какую-то херню и даже не понял, что сказал херню
Держу пари, ты этот самый фантазер >>1367653

>А ещё тут где-то анон ходил, с 9 часовым курсом по регуляркам.
Снова нерелевантная хуйня. Я бы на твоем месте прошел курс по мат.логике от мфти
Аноним 20/03/19 Срд 21:24:51 1367769404
Что-то вспомнилось недавнее - из треда айтишников. Там аналогичного идиота вычислили, с похожим стилем постов как у этого >>1367697. Уволили ещё которого за то, что народ хуесосил и вообще токсичное чмо.

Ты смотри, пацан, такая манера общения быстро прилипает. Сам не заметишь как в реале хамить людям начнёшь, а там в щи быстро прилетит административно или физически.
Аноним 20/03/19 Срд 21:29:01 1367772405
2e717221a2.png (3Кб, 194x81)
194x81
>>1367658
Перед десяткой не помешал бы пробел.
Аноним 20/03/19 Срд 21:35:11 1367777406
>>1367772
Тогда уж и \n не нужен и лучше PHP_EOL использовать.
Хотя это всё мелочи.
Аноним 20/03/19 Срд 21:41:20 1367780407
>>1367769
>Сам не заметишь как в реале хамить людям начнёшь, а там в щи быстро прилетит административно или физически.
В реале я с такими мудаками обычно не сталкиваюсь. А если сталкиваюсь, то они никогда не входят в круг моего постоянного общения, очевидно же. Ну а незнакомым людям на улице я и не хамлю без причины, так что за щи не беспокойся

>вообще токсичное чмо
Проиграл с адеквата:
>токсичное чмо
>>1367655 >>1367653 >>1367662
Аноним 20/03/19 Срд 21:50:29 1367786408
image.png (46Кб, 514x510)
514x510
>>1367780
>Проиграл с адеквата:
Это разные люди, токсичный шизик. Ты сам не понимаешь чего несёшь. Не позорься и замолкни лучше.
Аноним 20/03/19 Срд 22:12:52 1367794409
>>1367786
>Это разные люди, токсичный шизик.
А где я сказал о том, что это один и тот же человек? Я намекнул на то, что токсичная мразь не я, а они.

>Ты сам не понимаешь чего несёшь.
Нет, я прекрасно понимаю.

>Не позорься и замолкни лучше.
Я пока еще ни разу не опозорился, никаких противоречий в моих словах нет, это твои маняпроекции.
Аноним 20/03/19 Срд 22:22:02 1367803410
>>1367794
>токсичная мразь не я, а они
Так-то тебе вполне нормально посоветовали. Хочешь по-быстрому, то читай доки. Не поймёшь 80% так как у тебя базы нет так как ты с программизмом никак не связан, но ты сам просил "чтобы быстро вкатиться", а не нормально - значит страдай.

По курсам от "Профита" не скажу - не смотрел.
Аноним 20/03/19 Срд 23:14:52 1367836411
>>1367803
Ага, ясно

>>1367803
>По курсам от "Профита" не скажу - не смотрел.
А, такой курс на самом деле есть, лол? Вычеркиваю >>1367655 из списка мудаков
Аноним 20/03/19 Срд 23:32:32 1367842412
Аноним 21/03/19 Чтв 07:18:04 1367914413
Аноны, пытаюсь сделать большие буквы после знака препинания и пробела.
$regexp = '/([.,!?])( )([а-я])/u';
$text = preg_replace($regexp, '$1$2mb_strtoupper($3)', $text);
Однако нихера, программа вместо перевода $3 в верхний регистр просто выводит mb_strtoupper буквально. Как сделать так, чтобы прога воспринимала это как команду?
Аноним 21/03/19 Чтв 12:13:38 1367967414
Аноним 21/03/19 Чтв 12:16:34 1367968415
>>1367914
У тебя функция в кавычках - конпелятор её как строку воспринимает.
Аноним 21/03/19 Чтв 12:19:50 1367969416
>>1367914
1. функция в строке работать не будет;
2. $3 - эту хуйню в строке ждет функция preg_replace, для mb_strtoupper - она нихуя не значит, поэтому сделать так, как ты задумал нельзя. Другие способы ищи
Аноним 21/03/19 Чтв 14:59:22 1368017417
>>1367914

Нужно использовать preg_replace_callback. Ты создаешь функцию, передаешь ее и preg_replace_callback вызывает ее на каждое совпадение с регуляркой и спрашивает, на что заменить текст.
Аноним 21/03/19 Чтв 17:08:28 1368056418
изображение.png (11Кб, 661x156)
661x156
Анчоусы, объясните нубу или направьте на доки, почему здесь $elem[0], это индекс массива или что?

P.s это задачка.
>Ведите на экран только те числа из массива, которые начинаются на цифру 1, 2 или 5.
Аноним 21/03/19 Чтв 17:10:35 1368058419
>>1368056
>fix
Блин, зачем то сполйер сделал, интересует индекс, почему [0]
Аноним 21/03/19 Чтв 17:54:07 1368065420
>>1368056
>$elem[0], это индекс массива или что?
Да, индекс массива.

Но в твоём примере цикл foreach разбирает массив на элементы, возвращая их уже без индекса. То есть у $elem нет индекса, это тупо переменная со значением.

А если интересно, то у каждого элемента твоего массива, значения проставляются автоматически по порядку добавления. У первого добавленного элемента будет 0, у второго 1 и т.д.

Вот как оно выглядит
$arr = [0 => 10, 1 => 20, 2 => 30, 3 => 50, 4 => 235, 5 => 3000];

И да, не нужно числа оборачивать в кавычки '' из-за этого они становятся строками.
Аноним 21/03/19 Чтв 18:04:51 1368067421
>>1368065
Огромное спасибо, я довольна дотошный, за это отдельное спасибо.
>И да, не нужно числа оборачивать в кавычки '' из-за этого они становятся строками.
P/s
Просто не смог найти больше подробностей, по поводу
>Но в твоём примере цикл foreach разбирает массив на элементы, возвращая их уже без индекса. То есть у $elem нет индекса, это тупо переменная со значением.
Аноним 21/03/19 Чтв 18:05:19 1368069422
>>1368056
Намекну. Чтобы отрезать первую цифру от цельного числа, можешь использовать функцию substr($number, 0, 1).

Помог как смог.
Аноним 21/03/19 Чтв 18:10:46 1368076423
>>1368069
>substr
Спасибо, но она со строками работает, а я сделал ошибку, анон выше правильно заметил, я числа в строку превратил, зачем? да хуй знаетдумал всегда надо оборачивать в ковычки, любые данные.
Аноним 21/03/19 Чтв 18:36:47 1368088424
>>1368067
>Просто не смог найти больше подробностей, по поводу
https://ideone.com/WAO6Ts
Примерно так оно работает, короче с опытом придёт понимание.

>Спасибо, но она со строками работает
Соображаешь, но она может приводить числа к строке и успешно их считать. Хотя при строгом сравнении === это не прокатывает.
Аноним 21/03/19 Чтв 18:49:21 1368097425
изображение.png (3Кб, 477x33)
477x33
>>1368088
>Примерно так оно работает, короче с опытом придёт понимание.
Надеюсь, я понял как происходит индексация элементов массивавсегда с 0, но можно это переделать за счет удаления , я просто не мог понять, как скрипт понимает, что надо выдергивать определенные элементы из массива, еще и с определенными условиями.
P/s.
https://ideone.com/WAO6Ts
Я посмотрел, да красиво и элегантно непонятно мне еще учиться и учиться до PHP_EOL (string) .
Спасибо еще раз за подробное объяснение, у меня проблемы с циклами, вот я и решаю с разных сайтов задачки, что могу решить, хочу довести до автомата это понимание.
Аноним 21/03/19 Чтв 19:24:55 1368109426
пхпэшник1.jpg (56Кб, 640x640)
640x640
Аноним 21/03/19 Чтв 19:51:37 1368115427
>>1368097
>я просто не мог понять, как скрипт понимает, что надо выдергивать определенные элементы из массива, еще и с определенными условиями.

$массив = [ключ => значение];
$значение = $массив[ключ];

$array = [4, 20, 34];
То же самое, что и:
$array = [0 => 4, 1 => 20, 2 => 34];

$array[0] вернет число 4;
Аноним 21/03/19 Чтв 20:04:21 1368117428
>>1368115
Понятно, теперь все по полочкам в моей голове.
Аноним 21/03/19 Чтв 20:59:50 1368140429
Есть ли различия у Сервис-Локатора и Контейнера Зависимостей?
Аноним 21/03/19 Чтв 21:39:11 1368154430
>>1368140
Первый передается в конструктор и там уже берется зависимость. Контейнер не передается в конструктор, он передает зависимость аргументом извне.
Аноним 21/03/19 Чтв 21:44:05 1368156431
kateesnameyarik1.png (16Кб, 517x529)
517x529
Аноним 21/03/19 Чтв 22:00:03 1368164432
>>1368156
Молодец, сколько времени затратил на создание?
Аноним 21/03/19 Чтв 22:07:11 1368168433
>>1368164
20 дней в сумме. Бывало, что над какой-то мелочью думал целый день, а бывало, что целый компонент мог написать за пару часиков. Но это нормально в программировании, как я понял.

В фаерфоксе таблица не на всю ширину открывается, какие-то баги.
Аноним 21/03/19 Чтв 22:22:55 1368176434
Screenshot15.png (30Кб, 884x482)
884x482
Вечерочка.
Анон, как занести в массив несколько совпадений, а не только первое?
Аноним 21/03/19 Чтв 22:36:31 1368182435
Screenshot16.png (9Кб, 573x371)
573x371
>>1368176
Нашел PREG_SET_ORDER.
Но оно выводит массив, который в массиве, который в массиве.
Как просто вывести совпадения?
Аноним 21/03/19 Чтв 22:38:17 1368183436
Аноним 21/03/19 Чтв 22:39:55 1368184437
Аноним 21/03/19 Чтв 22:40:11 1368185438
>>1368183
Да и так его использую, но он выводит тогда "МассивМассив".
Аноним 21/03/19 Чтв 22:48:20 1368187439
Screenshot18.png (16Кб, 668x624)
668x624
Screenshot17.png (22Кб, 808x458)
808x458
Короче.
Когда и вызываю [$i[0]], то он выдает пустоту.
Когда вызываю просто [$i], то получаю массив, в котором массив, в котором массив.
Как фиксить?
Аноним 21/03/19 Чтв 22:53:17 1368191440
>>1368187
Кинь ссылку на айдеон.
Аноним 21/03/19 Чтв 22:54:05 1368192441
Аноним 21/03/19 Чтв 22:57:20 1368194442
>>1368187
>Когда и вызываю [$i[0]], то он выдает пустоту.
Ты пытаешься получить значение нулевого ключа в переменной $i, которая не является массивом и вообще содержит число.

Вбрось код с ideone, посмотрю.
Аноним 21/03/19 Чтв 22:59:06 1368197443
>>1368194
Вот тут >>1368192.

>переменной $i, которая не является массивом
Ай, блять.
Аноним 21/03/19 Чтв 23:01:37 1368199444
>>1368194
Я думал, что $i тоже массив, так как при использовании echo мне выводит, что $mails[$i] это ArrayArray.
Аноним 21/03/19 Чтв 23:05:22 1368204445
>>1368192
Вот так можно. Нулевой индекс содержит все совпадения (в твоем случае, все индексы содержат все совпадения), берешь и достаешь оттуда мыла.

https://ideone.com/n9kudx
Аноним 21/03/19 Чтв 23:07:36 1368209446
>>1368176

preg_match находит только первое совпадение, тебе нужен preg_match_all. Придется раскурить мануал, и поработать с var_dump, чтобы понять, в каком формате он возвращает данные.
Аноним 21/03/19 Чтв 23:08:16 1368210447
>>1368204
Спасибо тебе, я понял свою ошибку.
Я выводил [ 0 [0] ],то есть, внутри одних скобок, писал другие.
Надо было просто рядом поставить, блять.
Аноним 21/03/19 Чтв 23:08:54 1368213448
Аноним 21/03/19 Чтв 23:10:52 1368217449
>>1368213
>>1368204
Задача одна, а решения разные.
Спасибо, буду иметь ввиду.
Аноним 21/03/19 Чтв 23:11:15 1368218450
>>1368210
Да ничего, я в начале пути еще не так ошибался, лул.
Аноним 21/03/19 Чтв 23:14:16 1368221451
>>1368217
Да то же самое решение, просто он вместо вайла взял форыч, и регулярку прям в функцию вставил.
Аноним 21/03/19 Чтв 23:17:14 1368224452
>>1368221
Регулярка укороченная, кек
/\S+@\S+/i
Аноним 21/03/19 Чтв 23:20:41 1368226453
image.png (18Кб, 924x160)
924x160
>>1368156
>Autoloader.php
Почему ты не реализовал загрузчик классов как на пике, а написал целый класс? Мне думается, что громоздко вышло.

>init.php
Почему ты его решил в конфиг положить? Я такое обычно прямо в корень кладу - инициализация приложения вроде как.
Или ты просто не заморачивался на этот счёт?

Намотал себе на ус несколько твоих приёмов.
Аноним 21/03/19 Чтв 23:25:21 1368228454
>>1368226
Не задумывался каким образом будешь показывать страницу ошибки, если пользователь захочет зайти на несуществующую страницу или где-то выбросится исключение?

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

мимо другой анон, делающий студетов
Аноним 21/03/19 Чтв 23:29:30 1368229455
>>1368224
Я лично постоянно забываю, что означают все эти классы буквенные в регулярках. Намного нагляднее писать вместо \S - [a-z0-9.+_-], сразу видно, что ищем, читается проще, хоть и длиннее. + можно отредактировать тут же, если какой-то символ не понадобится.
Аноним 21/03/19 Чтв 23:34:26 1368231456
>>1368228
>каким образом будешь показывать страницу ошибки
Если маршрут не найден, то маршрутизатор возвращает заранее определённый адрес страницы ошибки. Потом всё это дело идёт на выполнение.
Но я про автозагрузку классов спрашивал, а не роутинг. Это немного разное.
Аноним 21/03/19 Чтв 23:46:33 1368234457
>>1368226
>Почему ты не реализовал загрузчик классов как на пике, а написал целый класс? Мне думается, что громоздко вышло.

Видел бы ты, сколько у композеровского загрузчика классов, вроде 5-8, если мне не изменяет память.

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

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

>Намотал себе на ус несколько твоих приёмов.
Поднял мне чсв, лол. Только не копипасть, не думая. Я даже если копипащу что-то откуда-то, то всегда переписываю другим способом, чтобы понять, как это работает.
Аноним 22/03/19 Птн 00:06:50 1368238458
>>1368234
>автозагрузчик это ведь тоже некая сущность
Но получается так, что при добавлении нового неймспейса тебе приходится лезть в этот класс и править его исходник, дописывая пути.

Алсо, обрати внимание на этот диалог >>1368140 так как твой DI это Сервис-Локатор, а не Контейнер Зависимостей. Если я не ошибаюсь, то у тебя он целиком в конструкторы передаётся, что есть бад-практис, так как в норме сторонние классы не должны знать поимённо сервисы в контейнере зависимостей - внутри они их по своему даже могут называть. Потом просто при тестировании проблемы будут, и при изменении имён сервисов тоже возни много - по всему коду лазать, вместо правки в месте создании объекта.
Аноним 22/03/19 Птн 00:24:02 1368243459
Screenshot4.png (10Кб, 1397x371)
1397x371
>>1368156
Забыл про расширение на затемнение всех сайтов, подумал, пиздатый ты дизайн сделал, въеби мб так приммерно или это мне уже глаза выжигает белый с непривычки, если отключить расширение?
Аноним 22/03/19 Птн 00:38:24 1368246460
>>1368238
>Но получается так, что при добавлении нового неймспейса тебе приходится лезть в этот класс и править его исходник, дописывая пути.

Щас уже не вспомню, почему я так сделал. Была какая-то причина вроде той, что этот анон пишет. >>1368228


>Алсо, обрати внимание на этот диалог >>1368140 так как твой DI это Сервис-Локатор, а не Контейнер Зависимостей.

Это я и отвечал.

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

>в норме сторонние классы не должны знать поимённо сервисы в контейнере зависимостей

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

>>1368243
Я дизайн на коленке сваял, а цветовую схему взял с картинки какой-то в стиле 80х. Мне не режет ничего. Да и не дизайнер я, чтобы глаза твои беречь, лол.
Аноним 22/03/19 Птн 01:08:06 1368251461
>>1368228
ОП, в правильном ли направлении я думаю?
Аноним 22/03/19 Птн 01:14:49 1368254462
>>1368238
Покопался щас в своем коде. Да, действительно, в описании Connection я напрямую передаю контейнер в конструктор класса. Это ошибка, которую я не исправил. Я в самом начале написания программы где-то прочитал, как нужно готовить DI-контейнер и это оказалось брехней. Человек спутал локатор с контейнером. Но я обязательно исправлю.
Аноним 22/03/19 Птн 01:20:08 1368256463
>>1368254
>Человек спутал локатор с контейнером.
Частое явление, как я смотрю - тоже встречал такое пару раз. Подводные камни как есть.
Аноним 22/03/19 Птн 01:41:49 1368259464
>>1368256
Материалов нет нормальных на русском. А что есть - либо какая-то общая информация из переведенных надмозгом книжек, либо неверное понимание шаблонов. Почти везде одна теория. А практика если и есть, то очень сферическая в вакууме. Нет кода из реальных проектов, пусть даже учебных.
Про платную информацию не говорю, не знаю, может, и есть что-то.
Аноним 22/03/19 Птн 01:44:43 1368260465
>>1368259
>Материалов нет нормальных на русском.
Ну, кроме ОПовских. Но часто ли его ссылка мелькает в выдаче гугла? Хотя это хорошо, с другой стороны, конкуренция слабее.
Аноним 22/03/19 Птн 04:26:17 1368297466
image.jpeg (551Кб, 1800x1795)
1800x1795
image.jpeg (676Кб, 1800x1618)
1800x1618
Анон, расскажи, где я не прав.

Вроде бы и флаг верный, но работает только с первым массивом, со вторым - второй пикрил.

Может я чего-то не понял, но прег_сет_ордер должен раскидывать по массивам совпадения, но при вызове второго массива я получаю хуй.
Аноним 22/03/19 Птн 12:06:03 1368379467
>>1353705 (OP)
1) В статье про архитектуру MVC в программе сервиса для управления студентов есть строчки типа:
/
@var Post[] Список объявлений
/
что это значит? Зачем нужна собачка?
2) И еще, если кто сможет объяснить, там есть дерево файлов. Можете объяснить всю схему:
Есть 2 папки public и view. На этом уровне есть файлы bootstrap и Post. А где PostService? Он просто странно расположен.
Статья про MVC
https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Аноним 22/03/19 Птн 12:11:33 1368380468
>>1368379
Ой, там звездочки были в первом примере. Две звездочки после /, одна звездочка перед @var и одна звездочка перед /
Попробую обойти вакабу ари помощи комментов, но если что в статье можно найти
>/
> @var Post[] Список объявлений
>
/
Аноним 22/03/19 Птн 12:12:47 1368381469
Аноним 22/03/19 Птн 12:14:28 1368384470
>>1368380
Так это многострочный комментарий, почитай в гугле, что такое phpdoc.
Аноним 22/03/19 Птн 13:38:48 1368414471
>>1368379
>А где PostService? Он просто странно расположен
Где угодно. MVC-шаблон не обязывает хранить модели, контроллеры или представления только в определённых папках. Можно даже просто в корень всё бросать, правда это не очень удобно.
Я в таких маленьких приложениях классы в папку lib кладу. Вроде как бибилиотека классов.
Аноним 22/03/19 Птн 17:19:50 1368511472
Аноним 22/03/19 Птн 17:37:23 1368517473
>>1368511
Та ты заебал со своими регулярками. Я тебе скинул уроки - смотри, там все есть, доступно и понятно
Аноним 22/03/19 Птн 17:44:32 1368520474
>>1368511
Так может и нет ничего во втором массиве, посмотри, что в нем.
Аноним 22/03/19 Птн 18:34:51 1368537475
>>1368297

Для вывода массива лучше использовать var_dump.

У тебя в регулярке стоит ^ - привязка к началу строки. Второе и далее слова она никогда не найдет.

>>1368517

Не нравится - не читай. Это обучающий тред.
Аноним 22/03/19 Птн 18:36:48 1368539476
Кстати, задачка для тех, кто хочет подумать. Как бы вы спроектировали стандартные функции preg_match и preg_match_all ? Какие аргументы они должны принимать и что возвращать?
Аноним 22/03/19 Птн 18:54:23 1368546477
>>1368297
^ - вот этот символ означает начало строки. То биш в твоей регулярке всё что не является первым словом не соответствует регулярному выражению.

А вjобще удобней проверять регулярки если сразу наглядно видно как она работает. Можешь посмотреть как она работает на таких сайтах как regexr или regex101.
https://regexr.com/
https://regex101.com/

Аноним 22/03/19 Птн 19:57:15 1368569478
Обратил внимание, что во фреймворках получают данные от пользователя не через функции типа $_POST и подобные, а объектом класса Request. Я так понимаю это нужно для тестирования? Стоит ли пилить подобный класс в списке студентов?

Будет нужно сделать что-то подобное?
https://ideone.com/iF8vXE
Аноним 22/03/19 Птн 19:59:06 1368571479
Установил yii с помощью композера. Страница приветствия «Congratulations!» недоступна. Нужно веб-сервер устанавливать? Встроенный сервер php может запускать такое? Посоветуйте мануал.
Аноним 22/03/19 Птн 20:11:43 1368578480
Таки запустил yii на встроенном сервере. Нужно чтобы все позеленело в Requirement Checker? У меня например Intl extension желтый, PDO MySQL extension, и еще несколько зависимостей.
Аноним 22/03/19 Птн 20:34:31 1368591481
>>1368569
>Стоит ли пилить подобный класс в списке студентов?
Думаю, что можно и без него, но с ним будет лучше - по PSR.
Аноним 22/03/19 Птн 20:46:30 1368592482
>>1368569
>Я так понимаю это нужно для тестирования?
Нет. Это абстракция скрывающая ненужное, и выделяющая существенное. Чтобы поворачивать на авто удобно руль использовать. При этом не нужно знать что под ним, как он крепится, и как управляет механизмами поворота колес. Request работает по такому же принципу. Поэтому дело тут отнюдь не в тестировании.
Аноним 22/03/19 Птн 20:46:45 1368593483
>>1368537
>Не нравится - не читай. Это обучающий тред.
Не нравится не бугурть. Это анонимная борда
Аноним 22/03/19 Птн 20:57:44 1368597484
>>1368517
Хочу учиться среди людей.

>>1368520
Да, там пустота.

>>1368537
Указал на ошибку. Спасибо за это.
Сейчас понял, в чем дело было.
Аноним 22/03/19 Птн 22:07:11 1368625485
Начинаю делать файлообменник. Можно ли просто и без задней мысли попробовать энджин-икс вместо апача? Или он не создан для того, чтобы быть полноценным серваком?
Аноним 22/03/19 Птн 22:25:33 1368635486
>>1368625

Конечно, используй. Никакого требования использовать Апач нету. Только вместе с ним тебе скорее всего придется освоить php-fpm (менеджер процессов PHP и FastCGI сервер).
Аноним 22/03/19 Птн 22:35:03 1368638487
>>1368635
А пригодится это вообще в работе дальнейшей? Не то чтобы я пекусь о том, что зря, а что нет, просто у меня срок сделать все задачи из оп-поста до сентября, хочу все успеть.
Аноним 22/03/19 Птн 22:48:05 1368642488
Еще раз репостну, мб найдется кто. Не злитесь, хочу найти няшу-двачера и лампово работать, а не пидорга-кидалу с хэдхантера.

Нужен толковый чувак, веб-разработчик широкого профиля (фуллстак).

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

Языки программирования: PHP (на сервере 7.2), JS, HTML/CSS, SQL (на сервере MySQL или MariaDB).
Фреймворки: Yii, jQuery.
Технологии и инструменты: scss(sass), gulp, git, PHPStorm.
Нужен опыт работы над крупными yii-проектами (крупнее лаба10.пхп и сокращателя ссылок).

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

Задачи: доработка существующего продукта, который, по идее, написан неплохо (MVC, вся фигня), с нынешним разработчиком познакомлю, введем в курс дела.

dvachheadhunting@yandex.ru
Аноним 22/03/19 Птн 23:44:22 1368664489
>>1368642
Если имел дело с laravel, но с yii нет, имеет смысл писать?

Аноним 22/03/19 Птн 23:52:53 1368670490
>>1368638
Обязательно пригодится. Нужно понимать разницу между ними. Понимать какие задачи они лучше или хуже выполняют.
Аноним 22/03/19 Птн 23:58:58 1368673491
>>1368670
Понял, благодарю за ответ.
Аноним 23/03/19 Суб 00:00:14 1368674492
>>1368642
Двачую этого >>1368664.
Я на симфонии проект небольшой написал. Но с юей уж подавно смогу разобраться. Вам срочно нужен человек?
Аноним 23/03/19 Суб 00:31:43 1368684493
>>1368664
>>1368674
Ну, недельку могу подождать. Но там же всякие особенности типа актив рекорд с актив форм, гридвью, миграциями (хотя эти вроде везде есть), все дела. Мне главное, чтобы не вышло ситуации, когда кодер не справится, свалит через месяц-два, а кодовая база к тому времени будет представлять собой адовую лапшу без mvc и psr, за которую уже никто адекватный точно не возьмется. Могу какое-то тестовое задание дать или предложить перепилить ваш ларавель-симфони проект (крупнее сокращалки ссылок) на йии с его фишками, показать код текущему разрабу, если ему будет ок, возьму с радостью.
Аноним 23/03/19 Суб 00:48:21 1368691494
2019-03-2300-44[...].png (22Кб, 790x512)
790x512
Уважаемые, на связи снова >>1367654 вкатывальщик.
Я вас наверное заебу, простите.
На циклах я опять сломался, логика никогда не была моей сильной стороной, но всё-таки осилил.

Пожалуйста, напишите замечания, можно ли было сделать лучше и подскажите возможно ли менее заёбно работать с процентами?
https://ideone.com/RCwvSU
Аноним 23/03/19 Суб 01:27:54 1368704495
>>1368691
>возможно ли менее заёбно работать с процентами?
Потому тебе и заёбно, что у тебя неправильно. Проценты в теле цикла считаются, а не в объявлении.
Аноним 23/03/19 Суб 01:38:36 1368709496
>>1368704
Хорошо, но какая будет разница, поменяй я местами слагаемые ?
Я к тому что я не могу написать "+15%", приходится делить на сто и у множать на процент. Можно это как-то сократить?
Аноним 23/03/19 Суб 02:08:40 1368717497
>>1368709
Просто почитай\посмотри как люди с циклами работают.
Аноним 23/03/19 Суб 02:09:59 1368718498
Аноним 23/03/19 Суб 02:20:11 1368723499
>>1368691
>возможно ли менее заёбно работать с процентами?
Типа вот так:
$rubles = $rubles * $percent, где $percent = 0.1
ты имеешь ввиду?
Аноним 23/03/19 Суб 02:34:58 1368726500
impossible-capt[...].PNG (153Кб, 401x608)
401x608
Искуственный интеллект Гугл, похоже, превзошел человека, потому что я решить эту капчу не могу.

>>1368691

Не надо здесь ставить скобки: ($age++); Можно писать просто $age++;

Точка с запятой завершает команду и скобки тут ни на что не влияют.

Аноним 23/03/19 Суб 02:46:31 1368731501
>>1368726
Лестницы, светофоры, витрины, автобусы, такси. Гугл нейронку-водителя на нас обучает что-ли?
Аноним 23/03/19 Суб 02:59:09 1368734502
>>1368731
Похоже на то. Ещё гидранты и велосипеды
Аноним 23/03/19 Суб 03:13:27 1368736503
Аноним 23/03/19 Суб 03:31:14 1368740504
Аноним 23/03/19 Суб 04:20:21 1368742505
Аноним 23/03/19 Суб 10:08:13 1368790506
image.jpeg (277Кб, 750x962)
750x962
Аноны, поясните за подобные вакансии.
Иногда всплывают, такое ощущение, будто им нужны веб-макаки для простой (реально простой) работы.
Может я не понимаю чего- то.

Или они набирают нуфагов, чтоб заточить их под работу в своей конторе?
Аноним 23/03/19 Суб 12:01:57 1368814507
ОП, напомни пожалуйста, как в Doctrine принято организовывать переиспользуемые поведения сущностей, например я хочу сделать поведения Taggable, Likeable, Commentable и переиспользовать эти поведения в 3-х сущностях. Нагуглил в других ORM полиморфные реляции - выглядят как костыль: https://logrocket.com/blog/polymorphic-relationships-in-laravel/
Аноним 23/03/19 Суб 12:44:46 1368821508
>>1368642
почему выбрали уи? смотри тут сколько разработчиков на чем угодно.
Аноним 23/03/19 Суб 14:28:07 1368847509
>>1368790
> Или они набирают нуфагов, чтоб заточить их под работу в своей конторе?
Возможно, это же стажировка. Набирают чернорабочих за еду. А может просто так написали, а на собеседовании ебут всякой хуйней и хотят найти какого-то омежку стронг-джуна за еду.
Аноним 23/03/19 Суб 15:33:42 1368872510
>>1368821
Тут это где? Просто несложный, документированный фреймворк. На чем прошлый разраб писал, на том и писали, на самом деле, просьба только была, чтоб распространенное что-то, а симфони, ларавель или йии это будет - неважно. Почему нет?
Аноним 23/03/19 Суб 15:46:33 1368877511
>>1368821
>смотри тут сколько разработчиков на чем угодно
На уи есть?
53-232 Аноним 23/03/19 Суб 23:14:15 1369055512
>>1355067

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

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

>>1356794

> if($this->correctAnswer == $answer) {
> return true;
Так как оператор == уже возвращает true/false, то можно писать просто return $this->correctAnswer == $answer;

> if (($this->correctAnswer == $answer) || (($answer <= $plusDeviation) && ($answer >= $minusDeviation))

Первое сравнение на равенство лишнее.

А так, решено правильно.

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

>>1357720

Хорошо, ответ верный.
https://github.com/asdasdasdasddasasdasdas/StudentList Аноним 23/03/19 Суб 23:15:07 1369057513
>>1358261

> https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/students.sql#L24
> `hash` varchar(100) NOT NULL,

Здесь стоит добавить комментарий (COMMENT ...) с пояснением, что в этой колонке.

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/bootstrap.php

Ты сделал DI так, что для контроллера он возвращает функцию-фабрику, которую надо вызвать, чтобы получить сам контроллер. Но лучше было бы решить это на уровне самого DI контейнера, например, сделать отдельный метод bindFactory, чтобы указать, что этот объект создается функцией. А получатель просто вызывает $di->get() и не задумывается о том, как именно создан объект.

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/helpers/DIContainer.php#L37
Нет смысла писать throw и catch рядом. Ты можешь заменить их на обычный if, и код будет проще читать.

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/exceptions/DIContainerException.php
Тут ошибка. Исключение - это объект, хранящий информацию об ошибке. Но в нем нет обработчика, который решает, что делать в случае ее возникновения. Если ты хочешь при ошибке показывать страницу, то проще всего ловить ошибку где-то в роутере, и выводить страницу ошибки. Не забудь также логгировать исключение, например, с помощью error_log(). В твоем варианте разработчик даже не узнает про ошибку.

Урок про исключения: https://github.com/codedokode/pasta/blob/master/php/exceptions.md

В роутере мне не нравится, что у тебя у одной страницы может быть много URL, например: /registration, /registration/xyz. Это плохо для поисковой оптимизации.

Сообщения о коммитах плохие: https://github.com/asdasdasdasddasasdasdas/StudentList/commits/ads

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/controller/MainController.php#L30
> $countStudents = $_GET['search'] !== '' ?

Здесь при отсутствии ключа search в массиве генерируется notice. Странно, что ты его не заметил - может, у тебя отключен их показ?

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/model/StudentTableGateway.php
Здесь стоило использовать DI для передачи соединения с БД снаружи. Класс DBConnector тогда становится не нужен.

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

Стоит добавлять тайп-хинты (string, int) в аргументы функций. Это защищает от ошибок и документирует код.

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/model/StudentTableGateway.php#L70
Здесь в getStudents(int $offset, int $limit) в SQL запросе ты не указал способ сортировки. Это значит, что БД может возвращать любые записи, например, одни и те же записи для любой страницы. То есть конструкция OFFSET без сортировки не имеет особого смысла.

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/model/StudentTableGateway.php#L143
Проверка сделана некорректно тут:

> } elseif ($result['id'] == $id && $result['email'] == $email) {

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

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/controller/ProfileController.php#L83
тут можно было сделать вспомогательную функцию, чтобы не копипастить длинные выражения.

> $student = $this->auth->getAuthUser($this->auth->getHash());
Странно, что мы должны передавать хеш, хотя $this->auth его и так знает.

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/helpers/Authorization.php#L22
> public function IsLoggedIn()
> {
> return isset($_COOKIE['hash']) ? true : false;
Этой проверки недостаточно, чтобы считать пользователя залогиненным. Что, если он сам себе поставит куку hash=1 ?

https://github.com/asdasdasdasddasasdasdas/StudentList/blob/ads/app/view/partials/form.php
Тут стоит добавить атрибуты для HTML5 валидации до отправки формы.

> <?= $student->gender == 'f' ? 'checked=checked' : null; ?>
echo выводит только числа и строки, неправильно передавать на вывод null

Радует, что ты прочитал про SQL-инъекции и XSS. А есть ли у тебя защита от XSRF?

> if ($this->paginator->getPreviousPage() !== null
Красивее писать if ($this->paginator->hasPreviousPage()), а еще лучше $paginator->hasPreviousPage()

При ошибке 404 надо отдавать соотв. HTTP-код. То же самое касается страницы ошибки в приложении.

Сессии наверно не нужны в index.php?

Вообще, пока впечатление по коду хорошее.
Аноним 23/03/19 Суб 23:15:46 1369058514
>>1358262

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

>>1358554

> https://3v4l.org/NSVsb - задача про зарплату
overtime должен вычисляться автоматически. Все, что больше 40 часов в неделю - переработка.

> https://3v4l.org/4GGth - задача про вопросы
Тут можно было ставить тайп-хинт на возвращаемое значение:

> public function checkAnswer($answer): bool

А так, все верно.

> https://3v4l.org/3avqA - задача про Вектор

В качестве названий профессий можно было использовать константы-имена классов вроде Manager::class: http://php.net/manual/en/language.oop5.constants.php

addEmployees лучше бы вынести наружу из Департамента, так как это не позволяет создавать новые профессии, не трогая существующий код. Ну например, если твои классы будут оформлены в виде библиотеки, которую делает один человек, то другой человек, который ей пользуется, не сможет добавлять свои профессии. Случай, конечно, немного придуманный, но надеюсь, смысл передает. У тебя класс Department сейчас по сути содержит захардкоженный список возможных профессиий. А это не его зона ответственности - знать, какие профессии есть.

> public function getInformation(): array {
Мне кажется, было бы удобнее сделать несколько отдельных методов, но можно и так. Но name и employeesCount точно надо вынести отдельно. Так как неудобно будет их получать и никакой экономии от помещения их в этот метод мы не получаем.

Если доводить до абсурда, то мы тогда можем сделать в любом классе 2 метода setInformation и getInformation и работать со старыми добрыми массивами. Это не очень удобно, и в плане получения данных (надо извлекать их из массива), и в плане кода (все собрано в одном огромном методе).

Класс Table правильнее назвать TablePrinter, TableFormatter, так как он не представляет информацию о таблице.

А вообще хорошо, меня радует, что и у нас в треде, да и вообще в программистском сообществе стали лучше понимать ООП. А не как раньше, когда все сидели на CMS и городили жуткие конструкции на многомерных массивах.
Аноним 23/03/19 Суб 23:16:08 1369059515
>>1358927

Я приведу пример про числа и строки:

$a = 123; // это число. Его можно складывать, вычитать итд.

$b = "123"; // это строка. Это набор букв. Вычитать строки нельзя, но PHP
// автоматически преобразует строку в число, если ты попытаешься
// это сделать

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

Вместо is_int ты можешь использовать is_numeric.

>>1360327

Сделано неправильно. Ты сравниваешь только одну пару букв (самую первую и самую последнюю), и после сравнения завершаешь программу, а надо сравнивать все.

>>1360712

Postgres интересная БД, у нее много фич, по ней есть хорошая актуальная документация на русском, стоит прочесть. Например, там много интересных видов индексов.

>>1360810

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

>>1360904

Сегодня я выучил новую поговорку.
Аноним 23/03/19 Суб 23:31:15 1369069516
>>1368723
Я имел ввиду что-то типа число * 10%
Аноним 24/03/19 Вск 00:59:20 1369103517
>>1368814

Ты можешь посмотреть, как сделано в Doctrine Extensions если тебя интересует именно реализация расширений: https://github.com/Atlantic18/DoctrineExtensions

Там используются события Доктрины.

Для простых случаев можно использовать просто трейты.

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

Плюс, надо помнить о производительности. Если тебе надо получить число лайков, то быстрее всего иметь поле с этим числом. А ставить лайк SQL-запросом (если хайлоад - то через очередь в редисе и групповые обновления). Да, не универсально, зато просто и быстро. Ну и в рамках Доктрины эффективные групповые обновления сделать будет трудно.
Аноним 24/03/19 Вск 01:07:53 1369109518
2019-03-2401-07[...].png (33Кб, 756x470)
756x470
Я уже из себя все соки с этой задачей про айфон выпил.
Вы обещали что с тройкой по математике можно!
Почему это неправильно? Что вообще нужно сделать? У меня уже опускаются руки.
https://ideone.com/QIFtDz
Аноним 24/03/19 Вск 01:11:56 1369113519
>>1369109

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

Ты зря скопировал код, который был дан, так как в нем была специально сделана ошибка.

Давай попробуем составить более простой алгоритм.

Попробуй переписать код внутри цикла примерно так:

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

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

Аноним 24/03/19 Вск 01:15:53 1369119520
>>1369109

И еще, вот здесь очень странный код:

if ($creditBalance < $monthlyPayment){
$monthlyPayment = $creditBalance; / Почему это не работает? /
echo "С меня хватит!\n";
break;
/ Почему это не работает? /
}

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

как в твоем понимании должна была "работать" строка $monthlyPayment = $creditBalance; ? Она копирует число из одной переменной в другую. Но так как дальше идет break и программа завершается, то это уже ни на что не влияет.

Ни в коем случае не пытайся писать код наугад. Ты должен понимать, что ты хочешь сделать, что будет делать каждая строчка, что будет происходить, и только потом писать код, а не переставлять команды наугад в надежде, что оно как-то заработает. Даже если оно заработает, это не даст никаких навыков.
Аноним 24/03/19 Вск 15:50:40 1369352521
>>1369059
>Читай постепенно. Если ты не любишь читать документацию, то развиваться будет трудно.
Не в этом дело, просто гора чего еще в планах выучить/прочитать и postgres не в приоритете. Если бы для ознакомления надо было уделить немного времени то ок, а так придется отложить в долгий ящик
Аноним 24/03/19 Вск 15:55:46 1369356522
Поясните про паттерны проектирования.

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

Несколько раз брался их изучить (читал/смотрел видеоуроки) но так и не понял нахуя они нужны?

Я понимаю например MVC - понятна суть такой структуры, но когда смотрю какуюнибудь фабрику, то не пойму о чем речь. Фабрика как я понял - это идея о порождении объектов другим объектом? Это и вся суть? Я постоянно пишу подобные структуры и не понимаю, зачем мне надо знать, что это называется фабрикой? Или я наделяю паттерны большим значением, чем они имеют на самом деле?
Аноним 24/03/19 Вск 16:56:01 1369388523
Верно ли я понимаю, что на PHP можно писать даже десктоп-приложения?
Увидел вот это - https://github.com/cztomczak/phpdesktop - и хочу спросить мнения анона по данной идее.
Аноним 24/03/19 Вск 17:58:57 1369417524
>>1369356
Большинство задач. с которыми часто приходится сталкиваться программистам. уже давным-давно решены другими членами сообщества. С помощью проектных шаблонов просто выделяют общие задачи, определяют проверенные решения и
описывают вероятные результаты. Задачи имеют свойство повторяться, и веб-программистам приходится решать их снова и снова. Со временем мы находим более или менее изящные ответы на эти вопросы и создаем неформальный набор методик, которые затем снова и снова используем в своих проектах. Эти методики - и есть проектные шаблоны.

Что касается знаний названий шаблонов, то наименование шаблона уже само по себе очень ценно; таким образом создается
что-то вроде общего словаря. Вот сравни две ситуации.
На совещании тебе дали задание, что в проекте имеет смысл сделал интерфейс для создания семейств взаимозависимых объектов, не специфицируя их конкретных классов. Это всё должно быть реализовано созданием абстрактного класса, который представляет собой интерфейс для создания компонентов системы. Далее должны быть классы, реализующие этот интерфейс."

Или просто сказали, что система должна создавать каждый набор с помощью шаблона Abstract Factory.

Зандстра, Мэтт.
РНР: объекты, шаблоны и методики программирования
Аноним 24/03/19 Вск 18:39:54 1369447525
>>1369417
>Зандстра, Мэтт.
>РНР: объекты, шаблоны и методики программирования
То читал. Технически понятно все, но зачем все то выделяется в отдельную дисциплину - не понятно.

>На совещании тебе дали задание, что в проекте имеет смысл сделал интерфейс для создания семейств взаимозависимых объектов, не специфицируя их конкретных классов. Это всё должно быть реализовано созданием абстрактного класса, который представляет собой интерфейс для создания компонентов системы. Далее должны быть классы, реализующие этот интерфейс.
Вот я и буду реализовывать то, что сказали. Зачем мне для этого знать, то, что кто-то это уже реализовывал и дал этому название?
Аноним 24/03/19 Вск 18:40:26 1369448526
>>1369447
>То читал.
Тоже читал

>то выделяется
это
Аноним 24/03/19 Вск 19:12:20 1369469527
>>1369447
>зачем все то выделяется в отдельную дисциплину

Шаблон описывает лишь общее решение. Не обязательно им слепо следовать и пихать куда не попадя. Если задачу решить без шаблонов проще и удобней, решай без шаблонов. Шаблон не самоцель, просто некий вариант решения.

>Зачем мне для этого знать, то, что кто-то это уже реализовывал и дал этому название?

Если у тебя возник такой вопрос, то видимо не зачем. Но если будешь часто сталкиваться с такой ситуацией, то рано или поздно запомнишь названия шаблонов. Считай это профессиональной лексикой.
Аноним 24/03/19 Вск 20:45:13 1369525528
Аноны, на каком ресурсе искать книги по php в формате fb2, mobi? Конвертировал из pdf в данный формат, просто пиздец, не читабельно от слова совсем.
Аноним 24/03/19 Вск 23:15:47 1369614529
14526755847340.jpg (57Кб, 600x600)
600x600
Котоны, помогите сделать выборку из одного массива по индексу из другого массива, пожалуйста:

https://ideone.com/IKruQg

То есть у меня список Id в одном массиве вида: 3,10,12,25
А другом значения.

Id выводит верный - итерируется, а значение - нет.
Аноним 25/03/19 Пнд 00:51:31 1369646530
>>1369614
https://ideone.com/dCvwSr
Не брезгуй залезть в документацию по языку, когда работаешь с каким-то типом данных чтобы не приходилось писать уже существующие функции.
Аноним 25/03/19 Пнд 01:05:46 1369648531
Аноним 25/03/19 Пнд 09:57:40 1369724532
Аноним 25/03/19 Пнд 13:40:38 1369793533
Аноним 25/03/19 Пнд 16:19:52 1369843534
Я тупой и заранее сори за тупые вопросы.
Могу ли я прихуячить js файл в php и он будет нормально работать?
Смогу ли я брать данные из sql и рендерить их при помощи js в пхп?
Сильно ли отличается PHP Bootstrap от ванильного?
Аноним 25/03/19 Пнд 16:30:06 1369846535
Почему в ларавеле столько трейтов? Это же вроде не очень хорошо с точки зрения ООП.
Аноним 25/03/19 Пнд 16:35:36 1369851536
Аноны, есть один массив массивов arr[]:

https://ideone.com/Gow8Pf

как добавить первичный индекс цифру каждого из них к значению, в начало то есть перед всем остальным subarr[]? Что я делаю не так?
Аноним 25/03/19 Пнд 16:43:11 1369854537
>>1369851
>Что я делаю не так?
Ты не изучил работу с массивами и не потренировался с ними.
Если ты взялся за реальную задачу, не имея скиллов, то земля тебе пухом, братишка. Тут тебя тащить никто не будет.
Аноним 25/03/19 Пнд 16:46:00 1369855538
>>1369846
Потомучто ларавель разрабатывают программисты, а не двачеры или вкатывальщики с каргокультом
Аноним 25/03/19 Пнд 20:16:32 1369955539
2019-03-2520-15[...].png (26Кб, 759x480)
759x480
>>1369113
>>1369119

Спасибо за подсказку, но всё равно не получается.
По моей логике если долг меньше ежемесячного платежа, то ежемесячный платеж нужно сравнять с остатком долга, соответственно заплатить его, и должен получиться "0". Но почему ноль не получается? Я не могу понять.
https://ideone.com/hcLusb
Аноним 25/03/19 Пнд 20:46:41 1369971540
>>1369955
Ты в последний месяц (в твоем if) не уменьшаешь $creditBalance и не изменяешь $paymentTotal и делаешь break; из цикла. Поэтому выводится баланс и т.д. за предпоследний месяц.
Аноним 25/03/19 Пнд 20:55:41 1369980541
>>1369855
В нормальных языках (C#/Java) нет никаких трейтов, люди следуют SOLID и пишут нормальный код. Ларавель пишут говнокодеры, ломающие обратную совместимость в минорных версиях ( https://github.com/laravel/framework/issues/27949 ), создающие трейты на каждый чих, порождая хрупкий код, вместо того, чтобы подумать и нормально разделить ответственности. Одно дело когда в модели переиспользуемые поведения, совсем другое - когда вся архитектура на запутанном месиве из трейтов и магических методов, которые нативно не поддерживаются IDE и статическими анализаторами. Частично помогают лишь сторонние костыли и заплатки. Не пишу на ларавеле больше года и очень рад, что больше не имею с ним дел.
Аноним 25/03/19 Пнд 21:37:29 1370005542
2019-03-2521-36[...].png (45Кб, 812x726)
812x726
>>1369971
Ну неужели у меня получилось, наконец-то!
Понял свою ошибку в понимании построения кода теперь скажи, это сильно пиздец и стоит попробовать как-то оптимизировать код и количество команд, или что-то вроде этого и должно было получиться?
https://ideone.com/CPJLAo
Аноним 25/03/19 Пнд 22:17:58 1370025543
Аноним 25/03/19 Пнд 22:22:36 1370030544
>>1369854
Спасибо, Анон! Спустя 4 часа пердолинга, у меня-таки получилось.
Аноним 25/03/19 Пнд 23:02:35 1370062545
>>1370030
>Спустя 4 часа пердолинга
Поначалу - обычное дело. Вообще привыкай учиться сразу потом мозги сами нормально встанут.
Аноним 25/03/19 Пнд 23:46:35 1370100546
>>1370005
Хорошо. Решай дальше.
Аноним 26/03/19 Втр 01:58:52 1370139547
- Вникаю в паттерны и нахожу их полезными знаю не все наверно
- Понимаю MVC есть свой - вечнонедоделанный и нубский микрофрейм
- Работал с APIделал обёртки, встраивал, разрабатывал - разбирался
- Знаю пару библиотек с Гитхаба. И вообще очень ленивый - мне проще у кого модуль скачать и встроить главное чтобы без лютого говнокода и с доками, чем с нуля собирать.
- Знаю штук пять-шесть Структур Данных
- Предпочитаю писать на ООП - как-то легче на нём мне пишется. Из фреймворков только пока Слим пробовал
- Ну и всякое по мелочи.

Можно уже ходить по собесам?
Аноним 26/03/19 Втр 08:12:47 1370183548
>>1370139
С твоими знаниями я бы еще немного хтмл/ксс и js подучил и вкатился бы на собеседование.
Аноним 26/03/19 Втр 11:11:16 1370277549
image.png (6Кб, 234x198)
234x198
>>1353705 (OP)
Подскажите дурачку какой-нибудь простой финт ушами на чистом пхп (хотя можно какую-то библиотеку, главное чтоб юзать было просто) который якобы защитит меня от sql инъекций (нужно для диплома, просто показать, в гугле какие-то сложные вещи)
Начал пользоваться кодигнайтером для этих целей, но у меня стили не подгружаются, хотя гуглил и делал все как тут https://stackoverflow.com/questions/11581636/fatal-error-call-to-undefined-function-base-url-in-c-wamp-www-test-ci-applic (возможно это из-за галповских scss, хуй знает как все что на пике вообще в фреймворком подгрузить)
Аноним 26/03/19 Втр 11:17:47 1370281550
Аноним 26/03/19 Втр 11:29:18 1370287551
>>1353705 (OP)
Чем бэкенд-разработчик занимается по 8 часов в день? Как часто с базами данных работает?
Аноним 26/03/19 Втр 11:29:18 1370288552
>>1369980
справедливости ради стоит вспомнить, что по их схеме версионирования это мажорный апдейт
Аноним 26/03/19 Втр 13:23:21 1370358553
>>1353705 (OP)
Пагни, использую symfony4. Нужно чтобы определённый пхп скрипт выполнялся перед загрузкой каждой страницы. В скрипте происходит обращение к удалённому сервису, который возвращает некоторое дерьмо. Это дерьмо должно быть доступно после в любом контроллере для последующей передачи во вьюхи.
Как это правильно реализовать?
Аноним 26/03/19 Втр 13:25:19 1370359554
>>1370287
Привет. Я бекенд-разработчик. Я пишу бекенд для сайтов, сервисов и всякие разные скрипты автоматизации. Но чаще нихуя не делаю. В среднем я работаю с базами данных по 146 раз в день.
Аноним 26/03/19 Втр 13:59:27 1370368555
>>1370359
Понятно, видимо это не для меня. От одного изучения sql уже тошнит
Спасибо
Аноним 26/03/19 Втр 14:33:35 1370381556
>>1370359
>Но чаще нихуя не делаю
У меня друг сеньор-помидор с $3700 на руки. Говорит что если 4.5 часа за день кодировал и на митинге орал, то это был ппц напряженный день.
>>1370358
https://symfony.com/doc/current/event_dispatcher/before_after_filters.html
>обращение к удалённому сервису, который возвращает некоторое дерьмо
Я бы подумал о выдергивании некоторого дерьма в кэш или бд скриптом по крону например, если время жизни некоторого дерьма позволяет.
Аноним 26/03/19 Втр 14:54:51 1370392557
>>1370358

Это плохая идея и приведет к багам и тормозам на сайте. Лучше от нее отказаться и реализовать по-другому.
Аноним 26/03/19 Втр 15:02:46 1370397558
Аноним 26/03/19 Втр 18:13:27 1370476559
>>1353705 (OP)
Устанавливаю зависимости через composer. Есть одна либа в приватном репозитории, у которой нет package.json и вообще файлов с метаинформацией.
Добавляю я её так

>{
> "repositories": [
> {
> "type": "package",
> "package": {
> "name": "xxx/package_name",
> "version": "1",
> "source": {
> "url": "https://xxx@bitbucket.org/xxx/package_name.git",
> "type": "git",
> "reference": "master"
> }
> }
> }
> ]
>}

Устанавливается она нормально. В папке vendor вижу склонированную репу. Но если она обновляется в удалённом репозитории и я делаю composer update - либа в vendor остаётся старой версии. Пробовал делать composer clear-cache - без изменений. Помогает только ручное удаление директории либы в vendor и запуск после composer update - только после этого скачивается новая версия из репозитория. Почему так происходит и как сделать так, чтобы composer скачивал ту версию либы, которая на данный момент находится в удалённом репозитории?
Аноним 26/03/19 Втр 18:21:53 1370479560
>>1370476
А, да. Пробовал ещё делать
$ composer update --prefer-source
Тоже безрезультатно
Аноним 26/03/19 Втр 19:58:35 1370526561
>>1370183
>хтмл/ксс
Вкатывался через вёрстку - могу делать небольшие правки. Даже пара лендосов собственноручно свёрстанных где-то есть, не то, чтобы очень хороших. Немного бутстрап пробовал, было дело и на вордпресс натягивал.

>js
Тоже об этом думаю. Ещё не трогал его.
Аноним 26/03/19 Втр 20:34:30 1370540562
Вы используете в проектах встроенную авторизацию ларавель или делаете все с нуля?
Аноним 26/03/19 Втр 23:18:55 1370622563
>>1370476

Иногда стоит смотреть мануал. Вот, что тут написано про тип package: https://getcomposer.org/doc/05-repositories.md#package-2

> Composer will not update the package unless you change the version field.

То есть это для случая, когда "пакет" это просто зип-архив с фиксированной версией.

Тебе стоит попробовать тип VCS: https://getcomposer.org/doc/05-repositories.md#vcs

Версии пакетов автоматически определяются из меток (тегов) в репозитории.

Также, я сам не разбираюсь в композере, но тебе советовал бы полистать мануал. Например:

- https://getcomposer.org/doc/02-libraries.md
- https://getcomposer.org/doc/articles/aliases.md

Аноним 27/03/19 Срд 21:43:53 1371041564
>>1370288
> по их схеме версионирования
Я в курсе. Это значит, что разработчикам не хватает профессионализма, чтобы релизить новый функционал, не меняя код, на который завязались люди в своих проектах. Все серьёзные фреймворки умеют в deprecation warnings:
- Spring: https://beginnersbook.com/2014/07/deprecated-annotation-in-java/
- ReactJS: https://reactjs.org/blog/2017/04/07/react-v15.5.0.html#new-deprecation-warnings
- Symfony: https://symfony.com/doc/current/contributing/code/conventions.html#deprecations
В симфони так вообще есть Backward Compatibility Promise, в котором точно описано, что и в каком случае может поменятся: https://symfony.com/doc/current/contributing/code/bc.html
Думаешь им хочется с этим всем заморачиваться? Вряд ли, просто они понимают, что проекты на Symfony как правило большие, сложные и долгоживущие и ломать что-то в минорных версиях недопустимо. Да и глупо не следовать семантическому версионироваю в 2019-м году, когда любой более-менее популярный фреймворк ему следует.
Аноним 27/03/19 Срд 22:00:19 1371052565
Народ, поясните. Что я накосячил т к идеон выдает ошибку неверная функция, но я ее аж с мануала специально копирнул https://ideone.com/tAT7Qv
Аноним 27/03/19 Срд 22:00:28 1371053566
Как вы тестирование изучали, от корки до корки читали phpunit/codedeption всю доку или основоное как запускать и как что тестировать?
Аноним 27/03/19 Срд 22:52:09 1371176567
>>1371052
В пхп должен быть подключен модуль mb_ из которого эта функция берется. Уебки ideone этого уже который год не делают. Используй другой сервис для пхп онлайн.
Аноним 27/03/19 Срд 22:54:17 1371177568
>>1371052
в идеоне нет поддержки многобайтовой кодировки, это означает что функций mb не будут там работать, добро пожаловать в пиайчпи (используй сендбокс)
Аноним 27/03/19 Срд 22:59:39 1371180569
>>1371177
>>1371176
Спасибо. А то я совсем ебу уже давать собирался.
Аноним 27/03/19 Срд 23:10:32 1371185570
Аноним 27/03/19 Срд 23:23:41 1371190571
>>1371185
я автор вопроса.
1. Нагуглил статьи и повторил.
2. Аналогично на ютубчике

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

Но открыл доку и там яяяяябать сколько всего. Казалось бы тесты, но пиздец как лень читать
Аноним 27/03/19 Срд 23:35:51 1371192572
Аноним 28/03/19 Чтв 02:00:29 1371225573
Аноним 28/03/19 Чтв 10:05:44 1371294574
>>1371225
Все прочитал что есть, статьи огонь!
У меня такая проблема, вот я беру что-то учить и учу от корки и до корки.

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

И тот же yii2 учу, все видосы на ютубе (проматывал то чего знаю), статьи + вся дока для создания индексов в голове и чтобы знать что он может. Осталось добить RBAC, REST и прочее

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

бляя, глянул на список чего сам себе составил учить, там пиздец сколько всего(
Аноним 28/03/19 Чтв 14:57:32 1371417575
>>1371041
справедливости ради стоит отметить, что я не пытался таким образом их оправдать
Аноним 28/03/19 Чтв 15:06:45 1371425576
БЛЯ!!! Отправил им недоделанных студентов и они меня позвали на собеседование на завтра. Больно будет?
Аноним 28/03/19 Чтв 16:10:42 1371463577
>>1371294

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

Так что считай это своим плюсом. Учиться вообще тебе придется постоянно. На досуге можешь почитывать статьи про собеседования от яндекса. Когда ты сможешь там решить все задачи, то значит, знаний ты набрал достаточно.
Аноним 28/03/19 Чтв 17:29:43 1371506578
>>1371425
>Больно будет?
Думаю, что главное чтобы ты по своему коду мог пояснить - что и зачем сделал.
Аноним 28/03/19 Чтв 18:01:09 1371529579
А что для тестирования базы данных используется?
В phpunit пишут что устарело
https://phpunit.readthedocs.io/ru/latest/database.html

И вообще, этого достаточно или еще надо
phpunit, codeception (там же и BDD подход), TDD
Этого хватит для middle?
Аноним 28/03/19 Чтв 18:06:16 1371535580
>>1371529
>А что для тестирования базы данных используется?
Строку на выходе сравнить что ли?
Аноним 28/03/19 Чтв 18:06:51 1371537581
image.png (76Кб, 1024x655)
1024x655
Коллеги, накопилось несколько вопросиков по студентам. Делаю сейчас первую страницу - отображение списка. БД подключено через PDO, СУБД - sqlite. В качестве шаблонизатора - twig.
1. Записи выводятся по 10 штук (пока) на страницу. Записи просматриваю с помощью fetch(). Поскольку подразумевается, что записей может быть много, делать fetchAll() неправильно. Соответственно, сначала мы считываем первые десять записей в массив и отображаем. А если нам сразу нужно будет отобразить записи с 30 по 40? Также в цикле делать fetch и просто пропускать записи? Как-то принудительно можно начать читать с определенной записи?
2. Вопрос вытекает из предыдущего - пагинация. Я правильно понимаю, кто кнопки пагинации содержат в своих гиперрсылках информацию о текущей странице, то есть на каждой странице ссылки разные вида, например, ?first_page=10&last_page=20 и потом мы это получаем в переменной $_GET? Я как бы сам до этого допер, но правильный ли это вообще подход? Может подскажете, где можно почитать про перенаправление и вот это вот все. Пагинацию тоже наверное имеет смысл сделать объектом?
3. Уже собственно про twig. Страница шаблона должна быть в одном файле или можно их как-то объединять несколько? Может ту же пагинацию в отдельном файле хранить? И еще, передача данных в шаблон передается массивом, что насчет быстродействия при передаче больших объемов информации?
4. Создание объекта PDO делаю так:
$db = new StudentsTable(new PDO('sqlite:db/students.db'));
Я почему-то из уроков по студентам сначала подумал, что привязка в объекту PDO будет в самом классе, но потом как-бы понял, что это свойство может быть присуще именно объекту. Поправьте меня, может я все же что-то не допонял.
Сорян за нубские вопросы, но немножко тупички небольшие возникли
Был тут с вами два года назад, принимайте пополнение, пикрелейтед
Аноним 28/03/19 Чтв 18:11:06 1371540582
>>1371535
да хуй его знает, всякие моки хуеки, вот есть AR модель, как-то че-то пошуршать и заебенить, по пацанский четко хуяк хуяк ну ты понял, да?
Аноним 28/03/19 Чтв 18:31:34 1371555583
>>1371537
>Поскольку подразумевается, что записей может быть много
В базе - много, а на руки запрашивай ровно столько, сколько надо - одну страницу, и разбирай всё что пришло. Пагинация получается - это смещение по твоим страницам.

>кнопки пагинации содержат в своих гиперрсылках информацию о текущей странице
Объект Пагинатор должен знать сколько у тебя всего записей, сколько выводится на одну страницу и текущее смещение. Этого достаточно чтобы получить общее количество страниц и текущую.
Я ему ещё иногда хтмл-шаблон для вывода всей ссылки отдаю - чтобы сразу оформленные блоки с номерами выдавал, а не тупо цифры. Удобно, но не везде любят такое.

>$db = new StudentsTable(new PDO('sqlite:db/students.db'));
А если с двумями таблицами будешь работать в приложении - вторую переменную создашь с ещё одним PDO? А если мне надо будет заменить объект PDO для тестов, а он у тебя гвоздями при создании вкручен.
Аноним 28/03/19 Чтв 18:32:26 1371556584
>>1371537

1) Неправильно выбирать все записи, а потом читать только часть.

Чтобы выбрать только часть записей есть конструкция LIMIT/OFFSET: https://www.sqlite.org/lang_select.html

Обрати внимание, что LIMIT/OFFSET не входит в стандарт языка SQL и является дополнением, которое поддерживается только в некоторых СУБД вроде MySQL или SQlite.

Описание на русском есть тут на примере Postgres: https://postgrespro.ru/docs/postgresql/11/queries-limit (прочти внимательно).

Стандартные способы постраничной выборки данных есть в Википедии: https://en.wikipedia.org/wiki/Select_(SQL)#Limiting_result_rows

2) Я правильно понимаю, кто кнопки пагинации содержат в своих гиперрсылках информацию о текущей странице

Да, в в соответствие с буквой S (stateless) из REST.Сервер не "запоминает", какие параметры сортировки выбирал пользователь.

Ссылки неудобно собирать руками, лучше сделать фукнцию, которая их будет генерировать.

3) Страница шаблона должна быть в одном файле или можно их как-то объединять несколько?

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

> И еще, передача данных в шаблон передается массивом, что насчет быстродействия при передаче больших объемов информации?

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

Учись делать измерения с помощью microtime(true).

4) Ты интуитивно сделал правильное решение. Класс StudentsTable не должен думать, где взять "соединение" (на самом деле не соединение, а просто объект для связи) с БД, какие у него параметры. Он должен получать его снаружи через конструктор. Это называется DI и у меня есть урок про это на гитхабе.

Аноним 28/03/19 Чтв 18:33:39 1371558585
>>1371555

> Я ему ещё иногда хтмл-шаблон для вывода всей ссылки отдаю

Это плохая идея, так как разные ссылки могут оформляться по-разному, например, первая ссылка может быть выделена. Лучше сделать отдельный шаблон для пагинации.
Аноним 28/03/19 Чтв 18:39:08 1371560586
Аноним 28/03/19 Чтв 18:47:00 1371565587
>>1371529

Саму БД тестировать не надо - ее тестируют ее разработчики. Ты наверно хотел тестировать код, который работает с БД?

Тут есть пара вариантов:

1) разделить код на тот, которому точно нужна БД и тот, который только подготавливает данные. Тот, который подготавливает данные, тестировать, подсунув ему заглушку вместо реальной БД.

2) код, который работает непосредственно с БД можно тестировать, используя тестовую БД. Для соблюдения требования об изоляции тестов друг от друга мы должны перед каждым тестом воссоздавать одинаковое состояние БД. Например, загружать в БД дамп. Но тут 2 проблемы:

- это медленно
- если у нас 1000 тестов и мы данные для каждого добавим в дамп, то он будет большой и непонятно, какие данные кому нужны

Потому обычно делают так:

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

- перед каждым тестом мы начинаем транзакцию, и откатываем ее после теста, отменяя все изменения

- если тесту нужно наличие каких-то записей в БД, он сам их создает

Вот как-то так. Если СУБД поддерживает создание таблиц в памяти, то стоит это использовать для ускорения. SQlite умеет такое, например.

Допустим, ты тестируешь репозиторий Пользователей, который умет создавать пользователей в БД, искать их по id, удалять. Тест создания пользователя может выглядеть так:

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

Аноним 28/03/19 Чтв 19:02:11 1371573588
Привет анон.
У меня есть вопрос, поможешь мне?
В пхп я (как и везде) почти ноль. Есть сайт на котором по api показывался блок погоды. После переезда сайта на новый хостинг данные перестали выводится, хотя код я не менял. Ключ АПИ так же работает и при открытии напрямую все данные есть. На сайте же невыводится ничего. В чем может быть проблема? В настройках хостинга, версии пхп или в чем?
Аноним 28/03/19 Чтв 19:07:58 1371574589
>>1371573
Я реально тупенький и не понимаю в чем может быть проблема,
Код типа такой:


<?
$url = "мой ключ апи";
$contents = file_get_contents($url);
$clima = json_decode($contents);
$temp = $clima->main->temp;
$temp_max = $clima->main->temp_max;
$temp_min = $clima->main->temp_min;
$desc = $clima->weather[0]->main;
?>
<? echo "". $temp ."&deg; ". $desc .""; ?>
Аноним 28/03/19 Чтв 21:17:39 1371621590
Аноны, подскажите, в чем проблема. https://ideone.com/oO5WuX меня интересует откуда в последней строке ошибка. Функцию я вроде закрыл, а ошибка со скобкой лезет
Аноним 28/03/19 Чтв 21:18:55 1371622591
>>1371574
А в самих переменных в этот момент что находится?
Аноним 28/03/19 Чтв 21:26:50 1371623592
>>1371622
Слово function в 19 строке лишнее. Оно нужно если ты обьявляешь новую функцию.
Аноним 28/03/19 Чтв 21:32:52 1371625593
>>1371623
Тю блять. Невнимательность спасибо
Аноним 28/03/19 Чтв 22:43:35 1371655594
>>1371052
Вроде получилось, но я 2 момента не понимаю.
http://sandbox.onlinephpfunctions.com/code/804b14ca336e4c0eed19d07f4a905cf61e897acf
1. Я выдираю из противоположной стороны фразы. Если для этого я использую аргумент -$i, то после первой буквы а идет еще одна а. это легко проверяется по эху. Почему так происходит, как я понял это из за того, что при 0 аргументе первая буква всегда первая в предложении 1ца дает 2ю букву в одном направлении и 0ю(в данном случае первую с обратной стороны) так?
2. Как мне сделать так, что бы если слово не было палиндромом ехо после цикла не выводилось?
Аноним 28/03/19 Чтв 23:02:29 1371666595
>>1371621
Попробовал - не пашет, сейчас переделал и все равно не пашет. https://ideone.com/ucPQkR Вроде и комментарии сам себе расписал, почему-то пишет про неопределенный аргумент, но я его определил до начала цикла
Аноним 28/03/19 Чтв 23:44:02 1371683596
Безымянный.png (11Кб, 459x513)
459x513
>>1371622
Не совсем понял про переменные.
Переменные хукают данные из JSON (см. пик) и выводят их далее через echo.
Когда я со своим нулем знаний конструировал это, все работало. Все работало ровно до ебаного переезда хостинга.
Аноним 29/03/19 Птн 07:37:14 1371754597
Оп,а на каком уровне вёрстку стоит учить? Бесплатной хтмлакадемии и твоих задач хватит или надо ещё гриды,флексы и адаптивную подучить? Про js тот же вопрос.
Аноним 29/03/19 Птн 11:13:21 1371855598
Аноним 29/03/19 Птн 15:55:19 1371952599
>>1371573
>>1371574
>>1371683
Памахити

Пошли меня куда-нибудь анон. Где мне искать решение? Я вижу проблему в настройках хостинга, но там реально непробиваемые сидят и без уверенности (читай доказательств) писать в поддержку даже нет желания.
Аноним 29/03/19 Птн 16:59:52 1371971600
>>1371952
Попробуй просто в echo строку вывести без переменных,если все норм,то и хостинг не виноват. Мб какой xdebug поставь и проследи, что происходит, плюс в браузере в network посмотри, какие ответы на запросы приходят, какой код ответа. Я сам вкатывальщик, особо не шарю, но ты мало инфы дал анонам.
Аноним 29/03/19 Птн 17:02:13 1371973601
>>1371952

Для начала, почему ты гадаешь наугад? Так можно еще 100 лет гадать. Изучи ситуацию. Сделай следующее:

- убедись, что на сервере ведутся логи ошибок PHP или веб-сервера, найди их. Что логгирование не запрещено настройками PHP или хостинга.
- проверь, есть ли там сообщения, относящиеся к этому файлу с кодом - вдруг там происходит ошибка

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

Проверь - что именно вернула file_get_contents, какую страницу, что на ней?


Аноним 29/03/19 Птн 17:03:36 1371975602
>>1371952

Не используй echo, как тебе советуют, так как она выводит только строки и числа. Используй var_dump, которая выводит все типы данных. Подробности в мануале.
Аноним 29/03/19 Птн 17:04:25 1371977603
>>1371952
Можно ещё на локалке скрипт свой проверить,опенсервер какой быстро поставить и все.
Аноним 29/03/19 Птн 17:08:18 1371980604
>>1371621
>>1371666
У тебя в условии значение никогда не становится меньше или равно 0 и, соответственно, условие функции не доходит до ложного значения, и, соответственно ничего не возвращается.

>https://ideone.com/oO5WuX меня интересует откуда в последней строке ошибка.
Потому что ты задаешь функцию, которая уже создана. С помощью ключевого слова function, а тебе нужно её вызвать просто написав имяФункции().
Аноним 29/03/19 Птн 18:05:38 1372005605
>>1371971
Попробую
>>1371973
Спасибо, буду пробовать и курить мануал, как советует и этот >>1371975 анон

>>1371977
Все работало, говорю же. На двух сайтах все фурычило.
Аноним 29/03/19 Птн 18:53:59 1372023606
kaban.jpg (21Кб, 170x136)
170x136
Двач образовательный

Спасибо анону >>1371973 полез искать логи и все стало ясно нет:

file_get_contents(): failed to open stream: no suitable wrapper could be found in on line 90
file_get_contents(): http:// wrapper is disabled in the server configuration by allow_url_fopen=0 in *

Теперь дело за малым, понять что это и как фиксить. Спасибо, анонче.

Аноним 29/03/19 Птн 19:08:40 1372026607
Аноним 29/03/19 Птн 19:21:16 1372031608
>>1372026
Cпасибо. В тех уроках явно не хватает небольшой инфы о флагах. Уж очень задача упрощается.
Аноним 29/03/19 Птн 19:21:57 1372032609
>>1372031
Лил погуглил и нашел урок под это на другом сайте.
Аноним 29/03/19 Птн 20:29:10 1372058610
Аноним 29/03/19 Птн 21:34:23 1372084611
>>1372058
https://ideone.com/LYrtEq

$overallPaid=0;
переменная находится внутри цикла. И обнуляется каждый раз.

В остальном всё работает. Но проценты и комиссия банка абсурдны. Анон не успевает расплачиваться с кредитом. 100 витков цикла проходят до того как он расплатится. Потому ты не видишь вывода на экран.

Можешь отслеживать состояние переменных внутри программы командами echo или var_dump.
Аноним 29/03/19 Птн 21:38:11 1372089612
>>1372084
Ага, спасиб щас дампами обмажусь
Аноним 29/03/19 Птн 21:40:00 1372091613
>>1372084
Как надоели эти детские ошибк, ну йобана.
Аноним 29/03/19 Птн 23:30:59 1372130614
ОП, глянь, если сможешь, твои задачи по верстке:

1. https://codepen.io/codecoshauni/pen/bZQKyv
2. https://codepen.io/codecoshauni/pen/QoJBGz?editors=1100
3. https://codepen.io/codecoshauni/pen/bZzzWE
4. https://codepen.io/codecoshauni/pen/YgBgMV
5. https://codepen.io/codecoshauni/pen/ZPwZEz
6. https://codepen.io/codecoshauni/pen/MxLRzy
7. https://codepen.io/codecoshauni/pen/PLVvZM
8. https://codepen.io/codecoshauni/pen/YgBbVg
9. https://codepen.io/codecoshauni/pen/draExb
10. https://codepen.io/codecoshauni/pen/QoPLjW
11. https://codepen.io/codecoshauni/pen/ZPdyeK
12. https://codepen.io/codecoshauni/pen/oVKxbL
someApprentice !EaaiHmIJms 30/03/19 Суб 11:13:55 1372258615
Почему у меня в Питоне код работает по разному?

Вот набросок кода: https://repl.it/repls/ConsciousBlondElectricity (можно не разбираться в том что он делает, меня интересует синтаксис)

Вот примеры синтаксиса, которые работают как ожидаются:

https://repl.it/repls/GiantSeveralControlpanel

https://repl.it/repls/FixedAnnualRuntime

Но в рабочем коде, в первом случае, выдаётся ошибка

>if (details is None) or (not 'Bearer token' in details['authextra']):
>builtins.TypeError: argument of type 'NoneType' is not iterable

И, во втором случае,

>if (details is None) :
> principal[u'extra'] = {
> u'error': u"Access denied: No Bearer token in authexta"
> }
> return principal
>
>
> token = details['authextra']['Bearer token'];

return не выполняется и код продолжает выполнятся

>token = details['authextra']['Bearer token'];
>builtins.TypeError: 'NoneType' object is not subscriptable


И вот ещё 3-ий пример: https://repl.it/repls/DependentUnselfishDevelopment

но в рабочем коде

> try:
> payload = jwt.decode(token, JWT_SECRET)
> except Exception as e:
> principal[u'extra'] = {
> u'error': e
> }
> return principal
>
> ...

return снова не выполняется и вбрасывается ошибка: "WAMP message serialization error: Object of type 'InvalidSignatureError' is not JSON serializable"
https://pyjwt.readthedocs.io/en/latest/api.html#jwt.exceptions.InvalidSignatureError


Почему так может происходить? Версии Питона 3.6.x что на Repl.it, что и на машине, и примеры синтаксиса проверялись и у себя на машине в консоли с помощью команды python.
Аноним 30/03/19 Суб 12:17:51 1372272616
>>1372258
Потому что это php тред
Аноним 30/03/19 Суб 13:12:24 1372298617
Аноним 30/03/19 Суб 20:13:11 1372433618
Народ, подскажите в чем косяк. Регулярка про автомобильный номер. ВВел на сайте [а-я][0-9]{2}[а-я]{2}ugm с чувствительным кейсом тк сам автоеб и буквы всегда в нижнем регистре, но выдает ошибку. Написал простую прогу, но она внезапно корректно работает. https://ideone.com/4DlDPk чяднт на регексе?
Аноним 30/03/19 Суб 20:29:18 1372438619
2019-03-3020-28[...].png (13Кб, 758x332)
758x332
ОП, или сочувствующие, не смог по мануалу разобраться как работает array_rand, сделал одну из задач с помощью mt_rand, но очень хочу разобраться как всё-таки надо было сделать.
Мануал читал, честно, так и не дошло.
https://ideone.com/UYAeWZ
Аноним 30/03/19 Суб 20:41:24 1372446620
Аноним 30/03/19 Суб 20:47:40 1372451621
>>1372438
Работает - значит норм. Но вообще через array_rand лучше тк тут массив проиндексирован. Если бы он не был индексирован( удали ключи) то у тебя отсекся вариант да тк он был бы 0м. И 6го тупо не было. Представь, что массивы с разным числом значений, которые потом еще и меняться могут . В итоге не высчитывать же тебе все числа? Если через эту функцию то гораздо проще https://ideone.com/Nx5ew5
Аноним 30/03/19 Суб 22:02:27 1372489622
>>1372433
для того чтоб видеть ошибки включи их вывод.
error_reporting(-1);

флага g в пхп нет
Аноним 30/03/19 Суб 22:34:52 1372507623
>>1372489
Не в этом дело, я сейчас переписал на регексе с нуля уже другую задачу и все заработало. Странная хрень
Аноним 30/03/19 Суб 23:22:02 1372521624
>>1353705 (OP)
Возникли некоторые вопросы по объекту реализующему ResposeInterface из PSR-7.

Вы писали:
>Он представляет ответ на HTTP-запрос. В Симфони контроллер получает на вход Request и выдает на выходе Response, а фреймворк уже выводит его содержимое. Это удобно для тестирования, мы можем вызвать контроллер и смотреть, что он там сгенерировал.

Этот объект нужен для того, чтобы содержать в себе html-код? При тестировании каким-то образом проверяется его содержимое (html)? Не могу понять.

>Обычно это выглядит так:

public function indexAction(Request $request): Response
{
,....
return $this->render('template.twig', ['x' => 1, 'y' => 2]);
}

Получается метод $this->render(), встроенный в контроллер, подставляет наши значения в шаблон. Затем полученный html-код вставляется в поле $body конструктора объекта Response, который мы возвращаем как результат работы контроллера.

В каком месте выводить полученный результат?
Достаточно написать во фронт-контроллере echo $response->getBody(); ?

Например, пусть примерно так у нас выглядит файл init.php, который подгружается в index.php

$request = ServerRequest::fromGlobals();

$app = new App($request);
$response = $app->run();

echo $response->getBody();
Аноним 30/03/19 Суб 23:51:32 1372532625
хаккеры. Я камень. Закончил шарашку по специальности инженер-строитель. корочка ПГС. Как перекатиться в кодера (а то задолбался работать в миллионике за 20к)? щас вот тут с массивами разбираюсь ) и перехожу к следующему разделу.
Аноним 30/03/19 Суб 23:53:08 1372534626
>>1372446
Я вроде не выключал. Где включить и в чем с этим проблема?
Спасибо!
>>1372451
Спасибо!
Не очень понял как это работает в мануале, но оказалось что так, как там и было написано -_-
Аноним 31/03/19 Вск 00:45:54 1372541627
>>1372532
самое главное мозги ебать не надо, надо постоянно учить, основы типа переменные, массивы, циклы, функций, операторы и т.д это 5% из всего что надо знать. Теория те же 5% от знаний, применил, уже 10%, чтобы более менее что-то знать надо постоянно кодить. По мере опыта уже сам будешь разбираться и таких вопросов не возникнет
Аноним 31/03/19 Вск 10:58:23 1372622628
Нужен ли файл bootstrap/init.php если у меня в приложении будет единая точка входа public/index.php?
Аноним 31/03/19 Вск 12:46:33 1372652629
Screenshot57.png (39Кб, 822x438)
822x438
Аноны, помогите, жопа горит.
Как вывести вне цикла полную фразу, а не ее последнюю часть?
Аноним 31/03/19 Вск 12:47:22 1372654630
>>1372534
Это я ошибся, не обращай внимания
Аноним 31/03/19 Вск 12:49:34 1372655631
Аноним 31/03/19 Вск 12:51:00 1372656632
Аноним 31/03/19 Вск 13:00:05 1372660633
Аноним 31/03/19 Вск 13:03:13 1372662634
>>1372660
Спасибо тебе, а то я бы еще долго думал и бомбил.
Аноним 31/03/19 Вск 13:32:59 1372679635
>>1372532

https://www.youtube.com/user/TheLukesky1/playlists

В таком порядке:

PHP Start Теория
PHP Start Практика
PHP UP Теория
PHP UP Практика

Мимо 3-курс ПГС, но хочеться в ойти... вот вкатываюсь потихоньку...
Аноним 31/03/19 Вск 15:38:30 1372745636
image.png (92Кб, 957x790)
957x790
Аноним 31/03/19 Вск 15:47:47 1372749637
>>1372745
Выше в треде смотри
Аноним 01/04/19 Пнд 04:57:03 1373027638
Объясните пожалуйста суть Domain-Driven Design
Аноним 01/04/19 Пнд 14:12:04 1373172639
Котаны, помогите немного по регулярным выражениям. Не пойму как работают группировки.
Вот две строки, заменяю:
preg_replace( '/{([a-z]+):([^\}]+)}/ ', '(<\1>\2)' , $str); //вариант из учебного пособия

preg_replace( '/{([a-z]+):([^\}]+)}/' , '(<$1>$2)' , $str); // мой вариант

В чем отличие этих двух вариантов подстановки? А еще в том учебном фреймворке если я из '(<\1>\2)' или '(<$1>$2)' убираю первую "переменную" подстановки: <\1> или <$1> - то все ломается. Указание "переменной" в скобках <> - указывает на то что не нужно использовать данные из этой переменной, вроде. Но зачем тогда ее вообще указывать?
Аноним 01/04/19 Пнд 14:21:43 1373182640
>>1373172
Не то что бы фикс - изначально в строке пособия было указано так:
preg_replace('/{([a-z]+) : ([^\}]+)}/', '(?P<$1>$2)', $route);
- я подумал что "?P" - ничего не значит. Однако ток сейчас прочел такое: "Указать обратную ссылку на именованную подмаску можно с помощью (?P=name)".
Но в варианте пособия нет "=";

Чет я запутался.
Аноним 01/04/19 Пнд 17:12:28 1373272641
Добавьте в шапку, что без react/angular/vue вы сейчас никому не всрались с своим бекендом
Аноним 01/04/19 Пнд 17:22:30 1373280642
>>1373272
В большинстве вакансий вроде - базовый жс с jquery.
Аноним 01/04/19 Пнд 19:24:30 1373317643
>>1373280
У ЖС-макак свой манямирок, не спорь с ним. Через 3 года то же самое говорить будет. Только названия фреймворков поменяются.
Аноним 01/04/19 Пнд 20:00:40 1373327644
>>1373272
Такое требуют обычно только в днищеконторах, где ты будешь и за папу и за маму, и за админа, и за бухгалтера. И платить тебе будут как эникею.
Аноним 01/04/19 Пнд 20:08:49 1373333645
>>1373327
я живу не в СНГ. У меня все тренды , в том числе и айти, немножко раньше проявляются.
Аноним 01/04/19 Пнд 20:10:57 1373335646
>>1373317
Манямирок это делать ставку на пхп и использовать жейквери в 2019
Аноним 01/04/19 Пнд 20:21:53 1373346647
>>1373335
Руби умир. Нода нахрен никому нинужна.
У пхп из альтернатив разве что питон, но он как пишут помедленнее. Но что важнее - вакансии.
Аноним 01/04/19 Пнд 20:32:58 1373355648
>>1373333
Нет, просто ты только по ЖС ситуации на рынке видишь. ПХПшники же больше по ПХП видят. Зачем вообще лезть с советами, особенно в шапку, если и без тебя разберутся?
Аноним 01/04/19 Пнд 20:36:36 1373358649
>>1373335
>делать ставку на пхп
Мне вообще как-то насрать. Надо будет на питон или ещё куда перееду - примерно те же яйца. Просто на ПХП хайп уже прошёл, а у питона сейчас идёт.


Аноним 01/04/19 Пнд 20:37:18 1373359650
>>1373355
ПХП хоронят-хоронят... Но на чем пилить эти миллионы магазинов, блогов, форумов?
Аноним 01/04/19 Пнд 20:38:33 1373363651
>>1373358
Дваждую. Предметная область и опыт решают больше чем тупо синтаксис %%который +\- схож.
Аноним 01/04/19 Пнд 20:45:10 1373370652
>>1373355
Так я фулстак, и сейчас таких вакансий большинство и у вас так будет через год два
Аноним 01/04/19 Пнд 20:46:17 1373372653
>>1373359
Их без тебя тысячи фрилансеров сделают за 5 рублей
Аноним 01/04/19 Пнд 20:49:09 1373376654
>>1373370
>и у вас так будет через год два
Рыночек по регионам несколько отличается, как по фреймворкам, так и по наборам требуемых скиллов.
Аноним 01/04/19 Пнд 20:50:59 1373379655
>>1373370
>Так я фулстак
Так у вас и требования почти минимальные. У фуллстаков говнокода больше всего.
Аноним 01/04/19 Пнд 20:53:17 1373380656
>>1373379
Причем тут это вообще, я лишь сказал, что сейчас без фронта никуда. Но вы можете продолжать обучатся вебу по канонам 2013 года. Я уверен шапка не менялась с того времени
Аноним 01/04/19 Пнд 21:12:45 1373394657
>>1373380
>сейчас без фронта никуда
Не все пердолят лэндосы и темы для вордпресса, чтоб ты знал.
Аноним 01/04/19 Пнд 21:13:07 1373395658
2019-04-0121-11[...].png (99Кб, 746x783)
746x783
ОП или аноны, я что-то вообще залип в решении этой задачи.
Толкните хоть в нужное русло.
Как сделать так, чтобы случайное слово выбиралось из пяти разных массивов?
Аноним 01/04/19 Пнд 21:18:56 1373398659
Аноним 01/04/19 Пнд 21:30:18 1373402660
Аноним 01/04/19 Пнд 22:34:01 1373446661
Аноним 01/04/19 Пнд 23:03:14 1373468662
>>1373446
На 7 строке ошибка - палиндром пишется через "а".

На 4 строке он функцию не знает. Как так случилось и почему? Я в душе не ебу что ты за говносборку PHP там поставил.
Аноним 01/04/19 Пнд 23:08:10 1373474663
>>1373446
Вместо $textLower[$i] != $textLower[$lenghtText-$i] должно быть
$textLower[$i] != $textLower[$lenghtText-$i-1]
Аноним 01/04/19 Пнд 23:28:05 1373484664
image.png (570Кб, 1366x768)
1366x768
>>1373468
>На 7 строке ошибка - палиндром пишется через "а".
аха ха -ха, теперь то заработает нет =(
> Я в душе не ебу что ты за говносборку PHP там поставил.
на ideone php7.1.0, как я ее могу поставить?
Пробовал через консоль на винде открыть (7.3.3php) - не выходит видимо что то не так делаю,
>>1373474
Действительно, спасибо за замечание. Но проблема в том что анон выше написал. Даже без цикла переменные выводить не хочет.

Аноним 01/04/19 Пнд 23:30:12 1373486665
>>1373484
Проблема в русской кодировке, строка просто так не перебирается
Аноним 01/04/19 Пнд 23:45:02 1373499666
>>1373486
Затестил в другой песочнице - заработало. Правда заданный текст пришлось на транслите писать.
Всем спасибо
Аноним 01/04/19 Пнд 23:52:27 1373502667
Аноним 01/04/19 Пнд 23:53:43 1373505668
testhub.png (47Кб, 859x523)
859x523
Я тут пытаюсь приступить к задачке тестхаб. Возник вопрос по таблицам БД.
Есть таблица complited_test(список тестов которые прошёл пользователь) и она ссылается на test. Но как бы можно обойтись без этой связи.
complited_test ссылается на student_answers(список вариантов ответов пользователя). Варианты ответов ссылаются на вопрос, которому они принадлежат. Вопросы ссылаются собственно на тест из которого взяты. Для того что б получить строку данных из complited_test и test нужно составить сложный запрос для всей этой цепочки.
Собственно вопрос. Какой путь решения будет верным. Делать сложный запрос по всей цепочке. Или оставить лишнюю связь и получать ответы простым запросом.
Аноним 02/04/19 Втр 00:18:56 1373518669
>>1373505
а ты в какой орм работаешь?
Аноним 02/04/19 Втр 01:11:26 1373534670
>>1373502
Сэнкс. А зачем разделять строку на массив символов? Разве это не одно и то же?
Аноним 02/04/19 Втр 01:23:53 1373540671
>>1373534
А ты попробуй получи символы по отдельности из ютф8 строки
Аноним 02/04/19 Втр 01:25:02 1373541672
>>1373534
нет, не одно
это нужно для того, чтобы решить ахуительную задачку на переворачивание строки на собеседовании и кучу других
Аноним 02/04/19 Втр 01:52:56 1373548673
>>1373540
Ну на латинице вроде работало все, почитаю об этом
>>1373541
Я правильно понимаю, что основная библиотека php это лишь малая часть того, что должен знать разработчик? И на собеседованиях на джуна будут гонять по алгоритмам? Нужно ли заучивать функции с гайда для нубов, ведь если с ними работать они со временем запомнятся, и достаточно знать что такие существуют?
Аноним 02/04/19 Втр 02:30:38 1373552674
>>1373548
>что основная библиотека php это лишь малая часть того
Ты про SPL? Так-то это классика, это знать надо. Какой же ты погроммист без знаний структур данных?
Аноним 02/04/19 Втр 03:42:43 1373555675
>>1373484

Ты в консоли вместо Subl печатаешь Slub, о чем тебе и говорит сообщение.

Для проверки можно попробовать распечатать файл командой type c:\Subl\... и убедиться, что ты пишешь путь неправильно.

При наборе команды стоит использовать клавишу Tab для автодополнения имен папок и файлов.
Аноним 02/04/19 Втр 06:45:36 1373570676
>>1373518
На стандартной для Laravel орм планирую работать.
Eloquent — реализация шаблона ActiveRecord.
Аноним 02/04/19 Втр 09:05:32 1373595677
>>1373172
Повторю снова свой пост, может кто поможет:
Котаны, помогите немного по регулярным выражениям. Не пойму как работают группировки.
Вот две строки, заменяю:
preg_replace( '/{([a-z]+):([^\}]+)}/ ', '(<\1>\2)' , $str); //вариант из учебного пособия

preg_replace( '/{([a-z]+):([^\}]+)}/' , '(<$1>$2)' , $str); // мой вариант

В чем отличие этих двух вариантов подстановки? А еще в том учебном фреймворке если я из '(<\1>\2)' или '(<$1>$2)' убираю первую "переменную" подстановки: <\1> или <$1> - то все ломается. Указание "переменной" в скобках <> - указывает на то что не нужно использовать данные из этой переменной, вроде. Но зачем тогда ее вообще указывать?

Не то что бы фикс - изначально в строке пособия было указано так:
preg_replace('/{([a-z]+) : ([^\}]+)}/', '(?P<$1>$2)', $route);
- я подумал что "?P" - ничего не значит. Однако ток сейчас прочел такое: "Указать обратную ссылку на именованную подмаску можно с помощью (?P=name)".
Но в варианте пособия нет "=";

Чет я запутался.
Аноним 02/04/19 Втр 14:15:03 1373748678
>>1373595
>Чет я запутался.
Просто мозги ебёшь.

Одно дело, когда у тебя загововки улетают в вывод и ты не понимаешь где как у меня недавно, и другое дело дрочить какое-то пособие до основания и спрашивать у левых людей почему там именно так написано.
Аноним 02/04/19 Втр 14:24:31 1373756679
Как запустить из php-файла другой заданный php-файл так, будто его запросили из браузера?
То есть, нужно, чтобы у него были GET/POST параметры, куки, вся хуйня как обычно, но фактически такой запрос не выполняя.

Не тупо в консоли, а именно будто пришел пользовательский запрос.
Аноним 02/04/19 Втр 14:38:55 1373766680
>>1373756
Так из браузера и запрашивай. На локалхост положи его и вызывай.
Сам так недавно делал чтобы API проверить.
Аноним 02/04/19 Втр 14:41:49 1373769681
>>1373595
твое игнорирование пособия сразило меня наповал. зачем ты вообще его читаешь в таком случае.

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

ты список вида {name:group} превращаешь в регулярки вида
(?P<name>group) которые потом можно опять использовать в функциях preg

(?P<name>(...)) и (?P=name(...)) разные способы сделать одно и тоже в разных регулярных синтаксисах, я в пхп использую ?P<name> - другой вариант по моему не работает

эта фишка потом позволит тебе брать уже что-то следующее, парсить и получать массив с именноваными ключами для групп. это скорее всего какой то туториал как сделать роутер по типу "fast route"
Аноним 02/04/19 Втр 15:10:56 1373784682
>>1373766
>>1373756
Разобрался. В пыхе же есть встроенный веб-сервер (и похоже этот ублюдок охуеть какой быстрый).
Можно, когда нужно, оперативно поднять сервер на левом порту и в нужной папке.

Узрите же великую магию: https://pastebin.com/QXzR8sy4
Аноним 02/04/19 Втр 15:31:24 1373791683
>>1373769
Да именно это роутер.
>>твое игнорирование пособия сразило меня наповал
Дело в том, что именно этот момент и не разъяснен. Просто дан как данность.
Спасибо.
Аноним 02/04/19 Втр 15:43:58 1373800684
>>1373791
P.S. - теперь я рили понял. В комментах к туториалу неверно эту строку истолковали. И я перерыв документацию по регуляркам - не нашел того о чем они писали.
Впрочем плюс в том что регулярных я до этого косяка не знал. А так волей-не волей пришлось плотнее ознакомиться.
Спасибо еще раз.
Аноним 02/04/19 Втр 17:37:17 1373834685
Пагни, помогите с symfony и doctrine2
Я понимаю, что лезть руками в базу и вручную добавлять новые поля в таблицу это неправильный способ работы с доктриной, но чисто в учебных целях как сделать следующее: допустим в существующую таблицу добавлено новое поле напрямую, без участия доктрины. Как мне дать знать об этом доктрине и перегенерировать entity? В доке https://symfony.com/doc/current/doctrine.html есть следующий рецепт:

If you prefer to add new properties manually, the make:entity command can generate the getter & setter methods for you:

php bin/console make:entity --regenerate

If you make some changes and want to regenerate all getter/setter methods, also pass --overwrite.

Но после запуска этой команды entity файл на меняется. ЧЯДНТ?
Аноним 02/04/19 Втр 19:47:00 1373892686
>>1373834

Что тебе мешает руками дописать нужные поля и аннотации в entity?

> Но после запуска этой команды entity файл на меняется. ЧЯДНТ?

А ты добавил overwrite? Плюс, я подозреваю, эта штука перезапишет файл и может стереть какие-то методы, которые ты туда добавлял.

Вообще, Доктрина очень универсальная и поддерживает 2 модели:

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

2) источник правды - модели. Ты добавляешь нужные поля и аннотации и из них генерируешь миграции, которые вносят нужные изменения в БД.
Аноним 02/04/19 Втр 21:01:12 1373952687
>>1367259
https://regex101.com/r/qF7vT8/192
Нужна помощь с регуляркой. Как учитывать общее количество символов в группе если получается разброс от одного до трех символов в каждой группе
Аноним 02/04/19 Втр 23:31:44 1374025688
Аноним 03/04/19 Срд 00:10:07 1374041689
Господа, нужен ваш совет.
Нужно сделать редактируемую таблицу, а введенные в таблицу данные отправлять в базу.
Я так понимаю саму таблицу и отправку данных только с помощью js можно сделать?
Аноним 03/04/19 Срд 06:06:29 1374075690
>>1353705 (OP)
Вопрос по HTML и CSS...

Задача: сделать вывод текста и текстареи - в две колонки,
как тут: https://css-live.ru/articles/css-gridy-css-kolonki-%E2%99%A5.html
но так, чтобы при изменении размера текстареи, изменялся и размер line-height,
и чтоб не ровно на половину страницы разделялось, а с небольшим отступом.

Вопрос - как правильно сделать?
Аноним 03/04/19 Срд 10:54:10 1374121691
>>1373892
>Что тебе мешает руками дописать нужные поля и аннотации в entity?
Лень конечно же. Думал доктрина сделает это за меня при regenerate
>А ты добавил overwrite?
Да
>Плюс, я подозреваю, эта штука перезапишет файл и может стереть какие-то методы, которые ты туда добавлял.
Да, знаю, но я ничего в файл не добавлял, поэтому значения не имеет
Аноним 03/04/19 Срд 13:04:02 1374206692
>>1373769
Раз ты помог мне, подскажи еще с регулярками. Меня эта тема выносит уже.
Смотри
Я выполняю этот код на ideone
$str = 'admin/delete/{id:\w+}';
$newstr = preg_replace( '/{([a-z]+):([^\}]+)}/' , '(?P<\1>\2)' , $str);
echo $newstr;
результат : admin/delete/(?P<id>\w+)

Все как ты и объяснил. Все логично.

Я выполняю эти же строки на своем сервере и в результате получаю в результате: admin/delete/(?P\w+). Куда девается '<id>' ?
Что за дела?

Сервак OpenServer, версия PHP 7.2.10 Выполняю в отдельном файле. То есть ничего на этот код не влияет.


Аноним 03/04/19 Срд 14:01:50 1374247693
Как в phpunit передать некоторые параметры?
Есть интеграционные тесты, нужно передать такую инфу, как логин/пароль.
Аноним 03/04/19 Срд 14:26:12 1374280694
>>1373952
У меня была такая же проблема. Ты пытался написать код разделяя на очень много промежутков, которые могут быть при написании телефона. Твой код:
^\s?(\+\s?7|8)\s?[\s-]?\(?\s?\d{3,4}\s?\)?(([-\s]){0,3}(\d{1,3})){0,}$
Есть в коде лишние скобки и тут например вместо ([-\s]){0,3} можно было бы написать [-\s]{1,3} ну или вообще [-\s]+ ну и тд, упрощать и упрощать. В общем мой код для данной задачи такой:
^([ +]+7|\s?8)([() -]?\d){10}$. Тут есть начало кода ^([ +]+7|\s?8) потом середина, которая либо есть, либо её нету [() -]? и конец это.

Помогите понять как решать задачу по регулярке:
https://ideone.com/yxFIpH
Я никак не могу понять почему он выдаёт 892754-54305 и не считывает дефис посередине
\d)$.
Need help. Аноним 03/04/19 Срд 16:26:20 1374364695
image.png (26Кб, 1351x583)
1351x583
Хотел создать ib. Кхм... "Парашу" на бесплатном хостинге 000webhost. Взял движок Kusaba X, установил, но вот проблема. У меня вообще не отображается стиль на глав.странице, а вот с админ панелью почти все хорошо, стиль есть, правда правила нельзя отредактировать, и нельзя добавить доску.
В чем может быть проблема?
Хотелось бы верить, что это дерьмо заработает :d
Аноним 03/04/19 Срд 17:47:58 1374401696
Аноним 03/04/19 Срд 18:59:22 1374466697
>>1374206
первое что приходит на ум - ты выдал результат в браузер, который съел <id> как тег
Аноним 03/04/19 Срд 21:48:06 1374634698
Аноны, подскажите, как сделать перенаправление с, допустим, /randomfile.php обратно на index? По примеру как это в phpmyadmin. Долго ковырял это приложение, так и не понял как оно перенаправляет
Аноним 03/04/19 Срд 22:35:20 1374658699
Аноним 03/04/19 Срд 23:02:18 1374673700
При конфигурации движка lainchan вылезает ошибка "Unknown column 'uri' in 'order clause' "
Что делать?
Аноним 04/04/19 Чтв 00:08:15 1374699701
>>1374247

Обычно так не делают. Ведь когда твои тесты будет запускать CI сервер, он дописывать пароли не будет. Но есть варианты:

- сделать кастомный конфиг, в него вписать пароли. Он не комитится в гит, а туда коммитится лишь образец (config.ini.example) и каждый разработчик из образца делает себе конфиг со своими паролями

- передавать логины и пароли через переменные окружения:

APP_XYZ_LOGIN=123 phpunit
Аноним 04/04/19 Чтв 00:20:57 1374702702
>>1374121

Тогда есть еще вариант переместить куда-то файл и попросить Доктрину сгенерировать его заново. Там наверняка есть опции для генерации только одного файла.

Вообще, я тут пару минут погуглил и понял, что ты все перепутал. make - это команда из MakerBundle, она, как я понимаю, годится только для создания файлов с нуля.

Но у Доктрины есть инструменты для синхронизации кода и БД. Набери php bin/console list | grep doctrine (показать все команды и оставить только имеющие слово doctrine) и ты увидишь кучу полезных команд, например:

doctrine:mapping:import Imports mapping information from an existing database
doctrine:migrations:diff Generate a migration by comparing your current database to your mapping information.
doctrine:schema:update Executes (or dumps) the SQL needed to update the database schema to match the current mapping metadata

Изучи их и посмотри, нет ли там чего-то нужного.
Аноним 04/04/19 Чтв 00:27:54 1374704703
>>1374206
Браузер воспринимает результат вывода скрипта как HTML а <id> - как тег.

Решение - используй var_dump вместо echo или ставь правильные заголовки:

header("Content-Type: text/plain; charset=utf-8");

Это заставит браузер воспринимать то, что выводит твоя программа, как обычный текст, а не HTML.
Аноним 04/04/19 Чтв 00:28:02 1374705704
Вот допустим у нас выбросилось исключение в каком-то классе приложения. Ведь не хорошо показывать пользователю подробности ошибки. Получается нужно показать ему заглушку, а ошибку записать в лог и завершить программу.
Ах, да. Ошибки и предупреждения нужно каким-то образом превращать в исключения.

Мой вариант решения это проблемы, что скажете?

Допустим у нас есть фронт-контроллер, который расположен в public/index.php

Объявляем обработчик ошибок set_error_handler, в нём превращаем предупреждения/ошибки в исключения.

Затем оборачиваем исполняемый код в try catch

try {
// Код выполняемого приложения
} catch (Throwable $e) {
// Запись в лог
// Загрузка страницы ошибки
}
Аноним 04/04/19 Чтв 06:48:42 1374757705
image.png (25Кб, 684x261)
684x261
image.png (22Кб, 731x138)
731x138
>>1353705 (OP)
Не могу разобраться с рутингом
хочу чтобы при нажатии на линк (пик 1) у меня открывалась форма поста в той же секции, где на линку нажали, а не в начале страницы
что для этого нужно сделать?
сама форма (пик 2)
вопрос скорее по верстке, но может кто подскажет
Аноним 04/04/19 Чтв 09:10:53 1374792706
>>1374466
>>1374704
Спасибо большое.
ток var_dump не отображает все равно.
Помогла функция htmlspecialchars();
нужна твоя помощь анон! chajnik-kun 04/04/19 Чтв 10:44:14 1374827707
image.png (90Кб, 236x346)
236x346

На основе прикрепленных данных (resultset.csv) которые можно скачать здесь : https://mega.nz/#!UsARmI7T!wBBsHHKtJVPRB6ontDHRpsX7QAVq_DTUh4pY4aQaoQ4
нужно, создать
соответствующую структура базы данных MySQL и импортировать данные в нее.
PHP скрипт должен выбрать 10 последних заголовков из базы данных
статьи, предполагая, что каждый заголовок должен исходить из разных
категорий (категории в списке из 10 названий не могут повторяться).
Полученные записи должны отображаться на странице в формате
"категория - название - дата".
Аноним 04/04/19 Чтв 11:12:07 1374844708
Аноним 04/04/19 Чтв 11:21:41 1374850709
>>1374364

Открой инструменты разработчика в браузере (Ctrl + Shift + I), вкладку "Сеть" и перезагрузи страницу. Посмотри, нет ли ошибок загрузки каких-то ресурсов. Если потребуется, почитай про инструменты разработчика.

>>1374792

Header в начале кода бы тоже помог. Ну хоть освоил функцию htmlspecialchars().

>>1374757

Если ты хочешь, чтобы форма появлялась на той же странице без перезагрузки, то тебе и нужна одна страница, а не две. Также нужен яваскрипт или продвинутый CSS (псевдоселектор :target либо невидимый input type="checkbox" ).

Например:

- можно сделать форму скрытой и открывать яваскриптом при нажатии на кнопку (а ссылку убрать)
- попробовать использовать тег HTML5 details, который делает примерно то, что нужно
- можно сделать в кнопке невидимый input type="checkbox" и показывать форму при галочке в нем. Примеры похожих штук, где что-то показывается/скрывается: https://webref.ru/layout/pseudo-class-checked/tabs https://habr.com/ru/post/174029/

Аноним 04/04/19 Чтв 12:11:51 1374884710
>>1374658
Я в курсе об этой команде, но неужели мне нужно будет это в каждый фаил подключать?
Аноним 04/04/19 Чтв 12:30:34 1374894711
Screenshot2019-[...].png (118Кб, 720x1280)
720x1280
Делаю задачки по гайду из ОП-поста, дошёл до работы со строками а ideone отказывается работать с mb_string (хотя в гайде написано что он установлен на ideone). Пробовал repl.it и phptester, нормально на моём ведре работает только ideone а возможности сесть за пк нет. Может есть какой-нибудь нормальный компилятор для ведра?
Аноним 04/04/19 Чтв 12:44:59 1374900712
Screenshot2019-[...].png (125Кб, 720x1280)
720x1280
Screenshot2019-[...].png (90Кб, 720x1280)
720x1280
Аноним 04/04/19 Чтв 15:46:47 1374966713
>>1374900
Спасибо добрый анон
Аноним 04/04/19 Чтв 15:51:05 1374967714
>>1374966
Правда на строки mb_string не проверял, ещё этому компилятору инет нужен.
Аноним 04/04/19 Чтв 17:27:41 1375002715
>>1374699
Ну, в общем, почти так и сделал.
phpdotenv и .env.example в git'е.
Аноним 04/04/19 Чтв 19:03:29 1375048716
image.png (9Кб, 577x121)
577x121
Аноним 04/04/19 Чтв 20:32:34 1375095717
>>1374280
Твое не отлавливает скобки и с таким подходом можно каждую цифру оборачивать в скобки и она пройдет
Аноним 04/04/19 Чтв 20:41:49 1375098718
Как запилить нечеткий поиск с ограничениями? Нужно найти (в sql) все записи, содержащие "строка" или отличающиеся от нее на <=N символов. Например, если N=4, при поиске "строка" должны находиться "строки", "стрАка" (1 <= 4), "срака" (2 <= 4) и "строковой" (4 <= 4), но не должны находиться, например, "строка-массив" (7 > 4) или "строка12345" (5 > 4). У LIKE есть процент, означающий 0, 1 или более символов - это все подстроки в строке, есть _ - это 1 символ, а как мою хуйню запилить, я даже хз.
Аноним 04/04/19 Чтв 20:50:02 1375100719
Аноним 04/04/19 Чтв 22:51:28 1375156720
Аноны, стоит ли перекатываться с Laravel на Symfony? Какие подводные камни?
Аноним 05/04/19 Птн 08:20:18 1375282721
>>1375156
Бамп вопросу. Все чаще симфони на слуху стал быть, да и yii опять чето мелькать начал.

Стоит ли вкатиться в эти фреймворки или лары достаточно и потратить силы на изучение чего-то другого?
Аноним 05/04/19 Птн 08:51:48 1375291722
Аноним 05/04/19 Птн 09:59:52 1375309723
>>1375291
Посдскажи, не могу понять (я другой анон). В твоем коде проверка символов идет так (после 7или 8) скобка, тире пробел затем цифра. А если человек дебил и скажем поставил скобку после последней цифры? Например так 8 (888)(8888888) теоретически это неправильно и должно отсеяться тк последняя скобка не проверяется. Добавив проверку на знаки после цифры можно обойти это. Может я просто переусложняю без дела? И второй момент, при поиске первых цифр можно написать так ^(\s7или\s8) хз как горизонтальную линию с телефона ставить. почему ты ищешь [ 7]* в таком виде?
Аноним 05/04/19 Птн 10:14:07 1375312724
Парни, посоветуйте как правильно делается подобное в symfony:
у каждого сайта есть какие-то элементы, общие для всех страниц - это, например, шапка и футер. Если данные для шапки и футера подтягиваются из базы логично сделать так, чтобы эти данные были доступны в любой шаблоне сразу или любом контроллере, чтобы дальше передать их в шаблон. Как этот сделать без дублирования кода в каждом из контроллеров? Нужно добавить эти данные как глобальную переменную? Или как-то инжектить в каждый контроллер?
Аноним 05/04/19 Птн 10:14:51 1375313725
>>1374702
>Изучи их и посмотри, нет ли там чего-то нужного.
Спасибо, анончик. Очень полезно! Справился с задачей.
Аноним 05/04/19 Птн 10:19:13 1375314726
>>1375048
Тут всё проще. Сначала надо выкинуть весь мусор - то есть всё, что не является цифрами
Потом проверить длину строки и если больше 11 то забраковать
Если 11, то проверить какая цифра первая - если не 7 или 8 то забраковать
Если 7 то поменять на 8
Аноним 05/04/19 Птн 10:32:39 1375318727
Аноним 05/04/19 Птн 11:36:11 1375341728
Аноним 05/04/19 Птн 12:08:11 1375354729
>>1375291
+ 7 (999-)--------- 12)(3 4567
Вот такой номер пройдет твою проверку
Аноним 05/04/19 Птн 12:16:47 1375357730
>>1375354
А почему не должен? 11 цифр есть. И если ввод никак не ограничивается на стороне клиента то может быть и такое - клавиша залипла, например, тачскрин заглючил.
Аноним 05/04/19 Птн 12:20:01 1375359731
Аноним 05/04/19 Птн 12:20:04 1375360732
>>1375357
Вот анон выше ситуацию так же расписал
>>1375309
Лучше искать ошибки с 2х сторон.
Аноним 05/04/19 Птн 12:26:01 1375364733
Аноним 05/04/19 Птн 12:44:28 1375374734
>>1372026
>$symbol2= mb_substr( $text, -$i-1,1);
Неплохо, я бы даже сказал элегантно. А я доп. переменную вводил сразу, не мог допереть как с конца нормально индексировать.
Аноним 05/04/19 Птн 14:12:07 1375414735
>>1371655
>2. Как мне сделать так, что бы если слово не было палиндромом ехо после цикла не выводилось?

Можно вызовом exit() сделать:

if($first!=$last){
echo "Not palindrom\n";
exit();
}

Аноним 05/04/19 Птн 14:49:24 1375433736
chajnik-kun 05/04/19 Птн 17:32:57 1375519737
аноны, подскажите где можно найти человека который бы писал небольшие php халтурки за небольшие деньги, и так что бы не кинули?
Аноним 05/04/19 Птн 17:36:17 1375521738
>>1375519
Пример такой халтурки приведи и назови цену.
chajnik-kun 05/04/19 Птн 17:38:36 1375525739

>>1375521
я писал уже выше вот >>1374827, цена не больше 1000р
Аноним 05/04/19 Птн 18:52:04 1375571740
Анончики, где ошибка, впервые сталкиваюсь с ошибкой 'break' not in the 'loop' or 'switch' context
https://ideone.com/WeE8Hi
Аноним 05/04/19 Птн 21:17:10 1375635741
1288238683622.jpg (29Кб, 470x324)
470x324
Может не в тот тред, но он вроде тут самый адекватный.

Вот веб-студия. Допустим, я пойду туда устраиваться. Попрошу 80к. Оформят наполовину в серую, итого для конторы я обойдусь в 100к в месяц. Допустим, я чистый фронтендер. За две недели могу слепить сайт из шаблона от дизайнера. Сам шаблон дизайнер будет рисовать те же условные 2 недели. и бек-энд будет делать отдельный человек за 2 недели. Плюс ПМ, он же менеджер по работе с клиентами, он же притаскивает новые заказы и тому подобное. Итого - 4 человека будут работать 2 недели ради одного сайта. Если каждый получит 100к (до налогов), то за 2 недели заказчику это всё обойдётся в 200к. Плюс пренда офиса, уборщица-бухгалтер-печенки-кофемашина. Плюс хоть какая-то прибыль для владельца. Итого, обычный сайт будет стоить от 300к рублей.

Я не понимаю этого. Неужели кто-то платит такие деньги? Или там берут количеством и дизайнер только слегка перерисовывает готовые шаблоны, фронт натягивает очередной шаблон на вордпресс, а бек пилит мелкие свистелки? По паре сайтов в день. С утра ты пилишь сайт-визитку на вордпрессе, после обеда магазин на опенкарте, назавтра нужно запустить три лендинга на шаблонах, так что ли?
Аноним 05/04/19 Птн 21:18:58 1375636742
Аноним 05/04/19 Птн 21:44:57 1375644743
>>1375635
Думаю если дизайн пилит дизайнер, фронтенд - фронтендер, а бэк - бэкэндер, то продук определённо годным будет.
Во-первых, это может быть шаблон на продажу.
Во-вторых, это может быть сайт для больших дядей.
В-третьих, это может быть тупа аутсорс на забугор.
В-четвёртых, есть разные системы и проекты, и это даже необязательно может быть обычный сайт - какая-нить система автоматизации и прочий софт с годным дизайном, фронтендом и бэком.
Ну и прочие фантазии.
Аноним 05/04/19 Птн 21:52:00 1375649744
>>1375636
Спасибо, поясни как это нормально сделать. Мы же проверяем функцией if, а если не соответствует прекращаем проверку на одном из этапов
Аноним 05/04/19 Птн 21:54:46 1375653745
И пожалуйста анончики, старайтесь новичкам вроде меня не давать решения, которые отходят от объема функционала из методички. Все таки с начала пусть и через жопу стараемся решить с чем есть, а потом уже в оптимизацию идти
Аноним 05/04/19 Птн 22:20:37 1375673746
Аноним 05/04/19 Птн 22:36:25 1375690747
>>1375635

Давай я тебя верну на землю. Вот, допустим есть веб-контора. В ней программисту платят 30-40 к в месяц, с налогами пусть это 60. В итоге 3 000 р расходов за рабочий день, который мы естественно удлиняем как можем. Менеджер тратит 4 часа своего времени на переговоры и обсуждения. Покупается готовый шаблон долларов за 20. Берется CMS и программист, пыхтя, за день натягивает на нее шаблон. Затраты ты можешь оценить. Там, правда, еще деньги нужны на рекламу.

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

Я помню, как-то у меня спрашивали, сколько стоит создание сайта, а потом сказали, что есть компания, которая делает сайт за 3000. А что, почему бы и нет.

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

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

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

Если тебя интересует, как живут именно студии верхнего сегмента, то читай описание проектов Студии Лебедева ( https://www.artlebedev.ru/everything/ ), они очень интересно все описывают, Советы у Бюро Горбунова ( https://bureau.ru/bb/soviet/ ) ну и можно посмотреть, сайты каких-то студий из топа ( http://www.ruward.ru/index-ruward/united-web-rating-2018/ ) - вдруг они что интересное выкладывают.

Я должен предупредить, работать в студиях нижнего сегмента не очень интересно и не очень легко. Перфекционист там вообще умрет в первый же день. Не стоит наверно туда особо стремиться.
Аноним 05/04/19 Птн 22:42:11 1375693748
>>1375312

Скопипащу ответ из старого поста: https://phpclub.tech/pr/res/1353705.html#1359951

Обычно делают отдельно шаблон для "лейаута" (шапка/подвал) и "контента". Лейаутов может быть несколько - например, один для морды, другой для админки. Как передавать параметры для лейаута? Тут есть варианты:

- руками копипастить их в каждый метод каждого контроллера (боль)
- наследовать контроллеры от базового класса и в нем формировать данные. У базового класса может быть метод вроде "поменять тайтл текущей страницы". Плюс - инкапсуляция, трудно передать что-то неправильное, например, не-строку.
- передать эти данные во вью до или после выполнения контроллера, без использования наследования. Или передать в контроллер.
- сделать "контроллер для лейаута" и в нем формировать данные для лейаута. У "контроллера лейаута" могут быть вспомогательные методы вроде "поменять тайтл текущей страницы".

В фреймворках готового решения нет. Каждый изобретает сам.

Добавлю, что стоит держать в уме, что лейаутов может быть несколько (сайт, админка) и у них могут быть разные наборы параметров. Идея Симфони с прописыванием глобальных переменных в конфиге мне не очень нравится, но какой-то хелпер так передать вполне допустимо.
Аноним 05/04/19 Птн 22:44:58 1375697749
>>1375525
Готов сделать за тыщу, куда писать?
Аноним 05/04/19 Птн 23:06:31 1375710750
>>1375693
Раз уж такая тема, то тоже спрошу:
вот у меня есть простой самописный фрейм, который роутит роуты, передаёт зависимости, имеет базовые Реквест и Респонс. Ну на коленке собираю для изучения темы.
Не могу решить как там представление реализовать. Есть вариант через класс Представления обрабатывать лайеры с шаблонами и контентом, и отдавать это всё строкой в Респонс несколько вычурно и нелепо получается, конструкция вида $Response->body = $View->reder(бла-бла-бла), или лучше вообще его не использовать и тупо выводить рендером в любом месте, правда мне не очень это по нраву - я хотел бы чтобы вывод был в одном месте, в конце приложения.
Есть какие-то намёки как это половчее сделать?
Аноним 05/04/19 Птн 23:09:36 1375713751
>>1375690
Спасибо за ссылки, посмотрю.

>Если у него высокие запросы - вполне возможно, что с него возьмут эти 200к или больше.
Но верхушка - это процентв 10-20 рынка, не более, так ведь? Почему тогда так дико популярны фреймворки? Сделать сайт на вордпрессе можно за вечер, покликав мышкой и не оскверняя мозги киким-то там пхп и жаба-скриптом вообще. Сделать то же самое на условном Ларавеле займёт гораздо больше времени даже у профи. Если ент спроса, то людей, работающих с фреймворками (а тем более с машин лёрн, биг дата, блок чейн, пит буль) должно быть мало. Однако, когда я открываю хх, то у вебов почти все вакансии обязывают знать хоть один фреймворк.
Аноним 05/04/19 Птн 23:33:24 1375719752
>>1375713
>Сделать сайт на вордпрессе можно за вечер
Так там нормальных интерактивных сайтов почти и нет - вукомерс, который всё равно кодить придётся, и лэндосы, которые суть - один жаваскрипт.
Аноним 06/04/19 Суб 00:12:51 1375731753
Аноним 06/04/19 Суб 01:15:31 1375757754
>>1375713

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

Ну банальный пример: в Laravel есть ORM на основе ActiveRecord, в Symfony - Data Mapper. Что насчет вордпресса? Там этого банально нет. Там даже миграций БД по моему нет. Нет тестов, нет нормального деплоя.

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

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

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

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

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

Значит, они решают задачу, которую средствами CMS не решить. Ты бы посмотрел, чем компания занимается, какие проекты делает.
Аноним 06/04/19 Суб 05:08:57 1375786755
Есть функция, которой передаешь время ("17:42"), а она возвращает ДейтТайм этого времени в ближайшем будущем? То есть если сегодня еще будет это время,то со сегодняшним числом, иначе с завтрашним?
Аноним 06/04/19 Суб 09:22:37 1375838756
>>1353705 (OP)
не могу в yii 2
не открывается даже стартовая страница-пример
хотя все требования на сервере есть
An Error occurred while handling another error:
exception 'yii\web\HeadersAlreadySentException' with message 'Headers already sent in
An Error occurred while handling another error:
exception 'yii\web\HeadersAlreadySentException' with message 'Headers already sent in
E:\openserv\OSPanel\domains\ex\config\web.php on line 1.' in E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\web\Response.php:366
Stack trace:
#0 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\web\Response.php(339): yii\web\Response->sendHeaders()
#1 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\web\ErrorHandler.php(135): yii\web\Response->send()
#2 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\ErrorHandler.php(111): yii\web\ErrorHandler->renderException(Object(yii\base\ErrorException))
#3 [internal function]: yii\base\ErrorHandler->handleException(Object(yii\base\ErrorException))
#4 {main}
Previous exception:
exception 'yii\base\ErrorException' with message 'session_start(): Cannot send session cookie - headers already sent by (output started at E:\openserv\OSPanel\domains\ex\config\web.php:1)' in E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\web\Session.php:137
Stack trace:
#0 [internal function]: yii\base\ErrorHandler->handleError(2, 'session_start()...', 'E:\\openserv\\OSP...', 137, Array)
#1 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\web\Session.php(137): session_start()
#2 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\web\Session.php(612): yii\web\Session->open()
#3 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\web\Session.php(751): yii\web\Session->get('__flash', Array)
#4 E:\openserv\OSPanel\domains\ex\widgets\Alert.php(53): yii\web\Session->getAllFlashes()
#5 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\Widget.php(140): app\widgets\Alert->run()
#6 E:\openserv\OSPanel\domains\ex\views\layouts\main.php(65): yii\base\Widget::widget()
#7 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\View.php(348): require('E:\\openserv\\OSP...')
#8 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\View.php(257): yii\base\View->renderPhpFile('E:\\openserv\\OSP...', Array)
#9 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\Controller.php(399): yii\base\View->renderFile('E:\\openserv\\OSP...', Array, Object(app\controllers\SiteController))
#10 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\Controller.php(385): yii\base\Controller->renderContent('<div class="sit...')
#11 E:\openserv\OSPanel\domains\ex\controllers\SiteController.php(64): yii\base\Controller->render('index')
#12 [internal function]: app\controllers\SiteController->actionIndex()
#13 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\InlineAction.php(57): call_user_func_array(Array, Array)
#14 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\Controller.php(157): yii\base\InlineAction->runWithParams(Array)
#15 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\Module.php(528): yii\base\Controller->runAction('', Array)
#16 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\web\Application.php(103): yii\base\Module->runAction('', Array)
#17 E:\openserv\OSPanel\domains\ex\vendor\yiisoft\yii2\base\Application.php(386): yii\web\Application->handleRequest(Object(yii\web\Request))
#18 E:\openserv\OSPanel\domains\ex\web\index.php(12): yii\base\Application->run()
#19 {main}
Аноним 06/04/19 Суб 10:27:23 1375846757
Хелпер относится к модели в MVC?

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

Что правильнее?

class Controller
{
function indexAction()
{
if (AuthHelper::isAuthenticated()) {
$this->view->render('шаблон1');
} else {
$this->view->render('шаблон2');
}
}
}

Или

class Controller
{
function indexAction()
{
if (AuthHelper::isAuthenticated($_COOKIE['student'])) {
$this->view->render('шаблон1');
} else {
$this->view->render('шаблон2');
}
}
}
Аноним 06/04/19 Суб 12:11:11 1375887758
gnK6EijW9Ix-eyB[...].jpg (76Кб, 768x768)
768x768
Сап двач, я только что придумал типизированные коллекции в пыхе
https://ideone.com/t2sO1Y
Аноним 06/04/19 Суб 13:29:17 1375933759
Аноним 06/04/19 Суб 13:47:12 1375943760
Аноним 06/04/19 Суб 13:56:42 1375948761
Аноним 06/04/19 Суб 17:14:19 1376037762
Вскоре после того, как я освоил тесты, и прочитал фразу "Если вы хотите что-то напечатать методом print_r(), var_dump() и типа того - напишите вместо этого тест".
Я подумал: "Бля, а внатуре".
Теперь, когда надо проверить какую-то хуйню, тупо ебашу тест, там вывожу и заодно делаю какую-нибудь проверку побыстроляну.
Итого, я проверил что хотел - и у меня лишний ствол тест появился.

Это и называется test-driven development
Аноним 06/04/19 Суб 17:17:02 1376041763
>>1375887
Распаковка аргументов штука прикольная, можно задавать массив объектов последним параметром.
Но только 1 раз за метод и только последним.

Возвращаемого тайпхинта массива объектов в пыхе нет.
Кстати, я тот самый чел, что 2 треда рассирался про дженерики в пыхе и как их можно сделать.
В одном проекте даже реализовал.
Но понял, что это потребляет больше времени, чем экономит.

Теперь тупо делаю это через phpdoc.
Автокомпликт работает, это самое главное.
Ну а то, что фактической проверки типа возвращаемых значений и аргументов нет - ну что же, приходится забить на это хуй в угоду быстроте разработки.
Аноним 06/04/19 Суб 17:34:42 1376047764
>>1376037
>Это и называется test-driven development
Блять, вообще это был вопрос.
Это и называется test-driven development?
Аноним 06/04/19 Суб 17:50:03 1376054765
>>1376047
Как говорил мой дед: "Сначала пишешь тест, потом пишешь код, пока он не пройдет твой тест" Но меня такой подход ебет, потому что я почти всегда не знаю что хочу, и пишу сразу тесты для контроллера, типа при таких то параметрах вернуть то и то, а при таких ошибку высрать.
Аноним 06/04/19 Суб 23:06:01 1376290766
Аноны, может поймет кто, что у меня не так?


$regexp = '/\s{2,}/u';
$text = preg_replace($regexp, '',$text);
$regepx = '/([.?!;:,])(.)/ui';
$text = preg_replace($regexp, '$1 $2',$text);
return $text;

Первая регулярка проходит, вторая - нет. Ощущение что я ее не правильно написал, но тут все ок.https://regex101.com/r/H2Cwq3/1
Аноним 06/04/19 Суб 23:59:26 1376334767
>>1376290
разобрался, я просто дебил слепой
Аноним 07/04/19 Вск 00:49:53 1376366768
Сделал тестовое задание, но реакцию конторы узнать не получилось.
Задача:
>Сделать RESTful API телефонного справочника c использованием фреймворка Laravel.
https://github.com/tsubaku/phonebook

Если у кого-то есть свободное время, может посмотрите? Что там плохо?
Аноним 07/04/19 Вск 01:43:03 1376399769
>>1376366
Разрешите доебаться. В названии грится RESTful, а у тебя аутентификация походу через куки и сессии, и вообще не понятно нужно ли для этого задания использовать что-то другое. Можно через гварды указывать для каких методов нужна авторизация и получается что не особо много смысла иметь два Number контроллера в разных неймспейсах (это было бы не так важно если бы ты руты замапил без перфикса admin, ну это уже холиварная тема сама по себе). Для джсон ответов кстати очень удобно юзать ларавельские Resources. Контроллер search в неймспейса Ajax опять же не особо нужен, не проще в Number@index ( / url) добавить возможность фильтровать по запросу, например /?name=123&number=456 и возвращать отфильтрованные звонки. Еще не совсем понятно зачем сортировать в пхп а не в бд, и вообще про методы all() лучше забыть.
Из такого тестового хз какой вывод можно сделать, там и задания то внятного не было с требованиями, просто ЗДЕЛОЙТЕ, ну ты и сделал
Аноним 07/04/19 Вск 02:40:25 1376421770
Аноны, я помню, в этом или предыдущем треде шла речь про тестирование приложений с БД, и я дал совет для тестов сделать раздел tmpfs и хранить таблицы БД на нем, но не смог пояснить, как именно это делать. Так вышло, что я случайно наткнулся на интересную информацию в документации Postgres и вспомнил про этот вопрос.

В Postgresql есть "табличные пространства": https://postgrespro.ru/docs/postgresql/11/manage-ag-tablespaces (русс.)

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

- делаем раздел tmpfs, например, в /var/test-database/, даем на него права пользователю postgres. Чтобы он монтировался при старте системы, пишем его в /etc/fstab, если он будет пустой, то память все равно не тратит.
- даем пользователю postgres, под которым гоняются тесты, права создавать табличные пространства
- создаем в postgres табличное пространство в этой папке
- создаем в postgres новую БД под тесты и указываем ей это табличное пространство (CREATE DATABASE ... TABLESPACE = ...)
- очищаем тестовую БД, загружаем в неё дамп
- прогоняем тесты
- дропаем тестовую БД
Задача по webpaint Аноним 07/04/19 Вск 02:44:06 1376424771
>>1361773

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

> Можно ли сделать плавный переход по якорям без JS?

В новых браузерах, как пишет анон, есть scroll-behaviour.

> Можно ли задать плавное всплывание картинок по нажатию на какую-либо из кнопок?

Изучи CSS-переходы (transition) и анимации, и посмотри, есть ли что-то подходящее. Тут трюк в том, что смена некоторых свойств отключает переход или анимацию. Например, смена display с block на hidden. И приходится скрывать элементы каким-то другим способом.

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

В принципе, можно.

> Подписи к заголовкам обрамлять в <h> на пункт меньше или <p>?

Если ты про Consectetur, Tritiquet - то там наверно <p>. Если ты про "We are webpaint", то можно сделать h2 или div. <p> - это абзац текста, тут явно не абзац текста.

> Почему "margin: 0;" в body не работал и мне приходилось подписывать его к каждому элементу?

Если ты про поля по краям окна, то они могут быть заданы не на body, а на html, и не в виде маргина, а в виде паддинга. Стандарта тут нет. Потому надо обнулять и маргин, и паддинг на обоих элементах.

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

Кнопки соцсетей должны реагировать на наведение, например, бледнеть, становиться ярче, еще как-то меняться, ты можешь поискать готовые CSS эффекты. Также, картинки на кнопках очень плохого качества: https://imgur.com/a/WuWquKP в FF66

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

Скорее всего ты потерял полупрозрачность. Там иконки полупрозрачные, то есть там есть частично прозрачные пиксели с альфа-каналом. У тебя же альфа-канала в картинке нет и из-за этого иконки стали с угловатыми краями, а не плавными. Почитай про формат PNG, полупрозрачность и альфа-канал.

Для адреса и телефона надо использовать иконки из файла, а не посторонние.

Адаптивность под разные разрешения экрана сделана слабо, для галочки. Вот косяки:

- если мы уменьшаем ширину окна, то надпись "digital & branding agency based ..." криво переносится - она разбивается на 3 строчки разной ширины. Это из-за наличия там br, который надо либо отключать, либо заменить на что-то получше.
- на ширине 700 px меню упирается в правый край окна без отступов, а надпись ниже We Are Webpaint смотрится непропорционально большой. Я бы уменьшил шрифт заголовков до 44 px / 30 px на такой ширине, слегка убавил бы вертикальные паддинги в шапке. Попробуй сам на глаз подобрать размеры, чтобы надписи были бы не слишком большие, и не слишком маленькие, а в самый раз, и чтобы шапка смотрелась пропорционально.
- на ширине в 700px блоки Consectetur, Tristiquet разваливаются и выглядят криво
- на ширине в 540 px меню проваливается вниз
- на ширине 430 px надпись digital & branding agency упирается в края окна, что некрасиво. Вертикальное меню, наверно, тоже не самое удачное решение тут. Лучше наверно сделать его в 2 колонки и сделать расстояние между пунктами больше, чтобы пальцем не промазать. Также, можно сделать кнопку "меню" и спрятать меню за ней, хотя это снижает discoverability пунктов в нем - пользователь о них не узнает.
- на маленькой ширине блок Consectetur лучше было бы выстроить вертикально, в 1 колонку, вынеся картинку влево или убрав ее вообще.
- на маленькой ширине картинки в портфолио очень мелкие. Удобно ли их разглядывать? Хотя, мне нравится компактность и возможность их всех увидеть на одном экране
- На маленькой ширине иконка перед адресом вываливается на отдельную строку
- на маленькой ширине иконки соцсетей и телефон слишком близко и пальцем можно нажать не туда. Нужно предусмотреть отступ от телефона до иконок, сам телефон, кстати можно сделать крупнее. Я для эксперимента поставил ему размер 24px, отступы по 20px, выглядит не так и плохо.

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

По коду. Иконки принято делать не img, а фоновыми картинками. img используется для картинках в контенте - статьях, например. Тут img подходит для картинок портфолио, может быть для блока Consectetur, но не для остальных мест.

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

> title__of__service

Так длинно, пишут просто service-title. Плюс, тут этот класс вообще не нужен, так как ты можешь использовать стиль .service h3

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

Вместо i.font__light проще было бы выделить жирную часть просто тегом strong.

> .service{
> display: inline-block;

Стоит тут указывать vertical-align.

Когда ты используешь transition, стоит явно перечислять анимируемые свойства, чтобы не анимировалось ничего лишнего.

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

- https://developer.microsoft.com/en-us/microsoft-edge/tools/screenshots/ для IE (Не отображает сайты с jsbin)
- http://browsershots.org/https://jsbin.com/pofasoviqa/1/edit?output для FF/Chrome (плохо отображают сайты на jsbin)
- есть еще browserstack, он они хотят регистрацию, деньги и тд

Также, если что, для FF/Chromium можно найти портабельные версии, которые можно себе установить. С ИЕ так не получится и ради него придется делать виртуалки (по одной на каждую версию - спасибо Майкрософт). Хотя для этой задачи хватит и скриншотов, но для более серьезной работы удобнее иметь сами браузеры.

Я бы советовал поделить браузеры на 2 категории: новые и не-новые. В новых браузерах макет соответствует дизайну. В не-новых - может отступать от дизайна, если там нет нужной фичи, но оставаться читабельным. Например, если в браузере нет скругления уголков, то в таком браузере можно их сделать квадратными. ИЕ ниже 8 поддерживать не требуется, как и браузеры старше 10 лет.

Картинки в портфолио сделаны в PNG. Посмотри, можно ли их сжать в JPEG без заметных артефактов, чтобы получить меньший объем? Это умеет делать даже бесплатный GIMP.

Задавай вопросы, если что-то непонятно.
Аноним 07/04/19 Вск 03:44:02 1376434772
>>1376037

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

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

У тебя же другой подход: ты подгоняешь тесты под то, что вернет код. Значит, это скорее всего не очень хорошие тесты. Возможно, например, при твоем подходе у тебя в тестах захардкожены какие-нибудь массивы, которые возвращает функция, вместо проверки требований к ней.

Не забывай, что тесты проверяют именно выполнение требований.

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

>>1376041

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

> Но понял, что это потребляет больше времени, чем экономит.

Получил ценный опыт.

Аноним 07/04/19 Вск 03:45:10 1376435773
>>1372521
>>1375943

>> Он представляет ответ на HTTP-запрос. В Симфони контроллер получает на вход Request и выдает на выходе Response, а фреймворк уже выводит его содержимое. Это удобно для тестирования, мы можем вызвать контроллер и смотреть, что он там сгенерировал.

> Этот объект нужен для того, чтобы содержать в себе html-код? При тестировании каким-то образом проверяется его содержимое (html)? Не могу понять.

Да, содержит. И упрощает тестирование не только этим. В чистом PHP у программы нет явно определенных входных и выходных данных. Данные запроса она берет из глобальных переменных, а результат выводит куда-то наружу через echo. И это неудобно и при разработке, и при тестировании. Вот, допустим, мы хотим написать функцию, которая что-то определяет по входным данным. Как описать, что ей нужны эти данные? Тут-то нам и поможет реквест:

function getPageName(Request $req): string {}

Теперь явно видно, что использует функция. И это удобно при тестах, мы просто создаем временный объект Request, передаем ей, и это никак не влияет на остальной код. А если бы мы использовали глобальные переменные вроде $_GET, то не было бы видно, что функция зависит от входных данных, а при тесте изменения в $_GET либо пришлось бы как-то откатывать, либо бы наш тест мог бы повлиять на другие. Разве это удобно?

Наконец, в случае с объектом Request мы можем вызвать функцию на несуществующих данных. Если мы хотим проверить, "в случае, если пользователь пришлет такой запрос, что вернет функция?" - мы просто создаем временный объект Request, и вызвыаем функцию, а что делать при использовании глобальных переменных? Придется городить костыли.

Что касается Response, то он позволяет нам решать, что делать с ответом. В чистом PHP код отдает заголовки через header, отдает контент через echo и мы не можем их перехватить и что-то с ними сделать. В случае с Response, нам возвращают Response и мы с ним делаем, что хотим. То есть теперь мы решаем, что делать с ответом. Это полезно в тестах, и не только.

Например, мы хотим сделать автоматическое шифрование кук - при отдаче шифруем, при получении расшифровываем. В случае с Request/Response мы это можем сделать, не меняя сам код приложения. Просто пишем функцию, которая принимает на вход Response с открытыми куками и возвращает Response с зашифрованными (и тестировать такую функцию несложно). А вот если приложение использует глобальные переменные и отдает куки через setcookie, то сделать это сложно - без костылей вроде runkit вызов функции не перехватить.

Наконец рассмотрим еще один пример. Допустим, мы используем какую-то другую модель сервера, когда PHP код не умирает, а обрабатывает много запросов в цикле. Естественно, для отдачи контента там будут другие функции, и без объекта Response код, использующий Header/echo, с такой моделью работать не будет. В случае наличия объекта код трогать не придется.

То есть разговор о Request/Response похож на разговор про недостатки глобальных переменных. Плюсы:

- мы контролируем входные/выходные данные для кода и решаем, что с ними делать. Можем как-то их модифицировать, подменять итд.
- мы явно описываем, что код получает на вход и дает на выходе
- мы не получаем проблем, типичных для глобальных переменных

Ну и как дополнительный плюс, у объекта Request/Response могут быть какие-то дополнительные возможности, например, готовый метод для установки имени скачиваемого файла, или срока кеширования, чтобы нам не надо было вспоминать, какие заголовки за это отвечают.

> В каком месте выводить полученный результат?
> Достаточно написать во фронт-контроллере echo $response->getBody(); ?

Достаточно. Но только там не только тело, но и еще код ответа и HTTP-заголовки. В симфони у респонса есть метод send(), который все это отправляет в браузер.
Аноним 07/04/19 Вск 03:45:50 1376436774
>>1375673

break можно использовать только в определенных случаях, в циклах, например. В твоем случае хватит просто if/else. exit не требуется. Повтори, как работает if, и напиши так:

if (номер соответствует выражению) {
делать что-то одно;
} else {
делать что-то другое;
}

if/else можно вкладывать друг в друга. Не забывай про отступы и форматирование.

Твой код пока что неверный, так как он признает верным телефон из 11 букв.

> ^[7]

Скобки около семерки тут не требуются.

Регулярку стоит писать примерно так:

- в начале +7 или 8
- затем 11 раз повторяется конструкция: (одна цифра и любое число дополнительных скобок, минусов, пробелов)
- затем конец строки

>>1375846

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

Вообще, код не обязан строго относиться к M, V или C. MVC - это ключевые компоненты, которые участвуют в обработке запроса. Ну и MVC вообще был придуман для долгоживущих десктопных приложений с окошечками и кнопочками, и главной идеей было отделение кода UI от модели (так как до этого их могли смешивать). К веб-приложениям он немного притянут за уши, скажем так.

Ну например, крон-скрипт - это что? По расположению похож на контроллер. А почему он с пользователем не взаимодействует? А где его View?

> Можно ли из хелпера обращаться к глобальным переменным?

Обращаться к глобальным переменным плохо почти всегда, так что не стоит. Лучше, когда функция получает аргументы явно. А так, получается скрытая недокументированная зависимость: если ты не задал какую-то глобальную переменную, то функция не будет работать. Как об этом догадаться? Это не очевидно. А если функция меняет глобальную переменную, то это называется "побочный эффект".

В твоем случае, идеально, было бы, например, так:

$this->authHelper = new AuthHelper($request, $userDb);

...

if ($this->authHelper->isAuthorized()) ...

Или так (объект можно использовть многократно):

$this->authHelper = new AuthHelper($userDb);

...

if ($this->authHelper->isAuthorized($request))

Тут мы явно видим, от чего зависит класс. Но если у тебя нет класса Request, то можно работу с кукой сделать в хелпере, но оговориться, что с этой кукой никто больше не имеет право работать для соблюдения принципа единой ответственности.
Аноним 07/04/19 Вск 03:46:24 1376437775
>>1375838

Проверь, нет ли в твоих файлах символа BOM. Если есть, сохраняй в utf-8 без BOM.

>>1375786

Придется наверно писать руками. Можно попробовать new DateTime("tomorrow 12:00");

>>1375710

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

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

>>1375354

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

someApprentice !EaaiHmIJms 07/04/19 Вск 05:59:11 1376448776
>>1376421
Спасибо за предоставленный приём. Тесты на JS (а точнее на TypeScript) действительно проходят медленно, и иногда даже без асинхронных операций проверка запуска теста с единственной строчкой expect(true).toBeTrue() выдавал ошибку таймаута (???) или выполнялся спустя секунд 15. Представляю как серверная обработка запросов будет проходить так же медленно.

Всё больше убеждаюсь, что серверная часть должна быть написана на предназначенных для этого языках, например PHP. Передаю этот ценный опыт всем анонам и хочу чтобы они оценили преимущество этого языка в том, что он как раз предназначен для веб-технологий.
Аноним 07/04/19 Вск 07:20:54 1376454777
image.png (17Кб, 563x213)
563x213
image.png (137Кб, 1439x533)
1439x533
>>1376437
>Проверь, нет ли в твоих файлах символа BOM. Если есть, сохраняй в utf-8 без BOM.
да каждый файл проверил в нотпаде, там кодировка без бом
тем более это дефолтная страница от yii, все должно работать
может я просто с настройками (пик1) где-то проебался или ещё что-то
хотя тот же codeigniter у меня нормально работал
Аноним 07/04/19 Вск 09:52:59 1376515778
>>1376041
> Ну а то, что фактической проверки типа возвращаемых значений и аргументов нет - ну что же, приходится забить на это хуй в угоду быстроте разработки.

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

class UserCollection {
addUser(user: User) {}
removeUser(user: User) {}
}

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

2) Использовать статические анализаторы вроде PHPStan/Psalm. До языка TypeScript им, конечно же, далеко, но базовые потребности покрывают неплохо. Мы внедряли PHPStan с самым щадящим режимом (level 0) в CI, постепенно повышая уровень строгости, польза есть. Python, кстати, пошёл именно по этому пути, там типы в рантайме не проверяются: https://docs.python.org/3/library/typing.html

>>1375887
Это костыльно (работает только если аргумент последний) и влияет на перформанс. Лучше попробуй статические анализаторы.
Аноним 07/04/19 Вск 15:30:56 1376734779
>>1376435
>>1376436
Буду обдумывать, спасибо за развёрнутые ответы.
Аноним 07/04/19 Вск 16:31:54 1376763780
пишу пет проект на симфони, получается пока хорошо. с этим возьмут на работу? хД
Аноним 07/04/19 Вск 17:41:34 1376795781
Calculator.png (57Кб, 1519x962)
1519x962
Сап двач.
Дошел до задачи с калькулятором, не могу понять, как выполнить операцию из переменной $op над $result и $number
Аноним 07/04/19 Вск 18:04:36 1376807782
>>1376436
>- затем 11 раз повторяется конструкция: (одна цифра и любое число дополнительных скобок, минусов, пробелов)
Ебните меня хуем по лбу. Почему я до этого не допер. Никак не привыкну разбивать целое к частным.
Аноним 07/04/19 Вск 18:19:51 1376815783
>>1376436
>- в начале +7 или 8
>- затем 11 раз повторяется конструкция: (одна цифра и любое число дополнительных скобок, минусов, пробелов)
>- затем конец строки
Я над этим покумекал, а не будет ли выгоднее убрать плюс, но при этом оставить 11 цифр ( тут ошибку понял). А потом сделать проверку 7 или 8
Аноним 07/04/19 Вск 19:08:15 1376833784
>>1376399
>В названии грится RESTful, а у тебя аутентификация походу через куки и сессии
Делал через стандартную ларавелевскую. Думаешь, они имели в виду перепилить её на рестфулл? Возможно и так, но я не сообразил.
>Контроллер search в неймспейса Ajax опять же не особо нужен, не проще в Number@index ( / url) добавить возможность фильтровать по запросу, например /?name=123&number=456 и возвращать отфильтрованные звонки.
Аякс же. Там в дополнительных требованиях было обеспечить работу поиска без перезагрузки страницы (а ещё про то, что хорошо бы вообще весь фронт написать на реакте/ангуляре, но поскольку я в них не умею, то просто убрал лишнее из описания).
>Еще не совсем понятно зачем сортировать в пхп а не в бд, и вообще про методы all() лучше забыть.
Да, пожалуй. Надо будет мне переписать запросы.

Спасибо за ревью!
Аноним 07/04/19 Вск 20:38:37 1376865785
Аноним 07/04/19 Вск 20:55:31 1376879786
Аноны, можно ли сделать так? Я просто не уверен почему у меня это не работает. Может так вообще не выйдет, а я сижу и туплю. Функция же строку возвращает, так что должно работать. В итоге вопрос состоит в том, могу ли я использовать $0,$1,$2 в данной ситуации?
$text = preg_replace($regexp,mb_strtoupper('$0'),$text);
Аноним 07/04/19 Вск 21:14:46 1376892787
>>1376879

Ты сначала применяешь к строке '$0' функцию mb_strtoupper (от этого она не меняется), а потом передаешь результат в preg_replace.

Для твоей задачи нужна функция preg_replace_callback().
Аноним 07/04/19 Вск 21:32:31 1376912788
>>1376833
>Аякс же. Там в дополнительных требованиях было обеспечить работу поиска без перезагрузки страницы (а ещё про то, что хорошо бы вообще весь фронт написать на реакте/ангуляре, но поскольку я в них не умею, то просто убрал лишнее из описания).

Эти два метода делают одно и тоже, только формат ответа разный. Можно явно передавать ключ format=json/html где html будет дефолтным или смотреть например по Accept заголовку но я так не делал никогда и хз.
Аноним 07/04/19 Вск 21:35:32 1376913789
>>1376912
>Эти два метода делают одно и тоже, только формат ответа разный.
А и верно. Надо будет попробовать сделать поиск тем же контроллером, что и выдачу.
Аноним 07/04/19 Вск 21:52:46 1376921790
>>1376892
>Ты сначала применяешь к строке '$0'
Т.е я применяю функцию не к найденному тексту, а конкретно заданной строке '$0'? Соответственно возвращается это же строка, и только потом она считывается как "найденный по регулярке текст", и в итоге ничего не меняется.
Правильно ли я понимаю что preg_replace_callback принимает в себя только функции, а preg_replace функции не принимает?

С первого раза, кстати, вышло. Спасибо большое
http://sandbox.onlinephpfunctions.com/code/acc29ae465e387db405a8aacfcf5a583138c2c37
Аноним 08/04/19 Пнд 01:23:11 1377027791
>>1353705 (OP)
Ну кто делает треды с более 500-ми постов?
Тред сдох а весь браузер висит, а процессор в ноутбуке свестит и пердит.
А что если я прогружают с тилибона, где каждый килобайт трафика бабло насчитывает?

Зашёл ещё, как-то в arduino тред в /ra - так там вообще больше 1000 постов, ещё и с картинками, блядь.
Обычно на треды 500 постов до бамплимита, и перекат,
либо же - бесконечные треды с лимитом в 500 постов, в которых старые посты - обрезаются...

Пилите перекот!
Аноним 08/04/19 Пнд 01:25:24 1377028792
>>1377027

Погоди еще 2-3 дня. Сейчас разберемся с анончиками, которые писали свои вопросы, и сделаем перекат. Про тормоза я знаю.
Аноним 08/04/19 Пнд 08:40:28 1377061793
Последний пых - пиздат, но пиздат потомучто почучуть становится джавой.

В связи с этим вопрос: зачем нужен язык, который становится джавой, когда есть джава?
Аноним 08/04/19 Пнд 08:52:07 1377063794
Какой редактор / IDE посоветуешь, анон? Я нью, планирую вкатываться. Хочу нормальную подсветку синтаксиса, автокомплит и прочее.
Аноним 08/04/19 Пнд 11:10:52 1377106795
>>1377063
Для начала идеон, нопомни эта сука не может в кириллицу.
Аноним 08/04/19 Пнд 11:48:30 1377115796
Аноним 08/04/19 Пнд 12:13:50 1377123797
>>1377061
Потому, что он заточен под свою задачу. ЯП, который и швец и жнец и в жопе холодец - не очень обычно получается.
Аноним 08/04/19 Пнд 19:40:25 1377297798
v.jpg (67Кб, 667x960)
667x960
Я знаю основы программирования, как можно заработать на этом говне хотябы 150$ хикану?
Аноним 08/04/19 Пнд 23:41:51 1377423799
image.png (81Кб, 902x637)
902x637
https://ideone.com/A4UKZi
Задачка по регулярке, на проверку текста на ошибки с последующим их исправлением. Я текст разбил на массив и каждый элемент проверяю отдельно. Вот не знаю как сделать так, чтобы значение в условии if (это $result=", {$result}";) сохранилось для значения в массиве $results.
Аноним 09/04/19 Втр 00:10:18 1377438800
Аноним 09/04/19 Втр 00:46:48 1377455801
>>1377423

Ох, раза 3 перечитал, пока понял. Ты хочешь исправить все ошибки в словах и сделать текст со всеми исправлениями? Тогда лучше всего просто создать новый, пустой массив слов. На каждом шаге цикла класть в него либо исходное, либо исправленное слово. После окончания цикла собрать массив в строку с помощью implode(). Учти, что там могут быть сложности с пробелами между словами:

Были слова в массиве: да|но|это|не|точно
Стали после исправления: да|, но|это|не|точно

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

Тут можно добавлять запятую в другое слово:

да,|но|это|не|точно

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

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

И стоит называть переменные лучше. Не results, а, например, foreach ($words as $word).
Аноним 09/04/19 Втр 00:58:28 1377463802
>>1377455
>На каждом шаге цикла класть в него либо исходное, либо исправленное слово.
У меня на картинке есть массив, Там каждый индекс (ключ) из массива с его значением проверяется на регулярку и потом изменяется в условии if. По сути программа считает переменную $result внутри if (preg_match($regex3, $result)) как временную переменную. И я не понимаю, как изменения в $result передать для значения в массиве, чтобы он часть текста с ошибкой заменил на уже исправленный.
Аноним 09/04/19 Втр 01:22:50 1377472803
>>1377463

Во-первых, result - это не ключ, а значение элемента массива.

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

foreach ($words as $key => $word) {
$words[$key] = "hello, $word";
}

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

Аноним 09/04/19 Втр 05:09:30 1377517804
threecolumns.png (46Кб, 1309x605)
1309x605
>>1374075
Решил при помощи таблицы. Пикрил.
Аноним 09/04/19 Втр 09:43:33 1377564805
>>1353705 (OP)
Господа, я тупой или не очень?
Для одного проекта мне надо поставить db* из pear

Pear мне говорит, что db депрекейтед в пользу mdb2

При этом, 1.9.3 (stable) released on 2018-12-05
https://pear.php.net/package/DB/download/

а mdb2: Status: 2.5.0b5 (beta) released on 2012-10-29
Аноним 09/04/19 Втр 10:57:54 1377593806
>>1376454
пофиксил господи наконец-то
не юзайте говно мамонта типа пхп <7 как бы вам удобно это не казалось
Аноним 09/04/19 Втр 13:23:43 1377697807
>>1353705 (OP)
Вопрос по организации архитектуры сайта.
Например я сделаю личный бложек (с помощью фреймворка или велосипеда). И тут понадобится расширить сайт чем-то массивным, например прирутить форум. Как поступить в этом случае? Делать форум на фундаменте текущего блога (то есть писать код прямо рядом с php-классами блога) или создавать отдельный 'репозиторий', в который перенаправлять запросы через index.php? А если я хочу сделать общую авторизацию то как быть?
Переменная в http Аноним 09/04/19 Втр 14:00:08 1377722808
Нужно вставить переменную со случайным значением в http-запрос, но с выделением переменная не читается. Например:

$foo = 'n';
$request = '/bar/$foo/more';
Аноним 09/04/19 Втр 14:16:43 1377733809
>>1377722
Разобрался. Нужно юзать двойные кавычки.
someApprentice !EaaiHmIJms 09/04/19 Втр 14:27:15 1377739810
>>1372258
tl;dr

Проблема решена

>>if (details is None) or (not 'Bearer token' in details['authextra']):
>>builtins.TypeError: argument of type 'NoneType' is not iterable
>
>И, во втором случае,
>
>>if (details is None) :
>> principal[u'extra'] = {
>> u'error': u"Access denied: No Bearer token in authexta"
>> }
>> return principal
>>
>>
>> token = details['authextra']['Bearer token'];
>
>return не выполняется и код продолжает выполнятся
>
>>token = details['authextra']['Bearer token'];
>>builtins.TypeError: 'NoneType' object is not subscriptable
Здесь нет проверки на существование свойства authextra.

>> try:
>> payload = jwt.decode(token, JWT_SECRET)
>> except Exception as e:
>> principal[u'extra'] = {
>> u'error': e
>> }
>> return principal
>>
>> ...
>
>return снова не выполняется и вбрасывается ошибка: "WAMP message serialization error: Object of type 'InvalidSignatureError' is not JSON serializable"
>https://pyjwt.readthedocs.io/en/latest/api.html#jwt.exceptions.InvalidSignatureError
Питон сам по себе не сериализирует исключение в строку.


Решено в связи с https://forum.crossbar.io/t/python-code-does-not-work-as-expected/1495

Аноним 09/04/19 Втр 14:32:53 1377741811
>>1377697
>Делать форум на фундаменте текущего блога (то есть писать код прямо рядом с php-классами блога)
Конечно так. Тебе нужно чтобы у тебя были отдельно файлы например blog.php и forum.php. Почитай ещё про архитектуру MVC, станет очень много понятно.

https://github.com/codedokode/pasta/blob/master/arch/mvc.md
Аноним 09/04/19 Втр 17:41:32 1377837812
photo2019-04-01[...].jpg (25Кб, 400x225)
400x225
Хотелось спросить бы, ОП-кун, в частности. Я когда-то вкатился в PHP с твоих тредов, порешал все задачки, подтянул верстку и нашел работу. С тех пор прошло 3 года, я стал крепким мидлом, успел поработать в старапе с Y Combinator, собеседования для меня теперь не страшны и найти работу я легко могу почти в любом селе.

Чего мне читать, и как стать все-таки сеньером помидором? Если что js я почти не трогаю, текущий фреймворк Symfony 4. Комьюнити PHP в моем городе почти не существует, судьба забросила, увы.
Аноним 09/04/19 Втр 19:40:04 1377901813
>>1377837
Анонче, а в сколько годков вкатился?
Аноним 09/04/19 Втр 20:40:46 1377929814
Анончик помогающий с регулярками, глянь, где я не прав. https://ideone.com/S53UAG Решение я обосновал так, с начала я выкидываю к хуям все кроме цифр. Теперь нам не принципиально что в начале, затем проверяем число знаков и наконец проверяем что в начале 7 или 8, потом сразу же меняем 7 на 8мь. Я не могу понять почему на этапе проверки первых цифр происходит ошибка.
Аноним 09/04/19 Втр 22:18:46 1377979815
>>1353705 (OP)
Ох уж эта ебля с настройками, не могу направлять запросы через ФронтКонтроллер. Если на прямую к нему обращаться, то создает роутер и выполняет функцию из класса роутера. Чего я только не делал. И закидывал в стандартный путь, и новый адресс делал, и разные htaccess создавал, и переустанавливал ос. Уже не понимаю куда смотреть.
php7.2 Апач2.4 на виртуалке ubuntu 18.04.
Это в .htaccess:
"AddDefaultCharset utf-8

RewriteEngine on
RewriteBase /
RewriteRUle ^(.*)$ index.php"
Аноним 10/04/19 Срд 02:12:45 1378083816
>>1377929
Я не анончик проверяющий регулярки, сам только начал. Но кое-чем подсобить могу. С ideone лучше перекатывайся, у меня там тоже много чего не работало.
http://sandbox.onlinephpfunctions.com/code/134052c9924b5d9c6751b620f4774cb5533fec30
Вот, скрипт выполняется, но он все равно не правильный. Как минимум из за этой регулярки '/\D/' в 4 строке. Тебе же по заданию нужно сначала проверить верный ли номер. Если я напишу "+7892()326 ()-()2_032 сап Двач", то все кроме чисел выкинется, "+" тоже выкинется, а по заданию нам нужна проверка стоит ли там +7 или 8 (+8 и 7 - номер неверный) и т.д
Еще не забывай при выводе переменной, если сразу за ней идет текст заключать ее в {}.
Аноним 10/04/19 Срд 08:24:17 1378163817
>>1377979
Попробуй сделать так

RewriteEngine On
RewriteRule ^(.*)$ index.php

Если получится, желательно ещё отключить переадресацию для публичных файлов.
Аноним 10/04/19 Срд 08:37:31 1378169818
>>1377979

А в чем проблема? В том, что не вызывается index.php?

Для начала проверь, включено ли в конфиге Апача выполнение htaccess:

- https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride
- https://www.linode.com/docs/web-servers/apache/how-to-set-up-htaccess-on-apache/

Не забудь, что после изменения конфига надо перезапустить Апач.

Далее, глянь в лог ошибок веб-сервера (/var/log/apache2 или /var/log/httpd). Посомтри, нет ли там чего странного.

>>1377929

Там в начале может быть либо +7, либо 8. Если просто 7 или +8 - то это ошибка. Также, выкидывать лучше не все, а только пробелы, скобки, минусы. Ну а еще лучше все же написать полноценную регулярку для проверки:

- в начале идет 8 или +7
- затем выражение (одна цифра, за ней любое число скобок, минусов, пробелов), которое повторяется 11 раз

Далее, у тебя ошибки в коде:

> if (mb_substr ($clearNum,0,1)=='/7|8/'){

Знак "равно" просто делает посимвольное сравнение, он не интерпретирует выражение как регулярку. Тебе тут нужен preg_match.
Аноним 10/04/19 Срд 08:38:19 1378170819
>>1377837

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

Но сам по себе уровень разный - сеньор в подвальной веб-студии может не пройти собеседование в Яндексе на джуниора. В какой-то компании "сеньор" может просто значить "человек с 6 годами опыта".

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

3 года - это скорее мидл, если только ты не какой-нибудь вундеркинд с выдающимися способностями.

Вот, первая попавшаяся статьи из гугла, довольно адекватная: https://dataart.ru/news/junior-middle-senior-v-chem-raznifa-i-kuda-dalshe/

Так что ответ: развивайся, чтобы соответствовать написанному выше представлению. Изучай внимательно технологии, с которыми работаешь, интересуйся другими технологиями, изучай теорию, читай статьи, смотри доклады. Читай и решай задачи с собеседований в Яндекс. Вот сегодня, например, ты изучил что-то новое?

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

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

>>1377697

Удобнее всего будет сделать форму на отдельном домене (forum.example.com) или URL (http://example.com/forum/), взяв готовый движок. При необходимости интегрировать с сайтом (сделать сквозной логин, например).
Аноним 10/04/19 Срд 08:39:02 1378171820
>>1377739

Жаль, что-то у меня руки не дошли проверить код. Но я бы тебе посоветовал:

- использовать объекты вместо массивов для ключевых типов данных, которые используются во многих функциях в коде
- не городить такие массивы, когда можно обойтись без них. Тут вместо сложного массива principal можно было использовать внутри функции просто переменные вроде error, role, и при необходимости перед возвратом результата собирать из них массив. Хотя, тут можно просто возвращать кортеж (role, error), как мне кажется.
- разбивать стену кода на отдельные функции. Ты и токены проверяешь, и к БД подсоединяешься, и что только не делаешь.
- в try/except указывать конкрентные классы исключений, которые тебя интересуют, а не ловить все подряд

>>1377564

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

>>1377517

Чтобы не нарушать семантику, можно еще использовать display: table вместо настоящих таблиц. А так, да, вертикальное центрирование - это table или flexbox.

>>1377063

Sublime Text, Netbeans for PHP, Eclipse PDT, если ты богат (или если можешь выпросить лицензию как студент) и у тебя быстрый проц, то PHPStorm. VS Code неплоха, но не у всех быстро работает.
Аноним 10/04/19 Срд 08:39:21 1378172821
>>1376921

preg_replace принимает текстовое выражение
preg_replace_callback принимает функцию для замены

Твой код склеивает слова вместе, если между ними 2 или более пробелов.

$count; - эта строка ничего не делает, ее надо убрать.

[а-яё]|[a-z] - это равносильно [а-яёa-z]
Аноним 10/04/19 Срд 09:35:31 1378182822
<?php for ($i = 1; $i <= 5; $i++): ?>
<a href="<?php echo Utils::generateLink($i, 'query'); ?>"><?php echo $i ?></a>
<?php endfor; ?>

Можно ли так смешивать php и html?
Аноним 10/04/19 Срд 09:49:17 1378186823
>>1378169
Благодарю, помогло.
Phing Аноним 10/04/19 Срд 10:46:03 1378202824
Кто-то юзает phing? Насколько он актуален, стоит ли разобраться или есть что-то более пиздатое?
Аноним 10/04/19 Срд 11:12:20 1378210825
>>1377901
Вообще програмировать начал класса так с 6 или 7, какие-то основы паскаля и на олимпиадки ходил(правда там нифига не смог решить кроме первых задач ибо разрыв когда в школе тебя учат ифам, а на олимпиаде поиск минимального пути на графе просто выносит нахуй). На работу за бабло пошел через 3 месяца, как стукнуло 18, когда понял что найти работу джуном на яве - анриал, и пошел задротить PHP. Щас мне 22.

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

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

Яв основном так и вывозил и быстренько подрос по карьере. Чё. Оп-кун, короче спасибо тебе, я тут где-то с 18 или 20 треда сидел, хахахахахах.
Аноним 10/04/19 Срд 13:33:10 1378248826
>>1378210
Мда, а меня пхнула бабка на инженегра. Окончил бакалавра и 2 годика проработал. Сейчас понял, что это не мое, хотя к пк всегда душа лежала. Вот переучиваюсь сызнова.
Аноним 10/04/19 Срд 15:39:43 1378326827
>>1353705 (OP)
Пагни, поясните по структуре проекта на симфони 4. В /src проекта есть директории Entity и Repository. С Entity более менее понятно - там хранятся файлы-модели таблиц БД. А для чего нужна директория Repository?
Аноним 10/04/19 Срд 15:41:10 1378327828
>>1377593
Так в чём ошибка была ты понял? Расскажи.
someApprentice !EaaiHmIJms 10/04/19 Срд 17:02:33 1378381829
image.png (233Кб, 1920x1080)
1920x1080
Протестировал WAMP и сейчас собираюсь писать сервис сообщений. И сначала я хотел бы обсудить архитектуру которую я выбрал. Я считаю её безупречный, но я не безупречный разработчик, поэтому мне хотелось бы услышать опытный взгляд со стороны.

Задача
Каждый пользователь может написать другому пользователю. При первой отправке сообщения создаётся диалог. Сообщения могут быть текстовые, могут быть голосовые и могут быть видео. Каждое сообщение может удаляться либо у себя лично, либо у обоих пользователей. Диалоги так же могут удаляться у каждого пользователя лично (но не у обоих, т.е. каждый пользователь имеет только ссылку на диалог).

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

Диалоги могут быть приватные (тет-а-тет) а могут быть публичные (конференции).


Соответственно архитектура будет такая:

пользователь:
- ...

текстовое_сообщение:
-uuid
-пользователь (автор сообщения)
-сообщение
-дата
-прочитано (булевый)
-...

аудио_сообщение:
-uuid
-пользователь (автор сообщения)
-звукозапись (путь/к/аудиофайлу)
-дата
-прочитано (булевый)
-прослушано (булевый)
-...

видео_сообщение:
-uuid
-пользователь (автор сообщения)
-видеозапись (путь/к/видеофайлу)
-дата
-прочитано (булевый)
-просмотрено (булевый)
-...


текстовое_сообщения: (хранит в себя ссылки на сообщения для каждого отдельного пользователя)
-uuid
-пользователь (кому принадлежит ссылка)
-диалог (диалог в котором сообщение находится)
-сообщение
-...

аудио_сообщения:
-...

видео_сообщения:
-...


прикрепление_изображения:
-uuid
-сообщение
-изображение
-...

прикрепление_аудиозаписи:
-...

и т.д. за исключением что у каждого прикрепления своя ссылка на источник.


диалог:
-uuid
-приватный (булевый)
-...

участники: (для приватных диалогов всегда будет два участника)
-uuid
-диалог
-пользователь
...

диалоги: (ссылки на диалоги для каждого пользователя)
-uuid
-пользователь
-диалог
...


Такова вся архитектура. База данных будет psql.

Название таблиц в боевой базе данных будет идентично т.е. будет и сообщение и сообщения. Это же не создаёт затруднения для понимания?

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


>>1378171
>Жаль, что-то у меня руки не дошли проверить код. Но я бы тебе посоветовал:
>
>- использовать объекты вместо массивов для ключевых типов данных, которые используются во многих функциях в коде
>- не городить такие массивы, когда можно обойтись без них. Тут вместо сложного массива principal можно было использовать внутри функции просто переменные вроде error, role, и при необходимости перед возвратом результата собирать из них массив. Хотя, тут можно просто возвращать кортеж (role, error), как мне кажется.
>- разбивать стену кода на отдельные функции. Ты и токены проверяешь, и к БД подсоединяешься, и что только не делаешь.
>- в try/except указывать конкрентные классы исключений, которые тебя интересуют, а не ловить все подряд

>Жаль, что-то у меня руки не дошли проверить код.
Всё хорошо, у меня было время чем другим заняться. Я рад, что сэкономил ваше время.

>- использовать объекты вместо массивов для ключевых типов данных, которые используются во многих функциях в коде
>объекты
Я правильно понимаю, что в Питоне объект, это instance класса, как в PHP, а не как в JS? Для каких ключевых типов данных вы имеете ввиду?


>- не городить такие массивы, когда можно обойтись без них. Тут вместо сложного массива principal можно было использовать внутри функции просто переменные вроде error, role, и при необходимости перед возвратом результата собирать из них массив. Хотя, тут можно просто возвращать кортеж (role, error), как мне кажется.

>Тут вместо сложного массива principal можно было использовать внутри функции просто переменные вроде error, role, и при необходимости перед возвратом результата собирать из них массив.
Разве это не создаст дополнительные проверки и не раздует код? Т.е. во время ответа писать: if error is not None: principals['extra']['error'] = error; Почему нельзя собирать массив "на ходу"?

>Хотя, тут можно просто возвращать кортеж (role, error), как мне кажется.
Возвращать кортеж из функции авторизации, вы это имели ввиду? Это не правильно, потому что principals сериализуется в json и возвращается клиенту.


>- разбивать стену кода на отдельные функции. Ты и токены проверяешь, и к БД подсоединяешься, и что только не делаешь.
Конечно. Это только черновик где я тестирую чтобы посмотреть как работает код.

У меня будет вопрос по архитектуре, когда я его сформулирую.


>- в try/except указывать конкрентные классы исключений, которые тебя интересуют, а не ловить все подряд
Понял.
Аноним 10/04/19 Срд 18:11:53 1378449830
>>1378248
Ну я на математика учился. Мехмат. Любил математику, но понял, что хочется жрат и денех. Бросил где-то на втором курсе, хотя жалею сейчас немного.
Аноним 10/04/19 Срд 19:28:15 1378531831
Вопрос по симфони.
Допустим юзер отправляет через форму какие-то данные. Сразу, как эти данные приходят в контроллер мне нужно сделать с ними некоторую работу, которая требует времени. Результат этой работы возвращать юзеру не нужно. Но нужно вернуть ему сообщение, типа "мы вас услышали. спасибо. идите нахуй". Как мне это сделать, не дожидаясь, пока вот та времязатратная работа завершится?
Аноним 10/04/19 Срд 19:38:47 1378539832
Аноним 10/04/19 Срд 19:41:58 1378542833
Аноним 10/04/19 Срд 21:01:45 1378586834
>>1378542
Буквы-флаги. В начали урока по регуляркам. Вместо /[a-zA-Z]/
можно написать /[a-z]/i
Если используешь русские буквы в выражении - ставь флаг 'u'.
/[а-яё]/iu
Так же у тебя по условию нужно проверить является ли строка номером. У тебя она является номером, хотя содержит "позвать Люсю".
Аноним 10/04/19 Срд 21:14:04 1378602835
Не могу понять что делает <<<? В книге написано что это какой то маркер но больше нихуя не написано, помогите плиз.
Аноним 10/04/19 Срд 21:18:09 1378611836
>>1378602
Нагуглил что это heredoc какой то. Я так понимаю, это аналог htmlского <pre>?
Аноним 10/04/19 Срд 21:44:18 1378663837
>>1378586
Окей понял. За флаги спасибо, а то только через 101 проверил, а там автоматом проверяется. Перепсал с первичной проверкой любого текста. Но теперь почему-то выражение принимается в любом случае вне зависимости от того есть в нем буквы или нет (я писал только русские). http://sandbox.onlinephpfunctions.com/code/cce3879a8929314360111bd939069d09b7020410
Аноним 10/04/19 Срд 22:28:37 1378756838
>>1378663
Есть несколько моментов:

-в PHP есть функция preg_match($regexp, $text, $match). Она принимает на вход регулярку, текст и пустой массив. Она проверяет, есть ли в тексте подстрока, соответствующая данному шаблону и возвращает 0, если нет, или 1, если она есть.
If (preg_match('/[a-z]/',$text)), если функция найдет что нибудь по регулярному выражению - вернет 1. В обратном же случае вернет 0.
if (1) - Правда, идем дальше
if (0) - Ложь, переходим к Else.

-https://regex101.com/r/qF7vT8/3
Видишь, твоё регулярное выражение не очень то и работает. Должны светиться только ВСЕ правильные номера.

-Читай внимательнее уроки и задачки.

-Сделай сначала первую часть задания, где программа должна из массива номеров выдавать только правильные, а только потом преступай к их форматированию
Аноним 10/04/19 Срд 23:46:02 1378833839
Аноним 11/04/19 Чтв 00:52:59 1378889840
>>1378833
А теперь сделай чтобы скрипт массив номеров проверял. Исходник массивов в задании есть.
Аноним 11/04/19 Чтв 09:50:03 1378980841
3.PNG (45Кб, 1112x277)
1112x277
4.PNG (27Кб, 885x190)
885x190
Анон сдаю тест по битриксу, не знаю ответы на вопросы, хелп.
Выбранные ответы вроде не-верные.
Аноним 11/04/19 Чтв 11:35:39 1379009842
Этот сайт - говно.
Аноним 11/04/19 Чтв 14:23:39 1379090843
>>1378980
ПХП разрабы. Вот вы риал учите такую хуйню? Сука, ониб еще спросили каким цветом кнопка по созданию бэкапа блядь.

У пыхи огроменная экосистема - вордпресы, битриксы, друпалы, хуялы, ларавели, мускули, посгресйли, мариидб, докеры, композеры, паттерны, хуятерны, мемкешы, хуешы блядь. Этот список можно на 100500 страниц составить.

Это все выучить невозможно физически, а учитывая, что все оно периодически обновляется/меняется - то и поддерживать знания на актуальном уровне.

Вы реально все это учите?

Я работаю и когда мне приходится иметь дело с новой цмс - я просто тыкаю куда попало, лишь бы работало, потомучто я не собираюсь тратить свою жизнь на знание ебучих говно-цмс, которые через год будут работать по другому.
Аноним 11/04/19 Чтв 16:09:47 1379175844
Подскажите пожалуйста как эту регулярку одной скобкой записать. Заранее спасибо
(11|12|13|14|15|16|17|18|19)
Аноним 11/04/19 Чтв 16:30:32 1379192845
Как правильно создавать константу? В видеоуроках говорят что const CONSTANT, а в кнгиге define('CONSTNAME', value).
Где истина?
Аноним 11/04/19 Чтв 16:43:28 1379201846
>>1379090
Тут цимес не в учении, один хер забудешь половину, но когда столкнешься снова уже не будешь орать в ужасе и более менее соориентируешься куда копать.
Аноним 11/04/19 Чтв 16:46:09 1379203847
>>1379175
Типа одно число с 11 по 19? /[11-19]/
Аноним 11/04/19 Чтв 17:15:49 1379224848
>>1379203
Да, пытался так сделать. Но искало [один,один-девять, один]
Аноним 11/04/19 Чтв 17:18:07 1379225849
Аноним 11/04/19 Чтв 17:53:39 1379241850
Аноним 11/04/19 Чтв 17:56:32 1379246851
>>1379203
Ищи с начала 1цу, а потом от 1го до9. 1[1-9].
Аноним 11/04/19 Чтв 18:09:00 1379255852
Аноним 11/04/19 Чтв 19:36:33 1379314853
>>1378889
Сделал, глянь, https://ideone.com/v2XnwF. Дуболомно, но пашет. Я сейчас кстати сам с себя проиграл, половина номеров повторяются, а я думал, что один и тотже в цикле идет
Аноним 11/04/19 Чтв 19:49:32 1379319854
Аноним 11/04/19 Чтв 19:55:07 1379321855
Аноним 11/04/19 Чтв 20:15:07 1379335856
>>1379319
Раз все работает - можешь дальше задачки решать. Я сам только учусь, так что могу подсказать только то, что сильно выделяется. Например "грамматика", если ее можно так назвать
Вот как тут >>1353706 пытайся делать. Скобки, пробелы в блоках.
Чтобы код был более правильно оформлен
Аноним 11/04/19 Чтв 20:42:46 1379355857
>>1379335
Согласен, но со скобками пришлось так сделать т к я изначально накосячил с ними и подбивал куда нужно, спасибо тем не менее
Аноним 11/04/19 Чтв 21:03:49 1379381858
>>1379090
Всё сразу знать и не надо. Обычно у кодера есть какой-то свой стек полюбившихся\прибыльных технологий.
Ну понятно, что всегда есть какая-то база кодерская, которую знать просто необходимо для понимания как оно вообще работает и куда смотреть.
Аноним 11/04/19 Чтв 21:43:12 1379411859
Люди, а у вас регэксп нормально работает? Вот я сделал выражение для проверки почты из задания (условно, сейчас вопрос не в этом) https://regex101.com/r/wTzjEo/1 и у меня высвечивается pattern error, когда же я переписываю это так-же http://sandbox.onlinephpfunctions.com/code/b7b2d7d49e417c2b39be6f9dd27368f640ca136c все прекрасно заменяется.
Аноним 12/04/19 Птн 00:11:40 1379475860
Аноны, поясните по хардкору по исключениям. Прочитал уже много чего и не совсем понимаю, где нужно ловить, где нет и вообще для чего это все. Вот я делаю чтение ini файла с конфигурацией подключения к mysql.
if (file_exists(__DIR__ . '/' . 'dbconfig.ini')) {
$config = parse_ini_file(__DIR__ . '/' . 'dbconfig.ini');

} else {
throw new Exception('Database config file missing');
}

Так это должно выглядеть?
Аноним 12/04/19 Птн 03:32:14 1379512861
>>1379475

Ты этот урок читал? Там разве нет ответа? https://github.com/codedokode/pasta/blob/master/php/exceptions.md

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

Если не собираешься, то можно использовать стандартное исключение.
Аноним 12/04/19 Птн 07:31:50 1379535862
>>1379475
Во время разработки выбрасываешь. На продакшене ловишь и обрабатываешь.
Аноним 12/04/19 Птн 08:32:37 1379543863
>>1379512
Прочитал сейчас второй раз и уже понял более менее. В самом простом случае можно просто везде, где могут быть косяки выбрасывать исключения, а в фронт контроллере зарегать set_error_handler и там уже сохранять в лог, для всех исключений выводить в http ответ 503 и страницу с этой ошибкой для пользователя.
Аноним 12/04/19 Птн 09:40:51 1379547864
>>1379535

Что значит "во время разработки выбрасываешь"? В продакшене специально условие писать, чтобы не выбрасывать?

Тут каких-то различий между продакшеном и dev не требуется, разве что в dev можно подробности выводить.
Аноним 12/04/19 Птн 10:24:50 1379557865
>>1379547
Исключительные случаи должны обрабатываться так, чтобы во время разработки они были очевидны, а в промышленном коде — позволяли продолжить работу.
С. Макконелл Совершенный код


я понимаю так, как написал здесь >>1379535
Аноним 12/04/19 Птн 11:41:10 1379581866
>>1379475
По идее перед деплоем ты всё равно запускаешь тесты, и если конфиг с подключением к бд куда-то пропал то ты об этом узнаешь, я не понимаю как такое можно обработать чтобы приложение не упало

>>1379543
>в http ответ 503
Почему не 500?

Никого, кстати, не смущает что код ответа http часто совмещают с ответом самого приложения? Например мы сделали форму на сайте, клиент отправляет запрос с данными, мы видим там ошибку, часто ставят ответ 422, хотя по сути ответ же 200, сервер всё прочитал и понял, хттп на транспортном уровне сделал своё дело, а то что внутри запроса данные не такие это уже наше дело, нет?
Аноним 12/04/19 Птн 12:50:43 1379617867
>>1379581
Оп писал,что пустая страница с ответом 200 при выбросе исключения - это плохо. Там что-то про гугл и яндекс, которые индексируют такие страницы, а 503 они не трогают.
Аноним 12/04/19 Птн 13:13:32 1379629868
>>1379557

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

Возможно, Макконелл имел в виду "продолжить работу" с точки зрения пользователя, например, показать страницу ошибки и дать возможность повторно отправить запрос.
Аноним 12/04/19 Птн 13:19:32 1379633869
>>1379581

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

Ты наверно имел в виду HTTP API.Там часто код используют для сигнализирования об ошибке на уровне логики (пользователь с таким емайл уже существует). Почему бы и нет? Кто-то использует код ошибки, кто-то возвращает 200 и информацию об ошибке в JSON. Оба подхода имеют право на жизнь, лишь бы они были задокументированы.

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

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

В принципе, можно возвращать 422 и в ответ на форму регистрации, если ты гарантируешь, что браузеры вместо нее не покажут стандартную страницу ошибки.
Аноним 12/04/19 Птн 13:31:13 1379645870
1200.jpg (26Кб, 618x412)
618x412
Говорят что PHP простой язык. Нифига он не простой...
Аноним 12/04/19 Птн 14:40:35 1379713871
>>1379645
Не путай язык и задачи.
Аноним 12/04/19 Птн 15:39:59 1379741872
Сап двачеры. Помогите с одной проблемой:
echo <<< END
хуй
залупа
END; - видимо не работает в 7 версии - так как по-другому вывести несколько строк?
Аноним 12/04/19 Птн 15:46:08 1379743873
Аноним 12/04/19 Птн 15:47:42 1379744874
пишу на симфони, после того как залогинился страница исчезает и остается адресная строка, не пойму в чем проблемаа
Аноним 12/04/19 Птн 15:49:17 1379750875
image.png (257Кб, 1920x1080)
1920x1080
>>1379743
у меня не видит конца строки. Не пойму в чем проблема
Аноним 12/04/19 Птн 15:54:35 1379756876
Аноним 12/04/19 Птн 16:08:21 1379765877
>>1379744
прошу прощения, все исправил, ошибка идиотская)
Аноним 12/04/19 Птн 17:06:23 1379804878
Аноны, вот в выводе списка студентов есть кнопки постраничной навигации, сортировки и поиска, по отдельности это все понятно как сдклать. Вопрос, я жму на смену страницы в постраничной навигации, передается по get параметром номер страницы, а как передать текущую выбранную пользователем сортировку в таблице,чтобы она не сбилась?
Аноним 12/04/19 Птн 17:34:35 1379829879
>>1379804
Надеюсь я тебя правильно понял.

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

$orderBy = $_GET['orderBy'];
$orderDir = $_GET['orderDir'];

LinkHelper::generateLink($page, $searchQuery, $orderBy, $orderDir);

Должно получиться, что-то подобное

/?page=7&orderBy="name"&orderDir="DESC"
Аноним 12/04/19 Птн 17:37:21 1379833880
tmp22.jpg (29Кб, 509x207)
509x207
>>1379804
Вот моя функция на пике, которая решает эту проблему.
Идея в том, что гет-параметры сохраняются из предыдущего запроса и просто подставляются в новую ссылку. Функция передаётся как замыкание в шаблон и через неё формируются ссылки на пагинацию и т.д.
Если у кого есть идея лучше - прошу озвучить, так как я писал от балды.
Аноним 12/04/19 Птн 18:16:53 1379860881
ОП, можешь 2 задачки глянуть? Они работают, но мне кажется что уж сильно говнокод. Стоит ли пытаться решать по другому или идти дальше?
Числа в строки: http://sandbox.onlinephpfunctions.com/code/8f78a64f577b9d3eb6c00dfb5df5cba88483bd29
Простой калькулятор:
http://sandbox.onlinephpfunctions.com/code/5a4761d4e56d1d933fa1dbfe2f80e6feebe2f89a


Аноны, нужно ли устанавливать библиотеки функций для php?
У меня и консоль и localhost жалуются:
Call to undefined function mb_... on line ...
Аноним 12/04/19 Птн 19:28:33 1379893882
image.png (274Кб, 1000x1800)
1000x1800
Я начал с нуля изучать PHP и хочу сходу указать 2 недостатка этого phpbooktest'а. В пикриле справа сверху написано, что mb_substr вырезает подстроку, но это не так. mb_substr возвращает подстроку, а вот просто substr вырезает. И еще уроком ранее не был объяснен принцип цикла foreach (пришлось разбираться самому). В целом интересно и сжато (зато по существу), спасибо ОПу (если это сделал он)
Аноним 12/04/19 Птн 19:42:25 1379903883
>>1379893
Обосрался насчет substr
Аноним 12/04/19 Птн 21:43:15 1379990884
Что поделать, если впадлу делать сайт для тестирования (Который после файлообменника)? Вроде хочу начать, а ничего не понятно (тупо на ленивычах разбираться) и закрываю, и так не первый день.
Аноним 12/04/19 Птн 22:09:14 1380001885
Аноним 13/04/19 Суб 00:02:08 1380060886
Аноним 13/04/19 Суб 10:08:31 1380175887
>>1379629
Это я и имел ввиду. Может не так выразился.
Аноним 13/04/19 Суб 12:53:52 1380236888
>>1379765
НУ и нахуй так писать, не говоря, что за ошибка и как ты её исправил? Может кому-то полезно будет. И вообще это хороший тон отвечать с конкретикой на свой вопрос если удалось самому справиться с проблемой.
Аноним 13/04/19 Суб 13:14:59 1380244889
Котаны, подскажите - почему когда я пишу в txt файл, то у меня символы \n\r в нем отображаются? Пишу в виндоовс.

Я построчно из одного файла, где сплошной текст без переносов читаю, и пишу в другой файл, но так, что бы каждая новая часть была с переносом строки.
Что характерно в новом файле переносы работают, но '\r\n' так же отображаются. Как так то?
Код:
$handle = fopen($path, "r");
$handle1 = fopen($path1, 'a');
while(!feof($handle)){>>1380236

$str = fgets($handle, 50);
$str = $str.'\r\n';
fwrite($handle1, $str."\r\n");
}
fclose($handle);
fclose($handle1);
Аноним 13/04/19 Суб 13:16:05 1380247890
>>1380244
Бля, ссылка чет лишняя в коде. Я криволапый.
Аноним 13/04/19 Суб 13:19:49 1380250891
>>1380244
Бля,все ясно, я не отвечайте мне. Я просто косолапый в квадрате.
Аноним 13/04/19 Суб 15:09:00 1380297892
>>1380244
>\n\r
Юзаю PHP_EOL и проблем не знаю.
Аноним 13/04/19 Суб 21:17:22 1380455893
>>1379990

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

Ну или задавай вопросы, если есть какие-то конкретные вопросы.

>>1379893

Да, там не все идеально, если будет возможность, то надо будет исправить. Насчет "вырезает" - имелось в виду, естественно, возвращает. Разница между substr и mb_substr в том, что первая работает только с 8-битными кодировками, а вторая - с той, что задана в опции default_encoding в php.ini или функцией mb_default_encoding().

>>1379860

> Числа в строки: http://sandbox.onlinephpfunctions.com/code/8f78a64f577b9d3eb6c00dfb5df5cba88483bd29

> if(preg_match('/(11|12|13|14|15|16|17|18|19)/',$lastTwo))

Тут можно просто написать что lastTwo больше/равно 11 и меньше/равно 19. Числа все же правильнее сравнивать с помощью математических операций.

В if/else надо использовать фигурные скобки, так как иначе легко допустить ошибку при чтении или правке кода. Это же не Питон, где все оступами определяется.

В функции inclideWord if/else можно было написать в один уровень, без вложенности.

> $count = strlen($number);
> if ($count == 1){

Тут лучше использовать математику, например условие что number меньше 10.

Функция smallNumberToText переусложнена и в ней много копипасты. Нужно ее переделать. Например, так:

- если в числе есть сотни, добавить слово для сотен
- если число оканчивается на 11-19, добавить соотв. слово
- если в числе есть десятки, то добавить слово для них
- если в числе есть единицы, то добавить слово для них (с учетом пола)

Смотри, всего 4 условия.

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


> Аноны, нужно ли устанавливать библиотеки функций для php?
> У меня и консоль и localhost жалуются:
> Call to undefined function mb_... on line ...

Если ты под виндой, то скорее всего она просто не включена в php.ini директивой extension = .... Если под линуксом, то там обычно расширения ставятся отдельно (в Убунте/дебиане через apt-get install).

> Простой калькулятор:
http://sandbox.onlinephpfunctions.com/code/5a4761d4e56d1d933fa1dbfe2f80e6feebe2f89a

> if ($operation == ''){
> ...
> if ($operation == '+')

Здесь лучше было использовать elseif, так как у нас либо есть заданная ранее операция, либо нет.

А так, верно.
Аноним 13/04/19 Суб 21:18:19 1380456894
>>1379833

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

function makeLinkGenerator(array $basicParams): callable {
return function (array $override) { ... };
}

Использование:

$linkGen = makeLinkGenerator(['sort' => 'name', 'page' => 3]);
echo $linkGen(['page' => 2]); // Меняем страницу
echo $linkGen(['sort' => 'score', 'page' => '']); // при смене сортировки сбрасываем пагинацию

Можно сделать аналогичную штуку с помощью объекта:

$linkGen = new LinkGenerator([....]);
$linkGen->makeLink([....]);

Можно сделать специализированные функции для разных видов ссылок:

$linkGen = new LinkGenerator([....]);
$linkGen->makePaginationLink(3);
$linkGen->makeSortLink('-name');

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

Можно вместо массива с базовыми параметрами использовать объект ViewParams/ViewFilter.

Также стоит предусмотреть такие вещи:

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

>>1379741

Возможно, у тебя там отступ (пробелы) перед END или какие-то лишние символы после.
Аноним 13/04/19 Суб 21:19:04 1380458895
>>1379617

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

>>1379411

Сейчас оба регекспа работают. Надо учесть, что на regex101 немного другие флаги (в PHP нет флага global), и могут быть немного другие правила использования бекслешей (в PHP сначала обрабатываются бекслеши как часть синаксиса записи строк, а потом в том, что останется, обрабатываются бекслеши как часть регулярки).

>>1379090

Этот тест проверяет знание Битрикса. Если ты с ним каждый день работаешь, то ты и так знаешь ответы на эти вопросы.

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

Гордиться низким уровнем знаний и нежеланием развиваться довольно странно.

>>1379314

Решено верно, но.

> if (preg_match('/^(\+7)/',$checkNum)) {
> $checkNum=preg_replace('/^(\+7)/',8,$checkNum);
Тут сразу можно делать preg_replace без предварительной проверки.

И по тестированию: лучше не просто писать, что номер верный/неверный, а сразу добавлять, правильно ли определила его программа или нет. Так как сейчас у тебя надо вручную читать то, что вывели программа, чтобы проверить, что она правильно определяет номера.
Аноним 13/04/19 Суб 21:19:38 1380459896
>>1378663

> Но теперь почему-то выражение принимается в любом случае вне зависимости от того есть в нем буквы или нет (я писал только русские).

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

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

>>1378542

Чтобы регулярка корректно работала с нелатинскими символами в кодировке utf-8 (а у тебя она), надо ставить флаг u. Иначе регулярка думает, что перед ней текст в 1-байтовой кодировке, а русская буква - это 2 отдельных символа (так как она кодируется 2 байтами в utf-8). Описано тут: https://github.com/codedokode/pasta/blob/master/php/strings-utf8.md

>>1379192

const появился в PHP7, а книга наверно написана раньше. Лучше использовать const.

>>1378611

Это способ записи больших строк. Можно использовать кавычки, а можно heredoc. Ты бы документацию вместо книги почитал бы, например:

- https://www.php.net/manual/ru/language.types.string.php
- https://ru.wikipedia.org/wiki/Heredoc-%D1%81%D0%B8%D0%BD%D1%82%D0%B0%D0%BA%D1%81%D0%B8%D1%81

Главный плюс в том, что в нем можно использовать кавычки и/или спецсимволы без экранирования, что удобно. К тегу <pre> он отношения не имеет.

>>1378531

Есть очереди задач для этого.
Аноним 13/04/19 Суб 21:20:25 1380460897
>>1378381

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

Если ты хочешь делать для каждого пользователя свою копию сообщения, то не проще ли просто сделать таблицу "диалог", и таблицу "сообщения", где в сообщении стоит ссылка на диалог и ссылка на получателя, кому оно предназначено? То есть, так:

диалог:
- uuid

участники диалога:
- id пользователя
- id диалога

сообщения: (копия для каждого получателя)
- uuid
- id, объединяющий копии одного сообщения
- id диалога
- id отправителя
- id получателя этой копии
- признак прочтения
- текст

Кстати, в больших чатах невыгодно будет делать для каждого свою копию сообщения. Выгоднее делать всего одну копию для всех.

Далее, у тебя есть наследование таблиц (для текстовых, аудио, видео сообщений сделаны отдельные таблицы). Ты использовал Concrete Table Inheritance. Не очень удобно делать их разными таблицами. Представь, что тебе надо получить последние 10 сообщений в диалоге. Тебе надо будет запрашивать данные из каждой таблицы (из текстовых сообщений, аудио сообщений, видео сообщений) и объединять. Как ты себе представляешь эффективную пагинацию по ним?

Логичнее было бы использовать другой паттерн наследования, например, Single Table Inheritance или Class Table Inheritance. В случае STI мы делаем единую таблицу для всех видов сообщений. В случае CTI мы делаем одну таблицу для полей, которые есть в каждом виде сообщения (отправитель, время отправки, получено), и отдельные таблицы для доп. полей (которые есть только у опр. вида сообщения):

- http://design-pattern.ru/patterns/class-table-inheritance.html
- http://design-pattern.ru/patterns/single-table-inheritance.html

В обоих случаях мы можем легко получить последние N сообщений или сделать пагинацию без использования OFFSET.

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

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

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

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

Поэтому, думаю, схему надо доработать.

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

Но оно не дает нам эффективно делать пагинацию по сообщениям, что сводит плюсы на нет.

> Я правильно понимаю, что в Питоне объект, это instance класса, как в PHP, а не как в JS? Для каких ключевых типов данных вы имеете ввиду?

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

> Разве это не создаст дополнительные проверки и не раздует код? Т.е. во время ответа писать: if error is not None: principals['extra']['error'] = error; Почему нельзя собирать массив "на ходу"?

Потому, что это разные задачи: получение данных и формирование ответа на JSON-запрос. И скорее всего, лучше чтобы отдельно была функция проверки авторизации, а отдельно функция, которая формирует JSON-ответ. А не совмещать это все в одной функции. Но так как это тестовый код, то это не принципиально.
Аноним 13/04/19 Суб 21:21:10 1380463898
>>1378326

Repository это паттерн, про который можно прочесть тут:

- https://www.google.com/search?client=firefox-b-d&q=%D0%BF%D0%B0%D1%82%D1%82%D0%B5%D1%80%D0%BD+repository
- http://design-pattern.ru/patterns/repository.html
- https://martinfowler.com/eaaCatalog/repository.html

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

- https://github.com/doctrine/persistence/blob/master/lib/Doctrine/Persistence/ObjectRepository.php
- https://github.com/doctrine/collections/blob/master/lib/Doctrine/Common/Collections/Selectable.php

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

- https://github.com/doctrine/orm/blob/master/lib/Doctrine/ORM/EntityRepository.php

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

В общем: если ты изучаешь Симфони, то изучи Доктрину. А если ты ее изучаешь, то изучи связанные с ней паттерны, такие, как Entity Map, Unit Of Work, Lazy Load: http://design-pattern.ru/index.html . Посмотри, как они реализованы в Доктрине.

Доктрину надо изучать. Я постоянно вижу, что люди ее не знают, и думают, например, что persist сохраняет объект в базу данных. Почему им лень даже документацию прочесть?

>>378182

Вместо echo лучше использовать <?= , и надо экранировать спецсимволы в ссылках при выводе.

>>1380244

В одиночных кавычках \n это просто бекслеш и буква n.

>>1380297

А я посто везде \n использую. Пишется короче и код читабельнее. Блокнотом Windows я все равно не пользуюсь.


Аноним 13/04/19 Суб 21:48:23 1380491899
Аноны, переходите в новый тред >>1380485 (OP)

Я постараюсь тут в ближайшие пару дней проверить оставшиеся посты, но для надежности вы можете напомнить о них в новом треде.
someApprentice !EaaiHmIJms 14/04/19 Вск 11:05:28 1380677900
>>1380460
>Использование таблиц с похожими именами будет однозначно вызывать путаницу. Более того, я пока сам не понял, в чем разница между "сообщением" и "сообщениями" или "диалог" и "диалоги".
Сообщение - это конкретная запись сообщения имеющая все данные о нём, от содержания до автора, id, даты публикации и т.д., а сообщения - это запись какие сообщения принадлежат какому пользователю и/или диалогу. Т.е. "сообщения" хранит ссылки для пользователя на id конкретного сообщения.

Как можно понятней назвать таблицы чтобы не вызвать путаницу?

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

https://phpclub.tech/pr/res/1019301.html#1028550
>чаты и диалоги лучше делать одинаковым способом, то есть представить диалог 2 пользователей как чат из 2 участников.

>Первый вариант - сделать у каждого пользователя списки входящих и исходящих сообщений (по аналогии с почтовым ящиком), и помещать копии сообщения как отправителю, так и получателю. При этом каждый может независимо управлять своей историей сообщений, например, очищать ее. Для чатов сообщение придется копировать многократно.
>
>При этом, чтобы связать сообщения, можно сделать какой-нибудь добавочный id. Можно например сделать таблицу сообщений (где и будет этот id), и отдельно таблицу, которая хранит копию сообщения для конкретного получателя.

Мне хочется казать, что я слегка её отшлифовал, убрав многократное копирование сообщений заменив его "ссылками" на сообщения.


>Если ты хочешь делать для каждого пользователя свою копию сообщения, то не проще ли просто сделать таблицу "диалог", и таблицу "сообщения", где в сообщении стоит ссылка на диалог и ссылка на получателя, кому оно предназначено? То есть, так:
>
>диалог:
>- uuid
>
>участники диалога:
>- id пользователя
>- id диалога
>
>сообщения: (копия для каждого получателя)
>- uuid
>- id, объединяющий копии одного сообщения
>- id диалога
>- id отправителя
>- id получателя этой копии
>- признак прочтения
>- текст
>
>Кстати, в больших чатах невыгодно будет делать для каждого свою копию сообщения. Выгоднее делать всего одну копию для всех.
>- id, объединяющий копии одного сообщения
Это получается что объединяющее копия одного сообщения это отдельная сущность/таблица? Я не понимаю тогда, это получается тоже самое что и я предложил, только колонки в разных таблицах. Ну и контент сообщения в моём предложении находиться только оригинальном, а не дублируется.

Повторюсь, что в ссылке на сообщение находиться id на сообщение, а не его содержимое:

>текстовое_сообщения: (хранит в себя ссылки на сообщения для каждого отдельного пользователя)
>-uuid
>-пользователь (кому принадлежит ссылка)
>-диалог (диалог в котором сообщение находится)
>-uuid сообщения
>-...


>Далее, у тебя есть наследование таблиц (для текстовых, аудио, видео сообщений сделаны отдельные таблицы). Ты использовал Concrete Table Inheritance. Не очень удобно делать их разными таблицами. Представь, что тебе надо получить последние 10 сообщений в диалоге. Тебе надо будет запрашивать данные из каждой таблицы (из текстовых сообщений, аудио сообщений, видео сообщений) и объединять. Как ты себе представляешь эффективную пагинацию по ним?
>
>Логичнее было бы использовать другой паттерн наследования, например, Single Table Inheritance или Class Table Inheritance. В случае STI мы делаем единую таблицу для всех видов сообщений. В случае CTI мы делаем одну таблицу для полей, которые есть в каждом виде сообщения (отправитель, время отправки, получено), и отдельные таблицы для доп. полей (которые есть только у опр. вида сообщения):
>
>- http://design-pattern.ru/patterns/class-table-inheritance.html
>- http://design-pattern.ru/patterns/single-table-inheritance.html
>
>В обоих случаях мы можем легко получить последние N сообщений или сделать пагинацию без использования OFFSET.
Я думал об этом и предполагал, что у psql есть встроенная поддержка этого, и как оказалось, действительно есть https://postgrespro.ru/docs/postgresql/11/ddl-inherit


>Также, возможно, имеет смысл свести любые сообщения к текстовым сообщениям с приложениями. Тогда аудиосообщение будет просто текстовым сообщением без текста с приложенным аудио, с пометкой, что аудиосообщение тут главное. Тут надо взвесить плюсы и минусы. Плюс в упрощении структуры таблиц.
Не согласен. Аудиосообщение по сути это аудиозапись, и в прикрепление тоже могут прикладывать аудиозапись, и поэтому будет конфликт, что есть голосовое сообщение, а что аудиофайл. Для этого нужно будет наследовать отдельный тип прикрепления, что является тем же самым что и унаследовать от сообщений. Я считаю, что голосовые сообщения должны быть отдельным типом сообщения, а не прикрепления.


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


>>1380460
>> Я правильно понимаю, что в Питоне объект, это instance класса, как в PHP, а не как в JS? Для каких ключевых типов данных вы имеете ввиду?
>
>Да, как в PHP. Я имел в виду, что если у тебя в коде есть какой-то массив, который много где используется, передается и возвращается разными функциями, то правильнее будет сделать его объектом. Но, как я понял, там был просто тестовый код, и тогда это не важно.
Этот массив был бы объектом с одним свойством этого самого массива?
Аноним 14/04/19 Вск 11:24:17 1380688901
tmp23.jpg (125Кб, 1173x382)
1173x382
>>1380456
>У тебя как-то странно сделано, что параметры сохраняются в $this->get. Это значит, что если ты с помощью функции linkMaker() создашь 2 анонимных функции, то одна будет влиять на другую (параметры, переданные в одну, отобразятся в другой). Это неправильно.

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

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

>если мы меняем сортировку, то надо сбрасывать пагинацию
Зачем? Количество записей ведь не изменилось. Я вот со своей этой функцией поигрался - вполне юзабельно вроде. Страницы жмёшь - меняет страницы, сортировку меняешь - сортировка только и меняется, что нажали - то и выводит.
Аноним 15/04/19 Пнд 15:22:26 1381798902
так, при регистрации валидатор симфони ругается: data.password This 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
}

помогите пж нубасу)
Аноним 15/04/19 Пнд 16:18:39 1381826903
>>1381798

Во-первых, иди в новый тред, этот утонул, >>1380485 (OP) Вот-вторых, у тебя же в ограничении стоит NotBlank, то есть поле обязательно к заполнению.
someApprentice !EaaiHmIJms 15/04/19 Пнд 16:29:51 1381835904
>>1380677
>>> Я правильно понимаю, что в Питоне объект, это instance класса, как в PHP, а не как в JS? Для каких ключевых типов данных вы имеете ввиду?
>>
>>Да, как в PHP. Я имел в виду, что если у тебя в коде есть какой-то массив, который много где используется, передается и возвращается разными функциями, то правильнее будет сделать его объектом. Но, как я понял, там был просто тестовый код, и тогда это не важно.
>Этот массив был бы объектом с одним свойством этого самого массива?
Или я подумал, что это может быть объект со свойствами которые содержатся в этом массиве, и сделать этому объекту метод toArray().
Аноним 15/04/19 Пнд 16:56:36 1381843905
>>1380459
>Есть очереди задач для этого.
Ты имеешь в виду какой-нибудь rabbitmq? Из пушки по воробьям же. Мне нужно просто отправить юзеру view сразу, до того как долгий таск завершится. Я до этого писал всякую шляпу на fat free framework и там есть функция abort, которая делает нужное
https://fatfreeframework.com/3.6/base#abort
Я вполне способен залезть в исходники и посмотреть, что она там делает и перенести это в симфони, но ведь скорее всего это уже там есть и мой велосипед всяко будет хуже.
Аноним 15/04/19 Пнд 22:10:36 1382020906
Анонче, подскажи, а то я застрял. Делаю грамматического нациста, хочу сделать проверку по отсутствию знака препинания. Идея такая я делаю preg match all с preg set order< затем дампую. 0й массив. Но как мне ограничить регулярку? Я думал таком варианте
'/s|^. - это либо символ начала строки либо ограничивающий пробел.
\.\S - условие замены
.
\s|.*\. - ограничение по пробелу или концу строк
Я хочу что бы сделав дамп 0го массива вылезли все ошибки. Но почему - то даже правильные последовательности тоже выдаются. Где я перемудрил? По возможности намекните т к хочу допереть сам
Аноним 19/04/19 Птн 09:21:05 1383863907
Книбудь пишет в vscode? Как он вообще?
someApprentice !EaaiHmIJms 19/04/19 Птн 10:29:51 1383892908
>>1380677
>Как можно понятней назвать таблицы чтобы не вызвать путаницу?
Также, можно добавлять комментарии к таблицам. Разработчики часто их читают?

https://postgrespro.ru/docs/postgrespro/11/sql-comment
someApprentice !EaaiHmIJms 23/04/19 Втр 07:34:52 1387125909
>>1380677
>>1383892
>>Использование таблиц с похожими именами будет однозначно вызывать путаницу. Более того, я пока сам не понял, в чем разница между "сообщением" и "сообщениями" или "диалог" и "диалоги".
>Сообщение - это конкретная запись сообщения имеющая все данные о нём, от содержания до автора, id, даты публикации и т.д., а сообщения - это запись какие сообщения принадлежат какому пользователю и/или диалогу. Т.е. "сообщения" хранит ссылки для пользователя на id конкретного сообщения.
>
>Как можно понятней назвать таблицы чтобы не вызвать путаницу?
Можно вместо создания бесконечного количества ссылок создать поле с типом ARRAY и помещать в него все ссылки (UUID) на необходимые данные.

https://postgrespro.ru/docs/postgresql/11/arrays
https://postgrespro.ru/docs/postgresql/11/functions-array

Соответственно, все операции будет выполнятся легко и ловко.

Прим.

Message:
-uuid
...

Dialog:
-uuid
-private BOOLEAN
-participants UUID[] //массив из uuid получателей

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

И все операции выполняются очень легко:

// Пользователь удаляет свою копию сообщения
UPDATE Partcipant SET messages = array_remove(messages, uuid_of_message) WHERE uuid = uuid_of_participant;

// Проверить существует ли приватный диалог,
// не смотря на то что один из пользователей когда-то покинул диалог
SELECT * FROM Dialog WHERE private = true AND (uuid_of_alice = ANY(participants) OR uuid_of_bob = ANY(participants));
Аноним 24/04/19 Срд 23:23:50 1388116910
Есть ли какая-то принципиальная разница между этими методами?

public function do() {
//...
this->calculate($someVar);
}

private function calculate($someVar) {
//..
$this->supaVar = $someVar 42;
}

ИЛИ

public function do() {
//...
$this->supaVar = this->calculate($someVar);
}

private function calculate($someVar) {
//..
return $someVar
42;
}
Аноним 25/04/19 Чтв 05:26:21 1388215911
Аноним 25/04/19 Чтв 05:33:14 1388217912
someApprentice !EaaiHmIJms 25/04/19 Чтв 10:59:58 1388324913
Аноним 26/04/19 Птн 23:19:36 1389490914
Если планируете перекатываьтся за границу, то забейте на пхп. он мертв в развитых странах.
Говорю на своем опыте. я перекатился в израиль и тут нет вакансий. нода в 3-4 раза востребованей. самые топовые языки тут это с#, питон и джава
913 101 281
Настройки X
Ответить в тред X
15000 [S]
Макс объем: 40Mб, макс кол-во файлов: 4
Кликни/брось файл/ctrl-v
Стикеры X
Избранное / Топ тредов