Этого треда уже нет.
Это копия, сохраненная 22 ноября 2016 года.

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
33 Кб, 500x500
157 Кб, 1024x683
194 Кб, 1024x768
364 Кб, 1920x1080
Клуб изучающих PHP 82 #864640 В конец треда | Веб
Добро пожаловать в наш уютный тред. Тут мы изучаем язык PHP (а также JS/CSS/HTML/SQL), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет научиться программировать, кто-то - делать сайты, кто-то - просто размять мозги и заняться чем-то полезным.

Это не чат! Высказывайтесь одним большим постом, а не цепочкой мелких

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

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

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

Мейлруч лежит? Есть запасной тред: http://dobrochan.org/s/res/23225.xhtml#i46467

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

Правила: ведем себя воспитанно, помогаем новичкам, постим ссылки на решения задачек, ОП их проверяет и дает советы и замечания. ОП заходит редко, где-то раз в 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/Symfony: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование https://gist.github.com/codedokode/a455bde7d0748c0a351a
- Если ты все решил, переходи к 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://github.com/codedokode/pasta/blob/master/db/databases.md

Что почитать

- Мануал по PHP — http://www.php.net/manual/ru/langref.php
- Сайт phptherightway (перевод на русский: http://getjump.me/ru-php-the-right-way/ )
- По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
- По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
- JS: learn.javascript.ru
- Про Git: https://git-scm.com/book/ru/v1

Оформляй код аккуратно!!! — например пропусти через phpformatter.com . Также, если ты пользуешься IDE вроде PhpStorm, Netbeans, Eclipse, то в них эта опция встроена, подробнее: https://gist.github.com/codedokode/8759492

Платиновые вопросы

- Почему PHP? Потому что фейсбук и википедия на нем написаны, и вакансий море, и учить легко.
- Сайт опять упал!!!!! — Не паникуй, а открой http://rghost.ru/6bfCY9lfl и получи личную немного устаревшую оффлайновую копию сайта (можно читать хоть на андроиде без интернета)
- Что надо знать чтобы найти работу - разработчику: PHP, SQL, HTML/CSS, JS, ООП, Git, композер, MVC, фреймворк. Верстальщику - HTML/CSS, JS, jQuery
- Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
- Посоветуйте редактор кода - Sublime Text 3, Notepad++, PhpStorm
- Нужен ли ООП, фреймворки, MVC, git, composer? — Да, однозначно. Посмотри любую вакансию.
- Что самое главное для программиста? Умение аккуратно оформлять код.
- ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.
- Подскажи сайты для поиска работы, я не умею гуглить? — hh.ru, geekjob.ru, moikrug.ru (склеен с brainstorage.me), fl.ru, upwork.com (бывший одеск). Имей в виду, что кроме фриланса есть еще постоянная удаленная работа (remote job) когда тебе не надо тратить время на поиск заказов и переговоры с неадекватными заказчиками.
56 Кб, 500x644
359 Кб, 900x600
321 Кб, 1024x576
Прочти внимательно #2 #864641
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.

Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492

Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть стандарты PSR-1 и 2. Вот как надо оформлять код:

- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек
- мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)

Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:

PSR-1: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-2-coding-style-guide.md

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

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

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

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

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

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

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

Объясняй

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

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

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

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

Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
56 Кб, 500x644
359 Кб, 900x600
321 Кб, 1024x576
Прочти внимательно #2 #864641
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

Если тебе лень выравнивать код руками, закачай его на http://beta.phpformatter.com/ и нажми «format». Робот исправит выравнивание и отступы в мгновение ока (да, прогресс не стоит на месте). Если ты используешь мощную IDE вроде PhpStorm, там тоже есть функция форматирования кода.

Горячие клавиши для форматирования кода в разных IDE: https://gist.github.com/codedokode/8759492

Вообще, в PHP долгое время не было единого стандарта оформления кода, все писали как попало и было много бардака, но сейчас дело лучше — есть стандарты PSR-1 и 2. Вот как надо оформлять код:

- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- Название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский? Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо из-за обилия точек и кавычек
- мы используем для отступов 4 пробела (можно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)

Вот ссылка на стандарты, где все это описано подробнее и даны примеры оформления:

PSR-1: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-1-basic-coding-standard.md
PSR-2: https://github.com/samdark/fig-standards-ru/blob/master/accepted/ru/PSR-2-coding-style-guide.md

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

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

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

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

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

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

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

Объясняй

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

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

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

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

Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
#3 #864755
Yii2-знатоки, вопрос к вам. Имеется пикрелейтед. Header и footer подключаются через шаблон. При переходе на данную страницу срабатывает actionProfile контроллера Master, который рендерит страницу целиком(кроме очевидных хедера и футера). При нажатии на ссылку из меню управление передается контроллеру Master actionСсылкаНейм, который рендерит тот же самый profile, а помимо этого через параметры передает ссылку для рендера в правой части вида, т.е получается рендер в рендере.

По-хорошему же надо сделать так, чтобы view Profile, в котором только левое меню рендерилось один раз, а правая часть страницы менялась ajaxом при клике на другой пункт меню. Через скрытие блоков сделать нельзя, т.к. url в зависимости от выбранной ссылки должен меняться. Также планируются пункты меню из других контроллеров, которым тоже нужно передавать значение Мастера, в результате получаются охуенные костыли.
Буду рад любой помощи.
>>864757>>870287
13 Кб, 1238x560
#4 #864757
>>864755
Как назло отклеилось
#5 #864763
ребят помогите мне самбу настроить
делаю вроде простой конфиг, а всё равно ничего не разрешает в папке редактировать

comment = none
path = /var/www/html
browsable = yes
guest ok = yes
writable = yes
>>864924
#6 #864924
>>864763
Юзер самбы != юзер ос. Ты это ушёл?
>>864925>>865024
#7 #864925
>>864924
Учел *
#8 #864934
Все треды как треды, а пхп как для даунов

>Это не чат! Высказывайтесь одним большим постом, а не цепочкой мелких



А на самом деле шапка оче годная.
Satosi #9 #865009
Аноны, подскажите мне пожалуйста. Хочу запилить свою страничку, что-то типа бложика + раздел с проектами. Как думаете стоит это делать сейчас (Изучаю с 1 октября), когда знаю только функционалку, или стоит ещё месяц изучать ООП и MVC?
>>870287
#10 #865014
Sup
есть задачка
Например: есть число 123, то программа должна вычислить сумму цифр 1, 2, 3, т. е. 6.
мое решение

$numberRandom = 55;
$array = str_split($numberRandom);
echo array_sum($array);

решение автора

$number = "1547";
$sum = 0;
for($i = 0; $i <= strlen($number); $i++) {
$sum += $number[$i];
}
echo $number."<br/>";
echo $sum;

все разное, но мое короче
или что то я сделал не так?

вон какую программку я написал, теперь у меня есть шансы стать программистом?
>>865016>>870287
#11 #865015
Салам.
В чем разница фулстэк, бэкенд и т.д.?
Куда лучше стремиться развиваться? Плюсы и минусы.
>>865018>>870287
#12 #865016
>>865014
Теперь вычисли факториал 100! т.е. 12 ... 99100
>>865017
#13 #865017
>>865016
1x2x ... x99x100
>>865020
#14 #865018
>>865015

>бэкенд


Часто только PHP (+ вариации CGI, Java, Linux...)

>фулстэк


PHP(в общих чертах) + JS + CSS + HTML + 100500 технологий JS типа cofeeScript, React, Angular нутыпонял.
#15 #865019
Чот в прошлом треде спросил про то, как push делать через PHPStorm, мне ответили, я сказал спасибо, да и забил. А сечас перечитываю тред, а там ответов 40 про то, что надо консоли изучать и вообще я нуб. Ребзя, вопрост был, "Почему после каммита и пуша, происходит 20 изменений в 20 разных файлах и пуш перестаёт работать, выдавая сообщение что изменений нет? " Откуда вы взяли что я про Gitbush не знаю? Почему вы подумали что я консольные команды не знаю? Зачем вы об этом спорили, когда вопрос был именно про IDE? Вообще непонял.
>>870456
#16 #865020
>>865017
Подсказка log xy = log x + log y
>>870456
#17 #865024
>>864924
да мне уже подсказали
в ручную нужной папке уровень доступа нужный сделал
всё равно спасибо :3
#18 #865339
ПОБЕДА. Взяли джуном, на испытательный. Опыта 0. Показал решение задачи про регитрацию студентов из ОП-поста и решил тестовое задание. На вопросы на собеседовании отвечал очень хуево. Знаю ли битрик, что такое ORM, как сделать наследовать от нескольких классов, как запрашивать данные сразу из нескольких таблиц, ни на что ответить не смог. Спасло только то что, в отличии от конкурентов, придумал хороший алгоритм тестовой задачи и хорошо закомментировал там все. И наверное что попросил низкую зп на первое время.
Очень признателен ОПу за его уроки.
#19 #865344
>>865339
Но там еще был такой момент, в тестовом задании говорилось что нужно использовать МВЦ, ну я вспомнив урок Опа разделил всю логику приложения, работы с данными и отображения по разным классам и шаблонам и думал что этого достаточно, требования соблюдены. Но в конторе мне сказали ни хрена так не правильно, нужно именно создавать три папки модел, вью, контролер и складывать все в них. Такая хуйня.
А и да, я 27 лвл, образования нет, кодинг учу полгода где то.
>>865379>>870456
#20 #865364
Не в тему, но спрошу тут, так как нигде больше не отвечают: вот я через npm глобально установил яpug-cli (интерфейс командной строки для pug), все компилируется, а тогда зачем сам pug нужен, в том числе глобальный?
>>865366>>870456
#21 #865366
>>865364
pug-cli
#22 #865379
>>865344

> ни хрена так не правильно, нужно именно создавать три папки модел, вью, контролер


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

Хотя, забей. Искренне тебя поздравляю! :3
105 Кб, 1159x365
#23 #865424
Необходимо добавить значение в массив. Удаляет корректно, а вот добавить не могу, что-то идет не так.
>>870456
#24 #865554
Серьёзно торможу, как выбрать при помощи jQuery или JS значение поля формы, если есть несколько полей с одним именем в виде массива. Есть скрипт, который генерирует количество форм с одинаковым параметром name, взависимости от выбора пользователя. В каждую из этих форм вводится значения, как получить массив со всеми значениями? То есть допустим пользователь выбрал 3 формы и в каждое ввёл данные:

Введите телефон номер 1:
<input type="text" name="phones[]">
Введите телефон номер 2:
<input type="text" name="phones[]">
Введите телефон номер 3:
<input type="text" name="phones[]">

Как при помощи jquery выбрать все введённые значения?
>>865571>>865573
#25 #865559
>>865339

>придумал хороший алгоритм тестовой задачи


Напиши пожалуйста какую ты задачу решал?
>>866034
#26 #865571
>>865554
stackoverflow.com/questions/19529443/jquery-get-input-array-field
#27 #865573
>>865554

1) найти по name
2) обойти в цикле, например, each()
#28 #865574
>>858807

> $student=$this->c['table']->getStudentByHash($_COOKIE['hash']);


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



А зачем?

> https://github.com/TheSidSpears/Students/blob/master/app/Models/Student.php#L38


> Вообще, конечно методы вроде addInfo - это открытый путь к уязвимостям, так как люди забывают делать фильтрацию и передают туда сразу $_POST. Гитхаб так взломали однажды



Лучше всё вручную передавать? $s->name=$name; итл Или как?
>>870456
#29 #865582
Можно ли в action <form> писать ссылки с переменными?

<form method='get' action='main?sortBy=group_num&orderBy=desc'>
>>870287
98 Кб, 1366x768
#30 #865626
Сап , аноны. Помогите начинающему программисту. Я изучаю PHP по вашим урокам ( http://archive-ipq-co.narod.ru/). На 3 уроке встретился с проблемой выполнения задания , анон , помоги. Вот код который я написал для выполнения :
<?рhp
error_reporting(-1) ;
$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";
if {$anonDice1} == {$anonDice2} && {$compDice1} == {$compDice2} {
echo "У тебя выпали даблы\n";
exit();
}
$anonSum = $anonDice1 + $anonDice2;
$compSum = $compDice1 = $compDice2;
if {$anonSum} > {$compSum} {
echo "anon wins";
} else {
echo "comp wins"
exit()
}
?>
Но вместо выполнения оператора условия , мой код просто полностью выходит и всё. Команды не выполняются.
Жду вашей помощи , аноны
>>865629>>865850
#31 #865628
>>858807

> Насчет валидатора - у тебя нет желания как-то сделать его более ООП?



Да, попозже займусь этим

> У тебя есть такие относительные УРЛ и потому возможен баг.



Все url'ы рабочие

> > if( (isset($user->email)) and ($user->email==$student->email) ):


> Лучше проверять наверно по hash или id как неизменному значению. А если используется правильный дата маппер с Identity Map, то можно просто писать $user === $student.



Звучит прикольно, но как это реализовать? Погуглил, суть ясна, но сложно представляю с чего начать.
$user - это return ф-ии getStudentByHash();
$student- это элемент массива полученного от getStudents();
>>870456>>870459
#32 #865629
>>865626
Кидай лучше ссылку на код, а не копируй сюда.

Начни с простого: http://ideone.com/cptdIr
У тебя уже на этом этапе код работает неверно (см. на то, что он выводит). Разберись сначала с этим, дальше может поймешь, что не так
>>865633
#33 #865633
>>865629
Хотя подожди, какой-то глюк, вот тут тот же код выполняет всё: http://ideone.com/JoGYDy

Вообщем, ошибка в синтаксисе if'а. Там не нужны никакие {}

if($a==$b){
echo "Равны";
}

exit'ы тоже не нужны
#34 #865640
>>853691
Просто оставлю это здесь для себя.
#35 #865647
Кошерно ли использовать $_SESSION для передачи какихнить не очень важных данных между файлами пхп. например у меня сложный сайт с роутером и отедльными классами для работы с данными. Мне надо как то на рендер передавать информационные сообщения или ошибки (не кода, а пользовательских действий), после нескольких проб я попробовал передавать в $_SESSION['errors'] массив с ошибками, после чего я обрабатываю его при рендере, в зависимости от массива вывожу сообщение или информацию и очищаю эту переменную в $_SESSION. какие подводные камни? работает и выглядит все просто вроде
>>865852
#36 #865783
Насколько плохо я выполнил задачу со списком студентов?

https://github.com/anonymous011010/studentslist
>>874485>>874486
#37 #865850
>>865626

ideone видимо сломался и вместо выолнения php кода просто его выводит.

Попробуй другие сайты, например http://phptester.net/ или http://codepad.org/ или http://www.runphponline.com/

Или погугли по словам "run php code online".
#38 #865852
>>865647

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

Для передачи данных между скриптами сессии тоже не лучший вариант, так как куки (а следовательно и сессии) общие для всех вкладок в браузере. Если ты знаешь, как реализованы сессии, то понимаешь почему.
>>865948>>868883
#39 #865948
>>865852
вот именно между скриптами. там просто есть класс который возвращает данные, так за время выполнения (загрузки одной страницы) создается 3 экземпляра в разных местах. Получается в одном из экземпляров есть нужный мне массив, но хз как из него передать в другой скрипт, в котором создается новый экземпляр.

а $GLOBALS не правильно, аналогично сессиям или $GLOBALS уже норм?
>>865956
#40 #865956
>>865948

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

Способ, который работает в нескольких вкладках - передавать данные через POST/GET (но тут есть подвох что пользователь видит и может менять передаваемые данные).

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

Для проверки форм и вывода ошибок есть готовый алгоритм, не требующий сессий: https://github.com/codedokode/pasta/blob/master/forms.md

Он тебе подходит?
>>866170>>868884
#41 #866012
Добрый вечер, не знаю в этот или в JS тред писать, с какой стороны проблема.
Написал скрипт который работает долго, если лимитов нет по времени на сервере то часов 5-6, для того, чтобы не смущать пользователя сделал вывод информации в реальном времени о ходе выполнения, онлайновый стрим данных сделал с помощью 'text/event-stream', echo json даты и ob_flush(); flush();
На стороне браузера есть eventListener по message который обновляет статистику для юзера. Так вот, на локалке у меня всё нормально работает, обновляется примерно раз в 1-2 секунды, на продакшне сервер пошустрее работает - по-идее там выполнение скрипта в пару раз быстрее и статистика там не обновляется, висит долго ожидание соединения, потом через пару минут прилетает сразу огромное количество сообщений по eventStream за всё время ожидания, потом снова пауза. Я подозреваю что из-за более быстрой работы скрипта - браузер не справляется с флудом и не отрабатывает так как надо. Или всё же может быть другая проблема?
>>878132
#43 #866037
>>866034
У кого есть опыт, скажите это сложное задание для джуна?
>>866039
#44 #866039
>>866037
Простенькое, роутинг сделать самодельный и построить дерево на основе одной таблицы через связь id-parent
>>866042
#45 #866042
>>866039
А нет ли у тебя примеров заданий средней высокой сложности? Напомню задание на позицию джуна. Я вот даже не знаю что такое роутинг и зачем он нужен. Это что то с __DIR__?
Кстати, был еще в двух конторах, в одной попросили написать скрипт который бы находил страницу пользователя в фейсбуке зная его телефон. В другой нужно было написать 2 СКЛ запроса на выборку из двух таблиц.Как по мне это значительно проще.
>>866051
#46 #866051
>>866042

>Я вот даже не знаю что такое роутинг


Это формирование линков >Построить пути к элементам. Элементы каталога выводить ссылками. Например для Id=6 «Телевизор Series 7» вида «/catalog/samsung/s7/»

>средней высокой сложности


Мне давали тестовый таск однажды: Есть сторонний API который отдает за один раз 200 записей, API принимает некоторые параметры, к примеру я могу задать начиная с какой записи получить эти 200 записей.
Задача состояла получить все записи начиная с первой, вне зависимости от их общего числа и записать в CSV-файл, при этом остановиться, когда записи закончатся. На PHP это было бы просто, но задача стояла на nodejs и там была рекурсивная функция с асинхронными запросами.
>>866058
#47 #866058
>>866051
http://ideone.com/mGR87D
Потом в шаблоне $linkArray выводиться на экран.
Это и есть роутинг?

>Мне давали тестовый таск однажды


На php задача и правда не сложная. А есть примеры именно для php?
72 Кб, 1366x645
69 Кб, 1366x604
74 Кб, 675x310
#48 #866093
Аноны, как настроить ебучий автокоплит в Атоме? Ну это просто пиздец, такой красивый редактор, есть плагины, а автокомплит просто сука не работает, я же везде прописал верные пути к композеру и пхп, ну вы только гляньте на сколько красив атом и вырвиглазен нетбинс.

Что делать? Хожу писать код в красивом редакторе, а в нетбинсе сидеть противно.
>>866096>>866112
#49 #866096
>>866093
Поставить другую тему в Netbeans не пробовал?
>>866097
#50 #866097
>>866096
да они все там вырвиглазные
#51 #866112
>>866093
Разве что самому плагин писать.
PHPStorm попробуй, его можно купить на торрентах.
Satosi #52 #866117
Что-то вместо круга получился полукруг (ideone не отобразит)
http://ideone.com/lfiQW3

Есть идеи как поправить?
>>878132
#53 #866128
А может кто сказать как работает роутинг простым языком? А то у меня голова взорвалась.

Все объяснения которые я нахожу в интернете.

1 Делаем ссылку вида /pr/res/privet
2 Передаём её в роутер
3 ????
4 ШАБЛОН

3 пункт мне совершенно непонятен. Как роутер понимает какой шаблон брать? Как он понимает что нужно взять 5 шаблонов (футеры хедеры и прочее)? Как шаблон контактирует с CSS? Как шаблон содержит переменные, но при этом они все должны обрабатываться роутером, или нет?
>>866143>>866160
#55 #866143
>>866128
Точка входа в программу у тебя одна. Роутинг всегда обрабатывается. Получаешь ссылку по которой зашел пользователь, потом в зависимости от правил роутинг у тебя, делишь ссылку на составные части, из базы получаешь, что означает каждая часть (декодишь), исходя из этих данных определяешь какой контроллер должен обрабатывать ссылку и передаешь управление ему.
При построении ссылок пользуешься обратной функцией - которая из параметров собирает ссылку.
#56 #866160
>>866128

Роутинг (=маршрутизация) это процесс определения контроллера по УРЛ. Роутер - это часть приложения, которая получает на вход УРЛ определяет, какой контродллер его будет обрабатывать.

Логика работы роутера может быть любая, как программист решил, так и будет.

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

function route($url) {
if ($url == '/') {
return 'indexController';
} elseif ($url == '/news') {
return 'newsController';
} else {
return null;
}
}

Набрав MVC роутер в гугле, можно найти еще кучу примеров.

При чем тут шаблон, я не понимаю. Шаблон обычно выбирается и вызывается контроллером.

Почитай для начала про MVC https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Потом изучи какой-нибудь MVC фреймворк, в котором есть роутер.
#57 #866170
>>865956
Вот этот алгоритм, только исправленный так, как у меня работает.
$data = new Data(); //создаем экземпляр класса для работы с данными
$values = значения по умолчанию (пустые);
$errors = пустой массив;
Если (форма отправлена) {
Копируем переданные значения полей в $values;
Проверяем значения в $values и записываем найденные ошибки в $errors;
Тут валидация простая. а у меня идет в $data работа с БД + потом возвращаются данные. Конкретно у меня проводятся транзакции, где проверяется 1. Не заблокирован ли счет отправителя/получателя. 2. Хватило ли баланса 3. Если все ок с 1 и 2 проведена ли транзакция успешно.

Если (ошибок нет) {
$errors = $data->someDataMethod($values);
// если все ок то $errors = ['check' => 1, 'balance' => 1, 'transaction' => 1];
// Но как его передать в следующий скрипт, в котором ко всему создается свой экземпляр $data.

}
}

Выводим форму($values, $errors);

Но потом на самой странице выводится темплейт и в начале него создается еще один экземпляр Data(), я пробовал сохранить как public свойство в $data, но т.к. создается новый экземпляр, это не работает.
20 Кб, 181x415
44 Кб, 1128x228
#58 #866461
Есть простая страница с формой http://pastebin.com/aH2HwTeY

Есть скрипт, который отправляет два поля email и password на мыло, должен отправлять http://pastebin.com/LZQGvqNU

Отправка мыла на почту работает, если через терминал запустить скрипт. На скрине структура проекта.

После субмита через кнопку в test.html, вылетает ошибка на скрине-2.

Я особо в пхп не шарю. Больше по джаве
>>866468>>866631
#59 #866468
>>866461

а настраивать сервер умеешь? что у тебя написано в атрибуте action в начале формы?
>>866477
#60 #866477
>>866468
не обратил внимание на ссылки, проблема в настройке сервера, походу твой сервер настроен так, что не может видеть тот файлик, глянь в настройках сервера либо в .htacess.

либо же у тебя где-то есть файлик который обрабатывает входящие запросы и соответственно отдает нужные вьюшки, а твою ссылку обработать не может
>>866478
#61 #866478
>>866477
не вьюшку, а foo.php
>>866505
#62 #866505
>>866478
Запускаю через xampp, посмотрел его конф файл, ничего убедительного не нашел.
Каким способом можно еще отправить инфу на мыло?
>>866529>>866532
#63 #866529
>>866505
ручным

хранить скрипт и форму в одном файле
#64 #866532
>>866505
да и блять по папкам твоего приложения видно же, что запросы чем-то обрабатываются, у тебя вьюхи в отдельной папке лежат, ты же когда заходишь на сайт не пишешь
http://localhost/view/index.html

так что в эту сторону и копай, разберись для начала как работает твой код
>>866803
#65 #866631
>>866461

Это ошибка Апача, а не PHP. Можешь посмотреть в логе ошибок полный путь к файлу, который он не может найти.

Если ты не разбираешься в конфигах Апача и PHP, то даже если ты исправишь проблему, все равно твой скрипт будет скорее всего кривой и глючный, может быть с уязвимостями, открывающими доступ к серверу. Не надо браться за то, что не умеешь.
#66 #866633
Я ньюфажина лютая, поэтому ответьте на вопрос, как задать диапазон числе для $random?
>>866636
#67 #866636
>>866633
mt_rand(от числа, до числа)
#68 #866640
Анончики, помогите написать инъекцию, когда попадает 'test', выдает следующее

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'test'')' at line 1
38 Кб, 604x604
#69 #866756

>Решил 39 задачь и все дополнительные.


>Оп сказал что только 6 правильно

>>866783>>867409
#70 #866771
#71 #866783
>>866756

А ты думаешь, все остальные с первого раза все правильно делают? Если бы каждый после неправильно решенной задачи постил по лягушке, наш тред бы давно уже перенесли в /zoo/
#72 #866786
Привет, объясните пожалуйста одно из условий 5ой задачи по JS (остальные все выполнил)
http://dkab.github.io/jasmine-tests/?spec=6
"должна подставлять лишние аргументы в конец списка: partialAny(fn, 1)(2, 3) -> [1, 2, 3]"

Как должен выглядеть массив аргументов на примере исходных данных:
partialAny(test, 1, undefined, 3)(5)

Мое решение:
https://jsfiddle.net/soybo52k/
>>866787>>866790
#73 #866787
>>866786
6ой задачи, быстрофикс
#74 #866790
>>866786

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


partialAny(test, 1, undefined, 3)(5)

[1, 5, 3] так как 5 подставляется вместо udefined
>>866791>>866793
#75 #866791
>>866790
мое решение так и делает, подставляет 5 на место undefined, а что такое "лишние аргументы" в данном контексте?
>>866795
#76 #866793
>>866790

Я не могу понять ОДНО из условий в проверке робота.

Результат проверки роботом 6ой задачи (решение: https://jsfiddle.net/soybo52k/)

Функция partialAny(fn, foo, bar...)
дожна возвращать функцию OK
должна использовать строгое сравнение с undefined (null или 0 не должен восприниматься как undefined) OK

Возвращаемая функция
должна подставлять переданный аргумент вместо undefined: partialAny(fn, 5, undefined, 10)(1) -> [5, 1, 10] OK
должна оставлять undefined если аргумент не передан: partialAny(fn, 5, undefined, 10)() -> [5, undefined, 10] OK
должна подставлять несколько аргументов в partialAny(fn, a, undefined, undefined, b) OK
должна подставлять undefined если аргумент не передан в partialAny(fn, a, undefined, undefined, b) OK

должна подставлять лишние аргументы в конец списка: partialAny(fn, 1)(2, 3) -> [1, 2, 3] NOT OK

не должна передавать лишние аргументы внутренней функции: partialAny(fn, 1, undefined, 3, undefined)(2) -> [1, 2, 3, undefined] OK
может вызываться несколько раз и результаты во второй раз не зависят от первого OK

Вроде бы тут нет лишних аргументов, а если они были бы, то я должне их добавить в конец списка? Но следующее условие говорит, что я не должен их передавать во внутреннюю функцию, значит, затем я должен удалить их из списка, так?
>>866796
#77 #866795
>>866791

Это когда передано больше аргументов чем есть undefined в шаблоне:

partialAny(1, undefined, 2)(3, 4, 5 ,6) -> [1, 3, 2, 4, 5, 6]
#78 #866796
>>866793

(2, 3) лишние так как в первых скобках нет ни одного undefined и лишние аргументы подставляются конец списка.
#79 #866803
>>866532
Все работает на express-e. Закинул скрипт к папке во view, просипал форме action="foo.php"
Теперь уже Cannot POST /foo.php

Я бы с радостью не занимался этим дерьмом, но лаба требует
#80 #866907
>>864640 (OP)
Сап помогач, я сам джавист потому реквестирую вашей помощи, третий час бьюсь в истерике, суть такова: надо скомпилить протобаф.

В идеале если раскажете как его потом POSTом отправить.

Есть сервер на джаве и клиент на пыхе. они должны обмениваться протобафами. С джавой проблем нет, а как эту ебатеку скомпилдить на пхп для меня высшее колдунство. Помоги анон, волосы седеют.
>>866928
#81 #866928
>>866907

>Есть сервер на джаве и клиент на пыхе.


Очень смешно.
>>866949
#82 #866949
>>866928
Это условные названия, есть два сервака, один на джаве другой на пыхе. Надо обмен протобафами устроить. Нужна помощь по пхп части, кто в теме, пожалуйста.

Сам протобаф простоейший

package text.protobuf;

message Text{
required string text = 1;
}

Надо только его скомпилить, а дял этого надо скомпилить модуль пхп, и куда-то его потом подключить или положить, и это какой-то особый пиздец.
someApprentice #83 #866971
https://github.com/codedokode/pasta/blob/master/html/html.md#Главное-задание-на-верстку-макета
https://github.com/someApprentice/maintaskforlayout
https://someapprentice.github.io/maintaskforlayout/
https://www.browserstack.com/screenshots/a67572898943c3deb293b501f133cf43189a2946 (актуально до коммита с css-спрайтом увы, больше 100 изоброжений нельзя)

>кнопки и ссылки должны реагировать на нажатие и наведение мыши


А как узнать как они должны выглядеть?

>тег <img> используется только для картинок в портфолио


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


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

>здесь используются внешние шрифты, и довольно тяжелые. Если ты можешь уменьшить их объем, это будет плюсом


Не разу не работал со шрифтами. Можно подсказку как это сделать? Мне приходилось преобразовывать формат шрифтов для старых браузеров, это оно и есть?
#84 #867039
>>866971

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

Тут важно понимать, что браузерных движков не так и много:

- trident (в IE)
- presto (старая Опера, почти никем не используется)
- gecko (firefox)
- webkit (Хром, новая Опера, Яндекс браузер, мейл ру браузер, сафари, мобильные браузеры)
- blink, форк вебкита, использующийся по моему в новых версиях браузеров, ранее работавших на вебките

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

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


Псевдоэлементы не работают в старых браузерах? По моему разве что в ИЕ7 и ниже ( https://css-tricks.com/browser-support-pseudo-elements/ )

Если нужна поддержка ИЕ7 можно вместо псевдоэлементов использовать например спаны с background-image. Если нужен еще ИЕ6 то надо отказаться от полупрозрачных PNG. Но если подумать, это очень древние браузеры и в принципе иконки не настолько критичный элемент, чтобы ради них заморачиваться.

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

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


Новые форматы вроде woff/woff2 действительно поддерживают сжатие и позволяют уменьшить объем. Но более радикальный способ - выкинуть ненужные символы. Условно говоря, если твой сайт на английском, зачем тебе кириллица или хинди или математическеи символы? Если взять например шрифт roboto: https://fonts.google.com/specimen/Roboto (какой они сделали ужасный интерфейс, старый нематериальный веб-1.0 был в 100 раз лучше) то в нем много разных символов, и не все они нужны.

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

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

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

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

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

При нажатии на кнопки all/graphic/illustration часть работ должна скрываться.

Телефон в подвале должен быть кликабельным с помощью tel: ссылки, адрес - вести на любой картографический сервис.

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

У тебя стоит <meta name="viewport" content="width=device-width"> но фактически адаптивности там ноль. Зачем было ставить вводящий браузер в заблуждение тег?

meta charset не прописан.

> <i>


Сейчас для смыслового выделения фразы используют em, а тег i получил какое-то другое назначение в HTML5.

> PORTFOLIO


Текст в HTML надо писать в нормальном регистре. Верхний регистр делается через CSS, так как это часть оформления.

> <a name="portfolio">


Чтобы сделать якорь, лучше использовать атрибут id - он вроде даже в старых ИЕ работает. Тег a для этого использовать - устаревший подход.

> <img src="img\home


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

> <li><a class="rss" href=""></a></li>


Плохо что ссылка пустая. Как поисковый бот или программа чтения текста воспримет такую ссылку?

Тебе надо открыть HTML и почитать его, и такие нелогичности сразу станут видны.

В остальном HTML код хорош. Никаких лишних тегов, это хорошо.

Для ссылок на соцсети надо сделать реакцию на наведение.

Шрифты ты определил неправильно. Ты объявляешь щрифт LatoBlack:

> @font-face {


> font-family: LatoBlack;


Но это просто шрифт lato в жирном начертании. Все начертания шрифта Lato надо определить под одним именем, просто указать их вес и курсивность.

А в твоем варианте если ты сделаешь абзац с текстом Lato, а в нем strong, то браузер не догадается использовать LatoBlack так как для него это другой шрифт.

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

> font-family: 'Times New Roman', Arial, Helvetica, sans-serif;


Бредовый список. Times New Roman - шрифт с засечками, Arial и sans-serif - без, они едва ли взаимоменяемы.

> a, a:visited {


> color: #d9d9d9;


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

Далее, тебе надо проработать базовые стили CSS. Сделай новый файл с пустым body и впиши в него простой HTML без классов, с тегами вроде h1, h2, ul, li, p, a, img, blockquote (если нет фантазии или лень писать, скопируй с http://motherfuckingwebsite.com/ ). У тебя этот текст выводится бледно-серым на белом фоне - это значит, базовые стили не продуманы совсем. Ты написал не базовый CSS для всего сайта, а стили для единственной страницы и при добавлении новых страниц твой ксс придется значительно переделывать.

Почитай про назнаечние тегов в HTML5.Теги i и b в старом значении (задание начертания шрифта больше не используютя так как офомление должно задаваться в ксс, а не в HTML. Эти теги не соответствуют принципам HTML5).

> font-family: ReklameScriptRegularDEMO;


Не задан фоллбек (запасной) шрифт.

> .services .content div {


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

В данном случае можно либо добавить > либо добавить класс на див.

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

> .tristiquet::before {


> .fermentum::before {


> .elitultricies::before {



Слишком много копипасты. Там различается только позиция в спрайте.

> .portfolio .content .works :nth-child(4n) {


Это не будет работать с адаптивностью скорее всего, так как на узком экране картинок меньше.

> @media (max-width: 1110px) {


> body {


> width: 1110px;


Это так хитро записанный min-width? Он противоречит тегу meta viewport который говорит о поддержке маленьких экранов. А ее нет.

Для картинок ты выбрал PNG. Он дает хорошее каечство, но размер.... вот это вот https://someapprentice.github.io/maintaskforlayout/img/home_0003s_0001s_0022_Layer-1.png весит 130 Кб. не жирно ли? на некоторых сайтах всю страницу можно в 130 Кб уложить. Рассмотри другие форматы.
#84 #867039
>>866971

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

Тут важно понимать, что браузерных движков не так и много:

- trident (в IE)
- presto (старая Опера, почти никем не используется)
- gecko (firefox)
- webkit (Хром, новая Опера, Яндекс браузер, мейл ру браузер, сафари, мобильные браузеры)
- blink, форк вебкита, использующийся по моему в новых версиях браузеров, ранее работавших на вебките

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

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


Псевдоэлементы не работают в старых браузерах? По моему разве что в ИЕ7 и ниже ( https://css-tricks.com/browser-support-pseudo-elements/ )

Если нужна поддержка ИЕ7 можно вместо псевдоэлементов использовать например спаны с background-image. Если нужен еще ИЕ6 то надо отказаться от полупрозрачных PNG. Но если подумать, это очень древние браузеры и в принципе иконки не настолько критичный элемент, чтобы ради них заморачиваться.

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

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


Новые форматы вроде woff/woff2 действительно поддерживают сжатие и позволяют уменьшить объем. Но более радикальный способ - выкинуть ненужные символы. Условно говоря, если твой сайт на английском, зачем тебе кириллица или хинди или математическеи символы? Если взять например шрифт roboto: https://fonts.google.com/specimen/Roboto (какой они сделали ужасный интерфейс, старый нематериальный веб-1.0 был в 100 раз лучше) то в нем много разных символов, и не все они нужны.

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

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

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

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

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

При нажатии на кнопки all/graphic/illustration часть работ должна скрываться.

Телефон в подвале должен быть кликабельным с помощью tel: ссылки, адрес - вести на любой картографический сервис.

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

У тебя стоит <meta name="viewport" content="width=device-width"> но фактически адаптивности там ноль. Зачем было ставить вводящий браузер в заблуждение тег?

meta charset не прописан.

> <i>


Сейчас для смыслового выделения фразы используют em, а тег i получил какое-то другое назначение в HTML5.

> PORTFOLIO


Текст в HTML надо писать в нормальном регистре. Верхний регистр делается через CSS, так как это часть оформления.

> <a name="portfolio">


Чтобы сделать якорь, лучше использовать атрибут id - он вроде даже в старых ИЕ работает. Тег a для этого использовать - устаревший подход.

> <img src="img\home


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

> <li><a class="rss" href=""></a></li>


Плохо что ссылка пустая. Как поисковый бот или программа чтения текста воспримет такую ссылку?

Тебе надо открыть HTML и почитать его, и такие нелогичности сразу станут видны.

В остальном HTML код хорош. Никаких лишних тегов, это хорошо.

Для ссылок на соцсети надо сделать реакцию на наведение.

Шрифты ты определил неправильно. Ты объявляешь щрифт LatoBlack:

> @font-face {


> font-family: LatoBlack;


Но это просто шрифт lato в жирном начертании. Все начертания шрифта Lato надо определить под одним именем, просто указать их вес и курсивность.

А в твоем варианте если ты сделаешь абзац с текстом Lato, а в нем strong, то браузер не догадается использовать LatoBlack так как для него это другой шрифт.

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

> font-family: 'Times New Roman', Arial, Helvetica, sans-serif;


Бредовый список. Times New Roman - шрифт с засечками, Arial и sans-serif - без, они едва ли взаимоменяемы.

> a, a:visited {


> color: #d9d9d9;


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

Далее, тебе надо проработать базовые стили CSS. Сделай новый файл с пустым body и впиши в него простой HTML без классов, с тегами вроде h1, h2, ul, li, p, a, img, blockquote (если нет фантазии или лень писать, скопируй с http://motherfuckingwebsite.com/ ). У тебя этот текст выводится бледно-серым на белом фоне - это значит, базовые стили не продуманы совсем. Ты написал не базовый CSS для всего сайта, а стили для единственной страницы и при добавлении новых страниц твой ксс придется значительно переделывать.

Почитай про назнаечние тегов в HTML5.Теги i и b в старом значении (задание начертания шрифта больше не используютя так как офомление должно задаваться в ксс, а не в HTML. Эти теги не соответствуют принципам HTML5).

> font-family: ReklameScriptRegularDEMO;


Не задан фоллбек (запасной) шрифт.

> .services .content div {


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

В данном случае можно либо добавить > либо добавить класс на див.

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

> .tristiquet::before {


> .fermentum::before {


> .elitultricies::before {



Слишком много копипасты. Там различается только позиция в спрайте.

> .portfolio .content .works :nth-child(4n) {


Это не будет работать с адаптивностью скорее всего, так как на узком экране картинок меньше.

> @media (max-width: 1110px) {


> body {


> width: 1110px;


Это так хитро записанный min-width? Он противоречит тегу meta viewport который говорит о поддержке маленьких экранов. А ее нет.

Для картинок ты выбрал PNG. Он дает хорошее каечство, но размер.... вот это вот https://someapprentice.github.io/maintaskforlayout/img/home_0003s_0001s_0022_Layer-1.png весит 130 Кб. не жирно ли? на некоторых сайтах всю страницу можно в 130 Кб уложить. Рассмотри другие форматы.
>>867121>>874239
#85 #867043
>>866971

А ты не хочешь голову поломать над дополнителным заданием? Вот оно:

---------

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

----------

SVG довольно интересная штука. С одной стороны, у него много преимуществ (поддержка дисплеев с произвольным разрешением), с другой стороны проблем у него не меньше. Ты берешь, рисуешь картинку в inkscape и внезапно оказывается что в части браузеров не поддерживается часть фич SVG. Или что ее нельзя использовать в качестве фоновой. Я изучал и так, и эдак, и решил что проще использовать SVG только в процессе разработки, а в браузер отдавать сгенерированный из него PNG.
>>867121
#86 #867053
>>866971

про HTML5 теги:

- официальный стандарт (англ), самый подробный и авторитетный источник: https://www.w3.org/TR/html5/Overview.html#contents пункт 4
- https://developer.mozilla.org/en-US/docs/Web/HTML/Element

ссылки на русском:

- http://htmlbook.ru/samhtml5/sintaksis-html5
- http://htmlbook.ru/samlayout/verstka-na-html5/novye-tegi
- http://htmlbook.ru/html5
#87 #867121
>>867039

>Там обычно и не требуется делать скриншоты для всех версий браузеров. Самый проблемный тут ИЕ, потому для него стоит сделать по скрншоту для каждой версии. Для других браузеров хватит последней версии + при желании какую-нибудь древнюю. Плюс мобльные браузеры.


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

>Псевдоэлементы не работают в старых браузерах?


Я имел ввиду что нельзя воспользоваться нельзя воспользоваться такими свойствами как content и background: url, которые по версии caniuse не доступны с 8 версии.

>Если нужен еще ИЕ6 то надо отказаться от полупрозрачных PNG.


А можно пример что нужно написать? У меня не получилось вывести изоброжение с помощью background-image: url(img.jpg).

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


В нашем шаблоне есть иконки которые являются ссылками на контакты. По моему это важно выводить.

>> font-family: 'Times New Roman', Arial, Helvetica, sans-serif;


>Бредовый список. Times New Roman - шрифт с засечками, Arial и sans-serif - без, они едва ли взаимоменяемы.


Я не знаю чем различаются разные шрифты. Теперь буду замечать.

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


Как она должа выглядеть? Я старался сделать чтобы для экранов меньше 1110px (размер контной части) всё выглядело точно так же, за исключением резиновых отступов.

>У тебя стоит <meta name="viewport" content="width=device-width"> но фактически адаптивности там ноль. Зачем было ставить вводящий браузер в заблуждение тег?


Должны размеры шрифтов поменяться.

>> @media (max-width: 1110px) {


>> body {


>> width: 1110px;


>Это так хитро записанный min-width? Он противоречит тегу meta viewport который говорит о поддержке маленьких экранов. А ее нет.


На самом деле всё наманого хуже. Я совсем не понял как работают media features и не нашел описаний атрибута content для тэга viewport А хотелось бы знать как работают все его свойства.
Например, что указывает max-width в этом поле? Интуиция мне подскзывает что это максимальная ширина окна, но как оно определяется? Допустим моё окно будет 1000px, почему правило max-wdith: 1110px срабатывает? Как высчиталось 1110px из 1000px? Почему не 9999px?

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

>>867043

>А ты не хочешь голову поломать над дополнителным заданием?


Принято, но позже. Сначало нужно хотя бы js сделать.
#87 #867121
>>867039

>Там обычно и не требуется делать скриншоты для всех версий браузеров. Самый проблемный тут ИЕ, потому для него стоит сделать по скрншоту для каждой версии. Для других браузеров хватит последней версии + при желании какую-нибудь древнюю. Плюс мобльные браузеры.


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

>Псевдоэлементы не работают в старых браузерах?


Я имел ввиду что нельзя воспользоваться нельзя воспользоваться такими свойствами как content и background: url, которые по версии caniuse не доступны с 8 версии.

>Если нужен еще ИЕ6 то надо отказаться от полупрозрачных PNG.


А можно пример что нужно написать? У меня не получилось вывести изоброжение с помощью background-image: url(img.jpg).

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


В нашем шаблоне есть иконки которые являются ссылками на контакты. По моему это важно выводить.

>> font-family: 'Times New Roman', Arial, Helvetica, sans-serif;


>Бредовый список. Times New Roman - шрифт с засечками, Arial и sans-serif - без, они едва ли взаимоменяемы.


Я не знаю чем различаются разные шрифты. Теперь буду замечать.

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


Как она должа выглядеть? Я старался сделать чтобы для экранов меньше 1110px (размер контной части) всё выглядело точно так же, за исключением резиновых отступов.

>У тебя стоит <meta name="viewport" content="width=device-width"> но фактически адаптивности там ноль. Зачем было ставить вводящий браузер в заблуждение тег?


Должны размеры шрифтов поменяться.

>> @media (max-width: 1110px) {


>> body {


>> width: 1110px;


>Это так хитро записанный min-width? Он противоречит тегу meta viewport который говорит о поддержке маленьких экранов. А ее нет.


На самом деле всё наманого хуже. Я совсем не понял как работают media features и не нашел описаний атрибута content для тэга viewport А хотелось бы знать как работают все его свойства.
Например, что указывает max-width в этом поле? Интуиция мне подскзывает что это максимальная ширина окна, но как оно определяется? Допустим моё окно будет 1000px, почему правило max-wdith: 1110px срабатывает? Как высчиталось 1110px из 1000px? Почему не 9999px?

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

>>867043

>А ты не хочешь голову поломать над дополнителным заданием?


Принято, но позже. Сначало нужно хотя бы js сделать.
>>867314
#88 #867314
>>867121

Имей в виду, что эмуляция IE (через панель инструментов F12 или сторонние программы) не совсем полноценно повторяет все особенности той или иной версии. ИЕ так глубоко встроен в систему, что эмулировать все баги точно не получается.

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

Если же ты используешь виртуальные машины с ИЕ то там все ок.

background: url работает даже в Ие6. Вот псевдоэлементы, да, есть только начиная с ИЕ8. Но тут получается такой выбор:

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

> А можно пример что нужно написать? У меня не получилось вывести изоброжение с помощью background-image: url(img.jpg).


ИЕ6 в полупрозрачных (то есть с альфа-каналом) картинках формата PNG делает полупрозрачные пиксели черными. Изображения PNG8 с палитрой из 256-цветов и с прозрачностью без полупрозрачности работают нормально.

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

- https://ru.wikipedia.org/wiki/PNG
- https://ru.wikipedia.org/wiki/JPEG
- https://ru.wikipedia.org/wiki/GIF
- https://ru.wikipedia.org/wiki/SVG
- http://web-design-courses.narod.ru/graphics.html
- https://htmlacademy.ru/blog/113-image-formats
- https://www.artlebedev.ru/tools/technogrette/img/png-1/
- https://habrahabr.ru/post/45242/

> В нашем шаблоне есть иконки которые являются ссылками на контакты. По моему это важно выводить.


Это соцсети? Они да, должны быть видны. Но там ведь и не нужны вроде бы псевдоэлементы.

> Как она должа выглядеть? Я старался сделать чтобы для экранов меньше 1110px (размер контной части) всё выглядело точно так же, за исключением резиновых отступов.


В отладчике Хрома (да и фаерфокса тоже по моему) есть кнопка "тестирование адаптивной верстки". Можно нажать ее и походить по разным сайтам, посмотреть.

https://moonback.ru/page/check-adaptive

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

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

Википедию посмотри. Хабр (m.habrahabr.ru). Ютуб. Яндекс. Любые известные сайты.

Проблема с обычным сайтом в том, что он широкий (рендерится на 800-1000px) и на мобильном устройстве отображается в сильно уменьшенном масштабе. А если пользователь тапом приближает абзац текста, то абзац уходит за край экрана и надо его таскать вправо-влево, чтобы прочесть. Очень неудобно. Потому делают дополнительно верстку под ширину устройства (320-500px). Соответственно, блок с картинками скорее всего будет выводиться в 1-2 столбика. Размер текста, заголовков и отступов иногда также меняют чтобы не было больших пустых пространств (экран смартфона не резиновый) и смотрелось гармонично.

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

Чтобы сказать мобильным браузерам о том, что сайт для них адаптирован, используют тег meta viewport: http://frontender.com.ua/mobile-web/wtf-viewport/

> Например, что указывает max-width в этом поле?


@media (max-width: 1110px) значит что стили в этом блоке применяются только если ширина окна не более 1110 px.

- https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries
- https://developer.mozilla.org/en-US/docs/Web/CSS/@media
- http://htmlbook.ru/css/value/media
- http://htmlbook.ru/css/media

> Допустим моё окно будет 1000px, почему правило max-wdith: 1110px срабатывает? Как высчиталось 1110px из 1000px? Почему не 9999px?


Так как 1000px меньше чем 1110 то правила в блоке @media применяются к странице. Если окно станет шире 1110, то они перестанут применяться.

И еще одна вещь, про которую надо хотя бы почитать. Это ретина-дисплеи, то есть экраны с повышенной плотностью пикселей. Условно говоря на смартфоне может быть ширина экрана 720px. Но если вывести на нее сайт такой же ширины, то текст будет мелкий и нечитаемый. Потому браузер рендерит страницу на ширине 360px но в увеличенном масштабе. Если при этом на странице обычные картинки,то они будут увеличены и выглядеть не очень красиво. А если использовать векторный формат или картинки с двойной плотностью пикселей, то другое дело.

Погуглить можно атрибут srcset у img, а также примеры кода отсюда: https://css-tricks.com/snippets/css/retina-display-media-query/

Ну и еще ссылка, таблица размеров экранов: http://mydevice.io/devices/
#88 #867314
>>867121

Имей в виду, что эмуляция IE (через панель инструментов F12 или сторонние программы) не совсем полноценно повторяет все особенности той или иной версии. ИЕ так глубоко встроен в систему, что эмулировать все баги точно не получается.

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

Если же ты используешь виртуальные машины с ИЕ то там все ок.

background: url работает даже в Ие6. Вот псевдоэлементы, да, есть только начиная с ИЕ8. Но тут получается такой выбор:

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

> А можно пример что нужно написать? У меня не получилось вывести изоброжение с помощью background-image: url(img.jpg).


ИЕ6 в полупрозрачных (то есть с альфа-каналом) картинках формата PNG делает полупрозрачные пиксели черными. Изображения PNG8 с палитрой из 256-цветов и с прозрачностью без полупрозрачности работают нормально.

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

- https://ru.wikipedia.org/wiki/PNG
- https://ru.wikipedia.org/wiki/JPEG
- https://ru.wikipedia.org/wiki/GIF
- https://ru.wikipedia.org/wiki/SVG
- http://web-design-courses.narod.ru/graphics.html
- https://htmlacademy.ru/blog/113-image-formats
- https://www.artlebedev.ru/tools/technogrette/img/png-1/
- https://habrahabr.ru/post/45242/

> В нашем шаблоне есть иконки которые являются ссылками на контакты. По моему это важно выводить.


Это соцсети? Они да, должны быть видны. Но там ведь и не нужны вроде бы псевдоэлементы.

> Как она должа выглядеть? Я старался сделать чтобы для экранов меньше 1110px (размер контной части) всё выглядело точно так же, за исключением резиновых отступов.


В отладчике Хрома (да и фаерфокса тоже по моему) есть кнопка "тестирование адаптивной верстки". Можно нажать ее и походить по разным сайтам, посмотреть.

https://moonback.ru/page/check-adaptive

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

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

Википедию посмотри. Хабр (m.habrahabr.ru). Ютуб. Яндекс. Любые известные сайты.

Проблема с обычным сайтом в том, что он широкий (рендерится на 800-1000px) и на мобильном устройстве отображается в сильно уменьшенном масштабе. А если пользователь тапом приближает абзац текста, то абзац уходит за край экрана и надо его таскать вправо-влево, чтобы прочесть. Очень неудобно. Потому делают дополнительно верстку под ширину устройства (320-500px). Соответственно, блок с картинками скорее всего будет выводиться в 1-2 столбика. Размер текста, заголовков и отступов иногда также меняют чтобы не было больших пустых пространств (экран смартфона не резиновый) и смотрелось гармонично.

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

Чтобы сказать мобильным браузерам о том, что сайт для них адаптирован, используют тег meta viewport: http://frontender.com.ua/mobile-web/wtf-viewport/

> Например, что указывает max-width в этом поле?


@media (max-width: 1110px) значит что стили в этом блоке применяются только если ширина окна не более 1110 px.

- https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries
- https://developer.mozilla.org/en-US/docs/Web/CSS/@media
- http://htmlbook.ru/css/value/media
- http://htmlbook.ru/css/media

> Допустим моё окно будет 1000px, почему правило max-wdith: 1110px срабатывает? Как высчиталось 1110px из 1000px? Почему не 9999px?


Так как 1000px меньше чем 1110 то правила в блоке @media применяются к странице. Если окно станет шире 1110, то они перестанут применяться.

И еще одна вещь, про которую надо хотя бы почитать. Это ретина-дисплеи, то есть экраны с повышенной плотностью пикселей. Условно говоря на смартфоне может быть ширина экрана 720px. Но если вывести на нее сайт такой же ширины, то текст будет мелкий и нечитаемый. Потому браузер рендерит страницу на ширине 360px но в увеличенном масштабе. Если при этом на странице обычные картинки,то они будут увеличены и выглядеть не очень красиво. А если использовать векторный формат или картинки с двойной плотностью пикселей, то другое дело.

Погуглить можно атрибут srcset у img, а также примеры кода отсюда: https://css-tricks.com/snippets/css/retina-display-media-query/

Ну и еще ссылка, таблица размеров экранов: http://mydevice.io/devices/
>>874239
2595 Кб, Webm
Студенты #89 #867331
А я, тем временем, продолжаю неспешно постить сюда свой говнокод.
https://github.com/anotherCodeMunkey/studentsList
#90 #867356
Zend Studio - норм IDE для нуфага? Нетбинс и пхпшторм моя некропека не тянет, а использовать редакторы стало геморно когда я начал использовать ООП и пространства имен.
#91 #867362
Напомню себе, что надо бы проверить https://github.com/never3ver/students_list из поста >>862816
>>872056
#92 #867390
Напомню, что надо проверить https://github.com/ghp26/Students из >>863496
>>872086
#93 #867409
>>866756
Всё нормально. Я задачу на студентов за месяц сделал. И 5 месяцев доделываю конечно, делая параллельно другую задачу
#94 #867437
В природе существуют Java to JS/PHP трансляторы/конверторы? Очень нннада переписать код для веба, а жабки я не знаю.
>>867470>>867725
#95 #867451
Какой сейчас модный редактор для php на мак?
>>867778
#96 #867470
>>867437
Что-то существует, но вряд ли это пригодные для реального использования вещи.
Лучше JS выучить.
>>867725
#97 #867533
Привет анончики! делаю ТЗ в конторку и вот столкнулся с проблемой. нужно организовать фильтра для выборки из БД

4. При выводе данных добавить возможность отфильтровать сотрудников по отделу, должности или типу. (Пользователь может одновременно выбрать две и более критерии фильтрации)

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

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

>добавить возможность отфильтровать сотрудников по отделу


where otdel like ITdept and igorDapt

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


Sort by Birsday
Sort by ZORPLATA
>>867694
#99 #867561
>>867533
$query = 'SELECT * FROM table WHERE 1';

$sortby = array()
if($_POST['sort_birthday']){
$sortby[] = 'birthday';
}
if($_POST['sort_zarplata']){
$sortby[] = 'zarplata';
}
if(!empty($sortby)){
$query .= ' SORT BY '.implode(',', $sortby);
}

Вот типа такого. Без PDO, прости уж, но, думаю, смысл понятен.
>>867562>>867694
#100 #867562
>>867561
ORDER BY конечно же.
#101 #867666
#102 #867687
>>867533

Для построения запросов по частям есть паттерн Query Builder.

У Фаулера (там не совсем Query Builder, а Builder вообще): http://martinfowler.com/bliki/ExpressionBuilder.html

У меня: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md#query-builder

В простом маленьком приложении можно просто руками собрать запрос из частей.
>>867694
82 Кб, 604x453
#103 #867694
>>867536
>>867561
>>867687

Спасибо няшки!
#104 #867725
>>867470
Не js, а джаву тогда уж, С джавы на пхп/жс
>>867437
Бамп
#105 #867756
В старом треде я дал ответы на все вопросы и проверил все задачи. В частности:

- >>867751 - по сложному решению задачи на банкомат с комментариями

Если я кого-то пропустил или забыл - напомните о себе в этом, новом треде.
#106 #867778
>>867451
xcode же.
#107 #867779
Аноны. У кого-то я видел в регулярке для проверки email предположение, что домен верхнего уровня (то что идет после последней точки, например .ru) занимает от 2 до 6 символов. Это давно уже неактуально, не ставьте таких огранчиений.

Обратил внимание, что скайп не выделяет ссылки если в домене верхнего уровня много символов, например как в http://arzamas.academy/materials/994
>>867788>>869219
#108 #867788
>>867779
вот нормальный регэкс для емэйла:
(?:(?:\r\n)?[ \t])(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:
\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(
?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[
\t]))"(?:(?:\r\n)?[ \t])))@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\0
31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\
](?:(?:\r\n)?[ \t])
)(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+
(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:
(?:\r\n)?[ \t])))|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)
?[ \t])
)\<(?:(?:\r\n)?[ \t])(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\
r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[
\t])
)(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t]
)))(?:,@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
\t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])
)(?:\.(?:(?:\r\n)?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))))
:(?:(?:\r\n)?[ \t]))?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+
|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r
\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t
]))"(?:(?:\r\n)?[ \t])))@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](
?:(?:\r\n)?[ \t])
)(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?
:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?
:\r\n)?[ \t])))\>(?:(?:\r\n)?[ \t]))|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?
:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?
[ \t]))
"(?:(?:\r\n)?[ \t])):(?:(?:\r\n)?[ \t])(?:(?:(?:[^()<>@,;:\\".\[\]
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|
\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>
@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"
(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t])))@(?:(?:\r\n)?[ \t]
)
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?
:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[
\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])))|(?:[^()<>@,;:\\".\[\] \000-
\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(
?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t]))\<(?:(?:\r\n)?[ \t])(?:@(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([
^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\"
.\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\
]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])))(?:,@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\
[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)
\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\]
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]
|\\.)\](?:(?:\r\n)?[ \t])))):(?:(?:\r\n)?[ \t]))?(?:[^()<>@,;:\\".\[\] \0
00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t])))@(?:(?:\r\n)?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]
]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])))\>(?:(?:\r\n)?[ \t]))(?:,\s(
?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t]))(?:\.(?:(
?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[
\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t
])))@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t]))(?
:\.(?:(?:\r\n)?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|
\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t])))|(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\
]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t]))\<(?:(?:\r\n)
?[ \t])(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["
()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)
?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t])))(?:,@(?:(?:\r\n)?[
\t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t]
)(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])))):(?:(?:\r\n)?[ \t]))?
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t]))(?:\.(?:(?:
\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t])
))@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t]))(?:\
.(?:(?:\r\n)?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t])))\>(?:(
?:\r\n)?[ \t])
)))?;\s)
#108 #867788
>>867779
вот нормальный регэкс для емэйла:
(?:(?:\r\n)?[ \t])(?:(?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:
\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(
?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[
\t]))"(?:(?:\r\n)?[ \t])))@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\0
31]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\
](?:(?:\r\n)?[ \t])
)(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+
(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:
(?:\r\n)?[ \t])))|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)
?[ \t])
)\<(?:(?:\r\n)?[ \t])(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\
r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[
\t])
)(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)
?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t]
)))(?:,@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[
\t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])
)(?:\.(?:(?:\r\n)?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t]
)+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))))
:(?:(?:\r\n)?[ \t]))?(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+
|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r
\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:
\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t
]))"(?:(?:\r\n)?[ \t])))@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031
]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](
?:(?:\r\n)?[ \t])
)(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?
:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?
:\r\n)?[ \t])))\>(?:(?:\r\n)?[ \t]))|(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?
:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?
[ \t]))
"(?:(?:\r\n)?[ \t])):(?:(?:\r\n)?[ \t])(?:(?:(?:[^()<>@,;:\\".\[\]
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|
\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>
@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"
(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t])))@(?:(?:\r\n)?[ \t]
)
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?
:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[
\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])))|(?:[^()<>@,;:\\".\[\] \000-
\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(
?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t]))\<(?:(?:\r\n)?[ \t])(?:@(?:[^()<>@,;
:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([
^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\"
.\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\
]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])))(?:,@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\
[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\
r\\]|\\.)
\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\]
\000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]
|\\.)\](?:(?:\r\n)?[ \t])))):(?:(?:\r\n)?[ \t]))?(?:[^()<>@,;:\\".\[\] \0
00-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\
.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[^()<>@,
;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|"(?
:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t])))@(?:(?:\r\n)?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t])(?:[
^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\]
]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])))\>(?:(?:\r\n)?[ \t]))(?:,\s(
?:(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t]))(?:\.(?:(
?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[
\["()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t
])))@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t
])+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t]))(?
:\.(?:(?:\r\n)?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|
\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t])))|(?:
[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".\[\
]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t]))\<(?:(?:\r\n)
?[ \t])(?:@(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["
()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)
?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>
@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t])))(?:,@(?:(?:\r\n)?[
\t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,
;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t]))(?:\.(?:(?:\r\n)?[ \t]
)(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\
".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t])))):(?:(?:\r\n)?[ \t]))?
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\["()<>@,;:\\".
\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))"(?:(?:\r\n)?[ \t]))(?:\.(?:(?:
\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z|(?=[\[
"()<>@,;:\\".\[\]]))|"(?:[^\"\r\\]|\\.|(?:(?:\r\n)?[ \t]))
"(?:(?:\r\n)?[ \t])
))@(?:(?:\r\n)?[ \t])(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])
+|\Z|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)
\](?:(?:\r\n)?[ \t]))(?:\
.(?:(?:\r\n)?[ \t])
(?:[^()<>@,;:\\".\[\] \000-\031]+(?:(?:(?:\r\n)?[ \t])+|\Z
|(?=[\["()<>@,;:\\".\[\]]))|\[([^\[\]\r\\]|\\.)\](?:(?:\r\n)?[ \t])))\>(?:(
?:\r\n)?[ \t])
)))?;\s)
5 Кб, 200x200
#109 #867791
>>867797
#110 #867797
>>867791
RFC же, братиш
48 Кб, 314x300
#111 #867832
В самой первой задачке по html/css надо использовать calc? Это типа проще, чем с флоатом?
>>867910
#112 #867890
Аноны, подскажите к чему сначала приступить, JS или PHP? Вкатился вот прям совсем недавно, начинал с html и css. Спасибо.
>>867910>>867914
#113 #867910
>>867832

Не надо ни calc, ни float. Надо лишь внимательно изучить как работает width и margin при display: block.

>>867890

JS нет смысла изучать если не знаешь HTML/CSS.
>>868082>>868201
#114 #867912
ОП проверь айфон в кредит http://ideone.com/qe8F1j
Вроде то пальто, но с твоим ответом не сходится
>>867917
#115 #867914
>>867890

А так, можешь начать с JS. У нас есть уроки по нему в ОП посте.
>>868082>>868128
#116 #867917
>>867912

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

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

(( $creditBalance * $percent ) + $servicePayment повторяется 2 раза, нехорошо.
#117 #868066
В природе существуют Java to JS/PHP трансляторы/конверторы? Очень нннада переписать код с жабки на пыхо-жс, а жабки-то я и не знаю.

>GWT, Vaadin, JSweet


Что из этого действительно может сгенерить код в js + node или в js + php из джава-кода, использующего JPA и JSP?
>>868081
#118 #868081
>>868066

Проще изучить основы java, она во многом на php похожа.
#119 #868082
>>867910
>>867914
Спасибо за ответ, анон. HTML/CSS, вроде, норм освоил.
#120 #868128
>>867914
Ох, начать программировать с JS...
Туда нужно идти с понимаем ООП и базовых структур данных, иначе будет каша в голове, гроб, кладбище.
>>868132
#121 #868132
>>868128

Тогда надо изучить сначала пхп, у нас в учебнике есть урок по ООП для начинающих.
#122 #868179
>>867652
Это мне 5 вариантов кода писать? 1 для идеон, второй чтобы у меня работал в браузере, третий чтобы на гитхабе выложить закоментированный, четвёртый себе сохренить со всеми дампами м echo тестовыми...
>>868197
#123 #868197
>>868179

тебе же написали выше про нужный header()
>>868199>>868200
#124 #868199
#125 #868200
>>868197
Ты либо не мне ответил, либо обьясни как Header влияет на отображение пробелов при финальном отображении в браузере? Например хром видит что у меня 10 пробелом и символ и отображает это как один пробел. В результате всё форматирование отваливается.
>>868203
#126 #868201
>>867910

> Надо лишь внимательно


Но там написано, что и display нинужен.
>>868219
#127 #868203
>>868204
#128 #868204
>>868203
Блин, был же в коде, нет посветовали "Не пихай его куда попало, зачем ты это делаешь. Смысла от него нет."
#129 #868218
Интересный пост про ручное тестирование: https://m.habrahabr.ru/post/314140/

Автоматизированное тестирование - это по сути примерно то же самое, только выполняемое скриптом.

У нас есть обзорный урок по автоматизированному тестированию: https://gist.github.com/codedokode/a455bde7d0748c0a351a
#130 #868219
>>868201
А, ну да, оно там по умолчанию. Но всё равно ничего не выходит.
Если через паддинг родительского элемента задавать тот самый отступ в 10px, то он сам, естественно, раздвигается. А это, вроде, недопустимо, если судить по картинке.
>>868223
#131 #868223
>>868219

Давай тогда считать 34% и 66% от внутренней ширины контейнера после вычета паддинга.

Проще говоря можно желтому блоку просто поставить width 66%.
#132 #868436
Проверьте, пожалуйста.
https://github.com/anonymous011010/studentslist
>>874485>>874486
#133 #868459
Почему пхп лучше перла?
Их вообще можно сравнивать?
>>868478
#134 #868478
>>868459
Потому что PHP активно развивается и несоизмеримо популярнее.
>>868481
#135 #868481
>>868478
К примеру, книги Донцовой активно развиваются и несоизмеримо популярнее какой-нибудь условной классики. Но они от этого не лучше.
>>868495
#136 #868495
>>868481
Я бы не стал проводить подобную аналогию.
Популярность для языка значит, что у языка есть комьюнити, библиотеки, фреймворки и тд.
А еще с ним намного проще найти работу.
>>868497
#137 #868497
>>868495
Ладно, ты, пожалуй, прав
#138 #868763
Хорошо друзья. Хорошо. Теперь я понимаю что такое роутер, как он работает. Я бы даже смог написать свой, возникни вдруг такая необходимость.
Но я все еще не понимаю, НАХУЙ ОН НУЖЕН БЛЯДЬ?!
#139 #868766
>>868763
Объясни мне, плиз, своими словами.
>>869822
#140 #868786
>>868763
У тебя есть многостраничный проект, к примеру блог какой-нибудь или инет магазин. Человек зашел на главную, потом решил кликнуть на список постов/категорий/товаров, соответственно ссылка уже не "/", а к примеру index.php?route=category или "/category" смотря какие у тебя правила формирования линка, когда роутер обработает такую ссылку он передаст управление в контроллер категории, который отработает и вернет тебе представление категории. Зашел человек в товар/пост, "/product" "index.php?route=product&product_id=22" и роутер передал управление в контроллер продукта с гет параметром product_id = 22. Контроллер отработал и вернул представление продукта. Видимо ты ещё не работал с многостраничными приложениями. Советую всё же изучить уроки из ОП-поста, особенно MVC и задачу на студентов. там как раз и роутинг разберешь.
>>869822
#141 #868803
>>868763

А как ты без роутера определишь, какой контроллер должен обрабатывать запрос вроде /news/latest или /id12345?
>>869822
#142 #868847
>>868427

> Я не глупый, шарю в опп, но хоть убей не пойму что они от меня хотят.



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

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


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

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

Начни с чтения урока. Если тебе не нравится урок, в ОП посте есть 2 книги, в которых тоже есть подробный раздел про ООП.
#143 #868851
sup аноны.
я тот анон, что просил у вас помощи по фильтрам. В общем я уже подошел к концу своего тз и опять прочитав задания понял, что нихуя не понял что от меня хотят собственно вот:

Создать два базовых класса описывающих сотрудника с почасовой оплатой, второй, описывающий сотрудника с месячной ставкой. Вычисление оплаты труда для сотрудников с почасовой оплатой будет иметь следующую формулу: количество часов * сумму за один час. Для сотрудников со ставкой метод расчета возвращает месячную ставку. Реализовать следующую функциональность:

ну собственно дальше функциональность всю запилил, что они хотели.
Я не глупый, шарю в опп, но хоть убей не пойму что они от меня хотят.
как именно описать сотрудника?, типа при выводе всех сотрудников определять тип сотрудника и переводить его в нужный объект, который просто пересчитает его зп и закинет все параметры в свойства. По типу метода фабрики.
В общем кто из более опытных анонов понял в чем дела, прошу объяснить.
>>868889
#144 #868876
Аноны, как парсить битый JSON? Надо получить всего 2 параметра, но никак немогу. По любому поводу мне выдаётся ошибка конвертации обьекта в стринг. Второй день бьюсь.

JSON беру отсюда.
https://en.wikipedia.org/w/api.php?action=query&titles=Main Page&prop=revisions&rvprop=content&format=json
>>868886
#145 #868883
>>865852

>как куки (а следовательно и сессии) общие для всех вкладок в браузере


С этого места поподробней.
#146 #868884
>>865956

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


Для таких кейсов стоит реализовать сервис, в котором можно спрятать логику получения нужного значения.
>>868893
70 Кб, 962x706
#147 #868886
>>868876
Он не битый, чем ты его парсишь?
>>868887
#148 #868887
>>868886
$wikiData= json_decode($data, true);
А дальше с переменной работаю как с массивом, но мне выдаёт ошибку.

Алсо пробовал echo myarray[query][pages] Выдаёт array. Что я делаю не так?
>>868890>>868893
#149 #868889
>>868851
Какой нахуй метод фабрики. Тебе рузкем по белому написано - "Создать два базовых класса".
Возьми да и создай.
#150 #868890
>>868887

>выдаёт ошибку


Какую?

>Выдаёт array. Что я делаю не так?


Так там и есть array же, дурик. Этот... ассоциативный.
>>868894>>868900
#151 #868893
>>868887

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

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

>>868884

Ему там по моему просто переменную во view надо было передать, тут ничего усложнять не требуется.
>>868896>>868898
#152 #868894
>>868890
И как в нём получить pageid? Если там стоит 1558034, а php не воспринимает его как индекс массива.
>>868899
#153 #868896
>>868893
Зачем мне encode? Я хочу расшифровать JSON а не заново его зашифровать же.
#154 #868898
>>868893
Код который я привёл даже не мой, взял из статьи json_decode.

Пробовал работать как с массивом через foreach, мне выдаёт ошибку что не могу обращаться к обьекту как к массиву.
>>868901
#155 #868899
>>868894
Не 1558034, а 15580374
19 Кб, 538x61
#156 #868900
>>868890

>Какую?

>>868903
#157 #868901
>>868898
И выучи уже var_dump() и print_r().
>>868902
#158 #868902
>>868901
Я вижу и var_dump() и print_r(). Дальше что?
#159 #868903
>>868900
Ну я хз,
$json = file_get_contents('https://en.wikipedia.org/w/api.php?action=query&titles=Main Page&prop=revisions&rvprop=content&format=json');
$arr = json_decode($js, true);
print_r($arr);
У меня ошибок нет.
>>868904
#160 #868904
>>868903
Да блин, мне надо ЭЛЕМЕНТ массива вывести, и вот когда я обращаюсь к массиву как к массиву, он ВНЕЗАПНО говорит что массив у меня не массив, а обьект.
#161 #868908
>>868904
Тащи сюда свой код смердящий уже.
>>868914
#162 #868911
>>868904

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

И не превращайте тред в чат пожалуйста, пишите 1 большое сообщение, а не 10 сообщений по одному предложению.
>>868914
#163 #868914
>>868908
начал оформлять всё на IDEone и всё заработало. Даже не подозреваю что я сделал. Вообще тот же код.
>>868911
Поле Revisions графа * обрати внимание на неё. Некоторые парсеры его отказываются из JSON декодировать. И получается что они декодируют всё до и всё после.
>>869484
#164 #868917
кто-нибудь скажет мне почему людей, изучающих/программирующих на рнр принижают?
#165 #868945
>>868917
Потому, что кругом полно ебанатов с комплексами, которые нуждаются в том, чтобы унижать других. Не слушай юродивых, язык хуярит уже лет 15 и будет хуярить дальше как основной для веба. В нем есть почти что полноценное ооп, и всё что есть в современных яп. И вобше , плохих или хороших технологий нет, все зависит от разработчика и его уровня. Гавно можно клепать и на джаве или с и на прочих охуенных языках. Если что тыкай еблом в фесбук, контакт и хуеву тучу сайтов и пусть тебе объеснят почему эти гиганты успешно рвботают на php а не на их пиздатой джаве
4 Кб, 789x181
#166 #869152
>>869484
#167 #869189
>>867788
/.+@.+\..+/i
>>869201>>869482
#168 #869201
>>869189
Твоя регулярка считает, что имейл @@@@@@.@@ валиден: https://regex101.com/r/0fNSM5/1
>>869482
#169 #869215
>>868917
В пхп низкий порог входа, а потому дофига гавнокода

Сейчас работаю над проектом, что параллельно со мной ведет 42х летний самоучка, уверяющий про свой 3х летний опыт. Думаю молодость он провел веселую, увлекаясь тяжелыми наркотиками, потому что такие шедевры он пишет - это пиздец. Я нахожусь в состоянии близком к восторгу, пытаясь осознать масштабы его безумия, и животной истерики сразу. Ну и в отделе давно подшучивают, что когда он совсем съедет, то ссылки на репозитории с его кодом приобщат к истории болезни.
47 Кб, 432x402
#170 #869219
Пикрелейтед в треде.

>>867788
>>867779
Для проверки email'ов есть встроенная функция filter_var:filter_var('exafa|mpleANUSgmG|)ailPUNCTUMco Tgm', FILTER_VALIDATE_EMAIL);

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

>>868917
У языка дурная слава за счет того, что большая часть наших собратьев некомпетентные говноеды и разработка на пхп было про говномес с HTML либо MVC. С другой стороны, тебе ничто не мешает не быть говноедом, знать по настоящему ООА/П с принципами SOLID, GRASP и DDD, разрабатывать REST API на каком-нибудь Zend Expressive и когда ты зарабыватаешь > 250k на PHP в месяц как я, тебе уже решительно похуй на то, какое там мнение про твой стек технологий имеет рандомный скам.

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

>>867533
Почему ты просто не использовал Doctrine 2?
>>869226>>869482
#171 #869226
>>869219

> функция filter_var


Только она не может в кириллические домены.

Ну и раз уж зашёл, расскажи, если не сложно, как докатился до своего состояния, что было наиболее полезным на пути становления тебя как толковго PHP программиста и вообще что можешь посоветовать ботающему молодняку.
>>869248>>871321
13 Кб, 200x200
#172 #869248
>>869226

>


>Только она не может в кириллические домены.


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

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



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

Во-вторых, серьезно инвестигейтить в ООА/П, в знание принципов SOLID, DDD, GRASP, читать соотвествующие ресурсы и умных ребят вроде Сергея Теплякова. Читать дохуя книг обо всем и вся, о чистом коде, об ооа/п, всякие там дедлайны и прочее – чем больше кругозор, чем больше ты всего знаешь, тем более ценным разработчиком ты являешься. Работать с персонажами "я фронтенд-разработчик но верстать я не умею" очень сложно

В-третьих, поработать в серьезных, желательно богатых на бизнес-логику проектах. Корпоративные ERP, CRM = годно, пилить сайты на симфонипараше или интернет-магазина на магенто = fail

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

Что касается меня, то хз. С 14 лет пишу на пхп, вот 25 и теперь по два-три одновременно работаю, то есть по каждому проекту получается средние деньги, но оба вместе дают мне очень вкусные цифры
>>869417>>869482
#173 #869361
сап, аноны. пишу сейчас роутер (так для тренировки) и вот словил проблему на ошибке 404.
.htaccess все запросы перенаправляет на index, после я забираю урл и проверяю его, чуть что выкидываю 404. И вот самой главной целью- это передать заголовки в которых ответ 404, но интерпретатор не пускает- говорит, что заголовки уже переданы, но по сути я еще ничего не выводил в html, только инклудил один файл, в котором класс валидатора. Да без инклуда заголовки передает. без BOM сохранял
>>869375
50 Кб, 578x639
#174 #869375
>>869361
Либо BOM все-таки есть, либо ты сделал какой-нибудь пробел перед <?php
Попробуй в PHPStorm поискать по регулярке: ^(.+)\<\?php
#175 #869378
>>869375
<?php
include 'Validator.php';
#print_r($_REQUEST['url_qery']);
if ( Validator::url_query_validate($_REQUEST['url_qery']) === false ) {
header("Location: http://localhost/error404.php");
} else {
echo ($_REQUEST['url_qery']);
}
#176 #869379
>>869375
выглядит это так вот. тут я уже делаю редирект, на файл в котором меняю заголовки на 404 , но все так же не работает
>>869480
#177 #869381
>>866034
Сколько времени даётся на эту задачу?
>>869387
#178 #869385
>>869375
Сейчас все сработало, но когда проверяю заголовки, мне все равно выдает ответ 200, хоть я задал 404
>>869386
#179 #869386
>>869385
часа два
>>869387
#180 #869387
>>869381
обосрался
>>869386
#181 #869407
Анон, что почитать по хедерам (заголовкам), ответам и прочей хрени? Мне кажется, что я не совсем понимаю, что происходит.
>>869424>>869480
#182 #869417
>>869248

>В-третьих, поработать в серьезных, желательно богатых на бизнес-логику проектах. Корпоративные ERP, CRM = годно, пилить сайты на симфонипараше или интернет-магазина на магенто = fail


Не понял, поясни за симфонипарашу. Хочешь сказать на фреймворках писать хуёво, или у тебя претензии только к симфони?
>>869480
#183 #869424
>>869407
в самом мануале есть про заголовки , там еще ссылка на больше инфы, и еще почитай про http протокол
#184 #869480
>>869407

Тебе надо почитать про протокол HTTP. В Википедии есть кое-какая инфа, также погугли статьи и уроки по теме, также есть недописанный урок от ОПа:

- https://github.com/codedokode/pasta/blob/master/network/http.md
- https://github.com/codedokode/pasta/blob/master/network/urls.md

>>869417

Я тоже не понял чем ему Симфони не нравится.

>>869379

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

Посмотри что приходит в ответе.

В твоем коде как минимум 2 ошибки:

- после header Location ты не завершаешь скрипт
- ты не понимаешь как работает редирект. header Location выставляет код ответа 3xx вместо нужного.

То есть ты вместо "страница не найдена" говоришь браузеру "страница переехала по другому адресу".

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

Алсо, название плохое - Validator - надо было написать конкретнее, что это за валидатор. Алсо статические методы это не ООП.

В общем, я тебе советую поставить курл (не расширение к PHP, а утилиту командной строки) и например с помощью curl -v 'http://localhost/test' запрашивать страницу и смотреть заголовки.

Либо можно поставить wget и сделать wget -d 'http://...' -O - (не перепутай пробелы).

Либо какую-нибудь программу для отправки HTTP запросов с GUI.
#184 #869480
>>869407

Тебе надо почитать про протокол HTTP. В Википедии есть кое-какая инфа, также погугли статьи и уроки по теме, также есть недописанный урок от ОПа:

- https://github.com/codedokode/pasta/blob/master/network/http.md
- https://github.com/codedokode/pasta/blob/master/network/urls.md

>>869417

Я тоже не понял чем ему Симфони не нравится.

>>869379

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

Посмотри что приходит в ответе.

В твоем коде как минимум 2 ошибки:

- после header Location ты не завершаешь скрипт
- ты не понимаешь как работает редирект. header Location выставляет код ответа 3xx вместо нужного.

То есть ты вместо "страница не найдена" говоришь браузеру "страница переехала по другому адресу".

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

Алсо, название плохое - Validator - надо было написать конкретнее, что это за валидатор. Алсо статические методы это не ООП.

В общем, я тебе советую поставить курл (не расширение к PHP, а утилиту командной строки) и например с помощью curl -v 'http://localhost/test' запрашивать страницу и смотреть заголовки.

Либо можно поставить wget и сделать wget -d 'http://...' -O - (не перепутай пробелы).

Либо какую-нибудь программу для отправки HTTP запросов с GUI.
#185 #869482
>>869248

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

> и теперь по два-три одновременно работаю,


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

>>869219

Доктрина там по моему к вопросу прямого отношения не имеет. Ты бы мог упомянуть Query Builder.

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

>>869201

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

ifA}nav.ivanov.ANUS[O-examplePUNCTUMi6ncom
ivan.ivanov @example.com

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

>>869189

Вместо точки лучше \S или даже "не пробел и не @"
#185 #869482
>>869248

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

> и теперь по два-три одновременно работаю,


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

>>869219

Доктрина там по моему к вопросу прямого отношения не имеет. Ты бы мог упомянуть Query Builder.

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

>>869201

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

ifA}nav.ivanov.ANUS[O-examplePUNCTUMi6ncom
ivan.ivanov @example.com

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

>>869189

Вместо точки лучше \S или даже "не пробел и не @"
>>869604
#186 #869484
>>869152

Ох, а переносы строк-то поломались. header() забыл волшебный?

>>868914

"некоторые парсеры" ведь json_decode не включают - он звездочку ведь нормально декодирует.

>>868904

Значит у тебя действительно объект потому что ты так и не прочел мануал.
#187 #869577

>>846554


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



Для одного типа файлов будут одни поля, для другого другие. Как это организовать, чтобы не было избыточности?
>>869587
#188 #869587
>>869577

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

Разумеется вся работа с информацией о файле не должна быть в виде массиво-ориентированного кода, стоит инкапсулировать все это внутри класса.
>>869598
#189 #869598
>>869587
ок, понял

> https://github.com/TheSidSpears/FileHosting/blob/master/public/js/helper.js#L5


> Вместо этого удобнее просто перемещать единственную форму, чем сощздавать каждый раз новую



Что-то у меня трудности с пониманием, как это реализовать
>>869625
#190 #869604
>>869482

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


>


>inav.ivanoP@yv.ANUS~GlexamplePUNCTUMJRRcom


>ivan.ivanov @example.com


>


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


Верно, тем более настоящей валидацией существующего емейла должна быть ссылка активации в письме.
#191 #869625
>>869598

Ты DOM в яваскрипте изучал? appendChild и insertBefore забирают узел у старого родителя и добавляют новому.
26 Кб, 299x237
#192 #869671
Аноны, объясните в задачке навигатор пикрелейтед. Ведь в константы можно сразу вписать значения массива ниже, и не использовать массив совсем. Или может весь смысл в том, чтобы написать функцию принимающую значения констант, а отдающую значения массива? Или может существует ещё что-то о чем я не знаю, и для чего это нужно?
#193 #869729
Уютный тредик, открытый в браузере, отъедает память сотнями мегабайт и тормозит? Кажется, я нашел решение. Отключите "Автоматически следить за ...", отключите Топ тредов, и может еще несколько настроек, и вкладка с мейлручем перестает отъедать память. Посмотрим, конечно, еще пару дней, сколько там набежит.
7 Кб, 882x41
#194 #869735
Аноны, объясните в чем беда. Только начал изучать программирование. Поставил Denwer, решил проверить, как выглядит решенная задачка в браузере, а он мне выдал пикрелейтед. Пробовал поменять в настройках браузера кодировку с Windows-1251 на UTF-8, но это не помогло. Если что , пользуюсь яндекс браузером. На ideone все работает
>>869736>>869737
#195 #869736
>>869735
Файл там надо сохранять без BOM, что-то такое.
Посмотри в настройках при сохранении файла, такое есть в IDE.
>>869749
#196 #869737
>>869735

Нужен header с Content-Type: text/plain; charset=utf-8
>>869749
#197 #869749
>>869736
Отключил через File>Remove BOM в PhpStorm не помогло >>869737
Если я тебя правильно понял, я должен прописать в начале кода: $header = 'Content-type: text/html; charset=UTF-8'; ?
Если я правильно все сделал, то это тоже не помогает
>>869760>>869922
#198 #869760
>>869749
Попробуй тот же файл создать в Блокноте.
У меня такое было при первой установке Шторма.
>>870030
82 Кб, 1631x860
176 Кб, 1618x823
#199 #869774
https://www.codewars.com/kata/duplicate-encoder/train ну и хули ему надо от меня? Тесты в run examples проходит, а те которые в run suit нет.
>>869787
#200 #869787
>>869774

> Тесты в run examples проходит, а те которые в run suit нет.


Первый раунд тестов для тебя, ты их изменяешь и тут же в браузере всё тестишь. Там хоть assert 1 == 1 пиши, всё будет зелёненьким.

> ну и хули ему надо от меня?


Неправильно расставлены скобки. Но непонятно для какого слова. У меня тоже такое бывало, что непонятно какие тесты падают. Можно заглянуть в Discourse задачи, если проблема не только у тебя одного, то ты там найдёшь решение. Конкретно в твоём случае всё не так плохо, написано "should ignore case". Попробуй кодировать слова вроде WoRdD, wORDd и посмотри, правильно ли кодирует твоя программа.

Конкретно твоё решение слишком мудрёное, я без регулярок сделал.
>>869789
#201 #869789
>>869787
Хм, strtolower помог, хотя там вроде все кейс инсенситив.
#202 #869822
>>868786
>>868803
У меня в задаче про студентов в шаблонах были прописанны ссылки на контролеры(../registeration.php). Никаких недостатков этого подхода я не заметил, поэтому и спрашиваю. Зачем?
>>868766
Лучше чем здесь я бы не сказал>>868786
>>869919
35 Кб, 604x579
#203 #869823
Ну доблае утличка, поучим ваши пыхыпы
>>872656
56 Кб, 1061x452
#204 #869877
Как тут код узнал что именно где пишется дата, а где - ивент? Цикл идет, задается в теле цикла значение, что будет первым, а что нет. Понятно. Но где именно обозначение что индекс массива - это дата, а значение - ивент?

Только не гоните ссаными тряпками, я вот не понял действительно. Как работает вообще цикл с массивом?
#205 #869895
>>869877
В foreach().
foreach($что_перебирает as $индекс=>$значение)
Поскольку массив ассоцитивный, то в роли $индекса дата.

Есть краткая форма foreach($что_перебирает as $значение)
#206 #869918
>>869877
Когда объявляешь массив задаешь что будет у него ключем, а что значением.
$someShit = array(
'key' = > value,
'key2' => value2;
);
#207 #869919
>>869822

Так в твоем случае роутером просто служил Апач. Но иногда хочется более красивые и дружественные к поисковикам УРЛ чем news.php?action=view&id=1234

>>869877

foreach ($array as $key => $value)

$key - ключ текущего элемента
$value - значение

> Но где именно обозначение что индекс массива - это дата, а значение - ивент?


Потому что одна переменная стоит слева от стрелки, а другая справа. Слева стоит ключ, справа значение. Мануал в помощь http://php.net/manual/ru/control-structures.foreach.php

Вообще, ты правильно делаешь, что задаешь такие вопросы, по ним становится понятно что стоит поменять или добавить в уроке.
#208 #869922
>>869749

Нет, надо выдать HTTP заголовок Content-Type с помощью функции header(): http://php.net/manual/ru/function.header.php

Вот почитай немного про HTTP:

https://github.com/codedokode/pasta/blob/master/soft/web-server.md
https://github.com/codedokode/pasta/blob/master/network/http.md

Чтобы браузер понял, в какой кодировке страница, ему надо об этом сказать. Либо с помощью опции в заголовке Content-Type либо с помощью HTML-тега meta charset.
>>870030
#209 #870030
>>869760
Спасибо, это помогло. А в чем проблема со Штормом была не знаешь?
>>869922
Спасибо
>>870189
#210 #870039
итт мне помогут абстракцию построить на жаве?
>>870260
#211 #870189
>>870030
Да вот почему-то Шторм изначально делает какие-то кривые файлы.
Я сам возился три часа и орал в треде, пока анон не надоумил поменять файл с BOM на без него.
И с HTML простым там тоже может быть проблема, имей это в виду.
Но при этом у меня сейчас выходят нормальные файлы .php, уже и не вспомню, что именно сделал для этого. Может, по умолчанию поставил без BOM и в UTF-8, даже скорее всего.
#212 #870242
Сап, у меня тут маленький бугурт возник. Отправил свой код с тестовым. Там проверяющий сделал несколько мелких справедливых правок. Но что меня удивило, что он все мои двойные кавычки сменил на одинарные и записал это как мой недостаток, мол одинарные кавычки это тру, а двойные кавычки - это плохой тон в программировании. Это вообще нормально? Просто я вообще никогда не слышал что между ними есть хоть какая-то разница. Also в двойных кавычках есть профит в том, что внутри них моно писать одинарные, что даёт профиты в скорости написания кода. Есть тут кто сможет мне объяснить?
#213 #870243
>>870242

>двойные кавычки - это плохой тон в программировани


Если он так и сказал то он сказочный долбоеб.
>>870246
#214 #870246
>>870243
Я PSR-2 сейчас листаю, там вроде ничего такого нет, именно про кавычки, или поправьте меня пожалуйста если я неправ. Что-то прямо смущает меня этот коментарий. Всё-таки я ньюфаг с опытом в 2 месяца, могу ошибаться.
>>870252
109 Кб, 568x559
#215 #870252
>>870246
>>870242
Это должно быть в шапке.
#216 #870260
>>870039

Если это вопрос в общем по ООП, а не по особенностям его реализации в Яве.

>>870242

Если в PSR ничего про кавычки не написано, то это лишь его личные предпочтения.
>>870263
#217 #870263
>>870260

>Если это вопрос в общем по ООП, а не по особенностям его реализации в Яве.


https://bitbucket.org/user723142/video_organizer/src/a4d6c6847e5b3b556ea73d206cab54676f396064/src/main/java/hello/Reindexator.java?at=master&fileviewer=file-view-default

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

мне нужно сделать не так топорно как сейчас, а в виде абстракций.

в частности, мне нужно сделать ПРАВИЛА для добавения.

то есть допустим я захочу добавлять файлы размер которых больше 10МБ

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

то есть, мне нужно какая-то абстрактная конструкция. понимаешь? вот эта вся ооп магия.

как это сделать?
>>870276
#218 #870276
>>870263

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

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

Не надо слепо стараться все вынести в отдельные объекты. Надо применять инженерный подход, то есть ответить на вопрос: в чем преимущества подхода A перед B? Чем отдельный класс-компаратор лучше просто заложенного в коде if или приватного метода? Я например думаю, что приватный метод сделать проще и это его преимущество.

Также, мне не очень нравится интерфейс твоего объекта, вот эти вот методы setFilesFromDb, setFilesFromFilesystem. Ты по моему имитируешь тут передачу аргументов функции через сеттеры. Не проще просто написать

reindex(filesFromDb, filesFromFilesystem) ?

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

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

В общем, я тебе советую сделать сравнение через компаратор либо в виде приватного метода либо в виде интерфейса, если нужна расширяемость и возможность задавать произвольные правила.
>>870291
#219 #870287
>>865582

Да, можно. Но если форма имеет тип method="GET" то они будут переписаны данными формы, если POST то ок.

>>864755

Чтобы сделать обновление части страницы через аякс, советую сделать так. На клиенте при клике по ссылке делать запрос с добавлением параметра, например /some/page?noHeader=1

В приложении дописать костыль, который будет убирать header/footer при наличии параметра. В Юи есть такая штука как layout, она отвечает за вывод шапки/подвала. Надо в ней разобраться и доработать чтобы она могла ее не выводить.

>>865009

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

>>865014

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

>>865015

Фулстек конечно.
>>870295
#220 #870291
>>870276

>Обоснуй причину, почему ты хочешь сделать правила в виде объектов?


я хуёвый погромист и хочу дома попердолить что-нибудь посложнее тупых методов

>объект-компаратор


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

>Если у тебя десятки миллионов или больше файлов


нет, количество файлов небольшое, не нужно это учитывать
>>870388>>870390
#221 #870295
>>870287

>Фулстек конечно.


Странно, я вот недавно начал работать фуллстек девом, и я ощущаю себя эдаким jack of all trades, master of none. Я думал нужно стремиться к чему-то одному, а фуллстек оставлять тем, кто только начинает свой путь разработки и еще не является профессионалом в какой-то конкретной области.
>>870297
#222 #870297
>>870295
я мимо, если что
настоящие фулстек девелоперы - это гении кодинка.

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

так что смотри по себе. если слишком сложно для тебя - выбери направление уже.
#223 #870388
>>870291

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

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

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

Алсо, почитай эту статью: https://habrahabr.ru/post/153225/

> не понимаю что он должен из себя представлять.


> отдельный класс, и там куча методов?


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

Ты вещь Яву знаешь, должен знать что при сортировке можно использовать компаратор в виде класса либо лямбды: http://stackoverflow.com/questions/14154127/collections-sortlistt-comparator-super-t-method-example/14154185#14154185

я предлагал что-то похожее, но сейчас вижу что тебе это не нужно. Просто впиши нужные условия прямо в класс.
>>870399>>870402
#224 #870390
>>870291

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

Декомпозиция (разделение логики на классы) используется либо когда кода становится много и он становится сложным, либо когда код выносится в библиотеку, функциональность которой будут модифицировать другие люди.
#225 #870399
>>870388

>Если у тебя нет веских аргументов


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

этой программой я пользуюсь, почему бы здесь не сделать это.
>>870405
#226 #870402
>>870388

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


нет, сначала есть 2 списка - файлы в бд и файлы на диске

затем вызываются методы по очереди
setFilesToInsert(filesFromFilesystem, filesFromDbMap);
setFilesToDelete(filesFromDb, filesFromFsMap);

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

как сделать это красиво и абстрактно?
плес не надо больше про ТЕБЕ НЕ НУЖНА СЛОЖНОСТЬ. нужна, в этом и смысл
>>870405
#227 #870405
>>870399

Зачем практиковаться в написании переусложненного кода? Я тебе уже написал, если ты хочешь изучать паттерны, открой любой сложный фреймворк или ORM (Spring, Hibernate, код аднроида) и изучай. Это даст тебе намного больше пользы чем прикручивание паттернов туда, где они не нужны.

>>870402

У тебя какой-то странный алгоритм. Я бы сделал так:

- для каждого файла с диска filefromDisk {
- находим fileInDb = соответстующий ему файл в БД или null
- сравниваем fileInDb и FileFromDisk и решаем, что с ним делать
- помещаем fileFromDIsk в нужный список (на вставку, обновление итд)
}

Я могу только рассказать, как сделать код лучше. Рассказать, как его переусложнить, я не могу.
>>870408
#228 #870408
>>870405

>если ты хочешь изучать паттерны, открой любой сложный фреймворк или ORM


я не понимаю сложные абстракции когда читаю их

я полтора года работаю в жава-интерпрайсе на сложном фраемворке и нихуя не понимаю в нём вообще
#229 #870413
>>870408

Можешь задать вопрос в этом треде, главное правильно его сформулируй и дай ссылки на примеры кода. Может, я смогу разобраться. Ну или ссылку мануал дам.
>>870415
#230 #870415
>>870413
это бот написал?
>>870456
#231 #870456
>>870415

ОП

>>865019

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

>>865020

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

>>865339

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

Главное, продолжай учиться дальше.

>>865344

У них своеобразное понимание MVC. В той же Симфони папки Model нет так как к модели там относится почти все, кроме вью и контроллеров.

>>865364

Наверно pug-cli его как-то вызывает или использует?

>>865424

Ты уверен, что не работает? Сдампь содержимое массива до и после array_push и покажи, что после добавления массив остается точно таким же. Я думаю, причина в чем-то другом.

>>865574

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


> А зачем?


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

>>865574

> Лучше всё вручную передавать?


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

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

>>865628

>Все url'ы рабочие


Это они сейчас рабочие, а если ты завтра добавишь УРЛ вроде /student/123/profile то перестанут работать. Лучше бы использовать УРЛ от корня сайта, вроде '/register' вместо относительных 'register'.

> Звучит прикольно, но как это реализовать? Погуглил, суть ясна, но сложно представляю с чего начать.



=== для объектов проверяет, это один и тот же объект или разные.

Некоторые ORM, например, Doctrine, умеют автоматически искать и сохранять в базу изменения в ранее загруженных объектах. Эти же ORM гарантируют что одной записи в БД всегда соответствует один и тот же объект - если 2 раза запросить из базы одного и того же пользоватля, то во второй раз обращения к БД не будет, а будет возвращен ранее загруженный объект. Если бы это правило не соблюдалось, и записи могли бы соответствовать 2 разных объекта, то было бы непонятно, в каком из них актуальные данные.
#231 #870456
>>870415

ОП

>>865019

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

>>865020

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

>>865339

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

Главное, продолжай учиться дальше.

>>865344

У них своеобразное понимание MVC. В той же Симфони папки Model нет так как к модели там относится почти все, кроме вью и контроллеров.

>>865364

Наверно pug-cli его как-то вызывает или использует?

>>865424

Ты уверен, что не работает? Сдампь содержимое массива до и после array_push и покажи, что после добавления массив остается точно таким же. Я думаю, причина в чем-то другом.

>>865574

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


> А зачем?


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

>>865574

> Лучше всё вручную передавать?


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

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

>>865628

>Все url'ы рабочие


Это они сейчас рабочие, а если ты завтра добавишь УРЛ вроде /student/123/profile то перестанут работать. Лучше бы использовать УРЛ от корня сайта, вроде '/register' вместо относительных 'register'.

> Звучит прикольно, но как это реализовать? Погуглил, суть ясна, но сложно представляю с чего начать.



=== для объектов проверяет, это один и тот же объект или разные.

Некоторые ORM, например, Doctrine, умеют автоматически искать и сохранять в базу изменения в ранее загруженных объектах. Эти же ORM гарантируют что одной записи в БД всегда соответствует один и тот же объект - если 2 раза запросить из базы одного и того же пользоватля, то во второй раз обращения к БД не будет, а будет возвращен ранее загруженный объект. Если бы это правило не соблюдалось, и записи могли бы соответствовать 2 разных объекта, то было бы непонятно, в каком из них актуальные данные.
#232 #870459
>>865628

> Звучит прикольно, но как это реализовать?


Это паттерн Identity Map. Тебе придется сделать класс, хранящий ранее загруженные сущности и настроить его взаимодействие с Data Mapper. Не уверен, что стоит с этим заморачиваться в простом приложении, проще взять доктрину, которая уже умеет это делать.

В доктрине Identity Map - это массив внутри класса UnitOfWork: https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L100
#233 #870547
Вкатываюсь в тред, чтобы отписаться о своей стори. Гуманитарий, 25-лвл. В начале года усиленно занимался по учебнику ОПа, старательно проходя все задания (был уровень нуль нулём). Почти доделал студентов, активно писал в тредах и буквально жил тут у вас.

Потом как-то забил на довольно-таки долгое время(проблемы ИРЛ), не трогал пограминг до начала сентября почти. Вот пару месяцев назад вновь вспомнил и попытался восстановить в памяти всё. Довольно трудно было, но всё же мне это удалось. Начал искать работку, на удивление, ОПовский учебник мне охуенно помог(рили, прям всё-всё оттуда) и уже через пару собеседований мне перезвонили из одной конторы и вот уже полтора месяца я джуниор php-программист с окладом в 40 деревянных для ДС мало, но всё же.

На работе пишем на php(правда без ООП почти) + js(jquery) + css/html ну и на битриксе, как я понял, он оче у нас в рф популярен

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

так что, корзинки, не теряйте надежд, забейте на возраст и вышку, и желательно не брать перерывов, а сразу идти искать работу, даже до студентов
#234 #870550
>>870547

>а сразу идти искать работу, даже до студентов


всё хуйня, работаю больше 2х лет, зп 30к

тот кто не может в кодинг не сможет норм зарабатывать даже после всех учебников
>>870565
#235 #870565
>>870550

>работаю больше 2х лет, зп 30к


Какой город, чем конкретно занимаетесь на работе? Почему не растёшь?
>>870567
#236 #870567
>>870565
тольятти, багофикс и написание фичей для огромного интерпрайс фраемворка

>Почему не растёшь?


>>870408
>>870669
#237 #870583
>>870547
Я в 21 лвл на последнем укурсе пошёл работать, брали везде, толком нихуя не знал.
Отработал в 3ёх конторах по неделе, не выдерживал из-за социофобии. Сейчас уже почти год сижу дома, хуй знает что делать.
Реален хоть какой-т офриланс для программиста? Куда деваться? Батя предлагает лечь в больничку навсегда
>>870587>>870658
#238 #870587
>>870583
ты блять еблан какой-то

какая социофобия если ты в вузе был.
иди к психотерапевту, ложись в больницу. даун пиздец я ебал
>>870590
#239 #870590
>>870587
Социофобия начала развиваться на 3-4 курсе, тогда я ещё мог себя хоть как-то контролировать и терпеть. Потом уже контроль был утрачен практически полностью.
Побороть я не смог. Работать в обществе не могу. В больничку тоже не хочу.
>>870592
#240 #870592
>>870590

>не хочу


а кто диагноз поставил?
>>870601
#241 #870601
>>870592
Первый раз психиатр в военкомате, второй раз в районной больнице. Диагноз там из 3ёх вещей состоит - социофобия, на её фоне какая-то там депрессия развилась плюс ещё подозрение на какое-то там расстройство. Я это точно не помню.
Ну и само собой. когда у тебя едет крыша, то как-то сложно это не заметить. Даже некоторые шизофреники понимают. что они больные.
>>870641
#242 #870603
>>870408

>жава-интерпрайс


>сложный фреймворк


Охуеть теперь. Ты в AbstractEntityDao не въехал или в AbstractCrudService?
#243 #870641
>>870601
как можно не хотеть вылечится то?
вот болит у тебя зуб - ты же не сидишь дома подыхая - ты идёшь и лечишь.

а тут год сидеть дома? нахуя? родители твои куда смотрят? ты же жизнь проёбываешь свою. год без работы - тебя уже и не примут работать никуда, ты же всё забыл с вуза
>>870658
#244 #870642
Друзья, помогите. Срочно по работе приспичило написать веб-сервис, пхп изучаю параллельно.
Встала проблема. Есть одна страница, на ней таблица, где есть поле "количество" и кнопки - и +. Пользователь по ним жмакает, кол-во меняется. Сделал на jquery, все отлично. Теперь мне надо на этой странице жмакнуть на кнопку "сгенерачить" и открыть таким образом другую страницу, где я выведу то, что там наотмечал пользователь. Как собрать инфу со страницы и собрать в массив, я понял. Как передать массив? json или не json? Или как-то по-другому? Еще не догоняю немного про get и post. Я хочу в итоге получать короткую ссылку вида site.ru/ier234kj или site.ru/dks0992ww в зависимости от того, что там в массиве, чтобы сгенераченной страницей можно было поделиться с товарищем, а не заставлять его тыкать те же плюсики-минусики. Это значит, мне нужно передавать через get? Там вроде ограничение на кол-во данных, а у меня большой массив.
>>870658
#245 #870658
>>870642

Надо сделать обычную форму и отправлять данные методом POST, после успешной обработки которых можно редиректить на короткую ссылку. Читай урок про формы https://github.com/codedokode/pasta/blob/master/forms.md

>>870641

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

>>870583

Реален, почему нет.

>>870547

Не останавливайся в развитии, изучай ООП, фреймворки. Иначе тебя отправят на свалку как только Битрикс потеряет популярность.
>>870659>>870665
#246 #870659
>>870658

>Мозги вправлять пока не научились


манямир
#247 #870665
>>870658

>Реален, почему нет.


На чём сделать упор? Какие самые распространённые днищезадания на фрилансе?
>>870667
#248 #870667
>>870665

Зайди на фриланс-сайты и проанализируй. Но лучше поискать на сайтах поиска работу, на которой можно работать удаленно. на фрилансе ты будешь половину времени тратить на поиск и переговоры с заказчиками, и это время никто не оплатит.
#249 #870669
>>870567
я думал ты спрашиваешь чтобы помочь чем-то((((
7 Кб, 184x184
#250 #870758

> пикча


> $VAR_DUMP


Ору
#251 #870799
Не могу сделать задачу со школьником и айфоном. Не могу понять последовательность, куда проверку сувать и что с чем проверять.
>>870875>>872220
#252 #870803
>>853691

>5) Напиши на php простой echo-сервер, который слушает порт, принимает соединение и отсылает каждую принятую строчку обратно.


Как-то так http://ideone.com/UgSyOM

>6) Напиши простой HTTP-клиент на php, скачивающий файл по указанной ссылке


Не уверен, что я правильно понял задание http://ideone.com/rkE6MM
>>870861>>872220
#253 #870858
Я тут начал делать студентов. В принципе все понятно, только не знаю как реализовать архитектуру по людски. А именно, как правильно распределять контроллеры? Вот тут короче решил проблема максимально просто, но как по мне тупо. Есть .htacces который перенаправляет все на индекс.пхп в корне сайта. В нем этот код http://ideone.com/dSXrX3 т.е. если есть кука включается главный контроллер(в нем список студентов), если нет - идет форма регистрации и кука устнавливается. Так же не следует делать, да?
#254 #870861
>>870803
и http Сервер в догонку
http://ideone.com/laepMn
>>870870>>872220
sage #255 #870870
>>870861
Странные ты штуки пишешь на пхп. Для таких вот вещей существует хотя бы го.
#256 #870875
>>870799
Ссылку на идеоне, где пробовал, давай.
>>870972
#257 #870882
>>870870
Для каких? Я же не собираюсь этот хттп сервер использовать где-то, просто в целях ознакомления написал. А вообще хотелось бы какой-нибудь десктопный язык знать несложный, чтобы можно было какие-нибудь штуки полезные для ОС писать, я вот подумываю о Питоне.
>>870894>>872220
#258 #870893
http://ideone.com/9rWhLN

что скажите про этот код в контексте уместности? Вообще не понимаю как мне преодолеть пропасть от "я выучил ООП-примитивы и понятия" до "я уверенно пишу на ООП и знаю что где к месту"?
>>871369>>872217
sage #259 #870894
>>870882

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


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

>я вот подумываю о Питоне


Скриптопараша.
>>870897
#260 #870896
>>870870
Гуглоподелка же, загнётся лет через 5, как вообще всё что гугл делал.
>>870903
#261 #870897
>>870894

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


Ну так мне и удобнее на пхп работать.

>Скриптопараша.


Поясни. И что не скриптопараша? inb4: GO
#262 #870903
>>870896
Ты прав. Давай всё писать на яве.
мимоявист
>>871281
#263 #870925
Аноны, как вы определяете семейство шрифтов?

Вот есть семейство шрифт Open Sans, который я скачал с Google Fonts, и в архиве находятся шрифты OpenSans-Regular\Bold\Italic\etc. Как определить через @font-face __всё__ семейство?

@font-face {
font-family: "Open Sans";
src: url(Open_Sans/OpenSans-Regular.ttf) format("ttf");
font-weight: normal;
font-style: normal;
}

А дальше что? Каждый шрифт нужно так прописать?
>>872220
#264 #870972
>>870875
Вот, внимательно прочитал обьяснение под спойлером.
http://ideone.com/sx9xHt
>>872219>>872220
Slack канал #265 #870991
Сделал Slack канал дабы тут не разводился срачи , призываю всех анонов , скидывайте свои фейк мыльцо суда 2chph7FLpANUSmaiQwplinatorPUNCTUMc)A>om дам инвайт
>>870992>>872219
#266 #870992
>>870991
уже есть конфа нахуя плодить
вообещ бесит, раньше все в треде сидели, тепер ьвсе по конфам и другим разделам разбежались
#267 #870993
>>870992
ок дай ссылку пожалуйста )
>>870996
#268 #870996
>>870993
там мертво всё равно, ссылка в жс треде в оппосте
общая конференция /пр с разделами
#269 #871005
>>870992

>уже есть конфа нахуя плодить


А этим дебилам лишь бы конфу создать. Я такое не только здесь наблюдаю.
>>871011
#270 #871011
>>871005
>>870992
всё просто, дети мои
все эти конфы - неудобная моча
и каждый пилит там где ему удобнее

предлагаю здешним долбоёбам запилить свою эталонную конфу для всего двача

есть_14_стандартов.пнг
#271 #871028
http://ideone.com/UbxHCW

Как улучшить код?
>>871107>>872219
#272 #871107
>>871028
Удалить хеллоуворлд и написать что-нибудь полезное.
#273 #871145
Кажется, до меня доходит, почему в npm так много пакетов.
preg_quote в JS нет (!), свопнуть ключи и значения ассоциативного массива нельзя (array_flip в PHP), нельзя заменить в строке символы, используя карту (strtr в PHP). Нельзя из коробки, нужно велосипедить/копипастить/тыкать npm install.
Или у меня PHP головного мозга?
>>871158
#274 #871158
>>871145

>Кажется, до меня доходит, почему в npm так много пакетов.


Только потому что там пакеты создают ради функций уровня isObject и isNull.
>>872219
Назырбек Абрамович #275 #871181
Сап, двачеры.
Кто из вас шарит в CodeIgniter?
Нужны маны, для средняка (обучил тока модели, лэйаут и работа с mariadb).
>>872219
#276 #871206
>>870858
Рассудите меня позязь
#277 #871212
>>870858
ах ты ебанный шакал
#278 #871281
>>870903
У меня для тебя плохие новости. Ява умерла 2 года назад. Её главная фича была в кросплатвформенности, а она как раз и отвалилась в 2014. А если нет кросплатформенностиЮ то и ява ненужна.
>>871284
300 Кб, 1600x1096
#279 #871284
>>871281
блять чо несёт...
>>871287
#280 #871287
>>871284
Какой ты соня, тебя даже вчерашний шторм не разбудил. Всех подзадолбало что Оракл подаёт в суд на всё что движется и уже два года как все отказываются от Java. Эпл так вообще по дефолту 1.6 поддерживает. Такие дела.
>>871290
#281 #871290
>>871287

>уже два года как все отказываются от Java


ммм, ну если тебе в интернете так сказали...
>>871296>>871303
#282 #871296
>>871290
Оракл даже в гугл на андроид подали, что там всё на джаве.

Мимо
>>871300
#283 #871300
>>871296
эх, щас бы от пхп-обезьян услышать о том что жава умирает...
>>871307
#284 #871303
>>871290
2010 год
https://habrahabr.ru/post/106963/
Напомню что с тех пор у них ObjectiveC а теперь и Swift
https://tproger.ru/news/oracle-seeks-93-billion-for-googles-use-of-java-in-android/
Тут вообще пушка, 9 миллиардов на ровном месте хотят отсудить.
#285 #871307
>>871300
Ты бы ещё сказал что Delphi не помирает, лол. Очнись, большинство разрабов на жабе были только плагодаря андройду. Который судя по всему перекатится на какой-нибудь Go.
>>871312>>871377
10 Кб, 945x334
#286 #871312
>>871307

>2010


>Это последний гвоздь в гроб Java



>2016


>пикрилатед



эх, щас бы пхп-обезьянам объяснить что они обосрались
>>871315>>871320
#287 #871315
>>871312
Мы ведём дискуссию в разных плоскостях, а ты даже этого не понимаешь. Не вижу больше смысла продолжать с тобой разговор.
>>871319
#288 #871319
>>871315
Ох уж эти любители хоронить яву. Сливаются одними и теми же фразами уже десять лет.
>>871326
#289 #871320
>>871312
А чё за скрин, откуда?
#290 #871321
>>869226

>Только она не может в кириллические домены.


А где-то в природе существуют киррилические мэйлы?
>>871324>>872219
#291 #871324
>>871321
К сожалению да. Правда у них у всех есть не очень осмысленная версия латиницей.
#292 #871325
http://githut.info/
Просто оставлю это здесь.
>>871333
#293 #871326
>>871319
да все знают с явы так быстро не соскочить , даже если гугл откажется от ведра , ява будет в интерпрайзе , суть в том что , среднему и малому бизнесу ява не нужна ибо жрёт рам как не в себя
>>871329
#294 #871329
>>871326
да все знают с делфи так быстро не соскочить , даже если Борланд откажется от Delphi7, Delphi будет в интерпрайзе , суть в том что , среднему и малому бизнесу Delphi не нужна ибо жрёт рам как не в себя
ой, сейчас вроде ведь не 2007 год.
>>871333
#295 #871333
>>871325
В общем-то ничего удивительного. У JS нет альтернативе в веб фронтенде, да и кодеров на нем благодаря простоте побольше. А ява как жрала свой энтерпрайс, так и жрет.

>>871329

>ой, сейчас вроде ведь не 2007 год.


Ну как, вы же и в 2007 яву хоронили. А уже без пяти минут 2017. Подумай на досуге, почему ява успешна и какие у неё альтернативы.
>>871334
#296 #871334
>>871333
Ну так и в 2007 про делфи все говорили что непомрёт.

>почему ява успешна


Кросплатформенность во все поля. И маниакальные желания джава разрабов переписать всё на Java.

>какие у неё альтернативы.


С\ С++ сейчас они даже двигают в сторону веба.

>вы же и в 2007 яву хоронили.


Тогда это был язык для аплетов под банк клиенты. Алсо это были последние годы Sun, до того как их купили оракловцы. И все предрекали смерть именно поэтому.
#297 #871338
Начал сейчас читать про анонимные функции и постоянно слышу какие-то восхищения о том что "Наконец-то они появились в PHP, так долго ждали, так долго хотели и вот, новые возможности!!!". И как-то я вообще не понимаю в чём профит то? Ну вот была у нас классическая функция, теперь у нас тоже самое, только с немного другим вызовом. А посему вопрос. Хоть кто-ниюудь на практике сталкивался именно с использованием анонимной функции? Не для того чтобы её использовать, а чтобы что-то сделать, без чего не обойтись.
>>871344
#298 #871342
>>870870

Оп сейчас пишет небольшую утилиту на Го и там много неудачных решений. Отовсюду лезут сишные корни, указатели, нет классов, нет коллекций, нет даже функции вроде in_array, и попробуй найти, как в Го сделать exec (подсказываю: правильный ответ сильно зависит от версии Го, в той что в дебиане, придется вручную побайтово упаковывать параметры для сисколла execve) или fork (fork в Го делать нельзя).

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

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

Нет генериков. Хочешь автоматически разбирать параметры конфига и командной строки разных типов - обращайся к рефлекшену с runtime panic.

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

В моей утилите 80% кода занимает именно разбор аргументов и конфига, и только 20% - код, ради которого она писалась (несколько системных вызовов и libseccomp).

Мне кажется, восторженные отзывы про Го пишут либо те, кто в нем только не разобрался, либо те, кто другие языки не видел.
>>871402
#299 #871343
>>870870

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

Нет пакетного менеджера, и дурацкая схема организации папок по умолчанию.
>>871637
#300 #871344
>>871338

Изучи функции usort, array_map, array_filter - там они полезны. Ну например в сортировке функция-компаратор определяет порядок сортировки. Или можно написать функцию, которая из списка объектов отбирает часть по заданному в анонимной функции критерию.
>>871345
#301 #871345
>>871344

>например в сортировке функция-компаратор определяет порядок сортировки.


А рекурсивный вызов функции из тела функции тут непоможет? Или почему тут именно анонимная нужна?
>>871348
#302 #871348
>>871345

Посмотри мануал по usort. Попробуй сделать пример с ее использованием. Рекурсия здесь вообще не при чем.
>>871350
#303 #871350
>>871348
Спасибо няша, так и сделаю.
#304 #871369
>>870893
Бамп, хоть кто-нибудь может высказаться?
>>872217
#305 #871377
>>871307

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


>Не вижу больше смысла продолжать с тобой разговор.



>пруфаю рейтингом умирающего языка


>КОКОКО


>Не вижу больше смысла продолжать с тобой разговор.

#306 #871380
>>871377

>пруфаю рейтингом умирающего языка


Это не рейтинг языка, прочитай описание.
>>871381>>872217
#307 #871381
>>871380

>The TIOBE Programming Community index is an indicator of the popularity of programming languages


так и представляю что ты такой ОЙ, Я БЫЛ НЕ ПРАВ

хотя нет, я же на дваче в пхп-треде
>>871384
#308 #871383
>>871377

>Google судится с Oracle по поводу Java


>Apple отказались от Java



>Я покажу что на рынке очень много Java программистов это значит язык востребован



Тоесть ты даже непонимаешь где обосрался?
#309 #871384
>>871381
А теперь такой идёшь, и читаешь описание к графику.
229 Кб, 612x465
Satosi #310 #871390
>>864640 (OP)
Привет. Разбираю ответы опа, исправляю старый код. Не знаю как тут принято выкладывать исправления, но в общем так вот.

Игра в кости

> elseif ($sumManThrow = $sumAIThrow) {


>тут можно было не писать условие, а просто написать else.


Исправлено.
http://ideone.com/hs55ma

Миллион в банке

> $starterMoney+($starterMoney(10/100));


>Тут вместо числа 10 стоило использовать переменную $percent.


Исправлено
http://ideone.com/ujbtNY

Школьник и кредит на айфон

>Вообще, тут переменная $oversum лишняя и ее можно убрать. Также, хорошо бы избавиться от if/else где почти 2 одинаковых копии кода.


Сделал предварительный обсчёт $oversum и убрал всё что обсчитывалось в ней из if\else
Дальше не понимаю как улучшать.
Исправил
http://ideone.com/p494L2

Ответ на любой вопрос

> $random=array_rand ($answers, 2);


> не очень понятно, зачем брать 2 случайных ответа, но работает в общем верно.


Исправил
http://ideone.com/oKdt3x

Шифр

>Верно, хотя у тебя при расшифровке точка превращается в твердый знак.


Да я как-бы почти срзу сделал вот так. Надеюсь это считается как правильное решение тоже.
http://ideone.com/nZQDpf

Лев Толстой

>Вот тут не очень удачно: $rndWord1=mt_rand(0,3); - надо вручную считать число слов в массиве и пересчитывать при изменении. Лучше без этого.


>Также, тут можно было сделать массив вариантов и пройтись по нему циклом:



>$structure = [$word1, $word2, $word3, ["\n"], ...];


Ох... надеюсь я тебя правильно понял
http://ideone.com/PWMgWZ

Айпады.
Тут была куча недочётов то именования переменных, до неправильного подсчёта. Тот случай когда у себя поправил, а выложить забыл.
http://ideone.com/7Hc2oC

Задача на автономера.

> (А|В|Е|К|М|Н|О|Р|С|Т|У|Х)


>Удобнее использовать тут символьные классы: [АВЕКМНО...]


Вообще не догадывался что так можно, спасибо!

> for ($i=0;$i<$arCount;$i++){


>тут лучше foreach


Исправил.
http://ideone.com/fMXK7v

Спасибо тебе ОП, за твои уроки. Я и сам уже начал понемного понимать как и где что улучшить в старом коде, ты лучший!
229 Кб, 612x465
Satosi #310 #871390
>>864640 (OP)
Привет. Разбираю ответы опа, исправляю старый код. Не знаю как тут принято выкладывать исправления, но в общем так вот.

Игра в кости

> elseif ($sumManThrow = $sumAIThrow) {


>тут можно было не писать условие, а просто написать else.


Исправлено.
http://ideone.com/hs55ma

Миллион в банке

> $starterMoney+($starterMoney(10/100));


>Тут вместо числа 10 стоило использовать переменную $percent.


Исправлено
http://ideone.com/ujbtNY

Школьник и кредит на айфон

>Вообще, тут переменная $oversum лишняя и ее можно убрать. Также, хорошо бы избавиться от if/else где почти 2 одинаковых копии кода.


Сделал предварительный обсчёт $oversum и убрал всё что обсчитывалось в ней из if\else
Дальше не понимаю как улучшать.
Исправил
http://ideone.com/p494L2

Ответ на любой вопрос

> $random=array_rand ($answers, 2);


> не очень понятно, зачем брать 2 случайных ответа, но работает в общем верно.


Исправил
http://ideone.com/oKdt3x

Шифр

>Верно, хотя у тебя при расшифровке точка превращается в твердый знак.


Да я как-бы почти срзу сделал вот так. Надеюсь это считается как правильное решение тоже.
http://ideone.com/nZQDpf

Лев Толстой

>Вот тут не очень удачно: $rndWord1=mt_rand(0,3); - надо вручную считать число слов в массиве и пересчитывать при изменении. Лучше без этого.


>Также, тут можно было сделать массив вариантов и пройтись по нему циклом:



>$structure = [$word1, $word2, $word3, ["\n"], ...];


Ох... надеюсь я тебя правильно понял
http://ideone.com/PWMgWZ

Айпады.
Тут была куча недочётов то именования переменных, до неправильного подсчёта. Тот случай когда у себя поправил, а выложить забыл.
http://ideone.com/7Hc2oC

Задача на автономера.

> (А|В|Е|К|М|Н|О|Р|С|Т|У|Х)


>Удобнее использовать тут символьные классы: [АВЕКМНО...]


Вообще не догадывался что так можно, спасибо!

> for ($i=0;$i<$arCount;$i++){


>тут лучше foreach


Исправил.
http://ideone.com/fMXK7v

Спасибо тебе ОП, за твои уроки. Я и сам уже начал понемного понимать как и где что улучшить в старом коде, ты лучший!
>>872165
#311 #871402
>>871342

>Отовсюду лезут сишные корни


Ну ты неверно рассматриваешь го. Это же и есть сишка, только чуть захипстованная. Ты же не жалуешься на отсутствие вменяемого мультитретинга в пхп. Вот и там не нужны эти ваши дженерики (хоть и хочется).
>>871506
#312 #871506
>>871402

>Ты же не жалуешься на отсутствие вменяемого мультитретинга в пхп


Я вот жалуюсь что на PHP нет вменяемого 3d рендерера.
#313 #871598
Приветствую.
Хотел задать несколько вопросов. По большей части про css, вы же не против?
Первое. Как выровнять основное содержимое сайта по центру, без задания фиксированной ширины страницы, например, когда задаешь значение в процентах.
Второе. Как можно полностью убрать элемент со страницы? Не спрятать его, а именно чтобы его не было
Спасибо.
#314 #871619
>>871598
http://codepen.io/anon/pen/JbogNo
margin слева и справа;
display: none, чтобы спрятать обьект и занимать им место.
>>871829
#315 #871637
>>871343

> Нет пакетного менеджера


Гугли glide, мне хватает.

> И еще нет никакой логики в организации кода.


За этим сам следи. Вообще странно на это жаловаться в треде php.
>>872095
#316 #871688
Зачем нужны магические методы __get и __set, ведь если их определить, то по сути свойства станут публичными – какой смысл в их private? И не проще ли тогда их сразу как public объявить?
#317 #871733
>>871688
Ты мало видимо читал их. Они нужны что бы тебе не динамически всякую хуиту не прописывали в объекты, если ты того не хочешь. Или если хочешь, но так что бы это все управляемо было.
110 Кб, 612x813
108 Кб, 598x849
135 Кб, 592x773
115 Кб, 593x814
#318 #871819
Вместо бессмысленных объяснений...
У меня после прочтения в голове лишь щелкнуло в своё время что-то в духе: так вот оно как! Буду знать.
>>871890
128 Кб, 618x813
113 Кб, 645x742
#319 #871823
>>871890
#320 #871829
>>871619
>>871598

visibility: hidden - что бы спрятать объект и занимать им место,

>display: none


что бы убрать совсем
>>872136
sage #321 #871884
>>871688
Это просто синтакический сахар.
Представь что у тебя 10 приватных методов, каждому из них нужен геттер и сеттрер. У тебя будет 20 методов в класе, ололо.

А эти меджик методы автоматически их за тебя создают.
>>872708
#322 #871890
>>871819
>>871823
Откуда, из какой книги? На О'Рейли похоже.
>>871914
#323 #871911
Скорее всего Мэт Занстра.
>>871914
#324 #871914
#325 #872039
>>871688

> И не проще ли тогда их сразу как public объявить?


Нет, а если я хочу проверять, что свойству в качестве значения выставляется именно строка, а не число? Публичному полю можно присвоить всё, что угодно. В сеттере же можно делать проверки/валидацию.
#326 #872042
Что делать если при запуске скрипта из консоли он выдает синтакс эрор?

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

Через веб приложение работает, а вот через консоль и кроном соответственно некоторый функционал не хочет вызываться, падая вот так.
>>872089
#327 #872043
>>864640 (OP)
Ребятки! А возможно ли в регулярное выражение засунуть переменную? Вот допустим есть у меня функция, я в эту функцию передаю переменную:
$str = 'ня',
и я хочу найти все слова содержащие "ня". как написать регулярное выражение тогда?
"/w($key)w/u" не работает.
#328 #872046
>>872043
'/w($str)w/u' конечно же
>>872080
https://github.com/never3ver/studentslist #329 #872056
>>867362
>>862816

https://github.com/never3ver/students_list

Тут в посте была пара комментариев, может ты не видел: >>867397

Код из autoload.php возможно стоит включить прямо в init.php, а то у нас тут 2 инициализационных файла получается.

https://github.com/never3ver/students_list/blob/master/public/regedit.php#L32

> if ($authorizer->isStudentInDatabase()) {


Тут наверно логичнее было поставить проверку, что у student есть id, если есть то надо делать UPDATE. Но это впрочем мелочь.

https://github.com/never3ver/students_list/blob/master/public/regedit.php#L37

> $authorizer->SignIn($student);


> $gateway->addStudent($student);


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

https://github.com/never3ver/students_list/blob/master/app/StudentValidator.php#L20
Это выражение пропустит больше 5 символов.

https://github.com/never3ver/students_list/blob/master/app/StudentValidator.php#L20

> а-яА-ЯЁ


Почему-то маленькая ё не разрешена.

> filter_var($student->email, FILTER_VALIDATE_EMAIL)


Имей в виду, что он не пропускает кириллические домены вроде ik:3vanANUSприL("мерPUNCTUMрdPHф

> preg_match("/^(19|20)[0-9]{2}/


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

> if ($result > 0) {


> return FALSE;


Проще писать return $result == 0; (меньше нуля результат COUNT быть не может)

https://github.com/never3ver/students_list/blob/master/templates/editForm.html#L90
Тут у радиокнопки local всегда стоит checked, даже если в $student local == NOT_LOCAL

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

В форме поиска можно было бы использовать required

https://github.com/never3ver/students_list/blob/master/templates/parts/pagination.html
Тут логику выбора номеров страниц и генерацию ссылок можно было бы переложить на класс Pager, а в шаблоне оставить только их вывод.

> редактировать мои/ваши данные


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

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

Нет надписи "показаны результаты поиска по слову...". При поиске введенное слово не отображается в поле ввода после отправки формы.

Баг с вводом года 1900 так и не исправлен.

В общем, надо поработать на багами. Когда будешь сдавать на проверку, напомни, что у тебя все почти готово и все замечания исправлены.
https://github.com/never3ver/studentslist #329 #872056
>>867362
>>862816

https://github.com/never3ver/students_list

Тут в посте была пара комментариев, может ты не видел: >>867397

Код из autoload.php возможно стоит включить прямо в init.php, а то у нас тут 2 инициализационных файла получается.

https://github.com/never3ver/students_list/blob/master/public/regedit.php#L32

> if ($authorizer->isStudentInDatabase()) {


Тут наверно логичнее было поставить проверку, что у student есть id, если есть то надо делать UPDATE. Но это впрочем мелочь.

https://github.com/never3ver/students_list/blob/master/public/regedit.php#L37

> $authorizer->SignIn($student);


> $gateway->addStudent($student);


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

https://github.com/never3ver/students_list/blob/master/app/StudentValidator.php#L20
Это выражение пропустит больше 5 символов.

https://github.com/never3ver/students_list/blob/master/app/StudentValidator.php#L20

> а-яА-ЯЁ


Почему-то маленькая ё не разрешена.

> filter_var($student->email, FILTER_VALIDATE_EMAIL)


Имей в виду, что он не пропускает кириллические домены вроде ik:3vanANUSприL("мерPUNCTUMрdPHф

> preg_match("/^(19|20)[0-9]{2}/


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

> if ($result > 0) {


> return FALSE;


Проще писать return $result == 0; (меньше нуля результат COUNT быть не может)

https://github.com/never3ver/students_list/blob/master/templates/editForm.html#L90
Тут у радиокнопки local всегда стоит checked, даже если в $student local == NOT_LOCAL

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

В форме поиска можно было бы использовать required

https://github.com/never3ver/students_list/blob/master/templates/parts/pagination.html
Тут логику выбора номеров страниц и генерацию ссылок можно было бы переложить на класс Pager, а в шаблоне оставить только их вывод.

> редактировать мои/ваши данные


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

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

Нет надписи "показаны результаты поиска по слову...". При поиске введенное слово не отображается в поле ввода после отправки формы.

Баг с вводом года 1900 так и не исправлен.

В общем, надо поработать на багами. Когда будешь сдавать на проверку, напомни, что у тебя все почти готово и все замечания исправлены.
>>873486
#330 #872080
>>872043
>>872046
Вопрос снимается. Разобрался
https://github.com/ghp26/Students/ #331 #872086
>>867390
>>863496

https://github.com/ghp26/Students/

Ты пока ничего не ответил на пост >>867398

По коду:

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

> https://github.com/ghp26/Students/blob/master/dump.sql


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

> enum('муж','жен')


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

> `birth` date


Там ведь вроде только год нужен был, или ты дату вводишь?

> `hash` varchar(100) NOT NULL,


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

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

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

> https://github.com/ghp26/Students/blob/master/public/search.php#L8


> $_POST['searchValue']


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

Также, надо понимать, что любые внешние переменные могут отстуствовать. Стоит проверять, что d POST есть элемент searchValue, прежде чем обращаться к нему.

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

> https://github.com/ghp26/Students/blob/master/public/register.php#L4


> //include "src/DBGateway.php"; инклудиться в валидаторе


Вот это верный путь сделать ошибку. Завтра кто-нибудь уберет инклюд из валидатора, и код перестанет работать. Лучше использовать require_once, который подключает файл только 1 раз. А еще лучше - автозагрузку.

Далее, в этом файле https://github.com/ghp26/Students/blob/master/public/register.php у тебя кроме обработки формы идет низкоуровневая возня с куками. Лучше выделить код в отдельный класс, отвечающий за авторизацию, а в контроллере только вызывать методы вроде "получить текущего пользователя", "залогинить пользователя" и тд.

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

> $_POST[email]


Строку надо писать в кавычках.

> if (!$_COOKIE["MuhosranskUniversity"]) {


Название куки должно отражать ее назначение.

> header("location: index.php");


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

В register.php у тебя 3 вызова $displayer. Получается слишком запутанная логика и легко пропустить какую-то ветку и ничего не вывести. Предлагаю упростить код, оставив единственный вызов внизу файла.

В шаблоне шапка и подвал страницы (<head>) скопипащена в оба файла. Не надо копипастить, надо вынести ее в отдельный файл.

https://github.com/ghp26/Students/blob/master/public/tpl/profile.html#L63

> <input name="local" type="radio" value="Местный" checked> Местный


Тут почему-то checked стоит всегда, независимо от значения в переменной local.

https://github.com/ghp26/Students/blob/master/src/Displayer.php#L5
Тут лучше применить Dependency Injection ( https://github.com/codedokode/pasta/blob/master/arch/di.md ), то есть передавать объект твига через конструктор. задача Displayer ведь отображать страницу, а не искать, где расположен твиг.

Для подключения твига не надо вручную делать require, достаточно где-то в начале скрипта приинклудить vendor/autoload.php и все библиотеки из композера будут подключаться сами.

https://github.com/ghp26/Students/blob/master/src/Displayer.php#L22
View в MVC не должен работать с куками, это задача контроллера. Ты нарушаешь правило разделения кода на отдельные части.

Смысл класса Displayer не очень понятен. Не проще ли из контроллера сразу вызывать твиг?

> https://github.com/ghp26/Students/blob/master/src/Displayer.php#L46


> 'name' => $profileData['name'],


> 'surname' => $profileData['surname'],


> 'sex' => $profileData['sex'],


Удобнее не передавать поля по одному, а передать весь массив. А еще правильнее использовать ООП, и передавать модель Abiturient.

> foreach ($errorsArray as $key => $value) {//в $errorsArray будет единственное значение


> $errorKey = $key;


> $errorMessage = $value;


> }


Не очень понятен смысл этого действия. Чтобы взять последний элемент, кстати, можно сделать $value = end($array); $key = key($array), почитай мануал по этим функциям.

> print_r($errorKey);


забыл отладочный код

https://github.com/ghp26/Students/blob/master/src/Abiturient.php#L15

> public function __construct($values)


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

https://github.com/ghp26/Students/blob/master/src/DBGateway.php
Если ты захочешь создать еще одну-две таблицы, ты будешь код работы с ними тоже писать в этот класс? Обычно для каждой таблицы делают свой Gateway и соответственно отражают это в названии класса.

Объект PDO лучше передавать с использованием DI.

https://github.com/ghp26/Students/blob/master/src/DBGateway.php#L29

> require_once "Abiturient.php";


Все require должны быть в начале файла, а не раскиданы по коду, а еще лучше настроить автозагрузку.

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

https://github.com/ghp26/Students/blob/master/src/DBGateway.php#L50
Тут лишний prepare()

https://github.com/ghp26/Students/blob/master/src/DBGateway.php#L69
Почему-то тут возвращается null, а не false.

https://github.com/ghp26/Students/blob/master/src/Validator.php
Класс правильнее назвать AbiturientValidator.

https://github.com/ghp26/Students/blob/master/src/Validator.php#L14
Иф надо писать в 3 строчки, а не в одну длинную.

Вместо iconv_strlen можно использовать mb_strlen, а кодировку указать один раз в начале через mb_internal_encoding.

> А-Яа-я


ё в юникоде находится отдельно, не между буквами а и я и ее тоже надо указывать отдельно.

> А-Яа-я1-9


0 не разрешен?

Фамилии могут содержать пробел, например "фон Браун".

https://github.com/ghp26/Students/blob/master/src/Validator.php#L38
А для зарегистрированных студентов при редактировании уникальность емайл не проверяется?
https://github.com/ghp26/Students/ #331 #872086
>>867390
>>863496

https://github.com/ghp26/Students/

Ты пока ничего не ответил на пост >>867398

По коду:

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

> https://github.com/ghp26/Students/blob/master/dump.sql


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

> enum('муж','жен')


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

> `birth` date


Там ведь вроде только год нужен был, или ты дату вводишь?

> `hash` varchar(100) NOT NULL,


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

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

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

> https://github.com/ghp26/Students/blob/master/public/search.php#L8


> $_POST['searchValue']


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

Также, надо понимать, что любые внешние переменные могут отстуствовать. Стоит проверять, что d POST есть элемент searchValue, прежде чем обращаться к нему.

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

> https://github.com/ghp26/Students/blob/master/public/register.php#L4


> //include "src/DBGateway.php"; инклудиться в валидаторе


Вот это верный путь сделать ошибку. Завтра кто-нибудь уберет инклюд из валидатора, и код перестанет работать. Лучше использовать require_once, который подключает файл только 1 раз. А еще лучше - автозагрузку.

Далее, в этом файле https://github.com/ghp26/Students/blob/master/public/register.php у тебя кроме обработки формы идет низкоуровневая возня с куками. Лучше выделить код в отдельный класс, отвечающий за авторизацию, а в контроллере только вызывать методы вроде "получить текущего пользователя", "залогинить пользователя" и тд.

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

> $_POST[email]


Строку надо писать в кавычках.

> if (!$_COOKIE["MuhosranskUniversity"]) {


Название куки должно отражать ее назначение.

> header("location: index.php");


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

В register.php у тебя 3 вызова $displayer. Получается слишком запутанная логика и легко пропустить какую-то ветку и ничего не вывести. Предлагаю упростить код, оставив единственный вызов внизу файла.

В шаблоне шапка и подвал страницы (<head>) скопипащена в оба файла. Не надо копипастить, надо вынести ее в отдельный файл.

https://github.com/ghp26/Students/blob/master/public/tpl/profile.html#L63

> <input name="local" type="radio" value="Местный" checked> Местный


Тут почему-то checked стоит всегда, независимо от значения в переменной local.

https://github.com/ghp26/Students/blob/master/src/Displayer.php#L5
Тут лучше применить Dependency Injection ( https://github.com/codedokode/pasta/blob/master/arch/di.md ), то есть передавать объект твига через конструктор. задача Displayer ведь отображать страницу, а не искать, где расположен твиг.

Для подключения твига не надо вручную делать require, достаточно где-то в начале скрипта приинклудить vendor/autoload.php и все библиотеки из композера будут подключаться сами.

https://github.com/ghp26/Students/blob/master/src/Displayer.php#L22
View в MVC не должен работать с куками, это задача контроллера. Ты нарушаешь правило разделения кода на отдельные части.

Смысл класса Displayer не очень понятен. Не проще ли из контроллера сразу вызывать твиг?

> https://github.com/ghp26/Students/blob/master/src/Displayer.php#L46


> 'name' => $profileData['name'],


> 'surname' => $profileData['surname'],


> 'sex' => $profileData['sex'],


Удобнее не передавать поля по одному, а передать весь массив. А еще правильнее использовать ООП, и передавать модель Abiturient.

> foreach ($errorsArray as $key => $value) {//в $errorsArray будет единственное значение


> $errorKey = $key;


> $errorMessage = $value;


> }


Не очень понятен смысл этого действия. Чтобы взять последний элемент, кстати, можно сделать $value = end($array); $key = key($array), почитай мануал по этим функциям.

> print_r($errorKey);


забыл отладочный код

https://github.com/ghp26/Students/blob/master/src/Abiturient.php#L15

> public function __construct($values)


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

https://github.com/ghp26/Students/blob/master/src/DBGateway.php
Если ты захочешь создать еще одну-две таблицы, ты будешь код работы с ними тоже писать в этот класс? Обычно для каждой таблицы делают свой Gateway и соответственно отражают это в названии класса.

Объект PDO лучше передавать с использованием DI.

https://github.com/ghp26/Students/blob/master/src/DBGateway.php#L29

> require_once "Abiturient.php";


Все require должны быть в начале файла, а не раскиданы по коду, а еще лучше настроить автозагрузку.

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

https://github.com/ghp26/Students/blob/master/src/DBGateway.php#L50
Тут лишний prepare()

https://github.com/ghp26/Students/blob/master/src/DBGateway.php#L69
Почему-то тут возвращается null, а не false.

https://github.com/ghp26/Students/blob/master/src/Validator.php
Класс правильнее назвать AbiturientValidator.

https://github.com/ghp26/Students/blob/master/src/Validator.php#L14
Иф надо писать в 3 строчки, а не в одну длинную.

Вместо iconv_strlen можно использовать mb_strlen, а кодировку указать один раз в начале через mb_internal_encoding.

> А-Яа-я


ё в юникоде находится отдельно, не между буквами а и я и ее тоже надо указывать отдельно.

> А-Яа-я1-9


0 не разрешен?

Фамилии могут содержать пробел, например "фон Браун".

https://github.com/ghp26/Students/blob/master/src/Validator.php#L38
А для зарегистрированных студентов при редактировании уникальность емайл не проверяется?
#332 #872089
>>872043

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

>>872042

Надо найти и исправить ошибку. Там ведь номер строки написан наверно.

>>871688

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

Ну например можно сделать чтобы при обращении к $obj->name вызывался бы метод getName().

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

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

> Зачем нужны магические методы __get и __set, ведь если их определить, то по сути свойства станут публичными – какой смысл в их private?


Их можно использовать по-разному. Не только как ты написал. Или можно добавить какие-то проверки перед записью данных в свойство.
#333 #872095
>>871637

> Гугли glide, мне хватает.


Только там еще десяток есть. Где гарантия что в итоге все не пересядут на что-нибудь другое?

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

А встроенный go get просто скачивает пакет непонятно какой версии непонятно куда и непонятно как это интегрировать в обычный проект с гитхаба.

>> И еще нет никакой логики в организации кода.


> За этим сам следи. Вообще странно на это жаловаться в треде php


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

>>871598

Задать max-width и margin auto. Вообще, эта особенность блоков - это основы CSS, которые изучаются в самом начале. если ты это не знаешь, возможно тебе стоит подучить CSS и пройти наши задачки на CSS из ОП поста. Тогда верстка не будет для тебя представлять особой сложности.
>>872130>>872136
#334 #872130
>>872095

> Где гарантия что в итоге все не пересядут на что-нибудь другое?


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

> В пхп как раз с этим все в порядке: PSR-4, каждый класс в своем файле.


Счастливый человек. Я php начал с 4 ещё на поддержке проекта говнокодеров, вот это ад во плоти.

В целом хочу сказать что от го многого ждать не стоит, это не сильвер булет и во многом на php удобней писать средние и даже большие проекты. Но когда нужен маленький и быстрый сервис, с высокой отказоустойчивостью го почти нет равных.
>>872167
#335 #872136
>>871829
Все, понял в чем была проблема. Я просто не уточнил в начале, мне надо было эти параметры задать через @media и вышло так, что display: none не работал из-за того, что уже задан дисплей у блока, которому я хотел задать значение.
>>872095

>Задать max-width и margin auto


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

> возможно тебе стоит подучить CSS и пройти наши задачки на CSS из ОП поста


Спасибо, гляну что здесь у вас.
>>872167
#336 #872165
>>871390

> Игра в кости


> http://ideone.com/hs55ma


Все верно.

> Миллион в банке


Верно.

> Школьник и кредит на айфон


> $worthMoney = $worthMoney + $mounthlyPayment;


> echo $i . " платёж. Выплачено " . $worthMoney


> $worthMoney = $worthMoney + $oversum;


> echo "Последний " . $i . " платёж. Выплачено " . $worthMoney .


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

> } elseif ($oversum <= 5000) {


Можно просто else, условие не требуется.

> Ответ на любой вопрос


Верно.

> Шифр


О, хорошо сделано.

> Лев Толстой


> http://ideone.com/PWMgWZ


> if (is_array($someword) == true) {


Можно просто if (is_array($someword)) так как if по сути приводит значение в скобках к true или false и в зависимости от этого выбирает, выполнять ли код. Оператор == сам возвращает true/false и соответственно проверка вроде == true по сути возвращает то же самое значение. Смотри мануал http://php.net/manual/ru/language.types.boolean.php

Ты забыл еще букву "Я", но в остальном, решено верно.

> Айпады.



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

> } elseif ($debt < 0) {


> // echo "Что-то пошло не так.";


Ну так тут exit надо писать, если уверен что твой код правильный и это никогда не сработает.

> Задача на автономера.



> [АВЕКМНОРСТУХ]|[A-Z]


Это можно объединить в один символьный класс. Перечитай-ка мануал http://php.net/manual/ru/regexp.reference.character-classes.php

Слишком длинный номер считается почему-то верным: http://ideone.com/szMHz6
#336 #872165
>>871390

> Игра в кости


> http://ideone.com/hs55ma


Все верно.

> Миллион в банке


Верно.

> Школьник и кредит на айфон


> $worthMoney = $worthMoney + $mounthlyPayment;


> echo $i . " платёж. Выплачено " . $worthMoney


> $worthMoney = $worthMoney + $oversum;


> echo "Последний " . $i . " платёж. Выплачено " . $worthMoney .


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

> } elseif ($oversum <= 5000) {


Можно просто else, условие не требуется.

> Ответ на любой вопрос


Верно.

> Шифр


О, хорошо сделано.

> Лев Толстой


> http://ideone.com/PWMgWZ


> if (is_array($someword) == true) {


Можно просто if (is_array($someword)) так как if по сути приводит значение в скобках к true или false и в зависимости от этого выбирает, выполнять ли код. Оператор == сам возвращает true/false и соответственно проверка вроде == true по сути возвращает то же самое значение. Смотри мануал http://php.net/manual/ru/language.types.boolean.php

Ты забыл еще букву "Я", но в остальном, решено верно.

> Айпады.



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

> } elseif ($debt < 0) {


> // echo "Что-то пошло не так.";


Ну так тут exit надо писать, если уверен что твой код правильный и это никогда не сработает.

> Задача на автономера.



> [АВЕКМНОРСТУХ]|[A-Z]


Это можно объединить в один символьный класс. Перечитай-ка мануал http://php.net/manual/ru/regexp.reference.character-classes.php

Слишком длинный номер считается почему-то верным: http://ideone.com/szMHz6
>>872641
#337 #872167
>>872136

Центрирование блока через margin auto работает с шириной, заданной в любых единицах.

>>872130

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

> Это не js, да и функционал в целом опирается на заложенный в самом языке


Вообще-то менеджеров пакетов там не меньше 10: https://github.com/golang/go/wiki/PackageManagementTools

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


Но все приходится писать руками. Я вот обертку для вызова execve буду писать.
>>872209
#338 #872209
>>872167

> Я не вижу особых причин, почему код на Го будет при прочих равных лучше кода на PHP.


Он не лучше, он другой. Нужен онлайн магазинчик - php, нужен чатик для обратной связи или нужно заткнуть высоконагруженную часть - go.

> нет классов и стандартов


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

> Вообще-то менеджеров пакетов там не меньше 10


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

> Но все приходится писать руками.


По этому я и не говорю что go подходит для написания больших программ.

Я вот пишу парсер сайта и мне нравится что я могу запустить сразу 500 корутин и особо не волноваться.
#339 #872217
>>871377
>>871380

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

>>871369
>>870893

Классы IncomingDamage и FilteredDamage не имеют никакого смысла. Чем IncomingDamage отличается от Damage? Ради чего здесь применено наследование? Какие это выгоды нам дает?

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

Соответственно, если оставить только класс Damage, код упрощается.

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

В классе Armor я бы добавил конструктор, чтобы нельзя было создать защиту, не указав какие-то важные характеристики.

> $this->$elementResist


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

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

class Armor {
public function setArmor($armor);
public function getArmor();
public function setElementalResist($elementResist, $resist);
public function getElementalResist($elementResist);
public function getElementDamageReduction($elementResist);
public function filterIncomeDamage(Damage $damage);
}

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

Если ты хочешь обощенно работать с разными видами защиты, тебе надо сделать массив и константы для обозначения их видов:

$type = Damage::TYPE_FIRE;
$this->resist[$type] = ...

Ты же по сути из объект пытаешься использовать как массив.

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

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

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

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

Погуглить можно термин SOLID. Также, есть такая интересная статья: https://habrahabr.ru/post/153225/

Не хочешь задачку на ООП?

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

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

Система должна быть расширяемой, то есть должна быть возможность добавлять новые виды правил и проверок. Желательно, чтобы классы были переиспользуемыми, например, если есть код для проверки email на правильность, то нужно чтобы им можно было пользоваться и без формы. Правила валидации могут затрагивать несколько полей (ну например, проверка что 2 поля с паролем совпадают).
#339 #872217
>>871377
>>871380

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

>>871369
>>870893

Классы IncomingDamage и FilteredDamage не имеют никакого смысла. Чем IncomingDamage отличается от Damage? Ради чего здесь применено наследование? Какие это выгоды нам дает?

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

Соответственно, если оставить только класс Damage, код упрощается.

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

В классе Armor я бы добавил конструктор, чтобы нельзя было создать защиту, не указав какие-то важные характеристики.

> $this->$elementResist


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

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

class Armor {
public function setArmor($armor);
public function getArmor();
public function setElementalResist($elementResist, $resist);
public function getElementalResist($elementResist);
public function getElementDamageReduction($elementResist);
public function filterIncomeDamage(Damage $damage);
}

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

Если ты хочешь обощенно работать с разными видами защиты, тебе надо сделать массив и константы для обозначения их видов:

$type = Damage::TYPE_FIRE;
$this->resist[$type] = ...

Ты же по сути из объект пытаешься использовать как массив.

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

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

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

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

Погуглить можно термин SOLID. Также, есть такая интересная статья: https://habrahabr.ru/post/153225/

Не хочешь задачку на ООП?

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

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

Система должна быть расширяемой, то есть должна быть возможность добавлять новые виды правил и проверок. Желательно, чтобы классы были переиспользуемыми, например, если есть код для проверки email на правильность, то нужно чтобы им можно было пользоваться и без формы. Правила валидации могут затрагивать несколько полей (ну например, проверка что 2 поля с паролем совпадают).
>>872708
#340 #872219
>>871321

http://письмо.рф

А почему нет? Чем кириллица хуже других алфавитов?

>>871181

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

>>871158

Это не так и плохо, наверно. Я бы jQuery с удовольствием на модули распилил.

>>871028

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

[$word1, $word2, ...]

И затем пройтись по этому массиву циклом, выбирая слова.

>>870991

На майлинаторе любой может просмотреть все входящие емайлы: https://www.mailinator.com/inbox2.jsp?public_to=2chphp#/#public_maildirdiv

Не отправляйте письма на такие адреса

>>870972

> if ($creditBalance <= $monthlyPayment) {


> $monthlyPayment = $creditBalance;


Это можно заменить на min/max.

> $creditBalance = $creditBalance - $monthlyPayment;


Тут можно использовать -=.

А так, все верно.
#340 #872219
>>871321

http://письмо.рф

А почему нет? Чем кириллица хуже других алфавитов?

>>871181

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

>>871158

Это не так и плохо, наверно. Я бы jQuery с удовольствием на модули распилил.

>>871028

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

[$word1, $word2, ...]

И затем пройтись по этому массиву циклом, выбирая слова.

>>870991

На майлинаторе любой может просмотреть все входящие емайлы: https://www.mailinator.com/inbox2.jsp?public_to=2chphp#/#public_maildirdiv

Не отправляйте письма на такие адреса

>>870972

> if ($creditBalance <= $monthlyPayment) {


> $monthlyPayment = $creditBalance;


Это можно заменить на min/max.

> $creditBalance = $creditBalance - $monthlyPayment;


Тут можно использовать -=.

А так, все верно.
#341 #872220
>>870925

Откроем мануал (увы, англ): https://developer.mozilla.org/ru/docs/Web/CSS/@font-face
Или стандарт (тоже англ): https://www.w3.org/TR/css-fonts-3/#font-face-rule
Ну или на русском: http://htmlbook.ru/css/font-face

Соответственно, если у шрифта несколько начертаний, то надо на каждое начертание сделать @font-face с одинаковым font-family, но разными font-weight, font-style и разумеется src.

Также, надо учесть что разные браузеры поддерживают разные форматы, и указать ссылки для нескольких форматов. Также, старый ИЕ не поддерживает несколько форматов, потому для него надо указать ссылку хитрым костылем. есть готовый образец под названием Mo Bulletproof Font-face syntax: https://habrahabr.ru/post/113136/

Поддержка разных форматов:

- http://caniuse.com/#feat=woff
- http://caniuse.com/#feat=ttf
- https://developer.mozilla.org/en-US/docs/Web/Guide/WOFF
- http://transfonter.org/formats

Проанализировав матрицу поддержки форматов шрифтов браузерами, выбери комбинацию, дающую наибольший охват. Сконвертировать шрифты можно на fontsquirrel.

Сделай тестовый файлик (с разными буквами и начертаниями), выложи куда-ниудь и на сервисе вроде https://www.browserstack.com/screenshots или https://developer.microsoft.com/en-us/microsoft-edge/tools/screenshots/ можешь проверить отображение в разных браузерах.

>>870882

Питон не десктопный язык. Я бы советовал C#, он хорош, но по факту только под винду (я знаю про кроссплатформенность, но WPF никто не портировал). Либо, если ты хочешь кроссплатформенности, а производительность не очень важна, то HTML/CSS/JS упакованные с помощью программы вроде Electron. Работает кроссплатформенно, высокая скорость разработки, но память будет кушать как браузер.

Вообще, после HTML интерфейсы делать на чем-то другом - сплошная боль и трата времени.

>>870861

> set_time_limit(0);


> ob_implicit_flush();


В консоли не нужно.

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

socket_write использован некорректно. Открой мануал: http://php.net/manual/ru/function.socket-write.php

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



Тебе надо обязательно читать мануал по всем использованным функциям, иначе ты не будешь знать особенностей их работы. Сетевые функции чтения и записи, как правило работают так: ты можешь указать любой объем передаваемых или принимаемых данных, но по факту они возвращают выполнение после отправки/получения одного пакета. Если твои данные не влезли в один пакет - ты должен снова вызывать socket_write с остатком данных. И разумеется, любая сетевая операция может дать еще 2 исхода:

- ошибку
- EOF, например получатель мог закрыть соединение до передачи/получения всех данных, в этом случае функция возвращает 0 и ты можешь проверить вроде бы через feof(), открыто ли еще соединение.

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

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

>>870858

Архитектура MVC: например, скрипты-контроллеры, шаблоны, и остальные классы образующие модель: классы работы с БД, классы валидации данных. Плюс какие-то дополнительные классы вроде класса с вспомогательными функциями, класса авторизации, защиты от CSRF.

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


Лучше делать роутинг с проверкой УРЛ, то есть взять текущий УРЛ из REQUEST_URI и проверять:

если (УРЛ == '/register') вызвать контроллер регистрации
если (УРЛ == /) вызвать контроллер списка студентов
иначе выдать 404 ошибку

>>870803

> простой echo-сервер,


При ошибке создания сокета надо завершать скрипт.

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

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

> socket_read($msgsock, 2048, PHP_NORMAL_READ



Эта функция может вернуть:

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

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

> if (!$buf = trim($buf)) {


Во-первых, не стоит совмещать присваивание и иф. Во-вторых, if (!) сработает если в $buf будет строка "0".

> Напиши простой HTTP-клиент на php


> Не уверен, что я правильно понял задание


надо написать его на сокетах, а не на курле. Самому сформировать HTTP-запрос. Хотя написание на курле - тоже полезная практика.

Записывать пришедшие данные в фал желательно поточно, по мере скачивания. Если можешь, сделай поддержку gzip сжатия в ответе.

>>870799

Вот тут вариант кода хороший: >>870972
#341 #872220
>>870925

Откроем мануал (увы, англ): https://developer.mozilla.org/ru/docs/Web/CSS/@font-face
Или стандарт (тоже англ): https://www.w3.org/TR/css-fonts-3/#font-face-rule
Ну или на русском: http://htmlbook.ru/css/font-face

Соответственно, если у шрифта несколько начертаний, то надо на каждое начертание сделать @font-face с одинаковым font-family, но разными font-weight, font-style и разумеется src.

Также, надо учесть что разные браузеры поддерживают разные форматы, и указать ссылки для нескольких форматов. Также, старый ИЕ не поддерживает несколько форматов, потому для него надо указать ссылку хитрым костылем. есть готовый образец под названием Mo Bulletproof Font-face syntax: https://habrahabr.ru/post/113136/

Поддержка разных форматов:

- http://caniuse.com/#feat=woff
- http://caniuse.com/#feat=ttf
- https://developer.mozilla.org/en-US/docs/Web/Guide/WOFF
- http://transfonter.org/formats

Проанализировав матрицу поддержки форматов шрифтов браузерами, выбери комбинацию, дающую наибольший охват. Сконвертировать шрифты можно на fontsquirrel.

Сделай тестовый файлик (с разными буквами и начертаниями), выложи куда-ниудь и на сервисе вроде https://www.browserstack.com/screenshots или https://developer.microsoft.com/en-us/microsoft-edge/tools/screenshots/ можешь проверить отображение в разных браузерах.

>>870882

Питон не десктопный язык. Я бы советовал C#, он хорош, но по факту только под винду (я знаю про кроссплатформенность, но WPF никто не портировал). Либо, если ты хочешь кроссплатформенности, а производительность не очень важна, то HTML/CSS/JS упакованные с помощью программы вроде Electron. Работает кроссплатформенно, высокая скорость разработки, но память будет кушать как браузер.

Вообще, после HTML интерфейсы делать на чем-то другом - сплошная боль и трата времени.

>>870861

> set_time_limit(0);


> ob_implicit_flush();


В консоли не нужно.

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

socket_write использован некорректно. Открой мануал: http://php.net/manual/ru/function.socket-write.php

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



Тебе надо обязательно читать мануал по всем использованным функциям, иначе ты не будешь знать особенностей их работы. Сетевые функции чтения и записи, как правило работают так: ты можешь указать любой объем передаваемых или принимаемых данных, но по факту они возвращают выполнение после отправки/получения одного пакета. Если твои данные не влезли в один пакет - ты должен снова вызывать socket_write с остатком данных. И разумеется, любая сетевая операция может дать еще 2 исхода:

- ошибку
- EOF, например получатель мог закрыть соединение до передачи/получения всех данных, в этом случае функция возвращает 0 и ты можешь проверить вроде бы через feof(), открыто ли еще соединение.

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

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

>>870858

Архитектура MVC: например, скрипты-контроллеры, шаблоны, и остальные классы образующие модель: классы работы с БД, классы валидации данных. Плюс какие-то дополнительные классы вроде класса с вспомогательными функциями, класса авторизации, защиты от CSRF.

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


Лучше делать роутинг с проверкой УРЛ, то есть взять текущий УРЛ из REQUEST_URI и проверять:

если (УРЛ == '/register') вызвать контроллер регистрации
если (УРЛ == /) вызвать контроллер списка студентов
иначе выдать 404 ошибку

>>870803

> простой echo-сервер,


При ошибке создания сокета надо завершать скрипт.

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

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

> socket_read($msgsock, 2048, PHP_NORMAL_READ



Эта функция может вернуть:

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

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

> if (!$buf = trim($buf)) {


Во-первых, не стоит совмещать присваивание и иф. Во-вторых, if (!) сработает если в $buf будет строка "0".

> Напиши простой HTTP-клиент на php


> Не уверен, что я правильно понял задание


надо написать его на сокетах, а не на курле. Самому сформировать HTTP-запрос. Хотя написание на курле - тоже полезная практика.

Записывать пришедшие данные в фал желательно поточно, по мере скачивания. Если можешь, сделай поддержку gzip сжатия в ответе.

>>870799

Вот тут вариант кода хороший: >>870972
#342 #872391
Выручайте пыханы. Поставил силекс через композер. Пытаюсь запустить вот этот код:
require '../vendor/autoload.php';

$app = new Silex\Application();

$app->get('/hello/{name}', function($name) use($app) {
return 'Hello '.$app->escape($name);
});

$app->run();
Но силекс в браузере пишет: Sorry, the page you are looking for could not be found.
Работаю с nginx, то же происходит и со слимом. Гуглил, но пока ничего внятного по этому вопросу не нашел.
>>872397
#343 #872397
>>872391

> Но силекс в браузере пишет


А какой путь ты запрашиваешь в браузере? Попробуй hello/name
>>872401
#344 #872401
>>872397
Пиздос, как я так мог затупить. Заработало.
48 Кб, 412x635
#345 #872430
Оп, у тебя в учебники по js (https://gist.github.com/codedokode/ce30e7a036f18f416ae0#Задачки-на-js) в 14 задаче в строке...

var с = new Date(2014, 1, 1);

..."с" русская.

мимонаблюдательный на js задачах.
#346 #872431
>>872430
в 15ой. фикс
#347 #872440
>>872430
Ну и посмотри 15ую, решение получилось короткое, что подозрительно. http://ideone.com/ztZNiF . 16ая судя твоему примечанию очень сложная? Отложить ее после DOM задачек?
>>873037
82 Кб, 1820x172
#348 #872472
Ребята, помогите туповатому товарищу.
Может кто просто выделить начало и конец класса
который отвечает за рекламу автомобильных подушек?

view-source:https://vk.com/smcat
>>872580
#349 #872549
всем привет. начал изучать php и всю телегу, поэтому нубский-нубский вопрос: если мы где-то определили строковую переменную вида там $a = '$b + $c' (или просто $a = '2 + 3)', есть какой-то очевидный (правильный, короткий и т.д.) способ эту переменную выполнить как код?
>>872557>>873037
#350 #872557
>>872549
eval()
>>872559
#351 #872559
>>872557
сенкс
#352 #872580
>>872472
Запихни это куда-нибудь сюда: http://www.freeformatter.com/html-formatter.html
Или поищи аналогичные сервисы.
>>872900
59 Кб, 1280x720
32 Кб, 300x282
Satosi #353 #872641
>>872165
Новый пак исправлений.

> Школьник и кредит на айфон


>Это почти одинаковый код. Попробуй избавиться от повторов строчек.


Избавился

>Можно просто else, условие не требуется.


Исправил.
http://ideone.com/yb1bfA

>Ты забыл еще букву "Я", но в остальном, решено верно.


Есть такое решение, но мне оно ужасно не нравится. Новый массив строк и снова код менять.
http://ideone.com/X8kp2g
Есть ещё такое, гораздо "эластичнее".
http://ideone.com/FV1P5O

Ну и к айпадам применил модификации.
http://ideone.com/dMpAgx

Обьединил в один класс.

>Слишком длинный номер считается почему-то верным:


Очень странно пикрил говорит что нет, или ты про другой?
http://ideone.com/P2kkv1

Спасибо за ссылки, ты лучше всех!
37 Кб, 813x315
#354 #872651
Ору

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


На сосаче учиться делать сайты.
Типа кул кодеры тут. Шли бы и зарабатывали на этом как я.
#355 #872652
>>864640 (OP)
Говнокодеры собрались-.-
#356 #872655
>>872641

Посмотри код по моей ссылке http://ideone.com/szMHz6

Там есть номер a111abcdefghijklm и он проходит проверку.
>>872690
#357 #872656
>>869823
Почему скрипт должен быть заключен в <?php?>
Почему именно в это? Раз мы пишем на php, то понятно что это php.
И как оно расшифровывается? В моем учебнике указывается Hypertext Preprocessor, но если сократить то выйдет только hp
>>872658
#358 #872658
>>872656

Почитай мануал http://php.net/manual/ru/language.basic-syntax.phpmode.php

То, что не заключено в <?php просто выводится как есть. Этот синтаксис позволяет делать например HTML шаблоны с вставками PHP кода.

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

> И как оно расшифровывается?


PHP = PHP Hypertext Processor. рекурсивный акроним. Первоначально имелось в виду Personal Home Page.
68 Кб, 500x700
Satosi #359 #872683
>>872641
Из старого треда ответы.

Нормеа телефонов

> (^ ?8|^\+ ?7)


>^ можно вынести за скобки



> echo " ".phoneNumberCheck($correctNumbers[$i])." \n ";


>Но функция phoneNumberCheck() ничего не возвращает, а ты пытаешься ее результат вклеить в строку.



>Работает правильно.


Теперь функция возвращает строку.
http://ideone.com/WObMMl
>>873030
128 Кб, 1920x1080
#360 #872690
>>872655
Насколько я понял нужно так
http://ideone.com/Hrpkvw

Да, не заметил нового элемента в начале масссива.
>>873030
#361 #872708
>>872217
Спасибо большое за такой развернутый ответ. Ну я просто новичек, и когда у тебя 0 опыта, перед тобой постоянно всплывают выборы в которых ты понятия не имеешь как лучше поступить, сделать так или иначе, создавать еще 1 класс или обойтись одним, делать ли метод тут или там и прочее. В общем вот примерно какая была у меня логика:

>Классы IncomingDamage и FilteredDamage не имеют никакого смысла. Чем IncomingDamage отличается от Damage? Ради чего здесь применено наследование? Какие это выгоды нам дает?


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

>Причем она копирует только 2 вида урона, все остальные данные теряются.


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

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


Конечно по разному, в зависимости от защиты и прочих резистов. Но суть в том, что урон хоть и может быть смешанным аля ОГНЕННАЯ СТРЕЛА (физик + фаер), то у существа в итоге нужно отнять какое-то фиксированное количество жизней. Для этого и нужен метод, что бы собственно после всех резистов взять этот тотал дамаг и отнять из хп.

>Доллар лишний. Или это специально? Тогда это плохая идея так как внешний код должен знать подробности внутреннего устройства класса (названия приватных полей), да вдобавок еще нет проверки, а есть ли такое поле вообще.


Я подумаю. Просто я столкнулся с тем, что выше писал в треде вот этот господин >>871884 и придется для каждого резиста писать по 2 метода только что бы БЛЮСТИ ИНКАПСУЛЯЦИЮ, хз кароче как пока с этим разобраться. Если расширять в перспективе еще 1 резистом, то и так придется ВСЕ методы переписывать которые обрабатывают входящий урон и прочее. Хоть резисты блин в массиве храни, что бы можно было форичем обходить их. Ну или как-то так :(
#361 #872708
>>872217
Спасибо большое за такой развернутый ответ. Ну я просто новичек, и когда у тебя 0 опыта, перед тобой постоянно всплывают выборы в которых ты понятия не имеешь как лучше поступить, сделать так или иначе, создавать еще 1 класс или обойтись одним, делать ли метод тут или там и прочее. В общем вот примерно какая была у меня логика:

>Классы IncomingDamage и FilteredDamage не имеют никакого смысла. Чем IncomingDamage отличается от Damage? Ради чего здесь применено наследование? Какие это выгоды нам дает?


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

>Причем она копирует только 2 вида урона, все остальные данные теряются.


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

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


Конечно по разному, в зависимости от защиты и прочих резистов. Но суть в том, что урон хоть и может быть смешанным аля ОГНЕННАЯ СТРЕЛА (физик + фаер), то у существа в итоге нужно отнять какое-то фиксированное количество жизней. Для этого и нужен метод, что бы собственно после всех резистов взять этот тотал дамаг и отнять из хп.

>Доллар лишний. Или это специально? Тогда это плохая идея так как внешний код должен знать подробности внутреннего устройства класса (названия приватных полей), да вдобавок еще нет проверки, а есть ли такое поле вообще.


Я подумаю. Просто я столкнулся с тем, что выше писал в треде вот этот господин >>871884 и придется для каждого резиста писать по 2 метода только что бы БЛЮСТИ ИНКАПСУЛЯЦИЮ, хз кароче как пока с этим разобраться. Если расширять в перспективе еще 1 резистом, то и так придется ВСЕ методы переписывать которые обрабатывают входящий урон и прочее. Хоть резисты блин в массиве храни, что бы можно было форичем обходить их. Ну или как-то так :(
>>873025
#362 #872732
Что в MVC должно обрабатывать данные в POST/GET массивах?
>>872766
#363 #872766
>>872732
Контроллеры
41 Кб, 347x380
66 Кб, 1057x655
#364 #872825
Анончики, хожу за бесплатно на практику с возможностью трудоустройства.

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

Шо делать, анончики? Терпеть или сьебывать оттуда? Я хожу туда, чтобы учиться и развиваться, а не ковыряться в говне.
>>872844
283 Кб, 1330x1000
#365 #872833
Требуется помощь в составлении правильного SQL-запроса. Ситуация такова: есть 2 таблицы:

1) поля 'uid' (INT) и 'quantity' (DECIMAL 9,2)
2) поля 'id' (INT AUTOINCREMENT) , 'quantity' (DECIMAL 9,2) , 'uid' (INT)

Первая хранит расходы, вторая - поступления.

Поле 'uid' - это номер из внутреннего учета (для бухгалтерии). Он уникален для каждой уникальной вещи (например вот этот стул и ни какой другой). 'quantity' соответственно количество поступления и расхода.

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

Пока что родить смог только нечто подобное:

SELECT DISTINCT `uid`, ((SELECT SUM(`quantity`) FROM `incomes` WHERE `uid` = `uid`) - (SELECT SUM(`quantity`) FROM `demands` WHERE `uid` = `uid`)) AS `balance` FROM `incomes`;

Этот запрос на выходе дает таблицу из уникальных 'uid' и вторым полем по идее должен давать баланс, но там всегда одно число. Проблема, возможно, там где выделено жирным, а может и во всем запросе. Как не пытался сформулировать вопрос для гугла - выдает не то, даже близко нет.
#366 #872844
>>872825

>коммперционном проекте 2009 года, код пикрелейтед, написанный на первом зенде, все такое старинное



Да у вас код практический свежий.

Вот я работаю часто с кодом из 2003-4 года выпуска, и кто-что почему запиливал не ясно.
>>872879
#367 #872849
>>872833
я не знаю что там за данные, и проверить не начем, но я бы налабал бы чтонить в стиле таком:

select prihod.uid, SUM(prihod.quantity)-SUM(uhod.quantity) as balance
from prihod
join uhod
on prihod.uid = uhod.uid
Group by 1
>>873019
#368 #872857
http://ideone.com/5BLqZl - такое может сойти за нормальную автозагрузку?
>>872874>>873019
#369 #872874
>>872857
если ты все классы хранишь в корне проекта не рассфасовываешь по папкам, то да.

Только еще правильно путь укажи, на компе же у тебя не найдет файла по адресу "/Class.php"

http://ideone.com/hYnPIL
>>872884
#370 #872879
>>872844
оно того стоит, анон? это же путь вникуда
#371 #872884
>>872874
Не совсем понял о чем ты. Сама функци лежит в autoload.php, в корне ее подключаю. Вроде все находит.
>>872893>>872943
67 Кб, 1440x900
#372 #872893
>>872884
Забыл пик.
>>872991
#373 #872900
>>872580
Спасибо попробую.
#374 #872943
>>872884

не знал, что ты юзаешь неймспейсы, тогда все окей.

в добавок скажу, что подключения разных автолоадеров и конфигов должны находиться в отдельном файле от создания классов и функций и тому подобного, в стандартах это описано
>>872991>>873019
#375 #872991
>>872943

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


Это как? Т.е. >>872893 как тут я сделал нельзя? Как тогда правильно сделать?
#376 #873019
>>872857

У тебя куча ошибок.

> spl_autoload_register(autoload);


Строки надо заключать в кавычки.

> require_once '/' . $class . '.php';


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

Плюс, имя класса может быть с нейспейсами и бексешами. Это ты не учел.

Также, класс может отсутствовать. Ну например если написать

if (class_exists("ZZZZZ"))

С именем несуществующего класса то это вызовет ошибку при попытке подключить файл ZZZZZ.php

А вообще, надо не изобретать велосипеды, а прочитать мой урок про PSR-4 https://github.com/codedokode/pasta/blob/master/php/autoload.md

>>872943

Не окей, смотри выше.

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


Можно ссылку?

>>872849

Неправльно сделан джойн. Джойн это горизонтальное соединение таблиц, а тут нужно скорее вертикальное через UNION.

>>872833

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

Я бы тебе советовал посмотреть наши задачки по SQL из ОП поста, чтобы лучше в нем разбираться. Или почитать любой учебник по SQL. Тут нельзя наугад переставлять запросы в надежде что заработает.
#376 #873019
>>872857

У тебя куча ошибок.

> spl_autoload_register(autoload);


Строки надо заключать в кавычки.

> require_once '/' . $class . '.php';


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

Плюс, имя класса может быть с нейспейсами и бексешами. Это ты не учел.

Также, класс может отсутствовать. Ну например если написать

if (class_exists("ZZZZZ"))

С именем несуществующего класса то это вызовет ошибку при попытке подключить файл ZZZZZ.php

А вообще, надо не изобретать велосипеды, а прочитать мой урок про PSR-4 https://github.com/codedokode/pasta/blob/master/php/autoload.md

>>872943

Не окей, смотри выше.

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


Можно ссылку?

>>872849

Неправльно сделан джойн. Джойн это горизонтальное соединение таблиц, а тут нужно скорее вертикальное через UNION.

>>872833

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

Я бы тебе советовал посмотреть наши задачки по SQL из ОП поста, чтобы лучше в нем разбираться. Или почитать любой учебник по SQL. Тут нельзя наугад переставлять запросы в надежде что заработает.
>>873085>>873190
#377 #873025
>>872708

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



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

Правильно либо не пересоздавать объект либо сделать в самом Damage функцию для создания новой версии объекта.

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

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


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

> Если расширять в перспективе еще 1 резистом, то и так придется ВСЕ методы переписывать которые обрабатывают входящий урон и прочее. Хоть резисты блин в массиве храни, что бы можно было форичем обходить их. Ну или как-то так :(


Я тебе выше и написал, что можно хранить виды дамаджа в массиве.
>>874438
#378 #873030
>>872690

> foreach ($autonombers as &$value) {


зачем тут & ?

> [АВЕКМНОРСТУХ|A-Z]


Тебе надо перечитать про символьные классы. Если ты ставишь вертикальную черту после X, почему не ставишь ее между остальными буквами?

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

Круглые скобки там не нужны.

Имя функции принято начинать с глагола: checkNumber

>>872683

> ^\+ ?7



^ тут лишнее

Решено верно.

>>872641

> Школьник и кредит на айфон



Можно упростить дальше, а именно:

- убрать else
- убрать $credit = 0; $worthMoney += $oversum;
- использовать min/max для расчета суммы месячного платежа

> Лев Толстой


> if ($i==9) { // плохое решение если добавить массивы, но как по другому отследить последнюю строку я не знаю


Букву Я можно просто положить в массив со структурой стиха.

> Есть ещё такое, гораздо "эластичнее".


Так и надо делать.

> Ну и к айпадам применил модификации.


Тоже можно упростить как и айфоны.
#378 #873030
>>872690

> foreach ($autonombers as &$value) {


зачем тут & ?

> [АВЕКМНОРСТУХ|A-Z]


Тебе надо перечитать про символьные классы. Если ты ставишь вертикальную черту после X, почему не ставишь ее между остальными буквами?

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

Круглые скобки там не нужны.

Имя функции принято начинать с глагола: checkNumber

>>872683

> ^\+ ?7



^ тут лишнее

Решено верно.

>>872641

> Школьник и кредит на айфон



Можно упростить дальше, а именно:

- убрать else
- убрать $credit = 0; $worthMoney += $oversum;
- использовать min/max для расчета суммы месячного платежа

> Лев Толстой


> if ($i==9) { // плохое решение если добавить массивы, но как по другому отследить последнюю строку я не знаю


Букву Я можно просто положить в массив со структурой стиха.

> Есть ещё такое, гораздо "эластичнее".


Так и надо делать.

> Ну и к айпадам применил модификации.


Тоже можно упростить как и айфоны.
#379 #873037
>>872549

Есть eval, но это общем плохая идея и скорее всего он тебе не нужен.

>>872440

Решено верно.

> 16ая судя твоему примечанию очень сложная? Отложить ее после DOM задачек?


Не, лучше решить, а то ты и задачки дальше не решишь.

>>872430

Исправил. Уверен, твоя наблюдательность тебе сослужит хорошую службу.
>>874531
#380 #873056
Аноны у меня паника,с профой из вузика проблемы,поэтому хочу вкатиться в пхп,если начать по гуиду Оп то на джуна возьмут?
>>873061
141 Кб, 640x798
#381 #873061
>>873056
На, уважяемьiй.
>>873063
25 Кб, 230x244
#382 #873063
#383 #873084
Посоны, объясните! ковыряю yii2/ миграции. И вот что тут нашел {{%user}}
что это за хуйня? видал такое и раньше, но не придал значение. Предполагаю что это переменная или ссылка на нее, но почему так, чтоб я не понял?
реквестую объяснения или хоть где почитать про такое явление.
>>873359
#384 #873085
>>873019

>Тут нельзя наугад переставлять запросы в надежде что заработает.



Вот это я уже ощутил. Буду больше читать тогда.

uid это идентификатор ти'па вещи, которой может быть много (например, "молоко простоквашино 2,5% жирности 0,5мл" - обозначает только определенный уникальный продукт, которых может быть quantity - много-много штук, постепенно прибывающих и убывающих). Итоговый результат селекта должен как раз выводить пару 'тип предмета' - 'остаток', и состоять по логике из уникальных первых значений. Короче, я не могу даже здесь объяснить, аргх.
1 Кб, 340x89
#385 #873119
Что в css прописать, чтобы div изменял высоту в зависимости от кол-ва контента?
>>873122
#386 #873122
>>873119
height: auto;
overflow: auto
word-wrap: break-word;
#387 #873130
Автор сайта из шапки большой молодец

Помогите макаке передать из js в php (в новый файл php) - гетом или постом.

Что я делаю не так? Я 3 день бьюсь, пожалуйста, помогите!
http://ideone.com/HNVYLP

Нагугливаю сплошной ajax, jquery - но нихуя не нашел нужного примера. Может я не так ищу? МНе всего лишь нужно передать переменные из js в php.
#388 #873175
>>873130
Давай я тебя научу:
1. ОТкрываешь свою страничку с JS скриптом в браузере.
2. Нажимаешь F12, идешь на вкладку Net/Network/Сеть
3. Обновляешь страничку.
4. Смотришь на появившиеся запросы - ищешь свой.
5. Если не нашел - идешь на вкладку Console/Консоль и смотришь ошибку.
6. Если нашел, но PHP не работает - ставишь первой строкой своего скрипта print_r($_POST)
7. Смотришь, что PHP получил.
8. Думаешь
9. ???
10. ПРОФИТ
#389 #873190
>>873359
21 Кб, 775x369
9 Кб, 619x141
#390 #873199
Где я обосрался на 60 копеек?
>>873203>>873359
#391 #873203
>>873199
Там так и должно быть.
>>873206
#392 #873206
>>873203
Ок, спасибо.
25 Кб, 1346x325
#393 #873305
>>872833
Апдейтед: работает вот так, но хотелось бы получать такой результат сразу в SQL!
>>873330>>873359
#394 #873330
>>873305
Тебя заинтересуют PostgreSQL и оконные функции.
>>873359
#395 #873342
Если сюда, то сюда, если нет то извиняйте: для юникс (линукс)-подобных для верстки html/css подскажите годноту по программам. В идеале отображение html кода и css кода сразу (т.е либо 2 окна либо удобное переключение между ими).
#396 #873344
>>873342

тебе нужен какой-нибудь тайловый менеджер (например, i3) и текстовый редактор с плагинами (..., sublime)
#397 #873347
>>873342
http://brackets.io/
алсо рекомендую Atom, на него дофига плагинов
#398 #873359
>>873330

Это тут вообще не при чем. Стандартного SQL достаточно.

>>873305

Тогда изучи SQL. Там решение очень простое.

>>873199

Переменные надо было назвать получше. Параметры задачи (5000, 0.03 итд) лучше указывать в начале задачи как переменные, чтобы их было легко поменять и чтобы было понятно, что это за числа. У тебя ничего не понять.

>>873190

А, ну логично, файл либо содержит классы/функции, либо исполняемый код.

>>873130

Тебе надо не гуглить, а изучить яваскрипт, основы HTTP и jQuery. (в ОП посте кстати есть задачки). Гугление не поможет так как вряд ли кто-то специально для твоей задачи решение напишет.

>>873084

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

Если ты это в каком-то проекте увидел, может это не особенность Юи, а что-то самописное?
#399 #873376
>>873359

>простое


да чтоб тебя...
#400 #873383
#401 #873395
ОП, ты советовал написать тесты на файлообменник, возник вопрос, на какие методы нужно писать тесты? На геттеры и сеттеры свойств модели не надо же? Надо только на методы которые внутри себя совершают какие-то действия? С phpunit немного разобрался, но не могу уяснить для себя когда это нужно применять. В туториалах рассматриваются примеры с арифметическими действиями или заполнением массива, такие вещи тоже нужно тестировать?
>>873411
#402 #873411
>>873395

А зачем вообще писать тесты? Очевидно, чтобы иметь возможность быстро проверить: работает ли кусок кода корректно или нет.

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

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

Также, надо понимать, что написание тестов не бесплатно - на них надо тратить время.

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

> В туториалах рассматриваются примеры с арифметическими действиями


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

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

Сами тесты как правило пишут на основе требований к функции или странице. Ну условно говоря, ты пишешь функцию выбора имени файла для хранения и предъявляешь к ней такие требования:

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

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

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

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

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

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

В файлообменнике я вижу такие тесты:

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

Советую показать тесты на проверку. Также, могу прокомментировать тестовые сценарии.
#402 #873411
>>873395

А зачем вообще писать тесты? Очевидно, чтобы иметь возможность быстро проверить: работает ли кусок кода корректно или нет.

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

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

Также, надо понимать, что написание тестов не бесплатно - на них надо тратить время.

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

> В туториалах рассматриваются примеры с арифметическими действиями


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

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

Сами тесты как правило пишут на основе требований к функции или странице. Ну условно говоря, ты пишешь функцию выбора имени файла для хранения и предъявляешь к ней такие требования:

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

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

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

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

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

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

В файлообменнике я вижу такие тесты:

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

Советую показать тесты на проверку. Также, могу прокомментировать тестовые сценарии.
>>873413
#403 #873413
>>873411
Спасибо, буду думать.
#404 #873461
Тут кто-то пользуется эклипсом? Я вот доволен им неимоверно, но не хватает всего одной фичи - хочется создавать классы по клику, а не создавать пхп файл, потом прописывать название класса и неймспейс.
>>873469>>873482
#405 #873469
>>873461
Первая иде была именно эклипс, но быстро переполз на нетбинс. В 2 раза быстрее, темы встают нормально, нету этих дурацких перспектив и вообще збс. По твоему вопросу сказать нечего, никогда это не парило.
>>873470
#406 #873470
>>873469
Странно, у меня нетбинс медленно работает.
#407 #873482
>>873461

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

Алсо вот это вот расширение http://p2.pdt-extensions.org/phpfeatures.html вроде как поддерживает создание класса через диалог (но мне кажется, тут с тобой что-то не так, по идее руками должно быть быстрее).
>>873493
#408 #873486
>>872056
ОП, вроде все исправил.
https://github.com/never3ver/students_list
Одно только не стал переделывать:

>https://github.com/never3ver/students_list/blob/master/templates/parts/pagination.html


>Тут логику выбора номеров страниц и генерацию ссылок можно было бы переложить на класс Pager, а в шаблоне оставить только их вывод.


Генерация ссылок и так вроде в классе, стрелки я допустим могу перенести, а как убрать цикл из шаблона, что-то не соображу. Да и надо ли?
>>873488>>873545
#409 #873488
>>873486

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

1 ... 4 5 [6] 7 8 ... 15

как ты это реализуешь?
>>873494
#410 #873493
>>873482
Спасибо, попробую. Ну не знаю насчет удобно/не удобно, но имхо легче сразу же указывать название класса и неймспейса, таким образом в зендстудио можно даже каталоги сходу создавать.
#411 #873494
>>873488
Добавлю ифов для троеточий и цикл буду организовывать с -3 до +3 от нынешней страницы, ничего особо не изменится. Если я правильно тебя понял.
>>873512
#412 #873500
Нихуя не выходит ёбаное задание друга-ОПа.

Надо проверить телефонные номера через регулярное выражение.

>Подсказка: не надо строить сложных выражений и предусматривать все возможные комбинации символов. Достаточно написать: сначала идет +7 или 8, за ними ровно 10 цифр, между которыми может быть любое число скобок, минусов, пробелов



$regexp = '/^(\+7|8)[0-9]{10}$/u';

Здесь соовтетсвенно проверка, что в начале +7 или 8 и десять цифр. А вот как записать, что между цифрами было сколько угодно скобок, - и пробелов я не пойму. Пиздец какой-то, нихуя не соображу.
>>873512
#413 #873511
#414 #873512
>>873494

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

>>873500

Попробуй написать выражение "одна цифра, за которой идет любое число скобок, пробелов, минусов".
>>873516>>873545
#415 #873513
>>873359

> специально для твоей задачи решение напишет


>передать перенменную из js в php



Охуеть какая узкая задача
#416 #873516
>>873512

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



Ну, моей фантазии хватает только на такое: $regexp = '/^(\+7|8)[0-9](\(\-\s\))*$/u';
но похоже несу лютый порожняк, потому что конечно же не работает. Как меня вымораживают эти спецсимволы.
>>873527
#417 #873517
Хм. Я кажется понял почему у меня нетбинс медленно работал - я раньше качал пакет, в котором сразу же все фичи были. Сейчас скачал пакет только с пхп, аштиемель/цсс и яваскриптом и все залетало, не хуже эклипса, а функциональность больше. Алсо, поясните мне чего все так носятся с пхпштормом? Что в нем такого крутого по сравнению с тем же нетбинсом, который вроде все основные преимущества дает, но при этом швабодным и быстрый?
#418 #873527
>>873516

Ну вообще конечно я не просил 8 или +7 добавлять, а написать только нужную часть выражения.

И то, ты написал его неправильно. Вот это например: \(\-\s\) значит "скобка, за ней минус, за ним пробельный символ, за ним скобка".

А надо: скобки, минусы, пробелы в любом порядке и количестве.

Подумай еще.

Подсказка:

http://php.net/manual/ru/regexp.reference.character-classes.php
http://php.net/manual/ru/regexp.reference.alternation.php
>>873869
#419 #873533
Не обращайтесь непосредственно к суперглобальному массиву $_SERVER.

Вместо этого можно использовать функции фильтрации (например, filter_input(), conditions with is_
() functions и др.).
----*
Вот такое мне выдает нетбинс когда я использую $_SERVER['REQUEST_URI'] в методе класса. С чего бы это было плохо?
>>873534
#420 #873534
>>873533
Жри что дают.
Люся! И ему такое подай.
#421 #873545
>>873486
>>873512

>Там будут еще другие условия


Ну ок, теперь совсем все переделал. ОП, ты просил напомнить, что

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


https://github.com/never3ver/students_list
#422 #873552
Пишу проект с нуля для довольно крупного (по сравнению с моими предыдущими работами) сайта-магазина, посещаемость в день планируется около 4-5 тыс. человек. На данный момент идёт тестирование и допиливается фронтенд (заказчики из серии "кнопкуПовышеМожно?"). В общем в чём суть вопроса: вся html-часть состоит из множества (около сотни) файлов-чанков по 1-2 кб, и всё это дело вызывается в движке функциями с file_get_contents() и подстановкой значений из базы с помощью strtr() вместо каких-то переменных по типу {MENULIST}. Концепция в том, что чем меньше HTML внутри php, тем лучше.
Так вот иногда на сервере возникают ошибки функции file_get_contents(), мол, не удалось выполнить HTTP-запрос, ошибка 503. F5 - всё ок. Но раз в 15-20 запросов такая шляпа возникает. Вопрос: забить ли на это хуй (ведь, когда тестирование закончится, я припилю на всё это дело memcached), изменить логику в сторону уменьшения количества запросов к файлам, или поменять хостинг (beget)?
>>873557>>873603
#423 #873557
>>873552
И ещё вопрос вдогонку:
Хорошая ли практика для передачи значений переменных в js использовать код по типу:

(В HTML-шаблоне)
...
<script>
var a = {NUM};
</script>
...

(PHP)
return strtr($template, ['{NUM}' => $a]);

Или лучше закидывать переменные в hidden input'ы, или, как на первый взгляд кажется наименее костыльно, всё-таки для получения вообще всех данных с бэкенда выполнять get-запросы непосредственно из js?
>>873566>>873603
#424 #873566
>>873557
2) Нормальная практика, нужны переменные - генерируй код, нужны данные форм - делай инпуты. Я делал и так, и эдак - никто не умер. 1) Похуй что там на бекенде с чанками, раз горячие данные все равно в мемкеш.
#425 #873579
В клаасах TableDataGataway методы статическими надо делать?
>>873582>>873607
#426 #873582
>>873579
Ты должен привязать БД к объекту при его создании, так что не статические.
>>873586
#427 #873586
>>873582
Так, что-то я запутался. Я думал, что ТДГ это типа есть класс Users, и для него создается класс для работы с БД UsersGateway с объектами типа insert, delete и прочее, но это датамаппер, а из уроков ОПа я что-то вообще не понял что такое ТДГ - как это для работы с разными сущностными использовать один класс?
>>873587>>873607
#428 #873587
>>873586

> с объектами


С методами
фикс
#429 #873603
>>873552

Судя по описанию твой код это набор плохих практик. Дабы другие аноны не использовали их в своих проектах, опишу подробнее:

1) не надо писать свой кривой велосипедный шаблонизатор, есть twig который по возможностям раз в 100 мощнее "шаблонизатора" на strtr()
2) для получения данных по HTTP есть нормальные HTTP-клиенты
3) разобраться, почему происходят ошибки, надо
4) в принципе неправильно если при генерации обычной страницы ты шлешь куда-то HTTP запросы

> Концепция в том, что чем меньше HTML внутри php, тем лучше.


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

>>873557

Плохо сделано. А что если в переменной есть что-то, кроме цифр? А что, если она пуста?

В twig я делаю так:

var a = {{ a | json_encode | raw }};

В качестве домашнего задания оставлю тебе и другим анонам объяснить, как это работает, насколько надежно и зачем там raw.

> , всё-таки для получения вообще всех данных с бэкенда выполнять get-запросы непосредственно из js?


Какой смысл делать запрос, если можно обойтись без этого?
>>873728
#430 #873607
>>873579

Это почему?

>>873586

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

Также даю ссылки на перевод статей Фаулера по этим классам, попробуй сравнить их самостоятельно:

http://design-pattern.ru/patterns/table-data-gateway.html
http://design-pattern.ru/patterns/data-mapper.html
>>873616
#431 #873609
>>873130
Бамп
#432 #873616
>>873607

>Это почему?


То я сначала все вообще не так понимал.

>Также даю ссылки на перевод статей Фаулера по этим классам, попробуй сравнить их самостоятельно:


Честно говоря, так и не понял в чем разница. А вот это вообще даже примерно не понял:

>Это что-то напоминающее DataMapper, но он может быть реализован без объектов-сущностей.


https://gist.github.com/codedokode/c4cbc4d7dc8e45ea074a
>>873635>>873738
#433 #873635
>>873616
Короче в TDG можно делать так:
$userGateway->setName($id, 'Новое имя') и объекты-сущности не требуются.
В DataMapper будет так:
$user = new User();
$user->setName = 'Новое имя';
$userMapper->persist($user);
>>873645>>873738
#434 #873645
>>873635

>$userGateway->setName($id, 'Новое имя')


Зачем $id?

> и объекты-сущности не требуются.


А как отображать данные? Ну т.е. вот у меня есть метод getAll. Где-то там в недрах есть код return $sth->fetchAll(\PDO::FETCH_CLASS, $class) - и что тогда вместо класса?
>>873738
#435 #873662
Читаю ссылка на ТДГ в Зенд. https://framework.zend.com/manual/1.12/ru/zend.db.table.html у меня сложилось впечатление, буд-то ТДГ скорее на эктив рекорд похоже. Я похожий велосипед недавно писал, как тут все наследуются от Zend_Db_Table, так у меня был класс Model, в котором были методы для работы с БД, а в наследованых классах-сущностях я только добавлял соответствующие поля и название таблицы. Или это у меня не эктив рекорд был?
>>873755
#436 #873728
>>873603
Понятно, короче, просто под твиг вывод переписать.
А в рав очевидно же, чтобы с &quot'ами проблем не было, хотя это и не очень безопасно.
>>873755>>873761
#437 #873738
>>873616

Во-первых, ты читаешь старую версию урока, вот новая, с небольшими дополнениями: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md

Напишу еще раз:

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

> А вот это вообще даже примерно не понял:


>>Это что-то напоминающее DataMapper, но он может быть реализован без объектов-сущностей.



Имеется в виду, что в TDG может быть метод updateName($userId, $userName), а в Data Mapper обычно сначала загружают объект в память, меняют ему имя и сохраняют обратно в БД. Но зато некоторые Data Mapper вроде Doctrine умеют сами искать измененные объекты и автоматически сохранять эти изменения.

>>873635

Неправильный пример. new User создаст нового пользователя. Редактирование делается так:

$user = $userMapper->findById(10);
$user->name = 'Новое имя';
$userMapper->save($user); // или, в продвинутых мапперах, просто $mapper->flush(), а дальше он сам найдет измененные сущности и сохранит их

>>873645

>>$userGateway->setName($id, 'Новое имя')


> Зачем $id?


А как без него понять, какому именно пользователю мы меняем имя?

>> и объекты-сущности не требуются.


> А как отображать данные? Ну т.е. вот у меня есть метод getAll. Где-то там в недрах есть код return $sth->fetchAll(\PDO::FETCH_CLASS, $class) - и что тогда вместо класса?


Имелось в виду, что для выполнения update() можно обойтись без загрузки и сохранения сущностей. В отличие от Data Mapper.
#437 #873738
>>873616

Во-первых, ты читаешь старую версию урока, вот новая, с небольшими дополнениями: https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md

Напишу еще раз:

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

> А вот это вообще даже примерно не понял:


>>Это что-то напоминающее DataMapper, но он может быть реализован без объектов-сущностей.



Имеется в виду, что в TDG может быть метод updateName($userId, $userName), а в Data Mapper обычно сначала загружают объект в память, меняют ему имя и сохраняют обратно в БД. Но зато некоторые Data Mapper вроде Doctrine умеют сами искать измененные объекты и автоматически сохранять эти изменения.

>>873635

Неправильный пример. new User создаст нового пользователя. Редактирование делается так:

$user = $userMapper->findById(10);
$user->name = 'Новое имя';
$userMapper->save($user); // или, в продвинутых мапперах, просто $mapper->flush(), а дальше он сам найдет измененные сущности и сохранит их

>>873645

>>$userGateway->setName($id, 'Новое имя')


> Зачем $id?


А как без него понять, какому именно пользователю мы меняем имя?

>> и объекты-сущности не требуются.


> А как отображать данные? Ну т.е. вот у меня есть метод getAll. Где-то там в недрах есть код return $sth->fetchAll(\PDO::FETCH_CLASS, $class) - и что тогда вместо класса?


Имелось в виду, что для выполнения update() можно обойтись без загрузки и сохранения сущностей. В отличие от Data Mapper.
>>873807
#438 #873755
>>873662

В Зенде именно TDG так как там в примере

class Bugs extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs';
}

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

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

При этом в зенде некоторые методы выборки из БД возвращают объекты класса Zend_Db_Table_Row_Abstract. Они реализуют паттерн Row Data Gateway, то есть позволяют изменять соответствующую запись в БД и чем-то в этом плане напоминают актив рекорд.

>>873728

Это абсолютно безопасно. Согласно стандарту HTML содержимое тега script (а также style) воспринимается как есть и HTML-сущности там не декодируются. То есть если внутри script написать & quot то это будет воспринято буквально, а не как кавычка.

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

var x = & quot ; test & quot ;;

Вместо

var x = "test";

Единственный риск тут - если в наших данных содержится закрывающий тег </script> то можно закрыть тег script и вставить произвольный HTML. Но json_encode заменяет слеш / на \/ и потому закрывающий тег там не получится - получится <\/script>'

var x = '<\/script>'; // это не закрывающий тег

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

Если используется шаблон на php то вывод еще проще:

var x = <?= json_encode($x); ?>;

Этот способ позволяет передать из PHP в JS любые значения, включая массивы и хеши.
#438 #873755
>>873662

В Зенде именно TDG так как там в примере

class Bugs extends Zend_Db_Table_Abstract
{
protected $_name = 'bugs';
}

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

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

При этом в зенде некоторые методы выборки из БД возвращают объекты класса Zend_Db_Table_Row_Abstract. Они реализуют паттерн Row Data Gateway, то есть позволяют изменять соответствующую запись в БД и чем-то в этом плане напоминают актив рекорд.

>>873728

Это абсолютно безопасно. Согласно стандарту HTML содержимое тега script (а также style) воспринимается как есть и HTML-сущности там не декодируются. То есть если внутри script написать & quot то это будет воспринято буквально, а не как кавычка.

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

var x = & quot ; test & quot ;;

Вместо

var x = "test";

Единственный риск тут - если в наших данных содержится закрывающий тег </script> то можно закрыть тег script и вставить произвольный HTML. Но json_encode заменяет слеш / на \/ и потому закрывающий тег там не получится - получится <\/script>'

var x = '<\/script>'; // это не закрывающий тег

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

Если используется шаблон на php то вывод еще проще:

var x = <?= json_encode($x); ?>;

Этот способ позволяет передать из PHP в JS любые значения, включая массивы и хеши.
#439 #873761
>>873728

А без json_encode очень легко сломать JS. Ну например, в JS строках не разрешен перенос строки, и как я выше написал, если вставить строку </script> то можно закрыть тег script.

Так как JSON является (почти) подмножеством яваскрипт, то (почти) любой JSON код является валидным JS-выражением. Что бы мы не передавали в json_encode, мы получим (почти) валидное выражение.

(почти) здесь относится к паре экзотических символов которые недопустимы в JS строках, но допустимы в JSON:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON

> the Unicode line separator (U+2028) and paragraph separator (U+2029) characters are permitted;



К счастью (проверил экспериментально) json_encode кодирует эти спецсимволы как \u2028, а не вставляет как есть, и таким образом генерирует валидный JS-код.
#440 #873807
>>873738
Теперь почти все понял насчет ТДГ и дата мапера. Кроме одного - допустим мне нужен метод getAllNews что бы отображать новости на главной. В каком виде их выгружать из БД? Сохранять в виде масива объектов того же ТДГ, или же просто массив массивов делать?
>>873864
#441 #873816
Ребятааааа, а есть среди вас те, кто может странички вконтакте взломать? Очень нужно. Дело тянет на уголовщину а-ля хабаровска, а доказать причастность не можем
#442 #873819
>>873816
А что за уголовщина случилась в Хабаровске?
#443 #873824
>>873816
Так просто же всё, вводишь в гугле "Взломать страницу вконтакте без смс", и он тебе находит несколько ресурсов. Сам так взламывал, брат жив.
194 Кб, 1024x1024
#444 #873855
Вебом последний раз занимался в 2010-м, мама попросила запилить ей магазин для продажи шмоток-тряпок (авито уже не катит), порекомендуйте пхп магазин, чтобы поднять и настроить методы оплаты для русского покупателя, без лишнего геморроя?
>>873877>>873925
#445 #873864
>>873807

> Сохранять в виде масива объектов того же ТДГ


TDG представлят объект для работы с базой данных, а не новость. Ты все равно все путаешь.

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

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

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

>>873816

Таких мамкиных детективов сейчас по статье за незаконный доступ к информации сажают, уже были случаи. Расследованиями должна заниматься полиция.
>>873922
#446 #873869
>>873527
Ладно. Тогда ответ на твой предыдущий вопрос:

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



Получилось такое:
$regexp = '/^[0-9][\(][\)][\-][\s]/u';

Так должно быть?
>>873871
#447 #873871
>>873869

>$regexp = '/^[0-9][\(][\)][\-][\s]/u';


Т.е. $regexp = '/^[0-9][\(][\)][\-][\s]/u';

А то что-то звездочки пропали.
>>873873
#448 #873873
>>873871
В общем, после скобок [\(], [\)], [\-] и [\s]
звезды у меня стоят, но их макаба как курсив видит.
#449 #873877
>>873855
битрикс
>>873878
#450 #873878
>>873877
Хуитрикс
22 Кб, 773x368
#451 #873884
>>873359
А так понятно?
>>877986
#452 #873922
>>873864

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


Понял. Вот это мне и нужно было. Но с моей колокольни выглядит несколько неудобно то, что приходится делать пустой класс чисто для отображения. Ну да и ладно.
Кстати ОП, а ты будешь делать уроки по всяких паттернам окромя баз данных? Ну там всякие фабрики, фасады, декораторы? Уж больно годно у тебя получается.
Алсо есть такой баг или фича непонятная в IDE - когда я делаю класс синглтононом я не могу смотреть их через автодополнение. Такая хуита в нетбинсе и эклипсе. Что бы это значило? Это баг, или я чего-то не понимаю в ООП и паттерне синглтон?(использую синглтон для класса соединения с БД)
#453 #873925
>>873855
Wordpress с плагином Woocommerce.
inb4: хуйпресс с плагином хуйкомерце
>>873927
#454 #873927
>>873925
ИМХО быстрей будет уже поднять какой-нибудь опенкарт или престашоп.
#455 #874038
Добрый день, парсил с помощью curl большой инет магазин (700к товаров) и вроде как парсил мелкими порциями но (250 товаров раз в 15 минут) но теперь ловлю ответом access denied. Сервер мой стоит на виртуалке убунты, внешний IP у неё такой же как и на основной машине. При этом с браузера я могу зайти нормально, а именно curl нарывается на баг, пробовал сменить CURLOPT_USERAGENT - не помогло. Если бан дали не на IP и не на IP + useragent - тогда на что?
#456 #874039
>>874038

>баг


*бан
selffix
#457 #874056
>>874038
Поигравшись с опциями всё таки обошел бан установив no-cache.
#458 #874057
>>874038
хуй знает
посмотри все остальные хедеры
посмотри как он с куками работает
#459 #874081
Посмотрите, пожалуйста.

Нормально сделано задание про палиндром ?
Решал сам, без мам пап и кредитов.

http://ideone.com/iCawI5
#460 #874134
>>874081
Поставь там везде echo "Палиндром"/echo "Не палиндром", иначе ничего не понятно.
#461 #874162
Няши, чекните мое решение, пожалуйста.
https://github.com/anonymous011010/studentslist
>>874485>>874486
#462 #874239
>>867039
>>867314
https://github.com/someApprentice/maintaskforlayout
https://someapprentice.github.io/maintaskforlayout/

>кроссбраузерность



В ie7,8 ширина body всегда равна ширине окна. А вот в ie6 всё хорошо.

Даже оригинальный otf формат шрифта главного заголовка не отображается в ie6-8. В отличие от шрифта Lato.

Стили и вес моего семейства шрифтов Lato распределяются как попало:

firefox, webkit Наличие описания веса bolder переопределяет значение normal, т.е. c regular на bolder
ie<8 Цифровые значения веса наклоняют шрифты с жирным начертанием
ie Лёгкие шрифты становится жирными
firefox Лёгкие шрифты не определяются

Если убрать описание шрифтов с цифровым значением веса, то в webkit'е так же ломается отображение легких шрифтов - они становиться жирными. Далее, если убрать описание bolder, то абзацы вместо того чтобы стать lighter становится regular, т.е. normal. Однако, это чинит наклонность шрифтов в ie<8.

>адаптивность


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

Ещё я заметил странный отступ у ссылок на соц.сети в webkit'е. Его задает ul, menu, dir { user agent stylesheet
display: block;
list-style-type: disc;
-webkit-margin-before: 1em;
-webkit-margin-after: 1em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
-webkit-padding-start: 40px;
}

Что это такое?

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

>переработка базовых стилей


>Далее, тебе надо проработать базовые стили CSS. Сделай новый файл с пустым body и впиши в него простой HTML без классов, с тегами вроде h1, h2, ul, li, p, a, img, blockquote (если нет фантазии или лень писать, скопируй с http://motherfuckingwebsite.com/ ). У тебя этот текст выводится бледно-серым на белом фоне - это значит, базовые стили не продуманы совсем. Ты написал не базовый CSS для всего сайта, а стили для единственной страницы и при добавлении новых страниц твой ксс придется значительно переделывать.


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

Я старался найти ответы самому. Я могу хотя бы рамках обучения спросить подсказку? Учитывая что я первый раз верстаю. Что делать если такие не очевидные вопросы появится в боевых задачах? Такое поведение браузеров для меня очень странное, и я не знаю где я допустил пробел в изучении верстки, что у меня нету понимания почему так происходит.
#462 #874239
>>867039
>>867314
https://github.com/someApprentice/maintaskforlayout
https://someapprentice.github.io/maintaskforlayout/

>кроссбраузерность



В ie7,8 ширина body всегда равна ширине окна. А вот в ie6 всё хорошо.

Даже оригинальный otf формат шрифта главного заголовка не отображается в ie6-8. В отличие от шрифта Lato.

Стили и вес моего семейства шрифтов Lato распределяются как попало:

firefox, webkit Наличие описания веса bolder переопределяет значение normal, т.е. c regular на bolder
ie<8 Цифровые значения веса наклоняют шрифты с жирным начертанием
ie Лёгкие шрифты становится жирными
firefox Лёгкие шрифты не определяются

Если убрать описание шрифтов с цифровым значением веса, то в webkit'е так же ломается отображение легких шрифтов - они становиться жирными. Далее, если убрать описание bolder, то абзацы вместо того чтобы стать lighter становится regular, т.е. normal. Однако, это чинит наклонность шрифтов в ie<8.

>адаптивность


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

Ещё я заметил странный отступ у ссылок на соц.сети в webkit'е. Его задает ul, menu, dir { user agent stylesheet
display: block;
list-style-type: disc;
-webkit-margin-before: 1em;
-webkit-margin-after: 1em;
-webkit-margin-start: 0px;
-webkit-margin-end: 0px;
-webkit-padding-start: 40px;
}

Что это такое?

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

>переработка базовых стилей


>Далее, тебе надо проработать базовые стили CSS. Сделай новый файл с пустым body и впиши в него простой HTML без классов, с тегами вроде h1, h2, ul, li, p, a, img, blockquote (если нет фантазии или лень писать, скопируй с http://motherfuckingwebsite.com/ ). У тебя этот текст выводится бледно-серым на белом фоне - это значит, базовые стили не продуманы совсем. Ты написал не базовый CSS для всего сайта, а стили для единственной страницы и при добавлении новых страниц твой ксс придется значительно переделывать.


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

Я старался найти ответы самому. Я могу хотя бы рамках обучения спросить подсказку? Учитывая что я первый раз верстаю. Что делать если такие не очевидные вопросы появится в боевых задачах? Такое поведение браузеров для меня очень странное, и я не знаю где я допустил пробел в изучении верстки, что у меня нету понимания почему так происходит.
>>874513
#463 #874329
>>874361
#464 #874336
>>873130
>>873130
я конечно только вкатывальщик с недельным стажем. но в пятой сточке не хватает открывающих кавычек. и вроде бы именно об этом написано внизу.
#465 #874349
Привет,
подскажите по JS 12 задаче:
метод hamburger.calculateCalories() указанный в примере работы с классом и метод Hamburger.prototype.getCalories указанный в заготовке класса, это разные методы? Если да, то чем они отличаются? Или один, просто названия разные?
>>874361
#466 #874361
>>874349

Это одно и то же, ОП опечатался.

>>874081

Программа не пишет в итоге, палиндром это или нет.

> PHP Notice: Use of undefined constant i - assumed 'i' in /home/54lEmO/prog.php on line 16


Надо исправить, ты знак доллара забыл наверно.

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

>>874329

Твоя программа любое слово считает палиндромом: http://ideone.com/0T6DlV

Ты ее хоть тестировал? И там внизу ошибка написана.

Ну и я бы советовал внимательнее читать официальный мануал или мои уроки. То, что функция strrev переворачивает строку в каких-то других языках, не значит, что она работает так же в PHP. В PHP она работает только с ASCII символами и не работает с кириллицей: https://gist.github.com/codedokode/ff99e357e9860ea169b8
#467 #874405
PHPч, помоги нуфаку. Нормальным ли является решение написание php скриптов прямо в html файле страницы? Как я понял, браузером они не отображаются. И как можно изолировать .php файлы от .html файлов, и как потом их вызывать в html-формах в атрибуте form [action], если .php скрипт изолирован от .html файла?
inb4 гугли собака
гуглю уже прямо сейчас, просто мб анон может сам расписать или дать линк на достоверный/годный источник, где расписаны за и против различных методов симбиоза html и php?
#468 #874411
>>874405
В файлах шаблонов лежит только вывод информации, вся логика работы лежит отдельно.
PHP, JS скрипты лежат отдельно.
Когда твой php-скрипт отработал и все данные уже в конечном виде находятся и готовы к отображению - подключаешь подходящий файл с шаблоном и выводишь информацию на экран.

Если у тебя есть форма для обратной связи: в атрибуте action хранится путь к файлу который будет обрабатывать информацию из твоей формы, в атрибуте method хранится способ передачи: (POST/GET). Когда ты отправил данные, скрипт из action её обработал (валидация данных и тд) исходя из того какой результат обработки ты возвращаешь пользователю ту же страницу с ошибками, либо с надписью, что всё ОК и тд. Лучше почитай у ОПа есть статья по работе с формами.
>>874417
#469 #874417
>>874411
Ага, благодарю. Подключать в .html файлы .php можно только <?php include '%path%/*.php' ?>
или есть более предпочтительные альтернативы?
>>874427
#470 #874421
>>874405
Гугли MVC. Если кратко - то пхп-код можно использовать только в шаблонах для вывода содержимого страницы. Допустим, есть у тебя пхп-код, в котором ты подключаещбся к БД и вытаскиваешь из нее инфу по юзеру. Выглядит примерно так:
$user = new User();
$user->getById(1) //метод который заполняет свойства объекта user по id
Дальше просто подключаешь шаблон(именно так тоже лучше не делать, просто для наглядности)
include 'user_template.html';
В подключаемом файле, помимо хедера и боди что-то вроде того:
<table>
<tr>
<td><?php> echo $user->name; </php></td>
<td><?php> echo $user->secondName; </php></td>
</tr>
</table>
Как-то так. Короче в шаблоне можно использовать немного пхпшного когда для вывода инфы, но вот в пхпшном коде нельзя. Если все правильно делаешь, то у тебя получается нормальное разделение когда на бизнес-логику(т.е. само программирование) и логику отображения(для того верстка и нужна).
>>874442
#471 #874427
>>874405

Есть статья http://www.phpinfo.su/articles/practice/shablony_v_php.html

> Нормальным ли является решение написание php скриптов прямо в html файле страницы?


Нет, это ведет к бардаку в коде.

> И как можно изолировать .php файлы от .html файлов, и как потом их вызывать в html-формах в атрибуте form [action], если .php скрипт изолирован от .html файла?


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

Тебе сначала надо на 100% в этом разобраться.

Алсо у меня есть урок по обработке форм ( https://github.com/codedokode/pasta/blob/master/forms.md ), но сначала тебе надо разобраться с тем что происходит при их отправке.

>>874417

Лучше require. Посмотри чем оно отличается от include.
>>874442
#472 #874438
>>873025
Ну так вот об этом и речь. Что непонятно нифига новичку, куда какие методы нужно писать. Некоторые вещи как например взаимодействие классов вообще не ясно как будет работать.

Например по моей логике как раз

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


За эту разную восприимчивость к разному урону будет отвечать обязательный для каждого существа объект армор.
#473 #874442
>>874421
Спасибо за ответ, пока, правда, не совсем понимаю сути
include 'user_template.html'
Типа берется шаблон разметки (причем не всей, а какой либо её части, типа только div с таблицой из бд), заполняется посредством скрипта php, который в свою очередь соединяется с MySQL (кстати, только MySQL или возможны соединения с любыми БД, типа там постгрес, мсскл, и прочие?) бд, а потом заполненный контентом кусок html подгружается пользователю через какой нибудь ajax?
>>874427

>Что по твоему указывается в атрибуте action у тега form? Ты можешь объяснить, что происходит когда ты заполняешь форму и нажимаешь кнопку отправки?


На данный момент думаю (не знаю точно, но исходя из того, что успел прочитать по html, js и php), по нажатию input-элемента с type-submit происходит invoke действия, указанного в action. В целом, как я понимаю, туда можно захуячить что угодно: js code, php code, главное, чтобы браузер мог это выполнить. Думаю, что в action <form> можно указать путь к .php файлу, который содержит инструкции, которые необходимо выполнить, используя полученные от клиента параметры из $_GLOBALS и прочих $_POST $_GET, ну и потом по необходимости сообщить клиенту соответствующий ответ.
Насчёт урока и require вместо include - патиба, сейчас посмотрю.
>>874453
#474 #874453
>>874442

>Типа берется шаблон разметки (причем не всей, а какой либо её части, типа только div с таблицой из бд), заполняется посредством скрипта php, который в свою очередь соединяется с MySQL (кстати, только MySQL или возможны соединения с любыми БД, типа там постгрес, мсскл, и прочие?) бд, а потом заполненный контентом кусок html подгружается пользователю через какой нибудь ajax?


Смотри. Ты видимо не до конца понял что такое программирование, а что такое верстка. Представь что ты работаешь в команде из двух человек. Ты кодер - т.е. делаешь внутренную логику сайта, а твой напарник верстальщик, он делает красивый дизайн. Ты плохо разбираешься в верстке, он плохо в программировании. Задача, допустим, сделать маленький новостной сайт. Есть база данных(любая - mysql, postrge)в ней таблица - с новостями, поля - id новости(надеюсь ты понимаешь что это и зачем оно), заголовок новости, автор, ну и содержимое. Твоя задача как кодера - написать код, который каким-то образом вытаскивает данный из таблица и представляет ее в удобном виде(массив новостей, а еще луче массив объектов-новостей). А верстальщик делает красивую верстку для странички со списком новостей. Вот и подумай - будет ли вам удобно работать с кодом, где все это смешано? Того то и разделяют дизайн(отображение) и логику(код). Допустим ты сделал свой код, в качестве условного шаблона просто подключаешь сначала пустой шаблон в котором максимум выводишь все данные из весртки, а верстальщик уже расставляет эти данные что бы все красиво выглядело.
1267 Кб, 800x567
#475 #874470
Привет, анон. Нужен твой совет. Суть такова. Живу в сраной Украшке. И срочно потребовалась прибавка к зп, небольшая по московским или даже киевским меркам, может и небольшое, но по нашим мухосранским достаточно ощутимая. И я в общем-то наслышан, что Пых предоставляет такую возможность. Знаю английский на хорошем уровне. Из программирования знаком с сишкой (по учебнику Дейтела) и Жабку на уровне первого тома опус магнума Хорстманна-Корнелла. Я просто в начале года пытался раньше вкатиться в кодинг, но обстоятельства так сложились, что очень мало было свободного времени, да и то проебал попусту.

Так вот в чём вопрос. Сейчас как раз у меня нечто вроде отпуска почти на месяц, свободное время есть. Имеет ли смысл его потратить на пых, вместо того чтобы ковырять жабку? И как это сделать максимально быстро? Имеет ли смысл следовать гайду в оп-посте, или мой мизерный и не из этой оперы опыт поможет мне начать с чего-то более хардкорного, но быстрее?
#476 #874473
>>874470
Ну то есть ты хочешь за месяц вкатится во фриланс на языке, с которым не знаком + не имея опыта коммерческой разработки вообще ни на одном языке?
>>874476
#477 #874474
>>874470
Тут наверное стоит упомянуть какие вещи ты писал на каких языках, потому что книги, которые ты прочитал ни о чем не говорят, судить о твоих скилах можно только по практическому опыту.
#478 #874476
>>874473
ну не за месяц, естественно, за 5-6 хотя б. Просто этот месяц как раз свободен и хочется использовать его предельно эффективно.
>>874483
#479 #874482
>>874470
Чё-т не пойму эту гифку, не в первый раз вижу, только сейчас заинтересовался.
Какого чёрта deadline переносится, когда соня переносит с 15 пятницы на 13 среды? Dead - по этой логике - должна была пройти мимо его...

По сути твоего поста: всё имеет смысл. В PHP ты вкатишься быстро, если Javascript знаешь, поскольку PHP почти полностью копирует Javascript (ну, мне так показалось, когда одно после другого изучал, а JS всё-таки появился раньше и намного).
Другое дело, что надо будет разбираться во всяких CMS, работающих на PHP, а этого за месяц не освоить.
Но пробовать надо всегда и в любом случае.
#480 #874483
>>874476
PHP, JS сейчас основные направления во фрилансе.
https://github.com/anonymous011010/studentslist #481 #874485
>>865783
>>868436
>>874162

> https://github.com/anonymous011010/studentslist/blob/master/studentslist.sql#L38


> UNIQUE KEY `id_UNIQUE` (`id`),


Это не нужно так как первичный ключ по определению (ПК = идентификатор записи) уникален.

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

https://github.com/anonymous011010/studentslist/blob/master/app/bootstrap.php
Задача бутстрап-скрипта только инициализировать приложение и подготовить к работе. А не определять УРЛ и запускать контроллер. Ну вот например если мы захотим написать скрипт для командной строки, мы не сможем использовать бустрап файл, так как он попытается запустить контроллер, который в командной строке не имеет никакого смысла.

В твоем случае содержимое бустрап файла можно было бы просто поместить в index.php.

https://github.com/anonymous011010/studentslist/blob/master/app/bootstrap.php#L9
Мне не очень нравится идея использования констант для настроек: они доступны везде глобально и мы не можем ограничить область, где они доступны, не можем их передать только в определенные объекты.

https://github.com/anonymous011010/studentslist/blob/master/app/Handler.php
Этот класс стоило поместить в файл, путь к которому соответствует неймспейсу. Название стоит поменять, так как Handler значит "обработчик" и непонятно, что именно он обрабатывает.

Имена функций принято начинать с глагола, handleError, а не errorHandler.

https://github.com/anonymous011010/studentslist/blob/master/app/Handler.php#L33
У тебя не очень логичный подход в обработке ошибок. Если произошла ошибка, то ты продолжаешь выполнять программу, скорее всего с неправильными данными.

На мой взгляд единственно верный способ обработки ошибок это преобразование их в исключения: http://php.net/manual/ru/class.errorexception.php

Непонятно, почему разработчики PHP не сделали так с самого начала. Вся эта идея с 20 видами ошибок - пример неправильного проектирования. Статья по теме: https://habrahabr.ru/post/218325/

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

Также, ты по моему изобретаешь велосипеды. Ну например, ты выводишь ошибки при установленном APP_DEBUG, но в php.ini уже есть настройка, отвечающая за вывод ошибок на экран: display_errors.

Ты делаешь свой логгер, но в PHP уже есть лог ошибок и возможность писать в него через error_log(). В чем смысл заводить отдельный лог?

Наконец, если уж делать логгер, то лучше следовать интерфейсу логгера из PSR-3:

- (англ) http://www.php-fig.org/psr/psr-3/
- (рус) http://svyatoslav.biz/misc/psr_translation/#_PSR-3

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

Также, в логгере не очень понятно назначение метода setLogFile(). Зачем может понадобиться менять путь к лог-файлу в процессе? Разве недостаточно указать его при создании объекта?

Запись в файл сделана довольно неэффективно. Если тебе надо что-то писать в файл кусочками, то стандатный способ - fopen/write/fclose, а ты по сути на каждое сообщение открываешь и закрываешь файл.

> \RuntimeException('Unable to create the log file');


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

> public function log($type, $message, $file, $line) {


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

https://github.com/anonymous011010/studentslist/blob/master/app/Handler.php#L12

> Logger::getInstance();


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

https://github.com/anonymous011010/studentslist/blob/master/app/bootstrap.php#L7
use принято ставить в самом начале файла.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Core/Router.php#L14
Здесь тоже сделано нелогично. Конструктор предназначен для инициализации и подготовке объекта к использованию. Нелогично и неожиданно что конструктор может внезапно вызвать контроллер, который выведет страницу.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Core/Router.php#L45

> if ($_SERVER['REQUEST_URI']) {


А что будет если условие не сработает?

> return $url = \explode


Зачем тут "$url = "? зачем создавать переменную, которая нигде после не используется?

> list($urlPath, ) = \explode('?', \filter_input(\INPUT_SERVER, 'REQUEST_URI', \FILTER_SANITIZE_URL));


для этого есть функция parse_url

> \rtrim(\ltrim($urlPath, '/'), '/')


trim умеет обрезать с обоих сторон.

> if (\class_exists('\Studentslist\\Controllers\\' . \ucfirst($url[0]) . 'Controller')) {


> $this->controller = \ucfirst($url[0]);


Тут тоже нелогично, получается при любом несуществующем URL вроде /asdasdad будет вызван контроллер index, а должна быть страница 404.

Ну и твой метод роутинга на мой взгляд неудачный, так как он допускает существование множества URL для одной страницы, вроде /index/action/1/2/3/4/5/6/7/8, хотя у каждой страницы должен быть единственный URL.

> $page = ((!$page) || ($page < 1)) ? 1 : $page;


тут удобнее использовать max()

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Core/Controller.php#L15

> Метод получения объекта класса StudentDataGateway


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

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

> $token = (isset($_COOKIE['authToken'])) ? \filter_input(\INPUT_COOKIE, 'authToken',


> if ($auth->isRegistred($token)) {


Получение токена тоже наверно лучше инкапсулировать в класс авторизации

> $ErrorController = new \Studentslist\Controllers\ErrorController;


> $ErrorController->error404();


Название метода должно начинаться с глагола.

> \filter_input(\INPUT_GET, 'order', \FILTER_SANITIZE_STRING)


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

Методы search() и all() очень похожи, зачем 2 раза писать одно и то же?

> \filter_input(\INPUT_GET, 'q')


А что эта функция делает?

> public static function renderViewTable


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

> exit(0);


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

> public static function renderErrorView


Непонятно, чем это отличается от public static function renderView.

И кстати, почему методы render статические?

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Controllers/FormController.php
Тут методы редактирования и регистрации почти одинаковые. Не надо копипастить код.

Вообще, у тебя в коде слишком много die и exit. Я бы их убрал.

> header("Refresh:5; url=" . \APP_URL_ADDR, true, 303)


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

> } catch (\PDOException $ex) {


> $data['fail']['message'] = "Не удалось изменить данные, пожалуйста, повторите попытку снова.";


PDOException возникает при ошибке работы с БД, например если SQL запрос написан непраивльно. Какой смысл писать особый код для обработки этой ошибки? У тебя ведь уже есть страница на случай исключения.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Controllers/FormController.php#L81
тут слишком много вызовов renderView на мой взгляд.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/DBHelper.php#L26

> public function getOrder($order) {


Это проще переписать через массив разрешенных значений и in_array

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/DBHelper.php#L72
Это нужно для записи в БД? Тогда этот метод должен быть в StudentDataGateway.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/Paginator.php#L24
тут слишком много аргументов у конструктора. Надо либо передавать опции массивом, либо, что лучше, разделить их на обязательные и необязательные, необязельные задавать отдельными методами.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/Paginator.php#L81

> public function __set($property, $value) {


Попытка обращения к несуществующему свойству не вызовет ошибки и останется незамеченной.

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

В ссылки не обязательно подставлять имя хоста, хватило бы относительной ссылки.
https://github.com/anonymous011010/studentslist #481 #874485
>>865783
>>868436
>>874162

> https://github.com/anonymous011010/studentslist/blob/master/studentslist.sql#L38


> UNIQUE KEY `id_UNIQUE` (`id`),


Это не нужно так как первичный ключ по определению (ПК = идентификатор записи) уникален.

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

https://github.com/anonymous011010/studentslist/blob/master/app/bootstrap.php
Задача бутстрап-скрипта только инициализировать приложение и подготовить к работе. А не определять УРЛ и запускать контроллер. Ну вот например если мы захотим написать скрипт для командной строки, мы не сможем использовать бустрап файл, так как он попытается запустить контроллер, который в командной строке не имеет никакого смысла.

В твоем случае содержимое бустрап файла можно было бы просто поместить в index.php.

https://github.com/anonymous011010/studentslist/blob/master/app/bootstrap.php#L9
Мне не очень нравится идея использования констант для настроек: они доступны везде глобально и мы не можем ограничить область, где они доступны, не можем их передать только в определенные объекты.

https://github.com/anonymous011010/studentslist/blob/master/app/Handler.php
Этот класс стоило поместить в файл, путь к которому соответствует неймспейсу. Название стоит поменять, так как Handler значит "обработчик" и непонятно, что именно он обрабатывает.

Имена функций принято начинать с глагола, handleError, а не errorHandler.

https://github.com/anonymous011010/studentslist/blob/master/app/Handler.php#L33
У тебя не очень логичный подход в обработке ошибок. Если произошла ошибка, то ты продолжаешь выполнять программу, скорее всего с неправильными данными.

На мой взгляд единственно верный способ обработки ошибок это преобразование их в исключения: http://php.net/manual/ru/class.errorexception.php

Непонятно, почему разработчики PHP не сделали так с самого начала. Вся эта идея с 20 видами ошибок - пример неправильного проектирования. Статья по теме: https://habrahabr.ru/post/218325/

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

Также, ты по моему изобретаешь велосипеды. Ну например, ты выводишь ошибки при установленном APP_DEBUG, но в php.ini уже есть настройка, отвечающая за вывод ошибок на экран: display_errors.

Ты делаешь свой логгер, но в PHP уже есть лог ошибок и возможность писать в него через error_log(). В чем смысл заводить отдельный лог?

Наконец, если уж делать логгер, то лучше следовать интерфейсу логгера из PSR-3:

- (англ) http://www.php-fig.org/psr/psr-3/
- (рус) http://svyatoslav.biz/misc/psr_translation/#_PSR-3

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

Также, в логгере не очень понятно назначение метода setLogFile(). Зачем может понадобиться менять путь к лог-файлу в процессе? Разве недостаточно указать его при создании объекта?

Запись в файл сделана довольно неэффективно. Если тебе надо что-то писать в файл кусочками, то стандатный способ - fopen/write/fclose, а ты по сути на каждое сообщение открываешь и закрываешь файл.

> \RuntimeException('Unable to create the log file');


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

> public function log($type, $message, $file, $line) {


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

https://github.com/anonymous011010/studentslist/blob/master/app/Handler.php#L12

> Logger::getInstance();


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

https://github.com/anonymous011010/studentslist/blob/master/app/bootstrap.php#L7
use принято ставить в самом начале файла.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Core/Router.php#L14
Здесь тоже сделано нелогично. Конструктор предназначен для инициализации и подготовке объекта к использованию. Нелогично и неожиданно что конструктор может внезапно вызвать контроллер, который выведет страницу.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Core/Router.php#L45

> if ($_SERVER['REQUEST_URI']) {


А что будет если условие не сработает?

> return $url = \explode


Зачем тут "$url = "? зачем создавать переменную, которая нигде после не используется?

> list($urlPath, ) = \explode('?', \filter_input(\INPUT_SERVER, 'REQUEST_URI', \FILTER_SANITIZE_URL));


для этого есть функция parse_url

> \rtrim(\ltrim($urlPath, '/'), '/')


trim умеет обрезать с обоих сторон.

> if (\class_exists('\Studentslist\\Controllers\\' . \ucfirst($url[0]) . 'Controller')) {


> $this->controller = \ucfirst($url[0]);


Тут тоже нелогично, получается при любом несуществующем URL вроде /asdasdad будет вызван контроллер index, а должна быть страница 404.

Ну и твой метод роутинга на мой взгляд неудачный, так как он допускает существование множества URL для одной страницы, вроде /index/action/1/2/3/4/5/6/7/8, хотя у каждой страницы должен быть единственный URL.

> $page = ((!$page) || ($page < 1)) ? 1 : $page;


тут удобнее использовать max()

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Core/Controller.php#L15

> Метод получения объекта класса StudentDataGateway


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

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

> $token = (isset($_COOKIE['authToken'])) ? \filter_input(\INPUT_COOKIE, 'authToken',


> if ($auth->isRegistred($token)) {


Получение токена тоже наверно лучше инкапсулировать в класс авторизации

> $ErrorController = new \Studentslist\Controllers\ErrorController;


> $ErrorController->error404();


Название метода должно начинаться с глагола.

> \filter_input(\INPUT_GET, 'order', \FILTER_SANITIZE_STRING)


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

Методы search() и all() очень похожи, зачем 2 раза писать одно и то же?

> \filter_input(\INPUT_GET, 'q')


А что эта функция делает?

> public static function renderViewTable


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

> exit(0);


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

> public static function renderErrorView


Непонятно, чем это отличается от public static function renderView.

И кстати, почему методы render статические?

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Controllers/FormController.php
Тут методы редактирования и регистрации почти одинаковые. Не надо копипастить код.

Вообще, у тебя в коде слишком много die и exit. Я бы их убрал.

> header("Refresh:5; url=" . \APP_URL_ADDR, true, 303)


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

> } catch (\PDOException $ex) {


> $data['fail']['message'] = "Не удалось изменить данные, пожалуйста, повторите попытку снова.";


PDOException возникает при ошибке работы с БД, например если SQL запрос написан непраивльно. Какой смысл писать особый код для обработки этой ошибки? У тебя ведь уже есть страница на случай исключения.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Controllers/FormController.php#L81
тут слишком много вызовов renderView на мой взгляд.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/DBHelper.php#L26

> public function getOrder($order) {


Это проще переписать через массив разрешенных значений и in_array

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/DBHelper.php#L72
Это нужно для записи в БД? Тогда этот метод должен быть в StudentDataGateway.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/Paginator.php#L24
тут слишком много аргументов у конструктора. Надо либо передавать опции массивом, либо, что лучше, разделить их на обязательные и необязательные, необязельные задавать отдельными методами.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/Paginator.php#L81

> public function __set($property, $value) {


Попытка обращения к несуществующему свойству не вызовет ошибки и останется незамеченной.

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

В ссылки не обязательно подставлять имя хоста, хватило бы относительной ссылки.
>>875036
https://github.com/anonymous011010/studentslist #482 #874486
>>865783
>>868436
>>874162

Еще, задачи классов TableHelper, NavHelper, Paginator довольно-таки сильно пересекаются, не лучше ли генерацию ссылок перенести в один класс и передавать параметры как аргументы, вроде такого:

getStudentTableLink($order = null, $sort = null, $query = null)

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

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/TokenHelper.php
На мой взгляд создание аутентификационного токена логичнее делать в классе Auth.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Models/Student.php#L41
Вот не уверен, что тут надо делать read only свойство через магические методы. Не лучше ли сделать геттер и тем самым явно показать что оно только для чтения?

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

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Models/StudentDataGateway.php#L42
LIMIT и OFFSET надо бы поставлять через плейсхолдеры. Я вижу что тут переменные вставляются прямо в SQL запрос, значит возможна SQL инъекция.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Models/StudentDataGateway.php#L42

> public function addStudent(array $student) {


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

> SELECT EXISTS(SELECT `id`


Проще писать просто SELECT id ... LIMIT 1 или SELECT COUNT(*)

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Models/StudentValidator.php
Неудачная идея возвращать true либо строку. Логичнее при отсутствии ошибок возвращать пустое значение.

> (\S[^@])+


А что это значит? Должны чередоваться не-пробел и не-@? Вроде "@ @ @ @ @ @" ?

> if (!\preg_match_all($regExp, $email)) {


preg_match_all используется для поиска нескольких совпадений с регуляркой, тут логичнее использовать preg_match

> } elseif ($this->gateway->checkEmailExists($email)) {


> if ($this->gateway->getEmailOwnerId($email) != $id) {


Это кстати можно сделать одним SQL запросом

> "/^([а-яё]+[-\\s']?){1,32}$/


Эта регулярка пропустит гораздо больше 32 символов.

Для значений пола стоит завести константы Student::GENDER_MALE. Для метса жительства либо константы, либо true/false.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Views/navbar.php#L23

> value="<?= (isset($data['search'])) ? $data['search'] : ''; ?>">


тут возможна XSS

> <li class="disabled"><a href="#">…</a></li>


Что это за ссылка с адресом #? Тут надо использовать спан вместо <a>.

> endif;


каждую такую команду в шаблоне принято заключать в <?php ?>

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Views/results.php этот файл очень похож на index.php

Имена шаблонов обычно выбирают, чтобы они соответствовали именам контроллеров и действий.

> Возможна попытка CSRF-атаки, пожалуйста, проверьте


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

Чтобы не писать везде в шаблоне $data, обычно данные из массива превращают в переменные с помощью extract().

https://github.com/anonymous011010/studentslist/blob/master/logs/.gitignore
gitignore лучше класть в корень проекта в одном экземпляре.
https://github.com/anonymous011010/studentslist #482 #874486
>>865783
>>868436
>>874162

Еще, задачи классов TableHelper, NavHelper, Paginator довольно-таки сильно пересекаются, не лучше ли генерацию ссылок перенести в один класс и передавать параметры как аргументы, вроде такого:

getStudentTableLink($order = null, $sort = null, $query = null)

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

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Helpers/TokenHelper.php
На мой взгляд создание аутентификационного токена логичнее делать в классе Auth.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Models/Student.php#L41
Вот не уверен, что тут надо делать read only свойство через магические методы. Не лучше ли сделать геттер и тем самым явно показать что оно только для чтения?

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

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Models/StudentDataGateway.php#L42
LIMIT и OFFSET надо бы поставлять через плейсхолдеры. Я вижу что тут переменные вставляются прямо в SQL запрос, значит возможна SQL инъекция.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Models/StudentDataGateway.php#L42

> public function addStudent(array $student) {


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

> SELECT EXISTS(SELECT `id`


Проще писать просто SELECT id ... LIMIT 1 или SELECT COUNT(*)

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Models/StudentValidator.php
Неудачная идея возвращать true либо строку. Логичнее при отсутствии ошибок возвращать пустое значение.

> (\S[^@])+


А что это значит? Должны чередоваться не-пробел и не-@? Вроде "@ @ @ @ @ @" ?

> if (!\preg_match_all($regExp, $email)) {


preg_match_all используется для поиска нескольких совпадений с регуляркой, тут логичнее использовать preg_match

> } elseif ($this->gateway->checkEmailExists($email)) {


> if ($this->gateway->getEmailOwnerId($email) != $id) {


Это кстати можно сделать одним SQL запросом

> "/^([а-яё]+[-\\s']?){1,32}$/


Эта регулярка пропустит гораздо больше 32 символов.

Для значений пола стоит завести константы Student::GENDER_MALE. Для метса жительства либо константы, либо true/false.

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Views/navbar.php#L23

> value="<?= (isset($data['search'])) ? $data['search'] : ''; ?>">


тут возможна XSS

> <li class="disabled"><a href="#">…</a></li>


Что это за ссылка с адресом #? Тут надо использовать спан вместо <a>.

> endif;


каждую такую команду в шаблоне принято заключать в <?php ?>

https://github.com/anonymous011010/studentslist/blob/master/app/Studentslist/Views/results.php этот файл очень похож на index.php

Имена шаблонов обычно выбирают, чтобы они соответствовали именам контроллеров и действий.

> Возможна попытка CSRF-атаки, пожалуйста, проверьте


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

Чтобы не писать везде в шаблоне $data, обычно данные из массива превращают в переменные с помощью extract().

https://github.com/anonymous011010/studentslist/blob/master/logs/.gitignore
gitignore лучше класть в корень проекта в одном экземпляре.
>>875036
#483 #874502
Молю, помогите сделать запрос
http://ideone.com/HNVYLP
>>874506
#484 #874506
>>874502
Для начала у тебя в echo не открыта кавычка перед текстом.
>>874516
#485 #874513
>>874239

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

Проблемы со шрифтами

У меня в Хромиуме не работают кастомные шрифты.

При этом на вкладке Network в отладчике я вижу, что идет загрузка файла https://someapprentice.github.io/maintaskforlayout/fonts/lato-black-webfont.woff (только этого почему-то)

Я попробовал открыть страницу в фаерфоксе и там в отладчике пошли ошибки:

> downloadable font: invalid version tag (font-family: "Lato" style:normal weight:normal stretch:normal src index:0)


source: > https://someapprentice.github.io/maintaskforlayout/fonts/Lato-Regular.eot stylesheets.css

Видимо при наличии 2 атрибутов src браузер грузит шрифт по самой первой ссылке, и так как не понимает формат eot, бросает это дело.

Я в отладчике Хрома на вкладке Sources отредактировал твой CSS и убрал лишнюю строчку src - и шрифт заработал.

Есть статья на Хабре с проверенным синтаксисом

- https://habrahabr.ru/post/113136/
- (англ, более подробно) http://blog.fontspring.com/2011/02/the-new-bulletproof-font-face-syntax/

> Даже оригинальный otf формат шрифта главного заголовка не отображается в ie6-8. В отличие от шрифта Lato.



Для старых IE скорее всего нужен eot.

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

> firefox, webkit Наличие описания веса bolder переопределяет значение normal, т.е. c regular на bolder


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

И еще, font-weight bold и font-weight 700 по моему это одно и то же. bold это синоним 700:

https://www.w3.org/TR/CSS2/fonts.html#font-boldness

"firefox Лёгкие шрифты не определяются" - а где это можно увидеть? Без кода я не могу проверить. Можешь на jsfiddle или отдельной html страницей сделать пример?

С шрифтами надо бы разобраться.

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


Ну я сомневаюсь что есть устройства меньше 320px: http://mydevice.io/devices/

Дефолтные стили

> Ещё я заметил странный отступ у ссылок на соц.сети в webkit'е. Его задает ul, menu, dir { user agent stylesheet


user agent stylesheet - это встроенные в браузер CSS стили. Их можно увидеть в исходных кодах браузера по ссылкам тут:

http://stackoverflow.com/questions/6867254/browsers-default-css-for-html-elements/6867287#6867287

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

Стили по умолчанию отображают HTML примерно так, как отображали первые браузеры.

В твоем примере

ul {
display: block;
list-style-type: disc;
-webkit-margin-before: 1em;

задает, что тег ul по умолчанию имеет указанные свойства. Например, что он блочный, что элементы списка в нем маркируются точками и что перед ним делается отступ в 1em.

Стили по умолчанию надо учитывать, если они тебе мешают, то можно переопределить нужные своства.

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


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

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

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

Для соцсетей надо сделать изменение при наведении.

Сам код посмотрю наверно попозже.
#485 #874513
>>874239

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

Проблемы со шрифтами

У меня в Хромиуме не работают кастомные шрифты.

При этом на вкладке Network в отладчике я вижу, что идет загрузка файла https://someapprentice.github.io/maintaskforlayout/fonts/lato-black-webfont.woff (только этого почему-то)

Я попробовал открыть страницу в фаерфоксе и там в отладчике пошли ошибки:

> downloadable font: invalid version tag (font-family: "Lato" style:normal weight:normal stretch:normal src index:0)


source: > https://someapprentice.github.io/maintaskforlayout/fonts/Lato-Regular.eot stylesheets.css

Видимо при наличии 2 атрибутов src браузер грузит шрифт по самой первой ссылке, и так как не понимает формат eot, бросает это дело.

Я в отладчике Хрома на вкладке Sources отредактировал твой CSS и убрал лишнюю строчку src - и шрифт заработал.

Есть статья на Хабре с проверенным синтаксисом

- https://habrahabr.ru/post/113136/
- (англ, более подробно) http://blog.fontspring.com/2011/02/the-new-bulletproof-font-face-syntax/

> Даже оригинальный otf формат шрифта главного заголовка не отображается в ie6-8. В отличие от шрифта Lato.



Для старых IE скорее всего нужен eot.

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

> firefox, webkit Наличие описания веса bolder переопределяет значение normal, т.е. c regular на bolder


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

И еще, font-weight bold и font-weight 700 по моему это одно и то же. bold это синоним 700:

https://www.w3.org/TR/CSS2/fonts.html#font-boldness

"firefox Лёгкие шрифты не определяются" - а где это можно увидеть? Без кода я не могу проверить. Можешь на jsfiddle или отдельной html страницей сделать пример?

С шрифтами надо бы разобраться.

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


Ну я сомневаюсь что есть устройства меньше 320px: http://mydevice.io/devices/

Дефолтные стили

> Ещё я заметил странный отступ у ссылок на соц.сети в webkit'е. Его задает ul, menu, dir { user agent stylesheet


user agent stylesheet - это встроенные в браузер CSS стили. Их можно увидеть в исходных кодах браузера по ссылкам тут:

http://stackoverflow.com/questions/6867254/browsers-default-css-for-html-elements/6867287#6867287

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

Стили по умолчанию отображают HTML примерно так, как отображали первые браузеры.

В твоем примере

ul {
display: block;
list-style-type: disc;
-webkit-margin-before: 1em;

задает, что тег ul по умолчанию имеет указанные свойства. Например, что он блочный, что элементы списка в нем маркируются точками и что перед ним делается отступ в 1em.

Стили по умолчанию надо учитывать, если они тебе мешают, то можно переопределить нужные своства.

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


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

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

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

Для соцсетей надо сделать изменение при наведении.

Сам код посмотрю наверно попозже.
>>874968
#486 #874516
>>874506
Не помогло
>>874519
#487 #874519
>>874516
На ideone ты это не запустишь в любом случае
>>874525
#488 #874525
>>874519
Я знаю
#489 #874531
>>873037

http://ideone.com/Q9Ypyc

Шестнадцатая! Осталось переделать гамбургеры, электростанции и типы переменных, и на DOM.
>>874536
#491 #874554
А бывают стримы программирования, типа твича для программистов?
38 Кб, 500x434
#492 #874556
>>874554
Сразу вспомнил.
#493 #874559
>>874554
Да, у хекслета бывают. У меня приятель может постримить жаваскрипт.
>>874561
#494 #874560
>>874554
Хотел было пошутить, но они и вправду есть.
https://www.livecoding.tv/wpkenpachi/
40 Кб, 600x600
#495 #874561
>>874559

>постримить жаваскрипт.


Заржал на весь дом.
>>874594
#496 #874578
Статья на Хабре: Принимая PHP всерьез: https://m.habrahabr.ru/post/314970/

Разработчики Slack: "...По итоговым результатам, PHP предоставляет наилучший фундамент для создания, изменения и эксплуатации успешного веб-проекта по сравнению с конкурирующими средами. Сегодня я хотел бы начать новый проект на PHP...."

К кому мы прислушаемся, к разработчикам добившегося многомиллионного успеха стартапа или живущим на мамкином борще анонимным экспертам из раздела /pr/?
>>874579>>874581
#497 #874579
>>874578
Конечно программистов с двача.
#498 #874581
>>874578
Я конечно ньюфаг в PHP но

>К примеру, 123 == '123foo' оценивается как истина (что он там делает?), но 0123 == '0123foo' является ложью (хмм).


какого хрена вообще кому-то пришло в голову сравнивать число со строкой? Почему когда Антон делает это на Java - ему говорят "Ты чё, дебил?", а когда так делат на PHP - "Это язык странный".
#499 #874584
>>874581
Динамическое типизирование, оно такое.
#500 #874585
>>874581

В Яве еще веселее. Там строки - это объекты класса String и при сравнении через

s1 == s2

сравнивается не содержимое, а проверяется, ссылаются ли s1 и s2 на один и тот же объект. То есть 2 разных объекта, содержащих одинаковые строки, дадут false.

Сравнивать надо через метод, как if (s1.equals(s2))

Справедливости ради, в С++, от которого отпочковалась Ява, примерно такая же ерунда, если не переопределить оператор сравнения для класса строк.

Но конечно, все эти неявные преобразования в PHP это проблема в дизайне языка, добавленная давно в ранних версиях. Я надеюсь, что в будущем либо что-нибудь придумают либо в самом PHP либо в том же HHVM который не так печется о совместимости.
>>874590
#501 #874590
>>874585

>2 разных объекта, содержащих одинаковые строки, дадут false.


Кошмар. Меня до сих пор передёргивает от арифметических операций в JAVA и от бесконечных циклов как вполне себе обычное дело для реализации демонов.
>>874593>>874597
#502 #874592
>>874581
0 указывает на восьмиричную систему счисления. Так что здесь как раз все ок.
#503 #874593
>>874590
в пхп тоже будет вечный цикл при реализации демона , нужно понимать просто механизм работы демона
#504 #874594
>>874561
Ну в прошлый раз смотерл, он какой-то проект делал, я не уточнял.
#505 #874595
>>874581

> вообще кому-то пришло в голову сравнивать число со строкой?


Дело в том, что в твоей программе может произойти такая ситуация, когда ты будешь ожидать сравнения строки со строкой, а получишь число из-за закравшегося неведомо где бага. Решение крайне простое - ВСЕГДА использовать === (оператор сравнения без конвертации типов). JS-линтеры даже ругаются, если видят в коде двойное равно.
Алсо, кто как борется с отсутствием тайп-хантинга в JS? Браться за TypeScript/Flow не очень хочется. Вот вроде интересная либа: http://is.js.org/
но многовато туда всего напихали.
>>874599
#506 #874597
>>874590

>бесконечные циклы фуууу


Ну и как большие мальчики демонов делают?
#507 #874599
>>874595
Хз, я вот в typescript вкатываюсь попутно изучая angular2. Ванильный js знаю неплохо.
#508 #874608
Поясните, уже ведь нет смысла делать соединение с БД синглтоном?
#509 #874655
У вас тут ньюфажеские вопросы по HTML допускаются, а то отдельного треда не нашёл ни в /pr, ни в /web. Короче, допустим, есть сайт, у которого есть некоторая статическая часть: хэдер над меню, само меню (nav > ul), и футер. Хочу добиться следующего: при нажатии на кнопку в меню, в div (такой то wrapper) под меню идёт подгрузка контента html файла с помощью ajax'a. Всё бы казалось чикибрики, но, при обновлении страницы, меня, естессно, кидает на основную страницу. Следовательно, при подгрузке контента раздела сайта мне нужно менять текущий URL в браузере, что я хз как сделать.
Мне кажется жутко уебищным в каждом html-файле раздела дублировать
<head></head>
<nav><ul></ul></nav>
<footer>
и то, что до блока с контентом. Какие есть workaround'ы для этой проблемы? или проблема в том, что я ебучая макака и неправильно проектирую дерево сайта?
Сейчас пытаюсь сделать что то типа следующего: по нажатию на кнопку вообще, <a href="nextpage.html">" в меню на основной странице идёт переход на страницу nextpage.html, в которой находится только контент раздела, при этом через jquery подгружаю то, что должно быть до контента (head, nav>ul) и то что должно быть после (footer), и только по завершению after(). делаю .show("fast");
Как такой вариант? Или это ещё уебищнее, чем дублировать в каждом html-файле head, nav>ul и footer?
>>874661
#510 #874661
>>874655
Ой, вот я бедил. Для этого, походу, php как раз и можно использовать. Использование include('pagename.html'); нормальная практика?
#511 #874792
>>870547
Контора какая? Или чем занимается, если боишься деанона?
>>874797
#512 #874797
>>874792
А, видимо, веб-студия.
#513 #874845
Можно ли как то по вызову submit у формы вывести результаты некоторой работы в пхп скрипте на ту же страницу в определенном месте, например, в каком нибудь div'е под самой формой, и чтоб без перезагрузки страницы? Или только заново страницу загружать с результатами обработки формы?
>>874862>>874944
#514 #874862
>>874845
без перезагрузки только с AJAX/JQUERY
#515 #874944
>>874845
Не уверен точно, но попробуй через заголовки.
244 Кб, 1864x1398
#516 #874960
Вообщем решил я сделать список студентов, и в итоге по быстрому получилось вот сие https://github.com/InitF/StudentList . До этого пришлось немного поработать на Yii2, так что структура в общем может быть похожа. Собственно чего можете посоветовать (окромя самоубийства и стерилизации). Особенно интересно, как лучше разгрести ад в controllers/RegController.
>>876772
#517 #874968
>>874513

>Я попробовал открыть страницу в фаерфоксе и там в отладчике пошли ошибки:


Я не знал про этот инструмент. Я посмотрел что там за ошибки и исправил их. У меня был лишний пробел в описании форматов format (. Я исправил этот пробел, и это починило всё(!), за исключением наклона и отсутствия легких шрифтов в ie<8.

Далее, я убрал лишнюю строчку src, это не на что не повлияло - в ie шрифы ставятся, но с теми же багами.

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

webkit, firefox Перестают определять шрифт regular
firefox <b> теряет жирность (можно починить добавив этому элементу свойство font-weight: bold)
ie По прежнему легкие шрифты не определяются. Однако, в ie определятся шрифт regular.
ie<8 И по прежнему отсутствие цифровых значений веса чинят наклонность у жирных шрифтов

Я решил что можно определить шрифт regular цифровым значением т.е. 400, это починило регулярные шрифты, но сломало легкие. Я точно так же определил шрифты для легких задав значение 100. Что-то из этого сломало легкие наклонные шрифты в ie>8 сделав их жирными наклонными. Это так же починилось определив наклонный шрифт цифровым значением т.е. задав font-weidght: 100 и font-style: italic.

В ie<8 по прежнему не отображаются легкие шрифты (заместо них regular).

Firefox, кстати, всё равно выдает ошибки парсинга font-weight на значения bolder и lighter (если их убрать то ничего не изменится). Как такое может быть?

https://github.com/someApprentice/maintaskforlayout
https://someapprentice.github.io/maintaskforlayout/
>>875380
#518 #874970
>>864640 (OP)
Почему если при использовании YII2, я убираю имя формы из правила required в функции rules, то в переменной создания экземпляра класса модели значение поле формы не передаеётся? Передаются только те, которые указаны как required? Значения же сами должны передаваться, вне зависимости от того, обязательно поле для заполнения или нет?
>>875005>>875379
#519 #874984
Задам ещё один вопрос, по YII2, да и вообще. Допустим, в контроллере я добавлюя некоторую строку с данными, и после этого хочу перенаправить пользователя на страницу которая их выводит. Ничего если я это сделаю методом взятия последнего добавленного id записи в базу данных? Или так небезопасно и могут быть ошибки? Так вообще можно делать?
>>875004>>875379
#520 #874998
Я хотел бы поблагодарить господина OP за всё что он делает. Меня впечатляет как он успевает всем ответить, это невероятно продуктивная работа и это продолжается уже не один год. Это вдохновляет! То что он делает означает, что сколько бы не было в мире зла, добро всё равно победит! Такая работа безусловно достойна работы гения, и для меня большая честь учиться под его начинанием.
>>875003
#521 #875003
>>874998
а где спасибо мистер OP PHP'eц ?
#522 #875004
>>874984
нет , например если будет в базу параллельно записывать пару запросов (от 2 одновременно пользователей ) то выйдет что вы будете давать не ту инфу
>>875192
#523 #875005
>>874970
все поля должны быть в руле ,тк AR при save() вызывает валидацию всё рано , если оно не required то должно быть в отдельном массив safe
>>875026
#524 #875026
>>875005
ОП, ты ли это?
Здесь все еще разбирают и проверяют задачи?
Собираюсь вкатиться в пых по хардкору, пилить задания и всякое такое каждый день. Знал, что раньше тут был ОП с учебником, и вот нашел тред.
>>875161>>875379
37 Кб, 442x648
26 Кб, 720x464
10 Кб, 387x336
#525 #875034
Как сделать, что-бы всегда было по 4 элемента в ряд?
>>875035>>875379
#526 #875035
>>875034
display: inline block;
width:22%;
position:relative;

?
#527 #875036
>>874485

Огромное спасибо за проверку.

>Это не нужно так как первичный ключ по определению (ПК = идентификатор записи) уникален.


Да, этот индекс надо убрать.

>Задача бутстрап-скрипта только инициализировать приложение и подготовить к работе. А не определять УРЛ и запускать контроллер. Ну вот например если мы захотим написать скрипт для командной строки, мы не сможем использовать бустрап файл, так как он попытается запустить контроллер, который в командной строке не имеет никакого смысла.В твоем случае содержимое бустрап файла можно было бы просто поместить в index.php.


Я этого не знал. Cпасибо, я учту это.

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


Я и использовал их из-за глобальной доступности, но так делать не стоит, согласен.

>Этот класс стоило поместить в файл, путь к которому соответствует неймспейсу. Название стоит поменять, так как Handler значит "обработчик" и непонятно, что именно он обрабатывает.


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

>Имена функций принято начинать с глагола, handleError, а не errorHandler.


Хорошо, буду знать.

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


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

>На мой взгляд единственно верный способ обработки ошибок это преобразование их в исключения: http://php.net/manual/ru/class.errorexception.php


О, это действительно хороший способ, я не знал о существовании ErrorException. Спасибо.

>Ну например, ты выводишь ошибки при установленном APP_DEBUG, но в php.ini уже есть настройка, отвечающая за вывод ошибок на экран: display_errors.


Да, константу APP_DEBUG лучше убрать и управлять отображением ошибок через display_errors.

>Ты делаешь свой логгер, но в PHP уже есть лог ошибок и возможность писать в него через error_log(). В чем смысл заводить отдельный лог?


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

>Также, в логгере не очень понятно назначение метода setLogFile(). Зачем может понадобиться менять путь к лог-файлу в процессе? Разве недостаточно указать его при создании объекта?


Да, это и вправду нелогично сделано.

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


Да, он действительно "прибит" к логгированию ошибок.

>use принято ставить в самом начале файла.


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

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


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

>А что будет если условие не сработает?


Переменная $url будет иметь тип NULL, потому что ей не будет присвоено никакое значение.
Потом не сработает условие проверки на существования класса и будет свойство $controller будет иметь значение по умолчанию
Ну и т.д.
Я раньше не обращал внимания на это, честно говоря. Это нужно переделать.

>Зачем тут "$url = "? зачем создавать переменную, которая нигде после не используется?


Действительно, это совершенно бесполезная переменная.

>для этого есть функция parse_url


C REQUEST_URI parse_url работать не будет.

>Тут тоже нелогично, получается при любом несуществующем URL вроде /asdasdad будет вызван контроллер index, а должна быть страница 404.


Да, это плохо.

>Ну и твой метод роутинга на мой взгляд неудачный, так как он допускает существование множества URL для одной страницы, вроде /index/action/1/2/3/4/5/6/7/8, хотя у каждой страницы должен быть единственный URL.


Да, он действительно довольно неудачный.

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


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

>Получение токена тоже наверно лучше инкапсулировать в класс авторизации


Хорошо

>Ты знаешь, что именно делает \FILTER_SANITIZE_STRING, и зачем это тут нужно? Или ты ставишь "на всякий случай"? На мой взгляд бесполезные действия только усложняют проверку, безопасен ли код.


Знаю, но этот фильтр там бесполезен и не нужен. Его определенно нужно оттуда убрать.

>Методы search() и all() очень похожи, зачем 2 раза писать одно и то же?


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

А что эта функция делает?
Получает переменную извне (в этом случае с массива $_GET) и при необходимости фильтрует значение.
Поскольку фильтр не указан, используется FILTER_UNSAFE_RAW. Поэтому вызов этой функции с этими параметрами фактически равен присвоению переменной значения элемента суперглобального массива $_GET c ключем 'q'.

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


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

>Непонятно, чем это отличается от public static function renderView.


Подключает файлы из другой директории.

>И кстати, почему методы render статические?


В этом нет никакой необходимости, я не обратил на это внимание.

>Тут методы редактирования и регистрации почти одинаковые. Не надо копипастить код.


Опять-таки, мне это самому не нравится, но я не знаю как это решить.

>Вообще, у тебя в коде слишком много die и exit. Я бы их убрал.


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

>Это неправильный подход. Где гарантия что пользователь за 5 секунд успеет прочитать страницу? А если он слепой и исполоьзует программу для чтения вслух? А если он отвлекся?


Действительно.

>PDOException возникает при ошибке работы с БД, например если SQL запрос написан непраивльно. Какой смысл писать особый код для обработки этой ошибки? У тебя ведь уже есть страница на случай исключения.


Да, без этого можно обойтись.

>тут слишком много вызовов renderView на мой взгляд.


Да, согласен.

>Это нужно для записи в БД? Тогда этот метод должен быть в StudentDataGateway.


У меня были мысли о размещении его там, но я не был уверен в том, что его стоит там размещать.

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


Они там все обязательные

>>874486

>getStudentTableLink($order = null, $sort = null, $query = null)


Но это приведет к загромождению view.

>Не лучше ли сделать геттер и тем самым явно показать что оно только для чтения?


Да, лучше.

>LIMIT и OFFSET надо бы поставлять через плейсхолдеры.


Но как?

>Я вижу что тут переменные вставляются прямо в SQL запрос, значит возможна SQL инъекция.


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

>Неудачная идея возвращать true либо строку. Логичнее при отсутствии ошибок возвращать пустое значение.


Да, это действительно логичнее.

>А что это значит? Должны чередоваться не-пробел и не-@? Вроде "@ @ @ @ @ @" ?


Любой символ кроме проблема и @.

>gitignore лучше класть в корень проекта в одном экземпляре.


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

Еще раз спасибо, буду исправлять.
#527 #875036
>>874485

Огромное спасибо за проверку.

>Это не нужно так как первичный ключ по определению (ПК = идентификатор записи) уникален.


Да, этот индекс надо убрать.

>Задача бутстрап-скрипта только инициализировать приложение и подготовить к работе. А не определять УРЛ и запускать контроллер. Ну вот например если мы захотим написать скрипт для командной строки, мы не сможем использовать бустрап файл, так как он попытается запустить контроллер, который в командной строке не имеет никакого смысла.В твоем случае содержимое бустрап файла можно было бы просто поместить в index.php.


Я этого не знал. Cпасибо, я учту это.

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


Я и использовал их из-за глобальной доступности, но так делать не стоит, согласен.

>Этот класс стоило поместить в файл, путь к которому соответствует неймспейсу. Название стоит поменять, так как Handler значит "обработчик" и непонятно, что именно он обрабатывает.


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

>Имена функций принято начинать с глагола, handleError, а не errorHandler.


Хорошо, буду знать.

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


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

>На мой взгляд единственно верный способ обработки ошибок это преобразование их в исключения: http://php.net/manual/ru/class.errorexception.php


О, это действительно хороший способ, я не знал о существовании ErrorException. Спасибо.

>Ну например, ты выводишь ошибки при установленном APP_DEBUG, но в php.ini уже есть настройка, отвечающая за вывод ошибок на экран: display_errors.


Да, константу APP_DEBUG лучше убрать и управлять отображением ошибок через display_errors.

>Ты делаешь свой логгер, но в PHP уже есть лог ошибок и возможность писать в него через error_log(). В чем смысл заводить отдельный лог?


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

>Также, в логгере не очень понятно назначение метода setLogFile(). Зачем может понадобиться менять путь к лог-файлу в процессе? Разве недостаточно указать его при создании объекта?


Да, это и вправду нелогично сделано.

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


Да, он действительно "прибит" к логгированию ошибок.

>use принято ставить в самом начале файла.


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

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


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

>А что будет если условие не сработает?


Переменная $url будет иметь тип NULL, потому что ей не будет присвоено никакое значение.
Потом не сработает условие проверки на существования класса и будет свойство $controller будет иметь значение по умолчанию
Ну и т.д.
Я раньше не обращал внимания на это, честно говоря. Это нужно переделать.

>Зачем тут "$url = "? зачем создавать переменную, которая нигде после не используется?


Действительно, это совершенно бесполезная переменная.

>для этого есть функция parse_url


C REQUEST_URI parse_url работать не будет.

>Тут тоже нелогично, получается при любом несуществующем URL вроде /asdasdad будет вызван контроллер index, а должна быть страница 404.


Да, это плохо.

>Ну и твой метод роутинга на мой взгляд неудачный, так как он допускает существование множества URL для одной страницы, вроде /index/action/1/2/3/4/5/6/7/8, хотя у каждой страницы должен быть единственный URL.


Да, он действительно довольно неудачный.

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


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

>Получение токена тоже наверно лучше инкапсулировать в класс авторизации


Хорошо

>Ты знаешь, что именно делает \FILTER_SANITIZE_STRING, и зачем это тут нужно? Или ты ставишь "на всякий случай"? На мой взгляд бесполезные действия только усложняют проверку, безопасен ли код.


Знаю, но этот фильтр там бесполезен и не нужен. Его определенно нужно оттуда убрать.

>Методы search() и all() очень похожи, зачем 2 раза писать одно и то же?


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

А что эта функция делает?
Получает переменную извне (в этом случае с массива $_GET) и при необходимости фильтрует значение.
Поскольку фильтр не указан, используется FILTER_UNSAFE_RAW. Поэтому вызов этой функции с этими параметрами фактически равен присвоению переменной значения элемента суперглобального массива $_GET c ключем 'q'.

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


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

>Непонятно, чем это отличается от public static function renderView.


Подключает файлы из другой директории.

>И кстати, почему методы render статические?


В этом нет никакой необходимости, я не обратил на это внимание.

>Тут методы редактирования и регистрации почти одинаковые. Не надо копипастить код.


Опять-таки, мне это самому не нравится, но я не знаю как это решить.

>Вообще, у тебя в коде слишком много die и exit. Я бы их убрал.


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

>Это неправильный подход. Где гарантия что пользователь за 5 секунд успеет прочитать страницу? А если он слепой и исполоьзует программу для чтения вслух? А если он отвлекся?


Действительно.

>PDOException возникает при ошибке работы с БД, например если SQL запрос написан непраивльно. Какой смысл писать особый код для обработки этой ошибки? У тебя ведь уже есть страница на случай исключения.


Да, без этого можно обойтись.

>тут слишком много вызовов renderView на мой взгляд.


Да, согласен.

>Это нужно для записи в БД? Тогда этот метод должен быть в StudentDataGateway.


У меня были мысли о размещении его там, но я не был уверен в том, что его стоит там размещать.

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


Они там все обязательные

>>874486

>getStudentTableLink($order = null, $sort = null, $query = null)


Но это приведет к загромождению view.

>Не лучше ли сделать геттер и тем самым явно показать что оно только для чтения?


Да, лучше.

>LIMIT и OFFSET надо бы поставлять через плейсхолдеры.


Но как?

>Я вижу что тут переменные вставляются прямо в SQL запрос, значит возможна SQL инъекция.


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

>Неудачная идея возвращать true либо строку. Логичнее при отсутствии ошибок возвращать пустое значение.


Да, это действительно логичнее.

>А что это значит? Должны чередоваться не-пробел и не-@? Вроде "@ @ @ @ @ @" ?


Любой символ кроме проблема и @.

>gitignore лучше класть в корень проекта в одном экземпляре.


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

Еще раз спасибо, буду исправлять.
>>875037>>875378
#528 #875037
>>875036
пробела*
165 Кб, 1489x1026
#529 #875103
Сделал на yii2 всё по гайду https://yiiframework.com.ua/ru/doc/guide/2/rest-quick-start/
GET /tasks и /tasks/1 работают отлично, DELETE /tasks тоже.
Post-ом отправляю запрос на создание и получаю 500.
>>875106>>875377
#530 #875106
>>875103
Очень странно, задал дефалтные значения, и всё работает. Странно что сперва просто создается новая запись, а потом видимо апдейтится.
>>875108
#531 #875108
>>875106
Хотя нет, создало запись с дефалтными значениями и всё.
#532 #875115
Заметил интересную особенность поведения БД. Есть у меня табличка со студентами, поле email уникальное. Пытаюсь вставить методом поля, указал повторяющийся имейл - > ошибка. Но вот фишка в том, что если у последней записи id был 3, то у следующей, правильно вставленной, id уже 5. Т.е. из-за ошибки один порядковый номер айдишника куда-то пропал. Чому так?
>>875377
#533 #875147
Я правильно понял, что в классе можно объявить только 1 конструктор. Если мне нужен конструктор с другим набором параметров - соси писос/делай статические методы, возвращающие новый инстанс?
#534 #875151
>>875147
Зачем тебе два конструктора? Если тебе надо изменять свойства класса то делай методы. Или можешь делать это динамически, а еще лучше почитай про магические методы.
>>875169
#535 #875155
Ньюфаг врывается. Встал ступором на регулярных выражениях. Т.е. появляются какие-то мысли, но на уровне интуиции, а что-то дельное в голову не идёт. Есть ли какие-то годные уроки для всего этого делать, кроме учебника для нюфань из шапки?
#536 #875160
Почему-то мой хттп сервер перестал нормально отдавать данные браузеру. Когда делаешь socket_close сразу после socket_write браузер выдает ERR_CONNECTION_ABORTED, если поставить перед закрытием сокета sleep(10) все нормально отображается.
>>875376
#537 #875161
>>875026
нет я другой анон
>>875162
#538 #875162
>>875161
Я постом промахнулся, сорян.
Но, тем не менее, ОП тут? Он проверяет задачи?
>>875376
#539 #875169
>>875147
Да, в PHP нет перегрузки конструктора. Обычно используют статические конструкторы, выглядящие примерно так Foo::createFromBar($bar)
Вообще здесь всё очень спорно и нужно смотреть в код. Если нужно большим количеством разных способов создать объект, то быть может есть смысл выделить дополнительную абстракцию?

>>875151
Ух, и магия и сеттеры, изменяющие состояние. Это всего надо избегать по возможности, передавая параметры конфигурации в конструктор. Оцени новую магию в Laravel: https://laravel-news.com/2016/11/higher-order-messaging/
Они используют свойство объекта как callable. Восторженные фанбои уже ставят очередную звезду репозиторию.
#540 #875176
>>875155
1) Все нужные регулярки как правило давно без особых проблем гугляться 2) Их лучше вообще избегать.
>>875222>>875376
#541 #875183
Почему объект класса сериализуется через
serialize($object), т.е. вижу полученные CSV-подобные данные,
но не сохраняются значения массивов - свойства $anArray=array();
?
>>875221>>875376
#542 #875187
>>875155
Чисто в учебных целях не засирай себе голову ими. Просто в общих чертах пойми что это и зачем это, и потом уже если они тебе понадобятся, сломай себе моск.
>>875222>>875376
#543 #875190
http сервер, дубль 2
http://ideone.com/F3xhUr
>>875254
#544 #875192
>>875004
А как поступать в таком случае? Записывать в куки часть информации (если id то метод последнего id снова не прокатывает) которую ввёл пользователь, перенаправлять его на нужную страницу, а уже затем по этим записанным данным из куки выводить нужную инфу?
>>875253>>875670
#545 #875221
>>875183
Бамп вопросу? Есть класс, в котором есть двумерный массив, объект которого пробовал сериализовывать двумя способами:
1. просто использовать функцию serialize()
2. реализовал в классе интерфейс Serializable, пробовал сериализовать через $s = $obj.serialize();
где obj - объект класса с массивом. Но при записи в файл всё равно нет значений матрицы.
Алсо, я нуфак
>>875253
#546 #875222
>>875187
>>875176
Спасибо большое, прямо гора с плеч
>>875253
#547 #875232
ОП у меня вопрос. У тебя в гите в теме про паттерны работы с бд есть цитата:
"для работы с разными таблицами стоит использовать разные классы
".
А если у меня инет магазин с кучей таблиц: продукты, их описание, опции, атрибуты и прочее. Как сделать через такие классы выборку? К примеру я пишу модуль Аякс фильтрации. Мне исходя из этой цитаты придется вместо одного запроса с парой join делать неудобные 3-4 запроса плюс обрабатывать это все на стороне php. Что скажешь?
>>875254
#548 #875253
Стоило ОПу денек отдохнуть от треда, как он наводнился вредными советами.

>>875222

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

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

>>875221

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

Интерфейс Serializable нужен когда стандартный способ не работает.

> Но при записи в файл всё равно нет значений матрицы.


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

И это не матрица, а массив.

>>875192

Надо использовать lastInsertId ( http://php.net/manual/ru/pdo.lastinsertid.php ), в PDO метод так и называется, в Юи в классе работы с БД тоже наверно есть что-то аналогичное.
>>875283>>875671
#549 #875254
>>875232

Можно в классе работы с одной таблицей джойнить к ней вспомогательные.

>>875190

> echo "Не удалось выполнить socket_accept(): причина: " . socket_last_error($sock) . "\n";


> break;


тут наверно логичнее continue

> while ($read = socket_read($msgsock, 2)) {


Неправильно сделана проверка. Что, если socket_read вернет строку "0" ?

Плюс, не понимаю какая выгода читать по 2 байта? И почему именно 2?

> socket_set_nonblock($msgsock);


Неправильно. Если ты хочешь сделать сокет неблокирующим, то это надо делать один раз, а не каждый раз, как что-то из него прочитал. Плюс, для работы с неблокирующими сокетами нужен select (который ты изучишь чуть позже). Если не использовать select, то socket_read будет сразу же возвращаться при отсутствии данных и ты будешь грузить процессор на 100% в цикле while.

> function socketWrite


Эта функция делает только 2 попытки записи. Почему из должно быть 2? В теории за раз может даже 1 байт отправляться. Тут нужен цикл.

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

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


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

> //здесь был sleep(10) до того, как я стал читать данные из сокета. Без socket_read или sleep сокет как будто закрывается до того, как клиент успевает принять респонс, что приводит к ошибке в браузере


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

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

Чтение

Блокирующий сокет при чтении блокируется до возникновения одного из событий:

- пришел пакет данных - будет возвращен этот пакет (в пределах указанного тобой числа байт, если там больше, то остаток вернется при следующем чтении)
- удаленный хост закрыл соединение - будет возвращена строка длиной 0 байт и feof($socket) вернет true
- проихошла ошибка - будет возвращен false. Ошибка может быть в том числе если например удаленный хост отсоединился от сети и связь с ним прервалась. Ну сети на то и сети, что там сломаться может все, что угодно. Любая функция может вернуть ошибку.

Неблокирующий сокет отличается тем, что он не ждет прихода данных. Если данных пока нет, он сразу вернет строку длиной 0 байт (но feof($socket) покажет false). Если же данные пришли, соединение закрыто или произошла ошибка, он возвращает то же самое что и блокирующий.

Запись

Блокирующий сокет отправляет данные в сеть и блокируется до одного из событий:

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

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

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

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

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

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

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

Протокол HTTP определен в RFC 7230, 7231, 7232, 7233, 7234, 7235. Поищем ответ там.

https://tools.ietf.org/html/rfc7230#page-20 , пункт "Формат Сообщения":

> The normal procedure for parsing an HTTP message is to read the


> start-line into a structure, read each header field into a hash table


> by field name until the empty line, and then use the parsed data to


> determine if a message body is expected. If a message body has been


> indicated, then it is read as a stream until an amount of octets


> equal to the message body length is read or the connection is closed.



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

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

Так как мы делаем простую задачу, ты можешь не читать тело запроса и слать ответ сразу после окончания заголовков. Запрос GET все равно не содержит тела. Но если хочется, можешь добавить поддержку Content-Length и тогда сможешь например принимать тело POST-запросов.

В общем, тебе надо

1) разобраться получше, как работают блокирующие сокеты
2) разобраться получше, как работает HTTP

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

Пока, к сожалению, твой сервер совсем нерабочий.

Если тебе что-то непонятно по сокетам или HTTP - задавай вопросы.
#549 #875254
>>875232

Можно в классе работы с одной таблицей джойнить к ней вспомогательные.

>>875190

> echo "Не удалось выполнить socket_accept(): причина: " . socket_last_error($sock) . "\n";


> break;


тут наверно логичнее continue

> while ($read = socket_read($msgsock, 2)) {


Неправильно сделана проверка. Что, если socket_read вернет строку "0" ?

Плюс, не понимаю какая выгода читать по 2 байта? И почему именно 2?

> socket_set_nonblock($msgsock);


Неправильно. Если ты хочешь сделать сокет неблокирующим, то это надо делать один раз, а не каждый раз, как что-то из него прочитал. Плюс, для работы с неблокирующими сокетами нужен select (который ты изучишь чуть позже). Если не использовать select, то socket_read будет сразу же возвращаться при отсутствии данных и ты будешь грузить процессор на 100% в цикле while.

> function socketWrite


Эта функция делает только 2 попытки записи. Почему из должно быть 2? В теории за раз может даже 1 байт отправляться. Тут нужен цикл.

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

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


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

> //здесь был sleep(10) до того, как я стал читать данные из сокета. Без socket_read или sleep сокет как будто закрывается до того, как клиент успевает принять респонс, что приводит к ошибке в браузере


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

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

Чтение

Блокирующий сокет при чтении блокируется до возникновения одного из событий:

- пришел пакет данных - будет возвращен этот пакет (в пределах указанного тобой числа байт, если там больше, то остаток вернется при следующем чтении)
- удаленный хост закрыл соединение - будет возвращена строка длиной 0 байт и feof($socket) вернет true
- проихошла ошибка - будет возвращен false. Ошибка может быть в том числе если например удаленный хост отсоединился от сети и связь с ним прервалась. Ну сети на то и сети, что там сломаться может все, что угодно. Любая функция может вернуть ошибку.

Неблокирующий сокет отличается тем, что он не ждет прихода данных. Если данных пока нет, он сразу вернет строку длиной 0 байт (но feof($socket) покажет false). Если же данные пришли, соединение закрыто или произошла ошибка, он возвращает то же самое что и блокирующий.

Запись

Блокирующий сокет отправляет данные в сеть и блокируется до одного из событий:

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

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

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

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

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

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

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

Протокол HTTP определен в RFC 7230, 7231, 7232, 7233, 7234, 7235. Поищем ответ там.

https://tools.ietf.org/html/rfc7230#page-20 , пункт "Формат Сообщения":

> The normal procedure for parsing an HTTP message is to read the


> start-line into a structure, read each header field into a hash table


> by field name until the empty line, and then use the parsed data to


> determine if a message body is expected. If a message body has been


> indicated, then it is read as a stream until an amount of octets


> equal to the message body length is read or the connection is closed.



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

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

Так как мы делаем простую задачу, ты можешь не читать тело запроса и слать ответ сразу после окончания заголовков. Запрос GET все равно не содержит тела. Но если хочется, можешь добавить поддержку Content-Length и тогда сможешь например принимать тело POST-запросов.

В общем, тебе надо

1) разобраться получше, как работают блокирующие сокеты
2) разобраться получше, как работает HTTP

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

Пока, к сожалению, твой сервер совсем нерабочий.

Если тебе что-то непонятно по сокетам или HTTP - задавай вопросы.
>>875259
#550 #875259
>>875254
Всю стену еще не осилил, но пока ты тут пару вопросов/примечаний

>Плюс, не понимаю какая выгода читать по 2 байта? И почему именно 2?


Забыл вернуть обратно, проверял все ли данные читаются

>Эта функция делает только 2 попытки записи.


Почему 2? По идее она будет вызываться пока все данные не запишутся

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


С блокирующим он тоже не работал, в общем-то sleep я туда поставил еще когда он был блокирующим.
>>875375
#551 #875283
>>875253
Нет, я понял как они работают и как поставить, но всё это слишком сложно на моём уровне. Возможно это потому, что я делал перерыв около двух месяцев в изучении языка и кое-что мог забыть.
#552 #875331
Привет всем.

Может знает кто, как залить на heroku yii1 сайт?
И реально ли это?
Есть ли альтернативы heroku.
>>875672>>877210
#553 #875375
>>875259

> По идее она будет вызываться пока все данные не запишутся


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

> С блокирующим он тоже не работал, в общем-то sleep я туда поставил еще когда он был блокирующим.


значит, ты неправильно что-то сделал. Я написал в своем ответе логику, по которой должен работать сервер.
#554 #875376
>>875187

Вредный совет. Люди так пропускают темы, а потом ничего не понимают, например, когда дойдут до фреймворков.

>>875183

Покажи пример кода. Должно все работать.

>>875176

> 1) Все нужные регулярки как правило давно без особых проблем гугляться


Не всегда гуглятся, и не всегда они правильные (могут например не поддерживать кириллицу или еще что-то не учитывать)

> 2) Их лучше вообще избегать.


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

>>875162

Прокрути тред выше и посмотри ответы

>>875160

Если это тот сервер, что ниже, то потому, что он написан неправильно.

>>875155

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

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

>>875147

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

Вредный совет. Люди так пропускают темы, а потом ничего не понимают, например, когда дойдут до фреймворков.

>>875183

Покажи пример кода. Должно все работать.

>>875176

> 1) Все нужные регулярки как правило давно без особых проблем гугляться


Не всегда гуглятся, и не всегда они правильные (могут например не поддерживать кириллицу или еще что-то не учитывать)

> 2) Их лучше вообще избегать.


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

>>875162

Прокрути тред выше и посмотри ответы

>>875160

Если это тот сервер, что ниже, то потому, что он написан неправильно.

>>875155

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

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

>>875147

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

Может ты просто ранее удалил запись с номером 4?

>>875103

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

Ну и кстати это плохо что твое приложение отдает пользователям подробности ошибки.
#556 #875378
>>875036

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


ErrorHandler

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


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

Встроенный в PHP подход неправильный. Не бывает "некритических" ошибок. Программа либо написана правильно, либо нет.

>>use принято ставить в самом начале файла.


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


Нет. use ничего не загружает, он просто задает короткое обозначение для класса в коде ниже, что класс X это на самом деле \A\B\C\X.

> >для этого есть функция parse_url


> C REQUEST_URI parse_url работать не будет.


Будет, если ты пытаешься получить PHP_URL_PATH. Посмотри мануал и поэкспериментируй.

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


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

Я все же предлагаю выбрать одно из решений, например:

- создать в бутстрап-скрипте объекты и положить в контейнер (объект или массив), который передавать в контроллер
- сделать класс-DI контейнер, умеющий создавать все объекты
- взять готовый контейнер, например, Pimple

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


Делаешь один метод, а в нужных местах ставишь if ($isSearch).... Если передан не пустой поисковый запрос - значит, у нас поиск.

> Поэтому вызов этой функции с этими параметрами фактически равен присвоению переменной значения элемента суперглобального массива $_GET c ключем 'q'.


Я хотел написать, что проще сразу обращаться к $_GET, но поймал себя на мысли что там придется писать array_key_exists, и код с filter_input может быть получается короче, так что есть смысл его использовать. Ну добавил бы хотя бы strval() и trim() тогда что ли.

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


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


В контроллере вывода списка студентов.

>>Непонятно, чем это отличается от public static function renderView.


> Подключает файлы из другой директории.


Для этого наверно отдельную функцию заводить и не требуется.

>>Вообще, у тебя в коде слишком много die и exit. Я бы их убрал.


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


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

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


> Они там все обязательные


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

- задать функцию-генератор УРЛ вида function ($page) { ... }, которая по номеру страницы генерирует УРЛ (наиболее универсально)
- передать объект, генерирующий УРЛ
- передать шаблон URL вида /table?order=sort&page={page}, в который класс подставит номер страницы (немного костыльно конечно так как в теории например у 1-й страницы может быть УРЛ немного не такой, как у других, и вообще, может мы захотим номер страницы римскими цифрами вписывать)

Вот у тебя генерация УРЛ по моему по 3 классам раскидана. Может можно ее всю убрать в один класс?

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

Вот видишь, мы обнаружили в итоге что класс решает 2 задачи сразу (расчет пагинации и генерацию УРЛ) и этим вызвано такое большое число аргументов.

>>getStudentTableLink($order = null, $sort = null, $query = null)


> Но это приведет к загромождению view.


Ну не знаю, мне кажется, что нет. Ну можно попробовать сделать еще так:

getTableLink(['page' => 1]), getTableLink(['order' => 'name']), то есть передавать только параметры, которые должны измениться.

> >LIMIT и OFFSET надо бы поставлять через плейсхолдеры.


> Но как?


->bindValue(':limit', 100, какая-то константа). Смотри мануал https://secure.php.net/manual/ru/pdostatement.bindvalue.php

>>Я вижу что тут переменные вставляются прямо в SQL запрос, значит возможна SQL инъекция.


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


> Это, конечно, костыль но я не знаю как это лучше сделать.


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

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

>>А что это значит? Должны чередоваться не-пробел и не-@? Вроде "@ @ @ @ @ @" ?


> Любой символ кроме проблема и @.


Ну у тебя там неправильная регулярка. \S[^@] значит "сначала идет символ, не являющийся пробелом, за ним идет символ, не являющийся @".

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


Для этого используют файл с другим именем, например .gitkeep. .gitignore - это специальное имя, там задается список файлов, которые не должны попасть в репозиторий, и его лучше иметь в одном экземпляре в корне.
#556 #875378
>>875036

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


ErrorHandler

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


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

Встроенный в PHP подход неправильный. Не бывает "некритических" ошибок. Программа либо написана правильно, либо нет.

>>use принято ставить в самом начале файла.


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


Нет. use ничего не загружает, он просто задает короткое обозначение для класса в коде ниже, что класс X это на самом деле \A\B\C\X.

> >для этого есть функция parse_url


> C REQUEST_URI parse_url работать не будет.


Будет, если ты пытаешься получить PHP_URL_PATH. Посмотри мануал и поэкспериментируй.

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


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

Я все же предлагаю выбрать одно из решений, например:

- создать в бутстрап-скрипте объекты и положить в контейнер (объект или массив), который передавать в контроллер
- сделать класс-DI контейнер, умеющий создавать все объекты
- взять готовый контейнер, например, Pimple

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


Делаешь один метод, а в нужных местах ставишь if ($isSearch).... Если передан не пустой поисковый запрос - значит, у нас поиск.

> Поэтому вызов этой функции с этими параметрами фактически равен присвоению переменной значения элемента суперглобального массива $_GET c ключем 'q'.


Я хотел написать, что проще сразу обращаться к $_GET, но поймал себя на мысли что там придется писать array_key_exists, и код с filter_input может быть получается короче, так что есть смысл его использовать. Ну добавил бы хотя бы strval() и trim() тогда что ли.

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


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


В контроллере вывода списка студентов.

>>Непонятно, чем это отличается от public static function renderView.


> Подключает файлы из другой директории.


Для этого наверно отдельную функцию заводить и не требуется.

>>Вообще, у тебя в коде слишком много die и exit. Я бы их убрал.


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


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

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


> Они там все обязательные


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

- задать функцию-генератор УРЛ вида function ($page) { ... }, которая по номеру страницы генерирует УРЛ (наиболее универсально)
- передать объект, генерирующий УРЛ
- передать шаблон URL вида /table?order=sort&page={page}, в который класс подставит номер страницы (немного костыльно конечно так как в теории например у 1-й страницы может быть УРЛ немного не такой, как у других, и вообще, может мы захотим номер страницы римскими цифрами вписывать)

Вот у тебя генерация УРЛ по моему по 3 классам раскидана. Может можно ее всю убрать в один класс?

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

Вот видишь, мы обнаружили в итоге что класс решает 2 задачи сразу (расчет пагинации и генерацию УРЛ) и этим вызвано такое большое число аргументов.

>>getStudentTableLink($order = null, $sort = null, $query = null)


> Но это приведет к загромождению view.


Ну не знаю, мне кажется, что нет. Ну можно попробовать сделать еще так:

getTableLink(['page' => 1]), getTableLink(['order' => 'name']), то есть передавать только параметры, которые должны измениться.

> >LIMIT и OFFSET надо бы поставлять через плейсхолдеры.


> Но как?


->bindValue(':limit', 100, какая-то константа). Смотри мануал https://secure.php.net/manual/ru/pdostatement.bindvalue.php

>>Я вижу что тут переменные вставляются прямо в SQL запрос, значит возможна SQL инъекция.


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


> Это, конечно, костыль но я не знаю как это лучше сделать.


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

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

>>А что это значит? Должны чередоваться не-пробел и не-@? Вроде "@ @ @ @ @ @" ?


> Любой символ кроме проблема и @.


Ну у тебя там неправильная регулярка. \S[^@] значит "сначала идет символ, не являющийся пробелом, за ним идет символ, не являющийся @".

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


Для этого используют файл с другим именем, например .gitkeep. .gitignore - это специальное имя, там задается список файлов, которые не должны попасть в репозиторий, и его лучше иметь в одном экземпляре в корне.
#557 #875379
>>875034

Надо разобраться, в чем проблема. Скорее всего в том, что ты используешь col-md-3, а это float. Флоаты выстраиваются горизонтально, а если места не хватает, то они пытаются встать ниже, и видимо потому 5-й блок оказался под 4-м.

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

Ну и это показывает, что тебе надо бы изучить CSS. Бутстрап придуман для тех, кто уже знает CSS. У нас в ОП посте есть задания по CSS.

>>875026

Посмотри выше по треду, проверяют или нет.

>>874984

Надо использовать lastInsertId. В случае использования Active Record скорее всего Юи сам в модель проставляет ее id после вставки.

>>874970

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

Описано же в мануале (хотя если честно, замучался искать, но ты как специалист по Юи должен был найти быстрее меня):

- https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/structure-models.md#Массовое-Присвоение-
- http://www.yiiframework.com/doc-2.0/guide-structure-models.html#massive-assignment

Ну и ты всегда можешь присвоить нужное значение вручную без mass assignment.
#557 #875379
>>875034

Надо разобраться, в чем проблема. Скорее всего в том, что ты используешь col-md-3, а это float. Флоаты выстраиваются горизонтально, а если места не хватает, то они пытаются встать ниже, и видимо потому 5-й блок оказался под 4-м.

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

Ну и это показывает, что тебе надо бы изучить CSS. Бутстрап придуман для тех, кто уже знает CSS. У нас в ОП посте есть задания по CSS.

>>875026

Посмотри выше по треду, проверяют или нет.

>>874984

Надо использовать lastInsertId. В случае использования Active Record скорее всего Юи сам в модель проставляет ее id после вставки.

>>874970

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

Описано же в мануале (хотя если честно, замучался искать, но ты как специалист по Юи должен был найти быстрее меня):

- https://github.com/yiisoft/yii2/blob/master/docs/guide-ru/structure-models.md#Массовое-Присвоение-
- http://www.yiiframework.com/doc-2.0/guide-structure-models.html#massive-assignment

Ну и ты всегда можешь присвоить нужное значение вручную без mass assignment.
#558 #875380
>>874968

https://someapprentice.github.io/maintaskforlayout/MotherfuckingWebsite.html - вот это конечно никуда не годится. Ладно, отсутствие полей у html можно объяснить необходимостью, но шрифт по умолчанию не должен быть бледно-серым.

> Я исправил этот пробел, и это починило всё(!), за исключением наклона и отсутствия легких шрифтов в ie<8.


Я решил заглянуть в MSDN (мануалы майкрософта), чтобы найти информацию про font-face в ИЕ. Если что, информация по ИЕ есть в MSDN, по фаерфоксу в MDN, а у других браузеров нет таких сайтов и они обычно кивают в сторону стандартов, мол они их поддерживают.

https://msdn.microsoft.com/ru-ru/library/ms530757(v=vs.85).aspx

Тут мы видим:

> font-weight:fontWeight


> Internet Explorer 9. A valid font-weight property value (except for the relative values, bolder and lighter).



Итак, font-weight поддерживается только начиная с ИЕ9, и не поддерживаются относительные значения bolder, lighter (не очень-то и нужны).

Вот еще статья по теме (англ): http://itsravenous.com/blog/banishing-faux-italic-and-faux-bold--on-css3-fonts-in-IE-8-and-below

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

Если хочется поддерживать ИЕ8 и ниже, придется наверно делать отдельный CSS файл, подключаемый через условные комментарии https://msdn.microsoft.com/ru-ru/library/ms537512(v=vs.85).aspx . В нем объявить шрифты каждый под своим именем, только с eot файлами, например IeLatoRegular, IeLatoBold. Вписать эти имена в отдельные CSS правила только для ИЕ:

h1 {
font-family: IeLatoBold, sans-serif;
font-weight: normal; - сбрасываем вес, чтобы ИЕ не пытался "ужирнять" шрифт
}

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

> Firefox, кстати, всё равно выдает ошибки парсинга font-weight на значения bolder и lighter (если их убрать то ничего не изменится). Как такое может быть?


Это относительный вес ("чуть потяжелее") и его не стоит указывать внутри font-face в любом случае, так как непонятно относительно чего его отсчитывать.

https://github.com/someApprentice/maintaskforlayout/blob/master/stylesheets.css#L97

> font-family: Lato, 'Times New Roman', Arial, Helvetica, sans-serif;


Times New Roman совсем не похож на Lato (у него засечки). Я бы Arial и Helvetica тоже убрал (а зачем?) и оставил бы только Lato и sans-serif. sans-serif определен в стандарте и любой браузер должен уметь отобразить текст таким шрифтом. Arial это по сути стандарт де-факто (даже на тех системах, где его нет, например, Андроид, вместо него подставляют что-то похожее), но зачем он нужен, если есть sans-serif.

Вот еще ссылка, если интересно: http://www.cssfontstack.com/

> a {


> font-weight: bold;


> color: #d9d9d9;


> text-decoration: none;


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

> p {


> font-weight: lighter;


Вот это мне тоже не нравится. Почему вес шрифта изменен именно для абзацев? А что насчет таблиц, списков? Если ты хочешь сказать, что шрифт по умолчанию должен иметь вес 300, то надо объявить это на элементе html - шрифт по умолчанию задается именно там.

https://github.com/someApprentice/maintaskforlayout/blob/master/stylesheets.css#L146

> position: relative;


> bottom: 10px;


не очень понимаю, зачем это тут? Подвинуть блок вертикально можно через margin-top наверно?

> .header ul {


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

Я думаю, что тут ты не хотел написать "для всех списков внутри шапки". Скорее, ты хотел написать "для меню в шапке". Ну тогда так и напиши: .header .header-menu { ... }. А теперь, если подумать, то не так важно где находится это меню - в шапке или нет, и можно упростить до .header-menu { ... }.

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

> .header ul :nth-child(1n) {


С этим правилом проблема в том, что если мы захотим сделать подменю внутри меню, то правило сработает и на него. Лучше писать что-то вроде .header-menu > li.

Вот скриншот из ИЕ11: https://www.browserstack.com/screenshots/b5bec7763e6986c4898f75ece20e9d312e81834b/win10_ie_11.0.jpg

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

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

По моим ощущениям, у тебя многовато этих хаков с nth-child. Лучше наверно стараться, чтобы правила для ИЕ были как исключение, а не правила для нормальных браузеров.

Статья: https://habrahabr.ru/post/62002/

Я бы использовал хак со звездочкой для ИЕ или отдельный файл стилей.

> .consectetur::before {


> .tristiquet::before {


> .fermentum::before {


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

>.services .content .box p {


Что-то многовато тут компонент в селекторе. Зачем, например, тут .content? Он тут по моему лишний.

Когда задаешь font-size, стоит задавать и line-height. В абзаце текста под заголовком "Consectetur" например строки стоят очень тесно, правильный ли там line-height?

> .portfolio .content .works :nth-child(4n) {


> padding-right: 0px;


Это плохая идея, так как подразумевает что картинки идут ровно в 4 ряда, хотя на узком экране удобнее их размещать например по 2-3 в ряд. И будет ли это работать корректно, когда мы скроем часть картинок?

> .rss:before {


> .facebook:before {


Надо избавиться от повторов

> @media (max-width: 1110px) {


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

И мне кажется что точка переключения 1110px не очень удачная. Наверно, лучше сделать ее в районе 700-800px, так как на большем размере блоки consecutor смотрятся не очень удачно.

ну и например, что касается меню, можно для него использовать свои правила, например, перемещать логотип вверх только при ширине меньше 500px. А то на 800px там места сбоку вполне достаточно остается.

Для иконок соцсетей надо сделать реакцию на наведение.

Далее, я открыл отладчик в Хроме и закомментировал тег link, подключающий CSS файл. Именно так, без CSS, видят твой сайт поисковые роботы и программы чтения вслух. Сразу же нашлась проблема: ссылки на соцсети сделаны пустыми тегами <a>. Это плохо, надо бы, чтобы в них был какой-то текст, например название соцсети или надпись "мы на facebook".

Адрес и номер телефона при отсутствии CSS склеились слитно.

title у тебя идет раньше чем meta charset. Это может привести к тому что meta charset будет проигнорирован.

> srcset="img\home_0003s_0001s_0022_Layer-1-Large.jpg"


Я вижу, ты используешь srcset, но почему тут не указано разрешение картинки? Так и должно быть? Вот я статью нашел по теме, если что: http://frontender.info/webkit-implements-srcset-and-why-its-a-good-thing/

Вот этот вот WOFF легкий: https://github.com/someApprentice/maintaskforlayout/blob/master/fonts/ReklameScript-Regular_DEMO.woff - 13 Кб
Но вот этот вот https://github.com/someApprentice/maintaskforlayout/blob/master/fonts/ReklameScript-Regular_DEMO.ttf почему-то тяжеленный. 232Кб ради 7 букв в логотипе.
#558 #875380
>>874968

https://someapprentice.github.io/maintaskforlayout/MotherfuckingWebsite.html - вот это конечно никуда не годится. Ладно, отсутствие полей у html можно объяснить необходимостью, но шрифт по умолчанию не должен быть бледно-серым.

> Я исправил этот пробел, и это починило всё(!), за исключением наклона и отсутствия легких шрифтов в ie<8.


Я решил заглянуть в MSDN (мануалы майкрософта), чтобы найти информацию про font-face в ИЕ. Если что, информация по ИЕ есть в MSDN, по фаерфоксу в MDN, а у других браузеров нет таких сайтов и они обычно кивают в сторону стандартов, мол они их поддерживают.

https://msdn.microsoft.com/ru-ru/library/ms530757(v=vs.85).aspx

Тут мы видим:

> font-weight:fontWeight


> Internet Explorer 9. A valid font-weight property value (except for the relative values, bolder and lighter).



Итак, font-weight поддерживается только начиная с ИЕ9, и не поддерживаются относительные значения bolder, lighter (не очень-то и нужны).

Вот еще статья по теме (англ): http://itsravenous.com/blog/banishing-faux-italic-and-faux-bold--on-css3-fonts-in-IE-8-and-below

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

Если хочется поддерживать ИЕ8 и ниже, придется наверно делать отдельный CSS файл, подключаемый через условные комментарии https://msdn.microsoft.com/ru-ru/library/ms537512(v=vs.85).aspx . В нем объявить шрифты каждый под своим именем, только с eot файлами, например IeLatoRegular, IeLatoBold. Вписать эти имена в отдельные CSS правила только для ИЕ:

h1 {
font-family: IeLatoBold, sans-serif;
font-weight: normal; - сбрасываем вес, чтобы ИЕ не пытался "ужирнять" шрифт
}

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

> Firefox, кстати, всё равно выдает ошибки парсинга font-weight на значения bolder и lighter (если их убрать то ничего не изменится). Как такое может быть?


Это относительный вес ("чуть потяжелее") и его не стоит указывать внутри font-face в любом случае, так как непонятно относительно чего его отсчитывать.

https://github.com/someApprentice/maintaskforlayout/blob/master/stylesheets.css#L97

> font-family: Lato, 'Times New Roman', Arial, Helvetica, sans-serif;


Times New Roman совсем не похож на Lato (у него засечки). Я бы Arial и Helvetica тоже убрал (а зачем?) и оставил бы только Lato и sans-serif. sans-serif определен в стандарте и любой браузер должен уметь отобразить текст таким шрифтом. Arial это по сути стандарт де-факто (даже на тех системах, где его нет, например, Андроид, вместо него подставляют что-то похожее), но зачем он нужен, если есть sans-serif.

Вот еще ссылка, если интересно: http://www.cssfontstack.com/

> a {


> font-weight: bold;


> color: #d9d9d9;


> text-decoration: none;


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

> p {


> font-weight: lighter;


Вот это мне тоже не нравится. Почему вес шрифта изменен именно для абзацев? А что насчет таблиц, списков? Если ты хочешь сказать, что шрифт по умолчанию должен иметь вес 300, то надо объявить это на элементе html - шрифт по умолчанию задается именно там.

https://github.com/someApprentice/maintaskforlayout/blob/master/stylesheets.css#L146

> position: relative;


> bottom: 10px;


не очень понимаю, зачем это тут? Подвинуть блок вертикально можно через margin-top наверно?

> .header ul {


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

Я думаю, что тут ты не хотел написать "для всех списков внутри шапки". Скорее, ты хотел написать "для меню в шапке". Ну тогда так и напиши: .header .header-menu { ... }. А теперь, если подумать, то не так важно где находится это меню - в шапке или нет, и можно упростить до .header-menu { ... }.

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

> .header ul :nth-child(1n) {


С этим правилом проблема в том, что если мы захотим сделать подменю внутри меню, то правило сработает и на него. Лучше писать что-то вроде .header-menu > li.

Вот скриншот из ИЕ11: https://www.browserstack.com/screenshots/b5bec7763e6986c4898f75ece20e9d312e81834b/win10_ie_11.0.jpg

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

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

По моим ощущениям, у тебя многовато этих хаков с nth-child. Лучше наверно стараться, чтобы правила для ИЕ были как исключение, а не правила для нормальных браузеров.

Статья: https://habrahabr.ru/post/62002/

Я бы использовал хак со звездочкой для ИЕ или отдельный файл стилей.

> .consectetur::before {


> .tristiquet::before {


> .fermentum::before {


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

>.services .content .box p {


Что-то многовато тут компонент в селекторе. Зачем, например, тут .content? Он тут по моему лишний.

Когда задаешь font-size, стоит задавать и line-height. В абзаце текста под заголовком "Consectetur" например строки стоят очень тесно, правильный ли там line-height?

> .portfolio .content .works :nth-child(4n) {


> padding-right: 0px;


Это плохая идея, так как подразумевает что картинки идут ровно в 4 ряда, хотя на узком экране удобнее их размещать например по 2-3 в ряд. И будет ли это работать корректно, когда мы скроем часть картинок?

> .rss:before {


> .facebook:before {


Надо избавиться от повторов

> @media (max-width: 1110px) {


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

И мне кажется что точка переключения 1110px не очень удачная. Наверно, лучше сделать ее в районе 700-800px, так как на большем размере блоки consecutor смотрятся не очень удачно.

ну и например, что касается меню, можно для него использовать свои правила, например, перемещать логотип вверх только при ширине меньше 500px. А то на 800px там места сбоку вполне достаточно остается.

Для иконок соцсетей надо сделать реакцию на наведение.

Далее, я открыл отладчик в Хроме и закомментировал тег link, подключающий CSS файл. Именно так, без CSS, видят твой сайт поисковые роботы и программы чтения вслух. Сразу же нашлась проблема: ссылки на соцсети сделаны пустыми тегами <a>. Это плохо, надо бы, чтобы в них был какой-то текст, например название соцсети или надпись "мы на facebook".

Адрес и номер телефона при отсутствии CSS склеились слитно.

title у тебя идет раньше чем meta charset. Это может привести к тому что meta charset будет проигнорирован.

> srcset="img\home_0003s_0001s_0022_Layer-1-Large.jpg"


Я вижу, ты используешь srcset, но почему тут не указано разрешение картинки? Так и должно быть? Вот я статью нашел по теме, если что: http://frontender.info/webkit-implements-srcset-and-why-its-a-good-thing/

Вот этот вот WOFF легкий: https://github.com/someApprentice/maintaskforlayout/blob/master/fonts/ReklameScript-Regular_DEMO.woff - 13 Кб
Но вот этот вот https://github.com/someApprentice/maintaskforlayout/blob/master/fonts/ReklameScript-Regular_DEMO.ttf почему-то тяжеленный. 232Кб ради 7 букв в логотипе.
>>875850
#559 #875388
Проверьте, пожалуйста, правильно ли ? Есть какие советы?
http://ideone.com/hwzlXh
>>875422>>877696
#560 #875407
помогите, всю ночь мучаюсь! как добить эти ссаные регулярные выражения ?
http://ideone.com/2M0Sjp
>>875422
#561 #875422
>>875388
Покажи решение задачи про Айфон - по всей видимости, ты её тоже неправильно решил. Во втором банке (это тот же по параметром, который был в задаче про Айфон) должно получиться 61270, около того.

>>875407
Попробуй начать с того, чтобы регулярка просто верно определяла + 7, +7 и 8, потому что у тебя в самом конце такое: 7 234 5678901 - correct.
Дальше пробуй код, дальше основной номер.
Надо идти по чуть-чуть в этой ситуации.
>>875442
#562 #875442
>>875422
http://ideone.com/tngpKm
http://ideone.com/BSoy64

Так все вроде правильно ?
>>875445
#563 #875445
#564 #875483
Решил поискать работу на госпортале. Нашел вакансию программиста SAP с окладом 12 180 р: https://trudvsem.ru/vacancy/card/1037832048605/18b8f9d2-75f2-11e6-b903-bf2cfe8c828d?to=https://trudvsem.ru/vacancy/search?_page=1&_titleType=VACANCY_NAME&_title=%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%81%D1%82&_publishDateType=ALL

Бросайте PHP, изучайте SAP.
>>875485
#565 #875485
>>875483
Что я только что прочитал, это бред какой-то.

>Социально незащищенные категории: Инвалиды


Что бы это значило? Инвалиды же и так получают пенсию, она у них явно больше 12к.
Неужели, инвалид пойдёт работать за меньшие деньги, чем у него пенсия?
#566 #875489
Хочешь работать в Яндексе? Есть вакансия сишника от 12 000 р (ну учитывая качество кода типичного сишника, я бы больше и давал): https://trudvsem.ru/vacancy/card/1027700229193/cadd5c52-bae5-11e5-bbaf-3bdbd1a6e39d?to=https://trudvsem.ru/vacancy/search?_page=0&_titleType=COMPANY_NAME&_title=%D1%8F%D0%BD%D0%B4%D0%B5%D0%BA%D1%81&_publishDateType=ALL
#567 #875501
Как нормально подключать скрипты жс? Нихуя не выходит чет. Есть у меня файл шаблон, в нем же лежит js скрипт. Подключаю <script src="search.js"></script> - не работает. ЧЯДНТ?
>>875513
#568 #875513
>>875501

Открой вкладку network в отладчике браузера (ctrl + Shift + I), перезагрузи страницу, посомтри, грузится ли скрипт и откуда.
>>875516
55 Кб, 1440x900
#569 #875516
>>875513
Оно?
>>875521
#570 #875521
>>875516

Оно, только стоит выбрать "All " и перезагрузить страницу. Если нет скрипта- открыть исходный код страницы (ctrl + U) и поискать там тег "скрипт".
>>875534
62 Кб, 1440x900
#571 #875534
>>875521
Вроде все подключается, хм. Может в скрипте дело? На всский случай запощу
var cells = document.getElementsByTagName('td');
alert(cells);
>>875562>>875601
#572 #875553
Существуют ли адекватные, бесплатные, серверы/хостинги?
#573 #875562
>>875534

Посмотри еще в Console, нет ли ошибок. Ну и вообще, погугли и научись, как пользоваться инструментами разработчика.

С их помощью можно отладить скрипт, то есть пройти его по шагам и увидеть, как он выполняется.
>>875578>>875579
#574 #875578
>>875562
В консоли такая ошибка

>search.js:1 Uncaught SyntaxError: Unexpected token <

>>875600
#575 #875579
>>875562
Алсо сам скрипт работает, если его просто в hmtl код вставить.
#576 #875600
>>875578

По моему ты невнимательно пользовался инструментами разработчика. На вкладке Network надо нажать на запрос с search.js и проверить, что в содержимом правильный JS код, а не HTML.
#577 #875601
>>875534

Также проверь полный URL, по которому запрашивается search.js. У тебя там вместо JS HTML код отдается.
>>875605>>875606
#578 #875605
>>875601
Да, и правда. Наверное все дело в том, что я шаблон вызываю из котроллера, а не напрямую по ссылке.
#579 #875606
>>875601
Там вообще хрень какаято. Скрипт запрашивается по адресу search/search.js, которого у меня физически нет.
>>875625
#580 #875625
>>875606

Начни с чтения урока про ссылки https://github.com/codedokode/pasta/blob/master/network/urls.md
>>875627
#581 #875627
>>875625
Не понял как это применимо к моему случаю.
#582 #875646
Короче я понял в чем проблема. Суть в том, что я запускаю не какой-то файл, а метод контроллера из корня сайта, в index.php. Поэтому естественно не срабатывает подключать скрипт из просто закинув его туда же, куда и шаблон. Как тогда правильно подключать? Пробовал указывать путь <script src="/app/scripts/search.js"></script> - не срабатывает. Еще пробую <script src="<?php echo getcwd() . "\app\scripts\search.js"; ?>"></script> - но так возникает ошибка, браузер не разрешает из пеки грузить скрипт.
>>875667
#583 #875667
>>875646

У меня есть ощущение, что урок выше тебе все же надо прочитать.

Ты написал первоначально script src="search.js". То есть ты использовал относительный путь. Очевидно что тебе надо сначала изучить, как работают относительные пути, прежде чем их использовать. То есть прочитать урок по ссылке.

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

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


> браузер не разрешает из пеки грузить скрипт.


У тебя проблема с пониманием, как работает браузер и веб-сервер. И также проблема с пониманием, как устроены ссылки и что можно, а что нельзя писать в атрибуте src.

Браузер не знает ничего про файлы на сервере и он ничего не знает про то, какой файл генерирует страницу. Прочти в уроке про основы протокола HTTP: https://github.com/codedokode/pasta/blob/master/soft/web-server.md

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

Тебе надо:

- разобраться с относительными и абсолютными ссылками
- исправить приложение, чтобы при запросе с неправильным URL вроде /search/search.js отдавался код 404 как и положено в протоколе HTTP
>>875674
#584 #875670
>>875192
зачем ? просто загрузил в модель или модели , сделал сейв и либо отрисовал вьюху или узнал id этой записи (в AR должна быть функция) и направил на контроллер который будет брать эту запись с базы и рисовать во вьюхе
>>875684
#585 #875671
>>875253

>Надо использовать lastInsertId


не прокатит например если я сохранил запись а за мной сразу человек ешё сохранил запись оно вернёт значение записи 2 человека тк оно и будет последнее
>>875684
#586 #875672
>>875331
в гугле ответов аж отбавляй например
http://aaronfrancis.com/2013/automate-yii-migrations-in-heroku/
>>877093
#587 #875674
>>875667

>- разобраться с относительными и абсолютными ссылками


>- исправить приложение, чтобы при запросе с неправильным URL вроде /search/search.js отдавался код 404 как и положено в протоколе HTTP


Читал. Мало чего понял, но вроде как просто "search.js" - это относительный путь, тогда абсолютный должен быть \app\scripts\search.js? Т.е. от корня сайта. Но не работает же.
>>875677>>875684
#588 #875677
>>875674
может проблема в самом скрипте , код скрипта и файла в студию , но только на какой-то сервис для кода выложи
>>875680
80 Кб, 1440x900
#589 #875680
>>875677
Да я там просто alert('a') от греха подальше написал. В итоге абсурд какой-то.
#590 #875684
>>875671

lastInsertId возвращает последний вставленный id в рамках текущего соединения с mysql, оф мануал: http://dev.mysql.com/doc/refman/5.7/en/information-functions.html#function_last-insert-id

> The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, ....



>>875670

После успешной отправки формы надо редиректить (Post/Redirect/Get).

>>875674

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

> Мало чего понял


Значит надо перечитать еще раз и решить предложенные там задачи.

> но вроде как просто "search.js" - это относительный путь, тогда абсолютный должен быть \app\scripts\search.js?


Да, нужен путь от корня сайта.
#591 #875689
>>875684

>Что такое "корень сайта", по твоему, для браузера?


Ну вот вводишь example.com/ - разве это не корень сайта и есть?
>>875691
#592 #875691
>>875689

Ну вот, теперь правильно построй путь к скрупту от этого корня и впиши в src.
>>875698
#593 #875698
>>875691
Лол, так я это уже много раз делал. Не работает. Т.е. я так понимаю, если указать абсолютный путь, то без разницы из какого скрипта ты подключаешь другой скрипт? Вот есть у меня сайт students.local, скрипт лежит в /app/scripts/search.js, значит абсолютный путь будет src="/app/scripts/search.js"? Может мне лучше весь код показать? Заодно разберусь как выгружать проект на гитхаб. Но уже завтра.
>>875702
#594 #875702
>>875698

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

http://students.local/app/scripts/search.js

И проверить, что откроется?

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

Может у тебя корень не в той папке?

Код можешь показать, я гляну.
>>875704
#595 #875704
>>875702

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


Бля лол, спасибо. Это же надо так, слона то и не заметил. У меня же там просто редирект на index.php в любом случае.

>Код можешь показать, я гляну.


Тогда уже как студентов доделаю.
#596 #875765
История одного тестового задания: https://m.habrahabr.ru/company/ecwid/blog/315228/

А вы, аноны, можете его решить? Guzzle
>>875871
#597 #875800
>>875684
в фреймворке можно это не делать
http://stackoverflow.com/questions/13540317/active-record-last-insert-id
#598 #875805
>>875684
но за наводку в доку спасибо не знал
#599 #875849
Как изучать YII2? Прочитал документацию, посмотрел несколько видео. Понял как создавать модели, контроллеры, представления, понял как обрабатывать и выводить информацию в простейшем случае, узнал что есть хелперы и виджеты, которые всё упрощают, сделал постраничную разбивку, сделал формы, научился записывать в базу данных и выводить из неё данные. Смог написать блог, с добавлением записей, их отображением и сортировкой. Работает. Но такое ощущение что так ничего и не понял. Все эти модули, компоненты, приложения и многое другое о чём пишется в документации, воспринимаются как другая вселенная, я о них читаю и не представляют как их можно вписать и как их использовать. Складывается ощущение, что если не смотреть как кто-то их использует на реальной практике, я не смогу понять их смысл. Так как подсматривать не у кого, что делать? Как вы учили YII2 дальше знаний необходимых для создания блога? В документации у всех этих компонентов, модулей и всего остального нет демонстрации реального использования, только немного о том как они устроены, их код и синтаксис внутри фреймворка, и словесное описание для чего они нужны. Но так очень сложно понять их смысл.
>>875992>>877696
#600 #875850
>>875380

>https://someapprentice.github.io/maintaskforlayout/MotherfuckingWebsite.html - вот это конечно никуда не годится. Ладно, отсутствие полей у html можно объяснить необходимостью, но шрифт по умолчанию


С этим ещё я не разбирался, сначала нужно было с шрифтами разобраться. Закинул чтобы посмотреть что будет и случайно закоммител его.

>Я решил заглянуть в MSDN (мануалы майкрософта), чтобы найти информацию про font-face в ИЕ.


>


>https://msdn.microsoft.com/ru-ru/library/ms530757(v=vs.85).aspx


А я заместо этого читал про свойство font-weight в котором об этого ничего не сказано, а лишь помечено версией CSS2.1. Не удивительно что у меня столько проблем.

https://msdn.microsoft.com/ru-ru/library/ms530762(v=vs.85).aspx

>http://itsravenous.com/
Красивый дизайн. Похоже у меня появился один из примеров как должно выглядеть среднестатистическое портфолио верстальщика. (Для себя я сделаю что-нибудь по лучше)

>Я думаю, что в данном случае особо делать ничего не надо. Раз ИЕ8 и ниже не поддерживают семейства из нескольких начертаний, то пусть отображают шрифт как умеет. Моя точка зрения такая, что для малопопулярных браузеров достаточно, чтобы сайтом можно было пользоваться, а каким шрифтом будет отображена информация, не так и принипиально.


Интуитивно я приходил к этой мысли.

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


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

>> .consectetur::before {


>> .tristiquet::before {


>> .fermentum::before {


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


Я пытался это сделать, присвоить для всех заголовков общие свойства, но ничего не получилось https://jsfiddle.net/3fsukce0/

> .portfolio .content .works :nth-child(4n) {


> padding-right: 0px;


>Это плохая идея, так как подразумевает что картинки идут ровно в 4 ряда, хотя на узком экране удобнее их размещать например по 2-3 в ряд. И будет ли это работать корректно, когда мы скроем часть картинок?


А как тогда убрать отступ для последнего элемента в ряду? Учитывая что он не последний элемент по списку.
#600 #875850
>>875380

>https://someapprentice.github.io/maintaskforlayout/MotherfuckingWebsite.html - вот это конечно никуда не годится. Ладно, отсутствие полей у html можно объяснить необходимостью, но шрифт по умолчанию


С этим ещё я не разбирался, сначала нужно было с шрифтами разобраться. Закинул чтобы посмотреть что будет и случайно закоммител его.

>Я решил заглянуть в MSDN (мануалы майкрософта), чтобы найти информацию про font-face в ИЕ.


>


>https://msdn.microsoft.com/ru-ru/library/ms530757(v=vs.85).aspx


А я заместо этого читал про свойство font-weight в котором об этого ничего не сказано, а лишь помечено версией CSS2.1. Не удивительно что у меня столько проблем.

https://msdn.microsoft.com/ru-ru/library/ms530762(v=vs.85).aspx

>http://itsravenous.com/
Красивый дизайн. Похоже у меня появился один из примеров как должно выглядеть среднестатистическое портфолио верстальщика. (Для себя я сделаю что-нибудь по лучше)

>Я думаю, что в данном случае особо делать ничего не надо. Раз ИЕ8 и ниже не поддерживают семейства из нескольких начертаний, то пусть отображают шрифт как умеет. Моя точка зрения такая, что для малопопулярных браузеров достаточно, чтобы сайтом можно было пользоваться, а каким шрифтом будет отображена информация, не так и принипиально.


Интуитивно я приходил к этой мысли.

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


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

>> .consectetur::before {


>> .tristiquet::before {


>> .fermentum::before {


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


Я пытался это сделать, присвоить для всех заголовков общие свойства, но ничего не получилось https://jsfiddle.net/3fsukce0/

> .portfolio .content .works :nth-child(4n) {


> padding-right: 0px;


>Это плохая идея, так как подразумевает что картинки идут ровно в 4 ряда, хотя на узком экране удобнее их размещать например по 2-3 в ряд. И будет ли это работать корректно, когда мы скроем часть картинок?


А как тогда убрать отступ для последнего элемента в ряду? Учитывая что он не последний элемент по списку.
>>877696
#601 #875869
https://2ch.hk/pr/res/763854.html#875454 (М)
там еще один тред запилили. Какой православный то?
>>875911
#602 #875871
>>875765
Ну и как газлом качать многопоточно? Нужно как минимум pthreads ставить. Да и информация по этому расширению в сети скорее справочная, для тех, кто уже работал с многопоточностью в других языках. Для Java есть целые вводные книги по многопоточности.
>>875911
#603 #875911
>>875869

Этот. Тут ведь даже 700 постов еще нет. Куда спешить?

Тот тред там с лета висит.

>>875871

Не нужно. Нужно разобраться в возможностях курла и guzzle.

pthreads и треды уровня ОС работают хорошо только пока их мало. Странно, ты пишешь что работал с многопточностью, но не знаешь про другие подходы (например кооперативная многозадачность и асинхронные операции внутри одного потока ОС).
#604 #875916
Привет, подскажите по JS,
можно ли указывать свойство объекта в качестве ключа другого объекта?

Hamburger.allowedToppings = {
Hamburger.TOPPING_MAYO: 123
};

В топике JS подсказывают, что можно, но ideon и хром выдают ошибку:

SyntaxError: Unexpected token .

http://ideone.com/qpKFUB
>>875971>>877695
#605 #875971
>>875916

Нельзя использовать выражения в ключах в литерале объекта (литерал объекта это конструкция вида { a: 1, b: 2 }).
#606 #875992
>>875849

Yii очень гибкий, на некоторые вопросы о том, как правильнее использовать компоненты, разработчики отвечают, "Как хотите".

Есть https://github.com/samdark/yii2-cookbook можно полистать её, но лучше всего, смотреть, как сделаны готовые приложения или проекты.
Хотя везде всё не однозначно.
>>876044
#607 #876044
>>875992
Почему там половина страниц отсутствует: https://github.com/samdark/yii2-cookbook/blob/master/book/README.md
Жаль, интересный сборник, надо бы поискать, есть ли полный сборник на просторах, должен быть.
>>876067
#608 #876067
>>876044

> должен быть.


В описании написано, что книга полностью свободная, пишется Макаровым и контрибуторами с гитхаба, поэтому "полный сборник" искать бессмысленно.
Есть ещё полный Cookbook, но он по Yii 1.
28 Кб, 563x375
27 Кб, 683x267
#609 #876093
Почему с else не работает?
>>876097>>876104
#610 #876097
>>876093
В else нельзя указывать условия, так как else означает "во всех оставшихся случаях". Если нужно условие, то используй elseif
>>876098
#611 #876098
>>876097
Вот оно что. Спасибо.
#612 #876104
>>876093
а чего у тебя в if compDice1==compDice2 - два раза повторяются ?
#613 #876209
поясните ньюфагу, для чего в пышке имена переменных предваряются долларом? Только начал учиться по гайдам опа, никаких затруднений нет, но необходимость вставлять доллар перед именами заёбывает ппц как.
#614 #876212
>>876209
Что бы жизнь малиной не казалась.
#615 #876321
>>876209
А var писать в JS/Pascal не надоедает? А объявлять тип переменной в C/C++/Java/C#? В Perl и Bash тоже доллары предваряют переменные, привыкнешь и не будешь замечать.
69 Кб, 550x733
#616 #876331
Где можно почитать про так называемые "горячие клавиши", которым вы наверняка вы пользуетесь и какими чаще? Я имею ввиду допустим когда я пишу код все время переставлю все мышкой, кроме очевидных абзацев клавишей enter.
>>876386
#617 #876341
>>876209
Чтобы была иллюзия прибыльности в изучении программирования в общем и использования этого языка в частности...
(Смахивая скупую мужскую слезу.)
#618 #876384
>>876209
Чтобы отличить переменную от константы? На самом деле удобно
1287 Кб, 2480x3508
#619 #876386
>>876331
в описании своего текствого редактора.
Гугли cheat sheet
>>876389>>876442
#620 #876389
>>876386
Спасибо, няша
#621 #876442
>>876386
Я может в глаза долблюсь, но в твоем пикрелейтеде не вижу, как в атоме отформатировать код? Для примера, в нетбинсе я жму контрол-шифт-f и у меня сразу пробелы, отступы, переносы скобок и вся такая фигня появляется, а как в атоме?
>>876490>>876511
#622 #876490
>>876442
a basic version can be made by putting this in your keymap file:

'.editor:not(.mini)':
'alt-cmd-l': 'editor:auto-indent'
>>876618
#623 #876511
>>876442
плугин
atom-beautify
>>876618
#624 #876520
>>874536

Анончик расакажи пожалуйста про тестирование (генерацию ошибок) которое ты сделал в 12 задаче: http://ideone.com/873GTD

Такой способ тестирования как-то называется и кем-то где-то описан, или ты сам придумал?

Алсо, сколько лет занимаешься JS?
>>876749
#625 #876523
Привет, не могу понять как реализуется наследование в es3. Что такое "хак с прототипами" ? Rabbit.prototype.__proto__ = Animal.prototype;? В learn.javascript наследование описано с помощью Object.create().
>>876572>>877695
#626 #876572
>>876523

> В learn.javascript наследование описано с помощью Object.create()


Не только: http://learn.javascript.ru/new-prototype#inherit
414 Кб, 1455x1455
#627 #876599
Всем доброго дня,
http://ideone.com/YSfidW - опечаточки. Проблема в том, что бормалеи-корупционеры меняют сразу по две, а то и три буквы в слове и получается не очень.
http://ideone.com/meYReN - Gr. Nazi. Вроде работает.
>>877694>>877711
#628 #876618
>>876490
>>876511
Кошмар, прям емакс какой-то, все надо допиливать. Но все равно спасибо.
>>876628
#629 #876628
>>876618
а что тебе не нравится? Это текстовый редактор, а не IDE.
Ставь что нравится, а если бы стояло все на свете, то тормозил бы как PHPStorm
>>876632>>876653
#630 #876632
>>876628
Это какой древний калькулятор нужно откопать, что бы на нем PHPStorm тормозил?
>>876640
#631 #876640
>>876632
Ну я в игори не играю, поэтому мне хватает некропеки. Поставил пхпшторм - тормозит, один запуск секунд 30-40 чего стоит. Поставил нетбинс - все летает, грузится за 5 секунд, а функционал тот же. Еще и швабодно.
>>876687
#632 #876653
>>876628
Поставил я плагин, а оно мне ошибку, гуглю ошибку - 24000 результатов и танцы с бубнами. С емаксом то я погорячился. Атом - стильно, модно, молодежно и малопригодно к использованию.
>>876655>>876684
#633 #876655
>>876653
нормально пригодно, лол.
Да, у меня тоже не работает плугин (php-linter), а некоторые настраивать надо. НАпример этот же бьютифаер может потребовать немного в конфиге поковыряться или зависимости поставить
>>876687
#634 #876684
>>876653
Потому и стоит использовать IDE. Когда используешь редактор все время хочется еще какого-то функционала, а значит куча времени уходит на танцы с бубнами, в то время как в IDE есть все сразу искаропки. Тот же нетбинс удобен, швабоден, и темку можно как в атоме поставить, например.
#635 #876687
>>876655
>>876640

А у меня шото, шо то тормозит.
При то что саблайм текст нормально работает и я того же от атома ожидал в надежде уйти на него со шторма, хотя в нем всё же нет менеджера баз данных например и еще некоторых плюшек
>>876688
#636 #876688
>>876687

>А у меня шото, шо то тормозит.


Поставь пакет нетбинса, в котором только пхп+хтмл/цсс+жс. Тогда норм должно быть. Если и тогда будет тормозить - ну тогда не знаю, твоя последняя надежда эклипс.
#637 #876743
http://ideone.com/YUrAg9 чому не работает подстановка запроса? Если ставлю переменную в $sql то все норм, а подстановкой не сортирует.
>>877694
24 Кб, 704x562
#638 #876749
>>876520
Я его у другого анончика украл из готового решения, хех (когда одним глазком подсмотрел непонятный момент в задаче), так что не знаю что за способ. Обычный цикл с вызовом функций. Лет? 0,25, т.е. 3 месяца (если сложить время продуктивного обучения, то наберется на недели 3).
#639 #876772
>>874960
Таки бамп
>>876814
#640 #876814
>>876772

>бампать треды в бамп-лимите

>>876822
#641 #876822
>>876814
Так я не тред бампаю, я свой вопрос бампаю.
>>876841
#642 #876841
>>876822
Зачем ты его бампаешь? ОП проверяет всех без исключения, только это происходит не сразу и по очереди. А кроме ОПа тебе вряд ли кто-нибудь хороших советов напишет.
>>876846
#643 #876846
>>876841
ОП тоже человек, бывает пропустит пост какой-нибудь, не просто так же он иногда просит напоминать о себе.
#644 #876988
https://m.habrahabr.ru/post/315152/
"Ваш язык программирования — отстой"

Во многом согласен.
>>877008>>877033
#645 #877008
>>876988
как и говорили в комментах хороший старт лист для тролля , ну и естественно там только 1 язык не отстой brainfack
>>877023
#646 #877023
>>877008

Ну вот теперь тебе есть что ответить любителям других языков, если они будут критиковать пхп.
#647 #877033
>>876988

>//m.


Мне-бы хотелось сказать. Что так делать плохо.
#648 #877093
>>875672
Это ответ про миграции, а как запустить, там сам проект, всё еще не совсем ясно и вроде, как пишут что это не просто.

Бамп вопросу про альтернативы хероку или бесплатные серверы
>>877197>>877210
#649 #877158
http://ideone.com/c0TxC3

Куда дальше копать в отношении этого задания ?
Как добиться того, чтобы 8 (8122) 56-56-56 - этот номер принимало ?
Почему из списка неправильных номеров так много проходит ?
>>877694
#650 #877197
>>877093
а вы вообще понимаете как работает херок ?
#651 #877210
>>875331
>>877093

Позволь мне погуглить за тебя: https://devcenter.heroku.com/articles/getting-started-with-php
#652 #877253
Как правильно делать валидацию в на сервере? Гугл находит статьи, в которых данные просто надо прогонять через кучу функций типа трим, стрип_слешес и прочее, но я чую, что это плохой способ. Как это делать правильно?
>>877290>>877299
#653 #877290
>>877253
Нормальный способ, так оно и бывает.
Сейчас смотрю валидацию в Yii2 - там куча валидаторов, каждый цепляется один к другому, проверяя значение переменной на любые соответствия.
>>877300
#654 #877299
>>877253

Валидация - это проверка введенных данных на соответствие правилам. Например, что имя пользователя состоит из латинских букв, что возраст - это число от 1 до 200 и тд.

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

trim() это не часть валидации, но ее стоит делать, так как лишние пробелы справа не видны, но могут помешать прохождению валидации.
>>877301
#655 #877300
>>877290
Короче пока делаю так. Сначала проверяю данные на соответствие по длине и типу, потом если все норм - прогоняю их через эти функции. Сойдет?
>>877303>>877309
#656 #877301
>>877299

>Валидация - это проверка введенных данных на соответствие правилам. Например, что имя пользователя состоит из латинских букв, что возраст - это число от 1 до 200 и тд.


Знаю, а разве вместе с валидацией не убирают пробелы там и прочее?
>>877303>>877309
#657 #877303
>>877300

Нет, не сойдет. Зачем прогонять данные через какие-то функции?

>>877301

Валидация - это проверка данных. Убирают пробелы где-то в другом месте кода, например в коде для работы с формами.
>>877306>>877309
#658 #877306
>>877303

>Валидация - это проверка данных. Убирают пробелы где-то в другом месте кода, например в коде для работы с формами.


Хм. А почему нельзя все это в одном классе делать, например?
>>877309
#659 #877309
>>877300
Вполне.

>>877301
Да, при сохранении в БД - обязательно.
В Yii2 это trim валидатор будет.

>>877303
Как так зачем? Очистить от мусора, преобразовать "инъекции" в простой HTML.
Я что-то не пойму тебя.

>>877306
В Yii2 в одном и делается, там два метода: на клиенте проверка до отправки на сервер и уже на самом сервере.
>>877350
#660 #877310
Точнее так - я хочу сделать класс валидатор, допустим Validator, который убирает проблемы, прогоняет данные через htmlspecialchars а потом проверяет данные по нужным мне критериям. Так сойдет?
>>877350>>877355
#661 #877317
Кстати а зачем вообще делать валидацию и в клиенете, и на сервере?
>>877321>>877350
#662 #877321
>>877317
Потому что пользователи могут отключить js в браузере и отправить drop table и если на сервере не проверить выебут тебя.
>>877324
#663 #877324
>>877321
А почему тогда не запретят такую ебалду по http передавать?
>>877338
#664 #877338
>>877324
какую ? данные ? запретить передавать данные по http ?
>>877371
#665 #877350
>>877309

> Очистить от мусора, преобразовать "инъекции" в простой HTML.


В документации по strislashes написано, что она удаляет мусор и защищает от инъекций?

Ты видимо просто не понимаешь как работают SQL-инъекции (и XSS) и потому не знаешь, как от них надо защищаться. Люди, у которых мало знаний, часто обращаются к религии и суевериям. Потому ты ставишь в начале программы пару "волшебных" функций как оберег.

>>877310

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

>>877317

На сервере в целях безопасности и для гарантии соблюдения заданных правил.

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

>>877309

> В Yii2 это trim валидатор будет.


я сомневаюсь, что это "валидатор", ты по моему просто так думаешь потому, что trim в модели пишется рядом с правилами валидации.
>>877566
#666 #877355
>>877310
Зачем тебе htmlspecialchars, он для защиты от XSS при выводе информации, отправленной пользователем. Не надо думать "понипихаю побольше функций, хуже не будет". Будет. Вот пример: http://pyha.ru/forum/topic/5684

> 'format' => 'json',


Заметил сколько мусора здесь? Это потому, что люди бездумно используют кучу функций, думая, что "хуже не будет, только безопасней".
>>877371
#667 #877371
>>877338
Ну типа, что бы если сервер виделв запросе sql-код то он бы просто игнорировал его.
>>877355
Хорошо. Тогда где вызывать тот же trim()?
>>877375
#668 #877375
>>877371

Как отличить SQL-код от не SQL кода? LIMIT 10 это SQL код или нет? Что, если надо опубликовать комментарий или пост, содержащий SQL код?

> Тогда где вызывать тот же trim()?


Там, где ты получаешь данные, пришедшие из формы.
>>877380>>877393
#669 #877380
>>877375

>Как отличить SQL-код от не SQL кода? LIMIT 10 это SQL код или нет? Что, если надо опубликовать комментарий или пост, содержащий SQL код?


Теперь понятно.
#670 #877393
>>877375
Нашел еще функцию strip_tags(), по описанию годно. Ее стоит использовать?
#671 #877566
>>877350

>Ты видимо просто не понимаешь как работают SQL-инъекции (и XSS) и потому не знаешь, как от них надо защищаться. Люди, у которых мало знаний, часто обращаются к религии и суевериям. Потому ты ставишь в начале программы пару "волшебных" функций как оберег.


Я только ещё учусь. Но ты же не думаешь, что не нужно преобразовывать введённый пользователем код в простой и безопасный HTML? А чего тогда? Мы только об этом и говорим пока, что это нужно.

>я сомневаюсь, что это "валидатор", ты по моему просто так думаешь потому, что trim в модели пишется рядом с правилами валидации.


Это базовый FilterValidator ([[yii\validators\FilterValidator|trim]]), вот его структура:
[
[['username', 'email'], 'trim'],
]
Никто не говорит про смешать всё вместе и не по ООП, мы говорим про то, что надо всячески проверять введенные данные на клиенте и сервере, для этого надо использовать функции, если человек всё пишет с нуля.
>>877641
#672 #877641
>>877566

А ты читал мои (или не мои) уроки по уязвимостям?

- https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
- https://github.com/codedokode/pasta/blob/master/security/xss.md
- https://github.com/codedokode/pasta/blob/master/security/xsrf.md

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

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

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

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

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

> Это базовый FilterValidator ([[yii\validators\FilterValidator|trim]]),


Действительно, в неймспейсе написано validators. Но я не поленился заглянуть в код:

https://github.com/yiisoft/yii2/blob/master/framework/validators/FilterValidator.php#L13

> FilterValidator is actually not a validator but a data processor.



Это просто разработчики Юи неудачно назвали класс. Это правильнее называть "фильтр". Чтобы увидеть разницу между фильтром и валидатором, можно попробовать применить валидацию не к данным из формы, а например к данным из БД. Для них trim делать не потребуется, так как они там уже отфильтрованные.

> что надо всячески проверять введенные данные на клиенте и сервере, для этого надо использовать функции, если человек всё пишет с нуля.


Проверять надо, но ты-то предложил просто поставить в начале strip_tags не особо разбираясь, к чему это приведет. А приведет это к искажениям пользовательских данных.
#672 #877641
>>877566

А ты читал мои (или не мои) уроки по уязвимостям?

- https://github.com/codedokode/pasta/blob/master/security/sql-injection.md
- https://github.com/codedokode/pasta/blob/master/security/xss.md
- https://github.com/codedokode/pasta/blob/master/security/xsrf.md

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

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

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

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

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

> Это базовый FilterValidator ([[yii\validators\FilterValidator|trim]]),


Действительно, в неймспейсе написано validators. Но я не поленился заглянуть в код:

https://github.com/yiisoft/yii2/blob/master/framework/validators/FilterValidator.php#L13

> FilterValidator is actually not a validator but a data processor.



Это просто разработчики Юи неудачно назвали класс. Это правильнее называть "фильтр". Чтобы увидеть разницу между фильтром и валидатором, можно попробовать применить валидацию не к данным из формы, а например к данным из БД. Для них trim делать не потребуется, так как они там уже отфильтрованные.

> что надо всячески проверять введенные данные на клиенте и сервере, для этого надо использовать функции, если человек всё пишет с нуля.


Проверять надо, но ты-то предложил просто поставить в начале strip_tags не особо разбираясь, к чему это приведет. А приведет это к искажениям пользовательских данных.
>>877663
12 Кб, 769x181
#673 #877662
Анончик, ответь, пожалуйста, на нубовопрос. Задачка из учебника ОПа про кредиты на гейфон. И в конце вывожу методом echo переплату и период. Причём переплата вычисляется непосредственно в методе. Из-за чего в выходной строке пропадает слово "Переплата" как на пикрелейтед. Почему так происходит? И как правильно вставлять выражения в строку вывода?
>>877664
#674 #877663
>>877641
Спасибо, постараюсь охватить сие своим умишком...
#675 #877664
>>877662
Это из-за приоритета операторов, сначала происходит конкатенация строки "Переплата" и переменной $total, а из получившегося результата вычитается $credit. Можно явно указать PHP повысить приоритет для вычитания, обернув выражение $total - $credit в скобки.
#676 #877694
>>877158

> \+7|\+\s7|^8|^\\s8([0-9](\s|\-|\(|\))?){10}



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

(\+7) или (\+\s7) или (^8) или (^\\s8([0-9](\s|\-|\(|\))?){10})

То есть например, если номер начинается с 8 то он всегда пройдет независимо от того, что идет дальше. Или если в номере на любой позиции есть +7, он тоже проходит.

Ты наверняка имел в виду что-то другое, потому используй круглые скобки, чтобы огранить действие вертикальной черты. Примерно так: (a|b|c)d

Далее, \+7 и \+\s7 можно легко объединить вместе.

(\s|\-|\(|\))? - это значит, что может встретиться любой из этих символов не более 1 раза. Но я бы сделал, чтобы они могли встретиться любое число раз, так как например скобка может быть окружена пробелами.

>>876743

Через плейсхолдеры можно подставлять только числа (WHERE x = 100) или строки в кавычках (WHERE x = 'abc'). Подставить имя колонки нельзя, так как оно вставится как ORDER BY 'name' - и смысл меняется, так как 'name' это постоянная строка, а не значение соотв-й колонки.

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

>>876599

> \p{Cyrillic}


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

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

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


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

Gr. Nazi.

Боюсь, у тебя проверяются не все правила. Вот например: "нет пробела после запятой, точки с запятой, восклицательного знака, вопросительного знака, двоеточия" - это не проверяется. Или "в тексте есть слово «координально» или «сдесь», «зделал», «зделаю», «зделан»". Также, есть правило для "но", но нет правила для "а".

Выражения для жы/шы можно было бы объединить вместе.

Я думаю, ты зря там используешь preg_quote и проще было бы сразу писать нужные регулярные выражения.
#676 #877694
>>877158

> \+7|\+\s7|^8|^\\s8([0-9](\s|\-|\(|\))?){10}



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

(\+7) или (\+\s7) или (^8) или (^\\s8([0-9](\s|\-|\(|\))?){10})

То есть например, если номер начинается с 8 то он всегда пройдет независимо от того, что идет дальше. Или если в номере на любой позиции есть +7, он тоже проходит.

Ты наверняка имел в виду что-то другое, потому используй круглые скобки, чтобы огранить действие вертикальной черты. Примерно так: (a|b|c)d

Далее, \+7 и \+\s7 можно легко объединить вместе.

(\s|\-|\(|\))? - это значит, что может встретиться любой из этих символов не более 1 раза. Но я бы сделал, чтобы они могли встретиться любое число раз, так как например скобка может быть окружена пробелами.

>>876743

Через плейсхолдеры можно подставлять только числа (WHERE x = 100) или строки в кавычках (WHERE x = 'abc'). Подставить имя колонки нельзя, так как оно вставится как ORDER BY 'name' - и смысл меняется, так как 'name' это постоянная строка, а не значение соотв-й колонки.

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

>>876599

> \p{Cyrillic}


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

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

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


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

Gr. Nazi.

Боюсь, у тебя проверяются не все правила. Вот например: "нет пробела после запятой, точки с запятой, восклицательного знака, вопросительного знака, двоеточия" - это не проверяется. Или "в тексте есть слово «координально» или «сдесь», «зделал», «зделаю», «зделан»". Также, есть правило для "но", но нет правила для "а".

Выражения для жы/шы можно было бы объединить вместе.

Я думаю, ты зря там используешь preg_quote и проще было бы сразу писать нужные регулярные выражения.
>>877711>>877756
#677 #877695
>>876523

Такой важный вопрос, а я пропустил.

__proto__ - это нестандартная конструкция и ее использовать не стоит (ее используют в учебнике для простоты). В ES5 есть функция Object.getPrototypeOf(o) чтобы получить прототип объекта (а в ES6 - еще и Object.setPrototypeOf()).

В JS есть 3 способа создать объект с заданным прототипом:

1) в ES5 есть функция Object.create(p), которая создает пустой объект с прототипом p
2) в ES6 есть Object.setPrototypeOf(), которая задает объекту прототип
2) с помощью оператора new

В ES3 нам доступен только new. Посмотрим, как он работает:

function F() { ... };
F.prototype = p;
obj = new F;

Оператор new F() делает следующее:

- создает новый пустой объект
- делает его прототипом объект, хранящийся в F.prototype
- вызывает функцию F, передав в качестве this новый объект

Таким образом, мы можем написать на ES3 аналог функции Object.create(). Очевидно, что нам надо использовать оператор new, а объект-прототип p сохранить в свойство prototype функции-конструктора. Саму функцию-конструктор можно сделать пустой:

function createWithPrototype(p) {
function F() {};
F.prototype = p;
return new F();
}

Прочитай еще уроки из учебника:

- https://learn.javascript.ru/constructor-new
- https://learn.javascript.ru/new-prototype

>>875916

Можно писать так:

allowed[Hamburger.TOPPING_...] = ...;
#677 #877695
>>876523

Такой важный вопрос, а я пропустил.

__proto__ - это нестандартная конструкция и ее использовать не стоит (ее используют в учебнике для простоты). В ES5 есть функция Object.getPrototypeOf(o) чтобы получить прототип объекта (а в ES6 - еще и Object.setPrototypeOf()).

В JS есть 3 способа создать объект с заданным прототипом:

1) в ES5 есть функция Object.create(p), которая создает пустой объект с прототипом p
2) в ES6 есть Object.setPrototypeOf(), которая задает объекту прототип
2) с помощью оператора new

В ES3 нам доступен только new. Посмотрим, как он работает:

function F() { ... };
F.prototype = p;
obj = new F;

Оператор new F() делает следующее:

- создает новый пустой объект
- делает его прототипом объект, хранящийся в F.prototype
- вызывает функцию F, передав в качестве this новый объект

Таким образом, мы можем написать на ES3 аналог функции Object.create(). Очевидно, что нам надо использовать оператор new, а объект-прототип p сохранить в свойство prototype функции-конструктора. Саму функцию-конструктор можно сделать пустой:

function createWithPrototype(p) {
function F() {};
F.prototype = p;
return new F();
}

Прочитай еще уроки из учебника:

- https://learn.javascript.ru/constructor-new
- https://learn.javascript.ru/new-prototype

>>875916

Можно писать так:

allowed[Hamburger.TOPPING_...] = ...;
#678 #877696
>>875850

> А я заместо этого читал про свойство font-weight в котором об этого ничего не сказано, а лишь помечено версией CSS2.1. Не удивительно что у меня столько проблем.


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

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


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


Ну попробуй, если хочешь.

> Я пытался это сделать, присвоить для всех заголовков общие свойства, но ничего не получилось https://jsfiddle.net/3fsukce0/


h3 и h3::before это разные элементы. Потому нельзя задавать content на h3, надо на h3::before.

> А как тогда убрать отступ для последнего элемента в ряду? Учитывая что он не последний элемент по списку.


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

parent { margin-left: -10px; }
child { margin-left: 10px; }

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

>>875849

Может тебе надо попробовать сделать что-то посложнее блога? У нас в ОП посте есть задача на сайт TestHub например.

- "компоненты" в Юи, как я понимаю, это обычные классы-сервисы, выполняющие какую-то функцию. Например, компонент для отправки уведомлений на почту.
- "модули" нужны для группировки контроллеров, вью и моделей в больших приложениях. Когда у тебя будет 20-30-40-50 контроллеров и куча моделей, неудобно хранить все в одной папке. Удобно разбить приложение на отдельные модули. Также модули можно делать для повторного использования. Например, модуль форума, который можно подключить к любому сайту.
- "приложения" можно исплользовать, например, если мы хотим в одном проекте реализовать несколько сайтов, мы можем сделать каждый отдельным приложением. При этом какие-то модули можно использовать в нескольких приложениях сразу. Иногда админку или личный кабинет делают отдельным приложением. Главное что для приложения можно задать индивидуальные настройки.

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

В общем, модули и приложения нужны для организации кода в больших приложениях.

>>875388

> $totalPayment = $totalPayment + $creditBalance;


Это повторяется 2 раза, хорошо бы избавиться от повтора.
#678 #877696
>>875850

> А я заместо этого читал про свойство font-weight в котором об этого ничего не сказано, а лишь помечено версией CSS2.1. Не удивительно что у меня столько проблем.


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

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


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


Ну попробуй, если хочешь.

> Я пытался это сделать, присвоить для всех заголовков общие свойства, но ничего не получилось https://jsfiddle.net/3fsukce0/


h3 и h3::before это разные элементы. Потому нельзя задавать content на h3, надо на h3::before.

> А как тогда убрать отступ для последнего элемента в ряду? Учитывая что он не последний элемент по списку.


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

parent { margin-left: -10px; }
child { margin-left: 10px; }

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

>>875849

Может тебе надо попробовать сделать что-то посложнее блога? У нас в ОП посте есть задача на сайт TestHub например.

- "компоненты" в Юи, как я понимаю, это обычные классы-сервисы, выполняющие какую-то функцию. Например, компонент для отправки уведомлений на почту.
- "модули" нужны для группировки контроллеров, вью и моделей в больших приложениях. Когда у тебя будет 20-30-40-50 контроллеров и куча моделей, неудобно хранить все в одной папке. Удобно разбить приложение на отдельные модули. Также модули можно делать для повторного использования. Например, модуль форума, который можно подключить к любому сайту.
- "приложения" можно исплользовать, например, если мы хотим в одном проекте реализовать несколько сайтов, мы можем сделать каждый отдельным приложением. При этом какие-то модули можно использовать в нескольких приложениях сразу. Иногда админку или личный кабинет делают отдельным приложением. Главное что для приложения можно задать индивидуальные настройки.

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

В общем, модули и приложения нужны для организации кода в больших приложениях.

>>875388

> $totalPayment = $totalPayment + $creditBalance;


Это повторяется 2 раза, хорошо бы избавиться от повтора.
320 Кб, 1455x1455
#679 #877711
>>877694
Я вот этот парень >>876599. В Gr.Nazi использовал такой подход чтобы упростить добавление или удаление правил и все правила я не прописал, постараюсь переписать для каждого правила своя регулярка.
Над "опечатками" мысль принял к обдумыванию.
Тысячу лет жизни тебе ОП.
#680 #877756
>>877694
http://ideone.com/c0TxC3
вот так исправил.
Спасибо тебе за то, что отвечаешь )
#681 #877798
Возомжно ли нетбинс обмазать под JS и HTML/CSS так, что бы не пользоваться вебштормом? А то нетбинс и быстрей, и бесплатный, и в качестве ide для пхп меня более чем устраивает.
#682 #877869
Подскажите, нигде не могу найти информации:
Есть ли какой то существенный недостаток такого использования $$ http://ideone.com/fpraVK кроме засорения пространства имен ?
Я конечно не так использую, просто для наглядности сделал пример.
К примеру у меня есть большой массив который хранит в себе информацию по действиям который должны выполняться над некоторым текстом, и чтобы не выдумывать имена переменным внутри foreach я использовал $$ с ключом .
>>877907
#683 #877907
>>877869

Недостаток в том что код невозможно понять так как неизвестно какие именно переменные будут созданы. Вместо $$ надо использовать массив.
>>877908
#684 #877908
>>877907
Ну это >кроме засорения пространства имен.
А помимо этого?
>>877914>>877916
#685 #877914
>>877908

Бессмысленное усложнение и запутывание кода. Можно написать $x = 1, а можно $y = 'x'; $$y = 1;
#686 #877916
>>877908

Есть впрочем функция extract(), она обычно используется для передачи переменных в HTMl шаблон. Но в твоем примере кода цикл не нужен.
37 Кб, 1000x443
#687 #877986
>>873884
А так понятно?
>>878072
#688 #878072
>>877986

В PSR переменные называют кемелКейсом, а не через подчеркивания. Названия надо выбрать получше:

text_ar -> characters
word -> character
text_ar_t - непонятно, что значит. Не сокращай слова, пиши полностью.
text_r_ar - непонятно, что значит
text_tr - непонятно
text_r_tr - непонятно

Для удаления пробела хватит str_replace, цикл не нужен

Вместо цикла for($i = 0 лучше использовать foreach

Есть готовая функция array_reverse.

strcasecmp не работает корректно с utf-8 и ее лучше не использовать, урок https://gist.github.com/codedokode/ff99e357e9860ea169b8

Вместо регистронезависимого сравнения проще привести строку в нижний регистр.
>>878107
#689 #878073
Двачую затруднения с регулярками, та ещё мозгоёбка. Например, вот из задачки с парсером телефонов, решение, которое здесь мелькало.

$regexp = '/^( ?8|^\+ ?7)([-() ]\d){10}$/';

Точнее, интересует её вторая половина (первая мне понятна, хотя и избыточна, имхо):

([-() ]
\d){10}

Почему указатель количества 10 применяется не ко всем символам, а только к цифрам? Т.е. не пройдёт такое:
+7---1---)--
#690 #878074
>>878073
после закрывающей квадратной скобки звезда не прошла, ну вы понели.
#691 #878077
>>878073
те., я бы прочитал этот кусок так: "должны быть цифры и опционально разделители. И суммарно их должно быть не больше 10". Но в итоге число 10 применяется именно к цифрам, а не ко все длине строки.
#692 #878088
>>878073

{10} применяется к тому, что идет перед ним, в данном случае там круглые скобки и повторение относится к их содержимому. То есть 10 раз x ( любое число дополнительных символов, за которыми ровно одна цифра ). В итоге получается ровно 10 цифр и произвольное число доп. символов перед каждой.
>>878093
#693 #878093
>>878088
благодарствую, анон, теперь понял.
#694 #878107
>>878072
foreach ведь перебирает элементы начиная с 0, а array_pop уменьшает стек, поэтому в массиве text_r(reverse)_ar будет не столько же элемов, сколько и в стеке. Поэтому я решил исп. простой цикл. Или я хуйню несу?
>>878108
#695 #878108
>>878107

Вообще лучше всего наверно было использовать цикл while, если ты его изучил:

пока (массив не пуст) {
снимаем один элемент;
...
}

но как я написал, есть уже готовая функция переворота массива.
>>878113>>878405
#696 #878113
>>878108
Не, там в уроках только for до этого. Мне он не нравится. text_r(reverse) есть жи.
#697 #878132
>>866012

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

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

>>866117

> (ideone не отобразит)


Почему не отобразит? Надо, чтобы отображал.

> $sinalpha=$lk/$lo;


Надо выбирать нормальные имена переменных. Что такое lk? Непонятно.

> $alpha=$key/$radius;


Вот наверно здесь ошибка. Непонятно, на каком основании ты делишь номер буквы на радиус? Надо преобразовть номер буквы в угол так, чтобы получались бы числа от 0 до 360 градусов. Градусы потом перевести в радианы с помощью deg2rad(). И радианы уже подставлять в синус.

> sin($alpha)*57.2958


Это попытка перевести радианы в градусы? Неправильно. Радианы и градусы - это меры величины угла, и радианы являются аргументов функции sin(). А результат sin() - это отношение сторон треугольника, от 0 до 1, и его умножать на 57 не имеет никакого смысла.

Повтори школьную тригонометрию: https://www.google.ru/search?q=математика+синус&btnG=Поиск&newwindow=1&gbv=1

> $x=(round(($x))+40);


Тут должно быть не число 40, а половина высоты.
#698 #878293
Ребята, плАчу в голос: знакомый прислал тестовое задание на джениора в контору, в которой он работает, у них там всё на yii2.
Эх, я вообще тупой и никуда не гожусь - я даже не понимаю, как так можно сделать, чтобы в любой год находился, допустим, второй вторник ноября...
Вот ТЗ тестовое:

Тестовое задание, Yii2
- несколько событий, обработчики, запуск и оповещения;
- веб-интерфейс создания и настройки события: само событие, время срабатывания (месяц, число, день недели и час суток) и время окончания, прочие условия срабатывания на своё усмотрение (выбор конкретного год срабатывания события или выбор повторения события каждый год).
- проверка:
1) события должны срабатывать каждый первый понедельник июня вне зависимости от года;
2) события должны срабатывать каждый четвёртый вторник ноября вне зависимости от года;
3) события должны срабатывать каждые третье воскресенье ноября вне зависимости от года;
- срок реализации: 5 часов.
Я плачу и ору в голос, не понимаю, что тут возможно сделать.
P.S. Я не устраиваюсь туда, просто решил проверить себя, годен ли.
Подскажите, как такое реализовать, чтобы конкретные дни недели определить в любой год.
#699 #878295
>>878293
*джуниора
#700 #878307
>>878293

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



Есть алгоритм вечного календаря же:
https://goo.gl/bDYhRC
Итеративно можно определить дни недели для всех дат нужного месяца нужного года.
>>878315>>878384
#701 #878315
>>878307
Спасибо!
http://ru.wikibooks.org/wiki/Реализации_алгоритмов/Вечный_календарь#PHP
Но я всё равно пока не соображу, как именно ко дню недели это привязать.
Вот надо найти второй вторник ноября в любой год.
Например, можно сделать цикл switch, в котором прогонять каждый день ноября через алгоритм, если это вторник - вуаля, событие активизируется.
Я верно мыслю?
>>878344
Аноним #702 #878344
>>878315
по всей видимости с помощью этого алгоритма ты должен находить дату , вернее число вторника 2 (10.12,11.01) и тд и инсертить в базу
>>878384>>878538
Аноним #703 #878363
>>878538
#704 #878384
>>878293

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

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

Нетрудно обобщить функцию до проверки что сегодня N-й по счету день недели M.

Почитай мануалы по функции date, strtotime

Ну и урок, может там что-то есть такое: https://gist.github.com/codedokode/10539805

>>878307

Этот алгоритм давно встроен в PHP (точнее в стандартную библиотеку Си под линуксом), определить текущий день недели можно через функцию date().

тебе тоже стоит почитать мануал.

>>878344

Я думаю, там нужен крон.
>>878538>>878594
30 Кб, 613x379
#705 #878405
>>878108
Верный ответ? Ну и имена норм?
>>878406
41 Кб, 643x640
#706 #878406
>>878405
Бля, забыл исправить в сравнении. Otвет тот же выходит
>>878518
#707 #878518
>>878406

Переменные в рекомендации PSR принято писать кемелКейсом, а не через подчеркивание (см второй пост треда).

Имена переменных пишут с маленькой буквы.

Метод расчета довольно костыльный: ты сначала переплачиваешь больше, чем нужно, а потом из общей суммы выплаченного вычитаешь лишнее.
>>878547
#708 #878538
>>878344
Как я понял, именно так - находишь дату, инсертишь в базу сразу на текущий год (например, 1 января каждого года или 31 декабря на будущий), а потом в эту дату срабатывает event, либо каждый день проверяется дата на такое соответствие и если находится, то срабатывае event (наверное, так даже предпочтительнее).
UPD: Знакомый сейчас сказал, что желателен для запуска проверки соответствий каждый день, чтобы любые изменения в течение года чекать.
>>878363
Спасибо, тоже интересный подход.
Хотя, в принципе, и в алогритме вечного календаря тоже всё есть, что нужно для этого.
UPD: Ну йокарный бабай, всё это есть в простой функции date(), как говорит ОП. Вот так, собака была зарыта неглубоко.
>>878384
Если сегодня вторник, то проверяем, не является ли он вторым вторником в ноябре?
Хм, немного кажется нелогичным, что ли..
Это так будет каждый вторник в течение года проверяться? Не проще ли экономичней исходить из месяца:
- опачки, ноябрь, 1 число
- проверяем, не вторник ли это
- нет, не вторник
- опачки, ноябрь, 2 число
- проверяем, не вторник ли это
- опачки, вторник
- активизируется event

>Почитай мануалы по функции date, strtotime


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

>Этот алгоритм давно встроен в PHP (точнее в стандартную библиотеку Си под линуксом), определить текущий день недели можно через функцию date().


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

>Я думаю, там нужен крон.


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

В итоге вышло, что тут работы для разибрающегося в Йии2 фреймворке и cron от силы на полчаса, если делать всё руками, а не с помощью Gii.
Вот так, буду знать, такая вроде бы несложность, а орал и плакал.
#708 #878538
>>878344
Как я понял, именно так - находишь дату, инсертишь в базу сразу на текущий год (например, 1 января каждого года или 31 декабря на будущий), а потом в эту дату срабатывает event, либо каждый день проверяется дата на такое соответствие и если находится, то срабатывае event (наверное, так даже предпочтительнее).
UPD: Знакомый сейчас сказал, что желателен для запуска проверки соответствий каждый день, чтобы любые изменения в течение года чекать.
>>878363
Спасибо, тоже интересный подход.
Хотя, в принципе, и в алогритме вечного календаря тоже всё есть, что нужно для этого.
UPD: Ну йокарный бабай, всё это есть в простой функции date(), как говорит ОП. Вот так, собака была зарыта неглубоко.
>>878384
Если сегодня вторник, то проверяем, не является ли он вторым вторником в ноябре?
Хм, немного кажется нелогичным, что ли..
Это так будет каждый вторник в течение года проверяться? Не проще ли экономичней исходить из месяца:
- опачки, ноябрь, 1 число
- проверяем, не вторник ли это
- нет, не вторник
- опачки, ноябрь, 2 число
- проверяем, не вторник ли это
- опачки, вторник
- активизируется event

>Почитай мануалы по функции date, strtotime


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

>Этот алгоритм давно встроен в PHP (точнее в стандартную библиотеку Си под линуксом), определить текущий день недели можно через функцию date().


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

>Я думаю, там нужен крон.


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

В итоге вышло, что тут работы для разибрающегося в Йии2 фреймворке и cron от силы на полчаса, если делать всё руками, а не с помощью Gii.
Вот так, буду знать, такая вроде бы несложность, а орал и плакал.
>>878560
174 Кб, 600x400
#709 #878545
Анончики, устроился на бесплатную практику на фирму.

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

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

Как думаете, анончики, стоит ли там оставаться или искать какую-то современную веб-студию которая дрочит на все новое и современное?
>>878560>>878601
#710 #878547
>>878518
А какой нужно метод? Я знаю, что вычитаю лишнее, это типа сдача.

Можно высчитывать дополнение 0 до долга, но когда оно будет < 5k, то заплатить его, а не 5к. Но это больше действий занимает, чем просто 1 раз вычесть.
>>878560
#711 #878560
>>878538

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

>>878545

Зенд еще не самый плохой вариант. Он хоть и старый, но модульный и объектно-ориентированный.

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

>>878547

> Можно высчитывать дополнение 0 до долга, но когда оно будет < 5k, то заплатить его, а не 5к. Но это больше действий занимает, чем просто 1 раз вычесть.


Ну да, но ненмного, на 1 строку больше, зато без костылей. Если ты понимаешь, как это сделать, то в принципе можешь и не делать.
#712 #878565
>>878560
после практики меня возьмут туда на работу
#713 #878571
>>878560

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


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

Сейчас вспомнил, что знакомый говорил про сайт про фитнес с разными тренями. Если это треня рассчитана на сентябрь, допустим, а 1е сентября у нас в среду, то может потребоваться начать треню с 30го августа - чтобы четко вписаться в месяц, там обычно по дням недели рассчитывается: сентябрь, понедельник - то-то, сентябрь, вторник - то-то.
Поэтому нужно добавить условия для восстановления этой целостности у недели.
И вот тут уже сложнота поперла.
Это у меня загоны, канешн, немношк, но походу так и нужно, скорее всего, такое подразумевалось.
>>878596
Аноним #714 #878594
>>878384
>>878384
я не спорю что нужен крон
Аноним #715 #878596
>>878571
нет по моему ты усложняешь анон , в задание чётко сказано что сделать , а та часть которая про 2 вторник месяца , это уже считай тесты , если так делать как ты и думать то за 5 ч явно не сделать , на тестовых нужно делать ровно то что дано и не придумывать
>>878600
Аноним #716 #878599
>>878560

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



для этого нужно само организация , не каждый человек её имеет , у меня например чёткие грани между дом\работа , дома я отдыхаю на работе я работаю , если этот анон так не сможет то по пи*де пойдёт обучение , в конторе же хоть по шапке настучат за то что вбыдле сидишь
#717 #878600
>>878596
Оке, так тож думаю.
Ну просто подумал, для чего такая перда может пригодиться им, пока с тем челом не связывался, выходной.
Что посоевтуешь на CodeSchool? Там есть бесплатные курсы ведь? По php и мускулу там норм курс?
>>878602
Аноним #718 #878601
>>878545
зенд не так плох , тот же МВЦ потому можешь месяц попрактиковать изучить его в комерц разработке (и в резюме написать , что не домашние странички делал , а сайты этот этот этот делал в них то то то) а потом свалишь на джуна в другую контору , для твоего уровня разницы будь то Ларавель или ЗФ нет
Аноним #719 #878602
>>878600
по пхп нету ешё , по SQL норм , там сейчас 2 дня все курсы открыты на халяву так что успей пройти . Можно ешё JQ LESS SASS пройти чтоб понимать хоть что это такое
>>878603
#720 #878603
>>878602
Да, вижу, спасибки.
#721 #878676
И в этот тред запощу, ибо уж очень сильно печёт.

Посоны, почему у Laravel такая убогая документация? Почему там нет ни слова про тот же RedirectIfAuthenticated? Почему не сказано, как вывести ошибки аутентификации/авторизации? Что за хуйня происходит? Хоть бери и пиши свои классы для аутентификации, иначе вообще нихуя не понятно.
>>878678
#722 #878678
>>878676
Потому что нормальным кодерам это говно не нужно, легко свое все напишут, а джуниоры пусть говно жрут.
>>878679
#723 #878679
>>878678
Да ебал я изобретать велосипеды, когда нормальные кодеры уже запилили их за меня.
>>878682
#724 #878680
Короче, не буду использовать готовые решения из документации, проще самому запилить аутентификацию, используя Illuminate.
#725 #878682
>>878679
Обычно говно же какое-то изобрели, которое под конкретный проект с пинками и костылями подходит, криво встает и багами покрывается, сразу ограничивая возможности. Сениорам зарплаты за то и платят, что свое такое могут написать под конкретные задачи и без багов. А для каких-то сложных фич есть подключаемые через Composer библиотеки, CMSы там нахуй не нужны.
>>878930
29 Кб, 1315x629
30 Кб, 1313x628
#726 #878693
Bootstrap. Не понимаю, почему второй класс на одной странице игнорируется, а на другой всё верно отображает
Опять я со своим хттп сервером #727 #878736
#728 #878766
Оп, а как тебе денег скинуть? Вроде как видел номер твоего яндекс кошелека, а сейчас найти не могу.
#729 #878817
Привет,
зацените 13 задачу по JS

http://ideone.com/4bJB05
>>879116
#730 #878895
>>878560
Почему на 1 команду больше? Как минимум столько же, сколько раз цикл будет повторяться.
#731 #878930
>>878682
Так Laravel - это не CMS, лол. Это фреймворк.
#732 #879116
>>878817
Охуеть. Сколько js дрочить надо, чтобы так писать научиться?
>>879138>>879414
35 Кб, 480x640
#733 #879137
Автомобильный номер http://ideone.com/rGVIk5
Номера телефонов http://ideone.com/RDCPVs
#734 #879138
>>879116

Я не он, но судя по номеру задачи, перед ней надо решить не менее 12 задач из списка из ОП поста.
#735 #879414
>>879116
На самом деле не много, первые 10 задач из мануала я решил за 3 дня. И примерно неделя ушла на решение 11, 12 и 13 задачи. В процессе решения последних были перерывы, и по факту с первой задачи прошел почти месяц.
#736 #879579
Чот дошли сейчас до темы с MVC и туплю на сессиях. Как их делать то в MVC? Тут же шаблон, на контроллере и моделью погоняет, а сессию када сувать?
>>879602
#737 #879602
Почему я не стал бы делать новый сайт на Руби: https://m.habrahabr.ru/company/Voximplant/blog/315720/

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

Я бы еще это отметил:

> фронтенд мигрировал с Prototype на jQuery, потом на Coffeescript, потом на Angular, потом на React.



Хорошо, когда есть лишние деньги, которые можно тратить на ерунду.

Также, в статье используются подогнанные под нужный результат графики. Ну например, график "А здесь показано, что происходит на рынке труда" на первый взгляд показывает превосходство Node.JS, а PHP почти на нуле. Но если присмотреться, то он показывает на абсолютные величины, а прирост в процентах. Пхп очень популярен и потому не особо растет. Понятно, что прирост от 100 до 1000 пользователей на этом графике будет выглядеть выше
чем от 10000 до 11000.

> Прямо сейчас Go очень популярен для микросервисов,


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

>>879579

Начни с вопроса, а зачем она тебе вообще нужна? Сессии не очень хорошо вписываются в концепцию REST. Зачем ты их используешь? Потому что в сомнительном устаревшем учебнике в каждом файле в начале стоит session_start()?

Также, знаешь ли ты, что сессия (как и куки) будет общая если открыть сайт в нескольких вкладках браузера?

Если тебе все равно нужна сессия, то очевидно:

- сессия привязана к протоколу HTTP , то есть к тому как браузер взаимодействует с сервером, и не может быть частью модели
- сессия не может быть частью предсталвения так как никак не связана с задачей отображения данных
- значит, с ней надо работать в контроллере.
#737 #879602
Почему я не стал бы делать новый сайт на Руби: https://m.habrahabr.ru/company/Voximplant/blog/315720/

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

Я бы еще это отметил:

> фронтенд мигрировал с Prototype на jQuery, потом на Coffeescript, потом на Angular, потом на React.



Хорошо, когда есть лишние деньги, которые можно тратить на ерунду.

Также, в статье используются подогнанные под нужный результат графики. Ну например, график "А здесь показано, что происходит на рынке труда" на первый взгляд показывает превосходство Node.JS, а PHP почти на нуле. Но если присмотреться, то он показывает на абсолютные величины, а прирост в процентах. Пхп очень популярен и потому не особо растет. Понятно, что прирост от 100 до 1000 пользователей на этом графике будет выглядеть выше
чем от 10000 до 11000.

> Прямо сейчас Go очень популярен для микросервисов,


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

>>879579

Начни с вопроса, а зачем она тебе вообще нужна? Сессии не очень хорошо вписываются в концепцию REST. Зачем ты их используешь? Потому что в сомнительном устаревшем учебнике в каждом файле в начале стоит session_start()?

Также, знаешь ли ты, что сессия (как и куки) будет общая если открыть сайт в нескольких вкладках браузера?

Если тебе все равно нужна сессия, то очевидно:

- сессия привязана к протоколу HTTP , то есть к тому как браузер взаимодействует с сервером, и не может быть частью модели
- сессия не может быть частью предсталвения так как никак не связана с задачей отображения данных
- значит, с ней надо работать в контроллере.
>>879605
#738 #879605
>>879602

>Сессии не очень хорошо вписываются в концепцию REST. Зачем ты их используешь? Потому что в сомнительном устаревшем учебнике в каждом файле в начале стоит session_start()?


Нет, сейчас на курсе по PHP. Дали тех задание написать свою реализацию. Собственно я на функционалке делал сессию и потом проверял её существование чтобы ограничить доступ незалогиненных людей к личным частям сайта.

>- значит, с ней надо работать в контроллере.


Хм... Спасибо огромное. Теперь я знаю что мне нужно делать.
>>879610
#739 #879610
>>879605

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


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

Для авторизации можно использовать сразу куки.
>>879612
#740 #879612
>>879610

>Недолгая у тебя авторизация получится.


Ну лично мне для своих нужд именно это и нужно, так что даже хорошо. А на курсе - скорее всего попросят куки прикручивать. А с ними я вообще никогда не работал. Но пока решаю проблемы по мере их поступления.
>>879642
#741 #879642
>>879612

Сессии используют куки. Ты выбрал очень странный порядок изучения, если учишь сессии до кук.
15 Кб, 335x531
#742 #880015
Помогите разобраться с Апи сбербанка? Есть один урл, по нему дергается недельный курс доллара.
http://www.sberbank.ru/common/js/get_quote_values.php?version=1&inf_block=123&_number_amount114=10000&qid[]=3&qid[]=2&cbrf=0&period=on&_date_afrom114=22.11.2016&_date_ato114=22.11.2016&mode=full&display=json

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

Ну и я ощущаю себя пиздец тупым, но как мне обратиться к полю с именем "3" у объекта????
#743 #880053
Код https://jsfiddle.net/w22g1txz/
Задание https://github.com/codedokode/pasta/blob/master/html/html.md#Задание-6

Вопросы:

>100%-230px


что это значит?

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


удалять можно по-разному: li в целом, или только текст, что находится между тегами <а>?

Каким образом вёрстка сломается, если удалить текст справа?
Есть ли в коде то, чего можно избежать/заменить?
Тред утонул или удален.
Это копия, сохраненная 22 ноября 2016 года.

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски