Двач.hk не отвечает.
Вы видите копию треда, сохраненную 15 января 2020 года.

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

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

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

Это тред для начинающих. Не написал за свою жизнь ни одной программы? Ты наш человек.

Устанавливать пока что ничего не требуется, разве что редактор кода вроде Sublime Text 3, Notepad++, Netbeans PHP или PhpStorm (с ним будет удобнее).

Предыдущий тред был тут: >>715010 (OP)

Что самое главное для программиста? Умение аккуратно оформлять код (читай второй пост прежде чем писать код).

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

Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 2-3 дня, у него мало времени, не жди его, решай задачки дальше. ОП отвечает на все вопросы по его задачкам и учебнику, а вот насчет каких-то других вещей - только если останется время. Но в треде немало анонимных экспертов разного уровня, так что вряд ли вопрос останется без ответа.

У нас есть уроки по основам PHP, они собраны и выложены по адресу http://archive-ipq-co.narod.ru/ Это учебник для изучающих с нуля, то есть если ты вообще ничего не знаешь, то надо начать с него. Он простой и понятный (по крайней мере в начале). Там есть задачи, их надо решать обязательно (чтобы стать программистом, надо писать код — иначе никак). Пости ссылки на решения в тред, мы их проверим, напишем замечания и дадим советы по улучшению.

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

Ты прошел весь учебник? Молодец, но это были лишь основы языка 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/Yii2: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование
- Если ты все решил, переходи к Symfony 2/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

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

Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания 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://gist.github.com/codedokode/10539213

Что почитать

- Мануал по 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

Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492
ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
Подскажи сайты для поиска работы, я не умею гуглить? — hh.ru, geekjob.ru, moikrug.ru (склеен с brainstorage.me), fl.ru, upwork.com (бывший одеск). Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
Важно! 2 729433
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

Если тебе лень выравнивать код руками, закачай его на 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/php-fig/fig-standards/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-2-coding-style-guide.md

------------------

Итак, ты зашел в тред и решил помочь какому-то анону, дав ему совет или подсказку. Спасибо! Но прочти сначала эти напоминания, чтобы твоя помощь действительно была полезной.

Давай удочку, а не рыбу

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

Будь доброжелателен

Не годится: «Ты мануал хоть раз в жизни открывал, обезьяна?»
Не годится: «В гугле забанили?»
Не годится: «Твой код плохой»
Хорошо: «Вот, как можно улучшить этот код: ...»
Хорошо: «Ты неправильно используешь функцию abc(). Вот ее описание: ссылка, и как видишь ей надо передать строку, а не массив»

Не придирайся к знанию английского языка.

Объясняй

Не очень хорошо: «сделай как в этом коде»
Хорошо: «если ты вставляешь текст от пользователя в SQL запрос, то получается SQl-инъекция, которая позволяет взломать твой сервер (ссылки). Чтобы этого избежать, надо вставлять данные с помощью плейсхолдеров (ссылки)»
Хорошо: «Помни, что код пишется для людей. Если писать такие большие функции, то в них становится трудно разобраться...»

Не проповедуй

Мы учим использованию самых распространненных подходов, стандартов, библиотеки фреймворков. Если ты не любишь ООП, пробелы в коде, jQuery, сам PHP, то рассказать об этом стоит в каком-нибудь другом треде.

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

Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
Важно! 2 729433
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

Если тебе лень выравнивать код руками, закачай его на 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/php-fig/fig-standards/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/php-fig/fig-standards/blob/master/accepted/ru/PSR-2-coding-style-guide.md

------------------

Итак, ты зашел в тред и решил помочь какому-то анону, дав ему совет или подсказку. Спасибо! Но прочти сначала эти напоминания, чтобы твоя помощь действительно была полезной.

Давай удочку, а не рыбу

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

Будь доброжелателен

Не годится: «Ты мануал хоть раз в жизни открывал, обезьяна?»
Не годится: «В гугле забанили?»
Не годится: «Твой код плохой»
Хорошо: «Вот, как можно улучшить этот код: ...»
Хорошо: «Ты неправильно используешь функцию abc(). Вот ее описание: ссылка, и как видишь ей надо передать строку, а не массив»

Не придирайся к знанию английского языка.

Объясняй

Не очень хорошо: «сделай как в этом коде»
Хорошо: «если ты вставляешь текст от пользователя в SQL запрос, то получается SQl-инъекция, которая позволяет взломать твой сервер (ссылки). Чтобы этого избежать, надо вставлять данные с помощью плейсхолдеров (ссылки)»
Хорошо: «Помни, что код пишется для людей. Если писать такие большие функции, то в них становится трудно разобраться...»

Не проповедуй

Мы учим использованию самых распространненных подходов, стандартов, библиотеки фреймворков. Если ты не любишь ООП, пробелы в коде, jQuery, сам PHP, то рассказать об этом стоит в каком-нибудь другом треде.

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

Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
3 729435
Напомню что в старом треде >>715010 (OP) я проверил все посты и ответил почти на все вопросы кроме вчерашних. На вчеращние - отвечу чуть позже. Если я вас забыл, напомните о себе в этом треде.
4 729497
>>729438
Так ведь $department это и есть объекты. Сам массив клонируется вместе с компанией, ведь это не объект, он копируется сразу.

>I ran into the same problem of an array of objects inside of an object


public function __clone() {
foreach ($this->varName as &$a) {
foreach ($a as &$b) {
$b = clone $b;
}
}
}
Вот ещё нашел в мануале, типа для клонирования массивов объектов. Но тоже не работает.
161 Кб, 850x1188
5 729503
Ребята, здравствуйте!

Пишу сейчас простенькую систему парольной аутентификации.

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

Когда пользователь вводит в форму правильную пару логин\пароль, ему выдается кука с SESSID (просто набор рандомных символов).

Этот SESSID так же прописывается в БД.

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

Собственно сам вопрос:
Что если потенциальные хацкеры напишут программу, которая будет пытаться подобрать куку с SESSID.

Спасибо
6 729508
Почоны, нашел xss уязвимость - вывел в консоль куки через поиск на сайте. Для чего можно использовать?
7 729513
>>29503
https://gist.github.com/codedokode/9576319

>>29508
залей им какашку на сайт, прекинь как у них бабахнет)))0
120 Кб, 700x525
8 729516
>>29513
По всей видимости, Вы, к сожалению, не поняли сути моего вопроса.

В статье, которую Вы привели, говорится о хранении паролей в БД.
Для хранения я использую функцию:
password_hash($_REQUEST["pass"], PASSWORD_DEFAULT);

Меня интересует как проверять перебирают ли хацкеры кукисы в которых хранится SESSID.
Привязывать в БД sessid к ip пользователя? Но если ip у пользователя сменится то под этой кукой ему уже не войти.

Делать ограничение на количество попыток с одного ip войти под разными кукисами?
9 729524
>>29516

>Но если ip у пользователя сменится то под этой кукой ему уже не войти.


Перечислите, пожалуйста, случаи, когда это может произойти вне зависимости от волеизъявления пользователя.
Например, он переходит из кафе в кафе, пользуясь бесплатным Wi-Fi, либо едет на поезде (летит на самолёте и т.п.), переключаясь между доступными мобильными сетями.
На этом моя фантазия, увы, иссякла.
10 729529
>>29524
Да, у пользователей редко меняется ip.

Но задача стоит в том чтобы пользователь мог войти при смене ip.

Возможно я ошибаюсь, но так в основном на всех сайтах и происходит
11 729535
>>29524
Динамический айпи.
12 729546
>>29529
Тогда в зависимости от частоты смены IP в промежуток времени, наверное. Если часто меняется - непорядок.
В одном из тредов вроде бы ОП советовал проверять, залогинен ли юзер в социальных сетях. То есть если он залогинен в одной сети, но IP меняется - плохо. Если ни в какой не залогинен и IP меняется - того хуже.
Соцсети, почта, поисковики, вот это всё.
Живой человек где-то да залогинен. Купи пасскод, азаза!
Неплохое решение от ОПа (вроде бы), только кучу всего надо изучать, наверное, я пока теоретик.
Ну а если зарегистрирован на самом сайте, то и шут бы со всем этим, если не нарушает какие-либо правила.
>>29535
У меня такой.
Так он не меняется в обычной ситуации, когда не отключаешь роутер. А если часто включаешь-выключаешь и находишься на сайте - тоже не всё чисто.
13 729548
>>29546
Оговорюсь: тогда речь шла о простом доступе к сайту, без регистрации на нём, говорили об анонимных лайках, как сейчас помнится.
14 729613
Оп, подскажи, когда лучше всего начать читать Шлосснейгла и Зандстру? В каком порядке? До знакомства с этим тредом, я начал читать обоих, но через ~ 70 страниц дропнул, т. к. мало что понял, а то, что понял, быстро забыл. Ибо без практики теорию плохо усваиваю.
На данный момент, я уже решил больше половины задач по сосновам: все до дополнительных задач, одну дополнительную (про банкомат), 2 из 4 про ООП.
157 Кб, 550x827
15 729793
http://ideone.com/P5Opwm // ООП. Два типа вопроса

И в прошлом треде за 27ое число три задачи без ответов, просил напомнить:
Числа прописью https://2ch.hk/pr/res/715010.html#728416 (М)
Объекты в PHP, часть 2 https://2ch.hk/pr/res/715010.html#728419 (М)
Задача про банкомат https://2ch.hk/pr/res/715010.html#728599 (М)
16 730130
>>29497

Верно, массив копируется при клонировании. Но в копии содержатся ссылки на старые объекты. Если тебе будет так проще понять, представь что у нас все объекты пронумерованы и переменные хранят просто их номера.

Когда ты делаешь

$x = clone $x;

Ты делаешь клон объекта и помещаешь его идентификатор в $x, но в массиве-то остаются старые идентифиаторы.

> foreach ($this->varName as &$a) {


А ты изучил мануал по ссылкам? Изучи сначала тогда этот раздел от кроки до корки, а не копируй бездумно код.

>>29503

> Что если потенциальные хацкеры напишут программу, которая будет пытаться подобрать куку с SESSID.


Надо сделать код достаточно длинным, чтобы было очень много вариантов кода и перебрать их было нереально. Например если брать 32 цифры или латинских буквы (с учетом регистра) то получается 62 в 32 степени вариантов, и это очень много: https://www.google.ru/search?q=62^32=&newwindow=1&gbv=1&sei=lHciV7CVO-md6ATQnreIAw

> Этот SESSID так же прописывается в БД.


Ты учел что можно залогиниться с нескольких браузеров на разных компьютерах?

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

>>29508

Сообщить разработчикам сайта

>>29516

Он хотел тебе сказать про число вариантов для перебора я думаю

>>29524

На мобильных устройствах при пропаже сигнала или переходе от сот к соте теоретически может происхоlить разрыв связи и выдача нового IP. да и у некоторых домашних провайдеров (если они используют какой-нибудь PPP) это бывает.

>>29613

Дойди в моем учебнике до ООП и можешь параллельно начинать читать.
16 730130
>>29497

Верно, массив копируется при клонировании. Но в копии содержатся ссылки на старые объекты. Если тебе будет так проще понять, представь что у нас все объекты пронумерованы и переменные хранят просто их номера.

Когда ты делаешь

$x = clone $x;

Ты делаешь клон объекта и помещаешь его идентификатор в $x, но в массиве-то остаются старые идентифиаторы.

> foreach ($this->varName as &$a) {


А ты изучил мануал по ссылкам? Изучи сначала тогда этот раздел от кроки до корки, а не копируй бездумно код.

>>29503

> Что если потенциальные хацкеры напишут программу, которая будет пытаться подобрать куку с SESSID.


Надо сделать код достаточно длинным, чтобы было очень много вариантов кода и перебрать их было нереально. Например если брать 32 цифры или латинских буквы (с учетом регистра) то получается 62 в 32 степени вариантов, и это очень много: https://www.google.ru/search?q=62^32=&newwindow=1&gbv=1&sei=lHciV7CVO-md6ATQnreIAw

> Этот SESSID так же прописывается в БД.


Ты учел что можно залогиниться с нескольких браузеров на разных компьютерах?

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

>>29508

Сообщить разработчикам сайта

>>29516

Он хотел тебе сказать про число вариантов для перебора я думаю

>>29524

На мобильных устройствах при пропаже сигнала или переходе от сот к соте теоретически может происхоlить разрыв связи и выдача нового IP. да и у некоторых домашних провайдеров (если они используют какой-нибудь PPP) это бывает.

>>29613

Дойди в моем учебнике до ООП и можешь параллельно начинать читать.
17 730263
Интересное чтение по IT тематике

https://m.habrahabr.ru/post/282674/
https://m.habrahabr.ru/post/282644/
18 730277
При настройке апача куда в файл настроек вписывать вот это?
#
LoadModule php5_module "c:/php/php5apache2.dll"
AddHandler application/x-httpd-php .php

# конфигурирование пути к php.ini
PHPIniDir "C:/php"
Просто скопировать в любое место?
19 730285
Почему программы работающие на ideone, выдают ошибки при запуске в своём браузере? Нужно доустанавливать какие-то компоненты?
20 730290
час ломал голову над тем как организовать структуру программы на Го. Официальные мануалы рекомендуют использовать GOPATH и складывать все в домашнюю папку, но по моему это идиотизм. Я хочу чтобы проект был в своей, отдельной папке, чтобы я мог в любой момент скопировать его, забекапить, и тд., а не сваливать все проекты в одну общую папку. Также, я не хочу хранить код в домашней каталоге а хочу хранить его под виндой, копировать в /tmp на линуксе и там его запускать и желательно без переменных окружения. Также я хочу разбить приложение на приложение-специфичный код и универсальнй код и вынести тот отдельно. Вообще, такое ощущение, что язык рассчитан на написание простых утилит помещающихся в один файл. Не верьте клоунам которые говорят что Го может что-то там заменить
21 730337
>>729418

>$validate = [


>'validateName' => 'getName',


>....


>];


А разве ключом не должно быть название поля? Как тогда обозначить ключ ошибки?

>>729418

>


>В качестве значения по умолчанию нельзя использовать выражение. И по моему ты плохо понял что написал. Когда ты пишешь


>


>$this->x = func();


>


>ты не сохраняешь функцию в поле. ты сохраняешь то,что она вернула - число например.


Нет нет, я понял что здесь подвох. Я просто не знал про функцию call_user_func.
22 730350
Господа, посоветуйте рабочее окружение под макось.
Задача разработка проекта на php, постоянно этим не занимаюсь поэтому особо в дебри лезть каких-то крутых иде не хочется. Что-то бесплатное чем можно комфортно выполнить задачу, пример из мира винды xampp + notepad++ например.
23 730507
>>30350
xampp для Mac чем не устроил? + atom/sublime/visual studio code.
24 730518
Можно ли перебирать массив с объектами с помощью foreach и вызывать методы каждого объекта, таким образом:

foreach ($this->departaments as $departament) {

$quantity = $departament->countEmployees();

$result[$departament->name] = $quantity;
}
25 730520
>>30518

>$result[$departament->name] = $departament->countEmployees();


Вполне.
26 730522
>>30507
Я еще не пробовал, решил сперва посоветоваться. Благодарю!
27 730528
>>30522
Советовал бы ставить всё по отдельности.
Не повторяй моих ошибок.
Apache, PHP, MySQL. И дальше IDE, которые советует анон.
28 730529
>>30528
А в чем могут быть проблемы? Я пару лет назад делал задачу на винде и хамп отлично справился.
29 730533
>>30529
1. Если проект потом переносить на сервер, то могут быть проблемы из-за настроек.
2. РНР там какой-нибудь 5 версии и не самой последней.
3. Perl Там на хрен не нужен тебе.
4. MariaDB тоже на хрен не нужна, Мускул таки лучше и ТРУЪ.
30 730537
>>30533
А эти отдельные пакеты я потом смогу удалить из системы? Задумался, может просто поставить это на виртуалку все...
31 730666
>>29430 (OP)
Ребзи, с помощью чего на PHP можно замутить систему лобби ? Хватит ли одного Аякса ?
32 730668
>>30666
На пхп такое делать будет неудобно. Я бы смотрел в сторону модного жс-фреймворка на фронт, и ноду\пайтон на бэкэнд.
33 730673
>>30668
Почему ? Неужели всё на столько сложно ?
34 730674
>>30673
Нет, он тралит.
Любой фреймворк на РНР для бэкенда, Аякс да хоть чистый JS для фронтенда.
35 730676
>>30674
Я чето слабо себе представляю как вообще такое реализовывать, даже с аяксом. Вот люди, сидящие на странице, отправляют аяксом пост запросы о своём присутствии в лобби, но что сервер должен с ними делать? Не в базу же заносить? Как их передать другим участникам лобби?
89 Кб, 807x792
36 730678
>>30674
Так а может какие-то сокеты посоветуешь ? Или на чистом аяксе можно всё сделать ?
37 730679
>>30673
Несложно, но аякса явно не хватит.
Нужен reactPhp.
38 730680
>>30676
Ну пускай они в лобби сидят, как на отдельной генерируемой страничке. Или не прокатит ?
39 730681
>>30680

>Ну пускай они в лобби сидят, как на отдельной генерируемой страничке


Wat? Во первых это как, а во вторых вопрос о передаче юзерам инфы друг о друге всё еще в силе.
40 730683
>>30676
На вебсокетах такие лобби делают обычно. Проблема в том что на пхп есть один вариант, это reactphp. И не важно нормальный он или нет, тебе все равно нужно будет его использовать, если хочешь реализовать такое на пхп. Я думаю проще было бы взять ноду и сделать все на ней.
41 730684
>>30681
Ну вот зашли они по факту на отдельную страницу, созданую для них двух, и Аякс там манипулирует ДОМ"ом и в реальном времени меняет то что нужно. Или так нельзя ?
42 730685
>>30683
Блеа. но мне не нужна нода, мне нужен php ...
дело в том, что на PHP уже многое сделано. Нужно уже добить.
43 730686
>>30684
Отдельная страница или нет, и что там аякс с домом делает это второстепенные вопросы. Главная проблема передать друг другу какую-то инфу, будь то сообщение в чате, или профиль.
44 730688
>>30685
Погугли что такое веб-сокеты и как они работают, потом возьми библиотеку для PHP которая реализует эти вебсокеты. Фронт на жсе, бэкэнд на пхп, и не нужно никаких аяксов, ноды и пайтона.
Для примера вот Ratchet http://socketo.me/ вроде как вполне норм.
>>30684
А ты подумал как в таком случае сделать обновление в реальном времени? Отправлять на сервер запросы каждые n секунд? В таком случае не слишком ли большая нагрузка будет для простого лобби с чатом?
111 Кб, 599x958
45 730691
>>30688
Окей. Спасибо. Доверюсь тебе.
46 730763
Анон, пытаюсь пилить свои ВЕБ ПРИЛОЖУХИ. Стоит ли выучить синтаксис питона и попытаться вкатиться в джангу? Какие перспективы у пхп и джанги? У пхп синтаксис вроде гибче, да и я с него начал, даже поработать на нем не успел, а уже смотрю на питон. Стоит ли?
47 730779
>>30763
Вперед и с песней.
48 730781
>>30779
Ой, ну объясни нормально, анон, что ты сразу.
sage 49 730792
>>30785 (Del)
Fuck you.
55 Кб, 600x763
50 730857
Дошёл до ООП.
Поясните по хардроку, как вообще это функционирует на сайтах.
1. Вот у меня файл .php со скриптом, там ООП, классы, вот это всё, ему нужны экземпляры класса создавать - как-то надо подключать их, ставить на место созданий экземпляра include с файлом, уже содержащим созданные классы? Я правильно понимаю логику? Или это всё возможно через БД - оттуда брать инфу и вставлять в скрипт?
2. Соответстветственно, ещё какой-нибудь скрипт отвечает за заполнение этого скрипта с экземплярами класса или БД с ними. Например, это студенты - скрипт собирает с регистрацией набивает БД студентами как экземплярами класса Student, а ты потом их вставляешь хитроумным способом в свой первый скрипт с ООП и вертишь там по-всякому.
Я верно это представляю себе?
51 730943
Азаза, задача 4 na JS с засадой такой, еле решил. Там так и подразумевалось, что apply надо использовать? Или есть другой более простой способ?
http://ideone.com/asjGPa
52 730967
>>30857
ООП - это такой стиль программирования, который придумали чтоб совсем не ахуеть с мильенами строк кода в разрастающихся приложениях. Оно типа упрощает все, структурирует.
Объекты эта такая штука, которая позволяет создавать тебе что-то вроде собственных типов данных, такие, как например уже знакомые тебе массивы. Очень гибкая и удобная.
Когда ты описываешь конструкцию class MyClass{}; ты типа вводишь новый тип данных в окружение и после этого можешь создавать экземпляры этого типа инструкцией new MyClass;. Я особо не шарю, но вроде и обычные массивы тоже можно создавать в таком стиле - $array = new ArrayObject;
Касательно где создавать экземпляры - там же где и массивы, если бы ты использовал их вместо специально созданного тобой класса студента.
53 730969
>>30857

>ставить на место созданий экземпляра include с файлом


Нет, юзай композер.

>Или это всё возможно через БД


БД вообще тут не при чем.

>ещё какой-нибудь скрипт отвечает за заполнение этого скрипта с экземплярами класса или БД с ними


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

>Я верно это представляю себе?


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

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

В MVC как ты наверно знаешь, приложение делят на 3 части - модель (не та модель что описана выше, а модель как 1/3 часть приложения), контроллер и вид. Ну вот, собственно в коде обычно ты в начале создаешь всякие нужные сервисы, контроллер и запускаешь его. А контроллер например просит у TDG взять из базы 10 студентов, и передает этих студентов в вид, который отображает их на HTML странице. Как-то так.

Читай замечания к задаче про студентов, все там подробно расписано. И конечно читай урок про ООП очень внимтельно и решай задачи там.
55 730978
>>30973

Разумеется разделение на модели и сервисы не очень четкое. Вот например что такое контроллер? С одной стороны это не модель так как он не соответствует никаким реальным объектам и не хранит информацию о них. С другой стороны это не совсем сервис, так как мы часто создаем новый контроллер на каждый новый запрос от пользователя. Хотя есть фреймворки который считают что контроллер это сервис. А некоторые считают что это такой "одноразовый сервис", который создается, обрабатывает 1 запрос пользователя и выбрасывается в корзину.
56 730987
>>30978

>это не совсем сервис, так как мы часто создаем новый контроллер на каждый новый запрос


Но ведь сервисы тоже создаются на каждый новый запрос
57 730995
>>30987

Ты подразумеаешь стндартную модель работы php когда скрипт обрабаывает запрос и завершается:

- создать все нужные сервисы
- проанализировать запрос
- сгенерировать ответ
- выйти

А вещи вроде взаимодействия с браузером по HTTP реализуют веб-сервер и ядро php.

Но PHP можно использовать и в другом сценарии:

- создать все нужные сервисы
- открыть порт и ждать входящий HTTP запрос
- бесконечно повторять {
-- принять запрос
-- проанализировать запрос
-- сгенерировать ответ
}

Эта модель имеет как преимущества так и недостатки:

+ инициализация делается 1 раз а не на каждый запрос
+ можно сохранять какие-то данные между запросами в памяти в переменных (напрмиер какие-то часто используемые данные можно загрузить в начале из БД в массив и дальше брать из него с огромной скоростью. Это хорошо работает только для read-only данных вроде всяких справочников которые не меняются в процессе работы)
+ соответственно не нужны кеши байткода вроде APC, opcache так как скрипты компилируются в момент запуска приложения а не при каждом запросе
- требуется большая внимательность. В стандартном подходе мы не боимся утечек памяти так как после заверщения скрипта она очищается, а тут может получиться такая ситацция что расход памяти будет расти, она закончится и наше приложение упадет
- опять же при какой-то фатальной ошибке падает все приложение а не обработчик одного запроса. Это обычно решают автоматическим перезапуском приложения при падении

В таком сценарии сервис может пережить много запросов, а например контроллер будет на каждый запрос создаваться новый (так как это проще чем очищать состояние). В других языках вроде явы именно такая модель используется и там сервисы долгоживущие.
57 730995
>>30987

Ты подразумеаешь стндартную модель работы php когда скрипт обрабаывает запрос и завершается:

- создать все нужные сервисы
- проанализировать запрос
- сгенерировать ответ
- выйти

А вещи вроде взаимодействия с браузером по HTTP реализуют веб-сервер и ядро php.

Но PHP можно использовать и в другом сценарии:

- создать все нужные сервисы
- открыть порт и ждать входящий HTTP запрос
- бесконечно повторять {
-- принять запрос
-- проанализировать запрос
-- сгенерировать ответ
}

Эта модель имеет как преимущества так и недостатки:

+ инициализация делается 1 раз а не на каждый запрос
+ можно сохранять какие-то данные между запросами в памяти в переменных (напрмиер какие-то часто используемые данные можно загрузить в начале из БД в массив и дальше брать из него с огромной скоростью. Это хорошо работает только для read-only данных вроде всяких справочников которые не меняются в процессе работы)
+ соответственно не нужны кеши байткода вроде APC, opcache так как скрипты компилируются в момент запуска приложения а не при каждом запросе
- требуется большая внимательность. В стандартном подходе мы не боимся утечек памяти так как после заверщения скрипта она очищается, а тут может получиться такая ситацция что расход памяти будет расти, она закончится и наше приложение упадет
- опять же при какой-то фатальной ошибке падает все приложение а не обработчик одного запроса. Это обычно решают автоматическим перезапуском приложения при падении

В таком сценарии сервис может пережить много запросов, а например контроллер будет на каждый запрос создаваться новый (так как это проще чем очищать состояние). В других языках вроде явы именно такая модель используется и там сервисы долгоживущие.
58 730996
>>30973
Модель - это не обязательно сущность. Только в небольших приложениях позволительно использовать ORM. Сразу видно, что ты новичок и никогда не работал с реальными проектами.
59 730998
>>30995

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

в случае умирающего подхода эта проблема решается сама собой, а вот в долгоживущем приложении ты еще замучаешся ее искать. В некоторых языках вроде Явы или C# (и даже в Хроме в инструментах разработчика) есть профайлеры памяти, позволяющие узнать кто сколько отъел, а вот в php вроде простого способа нет.

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

Если ты будешь делать логгер SQL запросов или чего угодно в массив - ограничивай его размер.
60 730999
>>30996

Поясни. Я про ORM ничего не говорил и есть подозрение что ты ошибаешься.
61 731041
>>723256

>> Я не вижу такого решения с помощью цикла, только прописывать всё в ручную


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


>


>$fieldName = 'year';


>$this->{$fieldName} = 1990;


>


>И соответственно можно использовать цикл по массиву разрешенных имен полей:


>


>$fields = ['name' ,surname'];


>foreach ($fields as $field) {


>....


>$this->{$field} = ....;


>}


Цикл не годиться потому что в массиве могут придти любые данные.

>Могут быть какие-то поля (например статус модератора) которые не должны заполняться из пришедших данных.



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

function fillFromArray(array $data)
{
$allowed = ['name', 'surname', ...];

foreach ($allowed as $value) {
$this->$value = $data[$value];
}
}

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

>А почему именно из массива? Вот например у меня раньше брались данные из $_POST, и я подумать не мог что они будут браться откуда-то еще. Если мы собрались расширять гибкость кода, то давайте расширять до конца. Например, мы можем получать данные и из объекта.

61 731041
>>723256

>> Я не вижу такого решения с помощью цикла, только прописывать всё в ручную


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


>


>$fieldName = 'year';


>$this->{$fieldName} = 1990;


>


>И соответственно можно использовать цикл по массиву разрешенных имен полей:


>


>$fields = ['name' ,surname'];


>foreach ($fields as $field) {


>....


>$this->{$field} = ....;


>}


Цикл не годиться потому что в массиве могут придти любые данные.

>Могут быть какие-то поля (например статус модератора) которые не должны заполняться из пришедших данных.



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

function fillFromArray(array $data)
{
$allowed = ['name', 'surname', ...];

foreach ($allowed as $value) {
$this->$value = $data[$value];
}
}

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

>А почему именно из массива? Вот например у меня раньше брались данные из $_POST, и я подумать не мог что они будут браться откуда-то еще. Если мы собрались расширять гибкость кода, то давайте расширять до конца. Например, мы можем получать данные и из объекта.

62 731052
Анон, есть несколько вопросов от полного нубаса по Doctrine ORM:

1) Модели можно объявить через PHP-классы, XML и YAML? Вторые два способа редко используются или как?

2) Где в модели указываются типы значений, внешние ключи и т.д.? Вижу в туторе комментарии над полями моделей, это оно что ли?

3) Миграции из коробки есть или надо модуль устанавливать?
63 731130
Уже пхп7 вышла. слыхали? Кто-нить тестировал на лампе? Какие обновы?
64 731147
>>31052

> Модели можно объявить через PHP-классы, XML и YAML?


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

> Где в модели указываются типы значений, внешние ключи и т.д.? Вижу в туторе комментарии над полями моделей, это оно что ли?


Это называется аннотации. Каждая аннотация представлена классом, и там даже поддерживаются неймспейсы то есть когда ты пишешь

use .... as ORM;

@ORM\Table(name=....)

То ты ссылаешься на класс Table из внутренностей доктрины: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Mapping/Table.php у которого как ты видишь есть свойство name.

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

https://github.com/doctrine/annotations
https://github.com/doctrine/annotationshttps://github.com/doctrine/annotations

> Миграции из коробки есть или надо модуль устанавливать?


есть https://github.com/doctrine/migrations но я им не пользовался. Попробуй, можешь рассказать нам потом о впечатлениях от исопльзования.

>>31041

> Единственный способ с циклом которые я вижу, это использовать в методе массив с белом листом полей которых можно заполнить


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

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


>>А почему именно из массива? Вот например у меня раньше брались данные из $_POST, и я подумать не мог что они будут браться откуда-то еще. Если мы собрались расширять гибкость кода, то давайте расширять до конца. Например, мы можем получать данные и из объекта.



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

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

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

То есть я не вижу смысла, но если ты хочешь, можешь сделать функцию берущую данные из другого источника кроме массива.
64 731147
>>31052

> Модели можно объявить через PHP-классы, XML и YAML?


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

> Где в модели указываются типы значений, внешние ключи и т.д.? Вижу в туторе комментарии над полями моделей, это оно что ли?


Это называется аннотации. Каждая аннотация представлена классом, и там даже поддерживаются неймспейсы то есть когда ты пишешь

use .... as ORM;

@ORM\Table(name=....)

То ты ссылаешься на класс Table из внутренностей доктрины: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/Mapping/Table.php у которого как ты видишь есть свойство name.

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

https://github.com/doctrine/annotations
https://github.com/doctrine/annotationshttps://github.com/doctrine/annotations

> Миграции из коробки есть или надо модуль устанавливать?


есть https://github.com/doctrine/migrations но я им не пользовался. Попробуй, можешь рассказать нам потом о впечатлениях от исопльзования.

>>31041

> Единственный способ с циклом которые я вижу, это использовать в методе массив с белом листом полей которых можно заполнить


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

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


>>А почему именно из массива? Вот например у меня раньше брались данные из $_POST, и я подумать не мог что они будут браться откуда-то еще. Если мы собрались расширять гибкость кода, то давайте расширять до конца. Например, мы можем получать данные и из объекта.



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

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

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

То есть я не вижу смысла, но если ты хочешь, можешь сделать функцию берущую данные из другого источника кроме массива.
65 731200
Здравствуйте господа. Подскажите пожалуйста а где проходит обсуждение задач из материала для новичков? А то есть вопросик по решению, но вдруг он уже задавался.
1,3 Мб, 866x2934
66 731208
Спасибо за ответы, братья, люблю вас.

>>30967
Это я в общих чертах понял. Но просто мы до ООП делаем так, что всё находится в одном скрипте, в одном файле. Мне интересен сейчас сам механизм - правильно ли я его себе представляю. Что надо подключать разные файлы к скрипту, создавать скрипты, которые отвечают за заполнение этих файлов. Либо не файлы, а строки в БД - оттуда как-то вставлять.
Я пока лишь разбираюсь в ООП - просто на будущее.
>>30969

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


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

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


Вот это ответ на мои вопросы, спасибо, это как раз интересовало больше всего.
>>30973
Спасибо, неплохо расписано!

>контроллер например просит у TDG взять из базы 10 студентов, и передает этих студентов в вид, который отображает их на HTML странице. Как-то так.


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

>мы часто создаем новый контроллер на каждый новый запрос от пользователя.


Хм, сложновато для меня пока.
Но что-то уже формируется, займусь-ка ООП.
67 731209
>>31200
Тут и происходит. Просто новичков сейчас мало. Наверно куличи пекут. Кидай вопросы и код не забудь.
68 731213
>>30998

>Если ты будешь делать логгер SQL запросов или чего угодно в массив - ограничивай его размер.


А если нужны прежние данные для чего либо (для статистики, например)?
Можно ли как-то настроить, чтобы раз в какой-либо промежуток времени этот массив становился равным массиву $period? Каждый раз разный, конечно, название - по первому моменту и по последнему моменту. Например, $mon2may2016_sun8may2016, что-то такое.
Так, стало интересно.
69 731223
>>31147
По поводу Доктрины:
Миграции автоматически анализируют аннотации полей и создают поля нужногл типа и связью в БД? Вообще странный подход в комментариях указывать такие важные вещи. В Джанго ОРМ и Алхимии, просто как параметр в конструкторе каждого поля передаётся.
70 731224
>>31208

> А как быть, когда уже созданы экземпляры? Они же где-то хранятся? В файлах или в БД лучше?



Экземпляр класса (объект) нельзя хранить в бд или файле, он хранится в памяти, единственные способы его создать - new или clone, нельзя сохранить произвольный объект в файл и восстановить (есть сериализация но она не работает с любыми классами).

Да и подумай, если бы мы вдруг хранили объекты в бд, нам нужен бы был объект который их оттуда достает, это проблема курицы и яйца.

Что касается кода то код хранится в файлах. Более удобного способа никто не придумал пока.
71 731225
>>31209
http://ideone.com/85fwQ6
Вот такое дерьмо написал по задаче с кубиками. Все время пишет что выиграл комп. Где я обосрался помимо того что родился?
Заранее благодарю.
72 731226
>>31223

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

> PHP Notice: Undefined variable: anonDIce2 in /home/ruUGkD/prog.php on line 13



пишет что нет такой переменной. Ты там большую букву с маленькой не перепутал?
74 731246
>>31227
Благодарю, Антоний, я и правда с регистром одной буквы обосрался.
75 731255
http://ideone.com/jwFmMH
Я в правильном направлении?
76 731304
>>31224
Ну, я имел в виду, что не в готовом виде хранится, а в отдельных соответствующих полях.

$student1 = new Student();
$student1->number = 321;
$student1->name = "Иван";
$student1->surname = "Иванов";
$student1->team = 2;

Вот эти "Иван", "Иванов" и 2 ведь хранятся в БД, а потом используются при создании экземпляра класса, когда надо вывести это всё или произвести иные действия?
Я не имею в виду, что вот такое создание экземпляра хранится в БД, а только эти элементы для создания.
Иначе как быстро доставать студента из файла? Ведь должно быть проще достать его из БД?
Я, наверное, неправильно сделал, что полез со своими вопросами - всё равно еще пока ООП не рассмотрел, ты уж извини, анончик.
Ну просто захотелось всё себе представить.
77 731305
>>31147

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


Да, есть, у меня класс Формы наследуется от класса студента, следовательно даже будет лучше, если у меня будет метод которые будет принимать данные и из массива и из объекта. Однако, этот метод всё равно придется переопределять в классе Формы потому что класс Формы содержит пароль и повторныйПароль, а класс Студента содержит хэш.

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

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

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

>>31147

>Но у объектов поля жестко заданы и даже если они называются одинаково это не значит что они связаны.


Элементы массива тоже могут быть не связанны.
76 Кб, 700x500
78 731308
Можно ли сразу начать изучать Yii2, или лучше сначала изучить Yii самый первый?
Помню, анон расписывал всё чётко, когда кто-то задавал такой вопрос, только я забыл, в чём была суть, лол.
Вроде Yii2 советовал, потому как первый вариант уже устарел чутка.
79 731312
>>30130
Я и есть один из разработчиков, мне нужно понять как работает xss уязвимость и чего я добьюсь тем что в инет. Магазине подменю свои кукизы чужими и зайду под чужим акком
23 Кб, 298x291
80 731320
>>31130
А ты быстрый! Обновления в основном "в ядре", теперь PHP стал более пригоден для хайлоада (но все равно еще на порядок медленнее чем остальные языки). Ну и по мелочи сделали возможность объявлять скалярные типы, объявлять какой тип вернет функция, анонимные классы и многое другое. Полный список новых вещей почитать можно тут http://php.net/manual/en/migration70.new-features.php
81 731341
Как в слиме изменить ответ? Почему-то он шлет мне всю страницу с разметкой, куда я уже только не пихал die() и exit(), один хуй отправляет всю страницу. Нужно же изменить body в responce? Но как? Гугл не помог.
82 731350
Как через php передавать на каждую страницу html-код интерфейса? Ну чтобы не прописывать каждый раз html-код а "вызывать" его и тем самым формировать вёрстку веб-страницы.

Автоматизировать процесс, так сказать.
83 731356
Хочу вместо локалхоста упражняться на каком-то хостинге, чтобы сразу видеть результат "какой будет". Посоветуйте хостинг.

Желательно, халявный или чтобы раз вносить оплату.
84 731402
>>31356
раньше мог посоветовать hostinger, но эта параша теперь требует смс-валидацию через смс(которая стоит почти 2 бакса).На данный момент нашел только один нормальный - 2freehosting.com Косяк там есть, но не знаю ошибка сайта или ограничение фри-версии акка - не делает бекап.
85 731404
>>31356
>>31402
https://beget.ru/ 100 рублей в месяц.
86 731436
>>31404

>Желательно, халявный


>халявный


731402-кун
87 731440
>>31436
Бесплатный сыр только в мышеловке, пора бы уже это понять.
88 731453
>>31440
ну я уже год работаю на этом хостинге, брат жив.Иногда сайт падает, но это незначительный минус.
89 731456
>>31312
Если куки чужая, то сможешь под этим акком заказы делать.
90 731458
>>31456

>заказы делать


не забывай о тайм-ауте сессии и сроке работы печеньки
91 731535
>>31404
За сто рублей можно впску взять с 256 оперативки и 10 гигами места. Это более чем достаточно для бложиков до 10к трафа и своих маня проектиков. Заодно придрочишь скилы в настройке сервера и работы по ссх. Оно тебе нужно будет.
92 731538
>>31535
Что-то я не видел таких впсок по 100 рублей. Везде минимальная цена 400 - 600 за самый дешевый тариф.
67 Кб, 796x457
93 731549
>>31538
Сто рублей это без админ панели или как она там называется. Ее можно прикупить, тогда будет рублей 400/мес, да.
Вот например: firstvds.ru/products/vds_vps_cheap
70 Кб, 1157x235
94 731563
>>31549
Вот еще одна, сам ей пользуюсь - x5x.ru. В чикаго/денвере не советую брать, пинг в консольке будет пиздецовый и дороже немного. Разве что для впн.
Рефочка http://x5x.ru/?aff=4349
95 731604
>>31458
Так я сделаю заказы, менеджеры свяжутся с клиентом в любом случае и очевидно что отменят заказ, даже если не отменят - он приедет не мне, а если я укажу удобный мне адрес - там либо предоплата по карте либо наложенный платеж, в самом аккаунте инфы о карте очевидно что нет, в итоге профита особого и нет как мне кажется.
96 731615
>>31402
А как на 2freehosting.com по FTP коннектнуться? Не работает что-то нихуя, как я не изголялся. Анон, что нужно-то? Прописываю порт, айпишник, имя, пароль от cPanel и сосу с "невозможно подключиться ко-ко-ко".
97 731619
PHP учебник, задачка про круг из фразы. Круг строится, но выглядит как дерьмо. Что я делаю не так?
https://ideone.com/TZL4rs
98 731626
>>31619
Поправь ошибки. У тебя там куча нотисов
99 731639
>>31615

>пароль от cPanel


>FTP

100 731646
>>31304

> Вот эти "Иван", "Иванов" и 2 ведь хранятся в БД, а потом используются при создании экземпляра класса, когда надо вывести это всё или произвести иные действия?


Да. Нам надо иметь возможность сохранять данные из модели в БД и наоборот, создавать модели по данным из БД. Это называется ORM - object to relational database mapping и есть 2 подхода, active record и data mapper. В комментариях к задаче есть ссылка на урок по этой теме.

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

>>31305

> Да, есть, у меня класс Формы наследуется от класса студента


Я считаю это неправильно. Форма это не разновидность Студента и вряд ли может от него наследоваться. даже если формально выполняется правило Лисков (что объект формы можно использовать в коде везде вместо объекта студента) мне кажется тут оно неприменимо.

Вот статья по теме:

https://tproger.ru/translations/inheritance-and-composition-in-java/
http://sergeyteplyakov.blogspot.ru/2012/12/vs-vs.html

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

Вот еще тут написано: https://msdn.microsoft.com/ru-ru/library/27db6csx(v=vs.90).aspx

> Наследование лучше использовать в следующих случаях.


> Иерархия наследования представляет собой отношения тождественности (is-a), а не отношения включения (has-a).



Вот попробуй ответить, какое утверждение звучит логичнее:

- "Форма Регистрации является (разновидностью или улучшенной версией) Студента"
- "Форма Регистрации содержит в себе модель Студента"
100 731646
>>31304

> Вот эти "Иван", "Иванов" и 2 ведь хранятся в БД, а потом используются при создании экземпляра класса, когда надо вывести это всё или произвести иные действия?


Да. Нам надо иметь возможность сохранять данные из модели в БД и наоборот, создавать модели по данным из БД. Это называется ORM - object to relational database mapping и есть 2 подхода, active record и data mapper. В комментариях к задаче есть ссылка на урок по этой теме.

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

>>31305

> Да, есть, у меня класс Формы наследуется от класса студента


Я считаю это неправильно. Форма это не разновидность Студента и вряд ли может от него наследоваться. даже если формально выполняется правило Лисков (что объект формы можно использовать в коде везде вместо объекта студента) мне кажется тут оно неприменимо.

Вот статья по теме:

https://tproger.ru/translations/inheritance-and-composition-in-java/
http://sergeyteplyakov.blogspot.ru/2012/12/vs-vs.html

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

Вот еще тут написано: https://msdn.microsoft.com/ru-ru/library/27db6csx(v=vs.90).aspx

> Наследование лучше использовать в следующих случаях.


> Иерархия наследования представляет собой отношения тождественности (is-a), а не отношения включения (has-a).



Вот попробуй ответить, какое утверждение звучит логичнее:

- "Форма Регистрации является (разновидностью или улучшенной версией) Студента"
- "Форма Регистрации содержит в себе модель Студента"
101 731649
>>31305

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


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

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


Это из-за того что ты считаешь Студента и Форму однотипной сущностью. Если использовать композицию, то есть сделать чтобы Форма содержала в себе Студента и записывала данные в него, эта проблема может решиться сама собой: в студенте будет поле для хеша, в форме поля для воода пароля. И кстати преобразовывать пароль в хеш форма не обязана самостоятельно - этим может например заниматься сервис авторизации в методе setStudentPassword($student, $password).

> Элементы массива тоже могут быть не связанны.


могут быть не связаны, могут быть связаны, но если пользователь передает его в метод простановки значений, то наверно они все же имеют отношение к студенту.
102 731658
>>31312

Если ты действительно разработчик то тебе надо ее закрыть, а не изучать что с ней можно сделать. Урок есть: https://github.com/codedokode/pasta/blob/master/security/xss.md

XSS похзволяет делать хакеру любые вещи от имени пользователя сайта и выводить на нем любую информацию. Как именно, я думаю, не принципиально.

>>31320

> (но все равно еще на порядок медленнее чем остальные языки)


Это же ложь. Динамические языки, такие как Руби и Питон медленнее пхп. И в php например за счет настоящих нерасширяемых классов и тайп-хинтов больше возможностей для оптимизации во время компиляции или выполнения (смотри HHVM). А на Си++ ты будешь сидеть в отладчике с утра до вечера в то время как php разработчики сделают несколько сайтов за это время.

>>31341

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

>>31350

include в шаблоне

>>31356

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

>>31440

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

>>31535

> взять с 256 оперативки


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

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

В то же время виртуалка на технллогии Xen например дает честную память, если ты что-то держишь в памяти то оно там и находится, а не в свопе. Ты можешь управлять свопом, и вообще возможностей больше. Такой тип виртуализации есть например в облаке селектела.
102 731658
>>31312

Если ты действительно разработчик то тебе надо ее закрыть, а не изучать что с ней можно сделать. Урок есть: https://github.com/codedokode/pasta/blob/master/security/xss.md

XSS похзволяет делать хакеру любые вещи от имени пользователя сайта и выводить на нем любую информацию. Как именно, я думаю, не принципиально.

>>31320

> (но все равно еще на порядок медленнее чем остальные языки)


Это же ложь. Динамические языки, такие как Руби и Питон медленнее пхп. И в php например за счет настоящих нерасширяемых классов и тайп-хинтов больше возможностей для оптимизации во время компиляции или выполнения (смотри HHVM). А на Си++ ты будешь сидеть в отладчике с утра до вечера в то время как php разработчики сделают несколько сайтов за это время.

>>31341

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

>>31350

include в шаблоне

>>31356

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

>>31440

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

>>31535

> взять с 256 оперативки


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

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

В то же время виртуалка на технллогии Xen например дает честную память, если ты что-то держишь в памяти то оно там и находится, а не в свопе. Ты можешь управлять свопом, и вообще возможностей больше. Такой тип виртуализации есть например в облаке селектела.
103 731661
Помогите разобраться с гитом. В гуи гите (GitHub Desktop) у меня были коммиты вида пикрелейтед1. Я решил освоить консольку, прочитал часть учебника по гиту из оп поста, создал тестовй репозиторий, запустил git bash, потыкал туда сюда, дошел до отправки коммита и опять я вижу пикрелейтед2. Что не так, а.
104 731664
>>31563

> OVZ


Имейте в виду что в openvz 256 мегабайт значит не то что вам даются реальные 256 мегабайт памяти, а виртуальные и условно говоря на сервере с реальными 256 Мб (или в виртуалке с Xen) вы сможете запустить больше программ чем тут. openvz позволяет оверселлить, то есть продавать больше памяти чем ее реально есть на сервере.
105 731675
>>31661

Скорее всего изменен тип окончаний строк. То есть в исходном файле например был формат окончаний строк windows (\r\n) а после изменений стал unix (\n) или наоборот. Или табы заменены на пробелы.

Как узнать реальную причину?

Для начала надо извлечь старую и новую версию файла из гита (например командой git checkout) и сохранить в отдельную папку.

Затем надо скачать hex редактор https://ru.wikipedia.org/wiki/Hex-редактор

Например https://en.wikipedia.org/wiki/HxD или бесплатный http://www.hexedit.com/ подойдет

Этот редактор покажет байты из которых состоит файл. Сравни файлы и сделай выводы.
106 731681
>>31675
Там даже самые первые коммиты (т.е. только отправленные в пустой репрозиторий) такие почти везде. Наверное у меня редактор сразу ставит не те переносы/табы?
107 731685
>>31675
Пикрелейтед 1 коммитился нормально и в гуи, и в консоле. А вот второй пикрелейтед нет. Я не понимаю причину по байтам в этом редакторе.
108 731687
>>31685
Не туда вставил скрин успешного коммита, скрин гитхаба слева должен быть у пикрелейтед2 и наоборот.
109 731732
>>31685

Посмотри внимательно на байты на первом скрипте что идут после <?php

Слева там 0D0D (\r\r), справа 0D0A0D0A (\r\n\r\n). Это разные способы обозначения конца строки, видимо ты в редакторе поменял формат конца строки.
Новое задание на MVC/JS 110 731757
Анончики, если вы уже изучили JS и DOM, гляньте этот урок: https://github.com/codedokode/pasta/blob/master/js/minesweeper-mvc.md

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

Упоминаются knockout, angular, react.

Пожалуйста, посмотрите, напишите свое мнение. Даже если вы пока плохо яваскрипт знаете.
161 Кб, 550x827
111 731758
Привет

http://ideone.com/oWbBYF // ООП. ООО Вектор. Департаменты и сотрудники
112 731799
>>31757
Хорошо. Давно хотел переделать, да всё как-то руки не доходят, да и слабо представлял MVC на жсе.
113 731813
>>31757
Спасибо, антош. Всё необходимое в одном месте собрал, мне нравится.
114 731816
Почему в некоторых примерах используются фигурные скобки при выводе переменных. А в некоторых нет?

echo "$sasamba";
echo "{$sasamba}";
115 731844
>>31758
А де у тебя среднее соотношение тугр./стр по всем департаментам?
Очень много сложноты в коде, мне кажется, гораздо проще многое возможно.
Давно хотел спросить: ты где-то учился кодингу? Чувствуется по подходу к решению задач - не совсем новичок.
116 731871
>>729415
Переделал задачу про сумму прописью.
http://ideone.com/Gq8ePe
117 731882
>>31844

> А де у тебя среднее соотношение тугр./стр по всем департаментам?



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

> Очень много сложноты в коде, мне кажется, гораздо проще многое возможно.



Да возможно, а что например?

>Давно хотел спросить: ты где-то учился кодингу? Чувствуется по подходу к решению задач - не совсем новичок.



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

По задаче вопрос, для чего тут имеет смысл использовать фабрику?
Ответы в прошлом треде 119 731919
Ответил на все посты в прошлом треде, зайдите прочитайте, если пропустил напомните о себе тут.

>>731911 числа прописью, вектор
>>731912 калькулятор, банкомат
>>731913 симфони, вордпресс
>>731915 https://github.com/fidnex/student
120 731946
>>29430 (OP)
Приветствую вас, уважаемые. Мой мозг опять решил включить тупого, и я не могу понять, где я снова обосрался, при попытке решить задачу про депозит из стартового туториала в оппосте.
http://ideone.com/qvdLfh
Вот код. Заранее благодарю за помощь
121 731948
>>31946

>PHP Parse error: syntax error, unexpected ';' in /home/dZCMd4/prog.php on line 3


Почему не читаешь уведомления об ошибках?
47 Кб, 963x452
122 731950
123 731951
>>31946

>x*10%


Поехавший чертяка. Прочитай начало самое, где рассказывается об операторах. Знак "%" нужен для того, чтобы остаток числа получить, ты не получишь так проценты.
124 731955
>>31732
Да. Увидел это сейчас в phpstorm. Спасибо!
125 731960
>>31948
Читаю, так эт хуйня пишет что нет скобочки.
>>31950
Исправил, все равно пишет что нет скобочки какой то.
>>31951
Благодярю за помощь, исправил.
126 731962
>>31960
У тебя там дофига точек с запятыми внутри for. Их должно быть три. Одинаковые вещи отделяются запятыми. Синтаксис такой:
for(Инициализация счетчика 1, инициализация счетчика 2... и тд ; условие 1, Условие 2... и т.д; увеличение счетчика 1, увеличение счетчика2... и т.д)
127 731963
>>31962

> Их должно быть три


То есть две.
28 Кб, 480x360
need help 128 731972
Реквестирую регулярку или готовый класс, или кусок кода.
Для того чтобы выдергивать ВСЕ урлы из текста.
Если есть класс, с бд всех доменов чтобы четко детектить урлы типа ololo.moscow и отличать их от от шлака типа web.hui будет вообще круто.

Строка для примера:
asdf asdf http://asdads1.ru asdf asdf asdf a11sffdads2.ru a maiZ@wlANUSmai/;OlPUNCTUMraT/u sdf asdf www.a11sffdads3.ru asdf фывафыа4.рф/ывапвыпа asdf http://фывафыа5.рф asdf a11sffdads3.ru/sdfdd фывафыа4.рф asdf
129 731974
>>31972
(http:\/\/|www\.)[^\s]+\.[a-z]{2,3}
130 731976
>>31972
все домены, минус .hui и .blya

/ [^.]*\.(?!hui)(?!blya).+ /U
131 731977
>>31976
А, сори, с ошибкой было, так правильно
/ [^.]*\.(?!hui)(?!blya)[^\s]+ /U
132 731979
>>31977
Алсо, пробелы в начале и конце строки придется обрезать через какой-нибудь trim, или используй группу захвата ().
44 Кб, 673x304
133 731987
>>725118
Привет, ОП. У меня студенты на ООП ̶b̶a̶d̶u̶m̶-̶t̶s̶s̶. Вообщем вот мой репозиторий (третий по счету) https://github.com/greenTea242/Student_List, но теперь в нем все коммиты отображаются. В него вошли два старых коммита из прошлого репозиторий и мои последние изменения.

> Тут уже возникает вопрос почему эти функции отдельные и какой смысл ставить одну куку, не поставив другую?


Установка кук для токена существует отдельно потому что в register.php проверяется защита на СSRF во время отправки формы, т.е. до момента регистрации студента и выставления оных.

>>725118
Ты мне советовал для выделения слов при поиске использовать preg_replace_callback. У меня не получилось ее правильно использовать, потому что она сразу меняет параллельно все совпадения по массиву регулярок и нигде нельзя посмотреть процесс изменения текста, а мне нужно сделать так, что если это совпадение уже в тегах <mark>, мне это не нужно делать. Данный результат мне удалось получить через дополнительный foreach. Результат по пикрелейтеду вроде правильный.
134 731989
>>31987
https://github.com/greenTea242/Student_List по традиции фиксим ссылку.
135 731990
>>31989
Хорошая традиция.
136 731997
137 732002
Дорогие похаперы, у меня вопрос. Я хочу начать изучать похапэ сам, так как я первокурсота и ждать третьего курса чтобы выучить один из самых добрых и простых языков мне лень. Так вот, в чем вопрос: Читал я ваш урок, пару книг качал - ну это же просто скука неебическая! Есть ли книжка где мне не будут объяснять что такое переменная, массив, цикл и тд. Я типа мамкины олимпиады в школе писал.
27 Кб, 715x488
138 732009
>>31919
Спасибо тебе большое.

>В сумме 60 бит энтропии. Для их записи хватит 10 символов (если каждый принимает 64 значения = 6 бит), а не 32.


Я, если честно, не совсем понимаю что это и зачем все оно нужно. Проблема в том что в моем коде неоправданно много ресурсов тратится на генерацию токена, да?

$i = 32; $hash = '';
while($i--) $hash .= chr(rand(40,126));
return $hash;
Сойдет такое? Меня возможная точка с запятой немного смущает.
139 732010
Анон, создаю базу данных в консоли, по рецепту. Но не пойму одно: где мне узнать мое имя, лол? Я его нигде не задавал, откуда мне его выдрать?
mysql> GRANT ALL ON menagerie.* TO your_mysql_name;

>your mysql name

140 732013
>>32010
А как ты в терминал SQl заходишь вообще, если не знаешь своего имени?
141 732014
>>32013
Я поставил mysql, придумал простой пароль. Захожу с помощью mysql command line
142 732015
>>32014
В этом комманд лайне нужно только пароль ввести.
143 732016
>>32015
Скорее всего под юзернеймом root сидишь
144 732017
>>32010
Создаешь пользователя, типа vasya@localhost, а потом даешь ему права на бд GRANT ALL ON menagerie.* TO vasya@localhost
145 732021
>>32017
Спасибо, браток
146 732024
1) Где хранить коды ошибок и их сообщения?
2) Как правильно сообщать об ошибках на разных уровнях: бд, валидатора, модели?
3) Где проверять логические ошибки? То есть, когда нам нужно сначала получить запись из бд и посмотреть, наш ли это комментарий, например. Пока получается нагромождение if'ов в модели.
147 732156
>>31909
Спасибо.
148 732163
>>31974
>>31977
слабовато на моем примере не со всеми ссылками срабатывает
149 732170
>>32163
(http:\/\/|www\.)?[^\s]+\.[a-z]{2,6}
50 Кб, 1709x316
150 732176
Может кто помочь?
Не могу найти что и где задаёт цвет верхней части в википедии, на скрине белым. Можете помочь понять где там её цвет менять?
151 732178
>>32176
Всё нашёл, там просто не было этого параметра!
153 732188
>>32183
suqa
(((http|s):\/\/)?(www\.)?)?[^\s]+\.[a-z]{2,6}([a-z0-9\/]+)
154 732196
>>32009

Давай я поясню более простым примером. Допустим ты генерируешь токен как

md5(rand(0, 9))

с виду кажется что это надежный токен из 32 символов но на самом деле там ровно 10 возожных вариантов, то есть по уровню защищеннности он равносилен

rand(0, 9)

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

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

> while($i--) $hash .= chr(rand(40,126));


сойдет, только я бы код оформил чуть получше, с фигурными скобками и циклом for вместо while так как в этом случае лучше будет видно что мы делаем ровно 32 итерации.

> Меня возможная точка с запятой немного смущает.


а что с ней не так? setcookie вроде бы делает urlencode для спецсимволов.
155 732200
>>32024

1) коды ошибок сделать константами, сообщения можно хранить где-нибудь в массиве или где-то еще. Но вообще я не думаю что тут так уж нужны коды, почему бы при проверке сразу не возвращать сообщения? Коды ведь не позволят сделать такое:

- поле "имя" должно содержать не более 50 символов, вы ввели 100

2) через return, например возвращать массив ошибок или объект ErrorsCollection содержащий список ошибок

3) сделать функцию валидации которая все проверяет. Подумай, что функия получает на вход? Наверно комментарий. А что дает на выходе? Список ошибок

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


ПРава доступа проверяют в контроллере, либо можно сделать функцию для из проверки (это даже лучше)

> получается нагромождение if'ов в модели.


неудобно делать валидацию в самой модели. Например не получится сделать проверку если надо обращаться к БД

Ты читал комментарии к задаче про студентов? Там вроде упомянуто это. Делается отдельный класс для валидации.
91 Кб, 309x249
156 732203
>>32196
И даже вложенные md5 не помогут? Пожалуй стоит почитать чего на тему.

>а что с ней не так? setcookie вроде бы делает urlencode для спецсимволов.


Тогда с 33 по 126 брать, довольно солидно выглядит.
157 732209
>>32188
А кириллические домены?
158 732267
>>32002
бумп
159 732272
А есть пример безопасной авторизации? Все, что находил очень старое или очень странное
160 732279
>>32002

Олимпиадные задачи и написание реальных приложений - разные вещи. Насчет учебника, если ты знаешь циклы и ифы - пропускай их, переходи сразу к массивам (если ты не изучал раньше php то ты вряд ли их знаешь так как массивы в пхп и массивы в Си это разные вещи), регуляркам, ООП. Если ты все это знаешь, можешь браться за студентов, но я бы советовал минимум решить задачи на регулярки и на ООП.
161 732301
>>32209
pidoras
/(((http|s):\/\/)?(www\.)?)?[^\s]+\.[a-zа-яё]{2,6}([a-zа-яё0-9\/]+)/ui
162 732313
>>32301

http|s - неправильно же
163 732317
>>32313
blyadina
/(((http(s)?):\/\/)?(www\.)?)?[^\s]+\.[a-zа-яё]{2,6}([a-zа-яё0-9\/]+)/ui
55 Кб, 842x396
164 732331
Аноны, можете накидать литературы по разработке модуля сайта.Модулем web-сайта будем называть программу, хранящуюся и выполняющуюся на сервере, имеющую один или несколько вариантов представления хранимой на сервере информации и интерфейс управления этой информацией. Ну либо поможете помочь разобраться? Реально это будет сделать за 1 день, даже не знаю с чего начинать. Прошу говном не кидаться.
165 732335
>>32331
Блог на wordpress
23 Кб, 652x237
166 732393
>>32317
Еще вот такая штука бывает
167 732399
>>32393
Хм, вообще вот эта часть рассчитана под такое:

>(((http(s)?):\/\/)?(www\.)?)?


А, нет, вот так надо:

>([a-zа-яё0-9\/]+)?


То есть после домена могут и не быть никакие символы.
Я с планшета, так бы давно сам проверил, соррян, делал наугад и для развлечения.
168 732421
http://ideone.com/6KVcTW
Приветствую, ананасики. Решил вот вкатиться в пхп, до этого изучал паскаль. Оцените решение задачки про рост.
115 Кб, 269x169
169 732572
>>729418

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


ОП, ну зачем ты так? Уже 5 дней ничего не пишу и только гадаю что у меня не так в КАЖДОЙ строчке. Напиши пожалуйста что не так.

>Ну например почему у тебя всюду статические методы


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

>или что за странный класс table (и погчему он с маленькой буквы?).


Это метод. Насчет странности я не понимаю о чем речь, взял тут https://laravel.com/docs/5.2/queries#retrieving-results

>Почему имя класса GetLinks начинается с глагола?


Уже переправил на PageProcessor. Как еще я мог назвать класс, который только и делает что достает ссылки из страницы? LinksExtractor?

>Тебе надо разобраться с ООП, MVC, прежде чем браться писать такие приложения. В ОП посте есть задача про студентов с комментариями, почитай. Про ООП есть в моем учебнике в ОП посте.


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

>> . Это правильно? Или надо передавать массив параметров в модель чтобы она меняла свое состояние сама?


>А за что по твоему отвечает модель? Чем она отличается от контроллера?


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

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


>А почему массив а не объект?


В Laravel view работает с массивами, но может и объект blade'y передать как элемент в массиве.
Модель не должна знать ничего про view и потому возвращать его не может.
Разобрался. Это должен делать контроллер.
115 Кб, 269x169
169 732572
>>729418

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


ОП, ну зачем ты так? Уже 5 дней ничего не пишу и только гадаю что у меня не так в КАЖДОЙ строчке. Напиши пожалуйста что не так.

>Ну например почему у тебя всюду статические методы


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

>или что за странный класс table (и погчему он с маленькой буквы?).


Это метод. Насчет странности я не понимаю о чем речь, взял тут https://laravel.com/docs/5.2/queries#retrieving-results

>Почему имя класса GetLinks начинается с глагола?


Уже переправил на PageProcessor. Как еще я мог назвать класс, который только и делает что достает ссылки из страницы? LinksExtractor?

>Тебе надо разобраться с ООП, MVC, прежде чем браться писать такие приложения. В ОП посте есть задача про студентов с комментариями, почитай. Про ООП есть в моем учебнике в ОП посте.


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

>> . Это правильно? Или надо передавать массив параметров в модель чтобы она меняла свое состояние сама?


>А за что по твоему отвечает модель? Чем она отличается от контроллера?


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

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


>А почему массив а не объект?


В Laravel view работает с массивами, но может и объект blade'y передать как элемент в массиве.
Модель не должна знать ничего про view и потому возвращать его не может.
Разобрался. Это должен делать контроллер.
170 732615
В PHP, как я понимаю, нельзя произвести редирект сразу после POST-запроса? Как обойти,коданы?
171 732630
>>32317
>>32399
Годно, а как теперь чтобы он не захватывал имейлы?
172 732647
>>32630
Он и так не захватывает
173 732654
Переделал задачу про калькулятор. Пока не доходит до меня как ввести поддержку дробных чисел.
http://ideone.com/qXKUpj
Задача про банкомат.
http://ideone.com/q63wGt
174 732719
>>32647
захватывает вместе с собакой
175 732720
>>32719
Как он их захватывает? Только если твои имейлы начинаются с www или http
176 732725
>>32720
(((http(s)?):\/\/)?(www\.)?)?[^\s]+\.[a-zа-яё]{2,6}([a-zа-яё0-9\/]+)?/u

Вот что ты споришь?
177 732741
Нужен даун фронтендщик на удаленку, но с опытом реальных проектов.
Резюме пилите на: spa1YQceship0x44ANUSyandexPUNCTUMr/j|u
178 732759
>>32725
Как-то так тогда.
\s(((http(s)?):\/\/)?(www\.)?)?[a-zа-яё]+\.[a-zа-яё]{2,6}([a-zа-яё0-9\/]+)?
Другой анон
179 732777
Анчоусы,не могу осилить 3е задание,не понимаю что от меня хотят,чтобы я сравнил суммы?

$anonDice1 = mt_rand(1,6);
$anonDice2 = mt_rand(1,6);

$compDice1 = mt_rand(1,6);
$compDice2 = mt_rand(1,6);

echo "У Анона выпало {$anonDice1} и {$anonDice2}\nУ Компьютера {$compDice1} и {$compDice2}\n";

$anonSum = ($anonDice1 + $anonDice2);
$compSum = ($compDice1 + $compDice2);

if (($anonDice1 == $anonDice2) && ($compDice1 == $compDice2)) {
echo "2 дабла - тебя ждет удача\n";
exit ();
}
180 732815
>>32759
С пробелом в начале регулярки не захватывает урл, если он в начале текста.

Еще один анон
181 732816
>>32777
Не понял вопроса.
У тебя в условии стоит если выпавшее у человека на первом кубике равно выпавшему на втором кубике, а выпавшее у компьютера на первом так же равно выпавшему на втором, то у них два дабла - выводим это и выходим из скрипта.
77 Кб, 400x369
182 732884
>>30857

>


>Дошёл до ООП.


>Поясните по хардроку, как вообще это функционирует на сайтах.


>1. Вот у меня файл .php со скриптом, там ООП, классы, вот это всё, ему нужны экземпляры класса создавать - как-то надо подключать их, ставить на место созданий экземпляра include с файлом, уже содержащим созданные классы? Я правильно понимаю логику? Или это всё возможно через БД - оттуда брать инфу и вставлять в скрипт?


>2. Соответстветственно, ещё какой-нибудь скрипт отвечает за заполнение этого скрипта с экземплярами класса или БД с ними. Например, это студенты - скрипт собирает с регистрацией набивает БД студентами как экземплярами класса Student, а ты потом их вставляешь хитроумным способом в свой первый скрипт с ООП и вертишь там по-всякому.


>Я верно это представляю себе?


Кто-нибудь может перевести на русский язык то что он написал?
183 732896
>>32884
Что тебе непонятно?
Интересно, как всё взаимосвязано на сайте.
Мы со всеми начальными задачами делаем так, что весь скрипт со всеми данными расположен на одной странице, в одном файле.
Но ведь на сайтах всё по-другому.
Что-то вводится пользователем, что-то берется из БД.
184 732920
>>29430 (OP)
Я не понимаю концепцию MVC. Вот сейчас пытаюсь ковырять yii2 и сделать на нём приложение. Мне нужна стартовая страница, где была бы простая форма, куда бы я добавил адрес треда на дваче и после нажатия на кнопку подтверждения данные треда (тема оп-поста, текст оп-поста, адрес треда и прочее) добавлялись бы в таблицу. Может кто-то на пальцах пояснить как это на yii2 реализовать?
185 732965
>>32421
бамп реквесту
186 732967
>>32741

Сомневаюсь что кто-то пойдет к "дауну" работодателю.

>>32759

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

>>32920

возможно MVC лучше изучать на примере более простого приложения без фреймворков.
7 Кб, 416x86
187 732988
Фреймворко-макака, на знающая основ, взялась за студентов.
Поэтому, пока не наделал глупостей, вопрос по роутингу: хочу создать класс Router, который будет парсить, разбивать запрос из адресной строки, а потом вызывать соответствующий контроллер и его метод. Каким образом лучше получать запрос из адресной строки? Один из вариантов - это указать в public/.htaccess правило вроде RewriteRule ^(.*)$ index.php?url=$1, чтобы все запросы вида controller/method преобразовывались в index.php?url=controller/method. Роутер проверит, если есть $_GET['url'], тогда нужно функцией explode() по слешу по слешу разбить строку, первый элемент массива на контроллер, второй на метод, остальные на параметры, а потом всё вызывать фунцией call_user_func_array(), для того, чтобы вызвать соответствующий контроллер и метод.
Второй вариант - использовать $_GET['REQUEST_URI'], но он указывает путь относительно локалхоста, то есть добавляет лишнее (пик). Вот как можно обойти: http://stackoverflow.com/a/13040861
Не слишком костыльно? Или лучше виртуальные хосты использовать?
5 Кб, 249x88
188 732991
Вот это выхлоп $_GET['REQUEST_URI'] с виртуальным хостом.
929 Кб, 1200x630
189 732992
Извиняюсь, не $_GET['REQUEST_URI'], а $_SERVER['REQUEST_URI'] в обоих случаях.
190 733003
>>32988

> Второй вариант - использовать $_GET['REQUEST_URI'], но он указывает путь относительно локалхоста, то есть добавляет лишнее (пик).


Лучше бы конечно REQUEST_URI. если испольщуешь реврайтинг надо добавлять флаг QSA иначе все GET-параметры теряются. Ну и надо помнить что сервера вроде nginx не поддерживают htaccess и не будут передавать параметр url, а REQUEST_URI должен работать везде.

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


Если он вызывает контроллер то это уже формально Front Controller а не просто роутер. Роутер никого не вызывает.

> по слешу по слешу разбить строку, первый элемент массива на контроллер, второй на метод, остальные на параметры


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

/some/page/x/1
/some/page/x/2
/some/page/x/3

что негативно может сказать на индексации поисковиками.

Как альтернатива можно использовать регулярки:

if (preg_match...) {
вызываем конроллер X;
}
191 733013
>>32896

>Что тебе непонятно?


Половину написанного.
>>30857

>Вот у меня файл .php со скриптом, там ООП, классы, вот это всё, ему нужны экземпляры класса создавать - как-то надо подключать их, ставить на место созданий экземпляра include с файлом, уже содержащим созданные классы?


Это у тебя вопросительное или утвердительное предложение? 34 слова в предложении - не многовато ли?

>Дошёл до ООП.


>Поясните по хардроку, как вообще это функционирует на сайтах.


>1. Вот у меня файл .php со скриптом, там ООП, классы, вот это всё,


Зачем ты это пишешь?

>ему нужны экземпляры класса создавать


Кому "ему"? Классу ничего не нужно. Объекты нужны тебе.

>как-то надо подключать их


Что подключать? Что? Объекты? Что значит "подключать"? Инициализировать может?

>ставить на место созданий экземпляра include с файлом, уже содержащим созданные классы?


"Созданий"? "Создания" может? Что за "include с файлом"? Пиши "include". Какие созданные "классы" у тебя в инклюде?
>>30969

>Нет, юзай композер.


Ты шутишь, да?

>БД вообще тут не при чем.


Как ни при чём если объекты заполняют с помощью массивов и таблиц БД, или в процессе работы данные узнают.

>>30857

>2. Соответстветственно, ещё какой-нибудь скрипт отвечает за заполнение этого скрипта с экземплярами класса или БД с ними. Например, это студенты - скрипт собирает с регистрацией набивает БД студентами как экземплярами класса Student, а ты потом их вставляешь хитроумным способом в свой первый скрипт с ООП и вертишь там по-всякому.


>Я верно это представляю себе?


Что тут вообще написано?
192 733018
>>33013

По моему ты занимаешься глупостью. Человек задал вопрос и получил на него какой-то ответ. Если он тебе непонятен, то возможно ты пока чего-то не знаешь. Перестань придираться к словам и тем более к опечаткам и смени тон разговора.
193 733023
>>33018

>По моему ты занимаешься глупостью.


Смени тон разговора. У человека с мышлением и рассудком не все в порядке. Мне интересно очень в каком порядке должны замкнуться нейроны чтобы вышел этот опус.
194 733027
>>33023

Это тред про программирование, а не тред грамматики, орфографии и синтаксиса.
2,7 Мб, webm,
1280x720
195 733031
ООО ВЕКТОР
Я опять выхожу на связь. Тащемта, запилил отдельные классы под каждую профессию и проверку названия профессии константой класса, например. Пока кидаю без антикризисных мер, но уже делаю их. http://ideone.com/Ery6OY
196 733033
>>33027
А программирование значит для тебя не лингвистика? И декодирование сбитой логики уже не входит в рамки анализа постановки задачи?
197 733055
>>33031

Ест правило: класс-предок ничего не знает о своих потомках. Так как классы-помтоки например могут писаться позже и заранее их наличие угадать невозможно.

У тебя это правило не соблюдается:

> if ($position == self::POSITION_MANAGER||$position == self::POSITION_MARKETER||


> $position == self::POSITION_ANALYST||$position == self::POSITION_ENGINEER)


{
$this->position = $position;
}else{
echo 'Професия введена неверно.'

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

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

Если тебе где-то надо передать идентификатор профессии, можно использовать такую конструкцию:

Marketter::class

это встроенная в пхп константа, возвращающая имя класса.

> foreach ($employees as $employee)


> {


> $this->quantity[] = $employee->quantity;


> $this->position[] = $employee->position;


Это тоже непрвильно. У тебя есть объект-сотрудник, и в нем хранится его должность, ранг. и тд. Зачем ты эти данные копируешь и храишь где-то еще? Это ведь тольео добавляет проблем. Что если у сотрудника поменяется ранг - он обновится в департаменте? Что если мы наймем или уволим сотрудника?

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

> }elseif ($this->position[$x] == 'Marketer')


> {


> $coffe = ((new Marketer($this->rank[$x], > $this->boss[$x]))->getCoffe())*$this->quantity[$x] + $coffe;


Тут жестко заложен список профессий и это не позволяет добавлять новые.

> class Company


>{


>public $total = 'Всего';


Это такое свойство компании? ЧТо оно обозначает? Какие еще значения у него могут быть?

>public $totalPersonelAmount;


>public $totalSalary;


Если я повышу сотруднику зарплату, она автоматически обновится в этом поле?

> class Employee


> {


>public $quantity;


У тебя класс называется "сотрудник" (не "группа сотрудников"), тогда почему там есть поле "количество"? И это плохая идея, так как непонятно, если у тебя один объект обозначает группу сотрудников, как например повысить ранг только одному из этой группы?
197 733055
>>33031

Ест правило: класс-предок ничего не знает о своих потомках. Так как классы-помтоки например могут писаться позже и заранее их наличие угадать невозможно.

У тебя это правило не соблюдается:

> if ($position == self::POSITION_MANAGER||$position == self::POSITION_MARKETER||


> $position == self::POSITION_ANALYST||$position == self::POSITION_ENGINEER)


{
$this->position = $position;
}else{
echo 'Професия введена неверно.'

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

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

Если тебе где-то надо передать идентификатор профессии, можно использовать такую конструкцию:

Marketter::class

это встроенная в пхп константа, возвращающая имя класса.

> foreach ($employees as $employee)


> {


> $this->quantity[] = $employee->quantity;


> $this->position[] = $employee->position;


Это тоже непрвильно. У тебя есть объект-сотрудник, и в нем хранится его должность, ранг. и тд. Зачем ты эти данные копируешь и храишь где-то еще? Это ведь тольео добавляет проблем. Что если у сотрудника поменяется ранг - он обновится в департаменте? Что если мы наймем или уволим сотрудника?

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

> }elseif ($this->position[$x] == 'Marketer')


> {


> $coffe = ((new Marketer($this->rank[$x], > $this->boss[$x]))->getCoffe())*$this->quantity[$x] + $coffe;


Тут жестко заложен список профессий и это не позволяет добавлять новые.

> class Company


>{


>public $total = 'Всего';


Это такое свойство компании? ЧТо оно обозначает? Какие еще значения у него могут быть?

>public $totalPersonelAmount;


>public $totalSalary;


Если я повышу сотруднику зарплату, она автоматически обновится в этом поле?

> class Employee


> {


>public $quantity;


У тебя класс называется "сотрудник" (не "группа сотрудников"), тогда почему там есть поле "количество"? И это плохая идея, так как непонятно, если у тебя один объект обозначает группу сотрудников, как например повысить ранг только одному из этой группы?
198 733062
Кстати, аноны, а я вот в уроке про ООП относительно недавно добавил разделы про наследование, агрегацию, исключения - они вам понятны? Что-то у меня ощущение что люди не очень понимают ООП-дизайн, проектирование классов и надо может какое-то задание сделать где надо придумать набор классов для описания чего-нибудь, например классы, которые бы описывали музыкальную библиотеку с Альбомами, Треками, группами или что-нибудь аналогичное?
199 733064
>>33062
Где урок лежит?
200 733069
>>33064

http://archive-ipq-co.narod.ru/l1/pasta.html

учебник из ОП поста же
201 733070
>>32816
Я имел ввиду,я должен сравнить суммы $anonSum и $compSum, если сумма у анона и кампуктера ровна, то объявляется ничья, итд итп.

if ($anonSum == $compSum) {
echo "Нечья\n";
} elseif ($anonSum > $compSum) {
echo "Человек победил.\n";
} elseif ($anonSum < $aiComp) {
echo "ИИ победил.\n";
}

Верно?
35 Кб, 604x579
202 733071
>>33055
>>33062
Да все понятно, только я, видимо, тупой и ленивый.
16 Кб, 200x296
203 733072
>>33013

>Половину написанного.


Согласен. Там поток сознания, писал с планшета и слегка засыпая.
Отредактирую сейчас именно тот пост:

"Дошёл до главы "Объектно-ориентированное программирование" в учебнике ОПа.
Прошу вас объяснить без лишних слов и затрагивая самую суть, каким именно образом скрипты, созданные с помощью ООП, функционируют на динамических сайтах.
1. Я создал файл с расширением .php, в нём создал скрипт на РНР, написанный с помощью ООП - там инициализированы классы, имеющие свои свойства и методы. Но ведь нам нужно каким-то образом динамически создавать экземпляры этих классов? Нам нужно как-то подключать их из сторонних файлов или базы данных? Обычно мы создавали экземпляры классов прямо в самих скриптах, а в случае с динамическими сайтами как должны поступать? В том месте скрипта, где необходимо оперировать уже созданным экземпляром класса, мы должны каким-то образом подключать сторонний файл, уже содержащий созданные экземпляры класса? Либо каким-то образом подключать информацию из базы данных? Правильно ли я понимаю логику взаимодействия разрозненных файлов в динамическом сайте?
2. Соответственно, нам могут потребоваться дополнительные скрипты, отвечающие за связь с базой данных и создание необходимых экземпляров класса? Своё предположение могу продемонстрировать на примере динамического списка студентов. Как мне кажется, для его функционирования необходим отдельный скрипт с регистрацией самих студентов (он отвечает за заполнение базы данных либо отдельного файла информацией, которая понадобится при создании экземпляров классов, необходимых для полноценной работы этого динамического списка студентов). Например, мы имеем класс Student, а в базе данных либо отдельном файле имеем информацию, которая каким-то образом должна использоваться при создании экземпляров этого класса Student. После чего мы получаем возможность тем или иным образом оперировать как с отдельными экземплярами, так и с их совокупностью.
Могу ли я считать, что мои первоначальные представления о функционировании динамического сайта верны хотя бы отчасти?"

Так лучше?

>>33018
Да, в целом я уже разобрался, спасибо братишкам. Я и хотел просто понять, верно ли я себе представляю динамику именно на самих сайтах.
16 Кб, 200x296
203 733072
>>33013

>Половину написанного.


Согласен. Там поток сознания, писал с планшета и слегка засыпая.
Отредактирую сейчас именно тот пост:

"Дошёл до главы "Объектно-ориентированное программирование" в учебнике ОПа.
Прошу вас объяснить без лишних слов и затрагивая самую суть, каким именно образом скрипты, созданные с помощью ООП, функционируют на динамических сайтах.
1. Я создал файл с расширением .php, в нём создал скрипт на РНР, написанный с помощью ООП - там инициализированы классы, имеющие свои свойства и методы. Но ведь нам нужно каким-то образом динамически создавать экземпляры этих классов? Нам нужно как-то подключать их из сторонних файлов или базы данных? Обычно мы создавали экземпляры классов прямо в самих скриптах, а в случае с динамическими сайтами как должны поступать? В том месте скрипта, где необходимо оперировать уже созданным экземпляром класса, мы должны каким-то образом подключать сторонний файл, уже содержащий созданные экземпляры класса? Либо каким-то образом подключать информацию из базы данных? Правильно ли я понимаю логику взаимодействия разрозненных файлов в динамическом сайте?
2. Соответственно, нам могут потребоваться дополнительные скрипты, отвечающие за связь с базой данных и создание необходимых экземпляров класса? Своё предположение могу продемонстрировать на примере динамического списка студентов. Как мне кажется, для его функционирования необходим отдельный скрипт с регистрацией самих студентов (он отвечает за заполнение базы данных либо отдельного файла информацией, которая понадобится при создании экземпляров классов, необходимых для полноценной работы этого динамического списка студентов). Например, мы имеем класс Student, а в базе данных либо отдельном файле имеем информацию, которая каким-то образом должна использоваться при создании экземпляров этого класса Student. После чего мы получаем возможность тем или иным образом оперировать как с отдельными экземплярами, так и с их совокупностью.
Могу ли я считать, что мои первоначальные представления о функционировании динамического сайта верны хотя бы отчасти?"

Так лучше?

>>33018
Да, в целом я уже разобрался, спасибо братишкам. Я и хотел просто понять, верно ли я себе представляю динамику именно на самих сайтах.
204 733080
>>33023
Какие нейроны? У человека просто напрочь отсутствуют представления о предмете разговора, поэтому он несет такую хуиту.
Например если бы я или ты, или другой человек совершенно незнакомый с генетикой попытался бы изложить свое представление
об этом вопросе, тоже получилась бы шизофазия вида
"ну там всякие рибосомы через митохондрии че-то там передают генетический код, код это короче типа молекула из атомов. скажите я правильно понимаю ООП генетику?"
А студенты медики такие "омг, фейспалм, ти вапщи с кокой плонети???77".

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

>>33023

>Смени тон разговора.


А ты соси хуй и не забывай где находишься. Или съеби в хабр/жж.
205 733084
>>33072

>Так лучше?


Намного. У тебя вопросы получились не про ООП, а про порядок исполнения многофайлового приложения.
>>33080
Ты посмотри что он написал >>33072. Он себе на все вопросы практически ответил.
36 Кб, 595x479
206 733087
>>33084
Отстань.
207 733133
>>33080

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


Да, всё верно.

>>33084

>У тебя вопросы получились не про ООП, а про порядок исполнения многофайлового приложения.


Да, я просто задумался об этом всём именно при изучении ООП.

>Он себе на все вопросы практически ответил.


Да, действительно.
Суть же в том, что это всё было моим предположением, я просил всего лишь объяснить этот механизм и подтвердить, верно ли я предполагаю это взаимодействие файлов.
Ну, спасибо, друзья, но не хотелось бы, чтобы это всё продолжалось - выяснение какое-то чего-то.
208 733136
При работе с сайтом URL'ы каждый раз проходят через DNS?
209 733183
Добрый день всем в этом треде. ОПчик, очень нужная твоя консультативная помощь, ну и всех кто знает. В общем такая проблема - одно время в админку получил доступ кто-то левый (неизвестно каким образом - скорее всего sql-инъекция). После этого предприняли меры - закрыли доступы в админку со всей ip кроме модераторов. Далее прошел месяц и стали отслеживаться подозрительные изменения файлов (причем не ясно это СЕОшники их делали или это какая-то третья сторона). Скрины подозрительных файлов - закрасил url нашего сайта (аяксом отправляются данные на php скрипт который курлом отправляет их куда-то). Что это может быть, как думаете?
210 733196
Спасибо, ОП, за задачи. Буду рад, если просмотрите, особенно ООП

Поиск пути: http://ideone.com/33ROxP
Текст по кругу: http://ideone.com/2q1F4N (в браузере красивее выглядел)
На вашем счету n рублей: http://ideone.com/JXvVHa

ООО Вектор: http://ideone.com/MbL6Pb (в XAMPP ошибки нет, не пойму чем ему int не нравится)
211 733202
>>33196

> public function delEmployee(int $i){


В пятом php нет тайпхинтов для скаляров.

>XAMPP


Говно из жопы.
212 733234
>>33202
А, всё, понял в чём ошибка. Просто у меня модно-новый php7, там так можно
213 733238
Есть тут yii2 боги? Хотел запилить rest api, а из коробки поддерживаются только запросы типа:
/api/x/2

А хотелось бы:

/api/x/2/y/1/z

Как быть?
214 733245
>>33238
Читать документацию.
215 733253
>>33245
Ты мне лучшую практику дай. Зачем я буду велосипеды городить?
92 Кб, 784x554
216 733360
Ответы 28 апреля 217 733641
>>29793

> ООП. Два типа вопроса


Ок, решено верно.

> И в прошлом треде за 27ое число три задачи без ответов,


На них вроде дал ответы в старом треде.

>>30277

В конфиг сервера, в винде он в папке conf Апача, в линуксе обычно в /etc/apache2/apache.conf или как-то так.

> Просто скопировать в любое место?


ну можно в конец например. Не знаю, важно ли расположение.

>>30285

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

>>30337

> А разве ключом не должно быть название поля? Как тогда обозначить ключ ошибки?


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

>>30350

На мак вроде через homebrew ставят пхп и апач.

>>30533

> MariaDB тоже на хрен не нужна, Мускул таки лучше и ТРУЪ.


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

>>30537

Если через homebrew ставить то оно вроде в отдельные папки ставится.

>>30666

Может быть, не знаю.

>>30763

Не знаю, спроси в Питон треде.

>>30943

Да. Причем можно было записать еще короче, без промежуточных переменных.
Ответы 28 апреля 217 733641
>>29793

> ООП. Два типа вопроса


Ок, решено верно.

> И в прошлом треде за 27ое число три задачи без ответов,


На них вроде дал ответы в старом треде.

>>30277

В конфиг сервера, в винде он в папке conf Апача, в линуксе обычно в /etc/apache2/apache.conf или как-то так.

> Просто скопировать в любое место?


ну можно в конец например. Не знаю, важно ли расположение.

>>30285

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

>>30337

> А разве ключом не должно быть название поля? Как тогда обозначить ключ ошибки?


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

>>30350

На мак вроде через homebrew ставят пхп и апач.

>>30533

> MariaDB тоже на хрен не нужна, Мускул таки лучше и ТРУЪ.


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

>>30537

Если через homebrew ставить то оно вроде в отдельные папки ставится.

>>30666

Может быть, не знаю.

>>30763

Не знаю, спроси в Питон треде.

>>30943

Да. Причем можно было записать еще короче, без промежуточных переменных.
Ответы 30 апреля 218 733642
>>30967

> Я особо не шарю, но вроде и обычные массивы тоже можно создавать в таком стиле - $array = new ArrayObject;


Нет, это не массив. Ты например не можешь передать его в функцию sort().

>>31213

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

>>31223

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

>>31255

Не совсем. Вот смотри:

> if ($number < 100) {


> $number = $spelling[($number % 100) - ($number % 10)].$spelling[$number % 10];



Если число меньше 100 то у него может и не быть единиц, например в числе "80"

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

> if (($a < 5) and ($a != 1) and ($a != 0)) {


> return "$textNumber ($number) рубля";


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

Ну и ошибку исправить:

> PHP Warning: Missing argument 2 for smallNumberToText(), called in /home/15mtSB/prog.php on line 66 and defined in /home/15mtSB/prog.php on line 18



>>31308

Можно

>>31604

Ты не можешь предугадать как уязвимостью воспользуются. Например с помощью XSS и социнженерии можно убедить сотрудника техподдержки что-то сделать что нужно взломщику.
Ответы 30 апреля 218 733642
>>30967

> Я особо не шарю, но вроде и обычные массивы тоже можно создавать в таком стиле - $array = new ArrayObject;


Нет, это не массив. Ты например не можешь передать его в функцию sort().

>>31213

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

>>31223

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

>>31255

Не совсем. Вот смотри:

> if ($number < 100) {


> $number = $spelling[($number % 100) - ($number % 10)].$spelling[$number % 10];



Если число меньше 100 то у него может и не быть единиц, например в числе "80"

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

> if (($a < 5) and ($a != 1) and ($a != 0)) {


> return "$textNumber ($number) рубля";


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

Ну и ошибку исправить:

> PHP Warning: Missing argument 2 for smallNumberToText(), called in /home/15mtSB/prog.php on line 66 and defined in /home/15mtSB/prog.php on line 18



>>31308

Можно

>>31604

Ты не можешь предугадать как уязвимостью воспользуются. Например с помощью XSS и социнженерии можно убедить сотрудника техподдержки что-то сделать что нужно взломщику.
47 Кб, 1342x642
219 733712
Всем хай. Имеется нубовопрос, решение на который сам найти не могу:
Есть модальное окошко-элемент с бутстрапа, хочу изменить в нем цвет тени вокруг элемента и никак не могу врубиться как это запилить, вроде и написано что через модал контент, но конкретный идентификатор элемента не представлен.
13 Кб, 380x255
220 733728
>>33003

>Это годится только для самых простых случаев.


Из этих соображений и исходил. Насчёт регулярок в роутере и бесконечное число URL. Разбивать не explode(), а регулярками? Но в таком случае удобнее воспользоваться parse_url(). Не понял.

Разбор URL и вызов соответствующих контроллеров/экшенов, получение конфига для доступа к БД пока вынес в класс App. Теперь понимаю, что это плохая идея, так как слишком много обязанностей различного характера на один класс.

И ещё, вот у меня есть StudentController c экшенами all(), one($id), create(). Модель студента содержит только свойства. За поиск студента по id, возврат всех студентов из базы отвечает StudentMapper. Конструкции на пикрелейтед допустимы? Просто я во фреймворках использовал схему обратиться к модели -> сохранить в переменную -> переменную направить во view. Почему DataMapper, а не, к примеру, наследование модели Student от класса Model, которая соединяется с БД, предоставляет методы для поиска/сохранения? Отнаследуется уйма ненужных методов?
221 733827
http://ideone.com/ZNqjGw

Почему я не могу произвести вычитание в конструкции echo если используется конкатенация строк?
222 733830
>>33712
А девтулс в браузере для кого?
223 733834
>>33827
Разобрался, причина оказалась в приоритетах операторов.
224 733838
>>33062

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


Было бы полезно очень.
>>32920-долбоёб
32 Кб, 600x396
225 733885
>>33062
Тот случай, когда прошёл урок по ООП, решил несколько задач (кроме кошек-мышек), а ОП переделал урок и теперь надо заново его проходить.
226 734054
>>33728

>Почему DataMapper, а не, к примеру, наследование модели Student от класса Model


Вот мне тут не понятно немного, разъясните за эти мапперы. Почему класс студента называют моделью, если он не работает с бд? Как в мвс приложениях с этими датамапперами работать? Это ведь то самое ОРМ?
227 734065
Заметил что на сайтах в последнее время стало модно добавлять счетчик времени на чтение, то есть бесполезный визуальный мусор. В мое время оценить объем статьи можно было по размеру двигающегося прямоугольника (забыл как он наызвается) на полосе прокрутки.

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

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


>>34054

> Почему класс студента называют моделью, если он не работает с бд?


Потому что модель студента (domain model, модель предметной области) - это объект соответствующий реальному студенту и описывающий его свойства. Почему он обязан работать с БД? Если ты где-то прочел "модель это то что работает с БД" то это неправильтно. Наверно там имели в виду Model из MVC которая отвечает за хранение данных в приложении, и включает в себя и модель студента, и маппер для сохранения ее в БД.

> Как в мвс приложениях с этими датамапперами работать? Это ведь то самое ОРМ?


да, разновидность ОРМ. Ты читал мой урок про паттерны работы с БД? active record, data mapper , table data gateway?
228 734084
>>34065
А, там модель из орм, а тут модель из мвс. Разные вещи с одинаковым названием. Пока понятно, спасибо.

>Ты читал мой урок про паттерны работы с БД?


Ага, раз десять. Еще разок почитаю.
229 734138
>>34065

>В мое время оценить объем статьи можно было по размеру двигающегося прямоугольника (забыл как он наызвается) на полосе прокрутки


Бегунок или движок. Стрелочки по бокам - кнопки прокрутки.
Сейчас на многих сайтах реализована бесконечная полоса прокрутки - перемещаешься в них экрана - а там подгружается новый контент. Так на любых социальных сетях, так даже на этой имиджборде, когда находишься в любом разделе и скроллишь в низ страницы - подгружаются новые треды.
Но, по сути, раньше это и было минимализмом - оценивал документ по этому бегунку на полосе прокрутки, а сейчас - увы - не всегда это возможно.
230 734151
>>34138
*в низ экрана
Раньше это было минимализмом - как структурированные сайты без CSS.
А сейчас - кроме как таким вот счётчиком - сложно оценить объём контента.
А когда под статьёй появляется добрая сотня комментариев и она раздвигается - тем более.
Так что, в целом, указание на примерный объём статьи - неплохая опора, ящитаю, возьму это на заметку. Встречал такое только на разных обучающих сайтах: Лингвалео, Гикбрейнс и т.п.
231 734193
>>34084
Модель в ORM не обязана взаимодействовать с базой данных.
Это ты наверное зашкварился об YII с ее AR, поэтому сложился такой стереотип, что модель это типа хрень работающая с базой данных.
То что идет в Yii это вообще не ORM, они это так назвали чисто в рекламных целях.
4 Кб, 144x113
232 734257
>>34193
Я ток вкатываюсь.
И если не модель, то как это все называется? Как мне папку назвать со всеми этими мапперами и гейтвеями?
233 734268
>>34065

>стало модно добавлять счетчик времени на чтение


Можно пример какой-нибудь посмотреть как это сделано?
234 734285
>>31844
>>33062
Новая редакция урока понятнее предыдущей. Задач мало не бывает.

Кстати, бывают абстрактные свойства, которые должны быть переопределены в классах-потомках в обязательном порядке?
235 734289
>>34193

Ну почему? Как я понимаю AR как раз одна из возможных реализаций ORM

>>34257

Не надо делать папки Controller, View, Model вообще. Разделение в MVC условное. Просто сделай все на 1 уровне:

Controller
Model
Mapper
...

>>34268

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

>>34285

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

Если тебе надо "абстрактное свойство" то лучше сделать абстрактный метод, возвращающий нужное значение.
236 734293
>>34289

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


А где посмотреть то реализацию можно? И не проще считать умножая среднее время чтения на количество слов?
Процедурки 238 734308
Аноны, чем плох процедурный код? Уже пол года пишу сайты на процедурах. Все красиво и аккуратно. Сейчас ещё и js начинаю учить чтобы сайты были более динамичнее.
239 734323
>>34299
Не увидел ничего подобного у Варламова.
Ну а на первом блоге если бы была куча комментариев, то указанное примерное время помогло бы сразу сориентироваться, не глядя на полосу прокрутки, которая вводила бы в заблуждение относительно реального объёма статьи.
240 734328
Фух, сейчас такой охуенный велосипед написал, хочется трогать себя в некоторых местах, когда на него смотришь. Все решения в гугле просто ужасны и громоздки на вид, а мое заняло 30 строчек кода.
241 734330
>>34328
Есть чё? Покежь ссылочеку, братуха!
242 734331
>>34330
Ну вы же разрушите мой манямирок сразу, я вас знаю.
243 734344
>>34330
Ладно, так и быть. Критикуйте:
http://ideone.com/sSTbuH
244 734374
>>34344

>'active'=>($i==$currentPage)? true:false


==

>'active'=>($i==$currentPage)

245 734376
>>34374
Спасибо, я уже забыл про эту фичу.
246 734503
>>34344
Говно.

Вот написал для сравнения: http://ideone.com/gW2O0v
Алсо вылезают +1/-1 из-за уродской нумерации начиная с 1.
247 734507
>>34308
Покажи пример процедурного кода.
248 734508
>>34503
Какая же пыха говнище из-за знака "$" .
Пока писал забывал его через раз, выбесило к хуям.
АЖТРИСЕТ
41 Кб, 500x500
249 734510
250 734605
Подскажите, пожалуйста, какие нибудь толковые видео уроки или уроки в текстовом виде по регуляркам.
105 Кб, 1024x683
251 734609
>>29430 (OP)
Ребята. Пишу сайтик на ПХП. В процедурном стиле. Есть файл индекс.пхп с которого производятся практически все манимуляции с сессиями и тд. Появилась потребность выполнить JS скрипт на стороне сервера.
Поясните пожалуйста, как это сделать ?
253 734689
Господа, простите за чатик, просто больше спросить негде, а у вас здесь адекватно.
Я не так давно вкатился, освоил поверхностно html и css (сейчас прохожу курсы на htmlacademy.ru для закрепления), но в какую сторону двигаться дальше?
Цель: начать фрилансить.
Я для себя наметил несколько направлений, но уже, если честно, сломал всю голову, поэтому спрашиваю у вас, не ругайтесь только, в какой последовательности лучше изучать?
То, что собираюсь выучить: JavaScript, PHP, MySQL, WP и Joomla. Хочу поскорее брать заказики на weblancer.net и остальное доучивать уже на практике, так я гораздо лучше усваиваю. А уже через полгода-год подтяну ангельский и перекачусь на upwork. Помогите лишь определиться с последовательностью? Я у кого ни спрошу, кто советует с КМСок начать, кто с ЖС, кто с пыха.
254 734791
>>34689
PHP c основами MySQL -> какой-нибудь популярный php-фреймворк (на yii2 много заказов и работы) -> JavaScript.

>WP и Joomla


Забудь про всё это говнище. Там как бы учить нечего, если знаешь php и ооп на примере хорошего фреймворка.
255 734793
Я сейчас долгое время сижу на очень странной стадии изучения пограмирования. Знаю фундамент, ООП, понимаю зачем нужны паттерны, могу пояснить за большинство понятий, с английским дружу так что при наличии гугла я богоподобен. Но мне просто не интересно писать код чтобы изучать код, я хочу задачи решать(не олимпиадные, олимпиадники пусть сосут хуи) но не могу ничего придумать. Если брать что-то простое то смысла нет, если что-то сложное то понимаешь что будешь писать велосипед. На ПХП можно написать КМС, но зачем когда их и так десятки всяких разных, опять напишу никому не нужную поеботину. Хочется все таки быть полезным. Ебучая жизнь.
256 734799
>>34793

Если ты хочешь быть полезным, сделай что-нибудь что интересно и нужно тебе самому, что может пригодиться потом и другим. Зачем писать CMS? алсо, это оффтопик получается, с этим наверно лучше в другой тред.
257 734820
>>34799

> оффтопик


Какой же оп хуй итт. Эх выгнать бы его нахуй на боброчан.
258 734857
>>34793

Я сейчас опять сижу на очень странной стадии изучения программирования. Знаю 17 управляющих конструкций, 8 типов, понимаю зачем нужен try-catch, немношко могу пояснить за историю ПХП, с английским особо не дружу, так что гугл для меня не особо полезен. Мне интересно писать код чтобы изучать код, я хочу задачи решать (хотелось бы выйти на уровень богоподобных олимпиадников), и так много их придумываю что жизни не хватит все написать. Если брать что-то сложное то смысла нет, поэтому беру простое и думаю над числом вариаций построения велосипедов. На ПХП можно написать все что угодно, но почему то даже для нужных вещей отсутствует документация, опять отгоняю от себя мысли залогиниться в группу документации и описать хоть одно расширение. Хочется все таки быть опытным. Верю что все впереди.
259 734914
Как ютюб это сделал?
260 734927
>>34914
Извиняюсь. Это фича браузера оказалась.
261 734931
>>34609
Сначала расскажи, что ты хочешь получить.
262 734963
1. Что лучше использовать в методах контроллера
[code lang="php"]
$this->view('index', [
'students' => $allStudents,
'pageTitle' => 'Студенты'
]);
[/code]
или
[code lang="php"]
$this->view->Page('index')->with([
'students' => $allStudents,
])->pageTitle('Студенты')
->render();
[/code]

2. https://designpatternsphp.readthedocs.io/en/latest/Structural/DataMapper/README.html
Почему в мане по паттерну DataMapper не используют __set() и __get()? Из-за того, что объясняется суть паттерна, а магия/сахар PHP не уместны? Или использовать __get() и __set() плохо? Мне магические геттеры/сеттеры помогли код сократить.

3. Нужно ли юзать DI-контейнеры? В процессе написания студентов понял, что мне не хватает глобальных переменных, так как первый раз пишу многостраничное приложение. Мне из контроллера нужно иметь доступ к объекту StudentMapper. Этот объект создаётся с передачей конфига для PDO. Инстанциирование StudentMapper(PDO $pdo) в контроллере выглядит уродливо, поэтому я в конструкторе контроллера получаю уже готовый объект StudentMapper, как мне кажется, так менее уродливей. Но не передавать же мне всё через конструктор? Или передавать?
345 Кб, 600x351
263 734967
Сап, /pr/. Есть один класс со статическим атрибутом, поэтому вопрос.
Значение этого атрибута будет одинаково во всех инстансах класса в каждом из запущенных скриптов например, один скрипт запустили дважды.
Или только для всех инстансов класса внутри одного запущенного скрипта?
264 734968
>>34963
Дополнение к пункту 1. В первом случае кода меньше, но смешиваются переменные. Первый случай под капотом просто require'ит путь APP_ROOT . "/views/" . первый_параметр . ".php"
Для второго случая нужно будет создавать класс и объект view.

Для того, чтобы листинги были более понятны, нужно поставить: https://github.com/ololoepepe/MakabaCode/
331 Кб, 1024x768
265 734982
>>34931
Пилю веб-приложуху. В данный момент идёт реализация системы лобби. тоесть есть по факту таблица, каждая строка которой - это отдельное лобби. Как на пике.

По нажатию на кнопку "создать лобби", появляется форма, заполняя которую создаётся лобби в этой таблице. Я прилепил на JS(jQuery) событие, что мол при заполнении полей и нажатии на кнопку "создать", в таблицу добавляется строка, с введёнными данными, но вот беда, она появляется до перезагрузки страницы. Мне же нужно, чтобы пункт в таблице вмонтировался в страницу, чтобы его видели другие пользователи и чтобы оно не пропадало после перезагрузки ...
В JS треде сказали выполнить скрипт на стороне сервера, но я уже по-ходу понял, что они имели Ноду ... А мне на ПХП надо.
266 734985
>>34982
Точнее добавляемый через jQuery элемент существует только на компьютере создавшего пользователя, да и то, пока тот не перезагрузит страницу. Мне же нужно, чтобы оно встроилось в страницу и было видно всем пользоателям.
267 735018
>>34793
Здесь есть тред идей. Зайди туда и выбирай что понравится.
268 735019
>>34985
Отправляешь форму на сервер. Чтобы страница не перегружалась, используй ajax
269 735032
>>34289

В задаче про Вектор и департаменты.
Если мы создаем абстрактный класс Профессия, в нем указываем свойства
ставка = 100;
потребление кофе = 10;
производительность = 20;
И наследуем от него классы профессии (Менеджер, Инженер и тд.), в каждом из которых переопределяем эти свойства.
Но что если, другой программист создаст новую профессию, как быть уверенным, что он переопределит значения по умолчанию?
270 735038
>>34982
Тебе же ответили выше про веб-сокеты (это же ты был?).
Можно ещё long-polling попробовать, но, я так понимаю, там задержки больше будут.
271 735085
>>29430 (OP)
Братишки, а чем вы код в текстовых редакторах (не IDE) дополняете?
272 735087
Добрый день, никто не сталкивался с задачами - просклонять имя прилагательное относительно существительного?
273 735111
>>35032
Ты имеешь в виду класс Сотрудник? Или помимо него ещё и класс Профессия?
Можно сделать абстрактный класс Сотрудник, а от него наследовать уже любую профессию. Ну или как ты хочешь.
Если другой программист добавляет другую профессию, то он по-любому наследует её от Сотрудника (или Профессии - в твоём случае). Он же должен посмотреть на те свойства, которые идут по умолчанию в них, естественно, что они их переопределит в соответствии с новой профессией.
>>35085
Плагины имеешь в виду или что?
>>35087
Интересная задача, но, наверное, это нереально без огромного списка исключений.
Хотя надо бы прикинуть.
А что на входе - начальная форма в Именительном падеже уже дана? "Синяя ночь", "синий день"? Довольно интересная же задачка, действительно. Уровня чисел прописью, а может даже выше.
274 735118
>>35111

>Плагины имеешь в виду или что?


Движки анализа/дополнения кода, что-то вроде Tern, Racer, Jedi, но если нет ничего подобного, то хоть что-то. Допустим, пользую я свой любимый Vim, какие у меня есть опции, кроме https://github.com/shawncplus/phpcomplete.vim, что мне YCM / Neocomplete скормить можно?
275 735142
Как экранировать символ '%'?
Пиздец, гугол не отвечает, я в ярости!
276 735144
>>35142
Зачем тебе его экранировать?
277 735151
>>35118

>любимый Vim


Его лучше любить, сидя на IDE. С Vim режимом. Для PHPStorm можно даже создать файл .ideavim и добавлять туда простейшие команды вроде map jj <Esc>
А так могу посоветовать Practical Vim и Practical Tmux заодно, всё из серии The Pragmatic Bookshelf. Там рассказано как с помощью ctags писать самому всякие find by usage и autocomplete плагины.
278 735162
>>35151

>Его лучше любить, сидя на IDE.


Нет, в Vim мне комфортно, осталось только понять, можно ли сделать дополнение чуточку интеллектуальнее.
279 735196
Тупанул, перепощу сюда >>735190

>Это нормально, если я передаю в метод аргументом метод из другого класса? Хочу проверять существование мыла в классе-валидаторе.

280 735200
>>35196

>Это нормально, если я передаю в метод аргументом метод из другого класса?


Вполне нормально, если такие методы ты делаешь универсальными. Универсальными - в том смысле чтобы можно было использовать где-нибудь еще, а не строить новый велосипед.
281 735210
Хелп, разработчики. Делаю фильтры для продуктов магазина через MySQL. Продукты одежда и обувь, фильтры примерно такие - брэнд продукта (тут сотня разных), пол (мужской, женский, дети, унисекс), размер, цвет, категория, материал, магазин (их много). Есть гора продуктов с id, для продуктов есть таблица all_products (где их id и всякие параметры), для фильтров таблица filters_to_products, где задается соответствие product_id - filter_id, еще есть таблицы store_depot_items где прописано соответствие depot - product_id и есть поле stock равное 0 или 1, т.е. на каком складе какой продукт есть. Ну и наконец таблица store_depots, где задается соответствие depot_id - store_id, т.е. какой склад в каком магазине. Таким образом наличие товара в магазине проверяется через 2 таблицы store_depots и store_depot_items, а остальные фильтры через filters_to_products. Задача - если выбраны фильтр, вывести продукты только под эти фильтры, плюс убрать фильтры, какие для отфильтрованных продуктов уже неактуальны. Например выбран фильтр одежда для девочек, цвет красный, соответственно должны убраться брэнды, у которых нет красной одежды для девочек. С первой частью задачи по выводу продуктов под фильтры я легко справился, просто используя WHERE и JOIN в Mysql, проблем не было. Со второй начались проблемы - тут нужен вложенный подзапрос. Выходит, что сначала собираем все продукты подходящие под фильтры SELECTом, потом смотрим для каждого из этих продуктов соответствия в filters_to_products (какие у каждого продукта есть фильтры), потом делаем SELECT DISTINCT для всех собранных фильтров. Вышло примерно такое (пример с 2 фильтрами 25 и 3):
SELECT DISTINCT filters.filter_id FROM (SELECT ta.filter_id, pa.product_id from filters_to_products ta JOIN all_products pa ON (pa.product_id = ta.product_id) JOIN store_depot_items sb ON (pa.product_id = sb.product_id) JOIN store_depots sdepot ON (sb.depot_id = sdepot.depot_id) WHERE sb.stock = 1 AND sdepot.store_id = 136 AND ta.tag_id = 25 AND ta.tag_id = 3) filters
Проблема в том, что запрос занимает по 4 секунды, поскольку продуктов около миллиона, а пользователь не готов столько ждать обновления фильтров. Можно делать все это как-то быстрее? В каком направлении копать? Сейчас я делаю этот запрос к SQL асинхронно из аякса, но фильтры все равно долго обновляются по нескольку секунд, заказчиков не устраивает. Видел шопы, где это мгновенно происходит, как такое делается?
281 735210
Хелп, разработчики. Делаю фильтры для продуктов магазина через MySQL. Продукты одежда и обувь, фильтры примерно такие - брэнд продукта (тут сотня разных), пол (мужской, женский, дети, унисекс), размер, цвет, категория, материал, магазин (их много). Есть гора продуктов с id, для продуктов есть таблица all_products (где их id и всякие параметры), для фильтров таблица filters_to_products, где задается соответствие product_id - filter_id, еще есть таблицы store_depot_items где прописано соответствие depot - product_id и есть поле stock равное 0 или 1, т.е. на каком складе какой продукт есть. Ну и наконец таблица store_depots, где задается соответствие depot_id - store_id, т.е. какой склад в каком магазине. Таким образом наличие товара в магазине проверяется через 2 таблицы store_depots и store_depot_items, а остальные фильтры через filters_to_products. Задача - если выбраны фильтр, вывести продукты только под эти фильтры, плюс убрать фильтры, какие для отфильтрованных продуктов уже неактуальны. Например выбран фильтр одежда для девочек, цвет красный, соответственно должны убраться брэнды, у которых нет красной одежды для девочек. С первой частью задачи по выводу продуктов под фильтры я легко справился, просто используя WHERE и JOIN в Mysql, проблем не было. Со второй начались проблемы - тут нужен вложенный подзапрос. Выходит, что сначала собираем все продукты подходящие под фильтры SELECTом, потом смотрим для каждого из этих продуктов соответствия в filters_to_products (какие у каждого продукта есть фильтры), потом делаем SELECT DISTINCT для всех собранных фильтров. Вышло примерно такое (пример с 2 фильтрами 25 и 3):
SELECT DISTINCT filters.filter_id FROM (SELECT ta.filter_id, pa.product_id from filters_to_products ta JOIN all_products pa ON (pa.product_id = ta.product_id) JOIN store_depot_items sb ON (pa.product_id = sb.product_id) JOIN store_depots sdepot ON (sb.depot_id = sdepot.depot_id) WHERE sb.stock = 1 AND sdepot.store_id = 136 AND ta.tag_id = 25 AND ta.tag_id = 3) filters
Проблема в том, что запрос занимает по 4 секунды, поскольку продуктов около миллиона, а пользователь не готов столько ждать обновления фильтров. Можно делать все это как-то быстрее? В каком направлении копать? Сейчас я делаю этот запрос к SQL асинхронно из аякса, но фильтры все равно долго обновляются по нескольку секунд, заказчиков не устраивает. Видел шопы, где это мгновенно происходит, как такое делается?
282 735215
>>35210

>как такое делается?


Оптимизацией БД (нормализация, индексы) и вменяемыми запросами, попробуй учебник какой-нибудь почитать на эту тему.
283 735216
>>35085
Ничем не дополняю. Фреймворк которым пользуюсь и тем более свой код я знаю наизусть, набираю быстро.
284 735218
>>35215
Индексы есть, таблицы нормализованные. Думал, может кто делал уже такое и есть какие-то готовые рецепты, как правильно ненужные фильтры убирать, используя список отфильтрованных продуктов.
285 735223
>>35218
Избавляйся от JOIN каким-то образом.
286 735224
>>35210
Почему бы не сделать просто SELECT * FROM products WHERE filter_param = filter_value AND ... ?
287 735226
>>35200
Чет не получается блин.
У меня есть класс валидации, у него есть метод, который принимает функцию и через нее прогоняет значение. Хочу передать в этот метод метод существующего экземпляра класса, не статического. Такое возможно вообще? Может pimple как-то умеет?
288 735227
>>35226

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


Ты наркоман?
289 735228
>>35216
Какой фреймворк? Не хочешь ли перейти на какой-нибудь другой по каким-нибудь причинам или прям всем тебя устраивает?
Для себя или заказчиков?
290 735230
>>35224
В products нет фильтров, там только продукты, они в filters_to_products. Каждому продукту соответствует несколько фильтров, например так:
product_id tag_id
34 7
34 136
34 80
Плюс продукты нужно искать, какие только в наличии в конкретном магазине, а это джойнить еще 2 таблицы со складами и магазинами.
291 735233
>>35227
Нормальный прием. Двойная деспетчеризация, все дела, но зачем она ему не совсем ясно.
292 735235
>>35210
Также вопрос - ускорится ли все это дело, если вместо джойнов использовать массивы в PHP? Если айдишники продуктов под фильтры например собрать в PHP уже обычным селектом, и передавать их оттуда в выборку новых фильтров через WHERE filters.product_id IN (id1, id2, id3 ...)
293 735236
>>35233
Проверить пришедшее с формы мыло на существование. Передавать маппер в конструктор ради одной проверки, чет как из пушки по воробьям. Наверное.
294 735239
>>35230
Продукт имеет свойства.
Фильтр - набор свойств и их значений. Можно, например, его передавать в uri как ?param1=value1&param2=value2&...
Зачем тут еще что-то, кроме WHERE param1=value1 AND ... ?
Ну а что касается необходимых джоинов для денормализации - без них никак. Поможет кэширование запросов. Но нужно учитывать объем памяти.
295 735262
>>35239
Фильтры отображать надо на сайте же, а чтобы фильтры отображать нужно сначала выбрать доступные фильтры для отфильтрованных продуктов. С одним where ничего не получится. Кэш невозможен, поскольку фильтры каждый раз разные, а продукты обновляются. С секунды на секунду красная рубашка Adidas для девочек может закончиться в магазе (stock=0 станет), а с ней и сразу пара фильтров накроется.
296 735277
>>35111

>>Интересная задача, но, наверное, это нереально без огромного списка исключений.


Хотя надо бы прикинуть.
А что на входе - начальная форма в Именительном падеже уже дана? "Синяя ночь", "синий день"? Довольно интересная же задачка, действительно. Уровня чисел прописью, а может даже выше.
Есть к примеру категории: Женская/Мужская и есть товар: блузка, пальто, футболки
Итого получим на выходе:
Женская блузка, женское пальто, женские футболки
и Мужское пальто, мужские футболки и тд.
Я откопал какие то словари http://phpmorphy.sourceforge.net/dokuwiki/download и библиотеку, но не совсем понял как именно мне поступать с существительным (как разбивать на корень, префиксы и суфиксы + окончания) чтобы потом искать это в словаре и определять по нему падеж, чтобы потом просклонять прилагательное относительно падежа существительного по тому же словарю. К сожалению документации к самому словарю я не нашел
297 735289
>>35262
Ты не понимаешь, что такое фильтр. Это просто параметры и значения: color=blue, size=34.
Показываешь все фильтры, пользователь выбирает нужные и делает запрос.
А запрос к бд получается:
SELECT FROM
(SELECT
FROM all_products WHERE color=blue AND size=34) p # этот подзапрос всегда в кэше
INNER JOIN {тут твои таблицы с наличием на складе} ...
WHERE stock = 1;
Весь запрос тоже будет закэширован до изменения таблиц с наличием.
298 735297
>>35289
То есть ты получишь выборку товаров, которые удовлетворяют условиям и есть в наличии. А скрыть бренды, у которых 0 продуктов в этой выборке, легко на самом клиенте.
299 735341
>>35289
Как такое кэширование делать? SQL сам умеет? Или memcached какой-то подключать? В кэшировании я вообще плаваю, у нас его нет.
>>35297
Скрыть бренды на клиенте не получится. Смотри - клиент получает только 200 товаров, но по фильтрам там доступно еще тысяч 20-500, которые подгружаются если клиент дальше жмет. Если ты будешь на клиенте скрывать по имеющимся товарам, то он у тебя скроет все, что в эти 200 не входит, а в большей выборке может быть больше фильтров доступно.
300 735349
>>35341
Здесь дальше - имеется в виду, что клиент жмет "показать следующую страницу", чтобы ему больше товаров по фильтрам подгрузилось. Тогда следующий SQL запрос делается, чтобы больше товаров поулучить. А вот ненужные фильтры нужно отключить уже на самом первом.
301 735420
Перехожу к более активным действиям: DataMapper сосёт!
https://designpatternsphp.readthedocs.io/en/latest/Structural/DataMapper/README.html

Я сначала не понял, зачем они в UserMapper.php запихали метод mapObject(array $row). Кратко, принцип работы с БД там такой: Мы делаем запрос к базе, получаем ответ в виде массива $row. Массив мапится на объект c помощью mapObject, оттуда возвращается объект класса User. А если бы я просто использовал ActiveRecord, то через FETCH_CLASS возвращал бы данные в виде нужного объекта. Почему в случае DataMapper нельзя воспользоваться FETCH_CLASS? Да потому, что конструктор модели User принимает 3 параметра, которые нужно ставить в null (см. содержимое ссылки). PDO фетчит данные в виде объекта, но когда этот объект создаётся, то все данные заполненные раннее PDO, теперь обращаются в null.

UPD: Нагуглил в PDO опцию FETCH_PROPS_LATE, всё работает: http://stackoverflow.com/a/2862563
А вот FETCH_INTO не работает, забавная ошибка: object must be an object.
В общем, я по-прежнему жалею, что не взялся сразу за ActiveRecord, столько бы времени сэкономил.

>>34963
>>33728
>>32988
-хуй
302 735503
>>29430 (OP)
помогите пожалуйста разобраться, почему мой скрипт http://pastebin.com/agNbgazH неправильно отображает мой ip-адрес, он должен быть 127.0.0.1, а этот код отображает его как "::1", объясните пожалуйста почему. Сам php-файл называется tuna.php, я запускаю его через Apache как localhost/tuna.php, и если я пишу echo "$ip", то мне выводится "::1", причем если запускать его как 127.0.0.1/tuna.php, то всё выводится верно.
303 735630
>>35111

> Он же должен посмотреть на те свойства, которые идут по умолчанию в них, естественно, что они их переопределит в соответствии с новой профессией.


Вообще. не факт. Если ты хочешь обязать класс-наследник определить какой-то параметр, надо использовать абстрактный метод (например getBaseSalary()) - PHP не позволит создать конкретный (не-абстрактный) класс без реализации всех абстрактных методов.
304 735631
>>35142

В какой ситуации? Это зависит от того где ты хочешь его использовать и какие там правила экранирования.

>>35196

нет, это странно. И как именно ты передаешь метод?
305 735651
Вот это вин - давно я так не смеялся над любителями яблок: https://m.geektimes.ru/post/275398/
Учебник по рекурсии и всяким сложным темам 306 735685
Аноны, у которых затруднения с рекурсией, алгоритмами и прочими сложными темами. Есть учебник (в переводе на русском) под названием SICP который вам поможет немного с ними разобраться.

http://newstar.rinet.ru/~goga/sicp/sicp.pdf

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

https://repl.it/languages/scheme

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

http://stackoverflow.com/questions/2521477/what-is-the-best-scheme-interpreter-or-compiler

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

-----

И кстати на repl.it есть интепретатор и для PHP: https://repl.it/languages/php

Просто пишете слева определения функций, а справа - выражения, ну например

$x = 1;
function a () { return 100; }
a() * 2; // выведет 200

Только точку с запятой ставить не забывайте.

Правда там по моему периодически коннект к серверу отваливается при фатальной ошибке в коде.
Учебник по рекурсии и всяким сложным темам 306 735685
Аноны, у которых затруднения с рекурсией, алгоритмами и прочими сложными темами. Есть учебник (в переводе на русском) под названием SICP который вам поможет немного с ними разобраться.

http://newstar.rinet.ru/~goga/sicp/sicp.pdf

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

https://repl.it/languages/scheme

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

http://stackoverflow.com/questions/2521477/what-is-the-best-scheme-interpreter-or-compiler

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

-----

И кстати на repl.it есть интепретатор и для PHP: https://repl.it/languages/php

Просто пишете слева определения функций, а справа - выражения, ну например

$x = 1;
function a () { return 100; }
a() * 2; // выведет 200

Только точку с запятой ставить не забывайте.

Правда там по моему периодически коннект к серверу отваливается при фатальной ошибке в коде.
307 735692
>>35349
Понятно, что ты хочешь. Пиши тогда хранимую процедуру, которая:
1) Выбирает все отфильтрованные продукты во временную таблицу
2) Делает по ней селект с GROUP BY по брендам.
Это вернет таблицу брендов.
3) Делает по ней селект с LIMIT X, Y.
Это вернет страницу товаров.
308 735700
>>35692

Это будет еще медленее, с временной таблицей
309 735709
>>35700
Будет разы быстрее, чем есть сейчас.
Сейчас он выбирает сначала продукты, потом опять их же выбирает и делает по ним джоины. Плюс запрос не оптимизирован.
310 735738
>>35709

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

И вообще я сомневаюсь что тут оптимизация поможет, если индексы проставлены и все равно тормозит то значит надо искать другие пути (кеш, сторонний поисковый движок). Ну и конечно не нужны там подзапросы, лучше джойны.
311 735789
Почему в pr нет треда для кулхацкеров?
312 735796
>>35651
Представляю смесь бугурта и любви к Apple у того музыканта.

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


Всю коллекцию собственных работ, например, вот так взять - и потерять.

>Тотальный контроль Apple над файлами пользователя напоминает их известную рекламу «1984», которая воплотилась в жизнь в зеркальном отражении, в печальной и гнетущей иронии, пишет Пинкстоун.


Яблочник прозрел, спешите видеть! С самого начала было понятно, что это именно Apple всегда и последовательно выступает как Большой Брат - с самого начала нельзя было назвать их демократичными. И люди, которые были в теме в то время, выкладывали тогда кирпичи от того, что таким вот образом и стал работать Большой Брат.
3 Кб, 230x122
313 735866
Я хочу по клику наращивать высоту дива .clicker на 10 пикселей каждый раз.
Но вместо этого он сразу рисует мне див высотой в 1000, тип мне похуй что у тебя там цикл.
Как правильно возвращать нужное значение? Или мб есть какие-нибудь более изящные варианты?
314 735870
>>35866

Ты изучал функции, переменные и замыкания в яваскрипте?
315 735877
>>35866

>тип мне похуй что у тебя там цикл


Как раз таки оно и выполняет цикл до конца, и возвращает значение функции в height().
Не вижу причин использовать цикл, тебе нужно по клику увеличить "текущую" высоту на 10, не более.
Ты мог бы также использовать "замыкания"
3 Кб, 191x149
316 735886
>>35870
>>35877
Спасибо, подтолкнули в нужном направлении, всё работает.
>>35870
У меня из рук вон плохо получается без практики, но да, вникал, читал, смотрел и всякое такое. Оно как будто витает где-то там, но до применения не доходит.
317 735890
>>35886

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

У тебя по-прежнему код странный так как 2 обработчика вложено друг в друга и ты их многократно навешиваешь. Не, тебе надо начать с правильного яваскрипта.
318 735891
>>35890
Нет времени.
319 735895
>>35891

Если у тебя нет времени, то тебе стоит заняться чем-то другим. Ибо на исправление багов и ошибок ты потратишь в сумме гораздо больше времени и заказчики/работодатели вряд ли будут счастливы.
320 735913
>>35895
Моя ближайшая перспектива - верстка, а не весь фронтенд. Может, ты и считаешь целесообразным сидя дома без штанов въебать полгода на JS, чтоб потом хуярить инфографику пизженными плагинами, но вот я думаю немного иначе.
321 736004
>>35692
Спасибо, попробую с временными таблицами.
>>35738
Да, может быть медленее, я сейчас товары как раз поэтому ограничиваю до 300-500, потому что иначе много времени занимает, и клиент не готов столько ждать. Думаю, можно создать не временные, а постоянные таблицы для популярных фильтров, где будут лежать наборы доступных для них фильтров. И обновлять их по cronjobу, который запускать раз в пару минут. Будет правда проблема, что этот cronjob кучу времени занимает, комбинаций фильтров же много.

>Ну и конечно не нужны там подзапросы, лучше джойны.


Для выборки продуктов подзапросов нет, но она все равно тормозит на миллионе продуктов, там 6 joinов и group by. Возможно в этом направлении надо крутить, попробую избавиться от лишних joinов для cronjobа.
322 736010
>>35738
Так все товары как раз и нужны, чтобы не показывать отсутствующие бренды. Только те, которые в них найдутся. Походу ты не понял задачи.
323 736012
>>35738

>искать другие пути (кеш


По кешам посмотрел, что в Mysql есть встроенный Mysql Query Cache. Он для подзапросов действует? Для SELECT xxx FROM (SELECT xxx from xxx) будет ли действовать для второго SELECT? Или он только для joinов?
324 736017
>>36010
Да, нужны все товары, фильтров может быть много (штук 7 их всего). При выборе любой комбинации из 7 фильтров, нужно пройтись по всем фильтрам и отключить более недоступные фильтры в каждом из 7. А для этого нужно пройтись по всем товарам, которые попали под эти 7 фильтров. Чем больше фильтров включено, тем доступных товаров по ним меньше (а значит быстрее по этим товарам проходить). Самый долгий обход, если включен только 1 фильтр, тогда может быть до полумиллиона-миллиона товаров под него. Самый быстрый соответственно, если все 7 фильтров включены, там может быть и 3 товара всего.
325 736023
>>35685
А в учебники написано нужен Лисп

> Для описания процессов нам нужен подходящий язык, и с этой целью мы используем


язык программирования Лисп.

Или Scheme это интерпретатор Лиспа?
326 736024
>>36012
Также, от кеша, как я понял, мне немного толку, поскольку каждый раз, как будет обновляться таблица с наличием товаров в магазинах, он будет очищаться и соответственно все закешированные запросы надо заново делать. Таблица наличия товаров обновляется каждые пару секунд-минут, в зависимости от подвозов-покупок.
327 736025
>>35685
>>36023

Прочитал еще пару абзацев, стало понятно.

>Тот диалект, которым мы пользуемся в этой книге, называется Scheme

63 Кб, 799x507
328 736068
Читаю документацию для Yii2 на русском языке: https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/
Ну и дичь...
Сколько всего ещё дополнительно нужно изучить после учебника ОПа, чтобы въехать во всё это? Там адова бездна, просто адова бездна.
329 736072
>>36068
Не знаю насчет иии(уайии?), но сейчас читаю доки по симфони, вроде все понятно, хотя это вроде как самый сложный фреймворк.
330 736074
>>36068

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

Алсо, ты весь учебник опа прошел? Вплоть до задачи с yii2?
331 736079
>>35913
Твоя перспектива - работать без сна и выходных за 15 тысяч.
65 Кб, 800x669
332 736121
>>36072

>Слово Yii (произносится как Йи [ji:]) в китайском языке означает «простой и эволюционирующий». Также Yii может расшифровываться как акроним Yes It Is!


>сейчас читаю доки по симфони, вроде все понятно, хотя это вроде как самый сложный фреймворк.


Ну а ты Студентов и ФО сделал? Я пока только ООП осилил с трудом, но Кошек-мышек пока не трогал - хочу на выходных попробовать.

>>36074

>ты весь учебник опа прошел?


Только ООП заканчиваю. До этого сделал все задачи на HTML+CSS, ещё до смены последовательности уроков.
Я бы не хотел сейчас притрагиваться к Студентам и ФО: слишком много времени уйдёт на это, я думаю.
У меня в планах MySQL на следующей неделе, а до конца мая надо разобраться в Yii2 на базовом уровне, чтобы уметь подключать модули, виджеты и подобное - как минимум.
333 736130
>>36079
Спасибо за оставленный отзыв!
334 736133
CSS обязательно учить?
Какого хуя верстальщик должен учить 2 языка программирования, html и css?
Думаю выучить за 2 года html и получать 100 000 рублей в месяц (так написано в рекламе видеокурса, они же не будут врать в отличее от неудачников с двача).
335 736135
>>36133

>языка программирования


> html и css?


Посмеялся, спасибо.
336 736136
>>36133

html и css это языки разметки текста и стилей оформления, а не программирования
337 736140
>>36136
Ну, надо сказать, что в SASS есть функции, переменные и циклы. Т.е. какой нибудь верстак, пишущий CSS на SASS, вполне себе программирует.
27 Кб, 665x327
338 736146
>>731915

>размещение стилей в футере приведет к тому что может отобразиться старница без стилей на какое-то время. размещение скриптов в футере чревато тем, что при использовании <button onсlick="fn()"> до загрузки скрипта мы получаем неработающую кнопку.


Гугл ругает за стили/js в хедере, а сеодебилы за это переживают. В остальном все вродь поправил. Посмотри пожалуйста: github.com/fidnex/students
339 736147
>>36130
Целеустремленность - это великолепно, но с таким подходом ты действительно соберешь все возможные неровности на пути, испортишь себе репутацию и потеряешь массу времени.
340 736149
>>36146

>сеодебилы


Грудь материнскую еще не успел изо рта вынуть, а уже окружающих дебилами называет.
341 736157
Где можно почитать про Big O и оценку алгоритмов? Язык русский или английский, без разницы.
342 736165
>>36147
Хорошо.
У меня есть месяц, чтоб довершить свои безумные умения в верстке. В день я уделяю в среднем 10-11 часов. кроме воскресенья и половины субботы
Остался JQ/JS, и я действительно чувствую, что я тону и насасываю, ибо привык брать памятью, а здесь эта хуйня не прокатывает. Разве что запоминать какие-то куски под нужную задачу.
Я могу уделить 10 дней качественному подходу к теории и 10 практике JS/JQ, но смогу ли я так получить больше, чем просто штурмуя всё подряд? Я не знаю.
Терять время я не могу.
343 736169
>>36165

>В день я уделяю в среднем 10-11 часов


Что-то мне слабо верится в это. С таким темпом работы учебник Ильи Кантора ты пройдешь за неделю.
344 736175
>>36149
К нам такая крутая московская сеоконтора тикеты бросала. Задачки были уровня выводить 404 страницу на все возможные страницы с гет параметрами
site.ru/ - главная страница
site.ru/?foo1 - 404
site.ru/?foo2=bar - 404
А то дубли страниц, ранжирование-хуирование плохое будет. Или опять же дублирующие страницы - товар лежит в site.ru/category1/tovar и в site.ru/category2/tovar. rel canonical ставить они не рекомендуют, потому нужно переписать кучу кода в тысяче местах и привести все ссылки в магазине к виду site.ru/product/tovar. И это крутая московская сео контора, которая выставляла нашему клиенту неебические ценники за такие вот аудиты. Как-то в общем не очень к ним отношение сложилось.
345 736207
>>36165

Учебник по яваскрипту у нас один - learn.javascript.ru. Если тебе хочется еще задачки, то они есть в ОП посте. Включая даже изучение MVC на примере игры в сапера.
346 736212
>>36175

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


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

>нужно переписать кучу кода в тысяче местах и привести все ссылки в магазине к виду site.ru/product/tovar


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

Раздался пронзительный голос со стороны SEO
347 736216
>>36175

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

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

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

> потому нужно переписать кучу кода в тысяче местах


Это сеоконтора виновата что вы DRY нарушаете и ссылки как попало генерируете, да еще небось и с копипастой?
348 736217
>>36212

Не надо через htaccess.

- дублируется функционал роутера, с вероятностью близкой к 100% будут баги
- при переносе на нгинкс придется руками все правила переписывать
349 736218
>>36175
Не учи людей делать их работу, особенно если ты в ней понимаешь ничего - делай хорошо свою.
350 736222
>>36165

>есть месяц


Это заранее провальное мероприятие, ты даже простенький макет вряд ли сверстать сможешь через месяц, не говоря уже о хоть каком-то программировании.
351 736236
>>36212
Мне кажется гет параметры редиректить это совсем маразм
>>36216

>Это сеоконтора виновата что вы DRY нарушаете и ссылки как попало генерируете, да еще небось и с копипастой?


Это ок, но чем им rel canonical не устроил? Магазину много лет, тысячи товаров, тысячи ссылок на них по всему интернету, а им вот приперлось вид ссылок поменять.
>>36218
Извини, не хотел никого обидеть.
352 736257
>>33641

>> А разве ключом не должно быть название поля? Как тогда обозначить ключ ошибки?


>действительно. Ну значит массив должен быть какой-то другой структуры.


А можно подсказку какой?

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

$validations = [
'name' = [
'validator' => 'validateName',
'parameters' => ['getName']
],
...
]

foreach($validations as $field => $validator) {
...
$error[$field] = call_user_func($this, $validator['validator'], $validator['parameters']);
...
}

https://ideone.com/9cuKjL
353 736361
>>36222
HTML/CSS уже относительно пройдены LESS не затрагивал пока+не пробовал резиновую верстку, только адаптивную.
>>36207
>>36169
Ну не верь. Кстати, спасибо за подкинутый учебник может и его возьму, если пойдет
>>36207
Да, начал читать, но как-то не особо легко частям заходит. Нахуя мне в самом начале знать регулярные выражения, если в большинстве случаев всё ограничивается их копипастом?
Но

> он один


Поэтому делать нечего.
Спасибо.
354 736391
>>36068

>Сколько всего ещё дополнительно нужно изучить после учебника ОПа, чтобы въехать во всё это?



Скажу по своему опыту: на фреймворках можно писать, вообще не думая. Эти избыточные абстракции и созданы для того, чтобы можно было при минимальном понимании ООП и MVC быстро воплотить задуманное в жизнь. Та же задачка на студентов требует какого-никакого проектирования. Пишу 3-й день подряд и не знаю, сколько ещё буду писать, так как каждый день обнаруживаю огромные пробелы в знаниях, а вот на фреймворке я её меньше, чем за час написал. Так что будь уверен, после студентов и файлообменника никакие монструозные фреймворки вроде Yii тебе не будут страшны.
355 736406
>>31646

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


А как пользоваться композицией в нашем случае?

Вот в Студенте у нас есть поля которые есть в Форме, и в Форме есть поля которых нету в Студенте. Далее, мы хотим чтобы эти поля заполнялись все сразу с помощью одной функции/проходили валидацию/итд, все этих методы используют цикл, но мы не можем заставить цикл проходиться по двум объектам по очереди, тем более в классе Студента есть лишние поля связные с хэшем. Нужно опять составлять массив со свойствами которые нам нужны?
356 736483
Чому div не на расстоянии 100 пикселей от левой части экрана,аноны?
<div style="left : 0 px"> Ффф </div>
<script>
var ch=document.getElementsByTagName('div')[0];
ch.style.left="100px";
</script>
357 736502
>>36483
Вроде position: absolute нужен. Заливай в следующий раз на jsfiddle.net, аноны охотнее помогут.
358 736613
>>36361

>пройдены


А сверстать не сможешь, такие дела.
359 736622
>>36361

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

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

Кстати, в ОП посте есть задания на HTML.

Если ты серьезно готов потратить месяц, каждый день уделяя много времени учебе, то вполне реально и HTML подтянуть и JS подучить и наверно немного DOM успеть изучить с jQuery. Задачи по всем этим темам, если что - в ОП посте.

>>36406

Композиция это когда один объект включает в себя другой. Тут по моему вариантов особых нет: в форме должно быть поле student в котором хранится студент.

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


Сделай 2 цикла. Или сделай универсальные методы вроде get($fieldname) которые понимают по имени поля, откуда его надо брать.

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

>>36391

Можно писать не думая только пока ты делаешь задачи аналогичные тем что в туториале. Как только надо сделать что-то нестандартное, если ты не понимаешь архитектуру фреймворка, ты будешь лепить костыли. Да и ты говоришь что просто, но мы не видели твой код и не знаем насколько он правильный.
360 736623
>>36257

>>Ну значит массив должен быть какой-то другой структуры.


> А можно подсказку какой?


Давай поставим вопрос по другому: а какие тебе данные нужны для валидации одного поля? (например, имя поля, имя функции-валидатора, еще что-то?) Такие и надо класть в массив.

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


Несколько аргументов можно передать через call_user_func_array. Она принимает массив аргументов.

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

Старайся не усложнять код без необходимости. Вот давай для начала попробуем сформулировать задачу:

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

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

Глядя на твой код, я например, не понимаю, зачем ты передаешь в функцию валидации 'getName'. Зачем ей имя геттера? Оно как-то помогает проверить правильность заполнения поля?

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

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

> но чем им rel canonical не устроил?


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

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

Ну и вы всегда можете поменять СЕО контору или даже заниматься оптимизацией сами.

>>36212

редиректить надо на уровне приложения.

>>36157

Увы, не знаю, погугли. Если кратко то O-нотация показывает как время выполнения или например объем потребляемой памяти увеличиваются при увеличении числа данных.

O(1) - алогритм работает одинаковое время независимо от объекма данных
O(N) - пропорционально объему данных, если данных в 10 раз больше то и работать будет в 10 раз дольше
O(log2(N)) - пропорционально логарифму, в 10 раз больше данных, примерно раза в 3 дольше работать, в 1000 раз больше - примерно в 10 раз дольше (не в 27, а в 10)
O(N^2) - пропорционально квадрату объема данных, в 10 раз больше данных - в 100 раз дольше их обрабатывать

и тд.

O(2N) это то же самое что O(N) и потому так не пишут.

Эта нотация показывает только относительный рост, а не абсолютные числа. Нельзя сказать, какой алгоритм быстрее при N = 100: тот что O(1) или O(N)
361 736626
>>36236

> но чем им rel canonical не устроил?


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

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

Ну и вы всегда можете поменять СЕО контору или даже заниматься оптимизацией сами.

>>36212

редиректить надо на уровне приложения.

>>36157

Увы, не знаю, погугли. Если кратко то O-нотация показывает как время выполнения или например объем потребляемой памяти увеличиваются при увеличении числа данных.

O(1) - алогритм работает одинаковое время независимо от объекма данных
O(N) - пропорционально объему данных, если данных в 10 раз больше то и работать будет в 10 раз дольше
O(log2(N)) - пропорционально логарифму, в 10 раз больше данных, примерно раза в 3 дольше работать, в 1000 раз больше - примерно в 10 раз дольше (не в 27, а в 10)
O(N^2) - пропорционально квадрату объема данных, в 10 раз больше данных - в 100 раз дольше их обрабатывать

и тд.

O(2N) это то же самое что O(N) и потому так не пишут.

Эта нотация показывает только относительный рост, а не абсолютные числа. Нельзя сказать, какой алгоритм быстрее при N = 100: тот что O(1) или O(N)
362 736634
>>36121

Ты проскакиваешь темы . Между ООП и фреймворком Юи очень много тем, которые надо изучить - архитектура веб-приложений, DI, MVC, работа с БД, формами - это все изучается в студентах.

>>36017

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

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

id рубрики - список брендов в ней
id рубрики - список цветов товаров в ней
+ комбинации из 2 значений каждого фильтра

В редисе например есть удобный тип hash для этого

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

рубрика, бренд, цвет

Такая таблица позволяет ответить на вопросы:

- какие бренды есть в рубрике
- какие цвета есть в рубрике
- какие цвета есть в рубрике + бренде

Имей в виду что для эффективной выборки нужно несколько индексов.

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

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

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

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

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

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

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

Сейчас даже в сфинксе есть что-то для фасетного поиска, но он по моему для этого не идеально подходит. Надо тестировать.
362 736634
>>36121

Ты проскакиваешь темы . Между ООП и фреймворком Юи очень много тем, которые надо изучить - архитектура веб-приложений, DI, MVC, работа с БД, формами - это все изучается в студентах.

>>36017

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

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

id рубрики - список брендов в ней
id рубрики - список цветов товаров в ней
+ комбинации из 2 значений каждого фильтра

В редисе например есть удобный тип hash для этого

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

рубрика, бренд, цвет

Такая таблица позволяет ответить на вопросы:

- какие бренды есть в рубрике
- какие цвета есть в рубрике
- какие цвета есть в рубрике + бренде

Имей в виду что для эффективной выборки нужно несколько индексов.

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

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

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

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

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

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

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

Сейчас даже в сфинксе есть что-то для фасетного поиска, но он по моему для этого не идеально подходит. Надо тестировать.
363 736637
>>36024

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

>>36012

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

>>36004

То что там анон предложил с временныим таблицами - это бред. Ты серьезно собрался копировать полмиллиона товаров во временную таблицу чтобы посчитать сколько там брендов? Анон то ли что-то путает то ли вообще не понимает в оптимизации.

>>35709

Зависит от структуры БД. Если отношение товар-бренд и товар-рубрика это 1 ко многим то можно сделать индекс и получать ответ "какие бренды есть в рубрике" довольно быстро. Вариант с созданием новой временной таблицы по моему заведомо самый медленный. Не веришь - попробуй сам сделать это на досуге и померяй.

>>35503

Используется Ipv6 а не IPv4, почитай википедию. Там другой формат адресов и ::1 это просто сокращение адреса где куча нулей и единица в конце.
364 736638
>>35420

> Я сначала не понял, зачем они в UserMapper.php запихали метод mapObject(array $row).


Чтобы преобразовать массив данных в модель.

> А если бы я просто использовал ActiveRecord, то через FETCH_CLASS возвращал бы данные в виде нужного объекта.


- имена полей объекта и БД могут не совпадать (удобнее когда совпадают конечно)
- FETCH_CLASS проставляет поля в обход сеттеров. Может у тебя в модели поля должны запоняться через setName и там есть какая-то логика, FETCH_CLASS ее игнорирует. Хуже, он сначала заполняет поля а потом вызывает конструктор. Это вообще пример глупо спроектированной фичи.
- могут требоваться преобразования типов данных. Например в БД дата хранится строкой а в PHP объектом DateTime. Также, могут быть специальные классы для других типов данных: например денег, каких-то сложных структур данных

Те же проблемы есть и в AR. Раз ты знаешь про эти 2 подхода ты наверно знаешь и главный недостаток AR и мне не надо его рассказывать?

Наконец исопьзование или не использование FETCH_CLASS вообще не имеет отношения к DataMapper или AR. Оба этих подхода могут использовать или не использовать эту фичу. Ты по моему что-то путаешь думая что AR это кодда мы используем FETCH_CLASS. Не так. AR это когда модель и код работы с БД объединены (перемешаны) в 1 классе, DM это когда модель ничего не знает про БД и логика работы с ней вынесена в отдельный класс (класcы).

Простой пример. Допустим у тебя есть код который работает с моделью. В случае AR он не может работать без БД, а в случае DM ты можешь брать модели хоть откуда, например создать вручную, и код будет работать точно так же, без базы.

> Почему в случае DataMapper нельзя воспользоваться FETCH_CLASS? Да потому, что конструктор модели User принимает 3 параметра, которые нужно ставить в null


То что конструктор требует параметры вообще не имеет никакого отношения к выбору между AR и DM.

> PDO фетчит данные в виде объекта, но когда этот объект создаётся, то все данные заполненные раннее PDO, теперь обращаются в null.


Это ошибка в PDO. Там есть параметр http://stackoverflow.com/questions/14336726/pdofetch-props-late-and-construct-call-using-fetched-data специально для исправления этого бага. Просто инвалиды которые делали PDO плохо разбираются в ООП. Лучше не полагаться на такие фичи, а написать свой код маппинга.
364 736638
>>35420

> Я сначала не понял, зачем они в UserMapper.php запихали метод mapObject(array $row).


Чтобы преобразовать массив данных в модель.

> А если бы я просто использовал ActiveRecord, то через FETCH_CLASS возвращал бы данные в виде нужного объекта.


- имена полей объекта и БД могут не совпадать (удобнее когда совпадают конечно)
- FETCH_CLASS проставляет поля в обход сеттеров. Может у тебя в модели поля должны запоняться через setName и там есть какая-то логика, FETCH_CLASS ее игнорирует. Хуже, он сначала заполняет поля а потом вызывает конструктор. Это вообще пример глупо спроектированной фичи.
- могут требоваться преобразования типов данных. Например в БД дата хранится строкой а в PHP объектом DateTime. Также, могут быть специальные классы для других типов данных: например денег, каких-то сложных структур данных

Те же проблемы есть и в AR. Раз ты знаешь про эти 2 подхода ты наверно знаешь и главный недостаток AR и мне не надо его рассказывать?

Наконец исопьзование или не использование FETCH_CLASS вообще не имеет отношения к DataMapper или AR. Оба этих подхода могут использовать или не использовать эту фичу. Ты по моему что-то путаешь думая что AR это кодда мы используем FETCH_CLASS. Не так. AR это когда модель и код работы с БД объединены (перемешаны) в 1 классе, DM это когда модель ничего не знает про БД и логика работы с ней вынесена в отдельный класс (класcы).

Простой пример. Допустим у тебя есть код который работает с моделью. В случае AR он не может работать без БД, а в случае DM ты можешь брать модели хоть откуда, например создать вручную, и код будет работать точно так же, без базы.

> Почему в случае DataMapper нельзя воспользоваться FETCH_CLASS? Да потому, что конструктор модели User принимает 3 параметра, которые нужно ставить в null


То что конструктор требует параметры вообще не имеет никакого отношения к выбору между AR и DM.

> PDO фетчит данные в виде объекта, но когда этот объект создаётся, то все данные заполненные раннее PDO, теперь обращаются в null.


Это ошибка в PDO. Там есть параметр http://stackoverflow.com/questions/14336726/pdofetch-props-late-and-construct-call-using-fetched-data специально для исправления этого бага. Просто инвалиды которые делали PDO плохо разбираются в ООП. Лучше не полагаться на такие фичи, а написать свой код маппинга.
365 736639
>>35277

Да phpmorphy мог бы помочь тут.

>>35239

Ты что-то путаешь

"джойны для денормализации" - это что-то странное.

>>35236

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

>>35235

Нет, выборка 500 000 товаров в PHP скорее всего приведет к перерасходу памяти и будет намного медленнее.

>>35233

Что значит "диспетчеризация"? Сишник? У нас в PHP это не имеет никакого знаения, не применяй термины из одного языка к другому.

у нас это называется функции высшего порядка.

>>35230

> Плюс продукты нужно искать, какие только в наличии в конкретном магазине, а это джойнить еще 2 таблицы со складами и магазинами.


Это скорее плюс так как снижает число просматриваемых записей.

>>35226

Можно, в виде [$obj, 'method']: http://php.net/manual/ru/language.types.callable.php
Но непонятно зачем.

>>35224

Там могут быть связи многие-ко-многим

>>35223

Бред.

>>35218

Кеш как временное решение или движок с поддержкой фасетного поиска.
365 736639
>>35277

Да phpmorphy мог бы помочь тут.

>>35239

Ты что-то путаешь

"джойны для денормализации" - это что-то странное.

>>35236

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

>>35235

Нет, выборка 500 000 товаров в PHP скорее всего приведет к перерасходу памяти и будет намного медленнее.

>>35233

Что значит "диспетчеризация"? Сишник? У нас в PHP это не имеет никакого знаения, не применяй термины из одного языка к другому.

у нас это называется функции высшего порядка.

>>35230

> Плюс продукты нужно искать, какие только в наличии в конкретном магазине, а это джойнить еще 2 таблицы со складами и магазинами.


Это скорее плюс так как снижает число просматриваемых записей.

>>35226

Можно, в виде [$obj, 'method']: http://php.net/manual/ru/language.types.callable.php
Но непонятно зачем.

>>35224

Там могут быть связи многие-ко-многим

>>35223

Бред.

>>35218

Кеш как временное решение или движок с поддержкой фасетного поиска.
366 736644
>>35210

> для фильтров таблица filters_to_products, где задается соответствие product_id - filter_id


Они там все многие-ко-многим что ли? А, понял, вы все фильтры держите в одной таблице.

> AND ta.tag_id = 25 AND ta.tag_id = 3


Тут явно ошибка - это не выберет записей так как условия противоречат - наверно таблицу джойнят 2 раза?

> Со второй начались проблемы - тут нужен вложенный подзапрос.


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

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

> Видел шопы, где это мгновенно происходит, как такое делается?


специализированный движок для фасетного поиска.
367 736646
>>35210

Памяти у вас достаточно на сервере для mysql?

>>35151

> Там рассказано как с помощью ctags писать самому всякие find by usage и autocomplete плагины.


костыли же которые в ИДЕ из коробки. Для ctags есть инкрементальное обновление по мере набора или сохранения файлов? В Саблайме например индекс функций обновляется сам собой.

>>34982

Данные надо сохранять на сервере

>>34968

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

>>34968

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

>>34967

Внутри одного скрипта. Выполнение 2 скриптов абсолютно независимо друг от друга и никаких общих данных у них нет.

>>34963

1) первое
2) код должен огбъяснять паттерн а не отвлекаться на лишние подробности. Да и мне тоже не нравятся эти магические методы, они затрудняют понимание кода, требуют больше времени чтобы разобраться (надо прочесть и анализировать их код, непонятно что там может быть написано). Для свойств должен быть специальный синтаксис вроде property name { ... } а мегические методы это уродливые костыли.

3) можно. Если объектов мало, можно просто в bootstrap.php создать их, но когда объектов становится больше, то вручную отслеживать кто от кого зависит становится утомительно.

> Мне из контроллера нужно иметь доступ к объекту StudentMapper. Этот объект создаётся с передачей конфига для PDO.


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

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

> Но не передавать же мне всё через конструктор?


Если есть контейнер, в контроллер можно передать его. Если нет - отдельные объекты. А что делать? не копипастить же код создания мапперов.
367 736646
>>35210

Памяти у вас достаточно на сервере для mysql?

>>35151

> Там рассказано как с помощью ctags писать самому всякие find by usage и autocomplete плагины.


костыли же которые в ИДЕ из коробки. Для ctags есть инкрементальное обновление по мере набора или сохранения файлов? В Саблайме например индекс функций обновляется сам собой.

>>34982

Данные надо сохранять на сервере

>>34968

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

>>34968

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

>>34967

Внутри одного скрипта. Выполнение 2 скриптов абсолютно независимо друг от друга и никаких общих данных у них нет.

>>34963

1) первое
2) код должен огбъяснять паттерн а не отвлекаться на лишние подробности. Да и мне тоже не нравятся эти магические методы, они затрудняют понимание кода, требуют больше времени чтобы разобраться (надо прочесть и анализировать их код, непонятно что там может быть написано). Для свойств должен быть специальный синтаксис вроде property name { ... } а мегические методы это уродливые костыли.

3) можно. Если объектов мало, можно просто в bootstrap.php создать их, но когда объектов становится больше, то вручную отслеживать кто от кого зависит становится утомительно.

> Мне из контроллера нужно иметь доступ к объекту StudentMapper. Этот объект создаётся с передачей конфига для PDO.


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

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

> Но не передавать же мне всё через конструктор?


Если есть контейнер, в контроллер можно передать его. Если нет - отдельные объекты. А что делать? не копипастить же код создания мапперов.
368 736680
>>36502
Точно,заработало. Забыл про это свойство. Спасибо,добрый анон!
369 736701
Домучал задачку с проверкой и исправлением ошибок. Вот что получилось:
Задачка на проверку: https://ideone.com/7gHlP7
Задачка на исправление: https://ideone.com/6TJwXr
Чекните, плез, на наличие велосипедов и ошибок.
370 736733
>>36646

>Для ctags есть инкрементальное обновление по мере набора или сохранения файлов?


https://github.com/ludovicchabant/vim-gutentags
Как минимум для JS, PHP и Python нормально настроенный Vim точно не хуже тех же Eclipse или Netbeans.
371 736739
>>36733
Но для php нет ничего лучше phpStorm. vim там и рядом не стоял.
372 736740
>>36739
Стоял.
PhpStorm стоит нефти.
Дырявые абстракции в Линукс 373 736818
Узнал про интересный пример т.н "дырявой абстракции" ( http://russian.joelonsoftware.com/Articles/LeakyAbstractions.html ) в Линуксе.

Там любят представлять все в виде файлов. Вот и значения некоторых системных параметров передаются из ядра в пользовательское пространство через псевдо-файлы. Ну например, есть такой псевдо-файл /proc/sys/kernel/pid_max который возвращает максимальный id процесса:

$ cat /proc/sys/kernel/pid_max
32768

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

$ stat -c '%s' /proc/sys/kernel/pid_max
0

Упс. Вот и первая дырка в абстракции. А я покажу вам еще одну. Попробуем читать этот псевдо-файл по 1 байту за раз:

$ dd if=/proc/sys/kernel/pid_max bs=1 count=20
31+0 records in

Прочиталась только первая цифра. Попробуем сделать размер блока равным 3 байтам:

$ dd if=/proc/sys/kernel/pid_max bs=3 count=20
3271+0 records in

Прочитались только цифры "327". (1+0 records in - это статистика).

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

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

Я еще проверил, другие псевдофайлы вроде /proc/cmdline или /proc/uptime читаются нормально. Видимо у них как-то избирательно все это реализовано.
Дырявые абстракции в Линукс 373 736818
Узнал про интересный пример т.н "дырявой абстракции" ( http://russian.joelonsoftware.com/Articles/LeakyAbstractions.html ) в Линуксе.

Там любят представлять все в виде файлов. Вот и значения некоторых системных параметров передаются из ядра в пользовательское пространство через псевдо-файлы. Ну например, есть такой псевдо-файл /proc/sys/kernel/pid_max который возвращает максимальный id процесса:

$ cat /proc/sys/kernel/pid_max
32768

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

$ stat -c '%s' /proc/sys/kernel/pid_max
0

Упс. Вот и первая дырка в абстракции. А я покажу вам еще одну. Попробуем читать этот псевдо-файл по 1 байту за раз:

$ dd if=/proc/sys/kernel/pid_max bs=1 count=20
31+0 records in

Прочиталась только первая цифра. Попробуем сделать размер блока равным 3 байтам:

$ dd if=/proc/sys/kernel/pid_max bs=3 count=20
3271+0 records in

Прочитались только цифры "327". (1+0 records in - это статистика).

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

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

Я еще проверил, другие псевдофайлы вроде /proc/cmdline или /proc/uptime читаются нормально. Видимо у них как-то избирательно все это реализовано.
374 736833
>>36701
и в дополнение прошу проверить еще вот эту задачку
https://ideone.com/DBSbir
375 736950
Зачем иногда делают специальную ссылку для редиректа на чужие сайты? Типа site.com/redirect/google.com. Что-то с SEO связано?
376 736962
Мимо-сисадмин-эникейшик вкатывается в ваш тред.
Обезумев от безделья, дохода, беспросветности и собственной никчемности он решил превозмочь, и наконец изучить хоть что нибудь полезное.
Вопросов не задаю, сижу тихо, мануалю манулов и курю бамбук.
Всем добра в вашем чатике!
377 736975
>>36634
Спасибо, наконец что-то прояснилось.

>скорее всего нужен поисковый движок с фасетным поиском для этой задачи


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

>Кеш-таблицы такого вида:


>рубрика, бренд, цвет


>для эффективной выборки нужно несколько индексов


Хорошая идея, но что делать, когда меняется stock для одного из товаров. Т.е. наличие товара добавляется или удаляется. Генерировать тут же все таблицы с кешами заново? Их, как я понял, много будет.

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


Возможны все сочетания для которых есть товары, фильтров всего от 7 до 13 штук (сейчас 7 используется, но до 13 подключаем), фильтры в одной таблице filters_to_product, часть фильтров по отдельным таблицам, например category_to_product, special_filter_to_product. Отношение везде много-ко-многим, т.е. множеству фильтров соответствует множество продуктов.

>База не будет быстро работать когда у тебя есть связи вида много-ко-многим (то есть у товара может быть несколько рубрик и несколько цветов) и надо искать по их сочетаниям.


У товара может быть только одна рубрика, бренд или цвет, и остальные фильтры все только по одному на товар.

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


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

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


Индексы все есть, на это нас хватило, про настройки БД возможно нет, до задачи с убиранием фильтров на все скорости хватало в пределах 1 секунды, что устраивало. Есть где про эти настройки руководство почитать?

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


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

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


Товаров больше не станет, около миллиона товаров всегда будет.

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


Это уже хорошо, что велосипедов не надо. Как я понял из твоих объяснений, из известных решений только кэш-таблицы и фасетный поиск? Или еще какие есть?
>>36637

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


Это как? Можешь схему примерно объяснить? Не очень представляю.
>>36644

>Они там все многие-ко-многим что ли? А, понял, вы все фильтры держите в одной таблице.


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

>Тут явно ошибка - это не выберет записей так как условия противоречат - наверно таблицу джойнят 2 раза?


Хм, да, там OR было, а не AND. Выбираются все фильтры с тэгами 25 или 3.

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


Внешний select выбирает фильтры из полученной таблицы доступных продуктов по этим фильтрам. SELECT DISTINCT filters.filter_id FROM (select товары по фильтрам которые в наличии, плюс фильтры к ним через join filters_to_products)
377 736975
>>36634
Спасибо, наконец что-то прояснилось.

>скорее всего нужен поисковый движок с фасетным поиском для этой задачи


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

>Кеш-таблицы такого вида:


>рубрика, бренд, цвет


>для эффективной выборки нужно несколько индексов


Хорошая идея, но что делать, когда меняется stock для одного из товаров. Т.е. наличие товара добавляется или удаляется. Генерировать тут же все таблицы с кешами заново? Их, как я понял, много будет.

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


Возможны все сочетания для которых есть товары, фильтров всего от 7 до 13 штук (сейчас 7 используется, но до 13 подключаем), фильтры в одной таблице filters_to_product, часть фильтров по отдельным таблицам, например category_to_product, special_filter_to_product. Отношение везде много-ко-многим, т.е. множеству фильтров соответствует множество продуктов.

>База не будет быстро работать когда у тебя есть связи вида много-ко-многим (то есть у товара может быть несколько рубрик и несколько цветов) и надо искать по их сочетаниям.


У товара может быть только одна рубрика, бренд или цвет, и остальные фильтры все только по одному на товар.

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


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

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


Индексы все есть, на это нас хватило, про настройки БД возможно нет, до задачи с убиранием фильтров на все скорости хватало в пределах 1 секунды, что устраивало. Есть где про эти настройки руководство почитать?

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


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

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


Товаров больше не станет, около миллиона товаров всегда будет.

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


Это уже хорошо, что велосипедов не надо. Как я понял из твоих объяснений, из известных решений только кэш-таблицы и фасетный поиск? Или еще какие есть?
>>36637

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


Это как? Можешь схему примерно объяснить? Не очень представляю.
>>36644

>Они там все многие-ко-многим что ли? А, понял, вы все фильтры держите в одной таблице.


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

>Тут явно ошибка - это не выберет записей так как условия противоречат - наверно таблицу джойнят 2 раза?


Хм, да, там OR было, а не AND. Выбираются все фильтры с тэгами 25 или 3.

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


Внешний select выбирает фильтры из полученной таблицы доступных продуктов по этим фильтрам. SELECT DISTINCT filters.filter_id FROM (select товары по фильтрам которые в наличии, плюс фильтры к ним через join filters_to_products)
378 736992
>>36975

По поводу обноления кеша, идея такая. Допустим у нас в кеше хранится информация, что для рубрики "Футболки", цвет "Красный", бренд "Adidas" есть 3 товара.

Допустим теперь товар Футболка красного цвета бренда адидас стал недоступен. Значит мы можем уменьшить соответствующую цифру в кеш-таблице на 1. Тем самым обновив информацию в кеше.

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

Я позже наверно напишу подробнее что думаю по этому поводу, сейчас просто некогда.
379 736993
>>36992

Пока можешь попробовать запрос с DISTINCT и подзапросом который ты писал выше, переписать на чистые джойны без подзапроса и посмотреть скорость.
380 736999
>>36992

>теперь товар Футболка красного цвета бренда адидас стал недоступен. Значит мы можем уменьшить соответствующую цифру в кеш-таблице на 1


Думаю, не можем. Потому что может быть еще другой товар, тоже футболка красного цвета бренда адидас. Т.е. чтобы уменьшить цифру в кеш-таблице, нам сначало надо пройтись опять по всем товарам в магазине, посмотреть есть ли другие товары, которые футболка красного цвета и бренда адидас, и только если их нет, можно из кэш таблицы удалить эту запись. Также видимо возникнет проблема - при исчезновении товара, какие таблицы обновлять. Если всего 13 фильтров, кеш-таблицы мы видимо создавать будем только по 3-4 фильтрам. Для 13 фильтров таких таблиц будет довольно много, значит при изменении наличия товара, нужно обойти всю эту кучу таблиц и для каждой обойти заново все товары в магазине, проверяя что нет товаров с такой комбинацией 3-4 фильтров. Хмм, кажется все это будет занимать много времени.

>>36993
Ок, попробую.
381 737007
>>36999
Также, для 13 фильтров, комбинаций из 3 фильтров будет 2197, это 2197 кеш-таблиц каждый раз проверять при исчезновении товара. Что-то много выходит.
382 737014
>>36638
Спасибо большое за ответы!

>Ты по моему что-то путаешь думая что AR это кодда мы используем FETCH_CLASS.


Я думал, что DataMapper подразумевает работу без FETCH_CLASS.

>Наконец исопьзование или не использование FETCH_CLASS вообще не имеет отношения к DataMapper или AR.


Дошло, я слишком буквально воспринимал тот сайт с паттернами, хотя мог бы догадаться по аббревиатуре DBAL в коде.

>Это неправильно и нарушает прицип DI. StudentMapper не должен создавать объект PDO.


Он и не создаёт, я немного запутанно объяснил здесь:

>поэтому я в конструкторе контроллера получаю уже готовый объект StudentMapper, как мне кажется, так менее уродливей.


Примеры на пике.

Вопросы:
1) Если упростить, в DataMapper для манипуляции данными в БД нужно первым делом найти модель по id, результат-объект в переменную; теперь для изменения/добавления данных нужно обращатся только к этому объекту; дальше у маппера вызывается метод save(), куда передаётся переменная-объект. Правильно понимаю? У меня сейчас именно так всё и работает.

2) Может ли хелпер обращаться к мапперу? Объясню зачем: есть хелпер Auth. Можно проверить зарегистрирован ли пользователь: <?php if (\App\Helper\Auth::check()): ?>

А вот Auth::user() возвращает $_SESSION['user'], то есть только строчку с ником.
Хотелось бы, что Auth::user() возвращал уже объект зарегистрированного пользователя, чтобы делать такие штуки Auth::user()->id или Auth::user()->email
Для этого из хелпера нужен доступ к мапперу.

3) Я гуглил Front Controller и ничего не понял. Сейчас у меня есть класс App, который запускается в index.php через $app = new App($config)
Этот класс App одновременно соединяется с БД, разбирает URI, определяет какой контроллер и экшн вызывать, заполняет контейнер объектами, вызывает контроллер и экшн. В объекте App чуть меньше 100 строк, но он слишком много разных вещей делает. Это норма?
383 737026
>>37007
А, сори, ступил, хеш-таблиц будет 455, а не 2197, ведь порядок полей не важен. Но все равно как-то много, если для каждой все товары сканировать.
384 737049
Проблемы с хелло вордом на слиме. В документации пишут, что нужно поставить правило
RewriteRule ^ index.php [QSA,L]
В итоге отрабатывает только $app->get('/'), какой бы юрл я не вводил. Непонятная чертовщина.
385 737130
>>37049
Разобрался, все хорошо.
386 737150
Аноны, подскажите нубу - хочу для начала изучить HTML и CSS
На сайте http://htmlbook.ru есть два самоучителя. по 4-й и по 5-й версии. Скажите нужно начать изучение с сразу с пятой, или сначала четверка, а потом пятерка?
387 737162
>>37150
Сразу с пятой.
Если ближайшие два года ты будешь просто учиться, то можешь сразу седьмую постигать какими-то путями.
388 737190
>>37150
Пятая, четвертая не используется уже почти. Также сразу учи CSS3 селекторы.
389 737203
>>37150
тот, что по 5-ой не про html в целом, а про нововведения, так что начинай с четвертой, там о том, как делать ссылки, таблицы и прочее..
390 737204
>>37203
про css то же самое, в старом про то что такое селекторы, классы и т.д.
391 737208
Аноны, а как вы смотрите на то, чтобы придумать еще задачек? Устроили бы скажем голосование, а ОП бы уже добавлял, картиночки из анимы подходящие тож запилить можно.
549 Кб, 728x720
392 737209
393 737211
>>37203
>>37204
Понял тебя. Сначала 4-ю, а потом пятую.
Там в комментах вроде говорил кто то об этом.
Может еще какие -нибудь учебники или тому подобное посоветуешь?

>>37162
>>37190
Вам спасибо все равно!
394 737212
>>37211
webref.ru от автора htmlbook но о современных технологиях, там и курсы новые добавили
395 737234
>>37208
Ну давай, начни.
396 737247
>>37208
Задачка о фасетном поиске, какой выше обсуждали, явно не помешала бы. Популярная же штука, почти в каждом магазе встречается, судя по данным гугла.
397 737288
>>36622

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


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

>>36623

>Глядя на твой код, я например, не понимаю, зачем ты передаешь в функцию валидации 'getName'. Зачем ей имя геттера? Оно как-то помогает проверить правильность заполнения поля?


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

>>36623

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


Я объектами делаю - на каждую сущность свой объект ошибок

class Student
{
...
}

class ErrorList
{
...
}

class StudentErrorList extends ErrorList
{
...
}

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

И еще у меня вопрос про паттерны. Немого погуглив и прочитал на википедии что паттерн это всего лишь пример решения проблемы/задачи, и связи с этим у меня возникло несколько вопросов:
Как (мне) новичку узнать какой паттерн применить лучше? Выучить их все и отталкиваться от собственной базы или есть какой-то способ узнать какой паттерн применить? Или же их вовсе не обязательно знать все? Например, когда я изучал код SymfonyForms я сразу обратил внимание что названиях классов содержится слова Builder и Factory и сразу смекнул что это какие-то паттерны, потому что видел что-то такое в твоих ссылках на Design Patterns. Выходит ли что паттерны это всего лишь некая договорённость правильного написания кода, чтобы проще было понимать что написано. Ведь для любой проблемы или задачи всегда можно найти какое-то собственное решение, которое будет не факт что понятно остальным.
397 737288
>>36622

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


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

>>36623

>Глядя на твой код, я например, не понимаю, зачем ты передаешь в функцию валидации 'getName'. Зачем ей имя геттера? Оно как-то помогает проверить правильность заполнения поля?


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

>>36623

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


Я объектами делаю - на каждую сущность свой объект ошибок

class Student
{
...
}

class ErrorList
{
...
}

class StudentErrorList extends ErrorList
{
...
}

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

И еще у меня вопрос про паттерны. Немого погуглив и прочитал на википедии что паттерн это всего лишь пример решения проблемы/задачи, и связи с этим у меня возникло несколько вопросов:
Как (мне) новичку узнать какой паттерн применить лучше? Выучить их все и отталкиваться от собственной базы или есть какой-то способ узнать какой паттерн применить? Или же их вовсе не обязательно знать все? Например, когда я изучал код SymfonyForms я сразу обратил внимание что названиях классов содержится слова Builder и Factory и сразу смекнул что это какие-то паттерны, потому что видел что-то такое в твоих ссылках на Design Patterns. Выходит ли что паттерны это всего лишь некая договорённость правильного написания кода, чтобы проще было понимать что написано. Ведь для любой проблемы или задачи всегда можно найти какое-то собственное решение, которое будет не факт что понятно остальным.
398 737298
>>37208
Реквестирую на проектирование бд.
Потому что пока там только лайки и кинотеатр, это несерьезно.

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

Только не мути очередной громадный квест, который выполнять полгода. Нужны короткие и красивые как шахматные этюды задания.
399 737339
Есть большой XML допустим, что рациональее - загнать данные из него в базу или ходить по файлу simple XML/XML reader ?
400 737343
>>37339
В базу конечно. Парсинг файлов медленное и неоптимальное дело, база же специально под такие задачи заточена.
401 737397
>>37288

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


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

Кстати, валидацию наверно стоит разбить на 2 функции: валидация модели Студента и валидация формы, которая может вызывать первую.

> да и кажется весьма логичным чтобы у каждой сущности был свой класс


Да не уверен. Чем StudentErrorList отличается от любого другого ErrorList? если ничем то не стоит и отдельный класс делать, я думаю.

> Как (мне) новичку узнать какой паттерн применить лучше?


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

http://design-pattern.ru/ (это краткая выжимка из книги Фаулера "Паттерны/Шаблоны Проектирования Корпоративных приложений", можешь ее поискать).

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

Ну например паттерн TableDataGateway ты наверно использовал.

Также, есть примеры тут с кодом, но судя по отзывам других анонов, они менее понятные и в общем похуже чем книга: http://designpatternsphp.readthedocs.io/ru/latest/README.html

> Например, когда я изучал код SymfonyForms я сразу обратил внимание что названиях классов содержится слова Builder и Factory и сразу смекнул что это какие-то паттерны,


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

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


Ну да, паттерн проектирования можно перевести как "шаблон". То есть шаблон решения для той или иной задачи. Вообще, если ты будешь решать ее, не зная паттернов, возможно что в итоге ты придешь к тому же самому, только это займет больше времени, решение получится не до конца идеальным. А в случае паттерна достаточно сказать "давайте используем тут паттерн N" - и все понимают что ты хотел сказать.
401 737397
>>37288

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


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

Кстати, валидацию наверно стоит разбить на 2 функции: валидация модели Студента и валидация формы, которая может вызывать первую.

> да и кажется весьма логичным чтобы у каждой сущности был свой класс


Да не уверен. Чем StudentErrorList отличается от любого другого ErrorList? если ничем то не стоит и отдельный класс делать, я думаю.

> Как (мне) новичку узнать какой паттерн применить лучше?


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

http://design-pattern.ru/ (это краткая выжимка из книги Фаулера "Паттерны/Шаблоны Проектирования Корпоративных приложений", можешь ее поискать).

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

Ну например паттерн TableDataGateway ты наверно использовал.

Также, есть примеры тут с кодом, но судя по отзывам других анонов, они менее понятные и в общем похуже чем книга: http://designpatternsphp.readthedocs.io/ru/latest/README.html

> Например, когда я изучал код SymfonyForms я сразу обратил внимание что названиях классов содержится слова Builder и Factory и сразу смекнул что это какие-то паттерны,


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

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


Ну да, паттерн проектирования можно перевести как "шаблон". То есть шаблон решения для той или иной задачи. Вообще, если ты будешь решать ее, не зная паттернов, возможно что в итоге ты придешь к тому же самому, только это займет больше времени, решение получится не до конца идеальным. А в случае паттерна достаточно сказать "давайте используем тут паттерн N" - и все понимают что ты хотел сказать.
402 737403
>>37209
>>32572

Ок, по коду.

- неправильные названия функций. имена функций начинаются с глагола, "сделайЧтоТо()" и не надо использовать нечитаемые сокращения в них вроде dbst(). parser() это не глагол. pageName это непонятно что.

Попробуй сам прочитать:

GetLinks::pageName()

ПолучитьСсылки::названиеСтраницы()

Как правильно: ПоисковикСсылок::получитьНазваниеСтраницы()

- в Queue::enqueue зачем-то передается двухмерный массив. зачем такая сложная структура? Лучше 1-мерный, а еще лучше - объект Node.
- имена классов - это существительные. GetLinks -> LinksGetter
- к Queue явно надо дописать что именно это за очередь
- нарушение инкапсуляции и зоны ответственности. За работу с очередью отвечает класс Queue. Почему мы узнаем размер очереди не из него напрямую, а через обращение к какой-то таблице?

Много статических вызовов и просто функций: Input::get, view(), Queue::enqueue(). По моему это не очень здорово, чем плохи статические методы? Тем что это по сути не ООП. Это ближе к использованию глобальных переменных или функций.

- Например, если какая-то функция обращается к Input::get, то получается она берет входные данные не из переданных ей аргументов, а откуда-то еще (побочные эффекты: https://github.com/codedokode/pasta/blob/master/good-code.md#Избегай-побочных-эффектов ), мы их не передаем явно, не можем подменить на другие. И это не видно из заголовка функции, что она к Input будет обращаться. То есть эта зависимость не видна, пока ты не изучишь весь код.

Если бы мы использовали не-статический класс Input то нам надо было бы передавать его объект явно в функцию. Было бы явно видно что ей нужны эти данные. Можно было бы их подменить.

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

- Нельзя создать несколько экземпляров объекта с разными данными (это не всегда нужно, но иногда бывает нужно, например при тестировании или каком-то нестандартном коде). Ну например у тебя нельзя создать и обрабатывать 2 Queue параллельно.

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

А вот если бы мы передавали объект Input, мы бы могли передать вместо него альтернативный совместимый с ним класс.

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

Вот еще урок который отчасти связан с этой темой: https://gist.github.com/codedokode/e1d31a31b37d5f635057

Вот как бы мог выглядеть код на объектах (для простоты все объекты я создаю руками без DI-контейенра):

$queueTableGateway = ...
$queue = new Queue($queueTableGateway);
$linksGetter = new LinksGetter();
$pageName = $linksGetter->getPageName();
$node = new Node($pageName, ...);
$queue->enqueue($node);

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

Ну вот посмотрим например на такую штуку:

\DB::setFetchMode(...)

Это как раз пример побочных эффектов. Функция parserResults() меняет глобальное состояние класса DB (который используется и другим кодом) после своего вызова. Допустим, какая-то другая функция использует другой fetchMode, и вызывает parserResults(). Та меняет fetchMode и исходная функция после этого перестает работать. Причем это абсолютно неочевидно, казалось бы, какая связь между ними?

Даже хуже, функция parserResults меняет это трежим не для себя, а видимо для какого-то другого класса (Queue? GetLinks?)

Как было бы лучше: ставить fetchMode не глобально, а только для запросов которые ты делаешь. И не в контроллере, а там, где эти запросы делаются.

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

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

> Как еще я мог назвать класс, который только и делает что достает ссылки из страницы? LinksExtractor?


Почему нет? Кстати, из-за того что он у тебя статический непонятно откуда он вообще берется, чем заполняется и тд.

> Решил передавать массив параметров напрямую в модель для разбора. Правильно или нет


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

>Модель отвечает за работу с БД (или это бизнес-логика делает уже - я пока не вкурил).


В общем, понимаешь ты плохо. Модель это и есть бизнес-логика, то есть сама суть приложения, оторванная от интерфейсов с внешним миром (этим занимаются контроллер и вью).
402 737403
>>37209
>>32572

Ок, по коду.

- неправильные названия функций. имена функций начинаются с глагола, "сделайЧтоТо()" и не надо использовать нечитаемые сокращения в них вроде dbst(). parser() это не глагол. pageName это непонятно что.

Попробуй сам прочитать:

GetLinks::pageName()

ПолучитьСсылки::названиеСтраницы()

Как правильно: ПоисковикСсылок::получитьНазваниеСтраницы()

- в Queue::enqueue зачем-то передается двухмерный массив. зачем такая сложная структура? Лучше 1-мерный, а еще лучше - объект Node.
- имена классов - это существительные. GetLinks -> LinksGetter
- к Queue явно надо дописать что именно это за очередь
- нарушение инкапсуляции и зоны ответственности. За работу с очередью отвечает класс Queue. Почему мы узнаем размер очереди не из него напрямую, а через обращение к какой-то таблице?

Много статических вызовов и просто функций: Input::get, view(), Queue::enqueue(). По моему это не очень здорово, чем плохи статические методы? Тем что это по сути не ООП. Это ближе к использованию глобальных переменных или функций.

- Например, если какая-то функция обращается к Input::get, то получается она берет входные данные не из переданных ей аргументов, а откуда-то еще (побочные эффекты: https://github.com/codedokode/pasta/blob/master/good-code.md#Избегай-побочных-эффектов ), мы их не передаем явно, не можем подменить на другие. И это не видно из заголовка функции, что она к Input будет обращаться. То есть эта зависимость не видна, пока ты не изучишь весь код.

Если бы мы использовали не-статический класс Input то нам надо было бы передавать его объект явно в функцию. Было бы явно видно что ей нужны эти данные. Можно было бы их подменить.

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

- Нельзя создать несколько экземпляров объекта с разными данными (это не всегда нужно, но иногда бывает нужно, например при тестировании или каком-то нестандартном коде). Ну например у тебя нельзя создать и обрабатывать 2 Queue параллельно.

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

А вот если бы мы передавали объект Input, мы бы могли передать вместо него альтернативный совместимый с ним класс.

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

Вот еще урок который отчасти связан с этой темой: https://gist.github.com/codedokode/e1d31a31b37d5f635057

Вот как бы мог выглядеть код на объектах (для простоты все объекты я создаю руками без DI-контейенра):

$queueTableGateway = ...
$queue = new Queue($queueTableGateway);
$linksGetter = new LinksGetter();
$pageName = $linksGetter->getPageName();
$node = new Node($pageName, ...);
$queue->enqueue($node);

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

Ну вот посмотрим например на такую штуку:

\DB::setFetchMode(...)

Это как раз пример побочных эффектов. Функция parserResults() меняет глобальное состояние класса DB (который используется и другим кодом) после своего вызова. Допустим, какая-то другая функция использует другой fetchMode, и вызывает parserResults(). Та меняет fetchMode и исходная функция после этого перестает работать. Причем это абсолютно неочевидно, казалось бы, какая связь между ними?

Даже хуже, функция parserResults меняет это трежим не для себя, а видимо для какого-то другого класса (Queue? GetLinks?)

Как было бы лучше: ставить fetchMode не глобально, а только для запросов которые ты делаешь. И не в контроллере, а там, где эти запросы делаются.

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

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

> Как еще я мог назвать класс, который только и делает что достает ссылки из страницы? LinksExtractor?


Почему нет? Кстати, из-за того что он у тебя статический непонятно откуда он вообще берется, чем заполняется и тд.

> Решил передавать массив параметров напрямую в модель для разбора. Правильно или нет


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

>Модель отвечает за работу с БД (или это бизнес-логика делает уже - я пока не вкурил).


В общем, понимаешь ты плохо. Модель это и есть бизнес-логика, то есть сама суть приложения, оторванная от интерфейсов с внешним миром (этим занимаются контроллер и вью).
Ответы 403 737404
>>31615

Скорее всего для FTP нужен отдельный логи и пароль, может он в письме, может в панели управления.

>>31619

> Круг строится, но выглядит как дерьмо.


Идеально он наверно и не будет выглядеть так как буквы ставятся не как угодно, а по сетке. Ну и коэффициент у тебя маловат: 1.1105 - там должно быть что-то в районе 1.4 ... 2. У тебя круг сплющенный из-за этого.

По коду: оформлено все плохо. Тебе надо работать над тем, чтобы делать код более понятным и лаконичным. Ну например код вывода данных на экран переусложнен.

Для вывода достаточно сделать 2-мерный массив, то есть массив строк, где каждая строка представлена как массив символов:

$field = [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' ']
];

Тогда установка буквы в определенную точку делается так:

$field[$y][$x] = 'А';

А вывод можно сделать например через цикл по строкам + implode для вывода строки.

Ты же выбрал другой способ хранения и как следствие получился запутанный код. Ты еще добавил сюда неудачные названия переменных ($xlast вместо $lastX или $xLast) и не смог разбить сложный код на отдельные простые функции. Ну давай посмотрим например на это:

for ($z=0;$z<$xlast;$z++) {
$echoTemp =$echoTemp.' ';
}

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

> $radius = ceil($leng/4);


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

Для разбиения строки на массив букв есть хак - preg_split("//u", $text, null, PREG_SPLIT_NO_EMPTY), хотя твой способ тоже интересный, если ты сам до него додумался.

> 'y' => round(cos(deg2rad($angle $i)) $radius),


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

В общем, советую переделать.
Ответы 403 737404
>>31615

Скорее всего для FTP нужен отдельный логи и пароль, может он в письме, может в панели управления.

>>31619

> Круг строится, но выглядит как дерьмо.


Идеально он наверно и не будет выглядеть так как буквы ставятся не как угодно, а по сетке. Ну и коэффициент у тебя маловат: 1.1105 - там должно быть что-то в районе 1.4 ... 2. У тебя круг сплющенный из-за этого.

По коду: оформлено все плохо. Тебе надо работать над тем, чтобы делать код более понятным и лаконичным. Ну например код вывода данных на экран переусложнен.

Для вывода достаточно сделать 2-мерный массив, то есть массив строк, где каждая строка представлена как массив символов:

$field = [
[' ', ' ', ' '],
[' ', ' ', ' '],
[' ', ' ', ' ']
];

Тогда установка буквы в определенную точку делается так:

$field[$y][$x] = 'А';

А вывод можно сделать например через цикл по строкам + implode для вывода строки.

Ты же выбрал другой способ хранения и как следствие получился запутанный код. Ты еще добавил сюда неудачные названия переменных ($xlast вместо $lastX или $xLast) и не смог разбить сложный код на отдельные простые функции. Ну давай посмотрим например на это:

for ($z=0;$z<$xlast;$z++) {
$echoTemp =$echoTemp.' ';
}

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

> $radius = ceil($leng/4);


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

Для разбиения строки на массив букв есть хак - preg_split("//u", $text, null, PREG_SPLIT_NO_EMPTY), хотя твой способ тоже интересный, если ты сам до него додумался.

> 'y' => round(cos(deg2rad($angle $i)) $radius),


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

В общем, советую переделать.
Ответы, Вектор 404 737407
>>31758

О, интересное реешние где профессия сделана отдельным объектом.

> public function setProfession ($profession) {


> public function setEmployee ($employee){


тут нужен тайп-хинт. Также по PSR вроде фигурная скобка ставится на новой строке. И лучше не set, а add.

Для классов профессий - ты переопределяешь поля с зарплатой, названием. Но тут есть недостатки:

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

Не хочешь попробовать решить обе проблемы за счет абстрактных методов?

> public $departaments = array(); // департаменты


Лучше наверно будет сделать приватным чтобы снаружи нельзя было что попало туда запихнуть или что-то сделать.

> public function getAvrSalary (){


average сокращается как avg, а еще лучше было бы не сокращать вообще. Если ты еще не сделал это, поставь себе удобный редактор или IDE.

> $avrSalary = round($this->getTotalSalary () / count($this->departaments), 2)


Вообще, окргление лучше делать при выводе, а тут давать точные данные. Кто знает как они испоьзоваться будут.

кстати, я подумал, а ведь Департамент не существует вне Компании, может имеет смысл тут применить композицию вместо агрегации? Хотя можно и так оставить.

> function creationEmployees (


Функции начинаются с глагола, создатьСотрудника, а не создание.

> for ($id = 1; $id <= $vacancyQuantity; $id++) {


> $employees[$id] = new Employee($id);


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

> $employees[$id]->setProfession($professions[$profession]);


> $employees[$id]->setRank($rank);


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

> $departament = $vector->departaments[$depName];


Вот тут явно стоило бы вместо прямого обращения использовать метод поиска по названию. А еще лучще - сделать чтобы функция работала с одним департаментом за раз и он передавался в нее объектом.

> public function padLeft($string, $length) {


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

Конструктор стоит писать первым в списке методов. Вообще, порядок такой: константы, публичные поля, непубличные, конструкторы, публичные методы, непубличные. Чтобы читать было удобнее.

> $this->str .= "\n" . $this->padRight($str, $this->length);


Логичнее хранить исходные загловки, а форматировать только при выводе.

> if ($caption==1) {


> // Добаляем горизонтальное поддчеркивание снизу, длина колонки * кол-во колонок


Логичнее черту по моему выводить в методе таблицы.

Вместо public $str лучше сделать метод getAsString() или render().

> unset($strs); // обнуляем массив


$strs = []; (что за название странное?)

В общем, неплохо, давай теперь еще антикризисные меры.
Ответы, Вектор 404 737407
>>31758

О, интересное реешние где профессия сделана отдельным объектом.

> public function setProfession ($profession) {


> public function setEmployee ($employee){


тут нужен тайп-хинт. Также по PSR вроде фигурная скобка ставится на новой строке. И лучше не set, а add.

Для классов профессий - ты переопределяешь поля с зарплатой, названием. Но тут есть недостатки:

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

Не хочешь попробовать решить обе проблемы за счет абстрактных методов?

> public $departaments = array(); // департаменты


Лучше наверно будет сделать приватным чтобы снаружи нельзя было что попало туда запихнуть или что-то сделать.

> public function getAvrSalary (){


average сокращается как avg, а еще лучше было бы не сокращать вообще. Если ты еще не сделал это, поставь себе удобный редактор или IDE.

> $avrSalary = round($this->getTotalSalary () / count($this->departaments), 2)


Вообще, окргление лучше делать при выводе, а тут давать точные данные. Кто знает как они испоьзоваться будут.

кстати, я подумал, а ведь Департамент не существует вне Компании, может имеет смысл тут применить композицию вместо агрегации? Хотя можно и так оставить.

> function creationEmployees (


Функции начинаются с глагола, создатьСотрудника, а не создание.

> for ($id = 1; $id <= $vacancyQuantity; $id++) {


> $employees[$id] = new Employee($id);


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

> $employees[$id]->setProfession($professions[$profession]);


> $employees[$id]->setRank($rank);


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

> $departament = $vector->departaments[$depName];


Вот тут явно стоило бы вместо прямого обращения использовать метод поиска по названию. А еще лучще - сделать чтобы функция работала с одним департаментом за раз и он передавался в нее объектом.

> public function padLeft($string, $length) {


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

Конструктор стоит писать первым в списке методов. Вообще, порядок такой: константы, публичные поля, непубличные, конструкторы, публичные методы, непубличные. Чтобы читать было удобнее.

> $this->str .= "\n" . $this->padRight($str, $this->length);


Логичнее хранить исходные загловки, а форматировать только при выводе.

> if ($caption==1) {


> // Добаляем горизонтальное поддчеркивание снизу, длина колонки * кол-во колонок


Логичнее черту по моему выводить в методе таблицы.

Вместо public $str лучше сделать метод getAsString() или render().

> unset($strs); // обнуляем массив


$strs = []; (что за название странное?)

В общем, неплохо, давай теперь еще антикризисные меры.
405 737432
>>37014
Дополнение к вопросу 2: возможность получать доступ из хелпера к мапперу возникла из-за того, что в форме для редактирования профиля нужно откуда-то брать значения, которые будут передаваться в value="" как дефолтные значения для инпутов.

Как сейчас это работает, если убрать лишнее:
- если пользователь зарегистрирован, получаю email этого пользователя
- обращаюсь к мапперу и получаю модель этого пользователя
- данные модели передаю во view, а во view-файле распихиваю переданные данные по value=""

Быть может, стоит при логине записывать в сессию все данные о пользователе, которые можно редактировать? Из сессии проще достать их потом и распихать по input'ам, через каждый раз запрос в БД делать.

2. Почитал я про DI у тебя в гистах и понял, что у меня в классе App подобие Registry и сделать из этого DI никак не получается. Service Locator подошёл лучше, невзирая на его недостатки; подключение к БД теперь вне App (пик).

>>32572

>Насчет странности я не понимаю о чем речь, взял тут https://laravel.com/docs/5.2/queries#retrieving-results


Если в Laravel можно делать X несколькими способами, то не стоит брать самые неочевидные. Query Builder следует использовать, когда Eloquent ORM недостаточно, а для подсчёта значений в таблице этой ORM достаточно. А вместо непонятно откуда берущегося Input обычно используют объект класса Request, которые передаётся в контроллер параметром.
406 737433
Привет, дорогие друзья, а подскажите, пожалуйста, существуют ли книги PHP о том как сделать сайт - блог. Всем заранее спасибо.
407 737434
P.S. Хочу потренировать популярные базовые навыки, то есть смастерить, скажем 10 блогов, и 10 интернет-магазинов исключительно ради тренировки. Книгу про интернет-магазины я нашёл, а про блоги нет.
408 737441
>>37434
Книгу про интернет-магазины в студию!
409 737447
>>37441
PHP и MySQL Создание интернет-магазинов Ларри Ульман.
Господа знатоки, но не забудьте и мне про блоги что-нибудь посоветовать.
45 Кб, 248x348
410 737470
>>37434
Пикрелейтед может пригодиться.
Только более новое издание нужно.
411 737474
>>37432
Пик отвалился. Даже показывать немного стыдно. Это тот класс, который мастер на все руки.

>Из сессии проще достать их потом и распихать по input'ам, через каждый раз запрос в БД делать.


*через каждый раз запрос в БД делать.

Безуспешно пытаюсь не плодить посты.

>>37434

>Книгу про интернет-магазины я нашёл, а про блоги нет.



Вот посмотри, сможешь ли ты реализовать такой примитивный блог: http://www.blogovo.ru/testovoe-zadanie-programmistu-php-junior
Если да, то тебе осталось добавить аутентификацию и комментарии. Если с этим проблемы, то задачка на список студентов их решит, так как суть везде одна и та же. И не нужны тебе целые книги, посвящённые созданию блогов.
Ньюфаг с задачами 412 737498
Аноны, подскажите, пожалуйста: задачка с проверкой на ошибки решается с одной регуляркой? У меня получилось только через функцию с отдельной регуляркой для каждой ошибки.
Что скажете насчёт опечаточника? http://ideone.com/yhglMW
413 737501
Что-то непойму. Не получается пдо подключить, пишет, что драйвер не найден, хотя в пхпини они включены и по пхпинфо они тоже есть( и пдо, и пдо_майскл), что за херня?
414 737504
>>37501
А, нет, это я аутист.
415 737589
>>37407

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


>- если кто-то забудет переопределить поле, это никак не обнаружится.


>


>Не хочешь попробовать решить обе проблемы за счет абстрактных методов?



Хочу, только я не понимаю как это сделать. Можно пример?

Я рассуждаю так:

Если я создаю абстрактный метод setSalaryRate, в дочернем классе он должен быть переопределен в обязательном порядке. Тогда программист, который решил создать новый дочерний класс (новую профессию), должен будет его описать. Но, если в данной реализации, программист может пропустить переопределение свойств, то что ему мешает скопипастить этот метод с класса профессии, которая уже существует, и в которой я описал этот метод. Тогда метод должен не просто переопределять свойство setSalaryRate, но и запрашивать значение при создании экземпляра? Тогда, логично описать этот метод в конструкторе. (Значит метод конструктор в классе предке будет абстрактным). И получится примерно такой функционал конструктора: при создании экземпляра класса, конструктор принимает аргументом значение setSalaryRate.
Но опять же, что если он не скопирует этот метод, и не будет описывать вообще какой либо функционал. Т.е. метод уже не абстрактный, но при этом ничего не делает?
Значит, реализация которую я представляю, не защитит от этой ошибки. Как сформулировать этот вопрос гуглгу?
К слову я уже задавал этот вопрос в этом треде >>35032,
думал, что мне ответил ОП >>35111
416 737607
помогите :с
что-то не так с регулярным выражением, я не могу понять
http://ideone.com/z2spPS
417 737634
Оп, запили урок по парсингу информации с веб страниц и хранению спаршенной инфы в базе. Что думаешь?
418 737635
ОП, а ты в бекэнд JS шаришь? Хотелось бы вкатиться безболезненнее в ноду, с ванильным js вроде всё ок
419 737647
>>37498
Опечаточник в порядке.
А в задаче с проверкой на ошибки можно сделать ассоциативный массив с регулярками в ключах и описаниями ошибок в значениях - это если без функции.
['/жы/ui' => 'Жи/ши пиши с буквой \"И\"', '/сдесь/ui' => 'Правильно писать \"Здесь\"', '/координально/ui' => 'Правильно \"кардинально\"'];
Дальше цикл foreach, который при соответствии найденным ошибкам (регулярки в ключах) будет выдавать описание ошибки (описания в значениях массива).
А так прилагай код всегда, так быстрее и точнее тебе ответят.

>>37607
Если символа между цифрами два и более - не захватывает весь номер. Это исправь.
45 Кб, 640x480
420 737657
ОП, спасибо за разбор задачи про Вектор в прошлом треде, вот небольшие изменения: http://ideone.com/kLgXIj
Главное изменение - внедрил класс Компания.
Вот твой разбор в прошлом треде: >>731915
Кое-что прояснело уже после того, как я это решение сделал, как обычно.
Получается, нам нужно создавать всё-таки кучу экземпляров класса Сотрудник, а потом приписывать их экземпляру класса Департамент? Ну и после этого экземпляры Департамента приписывать классу Компания?
Твой разбор сохранил, позже попробую именно по тем рекомендациям всё сделать.
Нереально ты помогаешь, братишка, куда бы я без тебя...
421 737661
>>37647
я сколько пытался чего-то менять, но никак ничего не получается. Ты не мог бы конкретно указать, что на что менять, а то я без сил -_-
422 737664
>>37661
А где у тебя первый вариант? Он был ближе к тому, что нужно.
Когда уже доходит до проверки чисел ЗА +7 и 8, то нужна регулярка "любое количество скобок, минусов, пробелов в любом порядке либо вообще ни одного", а дальше цифры.
Тебе понадобятся квадратные скобки, перечисление внутри них разных знаков, которые не могут быть или не быть, за скобками знак "любое количество указанного или полное отсутствие" - и всё. Дальше сами цифры от 0 до 9 повторить 10 раз.
Так немного понятнее?
423 737678
>>37664
что я делаю не так?
http://ideone.com/CE1S09
424 737702
>>37634
Гуглишь Simple HTML DOM, читаешь доку: http://simplehtmldom.sourceforge.net/manual.htm

Ты массив сможешь в БД вставить foreach'eм? Так вот, контент сразу парсишь в массив массивов массивов . Пробегаешься по массиву поэлементно, каждый элемент массива суёшь в базу запросами вида "INSERT INTO ..."
Для "вкатиться" тебе этого с головой хватит.

>>37634
Гуглишь что-то вроде "how learn X properly", получаешь гайд вроде http://javascriptissexy.com/learn-node-js-completely-and-with-confidence/

Не отвлекайте ОПа тем, что на первых станицах гугла можете легко найти сами.
425 737736
>>37678
все верные номера стали верными, а далее я никак, прошу помощи, черт подери
http://ideone.com/vw5P0b
426 737742
>>37678
Тут ты не даёшь понять, что все символы должны быть тесно связаны с цифрами.
Попробуй объединить круглыми скобками все знаки и цифру - и уже этому задай количество повторений - 10.
>>37736
А вот тут ты исправляешься, но забываешь про то, что в квадратных скобках символы меняют своё значение и большинство из них экранировать не надо. Убери несколько обратных слэшей из квадратных скобок.
427 737744
Господа, решаю задачу под название "Клавиша shift" из раздела "Повторим" и застопорился вот на каком моменте: " Исправь текст так, чтобы ... после знаков запятая, точка, точка с запятой, двоеточие, восклицательный и вопросительный знак стоял ровно один пробел (а перед ними — ни одного)"
Насколько я понимаю могут быть три случая неправильного расположения знака препинания и один правильный:
1)скачать , но
2)скачать ,но
3)скачать,но
4)скачать, но (правильный). Но неужели можно подобрать такую регулярку, чтобы она одновременно находила первые три и не находила четверую?
428 737745
>>37736
Аа, ты ещё не определяешь конкретно, чтобы проверка была именно этого номера, а не отдельных частей текста.
Вспомни про циркумфлекс и знак доллара, там было это в начале или середине урока.
429 737752
>>37736

>[+7|8]


Как ты это себе представляешь? Не имеет смысла ставить в квадратные скобки сравнение, потому что квадратные скобки - это "один из указанных символов в случайном порядке".
Тем более, что есть номера, которые начинаются с "+ 7" - как ты такие захватишь?
Давай-давай, постигай основы.
Это достаточно непростая задача для новичка, но надо самому дойти до всего.
430 737757
>>37744
Можно.
Условий всего два:
1. Перед запятой не должно быть пробела.
2. После запятой не должна сразу идти буква.
431 737765
>>33196
ОП, посмотри задачи, пожалуйста. Ты меня пропустил
4 Кб, 529x163
432 737812
>>37757
все выходит с точность до наоборот
а мне нужен обратный эффект
433 737840
>>37752
http://ideone.com/NDkmHy
J__________J
это было жестко, но спасибо тебе.
434 737846
>>37589

Нет, идея такая:

abstract class A
{
abstract protected function getBaseSalary();
}

class B extends A
{
protected function getBaseSalary()
{
return 500;
}
}

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

> Но, если в данной реализации, программист может пропустить переопределение свойств, то что ему мешает скопипастить этот метод с класса профессии, которая уже существует


Если он копирует код не думая, то, конечно, ничто ему не поможет. Идея другая.

- когда мы используем абс. методы, достаточно посмотреть на список абс. методов и понятно как именно сделать класс-наследника
- когда мы их не используем, то надо полностью анализиовать код класса и думать что надо переопределить. Обычно это дольше. У тебя конечно код классов-профессий очень простой и можно обойтись без абс. методов, но если бы у тебя были более сложные классы, то без абс. методов было бы тяжело.
435 737852
>>37744

Ищем такие последовательности:

(любое число пробелов в том числе 0) (знак препинания) (любое число пробелов в том числе 0)

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

(знак препинания) (1 пробел)
436 737854
>>717443

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


>- методы генерации соли и токена - не лучше ли разместить в классе авторизации?


Хелпер отвечающий за авторизацию и класс авторизации это те же самые вещи?

>>717443

>Вот представь что мы хотим взять модель студента и заполнить форму его данными. Сколько для этого кода надо? А хотелось бы чтобы это делалось в 2-3 строчки:


>


>$form->setStudent($sudent);


С использованием композиции, я лишился надобности заполнять данными Студента после валидации (класс формы заполняет его автоматически), и перед добавлением студента в дб остается только поменять в нём пароль. У меня появляются некоторые сомнения насчет того что это должен делать контроллер, а не класс формы. Вот небольшой отрывок из контроллера: https://ideone.com/yIPuZ6

Мы вместо двух строчек можем получить одну

//код метода Формы
function setStudentPassword()
{
$this->student->setPassword($this->password));
}

//код в контроллере
if (!$errors->hasErrors()) {
$registerStudentForm->setStudentPassword();
...
}

>>717443

>Насчет логина по имени - странная идея. Разве имена уникальны? Нужно тогда как минимум проверять что имя уникально и если нет, не разрешать логиниться через него. Также, надо иметь не 3 поля, а одно, в которое можно ввести что угодно. Это же неудобно, когда в форме лишние поля.


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

>>717443

>Наконец обрати внимание еще на это место:


>


>> https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L42


>Чтобы залогиниться у тебя надо написать сложный код. Почему бы не сделать проще, напрмиер так:


>


>if ($authService->isValidPassword($student, $password)) {


>$authService->login($student);


>....


>}


$authService это все тот же класс авторизации о котором я спрашивал выше?

>>717443

>Для авторизации не стоит исплоьзовать сессию. Она же устаревает и удаляется через 20-30 минут неактивности. Лучше просто использовать куку с id и хешем пароля.


А разве я не должен спросить у пользователя хочет ли он оставаться залогиненым?

>>717446 >>717241

>>Я захотел сделать чтобы для залогинивания можно было использовать и почту, и фамилию, и имя, я подошел к этому таким способом:


>>https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L40


>>Это можно как-нибудь сократить или это нужно вынести в отдельную функцию чтобы сделать контроллер 'тонким'? Если выносить в отдельную функцию, то кто этим должен заниматься? Контроллер или хелпер?


>Можно, но я думаю что не имеет смысла так как этот код нигде никогда больше не понадобится. Сам код цикла содержит много ошибок.


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

>>717446

>> Что будет если сделать редирект перед остановкой цикла?


>Не знаю, а что-то дложно быть? Редирект это просто выдача заголовка. после него код выполнять особого смысла нет.


Перефразирую вопрос: Что становится с кодом после ридеректа? Выполняется функция die()?

>>717446

>Значит, надо сделать такой метод:


>...->ispasswordValid($student, $password)


>Почему контроллер должен считать какие-то хеши? Почему он вообще должен знать что у нас исплоьзуются хеши? Это ответственность хелпера (сервиса) авторизации, знать как она устроена. Контроллер просто просит сервис проверить пароль на правильность. Или залогнинить студента. Или разлогинить. Не вдаваясь в детали, как он устроено.


>Это ответственность хелпера (сервиса) авторизации, знать как она устроена.


А почему не ответственность валидатора? В названии функции присутствует слово Valid, значит это как-то относится к валидации. И если, мы отнесем его к валидации то как не запутаться между этим методом и методом проверки на правильность написания пароля, которая нужна при регистрации?
436 737854
>>717443

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


>- методы генерации соли и токена - не лучше ли разместить в классе авторизации?


Хелпер отвечающий за авторизацию и класс авторизации это те же самые вещи?

>>717443

>Вот представь что мы хотим взять модель студента и заполнить форму его данными. Сколько для этого кода надо? А хотелось бы чтобы это делалось в 2-3 строчки:


>


>$form->setStudent($sudent);


С использованием композиции, я лишился надобности заполнять данными Студента после валидации (класс формы заполняет его автоматически), и перед добавлением студента в дб остается только поменять в нём пароль. У меня появляются некоторые сомнения насчет того что это должен делать контроллер, а не класс формы. Вот небольшой отрывок из контроллера: https://ideone.com/yIPuZ6

Мы вместо двух строчек можем получить одну

//код метода Формы
function setStudentPassword()
{
$this->student->setPassword($this->password));
}

//код в контроллере
if (!$errors->hasErrors()) {
$registerStudentForm->setStudentPassword();
...
}

>>717443

>Насчет логина по имени - странная идея. Разве имена уникальны? Нужно тогда как минимум проверять что имя уникально и если нет, не разрешать логиниться через него. Также, надо иметь не 3 поля, а одно, в которое можно ввести что угодно. Это же неудобно, когда в форме лишние поля.


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

>>717443

>Наконец обрати внимание еще на это место:


>


>> https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L42


>Чтобы залогиниться у тебя надо написать сложный код. Почему бы не сделать проще, напрмиер так:


>


>if ($authService->isValidPassword($student, $password)) {


>$authService->login($student);


>....


>}


$authService это все тот же класс авторизации о котором я спрашивал выше?

>>717443

>Для авторизации не стоит исплоьзовать сессию. Она же устаревает и удаляется через 20-30 минут неактивности. Лучше просто использовать куку с id и хешем пароля.


А разве я не должен спросить у пользователя хочет ли он оставаться залогиненым?

>>717446 >>717241

>>Я захотел сделать чтобы для залогинивания можно было использовать и почту, и фамилию, и имя, я подошел к этому таким способом:


>>https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L40


>>Это можно как-нибудь сократить или это нужно вынести в отдельную функцию чтобы сделать контроллер 'тонким'? Если выносить в отдельную функцию, то кто этим должен заниматься? Контроллер или хелпер?


>Можно, но я думаю что не имеет смысла так как этот код нигде никогда больше не понадобится. Сам код цикла содержит много ошибок.


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

>>717446

>> Что будет если сделать редирект перед остановкой цикла?


>Не знаю, а что-то дложно быть? Редирект это просто выдача заголовка. после него код выполнять особого смысла нет.


Перефразирую вопрос: Что становится с кодом после ридеректа? Выполняется функция die()?

>>717446

>Значит, надо сделать такой метод:


>...->ispasswordValid($student, $password)


>Почему контроллер должен считать какие-то хеши? Почему он вообще должен знать что у нас исплоьзуются хеши? Это ответственность хелпера (сервиса) авторизации, знать как она устроена. Контроллер просто просит сервис проверить пароль на правильность. Или залогнинить студента. Или разлогинить. Не вдаваясь в детали, как он устроено.


>Это ответственность хелпера (сервиса) авторизации, знать как она устроена.


А почему не ответственность валидатора? В названии функции присутствует слово Valid, значит это как-то относится к валидации. И если, мы отнесем его к валидации то как не запутаться между этим методом и методом проверки на правильность написания пароля, которая нужна при регистрации?
437 737875
>>37840
Вот и молодец.
Ну а вот мой вариант, который сделал, чтобы показать тебе, если совсем не пойдёт: http://ideone.com/bRC90j
То же самое, только кое-что местами поменяно.
Регулярные выражения вообще интересные штуки, мощная тема, надо бы что-нибудь дополнительно изучить по ним, я всё хотел.
438 737876
>>37812
Вообще неправильный подход вроде.
Там чуть выше ОП расписал алгоритм, попробуй его буквально воссоздать в регулярке, базарю, ещё захочешь, поцене 38 рублей.
439 737959
Подойдет ли пистон для начинающего веб разработчика? Или лучше все же пыха?
440 737967
>>37959
Лучше Java
441 737968
>>37959
pascal
442 737969
>>37959
питончик няшный и джанго там попроще какого нибудь zend'a будет
443 737980
>>37959
Выбирай то на чём хочешь зарабатывать деньги, если конечная цель именно это.
3 Кб, 159x170
444 737987
>>37852
спасибо большое
445 738027
>>37846
Спасибо, теперь стало понятнее для чего и как это делать

>>37702
Спасибо, прочитаю этот урок, потом про взаимодействие с бд. И потом начну пробовать.
446 738029
>>37967
Начинающий веб-разработчик в Спрингах утонет нахуй.
447 738040
>>38029
Да и вроде Java скорее больше для мобильных приложений, и для программ для ПК, чем для веб. Безусловно на Java можно и бэкенд сделать, но вакансий и фриланс работ не так уж и много по этому направлению как для PHP, JS.
448 738044
>>37854

> Хелпер отвечающий за авторизацию и класс авторизации это те же самые вещи?


да

> Мы вместо двух строчек можем получить одну


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

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


Имя в принципе не уникально так как Иванов много. Не надо полагаться на это вот "маловероятно".

> $authService это все тот же класс авторизации о котором я спрашивал выше?


Наверно да

> А разве я не должен спросить у пользователя хочет ли он оставаться залогиненым?


не знаю. Можешь спрашивать, я не против. Но и в этом случае сессия не нужна.

> Стыдно спрашивать, но можно подсказку в каких местах ошибки?



код если честно создает ощущение что автор не понимает ни как работает цикл ни как надо использовать переменные.

> foreach ($student as $key => $value) {


> if (!count(array_filter($student)))


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

> unset($student[$key]);


Зачем во время цикла удалять элементы из массива? Точнее зачем их вообще удалять?

> $student = $value;


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

> $_SESSION['id'] = $student->getId();


> $_SESSION['name'] = $student->getName();


> $_SESSION['surname'] = $student->getSurname();


> $_SESSION['token'] = $student->getToken();


Зачем класть так много данных? В чем преимущество сессии перед куками? Как ты сделашь залогинивание дольше чем на полчаса?

> $loginStudentForm->getError('login', "Incorrect username or password")


Непонятно почему этот код внутри цикла. Ты хочешь несколько раз ошибку добавить?

> Перефразирую вопрос: Что становится с кодом после ридеректа?


Можно die можно return, так даже аккуратнее мне кажется.

> А почему не ответственность валидатора?


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

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

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

В MVC для смены или проверки пароля форма не обязательна. И кстати проверить данные в модели студента тоже должно быть можно без формы.

Потому выгоднее может быть сделать что валидатор лишь проверяет соответсвие данных опредленному формату, а за проверку пароля отвечает не он. Но можешь делать как хочешь, если сделаешь неправильно я все равно увижу ошибку.
448 738044
>>37854

> Хелпер отвечающий за авторизацию и класс авторизации это те же самые вещи?


да

> Мы вместо двух строчек можем получить одну


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

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


Имя в принципе не уникально так как Иванов много. Не надо полагаться на это вот "маловероятно".

> $authService это все тот же класс авторизации о котором я спрашивал выше?


Наверно да

> А разве я не должен спросить у пользователя хочет ли он оставаться залогиненым?


не знаю. Можешь спрашивать, я не против. Но и в этом случае сессия не нужна.

> Стыдно спрашивать, но можно подсказку в каких местах ошибки?



код если честно создает ощущение что автор не понимает ни как работает цикл ни как надо использовать переменные.

> foreach ($student as $key => $value) {


> if (!count(array_filter($student)))


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

> unset($student[$key]);


Зачем во время цикла удалять элементы из массива? Точнее зачем их вообще удалять?

> $student = $value;


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

> $_SESSION['id'] = $student->getId();


> $_SESSION['name'] = $student->getName();


> $_SESSION['surname'] = $student->getSurname();


> $_SESSION['token'] = $student->getToken();


Зачем класть так много данных? В чем преимущество сессии перед куками? Как ты сделашь залогинивание дольше чем на полчаса?

> $loginStudentForm->getError('login', "Incorrect username or password")


Непонятно почему этот код внутри цикла. Ты хочешь несколько раз ошибку добавить?

> Перефразирую вопрос: Что становится с кодом после ридеректа?


Можно die можно return, так даже аккуратнее мне кажется.

> А почему не ответственность валидатора?


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

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

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

В MVC для смены или проверки пароля форма не обязательна. И кстати проверить данные в модели студента тоже должно быть можно без формы.

Потому выгоднее может быть сделать что валидатор лишь проверяет соответсвие данных опредленному формату, а за проверку пароля отвечает не он. Но можешь делать как хочешь, если сделаешь неправильно я все равно увижу ошибку.
449 738045
>>37657

> Получается, нам нужно создавать всё-таки кучу экземпляров класса Сотрудник, а потом приписывать их экземпляру класса Департамент? Ну и после этого экземпляры Департамента приписывать классу Компания?



Да

И судя по тому что в Компании есть поля вроде public $allSalary = 0; ты еще не все исправил.
450 738047
>>37635

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

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

Так же как раз есть 2 задачи имеющих некоторое отноешние к яваскрипту:

Сапер с MVC https://github.com/codedokode/pasta/blob/master/js/minesweeper-mvc.md
SPA приложение https://github.com/codedokode/pasta/blob/master/js/spa.md

Можешь глянуть.
451 738048
>>37634

Он не нужен если ты разбираешься в протоколе HTTP, знаешь библиотеку-HTTP-клиент, DOM, сами базы данных - тогда тебе все и так очевидно. Вот по этим темам уроки может быть были бы полезны, но считается что они относительно легкие.
452 738050
>>37474

Блог лучше делать на фреймворке или микрофреймворке. Задача на студентов только для изучения основ а не пример как надо писать приложения так как в ней слишком много "велосипедов" которые ты пишешь сам хотя лучше использовать готовое.

> Пик


new Session это уже странно. Зачем ты создаешь объхект который сразу же удаляется? Может проще его не создавать тогда?

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

Непонятно зачем ты указываешь путь к конфигу в методе setStudentMapper - зачем он там?

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

Картинка демонстрирует непонимание принципов ООП автором.

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

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

Не хватает пагинации и сортировки.
453 738052
>>37014

на пике я вижу очень странное слово self:: . Это точно ООП?

> 1) Если упростить, в DataMapper для манипуляции данными в БД нужно первым делом найти модель по id, результат-объект в переменную; теперь для изменения/добавления данных нужно обращатся только к этому объекту; дальше у маппера вызывается метод save(), куда передаётся переменная-объект.


вообще в навороченных мапперах в save не надо передавать модель. Они сами умеют находить изменения в любом числе моделей и сохранять их в БД. Более простые не умеют и там надо все вручную передавать.

> Правильно понимаю? У меня сейчас именно так всё и работает.


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

Маппер противопоставляется active record так как в AR модель умеет сама работать с базой. бизнес-логика и работа с БД тесно смешаны в одном классе. Главная разница в этом.
454 738055
Кстати, насчет ноды. А как её на хостинге поставить, если она сама по себе является сервером? Никак?
455 738056
>>37014

> 2) Может ли хелпер обращаться к мапперу?


Да так как это более высокоуровневый слой.

> <?php if (\App\Helper\Auth::check()): ?>


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

> 3) Я гуглил Front Controller и ничего не понял.


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

> В объекте App чуть меньше 100 строк, но он слишком много разных вещей делает. Это норма?


не знаю.

> что в форме для редактирования профиля нужно откуда-то брать значения, которые будут передаваться в value="" как дефолтные значения для инпутов.


А ты читал урок про обработку форм? Там же вроде написано откуда.

> Быть может, стоит при логине записывать в сессию все данные о пользователе, которые можно редактировать? Из сессии проще достать их потом и распихать по input'ам, через каждый раз запрос в БД делать.


Вижу что не читал. Иди и перечитай.
456 738058
>>37470

Там плохой код имейте в виду. Лапша на функциях. Автор сам по моему тот ее быдлокодер.

>>37433

Разработка блога ничем не отличается от других видов приложений

>>37434

Нет смысла делать 10 блогов. Блоги и ИМ делать проще всего взяв готовую CMS. Это не требует программирования.
457 738059
Ананасики, подзастрял на опечаточниках, а точнее на расширенном варианте задания. Пришел к выводу что можно решить таким образом: разбитие текста по символу переноса строки -> разбитие строки по пробелам -> проверка слова на специфичные символы свойственные языку (типа "qui или йцф"), если специфичных символов нет, то подсчет количества символов английского и русского алфавита, и в зависимости от того каких символов больше, в ту сторону и переводить через preg_replace с массивами схожих символов -> собирать слова в строки ->собирать строки в текст.
Подскажите, я вообще в правильном направлении иду, а то откуда-то возникает такое чувство, что я что-то упустил, и там может вообще двумя строчками все решается, а я тут горожу велосипеды через циклы.
12 Кб, 250x249
458 738062
Пыханы. Есть подработка (допилить скрипт магазина по мелочи, приделать апи внешнего сервиса, сделать загрузку xml->mysql, интересно в общем). Все расскажу по почте. Скромная оплата.

jwh0Qgv18ANUShmamailPUNCTUMcom
459 738076
>>38040
На Java пишутся массивные проекты, которые фрилансерам отдавать не будут, ровно поэтому нет разработки, но разного рода доработки и фиксы периодически заказывают. Btw, новичкам там делать нечего совершенно.
460 738080
>>38062

>Скромная оплата.


Сам дорабатывай, лол.
461 738098
>>38045

>И судя по тому что в Компании есть поля вроде public $allSalary = 0; ты еще не все исправил.


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

>по мелочи,


>приделать апи внешнего сервиса


>сделать загрузку xml->mysql


300 баксов и сделаю.
37 Кб, 400x235
463 738132
Я снова выхожу на связь, хотя не моя задача - просто заинтересовался.
http://ideone.com/AVe2d4 - так и не удаётся добиться того, чтобы работало с УРЛом в начале текста. Пробел ставишь - всё как нужно.
Чего не хватает? Как указать, что если другие буквы есть перед УРЛом, то он не нужен?
Туплю, помогите.
464 738202
Вечер в хату, анчоусы. Подскажите годный учебник по mySQL. Понимаю, что прошлый век, но всё же.
63 Кб, 604x604
465 738221
Аноны, не могу осилить задачи на ООП, по своему опыту я понял, что лучше я посмотрю готовое решение и пойму как надо, потому что само мне в голову это не залетит тупой я

Дайте, пожалуйста, ссыль на гитхаб с задачей студента сделанной идеально на ООП. Буду сидеть и копаться в коде.
11 Кб, 389x193
466 738377
>>38050

>new Session это уже странно. Зачем ты создаешь объхект который сразу же удаляется? Может проще его не создавать тогда?


Обёртка над session_start(). Проще не создавать.

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


Так эта функция должна вызываться до любого выхлопа на страницу. Однако её и вправду стоит засунуть туда, где успешно произошла аутентификация.

>Непонятно зачем ты указываешь путь к конфигу в методе setStudentMapper - зачем он там?


С этим проблема, я долго пытался отвязать конфиг от маппера. Сейчас маппер получает уже объект PDO вот так: new StudentMapper(Config::getPDOconnection);
Так лучше? Это максимум, до чего я смог додуматься.

>НЕпонятно почему в базовом классе контроллера есть публичные статические поля


Куда положить дефолтные controller и action? В методы setController и setAction?

>нездоровое увлечение цепочечными вызовами методв что на мой взгляд скорее дурнгая привычка так как замусоривает код нелогичными return $this.


С return $this можно использовать $obj->foo()->bar()->baz() вместо $obj->foo(); $obj->bar(); $obj->baz()
Хорошо, я постараюсь убрать цепочные вызовы там, где они лишние.

>непонятно почему в пути к шаблону пропущено расширение.


Ну так DRY, во всех аж 2-х фреймворках, на которых я крудил, расширение не указывается. В моём случае все шаблоны имеют расширение .php и можно в методе view один раз конкатенировать первый параметр с ".php", вместо того, чтобы в каждом вызове view() дописывать php.

>> <?php if (\App\Helper\Auth::check()): ?>


Ты хочешь проверить залогинен ли пользователь но ничего не передаешь в функицю.
Этот метод проверяет наличие $_SESSION['email']. Что передавать в метод, который проверяет, залогинен ли пользователь?

>> что в форме для редактирования профиля нужно откуда-то брать значения, которые будут передаваться в value="" как дефолтные значения для инпутов.


>А ты читал урок про обработку форм? Там же вроде написано откуда.



Там написано, что после отправления формы нужно заполнить values тем, что пришло (если ошибок нет). А вот если я уже зарегистрирован и хочу отредактировать свой профиль, то при переходе на страницу редактирования профиля я никаких форм не отправляю. Но в input'ах должен получить уже заполненные значения для моего профиля. Сейчас в контроллере алгоритм такой: [/i]если пользователь залогинен -> получить модель пользователя в переменную -> переменную отправить во view -> заполнить values тем, что передано во view[/i]

Вопросы:
1. Что должна представлять из себя обёртка над Location для редиректа? Часть класса, хелпер, как назвать, какие ещё функции можно туда добавить?
2. Статические классы. У меня статические - Validator, Auth (хелпер для регистрации/логина), Session, Config. Они ведь все работают только с какой-то одной сущностью, у которой не может быть несколько инстансов. Можно их статическими оставить?
У валидатора один публичный метод make, который принимает 2 массива (пик). Мне иногда кажется, что вместо классов Config и Validator было бы проще создать по одной функции.
11 Кб, 389x193
466 738377
>>38050

>new Session это уже странно. Зачем ты создаешь объхект который сразу же удаляется? Может проще его не создавать тогда?


Обёртка над session_start(). Проще не создавать.

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


Так эта функция должна вызываться до любого выхлопа на страницу. Однако её и вправду стоит засунуть туда, где успешно произошла аутентификация.

>Непонятно зачем ты указываешь путь к конфигу в методе setStudentMapper - зачем он там?


С этим проблема, я долго пытался отвязать конфиг от маппера. Сейчас маппер получает уже объект PDO вот так: new StudentMapper(Config::getPDOconnection);
Так лучше? Это максимум, до чего я смог додуматься.

>НЕпонятно почему в базовом классе контроллера есть публичные статические поля


Куда положить дефолтные controller и action? В методы setController и setAction?

>нездоровое увлечение цепочечными вызовами методв что на мой взгляд скорее дурнгая привычка так как замусоривает код нелогичными return $this.


С return $this можно использовать $obj->foo()->bar()->baz() вместо $obj->foo(); $obj->bar(); $obj->baz()
Хорошо, я постараюсь убрать цепочные вызовы там, где они лишние.

>непонятно почему в пути к шаблону пропущено расширение.


Ну так DRY, во всех аж 2-х фреймворках, на которых я крудил, расширение не указывается. В моём случае все шаблоны имеют расширение .php и можно в методе view один раз конкатенировать первый параметр с ".php", вместо того, чтобы в каждом вызове view() дописывать php.

>> <?php if (\App\Helper\Auth::check()): ?>


Ты хочешь проверить залогинен ли пользователь но ничего не передаешь в функицю.
Этот метод проверяет наличие $_SESSION['email']. Что передавать в метод, который проверяет, залогинен ли пользователь?

>> что в форме для редактирования профиля нужно откуда-то брать значения, которые будут передаваться в value="" как дефолтные значения для инпутов.


>А ты читал урок про обработку форм? Там же вроде написано откуда.



Там написано, что после отправления формы нужно заполнить values тем, что пришло (если ошибок нет). А вот если я уже зарегистрирован и хочу отредактировать свой профиль, то при переходе на страницу редактирования профиля я никаких форм не отправляю. Но в input'ах должен получить уже заполненные значения для моего профиля. Сейчас в контроллере алгоритм такой: [/i]если пользователь залогинен -> получить модель пользователя в переменную -> переменную отправить во view -> заполнить values тем, что передано во view[/i]

Вопросы:
1. Что должна представлять из себя обёртка над Location для редиректа? Часть класса, хелпер, как назвать, какие ещё функции можно туда добавить?
2. Статические классы. У меня статические - Validator, Auth (хелпер для регистрации/логина), Session, Config. Они ведь все работают только с какой-то одной сущностью, у которой не может быть несколько инстансов. Можно их статическими оставить?
У валидатора один публичный метод make, который принимает 2 массива (пик). Мне иногда кажется, что вместо классов Config и Validator было бы проще создать по одной функции.
467 738387
ОП, а как же тот факт, что срок истечения сессии можно выставлять вручную? Куки же менее безопасны, чем сессии. Первое хранится на стороне клиента, второе - на стороне сервера. Или возможность не разлогинивать пользователя спустя час бездействия важнее безопасности?

>>38202
Мне очень хорошо помог вкатиться Learning SQL Алана Бьюли, как-то так.
468 738409
Привет ОП и стремящиеся аноны
Сидел я тут раньше с вами, сделал студентов и почти доделал файлообменник https://github.com/V3N0m21 может кто помнит, потом нашел работу Magento developer'ом. И вот пришел спросить совет.

Все началось с того что пришло предложение сделать тестовое задание на Magento, нужно было сделать модуль отзывов, я еще тогда подумал что тестовое задание было сложновато как для джуна, хоть я и сказал что никогда с magento не работал, но могу попробовать разобраться. В общем за неделю гугления и чтения очень скупой документации я решил делать модуль для magento 2, которая только-только вышла я задание таки сделал и отправил, меня пригласили на собеседование которое проводили CEO и CMO конторы пацаны 23х лет, контора находится в съемной квартире которая дала тестовое задание . Я сказал что хоть я и написал тестовое задание, для меня это было достаточно сложно, и мне обязательно нужен наставник, или хотя бы просвященный человек которому можно задавать вопросы и пару месяцев времени чтоб нормально разобраться, они сказали без проблем, у нас есть люди с большим опытом. По технической части меня вообще ничего не спрашивали, просто сказали что можешь выходить в понедельник. Так как я работал на другой работе я сказал что мне нужно две недели. Написал заявление на работе, в тот же день из этой конторы мне перезвонили, сказали что нужно готовиться, завтра у меня собеседование с заграничным заказчиком и скинули мне мое резюме, чтоб я ознакомился, в котором было указано что-то около 4х лет опыта разработки magento и год разработки magento 2. Я спросил как так, я же говорил что я джун и для того чтоб нормально разобраться в теме мне нужно хотя бы месяца два-три, они ответили "не ссы, вопросы будут не сложные, тем более ты же говоришь по английски", короче всю ночь я готовился к этому собеседованию, на следующий день пришел к ним, созвонились с заказчиком по скайпу. Пообщался с заказчиком, поотвечал на вопросы, не на все, но все прошло более-менее, они меня взяли
tl;dr В общем мне надоело печатать в подробностях, поэтому коротко: я работаю на проекте зарубежного заказчика, среди моих коллег все адские нубы, плюс на зарубежного заказчика работаю только я, и только я работаю на magento2, все остальные на локальных проектах и на magento и wordpress'e, и помощи вообще нет никакой, во всем абсолютно нужно разбираться самому. Заказчик думает что я мидло-синиор, кидает тикеты которые я с адовым трудом и кучей замечаний закрываю. Так я проработал вот уже два месяца, деньги платят как договаривались $500, но силенок работать в таком режиме и таком стрессе у меня уже нет, с ужасом думаю что завтра на работу и там тикет который я скорее всего сделать не смогу. И так вопрос - что делать дальше? Превозмогать и ждать когда я уже досконально в этом всем разберусь, или уходить и искать что-то более адекватное с прошаренными коллегами и параллельно нормально доучить фронтенд и JS с фреймворками? Из плюсов того что есть сейчас, я очень-очень сильно подтянул свой уровень за эти два месяца. Где-то как за 8 месяцев обучения в обычном режиме. ОП, дай свой мудрый совет что делать, а то я запутался и адекватно ситуацию оценить не могу.
468 738409
Привет ОП и стремящиеся аноны
Сидел я тут раньше с вами, сделал студентов и почти доделал файлообменник https://github.com/V3N0m21 может кто помнит, потом нашел работу Magento developer'ом. И вот пришел спросить совет.

Все началось с того что пришло предложение сделать тестовое задание на Magento, нужно было сделать модуль отзывов, я еще тогда подумал что тестовое задание было сложновато как для джуна, хоть я и сказал что никогда с magento не работал, но могу попробовать разобраться. В общем за неделю гугления и чтения очень скупой документации я решил делать модуль для magento 2, которая только-только вышла я задание таки сделал и отправил, меня пригласили на собеседование которое проводили CEO и CMO конторы пацаны 23х лет, контора находится в съемной квартире которая дала тестовое задание . Я сказал что хоть я и написал тестовое задание, для меня это было достаточно сложно, и мне обязательно нужен наставник, или хотя бы просвященный человек которому можно задавать вопросы и пару месяцев времени чтоб нормально разобраться, они сказали без проблем, у нас есть люди с большим опытом. По технической части меня вообще ничего не спрашивали, просто сказали что можешь выходить в понедельник. Так как я работал на другой работе я сказал что мне нужно две недели. Написал заявление на работе, в тот же день из этой конторы мне перезвонили, сказали что нужно готовиться, завтра у меня собеседование с заграничным заказчиком и скинули мне мое резюме, чтоб я ознакомился, в котором было указано что-то около 4х лет опыта разработки magento и год разработки magento 2. Я спросил как так, я же говорил что я джун и для того чтоб нормально разобраться в теме мне нужно хотя бы месяца два-три, они ответили "не ссы, вопросы будут не сложные, тем более ты же говоришь по английски", короче всю ночь я готовился к этому собеседованию, на следующий день пришел к ним, созвонились с заказчиком по скайпу. Пообщался с заказчиком, поотвечал на вопросы, не на все, но все прошло более-менее, они меня взяли
tl;dr В общем мне надоело печатать в подробностях, поэтому коротко: я работаю на проекте зарубежного заказчика, среди моих коллег все адские нубы, плюс на зарубежного заказчика работаю только я, и только я работаю на magento2, все остальные на локальных проектах и на magento и wordpress'e, и помощи вообще нет никакой, во всем абсолютно нужно разбираться самому. Заказчик думает что я мидло-синиор, кидает тикеты которые я с адовым трудом и кучей замечаний закрываю. Так я проработал вот уже два месяца, деньги платят как договаривались $500, но силенок работать в таком режиме и таком стрессе у меня уже нет, с ужасом думаю что завтра на работу и там тикет который я скорее всего сделать не смогу. И так вопрос - что делать дальше? Превозмогать и ждать когда я уже досконально в этом всем разберусь, или уходить и искать что-то более адекватное с прошаренными коллегами и параллельно нормально доучить фронтенд и JS с фреймворками? Из плюсов того что есть сейчас, я очень-очень сильно подтянул свой уровень за эти два месяца. Где-то как за 8 месяцев обучения в обычном режиме. ОП, дай свой мудрый совет что делать, а то я запутался и адекватно ситуацию оценить не могу.
469 738410
>>38409

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


Охуеть, мне такое же задание давали. Но я его проебал.
470 738412
>>38410
Диванон? Ты тоже с запада Украины?
471 738415
>>38412
Лол, нет. Вообще мимо. Видимо всем такое дают.
472 738422
>>38409
Оп наверняка скажет "надрывайся-превозмогай".

Бросать сейчас конечно глупо, но что мешает параллельно искать другую работу, с более комфортными условиями?
Я когда устраивался, выложил во-первых резюме, во-вторых разослал по ~50 вакансиям. Ответили 9, плюс еще 5 сами отозвались на резюме, так что выбирать было из чего.
Не нужно хвататься за первую попавшуюся возможность при таком спросе.

>>38412
В Киеве легко можно найти стажировку с адекватной нагрузкой и обучением (~300$).
473 738432
>>38422
Проблема только в том что я не в Киеве и переехать туда в ближайшие год-полтора я точно не смогу, в Киеве и правда выбор широкий. Ну а вообще в принципе мне на джинне нормально предложений приходило, хотя во всех хотели Symfony или Zend Framework. Я именно поэтому и думал посидеть дома, подтянуть это все плюс верстку с JS.
Хотя по большому счету мне и Magento 2 нравится, просто вот этот вот адовый стресс это что-то невыносимое.
474 738440
>>38432
Обсуди этот вопрос с начальством (если в той шараге таковое имеется), а не на дваче.
Мол так и так, не справляюсь с нагрузкой/не хватает опыта-квалификации, раскидайте тикеты другим членам команды.
В конце концов ты сам можешь проявить лидерские качества и напрячь кого-то из джунов/верстальщиков, чтобы они помогли
хотя бы с черновой работой (небезвозмездно естественно).

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

Короче твоя проблема решается обсуждением в коллективе. Говори с начальством, ищи напарника, делай бочку.
475 738470
>>38409
Какой уровень английского и как учил?
476 738474
>>38470
А вы еврей, вопросом на вопрос отвечать?
477 738477
>>38470
Свободно общаюсь с сильным акцентом. Никак специально не учил, много читал книжки и интернеты, смотрел кинцо и сериалы без перевода, общался когда появлялась возможность с иностранцами.
478 738487
>>38409

>но силенок работать в таком режиме и таком стрессе у меня уже нет


Велкам ту программирование, года через три будет немного полегче, а спустя еще два всё просто заебет до невозможности.
479 738490
>>38477
Да ты успешен. Вангую зп 2к бакинских уже через год.
480 738494
>>38490
неужели английский так влияет на зп?(другой анон)
481 738497
>>38494
В Украине очень влияет, у них своих продуктов нет, поэтому вся Украина это рынок дешевой рабочей силы для белых людей.
482 738500
>>38409

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


Хуже всего то, что так почти всегда бывает.
И на фрилансах, и в реальной жизни - везде привирают.
Это какое-то днище для заказчика или того, кто нанимает на работу.
Это я как заказчик говорю.
Ну а с другой стороны, платить мидл-сениору 500 баксов - это сурово, очень сурово.
Но, походу, все тупо в курсе, не дураки ведь.
483 738501
>>38494
Хоть я еще и не джуниор, но английский по идее должен сильно возвышать тебя. Открывается весь мир клиентов из стран, в которых зп в 10 раз больше, чем в рашке.
484 738503
>>38494
Имхо его только и наняли из-за английского. Софт скиллс, лел.
485 738508
Проигрываю с вебмакак за 15к в месяц.
486 738509
>>38508
Байтослесарь за 16к?
487 738538
Ну так что, анонасы, какой бесплатный хостинг посоветуете?
488 738539
>>38538
hostinger
489 738542
>>38539
Так эта параша требует отправить смс за 50р.
490 738550
>>38542
тебе что, жалко 50 рублей? На толоке накликай.
491 738554
>>38550
Нет офисов Яндекса в городе.
492 738556
>>38554
поаскай на улице или попроси у анонов. Я как-то на домен себе 150 рублей напопрошайничал.
493 738557
>>38556
Да мне нужно сейчас сайт закинуть для дипломной работы. Это необязательно, но желательно.
494 738578
Бампану предыдущие просьбы
>>36701
>>36833
Настрочил еще две задачи из раздела "Повторим?". Проверьте, плез, кому не сложно. Хотелось бы знать ваше мнение по поводу решения.
https://ideone.com/n2jYia
https://ideone.com/07D9j9
Ответы 495 738598
>>31871

> $array = [];


Название ничего не значит. Массив чего?

> function spellSmallNumber($number, $number1, $female = null){


Вот это странный заголовок функции. Что такое number? чем оно отличается от number1? Непонятно. Ну и это нелогично, это функция которая преобразует небольшое число в строку, зачем передавать ей 2 числа?

Вот когда ты видишь что-то такое "нелогичное", скорее всего это говорит о том что код сделан неправильно.

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

> function zeroinNumbers(


Логичнее было назвать addIfNotZero. Название функции начинается с глагола. сам код можно было написать проще, if ( ...) { ... } без else.

Использование ссылок это в общем плохо. Вот посмотри:

> zeroinNumbers($hundreds, $numbertoWords, $array); //Сотни



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

Если (в числе есть сотни) {
добавить слово для сотен;
}

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

> 11 => 'одиннадцать ',


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

> }


> elseif($lastDigit == 1){


Это идет в одну строку: } elseif (...) {

> if($millions == 0 && $thousands != 0){


> return $thousandstoWords . $unitstoWords;


> }


> elseif($thousands == 0 && $millions != 0){


> return $millionstoWords . $unitstoWords;


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

>>31882

> По задаче вопрос, для чего тут имеет смысл использовать фабрику?


А я такое советовал? Вообще, тут фабрику можно использовать для создания работников по названию и рангу. В данном случае я фабрикой назвал функцию которая производит объекты, а не тот сложный паттерн с кучей классов и интерфейсов.
Ответы 495 738598
>>31871

> $array = [];


Название ничего не значит. Массив чего?

> function spellSmallNumber($number, $number1, $female = null){


Вот это странный заголовок функции. Что такое number? чем оно отличается от number1? Непонятно. Ну и это нелогично, это функция которая преобразует небольшое число в строку, зачем передавать ей 2 числа?

Вот когда ты видишь что-то такое "нелогичное", скорее всего это говорит о том что код сделан неправильно.

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

> function zeroinNumbers(


Логичнее было назвать addIfNotZero. Название функции начинается с глагола. сам код можно было написать проще, if ( ...) { ... } без else.

Использование ссылок это в общем плохо. Вот посмотри:

> zeroinNumbers($hundreds, $numbertoWords, $array); //Сотни



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

Если (в числе есть сотни) {
добавить слово для сотен;
}

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

> 11 => 'одиннадцать ',


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

> }


> elseif($lastDigit == 1){


Это идет в одну строку: } elseif (...) {

> if($millions == 0 && $thousands != 0){


> return $thousandstoWords . $unitstoWords;


> }


> elseif($thousands == 0 && $millions != 0){


> return $millionstoWords . $unitstoWords;


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

>>31882

> По задаче вопрос, для чего тут имеет смысл использовать фабрику?


А я такое советовал? Вообще, тут фабрику можно использовать для создания работников по названию и рангу. В данном случае я фабрикой назвал функцию которая производит объекты, а не тот сложный паттерн с кучей классов и интерфейсов.
496 738671
>>38409
Норм все у тебя, так программистами и становятся. Подумай вот о чем - еще несколько месяцев таких мучений, и ты и правда миддлом станешь, потом тебе везде дороги открыты. А вот как ты хотел, чтобы учили и показывали, так редко бывает, да и не научишься ничему особо. Если тебя держат, и кое-как справляешься, то так оно и должно быть. В свободное время почитывай книги по программированию, задавай вопросы на форумах, юзай stackoverflow.
497 738676
>>38409
Еще, забыл упомянуть - тебе это в кайф начнет становиться со временем. Стресс пройдет с увеличением скилла. Чем активнее читаешь и пробуешь, больше тикетов делаешь - тем тебе все это больше нравиться начинает. Потом будешь на джунов и их проблемы еще с усмешкой посматривать, разве же это проблемы.
498 738695
1)В каких случаях в MVC стоит создавать класс представления вместо обычного шаблона?

2)Как сказать апачу что индекс.php у меня в папке public и ссылаться надо на него? Сейчас в htacess прописано:

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^ index.php [QSA,L]
499 738704
>>38500
Платят там наверняка тыщи 2-3, а до анона доходит ток 500.
500 738707
>>38409
Помню тебя, я примерно в то же время делал студентов (года 1.5 назад) и тоже нашел работу. Но у меня ситуация другая: есть люди которые имеют опыт и которые отвечают на вопросы и могут помочь но зп низкое (250$) на данный момент (для моей мухосрани норм). Сперва были задачи по джумле/вордпресс, сейчас онли интернет-магазины. Верстку тоже пробовал на паре сайтов. В свободное время изучаю js. атмосфера в коллективе прекрасная. Стрессы тоже есть, куда без этого но есть и поддержка. Работаю почти год.
501 738758
Вот интересно, иногда мы видим какие-то библиотеки или фреймворки, которые вроде особо не используются, но почему-то о них много говорят. А вот тут вот (англ.) описано что автор фреймворка PHPPixie накручивает установки на пакаджисте (репозитории композера) и с помощью ботов создает видимость коммьюнити на реддите: http://andrewcarteruk.github.io/programming/2016/05/09/phpixie-fraud.html https://news.ycombinator.com/item?id=11661986 Видимо очень хочется славы и известности.
502 738781
Аноны, кто с ВК работал? Как там можно собрать список из айдишников или ссылок на подписчиков определенного сообщества? Есть метод в АПИ, но он собирает только первую тысячу, а мне надо несколько десятков тысяч.
503 738789
>>38781

Если они ограничивают то наверно не просто так. Соцсеть не хочет с каждым делиться информацией которую можно продать.

И вообще, это тред про программирование а не про спам и SMM (что в моем понимании одно и то же).
504 738795
>>38758
Это хипстерские фреймворки. О них говорят, чтобы быть сойти за продвинутого в последней моде.
505 738796
>>38781
Документацию почему не читаешь?
http://vk.com/dev/groups.getMembers
Максимальное значение получаемых айдишников - 1000. В запросе можно указать offset. Вот так и получаешь - выбрал 1000, увеличил оффсет на 1000, выбрал вторую тысячу и т.д.
Одним циклом можно все сделать.
506 738797
>>38781
Там же есть параметр offset
507 738798
>>38796
>>38797
Ебать вы вконтактеры собрались.
508 738800
>>38798
Ну что ты вот это сразу, не пользуюсь я им, просто по работе нужно было.
509 738810
>>38796
>>38797
Благодарю :3
Про оффсет я действительно проглядел.
>>38789

>это тред про программирование а не про спам и SMM


Так я просто для себя хотел программку написать легкую чтобы помогла отслеживать прирост подписчиков от рекламы. Спам тут не при чем.
510 738816
>>38810

Ну ладно тогда. Но по моему тогда проще будет получать только общее число подписчиков.
511 738828
>>38816
Нет, тут дело в том, что мне нужна информация о конкретном количестве подписчиков одного сообщества, которые после рекламы стали подписчиками моего. И подписчиках моего, которые подписались на сообщество другого человека. После взаимного репоста записей в наши сообщества. Я бы тогда смог отслеживать эффективность рекламы как в моем, так и в других сообществах и искать наиболее подходящих.
512 738883
>>38671

>еще несколько месяцев таких мучений, и ты и правда миддлом станешь


У него времени на это становление нет - ad-hoc влепил что-то более-менее с натяжкой, а тут следующий тикет меж булочек лезет. Но можно взять перерыв на год через несколько месяцев и подтянуть свой уровень на основе приобретенного опыта.
513 738970
>>38883
>>38707
>>38671
Спасибо аноны за поддержку.

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


На самом деле я забыл упомянуть что самая главная проблема именно в том что по magento 2 практически вообще еще нет инфы, есть две базовые книжки и документация, все это я уже перечитал вдоль и поперек, а больше инфы нету практически, ни на стаковерфлоу ни в гугле. Только чтение и изучение кода ядра, только хардкор
107 Кб, 680x410
514 739146
Пилите перекат.
57 Кб, 800x480
516 739157
517 739162
518 739165
>>39162
Это татарский.
519 739214
Опытные аноны, посоветуйте, что делать дальше вкатывающемуся в профессию программиста. Вот я закончу уроки опа, далее я вижу такие варианты:
1. Устроиться в любую около-веб шарагу в своем 700к мухосранске. Зп 35-40 к.
Плюсы - достаточно легко найти работу. Возможно получится немного откладывать 5-10 к.
Минусы - зп будет хватать только на аренду + еда + учеба + активити вроде тренажерного зала. Отсутствие профессионального и карьерного роста. Предполагаю, что не будет времени или сил для прокачки чего-либо кроме кмс.

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

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

4. Удаленная работа. Тут я не совсем в теме, как найти, какие будут условия. Очевидно если работать на СНГ, то зп будет как в п.1 или даже ниже. Если на буржуев, то возможно и выше.
Плюсы - постоянный доход, не обязательно носить штаны на работе.

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

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

Какой стул выбрать, если моя цель завести трактор, отложить 5-10k$ на эмиграцию, мне 28 и я заканчиваю первый курс заочки? Еще, я бы хотел заниматься, чем-то вроде анализа больших данных, или систем на основе машинного обучения или стрелять лазером из глаз.
519 739214
Опытные аноны, посоветуйте, что делать дальше вкатывающемуся в профессию программиста. Вот я закончу уроки опа, далее я вижу такие варианты:
1. Устроиться в любую около-веб шарагу в своем 700к мухосранске. Зп 35-40 к.
Плюсы - достаточно легко найти работу. Возможно получится немного откладывать 5-10 к.
Минусы - зп будет хватать только на аренду + еда + учеба + активити вроде тренажерного зала. Отсутствие профессионального и карьерного роста. Предполагаю, что не будет времени или сил для прокачки чего-либо кроме кмс.

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

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

4. Удаленная работа. Тут я не совсем в теме, как найти, какие будут условия. Очевидно если работать на СНГ, то зп будет как в п.1 или даже ниже. Если на буржуев, то возможно и выше.
Плюсы - постоянный доход, не обязательно носить штаны на работе.

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

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

Какой стул выбрать, если моя цель завести трактор, отложить 5-10k$ на эмиграцию, мне 28 и я заканчиваю первый курс заочки? Еще, я бы хотел заниматься, чем-то вроде анализа больших данных, или систем на основе машинного обучения или стрелять лазером из глаз.
520 739217
Анон, помоги идиоту сделать задачку из обучения, в чем моя ошибка? Хочу разобраться, реально понять, а не просто списать с инета...
https://ideone.com/5RnMlV
https://github.com/greenTea242/StudentList 521 739250
>>31987

https://github.com/greenTea242/Student_List

> https://github.com/greenTea242/Student_List/blob/master/public/index.php#L30


> if ($pager->checkPossiblePages($myPage)) {


> $abiturients = $gateway->getAbiturientsInPage($recordsPerPage, $pager->getOffsetForDB($myPage), $sort, $search, $order);


> }


А что если if не сработает? Чему будет равна $abiturients? Это очень подозрительно, когда переменная создается внутри ифа, а используется снаружи.

> require_once "../src/ini.php";


Не стоит подключать файлы с относильным путем, надежнее указывать полный путь через __DIR__, так как правила по которым php ищет файлы с относительным путем, очень мутные.

> /Массив свойств для заполнения модели/


> $properties = [


> "token",


Зачем разрешать перезаписывать токен? Пользователь разве может его редактировать?

https://github.com/greenTea242/Student_List/blob/master/public/register.php#L29

> if (!empty($_POST[$property])) {


А если пользователь при редактировании захочет очистить какое-то поле, эта проверка ведь его не пропустит?

https://github.com/greenTea242/Student_List/blob/master/public/inc/login.php
Почему этот файл в публичной папке?

> if ($gateway->isAbiturientExist($abiturientID, $token)) {


> $abiturient = $authorizator->getStudent($abiturientID);


> $authorizator->logIn($abiturientID, $token);


Это странный код: если куки устанвлены и они правильные, установим их еще раз. Зачем?

> $authorizator->setToken($token);


> $abiturient = new Abiturient();


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

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

> https://github.com/greenTea242/Student_List/blob/master/src/Authorization.php#L12


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

А сейчас у тебя авторизация размазана по нескольким местам кода.

> https://github.com/greenTea242/Student_List/blob/master/src/AbiturientDataGateway.php#L210


> if ($counter == 1) {;


Безопаснее писать > 0, а не равно 1. Точка с запятой после открывающей скобки не ставится.

https://github.com/greenTea242/Student_List/blob/master/src/AbiturientValidator.php
тут мне не нравится что трудно понять как пользоваться этим классом. Почему нельзя сделать один метод валидации, куда мы даем студента и получаем список ошибок, а не гадать в каком порядке надо вызывать методы?

https://github.com/greenTea242/Student_List/blob/master/src/AbiturientValidator.php#L151
Букву ё надо указывать отдельно.

https://github.com/greenTea242/Student_List/blob/master/src/TokenHelper.php
Насчет этого класса. Опять же, я думаю, надо инкапсулировать работу с CSRF кукой внутри него. А сейчас у тебя за проверку и генерацию токенов отвечает внешний код.

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

У тебя этот принцип не выполняется. И то, что ты там делаешь проверку на слово "mark" (<> воспринимаются как ограничители в регулярке) это костыль.

Я думаю, замену стоит делать так: сформировать регулярку вида:

длинноеслово1|среднееслово2|слово3

И уже ей заменять за 1 раз все вхождения на окруженные тегами. Причем в этом случае мы можем даже не разбивать текст на слова.

> $searchWords = preg_split("/[^\\w]+/ui", $search);


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

https://github.com/greenTea242/Student_List/blob/master/src/config.php
В конфиг стоит класть то, что можно менять и желательно в более простом виде. DSN сложный и в нем нельзя поменять тип БД так как твой код вряд ли заточен на любые базы данных. Потому стоит в конфиге просто сделать хост, порт, имя, пароль, название БД. Ну и количество записей.

https://github.com/greenTea242/Student_List/blob/master/templates/index.html#L3

> <?php require_once("/inc/head.html"); ?>


Не будет же работать, это абсолютный путь от корня диска.

Тут в файлах скопипащена часть тегов, например body и head:

https://github.com/greenTea242/Student_List/blob/master/templates/register.html
https://github.com/greenTea242/Student_List/blob/master/templates/index.html

Копипаста - плохо.

> <p>Показаны только абитуриенты, найденные по запросу "<?=$search?>".</p>


Где защита от XSS? Перечитай урок.

> <?php if ($order == "asc"): ?>


> <?php else: ?>


Тут ведь явно почти одно и то же. Нельзя ли это упростить за счет функций?

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

> <?php if ($search): ?>


> <td><?=ViewHelper::paintFound($abiturient->getName(), $search)?></td>


> <?php else: ?>


> <td><?=htmlspecialchars($abiturient->getName(), ENT_QUOTES)?></td>


Тоже по сути копипаста. Хорошо бы объединить paintFound и htmlspecialchars в одну функцию.

> <p><a href="<?=$_SERVER['PHP_SELF']?>"


Нехорошо что шаблон лезет в SERVER. Пусть ему URL передают снаружи.

> <?php for ($pageNum = 1; $pageNum <= $pager->getTotalPages(); $pageNum++): ?>


> <?php if ($pageNum == $myPage): ?>


> <?php elseif ($pageNum == $myPage + 1 ||


> $pageNum == $myPage - 1 ||


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

> <?php if(!empty($errorList['name'])): ?>


> <div class="control-group has-error">


> <?php endif ?>


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

> pattern="<?=$validator->getHTML5RegExpForName()?>"


Спецсимволы стоит экранировать

> &quot - &quot(дефис)


Точка с запятой забыта после quot, почитай про html мнемоники

https://github.com/greenTea242/Student_List/blob/master/templates/register.html#L120
Тут инпуты выбора пола скопипащены 3 раза. Избавься от копипасты.

https://github.com/greenTea242/Student_List
Тут разметка в ридми кривая.

> Установка кук для токена существует отдельно потому что в register.php проверяется защита на СSRF во время отправки формы, т.е. до момента регистрации студента и выставления оных.


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

> Ты мне советовал для выделения слов при поиске использовать preg_replace_callback. У меня не получилось ее правильно использовать, потому что она сразу меняет параллельно все совпадения по массиву регулярок и нигде нельзя посмотреть процесс изменения текста, а мне нужно сделать так, что если это совпадение уже в тегах <mark>, мне это не нужно делать.


Нет, прочитай выше, замену надо делать в один проход. preg_replace_callback это бы позволил сделать, как впрочем и другой вариант, что я предложил.
https://github.com/greenTea242/StudentList 521 739250
>>31987

https://github.com/greenTea242/Student_List

> https://github.com/greenTea242/Student_List/blob/master/public/index.php#L30


> if ($pager->checkPossiblePages($myPage)) {


> $abiturients = $gateway->getAbiturientsInPage($recordsPerPage, $pager->getOffsetForDB($myPage), $sort, $search, $order);


> }


А что если if не сработает? Чему будет равна $abiturients? Это очень подозрительно, когда переменная создается внутри ифа, а используется снаружи.

> require_once "../src/ini.php";


Не стоит подключать файлы с относильным путем, надежнее указывать полный путь через __DIR__, так как правила по которым php ищет файлы с относительным путем, очень мутные.

> /Массив свойств для заполнения модели/


> $properties = [


> "token",


Зачем разрешать перезаписывать токен? Пользователь разве может его редактировать?

https://github.com/greenTea242/Student_List/blob/master/public/register.php#L29

> if (!empty($_POST[$property])) {


А если пользователь при редактировании захочет очистить какое-то поле, эта проверка ведь его не пропустит?

https://github.com/greenTea242/Student_List/blob/master/public/inc/login.php
Почему этот файл в публичной папке?

> if ($gateway->isAbiturientExist($abiturientID, $token)) {


> $abiturient = $authorizator->getStudent($abiturientID);


> $authorizator->logIn($abiturientID, $token);


Это странный код: если куки устанвлены и они правильные, установим их еще раз. Зачем?

> $authorizator->setToken($token);


> $abiturient = new Abiturient();


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

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

> https://github.com/greenTea242/Student_List/blob/master/src/Authorization.php#L12


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

А сейчас у тебя авторизация размазана по нескольким местам кода.

> https://github.com/greenTea242/Student_List/blob/master/src/AbiturientDataGateway.php#L210


> if ($counter == 1) {;


Безопаснее писать > 0, а не равно 1. Точка с запятой после открывающей скобки не ставится.

https://github.com/greenTea242/Student_List/blob/master/src/AbiturientValidator.php
тут мне не нравится что трудно понять как пользоваться этим классом. Почему нельзя сделать один метод валидации, куда мы даем студента и получаем список ошибок, а не гадать в каком порядке надо вызывать методы?

https://github.com/greenTea242/Student_List/blob/master/src/AbiturientValidator.php#L151
Букву ё надо указывать отдельно.

https://github.com/greenTea242/Student_List/blob/master/src/TokenHelper.php
Насчет этого класса. Опять же, я думаю, надо инкапсулировать работу с CSRF кукой внутри него. А сейчас у тебя за проверку и генерацию токенов отвечает внешний код.

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

У тебя этот принцип не выполняется. И то, что ты там делаешь проверку на слово "mark" (<> воспринимаются как ограничители в регулярке) это костыль.

Я думаю, замену стоит делать так: сформировать регулярку вида:

длинноеслово1|среднееслово2|слово3

И уже ей заменять за 1 раз все вхождения на окруженные тегами. Причем в этом случае мы можем даже не разбивать текст на слова.

> $searchWords = preg_split("/[^\\w]+/ui", $search);


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

https://github.com/greenTea242/Student_List/blob/master/src/config.php
В конфиг стоит класть то, что можно менять и желательно в более простом виде. DSN сложный и в нем нельзя поменять тип БД так как твой код вряд ли заточен на любые базы данных. Потому стоит в конфиге просто сделать хост, порт, имя, пароль, название БД. Ну и количество записей.

https://github.com/greenTea242/Student_List/blob/master/templates/index.html#L3

> <?php require_once("/inc/head.html"); ?>


Не будет же работать, это абсолютный путь от корня диска.

Тут в файлах скопипащена часть тегов, например body и head:

https://github.com/greenTea242/Student_List/blob/master/templates/register.html
https://github.com/greenTea242/Student_List/blob/master/templates/index.html

Копипаста - плохо.

> <p>Показаны только абитуриенты, найденные по запросу "<?=$search?>".</p>


Где защита от XSS? Перечитай урок.

> <?php if ($order == "asc"): ?>


> <?php else: ?>


Тут ведь явно почти одно и то же. Нельзя ли это упростить за счет функций?

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

> <?php if ($search): ?>


> <td><?=ViewHelper::paintFound($abiturient->getName(), $search)?></td>


> <?php else: ?>


> <td><?=htmlspecialchars($abiturient->getName(), ENT_QUOTES)?></td>


Тоже по сути копипаста. Хорошо бы объединить paintFound и htmlspecialchars в одну функцию.

> <p><a href="<?=$_SERVER['PHP_SELF']?>"


Нехорошо что шаблон лезет в SERVER. Пусть ему URL передают снаружи.

> <?php for ($pageNum = 1; $pageNum <= $pager->getTotalPages(); $pageNum++): ?>


> <?php if ($pageNum == $myPage): ?>


> <?php elseif ($pageNum == $myPage + 1 ||


> $pageNum == $myPage - 1 ||


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

> <?php if(!empty($errorList['name'])): ?>


> <div class="control-group has-error">


> <?php endif ?>


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

> pattern="<?=$validator->getHTML5RegExpForName()?>"


Спецсимволы стоит экранировать

> &quot - &quot(дефис)


Точка с запятой забыта после quot, почитай про html мнемоники

https://github.com/greenTea242/Student_List/blob/master/templates/register.html#L120
Тут инпуты выбора пола скопипащены 3 раза. Избавься от копипасты.

https://github.com/greenTea242/Student_List
Тут разметка в ридми кривая.

> Установка кук для токена существует отдельно потому что в register.php проверяется защита на СSRF во время отправки формы, т.е. до момента регистрации студента и выставления оных.


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

> Ты мне советовал для выделения слов при поиске использовать preg_replace_callback. У меня не получилось ее правильно использовать, потому что она сразу меняет параллельно все совпадения по массиву регулярок и нигде нельзя посмотреть процесс изменения текста, а мне нужно сделать так, что если это совпадение уже в тегах <mark>, мне это не нужно делать.


Нет, прочитай выше, замену надо делать в один проход. preg_replace_callback это бы позволил сделать, как впрочем и другой вариант, что я предложил.
Ответы 1 мая 522 739251
>>32203

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

> Тогда с 33 по 126 брать, довольно солидно выглядит.


ну ок

>>32272

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

В базе хранишь не пароли, а только соленые (не обычные) хеши от них.

>>32331

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

>>32421

Выглядит очень переусложеннным. И сам алгоритм, и то как ты пишешь код.

> $temp1


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

> $numberOfPupils = 10;


Число учеников надо не считать вручную а получить из массива имен. Или они не связаны?

> $classList[$i]['name'] = $names[$index];


> $classList[$i]['height'] = 150 + mt_rand(0,50);


тут наверно проще было сделать массив вида имя => рост.

> echo "{$classList[$i]['name']} {$classList[$i]['height']} {$classList[$i]['isAnone']} <br>";


Тут много раз повторяется $classList[$i], тебя это не беспокоит? Вообще, это повторяется очень много раз в коде и это плохо.

То же касается $classList[$maxIndex]

> for ($i=1; $i<=$numberOfPupils; $i++) {


> if ($maxHeight < $classList[$i]['height']) {


тут надо использовать foreach, он лучше годится для обхода массива.

> if ($i == $temp1) {


> $classList[$i]['isAnone'] = 'Это анон';


Это поле не нужно так как всегда можно проверить индекс.

В общем, надо переделывать.
Ответы 1 мая 522 739251
>>32203

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

> Тогда с 33 по 126 брать, довольно солидно выглядит.


ну ок

>>32272

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

В базе хранишь не пароли, а только соленые (не обычные) хеши от них.

>>32331

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

>>32421

Выглядит очень переусложеннным. И сам алгоритм, и то как ты пишешь код.

> $temp1


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

> $numberOfPupils = 10;


Число учеников надо не считать вручную а получить из массива имен. Или они не связаны?

> $classList[$i]['name'] = $names[$index];


> $classList[$i]['height'] = 150 + mt_rand(0,50);


тут наверно проще было сделать массив вида имя => рост.

> echo "{$classList[$i]['name']} {$classList[$i]['height']} {$classList[$i]['isAnone']} <br>";


Тут много раз повторяется $classList[$i], тебя это не беспокоит? Вообще, это повторяется очень много раз в коде и это плохо.

То же касается $classList[$maxIndex]

> for ($i=1; $i<=$numberOfPupils; $i++) {


> if ($maxHeight < $classList[$i]['height']) {


тут надо использовать foreach, он лучше годится для обхода массива.

> if ($i == $temp1) {


> $classList[$i]['isAnone'] = 'Это анон';


Это поле не нужно так как всегда можно проверить индекс.

В общем, надо переделывать.
Ответы 2 мая 523 739252
>>32615

можно

>>32654

> задачу про калькулятор.



> function abc(&$op, &$char, &$number, &$result){


> $op = $char;


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

И что за бредовое название? Названия функции начинаются с глагола, сделайЧтоТо.

Тут вообще эта функция не нужна, код в ней можно поставить под блоком if/else

В остальном верно.

> Пока не доходит до меня как ввести поддержку дробных чисел.


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

> Задача про банкомат.


> echo "Выдача возможна, число купюр:\n";


не говори "гоп", пока не перепрыгнешь: http://ideone.com/3kTQeP - твой банкомат зажал 100 тугриков.

> $abc =


переменным надо давать осмысленные имена

>>33136

Что значат URL? Ты имеешь в виду каждый раз ли разрешается имя домена в IP адрес? Да, каждый, но результат может кешироваться, благо сам протокол DNS требует указать время в течении которого ответ можно использовать без повторных запросов.
Ответы 2 мая 523 739252
>>32615

можно

>>32654

> задачу про калькулятор.



> function abc(&$op, &$char, &$number, &$result){


> $op = $char;


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

И что за бредовое название? Названия функции начинаются с глагола, сделайЧтоТо.

Тут вообще эта функция не нужна, код в ней можно поставить под блоком if/else

В остальном верно.

> Пока не доходит до меня как ввести поддержку дробных чисел.


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

> Задача про банкомат.


> echo "Выдача возможна, число купюр:\n";


не говори "гоп", пока не перепрыгнешь: http://ideone.com/3kTQeP - твой банкомат зажал 100 тугриков.

> $abc =


переменным надо давать осмысленные имена

>>33136

Что значат URL? Ты имеешь в виду каждый раз ли разрешается имя домена в IP адрес? Да, каждый, но результат может кешироваться, благо сам протокол DNS требует указать время в течении которого ответ можно использовать без повторных запросов.
Ответы 2 мая 524 739253
>>33183

Может быть много причин. Может, уязвимость, может среди разработчиков есть "крот". Может кто-то сохранил пароль от FTP или SSH, а вирус его украл.

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

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

Ну и смотрите какие вы там библиотеки и плагины используете, гуглите, может они устарели уже и надо обновить.
525 739263
>>38409

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

Конечно заказчик и сам немного виноват что толком не проверил тебя.

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

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

> или уходить и искать что-то более адекватное с прошаренными коллегами


Если есть варианты то можно попробовать. Но не окажется ли там то же самое? Насколько я знаю, то, что тебе нужно есть в крупных организациях-аутсорсерах, у них там и сеньоры настоящие есть, и всякие современные штуки используются.
526 739267
>>39217
У тебя в цикле нет никаких действий, кроме echo.
Ещё:

>PHP Notice: Undefined variable: b in /home/YImoVw/prog.php on line 3


В начале ты объявил $a = ( $b * $b );, но ведь ты не объявил, чему равна $b. Всегда читай, что пишется в заметках - это помогает увидеть ошибки, для того они и нужны.
Тебе сейчас нужно определить переменные и поставить то выражение в тело цикла.
527 739279
>>39263
Оп, как устроиться в "в крупную организацию-аутсорсер"? Я понимаю, что ответ: открыть hh и посмотреть требования в вакансиях. Но ведь там часто пишут больше, чем реально требуется. И берут с меньшим количеством навыков и знаний. Или нет? У тебя есть опыт, возможно ты знаешь саксес стори коллег по цеху или твоих учеников. Какой реальный порог входа для подобных организаций?
528 739287
>>38501

> в которых зп в 10 раз больше, чем в рашке.


Давай не будем преувеличивать, далеко не в 10. В Европе программисты вообще не сильно больше среднего европейца получают, а самые большие зарплаты только в Калифорнии и в штате Нью-Йорк. И то, там условия жизни не сладкие, жилье дорогущее, транспорт плохой, пробки, постоянная нервотрепка. И внезапно в США ты сам платишь со своей зарплаты налоги, да еще и немаленькие. ЧТо-то я не уверен что в 10 раз больше. В странах СНГ хорошим разработчикам могут платить до 2000 -3000 долл.

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

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

"хорошо там, где нас нет" в общем.

Мне вспоминается история про тян из техподдержки которой там еду не на что покупать было: https://vc.ru/p/yelp-fired

Конечно в США можно жить хорошо - если ты из богатой семьи или если ты смог развить успешный бизнес. Но не всем так везет.
529 739303
>>39279

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

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


Не знаю. Но кто тебе мешает это изучить?
530 739590
>>39267
Спасибо добрый человек.
Удивительно, после стольких лет на двощах увидел тред в котором исключительно адекватные люди помогают другим, без агрессии, злобы и высокомерства. Прямо на душе теплее стало
531 739591
>>39590
Поссал на тебя.
532 739689
>>39591
стало теплее не толькотеа душе <3
121 Кб, 900x675
533 739718
Сап, пыхач, я не твой. Доставьте годный видеогайд, желательно на русском, как пошагово напилить интернет магазин на Php, mysql, вот это всё. Заказать не вариант, денег лишних нет, сам немного могу в кодинг, но боюсь что-то упустить, на Ютубе одни дауны или древнее говно. В одном из тамошних курсов хуйлан постоил интернет-магаз с скл-иъекциями и говорит в конце "вот смотрите мы слепили хороший сайт, за который готовы платить". Короче, доставьте хороший, годный.
534 739826
>>39214
1. Будет какое-нибудь говно устаревшее и говнокод. Увязнешь.
2. Норм вариант. Возьмут или не возьмут, зависит от того, кого набирают в данный момент. Иногда и сосем джунов берут. В любом случае, если возьмут, то многому научишься.
3. Время на прокачку тебе никто на фрилансе давать не будет. Везде хотят быстро, и чтобы вчера сделано. Естественно один говнокод с такими условиями. Клиенты будут кидать регулярно, пока базу не наберешь.
4. Норм вариант, но найти сложно. Из минусов, что удаленщиков вся остальная фирма за халявщиков держит. Коммуникации осложнены. Все заслуги будут офисным доставаться, а тебя как малоценного работника держать будут.
5. Откладывать вряд ли сможешь сильно больше, жилье дорогое же и все дорогое в ДС. Зато сможешь работу за неделю сменить, если надоест, их полным-полно, и берут охотно.
6. Без законченного высшего будут проблемы с визой, придется закончить сначала. А так, да, лучший вариант, и зарплаты самые высокие. Ну и инглиш конечно выучить надо.
535 739832
>>39287
Работаю в европке. Джунам платят 2500 евро брутто, сеньерам 5-7 штук. С работой проблем нет, много ее.
92 Кб, 1366x768
536 739964
Первую страничку пока токо сделал.
https://github.com/nsdvw/TestHub

По поводу прав на логи/кеш, перепробовал уже все комбинации. Давал любые права,
в том числе три семерки (как знаменитый портвейн), добавлял ввв-рута себе в друзяшки,
и сам к нему добавился.
Все равно какая-то фигня, там в standard-edition в композере какие-то пост-установочные
скрипты (от Distribution bundle), в том числе они должны чистить кеш. Но очистить кеш у него
не получается, говорит нет прав и вдобавок откатывает composer.json, сволочь.
То есть я даже бутстрап установить не мог, он откатывал изменения.

Помогло только заклинание, которое дают в документации по установке.
Что тут вообще написано?
$ HTTPDUSER=`ps axo user,comm | grep -E '[a]pache|[h]ttpd|[_]www|[w]ww-data|[n]ginx' | grep -v root | head -1 | cut -d\ -f1`
$ sudo setfacl -R -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX var
$ sudo setfacl -dR -m u:"$HTTPDUSER":rwX -m u:`whoami`:rwX var

Да, и почему оно работает только в dev режиме? В prod 404 на любой запрос.
А, нет, уже работает. Но стили похерились.
537 739998
>>39964

>Что тут вообще написано?


Вроде бы ищет апач в списке процессов, потом отсеивает рутовые апачи, и выдирает юзера из апачей, которые не под рутом. Потом ставит права этому юзеру на папку var.
538 740004
>>39998
Точнее двум юзерам права дает на папку var и все ее подпапки. Тебе и тому, на кого апач найденный запущен.
539 740027
Помогите с шестой задачей отсюда ( https://github.com/codedokode/pasta/blob/master/html/html.md ).

Какие есть способы сделать так, чтобы текст статьи не наезжал под меню? Я так понял, что мне нужно растянуть меню до нижней границы экрана. Как это можно сделать? Если выставить свойство height: 100% ничего не происходит. Получилось выставить лишь точное значение.

Исходники прилагаю: https://github.com/codedokode/pasta/blob/master/html/html.md
540 740030
105 Кб, 1024x683
541 740120
>>29430 (OP)
Ребятки, помогите плиз.
В файле .htaccess эти строчки:
RewriteRule ^.$ [NC,L]
RewriteRule ^.
$ index.php [NC,L]
Какого-то хуя убивают страничку, на которой расположен простенький ajax чатик. Всё остальное работает отлично. Отличие этого ajax чатика, от всех остальных страниц в том, что в нём инклудятся другие соседние файлы. С чем сввязано, как поправить ?
542 740126
>>40120
Точнее не убивают, а скорее заставляют сайтик игнорировать скрипты, которые должны выполняться.
543 740139
>>39964

Проблема с правами действительно есть. В общем случае у нас есть пользователь, от которого работает PHP (www-root или apache) и N пользователей-разработчиков которые могут править код, запускать скрипты.

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

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

Вдобавок есть еще так называемый umask. Он определяет какие биты будут сброшены в разрешениях на создаваемые файлы и папки. Ты можешь увидеть свой umask командой umask, и в php есть опция для его указания.

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

Вот какие я способы решения видел:

- создается отдельный пользователь для сайта, например, testhub, и php-fpm запускается от его имени. Для разработчиков добавляется право делать sudo в testhub через sudoers. Соответственно cli скрипты тоже запускаются от того же пользователя. Все файлы также принадлежат этому пользователю.

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

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

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

http://linux.die.net/man/5/acl
http://linux.die.net/man/1/setfacl

Можешь немного поизучать эту тему и подумать, как лучше все это делать.
544 740148
>>40027

> Какие есть способы сделать так, чтобы текст статьи не наезжал под меню?


А ты внимательно изучил особенности флоатов в учебнике на softwaremaniacs? Их надо знать наизусть.

Способ решения который подойдет здесь и во многих других случаях, такой: делаем меню флоатом, а контент - обычным блоком с паддингом слева. Чтобы загнать меню на паддинг, используем отрицатеьный маргин, мини-урок: https://gist.github.com/codedokode/3f6063edf0a2227eb313

> Я так понял, что мне нужно растянуть меню до нижней границы экрана. Как это можно сделать?


Только используя display:table-cell (или флексбокс который пока не везде работает), то есть заставить блоки меню и контента вести себя как ячейки таблицы. Но в данном случае с флоатами наверно удобнее.

О! Вот тебе задание. Изучи особенности работы display: table, display: table-row, table-cell. Сравни варианты верстки сайта из нескольких колонок флоатами и таблицей.

То есть у нас есть сайт из центральной колонки и одной или нескольких колонок сбоку. Довольно типичная ситуация.

Сравни преимущества и недостатки каждого способа. ну например:

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

Это мини-исследование поможет тебе лучше понять принципы расстановки и позиционирования блоков в CSS. Уверен что потраченное на него время окупится сторицей, благодаря тому что ты будешь лучше разбираться в CSS и быстрее решать какие-то проблемы в верстке.
544 740148
>>40027

> Какие есть способы сделать так, чтобы текст статьи не наезжал под меню?


А ты внимательно изучил особенности флоатов в учебнике на softwaremaniacs? Их надо знать наизусть.

Способ решения который подойдет здесь и во многих других случаях, такой: делаем меню флоатом, а контент - обычным блоком с паддингом слева. Чтобы загнать меню на паддинг, используем отрицатеьный маргин, мини-урок: https://gist.github.com/codedokode/3f6063edf0a2227eb313

> Я так понял, что мне нужно растянуть меню до нижней границы экрана. Как это можно сделать?


Только используя display:table-cell (или флексбокс который пока не везде работает), то есть заставить блоки меню и контента вести себя как ячейки таблицы. Но в данном случае с флоатами наверно удобнее.

О! Вот тебе задание. Изучи особенности работы display: table, display: table-row, table-cell. Сравни варианты верстки сайта из нескольких колонок флоатами и таблицей.

То есть у нас есть сайт из центральной колонки и одной или нескольких колонок сбоку. Довольно типичная ситуация.

Сравни преимущества и недостатки каждого способа. ну например:

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

Это мини-исследование поможет тебе лучше понять принципы расстановки и позиционирования блоков в CSS. Уверен что потраченное на него время окупится сторицей, благодаря тому что ты будешь лучше разбираться в CSS и быстрее решать какие-то проблемы в верстке.
545 740164
Приветствую вас, господа пограммисты.
Застрял на задаче про полином из стартового курса.
Вот ссылка: http://ideone.com/1PghDS Все время говорит что фраза не полином, хотя она полином, сука. Подскажите, где я обосрался?
Заранее спасибо за помощь.
546 740169
>>39964

По дизайну:

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

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

Конечно, подчеркивание, особенно когда его много, сильно отвлекает внимание и оно бывает "тяжелым" на надписям крупного размера. Но для этого есть способы борьбы - например подчеркивание можно делать через border-bottom на inline-элементе, сделав его тонким и бледненьким.

https://www.artlebedev.ru/kovodstvo/sections/171/

Кнопка "создать тест" слишком близко к тексту (сравни с расстоянием между абзацами) и такое ощущение что ее не мешало бы сдвинуть на пару пикселей левее.

Логотип норм.

https://github.com/nsdvw/TestHub/blob/master/tests/AppBundle/Controller/DefaultControllerTest.php
Тест стоит удалить как и сам default controller.

А, еще, какую БД ты используешь? Если mysql то советую вместо нее попробовать постгрес. Она использует тот же SQL так что на 80% там все то же, но у нее есть много других возможностей:

- строгий режим включен по умолчанию
- соответствие стандартам ANSI SQL
- поддерживается CHECK на колонках и таблицах (погугли что это)
- индексы по выражениям
- географические типы данных и индексы (вроде найти точки в радиусе R от данной)
- полнотекстовые индексы
- поддержка JSON с индексацией

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

Плюс, не знаю, важно ли это, но сейчас есть некоторое движение по замене Oracle/MSSQL на открытые БД во всяких крупных организациях, госорганизациях и обычно как замена используется именно постгрес. Хотя это конечно происходит не с такой скоростью, как хотелось бы.

Насчет генерации схемы из моделей. Это конечно красиво выглядит в теории, но на практике этого будет недостаточно, так как тебе захочется добавлять разные SQL опции в таблицы. Так что настраивайся на то, что надо будет переходить на SQL дампы и миграции.
546 740169
>>39964

По дизайну:

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

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

Конечно, подчеркивание, особенно когда его много, сильно отвлекает внимание и оно бывает "тяжелым" на надписям крупного размера. Но для этого есть способы борьбы - например подчеркивание можно делать через border-bottom на inline-элементе, сделав его тонким и бледненьким.

https://www.artlebedev.ru/kovodstvo/sections/171/

Кнопка "создать тест" слишком близко к тексту (сравни с расстоянием между абзацами) и такое ощущение что ее не мешало бы сдвинуть на пару пикселей левее.

Логотип норм.

https://github.com/nsdvw/TestHub/blob/master/tests/AppBundle/Controller/DefaultControllerTest.php
Тест стоит удалить как и сам default controller.

А, еще, какую БД ты используешь? Если mysql то советую вместо нее попробовать постгрес. Она использует тот же SQL так что на 80% там все то же, но у нее есть много других возможностей:

- строгий режим включен по умолчанию
- соответствие стандартам ANSI SQL
- поддерживается CHECK на колонках и таблицах (погугли что это)
- индексы по выражениям
- географические типы данных и индексы (вроде найти точки в радиусе R от данной)
- полнотекстовые индексы
- поддержка JSON с индексацией

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

Плюс, не знаю, важно ли это, но сейчас есть некоторое движение по замене Oracle/MSSQL на открытые БД во всяких крупных организациях, госорганизациях и обычно как замена используется именно постгрес. Хотя это конечно происходит не с такой скоростью, как хотелось бы.

Насчет генерации схемы из моделей. Это конечно красиво выглядит в теории, но на практике этого будет недостаточно, так как тебе захочется добавлять разные SQL опции в таблицы. Так что настраивайся на то, что надо будет переходить на SQL дампы и миграции.
547 740175
>>39964

Вообще команды от Симфони плохие. Они непонятные и там нет защиты от ошибок. Что если Апач не запущен? Что если запущен, но для других целей? Мне они не нравятся.
548 740187
>>39964

В ридми ты забыл упомянуть что после правки конфига надо почистить кеш симфони (cache:clear --env=-prod), также надо сделать assetic:dump для prod так как composer install почему-то делает его для dev.

И конечно там какой-то ад с этими конфигами, их много.
549 740188
>>40164

Перед этой строчкой

if ($text[$i] == $text[$x]){

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

И кстати, с чего ты взял что $text[$i] это i-я буква? Это i-й байт, в utf-8 буква состоиит из нескоьких байт и это не работает, урок https://gist.github.com/codedokode/ff99e357e9860ea169b8
550 740192
>>39718
Wordpress -> wooCommerce .
Задачка 551 740193
Алсо, дам еще такую задачку поломать голову. Допустим, мы хотим отслеживать случаи падения браузера на нашем сайте. Браузер может падать по разным причинам: нехватка оперативной памяти, баги в самом браузере или плагинах. В случае с однопроцессным браузером вроде фаерфокса, падает весь браузер, а в многопроцессных - отдельная вкладка (наверняка вы видели грустную рожицу в хроме).

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

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

Предложите ваши варианты реализации системы сбора такой информации.
552 740200
>>40164

>полином


>где я обосрался?


Уже на этом месте, например.

>$text = mb_strtolower ($text);


>$text[$i]


Ты путаешь строки и массивы.
Предыдущие задачи точно решил? Покажи парочку (или ссылки на них в треде дай, если уже показывал).
553 740209
Кто-нибудь работал с PHPmorphy? Как определить число (единственное или множественное) в котором слово находится?
554 740213
Посоны, прошу пояснить за сессии.

Допустим, постом передаём логин и пасс скрипту, делаем проверку с БД и если всё забеись, делаем такое $_SESSION['logged_id'] = 1;

Теперь, для того, чтобы отобразить закрытую страницу, достаточно просто чекнуть
if (isset($_SESSION['logged_id']) {# some shit}
так?

Вопрос в том, может ли сторона юзера это как-то подделать? Сессии же по идее на серваке храняться, так что видимо, не может?
Сегментация рынка 555 740281
Раз никто не спрашивает вопросов по задачкам.

Прочел новость про то что Тесла продает "программный" апгрейд аккумулятора: https://m.geektimes.ru/post/275516/

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

Это все конечно чушь. Цена на S70 полностью покрывает стоимость более мощного аккумулятора. Реальная причина - сегментация рынка с целью заработать больше денег. Про этот принцип хорошо написал Джоэл: http://russian.joelonsoftware.com/Articles/CamelsandRubberDuckies.html (очень интересная статья)

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

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

Разумеется все это Тесле с рук не сойдет. Никто не любит когда ему пытаются впарить по большей цене точно такую же модель (S75) как и дешевая (S70). Если бы я выбирал машину, это было бы фактором против теслы.

А плохо станет, когда выбора уже не останется.
556 740301
Посмотрите пожалуйста решение задачи для новичков про кредит, и подскажите нормально или говнокод?
http://codepad.org/525kYmga
557 740367
Анон, ты перекатывать будешь вообще?
558 740368
>>40367
А тебе зачем?
559 740408
>>40301

>11 месяцев спустя, долг = 4138.1720657184, выплачено 55000


Смотри, у тебя долг на 11-ом месяце 4138 с копейками. Далее тебе надо ещё раз прибавить к этому 3% и комиссию в 1000 рублей. Это происходит у тебя, но остаётся 262 рубля.
После этого твой скрипт просто прибавляет их к окончательной сумме выплат и всё.
А ведь он должен снова прибавить уже к 262-м рублям 3% и 1000 рублей комиссии.
Правильный ответ - 61270 рублей со многими копейками.
После того, как добьёшься выплаты верной суммы, протестируй на сумме кредита в 1000 рублей - итоговая сумма выплат в этом случае составит 2030 рублей.
50 Кб, 1344x681
560 740418
Ребят, у меня ступор.
Установил MySQL, вроде всё нормально (всё по настройкам из коробки, я же не разбираюсь пока).
Читаю по советам ОПа вот это: http://phpclub.ru/mysql/doc/connecting-disconnecting.html

Ну и там сразу идёт:
"3.1. Подсоединение к серверу и отсоединение от него

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

shell> mysql -h host -u user -p
Enter password:"

Это всё через консоль, что ли делать надо?
Ни черта же непонятно, где что.
561 740420
Вообще как с места стронуться?
Мускул стоит - что вообще дальше-то?
Может, есть какие не древние видеоуроки или что-то опять же более-менее современное в текстовом виде?
У меня СТУПОР, короче.
562 740440
>>40418

Урок по командной строке есть в ОП посте. Прочти его.

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

mysql ...

Если нет то надо писать полный путь

c:\mysql\bin\mysql.exe ....

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

хост = localhost, то есть твой компьютер
порт = стандартный 3306, указывать не надо
пользователь = root
пароль = задается при установке mysql, если ты не задавал то наверно пустой

Узнать подробности о клиенте mysql можно набрав

mysql --help

(если он не в PATH то с полным указанием пути)

Будь внимателен к пробелам, точкам, слешам и не перепутай ничего.
563 740441
>>40169
Я же над дизайном и не заморачивался, сделал по ваерфреймам gomockingbird.
Если есть макет, без проблем сверстаю.

>мне не нравится современная тенденция делать неподчеркнутые ссылки (речь о заголовках тестов)


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

>Логотип норм.


Мне тоже понравился, с намеком на тестирование ПО.
Позаимствован с shutterstock (в фотошопе замазал ватермарку).
Что можешь сказать по теме защиты петушиных авторских прав? Я имею ввиду, как устанавливается идентичность изображений, если я подкорректирую оригинал?

>Тест стоит удалить как и сам default controller.


Тест понятно, это шло из коробки. А контроллер-то зачем? Я удалил то что там было, пишу в него свои экшены.

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

>И конечно там какой-то ад с этими конфигами, их много.


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

>For now, don't worry about the specific configuration options in each section. The configuration file ships with sensible defaults. As you read more and explore each part of Symfony, you'll learn about the specific configuration options of each feature.


Так и живем.

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


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

>The moral of the story is this: after each change you make to your Doctrine mapping information, run the doctrine:migrations:diff command to automatically generate your migration classes.


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

Использовать подход с миграциями на основе аннотаций может быть имеет смысл с точки зрения согласованности, то есть если писать отдельно аннотации и отдельно миграции, неизбежны разночтения.
Ну ладно, я пока освою "ручные" миграции, как минимум в учебных целях пригодится.
563 740441
>>40169
Я же над дизайном и не заморачивался, сделал по ваерфреймам gomockingbird.
Если есть макет, без проблем сверстаю.

>мне не нравится современная тенденция делать неподчеркнутые ссылки (речь о заголовках тестов)


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

>Логотип норм.


Мне тоже понравился, с намеком на тестирование ПО.
Позаимствован с shutterstock (в фотошопе замазал ватермарку).
Что можешь сказать по теме защиты петушиных авторских прав? Я имею ввиду, как устанавливается идентичность изображений, если я подкорректирую оригинал?

>Тест стоит удалить как и сам default controller.


Тест понятно, это шло из коробки. А контроллер-то зачем? Я удалил то что там было, пишу в него свои экшены.

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

>И конечно там какой-то ад с этими конфигами, их много.


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

>For now, don't worry about the specific configuration options in each section. The configuration file ships with sensible defaults. As you read more and explore each part of Symfony, you'll learn about the specific configuration options of each feature.


Так и живем.

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


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

>The moral of the story is this: after each change you make to your Doctrine mapping information, run the doctrine:migrations:diff command to automatically generate your migration classes.


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

Использовать подход с миграциями на основе аннотаций может быть имеет смысл с точки зрения согласованности, то есть если писать отдельно аннотации и отдельно миграции, неизбежны разночтения.
Ну ладно, я пока освою "ручные" миграции, как минимум в учебных целях пригодится.
564 740446
>>40440
Спасибо!
Подумал, что это не в командной строке, вот я поехал...
565 740456
По поводу всяких "авторских прав", мое мнение: копираст не человек.
Давайте тогда мы, как разработчики веб-сайтов, требовать пожизненный процент от прибыли с каждого сделанного говносайта.
Ладно еще автор контента, но всякие посредники и прочие бездельники достойны только кала и мочи в качестве "отчислений".
566 740464
>>40441

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


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

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


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

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

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

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

Надо стремиться не копировать пиратское ПО, а развивать свободное.

> Увы, пока не нашел подробного описания, за что отвечает каждая настройка


Можно найти класс который их читает. Обычно в Симфони разбором конфигурации занимается конкретный бандл которому она нужна. Он задает правила и ограничения для нужных ему полей конфига и читает их значения.

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

Ну например, возьмем DoctrineBundle которая интегрирует доктрину в Симфони

Открываем https://github.com/doctrine/DoctrineBundle/blob/master/DoctrineBundle.php#L62

Там метод build отвечает за "компиляцию" бандла, которая вроде бы делается при прогреве кеша, а вот boot() вызывается при каждом запуске приложения.

Вот здесь https://github.com/doctrine/DoctrineBundle/blob/master/DependencyInjection/Configuration.php задаются ограничения для значений конфига.

Здесь они разбираются: https://github.com/doctrine/DoctrineBundle/blob/master/DependencyInjection/DoctrineExtension.php

Назначение этих файлов описано в мануале по бандлам, я плохо помню подробности, поищи их тут:

http://symfony.com/doc/current/cookbook/bundles/configuration.html
http://symfony.com/doc/current/book/bundles.html
http://symfony.com/doc/current/components/config/definition.html
http://symfony.com/doc/current/cookbook/bundles/extension.html

Также, там упоминается doctrine-bridge. В нем есть https://github.com/symfony/doctrine-bridge/blob/master/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php который ищет в конфигурации DI контейнера у сервисов теги вроде doctrine.event_listener и ставит эти сервисы обработчиками событий доктрины. Это делаетя на этапе "компиляции" контейнера, надеюсь ты знаешь что в целях оптимизации в продакшене DI контейнер компилируется из кучи конфигов (каждый бандл может что-то добавить в него от себя) в один большой файл и кладется в кеш.

Вот это я разобрал как найти в коде место где описаны и читаются параметры конфигурации одного бандла. Остальные бандлы устроены примерно так же.
566 740464
>>40441

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


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

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


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

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

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

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

Надо стремиться не копировать пиратское ПО, а развивать свободное.

> Увы, пока не нашел подробного описания, за что отвечает каждая настройка


Можно найти класс который их читает. Обычно в Симфони разбором конфигурации занимается конкретный бандл которому она нужна. Он задает правила и ограничения для нужных ему полей конфига и читает их значения.

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

Ну например, возьмем DoctrineBundle которая интегрирует доктрину в Симфони

Открываем https://github.com/doctrine/DoctrineBundle/blob/master/DoctrineBundle.php#L62

Там метод build отвечает за "компиляцию" бандла, которая вроде бы делается при прогреве кеша, а вот boot() вызывается при каждом запуске приложения.

Вот здесь https://github.com/doctrine/DoctrineBundle/blob/master/DependencyInjection/Configuration.php задаются ограничения для значений конфига.

Здесь они разбираются: https://github.com/doctrine/DoctrineBundle/blob/master/DependencyInjection/DoctrineExtension.php

Назначение этих файлов описано в мануале по бандлам, я плохо помню подробности, поищи их тут:

http://symfony.com/doc/current/cookbook/bundles/configuration.html
http://symfony.com/doc/current/book/bundles.html
http://symfony.com/doc/current/components/config/definition.html
http://symfony.com/doc/current/cookbook/bundles/extension.html

Также, там упоминается doctrine-bridge. В нем есть https://github.com/symfony/doctrine-bridge/blob/master/DependencyInjection/CompilerPass/RegisterEventListenersAndSubscribersPass.php который ищет в конфигурации DI контейнера у сервисов теги вроде doctrine.event_listener и ставит эти сервисы обработчиками событий доктрины. Это делаетя на этапе "компиляции" контейнера, надеюсь ты знаешь что в целях оптимизации в продакшене DI контейнер компилируется из кучи конфигов (каждый бандл может что-то добавить в него от себя) в один большой файл и кладется в кеш.

Вот это я разобрал как найти в коде место где описаны и читаются параметры конфигурации одного бандла. Остальные бандлы устроены примерно так же.
567 740467
>>40441

У меня подозрение что автоматические миграции могут быть рассчитаны на случаи, когда особой оптимизации БД не требуется, может на этапе разработки прототипа. Но чем доктрина и хороша, что не заставляет тебя их использовать и разрешает тебе саму управлять базой. Тем более что в Doctrine DBAL есть средства для ручных миграций.

>>40456

> Давайте тогда мы, как разработчики веб-сайтов, требовать пожизненный процент


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

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

Хотя конечно у авторского права есть свои проблемы - например малопопулярные книги или аудиозаписи могут со временем исчезать, так как переиздавать их нерентаьельно, а бесплатно их не отдадут. Теряется чей-то интеллектуальный труд. Надеюсь, в будущем придумают какое-нибудь решение, какую-нибудь библиотеку, хранящую копии всех старых произведений.
568 740489
Ребят, застрял на задаче "Числа прописью". Парюсь уже второй день. И бросать не хочу, и решения не могу подобрать. Мог бы кто нибудь объяснить как следует к ней подойти или поэтапно рассказать ход выполнения.
569 740501
>>40489

Надо разбить задачу на составные части. Там вроде в уроке написано, напомню еще раз:

- функция spellSmallNumber(), принимает на вход число от 0 до 999 и возвращает его текстовую форму: spellSmallNumber(123) → 'сто двадцать три'
- функция выбора формы слова, принимает на вход число и 3 формы слова и возвращает подходящую: getWordForm(23, 'кот', 'кота', 'котов') → 'кота'. С ее помощью склоняются слова вроде "тысяч".
- основная функция spellNumber(), которая принимает на вход большое число, разбивает его на части по 3 цифры и вызывая указанные выше функции, получает число прописью.

Первую и вторую функцию можно сделать отдельно, проверить, и если все ок, делать третью функцию.

Что именно тебе непонятно? На чем застрял?
570 740521
Ещё раз вопрос по архитектуре студентов. Я прочитал про SOLID и теперь чуть лучше понимаю DI, IoC.
Итак, если я хочу использовать DataMapper в контроллере, то есть такие варианты:
1. Захардкодить в контроллере $studentMapper = new StudentMapper. Плохо, мне нужно будет лезть в класс контроллера, если нужно поменять маппер + здесь ещё нужно объект PDO передавать в StudentMapper.
2. Передавать готовый StudentMapper в конструктор контроллера. Лучше, но контроллер по-прежнему знает, что ему передаётся не просто маппер, а StudentMapper.
3. Использовать IoC, конструктор контроллера будет выглядеть примерно так: __construct(IMapper $mapper), а для всех мапперов указать implements IMapper, чтобы у них были одинаковые методы. Контроллер не знает, что за маппер ему передали, классы стали менее связаны.

А теперь если я хочу передать несколько мапперов в контроллер? Нужны ServiceLocator или DI-контейнер. Но как будет выглядеть тело конструктора контроллера теперь? Примерно так:
$this->studentMapper = $mapperLocator->getMapper('Student');
Это плохо?
4 Кб, 194x83
571 740546
>>40501
Начал решение задачи с написания третьей функции и сразу же застопорился на моменте с разбиением: на пике процесс разбиения если число имеет длину от 7 до 9 знаков, то есть для миллионов. Только подходит от не для всех чисел. Если например число будет иметь вид 900000000 то выведет 0 0 900 вместо 000 000 900. И я вот не могу уловить, как потом это учитывать в функции перевода в текстовую форму.
572 740569
>>40546

> то выведет 0 0 900 вместо 000 000 900


А чем отличается 000 от 0? Это просто неправильная форма записи нуля. В PHP, как и в математике, число не может быть равно 000.

в php возможна строка "000" (обрати внимание на кавычки), но в данной задаче надо все решать через числа.

И я не понимаю, как это тебе мешает.

Отвечая на твой вопрос: ничего с этим делать не надо, числа бывают и меньше 3 разрядов и это нормально.
333 Кб, 1366x737
573 740586
шо это с ним? Доки не двач, не должны лежать.

На память может кто-нибудь помнит, как сменить драйвер в доктрине?
Для mysql это pdo_mysql, а для постгрес?
pdo_postrgres? postgres? postgresql?

Миграции через doctrine:migrations:diff генерируют оказывается голый sql, ну в смысле
$this->addSql('ALTER TABLE ...');
Диалекты-то сильно отличаются?

Причины, по которой мне не очень охота писать миграции вручную, во-первых это кол-во букв
(мне вот сейчас нужно создать около 8 таблиц, в каждой в среднем 5-7 колонок, куча индексов и ключей, я заколебаюсь писать
$table = $schema->createTable('first'); $table->addColumn('abc', 'string', [options])),
во-вторых опять отсутствие внятной документации.
Вот мне нужно сделать nullable колонку, ну в смысле чтобы она могла принимать значение null.
Пишу $table->addColumn('abc', 'string', ['nullable'=>true]) как в аннотациях, все равно генерирует NOT NULL.
Синтаксис другой походу, не как в аннотациях.
Вместо GeneratedValue нужно писать
'autoincrement' => true
Откуда я об этом узнаю? Из какого-то левого примера
http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/reference/generating_migrations.html#without-the-orm
А все остальные опции? Что, опять придется как лох читать исходный код?
574 740603
>>40586

Я сегодня смотрел

http://stackoverflow.com/questions/10588646/how-to-change-a-database-to-postgresql-with-symfony-2-0

> database_driver: pdo_pgsql


Где-то в конфиге или parameters.yml и перегенерировать кеш.
575 740607
>>40586

> (мне вот сейчас нужно создать около 8 таблиц, в каждой в среднем 5-7 колонок, куча индексов и ключей, я заколебаюсь писать


Ну не смеши, по 2 минуты на таблицу = 16 минут.

Как вариант можно генерировать и потом править SQL вручную.

> Пишу $table->addColumn('abc', 'string', ['nullable'=>true]) как в аннотациях, все равно генерирует NOT NULL.


Видимо такой опции нет или ты что-то напутал.

> Синтаксис другой походу, не как в аннотациях.


Видимо

Доки: http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/schema-representation.html

Ссылка на них стоит в самом начале страницы http://docs.doctrine-project.org/projects/doctrine-migrations/en/latest/reference/generating_migrations.html
576 740608
>>40586

И мне кажется чистый SQL удобнее этих createtable, он читается лучше.
577 740614
>>40608
Так драйвер же не получится сменить.
Я не знаю postgres, но наверное там есть отличия в диалекте. Например только что нагуглил вместо auto_increment используется какой-то serial.
Квери билдер это абстракция.

По 2 минуты на таблицу это когда знаешь наизусть апи, а я пока даже не знаю где это само апи искать.
Буду надеяться, что тут все есть
http://docs.doctrine-project.org/projects/doctrine-dbal/en/latest/reference/schema-representation.html

Я думал за сегодня успею полностью написать кусок с прохождением тестов, ты тут со своими миграциями и постгресом.
578 740746
>>40408
Спасибо, пойду думать
579 740754
>>40614

Я сегодня разворачивал твой проект на c9.io, и после замены конфига он мне сгенеирировал нужный SQL для постгрес, который тот с радостью принял.

> Например только что нагуглил вместо auto_increment используется какой-то serial.


Вообще, в постгресе генерация id отвязана от таблиц.Там есть отдельный объект - SEQUENCE который умеет генерировать последовательно возрастающие id. Ты можешь использовать его как хочешь. Тип SERIAL просто создает sequence и привязывает ее к полю таблицы.
40 Кб, 640x480
580 740817
>>40521
Почему не захуярить логику работы с данными в модели?
Допустим есть класс Student
private $mapper;
В нем конструктор
public function __construct()
{

$this->mapper = new StudentMapper();
}
и дальше уже дохерачить методы save, delete, load
ну?
581 740830
>>40521
Зачем делать привязку контроллеров к определенному классу? Почему бы просто не передавать контейнер в конструктор, а потом уже извлекать из него все что тебе нужно? Это конечно не очень хороший способ, потому что в больших приложениях ты можешь передавать 200+ элементов в контроллер, когда тебе нужен только один, но в студентах это вполне подойдет, наверное.
>>40817
Это называется Active Record. В данном случае код работы с базой и модель в одном классе, хотя модель вполне может существовать сама по себе. Решением этой проблемы является как раз Data Mapper который хочет использовать анон.
22 Кб, 526x564
582 740832
>>40817
Так суть DataMapper (насколько я понял) в том, что мы разделяем слой модели (которая теперь является точной проекцией содержимого строки таблицы) от слоя, который этой моделью манипулирует.
Это в ActiveRecord модель может сама себя удалять и записывать в БД.

Вспомнил и прилепил забавную картинку.
170 Кб, 1261x700
583 740839
>>40830
Так ведь можно вынести код работы именно с базой в StudentMapper таким образом полностью отделив саму базу от модели. Допустим в классе маппера тоже будут, save только он уже принимает данные из модели и сейвает их в базу.

Сорян, я сам то ни разу не очень опытен в проектировании, но по мне это логично и удобно
584 740846
>>40832
Какой язык на кружке?
Функции не как в РНР и ещё Coffee coffee - что, простите?
585 740849
>>40846
Здесь суть в coffee.drink() и сoffee.refill()
Кофе пьёт и кофе наполняет.

Язык может быть Java или C#, для этих языков нужно при инициализации указывать тип данных переменной. Тип данных в данном случае - Сoffee.
162 Кб, 760x1080
586 740854
>>40846
Где ты там функции то увидел полуумный?
587 740855
>>40849
Спасибо.

>>40854
Ну, я подумал, что это типа $coffee->drink() и $coffee->refill() в ООП на РНР.
588 740857
>>40855
Это методы
589 740858
>>40832
Явно не по PSR, скобки перенесены после условия на новую строку, название свойства с большой буквы, методы с большой буквы.
590 740860
PSR - это PHP Standards Recommendations. Очевидно, что другой язык их соблюдать не должен.
591 740865
>>40858
Есть два стиля форматирования кода основных, лол, в одном из них скобки по разному после условия
592 740883
>>40865
В PSR один стиль.
593 740895
>>40858
Ага, потому, что это ебучий php стандарт, но кроме его существует еще хуевая туча различных стилей под различные цмс и фреймворки, пошел нахуй.

И кроме того, в различных языках в стандартах прослеживаются вот именно 2 стиля.
594 741080
>>40849
Это C#, у Java методы с маленькой буквы пишут.
595 741103
>>40521

> Итак, если я хочу использовать DataMapper в контроллере, то есть такие варианты:


- передать DM через конструктор
- передать DI контейнер через конструктор

> . Захардкодить в контроллере $studentMapper = new StudentMapper. Плохо, мне нужно будет лезть в класс контроллера, если нужно поменять маппер + здесь ещё нужно объект PDO передавать в StudentMapper.


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

> Передавать готовый StudentMapper в конструктор контроллера. Лучше, но контроллер по-прежнему знает, что ему передаётся не просто маппер, а StudentMapper.


Норм

> 3. Использовать IoC, конструктор контроллера будет выглядеть примерно так: __construct(IMapper $mapper), а для всех мапперов указать implements IMapper


Неправильно. Если ты пишешь IMapper то это значит что контроллер готов работать с любым маппером, но ведь это не так, верно? Если ты решил сделать внедрение зависимостей через интерфейсы, то надо писать IStudentMapper тогда.

> А теперь если я хочу передать несколько мапперов в контроллер?


Либо передать их по отдельности либо передать DI контейнер.

>>40817

Потому что класс Student отвечает за хранение данных о студенте. Работать с БД не его обязанность. Ты предлагаешь смешать 2 обязанности в одном классе.

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

function doSomething(Student $student)

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

Подход когда код работы с БД засунут в модель, называется active Record - это вроде было в моем уроке по паттернам работы с БД.
595 741103
>>40521

> Итак, если я хочу использовать DataMapper в контроллере, то есть такие варианты:


- передать DM через конструктор
- передать DI контейнер через конструктор

> . Захардкодить в контроллере $studentMapper = new StudentMapper. Плохо, мне нужно будет лезть в класс контроллера, если нужно поменять маппер + здесь ещё нужно объект PDO передавать в StudentMapper.


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

> Передавать готовый StudentMapper в конструктор контроллера. Лучше, но контроллер по-прежнему знает, что ему передаётся не просто маппер, а StudentMapper.


Норм

> 3. Использовать IoC, конструктор контроллера будет выглядеть примерно так: __construct(IMapper $mapper), а для всех мапперов указать implements IMapper


Неправильно. Если ты пишешь IMapper то это значит что контроллер готов работать с любым маппером, но ведь это не так, верно? Если ты решил сделать внедрение зависимостей через интерфейсы, то надо писать IStudentMapper тогда.

> А теперь если я хочу передать несколько мапперов в контроллер?


Либо передать их по отдельности либо передать DI контейнер.

>>40817

Потому что класс Student отвечает за хранение данных о студенте. Работать с БД не его обязанность. Ты предлагаешь смешать 2 обязанности в одном классе.

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

function doSomething(Student $student)

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

Подход когда код работы с БД засунут в модель, называется active Record - это вроде было в моем уроке по паттернам работы с БД.
596 741108
>>40817

Также, ты заметил что в твоем коде явно проблемы с DI? Ты создаешь маппер, а где ты берешь объект PDO для него?

>>40830

> Зачем делать привязку контроллеров к определенному классу?


Это как раз логично так как контроллеру конкретный класс и нужен. Явно обозначить зависимость, что ему нужны классы X и Y - это хорошо.

> Это конечно не очень хороший способ, потому что в больших приложениях ты можешь передавать 200+ элементов в контроллер, когда тебе нужен только один,


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

>>40832

Код на картинке сомнительный. Кофе само себя выпило? Само себя наполнило?

Логичнее было бы

human.drink(coffee);

или если нам не важно кто его выпил то

coffee.decreaseVolume(10);

>>40846

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

>>40854

Метод в каком-то смысле функция в классе.

>>40895

А вот в C# как я помню стандарта оформления нет и каждый пишет как хочет.

> И кроме того, в различных языках в стандартах прослеживаются вот именно 2 стиля.


Только там где нет единого стандарта, там и бардак.
596 741108
>>40817

Также, ты заметил что в твоем коде явно проблемы с DI? Ты создаешь маппер, а где ты берешь объект PDO для него?

>>40830

> Зачем делать привязку контроллеров к определенному классу?


Это как раз логично так как контроллеру конкретный класс и нужен. Явно обозначить зависимость, что ему нужны классы X и Y - это хорошо.

> Это конечно не очень хороший способ, потому что в больших приложениях ты можешь передавать 200+ элементов в контроллер, когда тебе нужен только один,


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

>>40832

Код на картинке сомнительный. Кофе само себя выпило? Само себя наполнило?

Логичнее было бы

human.drink(coffee);

или если нам не важно кто его выпил то

coffee.decreaseVolume(10);

>>40846

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

>>40854

Метод в каком-то смысле функция в классе.

>>40895

А вот в C# как я помню стандарта оформления нет и каждый пишет как хочет.

> И кроме того, в различных языках в стандартах прослеживаются вот именно 2 стиля.


Только там где нет единого стандарта, там и бардак.
598 741225
>>41108
Оп-кун, я предлагаю не совсем Active Record. Да и я знаю, что такое ActiveRecord только я уже здесь почти не учусь, а больше года работаю ;)

Я предлагал что-то в духе Magento.

Student - модель, а StudentMapper ресурс для работы с базой данных, вот к примеру метод в Magento:
/
Load object data

@param integer $id
@return Mage_Core_Model_Abstract
*/
public function load($id, $field=null)
{
$this->_beforeLoad($id, $field);
$this->_getResource()->load($this, $id, $field);
$this->_afterLoad();
$this->setOrigData();
$this->_hasDataChanges = false;
return $this;
}
47 Кб, 321x480
599 741229
600 741250
>>41225

Что значит "не совсем active record". Если модель сама себя загружает из базы - это Active Record. Это я не сам придумал, названия и описания паттернов я взял у Фаулера.

Пример который ты привел это Active Record. Причем еще и с каким-то нездоровым количеством подчеркиваний. Им PHP5 все еще не завезли что ли?
601 741258
Интересует такой момент: есть ли в PHP функции высшего порядка как в javascript'е и "замыкания"? Развито ли функциональное программирование?
602 741276
>>41258

есть, не развито
603 741295
>>41276
Там можно определять функцию внутри функции/возвращать функцию из вызова функции? Интересно посмотреть пример
604 741317
>>41295

function x() {
return function () {

};
}

гугли анонимные функции.
605 741396
>>41250
Ты о Magento не слышал? ;) Это наверное лучшая e-commerce cms.

Это не классический ActiveRecord, а все потому, что работы с базой в модели нет, вся связь с базой вынесенна в ресурсные модели
606 741405
Подскажите по антикризисным мерам, как логичнее делать, создавать четыре одинаковых компании, и к трем из них применить соответственно 3 разные анткр меры, применять их к одной и тойже компании поочередно, откатывая измения после вывода таблицы результатов, или каким-то образом клонировать исходную компанию, что по сути первый вариант?
607 741429
>>41396

А это не важно, вынесена она или нет. Важно что у модели есть ссылка на классы работы с БД и метод load.

>>41405

Клонировать компанию. Надо сделать чтобы при клонировании компании клонировались бы все ее департеманты и сотрудники. Сделать это удобнее всего с помощью магического метода __clone.
608 741457
Задача Студенты
https://github.com/TheSidSpears/Students

1. Правильно ли я реализовал MVC?
2. Слышал о подходе, когда в классе все свойства закрытые, а обращаются к ним/изменяют через getter'ы/setter'ы. Нужно ли это?
3. Критикуйте полностью. Пока у меня нет уверенности, что я на верном пути, поэтому пока не оценят, дальше делать боюсь
609 741462
>>41429
Важно же, с ресурсными моделями нивелируется недостаток абстрактных источников данных, ресурсные модели могут работать с любыми абстракциями будь то json,csv,db,api
610 741466
Ребят, а может кто посоветовать каких нибудь курсов годных по пыхе на всяких coursera'ах и edx'ах.
611 741467
>>41429
ммм, магия.
612 741468
>>41466
Почему тебе не нравится ОП-курс? Чем курсеры лучше?
613 741472
>>38695
Бамп
614 741477
>>41466
На хекслете по SICP есть курс на пыхе, вот годнота
615 741478
>>41468
Возможно больше абстракции
616 741488
>>41477

>хекслет


>годнота



Скрины сделаны тогда, когда я проходил там один из тестов.
А ОП упоминал, что данные из инпутов нужно trim'ить, это азы. На хекслете об этом не знают.
617 741605
>>41488
Забавно, бредово.
Но вообще пока присматриваюсь к Хекслету и Гикбрейнс, к бесплатным курсам.
Так вот Гикбрейнс - просто плохо, всё просто ужасно с бесплатными курсами. Настолько плохо, что платные даже не хочется смотреть. А на Хекслете вроде получше всё.

Другой аноним
618 741628
>>41605
Ну а ты не задавался вопросами, откуда ребята из видеоуроков знают то, что знают? Наверняка они не по видеоурокам учились. Читали доки, маны, книги, скорее всего на инглише, экспериментировали, пробовали. Но точно не безучастно смотрели за тем, как кто-то на видео, с трудом связывая слова и запинаясь в объяснениях, пишет код.
Рахим в своём курсе по ОС так примерно так и говорит: "Этот курс это выжимка из Таненбаума. Хотите лучше что-то понять - читайте его".
99 Кб, 540x492
619 741852
>>41628
Проблема в том, что надо с чего-то начинать.
ОП даёт хорошую базу знания синтаксиса, всяких массивов и регулярок, а вот после ООП (не считаю HTML+CSS) начинается мрак и тьма, пришедшая со Средиземного моря.
В какой-то момент важно не просто получить огромный список того, что нужно знать, а хотя бы посмотреть и пощупать небольшой рабочий проект, пусть даже простую гостевую книгу или небольшой блог с минимумом функционала.
Для углубления - разумеется, читать нужно много.
Но для старта что-то пошаговое в создании гостевой либо блога было бы неплохим подспорьем для того, кто идёт с нуля.
Я вот сейчас прорабатываю Роберта Никсона "Создаём динамические сайты на PHP..." (>>37470), хотя ОП и не одобряет эту книгу.
Но можно делать то, что делает Никсон, и анализировать это с подходом ОПа - никто же не запрещает.
Я пока очень доволен всем, потому как там объяснения уровня начальных страниц учебника ОПа или даже выше.
Но вот хочется посмотреть и на то, как в нескольких уроках по 10-15 минут от начала до конца создают какой-нибудь динамический сайт.
620 741853
*Робина Никсона
Ответы 3 марта, Вектор 621 741855
>>33196

> Поиск пути: http://ideone.com/33ROxP



> function show_shortest_way($paths,$from,$where,$time,$way,$pointNames,$transportName){


time и way всегда одинаковые, зачем их передавать?

> $GLOBALS['ways']


Что еще за использование глобальных переменных? Тут можно было бы использовать return например вместо этого.

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

....
для каждой соседней точки:
- пути[] = проложить путь через точку

лучшийПуть = выбратьЛучшийИз(пути)
вернуть лучшийПуть

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

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

> if (isset($GLOBALS['ways']))


> return ($GLOBALS['ways']);


А если переменная не существует, что вернет функция? null? Почему она разные типы данных возвращает?

Ну и конечно рекурсивный алгоритм довольно неэффективный. Лучше было бы использовать например алгоритм Дейкстры или что-то еще. В Википедии есть статья по алгоритмам поиска пути.

> Текст по кругу: http://ideone.com/2q1F4N



> $sina=


надо писать кемелкейсом, например $sinA

> rad2deg(sin($alpha));


Это непраивльно. Синус возвращает не угол, а число от -1 до 1. И переводить его бессмысленно.

> for($x=0;$x<80;$x++){


> echo $screen[$y][$x];


Тут можно использовать implode

> На вашем счету n рублей: http://ideone.com/JXvVHa



> if(($number%100)<=20) //если два посл. числа <=20, то сравниваем их


> $n=$number%100;


надо ставить фигурные скобки в ифе

> $n=$number%100;


> $n=$number%10;


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

> return $text." ";


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

> $n[1]=$number;


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

> if ($number==0) //при нуле сразу пишем результат


> $text.=$spelling[0]." ";


тут логичнее сразу было ставить return

Сам алгоритм в общем верный, но код оформлен неаккуратно.

> ООО Вектор: http://ideone.com/MbL6Pb



> if(!in_array($department,$this->departments)){


Почитай описание in_array в мануале. Ты исопльзуешь неточное сравнение, которое сравнивает не идентичность объектов, а содержимое их полей. Это в общем плохо, в ООП в 99% случаев надо проверять именно идентичность, то есть хранят ли 2 переменных ссылку на один и тот же или разные объекты.

> public function countEmployees(){


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

> $empls


Не стоит так сокращать. Либо $employees, либо $count, либо $c.

> foreach($this->departments as $k=>$v){


> $k=>$v


Это плохой выбор названий так как $k и $v вообще ничего не значат (как и key/value). Тем более, ты еще и не используешь $k, зачем ее вообще писать тогда?

> public function newEmployee(


Названия функций начинаются с глагола, сделайЧтоТО(), например addEmployee

> public function delEmployee(int $i){


Неправильно выбран аргумент. Вот я хочу удалить сотрудника. Как я узнаю его ключ? Это внутренняя деталь реализации, которая спрятана в классе Department, которую я не знаю и не хочу знать. Надо передавать не индекс, а сам объект-сотрудника.

> public $employees=array(); //сотрудники класса Employee


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

> public static $rate; //int


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

Плюс, там легко ошибиться, использовав self:: вместо static::, и трудно обнаружить такую ошибку. Это "позднее статическое связывание" - какая-то очень мутная штука и я бы избегал его исопльзования вообще. Если тебе надо переопределять что-то в наследнике, для этого подойдут обычные поля.

В качестве решения можно:

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

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

> for($i=0;$i<3;$i++){


> $employee[0][]=new Manager(2,false);


> }


> for($i=0;$i<2;$i++){


> $employee[0][]=new Manager(3,false);


тут идет копипаста, нельзя ли это упростить, положив например информацию о сотрудниках в массив:

$people = [
[$marketing, Manager::class, 3, false],
[$marketing, Engineer::class, 5, false],
...

И потом по массиву насоздавать работников.

Антикризисные меры надо поместить в класс, а не писать код стеной.

> $vector=clone $vector_orig; //возвратили исходные данные


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

> foreach($depClass->employees as $empNum=>$empClass){


> if(get_class($empClass)=="Engineer"){


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

> if(get_class($empClass)=="Engineer"){


> $engArr["id"]=$empNum;


> $engArr["range"]=$empClass->range;


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

> foreach($engineers as $depNum=>$depEmpls){


Ужасные названия переменных. Возьми себе какую-нибудь IDE с автодополнением.

> array_multisort($range, SORT_ASC,$engineers[$depNum]);


Слишком сложно. Лучше выбрать обычный 1-мерный массив инженеров и отсортировать их через usort. Взять 40% можно через array_slice.

> Analyst::$rate = 1100;


Этим ты меняешь ставку во всех копиях компании, а надо только в одной

В общем, код надо рефакторить.
Ответы 3 марта, Вектор 621 741855
>>33196

> Поиск пути: http://ideone.com/33ROxP



> function show_shortest_way($paths,$from,$where,$time,$way,$pointNames,$transportName){


time и way всегда одинаковые, зачем их передавать?

> $GLOBALS['ways']


Что еще за использование глобальных переменных? Тут можно было бы использовать return например вместо этого.

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

....
для каждой соседней точки:
- пути[] = проложить путь через точку

лучшийПуть = выбратьЛучшийИз(пути)
вернуть лучшийПуть

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

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

> if (isset($GLOBALS['ways']))


> return ($GLOBALS['ways']);


А если переменная не существует, что вернет функция? null? Почему она разные типы данных возвращает?

Ну и конечно рекурсивный алгоритм довольно неэффективный. Лучше было бы использовать например алгоритм Дейкстры или что-то еще. В Википедии есть статья по алгоритмам поиска пути.

> Текст по кругу: http://ideone.com/2q1F4N



> $sina=


надо писать кемелкейсом, например $sinA

> rad2deg(sin($alpha));


Это непраивльно. Синус возвращает не угол, а число от -1 до 1. И переводить его бессмысленно.

> for($x=0;$x<80;$x++){


> echo $screen[$y][$x];


Тут можно использовать implode

> На вашем счету n рублей: http://ideone.com/JXvVHa



> if(($number%100)<=20) //если два посл. числа <=20, то сравниваем их


> $n=$number%100;


надо ставить фигурные скобки в ифе

> $n=$number%100;


> $n=$number%10;


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

> return $text." ";


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

> $n[1]=$number;


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

> if ($number==0) //при нуле сразу пишем результат


> $text.=$spelling[0]." ";


тут логичнее сразу было ставить return

Сам алгоритм в общем верный, но код оформлен неаккуратно.

> ООО Вектор: http://ideone.com/MbL6Pb



> if(!in_array($department,$this->departments)){


Почитай описание in_array в мануале. Ты исопльзуешь неточное сравнение, которое сравнивает не идентичность объектов, а содержимое их полей. Это в общем плохо, в ООП в 99% случаев надо проверять именно идентичность, то есть хранят ли 2 переменных ссылку на один и тот же или разные объекты.

> public function countEmployees(){


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

> $empls


Не стоит так сокращать. Либо $employees, либо $count, либо $c.

> foreach($this->departments as $k=>$v){


> $k=>$v


Это плохой выбор названий так как $k и $v вообще ничего не значат (как и key/value). Тем более, ты еще и не используешь $k, зачем ее вообще писать тогда?

> public function newEmployee(


Названия функций начинаются с глагола, сделайЧтоТО(), например addEmployee

> public function delEmployee(int $i){


Неправильно выбран аргумент. Вот я хочу удалить сотрудника. Как я узнаю его ключ? Это внутренняя деталь реализации, которая спрятана в классе Department, которую я не знаю и не хочу знать. Надо передавать не индекс, а сам объект-сотрудника.

> public $employees=array(); //сотрудники класса Employee


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

> public static $rate; //int


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

Плюс, там легко ошибиться, использовав self:: вместо static::, и трудно обнаружить такую ошибку. Это "позднее статическое связывание" - какая-то очень мутная штука и я бы избегал его исопльзования вообще. Если тебе надо переопределять что-то в наследнике, для этого подойдут обычные поля.

В качестве решения можно:

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

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

> for($i=0;$i<3;$i++){


> $employee[0][]=new Manager(2,false);


> }


> for($i=0;$i<2;$i++){


> $employee[0][]=new Manager(3,false);


тут идет копипаста, нельзя ли это упростить, положив например информацию о сотрудниках в массив:

$people = [
[$marketing, Manager::class, 3, false],
[$marketing, Engineer::class, 5, false],
...

И потом по массиву насоздавать работников.

Антикризисные меры надо поместить в класс, а не писать код стеной.

> $vector=clone $vector_orig; //возвратили исходные данные


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

> foreach($depClass->employees as $empNum=>$empClass){


> if(get_class($empClass)=="Engineer"){


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

> if(get_class($empClass)=="Engineer"){


> $engArr["id"]=$empNum;


> $engArr["range"]=$empClass->range;


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

> foreach($engineers as $depNum=>$depEmpls){


Ужасные названия переменных. Возьми себе какую-нибудь IDE с автодополнением.

> array_multisort($range, SORT_ASC,$engineers[$depNum]);


Слишком сложно. Лучше выбрать обычный 1-мерный массив инженеров и отсортировать их через usort. Взять 40% можно через array_slice.

> Analyst::$rate = 1100;


Этим ты меняешь ставку во всех копиях компании, а надо только в одной

В общем, код надо рефакторить.
622 741856
>>41852

1) есть недоделанный урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
2) есть туториал в php мануале
3) есть задача на студентов

Ты конечно можешь почитать книгу, но потом посмори задачу на студентов и увидишь насколько в той книге все отсталое.
597 Кб, webm,
640x360
623 741859
>>41856
Спасибо, я опять пропустил этот урок среди прочих паст...
Ответы 3-4 мая 624 741895
>>33360

О, понадеемся что удача выразится в том что ты сможешь решить все задачи.

>>33712

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

>>33728

> Разбивать не explode(), а регулярками? Но в таком случае удобнее воспользоваться parse_url(). Не понял.


Не разбивать, а анализировать. Вроде того:

если URL соответствует шаблону /news/\d+ то ...
если URL соответствует шаблону /news/by-year/\d+ то ...

Обычно конечно это не пишут руками, а используют конфиг где описываются шаблоны путей. А роутер читает этот конфиг и проверяет УРЛ на соответсвие шаблонам.

> Конструкции на пикрелейтед допустимы?


да

> Почему DataMapper, а не, к примеру, наследование модели Student от класса Model, которая соединяется с БД


это называется active record, недостаток в том что в одном классе смешивается 2 задачи: хранение информации о студенте и работа с БД. Ну и как следствие студент не может существовать без БД что нелогично.

>>33885

Вроде из задач там ничего особо не добавилось, добавилась только теория.
Ответы 3-4 мая 624 741895
>>33360

О, понадеемся что удача выразится в том что ты сможешь решить все задачи.

>>33712

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

>>33728

> Разбивать не explode(), а регулярками? Но в таком случае удобнее воспользоваться parse_url(). Не понял.


Не разбивать, а анализировать. Вроде того:

если URL соответствует шаблону /news/\d+ то ...
если URL соответствует шаблону /news/by-year/\d+ то ...

Обычно конечно это не пишут руками, а используют конфиг где описываются шаблоны путей. А роутер читает этот конфиг и проверяет УРЛ на соответсвие шаблонам.

> Конструкции на пикрелейтед допустимы?


да

> Почему DataMapper, а не, к примеру, наследование модели Student от класса Model, которая соединяется с БД


это называется active record, недостаток в том что в одном классе смешивается 2 задачи: хранение информации о студенте и работа с БД. Ну и как следствие студент не может существовать без БД что нелогично.

>>33885

Вроде из задач там ничего особо не добавилось, добавилась только теория.
Ответы 4-5 мая 625 741896
>>34308

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

>>35032

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

>>35210

копать в сторону фасетного поиска. В сфинксе есть что-то для этого, в Elastic Search есть.

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

>>35262

Вообще, мне кажется, если товар закончился, а в фильтре пункт остался - это не так и страшно.

>>35297

Нет, не легко если там сотни тысяч товаров.
626 741909
>>41855
Огромнейшее спасибо за такой развёрнутый ответ! Завтра буду исправлять
627 741926
>>41896

>Вообще, мне кажется, если товар закончился, а в фильтре пункт остался - это не так и страшно.


Страшно. Фильтр вываливает 1000 брэндов, пользователь начинает их по очереди тыкать, и везде вываливается - продуктов такого брэнда не найдено. Еще хуже, если комбинация из фильтров, например в каждом из 1000 брэндов может не быть одежды для девочек или маек красного цвета. Через 3-4 тычка пользователь уходит. Поэтому и нужны динамически обновляемые фильтры.
628 741930
>>41488
Так-с авторы самого сайта с разработчиками платформы не корелируют чуть мения чем никак, тем более, что курс то по SICP, что таки годнота.
629 741980
https://github.com/someApprentice/Students/

https://github.com/someApprentice/Students/blob/master/app/Model/Helper/RegistrationHelper.php
Я решил что не только ПомощникРегистрации должен заниматься ридеректом, и решил вынести функции редиректа в отдельный родительский класс https://github.com/someApprentice/Students/blob/master/app/Model/Helper/Helper.php
Теперь сам класс ПомощникаРегистрации стал совершенно не нужен, и ридеректом теперь занимается вовсе класс аутентификации https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php#L42
Не портит ли это модель?

https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Student.php#L113
https://github.com/someApprentice/Students/blob/master/app/Model/Entity/RegisterStudentForm.php#L34
https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php#L36
Не допустил ли я здесь ошибку с передачей авторайзера? Не должен ли он содержаться в классе студента изначально? И правильно ли я назвал эту переменную? Ведь авторизация, в отличие от аутентификации, отвечает за предоставление прав к данным, а не за вспомогательные функции к ней.

https://github.com/someApprentice/Students/blob/master/app/Model/Entity/LoginStudentForm.php#L9
https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Student.php#L20
https://github.com/someApprentice/Students/blob/master/app/Model/Entity/RegisterStudentForm.php#L18
Здесь присутствует копипаста метода. Будет ли лучше вынести этот метод в отдельный класс Entity (https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Entity.php), а переменную содержащую разрешенные поля ($allowed) вынести в отдельное свойство, и затем наследовать этот класс? Не портит ли вынесенное свойство $allowed сущность Студента?

>>38044

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


>Имя в принципе не уникально так как Иванов много. Не надо полагаться на это вот "маловероятно".


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

>>38044

>> А разве я не должен спросить у пользователя хочет ли он оставаться залогиненым?


>не знаю. Можешь спрашивать, я не против. Но и в этом случае сессия не нужна.


Сессиями больше не пользуются?

>>38044

>> $_SESSION['id'] = $student->getId();


>> $_SESSION['name'] = $student->getName();


>> $_SESSION['surname'] = $student->getSurname();


>> $_SESSION['token'] = $student->getToken();


>Зачем класть так много данных?


Если бы я пользовался куками, данные, такие как Имя, Фамилия, Возраст и так далее, тоже были бы лишними?

>>38044

>> $loginStudentForm->getError('login', "Incorrect username or password")


>Непонятно почему этот код внутри цикла. Ты хочешь несколько раз ошибку добавить?


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

https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L71
https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L77
https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L63

>>38044

>> Перефразирую вопрос: Что становится с кодом после ридеректа?


>Можно die можно return, так даже аккуратнее мне кажется.


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

>>38044

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


Тогда придется вызывать авторайзер, всё равно придётся что-то вызывать.

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


В консоли или через API обычно передают $_POST? Если да, то смогу - контроллер всегда вызывает валидатор если есть $_POST. Если нет, то мне придется переделывать контроллер чтобы он принимал в аргументы логин и пароль или еще что-то поменять. Ведь контролер же занимается пришедшими данными из вне?

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


Да, теперь я вижу чем этот метод отличается от обычных методов валидации. Просто было не понятно, ведь по сути этот метод отвечает за проверку, да и в контроллере вызывается как и класс авторизации так и класс валидатора.
629 741980
https://github.com/someApprentice/Students/

https://github.com/someApprentice/Students/blob/master/app/Model/Helper/RegistrationHelper.php
Я решил что не только ПомощникРегистрации должен заниматься ридеректом, и решил вынести функции редиректа в отдельный родительский класс https://github.com/someApprentice/Students/blob/master/app/Model/Helper/Helper.php
Теперь сам класс ПомощникаРегистрации стал совершенно не нужен, и ридеректом теперь занимается вовсе класс аутентификации https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php#L42
Не портит ли это модель?

https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Student.php#L113
https://github.com/someApprentice/Students/blob/master/app/Model/Entity/RegisterStudentForm.php#L34
https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php#L36
Не допустил ли я здесь ошибку с передачей авторайзера? Не должен ли он содержаться в классе студента изначально? И правильно ли я назвал эту переменную? Ведь авторизация, в отличие от аутентификации, отвечает за предоставление прав к данным, а не за вспомогательные функции к ней.

https://github.com/someApprentice/Students/blob/master/app/Model/Entity/LoginStudentForm.php#L9
https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Student.php#L20
https://github.com/someApprentice/Students/blob/master/app/Model/Entity/RegisterStudentForm.php#L18
Здесь присутствует копипаста метода. Будет ли лучше вынести этот метод в отдельный класс Entity (https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Entity.php), а переменную содержащую разрешенные поля ($allowed) вынести в отдельное свойство, и затем наследовать этот класс? Не портит ли вынесенное свойство $allowed сущность Студента?

>>38044

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


>Имя в принципе не уникально так как Иванов много. Не надо полагаться на это вот "маловероятно".


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

>>38044

>> А разве я не должен спросить у пользователя хочет ли он оставаться залогиненым?


>не знаю. Можешь спрашивать, я не против. Но и в этом случае сессия не нужна.


Сессиями больше не пользуются?

>>38044

>> $_SESSION['id'] = $student->getId();


>> $_SESSION['name'] = $student->getName();


>> $_SESSION['surname'] = $student->getSurname();


>> $_SESSION['token'] = $student->getToken();


>Зачем класть так много данных?


Если бы я пользовался куками, данные, такие как Имя, Фамилия, Возраст и так далее, тоже были бы лишними?

>>38044

>> $loginStudentForm->getError('login', "Incorrect username or password")


>Непонятно почему этот код внутри цикла. Ты хочешь несколько раз ошибку добавить?


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

https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L71
https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L77
https://github.com/someApprentice/Students/blob/master/app/Controller/LoginAction.php#L63

>>38044

>> Перефразирую вопрос: Что становится с кодом после ридеректа?


>Можно die можно return, так даже аккуратнее мне кажется.


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

>>38044

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


Тогда придется вызывать авторайзер, всё равно придётся что-то вызывать.

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


В консоли или через API обычно передают $_POST? Если да, то смогу - контроллер всегда вызывает валидатор если есть $_POST. Если нет, то мне придется переделывать контроллер чтобы он принимал в аргументы логин и пароль или еще что-то поменять. Ведь контролер же занимается пришедшими данными из вне?

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


Да, теперь я вижу чем этот метод отличается от обычных методов валидации. Просто было не понятно, ведь по сути этот метод отвечает за проверку, да и в контроллере вызывается как и класс авторизации так и класс валидатора.
630 742020
Нужно ли отделять результаты поиска студентов от таблицы со студентами на главной странице? Или нужно, чтобы найденных студентов тоже можно было сортировать? Просто я не знаю, как сделать второй случай без Query Builder. Получается в зависимости от GET параметров допустимы запросы вида getAll()->whereLike($search)->orderBy($column)->order($order)->get()
Или если без поиска getAll()->orderBy($column)->order($order)->get()

Маппер же не может делать такие запросы? А формировать голый SQL в контроллере не выход.
631 742023
И чтобы не юзать цепочные вызовы, можно ли в контроллере сделать так:
$mapper->build([
'search' => $search,
'orderBy' => $orderBy,
'order' => $order,
]);
35 Кб, 604x463
632 742159
>>41930

>чуть мения чем никак

633 742260
Помогите определить сущности: есть почтовая рассылка которая зависит от действий-бездействий юзера: я вижу
1. User. (пользователь и действия)
2. Mail (Почта)
3. Trigger (событие в ответ на действие User, использует Mail для отправки) тут не совсем уверен, может это больше к User относится
634 742406
>>42260
Фабрика для создания писем, письмо, юзер принимается на фабрику и там происходит магия. Отправление в контроллерах

Не плоди лишних, заебешься кодить
635 742443
А как подключить php скрипт к html файлу?
Хотя бы хеллоуворлд написать.
637 742527
Как получить данные по ссылке в PHP?
У меня есть одна ссылка, при переходе на которую мне открывается массив. Как его записать в переменную?
638 742530
>>42527
Ты плохо объяснил. Точнее опиши, что за ссылка и что за массив.
639 742537
>>42530
Я тот кун который насчет ВК АПИ пару дней назад спрашивал.
Там можно сгенерировать ссылку и получить по ней некоторые данные.

https://api.vk.com/method/groups.getById?group_id=22751485&fields=members_count

Вот например я хочу достать отсюда количество подписчиков паблика двача.
640 742542
>>42537
Тебе нужно декодировать json-ответ. Парсить ничего не нужно, есть готовые функции.
Вот пример: http://www.tutorialspoint.com/json/json_php_example.htm
641 742569
Такая беда: на хостинге ограничен объем памяти и таймаут короткий, как можно выгрузить пользователю огромный XLS из базы - и быстро и без превышений по памяти?
642 742770
>>42023
>>42020
На эти вопросы отвечать не нужно.
643 742788
Гайс, залейте, плез, кто нибудь решение к задаче "Числа прописью". Я не осилил, а посмотреть решение очень интересно
5 Кб, 792x149
644 742813
Аноны, еще понадоедаю с АПИ ВК немного.
Кто с ним работает, не знаете, сейчас обращения возможны только через приложение?
А то пытаюсь по ссылке, которую они в документации дают, обращаться.
Например то же.
https://api.vk.com/method/groups.getById?group_id=22751485&fields=members_count
В браузере вижу результат, но если попытаюсь использовать file_get_contents то пишет что failed to open stream: Connection refused in...
Или я рукожоп где-то ошибся в коде?
645 742819
>>42813
Насколько я знаю file_get_contents не работает с https. Тебе нужен CURL.

>Кто с ним работает, не знаете, сейчас обращения возможны только через приложение?


Есть список открытых и закрытых методов (закрытые - те которым нужен токен авторизации чтобы работать). Открытые методы это те которым такой токен не нужен, но это только основные, вроде запроса для получения основной информации о пользователе. Токен можно получить через OAuth, полный список методов можешь найти тут http://vk.com/dev/methods
Там же написано какие из них закрыте, какие открытые.
9 Кб, 720x75
646 742825
>>42813
Как видишь. Пример с количеством подписчиков в группе ru2ch.
647 742835
>>42825
А что я тут должен увидеть? Не понял ничего, если честно.
648 742837
>>42835
Запущен PHP в интерактивном режиме из консоли. Введена команда. Внизу нужный тебе результат - количество подписчиков группы.
107 Кб, 750x1000
649 742860
>>29430 (OP)
Братишки-php'шки. Помогите пожалуйста. Вот вопросик на stackoverflow, там не много кодика.
http://ru.stackoverflow.com/questions/523122

Вот вам няша
14 Кб, 311x363
650 742971
Закончил кусок приложения с прохождением теста.
Вроде было много вопросов, но уже ничего не помню, сплю до воскресенья.
https://github.com/nsdvw/TestHub
113 Кб, 1165x599
651 743187
Ну и какого члена оно пишет, что нет ключа, если он есть?

Один геморрой с этими миграциями. Мне всего лишь нужно изменить некоторые первичные ключи, с integer на bigint.
Но ведь это потянет за собой изменение всех внешних ключей. Значит я должен удалить внешний ключ, изменить первичный, после чего опять повесить внешний.
Проблема в том, что сразу не дал нормальные имена внешним ключам, а оно (doctrine migrations) сгенерировало какой-то хеш вместо имени, так еще и отказывается
принимать это имя, говорит нет такого ключа и все.
652 743221
>>43187

Не проще ли делать изменения через SQL запросы, а не через билдер?
653 743223
>>43187

Имя может быть чувствительно к регистру
654 743233
>>43221
Я же тебе говорил уже, билдер это абстракция, если уж мы используем доктрину, то везде нужно помнить, что базу может понадобиться сменить.
Диалекты ведь отличаются, я не могу захардкодить в классе миграции sql для конкретного диалекта.

>>40754

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


Так то ты генерировал наверное через doctrine:scheme:update.
Да, эта команда создает налету sql под текущий драйвер, указанный в конфиге.
Мы ведь уже говорим про миграции, файлы которые мне нужно хранить под системой контроля версий, они не должны быть завязаны на конкретную платформу.

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

>>43223
Попробовал удалить руками через консоль, говорит
Cannot drop index 'IDX_D87F7E0CA76ED395': needed in a foreign key constraint
Это на другой стороне тоже нужно что-то удалить?

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

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


На практике это малореалистично. Если ты хочешь сделать проект независимым от БД то тебе надо пользоваться минимальным подмножеством SQL которое поддерживается везде. Соответственно использовать например преимущества postgres не получится.

> Cannot drop index 'IDX_D87F7E0CA76ED395': needed in a foreign key constraint


Сначала надо удалить внешний ключ
656 743257
>>43233

Я не люблю билдеры так как сам SQL лаконичнее и выразительнее и не требует горы кавычек, скобок и стрелок.
657 743258
>>43233

Более того, в некоторых Бд нет LIMIT. Например в Oracle. Там вместо этого используется отбор по ROW_NUMBER() < ?.
658 743264
>>43233

Даже строковые функции или функции работы с датой разные в разных БД:

https://en.wikibooks.org/wiki/SQL_Dialects_Reference/Functions_and_expressions/String_functions
https://en.wikibooks.org/wiki/SQL_Dialects_Reference/Functions_and_expressions/Date_and_time_functions

Ты конечно можешь попробовать писать унивресальный код, но боюсь даже только для поддержки mysql + postgres уже уйдет много труда. И при этом ты не сможешь пользоваться разными оптимизациями, которые предлагают эти БД.
659 743295
>>43264

>уйдет много труда


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

Тогда буду писать миграции на sql. Тем более что есть инструмент doctrine:migrations:diff, который автоматически их генерирует из аннотаций, может чуть-чуть руками только подправить.
Тогда вопрос, что делать с теми миграциями что уже есть, где билдер? А ладно, пусть остаются, вроде никому не мешают.

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

В общем, первые впечатления от симфони: долго запрягаешь - быстро едешь. То есть нужно потратить уйму времени, чтобы разобраться в тонкостях, но уж если разберешься, получаешь йоба-инструмент, который делает разработку супер-быстрой и гибкой.
Например вчера 2 часа долбился, как сделать кастомный шаблон вместо того, что генерируют стандартные функции для форм. Такой код
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
генерирует label перед input, а мне нужно, чтобы input был вложен.
Сидел вардампил объект view, перечитал кучу ответов на stackoverflow, научился переопределять стандартные "темы" симфони.
Потом оказалось, что начиная с 2.8 (или 2.6?) в комплекте идет тема под бутстрап.
Так что моя проблема, над которой долбился 2 часа, решалась 2 строчками в конфиге
twig:
form_themes:
- 'bootstrap_3_layout.html.twig'

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

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

>уйдет много труда


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

Тогда буду писать миграции на sql. Тем более что есть инструмент doctrine:migrations:diff, который автоматически их генерирует из аннотаций, может чуть-чуть руками только подправить.
Тогда вопрос, что делать с теми миграциями что уже есть, где билдер? А ладно, пусть остаются, вроде никому не мешают.

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

В общем, первые впечатления от симфони: долго запрягаешь - быстро едешь. То есть нужно потратить уйму времени, чтобы разобраться в тонкостях, но уж если разберешься, получаешь йоба-инструмент, который делает разработку супер-быстрой и гибкой.
Например вчера 2 часа долбился, как сделать кастомный шаблон вместо того, что генерируют стандартные функции для форм. Такой код
{{ form_start(form) }}
{{ form_widget(form) }}
{{ form_end(form) }}
генерирует label перед input, а мне нужно, чтобы input был вложен.
Сидел вардампил объект view, перечитал кучу ответов на stackoverflow, научился переопределять стандартные "темы" симфони.
Потом оказалось, что начиная с 2.8 (или 2.6?) в комплекте идет тема под бутстрап.
Так что моя проблема, над которой долбился 2 часа, решалась 2 строчками в конфиге
twig:
form_themes:
- 'bootstrap_3_layout.html.twig'

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

Ну ладно, не буду отвлекать, в принципе я уже дошел до той стадии, когда могу найти сам все ответы в доках/гугле/исходном коде.
Проверяй как будет время, я пока отдыхаю, подумаю как сделать ту странную форму создания новых тестов/вопросов/вариантов/тегов, завтра попробую успеть запилить.
1,1 Мб, 1600x900
660 743671
Задачка ОПа: l33tspeak
http://archive-ipq-co.narod.ru/l1/strings.html
http://codepad.org/5XEkSKHI

Что там доделывать?
661 743698
>>43671
оп его знает

Может дополнить список кодов для замены, чтобы заменяло все буквы
http://lurkmore.to/_/2368#mws_PnElI97
может сделать обратный перевод.
662 743761
>>43671
Да, сделай обратный перевод. Разумеется, не трогая массив и не добавляя второго.
682 Кб, webm,
854x480
663 743811
Не могу запустить MySQL из командной строки.
Пишет или "Отказано в доступе", или "Не является внутренней или внешней командой, исполняемой программой или установленным файлом".
У меня вообще в папке с MySQL нет никакого bin - что я сделал не так? Как просто взять и запустить в Windows 8 MySQL?

>shell> mysql -h host -u user -p


Вообще не предлагает ввести пароль, а сразу пишет "Отказано в доступе".
shell> mysql -h host -u user -p хххх - то же самое.
ЧТО Я ДЕЛАЮ НЕ ТАК??7
664 743818
>>43811

>-h host


Попробуй вот это убрать
8 Кб, 674x342
665 743821
>>43818
Нет, ничего не выходит.
Я вообще правильно набираю команду?
От администратора делаю - вот этот результат.
А не от администратора было "Отказано в доступе".
666 743828
>>43821
Гугли переменные среды.
667 743831
>>43828
И что это даст - поможет узнать путь до bin?
Или что?
Загадка.
668 743834
>>43828
Ну вот путь до mysql.exe - на скриншоте.
Пытаюсь прописать его - нет, бесполезно сие занятие.
Я в тупике, короче.
Как всё было понятно с селекторами и прочим в книжке, а запустить сам Мускул не могу, вот лалка, сам себя затроллел.
14 Кб, 673x347
669 743836
Вот вроде бы удалось запустить.
Короче, просто нажимаешь Shift на папке bin, выбираешь "Открыть окно команд", там уже будет прописан верный путь до содержимого папки. Дописываешь "mysql.exe -u root -p", а дальше вводишь пароль.
Вроде получилось, но не знаю, как пойдёт дальше.
Буду держать всех в курсе и дальше, это очень важно.
670 743842
>>43821

shell> писать не надо, это подсказка которая выводится

Писать надо начиная с mysql

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

Возможно что у тебя клиент mysql будет не в одной из папок в PATH. В этом случае надо будет писать полный путь, например c:\mysql\bin\mysql.exe либо добавить нужную папку в PATH.

>>43834

Если ты пишешь полный путь то его надо начинать с буквы диска, то есть "c:\Program Files"

У тебя относительный путь, который отсчитывается от текущей папки (она написана в приглашении)
671 743847
>>43842

>В этом случае надо будет писать полный путь, например c:\mysql\bin\mysql.exe


>Если ты пишешь полный путь то его надо начинать с буквы диска, то есть "c:\Program Files"


А как его можно поменять, если по дефолту у меня там было с WINDOWS\system32 и подобное?
Ну вот щелчок ПКМ по папке bin и "Открыть окно команд" помогли запустить командную строку с уже прописанным путём, а дальше всё сработало.
Сейчас играюсь с селекторами и прочим, создаю индексы, красота.
Спасибо за помощь!
672 743857
>>43847

> А как его можно поменять,


Почитай урок по командной строке - есть команда cd. Также, можно создаять ярлык указывающий на cmd.exe где указана в качестве текущей нужная папка. Но удобнее добавить папку с mysql в PATH.
673 743858
>>43857
Спасибо!
674 743876
>>29430 (OP)
Мужчины, а сильно ли ударит по производительности, если создавать новые таблицы - тысячами в день а потом когда они не нужны - удалять их ?
someApprentice 675 743889
https://github.com/codedokode/pasta/blob/master/student-list.md#Работа-с-формами

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


Как не множить сущности, если в контроллере должны быть разные методы работы с БД?
676 743898
>>43889
Насколько я понял, нужно для форм регистрации и редактирования профиля общий код использовать.
https://github.com/fidnex/students/ 677 744032
>>36146

> https://github.com/fidnex/students/blob/master/config.ini


В конфиг стоит класть то, что может менять пользователь. тип БД (mysql) он вряд ли может поменять, его можно прописать и где-то в коде (тут вроде у же прописано: https://github.com/fidnex/students/blob/master/app/init.php - знаичт надо просто убрать это из конфига)

https://github.com/fidnex/students/blob/master/dump.sql
Тут стоит добавить уникальный ключ по значениям которые не должны повторяться (например email)

https://github.com/fidnex/students/blob/master/app/Controller/Main.php#L45

> $this->view->render('header');


> $this->view->render('main/index');


> $this->view->render('footer');


Тут лучше подключать только один шаблон, а хедер и футер подключать из него

https://github.com/fidnex/students/blob/master/app/Controller/Form.php#L35
Вместо длинной стены кода лучше наверно было сделать отдельный класс для этой формы и там все правила задать.

https://github.com/fidnex/students/blob/master/app/Lib/View.php#L9

> private function _output($str) {


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

https://github.com/fidnex/students/blob/master/app/Lib/Form.php#L5

> private $_currentItem = null;


не надо ставить подчеркивание. private и так показывает что оно приватное

В форме наверно лучше было бы разбить обработку формы на 2 этапа: подготовку формы и обработку и проверку данных POST. Тогда мы могли бы сделать отдельный класс ФормаРедактированияСтудента с уже настроенными правилами.

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

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

И еще мне не нравится что форма сама обращается к POST, было бы лучше если бы контроллер явно передавал этот массив например в submit.

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

> public function post($field) {


> public function val($method, $arg = null) {


имя функции должно начинаться с глагола

https://github.com/fidnex/students/blob/master/app/Lib/Form.php#L61
Тут нужна проверка что в модели есть такое поле - для защиты от опечаток

https://github.com/fidnex/students/blob/master/app/Lib/Form.php#L57
Плохо что функция возвращает либо массив либо объект. Лучше было сделать 2 разных функции.

https://github.com/fidnex/students/blob/master/app/Lib/Validation.php#L5
Зачем тут магический метод? PHP и так выдаст ошибку при обращении к несуществующему методу.

https://github.com/fidnex/students/blob/master/app/Lib/Form/ValStudent.php#L9

> public function __construct($helper) {


Нужен тайп хинт

> https://github.com/fidnex/students/blob/master/app/Lib/Form/ValStudent.php#L13


Лучше сделать название функции вроде validateMaxLength()

> if (strlen($data) > $length) {


Это считает не число символов, а число байт. Почитай урок https://gist.github.com/codedokode/ff99e357e9860ea169b8

https://github.com/fidnex/students/blob/master/app/Lib/Form/ValStudent.php#L33

> return 'Значение содержит недопустимые символы.';


Тут стоит предусмотреть возможность указать какие именно символы допустимые (в идеале еще и писать какой именно недопустим)

https://github.com/fidnex/students/blob/master/app/Helper/AuthHelper.php#L31

> $expire = intval(time() + 9460800000);


Это число лучше писать как 3600*24*356 - намного понятнее

Также, в AuthHelper логично бы добавить и метод разлогинивания.

https://github.com/fidnex/students/blob/master/app/Helper/TableHelper.php#L5

> public $page, $sortColumn, $sortType, $search;


Не стоит так оьбъявлять поля, лучше каждое по отдельности

https://github.com/fidnex/students/blob/master/app/Helper/TableHelper.php#L31
Не уверен что здесь стоит ставить htmlspecialchars так как это лучше делать в шаблоне и непонятно что делать если нам нужна неэкранированная ссылка.

https://github.com/fidnex/students/blob/master/app/Mapper/StudentTDG.php#L99
Тут надо проверять значения подставляемых переменных $sortColumn $sortTypeпо белому списку, а то получается SQL инъекция

https://github.com/fidnex/students/blob/master/app/View/footer.php#L2
Из-за того что ты ставишь CSS в конец, возможно такое, что при медленной загрузке браузер сначала отобразит страницу без стилей, а только потом применит стили. Я знаю, что некоторые советуют ставить статические файлы в конец, но на мой взгляд тут есть плюсы и минусы и стили в конец точно ставить не стоит.

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

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

https://github.com/fidnex/students/blob/master/app/View/form/index.php#L2

> <?php if(isset($this->errors['name'])) echo 'has-error';?>


не применяй echo в шаблонах. Тут лучше использовать <?= isset(...) ? ' has-error' : '' ?>

> ->val('regexp', '/[a-zа-яё0-9\-\'\"]/i')


Ты не используешь флаг u в регулярке, она будет работать некорретно с кириллицей

> ->val('regexp', '/.@./')


Тут должны стоять не зведочки, а плюсы

https://github.com/fidnex/students/blob/master/app/View/main/index.php#L13
Тут наверно не требуется крестик

https://github.com/fidnex/students/blob/master/app/Config.php
Я бы вынес загрузку конфига из файла в отдельный метод, а то у тебя нельзя создать конфиг без файла. Было бы чуть универсальнее.

https://github.com/fidnex/students/blob/master/app/Config.php#L25
В сообщении об ошибке стоит указывать название параметра.

Так, в общем, неплохо.
https://github.com/fidnex/students/ 677 744032
>>36146

> https://github.com/fidnex/students/blob/master/config.ini


В конфиг стоит класть то, что может менять пользователь. тип БД (mysql) он вряд ли может поменять, его можно прописать и где-то в коде (тут вроде у же прописано: https://github.com/fidnex/students/blob/master/app/init.php - знаичт надо просто убрать это из конфига)

https://github.com/fidnex/students/blob/master/dump.sql
Тут стоит добавить уникальный ключ по значениям которые не должны повторяться (например email)

https://github.com/fidnex/students/blob/master/app/Controller/Main.php#L45

> $this->view->render('header');


> $this->view->render('main/index');


> $this->view->render('footer');


Тут лучше подключать только один шаблон, а хедер и футер подключать из него

https://github.com/fidnex/students/blob/master/app/Controller/Form.php#L35
Вместо длинной стены кода лучше наверно было сделать отдельный класс для этой формы и там все правила задать.

https://github.com/fidnex/students/blob/master/app/Lib/View.php#L9

> private function _output($str) {


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

https://github.com/fidnex/students/blob/master/app/Lib/Form.php#L5

> private $_currentItem = null;


не надо ставить подчеркивание. private и так показывает что оно приватное

В форме наверно лучше было бы разбить обработку формы на 2 этапа: подготовку формы и обработку и проверку данных POST. Тогда мы могли бы сделать отдельный класс ФормаРедактированияСтудента с уже настроенными правилами.

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

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

И еще мне не нравится что форма сама обращается к POST, было бы лучше если бы контроллер явно передавал этот массив например в submit.

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

> public function post($field) {


> public function val($method, $arg = null) {


имя функции должно начинаться с глагола

https://github.com/fidnex/students/blob/master/app/Lib/Form.php#L61
Тут нужна проверка что в модели есть такое поле - для защиты от опечаток

https://github.com/fidnex/students/blob/master/app/Lib/Form.php#L57
Плохо что функция возвращает либо массив либо объект. Лучше было сделать 2 разных функции.

https://github.com/fidnex/students/blob/master/app/Lib/Validation.php#L5
Зачем тут магический метод? PHP и так выдаст ошибку при обращении к несуществующему методу.

https://github.com/fidnex/students/blob/master/app/Lib/Form/ValStudent.php#L9

> public function __construct($helper) {


Нужен тайп хинт

> https://github.com/fidnex/students/blob/master/app/Lib/Form/ValStudent.php#L13


Лучше сделать название функции вроде validateMaxLength()

> if (strlen($data) > $length) {


Это считает не число символов, а число байт. Почитай урок https://gist.github.com/codedokode/ff99e357e9860ea169b8

https://github.com/fidnex/students/blob/master/app/Lib/Form/ValStudent.php#L33

> return 'Значение содержит недопустимые символы.';


Тут стоит предусмотреть возможность указать какие именно символы допустимые (в идеале еще и писать какой именно недопустим)

https://github.com/fidnex/students/blob/master/app/Helper/AuthHelper.php#L31

> $expire = intval(time() + 9460800000);


Это число лучше писать как 3600*24*356 - намного понятнее

Также, в AuthHelper логично бы добавить и метод разлогинивания.

https://github.com/fidnex/students/blob/master/app/Helper/TableHelper.php#L5

> public $page, $sortColumn, $sortType, $search;


Не стоит так оьбъявлять поля, лучше каждое по отдельности

https://github.com/fidnex/students/blob/master/app/Helper/TableHelper.php#L31
Не уверен что здесь стоит ставить htmlspecialchars так как это лучше делать в шаблоне и непонятно что делать если нам нужна неэкранированная ссылка.

https://github.com/fidnex/students/blob/master/app/Mapper/StudentTDG.php#L99
Тут надо проверять значения подставляемых переменных $sortColumn $sortTypeпо белому списку, а то получается SQL инъекция

https://github.com/fidnex/students/blob/master/app/View/footer.php#L2
Из-за того что ты ставишь CSS в конец, возможно такое, что при медленной загрузке браузер сначала отобразит страницу без стилей, а только потом применит стили. Я знаю, что некоторые советуют ставить статические файлы в конец, но на мой взгляд тут есть плюсы и минусы и стили в конец точно ставить не стоит.

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

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

https://github.com/fidnex/students/blob/master/app/View/form/index.php#L2

> <?php if(isset($this->errors['name'])) echo 'has-error';?>


не применяй echo в шаблонах. Тут лучше использовать <?= isset(...) ? ' has-error' : '' ?>

> ->val('regexp', '/[a-zа-яё0-9\-\'\"]/i')


Ты не используешь флаг u в регулярке, она будет работать некорретно с кириллицей

> ->val('regexp', '/.@./')


Тут должны стоять не зведочки, а плюсы

https://github.com/fidnex/students/blob/master/app/View/main/index.php#L13
Тут наверно не требуется крестик

https://github.com/fidnex/students/blob/master/app/Config.php
Я бы вынес загрузку конфига из файла в отдельный метод, а то у тебя нельзя создать конфиг без файла. Было бы чуть универсальнее.

https://github.com/fidnex/students/blob/master/app/Config.php#L25
В сообщении об ошибке стоит указывать название параметра.

Так, в общем, неплохо.
60 Кб, 527x558
678 744230
>>44032
Спасибо.

>Тут лучше подключать только один шаблон, а хедер и футер подключать из него


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

>В форме наверно лучше было бы разбить обработку формы на 2 этапа: подготовку формы и обработку и проверку данных POST. Тогда мы могли бы сделать отдельный класс ФормаРедактированияСтудента с уже настроенными правилами.


А если добавлю метод валидации другим классом? Отдам ему данные с формы и получу от него ошибки. На пике накидал пример.

>Тут надо проверять значения подставляемых переменных $sortColumn $sortTypeпо белому списку, а то получается SQL инъекция


Они проверяются в TableHelper и только после этого передаются в модель. Но да, логичней там держать.
679 744231
>>44230

>->sumbit($_GET)


Лишнее.
Сумма прописью, Калькулятор 680 744246
ОП, проверь задачи, пожалуйста

Сумма прописью - http://ideone.com/HphHsa
Калькулятор - http://ideone.com/XjzcED
681 744338
>>43876
Скорее да, чем нет, а зачем, если не секрет, так делать?
682 744357
Задачка на Grammar Nazi http://ideone.com/2AWXeS

ОП проверь!
683 744418
>>44357
http://ideone.com/nO4ZHk - если в начале текста, то не захватывает ошибки.
В регулярке точка и количество символов не вполне годится для захвата текста вокруг ошибки.
684 744436
>>44338
Ну вот например если взять эту борду. Каждый тредик, это по факту новая таблица ? А в телеграмме ? Каждый чат рум, это тоже новая таблица ?
685 744443
>>44436
Это скорее запись в таблице
TestHub 686 744455

>Можно возвращаться к предыдущим вопросам. Можно не отвечать на вопрос.



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

Вы ответили не на все вопросы (пропущено {{ attempt.skippedCount }}).
У вас еще есть время ответить на них (осталось {{ attempt.timeLeft }}).
Ответить на пропущенные вопросы или завершить тест?
Кнопки "вернуться" и "завершить".

Тогда куда должна вести ссылка "вернуться"? На тот же url что и обычные вопросы? (/test/{testId}/question)
Но как тогда узнать, что это "повторное" прохождение? Ведь у "первого прохождения" другая логика выдергивания вопросов из базы (ищет в таблице ответов последний ответ к данному тесту и выдает следующий).
Передать гет-переменную и в зависимости от нее лепить ветку условий? Там и так уже бардак, не хочется.
Может сделать отдельный экшен /test/{testId}/review?
687 744513
>>44436

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

Вообще, "вернуться" имелось в виду именно вернуться назад на 1 вопрос. Но есть и другие варианты навигации - например один анон делал список номеров - как тут https://ege.yandex.ru/mathematics/1/ при клике на "1 из 20".

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


А зачем узнавать? У тебя где-то (в БД или во временном хранилище) хранится список данных ответов. Пользователь переходит например на 5-й вопрос. Ты смотришь - если он на него отвечал, то помечаешь выбранный им ранее вариант.

Если ты используешь GET то можно сделать для перехода URL вида /test/:tid/question/:qid, если форму с POST то можно передавать номер вопроса для перехода скрытым полем (а если он не передан, переходить на следующий), также есть еще вариант вообще загрузить все вопросы на клиент и переключать яваскриптом (то есть у нас как бы форма из 100 вопросов из которых виден только один).

Вообще, ссылка тут не очень годится. Она ведь не сохранит выбранный ранее ответ (если только ты как-то не используешь JS). Если тебе нужен вариант без JS то надо использовать форму, чтобы на сервер передался ответ на текущий вопрос. Например, при клике "назад" либо заполняется скрытое поле либо сервер определяет факт перехода по имени кнопки.

если используешь JS то конечно возможны варианты, сделать большую форму и показывать по частям либо хранить введенные ответы в переменной.
689 744527
>>44522

> (ищет в таблице ответов последний ответ к данному тесту и выдает следующий).


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

>Не разбивать, а анализировать. Вроде того:


>если URL соответствует шаблону /news/\d+ то ...


>если URL соответствует шаблону /news/by-year/\d+ то ...



ОП, попробовал реализовать примитивный роутер на регулярках. Ньюфаг ньюфагом, буду очень признателен за ревью: https://github.com/applejacky/tmp
691 744716
>>44677

- в роутере жестко прописано что URL надо брать из SERVER. Это нелогично. Нарушается принцип разделения обяхзанностей - это не задача роутера определять откуда брать URL

- чтобы метод getController() что-нибудь вернул, надо сначала вызвать другой метод. Как об этом догадаться? По моему это намеренное запутывание пользователя. должно быть проще: на вход даем URL (или Request), на выходе получаем нужные параметры в массиве или объекте.

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

> $controllerAction = explode(' ', $routeMapValue)[1];


Что такое 1? Что за странный формат хранения информации об URL? Лучше наверно хранить их в распакованном виде, например в виде объектов или массива. Так, вообще, понять формат сложно, глядя на код.

> [a-zA-Z0-9]


Очень ограниченный набор символов

> :num


Других плейсхолдеров нет?

> $controllerAction = explode(' ', $methodControllerAction)[1];


Что если второго элемента нет? И кстати, формат записи по моему неудобный. Удобнее было бы так:

GET /url Controller@ACtion
GET+POST /url Controller@Action

или как-то так.

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

if (preg_match(...)) { ... }
if (preg_match(...)) { ... }

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

http://symfony.com/doc/current/components/routing/introduction.html
https://github.com/symfony/routing
691 744716
>>44677

- в роутере жестко прописано что URL надо брать из SERVER. Это нелогично. Нарушается принцип разделения обяхзанностей - это не задача роутера определять откуда брать URL

- чтобы метод getController() что-нибудь вернул, надо сначала вызвать другой метод. Как об этом догадаться? По моему это намеренное запутывание пользователя. должно быть проще: на вход даем URL (или Request), на выходе получаем нужные параметры в массиве или объекте.

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

> $controllerAction = explode(' ', $routeMapValue)[1];


Что такое 1? Что за странный формат хранения информации об URL? Лучше наверно хранить их в распакованном виде, например в виде объектов или массива. Так, вообще, понять формат сложно, глядя на код.

> [a-zA-Z0-9]


Очень ограниченный набор символов

> :num


Других плейсхолдеров нет?

> $controllerAction = explode(' ', $methodControllerAction)[1];


Что если второго элемента нет? И кстати, формат записи по моему неудобный. Удобнее было бы так:

GET /url Controller@ACtion
GET+POST /url Controller@Action

или как-то так.

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

if (preg_match(...)) { ... }
if (preg_match(...)) { ... }

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

http://symfony.com/doc/current/components/routing/introduction.html
https://github.com/symfony/routing
692 744717
>>44677
Зачем у тебя там call_user_func_array, если число аргументов известно. Он не для этого - читай Зандстру в шапке.
Пустой конструктор - не нужен.
setControllerAction - у тебя от порядка вызова методов зависит использование класса. Что, если клиент забудет вызвать этот метод? Роутер не сработает, так, как ждет клиент. Класс сам себя должен настраивать через конструктор, а не завивесть от порядка вызываемых методов.
die в методах класса - плохо, exception юзай
Docblocks - почему не на всех функциях и не соответствуют содержимому? @throws RouterException нет, там у тебя die, @return на возвращающих значение функциях не указан.
parseRequest() - работает напрямую с $_REQUEST, это не задача роутера. Передавай запрос через dependency injection, лучше даже отдельным классом, который реализует публичный интерфейс.
private $requestPath = ''; - зачем ты инициируешь переменные в пустую строку? Чтобы код лишний раз засорить?
Двойной вызов функции:
if ($this->getRouteMapValues()) {
$routeMapValues = $this->getRouteMapValues();
Можно одним заменить, зачем 2 раза один и тот же код выполнять?
setControllerAction - сбивающее с толку имя метода, неясно сразу что делает. Может ты setControllerAndAction имел в виду? Так и пиши тогда.
22 Кб, 353x274
693 744720
>>44443
>>44513
Хмммм, ну если представить таблицу классического вида, то куда заносятся записи (посты )? Горизонтально в ячейки, что-ли ? А каждый тред это новая строка :?
Вы правы, действительно плохо понимаю ...
694 744723
>>44720
Запись - строка в таблице posts, треды - строка в таблице threads. Дальше делается соответствие между этими таблицами по primary key, чтобы можно было найти к какому треду какой пост относится. Чтобы вывести весь тред - ищешь в таблице threads этот тред, выводишь что есть, ищешь посты в таблице posts по ключу треда из найденного в threads, выводишь.
695 744729
>>44720
То есть все треды и посты находятся всего в двух таблицах ? Но ведь тогда эти таблицы просто огроменные.
А как тогда хранятся беседы в телеграмме ? Это же огромное к-во связей нужно проводить. Так и запутаться просто. А вот если отдельная таблица - это отдельный тред/беседа, то как-то и разобраться в них проще. Или я опять ошибаюсь ?
696 744732
>>44729
Ну типу, я мыслю таким образом, что яблоки в ящике с надписью "яблоки", а груши в ящике "груши" - лучше, чем один огромный ящик с надписью"фрукты".
697 744733
>>44729
Базы данных для этого и есть, чтобы огроменные таблицы держать. Таблицы запросто могут быть по нескольку гигабайт и состоять из нескольких миллионов строк. Каждая строка и будет постом. Чтобы быстро искать по такому количеству строк, в таблице существуют индексы. Это просто сортированные значения ключей. По сортированному можно быстро искать, так же как ты можешь легко искать записи в записной книжке по названию буквы.

>А вот если отдельная таблица - это отдельный тред/беседа, то как-то и разобраться в них проще.


Так тоже можно делать, но у тебя будут сложнее запросы и скорость меньше. Например ты захотел добавить в каждый пост в каждом треде что-то, или провести поиск по постам во всех тредах. Если у тебя гора таблиц, тебе придется обходить по очереди каждую, а это отдельный запрос на каждую таблицу, в то время как если у тебя все посты в одной таблице, ты просто проходишься быстро по всем строкам и смотришь/меняешь значения в полях.
698 744735
699 744736
>>44733
Спасибо. Вот теперь понял. Доступно объяснил.
700 744740
>>44723
На самом деле треды это тоже посты (оп-посты), а все остальные посты треда - комментарии к оп-посту.
https://2ch.hk/pr/res/729430.json (М)
Так что и "треды" (оп-посты) и комментарии к ним хранятся в одной таблице.
Оп-посты выделяются отдельной колонкой (parent=0), у остальных постов в parent ссылка на оп-пост. Номер оп-поста считается номером треда.

У опа кстати где-то есть задача на проектирование бд для сосача и написание запроса типа
"выбрать первые 10 тредов (оп-постов) + по три последних комментария к ним", как на главной.
701 744741
>>44729
Представил как SHOW TABLES выводит 168546 таблиц с тредами и проиграл.
702 744743
>>44741
Они же быстро тонут (удаляются).
Хотя конечно создавать новую таблицу на тред это глупость.
703 744746
>>44741
А теперь представь длину запроса с JOINами всех таблиц, чтобы что-то найти в этих тредах.
704 744757
>>44717

> Передавай запрос через dependency injection, лучше даже отдельным классом, который реализует публичный интерфейс.


запрос это не dependency а аргумент функции parse. Так как мы можем захотеть разроутить несколько разных запросов.

> @throws RouterException нет


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

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


Почему нет? Чтобы в ней всегда было знаечние строкового типа.

>>44720

В ОП посте есть задачи по mysql, там есть ссылка на туториал "SQL для начинающих" - изучай.

>>44733

С горой таблиц вообще невозможно работать. Попробуй выведи последние N постов или тредов с доски например.

>>44729

Принципы проектирования баз данных давно изучены. Гугли "нормализация баз данных" - там есть статьи, написанные простым языком, которые объясняют как правильно проектирвоать БД. И читай наши задачи на mysql.
Ответы 6-7 мая 705 744759
>>36701

> Задачка на проверку: https://ideone.com/7gHlP7


> "/шы/ui" => "ши",


> "/жы/ui" => "жи",


Можно объединить в одно правило за счет скобок и $1

> "/[,;!?:](?!\s)/ui" => "пропущен пробел",


правило сработает, если в самом конце строки точка и за ней ничего нет: https://ideone.com/S6XfDG

> "/[^,](\sно\b|\sа\b)/ui" => "пропущена запятая"


сработает на Но в начале предложения: https://ideone.com/S6XfDG

Также, не обнаруживает отстувие пробела после точки: https://ideone.com/BxS1eW

> Задачка на исправление: https://ideone.com/6TJwXr


> "/шы/ui" => "ши",


> "/жы/ui" => "жи",


Можно объединить

Не видит отстутвие пробела после точки, добавляет лишнюю запятую: https://ideone.com/pykbgl

>>36833

Ты ищешь все латинские буквы. Но надо искать слова, содержащие буквы разных алфавитов. Чтобы он на слово "hello" не реагировал.

>>36950

Наверно, не знаю.
Ответы 6-7 мая 705 744759
>>36701

> Задачка на проверку: https://ideone.com/7gHlP7


> "/шы/ui" => "ши",


> "/жы/ui" => "жи",


Можно объединить в одно правило за счет скобок и $1

> "/[,;!?:](?!\s)/ui" => "пропущен пробел",


правило сработает, если в самом конце строки точка и за ней ничего нет: https://ideone.com/S6XfDG

> "/[^,](\sно\b|\sа\b)/ui" => "пропущена запятая"


сработает на Но в начале предложения: https://ideone.com/S6XfDG

Также, не обнаруживает отстувие пробела после точки: https://ideone.com/BxS1eW

> Задачка на исправление: https://ideone.com/6TJwXr


> "/шы/ui" => "ши",


> "/жы/ui" => "жи",


Можно объединить

Не видит отстутвие пробела после точки, добавляет лишнюю запятую: https://ideone.com/pykbgl

>>36833

Ты ищешь все латинские буквы. Но надо искать слова, содержащие буквы разных алфавитов. Чтобы он на слово "hello" не реагировал.

>>36950

Наверно, не знаю.
Ответы 7 мая, фасеты 706 744760
>>36975

Посмотри такие движки:

- sphinx
- elastic search
- apache lucene

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

Также, можно конечно попробовать вариант с велосипедом на кеш-таблицах (или ключах в редисе) и инкрементальным обновлением, но я вижу тут проблемы: 1) сложность реализации, легко допустить баг 2) данные будут постепенно расходиться с реальностью 3) может быть тяжело их обновлять при поступлении/расходе товара 4) может получиться что мы изобретаем то что уже есть в том же elastic search

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

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

Соответственно нужны ключи вида

цвет:красный -> X товаров
цвет:синий -> Y товаров
бренд:adidas -> Z товаров

Этот кеш позволит получать фасеты когда не выбрано ни 1 условие. Аналогично можно сделать кеш или таблицу для подсчета фасетов при выборе 1 условия. В ней придется перебрать все возможные сочетания 2 фильтров, и записей может получиться много:

цвет:красный,бренд:adidas -> X
цвет:синий,бренд:adidas -> Y
....

предыдущую таблицу можно объединить с этой, добавив NULL (или например 0) в качестве разрешенного значения второго фильтра:

цвет:синий,NULL -> X
цвет:красный,NULL -> Y

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

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

Ссылки в помощь:

- (англ) https://lucene.apache.org/core/4_0_0/facet/org/apache/lucene/facet/doc-files/userguide.html
- (англ) http://sphinxsearch.com/blog/2014/05/22/the-facet-feature/
- (англ) https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html

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

> Хорошая идея, но что делать, когда меняется stock для одного из товаров. Т.е. наличие товара добавляется или удаляется. Генерировать тут же все таблицы с кешами заново?


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

> про настройки БД возможно нет, до задачи с убиранием фильтров на все скорости хватало в пределах 1 секунды, что устраивало. Есть где про эти настройки руководство почитать?


Если вы используете InnoDB то надо чтобы памяти в innodb pool было не меньше чем размер всех используемых индексов, чтобы они все в нее помещались. Увидеть размер индексов можно командой SHOW TABLES STATUS по моему.

> Как я понял из твоих объяснений, из известных решений только кэш-таблицы и фасетный поиск? Или еще какие есть?


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

> Внешний select выбирает фильтры из полученной таблицы доступных продуктов по этим фильтрам. SELECT DISTINCT filters.filter_id FROM (select товары по фильтрам которые в наличии, плюс фильтры к ним через join filters_to_products)


Не нужны тут подзапросы. Если у тебя есть запрос выбирающий все товары попадающие под фильтры, то чтобы найти какие еще фильтры доступны, тебе надо сделать SELECT filetr_id, COUNT(DISTINCT product_id) ... GROUP BY filter_id то есть сгруппировать найденные записи по id фильтра и получим таблицу вида

filter_id | COUNT

Из которой уже можно определить какие еще фиьтры доступны и сколько в них товаров. Без подзапросов и за 1 проход по таблице.

Ну например у нас применено 2 фильтра (цвет=красный, бренд=adidas). Запрос на выборку товаров:

SELECT DISTINCT product_id
FROM products_present ...
JOIN product_filter pf1 ON ...
JOIN product_filter pf2 ON ...
WHERE pf1.filter_id = ? AND pf2.filter_id = ?
LIMIT ?

Либо как альтернатива с 1 джойном (наверно так даже быстрее будет)

SELECT product_id
FROM products_present ...
JOIN product_filter pf ON ...
GROUP BY product_id
HAVING SUM(pf.filter_id = ?) > 0 AND SUM(pf.filter_id = ?) > 0
LIMIT ?

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

SELECT pf3.filter_id, COUNT(DISTINCT product_id)
FROM products_present ...
JOIN product_filter pf1 ON ...
JOIN product_filter pf2 ON ...
JOIN product_filter pf3 ON ...
WHERE pf1.filter_id = ? AND pf2.filter_id = ?
GROUP BY pf3.filter_id

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

>>36999

> Думаю, не можем. Потому что может быть еще другой товар, тоже футболка красного цвета бренда адидас.


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

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


Нет, только если какой-то вид товара полностью вышел из продажи (то есть остаток на складе стал равен нулю), мы уменьшаем число видов на 1.

> Если всего 13 фильтров, кеш-таблицы мы видимо создавать будем только по 3-4 фильтрам.


Для 3-4 фильтров будет слишком много комбинаций наверно. Потому что число записей в таблице = число сочетаний фильтров, если 1000 фильтров то комбинаций из 3 фильтров будет миллиард.

>>37007

Нет, мы рассмтриваем все виды фильтров как однородный список, то есть фильтр по цвету и по бренду идет на одном уровне. Представь что фильтров нет, а есть просто теги у каждого товара вроде "цвет:красный", "бренд:adidas". Вроде у вас так уже и сделано.

Кеш-таблица будет одна.
Ответы 7 мая, фасеты 706 744760
>>36975

Посмотри такие движки:

- sphinx
- elastic search
- apache lucene

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

Также, можно конечно попробовать вариант с велосипедом на кеш-таблицах (или ключах в редисе) и инкрементальным обновлением, но я вижу тут проблемы: 1) сложность реализации, легко допустить баг 2) данные будут постепенно расходиться с реальностью 3) может быть тяжело их обновлять при поступлении/расходе товара 4) может получиться что мы изобретаем то что уже есть в том же elastic search

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

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

Соответственно нужны ключи вида

цвет:красный -> X товаров
цвет:синий -> Y товаров
бренд:adidas -> Z товаров

Этот кеш позволит получать фасеты когда не выбрано ни 1 условие. Аналогично можно сделать кеш или таблицу для подсчета фасетов при выборе 1 условия. В ней придется перебрать все возможные сочетания 2 фильтров, и записей может получиться много:

цвет:красный,бренд:adidas -> X
цвет:синий,бренд:adidas -> Y
....

предыдущую таблицу можно объединить с этой, добавив NULL (или например 0) в качестве разрешенного значения второго фильтра:

цвет:синий,NULL -> X
цвет:красный,NULL -> Y

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

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

Ссылки в помощь:

- (англ) https://lucene.apache.org/core/4_0_0/facet/org/apache/lucene/facet/doc-files/userguide.html
- (англ) http://sphinxsearch.com/blog/2014/05/22/the-facet-feature/
- (англ) https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html

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

> Хорошая идея, но что делать, когда меняется stock для одного из товаров. Т.е. наличие товара добавляется или удаляется. Генерировать тут же все таблицы с кешами заново?


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

> про настройки БД возможно нет, до задачи с убиранием фильтров на все скорости хватало в пределах 1 секунды, что устраивало. Есть где про эти настройки руководство почитать?


Если вы используете InnoDB то надо чтобы памяти в innodb pool было не меньше чем размер всех используемых индексов, чтобы они все в нее помещались. Увидеть размер индексов можно командой SHOW TABLES STATUS по моему.

> Как я понял из твоих объяснений, из известных решений только кэш-таблицы и фасетный поиск? Или еще какие есть?


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

> Внешний select выбирает фильтры из полученной таблицы доступных продуктов по этим фильтрам. SELECT DISTINCT filters.filter_id FROM (select товары по фильтрам которые в наличии, плюс фильтры к ним через join filters_to_products)


Не нужны тут подзапросы. Если у тебя есть запрос выбирающий все товары попадающие под фильтры, то чтобы найти какие еще фильтры доступны, тебе надо сделать SELECT filetr_id, COUNT(DISTINCT product_id) ... GROUP BY filter_id то есть сгруппировать найденные записи по id фильтра и получим таблицу вида

filter_id | COUNT

Из которой уже можно определить какие еще фиьтры доступны и сколько в них товаров. Без подзапросов и за 1 проход по таблице.

Ну например у нас применено 2 фильтра (цвет=красный, бренд=adidas). Запрос на выборку товаров:

SELECT DISTINCT product_id
FROM products_present ...
JOIN product_filter pf1 ON ...
JOIN product_filter pf2 ON ...
WHERE pf1.filter_id = ? AND pf2.filter_id = ?
LIMIT ?

Либо как альтернатива с 1 джойном (наверно так даже быстрее будет)

SELECT product_id
FROM products_present ...
JOIN product_filter pf ON ...
GROUP BY product_id
HAVING SUM(pf.filter_id = ?) > 0 AND SUM(pf.filter_id = ?) > 0
LIMIT ?

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

SELECT pf3.filter_id, COUNT(DISTINCT product_id)
FROM products_present ...
JOIN product_filter pf1 ON ...
JOIN product_filter pf2 ON ...
JOIN product_filter pf3 ON ...
WHERE pf1.filter_id = ? AND pf2.filter_id = ?
GROUP BY pf3.filter_id

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

>>36999

> Думаю, не можем. Потому что может быть еще другой товар, тоже футболка красного цвета бренда адидас.


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

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


Нет, только если какой-то вид товара полностью вышел из продажи (то есть остаток на складе стал равен нулю), мы уменьшаем число видов на 1.

> Если всего 13 фильтров, кеш-таблицы мы видимо создавать будем только по 3-4 фильтрам.


Для 3-4 фильтров будет слишком много комбинаций наверно. Потому что число записей в таблице = число сочетаний фильтров, если 1000 фильтров то комбинаций из 3 фильтров будет миллиард.

>>37007

Нет, мы рассмтриваем все виды фильтров как однородный список, то есть фильтр по цвету и по бренду идет на одном уровне. Представь что фильтров нет, а есть просто теги у каждого товара вроде "цвет:красный", "бренд:adidas". Вроде у вас так уже и сделано.

Кеш-таблица будет одна.
Ответы 7 мая 707 744762
>>37498

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

опечаточник не воспринимает английские слова: http://ideone.com/7fGiyC

>>37657

Тебя не проверяем пока? Ты ведь вроде не все еще исправил?

>>38055

Ставишь приложение в автозапуск под контролем какого-нибудь супервизора. можно написанного на той же самой ноде.

Без прав root поставить ноду нельзя, нужен VPS/VDS/свой сервер.

>>38059

> разбитие текста по символу переноса строки -> разбитие строки по пробелам


\s в регулярке соответствует тому и другому сразу

> проверка слова на специфичные символы свойственные языку (типа "qui или йцф"), если специфичных символов нет, то подсчет количества символов английского и русского алфавита, и в зависимости от того каких символов больше, в ту сторону и переводить через preg_replace с массивами схожих символов


Сложно. Проще просто искать сочетания вида

- латинская буква, за ней русская

и наоборот.

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

>>38132

Как минимум проблема в том, что ты хочешь чтобы перед урл обязательно шел пробел.
Ответы 7 мая 707 744762
>>37498

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

опечаточник не воспринимает английские слова: http://ideone.com/7fGiyC

>>37657

Тебя не проверяем пока? Ты ведь вроде не все еще исправил?

>>38055

Ставишь приложение в автозапуск под контролем какого-нибудь супервизора. можно написанного на той же самой ноде.

Без прав root поставить ноду нельзя, нужен VPS/VDS/свой сервер.

>>38059

> разбитие текста по символу переноса строки -> разбитие строки по пробелам


\s в регулярке соответствует тому и другому сразу

> проверка слова на специфичные символы свойственные языку (типа "qui или йцф"), если специфичных символов нет, то подсчет количества символов английского и русского алфавита, и в зависимости от того каких символов больше, в ту сторону и переводить через preg_replace с массивами схожих символов


Сложно. Проще просто искать сочетания вида

- латинская буква, за ней русская

и наоборот.

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

>>38132

Как минимум проблема в том, что ты хочешь чтобы перед урл обязательно шел пробел.
Ответы 9 мая 708 744764
>>38221

Не поможет тебе готовое решение. Чтобы понять ООП надо сначала решить задачи про Вектор и Кошки-Мышки из учебника. также, разобраться с mysql, внимательно прочесть примечания к задаче про студентов.

На готовый код можно смотреть только после того как ты сделаешь свой вариант решения. так как до этого ты много чего просто не поймешь.

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

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

>>38377

> Обёртка над session_start(). Проще не создавать.


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

> Сейчас маппер получает уже объект PDO вот так: new StudentMapper(Config::getPDOconnection);


> Так лучше? Это максимум, до чего я смог додуматься.


да, так и надо. Только вот мне кажется класс конфиг должен отвечать за хранение конфига, а не создаение объектов PDO. И он не должен использовать статические методы, и вообще статические методы это не ООП.

> Куда положить дефолтные controller и action? В методы setController и setAction?


Просто в переменную кукю-нибудь

> Этот метод проверяет наличие $_SESSION['email']. Что передавать в метод, который проверяет, залогинен ли пользователь?


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

Что-то у тебя плоховато с ООП. Ты Вектор или кошки-мышки решал? Статические методы это процедурный код, а не ООП.

> 1. Что должна представлять из себя обёртка над Location для редиректа? Часть класса, хелпер, как назвать, какие ещё функции можно туда добавить?


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

> 2. Статические классы. У меня статические - Validator, Auth (хелпер для регистрации/логина), Session, Config. Они ведь все работают только с какой-то одной сущностью, у которой не может быть несколько инстансов. Можно их статическими оставить?


Не вижу логики. Что мешает нам создать несколько разных объектов-конфигов? Что мешает создать несколько валидаторов? Сессий? То, что в твоем конкретном случае нужен только один конфиг, тут особого значения не играет.

Также, ты читал урок про DI? Исплоьзование статических классов не дает полноценно использовать DI (что делает код хуже, так как все классы статновятся спутаны друг с другом намертво) и возможности ООП. Тестировать классы по отдельности тоже становится невозможно. Их зависимости явно не обозначены в конструкторе. По моему так получается не ООП код, а лапша.

Статические методы используются очень редко: в тех случаях. когда у нас нет объекта как такового, либо когда метод общий для любого числа объектов и не исплоьзует $this. Ну например, метод, который переводит число байт в строку вроде "3 Мб" можно сделать статическим (паттерн utility class).

То что в твоей программе валидатор нужен только один значения не имеет. Это объект? Объект. Значит, надо делать нормальный объект с нормальными методами.

> У валидатора один публичный метод make, который принимает 2 массива (пик).


Валидатор в ООп логичнее сделать так: ты создаешь валидатор, задаешь правила, а потом проверяешь им данные. И кстати очень странно что ты проверяешь не модель, а массив. Чем тебе модель не нравится? Зачем для студента делать альтернативное представление в виде массива? Массив ведь хуже объекта.

>>38387

Сессия это надстройка над куками. Что мешает их использовать напрямую?

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

Недостатки сессий:

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

> Куки же менее безопасны, чем сессии.


Если в них хранить длинный токен то это вполне безопасно

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


В чем проявляется "опасность" кук? Напиши пример уязвимости в авторизации через куки? Помни при этом что сессия тоже использует куки для хранения идентификатора.
Ответы 9 мая 708 744764
>>38221

Не поможет тебе готовое решение. Чтобы понять ООП надо сначала решить задачи про Вектор и Кошки-Мышки из учебника. также, разобраться с mysql, внимательно прочесть примечания к задаче про студентов.

На готовый код можно смотреть только после того как ты сделаешь свой вариант решения. так как до этого ты много чего просто не поймешь.

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

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

>>38377

> Обёртка над session_start(). Проще не создавать.


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

> Сейчас маппер получает уже объект PDO вот так: new StudentMapper(Config::getPDOconnection);


> Так лучше? Это максимум, до чего я смог додуматься.


да, так и надо. Только вот мне кажется класс конфиг должен отвечать за хранение конфига, а не создаение объектов PDO. И он не должен использовать статические методы, и вообще статические методы это не ООП.

> Куда положить дефолтные controller и action? В методы setController и setAction?


Просто в переменную кукю-нибудь

> Этот метод проверяет наличие $_SESSION['email']. Что передавать в метод, который проверяет, залогинен ли пользователь?


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

Что-то у тебя плоховато с ООП. Ты Вектор или кошки-мышки решал? Статические методы это процедурный код, а не ООП.

> 1. Что должна представлять из себя обёртка над Location для редиректа? Часть класса, хелпер, как назвать, какие ещё функции можно туда добавить?


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

> 2. Статические классы. У меня статические - Validator, Auth (хелпер для регистрации/логина), Session, Config. Они ведь все работают только с какой-то одной сущностью, у которой не может быть несколько инстансов. Можно их статическими оставить?


Не вижу логики. Что мешает нам создать несколько разных объектов-конфигов? Что мешает создать несколько валидаторов? Сессий? То, что в твоем конкретном случае нужен только один конфиг, тут особого значения не играет.

Также, ты читал урок про DI? Исплоьзование статических классов не дает полноценно использовать DI (что делает код хуже, так как все классы статновятся спутаны друг с другом намертво) и возможности ООП. Тестировать классы по отдельности тоже становится невозможно. Их зависимости явно не обозначены в конструкторе. По моему так получается не ООП код, а лапша.

Статические методы используются очень редко: в тех случаях. когда у нас нет объекта как такового, либо когда метод общий для любого числа объектов и не исплоьзует $this. Ну например, метод, который переводит число байт в строку вроде "3 Мб" можно сделать статическим (паттерн utility class).

То что в твоей программе валидатор нужен только один значения не имеет. Это объект? Объект. Значит, надо делать нормальный объект с нормальными методами.

> У валидатора один публичный метод make, который принимает 2 массива (пик).


Валидатор в ООп логичнее сделать так: ты создаешь валидатор, задаешь правила, а потом проверяешь им данные. И кстати очень странно что ты проверяешь не модель, а массив. Чем тебе модель не нравится? Зачем для студента делать альтернативное представление в виде массива? Массив ведь хуже объекта.

>>38387

Сессия это надстройка над куками. Что мешает их использовать напрямую?

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

Недостатки сессий:

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

> Куки же менее безопасны, чем сессии.


Если в них хранить длинный токен то это вполне безопасно

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


В чем проявляется "опасность" кук? Напиши пример уязвимости в авторизации через куки? Помни при этом что сессия тоже использует куки для хранения идентификатора.
709 744818
Аноны, подскажите, что делать когда не знаешь как решить задачу? Если сидишь и тупишь над ней? Перечитать ещё раз теорию и тупить дальше, или наконец посмотреть чужой код, и попробовать написать самому?
710 744858
>>44741
Ну давай разберём по порядку всё тобой написанное.
Разделов на имиджборде где-то 100 (примерно).
В каждом разделе ну никак не больше 100 тредов (может, и намного меньше).
Итого имеем максимум 10 тысяч таблиц.
И это не так уж и много.
>>44746
Так поиска нет по всем разделам сразу, поиск и есть только конкретному разделу из 100 тредов (может, я чего упустил - давно не был на главной, несколько лет уже). А перечисление ста таблиц в запросе с JOINом - это нормально.
711 744859
>>44757

>С горой таблиц вообще невозможно работать. Попробуй выведи последние N постов или тредов с доски например.


А где такое на имиджбордах? Впервые слышу.
Мне кажется, это сильное усложнение функционала. Так и во многих задачах из твоего учебника, мне кажется, хотя это очень помогает разобраться во всём.
Есть треды, которые бампаются, есть простой поиск по сообщениям в разделе.
Всё остальное - от лукавого ОПа-перфекциониста.
712 744860
>>44818
Задавай конкретные вопросы, прикладывай своё решение - хотя бы начало.
Чужой код лучше смотри только у тех задач, которые уже сам решил.
205 Кб, 550x827
713 744943
Приветствую!

http://ideone.com/cWbnDg // Антикризисные меры

Много кода, я думал намного меньше будет
714 744951
>>44943

> public function getSalaryRate()


> {


> return $salaryRate = 1100;


Зачем тут переменная? return и = это 2 отдкльных команды которые стоит писать на отдельной строке, или же, что лучше, убрать переменную вообще.
715 744975
>>44951
Исправил
716 745043
Как мне подключить модуль на собранном пхп? Лезу в php.ini, там есть блок с закоментированными строками типа

>;extension=php_mbstring.dll


dll это вообще виндовое вроде, не? Как оно делается по человечески?
717 745047
Какие бывают приложения по уровню поддержки разработчиками? Сейчас объясню что имею ввиду.

Допустим, есть говносайтики на cms, которые раз в пару месяцев нужно обновить, поправить перекосившиеся после обновления костыли, может прикрутить какой-то новый костыль. У владельца говносайтика нет денег на то чтобы содержать своих кодеров, поэтому либо лезет изредка на фриланс биржу и поручает это задание местным васянам, либо дрессирует своих контент-манагеров, чтобы могли сами обновить/пофиксить cms. Или делает сам.
Уровень ответственности: хуяк-хуяк -> в продакшн.
Темпы разработки: должно быть готово вчера.
Командная работа: на нуле, все делает один индус (причем каждый раз новый)

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

Наконец есть крупные богатые сайты организаций, которые либо держат свой отдел, либо постоянно сотрудничают с хорошей конторой. Возможно контора ведет этот сайт с самого создания, возможно своя cms. Ну или легаси от другой хай-левел конторы.
Ответственность: экстремальная (к GN: какого писюна слово экстрим пишется через И, а экстремальная через Е?), есть код-ревью, непременные тесты. Много уровней в планировании и обсуждении (всякие scrum, agile).
Темпы: средние.
Команда: отлично налаженное взаимодействие.

Правильно представляю классификацию?
И как попасть именно в контору третьего типа, где есть шикарный карьерный рост?
Сколько ни смотрел вакансии, джунов ищут только первые и вторые. А как я стану мидлом, если буду работать в дно-конторе? Какой-то замкнутый круг.
inb4: решить все задачки опа про калькулятор и устраиваться в сеньором в гугл
717 745047
Какие бывают приложения по уровню поддержки разработчиками? Сейчас объясню что имею ввиду.

Допустим, есть говносайтики на cms, которые раз в пару месяцев нужно обновить, поправить перекосившиеся после обновления костыли, может прикрутить какой-то новый костыль. У владельца говносайтика нет денег на то чтобы содержать своих кодеров, поэтому либо лезет изредка на фриланс биржу и поручает это задание местным васянам, либо дрессирует своих контент-манагеров, чтобы могли сами обновить/пофиксить cms. Или делает сам.
Уровень ответственности: хуяк-хуяк -> в продакшн.
Темпы разработки: должно быть готово вчера.
Командная работа: на нуле, все делает один индус (причем каждый раз новый)

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

Наконец есть крупные богатые сайты организаций, которые либо держат свой отдел, либо постоянно сотрудничают с хорошей конторой. Возможно контора ведет этот сайт с самого создания, возможно своя cms. Ну или легаси от другой хай-левел конторы.
Ответственность: экстремальная (к GN: какого писюна слово экстрим пишется через И, а экстремальная через Е?), есть код-ревью, непременные тесты. Много уровней в планировании и обсуждении (всякие scrum, agile).
Темпы: средние.
Команда: отлично налаженное взаимодействие.

Правильно представляю классификацию?
И как попасть именно в контору третьего типа, где есть шикарный карьерный рост?
Сколько ни смотрел вакансии, джунов ищут только первые и вторые. А как я стану мидлом, если буду работать в дно-конторе? Какой-то замкнутый круг.
inb4: решить все задачки опа про калькулятор и устраиваться в сеньором в гугл
718 745057
>>45043
Разобрался. Все ставится через консольку, типа apt-get install php7.0-gd
719 745058
>>45043
Я апт-гетом ставил и не морочился.
>>45057
Про расширения не забудь
php-mysql например, и что там еще подадобится
720 745071
>>45047
Сперва клепаешь говносайты чтобы было на что жить, в свободное время учишь что-то ещё, в итоге опыт + знания дают возможность перебраться на уровень выше.
721 745139
йоу, бразы, какой дебагер используете? Используете ли вообще? Насколько он упрощает / уменьшает время на поиск и исправление ошибок в коде?
Дебагер нужно покупать отдельно? Во взрослом IDE есть встроенные, этого хватит?

На реддите советуют PHPStorm и Netbeans. У меня стоит Komodo, там вроде тоже есть, но что-то не работает.
170 Кб, 1261x700
722 745141
Меня уволили ;(
723 745145
>>45139
В PHPStorm нужно накофигурить xdebug, в принципе даже в саблайме это можно сделать.
724 745148
>>45139

> Насколько он упрощает / уменьшает время на поиск и исправление ошибок в коде?


Очень помогает, не надо забивать голову и гадать как у тебя в определенном месте алгоритм отработал. Меньше вардампов будет в разы
725 745151
>>45141
Кулстори?
Быдлошарага без помощи со стороны коллег, или наоборот крутая контора, которую не потянул по уровню?
726 745160
>>45047

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



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

>Команда: отлично налаженное взаимодействие.



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

>И как попасть именно в контору третьего типа, где есть шикарный карьерный рост?



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

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

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



Если ты вообще нуб, то даже опыт работы в днище конторе поднимет твои навыки. Но долго там не задерживайся. Как тут уже советовали, поработай, возьми отпуск на пол года и учи еще. Затем повторяй весь цикл сначала.
727 745169
Нужна помощь, встретил в коде конструкцию $переменная.функция(параметры). Не совсем понятно что это за точка (какой-то вид сокращённой записи?) по учебнику ОПа ещё не дошел ни до чего подобного. Буду очень благодарен, если подскажете в какую сторону гуглить.
728 745171
>>45169
конкатинация, текст из переменной дописать до текста которые вернет функция
730 745200
Как в симфони сменить имя формы?
Вариант с переопределением в шаблоне
{{ form_start(form, {'name': 'new_form_name'})
не годится, потому что имена инпутов по-прежнему будут браться неизвестно откуда
old_form_name[input_name], а мне нужно new_form_name[input_name]

Вариант с createNamedBuilder тоже не годится.
Я создаю форму через createForm(MyForm::class, $data) контроллера, передавая ему имя класса формы.
В своем классе определяю метод
public function buildForm(FormBuilderInterface $builder, array $options)
который требуется интерфейсом FormTypeInterface

То есть там уже используется готовый билдер, созданный видимо через createBuilder. В нем как-то можно переопределить имя формы?
Это просто пиздец, у мну нет слов, чтобы изменить одну букву сидеть гуглить по двачаса.
2 Кб, 184x35
731 745258
>>45200
Помогло только расковыривание исходного кода.
Оказывается нужно было в классе формы переопределить метод AbstractType::getBlockPrefix()
(возможно я зря начал с 3-ей версии, под нее даже stackoverflow недостаточно загажен ответами)

Ну ок, +1exp в копилку. Еще 10k и стану архимагом.
732 745309
Что-то я уже совсем запутался.
Вот есть таблица attempts (попытки пройти тест).
id | test_id | user_id
Таблица answers (ответы) выглядит так
id | attempt_id | question_id | answer

Нужно узнать, является ли тест пройденным (попытка завершенной) - то есть на все ли вопросы теста пользователь дал ответы (на некоторые вопросы можно дать несколько ответов, варианты с чекбоксами).
То есть нужно сравнить кол-во вопросов к тесту с кол-вом уникальных (distinct) ответов.
Чистый sql для получения кол-ва уникальных ответов
select count(distinct question_id) from answers where attempt_id = :id

Собственно вопрос где этот код писать? В модели (например Attempt), или в ее репозитории (AttemptRepository, использую доктрину). Или может запилить какой сервис?
Удобно было бы в модели, вроде это логично, что Попытка должна знать о кол-ве ответов и т.д., и в контроллере код красивый типа
if ($attempt->isCompleted()) {...}
Но это вообще по-ормному, что модель обращается к базе данных?
С другой стороны, когда мы пишем $attempt->answers->count(), там тоже втихаря идет обращение к бд. Только с вытягиванием из бд всех связанных записей, созданием их объектов (ну или прокси), и только потом у объекта ArrayCollection вызывается метод count, который возвращает кол-во записей.
Тут конечно нужно писать чистый sql/dql.
Да нет, там же даже нет возможности получить entityManager, так что в модели наверное не нужно писать такой код.

Сервис или репозиторий? Если чет, пишу сервис, нечет репозиторий. На дабл иду играть в игры.
733 745363
Оп, объясни подробнее свое высказывание отсюда: https://github.com/codedokode/pasta/blob/master/good-code.md

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


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

Это что, вообще не рекомендуется использовать другие методы внутри функции? Эти методы нужно использовать при передачи аргумента?
45 Кб, 292x604
734 745384
Я ведь правильно понимаю, что если функция ничего не возвращает, результат ее работы будет void, то есть null. Норм если я буду использовать такую "фичу" или все же следует прописывать return null?
242 Кб, 595x315
735 745401
>>45151
По ровну. Сначала была быдло шарага, где никто не помогал, дальше выдрочился и стали объяснять не нубские вещи.

А потом охуел от наших менеджеров, когда они говорят "a little bit" и это часть ТЗ
736 745405
>>45401
Дрочи вопросы к собеседованиям, пиши резюме покруче и иди в другую. Преимущество работы программистом, что увольнение вообще на тебя никак не влияет, желающих нанять программистов шараг очень много. Увольнения вообще тебя заботить не должны, только набор опыта. Используй время между увольнениями, чтобы его еще поднабраться, делай тестовые проекты или open source.
737 745406
>>45405
Так и будет, но вообще я думаю на фриланс съебать на несколько месяцев и парт-тайм в другой конторе, где друзяшки работают. Просто не очень приятно, колектив хороший, уволили потому, что работки нихрена нет, и все бывают сидели без тасков по неделю-две
738 745411
>>44716
>>44717

Благодарю всех за дельные советы!

Учёл замечания, избавился от массивов массивов и необходимости их проверять трёхэтажными циклами.

https://github.com/applejacky/tmp

die() временно использую, чтобы сократить код для проверяющих. Exception'ы всегда можно добавить потом, мне гораздо важнее разобраться с архитектурой. Да, мне следовало об это сразу предупредить, чтобы вы на это не отвлекались.

>> [a-zA-Z0-9]


>Очень ограниченный набор символов


Добавил дефис и нижнее подчёркивание.

>> :num


>Других плейсхолдеров нет?


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

Поизучал роутинг в Symfony (сложно). Однако на нём и основывался, распределяя ответственности.
739 745425
>>45071
А если есть возможность поедать мамкины борщи, качая скиллы программирования, то обязательно ли идти в быдлошараги? Я пробыл пару недель в одной студии: сидел и разгребал кривые модули для WP и Джумлы, а гендир без наушников смотрел дом-2. Поэтому я сейчас качаюсь в сторону ООП и фреймворков, чтобы никогда больше за процедурный код не садиться.
740 745439
>>45425
Шараги в своем cv потом можно поднести как опыт работы в реальных проектах, а те что ты дома делаешь это такое себе.
741 745445
>>45425

Если ты готов относиться у обучению как к работе, то есть всерьез часов по 6 в день учиться то конечно учиться выгоднее. Ведь на работе надо работать, учиться некогда. Проблема в том что люди просто обычно забивают на это дело и бездельничают по 6 часов в день.
742 745446
>>45439
В тех проектах во вьюшках были SQL-запросы, в таблицах БД были не просто названия товаров, а названия товаров вперемешку с вёрсткой. GET-переменные шли прямиком в SQL-запрос без какой-либо фильтрации. Шторм треть функций на странице зачёркивал, так как они сильно устарели. Я хотел PHP бросить. До сих не верю, что кто-то может платить за аккуратный и грамотный код, а не за процедурные портянки, которые через задницу, но работают.

>>45445
Я достаточно отбитый, чтобы сутками аутировать за кодом.
743 745461
>>44032
Поправил. С валидацией что-то страшное сотворил.
https://github.com/fidnex/students/
744 745462
>>45446

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

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

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

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

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

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

Java - серьезный, взрослый язык с хорошей экосистемой, но многословный и скучноватый.
C# - серьезный, взрослый язык с хорошей экосистемой, но очень уж заточен на продукты МС.

Го - язык клоунов, придуманный чтобы было чем занять скучающих сотрудников Гугл. В коде будут перемешаны функции с маленькой и большой буквы, так как первая буква у них обозначает public/private и ты будешь постоянно их путать. Нет единого менеджера пакетов, нету классов, нету абстрактных типов. Нет никаких правил рапсределения кода по файлам потому все сваливают в одинфайл. Экосистемы нет, многие библиотеки на гитхабе выглядят так будето их писал умственно отатсалый, про вещи вроде разделения ответсвтенности никто и не слышал (ну, это термин из ООП, а ООП в Го не рады). Впрочем, лучше, чем Си.

Ты думаешь в других языках лучше, Да ничуть. Точно такие же толпы быдлокодеров везде. И точно также среди них выделяются те, кто подходит к изучению материала всерьез, расширяет свой кругозор, знает большое число технологий.
744 745462
>>45446

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

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

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

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

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

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

Java - серьезный, взрослый язык с хорошей экосистемой, но многословный и скучноватый.
C# - серьезный, взрослый язык с хорошей экосистемой, но очень уж заточен на продукты МС.

Го - язык клоунов, придуманный чтобы было чем занять скучающих сотрудников Гугл. В коде будут перемешаны функции с маленькой и большой буквы, так как первая буква у них обозначает public/private и ты будешь постоянно их путать. Нет единого менеджера пакетов, нету классов, нету абстрактных типов. Нет никаких правил рапсределения кода по файлам потому все сваливают в одинфайл. Экосистемы нет, многие библиотеки на гитхабе выглядят так будето их писал умственно отатсалый, про вещи вроде разделения ответсвтенности никто и не слышал (ну, это термин из ООП, а ООП в Го не рады). Впрочем, лучше, чем Си.

Ты думаешь в других языках лучше, Да ничуть. Точно такие же толпы быдлокодеров везде. И точно также среди них выделяются те, кто подходит к изучению материала всерьез, расширяет свой кругозор, знает большое число технологий.
745 745490
>>45446
У тебя хоть шторм был, в нашей шараге и на него пожалели, сидим в нетбинс.
746 745496
>>45490
Я был в шараге, где не знают что такое ide. Копируют контент при помощи мышки из исходного кода страницы, потом руками исправляют ссылки в блокноте. (какой линукс, какой вгет, какой курл, ты шо, вася)
Особо одаренные в ворде.

Это я пошел на неоплачиваемую стажировку. Свалил в ужасе на второй день.
Чтобы вы представляли, как обстоит дело в мухосранях, а то совсем зажрались в своих москвах. IDE за сто баксов им видите ли на халяву не раздают.
747 745500
>>45496

Не стоит соглашаться на неоплачиваемые стажировки (ты наверно это у же понял, а я еще для других анонов напишу). Если вы будете дома сидеть и решать например наши задачки, пользы будет скорее всего даже больше.
748 745536
>>45496
>>45490
Ребят, никто мне IDE не оплачивал, просто есть такая штука как студенческая лицензия. Отправляете фото студака на оф сайте и получаете лицензию на год. В конце концов, можно сидеть на триалке месяц, а перед удалением шторма скопировать конфиги куда-нибудь (продвинутые пакетные менеджеры вроде Pacman умеют удалять пакеты, не трогая конфиги). При новой установке шторма указывайте, чтобы он использовал старые конфиги. Занимает пару минут, хватает на месяц, никакого пиратства.
749 745616
>>45406
А сколько у тебя вообще опыт работы? И на чем сидел, на фреймворках, цмсках?
750 745621
>>45462

>JS - это язык верстальщиков


>node.js

751 745648
>>45616
Около 1,5 года. Сидел в основном на magento, иногда делал что-нибудь на микрофреймворках и один заказик был на wp, а его я знал еще раньше.
752 745791
>>45648
Ух ты, мадженто, прям как я, правда я на вторую сразу попал, я там выше свою историю написал.
Как вообще оцениваешь свой уровень именно в мадженто? Разобрался во всех тонкостях за полтора года?
753 745823
анон, нужно написать виджет, который можно было бы встраивать в сторонние сайты простым блоком разметки. Виджет должен повторять имеющийся на сайте функционал (на сайте общение с сервером происходит по ajax) и вот я сейчас в растерянности: как быть? как лучше реализовать? в виде айфрейма? или извратиться и сделать подгружаемую с сервера разметку и соответствующие js для выводимых блоков и организовать общение между ними по easyXDM?
754 745843
Начал задачу Кошки - Мышки.

Я правильно классы и логику задачи?

// Класс геймсет
// Размер поля
// Содержит массив Мышей
// Массив Кошек

// Конструктор (размер поля, кол-во Мышей, кол-во Кошек)

// Метод просчета игрового хода
// Цикл 20 ходов
// Запуск хода мышыей
// Запуск хода кошек
// Запус поедания Мышки Кошкой
// Вывод состояния текущего хода

// Метод вывода состояния текущего хода
// Метод поедания Мышки Кошкой

// Класс Мышка
// Координата Х
// Координата Y

// Метод генерации всех возможных ВариантовХодов (Размер поля)

// Метод оценки ВариантовХодов (ВариантХода, Координаты Кошек)
// Возвращает вес

// Выбор наилучшего ВариантХода (массив ВариантовХодов)
// Меняет координаты Мышки

// Клас Кошка
// Координата Х
// Координата Y
// Счетчик ходов

// Метод генерации всех возможных ВариантовХодов (Размер поля)

// Метод оценки ВариантовХодов (ВариантХода, Координаты Мышек)
// Возвращает вес

// Выбор наилучшего ВариантХода (массив ВариантовХодов)
// Меняет координаты Кошки

// Класс ВариантХода
// Координаты
754 745843
Начал задачу Кошки - Мышки.

Я правильно классы и логику задачи?

// Класс геймсет
// Размер поля
// Содержит массив Мышей
// Массив Кошек

// Конструктор (размер поля, кол-во Мышей, кол-во Кошек)

// Метод просчета игрового хода
// Цикл 20 ходов
// Запуск хода мышыей
// Запуск хода кошек
// Запус поедания Мышки Кошкой
// Вывод состояния текущего хода

// Метод вывода состояния текущего хода
// Метод поедания Мышки Кошкой

// Класс Мышка
// Координата Х
// Координата Y

// Метод генерации всех возможных ВариантовХодов (Размер поля)

// Метод оценки ВариантовХодов (ВариантХода, Координаты Кошек)
// Возвращает вес

// Выбор наилучшего ВариантХода (массив ВариантовХодов)
// Меняет координаты Мышки

// Клас Кошка
// Координата Х
// Координата Y
// Счетчик ходов

// Метод генерации всех возможных ВариантовХодов (Размер поля)

// Метод оценки ВариантовХодов (ВариантХода, Координаты Мышек)
// Возвращает вес

// Выбор наилучшего ВариантХода (массив ВариантовХодов)
// Меняет координаты Кошки

// Класс ВариантХода
// Координаты
755 745930
Работающие аноны, нужен совет ваш.
В Москве есть несколько компаний, набирающих новичков-стажеров в PHP, за еду, естественно. QSOFT, amoCRM, еще там кто-то. Что это за компании, я знаю, про текучку, отношения знаю. Но вот стоит ли туда пойти ради практики, чтоб через полгода-год этого ада устроиться на норм работу? Там вообще можно рассчитывать на стабильные 25к?
Вот, если че: https://career.ru/vacancy/16926757

Просто я после того, как доделаю задачу про студентов, буду даже ой как крут для них. А вот изучение фреймворков, мне кажется, это еще 4 месяца изучение дома, без работы и денег (лол)
756 745934
>>45791
Тонкостях? Не смеши, я всех атрибутов к блокам в layout-е не помню, не говоря уже о кучи различных фишек, хотя основы крепко вбиты в голову. Полюбил ее кстати. Вот с EAV по эксперементировать, ну а так готов написать, что угодно, правда по времени будут различия.

Вторую надо будет подучить сейчас, выделею себе на это день другой.
757 745938
>>45791
Пиздос, скажи, что ты еще во Львове, так я вообще ебанусь. Аноны из Львова хуярят под Magento2
162 Кб, 760x1080
758 745940
Оп-кун, посмотри что у меня по урокам с версткой выходит
https://github.com/babyba/html_path
759 745956
>>45934
Я имел в виду не все атрибуты на память, а вообще тонкости работы, там все эти квоты, передачи аттрибутов, филдсеты, обсерверы и вся эта хрень. Потому что я уже два с половиной месяца сижу на это второй магенте, и чем дальше, тем больше всяких непонятных и неочевидных вещей
>>45938
Не Львов, но 250км до негоб так что рядом
sage 760 745957
Теперь это тред хохлов и аниме.
761 745958
>>45956
А так то да, вроде все понятно. а что?

Эх, жалк
762 745972
Поставил PHPStorm (отправил фото зачетки, выдали лицензию на год).
Кто пользуется, подскажите, тут есть окно навигации, в котором видны все классы-свойства-методы, функции активного документа?
В Komodo IDE такой есть, вроде дерева папок, как в проводнике. Оч удобно, тут найти не могу.

Зы, для блокнота с подсветкой кушать пол гига памяти... хм. И тормозить сильнее чем Illustrator и Photoshop вместе взятые. Наверное это такой хитрый маркетинговый ход. Но цветовая схема Draacula приятная.
763 745975
>>45972
Спасибо, сам нашел, вкладка Structure
764 746285
>>45930

>Москва


>Зарплата от 20 000 до 30 000 руб.


Чума. Ради опыта если только.
765 746368
Помогите с решением. Есть поисковая строка на аяксе, надо выводить результаты поиска по мере того, как пользователь вводит символы в строку. По мере ввода аякс шлет запросы на сервак, на каждую букву по запросу, на удаление буквы тоже. Сделано так потому, что решение для планшетов и клава на экране, а не настоящая. На серваке каждый запрос обрабатывается php, pdo и mysql. Проблема в том, что каждый запрос обрабатывается достаточно долго (используется несколько LIKE %введенные данные% в разных таблицах), а пользователь печатает иногда быстро, но не всегда. Поэтому время от времени образуются повисшие запросы, которые еще не обработались, и ждут получения данных. Для решения этой проблемы был использован xhr.abort() для предыдущего запроса при посылании нового, который убивает предыдущий xmlhttprequest. На стороне клиента таким образом все хорошо, запросы вовремя убиваются, новые создаются, ничего не тормозит. Но обнаружилось, что на связке php-pdo-mysql сервер запросы все обрабатываются, даже когда аякс уже отрубился, по SHOW FULL PROCESSLIST висит их куча. Вопрос - как можно убить их тоже в процессе печатания, сервак зря грузят. Отменить нужно и сами запросы и pdo соединение и чтение данных в mysql. Видимо из php как-то или перед xhr.abort(), но ничего в голову не приходит. Есть идеи?
766 746471
>>46368

>шлет запросы на сервак, на каждую букву


Может стоит какой-то таймаут использовать? Типа если инпут в фокусе, то проверять время с его последнего изменения, и если больше например секунды двух слать запрос.
И если первая часть строки не изменилась, то можно фильтровать результаты прошлого поиска на стороне клиента, а не создавать новый, по сути уточняющий запрос.
С дивана
767 746476
>>46368

Не должно быть долго выполняющихся запросов в вебе. Либо переделывайте принцип работы, либо настраивйте индексы, либо подключайте поисковый движок либо отключайте автодополнение.
путь HTML 768 746482
>>46368

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

>>46285

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

>>45940

> https://github.com/babyba/html_path/blob/master/les1/index.html


Нет doctype (а это значит браузер будет отступать от стандартов при отображении), 2 раза стоит тег html, нет тега meta charset.

Само задание сделано верно.

> https://github.com/babyba/html_path/blob/master/les2/index.html


Тут максимальная ширина у тебя 622px а не 600 получается. width ведь задает внутреннюю ширину области контента.

Цвет фона очень темный -у меня черные буквы на нем еле видны. Надо было взять бледно-зеленый цвет с картинки.

Принцип решения верный.

> задача 3


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

Решено верно.

> задача 4


Между блоками больше 10px по горизонтали - к ним добавляется пробел. Это легко увидеть если выставить горизонтальные margin в ноль.

В комментариях к задаче есть ссылка на статью с обяснениями.

Цвета не точно соответствуют картинке.

> задача 5


В общем верно, если не считать того что цвета на картинке более светлые.

> задача 6


> font-family: "Trebuchet MS";


Надо всегда в конец списка добавлять один из встроенных шрифтов вроде sans-serif.

Верстка сделана ненадежно. Попробуй сделать больше текста справа- текст начинает обтекать меню и заходить под него снизу: https://jsfiddle.net/nc2nLv3f/1/

> задача 7


между кнопкой и инпутом больше 10px по горизонтали. Также, для свойства box-sizing надо добавлять версии с префикасми (вроде -moz-box-sizing) для старых браузеров.

> задача 8


Текст выровнен странно.

Верстка сделана неприавльно. Ты заключил отдельные абзацы в тег article. С какой стати? Это что, 2 отдельных не связанных статьи? Это абзацы одного текста. Верстка должна быть максимально простая, в таком стиле:

<p>абзац</p>
<div class="note">примечание</div>
<h2>заголовок</h2>
<p>абзац</p>

> width: calc(100% - 130px);


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

Эта задача решена неправильно.

> задача 9


> src="/home/vasil/Desktop/HTML/les9/images/img.gif"


Ты так поставил ссылки (указав полный путь к файлу) что они будут работать только на твоем компьютере. Почитай про относительные ссылки: https://github.com/codedokode/pasta/blob/master/network/urls.md

> display: inline-flex;


Это мало где поддерживается. И для такой простой задачи не требуется флексбокс. И к тому же непонятно почему inline-flex, а не flex, объясни, почему? хуже того, ты прописал контейнеру inline-flex, но сами возможности флексбокса не используешь. Или ты хотел написать inline-block? Это тоже неправильно.

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

> margin: 20px;


> width: 90%;


Неправильно прописаны свойства. Надо прописывать либо ширину и 1 маргин, либо только 2 маргина, а ширину в auto. У тебя в сумме (90% + 20px + 20px) может не получиться 100%.

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

Эта задача пока решена неправильно.

> задача 10


> width: 98.5%;


> padding-left: 5px;


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

Ну и паддинг там не 5, а вроде 10px.

> bottom: 4px;


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

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

Не реализована подгонка картинки под ширину страницы. Уменьши ширину body с 500 до 200 пикселей. Картинка должна сузиться до этиз 200 пикс, а она не сужается, а выводится в полную ширину.
путь HTML 768 746482
>>46368

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

>>46285

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

>>45940

> https://github.com/babyba/html_path/blob/master/les1/index.html


Нет doctype (а это значит браузер будет отступать от стандартов при отображении), 2 раза стоит тег html, нет тега meta charset.

Само задание сделано верно.

> https://github.com/babyba/html_path/blob/master/les2/index.html


Тут максимальная ширина у тебя 622px а не 600 получается. width ведь задает внутреннюю ширину области контента.

Цвет фона очень темный -у меня черные буквы на нем еле видны. Надо было взять бледно-зеленый цвет с картинки.

Принцип решения верный.

> задача 3


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

Решено верно.

> задача 4


Между блоками больше 10px по горизонтали - к ним добавляется пробел. Это легко увидеть если выставить горизонтальные margin в ноль.

В комментариях к задаче есть ссылка на статью с обяснениями.

Цвета не точно соответствуют картинке.

> задача 5


В общем верно, если не считать того что цвета на картинке более светлые.

> задача 6


> font-family: "Trebuchet MS";


Надо всегда в конец списка добавлять один из встроенных шрифтов вроде sans-serif.

Верстка сделана ненадежно. Попробуй сделать больше текста справа- текст начинает обтекать меню и заходить под него снизу: https://jsfiddle.net/nc2nLv3f/1/

> задача 7


между кнопкой и инпутом больше 10px по горизонтали. Также, для свойства box-sizing надо добавлять версии с префикасми (вроде -moz-box-sizing) для старых браузеров.

> задача 8


Текст выровнен странно.

Верстка сделана неприавльно. Ты заключил отдельные абзацы в тег article. С какой стати? Это что, 2 отдельных не связанных статьи? Это абзацы одного текста. Верстка должна быть максимально простая, в таком стиле:

<p>абзац</p>
<div class="note">примечание</div>
<h2>заголовок</h2>
<p>абзац</p>

> width: calc(100% - 130px);


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

Эта задача решена неправильно.

> задача 9


> src="/home/vasil/Desktop/HTML/les9/images/img.gif"


Ты так поставил ссылки (указав полный путь к файлу) что они будут работать только на твоем компьютере. Почитай про относительные ссылки: https://github.com/codedokode/pasta/blob/master/network/urls.md

> display: inline-flex;


Это мало где поддерживается. И для такой простой задачи не требуется флексбокс. И к тому же непонятно почему inline-flex, а не flex, объясни, почему? хуже того, ты прописал контейнеру inline-flex, но сами возможности флексбокса не используешь. Или ты хотел написать inline-block? Это тоже неправильно.

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

> margin: 20px;


> width: 90%;


Неправильно прописаны свойства. Надо прописывать либо ширину и 1 маргин, либо только 2 маргина, а ширину в auto. У тебя в сумме (90% + 20px + 20px) может не получиться 100%.

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

Эта задача пока решена неправильно.

> задача 10


> width: 98.5%;


> padding-left: 5px;


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

Ну и паддинг там не 5, а вроде 10px.

> bottom: 4px;


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

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

Не реализована подгонка картинки под ширину страницы. Уменьши ширину body с 500 до 200 пикселей. Картинка должна сузиться до этиз 200 пикс, а она не сужается, а выводится в полную ширину.
769 746504
>>45843

> // Конструктор (размер поля, кол-во Мышей, кол-во Кошек)


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

Так, в общем, выглядит нормально.

>>45823

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

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

>>45411

> https://github.com/applejacky/tmp/blob/master/app/Routing/RouteCollection.php#L17


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

> $pathRegex = "~^{$route->getPath()}$~";


Стоит исплоьзовать preg_quote так как в path могут быть спецсимволы.

Вообще, если подумать, метод проверки на соответсвие УРЛ логично поместить в сам роут. Хотя ... можно конечно и снаружи это делать, вопрос тут как ты рассматриваешь класс - как хранилище информации о роуте или как активный объект, который и сам умеет что-то делать.

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

> Добавил дефис и нижнее подчёркивание.


Все равно маловато ведь. А как насчет восклицательных знаков? Насчет шапочки? Скобок? Запятой?
769 746504
>>45843

> // Конструктор (размер поля, кол-во Мышей, кол-во Кошек)


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

Так, в общем, выглядит нормально.

>>45823

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

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

>>45411

> https://github.com/applejacky/tmp/blob/master/app/Routing/RouteCollection.php#L17


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

> $pathRegex = "~^{$route->getPath()}$~";


Стоит исплоьзовать preg_quote так как в path могут быть спецсимволы.

Вообще, если подумать, метод проверки на соответсвие УРЛ логично поместить в сам роут. Хотя ... можно конечно и снаружи это делать, вопрос тут как ты рассматриваешь класс - как хранилище информации о роуте или как активный объект, который и сам умеет что-то делать.

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

> Добавил дефис и нижнее подчёркивание.


Все равно маловато ведь. А как насчет восклицательных знаков? Насчет шапочки? Скобок? Запятой?
770 746505
>>45384

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

Если же функция иногла возвращает значение, а иногда null, то лучше прописать это в return явно.

>>45363

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


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

>>45309

> Таблица answers (ответы) выглядит так


> id | attempt_id | question_id | answer


Вообще, учитывая что бывают разные типы вопросов, получается что бывают и разные типы ответов на эти вопросы. Не забывай про это.

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


> То есть нужно сравнить кол-во вопросов к тесту с кол-вом уникальных (distinct) ответов.


Лучше сравнить множество id вопросов и множество id на которые даны ответы. И найти разницу между ними.

> Собственно вопрос где этот код писать? В модели (например Attempt), или в ее репозитории (AttemptRepository, использую доктрину). Или может запилить какой сервис?


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

> Но это вообще по-ормному, что модель обращается к базе данных?


К базе она обратиться не может так как в ней нет ссылки на entity manager. Обращаться к связанным сущностям она может. Представь что у тебя нет базы вообще и ты модели создаешь руками в начале скрипта. Будет ли твой код работать корректно? Если да то этот код можно поместить и в модель. В Data Mapper модель полностью отделена от базы, ничего о ней не знает и способна работать без нее.

> С другой стороны, когда мы пишем $attempt->answers->count(), там тоже втихаря идет обращение к бд


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

> Тут конечно нужно писать чистый sql/dql.


Тогда в репозиторий.

> Если чет, пишу сервис, нечет репозиторий


Ну вот ты и перечеркнул все мои многолетние усилия сделать из тебя программиста.
770 746505
>>45384

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

Если же функция иногла возвращает значение, а иногда null, то лучше прописать это в return явно.

>>45363

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


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

>>45309

> Таблица answers (ответы) выглядит так


> id | attempt_id | question_id | answer


Вообще, учитывая что бывают разные типы вопросов, получается что бывают и разные типы ответов на эти вопросы. Не забывай про это.

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


> То есть нужно сравнить кол-во вопросов к тесту с кол-вом уникальных (distinct) ответов.


Лучше сравнить множество id вопросов и множество id на которые даны ответы. И найти разницу между ними.

> Собственно вопрос где этот код писать? В модели (например Attempt), или в ее репозитории (AttemptRepository, использую доктрину). Или может запилить какой сервис?


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

> Но это вообще по-ормному, что модель обращается к базе данных?


К базе она обратиться не может так как в ней нет ссылки на entity manager. Обращаться к связанным сущностям она может. Представь что у тебя нет базы вообще и ты модели создаешь руками в начале скрипта. Будет ли твой код работать корректно? Если да то этот код можно поместить и в модель. В Data Mapper модель полностью отделена от базы, ничего о ней не знает и способна работать без нее.

> С другой стороны, когда мы пишем $attempt->answers->count(), там тоже втихаря идет обращение к бд


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

> Тут конечно нужно писать чистый sql/dql.


Тогда в репозиторий.

> Если чет, пишу сервис, нечет репозиторий


Ну вот ты и перечеркнул все мои многолетние усилия сделать из тебя программиста.
Вектор 771 746506
>>45258

Это очень странно что тебе надо переопределять префикс имен полей формы. Ты что-то делаешь не так с вероятностью 99%

>>45200

> Как в симфони сменить имя формы?


А зачем?

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


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

>>45169

склеивание строк

>>44943
>>44975

> static public function getXRankSalary ($rank)


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

> $xRankSalary


Не стоит добавлять странные префиксы. Я например не понял что значит x тут.

> 1 => '1',


Странно, почему ты коэффициент сделал строкой, а не числом. Это ведь число.

> public function getProfessionName ()


Не избыточная ли функция? Не лучше ли использовать getProfession()->getName()?

Вообще, я не уверен что нужно отдельно класс Coefficients и отдельно Profession. Мне тут вспоминается паттерн "Стратегия". Он используется когда нужно вынести вычисление чего-то из класса и сделать возможность замены алгоритма вычисления.

В данном случае мы можем сделать класс СтратегияРасчетаЗарплатыИДругихПараметровИнженера, в нем метод посчитатьзарплату(), посчитатьКофе(), в которые передаем профессию и ранг. Или самого работника. Или же совместить этот класс с Профессией. То есть, возможны варианты, я что-то сейчас сам не соображу как правильнее.

> public $name = ""; // название профессии


> abstract public function getSalaryRate();


А почему название полем? Можно его не задавать?

> / Класс аналитик


> class NewAnalyst extends Profession


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

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

> if ($employee->getProfessionName() == $profession) {


мне кажется название профессии - плохой идентификатор. Хороший - это само имя класса. Его можно получить как константу: SomeClasss::class

> // Если сотрудник не соответствует профессии


> if ($employee->getProfessionName() == $profession) {


Комментарий противоречит коду

> if ($profession == "") {


> $employeesNumber = count($this->employees);


лушче тогда null использовать, а еще лучше сделать для этого отдельный метод

> // параметр может принимать значение 'all', параметр будет игнорироваться


Нужно использовать константу для таких случаев. Или тот же null.

> public function findEmployee ($profession, $rank, $chief)


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

> $employeeKey = array_search($employee, $this->employees);


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

> // Поиск департамента по названию, аргумент "all" возращает все департааменты


Это 2 разных функции - найти один департамент и найти несколько.

> // Ничего не возвращам, мы обиделись


> die ("Департамент не найден");


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

> static public function dismissEngineers($company)


Что-то мне не нравится тут статический метод. Почему не обычный?

Также, эта функция делает слишком много задач:

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

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

Насчет выбора работников, все переусложнено. Выбирать лучше так:

- взять всех работников определенной профессии и рангов
- исключить из списка босса
- отсортировать по порядку увольнения
- взять первые N% через array_slice
- уволить

Так будет и проще и логичнее.

> // Находим аналитика самого высокого ранга


Это определенно стоит вынести в отдельную функцию. Разбей-ка слишком длинные функции на части.

> $rank = mb_substr ($vacancyName, 2, 1);


Лучше было парсить обозначение сотрудника регуляркой

>>44859
>>44858

Если ты не троллишь, то ты ошибаешься. Погугли "нормализация баз данных", "проектирование баз данных".
Вектор 771 746506
>>45258

Это очень странно что тебе надо переопределять префикс имен полей формы. Ты что-то делаешь не так с вероятностью 99%

>>45200

> Как в симфони сменить имя формы?


А зачем?

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


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

>>45169

склеивание строк

>>44943
>>44975

> static public function getXRankSalary ($rank)


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

> $xRankSalary


Не стоит добавлять странные префиксы. Я например не понял что значит x тут.

> 1 => '1',


Странно, почему ты коэффициент сделал строкой, а не числом. Это ведь число.

> public function getProfessionName ()


Не избыточная ли функция? Не лучше ли использовать getProfession()->getName()?

Вообще, я не уверен что нужно отдельно класс Coefficients и отдельно Profession. Мне тут вспоминается паттерн "Стратегия". Он используется когда нужно вынести вычисление чего-то из класса и сделать возможность замены алгоритма вычисления.

В данном случае мы можем сделать класс СтратегияРасчетаЗарплатыИДругихПараметровИнженера, в нем метод посчитатьзарплату(), посчитатьКофе(), в которые передаем профессию и ранг. Или самого работника. Или же совместить этот класс с Профессией. То есть, возможны варианты, я что-то сейчас сам не соображу как правильнее.

> public $name = ""; // название профессии


> abstract public function getSalaryRate();


А почему название полем? Можно его не задавать?

> / Класс аналитик


> class NewAnalyst extends Profession


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

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

> if ($employee->getProfessionName() == $profession) {


мне кажется название профессии - плохой идентификатор. Хороший - это само имя класса. Его можно получить как константу: SomeClasss::class

> // Если сотрудник не соответствует профессии


> if ($employee->getProfessionName() == $profession) {


Комментарий противоречит коду

> if ($profession == "") {


> $employeesNumber = count($this->employees);


лушче тогда null использовать, а еще лучше сделать для этого отдельный метод

> // параметр может принимать значение 'all', параметр будет игнорироваться


Нужно использовать константу для таких случаев. Или тот же null.

> public function findEmployee ($profession, $rank, $chief)


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

> $employeeKey = array_search($employee, $this->employees);


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

> // Поиск департамента по названию, аргумент "all" возращает все департааменты


Это 2 разных функции - найти один департамент и найти несколько.

> // Ничего не возвращам, мы обиделись


> die ("Департамент не найден");


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

> static public function dismissEngineers($company)


Что-то мне не нравится тут статический метод. Почему не обычный?

Также, эта функция делает слишком много задач:

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

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

Насчет выбора работников, все переусложнено. Выбирать лучше так:

- взять всех работников определенной профессии и рангов
- исключить из списка босса
- отсортировать по порядку увольнения
- взять первые N% через array_slice
- уволить

Так будет и проще и логичнее.

> // Находим аналитика самого высокого ранга


Это определенно стоит вынести в отдельную функцию. Разбей-ка слишком длинные функции на части.

> $rank = mb_substr ($vacancyName, 2, 1);


Лучше было парсить обозначение сотрудника регуляркой

>>44859
>>44858

Если ты не троллишь, то ты ошибаешься. Погугли "нормализация баз данных", "проектирование баз данных".
772 746525
>>46506

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

Некоторые хочу уточнить:

>> static public function getXRankSalary ($rank)


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


> другие расценки


> оплаты труда. Вообще, в ООП редко нужны статические методы.



Сделал статическим, чтобы иметь доступ к этому методу из любого места кода, не создавая экземпляра класса. Расчет на то, что коэффициенты могут меняться, и удобнее менять их в одном месте в коде. Хотя можно прописать их в формулу расчета зарплаты/кофе в классе Employee. И избавиться от отдельного класса.

А можно еще как-то получать доступ к коэффициентам из класса Employee?

> Вообще, я не уверен что нужно отдельно класс Coefficients и отдельно Profession.



Насчет класса Coefficients - вынес отдельно, чтобы они не болтались в классе Employee. Когда смотрел дамп компании увидел, что они копируются в каждом работнике. Там 1000 символов, в среднем по 2 бита на символ / 8 = 250 байт * 101(сотрудник) = 24 кБ, если я правильно посчитал. Решил вынести их из класса, для экономии (лет 30 назад, наверное было актуальнее).
Может быть логичнее хранить их в компании?
Но как получать к ним доступ из класса Employee? Обращаться к методу класса Company->getCoefficients из класса Employee не правильно?

У меня был вариант, но он мне показался не надежным, т.к. рассчет зп можно было запускать только из контекста класса Company, и передавать коэффициенты как аргумент вызова метода по цепочке Company > Department > Employee. Ведь так тоже не очень?

Паттерн "Стратегия" для изменения алгоритма расчета, а ведь тут меняется не алгоритм, а только коэффициенты?

Класс Profession отдельно, для того чтобы можно было поменять профессию у работника (Employee), и создавать новые классы профессий по шаблону родительского класса Profession. Идея была в том, что сторонний программист, создавая новый класс профессии должен переопределить обязательные методы для класса новой профессии. Хотя его можно убрать из кода, программа будет работать и без него.

>> static public function dismissEngineers($company)


>Что-то мне не нравится тут статический метод. Почему не обычный?



Решил не создавать объект класса АтикризисныеМеры, а напрямую обратиться к его методу. Думал статические методы именно для этого.
772 746525
>>46506

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

Некоторые хочу уточнить:

>> static public function getXRankSalary ($rank)


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


> другие расценки


> оплаты труда. Вообще, в ООП редко нужны статические методы.



Сделал статическим, чтобы иметь доступ к этому методу из любого места кода, не создавая экземпляра класса. Расчет на то, что коэффициенты могут меняться, и удобнее менять их в одном месте в коде. Хотя можно прописать их в формулу расчета зарплаты/кофе в классе Employee. И избавиться от отдельного класса.

А можно еще как-то получать доступ к коэффициентам из класса Employee?

> Вообще, я не уверен что нужно отдельно класс Coefficients и отдельно Profession.



Насчет класса Coefficients - вынес отдельно, чтобы они не болтались в классе Employee. Когда смотрел дамп компании увидел, что они копируются в каждом работнике. Там 1000 символов, в среднем по 2 бита на символ / 8 = 250 байт * 101(сотрудник) = 24 кБ, если я правильно посчитал. Решил вынести их из класса, для экономии (лет 30 назад, наверное было актуальнее).
Может быть логичнее хранить их в компании?
Но как получать к ним доступ из класса Employee? Обращаться к методу класса Company->getCoefficients из класса Employee не правильно?

У меня был вариант, но он мне показался не надежным, т.к. рассчет зп можно было запускать только из контекста класса Company, и передавать коэффициенты как аргумент вызова метода по цепочке Company > Department > Employee. Ведь так тоже не очень?

Паттерн "Стратегия" для изменения алгоритма расчета, а ведь тут меняется не алгоритм, а только коэффициенты?

Класс Profession отдельно, для того чтобы можно было поменять профессию у работника (Employee), и создавать новые классы профессий по шаблону родительского класса Profession. Идея была в том, что сторонний программист, создавая новый класс профессии должен переопределить обязательные методы для класса новой профессии. Хотя его можно убрать из кода, программа будет работать и без него.

>> static public function dismissEngineers($company)


>Что-то мне не нравится тут статический метод. Почему не обычный?



Решил не создавать объект класса АтикризисныеМеры, а напрямую обратиться к его методу. Думал статические методы именно для этого.
Путь HTML 773 746590
Возникла проблема с 11 заданием. ( https://github.com/codedokode/pasta/blob/master/html/html.md )

https://jsfiddle.net/uo6mnvxy/
Выполнил с использованием label с атрибутом for. Как можно обратится к label для установки фона когда внутри него находится input, с которого мы узнаём нажата кнопка или нет?
17 Кб, 277x312
774 746693
775 746699
>>39250
Оп, привет Студенты у меня https://github.com/greenTea242/Student_List

> А если пользователь при редактировании захочет очистить какое-то поле, эта проверка ведь его не пропустит?


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

> Тут ведь явно почти одно и то же. Нельзя ли это упростить за счет функций?


Я не нарушаю логику отображения перенося ее из шаблона в методы из вспомогательных классов как ты советовал? В борьбе с копипастом создал их(методов) несколько.

> Это странный код: если куки устанвлены и они правильные, установим их еще раз. Зачем?


Продление кук.

Это нормально что я несколько раз отклонился от общего для кода стиля(камелкейс) для имени переменной и имени метода и использовал вариант с нижним подчеркиванием ("CSRF_token")? Мне показалось, что не очень красиво если будет "CSRFToken". Стоило ли тогда тоже самое делать с authToken для, не знаю как сказать, симметрии чтоли.

> Зачем разрешать перезаписывать токен? Пользователь разве может его редактировать?


Ну он у меня в бд попадал через модель. Сейчас после манипуляций с двумя токенами я его добавляю отдельно https://github.com/greenTea242/Student_List/blob/master/public/register.php#L31 . Ок?

Алсо везде подбавлял абсолютных путей, сделал два токена. И еще вопрос, почему на пикрелейтед2 вокруг котика летает __DIR__? Помню я увидел пикчу в старых тредах и почему-то осталось в памяти что __DIR__ не есть хорошо.
776 746711
>>46699

Котика нарисовал не ОП, так что не знаю. Я думаю, автор пытался обратить внимание на нездоровое количество подчеркиваний, но это он еще Питон не видел.
777 746722
>>39250
>>46699
И еще забыл.

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



Нужно было перенести функционал метода addAbiturient в createErrorList или сделать как я сделал(методы теперь получают отдельно объект, без добавления его в свойства класса)?
1,3 Мб, 1200x1800
778 746723
Почему многие воспринимают PHP так предвзято, например цитата с реддита "PHP, which everyone hates but uses anyway"?
779 746727
>>46723
Низкий порог вхождения, из-за этого пишется очень много говнокода, поэтому у языка такая репутация. ЖС дрисня или Руби ничем не лучше пхп (а в некоторых местах даже хуже), но это сейчас модно и прогрессивно, поэтому пхп в англоязычных комьюнити хейтят в основном всякие хипстеры.
780 746745
>>46723

Пост отчасти в тему: >>45462
781 746747
>>46506

> Как в симфони сменить имя формы?


> А зачем?


Затем что у меня есть форма для ответов. Ответы хранятся в STI таблице. Соответственно в доктринке разные классы для ответов.
TextAnswer, DecimalAnswer, VariantAnswer и т.д.
Я беру вопрос, смотрю его тип, после чего создаю форму под тип ответа.
TextAnswerForm, VariantAnswerForm, поля ведь отличаются, там текстовый инпут, там чекбоксы или радиокнопки.

Формы ведь тоже отдельный класс, имена классов разные.
Функция start_form подставляет в name именно из имени класса.
Тогда как я не зная имя формы буду брать данные из запроса?
$formData = $request->request->get('имя_формы?');

Поэтому я унифицирую, чтобы вместо хуиты типа 'text_answer_form' или 'variant_answer_form' всегда была 'answer_form' вне зависимости от типа вопроса и можно было знать по какому имени к ней обращаться.
(впрочем сейчас дошло, что к данные из формы можно получить не из реквеста, а из ее объекта, пропустив через $form->handle($request), и оно уже само разгребет какие данные ему нужны).

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


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

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

/test/{id}/question/{num}
1. Если нет такого testId, выдать notFound.
2. Если у пользователя нет кук с токеном доступа, зарегистрировать его в фоновом режиме.
3. Найти у пользователя последнюю попытку пройти данный тест.
3.1. Если такой попытки нет, или она есть и ее статус 'completed', то создать новую.
3.2. Если такая попытка есть, и ее статус 'active' (по-умолчанию), то проверить
оставшееся время.
3.2.1. Если время истекло, редирект на /test/result/{attempt}, где выставить
статус в 'completed'.
3.2.2. Если время не истекло, проверить остались ли неотвеченные вопросы.
3.2.2.1. Если есть неотвеченные вопросы, взять id этой попытки.
3.2.2.2. Иначе редирект на /test/result/{attempt}, где выставить статус.
4. Если {num} не передан, /test/{id}/question методом GET выдать первый из
неотвеченных вопросов.
5. При запросе /test/{id}/question методом POST выдать первый из неотвеченных
вопросов, сохранить результат и сделать редирект на /test/{id}/question/{num}
где {num} это номер по порядку следующего неотвеченного вопроса.
6. При запросе /test/{id}/question/{num} метдом GET выдать вопрос {num}.
7. ... методом POST сохранить ответ и редирект /test/{id}/question/{num}.
8. Если нет следующего вопроса, проверить, есть ли у попытки пропущенные вопросы.
8.1. Если есть пропущенные, редирект на /test/{id}/confirm, где спросить
подтверждение завершения теста либо ссылку на /test/{id}/question (без параметра
{num}, cмотри пункт 4).
8.2. Если нет пропущенных, редирект на /test/result/{attempt}.
781 746747
>>46506

> Как в симфони сменить имя формы?


> А зачем?


Затем что у меня есть форма для ответов. Ответы хранятся в STI таблице. Соответственно в доктринке разные классы для ответов.
TextAnswer, DecimalAnswer, VariantAnswer и т.д.
Я беру вопрос, смотрю его тип, после чего создаю форму под тип ответа.
TextAnswerForm, VariantAnswerForm, поля ведь отличаются, там текстовый инпут, там чекбоксы или радиокнопки.

Формы ведь тоже отдельный класс, имена классов разные.
Функция start_form подставляет в name именно из имени класса.
Тогда как я не зная имя формы буду брать данные из запроса?
$formData = $request->request->get('имя_формы?');

Поэтому я унифицирую, чтобы вместо хуиты типа 'text_answer_form' или 'variant_answer_form' всегда была 'answer_form' вне зависимости от типа вопроса и можно было знать по какому имени к ней обращаться.
(впрочем сейчас дошло, что к данные из формы можно получить не из реквеста, а из ее объекта, пропустив через $form->handle($request), и оно уже само разгребет какие данные ему нужны).

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


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

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

/test/{id}/question/{num}
1. Если нет такого testId, выдать notFound.
2. Если у пользователя нет кук с токеном доступа, зарегистрировать его в фоновом режиме.
3. Найти у пользователя последнюю попытку пройти данный тест.
3.1. Если такой попытки нет, или она есть и ее статус 'completed', то создать новую.
3.2. Если такая попытка есть, и ее статус 'active' (по-умолчанию), то проверить
оставшееся время.
3.2.1. Если время истекло, редирект на /test/result/{attempt}, где выставить
статус в 'completed'.
3.2.2. Если время не истекло, проверить остались ли неотвеченные вопросы.
3.2.2.1. Если есть неотвеченные вопросы, взять id этой попытки.
3.2.2.2. Иначе редирект на /test/result/{attempt}, где выставить статус.
4. Если {num} не передан, /test/{id}/question методом GET выдать первый из
неотвеченных вопросов.
5. При запросе /test/{id}/question методом POST выдать первый из неотвеченных
вопросов, сохранить результат и сделать редирект на /test/{id}/question/{num}
где {num} это номер по порядку следующего неотвеченного вопроса.
6. При запросе /test/{id}/question/{num} метдом GET выдать вопрос {num}.
7. ... методом POST сохранить ответ и редирект /test/{id}/question/{num}.
8. Если нет следующего вопроса, проверить, есть ли у попытки пропущенные вопросы.
8.1. Если есть пропущенные, редирект на /test/{id}/confirm, где спросить
подтверждение завершения теста либо ссылку на /test/{id}/question (без параметра
{num}, cмотри пункт 4).
8.2. Если нет пропущенных, редирект на /test/result/{attempt}.
782 746822
>>46590
Если мы размещаем <label>asfa</label><input type="radio">

То проблему решают соседние селекторы, загугли
783 746867
>>46822
изменил, теперь при нажатии на label радиобаттон не устанавливается в положение checked

https://jsfiddle.net/g3333rfb/1/
784 746877
>>46867
Смотри подсказки же
https://habrahabr.ru/post/138020/
785 746884
бляя, ахуеваю просто чел, сайт прислал на доработку, там не единого фреймворка, контроллеры и модели через require включаются, ЗАПРОСЫ К БД ВОТ ТАК ПИШУТСЯ
$query = " SELECT t1.,t2.,t3.* FROM auctions_start t1 LEFT JOIN auctions_img t2 ON t1.auc_id = t2.a LEFT JOIN auctions t3 ON t1.auc_id = t3.id WHERE t3.category=$cat_id LIMIT $start,$size";

пиздец просто и за такое говно кто-то платит.
786 746905
>>46877
так у меня изначально и были лейблы с атрибутом for, но в задании требуется их не использовать
787 746913
>>46884
90% внутренностей интернета выглядит именно так. Радуйся тому, что хотя бы контроллеры и модели есть.

>>46693
Ты забыл дописать "быстро!".

>>46699
Без __DIR__ могут возникнуть проблемы при переносе кода между различными ОС, не вижу ничего плохого в нём.

>Мне показалось, что не очень красиво если будет "CSRFToken".


Пиши CsrfToken и не парься.
788 746939
Пойдет на джуниора?
http://baron-fon-kolt.github.io
804 Кб, 500x750
789 746941
>>29430 (OP)
Двачик, а как с помощью PHP определить, на какой именно странице сайта находится пользователь ?
790 746976
>>46913

>Ты забыл дописать "быстро!".


Я забыл написать "пожалуйста".
791 747172
>>46747
Дописал, теперь все работает как нужно, но код выглядит как земля с многоэтажными ифами и редиректами.
Нужны советы по рефакторингу.
https://github.com/nsdvw/TestHub

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

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

Займусь пока изучением юнит-тестов, потому что эта байда меня вконец вымотала.
792 747198
Пиздец прислали мне говно, которое никто не хочет делать, где вьюхи смешаны с работой с базой данных без моделей, одна сплошная каша, не понятно даже где и что тут.
793 747201
>>46913

>90% внутренностей интернета выглядит именно так


Но это же кошмар какой-то, мы тут сидим выдрачиваем стройную логику МВК, читаем про паттерны работы с базой данной и все равно без работы сидим, а они хуяк-хуяк и гребут бабки лопатой за такое вот неработающее говно, которое потом хуй кто разберет.
73 Кб, 604x297
794 747220
>>29430 (OP)
А можно ли отправлять такие запросы ?
$db->query("SELECT * FROM lobby WHERE link = 'substr($_SERVER[REQUEST_URI], 1)' ");
795 747227
>>47201
Я верю в то, что по-настоящему квалифицированный специалист будет обязательно востребованным. И такой специалист будет решать сложные задачи, используя паттерны, MVC и прочие непростые в освоении, но мощные штуки, а "кодеры" так и будут клепать однотипные лендинги на CMS/Самописном процедурном корявом движке до конца своих дней и разгребать говно за другими. В то время как ты сможешь без проблем раскурить сложный код другого специалиста, легко его расширить, ведь ты знаешь как, а гибкая архитектура этого приложения позволяет это сделать.
4 Кб, 168x170
796 747269
>>47227
Ребята, кто вам просто так доверит это всё - вы хотя бы об этом подумайте.
Специалист-шмециалист.
Во всяком деле, касающемся производства, либо создания интернет-магазина, либо создания просто портала под игори, надо смотреть на целевую аудиторию и сам спрос.
Штука-то в том, что спрос среди кодеров на РНР как раз и состоит в том, что надо CMS/Самопис поковырять вилкой, лендинг-шмендинг состряпать и так далее.
Это тщета и суета сует.
НО!
Пока вы сами не начнёте что-то делать для себя, пока не поднимите свой проект какой-нибудь.
Свободного или малоконкурентного и по сей день полно.
Например, на каком-то корявом самописе сделан сайт vsezverushki.ru (как-то его упоминал как раз в подобном контексте десяток тредов назад). Там посещаемость-то всего 2к в сутки, но доход - несколько тысяч рублей в сутки же. Сам сайт продавался на Телдери за несколько миллионов (ОП тогда сказал, что в итоге не купили его, но предлагали-то почти 2 миллиона в несколько ставок).
Вот к подобному надо стремиться, а не к тому, что придёт дядя, оценит, даст работу.
Кстати, дядя охотнее оценит и даст нормальную работу именно при наличии каких-либо проектов - это общее место уже.
333 Кб, 700x704
797 747280
798 747312
>>47269
Согласен с этим. Мужик правду говорит.
799 747354
>>47269

>Кстати, дядя охотнее оценит и даст нормальную работу именно при наличии каких-либо проектов - это общее место уже.


Работодатель отдаст предпочтение конченному аутисту, что двух слов связать на собеседовании не смог, чем амбициозному челу с каким-то там проектами в интернетах. Первый будет горбатиться за копейки и ссать прибавку к зп попросить, второй отработает годок и свалит на лучший офер в свой наебизнес
800 747376
>>47354

С аутистом тоже риски есть, что он уйдет в свой внутренний мир и ничего полезного по работе не сделает.
801 747393
>>47376
У меня пара коллег в офисе из таких вот, там другая проблема. Они если чего не знают или не поймут что им сказали, то будут весь день ебать гугл, вместо того чтоб спросить/уточнить и тем самым заваливают все сроки. И ничего тут не поделать, если к нему подойти и попытаться как-то помочь, тот будет потеть фонтаном и кивать головой, мол я все понял ток оставь меня в покое.
Код у них хороший. Один с 2010, другой с 2007 работает. Платят им на уровне джуниоров, обильно штрафуя по всякой хуйне, на что те и не против совсем.
49 Кб, 760x399
802 747400
Прив, Анон! Пикрелейтед Макака на связи. Помоги, пожалуйста! Надеюсь, ты сможешь мне помочь... Смотри, по условию, так как а и б имеют разные знаки (сработает else), я должен увидеть сумму а и б. Но вместо этого я вижу их произведение (срабатыват elsif). Почему так? Почему срабатывает elsif если одна из переменных больше ноля?? такая же хрень происходит и с if - срабатывает даже если одна из переменных меньше ноля, хотя по логике такого не должно быть, ведь && это TRUE если и $a, и $b TRUE. А выходит, что true даже если одна переменная true
803 747404
>>47400
http://php.net/manual/ru/language.operators.precedence.php
У операторов сравнения приоритет больше, чем у логических.
804 747405
>>46939
Если в Yii2 базовые знания есть, то пойдет, я думаю.
И правильно будет Портфолио Junior разработчика.
805 747406
>>45462
А что можешь сказать про Haskell?
806 747408
>>47400

if ($a && $b > 0)

Ты хотел написать "если обе а и б больше 0"? Язык программирования это не человеческий язык и компьютер понимает это выражение совсем по-другому:

if (($a) && ($b > 0 ))
"если а не равно нулю И б больше нуля"

То что тебе надо, пишется как ($a > 0) && ($b > 0)

дело в том что > это логический оператор. Он сравнивает числа и возвращает true или false. И то что ты написал, понимается совсем по-другому. И кстати && это тоже оператор который принимает 2 логических значения false или true и возвращает true только если справа и слева от него стоит true.

http://php.net/manual/ru/language.types.boolean.php
https://ru.wikipedia.org/wiki/Логический_тип
http://php.net/manual/ru/language.operators.logical.php
807 747423
После почти двухмесячного перерыва опять вкатываюсь с файлообменником.

https://github.com/foobar1643/filehosting

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

Вот этот костыль https://github.com/foobar1643/filehosting/blob/master/app/Model/File.php#L110 так и остался, я просто не понимаю как это сделать без цикла. Нужно из id файла получить целое число, которое будет именем папки, в которой этот файл хранится (100, 200, 300 и т.д.).

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

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

>Нужно из id файла получить целое число, которое будет именем папки, в которой этот файл хранится (100, 200, 300 и т.д.).


>public function getFolder()


>{


>for($i = 100; $i < 100000000; $i += 100) {


>if(($this->id / $i) <= 1) return $i;


>}


>return false;


>}



Больной ублюдок.
809 747456
>>47393

> Один с 2010, другой с 2007 работает


> Платят им на уровне джуниоров


Пиздец! Омега, он и в программировании останется омегой
810 747458
https://regex101.com/r/tL6gZ3/3

Анон, как сделать совпадения в рандомном порядке?
Нужно чтобы скобки, тире и пробелы выделялись независимо от того в каком порядке они стоят по отношению друг к другу.
811 747612
Есть случай, когда в переменную может прийти null или объект. Ну например мы извлекаем что-то из базы по айди, если не найдено, возвращает null.
$obj = $repo->find($id);

Если нужно обратиться к какому-то свойству или методу объекта, делать вложенные ифы для проверки на null, или корректно будет записать в
одном условии типа:

if ($obj === null or $obj->getSmth() === 100) {/.../}

Я проверял, если первый операнд слева от OR вернет true, то второй никогда не выполнится, то есть здесь формально ошибки нет, но выглядит как-то не очень. Правильно так писать, или может сделать вложенный иф?
812 747620
Аноны, че за хуйня? Пример из справочника выдает: Failed to load resource: the server responded with a status of 500 (Internal Server Error)

$base = array("orange", "banana", "apple", "raspberry");
$replacements = array(0 => "pineapple", 4 => "cherry");
$replacements2 = array(0 => "grape");
$basket = array_replace($base, $replacements, replacements2);
echo $basket;
813 747671
Не планируют ли вводить официальную поддержку синтаксических конструкций в комментариях?
В последнее время все чаще вижу, когда нехилый кусок логики приложения живет в комментариях, например аннотации в доктрине/симфони/юниттестах.
Было бы логично уже сделать оф.поддержку таких конструкций, если все ими пользуются.

>>45160

>На основе чего ты сделал такой вывод?


Личный опыт, плюс одна бабка на дваче сказала.
Вот еще кулстори от бабки
>>47393
про команду из заторможенных и взаимодействие с менеджерами уровня "если что-то будет непонятно спрашивайте)))))".

Не знаю, может я живу в каком-то маня-идеалистичном мире, но мне видится хорошее командное взаимодействие приблизительно так.
Каждый день тим собирается на совещание, минимум час. Пока все проснутся, перекусят, подтянутся опоздуны.
На совещании рассматривается: очередь и приоритеты новых задач, обсуждаются способы реализации конкретных глобальных задач, распределяются мелкие тикеты,
каждый в обязательном порядке отчитывается за прошедший день, может (и должен) выставить на рассмотрение свою проблему/затруднение, если на чем-то завис.
В конце двухнедельного срока большое совещание, 3-4 часа. Ни одна мелочь или проблема не должна быть упущена или оставлена на самотек. Каждый член команды
должен четко представлять, чего от него хотят, и как это релизовать.
Короче я вижу идеальной схему команды с опытным руководителем, в обязанности которого внезапно входит в первую очередь контроль над работой команды, распределение задач, контроль за исполнением, принятие главных решений в архитектуре (например спроектировать бд и набросать uml-схему основных классов), а также важные переговоры с бизнесом.
То есть тимлид (или как это называется), который выполняет функции диспетчера, но почти не пишет код, и команда ответственных исполнителей, которые с удовольствием реализуют грамотно поставленное тимлидом тз.

Не должно быть такого, что сидит группа аутистов, и манагеры им кидают бестолковые тз от неграмотного заказчика уровня "сайт не работает, сделайте чтобы работал".
Я был подобной шараге, приходилось с боем выбивать контакты заказчиков, чтобы самостоятельно черт побери выяснять подробности.
Несколько неплохих заказчиков кстати осталось с того времени, подкидывают изредка немножко работы в обход той шараги.
813 747671
Не планируют ли вводить официальную поддержку синтаксических конструкций в комментариях?
В последнее время все чаще вижу, когда нехилый кусок логики приложения живет в комментариях, например аннотации в доктрине/симфони/юниттестах.
Было бы логично уже сделать оф.поддержку таких конструкций, если все ими пользуются.

>>45160

>На основе чего ты сделал такой вывод?


Личный опыт, плюс одна бабка на дваче сказала.
Вот еще кулстори от бабки
>>47393
про команду из заторможенных и взаимодействие с менеджерами уровня "если что-то будет непонятно спрашивайте)))))".

Не знаю, может я живу в каком-то маня-идеалистичном мире, но мне видится хорошее командное взаимодействие приблизительно так.
Каждый день тим собирается на совещание, минимум час. Пока все проснутся, перекусят, подтянутся опоздуны.
На совещании рассматривается: очередь и приоритеты новых задач, обсуждаются способы реализации конкретных глобальных задач, распределяются мелкие тикеты,
каждый в обязательном порядке отчитывается за прошедший день, может (и должен) выставить на рассмотрение свою проблему/затруднение, если на чем-то завис.
В конце двухнедельного срока большое совещание, 3-4 часа. Ни одна мелочь или проблема не должна быть упущена или оставлена на самотек. Каждый член команды
должен четко представлять, чего от него хотят, и как это релизовать.
Короче я вижу идеальной схему команды с опытным руководителем, в обязанности которого внезапно входит в первую очередь контроль над работой команды, распределение задач, контроль за исполнением, принятие главных решений в архитектуре (например спроектировать бд и набросать uml-схему основных классов), а также важные переговоры с бизнесом.
То есть тимлид (или как это называется), который выполняет функции диспетчера, но почти не пишет код, и команда ответственных исполнителей, которые с удовольствием реализуют грамотно поставленное тимлидом тз.

Не должно быть такого, что сидит группа аутистов, и манагеры им кидают бестолковые тз от неграмотного заказчика уровня "сайт не работает, сделайте чтобы работал".
Я был подобной шараге, приходилось с боем выбивать контакты заказчиков, чтобы самостоятельно черт побери выяснять подробности.
Несколько неплохих заказчиков кстати осталось с того времени, подкидывают изредка немножко работы в обход той шараги.
814 747675
>>47620
Доллар забыл.
815 747682
>>47675
Бля, точно. Спасибо. Но чет, все равно не работает
816 747684
>>47682

> echo $basket


В баскет у тебя массив, нельзя массив через echo выводить, echo для строк.
817 747691
>>47684
Через Print_r тоже не выводится(
818 747695
>>47671

>Каждый день тим собирается на совещание, минимум час



Предлагаю собираться не один раз в день, а восемь. И увеличить время совещаний минимум в полтора раза. При таком раскладе командное взаимодействие станет еще более лучшим.
819 747700
>>47691
Если просишь помощи, нужно указать полную информацию.

Сделай скриншот своего кода (или выложи ссылку на ideone.com), скриншот сообщения об ошибке.
Желательно еще версию php (и сборки).

print_r пишется с маленькой буквы (регистр названий функций в php не имеет значения, но так принято)

>>47695
Согласен. В течение всего остального рабочего дня тоже можно и нужно обращаться за помощью, а не сидеть молча каждый в своем углу.
820 747709
>>47695
Опчек (если это ты), а почему ты против?
Разве тебе самому не профитно было бы занять место такого руководителя-организатора, от которого только и требуется, что раздавать задачи, проверять говнокод и отвечать на вопросы умственно отсталых (ты же этим в треде занимаешься, прикинь еще большие деньги будут платить, а самому не нужно заниматься рутинной работой типа чистки горячо любимого друпаля).

Хотя возможно бизнесу такая схема невыгодна, не знаю.
821 747712
>>47700
PHP Version 5.2.17
Пишу редактирование файла на сервере. Методом тыка понял что крашится на строчке с array_replace.
Ради эксперимента взял пример array_replace из мануала >>47620 Тоже ничего не выводит.
822 747723
>>47712

>array_replace


> (PHP 5 >= 5.3.0, PHP 7)


http://php.net/manual/ru/function.array-replace.php

Эта функция доступная только с версии 5.3
Альтернативы не знаю, нужно свою писать
http://stackoverflow.com/questions/6198679/array-replace-alternatives-for-earlier-version-of-php

Ну и как бы обновиться пора. PHP 7 уже на полном ходу, работает раза в 2 быстрее чем пятерка.
823 747738
>>47709

Оп постом ниже был

Ты в тимлиды метишь? Как думаешь достичь этой цели?
79 Кб, 736x518
824 747760
>>47738
Постом ниже чего? После поста саркастичного господина тоже мой потс.
Я думал то оп бомбанул от предложения час в день тратить на детальный разбор полетов, типа он говорил что ему и так времени на приготовить пожрать даже не хватает.
Так увеличение рабочего дня коснется только джунов, они должны быть только за, я бы например не против 9-часового дня, лишь бы была взаимопомощь и возможность учиться у опытных коллег.
Как раз для начальства рабочий день может быть и ограничится совещанием, а потом в свободном режиме руководитель может заняться код-ревью джуниоров, подумать над сложным вопросом архитектуры, который не по силенкам для джунов. Это можно сделать и дома например. Да и конференцию можно проводить по скайпу, ради бога.

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

>Ты в тимлиды метишь?


Не, руководитель это по определению чувак с многолетним опытом, прошедший через все круги ада.
У меня реального опыта меньше полгода в мухосранских веб-студиях. Плюс еще год в треде (что принесло намного больше опыта и знаний).
825 747764
>>47620
var_dump() сделай, есть ли там вообще что-то.
826 747776
>>47712

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

>>47723

5.2 безнадежное старье

>>47709

Это не я. На работу где не надо ничего не делать, меня вряд ли кто пустит. А типичный старший программист обычно кроме руководства, сам кодит в поте лица. С Друпалом не работал уже давно, хотя он довольно простой, с ним работа это скорее как отдых будет.

>>47671

> Не планируют ли вводить официальную поддержку синтаксических конструкций в комментариях?


Это с Явы взято, там аннотации это часть языка. В PHP (пока?) нет.

Каждый день тратить час всей команды на митинг расточительно и дорого. Лучше 15-минутный стендап раз в неделю. Новички могут общаться с надсмотрщиками и вне митинга.

>>47612

Выглядит не очень. Лучше бы if ($obj && $obj->...) или вложенный иф.

>>47458

Квадратные скобки

>>47456

Может у них просто другие интересы. Хотя если развиваться, мне кажется за 9 лет можно стать суперсеньором, нет?

>>47436

С такими комментариями лучше в /b - там твои братья обитают.
826 747776
>>47712

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

>>47723

5.2 безнадежное старье

>>47709

Это не я. На работу где не надо ничего не делать, меня вряд ли кто пустит. А типичный старший программист обычно кроме руководства, сам кодит в поте лица. С Друпалом не работал уже давно, хотя он довольно простой, с ним работа это скорее как отдых будет.

>>47671

> Не планируют ли вводить официальную поддержку синтаксических конструкций в комментариях?


Это с Явы взято, там аннотации это часть языка. В PHP (пока?) нет.

Каждый день тратить час всей команды на митинг расточительно и дорого. Лучше 15-минутный стендап раз в неделю. Новички могут общаться с надсмотрщиками и вне митинга.

>>47612

Выглядит не очень. Лучше бы if ($obj && $obj->...) или вложенный иф.

>>47458

Квадратные скобки

>>47456

Может у них просто другие интересы. Хотя если развиваться, мне кажется за 9 лет можно стать суперсеньором, нет?

>>47436

С такими комментариями лучше в /b - там твои братья обитают.
827 747777
>>47423

> я просто не понимаю как это сделать без цикла. Нужно из id файла получить целое число, которое будет именем папки, в которой этот файл хранится (100, 200, 300 и т.д.).


Поделить id на 100?
828 747782
>>47406

Не сталкивался близко, его вообще где-то за пределом университетов и селектела используют?

>>47269

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

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

Конечно можно какую-то незанятую нишу найти но сидеть в ней ты будешь ровно до того момента как кто-то возьмется за нее всерьез.
829 747787
>>47220

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

И странно что у тебя смешан код работы с базой и работа с внешними переменными.
830 747793
>>47787
То он жаловался, что ему прислали чистить такой код.
Я еще и не такое видел. В первом yii иногда принято сохранять куски php-кода в базу например.
831 747808
>>47423
$a = floor($this->id / 100);
if($a) return $a * 100;
return 100; // Если id файла меньше 100
176 Кб, 488x600
832 747810
>>47782
Я вяло занимался контекстной рекламой несколько лет, продал 5 сайтов за довольно неплохие деньги. Могу оценить суть сайта, его примерный доход от реального размещения рекламы. На тех зверюшках 200р или около того в сутки стоит разместить объявление о продаже. Объявление появляется только на главной, сами зверята стоят во много раз больше, это выгодно питомникам/заводчикам: 4к заплатил за сутки за всю главную - купили щенка за 25к - к примеру, всё окупилось в несколько раз.
Сайт знаком заводчикам и питомникам, тут ты прав, без этого многое не возможно было бы.
Но делали его простые энтузиасты - потому что на безрыбье и рак рыба.
Я не призывал эксплуатировать ниши, но только делать годные проекты для себя, людей и, в том числе, для работодателей, чтобы они заметили тебя.
http://www.telderi.ru/ru/viewsite/198901 - вот этот лот на Телдери. Там ставки делают реальные люди, это не система оценивает, было около 5 ставок, насколько вспоминаю сейчас, шаг в 200к рублей или около того. Система такое оценить не сможет - реальные люди платят за свои объявления, это не контекстная реклама, от кликов по которой вебмастеру перепадают крохи.
И суть в том, что сайт этот только на Москву рассчитан. Остальные города, наверное, на Авито и аналогах как-то рекламируются.
Просто в качестве примера это всё приводил.
833 747851
>>47793
В Yii так не принято, так принято среди говнокодеров. В Joomla вроде как тоже есть MVC, но на практике каждый модуль (который делали за 200-400 баксов) мешанина на 1000 строк из PHP-кода, JS, запросов к БД и вёрстки.
>>45446-хуй
63 Кб, 799x507
834 747853
>>47851
Прекрати обзывать себя.
Так ты не становишься лучше.
835 747860
>>47851
Так в оф.доках рекомендуют делать
http://www.yiiframework.com/doc/guide/1.1/ru/topics.auth#sec-9
Я имею ввиду использование "бизнес-правил".
Второй юи вроде хорошо почистили.

>>47853
Что вы все тут такие хомяки непуганные?
836 747861
>>47760

У меня негативный опыт планерок. Они отнимают время у тех кто работает. Для менеджера проекта есть СРМ с текущими задачами всех исполнителей. В образовательных целях стоит проводить семинары или лекции, в свободное от работы время.
Идеальная планерка по моему мнению, выглядит так: для каждого человека достаточно 2-5 минуты, что бы он отчитался по сделанной работе, обозначил свои цели на ближайшее время, и ответил на вопросы. 5-7 активных участников не больше. И того от 10 до 35 минут. Проводится 29 февраля. Служит целям сплочения коллектива.
837 747872
>>47860

>Что вы все тут такие хомяки непуганные?


Веди себя прилично. На анонимной борде оценивается характер сообщения. И вообще веди себя культурно в культурном обществе.
sage 838 747873
>>47872
Мать твою ебал.
839 747874
>>47810

Расскажи про сайты, которые ты продал? Какая тематика? Где брал контент, как раскручивал? Где продал?
У меня тож было пару сайтов, японская косметика, % с продаж, до обвала рубля приносили стабильный профит, но продать у меня не получилось не один из них, даже ставок не было. А MFA на торговой площадке (возможно талбери даже) расходились как горячие прижки. Партнер купил один из таких сайтов, через пару недель обвалилась посещаемость, а чуть позже его забанил адсенс.
840 747883
>>47874
Почему ты пишешь как ОП отступая одну строку после ответа? Ты можешь ввести в заблуждение новичков в нашем треде.
841 747884
>>47883
Лол, здесь много кто так пишет.
842 747892
>>47883

Так эстетичнее. А почему ты так не делаешь?
843 747902
>>47874
Мне кажется погромистам нужно не на статейники смотреть, а писать сервисы или модули для популярных кмсок.
844 747915
>>47902
У меня есть идея для сервиса,
сделать такой сайт, в который ты вводишь номер своего поста, а он проверяет тред каждые 5 минут, и если тебе ответили на сообщение, высылает на почту фото котика или смс в скайп, еще до конца на определился.

Бывает зарегистрируешься на форуме, чтобы только один вопрос задать, а потом забудешь.
845 747917
>>47915
Даже название придумал - ЕНОТ НАПОМИНУН
846 747925
>>47915
Тогда уж расширение для браузера и стучаться апишкой по заданному расписанию.
847 747937
>>47925
Я уверен такое расширение уже есть, но найти не могу, смотрел по запросам "wakaba", "answer cheker" и "post checker". Как еще можно поискать?
291 Кб, 819x718
848 747948
>>47776

>Квадратные скобки


Не понял тебя.
Квадратные скобки не помогли:
https://regex101.com/r/tL6gZ3/4

Зато переделал с квантификатором после группы и получилось:
https://regex101.com/r/tL6gZ3/5
150 Кб, 1200x1540
849 747953
Вопрос по Студентам.

Храню в классе Student инфу по каждому студенту: имя, фамилия и и.т.д.
Мне нужно запилить регистрацию и авторизацию. Для этого мне нужно хранить для каждого студента хеш. Один экземпляр в БД, другой у студента в куках.

1. Логично ли добавить столбец hash в таблицу students? Или сделать отдельную таблицу user со столбцами student_id и hash?
2. Соответственно, хранить ли свойство hash в классе Student или создать новый класс User?
850 747970
>>47874
Самая разнообразная тематика, но всё связано с реальным производством: бетонные изделия, металлический прокат, сантехника, авто - куча всего.
Сайты на простом WP все до единого.
Контент заказывал на text.ru и ещё у пары знакомых анонов, которых нашёл в /wrk (там тред про копирайтинг).
Не раскручивал никак, только статьи делал, много статей под семантическое ядро.
В среднем сайты продавал по 30к рублей (при этом на создание тратил тысячи 3 от силы), один продал за 100к, о чём пожалел через полгода, потому что у сайта посещалка выросла в три раза, хотя новый владелец ничего не делал ради этого (насколько я мог судить, проверяя бэклинки и кол-во страниц, просто сам сайт).
Спалить урлы не могу - всё это есть на Телдери, не хочу подставлять купивших, там все АДсенсом монетизируют и прямыми рекламодателями.
МФА - когда это годные статейники по Пузату, Фсео и так далее из инфобизнесменов - на Телдери разлетаются как пирожки даже за блиц. Я тоже по их технологии делал (ну, куча структурированных статей, картиночки, видосики, перелинковка, уникальный шаблон, даже маскота делал для одного сайта).

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


Накручивают, гады, очень много накручивают. Я думал, гораздо меньше будут накручивать. Я когда на лоты смотреееел...
По многим признакам можно определить, что накрутка есть. Часто несуразное соотношение траф/доход. Часто из гугла 90% трафа, а из яндекса всего 5% - или наоборот.
Проблема в том, что в рунете контекстка отмирает: как доллар взлетел, так доходы снизились, кризис коснулся мелкого бизнеса, они перестали сливать кучу денег на рекламу.
Вообще значение рекламы крайне преувеличено - мои наблюдения на одном сайте, на котором у меня прямые рекламодатели.
Там заходят по сочным коммерческим запросам, а выхлоп почти нулевой для реклов. Так, из-за имиджа только и платят мне за площадку, даже стыдно.
Надоело всё это - до жути.

>>47902
Неистово двачую!
Поэтому я и здесь.
850 747970
>>47874
Самая разнообразная тематика, но всё связано с реальным производством: бетонные изделия, металлический прокат, сантехника, авто - куча всего.
Сайты на простом WP все до единого.
Контент заказывал на text.ru и ещё у пары знакомых анонов, которых нашёл в /wrk (там тред про копирайтинг).
Не раскручивал никак, только статьи делал, много статей под семантическое ядро.
В среднем сайты продавал по 30к рублей (при этом на создание тратил тысячи 3 от силы), один продал за 100к, о чём пожалел через полгода, потому что у сайта посещалка выросла в три раза, хотя новый владелец ничего не делал ради этого (насколько я мог судить, проверяя бэклинки и кол-во страниц, просто сам сайт).
Спалить урлы не могу - всё это есть на Телдери, не хочу подставлять купивших, там все АДсенсом монетизируют и прямыми рекламодателями.
МФА - когда это годные статейники по Пузату, Фсео и так далее из инфобизнесменов - на Телдери разлетаются как пирожки даже за блиц. Я тоже по их технологии делал (ну, куча структурированных статей, картиночки, видосики, перелинковка, уникальный шаблон, даже маскота делал для одного сайта).

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


Накручивают, гады, очень много накручивают. Я думал, гораздо меньше будут накручивать. Я когда на лоты смотреееел...
По многим признакам можно определить, что накрутка есть. Часто несуразное соотношение траф/доход. Часто из гугла 90% трафа, а из яндекса всего 5% - или наоборот.
Проблема в том, что в рунете контекстка отмирает: как доллар взлетел, так доходы снизились, кризис коснулся мелкого бизнеса, они перестали сливать кучу денег на рекламу.
Вообще значение рекламы крайне преувеличено - мои наблюдения на одном сайте, на котором у меня прямые рекламодатели.
Там заходят по сочным коммерческим запросам, а выхлоп почти нулевой для реклов. Так, из-за имиджа только и платят мне за площадку, даже стыдно.
Надоело всё это - до жути.

>>47902
Неистово двачую!
Поэтому я и здесь.
851 747985
Добавил работу с БД (именно я наплодил в этом треде кучу глупых вопросов по DataMapper), DiContainer, каким его понял, класс-конфиг. Последний кажется мне очень однобоким, он не универсален и заточен только под БД. В общем, буду рад советам/предложениям по исправлению.
853 748097
>>47777
>>47808
Спасибо, работает.
Ответы 11 мая 854 748100
>>38578

Предыдущие задачи вроде проверил

Задача про исправление ошибок

> foreach ($sentence as $key => $sent) {


Лучше было назвать $sentences и $sentence

Так, решено верно.

Йода

> return($result);


Скобки не нужны так как return это оператор, а не функция. В остальном, все верно.

>>38695

> 1)В каких случаях в MVC стоит создавать класс представления вместо обычного шаблона?


Практически ни в каких

> 2)Как сказать апачу что индекс.php у меня в папке public и ссылаться надо на него?


Ты не совсем так делаешь. В htaccess менять ничего не требуется. Тебе надо указать что корень сайта в папке public. Это надо делать в конфиге, в виндоуз это conf/httpd.conf в папке апача, в линукс это файлы в /etc/apache2. Там должна быть опция DocumentRoot, либо в самом конфиге, либо внутри VirtualHost. В ней надо прописать путь к папке, например:

<VirtualHost .... >
ServerName neko.local
DocumentRoot c:/web/example/public/
...

>>39718

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

>>40120

> RewriteRule ^.$ [NC,L]


А что делает это правило?

Ну и слишком мало информации. Ты почему-то думаешь что дело в htaccess но оно модет быть и в чем то другом. На инклюды он никак повлиять не может.
Ответы 11 мая 854 748100
>>38578

Предыдущие задачи вроде проверил

Задача про исправление ошибок

> foreach ($sentence as $key => $sent) {


Лучше было назвать $sentences и $sentence

Так, решено верно.

Йода

> return($result);


Скобки не нужны так как return это оператор, а не функция. В остальном, все верно.

>>38695

> 1)В каких случаях в MVC стоит создавать класс представления вместо обычного шаблона?


Практически ни в каких

> 2)Как сказать апачу что индекс.php у меня в папке public и ссылаться надо на него?


Ты не совсем так делаешь. В htaccess менять ничего не требуется. Тебе надо указать что корень сайта в папке public. Это надо делать в конфиге, в виндоуз это conf/httpd.conf в папке апача, в линукс это файлы в /etc/apache2. Там должна быть опция DocumentRoot, либо в самом конфиге, либо внутри VirtualHost. В ней надо прописать путь к папке, например:

<VirtualHost .... >
ServerName neko.local
DocumentRoot c:/web/example/public/
...

>>39718

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

>>40120

> RewriteRule ^.$ [NC,L]


А что делает это правило?

Ну и слишком мало информации. Ты почему-то думаешь что дело в htaccess но оно модет быть и в чем то другом. На инклюды он никак повлиять не может.
Ответы 11 мая 855 748101
>>40209

Читай документацию и исходный код. Принцип там примерно такой: ты даешь слово, он возвращает возможные варианты форм слова и признаки (в каком числе, падеже слово). Ну например на слово "мыла" он вернет:

- глагол "мыть", в форме "мама мыла раму"
- существительное "мыло" в форме "мыла больше нет"
- сущестительное "мыло" во множ. числе: "разные мыла"

Как видишь тут по слову сказать в каком оно числе, и существительное ли оно, нельзя. Надо либо как-то мириться с этим, либо анализировать связи между словами (делать синтаксический анализ, это отдельная сложная задача) и по ним определять какой тут вариант.

>>40213

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

>>40441

Насчет миграций, я делаю так: написанные вручную на SQL миграции и аннотации в классах. Если я добавляю поле в таблицу, я делаю миграцию и добавляю поле с аннотацией в класс.

> Но в оф.доках к migrations bundle советуют как раз таки генерировать миграции автоматически на основе аннотаций.


Я сомневаюсь что это работает только в самых простых случаях. Не, SQL код, мне кажется, придется писать вручную.

>>41208

https://ideone.com/bUy2YN

> $creditSum -= $payout;


Это повторяется 2 раза, можно вынести наружу за цикл.

> if ($creditSum == 0) {


надежнее писать <= 0 на случай если мы ошибемся и поставим результат чуть меньше нуля.

Так, в общем, верно

https://ideone.com/PIkUhh

Нет привязки к концу строки: https://ideone.com/TIn4zU

https://ideone.com/UXs3Jd

Для знокаов вроде минусов и скобок лучше было использовать квадратные скобки, а у тебя заложен определенный порядок, например что минус идет после скобки. В остальном верно.
Ответы 11 мая 855 748101
>>40209

Читай документацию и исходный код. Принцип там примерно такой: ты даешь слово, он возвращает возможные варианты форм слова и признаки (в каком числе, падеже слово). Ну например на слово "мыла" он вернет:

- глагол "мыть", в форме "мама мыла раму"
- существительное "мыло" в форме "мыла больше нет"
- сущестительное "мыло" во множ. числе: "разные мыла"

Как видишь тут по слову сказать в каком оно числе, и существительное ли оно, нельзя. Надо либо как-то мириться с этим, либо анализировать связи между словами (делать синтаксический анализ, это отдельная сложная задача) и по ним определять какой тут вариант.

>>40213

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

>>40441

Насчет миграций, я делаю так: написанные вручную на SQL миграции и аннотации в классах. Если я добавляю поле в таблицу, я делаю миграцию и добавляю поле с аннотацией в класс.

> Но в оф.доках к migrations bundle советуют как раз таки генерировать миграции автоматически на основе аннотаций.


Я сомневаюсь что это работает только в самых простых случаях. Не, SQL код, мне кажется, придется писать вручную.

>>41208

https://ideone.com/bUy2YN

> $creditSum -= $payout;


Это повторяется 2 раза, можно вынести наружу за цикл.

> if ($creditSum == 0) {


надежнее писать <= 0 на случай если мы ошибемся и поставим результат чуть меньше нуля.

Так, в общем, верно

https://ideone.com/PIkUhh

Нет привязки к концу строки: https://ideone.com/TIn4zU

https://ideone.com/UXs3Jd

Для знокаов вроде минусов и скобок лучше было использовать квадратные скобки, а у тебя заложен определенный порядок, например что минус идет после скобки. В остальном верно.
https://github.com/TheSidSpears/Students 856 748102
>>41457

https://github.com/TheSidSpears/Students

> 2. Слышал о подходе, когда в классе все свойства закрытые, а обращаются к ним/изменяют через getter'ы/setter'ы. Нужно ли это?


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

https://github.com/TheSidSpears/Students/blob/master/config.json#L4

> "driver": "mysql",


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

> "tablename": "students"


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

Папку .idea надо убрать из репозитория, внести в gitignore и вернуть обратно (чтобы она не попала в репозиторий).

index.php - непонятно, зачем он, если он вне веб-папки и его вызвать нельзя.

> $config->db


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

> $token=md5(uniqid(rand(), true));


Что за нездоровое увлечение md5? Зачем он тут? Он не увеличивает число возможных вариантов хеша (даже чуть уменьшает). Не ставь функции наугад. uniqid испоьзует текущее время и потому плохо годится как источник случайных знаечний. Надо генерировать хеш из случайно выбранных символов.

> Попытка взлома. Без предупреждений перекидываем на главную


Не надо перекидывать. Надо либо вывести страницу ошибки с соответствующим HTTP кодом (например 403 или 400, поищи в википедии), либо выводить форму с заполненными значениями и сообщением об ошибке.

> foreach($form_data as $k=>&$s){


Эта переменная нигде не определена

https://github.com/TheSidSpears/Students/blob/master/public/register.php#L27

> $s=htmlspecialchars($s,ENT_QUOTES);


> $s=preg_replace("#((data|javascript)(://))#iu","",$s);


Это выглядит как код написанный наугад. Автор кода сам не понимает что он делает. Такой код я видел в некачественных учебниках и не стоит его копировать. Прочитай мой урок по XSS - там написано что htmlspecialchars пишется в шаблоне. Данные надо экранировать там, где они исопльзуются.

Вот например ты вырезаешь слово "яваскрипт". Но что, если у нас в форме есть поле "о себе" и пользователь хочет написать что он знаком с языком яваскрипт?

И еще кое-что. У меня есть такой урок и в нем задачка на экранирование: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Экранирование . Реши-ка ее.

> $check_student


Переменные пишутся кемелкейсом, checkStudent. Более того, они обычно не начинаются с глагола (кроме случаев типа $isValid).

> $check_student=new Student($form_data['name'],$form_data['sname'],$form_data['group_num'],$form_data['points'],$form_data['gender'],$form_data['email'],$form_data['b_year'],$form_data['is_resident']);


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

> $s=$check_student;


Название $s ничего не говорит.

> https://github.com/TheSidSpears/Students/blob/master/app/bootstrap.php


> Route::start();


Это не бутстрап. Скрипт инициализации должен только инициализировать приложение, подготовить нужные объекты, но не должен пытаться что-то роутить. То что у тебя называется front controller.

Кстати, тебе дополнительное задание. Сделай Cli скрипт который загружает по очереди всех студентов из БД, проверяет каждого на правильность и если есть ошибки, пишет id студента и подробности ошибок.

> function __autoload($className){


Это устаревшая функция. Надо переделать как описано в уроке https://github.com/codedokode/pasta/blob/master/php/autoload.md

> Route::start();


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

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

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

> catch(Exception $e){


> echo "Исключение: ", $e->getMessage(),"\n";


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

> $config=file('config.json',FILE_IGNORE_NEW_LINES);


> $config=implode('',$config);


Есть file_get_contents. Уже лет 10 как он появился.

>$config=json_decode($config);


Конфиг стоит декодировать в массив, а не в псевдообъект имитирующий массив.

> include('public/'.$controller.'.php');


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

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

- example.com/
- example.com/register.php

Либо например такие:

- example.com/register

https://github.com/TheSidSpears/Students/blob/master/app/class/Student.php
Класс сделан неудачно. Нельзя просто создать студента с незаполненными полями, надо передавать 10 аргументов, причем из порядок наизусть не запомнить.

> function __construct($db_params){


> //подключаемся к БД через PDO


Почитай урок про DI https://gist.github.com/codedokode/e1d31a31b37d5f635057

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

> $p=@$this->p; //для удобства


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

> function pdo_exec(


> function getStudents


Ты один делаешь проект и сам же не можешь выдержать единый стиль наименования функций.

> foreach($students as $k=>&$v){


Непонятно зачем тут & перед $v

https://github.com/TheSidSpears/Students/blob/master/app/class/StudentValidator.php#L32
В конструкторе не может быть return. Как, интересно, ты собрался получать результат вызова конструктора?

https://github.com/TheSidSpears/Students/blob/master/app/class/Route.php#L11
У тебя тут огромный try который содержит нескольког десятков строк, почти всю функицю. Это нехорошо, такие огромные конструкции, надо как-то переделать функцию чтобы он не был огромным.

Класс Route должен называться FrontController. Роутер только анализиурет URL и никого сам не вызывает.
https://github.com/TheSidSpears/Students 856 748102
>>41457

https://github.com/TheSidSpears/Students

> 2. Слышал о подходе, когда в классе все свойства закрытые, а обращаются к ним/изменяют через getter'ы/setter'ы. Нужно ли это?


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

https://github.com/TheSidSpears/Students/blob/master/config.json#L4

> "driver": "mysql",


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

> "tablename": "students"


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

Папку .idea надо убрать из репозитория, внести в gitignore и вернуть обратно (чтобы она не попала в репозиторий).

index.php - непонятно, зачем он, если он вне веб-папки и его вызвать нельзя.

> $config->db


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

> $token=md5(uniqid(rand(), true));


Что за нездоровое увлечение md5? Зачем он тут? Он не увеличивает число возможных вариантов хеша (даже чуть уменьшает). Не ставь функции наугад. uniqid испоьзует текущее время и потому плохо годится как источник случайных знаечний. Надо генерировать хеш из случайно выбранных символов.

> Попытка взлома. Без предупреждений перекидываем на главную


Не надо перекидывать. Надо либо вывести страницу ошибки с соответствующим HTTP кодом (например 403 или 400, поищи в википедии), либо выводить форму с заполненными значениями и сообщением об ошибке.

> foreach($form_data as $k=>&$s){


Эта переменная нигде не определена

https://github.com/TheSidSpears/Students/blob/master/public/register.php#L27

> $s=htmlspecialchars($s,ENT_QUOTES);


> $s=preg_replace("#((data|javascript)(://))#iu","",$s);


Это выглядит как код написанный наугад. Автор кода сам не понимает что он делает. Такой код я видел в некачественных учебниках и не стоит его копировать. Прочитай мой урок по XSS - там написано что htmlspecialchars пишется в шаблоне. Данные надо экранировать там, где они исопльзуются.

Вот например ты вырезаешь слово "яваскрипт". Но что, если у нас в форме есть поле "о себе" и пользователь хочет написать что он знаком с языком яваскрипт?

И еще кое-что. У меня есть такой урок и в нем задачка на экранирование: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Экранирование . Реши-ка ее.

> $check_student


Переменные пишутся кемелкейсом, checkStudent. Более того, они обычно не начинаются с глагола (кроме случаев типа $isValid).

> $check_student=new Student($form_data['name'],$form_data['sname'],$form_data['group_num'],$form_data['points'],$form_data['gender'],$form_data['email'],$form_data['b_year'],$form_data['is_resident']);


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

> $s=$check_student;


Название $s ничего не говорит.

> https://github.com/TheSidSpears/Students/blob/master/app/bootstrap.php


> Route::start();


Это не бутстрап. Скрипт инициализации должен только инициализировать приложение, подготовить нужные объекты, но не должен пытаться что-то роутить. То что у тебя называется front controller.

Кстати, тебе дополнительное задание. Сделай Cli скрипт который загружает по очереди всех студентов из БД, проверяет каждого на правильность и если есть ошибки, пишет id студента и подробности ошибок.

> function __autoload($className){


Это устаревшая функция. Надо переделать как описано в уроке https://github.com/codedokode/pasta/blob/master/php/autoload.md

> Route::start();


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

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

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

> catch(Exception $e){


> echo "Исключение: ", $e->getMessage(),"\n";


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

> $config=file('config.json',FILE_IGNORE_NEW_LINES);


> $config=implode('',$config);


Есть file_get_contents. Уже лет 10 как он появился.

>$config=json_decode($config);


Конфиг стоит декодировать в массив, а не в псевдообъект имитирующий массив.

> include('public/'.$controller.'.php');


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

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

- example.com/
- example.com/register.php

Либо например такие:

- example.com/register

https://github.com/TheSidSpears/Students/blob/master/app/class/Student.php
Класс сделан неудачно. Нельзя просто создать студента с незаполненными полями, надо передавать 10 аргументов, причем из порядок наизусть не запомнить.

> function __construct($db_params){


> //подключаемся к БД через PDO


Почитай урок про DI https://gist.github.com/codedokode/e1d31a31b37d5f635057

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

> $p=@$this->p; //для удобства


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

> function pdo_exec(


> function getStudents


Ты один делаешь проект и сам же не можешь выдержать единый стиль наименования функций.

> foreach($students as $k=>&$v){


Непонятно зачем тут & перед $v

https://github.com/TheSidSpears/Students/blob/master/app/class/StudentValidator.php#L32
В конструкторе не может быть return. Как, интересно, ты собрался получать результат вызова конструктора?

https://github.com/TheSidSpears/Students/blob/master/app/class/Route.php#L11
У тебя тут огромный try который содержит нескольког десятков строк, почти всю функицю. Это нехорошо, такие огромные конструкции, надо как-то переделать функцию чтобы он не был огромным.

Класс Route должен называться FrontController. Роутер только анализиурет URL и никого сам не вызывает.
Ответы 12 мая 857 748103
>>41477

Что годного в SICP? Во-первых, если тебе интересен этот курс, можно взять оригинальный учебник с кодом на scheme: http://newstar.rinet.ru/~goga/sicp/sicp.pdf Я не очень понимаю, в чем выгода от замены scheme на PHP и урезания объема курса. Плюс, у тебя по моему просто нездоровая реакция на слово SICP. Увидев его, ты теряешь способность видеть содержание урока. Какой-то религиозный фанатизм.

Во-вторых, на хекслете курс больше по основам PHP. Там вроде бы нет уроков по работе с формами, по MVC, по исключениям, по особенностям ООП, всего того, что мы изучаем в студентах. Зато есть много всяких сторонних вещей вроде алгоритмов.

>>41605

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

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

Ну и другие трюки, когда складывается впечателние что достаточно пройти один курс, хоят на деле надо пройти минимум несколько.
858 748106
>>41605

Вот пример человека которому перезавысили самооценку https://www.youtube.com/watch?v=YrXJzD2E6NU

Это конечно хорошо что хекслет такое выкладывает, но это скорее против них играет. Самооценка это хорошо, но она должна соотноситься с реальным уровнем знаний, а там у человека не то что пробелы, а зияющие пустоты в знании основных технологий с которыми он (по его словам) работал.
860 748144
>>47220
ни в коем случае. Юзай подготовленные запросы с плей-холджераи
861 748146
>>48101

>>сессии умирают после 20-30 минут


Это поведение можно менять session_set_cookie_params

А что, по-твоему, было бы лучшей идеей для логина? Я пробую варинаты.
862 748149
>>48103
Гикбрейнс ужасен почти всем. Курсы никто не сопровождает - нет даже видимости обратной связи с автором. Не выкладываются исходники файлов в курсах - ну что за бред? Там - до кучи - какая-то жуткая система оповещений, сам сайт какой-то кривой.
Постоянно присылают какие-то заманухи про гуманитариев, ставших программистами, что-то такое, я не читаю.
После знакомства с парой бесплатных курсов создалось впечатление, что платные не лучше (постоянно там отзывы по ходу встречаются, что человек и на платном такое встречал, платные разочаровали и т.п.).
>>48106
А что там? Вроде в итоге справился с тестовым (я в самом конце только посмотрел, там вроде всё решено). Вроде как собеседование - надо же себя позиционировать кукареку! соответствующим образом.
863 748163
У меня вопрос - мне нужно создать сайт для локальной сети, который может вести учёт перевозок. Т.е. он должен хранить списки водителей, машин, заказчиков и т.д. и выводить их по запросу. Это реально сделать на php или лучше использовать что-то другое?
864 748167
>>48163

>сайт для локальной сети


Для локальной сети лучше написать клиент-серверное приложение.
865 748172
>>48167

Туда будут заходить с телефонов тоже, или это не имеет значения?
866 748173
>>48172
Напиши приложения для телефонов. Это не так сложно.
867 748174
>>48173

Я в программировании на уровне "Hello world!", но по времени не ограничен.
868 748180
>>48174

>по времени не ограничен


Тогда используй ассемблер.
869 748207
>>48180
Хренассе ты тролляка
214 Кб, 468x658
870 748261
ОП, уточни, пожалуйста, почему тебе не понравился Никсон Робин, пикрелейтед?
Там ведь нет процедурщины, там по ООП всё!
Он там оговаривается в одном месте, что сначала разберём регистрацию и т.п. с точки зрения процедурщины, а потом пойдём по ООП, может, ты это увидел?
871 748292
>>48102

> $s=preg_replace("#((data|javascript)(://))#iu","",$s);


> что, если у нас в форме есть поле "о себе" и пользователь хочет написать что он знаком с языком яваскрипт?



Код удаляет "data://" и "javascript://", а вот строка "javascript" проходит на ура, что мне и требовалось

> Route::start();


> Это не бутстрап.



Мне тогда эту строку в public/index.php засунуть?

> Почитай про исключения


Ты про пользовательские классы исключений? Реализовал

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



Делаем пустой конструктор и фунцию addInfo($array). Так? Или много ф-ии типа addName, addGender...?

В общем я уже много чего исправил и еще доисправляю, и нового написал, можешь проверять: https://github.com/TheSidSpears/Students

Кстати, как правильно использовать гит? Типа внёс какое-то изменение в файл и сразу коммит пишешь, и так каждые 5 минут. А в конце push.
А то я часа 3 сижу пишу, а потом понимаю, что мне впадлу для каждого файла прописывать что я там менял, да и стоит ли?
872 748315
>>48100

>Ты не совсем так делаешь. В htaccess менять ничего не требуется. Тебе надо указать что корень сайта в папке public. Это надо делать в конфиге, в виндоуз это conf/httpd.conf в папке апача, в линукс это файлы в /etc/apache2. Там должна быть опция DocumentRoot, либо в самом конфиге, либо внутри VirtualHost. В ней надо прописать путь к папке, например:



Ок, получилось. Это делать каждый раз для разных приложений? Если у меня сейчас DocumentRoot "c:/Apache/htdocs/app1/public", то для другого проекта придется удалять это и писать свою папку?
873 748331
>>48292

> Ты про пользовательские классы исключений? Реализовал


нет, про то как надо делать страницу ошибки. Логгировать все, код правильный выдавать

> Кстати, как правильно использовать гит? Типа внёс какое-то изменение в файл и сразу коммит пишешь, и так каждые 5 минут. А в конце push.


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

> Делаем пустой конструктор и фунцию addInfo($array). Так?


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

> Мне тогда эту строку в public/index.php засунуть


Можно

> Код удаляет "data://" и "javascript://",


Хорошо, если пользователь хочет написать javascript:// ?
874 748333
>>48315

В апаче есть виртуальные хосты. Для нового проекта добавляется новый вирт. хост.

Тут чуть-чуть это упомянуто: https://github.com/codedokode/pasta/blob/master/soft/apache-install.md#q-Ок-Апач-работает-php-работает-Но-меня-напрягает-что-у-меня-только-один-хост--localhost-Я-бы-хотел-иметь-несколько-сайтов-на-компе-с-разными-адресами

Ну и погугли еще. Если что, задавай вопросы.
875 748363
>>48261
Ты тралируешь так?
Посмотри финальный проект книги. Там класическая процедурная лапша. Да даже она херово написана. Привет начало 2000-ных.
876 748367
>>48363
Я ещё не дошёл до конца, прост..
877 748416
>>48331

> Хорошо, если пользователь хочет написать javascript:// ?



> Если ты на сайте разрешаешь пользователям вводить ссылки (например, в разделе «О себе»), то надо проверять, что они начинаются с http:// или https:// . Иначе пользователь подсунет ссылку вида data://... или javascript:// .... при клике по которой выполнится код. Конечно, ему надо еще заманить других пользователей кликнуть по ней, но наверняка есть способы для этого. htmlspecialchars тут не спасет, но поможет проверка ссылки регулярным выражением на правильность.


Источник: https://github.com/codedokode/pasta/blob/master/security/xss.md Я это отсюда взял

Всё остальное понятно, исправляю постепенно, огромнейшее спасибо
878 748421
Первая часть доков по юнит тестам вроде вполне понятная, но начиная с главы посвященной бд начинается трешак.
Столько инфы, что каша в голове, и непонятно что собственно надо сделать.

Вот в случае этого TestHub, покрыть юнит-тестами только классы, которые отвечают за подсчет результатов теста и статистики прохождений?
Остальная логика содержится либо в контроллерах (надо бы отрефакторить и попытаться перетащить ее в сервисы), либо в сервисах, либо в репозиториях, и сводится к получению данных через entity manager sql запросом, dql или тупо $entity->getRelation()->getProperty(). Что тут собственно тестировать? Получение данных из бд и то что методы возвращают объект ожидаемого класса?

Допустим, методы сервисов и репозиториев не нужно покрывать тестами.
Возвращаясь к подсчету результатов и статистики: а эти методы должны брать dataSet (или как это называется) из базы данных, или можно подсунуть простой массив из dataProvider? Короче, тестировать здесь нужно именно логику подсчета результатов, или таки дополнительно проверить, что из бд возвращаются нужные данные?
879 748456
Помогите пожалуйста. Начал последнюю задачу в мануале для новичков. Почему последнее elseif не выводит результат. http://ideone.com/dIyb4d
880 748465
>>48456
Потому что когда в $char живет знак равенства в $op живет операнд умножения и потому последний elseif у тебя вообще не отрабатывает.
881 748472
>>45462

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


Я немного опоздал конечно, но ради интереса решил попробовать.
http://ideone.com/xH6Eja Как мне показалось самый очевидный вариант.
882 748475
>>48456
Спасибо. Я как раз не сохранил это своё решение пару месяцев назад.
883 748484
>>48465
Все, я понял. Спасибо
884 748497
>>48472
В юникоде один символ может занимать больше одного байт, от 1 до 4, так что твой вариант работает только с латиницей (для которой существует strrev).

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

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

На тему адекватных вопросов на собеседовании можно почитать Антона Шевчука http://anton.shevchuk.name/php/php-interview/
и даже книжка кажется есть со сборником вопросов https://www.kobzarev.com/wp-content/uploads/books/php/PHPbook.pdf
885 748513
>>48497

О, а вот это пригодится. Спасибо!
886 748528
Анон, делаю небольшой сайтик по книге. Цель такова: пользователь загружает изображение, мы это изображение закидываем в БАЗУ ДАННЫХ. Потом из базы данных мы его извлекаем и показываем. Но вместо изображения у меня пикрилейтед1, на втором пике скрин из локального phpmyadmin с пикчами в базе. Они вроде загрузились правильно. Почему вместо изображения у меня отображается квадратик? Прикладываю код в ideone (смотреть сразу на 30-ю строку лучше), но если у вас есть силы и желание помочь - просмотрите код глазами, там куча пояснений, чтобы было понятно. заранее благодарен, анончики.
https://ideone.com/JQVunA
887 748534
>>48528
Поправил: там на 37 строке ошибка.

Но я делаю так: извлекаю всю инфу о пикче,
кладу ее в $image = mysqli_fetch_array($result);
дальше header('Content-type: image/jpeg; charset=utf-8');
и получение инфы из блоба
echo $image['image_data'];
Но нихуя не работает. Что локально на сервере, что на сайте (там та же фигня).
888 748535
>>48534
Это, анон, я имею ввиду, что я не ошибку поправил, а поправил указание на ошибку, я не разобрался с этой херней. Помогите, пожалуйста.
889 748556
>>48528
Короче, анончик, разобрался я.
У меня в файле с коннектом к базе данных был лишний вывод инфы, вроде "база данных подключена". Этот кал примешивался к выводу инфы из блоба и пикча ломалась.
890 748624
>>48497

>anton.shevchuk.name


Спасибо, но нет.
Это ж каким дятлом надо быть, чтобы на собственном домене сделать поддомен со своим именем?
891 748633

> Каждое собеседование начинается с одного и того же вопроса:


> – Почему PHP?


> И, как ни странно, некоторые умудряются “засыпаться” уже на нем



Какой правильный ответ?

Я выбрал php потому что он самый популярный, на нем много заказов, и под него много библиотек и фреймворков.
Я люблю программирование, а язык только инструмент, и мне глубоко по-барабану на каком языке писать.
Было бы время, с удовольствием выучил бы новый, если это необходимо.
Не знаю, "правильный" ли это ответ, но я бы ответил так.
892 748637
>>48633
Часто важна не правильность ответа, а его адекватность.
Вот у тебя адекватный ответ.
А начнёшь дёргаться, говорить "похапе", "я хз" и подобное - будет не адекватный.
893 748670
>>48416

Это относится к тем данным которые в итоге оказываются внутри <a href="...">, img src=, iframe src=, то есть внутри определенных атрибутов тегов. Если данные выводятся как обычный текст, то проблемы нет - не забывай только про htmlspecialchars.

>>48421

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

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

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

Кстати самый простой и минимальный тест - это просто вызвать функцию или открыть страницу. даже такой тест позволит отлавливать определенные виды ошибок.

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

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

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

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

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

Так что начни с того, что посмотри на свои классы и функции и выбери наиболее важные и сложные.

Юнит-тесты это тесты, тестирующие одну функцию или класс отдельно от других. Они не используют базу данных (кстати здесь проявляется преимущество data mapper, мы можем использовать модели без базы данных). Файловую систему и тем более сеть тоже не стоит использовать, так как это все усложняет, делает тесты более хрупкими и увеличивает объем кода который мы тестируем.

Тестировать функции, использующие базу, можно так:

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

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

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

Также, читай статьи на хабре в блоге яндекса про тестирование - там много интересного.
893 748670
>>48416

Это относится к тем данным которые в итоге оказываются внутри <a href="...">, img src=, iframe src=, то есть внутри определенных атрибутов тегов. Если данные выводятся как обычный текст, то проблемы нет - не забывай только про htmlspecialchars.

>>48421

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

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

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

Кстати самый простой и минимальный тест - это просто вызвать функцию или открыть страницу. даже такой тест позволит отлавливать определенные виды ошибок.

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

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

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

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

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

Так что начни с того, что посмотри на свои классы и функции и выбери наиболее важные и сложные.

Юнит-тесты это тесты, тестирующие одну функцию или класс отдельно от других. Они не используют базу данных (кстати здесь проявляется преимущество data mapper, мы можем использовать модели без базы данных). Файловую систему и тем более сеть тоже не стоит использовать, так как это все усложняет, делает тесты более хрупкими и увеличивает объем кода который мы тестируем.

Тестировать функции, использующие базу, можно так:

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

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

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

Также, читай статьи на хабре в блоге яндекса про тестирование - там много интересного.
894 748683
>>48421

Ну давай пройдемся по коду и посмотрим что стоит тестировать юнит-тестами. Вот я открываю первый попавшийся файл: https://github.com/nsdvw/TestHub/blob/master/src/AppBundle/Helper/StringGenerator.php

Что мы тут видим? В глаза бросается бессмысленный вызов sha1, который только вхолостую тратит процессорные циклы и природный газ на электростанции, не выполняя никакой полезной функции. Ладно, сегодня мы пришли не за этим.

Мы видим 2 публичные функции, разницу между которыми я плохо понимаю:

- generateToken()
- generateString()

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

Итак, как протестировать generateString()? Надеюсь ты помнишь, что самый простой способ - это просто вызвать функцию. Этот способ отловит например программные ошибки внутри нее вроде бесконечного цикла или обращения к несущестсующей переменной. Пишем:

class StringGeneratorTest extends ...
public function testGenerateString()
{
StringGenerator::generateString();
}

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

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

- проверяем что возвращается строка
- проверяем что ее длина равна N символов
- хорошо бы проверить что символы случайные, но я плохо представляю как это сделать. В теории генератор случайных символов может выжать любую последовательность символов. Есть тесты генераторов случайных чисел (https://en.wikipedia.org/wiki/Randomness_tests), которые считают разные параметры статистики (вроде частоты выпадения символов и числа повторов), но им обычно требуются огромные объем данных, сотни мегабайт, и даже в этом случае мы тестируем нестолкьо саму нашу функцию сколько встроенный в php mt_rand. Потому забьем на это.

Ну или мы можем использовать упрощенный тест: сгенерировать 3-4 строки и проверить что среди них есть хотя бы 2 уникальных строки. Конечно генератор случайных чисел может выдать 4 одинаковых случайных 40-символьных строки, но вероятность этого сопоставима с вероятностью что завтра наша планета провалится в черную дыру. И если она провалится, то плохо работающий тест будет нас беспокоить меньше всего.

(кстати это как раз был пример творческого подхода к решению задачи. нам подходит не математически идеальное, но работающее решение)

Все ли хорошо? Нет, не все. Мы закладываем в тест длину генерируемой строки. Но что если завтра мы решим усилить защиту и повысим длину токена? тест упадет. Более того, функция называется generateString и она генерирует просто строки, а не токены. Хватит проверки, что строка не пустая.

А если взять функцию генерации токена, надо ли проверять что длина токена равна N? Давай подумаем, а какая вообще должна быть длина токена? Какие у нас к нему требования?

В нем не должно быть слишком мало символов (так как он тогда ничего не защищает) и не должно быть слишком много (так как у кук есть ограничение в 4 Кб на куки для одного домена). Вот и ответ. Для токена мы должны проверить, что:

- это строка
- что в 3-4 токенах есть различные строки
- она длиннее X символов
- она короче Y символов

-----

Ну, это было просто, давай поищем что-нибудь посложнее.
894 748683
>>48421

Ну давай пройдемся по коду и посмотрим что стоит тестировать юнит-тестами. Вот я открываю первый попавшийся файл: https://github.com/nsdvw/TestHub/blob/master/src/AppBundle/Helper/StringGenerator.php

Что мы тут видим? В глаза бросается бессмысленный вызов sha1, который только вхолостую тратит процессорные циклы и природный газ на электростанции, не выполняя никакой полезной функции. Ладно, сегодня мы пришли не за этим.

Мы видим 2 публичные функции, разницу между которыми я плохо понимаю:

- generateToken()
- generateString()

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

Итак, как протестировать generateString()? Надеюсь ты помнишь, что самый простой способ - это просто вызвать функцию. Этот способ отловит например программные ошибки внутри нее вроде бесконечного цикла или обращения к несущестсующей переменной. Пишем:

class StringGeneratorTest extends ...
public function testGenerateString()
{
StringGenerator::generateString();
}

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

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

- проверяем что возвращается строка
- проверяем что ее длина равна N символов
- хорошо бы проверить что символы случайные, но я плохо представляю как это сделать. В теории генератор случайных символов может выжать любую последовательность символов. Есть тесты генераторов случайных чисел (https://en.wikipedia.org/wiki/Randomness_tests), которые считают разные параметры статистики (вроде частоты выпадения символов и числа повторов), но им обычно требуются огромные объем данных, сотни мегабайт, и даже в этом случае мы тестируем нестолкьо саму нашу функцию сколько встроенный в php mt_rand. Потому забьем на это.

Ну или мы можем использовать упрощенный тест: сгенерировать 3-4 строки и проверить что среди них есть хотя бы 2 уникальных строки. Конечно генератор случайных чисел может выдать 4 одинаковых случайных 40-символьных строки, но вероятность этого сопоставима с вероятностью что завтра наша планета провалится в черную дыру. И если она провалится, то плохо работающий тест будет нас беспокоить меньше всего.

(кстати это как раз был пример творческого подхода к решению задачи. нам подходит не математически идеальное, но работающее решение)

Все ли хорошо? Нет, не все. Мы закладываем в тест длину генерируемой строки. Но что если завтра мы решим усилить защиту и повысим длину токена? тест упадет. Более того, функция называется generateString и она генерирует просто строки, а не токены. Хватит проверки, что строка не пустая.

А если взять функцию генерации токена, надо ли проверять что длина токена равна N? Давай подумаем, а какая вообще должна быть длина токена? Какие у нас к нему требования?

В нем не должно быть слишком мало символов (так как он тогда ничего не защищает) и не должно быть слишком много (так как у кук есть ограничение в 4 Кб на куки для одного домена). Вот и ответ. Для токена мы должны проверить, что:

- это строка
- что в 3-4 токенах есть различные строки
- она длиннее X символов
- она короче Y символов

-----

Ну, это было просто, давай поищем что-нибудь посложнее.
895 748693
>>48683
Вот ты накатал 2 полотна, буду до ночи читать только.

>Ну, это было просто, давай поищем что-нибудь посложнее.


Наверное, опоздал, и ты там выбрал уже что-то другое, но только что накатал большой метод для вычисления результатов теста.
Вот тут точно нужны тесты.
https://github.com/nsdvw/TestHub/blob/master/src/TestHubBundle/Service/Calculator.php
896 748697
>>48421

далее я иду в папку сервисов и вижу:

https://github.com/nsdvw/TestHub/blob/master/src/TestHubBundle/Service/Calculator.php

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

Теперь перейдем к классу поинтереснее: https://github.com/nsdvw/TestHub/blob/master/src/TestHubBundle/Service/TestService.php

Тут есть работа с базой. Прочитаем http://symfony.com/doc/current/cookbook/testing/database.html и понимаем что у нас такие варианты:

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

Посмотрим функции:

- findLastAttempt(Test $test, User $user) - нет особого смысла тестировать так как элементарный код
- createNewAttempt(Test $test, User $user) - нет особого смысла тестировать, плюс она еще и persist + flush зачем-то делает, мешая пользователю управлять транзакцией
- getUnansweredCount(Attempt $attempt) - в принципе можно протестировать интеграционно, хотя функция сама несложная
- public function findByNum($sequenceNumber, $testId) - кода в ней почти нет, тестировать нечего. При желании можно тестировать интеграционно, вставить в БД вопрос и попробовать найти
- questionAlreadyHasAnswer(Attempt $attempt, Question $question) - только интеграционно
- getFirstUnanswered(Attempt $attempt) - только интеграционно
- getNextUnansweredNumber(Attempt $attempt, $num) - интеграционно

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

Интеграционный тест лучше делать на отдельной базе расположенной в памяти, чтобы не тратить время на дисковые операции. Скрипт должен создать базу, залить в нее дампы или миграции, и только после запускать интеграционные тесты. Тесты надо писать изолированно, чтобы созданные одним тестом записи не ломали бы дргуие. Некоторые делают тест внутри транзакции, откатывая ее после теста. Некоторые после/перед тестом очищают таблицы в БД.
896 748697
>>48421

далее я иду в папку сервисов и вижу:

https://github.com/nsdvw/TestHub/blob/master/src/TestHubBundle/Service/Calculator.php

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

Теперь перейдем к классу поинтереснее: https://github.com/nsdvw/TestHub/blob/master/src/TestHubBundle/Service/TestService.php

Тут есть работа с базой. Прочитаем http://symfony.com/doc/current/cookbook/testing/database.html и понимаем что у нас такие варианты:

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

Посмотрим функции:

- findLastAttempt(Test $test, User $user) - нет особого смысла тестировать так как элементарный код
- createNewAttempt(Test $test, User $user) - нет особого смысла тестировать, плюс она еще и persist + flush зачем-то делает, мешая пользователю управлять транзакцией
- getUnansweredCount(Attempt $attempt) - в принципе можно протестировать интеграционно, хотя функция сама несложная
- public function findByNum($sequenceNumber, $testId) - кода в ней почти нет, тестировать нечего. При желании можно тестировать интеграционно, вставить в БД вопрос и попробовать найти
- questionAlreadyHasAnswer(Attempt $attempt, Question $question) - только интеграционно
- getFirstUnanswered(Attempt $attempt) - только интеграционно
- getNextUnansweredNumber(Attempt $attempt, $num) - интеграционно

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

Интеграционный тест лучше делать на отдельной базе расположенной в памяти, чтобы не тратить время на дисковые операции. Скрипт должен создать базу, залить в нее дампы или миграции, и только после запускать интеграционные тесты. Тесты надо писать изолированно, чтобы созданные одним тестом записи не ломали бы дргуие. Некоторые делают тест внутри транзакции, откатывая ее после теста. Некоторые после/перед тестом очищают таблицы в БД.
897 748701
>>48421

Наконец посмтрим еще сюда: https://github.com/nsdvw/TestHub/blob/master/src/TestHubBundle/Controller/TestController.php

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

> Что тут собственно тестировать? Получение данных из бд и то что методы возвращают объект ожидаемого класса?


Если функция тривиальная то можно не тестировать.

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


Юнит тесты не работают с БД, только если интеграционные.
898 748731
>>48528

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

> Content-type: image/jpeg; charset=utf-8


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

>>48633

А почему не ответить честно? Вообще, вопрос глупый так как ответ на него ничего не дает. Я бы никогда таких вопросов не спрашивал.
899 748736
>>48731

>а в базе хранить только информацию о них.


Давно хотел спросить а зачем это? Ну типа может там для каких-то картиночных хостингов актуально, а так например пользователь грузит аватарку зачем везде создают отдельную таблицу и хранят об этом инфу? Можно завести папку с айдишником пользователя и аватары переименовывать в avatar.jpg ну если надо будет найти и удалить.
900 748746
>>48736

Может для верстки надо знать ширину картинки. Ну и если загрузка картинки опциональная, можно с помощью запроса найти пользователей без аватарок.
901 748748
>>48736

Ну и ты мыслишь ограниченно. Большие веб-приложения часто работают на нескольких серверах и хранилище картинок может быть отдельно. Без базы проверить есть ли у пользователя картинка, никак нельзя (дикие варианты вроде сетевых файловых систем сразу отбросим).
902 748819
Пардон муа, прелюбодействую в очи: где располагаются задачки для изучения MySQL?
903 748821
>>48819
Снова пардон, мадам и месье:

>- MySQL: https://gist.github.com/codedokode/10539213

904 748907
>>48731
Я честно и говорю, что выбрал php из-за популярности, комьюнити и рынка вакансий.
Просто непонятно в чем подвох, может они хотят отсеять вованов с мотивацией уровня "мне на сосаче сказали что в айти можно легко зашибать бабло, ничего не делая".

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

>>48683

>В глаза бросается бессмысленный вызов sha1, ... не выполняя никакой полезной функции.


Этот класс задумывался как генератор для хеша соленого пароля в первую очередь. Потом я подумал, что наверное уже есть какой-то бандл для авторизации, типа FOS UserBundle. Но класс пригодился для тупой генерации токена доступа для неавторизованного пользователя.
Впрочем да, зачем его пропускать через функцию хеширования? Наверное удалю метод с хешированием, пусть останется только generateString, может она еще где-нибудь пригодится. (Опять таки наверняка где-то в недрах фреймворка есть класс для генерации рандомной строки, но я пока что-то не нашел, нагуглил какой-то Symfony\Component\Security\Core\Util\SecureRandom но это походу только во второй версии, я пользуюсь третьей).

Логику что тестировать в целом понял (по крайней мере для таких примитивных случаев), вот что получилось
http://ideone.com/UugEm1

Но даже здесь есть много вопросов
1. В симфони нет бандла для тестирования?
Если наследоваться от \PHPUnit_Framework_TestCase он говорит нет такого класса,
и не автодополняет. И сам phpunit я качаю phar архивом, наверняка оно там где-то
уже лежит в папке вендор, знать бы где.

2. Писать отдельный тест (метод в классе теста) под метод тестируемого класса?
Или можно написать несколько тестов для одного метода класса?
Например в случае StringGenerator::generateString нам нужно протестировать
что он возвращает строку,
что эта строка уникальна, и
что ее длина между X и Y (кстати сразу вопрос, 2.1.можно выставить левые значения
для X и Y, или таки эти значения нужно брать из какого-то конфига? подозреваю что
их можно засунуть в phpunit.xml, только не знаю куда именно)
Это отдельные тесты (методы класса теста), или можно в одном нафигачить кучу ассертов?
Походу отдельные, причем они зависят друг от друга, ну то есть можно скипать все
остальные, если первый тест провалился (где тип возвращаемого результата проверяется
на строку).
Какие имена им давать тогда, или по-барабану?

3. Насколько позволительно использовать в тестах постороннюю логику?
Вот я например хочу проверить уникальность генерируемой строки, создав несколько
(опять-таки, сколько? хардкодить число, или выносить непонятно куда?) строк,
положить в массив, и сделать
for($i = 0; $i < $iterations; $i++){$randoms[] = ...}
$this->assertEquals($iterations, count(array_unique($randoms)));
То есть тут две левые функции: count со вложенным array_unique. Я конечно не сомневаюсь
в том что они никогда не сломаются, просто логика может быть сложнее, наверное
таких ситуаций нужно избегать, а то не хватало еще тестировать тесты.
904 748907
>>48731
Я честно и говорю, что выбрал php из-за популярности, комьюнити и рынка вакансий.
Просто непонятно в чем подвох, может они хотят отсеять вованов с мотивацией уровня "мне на сосаче сказали что в айти можно легко зашибать бабло, ничего не делая".

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

>>48683

>В глаза бросается бессмысленный вызов sha1, ... не выполняя никакой полезной функции.


Этот класс задумывался как генератор для хеша соленого пароля в первую очередь. Потом я подумал, что наверное уже есть какой-то бандл для авторизации, типа FOS UserBundle. Но класс пригодился для тупой генерации токена доступа для неавторизованного пользователя.
Впрочем да, зачем его пропускать через функцию хеширования? Наверное удалю метод с хешированием, пусть останется только generateString, может она еще где-нибудь пригодится. (Опять таки наверняка где-то в недрах фреймворка есть класс для генерации рандомной строки, но я пока что-то не нашел, нагуглил какой-то Symfony\Component\Security\Core\Util\SecureRandom но это походу только во второй версии, я пользуюсь третьей).

Логику что тестировать в целом понял (по крайней мере для таких примитивных случаев), вот что получилось
http://ideone.com/UugEm1

Но даже здесь есть много вопросов
1. В симфони нет бандла для тестирования?
Если наследоваться от \PHPUnit_Framework_TestCase он говорит нет такого класса,
и не автодополняет. И сам phpunit я качаю phar архивом, наверняка оно там где-то
уже лежит в папке вендор, знать бы где.

2. Писать отдельный тест (метод в классе теста) под метод тестируемого класса?
Или можно написать несколько тестов для одного метода класса?
Например в случае StringGenerator::generateString нам нужно протестировать
что он возвращает строку,
что эта строка уникальна, и
что ее длина между X и Y (кстати сразу вопрос, 2.1.можно выставить левые значения
для X и Y, или таки эти значения нужно брать из какого-то конфига? подозреваю что
их можно засунуть в phpunit.xml, только не знаю куда именно)
Это отдельные тесты (методы класса теста), или можно в одном нафигачить кучу ассертов?
Походу отдельные, причем они зависят друг от друга, ну то есть можно скипать все
остальные, если первый тест провалился (где тип возвращаемого результата проверяется
на строку).
Какие имена им давать тогда, или по-барабану?

3. Насколько позволительно использовать в тестах постороннюю логику?
Вот я например хочу проверить уникальность генерируемой строки, создав несколько
(опять-таки, сколько? хардкодить число, или выносить непонятно куда?) строк,
положить в массив, и сделать
for($i = 0; $i < $iterations; $i++){$randoms[] = ...}
$this->assertEquals($iterations, count(array_unique($randoms)));
То есть тут две левые функции: count со вложенным array_unique. Я конечно не сомневаюсь
в том что они никогда не сломаются, просто логика может быть сложнее, наверное
таких ситуаций нужно избегать, а то не хватало еще тестировать тесты.
905 748914
>>29430 (OP)
Сап товарищи.
Такой вопрос. На сайт выводятся вопросы из базы данных в случайном порядке. Но вот вопрос, как можно сделать, чтобы запрос к базе обновлялся, переодически ?
Есть ли какой-то аналог setInterval(), только в PHP ?
906 748959
>>48907

> В симфони нет бандла для тестирования?


не знаю, погугли

> Писать отдельный тест (метод в классе теста) под метод тестируемого класса?


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

> не автодополняет.


Можно в композере прописать phpunit в require-dev или установить его в какую-нибудь левую папку. Ну и вообще, в пхпсторме наверно можно как-то включить поддержку автодополнения

> Это отдельные тесты (методы класса теста), или можно в одном нафигачить кучу ассертов?


Они все свзяаны так что не вижу смысла раскидывать по разным методам. Какая от этого польза?

> кстати сразу вопрос, 2.1.можно выставить левые значения


для X и Y, или таки эти значения нужно брать из какого-то конфига?
Прописать как цифры в тесте. Не надо усложнять.

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


> остальные, если первый тест провалился (где тип возвращаемого результата проверяется


> на строку).


Это как раз значит 1 тест

> Какие имена им давать тогда, или по-барабану?


В названии функции ты пишешь что хочешь протестировать

> . Насколько позволительно использовать в тестах постороннюю логику?


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

> То есть тут две левые функции: count со вложенным array_unique.


Их тестируют разработчики языка php и я думаю что они надежные.

Для проверки типа есть https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertInternalType

> $this->assertEquals($iterations, count(array_unique($randoms)));


Я бы для надежности тестировал что там есть хотя бы 2 разных строки. А не что их ровно 5.

> mb_internal_encoding('utf8');


Это должно быть в bootstrap.php. Не надо менять глобальные натсройки посередине одного теста, влияя на все другие

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

Ну, это была самая простая функция, давай что-ниьудь посложнее тестировать тоже.
906 748959
>>48907

> В симфони нет бандла для тестирования?


не знаю, погугли

> Писать отдельный тест (метод в классе теста) под метод тестируемого класса?


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

> не автодополняет.


Можно в композере прописать phpunit в require-dev или установить его в какую-нибудь левую папку. Ну и вообще, в пхпсторме наверно можно как-то включить поддержку автодополнения

> Это отдельные тесты (методы класса теста), или можно в одном нафигачить кучу ассертов?


Они все свзяаны так что не вижу смысла раскидывать по разным методам. Какая от этого польза?

> кстати сразу вопрос, 2.1.можно выставить левые значения


для X и Y, или таки эти значения нужно брать из какого-то конфига?
Прописать как цифры в тесте. Не надо усложнять.

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


> остальные, если первый тест провалился (где тип возвращаемого результата проверяется


> на строку).


Это как раз значит 1 тест

> Какие имена им давать тогда, или по-барабану?


В названии функции ты пишешь что хочешь протестировать

> . Насколько позволительно использовать в тестах постороннюю логику?


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

> То есть тут две левые функции: count со вложенным array_unique.


Их тестируют разработчики языка php и я думаю что они надежные.

Для проверки типа есть https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertInternalType

> $this->assertEquals($iterations, count(array_unique($randoms)));


Я бы для надежности тестировал что там есть хотя бы 2 разных строки. А не что их ровно 5.

> mb_internal_encoding('utf8');


Это должно быть в bootstrap.php. Не надо менять глобальные натсройки посередине одного теста, влияя на все другие

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

Ну, это была самая простая функция, давай что-ниьудь посложнее тестировать тоже.
https://github.com/someApprentice/Students/ ответы 907 748987
>>41980

https://github.com/someApprentice/Students/

> Я решил что не только ПомощникРегистрации должен заниматься ридеректом, и решил вынести функции редиректа в отдельный родительский класс


Тогда можно его и использовать, а ResgistrationHelper можно удалять так как в нем нет методов и непонятно зачем он вообще нужен.

https://github.com/someApprentice/Students/blob/master/app/Model/Helper/Helper.php
Странная функция. Если URL соответствует шаблону, она редиректит, а если нет - то нет. И что происходит в этом случае? Я бы просто редиректил на главную например.

> Не портит ли это модель?


Модель не занимается редиректами. Это относится к контроллеру или представлению.

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


Именно так. authorizer должен отвечать за залогинивание и проверку авторизации. У тебя он как-то странно используется. Ну например:

$registerStudentForm->setStudentPassword($this->authorizer);

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

А зачем форме знать про класс авторизации? Как они связаны? Если тебе надо взять пароль из формы и проставить студенту через сторонний класс то можно так и сдеать:

пароль = форма->получитьПароль
сервисАвторизации->назначитьПароль(студент, пароль)

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

пароль = форма->получитьПароль
студент->назначитьПароль(пароль)

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

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

> Здесь присутствует копипаста метода. Будет ли лучше вынести этот метод в отдельный класс Entity


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

Также, этот метод явно неправильный:

> https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Student.php#L40


> fillDataFromDB(array $result)


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

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


Я не против, но она должна быть сделана разумно. Ну например если ты используешь фамилию то ты должен отказываться принимать ее, если она не уникальна в базе. Или требовать имя + фамилию.

>>Но и в этом случае сессия не нужна.


> Сессиями больше не пользуются?


Тут просто кук же хватит, зачем сессия?

> Если бы я пользовался куками, данные, такие как Имя, Фамилия, Возраст и так далее, тоже были бы лишними?


Конечно, лишние. Достаточно иметь id, все данные студента есть в базе. Какая выгода от дублирования? От этого наоборот проблемы. Представь что студент залогинен с 2 разных устройств и имеет 2 сессии. Он меняет свою фамилию. Поменяется ли она в обоих сессиях? Очевидно нет.

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

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


по моему ты переусложнил алгоритм. Алгоритм там пишется так:

----

пусть у нас есть "логин", который может быть фамилией либо емайлом, и "пароль"

если (логин выглядит как емайл и (в базе есть студент с таким емайлом и паролем)) {
то это он
выходим
}

если (логин (соответствует фамилии ровно одного студента и пароль подходит)) то {
студент найден
выходим
}

иначе не удалось авторизоваться

----

Я тут не вижу циклов и сложных манипуляций массивами. Достаточно сделать 2 метода: авторизоватьсяПоФамилии и авторизоватьсяПоемайлу и вызвать их по очереди.

> Так это нужно вызывать в ручную? Я собираюсь прямо по среди цикла делать ридерект, даже если я пропишу break или die после этого, ридерект не сломает мой код?


Наверно нет. А как он сломает код?

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


> В консоли или через API обычно передают $_POST? Если да, то смогу - контроллер всегда вызывает валидатор если есть $_POST. Если нет, то мне придется переделывать контроллер чтобы он принимал в аргументы логин и пароль или еще что-то поменять. Ведь контролер же занимается пришедшими данными из вне?


В консоли нет никакого POST. POST это данные пришедшие в теле HTTP запроса который получил от браузера веб-сервер. В консоли нет ни браузера, ни запроса от него, ни веб-сервера и значит в POST ничего не будет.

> Если нет, то мне придется переделывать контроллер чтобы он принимал в аргументы логин и пароль или еще что-то поменять


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

Если что-то непонятно, задавай уточняющие вопросы. И старайся определить, за что отвечает каждый класс, как мы распределим обязанности. Это конечно не всегда просто, так что придется поломать голову.
https://github.com/someApprentice/Students/ ответы 907 748987
>>41980

https://github.com/someApprentice/Students/

> Я решил что не только ПомощникРегистрации должен заниматься ридеректом, и решил вынести функции редиректа в отдельный родительский класс


Тогда можно его и использовать, а ResgistrationHelper можно удалять так как в нем нет методов и непонятно зачем он вообще нужен.

https://github.com/someApprentice/Students/blob/master/app/Model/Helper/Helper.php
Странная функция. Если URL соответствует шаблону, она редиректит, а если нет - то нет. И что происходит в этом случае? Я бы просто редиректил на главную например.

> Не портит ли это модель?


Модель не занимается редиректами. Это относится к контроллеру или представлению.

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


Именно так. authorizer должен отвечать за залогинивание и проверку авторизации. У тебя он как-то странно используется. Ну например:

$registerStudentForm->setStudentPassword($this->authorizer);

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

А зачем форме знать про класс авторизации? Как они связаны? Если тебе надо взять пароль из формы и проставить студенту через сторонний класс то можно так и сдеать:

пароль = форма->получитьПароль
сервисАвторизации->назначитьПароль(студент, пароль)

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

пароль = форма->получитьПароль
студент->назначитьПароль(пароль)

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

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

> Здесь присутствует копипаста метода. Будет ли лучше вынести этот метод в отдельный класс Entity


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

Также, этот метод явно неправильный:

> https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Student.php#L40


> fillDataFromDB(array $result)


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

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


Я не против, но она должна быть сделана разумно. Ну например если ты используешь фамилию то ты должен отказываться принимать ее, если она не уникальна в базе. Или требовать имя + фамилию.

>>Но и в этом случае сессия не нужна.


> Сессиями больше не пользуются?


Тут просто кук же хватит, зачем сессия?

> Если бы я пользовался куками, данные, такие как Имя, Фамилия, Возраст и так далее, тоже были бы лишними?


Конечно, лишние. Достаточно иметь id, все данные студента есть в базе. Какая выгода от дублирования? От этого наоборот проблемы. Представь что студент залогинен с 2 разных устройств и имеет 2 сессии. Он меняет свою фамилию. Поменяется ли она в обоих сессиях? Очевидно нет.

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

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


по моему ты переусложнил алгоритм. Алгоритм там пишется так:

----

пусть у нас есть "логин", который может быть фамилией либо емайлом, и "пароль"

если (логин выглядит как емайл и (в базе есть студент с таким емайлом и паролем)) {
то это он
выходим
}

если (логин (соответствует фамилии ровно одного студента и пароль подходит)) то {
студент найден
выходим
}

иначе не удалось авторизоваться

----

Я тут не вижу циклов и сложных манипуляций массивами. Достаточно сделать 2 метода: авторизоватьсяПоФамилии и авторизоватьсяПоемайлу и вызвать их по очереди.

> Так это нужно вызывать в ручную? Я собираюсь прямо по среди цикла делать ридерект, даже если я пропишу break или die после этого, ридерект не сломает мой код?


Наверно нет. А как он сломает код?

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


> В консоли или через API обычно передают $_POST? Если да, то смогу - контроллер всегда вызывает валидатор если есть $_POST. Если нет, то мне придется переделывать контроллер чтобы он принимал в аргументы логин и пароль или еще что-то поменять. Ведь контролер же занимается пришедшими данными из вне?


В консоли нет никакого POST. POST это данные пришедшие в теле HTTP запроса который получил от браузера веб-сервер. В консоли нет ни браузера, ни запроса от него, ни веб-сервера и значит в POST ничего не будет.

> Если нет, то мне придется переделывать контроллер чтобы он принимал в аргументы логин и пароль или еще что-то поменять


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

Если что-то непонятно, задавай уточняющие вопросы. И старайся определить, за что отвечает каждый класс, как мы распределим обязанности. Это конечно не всегда просто, так что придется поломать голову.
Ответы 13 мая 908 748988
>>42020

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

> Просто я не знаю, как сделать второй случай без Query Builder.


Можно сделать у функции получения студентов параметр $search и если он равен null то поиск не проводится, возвращаются все студенты. Тут не нужен Query Builder я думаю.

>>42023

Модно передавать параметры функции массивом, можно по отдельности, только она должна называться не build а например getStudents

>>42260

Ты наверно переусложняешь. У тебя же этим будет заниматься крон-скрипт, который просто ищет в базе пользователей по определенным условиям. Тут можно сделать класс типа Trigger и User.

---

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

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

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

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

>>42569

Скорее всего никак. Ну или подготовить этот xls заранее, сохранить на диск и отдавать с диска.
Ответы 13 мая 908 748988
>>42020

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

> Просто я не знаю, как сделать второй случай без Query Builder.


Можно сделать у функции получения студентов параметр $search и если он равен null то поиск не проводится, возвращаются все студенты. Тут не нужен Query Builder я думаю.

>>42023

Модно передавать параметры функции массивом, можно по отдельности, только она должна называться не build а например getStudents

>>42260

Ты наверно переусложняешь. У тебя же этим будет заниматься крон-скрипт, который просто ищет в базе пользователей по определенным условиям. Тут можно сделать класс типа Trigger и User.

---

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

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

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

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

>>42569

Скорее всего никак. Ну или подготовить этот xls заранее, сохранить на диск и отдавать с диска.
ОТветы 13 мая 909 748989
>>42788

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

>>42860

Открывай developer tools и смотри что получается в переменной, что отправляется. Вообще, конечно в коде каждая вторая строка с ошибками, ад какой-то. Ну например, объясни почему ты не проверяешь при отправке запроса ситуацию, когда произолшла ошибка? Почему не блокируешь кнопку на время отправки? Почему у тебя $("#userArea") 2 раза встречается? Зачем инклудить ajaxLoad.php? Зачем замедлять загрузку страницы дополнительным аякс запросом?

Зачем у тебя слеши в конце одиночных тегов?

>>43295

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

Для вывода формы достаточно писать {{ form(form) }}

>>43671

ну можно от себя пару букв добавить в массив например

>>43898

Верно.

>>44230

> А если некий шаблон выводят разные контроллеры и им нужен свой хедер или вообще его отсутствие?


Можно сделать переменную $headerTemplate и инклудить через нее. Или можно сделать файл layout.php который отвечает за шапку/подвал и подключает шаблон с содержимым.

> А если добавлю метод валидации другим классом? Отдам ему данные с формы и получу от него ошибки. На пике накидал пример.


Мне кажется что конструировать форму лучше в классе формы. а не контроллере. То есть сделат клас например StudentForm. Не уверен что стоит использовать формы для обработки параметров сортировки таблицы - это возможно, но мне кажется переусложнением. Хотя можно и так.
ОТветы 13 мая 909 748989
>>42788

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

>>42860

Открывай developer tools и смотри что получается в переменной, что отправляется. Вообще, конечно в коде каждая вторая строка с ошибками, ад какой-то. Ну например, объясни почему ты не проверяешь при отправке запроса ситуацию, когда произолшла ошибка? Почему не блокируешь кнопку на время отправки? Почему у тебя $("#userArea") 2 раза встречается? Зачем инклудить ajaxLoad.php? Зачем замедлять загрузку страницы дополнительным аякс запросом?

Зачем у тебя слеши в конце одиночных тегов?

>>43295

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

Для вывода формы достаточно писать {{ form(form) }}

>>43671

ну можно от себя пару букв добавить в массив например

>>43898

Верно.

>>44230

> А если некий шаблон выводят разные контроллеры и им нужен свой хедер или вообще его отсутствие?


Можно сделать переменную $headerTemplate и инклудить через нее. Или можно сделать файл layout.php который отвечает за шапку/подвал и подключает шаблон с содержимым.

> А если добавлю метод валидации другим классом? Отдам ему данные с формы и получу от него ошибки. На пике накидал пример.


Мне кажется что конструировать форму лучше в классе формы. а не контроллере. То есть сделат клас например StudentForm. Не уверен что стоит использовать формы для обработки параметров сортировки таблицы - это возможно, но мне кажется переусложнением. Хотя можно и так.
Ответы 15 мая 910 748990
>>44246

> $endingNumber = $endingNumber % 100;


> } else {


> $endingNumber = $endingNumber % 10;


по моему это усложняет функцию. проще просто провеярть, если число от 11 до 19 то возвращать определенный вариант сразу.

> function smallNumberToarrayOfWords($number, $end)


тут по моему проще поместить массив $end внутрь функции либо сделать отдельную функцию возвращающую его

> echo "На вашем счету ноль рублей";


> exit;


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

> if ($discharge == 0 && $key == 2) {


> $numberOfWord++;


> $arrayOfWords[$numberOfWord] = "рублей";


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

> $arrayOfWords[$numberOfWord]


Переменная $numberOfWord не нужна

> function writeThousand($key, $discharge, $spelling) {


Если смотреть только на эту функцию то непонятно что за переменная key. По моему так ее надо заменить на что-то более понятное. например переменную обозначающую род слова.

калькулятор

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

Это позволит вместо 3 регулярок обойтись одной.

Ну вот например ошибка: http://ideone.com/2UHnq2
Или вот: http://ideone.com/AcQSgh
Ответы 15 мая 910 748990
>>44246

> $endingNumber = $endingNumber % 100;


> } else {


> $endingNumber = $endingNumber % 10;


по моему это усложняет функцию. проще просто провеярть, если число от 11 до 19 то возвращать определенный вариант сразу.

> function smallNumberToarrayOfWords($number, $end)


тут по моему проще поместить массив $end внутрь функции либо сделать отдельную функцию возвращающую его

> echo "На вашем счету ноль рублей";


> exit;


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

> if ($discharge == 0 && $key == 2) {


> $numberOfWord++;


> $arrayOfWords[$numberOfWord] = "рублей";


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

> $arrayOfWords[$numberOfWord]


Переменная $numberOfWord не нужна

> function writeThousand($key, $discharge, $spelling) {


Если смотреть только на эту функцию то непонятно что за переменная key. По моему так ее надо заменить на что-то более понятное. например переменную обозначающую род слова.

калькулятор

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

Это позволит вместо 3 регулярок обойтись одной.

Ну вот например ошибка: http://ideone.com/2UHnq2
Или вот: http://ideone.com/AcQSgh
Ответы 911 748991
>>44357

> .{15}(ж|ш)ы.


получается перед ошибкой должно идти не менее 15 символов?

>>45309

> когда мы пишем $attempt->answers->count(), там тоже втихаря идет обращение к бд. Только с вытягиванием из бд всех связанных записей, созданием их объектов (ну или прокси), и только потом у объекта ArrayCollection вызывается метод count, который возвращает кол-во записей.


Тут конечно нужно писать чистый sql/dql.
Кстати в доктрине для такого есть сверхленивые коллекции - они вычисляют count не загружая сами записи.

>>46525

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


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

> А можно еще как-то получать доступ к коэффициентам из класса Employee?


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

> Когда смотрел дамп компании увидел, что они копируются в каждом работнике. Там 1000 символов, в среднем по 2 бита на символ / 8 = 250 байт * 101(сотрудник) = 24 кБ, если я правильно посчитал


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

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

В общем, не стоит заниматься оптимизаиями, не зная осоюенностей внутреннего устройства php. Если интересно, гугли статьи на хабре и читай internals раздел в мануале:

https://www.gitbook.com/book/romka/php-internals-book-ru/details
https://secure.php.net/manual/ru/internals2.php

> Обращаться к методу класса Company->getCoefficients из класса Employee не правильно?


Можно и так

> т.к. рассчет зп можно было запускать только из контекста класса Company, и передавать коэффициенты как аргумент вызова метода по цепочке Company > Department > Employee. Ведь так тоже не очень?


сложновато. Вообще, я подумал, проще всего их прямо в employee и прописать.

> Паттерн "Стратегия" для изменения алгоритма расчета, а ведь тут меняется не алгоритм, а только коэффициенты?


верно

> Класс Profession отдельно, для того чтобы можно было поменять профессию у работника (Employee), и создавать новые классы профессий по шаблону родительского класса Profession. Идея была в том, что сторонний программист, создавая новый класс профессии должен переопределить обязательные методы для класса новой профессии. Хотя его можно убрать из кода, программа будет работать и без него.


Стоит оставить. Не надо убирать.

> Решил не создавать объект класса АтикризисныеМеры, а напрямую обратиться к его методу. Думал статические методы именно для этого.


Статические методы обычно используют в функциях, которым не нужен конкретный объект и $this, которые для всех экземпляров объекта работают одинково. Ну например фнкция перевода миль в километры. Тут лучше обычный объект и обычные методы. Так как Антикризисный КОмитет это вполне себе объект.
Ответы 911 748991
>>44357

> .{15}(ж|ш)ы.


получается перед ошибкой должно идти не менее 15 символов?

>>45309

> когда мы пишем $attempt->answers->count(), там тоже втихаря идет обращение к бд. Только с вытягиванием из бд всех связанных записей, созданием их объектов (ну или прокси), и только потом у объекта ArrayCollection вызывается метод count, который возвращает кол-во записей.


Тут конечно нужно писать чистый sql/dql.
Кстати в доктрине для такого есть сверхленивые коллекции - они вычисляют count не загружая сами записи.

>>46525

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


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

> А можно еще как-то получать доступ к коэффициентам из класса Employee?


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

> Когда смотрел дамп компании увидел, что они копируются в каждом работнике. Там 1000 символов, в среднем по 2 бита на символ / 8 = 250 байт * 101(сотрудник) = 24 кБ, если я правильно посчитал


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

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

В общем, не стоит заниматься оптимизаиями, не зная осоюенностей внутреннего устройства php. Если интересно, гугли статьи на хабре и читай internals раздел в мануале:

https://www.gitbook.com/book/romka/php-internals-book-ru/details
https://secure.php.net/manual/ru/internals2.php

> Обращаться к методу класса Company->getCoefficients из класса Employee не правильно?


Можно и так

> т.к. рассчет зп можно было запускать только из контекста класса Company, и передавать коэффициенты как аргумент вызова метода по цепочке Company > Department > Employee. Ведь так тоже не очень?


сложновато. Вообще, я подумал, проще всего их прямо в employee и прописать.

> Паттерн "Стратегия" для изменения алгоритма расчета, а ведь тут меняется не алгоритм, а только коэффициенты?


верно

> Класс Profession отдельно, для того чтобы можно было поменять профессию у работника (Employee), и создавать новые классы профессий по шаблону родительского класса Profession. Идея была в том, что сторонний программист, создавая новый класс профессии должен переопределить обязательные методы для класса новой профессии. Хотя его можно убрать из кода, программа будет работать и без него.


Стоит оставить. Не надо убирать.

> Решил не создавать объект класса АтикризисныеМеры, а напрямую обратиться к его методу. Думал статические методы именно для этого.


Статические методы обычно используют в функциях, которым не нужен конкретный объект и $this, которые для всех экземпляров объекта работают одинково. Ну например фнкция перевода миль в километры. Тут лучше обычный объект и обычные методы. Так как Антикризисный КОмитет это вполне себе объект.
Ответы 912 748992
>>46590

> Выполнил с использованием label с атрибутом for. Как можно обратится к label для установки фона когда внутри него находится input, с которого мы узнаём нажата кнопка или нет?


Никак нельзя, но можно после input поместить например спан или див и менять его свойства.

for неудобен тем что надо генерировать уникальные id.

Клавиатурная навигация работает, хорошо.

> .rb-container label {


> width: 50px;


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

> transition: 0.1s;


надо писать какие свойства участуют

> position: absolute;


> top: -1000px;


не лучше через opacity скрыть? 1000px не так и много, бьывают страницы выше.

Так, в общем, неплохо сделано.
913 748993
Напомню себе глянуть https://github.com/fidnex/students/
914 749215
>>48987

>> Не портит ли это модель?


>Модель не занимается редиректами. Это относится к контроллеру или представлению.


Моя вина, я имел ввиду модель программирования. Ведь так же можно выразиться о всей нашей MVC?

Перефразирую вопрос: Не выходит ли за рамки MVC использование в контроллере регистрации функции редиректа через сервис авторизации, а не через свой собственный хелпер? Ведь собственный хелпер, по сути, будет содержать те же методы что и сервис авториазации.
https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php#L42

>>48987

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


Потому что сначала нужно проверить пароль на валидность а потом уже хешировать его.

>>48987

>Если студент умеет сам ставить себе пароль, то можно сделать так:


>


>пароль = форма->получитьПароль


>студент->назначитьПароль(пароль)


Умение студента самому себе ставить пароль, это имеется ввиду собственная функция получения хэша?
Мне нравится больше такой подход, потому что тогда не придется писать отдельную функцию назначитьПарольДляСтудента(студент, пароль) в сервисте авторазации, но я не понимаю откуда мы будем получать хэш, в предложенном тобой методе, если форма\студент и класс авторизации никак не связанны?

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

Является ли сервис авторизации аутентификацией и при этом не является самой авторизацией?

>>48987

>> https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Student.php#L40


>> fillDataFromDB(array $result)


>Модель лучше отвязать от базы данных, а метод перенести в класс работы с БД. Вместо того чтобы поместмть работу с БД в один класс, ты ее размазываешь по 2 классам.


Но этот метод никак не работает с БД, он просто получает переданные данные оттуда. Почему этот метод относится больше к классу работы с БД, чем к классу студента, ведь он же с самой БД никак не взаимодействует, а только меняет данные в классе студента?

>И я не вижу смысла делать 2 метода fillFrom ... Я бы сделал олин метод, который ставит любые поля, а проверку по белому списку сделал бы где-то выше, например в классе формы.


Получается нужно белый список передавать в эту функцию fillFromArray($allowed, $array)? А как тогда передавать его в классе БД? Писать прямо по среди функции? Это же не его задача, почему класс с БД должен знать что есть какой-то белый список для студента?

public function getStudentByСolumn($column, $value)
{
...
$allowed = [...];
$student->fillDataFromArray($allowed, $result);
...
}

>>48987

>> Если бы я пользовался куками, данные, такие как Имя, Фамилия, Возраст и так далее, тоже были бы лишними?


>Конечно, лишние. Достаточно иметь id, все данные студента есть в базе.


Тогда при выводе данных нужно получать их из БД?

>>48987

>>>Но и в этом случае сессия не нужна.


>> Сессиями больше не пользуются?


>Тут просто кук же хватит, зачем сессия?


>А теперь объясни свою точку зрения. Почему надо использовать сессию вместо кук и почему надо в ней хранить имя и фамилию? Какая от этого выгода?


Если пользователь не захочет оставаться залогиненым, то можно использовать сессию, а не создавать кукисы на 30 минут. К тому же, пользователь не сможешь отредактировать сессии, в отличие от кук. Но я не настаиваю на сессиях. Просто не понятно, почему нет.

>и почему надо в ней хранить имя и фамилию? Какая от этого выгода?


Когда я решал эту задачу я отталкивался от нашей старой задачи на простую регистрацию, где мы делали её процедурно https://github.com/someApprentice/simpleRegistration
Там мы использовали кукисы и сессии для вывода данных:
https://github.com/someApprentice/simpleRegistration/blob/master/index.php#L7-L11
https://github.com/someApprentice/simpleRegistration/blob/master/Lib/functions.php#L65

Но, тем не менее, меня все же смутило что мы берем данные из кук, а не из БД, ведь куки можно отредактировать самостоятельно, не смотря даже на то что это не на что не повлияет, кроме как на личное отображение страницы.

>>48987

>Я тут не вижу циклов и сложных манипуляций массивами. Достаточно сделать 2 метода: авторизоватьсяПоФамилии и авторизоватьсяПоемайлу и вызвать их по очереди.


Эти методы реализуются в контроллере? Могу я обойтись без них, а просто реализовывать авторизацию прямо в условии, даже не смотря на то что в условиях будет копипаста? Хотя, если делать это в методах, то в них тоже будет та же самая копипаста.

если (логин выглядит как емайл и (в базе есть студент с таким емайлом и паролем)) {
то это он
создаемКукисы
ридеректим
выходим
}

если (логин (соответствует фамилии ровно одного студента и пароль подходит)) то {
студент найден
создаемКукисы
ридеректим
выходим
}

Или вовсе написать одно условие с выборкой(?):
если (
(логин выглядит как емайл и (в базе есть студент с таким емайлом и паролем))
или
(логин (соответствует фамилии ровно одного студента и пароль подходит))
) {
...
}
914 749215
>>48987

>> Не портит ли это модель?


>Модель не занимается редиректами. Это относится к контроллеру или представлению.


Моя вина, я имел ввиду модель программирования. Ведь так же можно выразиться о всей нашей MVC?

Перефразирую вопрос: Не выходит ли за рамки MVC использование в контроллере регистрации функции редиректа через сервис авторизации, а не через свой собственный хелпер? Ведь собственный хелпер, по сути, будет содержать те же методы что и сервис авториазации.
https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php#L42

>>48987

>Можно сделать чтобы и форма проставляла пароль, так иногда удобнее, но наверно в этом случае это должно происходить автоматически. Ты же не пишешь что форма должна проставить студенту имя и фамилию, а почему тогда про пароль пишешь?


Потому что сначала нужно проверить пароль на валидность а потом уже хешировать его.

>>48987

>Если студент умеет сам ставить себе пароль, то можно сделать так:


>


>пароль = форма->получитьПароль


>студент->назначитьПароль(пароль)


Умение студента самому себе ставить пароль, это имеется ввиду собственная функция получения хэша?
Мне нравится больше такой подход, потому что тогда не придется писать отдельную функцию назначитьПарольДляСтудента(студент, пароль) в сервисте авторазации, но я не понимаю откуда мы будем получать хэш, в предложенном тобой методе, если форма\студент и класс авторизации никак не связанны?

И что такое связь между классами? Я могу сказать что форма и класс авторизации связанны тем, что форма содержит в себе сущность студента, которая содержит в себе метод работающий с классом авторизации, но ты, по всей видимости, не согласен с этим, поэтому, логично будет спросить, как определяется эта связь?

Является ли сервис авторизации аутентификацией и при этом не является самой авторизацией?

>>48987

>> https://github.com/someApprentice/Students/blob/master/app/Model/Entity/Student.php#L40


>> fillDataFromDB(array $result)


>Модель лучше отвязать от базы данных, а метод перенести в класс работы с БД. Вместо того чтобы поместмть работу с БД в один класс, ты ее размазываешь по 2 классам.


Но этот метод никак не работает с БД, он просто получает переданные данные оттуда. Почему этот метод относится больше к классу работы с БД, чем к классу студента, ведь он же с самой БД никак не взаимодействует, а только меняет данные в классе студента?

>И я не вижу смысла делать 2 метода fillFrom ... Я бы сделал олин метод, который ставит любые поля, а проверку по белому списку сделал бы где-то выше, например в классе формы.


Получается нужно белый список передавать в эту функцию fillFromArray($allowed, $array)? А как тогда передавать его в классе БД? Писать прямо по среди функции? Это же не его задача, почему класс с БД должен знать что есть какой-то белый список для студента?

public function getStudentByСolumn($column, $value)
{
...
$allowed = [...];
$student->fillDataFromArray($allowed, $result);
...
}

>>48987

>> Если бы я пользовался куками, данные, такие как Имя, Фамилия, Возраст и так далее, тоже были бы лишними?


>Конечно, лишние. Достаточно иметь id, все данные студента есть в базе.


Тогда при выводе данных нужно получать их из БД?

>>48987

>>>Но и в этом случае сессия не нужна.


>> Сессиями больше не пользуются?


>Тут просто кук же хватит, зачем сессия?


>А теперь объясни свою точку зрения. Почему надо использовать сессию вместо кук и почему надо в ней хранить имя и фамилию? Какая от этого выгода?


Если пользователь не захочет оставаться залогиненым, то можно использовать сессию, а не создавать кукисы на 30 минут. К тому же, пользователь не сможешь отредактировать сессии, в отличие от кук. Но я не настаиваю на сессиях. Просто не понятно, почему нет.

>и почему надо в ней хранить имя и фамилию? Какая от этого выгода?


Когда я решал эту задачу я отталкивался от нашей старой задачи на простую регистрацию, где мы делали её процедурно https://github.com/someApprentice/simpleRegistration
Там мы использовали кукисы и сессии для вывода данных:
https://github.com/someApprentice/simpleRegistration/blob/master/index.php#L7-L11
https://github.com/someApprentice/simpleRegistration/blob/master/Lib/functions.php#L65

Но, тем не менее, меня все же смутило что мы берем данные из кук, а не из БД, ведь куки можно отредактировать самостоятельно, не смотря даже на то что это не на что не повлияет, кроме как на личное отображение страницы.

>>48987

>Я тут не вижу циклов и сложных манипуляций массивами. Достаточно сделать 2 метода: авторизоватьсяПоФамилии и авторизоватьсяПоемайлу и вызвать их по очереди.


Эти методы реализуются в контроллере? Могу я обойтись без них, а просто реализовывать авторизацию прямо в условии, даже не смотря на то что в условиях будет копипаста? Хотя, если делать это в методах, то в них тоже будет та же самая копипаста.

если (логин выглядит как емайл и (в базе есть студент с таким емайлом и паролем)) {
то это он
создаемКукисы
ридеректим
выходим
}

если (логин (соответствует фамилии ровно одного студента и пароль подходит)) то {
студент найден
создаемКукисы
ридеректим
выходим
}

Или вовсе написать одно условие с выборкой(?):
если (
(логин выглядит как емайл и (в базе есть студент с таким емайлом и паролем))
или
(логин (соответствует фамилии ровно одного студента и пароль подходит))
) {
...
}
915 749300
Какие команды в гите вы используете? Кроме
git clone репа
git status
git add .
git commit -m ""
git log
git remote add origin репа
git push origin master
Про ветки знаю, пока не доводилось использовать
916 749302
>>48731

>Вообще, вопрос глупый так как ответ на него ничего не дает. Я бы никогда таких вопросов не спрашивал.


Вот поэтому ты и пограммист, а не йоба-мэн, принимающий на работу, оу йес.
Ответ на него даёт представление о человеке.
Глупо думать, что на собеседовании проверяют только знание каких-то моментов из программирования.
Работать-то в итоге с человеком, а не с набором знаний о РНР и прочем.
917 749320
>>49302

> Вот поэтому ты и пограммист, а не йоба-мэн, принимающий на работу, оу йес.


Нет, не потому. Вопрос бессмысленный так как человека нанимают чтобы писать код, и самое важное это умение писать код.

Но ты, я вижу, знаешь что-то, что обычные люди вроде нас не понимают. Объясни какие варианты ответа на этот вопрос возможны и как их надо интерпретировать.
2,5 Мб, webm,
400x226
918 749342
>>49320
Я просто сам принимал на работу несколько раз - вот и вся моя возможная необычность.
Инструкции от начальства были чёткие: без высшего образования даже не рассматривать (сфера такая), неадекватов не брать (внешний вид, поведение, интересы).
Поэтому куча вопросов была не по теме - просто чтобы узнать, что за человек.
Я уже давненько не принимал на работу (наоборот, увольнять приходилось из-за проклятого кризиса), а вот знакомого, который недавно принимал на работу, обязали ознакомиться с цифровым профилем соискателя - по возможности. Профили в соцсетях, просто инфа в Гугле, всё-такое.

>человека нанимают чтобы писать код, и самое важное это умение писать код.


Почти любого можно обучить писать код (сужу по себе, азаза, лалка, сам себя затролел). А на работу принимают, чтобы вместе решать какие-то задачи, тесно общаться и вообще быть бок о бок 8 часов 5 дней в неделю.
Дело не в интерпретации ответа, а в простой адекватности соискателя.
Ты задал тот вопрос про РНР, а он испугался, ручонки вспотели, ножки задрыгались, "М-м-м-м, а де моё тестовое? Я сюда пришёл задачки решать, а не лясы точить!.." - и прочее. Зрачки расширились, зубы оскалены.
И с таким человеком нужно будет бок о бок 5 дней в неделю?
Максимум естественности.
Ответ братишки выше - адекватный.
Остальное - не имеет значения.
Правильного ответа нет и быть не может.
919 749350
>>49342

Ты уже троллишь по моему. Написал такую телегу, а как понимать ответы на вопрос не написал. Потому что очевидно что на него ответят стандартным ожидемым ответом. Если научить можно любого, почему бы тебе и не брать любых людей и не обучать их за счет компании? Наверно потому, что ты мамкин фантазер.
920 749354
>>49342

> без высшего образования даже не рассматривать (сфера такая)


Не хочется в тысячный раз подымать донельзя заезженную тему, но почему нельзя без ВО, что за сфера такая? Я уже свою шарагу не выдерживаю.

>>49350

>Если научить можно любого, почему бы тебе и не брать любых людей и не обучать их за счет компании?


Он вполне внятно описал, почему нельзя брать кого попало, что "с таким человеком нужно будет бок о бок 5 дней в неделю".
921 749365
Как-нибудь вообще возможно разместить <img> по центру по вертикали?
Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL)
50 Кб, 242x193
922 749366
>>29430 (OP)
Существуют ли php рекрутеры? Если да, подскажите где они обитают и как им попадаться на глаза?
924 749370
>>49350

>как понимать ответы на вопрос не написал.


Всё ясно, у вас программирование головного мозга.
Спасибо, до свидания, мы вам перезвоним.

>Если научить можно любого, почему бы тебе и не брать любых людей и не обучать их за счет компании?


Зачем, когда куча готовых реальных специалистов и нужно просто выбрать наиболее - какого? какого? - адекватного.
"Брать любых людей", "обучать за счёт компании" - ну ты даёшь.
Хотя знакомый рассказывал, как получал стипендию от какого-то металлургического комбината, когда учился в техникуме, проходил там практику, - его хотели таким образом поддержать, так или иначе готовили своего работника. Если не ошибаюсь, такое повсеместно в Европе и Америке бывает.

>>49354

>Не хочется в тысячный раз подымать донельзя заезженную тему, но почему нельзя без ВО, что за сфера такая?


Высшее образование в общем и целом - это как лакмусовая бумажка. Человек после школы определился со сферой, поступил в вуз - и окончил его, что немаловажно. Это значит, что у человека есть какие-никакие цели в жизни, он их так или иначе добивается. Высшее образование так или иначе гарантирует, что человек на многое способен, обладает многими навыками.
Сфера работы - издательское дело, одно из крупнейших российских издательств.
Никто не будет рассматривать кандидатуру соискателя, не имеющего высшего образования, - любого высшего образования, гуманитарного или технического - без разницы.
И образование играет здесь роль именно лакмусовой бумажки - характеризует человека, а не обязательно требуется из-за специфики самой работы. Хотя приоритет отдаётся гуманитарному ( филологическому) образованию, конечно.
Однако и высшее образование не гарантирует, что человек стопроцентно получит работу.
А вдруг он полный неадекват, азаза?
925 749373
>>49368
И зачем мне находить 1000 паст про vertical-align который не работает нихуя?
926 749375
927 749385
>>49370

>вакансия веб-программиста


>приоритет отдаётся гуманитарному ( филологическому) образованию, конечно.


>дружный коллектив, печеньки-корпоративы))))



Ну ясно в общем. Кто-то ищет профессионала, а кто-то члена в дружный коллектив, лишь бы человек был хороший)
Все зависит от конторы. В больших компаниях, где куча отделов, и программисту приходится общаться с левыми людьми типа менеджеров или сеошников, конечно в первую очередь важны социальные скиллы.
В маленьких конторах в первую очередь профессиональные навыки.
Хотя клинические психи или аутисты-тормоза естественно не нужны, но разве их так много?

>>49342

>Зрачки расширились, зубы оскалены.


И часто такие на практике встречаются? По-моему это либо клинический случай, либо 15-летние позеры из rf.

>webm


Шикарный демагог кстати, можно наравне с геббельсом заносить в учебники.
928 749390
>>49342
Ебучий сброд, по вашим вопросам делают оценку и по вам. Если кто-то после таких вопросов дальше хочет устроится в ваш быдлобиореактор, то вы набираете только максимум отбитых дегенератов. Надеюсь у вас устроют какой-нибудь теракт чтобы очистить генофонд человечества.
929 749394
>>49390
Семен семеныч.
sage 930 749576
>>49385

>Шикарный демагог кстати, можно наравне с геббельсом заносить в учебники


Прошу заметить что поп говорит во втором лице не помню как правильно называется эта форма речи - "ты", "тебе". Не разу не сказал, например, "Мы живем в аду". Более того его выражения полны презрения к аудитории "харя", "сынок", "нажраться", "наколоться". Никакого глубокого психоанализа и не нужно чтобы понять каким лицемерием обладают служители рпц.
931 749599
>>49385
Ты прав, я только предполагаю, что в случае с вопросом о РНР - это проверка адекватности.
Но ты всё-таки утрируешь слегка: профессиональные навыки всё-таки в большом почёте, этого никто не отменял. Хотя они и не гарантия трудоустройства - а разве где-то бывает по-другому?

>В маленьких конторах в первую очередь профессиональные навыки


У меня был печальный опыт работы с довольно неплохим программистом, который кучу плагинов написал для WP, свои темы, разные приложения и т.п.
Просто адов кошмар - многое не принимает во внимание, многое интерпретирует совершенно непонятно, перескакивает с пункта на пункт в ТЗ.
В итоге ничего не вышло, хотя профессиональные навыки у него были вполне на высоте.
Кулстори, бро, короче.

>И часто такие на практике встречаются?


Отсеиваем на этапе собеседования же, тут сложно сказать.
Ко мне приходил парнишка с - как сказал бы Джером Дэвид Сэлинджер - обкусанными до мяса ногтями - я его быстренько так собеседовал и отпустил с Богом. Остальные несколько человек были вполне приемлемыми, с некоторыми до сих пор работаем.

>И часто такие на практике встречаются?


>>49390

>Шикарный демагог кстати, можно наравне с геббельсом заносить в учебники.


У них всё связано с тем, что человек осознаёт свою греховность (другие и не идут в церковь).
Христос спрашивал бросавших в гулящую женщину камни - кто без греха?
Принимаешь осознание греховности -> чувствуешь его правоту -> стремишься к избавлению от греха.
Не знаю, мне очень нравятся его слова, в какой-то момент буквально до слёз. Особенно, про мешающих спать соловьёв. Аз есмь грешен как чертяка потому что...

>>49576

>Не разу не сказал, например, "Мы живем в аду".


А почему он должен был это сказать?
Он живёт полной жизнью, так или иначе исцеляет души людей. В него верят, его слушают, ему известна какая-то Истина.
Он не находится в аду - по его терминологии.
932 749611
>>49576

>Прошу заметить что поп говорит во втором лице не помню как правильно называется эта форма речи


Обращение, наверное.
933 749619
Достаточно короткого ответа: есть несколько похожих объектов, которые в конструкторе принимают один и тот же аргумент. Верно ли, что для них можно создать фабрику, которая будет проверять класс на существование, инстанциировать объект и возвращать его? Нагуглил static factory method: https://stackoverflow.com/questions/929021/what-are-static-factory-methods
934 749625
>>49576
Он статью "ты" на лурачке прочитал прост, и решил потралить ссачеров)))00
На самом деле обычный прием демагогии под названием "перевод стрелок".
Правда действует только на впечатлительных маменькиных сынков на сосаче, или старух в церкви.

Допустим, журналист обращается к коррумпированному чиновнику с вопросом: "откуда были взяты средства на строительство храмов рпц? а на вот эти наручные часы?", следует ответ:
"а ты почему спрашиваешь? Наверное у тебя в жизни не все в порядке. Может тебе бабы не дают? У тебя кривые зубы. Жиртрест. У тебя нет отца? Да ты же ублюдок. Что такое? Ой, ты сейчас заплачешь)))"

В эпизоде 1501 южного парка похожая ситуация: Картман перед всеми хвалится своим новым айпадом, тут к нему подходит крейг и говорит:
"Том Зальцман сказал, что у тебя нет айпада, что ты приклеил наклейку на кусок пластика и понтуешься"
Пауза.
"Отец Тома Зальцмана алкаш, а еще его мать бьет!"


>>49599

>Принимаешь осознание греховности -> чувствуешь его правоту -> стремишься к избавлению от греха.


Те качества, которые эти люди объявят греховными, я таковыми не считаю, и не считаю себя должным с ними согласиться в этом плане.
Я считаю греховными их, за то что они одурачивают глупых и слабым духом людей, забирают их последние копейки на свои дорогие машины и храмы, а также сотрудничают с бандитскими олигархическими кланами в деле популизма и пропаганды.
Они тормозят развитие человечества, как в культурном, так и техническом плане.

И вообще судя по всему ты даже не программист, а какой-нибудь редактор или сеошник, как ты можешь проводить собеседования на программиста? Школьную задачку на вектор хоть дорешал?
Признай, что тебе просто скучно на работе, поэтому отсеиваешь необщительных чуваков, чтобы было с кем попиздеть.
Я тоже могу "проповедовать".

Оп-слоупок, ты перекат хоть к тысячному посту оформишь? Люди заждались, сейчас быстро до тысячи добьем флудом.
935 749632
>>49619

Нет, фабрика не для этого. Фабрика для случаев когда мы хотим иметь возможность на процесс создания объектов другим классом.

>>49599

> довольно неплохим программистом


> многое не принимает во внимание, многое интерпретирует совершенно непонятно, перескакивает с пункта на пункт в ТЗ.


Ты сам себе противоречишь

Для проверки "адекватности" (что это значит?) достаточно просто лично побеседовать с человеком, и дополнительные бессмысленные вопросы задавать не надо. Такие вопросы обычно любят задавать не-программисты, например, менеджеры или HR.

>>49370

Про образование забавно. Одно дело когда такие требования выдвигает серьезная крупная компания - их можно понять, им хочется как-то унифицировать требования и проще отсеять хорошего кандидата чем пропустить нехорошее - но совсем другое когда это требования для натягивателя шаблонов на вордпресс.

>>49370

> Сфера работы - издательское дело


Это не IT компания.
936 749636
>>49365

Способы описаны в интернетре, у каждого свои ограничения, например зависит от того известны ли ширина и высота объекта или нет, погугли и выбери тот который подойдет.

>>49373

Вообще-то он работает, ты наверно просто не знаешь в каких именно случаях. Я подскажу. VA работает либо на ячейках таблицы (с display table-cell) либо на инлайн-блоках и инлайн элементах в строчном конексте форматирования. Он не позволяет выровнять что угодно относительно чего угодно. Судя по твоим вопросам, у тебя есть непонимание некоторых вещей CSS и я бы советовал заполнять эти пробелы.

На эту тему целая книга есть: http://css-live.ru/articles/obzor-inlajnovyj-kontekst-formatirovaniya.html
937 749638
>>49366

Они обитают на сайтах вакансий вроде hh, мой круг, geekjob и подобных.
938 749648
>>49632
Спасибо, и ещё вопрос: Factory Method решает какую реализуацию инстанциировать и возвращает её. Каким образом решает? В примерах используется switch/case, хорошая ли это практика?
939 749649
>>49638
И всё? Я ожидал что они не настолько ленивые уёбки(
940 749652
>>49215

> Не выходит ли за рамки MVC использование в контроллере регистрации функции редиректа через сервис авторизации, а не через свой собственный хелпер?


Немного странно что класс посвященный залогиниванию, занимается у тебя только редиректами. Может тогда правильнее его назвать RedirectHelper? За рамки MVC не выходит.

>>Можно сделать чтобы и форма проставляла пароль, так иногда удобнее, но наверно в этом случае это должно происходить автоматически. Ты же не пишешь что форма должна проставить студенту имя и фамилию, а почему тогда про пароль пишешь?


> Потому что сначала нужно проверить пароль на валидность а потом уже хешировать его.


Я имею в виду, у тебя у формы есть метод, который возвращает заполненную модель студента. Пусть он заодно и хеш пароля ему проставляет. ЛИбо пусть форма не связыается с паролями вообще.

Вообще, мне кажется, удобнее всего сделать в модели Студента метод "задать пароль". Для хеширования можно сделать статический метод в хелпере авторизациии. Можно даже в самом студенте конечно. Лишь бы он был в одном экземпляре, а не раскидан по коду несколько раз.

> Умение студента самому себе ставить пароль, это имеется ввиду собственная функция получения хэша?


Она может быть собственной, а может находиться в другом классе в виде статической функции.

> но я не понимаю откуда мы будем получать хэш, в предложенном тобой методе, если форма\студент и класс авторизации никак не связанны?


Можно сделать статический метод хеширования в любом из этих классов.

> И что такое связь между классами?


Это значит что например один класс в себе содержит ссылку на другой, или вызывает его статический метод. Ну то есть представь что 2 класса пишут 2 разных человека. Если они могут их написать не заглядывая в код друг друга, то классы полностью отделены и никак не связаны.

Ну например для того чтобы написать класс работы с бапзой данных, тебе надо знать про модуль студента, какие у нее поля и методы, верно? А вот про валидатор или класс автоизации тебе знать не надо, так как они тут никакого отношения не имеют.

В твоем случае, ты в форму передаешь как аргумент класс авторизации, потому форма о нем знает. Не то чтобы это плохо, но тогда лучше передавать его через конструктор, а еще лучше чтобы она о нем не знала.

> Является ли сервис авторизации аутентификацией и при этом не является самой авторизацией?


Давай считать что он занимается и тем и другим.

> Но этот метод никак не работает с БД, он просто получает переданные данные оттуда.


Вот опять. ВОт скажи, ты можешь написать моудль студента, не зная структуры базы данных? Нет, не можешь так как ты расчитываешь что тебе придут поля с определенными названиями. Получается, знание о базе данных у тебя вытекло из StudentGateway и затекло в Student, что плохо. Лучше когда за работу с БД отвечает только один класс, а не два.

> Получается нужно белый список передавать в эту функцию fillFromArra


Есть такие варианты:

- проставлять данные из базы в StudentGateway
- передавать список полей явно
- сделать метод, принимающий любые поля, но в контроллере отфильтровывать POST по списку полей
- сделать у функции опцию вроде "разрешить любые поля"
- сделать 2 функции, одна проверяет список полей, другая нет
940 749652
>>49215

> Не выходит ли за рамки MVC использование в контроллере регистрации функции редиректа через сервис авторизации, а не через свой собственный хелпер?


Немного странно что класс посвященный залогиниванию, занимается у тебя только редиректами. Может тогда правильнее его назвать RedirectHelper? За рамки MVC не выходит.

>>Можно сделать чтобы и форма проставляла пароль, так иногда удобнее, но наверно в этом случае это должно происходить автоматически. Ты же не пишешь что форма должна проставить студенту имя и фамилию, а почему тогда про пароль пишешь?


> Потому что сначала нужно проверить пароль на валидность а потом уже хешировать его.


Я имею в виду, у тебя у формы есть метод, который возвращает заполненную модель студента. Пусть он заодно и хеш пароля ему проставляет. ЛИбо пусть форма не связыается с паролями вообще.

Вообще, мне кажется, удобнее всего сделать в модели Студента метод "задать пароль". Для хеширования можно сделать статический метод в хелпере авторизациии. Можно даже в самом студенте конечно. Лишь бы он был в одном экземпляре, а не раскидан по коду несколько раз.

> Умение студента самому себе ставить пароль, это имеется ввиду собственная функция получения хэша?


Она может быть собственной, а может находиться в другом классе в виде статической функции.

> но я не понимаю откуда мы будем получать хэш, в предложенном тобой методе, если форма\студент и класс авторизации никак не связанны?


Можно сделать статический метод хеширования в любом из этих классов.

> И что такое связь между классами?


Это значит что например один класс в себе содержит ссылку на другой, или вызывает его статический метод. Ну то есть представь что 2 класса пишут 2 разных человека. Если они могут их написать не заглядывая в код друг друга, то классы полностью отделены и никак не связаны.

Ну например для того чтобы написать класс работы с бапзой данных, тебе надо знать про модуль студента, какие у нее поля и методы, верно? А вот про валидатор или класс автоизации тебе знать не надо, так как они тут никакого отношения не имеют.

В твоем случае, ты в форму передаешь как аргумент класс авторизации, потому форма о нем знает. Не то чтобы это плохо, но тогда лучше передавать его через конструктор, а еще лучше чтобы она о нем не знала.

> Является ли сервис авторизации аутентификацией и при этом не является самой авторизацией?


Давай считать что он занимается и тем и другим.

> Но этот метод никак не работает с БД, он просто получает переданные данные оттуда.


Вот опять. ВОт скажи, ты можешь написать моудль студента, не зная структуры базы данных? Нет, не можешь так как ты расчитываешь что тебе придут поля с определенными названиями. Получается, знание о базе данных у тебя вытекло из StudentGateway и затекло в Student, что плохо. Лучше когда за работу с БД отвечает только один класс, а не два.

> Получается нужно белый список передавать в эту функцию fillFromArra


Есть такие варианты:

- проставлять данные из базы в StudentGateway
- передавать список полей явно
- сделать метод, принимающий любые поля, но в контроллере отфильтровывать POST по списку полей
- сделать у функции опцию вроде "разрешить любые поля"
- сделать 2 функции, одна проверяет список полей, другая нет
941 749663
>>49215

> Это же не его задача, почему класс с БД должен знать что есть какой-то белый список для студента?


Он должен знать какие поля есть в БД. Меня правда беспокоит что у нас тут список полей дублируется многократно и при добавлении или переименовании поля придется в куче мест менять.

какие ты видишь варианты? нам надо и загружать студента из базы, и разрешить редактировать через форму.

> >Конечно, лишние. Достаточно иметь id, все данные студента есть в базе.


> Тогда при выводе данных нужно получать их из БД?


Да

> Если пользователь не захочет оставаться залогиненым, то можно использовать сессию, а не создавать кукисы на 30 минут.


Но можно и создать куки. Куки не требуют места на севрере например.

> К тому же, пользователь не сможешь отредактировать сессии, в отличие от кук


Это да, потому нужен токен для проверки подлинности пользователя, и надо его проверять по базе.

Просто мне кажется что разлогиниваться через полчаса довольно неудобно.

> Когда я решал эту задачу я отталкивался от нашей старой задачи на простую регистрацию, где мы делали её процедурно


ну, это было давно, сейчас мы можем и посложнее вещи делать.

> ведь куки можно отредактировать самостоятельно, не смотря даже на то что это не на что не повлияет, кроме как на личное отображение страницы.


Потмоу что не на что не повлияет, я думаю. Но лучше не хранить там имя вообще.

> если (логин выглядит как емайл и (в базе есть студент с таким емайлом и паролем)) {


> то это он


> создаемКукисы


> ридеректим


> выходим


> }


Не "создаемКукисы" а вызываем метод "залогинитьСтудента".

> Или вовсе написать одно условие с выборкой(?):


Скорее всего будет громоздко
941 749663
>>49215

> Это же не его задача, почему класс с БД должен знать что есть какой-то белый список для студента?


Он должен знать какие поля есть в БД. Меня правда беспокоит что у нас тут список полей дублируется многократно и при добавлении или переименовании поля придется в куче мест менять.

какие ты видишь варианты? нам надо и загружать студента из базы, и разрешить редактировать через форму.

> >Конечно, лишние. Достаточно иметь id, все данные студента есть в базе.


> Тогда при выводе данных нужно получать их из БД?


Да

> Если пользователь не захочет оставаться залогиненым, то можно использовать сессию, а не создавать кукисы на 30 минут.


Но можно и создать куки. Куки не требуют места на севрере например.

> К тому же, пользователь не сможешь отредактировать сессии, в отличие от кук


Это да, потому нужен токен для проверки подлинности пользователя, и надо его проверять по базе.

Просто мне кажется что разлогиниваться через полчаса довольно неудобно.

> Когда я решал эту задачу я отталкивался от нашей старой задачи на простую регистрацию, где мы делали её процедурно


ну, это было давно, сейчас мы можем и посложнее вещи делать.

> ведь куки можно отредактировать самостоятельно, не смотря даже на то что это не на что не повлияет, кроме как на личное отображение страницы.


Потмоу что не на что не повлияет, я думаю. Но лучше не хранить там имя вообще.

> если (логин выглядит как емайл и (в базе есть студент с таким емайлом и паролем)) {


> то это он


> создаемКукисы


> ридеректим


> выходим


> }


Не "создаемКукисы" а вызываем метод "залогинитьСтудента".

> Или вовсе написать одно условие с выборкой(?):


Скорее всего будет громоздко
942 749669
>>49625

>Те качества, которые эти люди объявят греховными, я таковыми не считаю, и не считаю себя должным с ними согласиться в этом плане.


Ты бы и не пошёл никогда в церковь, разве не так?
Проповедь-то обращена к прихожанам и к символическому греховному человеку, который всем вечно недоволен и т.п. Кто-то может узнать в этом человеке себя - только и всего.

>И вообще судя по всему ты даже не программист, а какой-нибудь редактор или сеошник, как ты можешь проводить собеседования на программиста?


Да я же не на программиста проводил собеседования, а просто описывал свой опыт со стороны рекрутера - для чего могут задаваться такие отвлечённые вопросы, как "Почему вы выбрали РНР?". SEO, простые сайты на WP и HTML - моё всё. Сейчас уже полгода варюсь с вами в жарких котлах этих тредов.

>Школьную задачку на вектор хоть дорешал?


Решил недавно с грехом (siс!) пополам. ОП не одобрил. Антикризисные меры как применить - я пока не представляю. Изучаю сейчас MySQL, наваял подобие Guestbook вчера.

>>49632

>Ты сам себе противоречишь


Дело в том, что у него собственное понимание того, каким продукт должен быть в итоге. А я - в силу того, что в то время вообще ничего не понимал, - не мог повлиять на его решение идти по ТЗ как попало. Он говорил мне, что так лучше, - а я и верил. Несколько различных модулей сделаны наполовину - при видимости готового решения.
А его собственные работающие приложения ведь никто не отменял, они есть, работают нормально.
Итого: отличные навыки программирования, но полное нежелание работать в команде (из двух человек, тандеме, так сказать).

>Для проверки "адекватности" (что это значит?) достаточно просто лично побеседовать с человеком, и дополнительные бессмысленные вопросы задавать не надо.


Не всегда, ну да ладно.

>Одно дело когда такие требования выдвигает серьезная крупная компания


Так и есть.

>Это не IT компания.


Я говорил, ну да ладно.
943 749671
>>49648

Зачем нужен Factory Method. Вот допустим кто-то написал класс Скачивальщик который отправляет HTTP запрос и возвраащет Ответ:

скачивальщик = new Скачивальщик;
запрос = Запрос::скачать('http://example.com/1.html');
ответ = скачивальщик->отправитьЗапрос(запрос);

теперь допустим ты хочешь расширить класс Ответ через наследование, добавив ему полезные методы или поменяв его поведение. Как ты заставишь Скачивальщик создавать объеты класса УлучшенныйОтвет вместо Ответ? Тут-то и поможет паттерн Factory Method, при условии что автор класса Скачивальщик вынес создание ответа в отдельный метод.

> Каким образом решает? В примерах используется switch/case, хорошая ли это практика?


Это вообще никакого значения не имеет тут. как хочешь так и проверяй. Ты по моему суть паттерна не понял, а спрашиваешь про мелкие детали реализации.
944 749675
>>49669

> Да я же не на программиста проводил собеседования, а просто описывал свой опыт со стороны рекрутера - для чего могут задаваться такие отвлечённые вопросы


Их задают потому что по теме сказать ничего не могут.

> что у него собственное понимание того, каким продукт должен быть в итоге.


Если он не старший разработчик то у него и не должно быть понимания - у него должно быть ТЗ или описание задачи.

> Несколько различных модулей сделаны наполовину - при видимости готового решения.


Скорее всего он просто не разобрался в силу нехватки знаний, опыта или времени. Вот когда на собеседовании задают не технические вопросы, а общие, таким людям как раз пролезть легче.

> Итого: отличные навыки программирования


нет
945 749685
>>49669

>Проповедь-то обращена к прихожанам и к символическому греховному человеку


Она явно обращена как к прихожанам, так и к оппонентам церкви и бандитской власти (обрати внимание, он упомянул слово "политика"), так как транслировалась по телевидению, возможно даже по национальным каналам.
Цели речи две: убедить прихожан в том, что атеисты и либералы это пидоры и неудачники, ну и заодно задеть самых неуверенных в себе слушателей этой речи со стороны оппозиции.
Если бы целью речи было убедить прихожан в том, что они должны любить и прощать близких и вообще всех окружающих, не осуждать, относиться с сочувствием, пытаться понять и помочь. Но нет, содержание речи противоположное: все кто не ходит в церковь и не голосует за путина - лузеры и плохие люди, так что ходите в церковь, платите десятину, голосуйте за путина.
Мой вывод: рпц это псевдохристианская организация, цель которой - оболванивание людей и пополнение легиона доверчивых, манипулируемых и глупых избирателей, которые никогда не будут иметь своего мнения, а спрашивать разрешения у красномордого жлоба-проповедника или царя-батюшки.
Вместо того, чтобы воспитывать умных людей, умеющих самостоятельно анализировать свою жизнь и проблемы, церковь оболванивает людей, хуже того навязывает ксенофобию, мракобесие, нетерпимость.

У любого человека, если он не безмозглый баран, должна существовать одна "совесть": не легко манипулируемое чувство вины, как у щенка написавшего в ботинок, а критическое мышление, основанное на логике и рассудке.

Да я помню тебя, ты тот симпатичный толстячок-редактор.
Надеюсь у тебя достаточно развито хоть какое-то мышление, чтобы не обижаться на резкие слова на дваче?
Все что здесь пишут, пишут с некоторыми целями, обычно ради провокаций или развлечения, и не нужно воспринимать всерьез.
Хотя сказка ложь, да в ней намек.
946 749694
Аж палец заболел прокручивать.
Смотрите какое интересное ТЗ, тут и постгре и архивы и сложная структура таблиц и Редис. Может кто-нибудь хочет сделать аналог чатика в вконтакте по такому ТЗ чисто в обучающих целях? Могли бы одновременно с кем-нить делать, чтобы был пример чужого кода.

https://www.fl.ru/projects/2797768/skript-lichnaya-perepiska-chat-po-funktsionalu-blizka-k-vkcom.html
947 749701
>>49694

Довольно бредовое. Если в обучающих целях, то я бы выкинул оттуда все кроме PHP и постгреса для начала и сделал нормализованную Бд.А только потом занимался бы оптимизациями.
948 749706
>>49694

>Аж палец заболел прокручивать.


Для этого есть ссылка "вниз" и "вверх" соответственно.

Из тз вообще ничего не понял, у меня по несколько вопросов на каждую строку этой шизофазии.

Я сейчас наверное накатаю вопросы, а оп или кто-нибудь пусть ответит. Получится практическое занятие на тему
"взаимопонимание заказчика и программиста-аутиста".

Решать само задание естественно не собираюсь, нет ни квалификации, ни желания.
949 749722
Давайте посмотрим на пример того как люди (видимо из-за наличия большого количества свободного времени) сами себе придумали проблему и сами решают ее: https://m.habrahabr.ru/post/301288/

> Можно сказать, что мы медиа сайт, т.к. у нас очень много всевозможных статей,


> 90% приходит из поиска Google.


> почти полгода мы разрабатывали Single Page Application версию



Дальше еще велесее:

> Из-за неравномерной нагрузки на сервера, и невозможности гибко оптимизировать страницы, было решено разделить сайт на backend (текущая версия на Drupal) и frontend (SPA на AngularJS).


> Из Drupal сделали REST сервер,


То есть нагрузка по идее должна была остаться примерно такая же.

Я бы советовал этим товарищам назвать статью "Ёжик в тумане". А, хотя жалко такое тянущее на отдельную книгу про современные методологии разработки приложений название использовать для одной статьи.

Объясните уже им кто-нибудь что бывают сайты, а бывают приложения и не надо использовать везде SPA потмоу что это слово часто пишут в твиттере.

Кстати, тем кто хочет увидеть реальный пример SPA, в ОП посте есть задачка на эту тему. Это вам не даунские туториалы по хелло ворлду на ангуларе или реакте, тут думать и разбираться в архитектуре надо.

>>49706

А еще кнопки Home/End.
950 749725
ОП, зачем ты все время даешь ссылки на мобильную версию сайта? Вырвиглазно же.
951 749726
>>49694
>>49706
Во-первых, мне всегда хочется видеть хоть какую-то схему приложения, хоть какой-то вайрфрейм, каркас, или как это называется, а еще лучше макет.
Тогда достаточно было бы просто уточнить детали, а не сидеть ломать голову, что это вообще такое.

>скрипт личная переписка (чат) по функционалу близка к vk.com


Скрипт? Что они подразумевают под "скриптом"? Это должен быть один файл с процедурщиной, а не ооп-приложение на классах с полноценной архитектурой?
В скобках написано "чат". Это видимо человек хотел мне помочь понять, но на самом деле только запутал.
Личная переписка, это когда два человека общаются, и не обязательно в онлайне, почта это тоже переписка, там допустим таймаут. А чат - когда толпа людей строчит односложные бессмысленные сообщения и смайлы.
Так что им нужно? Рум на двух человек, или открытый чат?
В vk никогда не сидел, пару раз видел только стену.
Чат как на стене, или в диалогах? В диалогах там же 2 человека общаются, или есть возможность для конференции?

>1. users: 'id', кука 'uid'..etc


Что еще за кука 'uid'? Мы тут в треде для анонимного доступа используем токены доступа, возможно они это имели ввиду.

> user_message_dialog: hash (формируется как диалог между 2user), count_messge (кол-во сообщений в переписке), unread(user1), unread(user2)


Я в ауте.
По-моему должна быть отдельная таблица 'message' с полями 'id', 'from_user', 'to_user', 'content', 'status=read/unread', или как-то так.
Кол-во сообщений в диалоге естественно можно получать запросом, а не хранить в таблице, и как они его собрались хранить? Что за 'hash'? Хеш чего? Текста сообщения?

>также в этой базе еще аналогичная таблица user_msg_archive


Ну выставь колонку в таблице сообщений, типа 'active/archived/deleted'. Зачем еще одна таблица?

>сам функционал (на примере отдельного пользователя): redis пуст пользователь зашел на сайт, авторизовался, после авторизации заполняется redis данными из "user_message_dialog", только в части новых (непрочитанных сообщений), т.е. hash и unread (для этого пользователя).


Зачем тут вообще редис? Редис можно использовать как кеш, или временное хранилище, чтобы снизить нагрузку на базу.

Короче чушь несусветная, и я бы не справился, именно по причине непонимания.

Скажите, я очень много хочу, если смогу работать только в команде, где один специально обученный человек будет долго беседовать с заказчиком, чтобы выяснить все подробности, сформулирует качественное тз, а потом всем тимом сесть и обсудить, как это реализуется?

>>49725
Может он в метро с планшета? Тебе лень удалить букву m?
951 749726
>>49694
>>49706
Во-первых, мне всегда хочется видеть хоть какую-то схему приложения, хоть какой-то вайрфрейм, каркас, или как это называется, а еще лучше макет.
Тогда достаточно было бы просто уточнить детали, а не сидеть ломать голову, что это вообще такое.

>скрипт личная переписка (чат) по функционалу близка к vk.com


Скрипт? Что они подразумевают под "скриптом"? Это должен быть один файл с процедурщиной, а не ооп-приложение на классах с полноценной архитектурой?
В скобках написано "чат". Это видимо человек хотел мне помочь понять, но на самом деле только запутал.
Личная переписка, это когда два человека общаются, и не обязательно в онлайне, почта это тоже переписка, там допустим таймаут. А чат - когда толпа людей строчит односложные бессмысленные сообщения и смайлы.
Так что им нужно? Рум на двух человек, или открытый чат?
В vk никогда не сидел, пару раз видел только стену.
Чат как на стене, или в диалогах? В диалогах там же 2 человека общаются, или есть возможность для конференции?

>1. users: 'id', кука 'uid'..etc


Что еще за кука 'uid'? Мы тут в треде для анонимного доступа используем токены доступа, возможно они это имели ввиду.

> user_message_dialog: hash (формируется как диалог между 2user), count_messge (кол-во сообщений в переписке), unread(user1), unread(user2)


Я в ауте.
По-моему должна быть отдельная таблица 'message' с полями 'id', 'from_user', 'to_user', 'content', 'status=read/unread', или как-то так.
Кол-во сообщений в диалоге естественно можно получать запросом, а не хранить в таблице, и как они его собрались хранить? Что за 'hash'? Хеш чего? Текста сообщения?

>также в этой базе еще аналогичная таблица user_msg_archive


Ну выставь колонку в таблице сообщений, типа 'active/archived/deleted'. Зачем еще одна таблица?

>сам функционал (на примере отдельного пользователя): redis пуст пользователь зашел на сайт, авторизовался, после авторизации заполняется redis данными из "user_message_dialog", только в части новых (непрочитанных сообщений), т.е. hash и unread (для этого пользователя).


Зачем тут вообще редис? Редис можно использовать как кеш, или временное хранилище, чтобы снизить нагрузку на базу.

Короче чушь несусветная, и я бы не справился, именно по причине непонимания.

Скажите, я очень много хочу, если смогу работать только в команде, где один специально обученный человек будет долго беседовать с заказчиком, чтобы выяснить все подробности, сформулирует качественное тз, а потом всем тимом сесть и обсудить, как это реализуется?

>>49725
Может он в метро с планшета? Тебе лень удалить букву m?
952 749730
>>49725

Не знаю, я ее читаю. Мне она нравится тем, что там все очень компактно и главная просто выглядит как список ссылок, а на десктопном сайте главная перегружена текстами и картинками и я не могу ее воспринимать. Она по высоте занимает экранов 10 и у меня сил нет все это читать и прокручивать.

Видимо дело вкуса и привычки.
953 749737
>>49726

> мне всегда хочется видеть хоть какую-то схему приложения, хоть какой-то вайрфрейм


Можно попросить заказчика нарисовать.

> Что они подразумевают под "скриптом"?


Набор скриптов, миграций и работа по их установке на сервере

> Так что им нужно? Рум на двух человек, или открытый чат?


телепат во мне говорит что нужны ЛС на существующем сайте.

> Чат как на стене, или в диалогах? В диалогах там же 2 человека общаются, или есть возможность для конференции?


2 человека + можно добавлять участников, вкидывать смешные картинки, файлы и ссылки. Ну как в скайпе например

> По-моему должна быть отдельная таблица 'message' с полями 'id', 'from_user', 'to_user', 'content', 'status=read/unread', или как-то так.


Автор наверно думает что его вариант производительнее

> Что за 'hash'? Хеш чего?


2 идентификатора беседующих пользователей

> Зачем еще одна таблица?


> Зачем тут вообще редис?


Возможно автор думает что так будет производительнее

> Скажите, я очень много хочу, если смогу работать только в команде, где один специально обученный человек будет долго беседовать с заказчиком, чтобы выяснить все подробности


Вообще, многовато. Иногда других технических специалистов нет.
954 749751
>>49671

>Ты по моему суть паттерна не понял,


Запутался полностью.

Тут: https://www.sitepoint.com/understanding-the-factory-method-design-pattern/
Первый листинг.

А вот здесь это уже Static Factory: http://designpatternsphp.readthedocs.io/ru/latest/Creational/StaticFactory/README.html

Вот мне и нужно то, что в последнем примере, но ведь фабрика не для этого?
955 749762
>>49751

Я говорил про Factory Method а не static Factory. Насчет static factory как именно определяется имя класса, через иф, свитч, массив, функцию - не принципиально.

static factory это просто функция которая получает какие-то аргументы на вход и создает какой-то объект на выходе.
956 749767
>>49762
Да, это я >>49619 здесь не уточнил.

>static factory это просто функция которая получает какие-то аргументы на вход и создает какой-то объект на выходе.


Имеет ли смысл прятать в неё проверку на существование класса? Есть 2 похожих класса, принимающих один и тот же параметр в конструктор. Мне приходится в 2-х случаях проверять класс на существование.
957 749790
>>29430 (OP)
Господа, ну подскажите же как мне сделать видео чат на пхп. Как с этим флешем работать??
958 749803
О. помните тут кто-то уменьшал картинки через пхп, чувак ты не дашь ссыль на свою работу? А то я аналогичное тЗ нашел.
https://www.fl.ru/projects/2797994/trebuetsya-programmist-dlya-optimizatsii-izobrajeniy.html
959 749828
>>49675

>Если он не старший разработчик то у него и не должно быть понимания - у него должно быть ТЗ или описание задачи.


Он программист-одиночка, немного работает на биржах фриланса.
Вряд он когда-нибудь сможет работать в команде. Но не потому, что не осилит техническую сторону, нет.

>Вот когда на собеседовании задают не технические вопросы, а общие, таким людям как раз пролезть легче.


Вообще да, ты прав, действительно, как мне кажется.
Но я изначально имел в виду просто обычные приёмы для проверки на адекватность, которые часто используют рекрутеры и которые я сам использовал, когда принимал на работу.
Это было важным дополнением, необходимо было оценить все стороны соискателя, ведь именно мне именно с ним потом придётся постоянно общаться, давать задачи, так или иначе отвечать за его работу.

>нет


Как минимум, очень хороший уровень именно программирования.
Хотя твоя оценка и моя оценка должны сильно различаться.
Я вот пока не чувствую себя готовым взглянуть на код того, что он наваял полгода назад, - я только подбираюсь к этому.
Возможно, поменяю своё мнение в скором времени.

>>49685

>Если бы целью речи было убедить прихожан в том, что они должны любить и прощать близких и вообще всех окружающих, не осуждать, относиться с сочувствием, пытаться понять и помочь.


Возможно - если ты сейчас серьёзен, - ты почему-то не почувствовал именно этот посыл в его речи. Он ведь и говорит, что недовольный всем окружающим (людьми, высшим светом, просто природой и даже своим отражением) греховный человек находится именно в аду. Из этого выход - к Богу. Ну а Бог находится в церкви, в которую ходят люди, стремящиеся очиститься от этого ада внутри и снаружи. Подобные проповеди обычно оканчиваются приглашением покаяться (вспомнить о грехах) и помолиться (собраться вместе в церкви).
А так нечестивых людей везде полно, церковь как организация - не исключение.

Спасибо за симпатичного толстячка, братишка.
960 749829
>>49790
Попробуй OpenMeetings, BigBlueButton или аналоги, например.
961 749834
>>49803

>О. помните тут кто-то уменьшал картинки через пхп, чувак ты не дашь ссыль на свою работу?


Тут, наверное, много кто делал, это же из учебника ОПа задачка. Вот, например
https://github.com/MindiMakridi/RESTFUL
35 Кб, 635x468
962 749836
>>49685

>Цели речи две


Ты ошибаешься, никакой цели не было, это просто богатый толстый дядька с ученной степенью по ПГМ несет свой говноконтент своей целевой аудитории. Что-то вроде рок концерта.

>Вместо того, чтобы воспитывать умных людей, умеющих самостоятельно анализировать свою жизнь и проблемы, церковь оболванивает людей, хуже того навязывает ксенофобию, мракобесие, нетерпимость.


Опять же ошибаешься, церковь сама по себе ничего не делает, люди сам приходят туда, сами приводят своих детей. Воспитывать умных людей должны собственные родители, а не какая-то сторонняя организация.

Вообще никто не должен был провоцироваться на вбросы этого отбитого >>49342
Конторки с вопросами от дебилов для дебилов, любовь к изречениям, не постесняюсь этого слова, мудака из рпц. Еще и выставил мой максимально адекватный пост на их быдлоконтору как за не имеющий место, пытаясь смаконуть тем самым свою правоту. Все эти факторы только доказывают обратное, что все в его конторе и он сам максимально деграданты.

>>49599

>>Не разу не сказал, например, "Мы живем в аду".


>А почему он должен был это сказать?


>Он живёт полной жизнью, так или иначе исцеляет души людей. В него верят, его слушают, ему известна какая-то Истина.


>Он не находится в аду - по его терминологии.


Если бы он исцелял души людей, он бы не говорил об этом т.к. в "В аду" больше не было бы никого. Если бы он не справлялся с количеством людей "В аду", то значит он был бы "В аду" сам.

Еще одно логичное заключение с моей стороны, к которому тебе не дано прийти самостоятельно, и которое вновь доказывает что в таких конторах зачастую обитают только умственно отсталые.

Вы можете подумать что я срусь с ним потому что мне противна такая мразь, но это не по этому. Мой уровень бытья находится ваше этого - за исключением этого случая, я игнорирую посты даунов, и не доказываю им что они дауны. Я просто хочу чтобы в моем любимом треде новички случайно прочитавшие его посты знали, что есть жесткая, решительно настроенная и не знающая компромиссов оппозиция его праздника слабоумия.


Аноны пишущее как ОП отступая одну строку, будьте осторожны в написании своих постов, вы можете ввести в заблуждение новичков и выставить ОПа в дурном свете, подвергаясь на провокации других.

Очень сожалею что выражаюсь, может быть, в не корректной форме - я давно уже засыпаю.
35 Кб, 635x468
962 749836
>>49685

>Цели речи две


Ты ошибаешься, никакой цели не было, это просто богатый толстый дядька с ученной степенью по ПГМ несет свой говноконтент своей целевой аудитории. Что-то вроде рок концерта.

>Вместо того, чтобы воспитывать умных людей, умеющих самостоятельно анализировать свою жизнь и проблемы, церковь оболванивает людей, хуже того навязывает ксенофобию, мракобесие, нетерпимость.


Опять же ошибаешься, церковь сама по себе ничего не делает, люди сам приходят туда, сами приводят своих детей. Воспитывать умных людей должны собственные родители, а не какая-то сторонняя организация.

Вообще никто не должен был провоцироваться на вбросы этого отбитого >>49342
Конторки с вопросами от дебилов для дебилов, любовь к изречениям, не постесняюсь этого слова, мудака из рпц. Еще и выставил мой максимально адекватный пост на их быдлоконтору как за не имеющий место, пытаясь смаконуть тем самым свою правоту. Все эти факторы только доказывают обратное, что все в его конторе и он сам максимально деграданты.

>>49599

>>Не разу не сказал, например, "Мы живем в аду".


>А почему он должен был это сказать?


>Он живёт полной жизнью, так или иначе исцеляет души людей. В него верят, его слушают, ему известна какая-то Истина.


>Он не находится в аду - по его терминологии.


Если бы он исцелял души людей, он бы не говорил об этом т.к. в "В аду" больше не было бы никого. Если бы он не справлялся с количеством людей "В аду", то значит он был бы "В аду" сам.

Еще одно логичное заключение с моей стороны, к которому тебе не дано прийти самостоятельно, и которое вновь доказывает что в таких конторах зачастую обитают только умственно отсталые.

Вы можете подумать что я срусь с ним потому что мне противна такая мразь, но это не по этому. Мой уровень бытья находится ваше этого - за исключением этого случая, я игнорирую посты даунов, и не доказываю им что они дауны. Я просто хочу чтобы в моем любимом треде новички случайно прочитавшие его посты знали, что есть жесткая, решительно настроенная и не знающая компромиссов оппозиция его праздника слабоумия.


Аноны пишущее как ОП отступая одну строку, будьте осторожны в написании своих постов, вы можете ввести в заблуждение новичков и выставить ОПа в дурном свете, подвергаясь на провокации других.

Очень сожалею что выражаюсь, может быть, в не корректной форме - я давно уже засыпаю.
963 749837
>>49706
заебался я прокручивать весь пр до этого треда.
964 749840
>>49706

>у меня по несколько вопросов на каждую строку этой шизофазии.


хаха, ну вот так и проиходит работа пхп-программиста, разгребать абсолютно шизофренические, непонятные задания.
965 749842
>>49836

>смаконуть


fix
966 749843
>>49726

>По-моему должна быть отдельная таблица 'message' с полями 'id', 'from_user', 'to_user', 'content', 'status=read/unread', или как-то так.


>Кол-во сообщений в диалоге естественно можно получать запросом, а не хранить в таблице, и как они его собрались хранить? Что за 'hash'? Хеш чего? Текста сообщения?


Вот тебе смешно, а мне приходится на такие шизо-заказы сабмитеться за кусок хлеба.
967 749844
>>49843
А что на работу не устроишься?
968 749850
>>49834

>это же из учебника ОПа задачка


А можешь ссылкой на само задание поделиться? И ещё кто-то говорил про задание на проектирование БД борды. Где это всё искать? Я вроде ковырялся в gist'ах ОПа.

Алсо делал подобное >>49803 на Bash'е с помощью ImageMagick, 5-6 строк вышло.

>>49837
- Тред можно добавить в избранное.
- Ссылка на текущий PHP-тред есть в шапке прикреплённого ньюфаг треда pr (но там частенько ссылка на устаревший тред)
- В конце концов можно написать js скрипт, работающий с 2ch.hk API, который находит самый новый PHP-тред и редиректит на него. Сам скрипт оформить в виде букмарклета, который можно добавить в закладки браузера. И у тебя будет закладка, которая постоянно ведёт тебя на текущий PHP-тред. Сам пользовался этим вариантом, до тех пор пока не обнаружил возможность добавлять тред в избранное.
969 749865
>>49844
живу в деревне, работы нет.
970 749866
>>49850

>ImageMagick


о кстати да, я вспомнил этот либ в пхп, реально в одну строчку уменьшает картинки.
971 749869
>>49850

>Ссылка на текущий PHP-тред


битая ссылка

>избранное


я не хочу иметь сосач в перечне закладок, а то вдруг еще люди увидят такой срам.

>можно написать js скрипт


Почему бы макаке на своем сайте не написать скрипт, фильтрующий треды по пхп/ruby/java тегам, выбирающий последний по дате и не занести ссылку на него в переменную прикрепленной шапки? У него доступ к бд есть, а мне еще с парсерами ебаться и виртуальную машину поднимать по такому случаю.
40 Кб, 743x169
972 749874
>>49869

>я не хочу иметь сосач в перечне закладок, а то вдруг еще люди увидят такой срам.


Ну измени название. И "Избранное" это фишка на сосаче, смотри пик.

>Почему бы макаке


Тебе дали API, просто пройдись по нему, получи первый occurrence фразы "Клуб изучающих" в названии треда, выдерни ссылку и перейди по ней. Какие виртуальные машины, скрипт будет в браузере отрабатывать.
98 Кб, 1920x1080
973 749880
>>49874

>перепись жирух



>>49836

>Аноны пишущее как ОП отступая одну строку, будьте осторожны в написании своих постов, вы можете ввести в заблуждение новичков и выставить ОПа в дурном свете

974 749883
>>49880
Что за наркоман форсит правило, мол что если есть отступы, то пост ОПа?
975 749901
>>49874

>получи первый occurrence фразы "Клуб изучающих" в названии треда, выдерни ссылку и


чиво?
nsdvw 976 750023
Анончик который https://github.com/nsdvw - а почему у тебя гитхаб не учитывает твои коммиты на графике на этой странице? Он весь пустой. Может ты в гите не настроил правильно email и он не воспринимает их как твои коммиты?
46 Кб, 800x600
977 750036
>>50023
Я в курсе.
Не хочу светить никаких данных.
978 750043
>>49837
>>49850
А еще движок борды поддерживает функционал коротких тегов, и поиск по ним. Это уже работает на досках с большим количеством щитпостеров, например /vg/ и /tv/. Довольно удобная вещь, позволяет быстро искать треды по тегу. Не знаю почему на этой доске теги не включили.
979 750066
ОП, когда будешь мое проверять >>47423 не смотри комментарии, я внезапно осознал насколько там все плохо и сейчас все переделываю.
980 750126
https://github.com/TheSidSpears/Students
В общем меня можно снова проверять. Большинство ошибок уже исправлено
981 750140
>>49652

>Для хеширования можно сделать статический метод в хелпере авторизациии.


А почему здесь не нарушается принцип DI?

>>49652

>> Является ли сервис авторизации аутентификацией и при этом не является самой авторизацией?


>Давай считать что он занимается и тем и другим.


А если бы у нас не было бы такой договоренности, то как бы было принято считать?

>>49652

>- сделать у функции опцию вроде "разрешить любые поля"


Мне нравится этот вариант

Я сделаю так

function fillDataFromArray($data, $allowed = array())
{
if (!empty($allowed)) {
$allowed = array_keys($data);
}

...
}

И в классе формы я напишу так

function fillDataFromArray(array $data)
{
$allowed = [
'name',
'surname',
'gender',
'grupNumber',
'email',
'satScores',
'yearOfBirth',
'location'
];

$this->student->fillDataFromArray($data, $allowed);

$allowed = [
'password',
'retryPassword',
];

foreach ($allowed as $value) {
if (isset($data[$value]) and is_scalar($data[$value]) and property_exists($this, $value)) {
$this->$value = trim($data[$value]);
}
}
}

И я подумал, что две переменные $allowed можно объединить в одну - всё равно лишние поля не заполнятся потому что есть условие которое проверяет на наличие таких свойств.

>>49663

>> Это же не его задача, почему класс с БД должен знать что есть какой-то белый список для студента?


>Он должен знать какие поля есть в БД. Меня правда беспокоит что у нас тут список полей дублируется многократно и при добавлении или переименовании поля придется в куче мест менять.


>


>какие ты видишь варианты? нам надо и загружать студента из базы, и разрешить редактировать через форму.


Варианты с тем чтобы не дублировать поля?

Я бы сделал одно свойство $data и заполнял его в соответствии с пришедшими данными из формы (проверяя при этом на разрешенные поля) или из БД, или лучше на оборот сделал чтобы форма и запросы из БД делались автоматически на основе свойств той или иной сущности, но чтобы это сделать нужно полностью переписывать код.
981 750140
>>49652

>Для хеширования можно сделать статический метод в хелпере авторизациии.


А почему здесь не нарушается принцип DI?

>>49652

>> Является ли сервис авторизации аутентификацией и при этом не является самой авторизацией?


>Давай считать что он занимается и тем и другим.


А если бы у нас не было бы такой договоренности, то как бы было принято считать?

>>49652

>- сделать у функции опцию вроде "разрешить любые поля"


Мне нравится этот вариант

Я сделаю так

function fillDataFromArray($data, $allowed = array())
{
if (!empty($allowed)) {
$allowed = array_keys($data);
}

...
}

И в классе формы я напишу так

function fillDataFromArray(array $data)
{
$allowed = [
'name',
'surname',
'gender',
'grupNumber',
'email',
'satScores',
'yearOfBirth',
'location'
];

$this->student->fillDataFromArray($data, $allowed);

$allowed = [
'password',
'retryPassword',
];

foreach ($allowed as $value) {
if (isset($data[$value]) and is_scalar($data[$value]) and property_exists($this, $value)) {
$this->$value = trim($data[$value]);
}
}
}

И я подумал, что две переменные $allowed можно объединить в одну - всё равно лишние поля не заполнятся потому что есть условие которое проверяет на наличие таких свойств.

>>49663

>> Это же не его задача, почему класс с БД должен знать что есть какой-то белый список для студента?


>Он должен знать какие поля есть в БД. Меня правда беспокоит что у нас тут список полей дублируется многократно и при добавлении или переименовании поля придется в куче мест менять.


>


>какие ты видишь варианты? нам надо и загружать студента из базы, и разрешить редактировать через форму.


Варианты с тем чтобы не дублировать поля?

Я бы сделал одно свойство $data и заполнял его в соответствии с пришедшими данными из формы (проверяя при этом на разрешенные поля) или из БД, или лучше на оборот сделал чтобы форма и запросы из БД делались автоматически на основе свойств той или иной сущности, но чтобы это сделать нужно полностью переписывать код.
982 750142
>>49663

>Не "создаемКукисы" а вызываем метод "залогинитьСтудента".


А что это за метод? Что он будет содержать в себе помимо создания кукисов? Да и не занимается ли сам контроллер залогиниванием студента?
983 750162
Помогите намекнуть апачу, чтоб точка входа в приложение была не в корне, а в директории (вроде /app)
984 750167
>>50162
В httpd.conf есть опция DocumentRoot. Смени её на нужную.
985 750173
>>50167
А через .htaccess можно?
986 750232
>>50173
Нашёл, можно примерно таким образом
RewriteEngine on
RewriteCond %{REQUEST_URI} !app/
RewriteRule (.*) /app/$1 [L]
987 750239
>>50232
https://httpd.apache.org/docs/current/rewrite/flags.html#flag_qsa

>With the [QSA] flag, a request for /pages/123?one=two will be mapped to /page.php?page=123&one=two. Without the [QSA] flag, that same request will be mapped to /page.php?page=123 - that is, the existing query string will be discarded.



И обычно корневой папку делают с помощью виртульных хостов.
988 750407
>>48697
Ни черта не понятно.

>Интеграционный тест лучше делать на отдельной базе расположенной в памяти


Где? Я не знаю, как создавать базу расположенную "в памяти". Знаю только таблицы типа memory в mysql, но там же нет ни внешних ключей, ничего.

>Скрипт должен создать базу


Как? Я знаю только способ создать базу через консольную команду doctrine:database:create -e test
Как это сделать через левый класс?
Аналогично миграции, знаю только консольные команды для миграций, не знаю как их запустить из своего кода.
989 750420
>>48697
Короче я пока создаю обычную базу на диске (других не знаю) для тестов через консольную команду, используя конфиги тестового окружения из config_test.yml.
Вручную накатываю миграции через консольную команду.
Наследуюсь от PHPUnit_Extensions_Database_TestCase и подгружаю dataSet из дампа.
https://phpunit.de/manual/current/en/database.html#database.yaml-dataset

> класс Attempt с кучей релейшенов


>Ну, это элементарно. Создаем разные Attempt разных типов


Нет, я заколебаюсь делать моку под него. Тут наверное тоже нужен интеграционный тест с участием бд.
990 750495
>>49865
Я тоже в деревне живу, ближайший город 700К, 10 php вакансий на hh. Но я собрался после сессии устраиваться на удаленку, вакансий много. Почему ты не попробуешь? Особенно если у тебя есть опыт.
991 750503
>>49883

точно не я
992 750507
>>48146
я апну вопрос. Как следует реализовывать механизм логина если не сессиями?
993 750509
>>50507
Куками.
994 750515
>>50509
а подробнее? Нет, я могу поставить куку isadmin=1 при авторихации и проверять её,
но любой вася может сделать то же самое на стороне юзера.
995 750521
>>50515
Соленый хеш пароля ставить в куку.
При аутентификации проверять, есть ли у пользователя куки для id и хеша, если есть извлечь из базы запись по id, сравнить хеш из бд с хешом из куки.
996 750542
>>50521
Спасибо.
А хеш всегда один и тот же получается будет лежать в таблице?
14 Кб, 358x397
997 750547
Как выложить guestbook на Github и не спалить доступ к своей базе данный MySQL? Чтобы не проникли в мой компьютер, зная пароль и мой IP.
Я помню, какой-то братишка так спалился каким-то образом пару месяцев назад, когда выложил на Гитхабе проект с дампом базы.
Вообще не пойму, с чего начать.
Есть готовая Гостевая - пара файликов, хочу иметь первый проЭкт на Гитхабе.
998 750555
>>50547
очевиндо: не держать захардкоденными доступы к БД, а читать их из файла конфига.
999 750586
>>50555
Бро, как понять "захардкоденными"?
В файле конфига вообще не указывать пароль, может быть? Никто же не будет её тестировать, там строк 60 кода всего.
Или сами поставят пароль, если надумают тестировать.
Я в сомнениях и раздумьях, короче.
1000 750593
>>50586
Ну ты пароль хранишь в переменной, переменную реквайришь из файла config.php
В весрию для гитхаба в этом файле пишешь
$passw = ''; # DB password

в чем проблема я не понимаю.
63 Кб, 799x507
1001 750606
>>50593

>реквайришь

1002 750607
>>50593
Я просто пока не разбираюсь в терминах.
Сделаю так, как ты говоришь, спасибо!
1003 750657
>>50607
require_once("path/to/config.php");
1004 750668
>>50586
Указываешь пустой пароль в конфиге. Потом говоришь git'у не отслеживать изменения для данного файла командой:
git update-index --assume-unchanged <file>

Потом вставляешь свой пароль в файл, пушишь на GitHub.

На всякий случай, отслеживание изменений обратно включается командой: git update-index --no-assume-unchanged <file>
22 Кб, 632x644
1005 750966
Немного мотивации на ночь глядя.
77 Кб, 1091x498
1006 750971
>>50966
Съеби в лузер-тред.
1007 750988
Написал новую версию урока по DI, в том числе, пытаюсь объяснить, чем плохи глобальные переменные и статические методы. Прочитайте, может какие советы или комментарии будут: https://github.com/codedokode/pasta/blob/master/arch/di.md
1008 751035
>>48697

>- делать моки для репозитория и инжектировать в класс для теста. Трудоемко


Более чем.
У меня же там куча связей у каждой модели, если бы была только пара свойств, я бы не возникал.

>- делать интеграционные тесты, вставив в чистую базу заранее известные данные и вызывая методы.


Не знаю как из класса теста обратиться к доктрине.

Функциональные тесты насколько я понял относятся к контроллерам, о них пока не вспоминаем.

В манах симфони ни слова не сказано про "интеграционные тесты".
В book как обычно даунский пример со сложением двух чисел, про работу с базой не сказано.
http://symfony.com/doc/current/book/testing.html
Затем сразу переключаются на функциональные тесты.

В рецептах сказано использовать моки.
http://symfony.com/doc/current/cookbook/testing/database.html
Это конечно хорошо, что они приводят в качестве примера офигенно сложную модель с двумя int свойствами
$employee->expects($this->once())
->method('getSalary')
->will($this->returnValue(1000));
$employee->expects($this->once())
->method('getBonus')
->will($this->returnValue(1100));
Только вот у меня в свойствах лежат коллекции объектов, густо переплетенные перекрестными связями.

Наконец есть доки phpunit
https://phpunit.de/manual/current/en/database.html
где предлагают возню с xml-ными конфигами и дампами.

Не понимаю, что делать.
Кладу пока на тесты и пишу другие части приложения.
1008 751035
>>48697

>- делать моки для репозитория и инжектировать в класс для теста. Трудоемко


Более чем.
У меня же там куча связей у каждой модели, если бы была только пара свойств, я бы не возникал.

>- делать интеграционные тесты, вставив в чистую базу заранее известные данные и вызывая методы.


Не знаю как из класса теста обратиться к доктрине.

Функциональные тесты насколько я понял относятся к контроллерам, о них пока не вспоминаем.

В манах симфони ни слова не сказано про "интеграционные тесты".
В book как обычно даунский пример со сложением двух чисел, про работу с базой не сказано.
http://symfony.com/doc/current/book/testing.html
Затем сразу переключаются на функциональные тесты.

В рецептах сказано использовать моки.
http://symfony.com/doc/current/cookbook/testing/database.html
Это конечно хорошо, что они приводят в качестве примера офигенно сложную модель с двумя int свойствами
$employee->expects($this->once())
->method('getSalary')
->will($this->returnValue(1000));
$employee->expects($this->once())
->method('getBonus')
->will($this->returnValue(1100));
Только вот у меня в свойствах лежат коллекции объектов, густо переплетенные перекрестными связями.

Наконец есть доки phpunit
https://phpunit.de/manual/current/en/database.html
где предлагают возню с xml-ными конфигами и дампами.

Не понимаю, что делать.
Кладу пока на тесты и пишу другие части приложения.
1009 751049
>>51035

> У меня же там куча связей у каждой модели, если бы была только пара свойств, я бы не возникал.


А вот и нет. Что тебе мешает сделать так:

$test = new Test;
$test->setName(...);
$q = new Question;
$test->addQuestion($q);

ну и так далее. Я думаю, это можно разбить на части, отдельно функция создания теста, отдельно функция вбивания вопросов в него. Поля все заполнять не требуется, только обязательные.

> Функциональные тесты насколько я понял относятся к контроллерам, о них пока не вспоминаем.


Они тестируют может ли приложение в целом выполнять свои функции. Там обычно используется эмулятор браузера.

> В манах симфони ни слова не сказано про "интеграционные тесты".


Это тесты, проверябщие как компоненты взаимодействуют друг с другом и работают вместе

https://ru.wikipedia.org/wiki/Интеграционное_тестирование

https://habrahabr.ru/post/146984/

В данном случае имеется в виду интеграция базы данных и кода работающего с ней. Вроде же соответствует определению.

> В рецептах сказано использовать моки.


я тебе советую держаться подальше от тестов, как в примере. Вот посмотри, что тестирует этот код? Что такая-то функция будет вызвана. Это применимо если ты например тестируешь систему событий и проверяешь вызовется ли твой обработчик, но в других случаях это неправильно так как ты в тест закладываешь знания о том как работает тестируемый код и что он вызывает. Это ненадежно, при первом же рефакторинге это сломается.

Ну и второй момент, что моком подменяют возвращаемые результаты. ну опять же, тут тест слишком завязывается на внутреннюю структуру кода, мне кажется.
1009 751049
>>51035

> У меня же там куча связей у каждой модели, если бы была только пара свойств, я бы не возникал.


А вот и нет. Что тебе мешает сделать так:

$test = new Test;
$test->setName(...);
$q = new Question;
$test->addQuestion($q);

ну и так далее. Я думаю, это можно разбить на части, отдельно функция создания теста, отдельно функция вбивания вопросов в него. Поля все заполнять не требуется, только обязательные.

> Функциональные тесты насколько я понял относятся к контроллерам, о них пока не вспоминаем.


Они тестируют может ли приложение в целом выполнять свои функции. Там обычно используется эмулятор браузера.

> В манах симфони ни слова не сказано про "интеграционные тесты".


Это тесты, проверябщие как компоненты взаимодействуют друг с другом и работают вместе

https://ru.wikipedia.org/wiki/Интеграционное_тестирование

https://habrahabr.ru/post/146984/

В данном случае имеется в виду интеграция базы данных и кода работающего с ней. Вроде же соответствует определению.

> В рецептах сказано использовать моки.


я тебе советую держаться подальше от тестов, как в примере. Вот посмотри, что тестирует этот код? Что такая-то функция будет вызвана. Это применимо если ты например тестируешь систему событий и проверяешь вызовется ли твой обработчик, но в других случаях это неправильно так как ты в тест закладываешь знания о том как работает тестируемый код и что он вызывает. Это ненадежно, при первом же рефакторинге это сломается.

Ну и второй момент, что моком подменяют возвращаемые результаты. ну опять же, тут тест слишком завязывается на внутреннюю структуру кода, мне кажется.
1010 751058
>>50668
>>50586
>>50547

Нет, наверно лучше не так. Надо добавить конфиг в gitignore, а вместо него в репозиторий поместить образец конфига, например config.ini.dist без паролей и имен.

Другой вариант - сделать базовый конфиг (config.ini) без паролей, и локальный конфиг, config.local.ini, который в гитигноре и который переопределяет пароль.

Ну и не забыть про это написать в ридми.

В любом случае в репозитории должен быть код, подходящий всем, там не должно быть твоих личных паролей.

>>50407

У sqlite есть такой режим, хранить данные в памяти, у postgresql вроде нет, печалька: http://stackoverflow.com/questions/7872693/running-postgresql-in-memory-only

У редиса можно легко поднять временный демон не сохраняющий никаких данных.

Ну в mysql оказывается тоже не все хорошо. У меня еще есть мысль, что можно примонтировать tmpfs (ФС хранящая файлы в памяти), поднять mysql с базой на ней, инициализировать, а после тестов выкинуть. Но это наверно сложно.

Раз так, можно просто сделать отдельную БД и очищать ее или определенные таблицы в ней перед тестами. То есть скрипт выглядит так:

- очистить БД
- накатить миграции и справочные данные
- прогнать тесты

Ну и в тесте дополнительно можно делать TRUNCATE некоторым таблицам например. Или делать тест в транзакции, которую откатывать после. Это все нужно для изоляции, чтобы вставленные одним тестом данные не влияли на другой.

> Как это сделать через левый класс?


Я имел в виду баш скрипт. Он подготавливает все что нужно и запускает phpunit.

>>50420

Ну ок.

> и подгружаю dataSet из дампа.


Тут есть подвох, что при изменениях в БД дамп не будет работать, надо решать проблему связей... не лчше ли сделать вспомогательный класс, который создает тесты и вопросы например через сервисы или доктрину?
1010 751058
>>50668
>>50586
>>50547

Нет, наверно лучше не так. Надо добавить конфиг в gitignore, а вместо него в репозиторий поместить образец конфига, например config.ini.dist без паролей и имен.

Другой вариант - сделать базовый конфиг (config.ini) без паролей, и локальный конфиг, config.local.ini, который в гитигноре и который переопределяет пароль.

Ну и не забыть про это написать в ридми.

В любом случае в репозитории должен быть код, подходящий всем, там не должно быть твоих личных паролей.

>>50407

У sqlite есть такой режим, хранить данные в памяти, у postgresql вроде нет, печалька: http://stackoverflow.com/questions/7872693/running-postgresql-in-memory-only

У редиса можно легко поднять временный демон не сохраняющий никаких данных.

Ну в mysql оказывается тоже не все хорошо. У меня еще есть мысль, что можно примонтировать tmpfs (ФС хранящая файлы в памяти), поднять mysql с базой на ней, инициализировать, а после тестов выкинуть. Но это наверно сложно.

Раз так, можно просто сделать отдельную БД и очищать ее или определенные таблицы в ней перед тестами. То есть скрипт выглядит так:

- очистить БД
- накатить миграции и справочные данные
- прогнать тесты

Ну и в тесте дополнительно можно делать TRUNCATE некоторым таблицам например. Или делать тест в транзакции, которую откатывать после. Это все нужно для изоляции, чтобы вставленные одним тестом данные не влияли на другой.

> Как это сделать через левый класс?


Я имел в виду баш скрипт. Он подготавливает все что нужно и запускает phpunit.

>>50420

Ну ок.

> и подгружаю dataSet из дампа.


Тут есть подвох, что при изменениях в БД дамп не будет работать, надо решать проблему связей... не лчше ли сделать вспомогательный класс, который создает тесты и вопросы например через сервисы или доктрину?
1011 751069
>>50140

Вот, для начала почитай-ка мой новый урок по DI: https://github.com/codedokode/pasta/blob/master/arch/di.md

Все эти принципы мы применяем не потому что кто-то умный так сказал, а чтобы бороться с той или иной проблемой. И тут всегда надо искать компромисс - вот например при строительстве моста мы можем ставить опоры чаще (но это будет дорож и затруднит судоходство), а можем реже (но тогда секции должны быть более прочными). Так же и с кодом, если мы его будем писать стеной, то в нем будет не разобраться, а если будем применять все возмодные паттерны и разобьем на 1000 классов, то тоже не очень хорошо будет.

>>Для хеширования можно сделать статический метод в хелпере авторизациии.


>А почему здесь не нарушается принцип DI?


Хеширование не обращается к полям класса, небольшое по объему, не имеет зависимостей, потому его можно сделать статическим методом.

>>Давай считать что он занимается и тем и другим.


> А если бы у нас не было бы такой договоренности, то как бы было принято считать?


Тут надо не считать, а взвесить плюсы и минусы. "Если мы сделаем авторизацию и аутентификацию в одном классе то...", "если мы сделаем это в 2 отдельных классах то....". Я не вижу никаких плюсов в 2 классах, по моему только сложнее будет.

> Мне нравится этот вариант


> Я сделаю так


> function fillDataFromArray($data, $allowed = array())


Ну тут по моему как раз закладывается мина замедленного действия. В моем понимании пустой массив значит что никакие поля не разрешены, а функция поступает ровно наоборот. Функции не должны вести себя неожиданно и неинтуитивно. Так как в этом случае кто-то сделает ошибку.

Насчет белого списка полей - что-то я затрудняюсь. Может для БД все же лучше сделать отдельную функцию, не проверяющую список? А то мы замучаемся поддерживать кучу списков полей при изменении структуры таблицы.

> Я бы сделал одно свойство $data


ну это не ООП. Ты по сути заменяешь хороший класс на плохой массив, в котором неизвестно какие поля могут быть. Если ты так сделаешь в реальном приложении, то один программист положит туда один набор полей, другой - другой и в итоге будет не понять что там должно быть, а что нет.

> тобы форма и запросы из БД делались автоматически на основе свойств той или иной сущности


Что интересно, в Симфони примерно так и делается, только там к полям пишутся комментарии - например какому типу в БД оно соответствует, также можно приписывать правила валидации (изучай доктрину, symfony Validation и symfony forms если интересно). Но это довольно сложная штука, ее писать с нуля наверно нет смысла, тем более когда есть готовая. У нас маленькое приложение, я думаю, один-два раза список полей можно и вручную вписать.
1011 751069
>>50140

Вот, для начала почитай-ка мой новый урок по DI: https://github.com/codedokode/pasta/blob/master/arch/di.md

Все эти принципы мы применяем не потому что кто-то умный так сказал, а чтобы бороться с той или иной проблемой. И тут всегда надо искать компромисс - вот например при строительстве моста мы можем ставить опоры чаще (но это будет дорож и затруднит судоходство), а можем реже (но тогда секции должны быть более прочными). Так же и с кодом, если мы его будем писать стеной, то в нем будет не разобраться, а если будем применять все возмодные паттерны и разобьем на 1000 классов, то тоже не очень хорошо будет.

>>Для хеширования можно сделать статический метод в хелпере авторизациии.


>А почему здесь не нарушается принцип DI?


Хеширование не обращается к полям класса, небольшое по объему, не имеет зависимостей, потому его можно сделать статическим методом.

>>Давай считать что он занимается и тем и другим.


> А если бы у нас не было бы такой договоренности, то как бы было принято считать?


Тут надо не считать, а взвесить плюсы и минусы. "Если мы сделаем авторизацию и аутентификацию в одном классе то...", "если мы сделаем это в 2 отдельных классах то....". Я не вижу никаких плюсов в 2 классах, по моему только сложнее будет.

> Мне нравится этот вариант


> Я сделаю так


> function fillDataFromArray($data, $allowed = array())


Ну тут по моему как раз закладывается мина замедленного действия. В моем понимании пустой массив значит что никакие поля не разрешены, а функция поступает ровно наоборот. Функции не должны вести себя неожиданно и неинтуитивно. Так как в этом случае кто-то сделает ошибку.

Насчет белого списка полей - что-то я затрудняюсь. Может для БД все же лучше сделать отдельную функцию, не проверяющую список? А то мы замучаемся поддерживать кучу списков полей при изменении структуры таблицы.

> Я бы сделал одно свойство $data


ну это не ООП. Ты по сути заменяешь хороший класс на плохой массив, в котором неизвестно какие поля могут быть. Если ты так сделаешь в реальном приложении, то один программист положит туда один набор полей, другой - другой и в итоге будет не понять что там должно быть, а что нет.

> тобы форма и запросы из БД делались автоматически на основе свойств той или иной сущности


Что интересно, в Симфони примерно так и делается, только там к полям пишутся комментарии - например какому типу в БД оно соответствует, также можно приписывать правила валидации (изучай доктрину, symfony Validation и symfony forms если интересно). Но это довольно сложная штука, ее писать с нуля наверно нет смысла, тем более когда есть готовая. У нас маленькое приложение, я думаю, один-два раза список полей можно и вручную вписать.
1012 751078
>>49866

только к этой строчке надо дописать проверку результата, сохранение/перенос файлов, сборку мусора, логгирование, обработку ошибок, таймаут. Получается не так и мало. Да и по моему средствами пхп делать это удобнее чем вызывая внешний процесс. И кстати imageMagick доступна как расширение пхп.

>>49850

> на Bash'е с помощью ImageMagick, 5-6 строк вышло.


А логгирование, проверку ошибок, таймауты - ты делал?
148 Кб, 658x515
Нужно сделать обновление в sql db из таблицы на сайте. Lamer 1013 751212
Не обновляет в sql базе из таблицы на сайте при нажатии на кнопку

update.php отправляет запрос на обновления в sqlbd

!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<link rel="stylesheet" type="text/css" href="../style.css">
<title>Untitled Document</title>
</head>

<body>

<?php
require 'connect.php';
$id=$_REQUEST['id'];
$first_name=trim($_REQUEST['first_name']);
$fast_name=trim($_REQUEST['fast_name']);
$metod=trim($_REQUEST['metod']);

$update_sql = "UPDATE users SET first_name='$first_name', fast_name='$fast_name', metod='$metod', administr='$administr' WHERE id='$id'";
mysql_query($update_sql) or die("Ошибка вставки" . mysql_error());
echo '<p>Запись успешно обновлена!</p>';
?>

<a href="../info_form.html">Добавить пользователя</a><br/><br/>
<a href="../search_user.html">Вернуться к поиску</a><br/><br/>
<a href="../select_change.php">Вернуться к выбору записей для редактирования</a><br/><br/>
</body>
</html>

all_users.php здесь находятся данные, которые нужно обновить в sqlbd через поля в таблице.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<title>Информационно - образовательная среда</title>
</head>
<body>
<h1 align="center">Информационно - образовательная среда</h1>
<?php
$dom = new DOMDocument();
include('simple_html_dom.php');
require 'scripts/connect.php';
$sql_select = "SELECT FROM not_new_db";
$result = mysql_query($sql_select);
$result=mysql_query("SELECT id,first_name,fast_name,metod,administr FROM users ORDER BY id");
$row = mysql_fetch_array($result);
$dom = new DOMDocument();
$data = $dom->getElementById("metod");

do
{

/
printf("<p>Пользователь: " .$row['fast_name'] . " " .$row['first_name'] . " " .$row['third_name'] ."</p>
<p><i>Контактные данные</i></p><p>методы и средства: " .$row['metod'] . "</p><p>administr: " .$row['administr'] . "</p>---------<br/>"
); */
$n=mysql_num_rows($result);
echo "<table border=1>
<tr><th>ID</th><th>Имя</th><th>Предмет</th><th>Оценка</th></tr>";

//вывод построчно
for($i=0;$i<$n;$i++)
echo
"<tr><td contenteditable=true id=".mysql_result($result,$i,id).">".mysql_result($result,$i,id),
"</td><td contenteditable=true id=".mysql_result($result,$i,first_name).">".mysql_result($result,$i,first_name),
"</td><td contenteditable=true id=".mysql_result($result,$i,fast_name).">".mysql_result($result,$i,fast_name),
"</td><td contenteditable=true id=".mysql_result($result,$i,metod).">".mysql_result($result,$i,metod),
"</td></tr>";
echo "</table>";
}

while($row = mysql_fetch_array($result));

printf("<form action='scripts/update.php'>")

?>

<input id='submit' type='submit' value='Редактировать запись'>

<div id="heretext"></div>
<br/><br/>

</body>
</html>

На пике таблица из которой нужно обновить поле оценок в sql.
148 Кб, 658x515
Нужно сделать обновление в sql db из таблицы на сайте. Lamer 1013 751212
Не обновляет в sql базе из таблицы на сайте при нажатии на кнопку

update.php отправляет запрос на обновления в sqlbd

!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">
<link rel="stylesheet" type="text/css" href="../style.css">
<title>Untitled Document</title>
</head>

<body>

<?php
require 'connect.php';
$id=$_REQUEST['id'];
$first_name=trim($_REQUEST['first_name']);
$fast_name=trim($_REQUEST['fast_name']);
$metod=trim($_REQUEST['metod']);

$update_sql = "UPDATE users SET first_name='$first_name', fast_name='$fast_name', metod='$metod', administr='$administr' WHERE id='$id'";
mysql_query($update_sql) or die("Ошибка вставки" . mysql_error());
echo '<p>Запись успешно обновлена!</p>';
?>

<a href="../info_form.html">Добавить пользователя</a><br/><br/>
<a href="../search_user.html">Вернуться к поиску</a><br/><br/>
<a href="../select_change.php">Вернуться к выбору записей для редактирования</a><br/><br/>
</body>
</html>

all_users.php здесь находятся данные, которые нужно обновить в sqlbd через поля в таблице.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1251">

<link rel="stylesheet" type="text/css" href="style.css">
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.4/jquery.min.js"></script>
<title>Информационно - образовательная среда</title>
</head>
<body>
<h1 align="center">Информационно - образовательная среда</h1>
<?php
$dom = new DOMDocument();
include('simple_html_dom.php');
require 'scripts/connect.php';
$sql_select = "SELECT FROM not_new_db";
$result = mysql_query($sql_select);
$result=mysql_query("SELECT id,first_name,fast_name,metod,administr FROM users ORDER BY id");
$row = mysql_fetch_array($result);
$dom = new DOMDocument();
$data = $dom->getElementById("metod");

do
{

/
printf("<p>Пользователь: " .$row['fast_name'] . " " .$row['first_name'] . " " .$row['third_name'] ."</p>
<p><i>Контактные данные</i></p><p>методы и средства: " .$row['metod'] . "</p><p>administr: " .$row['administr'] . "</p>---------<br/>"
); */
$n=mysql_num_rows($result);
echo "<table border=1>
<tr><th>ID</th><th>Имя</th><th>Предмет</th><th>Оценка</th></tr>";

//вывод построчно
for($i=0;$i<$n;$i++)
echo
"<tr><td contenteditable=true id=".mysql_result($result,$i,id).">".mysql_result($result,$i,id),
"</td><td contenteditable=true id=".mysql_result($result,$i,first_name).">".mysql_result($result,$i,first_name),
"</td><td contenteditable=true id=".mysql_result($result,$i,fast_name).">".mysql_result($result,$i,fast_name),
"</td><td contenteditable=true id=".mysql_result($result,$i,metod).">".mysql_result($result,$i,metod),
"</td></tr>";
echo "</table>";
}

while($row = mysql_fetch_array($result));

printf("<form action='scripts/update.php'>")

?>

<input id='submit' type='submit' value='Редактировать запись'>

<div id="heretext"></div>
<br/><br/>

</body>
</html>

На пике таблица из которой нужно обновить поле оценок в sql.
1015 751234
>>51226

Рано перекатывать. Погоди до вечера, там еще много анонов без ответов.
1016 751246
>>51226
Анус себе перекати таким способом, пес.
Не смог промолчать.
42 Кб, 604x400
1017 751280
>>50657
Не пойму.
>>50668
Вообще не пойму.
>>51058

>Нет, наверно лучше не так.


Ну и совсем вообще не пойму.
Передумал выкладывать гостевуху на Гитхаб, всем огромное спасибо!

Наверну-ка Гитбук, что ли, придётся теперь, похоже. Настало моё времечко. А то половину терминов не пойму пока что.
1018 751358
>>51280
Да, ты типа привыкай.
Чтобы написать 2 строчки кода, нужно прочитать (и запомнить) трехтомную документацию. Если не запомнишь с первого раза, повторить цикл.

Для гита кстати коротенький мануал, всего 285 страниц.
1019 751448
Пока тред не перекатился, поясните за фриланс. Что вы там делаете? Точнее как это выглядит? Вы на каком-то сайте даёте объявление мол - сделаю оригинальный сайт за 100 рублей? Какие в основном запросы у клиентов? В смысле чего они чаще всего требуют?
1020 751453
>>51069
У меня больше вопросов нет, за исключением вот этого >>50142, который я забыл спросить в одном посте.
1021 751460
>>51448
Чаще всего ты ищешь себе клиентов, они тебе дают уже готовый говнокод к которому ты должен что-то добавить или исправить. Часто попадаются неадекваты и люди которые могут не заплатить. На апворке и других англоязычных сайтах будешь конкурировать с толпой индусов за пачку доширака. Вроде всё.
1022 751465
>>51460

>Чаще всего ты ищешь себе клиентов, они тебе дают уже готовый говнокод к которому ты должен что-то добавить или исправить.



Это что-то вроде добавить галерею на сайт?

> Часто попадаются неадекваты и люди которые могут не заплатить.



И что в этом случае делать?

> На апворке и других англоязычных сайтах будешь конкурировать с толпой индусов за пачку доширака. Вроде всё.



Я рассматриваю фриланс как дополнителный доход к основной работе, напрямую не связанной с программированием. Денег мало, кушать охота.
1023 751476
>>51465

>Это что-то вроде добавить галерею на сайт?


Что-то вроде этого, да. Но представь что сайт написали макаки-индусы без какого либо намека на ООП или разделение кода. Вся логика и отображение в одном файле, с странными названиями переменных. И вот к этой каше тебе нужно что-то добавить, и желательно сделать быстро, за пару часов, а то господин будет недоволен и заплатит тебе меньше, или вообще минус в репутацию поставит. Так же бывают задачи посерьезнее, на 1 - 4 дней работы, но для такого нужно иметь хорошую репутацию и communication skills.

>И что в этом случае делать?


От сайта зависит. Я бы на твоем месте лучше о неадекватах подумал, их куда больше.

>Я рассматриваю фриланс как дополнителный доход к основной работе, напрямую не связанной с программированием. Денег мало, кушать охота.


Денег будет хватать если будешь получать в долларах, но для этого нужно знать английский и уметь конкурировать с индусами.
1024 751763
>>51049

>А вот и нет. Что тебе мешает сделать так


> написал 4 строчки


> ну и так далее



Мне мешает "и так далее", даже не потому что оно занимает больше 100 строк кода, а то что это кропотливейшая и медленная работа.
Набрать сто строчек не проблема, проблема нигде не ошибиться.
http://ideone.com/XUfvWb
Кода получилось немного, сам в итоге вижу что выглядит со стороны не страшно.
Но мне приходилось постоянно заглядывать в свои модели, сверяться какие у них свойства, проверять вызовы в тестируемом классе, в итоге заняло больше 2 часов времени написание одного несчастного теста.
Если это время мне будут давать на работе, то без проблем. Но меня терзают смутные сомнения, что кто-то даст столько времени на тесты.
Это надо держать целый отдел тестировщиков, чтобы они могли все свое время уделять не написанию кода, а его тестированию.

Кроме того, мне еще сеттеры для id пришлось добавлять в модели. Доктрина такого делать не рекомендует.

Короче, тестирование это конечно хорошо на бумаге, но реализация пока не очень.

В общем, у меня негативные впечатления от интеграционных тестов. Юнит тесты отдельных изолированных методов еще ничего.
Сейчас переключусь на функциональные, должно быть приятно благодаря краулеру и прочим шикарным библиотекам, и не нужно никаких селениумов.

Ну и если функциональные тесты требуют заполнять бд фейковыми данными, зачем я здесь занимался ручной сборкой десятков объектов?
Не лучше ли сразу залить фейковую бд, и на ней выполнять как интеграционные, так и функциональные тесты за один присест?
129 Кб, 549x600
1025 751859
>>51058

>То есть скрипт выглядит так:


> - очистить БД


> - накатить миграции и справочные данные


> - прогнать тесты



Только что нагуглил плагин для доктрины doctrine fixtures.
Имеешь что-то против нее, или не знал о ней/любишь велосипеды?

Несколько ссылок на тему (потому что у меня уже закладок не хватает, и может еще кому пригодится)
http://stackoverflow.com/questions/14752930/best-way-to-create-a-test-database-and-load-fixtures-on-symfony-2-webtestcase
http://plutov.by/post/data_fixtures
https://www.theodo.fr/blog/2011/09/symfony2-unit-database-tests/

И не надо никаких левых баш-скриптов.
1026 752136
>>48633
Пиздец, не думал что столкнусь с точно такой же херней. Выполнил тестовое задание и попал на собеседование только чтобы отлететь на вопросе "с какой целью вы изучаете пхп?".
1027 752144
>>52136
У меня на собеседовании спросили, девственник ли я, и не гей ли часом?
Ответил положительно на оба вопроса, сразу взяли, больше ничего не спрашивали, сказали завтра же приходить на работу.
Просили соблюдать дресс-код.
1028 752489
Вопрос по пасте про DI.

>Заметь что контейнер — внешняя вещь по отношению к сервису. Мы не передаем сам контейнер в конструктор (иначе это будет ServiceLocator)



А если ServiceLocator не передавать через конструктор, то это будет DI-контейнер? И как не передавать контейнер через конструктор тому же контроллеру, если в контроллере мне нужны TDG, хелпер для регистрации и т.д?
1029 752552
Таки успел переделать комментарии тут >>47423
Теперь этот пост >>50066 можно игнорировать.
1030 752569
>>51358
не надо запоминать.
надо знать, где посмотреть. Если всё запоминать, можно быстро ёбу дать.
52 Кб, 604x474
1031 752697
Можно/нужно ли в Javascript использовать camelCase в названиях переменных?
1032 752704
Посоны, помогите

Как выполнить подобный запрос?

INSERT INTO adAccess (id_user,type)
VALUES (
SELECT DISTINCT
users.`id_user`
FROM users
INNER JOIN users_address ON users_address.id_user = users.id_user
, 3)
1033 752705
>>52704
Вернее как правильно его написать
1034 752709
>>52697
Именно так и только так. Snake-case используется только в HTML и CSS.
55 Кб, 1280x1024
1035 752711
1036 752713
>>52711
Убрал свою шлюху отсюда, тут пацаны делом занимаются, а ты отвлекаешь.
1037 752780
>>52711
Закинь пожалуйста еще этих шлюх да выпей чаю
1038 752787
Вопрос такой про iPad в кредит. В задаче % ставка это месячная или годовая? Не жирно ли школьнику платить 100к?
1039 752789
Успешноtime: 0.02 memory: 52480 signal:0

HomoCredit: 88692.768160878 руб.
SoftBank: 118952.9694837 руб.
StrawberryBank: 102547.63370281 руб.

>>52787
1040 752791
>>52787

Переделал. Получается у гомо кредита самые выгодные условия.
http://ideone.com/v2Xbrk

<?php

error_reporting(-1);

function getFinalPrice ($credit, $pay, $loanRate, $comission){
$totalPay = 0;
while ($credit > 0):
$credit = $credit * (1 + $loanRate/100) + $comission - $pay;
$totalPay += $pay;
endwhile;
$totalPay += $credit;
return $totalPay;
}

$homoCreditTotal = getFinalPrice(39999, 5000, 4, 500);
$softBankTotal = getFinalPrice(39999, 5000, 3, 1000);
$strawberryBankTotal = getFinalPrice(47776, 5000, 2, 0);

echo "HomoCredit: $homoCreditTotal руб.\n";
echo "SoftBank: $softBankTotal руб.\n";
echo "StrawberryBank: $strawberryBankTotal руб.\n";
1041 752913
Хочу запилить шаблонизатор для писем (для рассылки), думаю взять за основу идею с шорткодами в вордпрессе (вставлять данные типа [name], [order_id] и тд, но это) Но всё равно это не позволит сформировать мне весь html на стороне шаблонизатора, только какие то-куски (title, greetings, body) с заменой шорткодов в теле, с последующей вставкой этого в шаблон и отправкой пользователю. Есть идеи более глобального шаблонизатора? (работал с visual composer на вордпрессе, но чтобы его написать уйдет месяца 2-3, и соответственно заказчик за это платить не захочет)
1042 753002
Как подключиться к базе данных, расположенной на сайте? типа www.site/phpmyadmin
вот на этом сайте лежит бд, как мне к ней подключиться, чтобы дамп себе в mysql не качать? логин и пароль известен. в интенрете что-то непонятное пишут, типа надо заходить в пхпадмин и прописывать свой айпишник, как доверенный для подключения извне??
1043 753007
>>50495
да я фл.ру штурмую. не хотел про-акк просто покупать.
1044 753048
>>53002
Доступ к панели управления хостингом есть? Там, как правило, есть ссылка на phpmyadmin.
1045 753342
Помогите решить задачу.
Нужно распарсить строку вида "фигня, фигня, фигня", причем фигня может содержать запятую с пробелом, поэтому explode не подходит.

Регулярка /(?:(фигня), )?(фигня)/ матчит строку, но в первой подмаске значения затирают друг друга.

Как сохранить всю "фигню" из строки?
1046 753351
>>53007

Много отзывов уже набрал? Сколько в среднем стоимость проекта, за которые ты берешься/тебя нанимают? Сколько выходит в час?

Почему именно flru? Есть еще weblancer.net там тож много около-веб-программирования и фрилансим.ру, который на хабре форсят. Про последний не в курсе, возможно заказчики более вменяемые, ит-тусовка.
1047 753452
>>53342
Гугли preg_split. Эта функция работает как explode, только в качестве разделителя позволяет использовать не только символ, но и регулярку. В твоём случае это будет регулярка вроде /\s?,/
1048 753579
>>53452
Ну и чем это будет отличаться от explode?
Повторюсь, фигня может содержать запятую с пробелом, и у фигни есть определенный синтаксис.
1049 753587
Вот сама задача:

Нужно распарсить строку с ETag по RFC. Правильные ответы: "s"d, fsdf" "sdf, sd"f2" "dsf"sdf, sdf345".
И они правильно матчатся, но первая подмаска хранит только последнее значение. Как сохранить все значения?
1050 753589
Вот задача: regexr[точка]com/3dg71
1051 753590
Сука, у обезьяны точка-ком в спам-листе что ли?
1053 753748
>>53589
>>53587

Если у тебя задача матчить списки вида a, b, c то одним применением регулярки сделать это не получится. Такие варианты:

- применять регулярку, используя preg_match_all, недостаток: если в строке есть мусор то он молча проигнорируется. Победить этот недостаток можно сделав preg_split и посмотрев что останется - должны быть только пустые строки с проблемами.
- применять регулярку несколько раз используя preg_match с указанием позиции
- парсить как-то по-другому, без регулярок, например исплоьзуя метод рекурсивного спуска.

>>53599

Да, аноны, перекатывайтесь туда, я хотел позавчера сделать перекат, но устал и уснул. А, и сейчас кстати мне тоже скоро надо будет уходить.

>>53002

Обычно у баз данных стоит ограничение, откуда к ним можно подключаться. Так что чтобы к ней подсоединиться тебе скорее всего нужен ssh-доступ, чтобы прокинуть туннель. Либо использовать phpmyadmin доступ к которому тебе дан.

>>52913

https://habrahabr.ru/post/230737/
Прочитай тут пункт 6

Не понимаю зачем изобретать шаблонизатор когда есть много существующих, например, твиг.

>>52791

> while ($credit > 0):


Версии с двоеточием для шаблонов. используй в коде версию с фигурными скобками.

Алгоритм конечно немного странный, что ты сначала уходишь в минус, а потом как-то костыльно возвращаешь лишние деньги, но ответ получается правильный.
1053 753748
>>53589
>>53587

Если у тебя задача матчить списки вида a, b, c то одним применением регулярки сделать это не получится. Такие варианты:

- применять регулярку, используя preg_match_all, недостаток: если в строке есть мусор то он молча проигнорируется. Победить этот недостаток можно сделав preg_split и посмотрев что останется - должны быть только пустые строки с проблемами.
- применять регулярку несколько раз используя preg_match с указанием позиции
- парсить как-то по-другому, без регулярок, например исплоьзуя метод рекурсивного спуска.

>>53599

Да, аноны, перекатывайтесь туда, я хотел позавчера сделать перекат, но устал и уснул. А, и сейчас кстати мне тоже скоро надо будет уходить.

>>53002

Обычно у баз данных стоит ограничение, откуда к ним можно подключаться. Так что чтобы к ней подсоединиться тебе скорее всего нужен ssh-доступ, чтобы прокинуть туннель. Либо использовать phpmyadmin доступ к которому тебе дан.

>>52913

https://habrahabr.ru/post/230737/
Прочитай тут пункт 6

Не понимаю зачем изобретать шаблонизатор когда есть много существующих, например, твиг.

>>52791

> while ($credit > 0):


Версии с двоеточием для шаблонов. используй в коде версию с фигурными скобками.

Алгоритм конечно немного странный, что ты сначала уходишь в минус, а потом как-то костыльно возвращаешь лишние деньги, но ответ получается правильный.
1054 753759
>>52704

Твой запрос неправильный. Посмотри сам на код:

VALUES(много значений, одно значение)

Это так не работает. Если ты используешь SELECT внутри VALUES то он должен вернуть одно значение.

Однако можно сделать так

INSERT INTO t SELECT x, 3 AS num FROM ...

>>52489

> А если ServiceLocator не передавать через конструктор, то это будет DI-контейнер?


Я бы сказал наоборот: ServiceLocator это когда контейнер передают в конструктор.

> И как не передавать контейнер через конструктор тому же контроллеру, если в контроллере мне нужны TDG, хелпер для регистрации и т.д?


Для контроллеров обычно делают исключение и переают контейнер. Либо можно передавать только необходимые сервисы.

>>52144

Не знаю, в чем тут штука, но за второй вопрос в западных странах можно и судебный иск получить.

>>51859

По моему баш скрипты как раз удобнее для каких-то подготовительных действий. Ими можно запустить какой-нибудь сервис, например временный инстанс редиса с тестовым конфигом. И прибить его по завершению теста.

То, что ты указал, это тоже вариант, хотя мне кажется на баш делать это просто удобнее.

Тут еще надо смотреть как бы тесты не стали слишком медленными. С одной стороны в идеале надо каждый тест запускать на идентичной БД, с другой стороны, это может занять много времени.

Может быть годится вариант сначала подготовить SQL дамп а потом перед каждм тестом его заливать. Хотя .... мне кажется что и так медленно.

Может у тебя какие-то идеи есть? Помни, в реальных приложениях часто под сотню таблиц, тысячи тестов, и надо иметь возможность выполнять их параллельно (знчит надо несколько баз).

Можешь почитать например про баду: https://habrahabr.ru/company/badoo/blog/181488/
1054 753759
>>52704

Твой запрос неправильный. Посмотри сам на код:

VALUES(много значений, одно значение)

Это так не работает. Если ты используешь SELECT внутри VALUES то он должен вернуть одно значение.

Однако можно сделать так

INSERT INTO t SELECT x, 3 AS num FROM ...

>>52489

> А если ServiceLocator не передавать через конструктор, то это будет DI-контейнер?


Я бы сказал наоборот: ServiceLocator это когда контейнер передают в конструктор.

> И как не передавать контейнер через конструктор тому же контроллеру, если в контроллере мне нужны TDG, хелпер для регистрации и т.д?


Для контроллеров обычно делают исключение и переают контейнер. Либо можно передавать только необходимые сервисы.

>>52144

Не знаю, в чем тут штука, но за второй вопрос в западных странах можно и судебный иск получить.

>>51859

По моему баш скрипты как раз удобнее для каких-то подготовительных действий. Ими можно запустить какой-нибудь сервис, например временный инстанс редиса с тестовым конфигом. И прибить его по завершению теста.

То, что ты указал, это тоже вариант, хотя мне кажется на баш делать это просто удобнее.

Тут еще надо смотреть как бы тесты не стали слишком медленными. С одной стороны в идеале надо каждый тест запускать на идентичной БД, с другой стороны, это может занять много времени.

Может быть годится вариант сначала подготовить SQL дамп а потом перед каждм тестом его заливать. Хотя .... мне кажется что и так медленно.

Может у тебя какие-то идеи есть? Помни, в реальных приложениях часто под сотню таблиц, тысячи тестов, и надо иметь возможность выполнять их параллельно (знчит надо несколько баз).

Можешь почитать например про баду: https://habrahabr.ru/company/badoo/blog/181488/
1055 753775
>>53759
Остановился на truncate таблиц во время setUp и заливки свеженьких данных. Да, времени много занимает, но оно же в фоне выполняется. Не говоря уже о трависе, который сделает это на автомате.

Тесты на то и автоматические, что роботу все равно, какая у них там производительность.

>Может быть годится вариант сначала подготовить SQL дамп


Не универсально. Вариант с классами fixtures лучше, потому что не нужно их переписывать при смене платформы.

Кстати doctrine fixtures во время заливки данных по-умолчанию делает delete from table, что неудобно, потому что я не могу знать id.
Для выполнения truncate пришлось писать костыль по рецепту
https://coderwall.com/p/staybw/workaround-for-1701-cannot-truncate-a-table-referenced-in-a-foreign-key-constraint-using-doctrine-fixtures-load-purge-with-truncate

Разбираюсь сейчас с функциональными тестами, отправка форм и работа с куками в том browser-kit, что используется в симфони.

Пока так
https://github.com/nsdvw/TestHub
1056 753777
>>51763

> Мне мешает "и так далее", даже не потому что оно занимает больше 100 строк кода, а то что это кропотливейшая и медленная работа.


решение давно известно: надо делать отдельные функции, создать тест, добавить вопрос итд.

> Набрать сто строчек не проблема, проблема нигде не ошибиться.


Плохо что ты прямо в тест код вставляешь, я бы выносил отдельно создание теста так как это наверняка и в других тестах понадобится да и код у тебя сейчас нечитаемый. Стена кода.

> Но мне приходилось постоянно заглядывать в свои модели, сверяться какие у них свойства, проверять вызовы в тестируемом классе,


Вот это мне кажется неправильно. Надо избегать закладывать в тесты знания о внутреннем устройстве кода. Ты тестируешь АПИ как черный ящик.

> Это надо держать целый отдел тестировщиков, чтобы они могли все свое время уделять не написанию кода, а его тестированию.


Такое бывает. Некоторые делают тестовые сценарии в екселе, некоторые в текстовом виде, и в большом приложении такие сценарии могут быть по объему как книга. И потом отдел живых тестеров по ним проходится. А как ты хотел? Если не тестировать что качество продукта на выходе стремительно пойдет вниз, это к гадалке не ходи.

Впрочем есть и другие примеры. Например, соцсети часто тестируют так: разработчик смотрит новую фичу, менеджер смотрит новую фичу (на продакшене), выкатывают на часть пользователей, потом на всех. Если идут жалобы - откатывают назад. Экономия на тестерах, но для банковского или медичинского приложения такой подход недопустим. Хотя... все мы помним историю с провалом дорогущего американского портала госуслуг по здравоохранению.

> что кто-то даст столько времени на тесты.


Зависит от масштаба проекта. Праздник оплачивает заказчик или работодатель.

> Кроме того, мне еще сеттеры для id пришлось добавлять в модели


Почему кстати? Зачем калькулятору id? Вообще-то вся идея доктрины как раз в том чтобы отвзяать модель от базы.

> должно быть приятно благодаря краулеру и прочим шикарным библиотекам, и не нужно никаких селениумов.


Так яваскрипт не научишься тестировать. Хитрый какой, конечно голый HTML намного проще тестировать чем реальный браузер гонять со всеми багами и задежрками.

> Ну и если функциональные тесты требуют заполнять бд фейковыми данными, зачем я здесь занимался ручной сборкой десятков объектов?


> Не лучше ли сразу залить фейковую бд, и на ней выполнять как интеграционные, так и функциональные тесты за один присест?


ну я подумал что без базы тестировать проде должно быть проще и быстрее.
1056 753777
>>51763

> Мне мешает "и так далее", даже не потому что оно занимает больше 100 строк кода, а то что это кропотливейшая и медленная работа.


решение давно известно: надо делать отдельные функции, создать тест, добавить вопрос итд.

> Набрать сто строчек не проблема, проблема нигде не ошибиться.


Плохо что ты прямо в тест код вставляешь, я бы выносил отдельно создание теста так как это наверняка и в других тестах понадобится да и код у тебя сейчас нечитаемый. Стена кода.

> Но мне приходилось постоянно заглядывать в свои модели, сверяться какие у них свойства, проверять вызовы в тестируемом классе,


Вот это мне кажется неправильно. Надо избегать закладывать в тесты знания о внутреннем устройстве кода. Ты тестируешь АПИ как черный ящик.

> Это надо держать целый отдел тестировщиков, чтобы они могли все свое время уделять не написанию кода, а его тестированию.


Такое бывает. Некоторые делают тестовые сценарии в екселе, некоторые в текстовом виде, и в большом приложении такие сценарии могут быть по объему как книга. И потом отдел живых тестеров по ним проходится. А как ты хотел? Если не тестировать что качество продукта на выходе стремительно пойдет вниз, это к гадалке не ходи.

Впрочем есть и другие примеры. Например, соцсети часто тестируют так: разработчик смотрит новую фичу, менеджер смотрит новую фичу (на продакшене), выкатывают на часть пользователей, потом на всех. Если идут жалобы - откатывают назад. Экономия на тестерах, но для банковского или медичинского приложения такой подход недопустим. Хотя... все мы помним историю с провалом дорогущего американского портала госуслуг по здравоохранению.

> что кто-то даст столько времени на тесты.


Зависит от масштаба проекта. Праздник оплачивает заказчик или работодатель.

> Кроме того, мне еще сеттеры для id пришлось добавлять в модели


Почему кстати? Зачем калькулятору id? Вообще-то вся идея доктрины как раз в том чтобы отвзяать модель от базы.

> должно быть приятно благодаря краулеру и прочим шикарным библиотекам, и не нужно никаких селениумов.


Так яваскрипт не научишься тестировать. Хитрый какой, конечно голый HTML намного проще тестировать чем реальный браузер гонять со всеми багами и задежрками.

> Ну и если функциональные тесты требуют заполнять бд фейковыми данными, зачем я здесь занимался ручной сборкой десятков объектов?


> Не лучше ли сразу залить фейковую бд, и на ней выполнять как интеграционные, так и функциональные тесты за один присест?


ну я подумал что без базы тестировать проде должно быть проще и быстрее.
1057 753783
>>53775

Про дамп - я имел в виду вместо того чтобы перед каждым тестом делать полную инициализацию базы, сгенерировать дамп и дамп перезаливать.

Вообще, я сам предпочитаю не совсем чистое тестирование, когда просто перед тестом вставляются в БД нужные мне в тесте сущности. Чтобы защититься от дубликатов , приходится генерировать уникальные email, идентификаторы и тд.

truncate еще по моему как-то не дружит с внешними ключами...

> Кстати doctrine fixtures во время заливки данных по-умолчанию делает delete from table, что неудобно, потому что я не могу знать id.



> echo shell_exec('app/console doctrine:fixtures:load


А куда в этом варианте идут ошибки выполнения скрипта? Здесь же это даже не проверяется, ну и ад. А ты говоришь баш скрипты - плохо, но там хотя бы результат выполнения команд проверяется если ставить set -e в начале.

> Тесты на то и автоматические, что роботу все равно, какая у них там производительность.


Иногда тебе хочется прогнать тесты самому.

> не нужно их переписывать при смене платформы.


ох, ты все думаешь что можно написать приложение с поддержкой нескольких баз данных...
1058 753793
>>53775

https://github.com/nsdvw/TestHub/blob/master/tests/TestHubBundle/Helper/StringGeneratorTest.php
В этом тесте незачем вызывать инициализацию БД.
1059 753798
>>53775

Еще мне не нравитя что тестовые данные лежат не вместе с тестами. А что если кто-то на продакшене их загрузит?

Ну и конечно вставлять данные в базу через доктрину это самый медленный способ который только можно придумать. Пока у тебя тестов мало, это конечно не проблема, но мне кажется дальше надо будет как-то это оптимизировать. Ну например как я предложил, через дамп.

Ну и еще один вариант, про который я тоже выше говорил, выполнять тест внутри транзакции которую потом откатить, и если ничего в базе не поменялось, то дамп можно заново не заливать.
1060 753801
Перекатывайтесь в новый тред >>753595 (OP)

тут будут ответы только на старые посты.
1061 753816
>>53783
Ну ок, подумаю как вынести заливку данных из setUp в более надежное место.
Кстати то он в статье делает прямой shell_exec, я у себя обернул в примочки симфони, что-то типа
$application->run(new StringInput($command));
Сейчас разберусь, если там есть проверка на ошибки, то все оставлю как есть.

>ты все думаешь что можно написать приложение с поддержкой нескольких баз данных...


А что мне думать? Из серверов баз данных знаю только mysql, ни разу не писал под другую, и естественно ни разу не делал миграцию с одной бд на другую.
Только получив такой опыт, я смогу как-то заранее угадывать, какой кусок кода будет портируемым, а какой нет.

Впрочем здесь я уверен: классы LoadEntityData явно портируемые, потому что все что там происходит это
$entity = new Entity;
$entity->setSmth($smth);
$manager->persist($entity);
$manager->flush();

Полностью поддержку нескольких баз сделать не получится (доверюсь твоему авторитету и опыту), но хотя бы нужно стремиться минифицировать геморрой при переезде.

>>53798

>например как я предложил, через дамп.


Ты же выше говорил, что
>>51058

> с дампом есть подвох, что при изменениях в БД дамп не будет работать, надо решать проблему связей



>вставлять данные в базу через доктрину это самый медленный способ который только можно придумать.


Самый медленный для робота, для меня самый быстрый. Когда понадобится, тогда поправлю. Пока меня все устраивает.

>А что если кто-то на продакшене их загрузит?


Зачем? Во всяком случае это проблема того кто загрузит.
И в дев-режиме я их как раз использую, когда открываю сайт в браузере, не сидеть же на голой базе?

>Еще мне не нравитя что тестовые данные лежат не вместе с тестами.


http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#writing-simple-fixtures

>For a bundle located at src/AppBundle, the fixture classes should live inside src/AppBundle/DataFixtures/ORM


Шуд так шуд.

Вообще мне кажется ты стремишься к перфекционизму там где это не нужно.
Выгадать 3 секунды на тестах, которые делает робот - зачем? Чтобы показать что могу?
Сидеть и 2 часа думать над нестандартным алгоритмом генерации дампа, чтобы выгадать даже не знаю что.
На практике есть 2 фактора: затраченное время и поддерживаемость кода. Мне нужно писать как можно быстрее, и чтобы мой код разобрали самые тупые коллеги.
Я могу сейчас сесть, потратить пару часов времени и накатать нечто, что будет выполнять тест максимально быстро.
Но во-первых зачем? Во-вторых потом моим воображаемым коллегам сидеть и изучать то что я натворю?
Следовательно я должен придерживаться стандартов, даже если они не всегда оптимальные.

Ладно, короче проверь потом как будет время тесты и все остальное, у меня пока есть чем заняться.
1061 753816
>>53783
Ну ок, подумаю как вынести заливку данных из setUp в более надежное место.
Кстати то он в статье делает прямой shell_exec, я у себя обернул в примочки симфони, что-то типа
$application->run(new StringInput($command));
Сейчас разберусь, если там есть проверка на ошибки, то все оставлю как есть.

>ты все думаешь что можно написать приложение с поддержкой нескольких баз данных...


А что мне думать? Из серверов баз данных знаю только mysql, ни разу не писал под другую, и естественно ни разу не делал миграцию с одной бд на другую.
Только получив такой опыт, я смогу как-то заранее угадывать, какой кусок кода будет портируемым, а какой нет.

Впрочем здесь я уверен: классы LoadEntityData явно портируемые, потому что все что там происходит это
$entity = new Entity;
$entity->setSmth($smth);
$manager->persist($entity);
$manager->flush();

Полностью поддержку нескольких баз сделать не получится (доверюсь твоему авторитету и опыту), но хотя бы нужно стремиться минифицировать геморрой при переезде.

>>53798

>например как я предложил, через дамп.


Ты же выше говорил, что
>>51058

> с дампом есть подвох, что при изменениях в БД дамп не будет работать, надо решать проблему связей



>вставлять данные в базу через доктрину это самый медленный способ который только можно придумать.


Самый медленный для робота, для меня самый быстрый. Когда понадобится, тогда поправлю. Пока меня все устраивает.

>А что если кто-то на продакшене их загрузит?


Зачем? Во всяком случае это проблема того кто загрузит.
И в дев-режиме я их как раз использую, когда открываю сайт в браузере, не сидеть же на голой базе?

>Еще мне не нравитя что тестовые данные лежат не вместе с тестами.


http://symfony.com/doc/current/bundles/DoctrineFixturesBundle/index.html#writing-simple-fixtures

>For a bundle located at src/AppBundle, the fixture classes should live inside src/AppBundle/DataFixtures/ORM


Шуд так шуд.

Вообще мне кажется ты стремишься к перфекционизму там где это не нужно.
Выгадать 3 секунды на тестах, которые делает робот - зачем? Чтобы показать что могу?
Сидеть и 2 часа думать над нестандартным алгоритмом генерации дампа, чтобы выгадать даже не знаю что.
На практике есть 2 фактора: затраченное время и поддерживаемость кода. Мне нужно писать как можно быстрее, и чтобы мой код разобрали самые тупые коллеги.
Я могу сейчас сесть, потратить пару часов времени и накатать нечто, что будет выполнять тест максимально быстро.
Но во-первых зачем? Во-вторых потом моим воображаемым коллегам сидеть и изучать то что я натворю?
Следовательно я должен придерживаться стандартов, даже если они не всегда оптимальные.

Ладно, короче проверь потом как будет время тесты и все остальное, у меня пока есть чем заняться.
Ответы https://github.com/timrene/php-link-list/blob/master/D180D0B5D188D0B5D0BDD0B8D0B520D0B7D0B0D0B4D0B0D187.md 1062 755108
>>45461

https://github.com/fidnex/students/
Тебе я отвечу в новом треде >>753595 (OP) позже

https://github.com/timrene/php-link-list/blob/master/решение задач.md
>>46693

W1.(Начало) http://ideone.com/92myam
Ок

W2.(Переменные) http://ideone.com/6wmX2d
Все верно

W3.(Переменные) http://ideone.com/xs7wtu
Тут все верно.

W4.1(Условия и игра в кубики) http://ideone.com/2uOaPB
Все правильно

W4.2(Циклы и айфон в кредит) http://ideone.com/gWyK0D
Верно

W5.1(Циклы и айфон в кредит) http://ideone.com/BqCQWa

> $creditBalance != 0;


Безопаснее ставить условие > 0 чтобы если получится чуть меньше нуля, цикл не оказался вечным.

> $paymentTotal = $paymentTotal + $monthlyPayment - abs($creditBalance);


Выглядит как-то костыльно. Ты уходишь в минус, а потом пытаешься вернуть переплаченные деньги. А нельзя ли их просто не вычитать? Например

- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

W5.2(Циклы и айфон в кредит) http://ideone.com/ZNqjGw
Считает верно, но не советую писать циклы с большой шапкой, так как трудновато его читать. Лучше бы увеличение капитала поместить в тело цикла.

W5.3(Массивы и рулетка) http://ideone.com/ryNGzj
Правильно

W5.4(Массивы и рулетка) http://ideone.com/c4Wtet
Верно

W5.5(Массивы и рулетка) http://ideone.com/Cy79xO
Ок, все правильно.

W5.6(Массивы и рулетка) http://ideone.com/cVtRbN
Правильно.

Строки, хакеры и шифровки (В тылу врага) http://ideone.com/Otzabk
Да, правильно.

Строки, хакеры и шифровки (l33tspeak) http://ideone.com/51m937
Ок, тут все верно.

Строки, хакеры и шифровки (На словах ты Лев Толстой) http://ideone.com/eE0lka
Все правильно. Хотя ты бы мог использовать цикл чтобы не копипастить первые 2 строки.

Строки, хакеры и шифровки (Палиндром) http://ideone.com/07Ea89
Работает верно, но после первого несовпадения можно было бы выходить из цикла.

Функции и новый айпад http://ideone.com/shMxHY
Тут то же замечание что и к айфону: сложновато как-то, в остальном верно.

Регулярные выражения http://ideone.com/b4XOqO
да, правильно.

Регулярные выражения http://ideone.com/qT0TVN
Праивльно, но когда пишешь тесты то стоит выводить что именно неправильно, а у тебя просто пишется что проверка неуспешна, а почему - непонятно.

Регулярные выражения http://ideone.com/c1LKpO
Ок, верно

Регулярные выражения http://ideone.com/vLQDWx
Все правильно

Регулярные выражения https://ideone.com/FRAp6H
Почти верно, но в имени домена не может быть подчеркивания или плюса.

Регулярные выражения https://ideone.com/7oED9U

> [.,;:!?][^ ]


Это сработает на 2 вопроса подряд. Лучше требовать чтобы за знаком шла буква

> зделал|зделаю|зделан


Повторяющуюся часть можно сгруппировать вместе.

А так, в общем, хорошо. Продолжай в том же духе.
Ответы https://github.com/timrene/php-link-list/blob/master/D180D0B5D188D0B5D0BDD0B8D0B520D0B7D0B0D0B4D0B0D187.md 1062 755108
>>45461

https://github.com/fidnex/students/
Тебе я отвечу в новом треде >>753595 (OP) позже

https://github.com/timrene/php-link-list/blob/master/решение задач.md
>>46693

W1.(Начало) http://ideone.com/92myam
Ок

W2.(Переменные) http://ideone.com/6wmX2d
Все верно

W3.(Переменные) http://ideone.com/xs7wtu
Тут все верно.

W4.1(Условия и игра в кубики) http://ideone.com/2uOaPB
Все правильно

W4.2(Циклы и айфон в кредит) http://ideone.com/gWyK0D
Верно

W5.1(Циклы и айфон в кредит) http://ideone.com/BqCQWa

> $creditBalance != 0;


Безопаснее ставить условие > 0 чтобы если получится чуть меньше нуля, цикл не оказался вечным.

> $paymentTotal = $paymentTotal + $monthlyPayment - abs($creditBalance);


Выглядит как-то костыльно. Ты уходишь в минус, а потом пытаешься вернуть переплаченные деньги. А нельзя ли их просто не вычитать? Например

- прибавляем проценты и комиссию к остатку долга (!не вычитаем ничего пока!)
- если остаток маленький, выплачиваем сколько осталось и уходим
- иначе платим 5000

W5.2(Циклы и айфон в кредит) http://ideone.com/ZNqjGw
Считает верно, но не советую писать циклы с большой шапкой, так как трудновато его читать. Лучше бы увеличение капитала поместить в тело цикла.

W5.3(Массивы и рулетка) http://ideone.com/ryNGzj
Правильно

W5.4(Массивы и рулетка) http://ideone.com/c4Wtet
Верно

W5.5(Массивы и рулетка) http://ideone.com/Cy79xO
Ок, все правильно.

W5.6(Массивы и рулетка) http://ideone.com/cVtRbN
Правильно.

Строки, хакеры и шифровки (В тылу врага) http://ideone.com/Otzabk
Да, правильно.

Строки, хакеры и шифровки (l33tspeak) http://ideone.com/51m937
Ок, тут все верно.

Строки, хакеры и шифровки (На словах ты Лев Толстой) http://ideone.com/eE0lka
Все правильно. Хотя ты бы мог использовать цикл чтобы не копипастить первые 2 строки.

Строки, хакеры и шифровки (Палиндром) http://ideone.com/07Ea89
Работает верно, но после первого несовпадения можно было бы выходить из цикла.

Функции и новый айпад http://ideone.com/shMxHY
Тут то же замечание что и к айфону: сложновато как-то, в остальном верно.

Регулярные выражения http://ideone.com/b4XOqO
да, правильно.

Регулярные выражения http://ideone.com/qT0TVN
Праивльно, но когда пишешь тесты то стоит выводить что именно неправильно, а у тебя просто пишется что проверка неуспешна, а почему - непонятно.

Регулярные выражения http://ideone.com/c1LKpO
Ок, верно

Регулярные выражения http://ideone.com/vLQDWx
Все правильно

Регулярные выражения https://ideone.com/FRAp6H
Почти верно, но в имени домена не может быть подчеркивания или плюса.

Регулярные выражения https://ideone.com/7oED9U

> [.,;:!?][^ ]


Это сработает на 2 вопроса подряд. Лучше требовать чтобы за знаком шла буква

> зделал|зделаю|зделан


Повторяющуюся часть можно сгруппировать вместе.

А так, в общем, хорошо. Продолжай в том же духе.
https://github.com/greenTea242/StudentList/ 1063 755109
>>46699

https://github.com/greenTea242/Student_List/compare/master@{20 day}...master
Тебе я отвечу в новом треде >>753595 (OP) позже

А зачем ты вынес bootstrap из public? Ведь там идея что корень сервера в public и все, что за ним, недоступно через веб-сервер. Я имел в виду что бутстрап должен быть в исходном, неисправленном виде в своей папке внутри public.

>> А если пользователь при редактировании захочет очистить какое-то поле, эта проверка ведь его не пропустит?


> Можно удалять поля полностью и добавлять их в бд? Я про это не знал. Мои регулярки не пропускают пустые значения. Менять? Пользователь что, вообще может не заполнять ничего?


Я имел в виду, что если там есть необязательное поле (не помню есть ли оно в условиях), то тогда разумеется пользователь может очистить это поле чтобы сохранить пустое значение.

> Я не нарушаю логику отображения перенося ее из шаблона в методы из вспомогательных классов как ты советовал? В борьбе с копипастом создал их(методов) несколько.


Немножечко нарушаешь, так что лучше особо большие куски кода так не делать. Вообще, в нормальных шаблонизаторах вроде twig есть макросы, то есть "подшаблоны", и в них можно выносить куски кода и позже их вызывать. У нас их нет, так что надо либо куски выносить в отдельные файлы либо делать класс-помощник.

Но для борьбы с копипастом, я думаю, это приемлемо. Просто изолируй все такие функции в отдельном классе.

> [Конфигурация нашей базы данных]


В ini файлах так обозначают не комментарий, а название секции. Их лучше делать латинницей и короткими (или вообще не делать если файл маленький). Комментарий это строка, начинающаяся с точки с запятой.

> static function isInputChecked($genderOfAbiturient, $valueFromInput)


вообще тут можно было просто написать <?= $student->getGender() == Student::GENDER_MALE ? ' checked' : '' ?>. Но можно и функцию.

Остальное позже в новом треде напишу.

> Это нормально что я несколько раз отклонился от общего для кода стиля(камелкейс) для имени переменной и имени метода и использовал вариант с нижним подчеркиванием ("CSRF_token")? Мне показалось, что не очень красиво если будет "CSRFToken". Стоило ли тогда тоже самое делать с authToken для, не знаю как сказать, симметрии чтоли.


Нет, нехорошо. Лучше CSRFToken или csrfToken.

> Ну он у меня в бд попадал через модель. Сейчас после манипуляций с двумя токенами я его добавляю отдельно https://github.com/greenTea242/Student_List/blob/master/public/register.php#L31 . Ок?


Я думаю, не стоит ради токена делать лишний аргумент в setProperties. Его можно задать отдельной командой вроде

$student->setToken(...);

>>46722

> Нужно было перенести функционал метода addAbiturient в createErrorList или сделать как я сделал(методы теперь получают отдельно объект, без добавления его в свойства класса)?


Главная идея что удобнее когда у нас есть 1 метод, которому мы даем студента и получаем ошибки, а не несколько методов и надо угадать в каком порядке их правильно вызывать. То есть твой вариант годится.
https://github.com/greenTea242/StudentList/ 1063 755109
>>46699

https://github.com/greenTea242/Student_List/compare/master@{20 day}...master
Тебе я отвечу в новом треде >>753595 (OP) позже

А зачем ты вынес bootstrap из public? Ведь там идея что корень сервера в public и все, что за ним, недоступно через веб-сервер. Я имел в виду что бутстрап должен быть в исходном, неисправленном виде в своей папке внутри public.

>> А если пользователь при редактировании захочет очистить какое-то поле, эта проверка ведь его не пропустит?


> Можно удалять поля полностью и добавлять их в бд? Я про это не знал. Мои регулярки не пропускают пустые значения. Менять? Пользователь что, вообще может не заполнять ничего?


Я имел в виду, что если там есть необязательное поле (не помню есть ли оно в условиях), то тогда разумеется пользователь может очистить это поле чтобы сохранить пустое значение.

> Я не нарушаю логику отображения перенося ее из шаблона в методы из вспомогательных классов как ты советовал? В борьбе с копипастом создал их(методов) несколько.


Немножечко нарушаешь, так что лучше особо большие куски кода так не делать. Вообще, в нормальных шаблонизаторах вроде twig есть макросы, то есть "подшаблоны", и в них можно выносить куски кода и позже их вызывать. У нас их нет, так что надо либо куски выносить в отдельные файлы либо делать класс-помощник.

Но для борьбы с копипастом, я думаю, это приемлемо. Просто изолируй все такие функции в отдельном классе.

> [Конфигурация нашей базы данных]


В ini файлах так обозначают не комментарий, а название секции. Их лучше делать латинницей и короткими (или вообще не делать если файл маленький). Комментарий это строка, начинающаяся с точки с запятой.

> static function isInputChecked($genderOfAbiturient, $valueFromInput)


вообще тут можно было просто написать <?= $student->getGender() == Student::GENDER_MALE ? ' checked' : '' ?>. Но можно и функцию.

Остальное позже в новом треде напишу.

> Это нормально что я несколько раз отклонился от общего для кода стиля(камелкейс) для имени переменной и имени метода и использовал вариант с нижним подчеркиванием ("CSRF_token")? Мне показалось, что не очень красиво если будет "CSRFToken". Стоило ли тогда тоже самое делать с authToken для, не знаю как сказать, симметрии чтоли.


Нет, нехорошо. Лучше CSRFToken или csrfToken.

> Ну он у меня в бд попадал через модель. Сейчас после манипуляций с двумя токенами я его добавляю отдельно https://github.com/greenTea242/Student_List/blob/master/public/register.php#L31 . Ок?


Я думаю, не стоит ради токена делать лишний аргумент в setProperties. Его можно задать отдельной командой вроде

$student->setToken(...);

>>46722

> Нужно было перенести функционал метода addAbiturient в createErrorList или сделать как я сделал(методы теперь получают отдельно объект, без добавления его в свойства класса)?


Главная идея что удобнее когда у нас есть 1 метод, которому мы даем студента и получаем ошибки, а не несколько методов и надо угадать в каком порядке их правильно вызывать. То есть твой вариант годится.
Ответы - TestHub 1064 755110
>>46747

> Функция start_form подставляет в name именно из имени класса.


> Тогда как я не зная имя формы буду брать данные из запроса?


> $formData = $request->request->get('имя_формы?');


Форма сама берет данные из запроса если ты ей передаешь Request.

> (впрочем сейчас дошло, что к данные из формы можно получить не из реквеста, а из ее объекта, пропустив через $form->handle($request), и оно уже само разгребет какие данные ему нужны).


Вот именно. И разные названия форм защищают нас от случая когда мы обрабатываем данные не тем классом.

По алгоритму. Я думаю, что нам удобнее конечно передавать id сеанса прохождения явно скрытым полем либо в URL либо хранить его в куках (тут надо учесть что пользователь может теоретически попытатться пройти 2 разных теста параллельно - значит нужные разные куки).

Соответственно идея такая:

- пользователь заходит на вводную страницу и ПОСТит запрос "начать тест" (изменения на сервере мы делаем через ПОСТ)
- создается сеанс (и регистрация если надо), и пользователь получает ид сеанса (либо в куку либо в URL, вариант с URL более соответствует REST имхо - не имея сеанса нельзя открыть вопрос и не требуется проверять соответствие сеанса тесту. Также при истечении времени мы можем показать ссылку на результат). Например /test/session/{sessionId}/question/{qId} или вариант с /test/ + кука.
- далее, пользователя редиректит на первый вопрос
- если у пользователя нет id сеанса, и он хочет открыть вопрос, показываем ошибку (может время закончилось? может пользователь уже прошел тест? может пользователь опечатался в УРЛ? может баг у нас?) и предлагаем начать тест заново либо посмотреть результат например. Возможны варианты.
- отвечая, пользователь ПОСТит ответ на вопрос и редиректится либо на следующий либо на результат или видит ошибки если время истекло.
- заканчивая тест, пользователь ПОСТит соотв. запрос и редиректится на страницу результата.

У тебя мне не очень нравится вся эта магия с автоматическим созданием сеансов, да еще и в ответ на GET запрос, это по моему плохо соответствует логике HTTP. И смотри, у тебя там есть магия с угадыванием ид сеанса, а в моем варианте все однозначно - сеанс указан в УРЛ. Меньше проверок, меньше дыр, меньше ошибок. И у меня все чин чином - GET для получения данных, POST - Redirect - GET для изменения.

Что скажешь? И почитай про REST тогда если не читал.
Ответы - TestHub 1064 755110
>>46747

> Функция start_form подставляет в name именно из имени класса.


> Тогда как я не зная имя формы буду брать данные из запроса?


> $formData = $request->request->get('имя_формы?');


Форма сама берет данные из запроса если ты ей передаешь Request.

> (впрочем сейчас дошло, что к данные из формы можно получить не из реквеста, а из ее объекта, пропустив через $form->handle($request), и оно уже само разгребет какие данные ему нужны).


Вот именно. И разные названия форм защищают нас от случая когда мы обрабатываем данные не тем классом.

По алгоритму. Я думаю, что нам удобнее конечно передавать id сеанса прохождения явно скрытым полем либо в URL либо хранить его в куках (тут надо учесть что пользователь может теоретически попытатться пройти 2 разных теста параллельно - значит нужные разные куки).

Соответственно идея такая:

- пользователь заходит на вводную страницу и ПОСТит запрос "начать тест" (изменения на сервере мы делаем через ПОСТ)
- создается сеанс (и регистрация если надо), и пользователь получает ид сеанса (либо в куку либо в URL, вариант с URL более соответствует REST имхо - не имея сеанса нельзя открыть вопрос и не требуется проверять соответствие сеанса тесту. Также при истечении времени мы можем показать ссылку на результат). Например /test/session/{sessionId}/question/{qId} или вариант с /test/ + кука.
- далее, пользователя редиректит на первый вопрос
- если у пользователя нет id сеанса, и он хочет открыть вопрос, показываем ошибку (может время закончилось? может пользователь уже прошел тест? может пользователь опечатался в УРЛ? может баг у нас?) и предлагаем начать тест заново либо посмотреть результат например. Возможны варианты.
- отвечая, пользователь ПОСТит ответ на вопрос и редиректится либо на следующий либо на результат или видит ошибки если время истекло.
- заканчивая тест, пользователь ПОСТит соотв. запрос и редиректится на страницу результата.

У тебя мне не очень нравится вся эта магия с автоматическим созданием сеансов, да еще и в ответ на GET запрос, это по моему плохо соответствует логике HTTP. И смотри, у тебя там есть магия с угадыванием ид сеанса, а в моем варианте все однозначно - сеанс указан в УРЛ. Меньше проверок, меньше дыр, меньше ошибок. И у меня все чин чином - GET для получения данных, POST - Redirect - GET для изменения.

Что скажешь? И почитай про REST тогда если не читал.
Ответы 1065 755111
>>46905

Можно положить внутрь label инпут и еще один элемент для подсветки кнопки. Тогда for не нужен.

>>46939

> Junior'a разработчика


Junior разработчика

>>46941

В $_SERVER посмотри

>>47172

https://github.com/nsdvw/TestHub я наверно гляну позже в новом >>753595 (OP) треде

> Дня 3 только обдумывал как сделать, переписывал несколько раз.


Это нормально учитывая что ты начинающий

> Как вообще по времени в нормальной конторе?


зависит от компании но долго тянуть в любом случае плохо. Пока ты начинающий впрочем требования не такие строгие.

> Короче, у меня трудности в проектировании архитектуры приложения


Ну не беда, думаю, с опытом будет лучше.

> Но я все-таки думаю, что в хорошей конторе действительно будет хотя бы командная работа


Вообще бывает по-разному. Некоторая самостоятельность не помешает. Но начинающим конечно обычно дают задачи попроще.
Ответы 1065 755111
>>46905

Можно положить внутрь label инпут и еще один элемент для подсветки кнопки. Тогда for не нужен.

>>46939

> Junior'a разработчика


Junior разработчика

>>46941

В $_SERVER посмотри

>>47172

https://github.com/nsdvw/TestHub я наверно гляну позже в новом >>753595 (OP) треде

> Дня 3 только обдумывал как сделать, переписывал несколько раз.


Это нормально учитывая что ты начинающий

> Как вообще по времени в нормальной конторе?


зависит от компании но долго тянуть в любом случае плохо. Пока ты начинающий впрочем требования не такие строгие.

> Короче, у меня трудности в проектировании архитектуры приложения


Ну не беда, думаю, с опытом будет лучше.

> Но я все-таки думаю, что в хорошей конторе действительно будет хотя бы командная работа


Вообще бывает по-разному. Некоторая самостоятельность не помешает. Но начинающим конечно обычно дают задачи попроще.
Ответы 1066 755112
>>47423

Тебя https://github.com/foobar1643/filehosting я наверно проверю в следующем >>753595 (OP) треде

>>47709

Быть старшим не так просто. Ведь если ты старший и ты допустим что-то забыл проверить или сделать, то джуниоры будут сидеть без дела или тупить. И терять время. Надо вовремя проверять их код, заранее подготавливать им задачи с пояснениями и постоянно отвечать на их вопросы (даже когда думаешь над задачей). Особенно весело когда что-то от тебя нужно сразу нескольким людям, включая не-разработчиков. И свои задачи успевать делать. И думать можно ли доверить человеку задачу требующую понимания архитектуры например, не наломает ли он дров.

А что касается времени, если это в офисе то те же самые 8 часов. ну может иногда придется задержаться или прийти пораньше чтобы джуну задачу подготовить или замечания написать.

А у джуниора ответственности меньше, если он протупил то никто другой не страдает.

Но вообще, везде по-разному. Где-то просто неопытных и несамостоятельных вообще не берут, где-то с ними возятся, где-то отправляют в гугл.

>>47760

> я бы например не против 9-часового дня


приходишь домой, открываешь мануал симфони и пхп тред и учишься :3

> Я к тому, что опытный квалифицированный чел должен быть избавлен от рутинной работы, ему поручить сложные общие вопросы типа архитектуры, алгоритма работы какой-то нестандартной фичи, а также код-ревью.


Ну, так никто работать не будет. Обычно старший разработчик тоже кодит.

> Я думал то оп бомбанул от предложения час в день тратить на детальный разбор полетов,


Час общего времени в день это много и дорого. Потому я говорил про 15 минут в неделю. А насчет проверки кода - это можно сделать в частном порядке, не отвлекая других.
Ответы 1067 755113
>>47948

[abcd]* значит любые указанные символы в любом порядке. Ты что-то не так наверно сделал, у тебя же идет вариант (a*b*c*d*){4} который как минимум странный.Например непонятно откуда цифра 4 взялась.

>>47953

1) логично в students добавить так как хеш это свойство студента
2) да, в классе Student

>>47986

тебя https://github.com/applejacky/tmp я прверю в новом треде >>753595 (OP)

>>48131

https://ideone.com/DXHFhC
правильно

https://ideone.com/qwtIDQ
Ок, верно, можно еще было исплоьзовать флаг i чтобы не писать отдельно маленькие и большие буквы.

https://ideone.com/pMXJWi
Тоже верно.

https://ideone.com/XL60TP

> "/ |-|\(|\)/";


Тут удобнее использовать квадратные скобки наверно. А так, праивльно.

https://ideone.com/PJMCE3
Ок. верно

https://ideone.com/Z2HIdy
Почти верно, ты только забыл что в домене могут быть цифры: 003.ru
Ответы 1067 755113
>>47948

[abcd]* значит любые указанные символы в любом порядке. Ты что-то не так наверно сделал, у тебя же идет вариант (a*b*c*d*){4} который как минимум странный.Например непонятно откуда цифра 4 взялась.

>>47953

1) логично в students добавить так как хеш это свойство студента
2) да, в классе Student

>>47986

тебя https://github.com/applejacky/tmp я прверю в новом треде >>753595 (OP)

>>48131

https://ideone.com/DXHFhC
правильно

https://ideone.com/qwtIDQ
Ок, верно, можно еще было исплоьзовать флаг i чтобы не писать отдельно маленькие и большие буквы.

https://ideone.com/pMXJWi
Тоже верно.

https://ideone.com/XL60TP

> "/ |-|\(|\)/";


Тут удобнее использовать квадратные скобки наверно. А так, праивльно.

https://ideone.com/PJMCE3
Ок. верно

https://ideone.com/Z2HIdy
Почти верно, ты только забыл что в домене могут быть цифры: 003.ru
Ответы 1068 755114
>>48146

> Это поведение можно менять session_set_cookie_params


Это парааметры жизни куки, а не самой сессии на сервере

> А что, по-твоему, было бы лучшей идеей для логина? Я пробую варинаты.


куки

>>48149

> Вроде в итоге справился с тестовым


Вообще, нет, ему по моему сказали учебники идти читать (второй раз).

>>48163

Реально, но может 1с удобнее?

>>48261

Код некачественный, по моему есть проблемы с безопасностью местами. "Соцсеть" - набо процедурной лапши.

>>48292

тебя https://github.com/TheSidSpears/Students я наверно проверю позже в новом треде >>753595 (OP)

>>48907

> . Конечно хорошо, когда только закоммитишь, а травис тебе уже во всю трубит о баге.


Потому что часто такие ситуации, когда баг обнаруживается спустя много времени, код разросся, исправлять тяжело и неудобно.
Даже хуже: ты написал функционал, через полгода ты или ньюфаг его сломал, и ошибка может остаться незамеченной. Тестами ты защищаешь свою сделанную работу.

> 1. В симфони нет бандла для тестирования?


Не знаю, погугли или помануаль. Там есть например эмулятор html браузера и штука для выборки узлов ДОМ по css селекторам (DomCrawler):

http://symfony.com/doc/current/book/testing.html
http://symfony.com/doc/current/best_practices/tests.html
Ответы 1068 755114
>>48146

> Это поведение можно менять session_set_cookie_params


Это парааметры жизни куки, а не самой сессии на сервере

> А что, по-твоему, было бы лучшей идеей для логина? Я пробую варинаты.


куки

>>48149

> Вроде в итоге справился с тестовым


Вообще, нет, ему по моему сказали учебники идти читать (второй раз).

>>48163

Реально, но может 1с удобнее?

>>48261

Код некачественный, по моему есть проблемы с безопасностью местами. "Соцсеть" - набо процедурной лапши.

>>48292

тебя https://github.com/TheSidSpears/Students я наверно проверю позже в новом треде >>753595 (OP)

>>48907

> . Конечно хорошо, когда только закоммитишь, а травис тебе уже во всю трубит о баге.


Потому что часто такие ситуации, когда баг обнаруживается спустя много времени, код разросся, исправлять тяжело и неудобно.
Даже хуже: ты написал функционал, через полгода ты или ньюфаг его сломал, и ошибка может остаться незамеченной. Тестами ты защищаешь свою сделанную работу.

> 1. В симфони нет бандла для тестирования?


Не знаю, погугли или помануаль. Там есть например эмулятор html браузера и штука для выборки узлов ДОМ по css селекторам (DomCrawler):

http://symfony.com/doc/current/book/testing.html
http://symfony.com/doc/current/best_practices/tests.html
Ответы 1069 755115
>>49300

git branch , git config, got log -p, git diff , git reset

>>50126

тебя https://github.com/TheSidSpears/Students я наверно проверю позже в новом треде >>753595 (OP)

>>51035

> Не знаю как из класса теста обратиться к доктрине.


Получить через контейнер

> где предлагают возню с xml-ными конфигами и дампами.


Вообще если дамп в том же csv или yaml то это удобнее чем код писать, меньше лишнего.

>>51212

Отлаживай код. Натыкай var_dump и посмотри что в переменных, смотри, какие ветки выполняются, а какие нет, сдампь что пришло в var_dump($_POST); и тд.

Также, надо либо включить режим вывода ошибок (display_errors) если речь о тестовом сервере либо смотреть их в логах (погугли) если речь о продакшене.

>>53816

> Кстати то он в статье делает прямой shell_exec, я у себя обернул в примочки симфони, что-то типа


> $application->run(new StringInput($command));


разниа есть, в первом случае запускается shell и из него процесс php, во втором все внутри текущего процесса происходит
Ответы 1069 755115
>>49300

git branch , git config, got log -p, git diff , git reset

>>50126

тебя https://github.com/TheSidSpears/Students я наверно проверю позже в новом треде >>753595 (OP)

>>51035

> Не знаю как из класса теста обратиться к доктрине.


Получить через контейнер

> где предлагают возню с xml-ными конфигами и дампами.


Вообще если дамп в том же csv или yaml то это удобнее чем код писать, меньше лишнего.

>>51212

Отлаживай код. Натыкай var_dump и посмотри что в переменных, смотри, какие ветки выполняются, а какие нет, сдампь что пришло в var_dump($_POST); и тд.

Также, надо либо включить режим вывода ошибок (display_errors) если речь о тестовом сервере либо смотреть их в логах (погугли) если речь о продакшене.

>>53816

> Кстати то он в статье делает прямой shell_exec, я у себя обернул в примочки симфони, что-то типа


> $application->run(new StringInput($command));


разниа есть, в первом случае запускается shell и из него процесс php, во втором все внутри текущего процесса происходит
Тред закрыт 1070 755116
Аноны, я всем ответил (кроме нескольких человек которым планирую ответить в следующем треде).

Переходите в новый тред >>753595 (OP)
1071 755117
Если я кого-то пропустил - напомните о себе в новом треде.
Обновить тред
Двач.hk не отвечает.
Вы видите копию треда, сохраненную 15 января 2020 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски