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

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

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

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

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

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

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

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

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

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

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

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

Ты прошел весь учебник? Молодец, но это были лишь основы языка PHP, этого недостаточно. Вот что в идеале надо изучить еще: ООП, как работает веб-сервер, HTML/CSS, SQL, PDO, работа с таблицами в БД, работа с формами, MVC, git, composer, JS, фреймворки, автоматизированное тестирование.

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

- для начала прочти урок https://github.com/codedokode/pasta/blob/master/soft/web-server.md
- установи Апач + PHP (советы выше и ниже) и читай туториал http://php.net/manual/ru/tutorial.php
- Учи HTML/CSS и SQL, PDO, хотя бы основы
- Далее простая, но полезная задача сделать список студентов, в ней много полезных советов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Yii2: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование
- Если ты все решил, переходи к Symfony 2/Doctrine 2
- Почитать про паттерны http://designpatternsphp.readthedocs.org/ru/latest/README.html (если ты не изучил ни одного фреймворка, то это будет рановато), тут с примерами кода http://designpatternsphp.readthedocs.org/ru/latest/README.html . Имей в виду что без примеров использования их учить бесполезно - не поймешь, хочешь увидеть примеры использования паттернов - ковыряй исходники Симфони, например Symfony Forms. Не заучивай паттерны - смотри код и думай, зачем тут они использованы.

Чтобы делать эти задания, тебе надо установить Апач + PHP (можно заодно сразу и MySQL) на компьютер. Вот полезные инструкции:

https://github.com/codedokode/pasta/blob/master/soft/php-install.md
https://github.com/codedokode/pasta/blob/master/soft/apache-install.md

Может тебе понадобится пользоваться командной строкой, вот гайд https://github.com/codedokode/pasta/blob/master/soft/cli.md

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

Также, у нас есть задачи которые позволят тебе изучить или подтянуть до нормального уровня знания JS/HTML/CSS/SQL. Решай их параллельно с задачами выше.

- HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md
- JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
- SPA (сложно): https://github.com/codedokode/pasta/blob/master/js/spa.md
- Проверялка решений на JS: http://dkab.github.io/jasmine-tests/
- MySQL: https://gist.github.com/codedokode/10539213

Что почитать

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

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

Шапка треда: http://pastebin.com/mP2aPRBb
Важно! #2 #769612
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

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

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

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

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

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

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

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

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

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

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

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

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

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

Объясняй

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Объясняй

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

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

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

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

Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
#3 #769638
Анон, балуюсь тут в пхп, значица проект - блог.
Отображает из бд всё норм, но, вот хочу сделать кнопку добавления поста (пока все значения, кроме заголовка забиты руками в запрос. Заголовок в текстбоксе рядом). Две строки, я думаю можно сюда закинуть. Так вот, ну типа если нажата кнопка сабмит, то делаем то, что ниже.

title <input type="text" id="titlel" name="title"><br>
$add = mysql_query('INSERT INTO blog VALUES (NULL, ($_POST[title]), '2016-06-11', 'Hello!'')');

//run/$add;

Не добавляется короч значение в бд, если указан вот этот заголовок ($_POST[title]). Пробовал разные виды кавычек, скобок и т.п. Если туда такое же значение забитое руками в запрос написать, то всё ок, а если из текстбокса, то всё, не добавляется. Причём, если это значение просто на странице вывести, то выводится. А в бд не добавляется.

Вот собственно вопрос - меня смущает вот это //run/ - это действительно всегда так должна выглядеть операция запуска запроса?
>>769642
#4 #769642
>>769638
Дело в том, что вы отправляете $_POST['title'] обычным текстом, то есть не отправляете значение переменной, а просто сам код.

Должно быть вот так, думаю:

Html с формой:
<form action="post.php" method="post">
<input type="text" name="title">
<input type="submit">
</form>

Сам файл post.php

mysql_query("INSERT INTO 'blog' VALUES (NULL, ".$_POST[title].", '2016-06-11', 'Hello!')");
>>770055
#5 #769722

> IMVU’s backend had been written in PHP from the beginning. Startup code is always gross, but after years of learning PHP’s ins and outs, we bent it to our will. Part of me looks back and says “It wasn’t that bad”, and indeed, it has a lot of great properties. But then I remember the horror.



> The terrible straight-line performance, the lack of concurrent IO, the insane memory usage. Once the codebase reached about a million lines, the latency on our REST service response times was over half a second and in the worst case several second



> In fact, one weekend, Andy went home with the explicit goal of proving that Haskell was stupid and not good for writing production software.



> Andy came back on Monday glowing. “Haskell is perfect for web services! We should use it! It’s fast and safe and concurrent!” We smiled and nodded (sometimes Andy gets enthusiastic about new things) and went on with our daily work. But in the evenings and weekends he plugged away, and built a prototype web service that was 1) dramatically faster than the corresponding PHP services 2) actually quite short in implementation and 3) surprisingly clear



> https://chadaustin.me/2016/06/the-story-of-haskell-at-imvu/

>>770054
#6 #770054
Ну вы скорострелы. Я еще в старом треде пару дней посижу, поотвечаю.

>>769722

Мне интересно, сколько надо времени для переписывания миллиона строк. пару человеко-лет?

Алсо возможно пхп код писали не очень опытне специалисты, а для хаскелл версии выбрали старичков.
>>775528
#7 #770055
>>769642

Расширение mysql устарело. Пора изучать PDO уже. Данные надо вставлять не напрямую (скл-инъекция), а через плейсхолдеры:

$q = $pdo->prepare("INSERT ... VALUES(:title)");
$q->execute([':title' => $_POST['title']);

Алсо статья и уроки про работу с формами:

https://github.com/codedokode/pasta/blob/master/forms.md
https://github.com/codedokode/pasta/blob/master/soft/web-server.md
#8 #770074
Зачем перекатат сделали? Вам лень добавить тонущий тред в избранное? Тонуть он ещё будет дней 10, если не дольше.
#9 #770079
Ребят, нужен ли пхп фронтенд-разработчику? Почему-то попросили выучить в компании, куда апплаился.
>>772833>>773658
#10 #770113
Сосаны, у меня есть домен и субдомен
На домене у меня https, а на субдомене http
На домене я сделал редирект с http на https
А сделать, чтобы если заходят по ссылке вида
https://субдомен перебрасывало на http://субдомен не получается, выдает ошибку безопасности. Я думаю, там даже не доходит до обработки моего .htaccess
Как быть?
>>773668
#11 #772114
Анончики, реально ли к осени уже начать потихоньку подрабатывать фрилансом в этой сфере? не особо хочется на улицу, а физически работать я не в состоянии, зато мне нравится это, оно интересно
>>772357
#12 #772312
Подскажите IDE для вашей ссанины с нормальным отладчиком.
>>772347
32 Кб, 480x480
#13 #772347
>>772312
Ideone
#14 #772357
>>772114
нет. Во первых не успеешь выучить (если только нет большого опыта в других языках) А во вторых для фриланса надо пару лет опыта работы в офисе

И рекомендую удалёнку а не фриланс
>>772426
#15 #772426
>>772357
Ок, а если по законам страны я несовершеннолетний? у меня в жопе мира 21 год совершеннолетие Там же вроде договор нужен и тому подобное. Можешь, если не трудно, рассказать как вообще дела в этой сфере обстоят?
>>772747
#16 #772631
Поясните мне, почему один и тот же месяц одной даты уменьшается на единицу, если переводить в mktime?

$date = date('m.Y',$randomStamp);

$arr = explode(".", $date);

$month = $arr[0];
$year = $arr[1];

rtrim($month, '0');

$d = date('l m Y', mktime(0, 0, 0, $month+1, 0, $year));

приходится к нему единицу прибавлять.
>>772737
#17 #772645
Доброго времени суток! Прошу проверить задачу: http://ideone.com/WgUfLT (регулярка, задача на номера телефонов).

Такой вопрос - для того, чтобы обрезать номера типа "888-888-888-8 позвать люсю" я пользовался постановкой флагов /^ $/
Есть какой-нибудь другой способ ограничить регулярку? Мол, мне нужно только 10 символов и точка, все, что больше - мимо?
>>773668>>780353
#18 #772710
Пилю краткую саксес стори:
В сентябре начал потихоньку изучать php, в том числе и с помощью треда. Болеменее вкатился в ООП, поигрался с фреймворками(Laravel с Eloquent в основном) и отправил резюме в пару контор, у которых в описании было нормальное отношение к джуниорам. На следующий же день дали тестовое задание в одной и после решения позвали на интервьюирование, после которого пригласили на работу. Задавайте ответы если интересно + буду мб потихоньку репортить о выдаваемых задачах. (Кун из мухосранска)
#19 #772737
>>772710
ну надо же, а я три года пишу на пхп, жаве и жс, знаю весь веб стек со фреймворками и цмс. сейчас делаю вот эту шизозадачу >>772631
и скорее всего мне опять перезвонят. сижу на шее у мамки.
(тоже из мухосрани)
>>773668
#20 #772743
>>772710
Сколько денег?
>>772786
#21 #772747
>>772426
Если несовешеннолетний, так какого чёрта дёргаешься. Сиди у мамки на шее и учись потихоньку

На удалёнку часто можно устроиться вообще безо всякого оформления, но рискованно. Могут кинуть на месячную ЗП

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

Учись не спеша. Основы ПХП -> фреймворки -> пару серьёзных учебных проектов -> продвинутое ООП. Где то год-полтора если совсем нуля. ПОтом свои учебные проекты показываешь потенциальным работодателям, ищущим студентов на удалёнку за доширак. Работаешь. Как опыта наберёшься - прыгаешь на проеткы получше.

Но надо натурально задрачивать
>>772871
#22 #772786
#23 #772833
>>770079
значит в компанию нужен не фронтэнд-разработчик а человек-оркестр
>>780855
#24 #772843
Сколько времени проходит от первого открытия учебника, то вёрстки первого полноценного сайта?
>>773658
#25 #772871
>>772747
Хорошо, спасибо затрачивать могу, так как мне это очень нравится и вообще интересно
>>772981
#26 #772928
Что такое вьюшка (view из модели MVC)? Вьюшка это функция без сайд эффектов, которая принимает какие-то параметры и возвращает строку.
Можно ли вьюшки заключать внутрь статических методов модели (html, само собой, хранить в отдельных файлах)? Контроллер дёргает одну вьюшку, а та уж пусть что хочет, то и делает, включая вызов других вьюшек.
Правда в этом случае Model получается не fat, а fat & ugly.

____________
Обоснуйте где я неправ
#27 #772962
Народ, проясните мне ситуацию. Сижу на ideone, делаю задачки, и вдруг он перестал мне выдавать результат. То есть я до этого сидел, код написал, запустил - увидел результат вычислений. А сейчас он пишет просто, что компиляция прошла успешно и всё. А где результат? Почему он перестал мне его показывать? Помогите, а то всё застопорилось
>>773028
#28 #772980
>>772928
Ты неправ в том месте, где ты начинаешь изобретать какой то ебучий велосипед.

- Берёшь фрейморк (Yii, Laravel, Symfony).
- Читаешь к нему мануал. В том числе, там написано, как в данном фреймворке правильно обращаться с моделями.
- Делаешь как там написано
- Профит.
>>773155
#29 #772981
>>772871
Если реально интересно и нравится - значит есть хорошие шансы, что всё получится. Дерзай
118 Кб, 1366x768
133 Кб, 1366x768
#30 #773028
>>772962
Со скринами будет понятнее:
>>773039>>773657
#31 #773039
>>773028
Понял, в чём проблема.
#32 #773074
Есть тут кто?
Оп тут? Есть пара вопросов...
>>793703
#33 #773155
>>772980
Да, я изобретаю велосипед для своей ЦМСки. Я поработал с Yii, и мне очень понравилось как там сделана система вьюшек. На каких-нибудь сайтах-блогах (абстрактном Дваче) они не нужны, но когда у тебя база данных со связанными сущностями, то вьюшки (и их реиспользование) это очень и очень и очень удобно. И я хочу сделать также. Но я не хочу заводить отдельный engine на реализацию вьюшек и также не хочу хранить код вьюшек отдельно от модели. Я вижу вьюшки как производную от моделей, а потому закономерно спрашиваю "а не должен ли код вьюшек храниться в моделях?"
Даже такие страницы как "главная страница сайта" можно загнать в метод какого-нибудь отдельного класса, который уже будет рендерить (на дваче) три таблицы: список последних тредов, список последних загруженных файлов, список последних постов в тредах.

Так вот, где я неправ?
>>773161>>773657
#34 #773161
>>773155
Ты неправ в том месте, где тебе надо будет работать над проектом вместе с верстальщиками, нифига не смыслящими в программировании.

Будешь учить их ПХП, когда им надо будет переверстать HTML какой нибудь модели?
>>773194
#35 #773194
>>773161
А какая разница, если в том же Yii вьюшки это php-файлы с перемешкой php с html? По крайней мере мне достался проект на работе в таком виде. А этой системой пользовалось куча народа по всей России, и она приносила миллионы хозяевам компании

> Будешь учить их ПХП


Нет, они будут верстать html, а натягивать всё равно придется мне, это нормально
133 Кб, 1366x768
#36 #773211
Вызываю вот эту функцию для объекта, у которого значение поля nick не unique в бд. Обернул всё в try catch, но вместо срабатывания catch, у меня всё ломается с ошибкой:

> PHP Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'Name' for key 'nick'' in ...



Почему так?

Если где-то совсем уж говнокод - покажите, пожалуйста.
#37 #773214
>>773211

>значение поля nick не unique в бд


Пиздишь.

>Duplicate entry 'Name'

>>773221
#38 #773221
>>773214
Да я не могу сформулировать просто.

Есть таблица в БД, в которой поле nick - unique.
Я пытаюсь добавить в таблицу строку с неуникальным полем nick (т.е. такой ник уже есть в таблице).
Мне должна прийти ошибка, что такой ник уже есть и добавить строку не удалось. Собственно, онa и приходит, но почему-то не обрабатывается в catch.
>>773233
#39 #773233
>>773221
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION )
>>773234
#40 #773234
>>773233
[code]$opt = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);[/code]

Вроде бы такое есть..
#41 #773241
>>773211
Ты ж внутри немспейса Users находишься
catch (PDOException $s)
PHP воспринимает как
catch (\Users\PDOException $e)

надо
catch (\PDOException $e)

Кстати код неплох, но только уж если используешь ООП - иди до конца. Зачем глобальную функцию getBase() используешь?

Правильно всю работу с БД оформить через отдельный класс.
А внутри класса User этот класс или с помошью паттерна "синглетон" получать, через вызов статического метода (нубский способ; почитай в инете как делается)
Или с помошью Dependency Injection (как настоящие папки делают)
112 Кб, 1366x768
#42 #773263
>>773241
Точно, спасибо.

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

Раз тот неплох, тогда вот действительно говнокода.
В нижнем файле с формой, нужно всё как у меня - выводить через echo, или лучше закрыть php ?> и вывести просто html-кодом?
В верхнем файле, если всё в ООП переводить, то это ведь в ООП не перевести никак, так оставлять?
#43 #773272
>>773263
>>773241
И, namespace. Я их на самом деле добавил только потому, что помощник ругался, если без namespace (тот, который снизу на первом скрине).
Мне для каждого класса что-ли делать отдельный namespace? Ну, там
namespace Posts;
class Post{}

В другом файле
namespace DataBases
class DataBase{}

Или для всех файлов один namespace Site;
Или он вообще тогда не нужен, если мне не нужен?
>>773283>>773657
#44 #773275
>>773263
Конечно же закрыть тег

Внутри тегов ПХП оставить только реквайры хедера и футера
В них, кстати, вообще голый HTML должен быть
>>773288
#45 #773283
>>773272
Неймспейсы в современном
ПХП нужны для автозагрузки классов. ПОэтому они повторяют структуру папок, по которым у тебя распиханы файлы классов.

А уж как там файлы классов по папкам сортировать - это .... ну как правило это определяется структурой фреймворка, в котором пишешь проект.
Да-да, на голом ПХП никто ничего уже лет 12 не пишет.

В учебном проекте распихивай файлы по папкам как тебе удобно. МОжешь группировать классы по смыслу, можешь работающие в связках классы ложить поближе друг к другу
>>773288>>773657
#46 #773288
>>773275
>>773283
Спасибо.

А это, так оставлять?

>В верхнем файле, если всё в ООП переводить, то это ведь в ООП не перевести никак, так оставлять?

>>773297
#47 #773297
>>773288
В твоем случае - оставлять как есть
Потом знакомься с MVC фреймворками (начни со Slim) - там увидишь как правильно.

Если коротко - все запросы попадают на входной скрипт - роутер запросов, который смотрит, что там в адресной строке введено. И в зависимости от введённого адреса, обращается к тому или иному классу-контроллеру, внутри которых и пишется код, типа того, что ту тебя в верхнем файле.
>>773299
#48 #773299
>>773297
Примерно понял, спасибо.
#49 #773358
Тяжело ли написать сайт?
Я очень давно писал всякие на пхп, но уже ничего не помню. Тяжело ли вспоминать?
Хочу запилить 1 сайт.
>>773384>>773582
#50 #773384
>>773358
Что ты ожидаешь услышать в ответ?
>>773439
#51 #773439
>>773384
пидоа ответ
>>773657
#52 #773582
>>773358
Ты идиот? Не хочешь заодно спросить, тяжело ли сходить в магазин за хлебом?
>>773657
#53 #773657
>>773439
>>773582

Катитесь-ка в другой тред с такой манерой общаться.

>>773283

Они не для автозагрузки. У меня в уроке написано, что они придуманы для борьбы с конфликтами имен классов и длинными именами: https://github.com/codedokode/pasta/blob/master/php/autoload.md

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

>>773272

Читай урок про неймспейсы и PSR-4 выше.

>>773263

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

> В верхнем файле, если всё в ООП переводить,


То это все пойдет в класс контроллера.

>>773155

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


И это неправильно. Вью это просто кусок страницы, он может соответствовать модели, их сочетанию или ничему (например статический текст).

> Даже такие страницы как "главная страница сайта" можно загнать в метод какого-нибудь отдельного класса, который уже будет рендерить (на дваче) три таблицы


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

>>773028

У тебя поставлено условие что цикл выполняется только если $x больше или равно 120. Очевидно что он не выполнится ни разу так как в начале $x равно 100.

>>772928

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

> Вьюшка это функция без сайд эффектов, которая принимает какие-то параметры и возвращает строку.


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

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


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

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

А твой подход - отказаться от MVC и савлить все в кучу.

И вообще по моему ты что-то не о читал или не так понял. Я советую тебе сделать например задачу про студентов чтобы разобраться. Или изучить фреймворк.
#53 #773657
>>773439
>>773582

Катитесь-ка в другой тред с такой манерой общаться.

>>773283

Они не для автозагрузки. У меня в уроке написано, что они придуманы для борьбы с конфликтами имен классов и длинными именами: https://github.com/codedokode/pasta/blob/master/php/autoload.md

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

>>773272

Читай урок про неймспейсы и PSR-4 выше.

>>773263

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

> В верхнем файле, если всё в ООП переводить,


То это все пойдет в класс контроллера.

>>773155

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


И это неправильно. Вью это просто кусок страницы, он может соответствовать модели, их сочетанию или ничему (например статический текст).

> Даже такие страницы как "главная страница сайта" можно загнать в метод какого-нибудь отдельного класса, который уже будет рендерить (на дваче) три таблицы


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

>>773028

У тебя поставлено условие что цикл выполняется только если $x больше или равно 120. Очевидно что он не выполнится ни разу так как в начале $x равно 100.

>>772928

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

> Вьюшка это функция без сайд эффектов, которая принимает какие-то параметры и возвращает строку.


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

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


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

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

А твой подход - отказаться от MVC и савлить все в кучу.

И вообще по моему ты что-то не о читал или не так понял. Я советую тебе сделать например задачу про студентов чтобы разобраться. Или изучить фреймворк.
>>773952
#54 #773658
>>772928

А, и еще. Если ты думал что MVC поразумевает наличие ровно 3 классов (контроллер, модель, вью) то это тоже неверно.

>>772843

Полгода-год

>>770079

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

В моем понимании фронтенд-специалист, это тот, кто знает как решить задачу про SPA из ОП-поста. А не копировать кривые плагины на джейквери или делать хелловорлды на реакте и воображать что он что-то умеет.
#55 #773668
>>772737

Ты за 3 года открыть мануал не нашел времени? http://php.net/manual/ru/function.mktime.php - тут ответ на твой вопрос.

>>772645

>Такой вопрос - для того, чтобы обрезать номера типа "888-888-888-8 позвать люсю" я пользовался постановкой флагов /^ $/


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

пробел это не спецсимвол, перед ним не надо ставить бекслеши.

> (\\(|\\)|\\ |\\-)


Это короче записать через квадратные скобки.

В остальном верно.

>>770113

Изучать почему ошибка. Например сертификат не распространяется на поддомен.
>>780353
#56 #773689
О, ОП, подскажи-ка:
Присматриваюсь к задаче про SPA, хочу попарктиковаться в ангуляре

Такой вопрос:
Вот у меня есть проект на ангуляре. В нём куча JS файлов со всякими сервисами-компонентами

Как всё это вместе сливают в одно приложение?
- понятно, что все JS файлы подключать по отдельности к странице - не вариант, ибо их десятки будут, если не сотни.
- воспользоваться чем-то вроде requireJS, который будет те же фалы подключать автоматически, по мере необходимости
- с помошью какого нибудь webpack слить все JS файлы проекта в 1 большой фаил, и заодно его минифицироваать. По идее тогда и RequireJS в проекте не нужен.

Какой вариант использовать? Как вообще это дело в промышленных проектах делают? Мельком видел какие-то странные связки из webpack + requireJS, непонятно только, если всё влито в 1 фаил - нафига require

Ну и слияние всего в 1 фаил - она же не даст использовать отладчик в браузере. Подозреваю, что тут как-то надо разные окружения заюзать. Типа, в dev окружении всё по отдельным файлам, а в prod - один слитый минифицированный фаил? Но как это на практике реализовать - пока совсем неясно...
#57 #773734
Тред надо переименовать в "клуб анонимных пехапешников"
#58 #773783
>>773689

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

> Ну и слияние всего в 1 фаил - она же не даст использовать отладчик в браузере.


Так оптимизации надо делать только на продакшене. На дев-сервере удобнее подключать файлы по отдельности (у webpack должен быть такой режим, если нет, то используй что-нибудь другое или самописный велосипед)
#59 #773784
>>773689

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


Ангуляр там максимум дает 25% решения. Мне он вообще не нравится тем, что это не библиотека, а фреймворк.

> Но как это на практике реализовать - пока совсем неясно...


Начни с изучения документации по webpack/requirejs
Старый тред #60 #773831
В старом треде ответы на многие неотвеченные ранее посты:

>>773829 ООО Вектор от 30 мая
>>773648 https://github.com/someApprentice/Students
>>769949https://github.com/timrene/php-link-list/blob/master/решение задач.md
>>768780 https://github.com/nsdvw/TestHub
>>767215 https://github.com/foobar1643/filehosting

зайдите, посмотрите, вдруг на ваш вопрос ответили.

Если я вам не ответил - напомните о себе в этом треде
#61 #773866
>>773689

gulp, browserify
webpack тоже вариант
#62 #773952
>>773657

>Они не для автозагрузки. У меня в уроке написано, что они придуманы для борьбы с конфликтами имен классов и длинными именами: >https://github.com/codedokode/pasta/blob/master/php/autoload.md


>Читай урок про неймспейсы и PSR-4 выше.



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

> Не используй echo в шаблоне, это же очень неудобно. Плюс, ты еще и форму неправильно обрабатывваешь, почитай урок https://github.com/codedokode/pasta/blob/master/forms.md


> То это все пойдет в класс контроллера.


Ну, анон выше, в принципе, так и пояснил. А форму только создал, чтобы научиться с бд работать, поэтому еще никак не обрабатываю.
Но, все равно спасибо.
>>774186>>774413
#63 #774186
>>773952

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


Бери spl_autoload_register, для таких целей тебе этой функции с головой хватит.
#64 #774246
Помогите с решением задачки. Как полученные после циклов слоги сложить в слово ? http://ideone.com/8MNM0E
Сделал то же самое вот так http://ideone.com/3MoT8V
Я стал быдлокодером с самого начала?
>>793703
#65 #774291
>>769611 (OP)
ОП, тут в /b дискасс полыхал, мне очень интересно твое мнение. Ответь пожалуйста развернуто, если можешь. Почему именно PHP, ну, для себя почему ты выбрал его и учишь здесь ему? Мог бы взять пайтон и ебашили бы игрушки, мат.расчеты, скрипты для никсов и не только для никсов, приложения десктопные на pyqt, статистика и дата майнинг? Потолка нет, приложения ограничены лишь фантазией. А пхп - это какие-то бесконечные сайты для пиццерий, круды, плагины к вордпрессу, сайты для пиццерий, круды, плагины к вордпрессу, сайты для пиццерий, круды, плагины к вордпрессу... С соответствующим потолком зарплаты и перспективами карьерного роста вникуда.
>>774442>>774686
#66 #774413
>>773952

Тебе проще всего сделать по PSR-4, то есть неймспейсы определяются вложенностью файлов:

src/Model/Student.php -> namespace Model
src/Service/Valudator.php -> namespace Service
>>774686
#67 #774442
>>774291

> игрушки,


На Питоне из игр разве что визуальные новеллы. Игры пишут на Си++ + OpenGL/DirectX. По крайней мере квейки, думы, халф лайфы на нем написаны

в наше время есть еще Юнити с C#.

> мат.расчеты,


скучно и неоплачиваемо

> скрипты для никсов


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

> дата майнинг


новомодное словечко из булшит бинго.

> какие-то бесконечные сайты для пиццерий, круды, плагины к вордпрессу


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

Вот ты говоришь Питон, а скажи-ка, есть ли в Питоне:

- работающие тайп-хинты в функциях
- private/public и вообще нормальный ООП
- компиляторы вроде HHVM
- библиотеки на Си
- фреймворки и библиотеки в больших количествах

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

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

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

А когда я начинал, Питон вообще мало где использовался.

Сам по себе Питон в общем неплохой язык, но мне кажется что он используется меньше.

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

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


Расскажи, какие переспективы карьерного роста есть с питоном? Старший борщехлеб в разваливающемся НИИ?
#67 #774442
>>774291

> игрушки,


На Питоне из игр разве что визуальные новеллы. Игры пишут на Си++ + OpenGL/DirectX. По крайней мере квейки, думы, халф лайфы на нем написаны

в наше время есть еще Юнити с C#.

> мат.расчеты,


скучно и неоплачиваемо

> скрипты для никсов


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

> дата майнинг


новомодное словечко из булшит бинго.

> какие-то бесконечные сайты для пиццерий, круды, плагины к вордпрессу


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

Вот ты говоришь Питон, а скажи-ка, есть ли в Питоне:

- работающие тайп-хинты в функциях
- private/public и вообще нормальный ООП
- компиляторы вроде HHVM
- библиотеки на Си
- фреймворки и библиотеки в больших количествах

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

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

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

А когда я начинал, Питон вообще мало где использовался.

Сам по себе Питон в общем неплохой язык, но мне кажется что он используется меньше.

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

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


Расскажи, какие переспективы карьерного роста есть с питоном? Старший борщехлеб в разваливающемся НИИ?
>>774564>>775493
#68 #774564
>>774442

> работающие тайп-хинты в функциях


Есть, хотя он не такой, как в пыхе(хотя, ввести в пыхе тайп хинтинг и не ввести возвращаемое void значение -- это мощно)

> private/public и вообще нормальный ООП


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

> компиляторы вроде HHVM


Ну это вообще смешно. PyPy, Jython?

> библиотеки на Си


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

> фреймворки и библиотеки в больших количествах


Pypi - 82744 packages here
>>774624
144 Кб, 1366x768
#69 #774618
Народ, помогите разобраться. Почему кубик выдаёт только последнее значение из массива постоянно? Где я обосрался?
#70 #774624
>>774564

В новой версии php хотят сделать viod

> Там он не нужен, ибо философия другая


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

Видимо просто традиционно на Питоне ничего сложного не пишут.

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

> Ну это вообще смешно. PyPy, Jython?


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

>>774618

Точка с запятой после foreach. Тело цикла надо заключать в фигурные скобки.
>>774653>>774952
64 Кб, 960x640
#71 #774653
>>774624
ЗАРАБОТАЛО, ССУКА! Спасибо, анон
#72 #774686
>>774413
Да, именно так первый анон и посоветовал, спасибо.
А вообще, я потихоньку MVC стал разбирать, вот там неймспейсы очень кстати.

>>774291
Не ОП, но пару дней назад даже линукс поставил, чтобы начать учить и писать сайты на Питоне, так как считал, что php хуже червя-пидора, хуже js.
Но потом появились догадки, что для сайтов на питоне обычные хостинги не подойдут, а нужно искать специальные Так ли это?, а значит они дороже. Плюс в php С-подобный синтаксис. А потом оказалось, что тут еще и ООП есть. Да и работы, думаю, для php побольше будет. Вот я и тут.
А для всего остального есть С++.
>>774853>>775493
#73 #774711
>>774618

>


а зачем тебе foreach ?
можно ведь просто нарандомить элемент массива http://ideone.com/pAkJUv
>>774713
#74 #774713
#75 #774715
Текстовый php редактор для linux?
>>774733
#76 #774733
>>774715
Cоветую Vim.
>>774821
#77 #774786
Опчик, вопрос по xsrf если я буду хранить в сессии токен есть минусы кроме того что если форма будет долго открыта и сессия закроется то код будет не действителен?
>>774903
#78 #774821
>>774733
Вторая рука обычно занята, так что увы. Остановился пока на Sublime.
>>774853
#79 #774853
>>774821
Чем более важным, чем программирование, может быть занята твоя вторая рука во время кодинга?
Ты там на свой код оргазмируешь?
И вообще, ты допускаешь глупейшую ошибку, прося посоветовать Х, но не указывая что конкретно тебе от этого Х нужно. Таким как ты обычно советуют играть в Battletoads первый и смотреть Boku No Pico.

>>774686во время программирования может быть занята твоя вторая рука, что во время программирования для тебя является более важным
Что может быть хуже JS?
Сбивающие с толку null и undefined, когда в PHP есть isset и is_null/empty, неочевидные правила превращения переменных, нет привычного ООП, класс и ассоциативный массив - одно и то же, тысяча фреймворков, сменяющих друг друга с калейдоскопической быстротой.
#80 #774857
>>774853

>Что может быть хуже JS?


Потому он и ниже червя-пидора.
#81 #774861
>>774853
Всегда использовал первый попавшийся текстовый редактор, потому не знал, что существует такое многообразие.
#82 #774903
>>774786

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

Так да, недостаток что сессии временные, по умолчанию по моему после 30 минут неиспользования удаляются.
>>774916
#83 #774916
>>774903
Человек который ведёт проект просто категорически против добавления лишней информации в куки и поднимает вой каждый раз
>>793703
#84 #774917
Подкиньте подсказок, как можно написать генератор стихов, пожалуйста.
>>774918
#85 #774918
>>774917
Гугли "конкатенация переменных PHP".
#86 #774952
>>774624

>Видимо просто традиционно на Питоне ничего сложного не пишут.


Вот это тролльное очень утверждение(приводить примеры огромных проектов приводить не буду, сам гугланёшь). А вот огромных проектов на пыхе я чот не видел, потому-что она часто используется в серверном фронтенде(фейсбук, например юзает для серьёзных задач скалку). ООП в пыхе -- это калька с джавы, где на каждый чих нужны интерфейсы и абстрактный фабрики(пыха в этом плане выигрывает ибо динамика). Как я говорил -- ООП питона позволяет решать задачи нестандартно, без анальной ёбли(тестирование, миксины, прототипы). А интерфейсы в динамической типизации -- просто очень бредовая идея, которая демонстрирует странную логику архитекторов пыхи(ортогональность в функциях стандартной библиотеки тоже). Так что говорить, что же лучше тут однозначно нельзя. У этих подходов есть и плюсы и минусы.
P.S. Void появился в 7.1. И да, я не хуй с горы, который пришёл похейтить пыху и довелось с ней работать и я знаю анальную боль, которая приносит работа с пыхой.
>>774959
#87 #774959
>>774952

>фейсбук, например юзает для серьёзных задач скалку


http://stackshare.io/facebook/facebook
Где она тут?
>>774998>>775077
#88 #774998
>>774959
Огромные проекты на PHP конечно есть.
Только появляются они не потому что кто-то хотел делать большой проект на PHP, а так получилось - делали домашнюю страничку, хуяк-хуяк, и вот у нас Фейсбук с миллионами строк на PHP, с которым ничего уже не сделать - остается только делать его компилятор и подставлять другие костыли и перематывать изолентой.
#89 #775077
>>774959
Сорян, спутал с твиттером. У них юзается хачкель, эралнг, джавка и куча всего.
#90 #775116
Нужно загрузить презентацию на сервер (предполагается файл формата ppt), как вытащить её превьюшку? То есть получить в виде картинки, например, её первый слайд.
>>775121
#91 #775121
>>775116
Установи на сервере PowerPoint, передавай ему презентацию через COM, вытаскивай картинку.
#92 #775122
А лучше сначала во фронт-энде поработать или сразу в бэк попробовать идти?
>>775331
#93 #775124
Объясните, как создаются страницы со статьями? В самодельной CMS как сделать, допустим, article/1111 или article/how-do-you-make?
>>775128>>793703
#94 #775128
>>775124

> article/how-do-you-make


фикс, article/how-do-you-make.php, конечно
#95 #775327
Сегодня туплю, ткните носом, как упростить такую конструкцию IF'а
https://ideone.com/FsPyrH
>>775371>>793703
#96 #775331
>>775122
Что нравится то и делай
и то и то пересекается
и в том и в том свои геморои
#97 #775351
Аноний, поясни за вакансию.
https://hh.ru/vacancy/17404178?query=php
договор на год на 30к это норма?
>>775366>>775379
#98 #775358
Запилили перекат и молчат.
#99 #775365
>>774853

>Что может быть хуже JS?


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



От это точно. Тут мне на работе,кроме бекенда на PHP+Symfony2 пытаются фронт на Ангуляре подсунуть - это пиздец, товарищи
Такого говна я ещё ни разу не видел. Даже самые днищепроекты на PHP куда лучше этого

Процедурный код. Предыдущий писака об ООП, инкапсуляции и разделении ответственности даже не слышал.

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

IDE в этой мешанине, ничего, естественно, подсказать не может. Автодополнение? Автоподсказки? Доки на JSDoc? - забудьте!

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

Один только Gulp одновременно с webpackом чего стоят...
#100 #775366
>>775351
Через пол года, если не дурак, и будешь активно учиться всё это время - будешь стоить больше, но сьебнуть или попросить повышение - не сможешь. На то и рассчет
>>775379
#101 #775371
>>775327
А что делать функция должна?
>>775437
#102 #775379
>>775366
>>775351

Российское законодательство позволяет тебе уволиться в любой момент при условии предупрждения за 2 недели.
#103 #775382
>>773241
С БД особо-то дел никогда не имел, поэтому: соединение может быть только одно Тогда и нужен синглeтон?, закрывать тогда его не нужно, ибо сам закроется, когда все запросы выполнятся и потеряются ссылки, а когда снова понадобится - откроем.
Или для каждого запроса открывать соединение и после его выполнения зарывать?

Я тут в MVC вникаю. Мне что-то подсказывает, что Dependency Injection для БД тут использовать не получится Так как тогда объект БД нужно будет создавать в контроллере и передавать в качестве аргумента в модель, но контроллер ведь для этого не предназначен, тогда создавать объект логичней все же в модели?
#104 #775388
>>775382

>соединение может быть только одно


да
Алгоритм такой:
- браузер делает запрос. Запускается PHP скрипт.
- Скрипт открывает ОДНО соединение с БД. Соединение упаковано в синглетон, и ты его в любую часть скрипта можешь подтянуть, гогда тебе в этом месте надо обратиться к БД
- Закрывать соединение руками не нужно, скипт закончит своё исполнение - обьект, в который упаковано соединение уничтожится, и соединение само закроется.

Таким образом - на один запрос браузера открывается 1 соединение с БД. На другой запрос - будет запущен другой скрипт, там будет открыто другое соединение.

Предваряя вопрос - соединение, открытое в одном скрипте, ты в другой скрипт передать не сможешь - ПХП так не работает.
>>775389>>775390
#105 #775389
>>775388
Спасибо.
#106 #775390
>>775388

Синглтон это антипаттерн. DI тут использовать можно.

- браузер делает запрос. Запускается PHP скрипт.
- Скрипт открывает ОДНО соединение с БД.
- скрипт создает классы работы с БД и передает в них это соединение
>>775397
#107 #775393
>>775382
С DI всё чуток посложнее. Для того, чтоб им нрмально пользоваться, тебе нужна хрень, под названием DI Container. Ты туда ложишь соединение при старте скрипта, а потом, когда оно тебе нужно, достаешь его оттуда.

Посмотри как container в Slim`е устроен, там очень простое и очень крутое устройство.

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

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

Пишу тут, и думаю, что тебе лучше пока не забивать этим голову. Это продвинутое ООП, к нему лучше переходить сильно позднее. Пока с синглетоном всё просто сделай
>>775430
#108 #775397
>>775390

>Синглтон это антипаттерн.


Не забивай начинающим голову этой хренью. Сам-то хоть сможешь обьяснить, почему это антипаттерн?
>>775430>>775431
#109 #775430
>>775393

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


нет. Вот пример DI без контейнера:

$pdo = new PDO(....);
$userDataGateway = new UserDataGateway($pdo);
$validator = new Validator($userDataGateway);

DI не требует контейнера. Ты наверно путаешь общий принцип DI и какую-то реализацию DI которую ты видел.

> И, если делать всё по всем правилам ООП, то передавать руками соединение в модель при её создании.... ну можно в принципе, но лучше для таких дел создать фабрику моделей


Не надо придумывать велосипеды, это все уже давно известно и описано например в уроке https://github.com/codedokode/pasta/blob/master/db/patterns-oop.md

>>775397

В уроке пытался (раздел про глобальные переменные и статические методы): https://github.com/codedokode/pasta/blob/master/arch/di.md

Согласись, кстати, что вопросы их того урока хорошо бы пошли на собеседовании: чем плохи глобальные переменные (и чем хороши), чем плохи статические вызовы. Мало кто может на них ответить. Я сталкивался с тем что у людей большой опыт программирования, но они плохо понимают ООП, исключения, обработку ошибок, общие принципы повышения качества кода.
#110 #775431
>>775397
ТАК НА ХАБРЕ НАПИСАЛИ РЯЯЯЯЯЯЯЯЯ!!!!11111 У кого свое мнение есть, тот в других тредах сидит.
#111 #775433
>>775430
Заебись. И сидишь ты такой на пятом уровне иерархии, пытаясь разобраться в методе с десятью параметрами, в которых передаются зависимости. Зато чистота, хуле.
>>775449
#112 #775437
>>775371
Функция там большая, это схематичный вид и интересует меня лишь ИФ.
У меня там при двух случаях джойница одна таблица, но потом действия для этих случаев расходятся, вот.
#113 #775442
>>775430
Да, не требует.
Но без него все классы, где используется композиция, надо собирать руками, а это весьма муторное занятие, ибо иногда там бывает дофига уровней вложенности
>>775449
#114 #775449
>>775442

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

__construct(SomeService $service, SomeOtherService $someOtherService)

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

Вот ты зря урок не прочел. Там написано про достоинства и недостатки разных подходов.

>>775433

По моему ты ничего не понял. Алсо, больше 4-5 аргументов делать не рекомендуется.
>>775458>>775461
#115 #775453
Минутка юмора в этом итт.
Смотрите, какую приколюху нашёл: https://github.com/PHPointless/monolol
>>775497>>775765
#116 #775454
>>775430

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



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

Ато вот щас достался проект системы электронного документооборота на PHP+Symfony2, но при этом с процедурным кодом внутри (всё свалено в огромные классы с иманами что-то-там-Serivce, где по 20-30 публичных методов, в каждом из которых по 50-400 строк кода. Простыни по 4 экрана в среднем...). Это пиздец, товариши. Какие-то клоуны слышали, что Symfony2 луший фреймворк для сложных проектов, но как им пользоаться - понятия не имели.
И вот как теперь с этой хренью работать??
>>775459>>788598
#117 #775458
>>775449
Зря ты думаешь, что не прочел. Давным-давно уже...

Кстати пешы исчо, у тебя талант излагать сложные вещи так, что любой дурак поймёт
>>775461>>775463
#118 #775459
>>775454

>Блядь, где все нормальные программисты-то?


Раньше они составляли 10% от общего количества, сейчас 0.01%, вот тебе и кажется что их нет.
Людей всем не хватает, берут любую макаку, лишь бы цикл умела написать.
В начале девяностых так с бухгалтерами было - двухмесячные курсы и готов новый главбух для "рогов и копыт".
#119 #775461
>>775449
>>775458
Могу даже следующую темку подкинуть.
Про DDD тебе бы изложить, хотя бы про самые основы, и ссылки на книги, где развёрнуто почитать
>>775469
#120 #775463
>>775458

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


Не самый приятный комплимент.
>>775467>>775469
#121 #775467
>>775463
странно, мне было бы приятно, ибо я такого таланта напрочь лишен. Обьяснять просто - совсем не умею
#122 #775469
>>775461

Увы, с этим проблема, так как я никогда вроде с Domain Driven Dev-t не сталкивался.

>>775463

Почему же, приятный.
#123 #775478
Моё скромное мнение, ОПу, чем размениваться тут по мелочам, надо книгу по PHP написать - от основ, до мастеринга. И пользу бы большую сообществу принёс, и денег бы точно подзаработал

ОП, книгу не думаешь написать?
>>793703
#124 #775493
>>774853
>>774442
>>774686
Спасибо, анончики. А такой вот вопрос: есть мнение, что в случае PHP ты достигаешь условного потолка в 150к/мес и дальше только из страны валить или искать другую работу, а с питоном/жабой/шарпом ты можешь вроде как перерасти в инженера, аналитика, руководителя и т. д. да и потолок зарплат за счет энтерпрайзности. Или это тоже не совсем так?
И еще.

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


Разве это не относится к PHP? Вот смотрите: у Ruby - Rails. У Python - Django, Flask, aio. У С# - .Net. У java - EE. У С++ - Boost + любой фреймворк гуя. У PHP - Yii/Yii2, Symfony 2/Doctrine 2, игнитер, ларавель, кохана, зенд, фалькон, кейк, ну и конечно же джумла, друпал и вордпрес. Ну нихуя, блядь, себе! То есть, для руби я учу рельсы и иду работать, а для пхп я должен покопаться во всех этих сортах или даже хорошо их все знать? А если на работу требуется игнитер, а я учил симфонию? Не возьмут же.
#125 #775497
>>775453
Ну смешно же!
#126 #775513
>>775493
На самом деле сегодня на рынке только 3 фреймворка: Yii, Laravel и Symfony
Если есть вакансии по другим фреймворкам - то это, почти всегда, поддержка старого Legacy-говня
#127 #775514
>>775493
Ну а wordperss и joomla - это и программированием-то тяжело назвать
123 Кб, 1024x768
#128 #775515
>>775493

> У С# - .Net. У java - EE.


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

> То есть, для руби я учу рельсы и иду работать


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

>А если на работу требуется игнитер, а я учил симфонию?


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

мимо-с-дивана
#129 #775528
>>770054
Так обычно и бывает.
Мне почему-то напомнило путешественников из российских мухосраней, которые восхищаются любыми заграницами, а там бывают только в столицах или на курортах. И при этом заявляют, что в России всё-всё плохо - и так далее, хотя сами в Москве или Петербурге бывали только проездом.
Тред не успел начаться, а уже 129 постов, воу, воу, палехчи!..
>>775552
#130 #775552
>>775528
Заграницей и в маленьких городах ахуенно, а в Рашке только ДСы нормально выглядят и только в центре.
>>775557
#131 #775557
>>775552
Лень даже спорить, извини, бро.
#132 #775558
>>775493

>Не возьмут же.



Возьмут, игнетер плохой пример.
Но с хорошего фремворка на хороший ты будучи не тупым быстро перекатишься, это просто.
Люди вон с языка на язык скачут, а тут всего лишь фреймворк, важнее показывать гибкость ума и знание основ.
#133 #775562
>>775493
В твоем списке можно сказать что PHP - Laravel
На другие языки тоже много фреймворков.
#134 #775582
Сап, анонс. Есть некий сервис крутится на сервере win с mssql. Есть скрипт регистрации пользователя который записывает данные в user management систему на mysql находится это на другом сервере. Я не разработчик, но курс из op поста освоил. Как лучше организовать одновременную запись в две базы из скрипта регистрации, с меня нефть.
#135 #775636
Дорогой мой аноний, помоги найти ошибку:

решаю задачу со списком абитуриентов https://github.com/codedokode/pasta/blob/master/student-list.md

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

Проблемная часть кода - http://pastebin.com/YTHLqCng.

По-моему, я выдумываю велосипед, как можно улучшить код?
>>775638>>775913
#136 #775638
>>775636
рабочая ссылка на пастебин - http://pastebin.com/YTHLqCng
#137 #775673
Всем привет. Начал изучать шаблонизатор "PHP". Возникла следующая задача: распарсить JSON. В шаблонизаторе "PHP" есть функция json_decode, но она почему-то возвращает NULL для невалидного JSON:

json_decode("42"); // => 42
json_decode("null"); // => NULL
json_decode("xxx"); // => NULL - WTF?

Собственно вопрос: как в шаблонизаторе "PHP" распознать, что json_decode возвращает NULL из-за невалидности JSON? В языках программирования обычно кидается исключение. А как с этим обстоят дела в шаблонизаторе "PHP"?
#138 #775678
>>775673
азаза, траль в треде, все в монаду!
#139 #775707
>>775673
Обпараморфизился.
>>775715
#140 #775715
>>775707
О, нашел ответ. В шаблонизаторе "PHP", как и ожидалось, исключений как таковых нет, надо дергать json_last_error. Ну, в принципе неплохо. Хотя бы что-то. Не сравнится, конечно, с языками программирования. Но для "PHP" как шаблонизатора тоже неплохо.
>>775718>>779542
#141 #775718
>>775715
Ну так чего ты хотел от шаблонизатора в котором AST появилось в 7 версии. А вообще, это не очень хорошо, что ты тут так жирно всё это высказываешь, у вас же есть свой загон с бананами и линзами, не(я хоть и не люблю пыху очень и писать приходится иногда, но такого жирного траллинга себе тут не позволяюй)? А ещё меня вы радуете своим раздутым ЧСВ, которое не соответствует скиллу практическому. Ни один не показал проект на хачкеле/эрланге/кложуре крупный и гитхуб свой не выкладывал. Может ты похвастаешься.
P.S. Забайндил монаду тебе за категорию, проверяй.
#142 #775752
Антуаны, пилю свою первую контактную форму. При submit'е она загружает эту же страницу, но с благодарственной надписью, письмо отправляет. Скрипт валидации и отправки письма находится в том же php файле. Так вот, когда письмо отправилось и вылезла страница с благодарочкой, если нажать F5, то страница снова обновится с благодарственным сообщение и отправит еще одно письмо. Как с этим бороться?
Код здесь:
http://pastebin.com/W5QKAHCf
>>775903
#143 #775765
>>775453
Monolol, мда.
А в чём прикол?
>>775802
#144 #775767
аноны хелпните нужна помощь с php. Нужно сделать: "На основе заданного файла, содержащего натуральные числа, получить новый, где цифры каждого из данных чисел записаны в обратном порядке". Вот только проблема в php я полный ноль из html знаю <head> <body> <hello world>.
>>775771>>775774
#145 #775770
>>775673

> как в шаблонизаторе "PHP" распознать, что json_decode возвращает NULL из-за невалидности JSON? В языках программирования обычно кидается исключение. А как с этим обстоят дела в шаблонизаторе "PHP"?



Легко, гугли set_error_handler. Создаётся глобальный error handler в котором выбрасывается ErrorException в случае возникновения ошибки. В последний раз я в зк видел точно такую же претензию к PHP от чувака, который яро агитировал всех перекатываться на JS. А в этом треде как раз критиковать этот язык начали. Не выдержал?
>>775903
#146 #775771
>>775767

> Вот только проблема в php я полный ноль


Ну учи тогда. Ты палец о палец не ударил для решения задачи и хочешь, чтобы тебе на серебряном блюдечке подали ответ.
#147 #775774
>>775767
1. Написать регулярку для поиска чисел в тексте.
2. Находить число и переводить его в строку.
2. С помощью mb_strlen в цикле отрывать по символу с начала строки и присоединять спереди к переменной, содержащей пустую строку: $result += $letter.
3. После завершения цикла выводить $result.
4. Повторить с другим найденным числом.
Для этого надо изучить несколько тем: циклы, массивы (не обязательно именно для этой задачи, можно обойтись), регулярные выражения.
>>775775
#148 #775775
>>775774
То есть $result = $letter + $result.
>>775777
#149 #775777
>>775775
Соррян, туплю, там же строки.
Совсем уехал с этим ООП уже.
$result = $letter . $result
#150 #775782
>>775582
бамп вопросу.
#151 #775802
>>775765
В лолифайерах. Мне больше всего нравится лолифайер "YOLO".
32 Кб, 600x396
#152 #775823
Это какой-то мрак, мрак, кладбище, филолог...
То руководство Сафронова - я не могу даже плагин для Композера установить битый час...
Почему на Windows в cmd всё работает в любой версии, в любом виде, а тут какая-то непролазная ЗАДНИЦА в изменениях, почему так всё неудобно и непонятно?..
Бугурта на вас нет, ироды проклятые...
>>775903
#153 #775903
>>775770

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

>>775752

Почитай про обработку форм https://github.com/codedokode/pasta/blob/master/forms.md

>>775582

Установить 2 соединения с двумя БД и в каждом делать INSERT . Но вообще это по моему плохая идея использовать 2 БД, так как будут расхождения. Тебе тогда по идее надо еще писать скрипт который будет запускаться по расписанию, проверять списки в обоих базах и выявлять расхождения.

>>775823

Ну без публикации подробностей ошибки ты будешь ее еще не один час искать.
>>775967
#154 #775906
>>775582
С использованием менеджера распределенных транзакций.
#155 #775913
>>775636

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

далее, тут неправильно:

> switch ($value) {


> case (empty($value['name'])):


как это по твоему должно работать? В case пишется не выражение, а значение, которому должно быть равно value, например case 1: ....

При ошибке логичнее писать не единицчку, а сразу сообщение с причиной.

> INSERT INTO abitList VALUES ('', ?, ?, ?, ?, ?, ?)


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

> $value[$element] = isset($value[$element]) ? $value[$element] : '';


Слева должна стоять просто переменная, а не элемент массива

> value="<?=regOutValue($value, 'name')?>


Читай урок про XSS, данные надо корректно экранировать

Проверки у тебя только на то, заполнено ли поле, надо проверять более тщательно. Например чтобы не ввели фамилию '123' или '???'.
154 Кб, 1366x768
#156 #775953
Народ, есть проблема. Мне нужно собрать имя из слогов, которые получаются в случайном порядке, однако выводится только последний. В чём может быть проблема? В массив записывается только один слог - последний, и при выводе он один и выводится.

Код такой:

<?php

$letters = array(
'ко',
'и',
'дзу',
'ми',
'са',
'ку',
'ра',
'да',
'чи',
'ки',
'ри'
);
$name = '.';
for ($i = 1; $i <= 4; $i ++) {
$random = array_rand($letters, 1);
echo "vipalo chislo {$random}, slog {$letters[$random]}\n";
$slogi = array();
$slogi[] = $letters[$random];
}
$slovo = implode("", $slogi);
echo "$slovo";
154 Кб, 1366x768
#156 #775953
Народ, есть проблема. Мне нужно собрать имя из слогов, которые получаются в случайном порядке, однако выводится только последний. В чём может быть проблема? В массив записывается только один слог - последний, и при выводе он один и выводится.

Код такой:

<?php

$letters = array(
'ко',
'и',
'дзу',
'ми',
'са',
'ку',
'ра',
'да',
'чи',
'ки',
'ри'
);
$name = '.';
for ($i = 1; $i <= 4; $i ++) {
$random = array_rand($letters, 1);
echo "vipalo chislo {$random}, slog {$letters[$random]}\n";
$slogi = array();
$slogi[] = $letters[$random];
}
$slovo = implode("", $slogi);
echo "$slovo";
>>775965
#157 #775965
>>775953

Попробуй словами кратко написать что делает каждая строчка внутри цикла for.
>>775978
42 Кб, 800x302
#158 #775967
>>775903

>Ну без публикации подробностей ошибки ты будешь ее еще не один час искать.


Да, не подумал, извинения прошу. Просто ИЗЛИЛСЯ в тред...
Ну вот
<-----
В руководстве указано: "Обратите внимание, что эту команду (несмотря на наличие аргумента под названием global) не нужно выполнять с правами администратора, иначе далee вы не сможете установить шаблон приложения из-за недостаточых прав доступа".
Запускать пробовал из разных директорий, под root тоже пробовал.
Сначала не увидел, что ошибки в самой команде - так скопировал. Потом набрал руками - без разницы.
63 Кб, 799x507
#159 #775968
>>775967
Стоп, там же нужно быть залогиненным на Github? Или нет?
Ну как всегда - только спросишь, как сразу появляются идеи...
>>775972>>776069
#160 #775972
>>775967

>composer .phar


Что за файл такой - .phar? Ты вообще понимаешь, что ты копируешь?

>>775968
Нет. Пакеты тянутся в основном с этого сайта: https://packagist.org/
>>775991
#161 #775977
>>775967
И зачем в корень ФС переходить? В PATH что у тебя? Зачем тебе компоненты Symfony?
>>775991
#162 #775978
>>775965
У нас есть i, которое доходит до 4-х,
присваиваем переменной слог четыре раза;
переносим каждую новую строку, в них пишем выпавшее число и слог;

Дальше я хотел массив сделать, в который записывались бы выпавшие слоги, а потом всё это вывелось бы в одну строку - вот тут и косяки
>>776069
#163 #775986
>>775967
Тут советовали для понимания попробовать совладать с Gentoo/Arch по их всеобъемлющим и исчерпывающим мануалам, но тут вряд ли за это кто-то возьмётся, так что советую статьи проще и короче: https://habrahabr.ru/post/99041/
>>775991>>776069
#164 #775991
>>775972
Я там ошибся, потом уже исправил.
На скрине наползло ещё то, что я вышел из той директории.

>Пакеты тянутся в основном с этого сайта: https://packagist.org/


То есть мне надо в source.list его как-то добавить, как я добавлял dotdeb.com?
>>775977

>И зачем в корень ФС переходить? В PATH что у тебя? Зачем тебе компоненты Symfony?


У меня вроде юзер в PATH (если я понимаю, о чём ты). ВОт сейчас так попробовал
<-----
Переводит в /home/user/ сразу.
>>775986
Спасибо, придётся вникнуть, похоже.
Но вот такое вызывает неописуемое жжение пониже спины:

>Если вы уже использовали Linux ранее, то наверняка знаете, что после входа в систему вас приветствует приглашение, которое выглядит примерно так:


>$


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


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


И так там во всём, с чем я уже успел столкнуться...
>>776069
33 Кб, 800x329
#165 #775992
>>776069
44 Кб, 804x344
#166 #776006
Вот что сейчас удалось и не удалось.
Под root - установилось. Под юзером - получил красным предупреждением по лбу.
А если под root, то потом не удастся установить сам проект, как написано в руководстве.
Хотя там много чего написано, а работает уже не только лишь всё. Вернее, работает всё, но мало именно благодаря тому, что там написано. (с) Виталий Кличко.
>>776008>>776073
#167 #776008
>>776006
Сделай ls /
>>776010
19 Кб, 718x113
#168 #776010
>>776016
#169 #776016
>>776010
Проиграл. Анончик, почитай то, что скинули выше по линуксу. Файл composer.json - это файл, в котором указываются зависимости для проекта, зависимости скачиваются в папку vendor. И так для каждого отдельного проекта. У тебя выходит, что содержимое корня файловой системы - твой проект. Твой пользователь не может писать в корень фс, а root может. Короче, вот задание: создай папку в /var/www/, например foo/, перейди в эту папку, оттуда вызови composer require (...) и выведи содержимое папки. Всё делай через консоль.
>>776033
54 Кб, 804x380
#170 #776033
>>776016
Ну я понимаю, что смешно выгляжу, как дитё малое, которое делает первые шаги.
Но я создавал как-то папки через консоль.
Вот сейчас сделал
<-----
Вроде это то, что было нужно?
Теперь ls / показывает прежние папки, как будто они просто перенеслись в этот каталог. Всё верно сейчас?
Мне всего лишь надо было вспомнить про sudo, стукнутый я по голове...
Попробую установить Yii2 чуть позже.
Какая боль, какая боль: консоль Linux против филолога - 5:0.
>>776054
83 Кб, 1009x592
#171 #776054
>>776033
Bower ещё нужен, что ли. Я думал, в плагине Asset он уже есть, я когда его устанавливал.
А вообще:
СМОТРЮ В РУКОВОДСТВО
@
ИЩУ РАБОТАЮЩИЕ АНАЛОГИ КОМАНД
Я мог бы так и на cmd делать вполне.
>>776073
#172 #776069
>>775967

1) ты плохо скопировал команду и добавил в нее лишние пробелы и бекслеши
2) не надо от рут запускать композер. Не надо вообще сидеть под рутом

Кстати, ты читал мой гайд по командной строке из Оп поста?

Набери php -h (и прочитай этот раздел http://php.net/manual/ru/features.commandline.options.php ). Тогда тебе станет понятна причина части ошибок.

Еще: http://php.net/manual/ru/features.commandline.usage.php

>>775968

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

>>775978

Ты не полностью описал что делают эти строки. Ты не написал, что делают последние две:

\t$random = array_rand($letters, 1);
\techo "vipalo chislo {$random}, slog {$letters[$random]}\n";
$slogi = array();
$slogi[] = $letters[$random];

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

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

4 раза повторяем последовательность действий: {
- присваиваем переменной слог
- пишем выпавшее число и слог;
- .... что-то делаем с массивом ....
}

>>775986

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

>>775991

> То есть мне надо в source.list его как-то добавить, как я добавлял dotdeb.com?


Нет. sources.list это конфиг менеджера пакетов apt. Композер это отдельная программа у которой свои конфиги и особенности.

>>775992

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

Проверить актуальную версию плагина можно тут: https://packagist.org/search/?search_query[query]=composer-asset-plugin

На этой странице https://packagist.org/packages/fxp/composer-asset-plugin написана команда которой он ставится.
#172 #776069
>>775967

1) ты плохо скопировал команду и добавил в нее лишние пробелы и бекслеши
2) не надо от рут запускать композер. Не надо вообще сидеть под рутом

Кстати, ты читал мой гайд по командной строке из Оп поста?

Набери php -h (и прочитай этот раздел http://php.net/manual/ru/features.commandline.options.php ). Тогда тебе станет понятна причина части ошибок.

Еще: http://php.net/manual/ru/features.commandline.usage.php

>>775968

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

>>775978

Ты не полностью описал что делают эти строки. Ты не написал, что делают последние две:

\t$random = array_rand($letters, 1);
\techo "vipalo chislo {$random}, slog {$letters[$random]}\n";
$slogi = array();
$slogi[] = $letters[$random];

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

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

4 раза повторяем последовательность действий: {
- присваиваем переменной слог
- пишем выпавшее число и слог;
- .... что-то делаем с массивом ....
}

>>775986

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

>>775991

> То есть мне надо в source.list его как-то добавить, как я добавлял dotdeb.com?


Нет. sources.list это конфиг менеджера пакетов apt. Композер это отдельная программа у которой свои конфиги и особенности.

>>775992

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

Проверить актуальную версию плагина можно тут: https://packagist.org/search/?search_query[query]=composer-asset-plugin

На этой странице https://packagist.org/packages/fxp/composer-asset-plugin написана команда которой он ставится.
>>776454
#173 #776073
>>776006

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

- Во-первых прочти гайд ОПа из ОП поста по командной строке (целиком)
- Затем страницы мануала пхп про командную строку
- Затем прочти документацию или статьи по композеру: https://www.google.ru/search?q=композер+документация&newwindow=1&gbv=1&sei=70hpV9irO8itsgHhlYn4Aw (увы, официальная документация только на английском, на русском только небольшие статьи)
- затем нагугли и прочти про структуру файловой системы лиункса, например: http://help.ubuntu.ru/wiki/разделы_и_файловые_системы_linux
- и вот это еще тоже http://www.k-max.name/linux/fajlovaya-sistema-linux-i-struktura-katalogov/
- прочти про систему разрешений (привилегий) для доступа к файлам в линуксе: https://www.opennet.ru/base/sys/file_access.txt.html
- http://help.ubuntu.ru/wiki/стандартные_права_unix

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

>>776054

Можно без bower. Добрые люди сделали возможность ставить пакеты бовера через композер напрямую: https://asset-packagist.org/

Для этого тебе не нужен assets-composer-plugin. Это если тебе это нужно для своего проекта.

Если ты что-то устанавливаешь через assets-composer-plugin то придется еще ставить ноду, npm и bower.
>>776454
#174 #776080
Как в notepad запускать код?
>>776083
#175 #776083
>>776080

Код можно запускать из командной строки

Тебе наверно надо прочесть это:

- https://github.com/codedokode/pasta/blob/master/soft/php-install.md
- гайд по командной строке https://github.com/codedokode/pasta/blob/master/soft/cli.md
- урок про веб-сервер https://github.com/codedokode/pasta/blob/master/soft/web-server.md
>>776084
#176 #776084
>>776083
Какой кошмар, а попроще нельзя? Чтобы кнопочку нажимаешь в нотпаде, открывается консоль, вводишь, выводишь.
>>776101
#177 #776098
Хочу устроиться на работу php-разработчиком. С нуля. Вопрос: в каких объемах мне нужен java-script?
>>776099
#178 #776099
>>776098
1,5 литра перорально ежедневно.
#179 #776101
>>776084
нотпад
как там в 2007?
#180 #776112
Анон, поясни ньюфагу за всю хуйню. Вот есть веб платформа, например вконтактик. Каким образом при переходе на разные страницы шапка не перезагружается, аудио и видосики продолжают играть? Как примерно выглядит структура таких сайтов?
>>778223>>778347
#181 #776378
Дано: папка на сайте. Предположим sitename.com/papka а в ней 100 изображений.
Задача: скачать по нажатию на кнопку эту папку.

Как это реализовать? Мне нужно как-то архивировать эту папку и скачивать архив? Скачивать по одному файлу не подойдет.
#182 #776384
Можно ли устроиться на хорошую должность с высшим(не программист) образованием, но с знаниями человека работающего в этой сфере?
#183 #776394
>>776384
Можно.
#184 #776395
>>776384
Нельзя.
#185 #776396
>>776384
Можно вообще без вышки, лишь бы уровень компетенции был достаточный.
55 Кб, 640x369
#186 #776454
>>776069
>>776073
Спасибо, ОП.

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


Эх, я же только в Yii2 хотел разобраться, в консоли - постольку-поскольку...
Ну придётся понемногу разбираться.

>Во-первых прочти гайд ОПа из ОП поста по командной строке (целиком)


Я прочитал как раз перед первой установкой Yii2 на Windows 8, потом перечитал уже под Linux, сейчас посматриваю ещё и тот гайд с Хабра, который подкинул братишка.
Спасибо, сохраню все ссылки и сообщение.
Сейчас, честно говоря, начал изучать генерируемые Gii файлы, чтобы лишний раз посмотреть на структуру MVC, хотя вроде в ней уже разобрался.
Это у меня в приоритете было изначально.
Но консоль нужна, Linux и cmd, всё осилю, постараюсь, спасибо, ОП.
#187 #776605
https://sharisha-status.appspot.com/
Зацените, за 2 дня сделал, для себя.

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

Рейт крч. Впервые что-то пишу на PHP, это мой первый hello world. Странно, что я так долго не писал на ПХП, наверно потому что я люблю нативный десктоп-кодинг.
#188 #776689
>>776605

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


Что обновлять?
#189 #776710
>>776605
Забавно. Для фагов нормально.
Нужна возможность добавлять самому своих богинь и следить за ними.
Но тут вряд ли взлетит, потому что таких богинь почти нет.
Для фагов Карины - ЗБС-СПС.
#191 #776783
>>776605
Покажи код
#192 #776795
Сосанчики, чому имя не выводит?(
https://ideone.com/yem5e6
>>776802
#193 #776802
>>776795
Потому, что ты передаешь $name в конструктор и нечего с ним там не делаешь.
>>776813
#194 #776813
>>776802
Спасибо.

Так верно?
public function __constructor($name){
$this->name = $name;
}
>>776945
#195 #776877
ОП, а вот допустим у меня есть класс StudentsTable такой типа маммер с методами доступа к БД.
Есть методы getStudentById и getStudentByName, которые возвращают хеш студента со полями инфы о нём. Разница в них только в том, какой столбец сравнвается в WHERE запроса.

А кошерно ли сделать метод getStudent, а в аргумент ему передавать либо id (целоцисленный) либо строку (имя стулента), а в методе распарсить её регуляркой и если это число (ну напрмиер так /^\d+$/ ) то вызывать метод getStudentById а если это не число, то вызывать метод getStudentByName

Кошерно ли это с точки зрения ООП как такового?
>>777230>>777324
#196 #776912
Можно дикий вопрос?
Знак "точка с запятой (semicolon)" используется как символ окончание инструкции и для разделения выражений в "шапке" цикла for. В гугле и в официальном руководстве нет перечисления всех способов использования данного знака.
Как быть точно уверенным что точка с запятой больше нигде не используется в синтаксисе? Выучить весь синтаксис и методом исключения определить места где используется этот символ?
ОП называет выражения в скобках после ключевого слова for "шапкой". Где в официальном руководстве сказано что так можно называть эту часть конструкции? У неё вообще есть официальное название?
>>776930>>777337
#197 #776930
>>776912
завершил инструкцию - поставил точку с запятой, что не ясно?
#198 #776934
Господа, ребята, товарищи.
Подскажите, есть ли годные видео уроки по php js css? Годные, в плане полезные и актуальные.
>>776945
#199 #776945
>>776934
Да.

>>776813
Да.

>"My name is ".$this->name;


Зачем использовать конкатенацию, если в строку из двойных кавычек можно вставлять переменную вот так "My name is {$this->name}". Вот с одинарными - да, нужно конкатенировать.
>>777040
#200 #777040
>>776945
А чуток подробнее?
>>777041
#201 #777041
>>777040
Это я про годные видео уроки офк
>>777047>>777049
#202 #777047
>>777041
Ты шапку ОП-поста чем читал? Неужели ты думаешь, что настолько уникален в своих вопросах и поисках?
#203 #777049
>>777041

> видео уроки


Ой, не заметил. Тебе именно видеоуроки нужны? Можешь сразу дропать программирование, если другие источники знаний не устраивают.
>>777251
#204 #777230
>>776877

>А кошерно ли


Очень кошерно

>>776877

>а в аргумент ему передавать либо id (целоцисленный) либо строку (имя стулента), а в методе распарсить её регуляркой и если это число (ну напрмиер так /^\d+$/ ) то вызывать метод getStudentById а если это не число, то вызывать метод getStudentByName


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

public function getStudentByСolumn($column, $value)
{
$query = "SELECT * FROM students WHERE {$column}={$value}";
...
}
>>777324
#205 #777251
>>777049
Как альтернативный источник для восприятия информации - почему бы и нет?
Если нет - поясни
>>777294>>777327
#206 #777260
Правильно ли я понимаю, что при использовании Slim, контроллеры не нужны? Все данные и вызывания моделей будут в роутах?
#207 #777281
>>777260
https://github.com/revuls/SlimMVC/blob/master/routers/user.router.php вот смотрю сюда и чего-то не понимаю.
>>777294
#208 #777292
>>777260
Колбек функции в роутах заменяют тебе контроллеры.
#209 #777294
>>777260
Можно и без контроллеров, но вряд ли это можно назвать хорошей практикой. В доках просто нужно изложить информацию кратко, поэтому и пихают всё в один файл. Ну и вот есть же возможность использовать контроллеры: http://www.slimframework.com/docs/objects/router.html#container-resolution

>>777251
Нет желания объяснять очевидные вещи. Тебя водят за руку, что не даёт ничего кроме false sense of accomplishment. А потом когда задача выходит за рамки разжёванного в видеоуроках, в треде появляется куча нубских вопросов от практикующих youtube-driven-development, ведь неоткуда бездумно скопировать.

>>777281
Там как бы последний коммит 3 года назад. И с чего ты взял, что его коду нужно следовать?
>>777327
#210 #777324
>>777230

У тебя SQL инъекция. Имя колонки надо проверять по белому списку либо еще как-то, значение подставлять через плейсхолдер.

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


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

>>776877

> А кошерно ли сделать метод getStudent, а в аргумент ему передавать либо id (целоцисленный) либо строку (имя стулента), а в методе распарсить её регуляркой и если это число (ну напрмиер так /^\d+$/ ) то вызывать метод getStudentById а если это не число, то вызывать метод getStudentByName


Это плохой и опасный подход. Плохо когда аргумент функции может быть разных типов так как легко ошибиться, передать что-то не то, а функция за счет своей всеядности проигнорирует ошибку. Да и в коде функции ошибку легко допустить если аргумент может быть разных типов.
>>777432
#211 #777327
>>777251

Да, почему бы и нет. можно например смотреть и подмечать ошибки и неточности в объяснениях.

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

>>777260

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

>>777294

Слим предназначен в первую очередь для маленьких приложений где все контроллеры тоже маленькие и умещаются в один файл.
#212 #777337
>>776912

> Как быть точно уверенным что точка с запятой больше нигде не используется в синтаксисе? Выучить весь синтаксис и методом исключения определить места где используется этот символ?


да. Но мануал по ситаксису не такой и огромный, 2-3 дня максимум на тщательное изучение.

> ОП называет выражения в скобках после ключевого слова for "шапкой". Где в официальном руководстве сказано что так можно называть эту часть конструкции? У неё вообще есть официальное название?


Я встречал слова вроде "заголовок цикла". Вот например что гугл выдает на запрос "for loop header":

http://stackoverflow.com/questions/28506401/which-for-loop-header-performs-better
https://www.arduino.cc/en/Reference/For

Можно поискать и на русском: https://www.google.ru/search?q=заголовок+цикла+for&btnG=Поиск&newwindow=1&gbv=1

Поиск по "шапка цикла for" выдает всякую ерунду. Неужели это я сам придумал такое название?
>>777425
#213 #777344
Привет, хочу на пыхе сделать скрипт, который делает посты на одном сервисе посредством casperjs. Работать будет на локалке. Будет 2 файла: sample.php и sample.js. Php должен парсить информацию и передавать ее в жс, который уже и сделает пост. Как проще всего это реализовать? Как запустить каспер жс скрипт из пхп и передать в него информацию?
>>777569
#214 #777409
ролл
#215 #777413
Подскажите, как в ЦСС сделать так, чтобы тест...
В общем вот:
<tag>Текст</tag> далее.
Был в 1 строке?
Что за тэг заюзать?
>>777433>>777569
#216 #777425
>>777337

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


Может быть, а может и нет.
>>777337

>да. Но мануал по ситаксису не такой и огромный, 2-3 дня максимум на тщательное изучение.


2-3 дня на изучение всего справочника языка? Это каким же гением с идеальной памятью надо быть?
#217 #777432
>>777324

>>Это плохой и опасный подход


Полиморфизм не вышел :(
вычёркиваем этот метод

Хотя по-моему это удобно было бы. Что "не то" там можно передать по сути? Всё приведено к строке, оттримлено как полагается...
>>777569
#218 #777433
>>777413
Ну что же вы... Или не поможете?
>>777460
#219 #777442
Сосаны, проебал свою базу данных проекта на yii2.
Модельки то есть и можно было бы вручную сделать новые.
Но, может быть, есть возможность из них автоматически сгенерировать таблицы?
Поверхностно погуглив не нашел ничего внятного, хелп
>>777445>>777569
#220 #777445
>>777442
Doctrine может генерить таблицы, если прописаны сущности. Гугли orm:schema-tool:create и что для неё нужно
>>777569
#221 #777460
>>777433
Помню в 2004-ом году мне было 17 лет. Я второй год изучал программирование. Интернета тогда не было. Компьютера не было. Денег на учебники тоже не было. Я каждый день ходил в библиотеку и читал одну книжку о программировании. Конспектировал и тут же составлял программы в тетрадке. Набирал код на уроках информатики. Мой код был в 10 раз сложнее кода сверстников и весь урок информатики уходил лишь на то чтобы успеть перепечатать с тетрадки код и показать на проверку преподавателю. Об отладке не могло быть и речи, жизнь заставляла меня писать сразу правильно.
>>777461>>777470
#222 #777461
>>777460
Я, просто, не изучаю цсс и пхп, а в программе 1 надо сделать так. Я никакие теги и из свойства не знаю совершенно, а ради простенькой задачки в мимопрограмме учить цсс и пхп было бы странным.
>>777470>>777477
#223 #777470
>>777460
Тоже склоняюсь к мысли, что всюду открытые двери - не всегда хорошо. Художник должен быть голодным.
По-настоящему начинаешь ценить время и рационально распоряжаться им только тогда, когда ощущаешь его нехватку.

>>777461
Люди в таких случаях используют гугл, формулируя запрос на английском языке. Не говоря уже о том, что есть более подходящие треды для твоего вопроса.
>>777472
#224 #777472
>>777470
Ест-но не зная цсс я смогу сформулировать вопрос? А ладно.
#225 #777475
пишу, чтобы добавить тред в избранное. Куда звездочка делась?
>>777513
#226 #777476
Оп, а у тебя нет урока по namespace?
>>777518>>777569
#227 #777477
>>777461
Я проводил все свободное время в библиотеке. Вечера, выходные, два лета. Мои сверстники гуляли, ездили отдыхать, играли в любовь, а я сидел в библиотеке. Я получил отлично, так же как и те кто просил меня написать им программы в рамках курса. Мне было несложно помочь, времени уходило 10 минут. Свой же код я кропотливо писал часами. Если подумать, то можно прийти к выводу что наша система оценок в образовании несправедлива. Думаю я заслужил 50 баллов из 5. Просто отбивает все желание развиваться дальше.
#228 #777479
>>777477
Ты пришел к успеху? Чем занимаешься?
>>777496
#229 #777482
>>772710
сеймщит, учил сам (фронтенд/seo мой конек), seo заебало, а учить обоссаный жс дальше жквери мне было откровенно в падлу.
Посидел в треде, полистал книжечки, сейчас туплю юниором в одной небольшой компании
#230 #777491
Посоны, где мне почитать про то, как правильно выстраивать архитектуру приложений?
Сейчас использую yii2. Говорят должны быть толстые модели и тонкие контроллеры, но не перечит ли это здравому смыслу? Ведь многие таблицы связаны и стоит поменять логику в одной из связанных модели, как связь пойдет по пизде. Может быть есть примеры грамотных приложений, чтобы я посмотрел как работают нормальные люди.
>>777569
#231 #777496
>>777479
Пришел ли я к успеху? Я отлично провел молодость. Клубы, девки, алкоголь, трава, рок-н-ролл сутками напролет. Под конец я вроде бы уже опомнился что хватит гулять, но попал в лютую аварию во время стритрейсинга. ЧМТ, головные боли, таблетки, деменция. Мое IQ упало со 135 до 89. После таблеток вроде 115 стало. Да. Я пришел к успеху.
Чем занимаюсь? Пытаюсь вкатиться после 30.
>>777497
#232 #777497
>>777496
Как-то не вяжется с этой >>777477
кулсторией
>>777509
#233 #777509
>>777497
Прикол в том что у нас бюджетные места распределялись по среднему баллу. Пока я занимался информатикой, я запустил на четверки некоторые гуманитарные предметы. В итоге я по рейтингу оказался на 4-ом месте после тех кому я помогал с задачами. Специальности распределялись по принципу одна специальность на одного человека. 3 человек впереди меня собрали все компьютерные науки. Мне пришлось навсегда отказаться от затеи быть программистом. В те года никто бы не поверил что появятся самообразованные в интернетах джуны, которым даже диплом специалиста не понадобится. Они будут пользоваться гуглом, и смеяться над выпускниками вузов.
113 Кб, 755x191
#234 #777513
>>777475
Пик.

>>777477
Есть у него, открой задачу про студентов в ОП-посте или просто поищи в репозитории pasta на GitHub.
>>777517>>777518
#235 #777514
>>769611 (OP)
ОП-няша, скажи пожалуйста, нет опасений, что нода с питоном повытеснят PHP из его ниши? Вот, жирнота в прикрепленном PHP "шаблонизатором, а не языком" называет, но вообще с JavaScript и его многочисленными фреймворками все так носятся, на TIOBE рейтинг PHP падает ниже некуда, вакансий по JS/Python/Ruby все больше, а по PHP как-то не прибавляется. Особенно пугает JS с его идеей фулстак девелопмента, максимум асинхронности и всего такого. Ты-то перекатишься легко, а те, кого ты учишь? Да и зарплаты у них у всех как-то зачастую повкуснее Какие вообще перспективы и видение будущего в связи с описанным? Извини пожалуйста, если платина.
#236 #777517
>>777513

>Есть у него, открой задачу про студентов в ОП-посте или просто поищи в репозитории pasta на GitHub.


О чем ты, человек?
>>777518
#237 #777518
>>777517
Не тому ответил. Вот так:
>>777476 --> >>777513
#238 #777535
>>777514
Лично я больше опасаюсь конструкторов сайтов. Все эти настраиваемые блоки, пошаговые мастера, модули расширения уже позволяют Васяну из 7-б клепать полноценные порталы. Кто-нибудь скоро додумается оптимизировать и объединить все это дело. Вот тогда каюк. Вот тогда песец.
#239 #777539
>>777535
Это фронтенд.
А если ты про CMS, то плагины к ним пишут, внезапно, на PHP.
>>777545>>777554
#240 #777540
Блять, хочу поставить xdebug. Что для этого надо сделать? Поставить пхп и апач? ЧТо-то хуйня и у меня не работает. Еще гдето ебучий php.ini
>>777544>>777603
#241 #777544
>>777540

>Блять


>ЧТо-то хуйня


>ебучий


>гдето



Ещё один. Как вы вообще сюда просачиваетесь? Подобная манера общения напрочь отбивает желание помогать.

>>777514
Квалифицированный специалист будет востребован в любой области. На чём хочешь зарабатывать - то и выбирай для изучения.
>>777548>>777601
#242 #777545
>>777539
Внезапно все эти плагины уже написаны.
>>777851
#243 #777546
Надо вызвать из php js-скрипт, лежащий на локалке, передав в него данные для нескольких переменных.

Вообще ноль в этом вашем програмировании, прошу помочь
>>793703
#244 #777548
>>777544
Бонжур, сударь.
Благодарю за оказанную помощь.
Всех благ.

Regards.
#245 #777554
>>777539

>А если ты про CMS


А много ли вообще сайтов без CMS?
>>777851
#246 #777564
>>777535
Вот этого двачну. Лично я сейчас параллельно учу питон на всякий случай. Он мощный и мало чем отличается, плюс он будет куда более востребованным, ящитаю, со временем. К тому же простой оче, на нем что-то написать на выброс - как два пальца обоссать. Если питон не попрет, то нет проблем выучить какой-нибудь C#/Java, тем более зная синтаксис php.
JS не взлетит. Очень много костылей, очень мало tools для работы, они тоже костыльные, все приходится писать руками (js проходит ту же стадию, что пхп лет 10 назад). Короче, единственное, чего реально надо бояться - конструкторов сайтов. Алсо, JS не стоит трогать, т.к. это один большущий костыль.
#247 #777566
>>777564
Не очень вариант, ИМХО.
От питона к джаве довольно сложно, обычно наоборот. Питон ООЧЕНЬ упрощает проганье. Обычно советуют учить базу c/c++/java, а уже после переходить к другому.
Очень полезно понимать про указатели, байты, блокировки.
Сейчас набегут кукоретики, но это необходимо знать, если ты хочешь стать крутым профи.
>>777851
#248 #777567
>>777564
А, пардон, ты вообще сказал, что можно выучить джаву, зная пхп. Ну это довольно смешно, если честно.
>>777851
#249 #777569
Давайте флудить поменьше.

>>777344

Ой, это наверно не имеет отношения к треду и вообще мы тут не обсуждаем программы для постинга в соцети, доски объявлений и тд. Берите АПИ, читайте документацию и делайте как там написано.

>>777413

Не понял вопрос. Что значит "был в одной строке"? Советую все же изучить основы HTML и CSS.

>>777432

Ну сам подумай как ты можешь нормально писать код если в переменной $x у тебя может быть число, массив чисел, строка или объект? Да и к тому же это не полиморфизм по моему.

>>777445

Но у него не доктрина

>>777442

Да вручную проще сделать если там немного моделей.

>>777476

Посмотри тут, точно есть: https://github.com/codedokode/pasta/

>>777491

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

Толстые модели это в общем верно. Код в контроллере 1) нельзя повторно использовать 2) имеет доступ к слишком многим вещам. Мы хотим в идеале иметь какие-то функции с минимумом зависимостей и побочных эффектов, и в контроллере их нельзя сделать.

И я не очень понял про "если поменять логику". Вот у тебя допустим есть функция лайканья поста в модели addLike(Post $post, User $user). Ты можешь как угодно менять в ней логику, лишь бы она делала то, что написано в названии.

Правда в Yii своя атомсфера, они там исплоьзуют актив рекорд и у них очень много всего совмещено в одном классе модели - хранение данных, работа с БД, валидация, то что в других фреймворках разнесено по нескольким классам.
#249 #777569
Давайте флудить поменьше.

>>777344

Ой, это наверно не имеет отношения к треду и вообще мы тут не обсуждаем программы для постинга в соцети, доски объявлений и тд. Берите АПИ, читайте документацию и делайте как там написано.

>>777413

Не понял вопрос. Что значит "был в одной строке"? Советую все же изучить основы HTML и CSS.

>>777432

Ну сам подумай как ты можешь нормально писать код если в переменной $x у тебя может быть число, массив чисел, строка или объект? Да и к тому же это не полиморфизм по моему.

>>777445

Но у него не доктрина

>>777442

Да вручную проще сделать если там немного моделей.

>>777476

Посмотри тут, точно есть: https://github.com/codedokode/pasta/

>>777491

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

Толстые модели это в общем верно. Код в контроллере 1) нельзя повторно использовать 2) имеет доступ к слишком многим вещам. Мы хотим в идеале иметь какие-то функции с минимумом зависимостей и побочных эффектов, и в контроллере их нельзя сделать.

И я не очень понял про "если поменять логику". Вот у тебя допустим есть функция лайканья поста в модели addLike(Post $post, User $user). Ты можешь как угодно менять в ней логику, лишь бы она делала то, что написано в названии.

Правда в Yii своя атомсфера, они там исплоьзуют актив рекорд и у них очень много всего совмещено в одном классе модели - хранение данных, работа с БД, валидация, то что в других фреймворках разнесено по нескольким классам.
>>778200
#250 #777575
>>777514

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

Вот например статья, как стать веб-разработчиком: https://vc.ru/p/how-to-became-developer (при внимательном изучении можно увидеть что она скорее напоинает рекламу одного сайта).

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

- нет нормального ООП
- нет фреймворков
- нет ORM
- нет тайп хинтов
- нет нормальной поддержки windows

И монгу в которой:

- нет SQL
- нет транзакций
- нет согласованности и надежности
- нет поддержки windows (?)

--cut--

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

Отдельно хочу заметить что абсурдно новичкам, не понимающим ничего в архитектуре, давать ангуляр. Без полного понимания как он работает, получится гора неподдерживаемой лапши. Ангуляр не для начинающих. Как и SPA в общем. Не верите - почитайте мою задачу на СПА в ОП посте и подумайте, можете ли вы ее сделать.
#250 #777575
>>777514

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

Вот например статья, как стать веб-разработчиком: https://vc.ru/p/how-to-became-developer (при внимательном изучении можно увидеть что она скорее напоинает рекламу одного сайта).

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

- нет нормального ООП
- нет фреймворков
- нет ORM
- нет тайп хинтов
- нет нормальной поддержки windows

И монгу в которой:

- нет SQL
- нет транзакций
- нет согласованности и надежности
- нет поддержки windows (?)

--cut--

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

Отдельно хочу заметить что абсурдно новичкам, не понимающим ничего в архитектуре, давать ангуляр. Без полного понимания как он работает, получится гора неподдерживаемой лапши. Ангуляр не для начинающих. Как и SPA в общем. Не верите - почитайте мою задачу на СПА в ОП посте и подумайте, можете ли вы ее сделать.
#251 #777576
>>777575

Спам фильтр не пропустил абзац:

....

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

....
#252 #777579
Ага, методом исключения нашел не проходящие фильтр слова:

....key value с индексами - они ведь были и до SQL,....
>>777599
#253 #777583
>>777575

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


У них там всё так. Их статьи не стоит принимать близко к сердцу. Там поголовное большинство - непрофессионалы или люди, сорвавшие куш в своё время, а теперь вещающие, как правильно заниматься бизнесом, инвестировать (в их проекты или фонды) и так далее.
Эдакие Павлы Дуровы среднего пошиба, оказавшиеся в нужное время в нужном месте.
#254 #777584
>>777575
Так нет. Как ты думаешь, все ли сейчас так радужно, как было раньше? JS тот же вкатывается в backend. Питон с джавой рядом и тп.
>>777601>>777603
#255 #777598
А, хотел еще дать пример, характеризующий разработчиков на всех этих новомодных технологиях (gulp, grunt, webpack, нода).

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

Пример статьи: http://frontender.info/getting-started-with-gulp-2/ - тут и watch и livereload. Больше костылей богу костылей!

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

Бывают конечно случаи, когда это малореально, например, компилируемые/транспилируемые языки. даже тут гулп и грант подкладывают свинью: в отличие от make который придуман в 80-х годах и умееет перекомпилировать только измененные файлы, они перекомпилируют все файлы целиком. Если только вы не извернетесь и не найдете обходной путь.

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

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

А, еще нода плохо работает под виндой. Попробуйте найти библиотеку работы с xml. Она потребует libxml. Где взять libxml под виндоуз? для этого вам предлагают скачать и установить многогигабайтовый тяжеленный несвободный ужасный visual studio что-то там и мучаться с его настройкой. В отличие от них, для php многие модули под виндоуз доступны в виде готовой dll.

Выбирайте что вы хотите: качать тяжелый visual studio или получить dll которая идет в комплекте с пхп.

>>777514

> Особенно пугает JS с его идеей фулстак девелопмента, максимум асинхронности и всего такого



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

Вот кстати нашел пример сайта на ноде: https://github.com/iliakan/javascript-nodejs

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

> я. Особенно пугает JS с его идеей фулстак девелопмента, максимум асинхронности и всего такого.


> Ты-то перекатишься легко, а те, кого ты учишь?


А я запрещаю кому-то учить ноду? Задачи по JS у меня есть, а дальше сами доучите чего вам не хватает. Если хотите, можем еще задачи на сетевое программирование порешать и тд.
#255 #777598
А, хотел еще дать пример, характеризующий разработчиков на всех этих новомодных технологиях (gulp, grunt, webpack, нода).

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

Пример статьи: http://frontender.info/getting-started-with-gulp-2/ - тут и watch и livereload. Больше костылей богу костылей!

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

Бывают конечно случаи, когда это малореально, например, компилируемые/транспилируемые языки. даже тут гулп и грант подкладывают свинью: в отличие от make который придуман в 80-х годах и умееет перекомпилировать только измененные файлы, они перекомпилируют все файлы целиком. Если только вы не извернетесь и не найдете обходной путь.

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

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

А, еще нода плохо работает под виндой. Попробуйте найти библиотеку работы с xml. Она потребует libxml. Где взять libxml под виндоуз? для этого вам предлагают скачать и установить многогигабайтовый тяжеленный несвободный ужасный visual studio что-то там и мучаться с его настройкой. В отличие от них, для php многие модули под виндоуз доступны в виде готовой dll.

Выбирайте что вы хотите: качать тяжелый visual studio или получить dll которая идет в комплекте с пхп.

>>777514

> Особенно пугает JS с его идеей фулстак девелопмента, максимум асинхронности и всего такого



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

Вот кстати нашел пример сайта на ноде: https://github.com/iliakan/javascript-nodejs

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

> я. Особенно пугает JS с его идеей фулстак девелопмента, максимум асинхронности и всего такого.


> Ты-то перекатишься легко, а те, кого ты учишь?


А я запрещаю кому-то учить ноду? Задачи по JS у меня есть, а дальше сами доучите чего вам не хватает. Если хотите, можем еще задачи на сетевое программирование порешать и тд.
>>777606>>777655
#256 #777599
>>777579
До SQL только они и были. Модель CODASYL и до нее.
Только и они были с транзакциями, а не как в Монге и находили то что в базе есть, а не то ближе лежало - https://engineering.meteor.com/mongodb-queries-dont-always-return-all-matching-documents-654b6594a827#.s3ko3vfnx

Посмотрите ради любопытства когда транзакции появились в Оракеле - в какой его версии.
#257 #777601
>>777544

>Квалифицированный специалист будет востребован в любой области. На чём хочешь зарабатывать - то и выбирай для изучения.


Все очень относительно.
>>777575

> рекламирует ноду, в которой:


> И монгу в которой:


Тут скорее особенности. JS тот же позиционируется как язык для всего, в противовес чему PHP - "шаблонизатор для домашних страничек". Перспектив больше, направлений деятельности больше, приложения усилий. Ну и интегрированность. Типа "зачем учить какой-то там php и все равно учить javascript, если можно учить только последний и иметь при этом больше возможностей, не ограничиваясь бекэндом и веб-программированием вообще". Фреймворков для сети в js таки есть, не только голая нода.
>>777584
Вот, вопрос был и в этом. Меня очень пугает то, что я вижу здесь
http://www.tiobe.com/tiobe_index
или вот здесь
https://github.com/blog/2047-language-trends-on-github
Кроме того, за всем этим хайпам стоит js-движок гугла, а это значит, что перспектив у него уже больше, чем у "каких-то там" растов, го и питонов.
>>777610>>777617
#258 #777603
>>777535

Сконструируй мне вконтакте на нем. Эка новость, CMS были всегда, сколько я работаю в этой сфере.

>>777540

xdebug это модуль (расширение) php, так что без php ставить его нет смысла.

ты не написал даже какая у тебя ОС. Как тут помочь?

>>777584

Питон с джавой? Разве что как язык для вспомогательных скриптов для чистки репозитория.
>>777608>>777626
#259 #777606
>>777598

>Если хотите, можем еще задачи на сетевое программирование порешать и тд.


А было бы охуенно. Вообще, о разном.

Ты на стороне PHP идеологически и из-за его фишек, которые тебе субъективно кажутся удобнее, приятнее, или все-таки по коммерческим и прагматическим каким-то причинам? Есть же еще Python, Java - это уже не хипстота.
>>777613
#260 #777608
>>777603

>Питон с джавой? Разве что как язык для вспомогательных скриптов для чистки репозитория.


Подожди. Ну ладно еще Питон, хотя на нем сейчас много чего крутого делают, не только скрипты. Но Джава-то всегда была самым энтерпрайзным, самым серверным языком для самого хайлоада, она-то как же?
>>777611
#261 #777610
>>777601

JS не для начинающих и не для новичков.

Возьмем простые примеры файлов:

1) https://github.com/iliakan/javascript-nodejs/blob/master/gulpfile.js
2) https://github.com/iliakan/javascript-nodejs/blob/master/bin/server.js
3) https://github.com/iliakan/javascript-nodejs/blob/master/modules/application.js

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

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

Посмотри код. Ты уверен что он простой? Это не джейквери скрипт уровня $(..).click(() => $(...).hide());

Также, посмотрите структуру кода по ссылкам. Из-за отстутсивя нормального ООП код там представляет просто кучу функций, хаотично разбросанных по огромному количеству файлов. В Яве есть свои правила, в пхп есть PSR-4, а у них каждый пишет как хочет. Они действительно сейчас на том уровне, где пхп был 10 лет назад.

Я не представляю чем эта каша из функций, скобок и 100 кривых библиотек с гитхаба лучше пхп.
#262 #777611
>>777608

>Джава-то всегда была самым энтерпрайзным, самым серверным языком для самого хайлоада


И сейчас неплохо смотрится - undertow в особенности https://www.techempower.com/benchmarks/#section=data-r12
#263 #777613
>>777606

Прагматическим. Переход на другой язык требует тратить время (неоплачиваемое!) и силы и ничего не даст мне. У меня нет цели получить одобрение от завсегдатаев /pr или hacker news. У меня нет желания разбираться в горе кривых библиотек с гитхаба.

Плюс, в php у меня большой опыт, а на других платформах естественно я поначалу буду слоупочить. И это разумеется не может не отразиться отрицательно на доходе.
>>777621
#264 #777614
>>777610

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


Это близко к истие. Только был ли сравним PEAR тех времен с сегодняшними npm-репозиториями?

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


Тем же, чем она лучше и всего остального в сегодняшнем мире - нужно знать только один язык, и этого достаточно для всего (с React Native - совсем для всего)
#265 #777617
>>777601

Ну-ка, те, кто считает что нода простая, объясните хотя бы такой простой пример кода:

https://github.com/iliakan/javascript-nodejs/blob/master/modules/application.js#L50

waitBootAndListen(host, port) {
yield
this.waitBoot();

yield (callback) => {
this.server = this.listen(port, host, callback);
};

this.log.info('Server is listening %s:%d', host, port);
}

Зачем тут yield, да еще и несколько раз?
#266 #777618
>>777610

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


Хм. Но
https://ru.wikipedia.org/wiki/PHP#.D0.A4.D1.80.D0.B5.D0.B9.D0.BC.D0.B2.D0.BE.D1.80.D0.BA.D0.B8_.D0.B8_.D1.81.D0.B8.D1.81.D1.82.D0.B5.D0.BC.D1.8B_.D1.83.D0.BF.D1.80.D0.B0.D0.B2.D0.BB.D0.B5.D0.BD.D0.B8.D1.8F_.D1.81.D0.BE.D0.B4.D0.B5.D1.80.D0.B6.D0.B8.D0.BC.D1.8B.D0.BC
+ PEAR + API всяких Wordpress и не только их + всякие GD2, ImageMagiки...

>В пхп все просто: скрипт запустился, сгенерировал страницу, умер


Не накладывает ли это некоторых ограничений на, собственно, хайлоадную хуйню, асинхронную подгрузку инфы "в реальном времени", создании тех же SPA?
>>777625
#267 #777621
>>777610
>>777613
Сразу два дополнительный вопроса, которые ну невозможно не задать, хотя и неудобно:
сколько такой гуру как ты в среднем получает и сколько у такого займет перекат из одного стека технологий в другой при возникновении такой необходимости?
>>777624>>777629
#268 #777624
>>777621
$2-3

Месяц-два чтоб набрать среднюю скорость, еще два-четыре чтоб вкатиться по-настоящему
>>777634
#269 #777625
>>777618

Исплоьзование ноды само по себе не сделает твой сайт высокопроизводительным. Чтобы писать хайлоад сайты нужен такой багаж знаний который у нододетей вряд ли есть. То же касается СПА, если мы говорим про настоящие Single Page Application вроде того что в ОП посте а не хелло ворлд на ангулар, там нужен серьезный уровень знаний и широкий кругозор которого у нододетей нету. максимум они могут что-то сделать на готовом фреймворке вроде meteor при условии что задача лежит в рамках его ограничений и приложением пользуется не больше нескольких человек.
>>777630
#270 #777626
>>777603
Анон, пардон, не нашел в шапке о xdebug'e, это нужная вещь? Сам недавно начал совсем.
#271 #777629
>>777621

Сколько ты получаешь зависит (не только от уровня знаний, но и) от того, где ты работаешь. Потому спрашивать меня бесполезно - посмотри сайты вакансий и увидишь сколько и где ты (а не я) сможешь заработать. Можешь добавить некоторую надбавку из предположения что со временем, если ты хорошо справляешься, тебе будут периодически повышать зарплату, давать премии и тд (кстати премии - важная вещь, про них не пишут в вакансии, но в одних компаниях их раздают охотнее, а в других нет). Там, где можно больше зарабатывать, я работать не хочу. Я вообще работать не хочу так как это неинтересно и мне жалко тратить на это свое время.
>>777634
#272 #777630
>>777625
Это экосистема, порожденная венчурным капиталом. Задачи сделать что-то работоспособное чаще всего не стоит. Когда встает - зовут тех кому похер на чем делать хайлоад, хоть на Фортране (http://fortran.io lol), лишь бы платили хорошо и сдельно.
Все жители страны веченого детства мечтают запилить прототип, пойти к VC и получить лимон зелени. Или 10.
Весь LA забит wannabe-актерами, каждый официант "берет классы актерского мастерства". Все мечтают стать звездами. Звездами становятся единицы, но миллионы продолжают работать официантами и ходить по кастингам.
В южной калифорнии свои игры - в актеров, в северной свои - в цукербергов.
#273 #777634
>>777624

>$2-3


В России? Или это уровень аппворка?
>>777629
Какой ты правильный няша, еще и анончиков учишь. Хотел бы таким быть.
>>777636
#274 #777635
Или вот это - это читабельный, простой и понятный новичку код?

https://github.com/iliakan/javascript-nodejs/blob/master/modules/iprotect/index.js
>>777639>>777651
#275 #777636
Так. давайте сворачивать флуд не про программирование.

>>777634

Это видимо уровень макдональдса в котором работает автор того поста.
>>777639>>777641
#276 #777637
>>769611 (OP)
Можешь посоветовать бесплатный хостинг с php, чтобы не было лимитов по трафику и скорость более-менее? Плюс нужно, чтобы давал свой не совсем уебищный домен <25 уровня или хотя бы возможность прописать dns от какого-нибудь бесплатного. Под http-proxy, так что не в России. FTP доступ там, все дела. А еще хорошо, если какая-нибудь такая же впска будет, помню, были халявные балтийские, в Литве что ли. Там, естественно, лимиты уже будут, но хорошо, если будет рут по ссш и возможность накатить свой дистр. Это уже для тренировки.
>>793703
#277 #777639
>>777636

>Это видимо уровень макдональдса в котором работает автор того поста.


Я думаю, это имелось ввиду в тысячах долларов, выглядит реалистично.
>>777635
Ну тут тебя бы столкнуть с разбирающимся адептом этой самой ноды или питонщиком Получился бы интересный срач, а то так все хаят других перед новичками и обвиняют в этом друг друга.
208 Кб, 1521x690
#278 #777641
>>777636
В каком макдональдсе платят три К зелени? Адрес, телефон? Что спрашивают на собеседовании?

NodeJS захватывает энтерпрайз тем временем. На картинке - Netflix
https://blog.risingstack.com/node-js-examples-how-enterprises-use-node-in-2016/
#279 #777648
Sublime vs PHPStorm. И разумеется, почему? Нормальная ИДЕ вроде как помогает и ускоряет процесс, но не разучусь ли я программировать и не стану ли макакой? А Саблайм в связке со всякими иксдебагами вроде может и частично заменить шторм?
#280 #777651
>>777635
Новички внутрь ноды не лазят. И внутрь реакта. Оно для них магический черный ящик. Берут тьюториалы и ебошат, периодически бегая на StackOverflow с вопросами.
>>777658
#281 #777652
>>777648
Станешь. Бери Emacs.
>>783331
#282 #777653
>>777648
Попробуй сам и реши, что тебе удобней. Разработчик самого популярного PHP-фреймворка - Laravel - использует ST с плагинами. Вроде бы комплексная и навороченная система с огромной иерархией классов, тем не менее обходится без IDE.
#283 #777655
>>777575
>>777598
Браток, полегче. На hh 130 вакансий по ноде. Это столько же, сколько по ларавелю и симфони вместе взятым.
#284 #777658
>>777651

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

>>777641

У меня есть ощущение что это продиктовано не практическими соображениями, а личными предпочтениями или им просто скучно.
>>777661
#285 #777661
>>777658

>Если ты хочешь писать на ноде ты должен в этом разбираться


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

Они там отвечают на вопросы почему и зачем..
>>777672
#286 #777672
>>777661

>Они там отвечают на вопросы почему и зачем..


Язык для всего, самодостаточный язык, единство синтаксиса и семантики, реализация всего на свете в каком-нибудь очередном фреймворке, язык будущего, язык асинхрона.
>>777698>>777703
#287 #777698
>>777672
Не только.

> From the business perspective: the teams can reuse some of the modules and templates for example, and some of the libraries as well. It’s great from both the developers and from the managerial perspective.


> Also, Node has a noticeable effect on the positions and responsibilities of the engineers as well.


> Big companies like Capital One will definitely need pure back-end engineers for some of the projects in the future, but more and more teams employ ninjas who can do front-end, back-end, and a little bit of DevOps too - so the teams are becoming smaller.


> Instead of two teams, one is a pure back end, and one is a pure front end - consisting seven people overall - a ninja team of five can do both.


> “That removes a lot of overhead in communication because now you have fewer people, so you need fewer meetings, and you actually can focus more on the work, instead of just wasting your time.”



> Because of the way Node works we can attach debuggers, and set breakpoint steps through the code. If you wanted to debug these groovy scripts in the past, you would make some code changes upload it to the edge layer, run it, see if it breaks, make some more changes, upload it again, and so on.”


> It saves us tens of minutes to test, but the real testament to this project is: all of our engineers who are working on the clients are asking: when do we get to use this instead of the current stack? - told Yunong.

#288 #777703
>>777672

> I use node.js for a web backend. I'll provide the one and only one valid counterpoint to this otherwise correct set of articles


> The node.js ecosystem is full of incredibly well maintained modern stuff that lets you write a modern web app and ship it right now.


> My favorite example is passport.


> "npm install passport passport-twitter passport-facebook passport-google passport-local"


> hack for ten minutes


> Okay, now my site has both internal local authentication and OpenID authentication for the three most popular OpenID providers. I did not have to write a low-level OpenID provider myself and the learning curve was very shallow and easy.


> My users want Github?


>"npm install passport-github"


> hack for two minutes


> Okay, now they've got GitHub logins. Next!


> When I saw that stuff I picked node even though the language sucks.

#289 #777704
>>777610

>В пхп все просто: скрипт запустился, сгенерировал страницу, умер



Вы тут php.exe через CGI штоле запускаете на каждый реквест? Иначе это опасная иллюзия

> PHP seems like shared-nothing, but its default configuration actually cheats in a non-obvious way: It locks on session-data, so all requests with the same session-ID are forced to run sequentially on a server!


> If you change your session handler (such as to let sessions migrate between multiple hosts) or if you force-release the session early, sometimes you'll find many different symptoms of formerly-latent race-conditions bubbling up from your code. This is especially true if there are lots of AJAX requests, people double-clicking on buttons, many simultaneous tabs, etc.


> The sequencing is not a bad capability to have, but it's definitely worth deliberate decisions about where and how to apply it. Avoid sessions altogether? Store/update them differently? Even just closing them ASAP when you don't need to alter $_SESSION can make multi-request (AJAX, iframe) scenarios considerably more snappy.

#290 #777705
Краткое описание мира вечного детства и механизма всплывания говн

> Unfortunately, that's how things get popular, it seems. Someone makes something that only takes a few minutes to get going, past that you're on your own and it's riddled with bugs and unimplemented features. So people start implementing what's missing and fixing the bugs. And each generating more bugs for others to fix. Along the way, a thousand guys have had reason to put their name on github and write a blog post that gets pageranked. Of course, it's all built on shaky foundations and band-aids, but that's more reason for people to blog and debug and write books etc etc.


> Compare that with the situation where an expert puts a finished, mature, practically bug-free piece of perfection that leaves nothing for those guys to do. So many such great quality projects exist online that hardly anybody hears about.



И сравним с PHP

> Created in 1994 by Rasmus Lerdorf, the very first incarnation of PHP was a simple set of Common Gateway Interface (CGI) binaries written in the C programming language. Originally used for tracking visits to his online resume, he named the suite of scripts "Personal Home Page Tools"


> Early PHP was not intended to be a new programming language, and grew organically, with Lerdorf noting in retrospect: "I don’t know how to stop it, there was never any intent to write a programming language. I have absolutely no idea how to write a programming language, I just kept adding the next logical step on the way."

#291 #777722
Пыханы, есть один апач, на котором есть текстовый файл с инфой, который нужно прочитать и передать инфу на хтмл страницу. Пхп скрипт может это сделать или это делается какими то другими средствами? И если может, направьте плиз в сторону инфы, которую нужно почитать, чтобы написать такой скрипт. Сам то я быдлокожу на крестах и не силен в этом вашем вебе.
>>777725
#292 #777723
>>777641
Объяснение картинки - http://trimbo.blogspot.ru/2014/04/why-node-is-future-of-web-tier.html

tldr - frontend becomes more sophisticated and contains more logic, the Back End folks are no longer interested in writing a simple DAL/CRUD web-tier for Front End people to call into. That kind of work is a solved problem, and if the real interesting application logic lives in Javascript, it's no fun. Rather, they're more interested in working on scalable internal services and systems that the lightweight web tier can call back into and work on

Бэкенд остается нужен и никуда не денется (но в нем нет места PHP, там серьезные СУБД и серьезные сервисы)
Веб-бэкенд нафиг не нужен, потому что все чем он занимается с момента появления сложной логики в клиентском браузере - это бессмысленный пердолинг JSON-CRUD-ORM. С появлением GraphQL бессмысленность веб-бэкенда приблизилась к 100%.
>>777726>>777782
#293 #777725
>>777722
Просто открываешь файл с помощью PHP, записываешь его содержание в переменную и потом в этом же скрипте выводишь его пользователю. Странно что ты об этом не подумал, с основой на крестах-то.
Открыть файл можно с помощью fopen - http://php.net/manual/en/function.fopen.php
Как вывести переменную на экран средставми PHP я надеюсь ты знаешь.
>>777727
#294 #777726
>>777723
Вот демагогию развели. Сейчас даже на делфях что-то делают, а вы говорите пыха умрет. Лолирую с вас. Лет 10 минимум ещё живее всех живых будет. Можете скринить.
#295 #777727
>>777725
Про пхп я вообще ничего не знаю. Даже не представляю как хело ворлд написать. Видел только пару раз пхп скрипт в составе веб странички и всё. Но это же не серверная часть получается. Спасибо за ответ, буду читать.
#296 #777780
>>777641

>>В каком макдональдсе платят три К зелени? Адрес, телефон?


Поддвачну вопрос

>> Что спрашивают на собеседовании?


Пять врагов фритюра
>>777876
#297 #777782
>>777723

>Веб-бэкенд нафиг не нужен


Чё-т в голосяку!
Скажите это огромной куче сервисов, которые не могут существовать лишь в браузере пользователя.
Скажите это сайту, на котором мы все сейчас сидим.
Бэкенд не нужен, ahahaha, oh wow!..
>>777795>>777818
#298 #777788
>>769611 (OP)
Парни, кто-нибудь рубит в mysql?
У меня есть таблица, стоки которой каждую минуту обновляются.
1. Я удаляю все строки.
2. Я заполняю их новыми данными.

По сути там всего 3 строки, но существует промежуток времени (где-то секунда) в течение которого в таблице нет строки или 1 или 2. И эта секунда будет критичной, если клиент обратиться к базе в этот момент.
Есть какие-то пути исправления? Может есть какая-то возможность сначала заполнить, потом удалить? Хер знает. Помогите!
>>777822>>778152
#299 #777795
>>777782
Там же крупными буквами выделено, не нужен только веб-бэкенд, а не любой бэкенд.

Вечер. Едет автобус.
На первом сиденье сидят двое. У них коэффициент интеллекта (IQ) 180:
- Знаете, я вчера Гамлета в оригинале читал. Такое эстетическое наслаждение...
На другом сиденье сидят ещё двое. У них IQ=140:
- Я вчера посмотрел "Андалузского пса" и нашёл коррелят с ранними картинами Пикассо...
На другом сиденье сидят двое. У них IQ=100:
- Мы с другом час назад посмотрели "От заката до рассвета". Как там Т. говорит тёлке, что...
На другом сиденье сидят другие двое. У них IQ=80:
- Слышь, братуха! Помнишь, какое пойло мы в меpсе пили, когда ноги какой-то бляди торчали в окне...
А на задней площадке стоят двое с IQ=40:
- Ну вот, значит, компилю сорцы в студии...
>>777815
#300 #777799
ОП, привет. Я решил углубиться во фронт-енд и начал изучать js. Так вот, пишу Сапера. Возник вопрос: как открыть пустые клетки, как в виндовом Сапере?

И еще посмотри, пожалуйста, код, я стараюсь использовать ООП, но понимаю, что мне становиться тяжело читать код, а значит я что-то делаю неправильно.

https://jsfiddle.net/97rk90jp/
>>778083>>794739
#301 #777800
Ребят, а можно ли реализовать вот такое на php?
В общем я хочу сделать сервис, который бы сохранял фотографии с финдфейса. То есть я бы открыл финдфейс, задал запрос по фотке, получил страницы девушек, а сервис бы прошел по всем выданным результатам и сохранил все фотки с каждой странички.
Ну или как-нибудь по-другому с таким же эффектом. Желательно чтобы я мог запустить это на денвере и сохранять сразу на пеку.
>>777816
#302 #777815
>>777795

>не нужен только веб-бэкенд


У сервисов в сети какой бэкенд, во-Вашему, сударь? Веб-бэкенд или просто бэкенд?
Что вообще означает выражение "веб-бэкенд"? Есть сервер, на нём вся серверная часть хранится - это бэкенд и есть.
>>777819>>777824
#303 #777816
>>777800
Тебе нужно просто скачать картинки со страницы? Хватит скрипта на Simple HTML DOM и функции file_put_conents.
#304 #777818
>>777782

>сайту, на котором мы все


Он может.
Децентрализованные борды на джаваскрипте без бэкендов давно открыли.
#305 #777819
>>777815

>хранится - это бэкенд и есть


Правильно.
А веб- бэкенд - это то что между бэкендом и клиентом.
#306 #777822
>>777788
Ты делаешь неправильно всё.
Не знает поможет ли тебе это знание, думаю что нет.
>>778092
#307 #777824
>>777815
Веб - это когда исключительно для браузера. Согласен с аноном, что он не нужен. Нужно делать REST сервис, его можно юзать откуда угодно, хоть в игорях через TCP сокеты.
#308 #777832
date('F/j/Y',strtotime($timestamp_from_sql));

Это единственный верный способ переформатировать результат таймстемпа из базы?
>>777835
#309 #777835
>>777859
#310 #777851
>>777514
Вообще покачто PHP top1 на всех биржах вакансий/фриланса.
Ну а в целом, перекат с языка на язык, дело не самое сложное

>>777545
Все сайты уже написаны, закрывайте тред.

>>777535
Если уж на цмс стараются не писать сайты, то про это вообще лучше не говорить
>>777554
Ни одна из существующий массовых ЦМС не удовлетворяет потребностей крупных заказчиков и серьезных проектов.
Да считай у всех пишущих на фреймфорках есть свои ЦМСки, но это как правило более гибкие и менее монструозные вещи чем всякие ВордПрессы
>>777566
>>777564
>>777567
Важно понят основы программирования и построение алгоритмов в целом, базовые патерны и приемы.
Умные люди говорили что у ТРУъ прогера перекат на язык может занять всего день(понятное дело не до уровня сенйора-помидора)
Но вообще когда хорошо освоишься в одном языке, даже в ПХП, то понимаешь что можно писать на чем угодно открыв документацию и стек оверфлоу, все осваивается быстрее.
Чем тогда когда ты учился делать циклы и классы первый раз в жизни.
#311 #777859
>>777835
Помогает избежать не красивой на вид конвертации число-строка-туда-сюда.
Но суть все же одна, чертов MySql, решайт за меня как timestamp показать, а мне ебись
>>777865
#312 #777865
>>777859
Ты скажи мускуэлу что тебе надо, он тебе как надо и выдаст.
суп пхп инженеры #313 #777874
Рейтаните решение задачи http://ideone.com/FemCIe
если полная хуйня - намекните как надо было сделать.

Кстати, какие еще есть способы вставить пробел между рандомными элементами массивов, помимо ," ",?
#314 #777876
>>777780
Про фритюр достаточно знать что
- масло не выкипает и не выгорает, строго говоря
- выкипает вода
- в масле окисление идет (в нем много ненасыщенных связей). Обычно окисление начинается после выкипания воды.
- чтобы масло не менять неделями, оно должно не окисляться. для этого оно должно быть насыщенное
- насыщенные масла считаются обывателями вредными, поэтому приходится идти на разные изъебства (http://www.newyorker.com/magazine/2001/03/05/the-trouble-with-fries)
>>777879
#315 #777879
>>777876
Все это относится к растительному маслу, с животным все иначе, там низкий процент ненасыщенных связей, и поэтому окисление медленное. Если жарят не на сковородке, а в масле, то обязательно, так масло остается при высокой температуре долгое время, к тому же быстро загрязняется. Классические макдональдовские картошки были на https://en.wikipedia.org/wiki/Tallow но пали в борьбе роковой еще в 1983-м году http://www.westonaprice.org/know-your-fats/the-oiling-of-america/
Сейчас там гидрогенизированные растительные масла + полидиметилсилоксаны, чтобы масло не пенилось https://en.wikipedia.org/wiki/Polydimethylsiloxane#Foods
#316 #777953
>>777874
Я бы юзал просто rand() и count() если нужно;
Или shuffle().

Но это на любителя.

Обеденить потом можно через implode или array_map
#317 #778029
Привет анон, вот зная HTML CSS, хочу начать изучать PHP. Соль в том, что я не знаю по каким книгам ( учу онли по печатным книгам , сайты и пдф книги вертел на хую) . Подскажи анон, какую книгу начать изучать для слоупока?
>>778069>>794740
#318 #778069
>>778029
Учебник ОПа
#319 #778083
>>777799
Немножко поправил. https://jsfiddle.net/mayzx8qt/
>>794739
#320 #778092
>>777822
Это не знание, а мнение... анонима... с двача.
#321 #778117
Какие есть готовые функции поиска по массиву по нестандартным параметрам (с помощью пользовательской функции), кроме array_filter ?
>>778500
#322 #778133
>>777874

>echo $word1[$randWord1[0]]," ", $word2[$randWord2[0]]," ",$word3[$randWord3[0]],"\n";


>echo $word1[$randWord1[1]]," ", $word2[$randWord2[1]]," ",$word3[$randWord3[1]],"\n";


По сути, это повторяется. Тут можно было бы одинаковую строку два раза в цикле с for ($i = 0; $i < 2; $i++) повторить, а потом вывести третью строку.
Ну и все эти
$randWord1 = array_rand($word1, 2);
$randWord2 = array_rand($word2, 2);
$randWord3 = array_rand($word3, 2);
$randWord4 = array_rand($word4, 1);
$randWord5 = array_rand($word5, 1);
- тоже впечатление громоздкости создают.
Задача в целом решена верно, но ты подходишь к такому этапу, когда нужно стремиться сделать максимально лаконично, без лишних телодвижений и повторений кусков кода.
#323 #778144
ОПчик, а вот твоя паста про паттерны. В частности, паттерн Data Mapper:
<?php
class NewsMapper
{
/ Загружает модель из базы имея $id */
public function getById($id) { ... }
}

А что по идее должен вернуть метод getById ?
Объект класса News по логике?
>>778146
#324 #778146
>>778144
Объкт класса News, у которого id равен $id параметра функции.
>>778179>>778188
#325 #778152
>>777788

Транзакции.
>>778651
#326 #778160
Объясните как в ideon видеть где конкретно ошибка в коде?
>>778161
#327 #778161
>>778160
Обновить страницу полностью, нажав F5, будет там в самом низу список.
>>778165
#328 #778164
>>777874
Лучше форкай прежний код, чтобы братишки видели, к чему относился твой предыдущий вопрос, как код изначально выглядел.
Ну и вот тебе в помощь:
shuffle($word1);
shuffle($word2);
shuffle($word3);
shuffle($word4);
shuffle($word5);
Хотя, я думаю, ты и так догадался.
>>778650
#329 #778165
>>778161
Ничего совсем. Если у тебя есть время мб скинешь скриншот?
>>778167
#330 #778167
>>778165
Дай ссылку на свой код.
Просто нажать на F5 - и всё.
Может, у тебя просто ошибок там нет или ты не поставил error_reporting(-1); в самом начале кода.
>>778184
#331 #778179
>>778146
збс, понял
#332 #778184
>>778167
Спасибо анон,но я решил самому сделать и получилось. Алсо ф5 не работает
>>778185
#333 #778185
>>778184
Как так не работает простое обновление страницы в браузере?..
>>778186
#334 #778186
>>778185
Я про то что нет инфы где именно в коде ошибка.
#335 #778188
>>778146
/ Сохраняет данные из модели в базу, делая UPDATE или INSERT запрос */
public function save(News $news) { ... }

А как метод должен определить, UPDATE или INSERT запрос делать?
>>778190
#336 #778190
>>778188
По тому, заполнено ли поле id у объекта студента.
>>778208
#337 #778192
Пагни, есть одна функция.
public function getStudents($limit, $offset, $sort, $order) {
$pdoStatement = $this->pdo->prepare("SELECT FROM students ORDER BY :sort :order LIMIT :limit OFFSET :offset");
$pdoStatement->bindValue(":limit", intval($limit, 10), PDO::PARAM_INT);
$pdoStatement->bindValue(":offset", intval($offset, 10), PDO::PARAM_INT);
$pdoStatement->bindValue(":sort", $sort);
$pdoStatement->bindValue(":order", $order);
$pdoStatement->execute();
/
$pdoStatement = $this->pdo->query($statement);
return $pdoStatement;
}
Оно выдает неотсортированый результат, где я недобиндил? Осло, если подставить все значения в запрос вручную то все все прекрасно сортируется. Все аргументы в функцию заходят.
>>778195>>778201
#338 #778195
>>778192
Криво скопировал блин.

public function getStudents($limit, $offset, $sort, $order) {
$pdoStatement = $this->pdo->prepare("SELECT * FROM students ORDER BY :sort :order LIMIT :limit OFFSET :offset");
$pdoStatement->bindValue(":limit", intval($limit, 10), PDO::PARAM_INT);
$pdoStatement->bindValue(":offset", intval($offset, 10), PDO::PARAM_INT);
$pdoStatement->bindValue(":sort", $sort);
$pdoStatement->bindValue(":order", $order);
$pdoStatement->execute();
return $pdoStatement;
}
>>778204
#339 #778200
>>777569

>Но у него не доктрина


А какая проблема поставить её?
#340 #778201
>>778192

При подстановке через :sort подставляется не имя поля, а строка и получается

ORDER BY 'name' (взять указанную строку) вместо BY name (взять значение поля)

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

имена полей нельзя вставлять через плейсхолдер, только через переменную с проверкой по списку.
>>778210
#341 #778204
>>778195
Алсо у тебя метод получитьСтудентов возвращает не студентов, а какой-то pdoStatement. Написано же в названии, что возвращает студентов, так вот пусть студентов и возвращает.
>>778210
#342 #778205
http://ideone.com/IXqHnc //антикризисные меры

ОП, как всегда исправил большинство, кроме

>>class Manager extends Profession


>> protected $salaryRate = 500; // базовая ставка


>> public function getProduct()


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


>Разве не логично для всех 3 полей сделать абстр. методы? Чтобы гарантированно


>не забыли их переопределить?


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

>> // Если сотрудник соответствует профессии


>> if ($employee->getProfession()->getName() == $profession) {


>Если у тебя профессия - это объект, может логично передавать для поиска не >название, а этот объект?


>Или хотя бы сделать константы для обозначений профессий.


Тогда нужно где-то хранить объекты профессии, чтобы потом их передать в качестве аргументов. А про константы не понятно, их нужно будет создавать в начале программы, а где гарантия, что при создании новой профессии программист создаст новую константу? А если объявлять константу внутри класса профессии, то какой тогда в этом смысл, если можно использовать названия класса? Корректно ли использовать такую конструкцию в качестве аргумента $departament->findEmployees(get_class (new Analyst)); ?

>> // Если таковых нет, переходим к следующему департаменту


>> if (!$analysts) continue;


>В общем-то эта строка не нужна.


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

>> // Назначаем Аналитика шефом


>> $analyst->setСhief(1);


>> // Снимаем с должности текущего шефа


>> $chiefEmployee->setСhief(0);


>Это явно нарушение инкапсуляции. Разве замена босса - это не задача департамента?


Почему это ошибка именно инкапсуляции, а не логики?
Я переделал, теперь метод смены работника в департаменте, которому аргументом передают работника, который если есть в депе получает статус шефа. Но деп все также обращается к методу Employee->setСhief(0); Я исправил ошибку?
#342 #778205
http://ideone.com/IXqHnc //антикризисные меры

ОП, как всегда исправил большинство, кроме

>>class Manager extends Profession


>> protected $salaryRate = 500; // базовая ставка


>> public function getProduct()


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


>Разве не логично для всех 3 полей сделать абстр. методы? Чтобы гарантированно


>не забыли их переопределить?


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

>> // Если сотрудник соответствует профессии


>> if ($employee->getProfession()->getName() == $profession) {


>Если у тебя профессия - это объект, может логично передавать для поиска не >название, а этот объект?


>Или хотя бы сделать константы для обозначений профессий.


Тогда нужно где-то хранить объекты профессии, чтобы потом их передать в качестве аргументов. А про константы не понятно, их нужно будет создавать в начале программы, а где гарантия, что при создании новой профессии программист создаст новую константу? А если объявлять константу внутри класса профессии, то какой тогда в этом смысл, если можно использовать названия класса? Корректно ли использовать такую конструкцию в качестве аргумента $departament->findEmployees(get_class (new Analyst)); ?

>> // Если таковых нет, переходим к следующему департаменту


>> if (!$analysts) continue;


>В общем-то эта строка не нужна.


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

>> // Назначаем Аналитика шефом


>> $analyst->setСhief(1);


>> // Снимаем с должности текущего шефа


>> $chiefEmployee->setСhief(0);


>Это явно нарушение инкапсуляции. Разве замена босса - это не задача департамента?


Почему это ошибка именно инкапсуляции, а не логики?
Я переделал, теперь метод смены работника в департаменте, которому аргументом передают работника, который если есть в депе получает статус шефа. Но деп все также обращается к методу Employee->setСhief(0); Я исправил ошибку?
>>794740
#343 #778208
>>778190
чотко!
#344 #778210
>>778201
Спасибо.
>>778204
Не согласен. Наоборот видно что отдается объект pdostatement а не что-то другое.
>>778239>>778342
#345 #778217
Вот еще пример того как "просто" программировать на яваскрипт: https://m.habrahabr.ru/company/tcsbank/blog/303580/

Такое ощущение что они сами себе создают проблемы и сами же их решают. Давно придуман MVC, а они вместо этого занимаются ерундой.
#346 #778221
Я (>>773211) тут случайно "chmod -R 755 /", переустановил ось, поставил всё заново, но теперь не могу запустить сайт, выдаёт 403 ошибку

>>>You don't have permission to access / on this server.


Папки, файлы /var/www с 777 правами, владелец www-data; в апаче.конф:

><Directory /var/www/>


> Options Indexes FollowSymLinks


> AllowOverride All


> Require all granted


></Directory>


в файле настройки сайта: "*:80"
Что делать?
>>778245>>778247
#347 #778223
>>776112
Single Page Application
#348 #778224
Оп, стоит ли изучать laravel, если я знаю на достаточном уровне yii2? При условии, что это только для себя.

Есть ли плюсы в нём? Многие хвалят, а я документацию посмотрел и мне не очень нравится этот код (Хотя может я просто толком не разобрался)

Ещё нужно изучить симфони, но из-за него я получил травму неокрепшей, тогда ещё, психики. Ломанулся, ели освоим пхп и больно получил по носу.
>>778347
#349 #778239
>>778210

> Наоборот видно что отдается объект pdostatement


Откуда видно? Из названия метода getStudents видно, что отдаётся pdoStatement?
Несоответствием названия метода и возвращаемого значения ты обманываешь программиста, который будет в этом коде разбираться. Странно, что такие вещи приходится объяснять.
>>778342
#350 #778245
>>778221
Лёл, весь день ебался с этой фигнёй, оказалось в скопированном конфиге путь был /home/user/server/, а не /var/www
#351 #778247
>>778221

> "chmod -R 755 /", переустановил ось


> /var/www с 777 правами



Это комбо. Ты можешь поставить линукс, но так и останешься с мышлением виндузятника на всю жизнь.
>>778248
#352 #778248
>>778247
755 - проебался, сразу же понял, но было поздно.
777 - а что еще делать, если ничего не помогает?
>>778315
#353 #778315
>>778248

>что еще делать, если ничего не помогает?


Ознакомиться с документацией, выяснить причину проблемы, устранить ее, понять как не повторять впредь.
Так до интернетов еще делали - работало.
>>778331
#354 #778331
>>778315
Что неясного в "ничего не помогает"? Очевидно, что несколько инструкций по установке сервера было прочитано, очевидно что вопросы гуглу по поводу проблемы были заданы. Может ты предлагаешь все доки по апачу прочитать?
Нормальная система пытается минимизировать свою работу, максимизировать результат. Я бы мог потратить несколько часов в поисках и изучению доков о необходимых правах, а мог бы за минуту дать полные права и посмотреть - исправилась ли ситуация. Если ты делаешь наоборот - ты странный. А еще ты странный, ибо приёбываешься к пустякам.
В данном же случае, мне не помогло бы и знание всех доков в мире, ибо тут проблема была в невнимательности.
#355 #778334
>>778331
Я мимокрокодил, но судя по тому, что ты пишешь, тебе не стоит заниматься программированием.
>>778336>>778347
#356 #778336
>>778334
Ваше мнение очень важно для нас.
>>778343
#357 #778342
>>778239
>>778210

Одна из идей ООП это Single Responsibility, то есть когда у каждого класса своя задача. Как в организации: бухгалтер отвечает за отчеты, а кладовщик - за содержимое склада. Когда кто-то просит у кладовщика выдать ему товар, он не говорит тому, где его искать - это забота кладовщика. И когда руководителю нужен отчет о расходах, он не объясняет бухгалтеру как его составлять.

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

Когда ты отдаешь наружу объект pdoStatement ты нарушаешь этот принцип. Вся работа с PDO должна быть в Table fata gateway и наружу никакие объкты PDO отдаваться не должны. Получается в твоем классе кладовщик просто открывает двери склада и говорит: "а, иди вот там сам в углу поищи". Согласись, при таком подходе появляется вопрос, а зачем этот кладовщик вообще нужен.

Метод getStudents/getStudent должен возвращать модель студента или например массив таких моделей. А не предлагать самому поискать их в базе данных. Это его ответственность сохранять и загружать эти модели из базы данных.
>>778344
#358 #778343
>>778336
Я не оскорбляю тебя, я просто говорю, что, возможно, стоит заняться чем-то другим.
Так как в программировании постоянное чтение документации это одна из главных составляющих обучения и работы.
А ты считаешь чтение доков к апачу каким-то нонсенсом.
>>778351
#359 #778344
>>778342
Ты так красиво говоришь.
#360 #778347
>>778331

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



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

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

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

>>778334

Не надо так.

>>778224

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

>>776112

Аяксом загружается нужная страница и заменяется часть дерева DOM. Никакого СПА там нет в помине.
>>778351
#361 #778351
>>778343
>>778347
Если бы мне сказали, что файл не найден - я бы искал ошибки в путях;
Мне же сказали, что доступ запрещён - очевидное решение - дать доступ.
Где тут отсутствие анализа и слепой перебор?

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


Ты сначала изучаешь в подробностях доки, а только потом пишешь хеллоуворд, или наоборот? Я же даже до хеллоуворда не дошёл.
>>778371
#362 #778358
Поставил себе ide notepad++, выглядит клево
Некто не знает как из нее запустить код на похапе?
>>778371
#363 #778371
>>778351

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

>>778358

Это не иде, а текстовый редактор. Запустить пхп скрипт можно из командной строки, гайд по ней в ОП посте.
>>778373
#364 #778373
>>778371

> доступ запрещён - очевидное решение - дать доступ.

>>778398
#365 #778398
>>778373
Есть некоторая вероятность, что доступ запрещен не просто так, а с какой-то целью.
Так что очевидным было бы подумать, зачем выставлены такие права на служебные папки, и что произойдет на рабочем сервере при получении общего доступа.
>>778406
#366 #778406
>>778398
Или изначально у этих папок были одни права, а для работы веб-сервера нужны другие права, что более очевидней.
>>778445
#367 #778445
>>778406
Подумать почему у них были изначально другие права? Вдруг эти права были выбраны не бросанием кубиков от нечего делать?
>>778452
#368 #778446
>>778331

>Что неясного в "ничего не помогает"?


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



Формулировка неверна. Не "Ничего не помогает", а "ничего не помогает без включения головы, а голову я включать не хочу, хочу только перебирать пошаговые инструкции для макак, пока какая-то из них не заработает, не понимая что в них написано".
>>778452
#369 #778452
>>778446
Тебе-то виднее, что я делал.
>>778445
Например, эти права были выбраны из соображения нужд линукса, который о апаче ничего не знает.
>>778459
#370 #778455
ОП, проверь пожалуйста.
https://github.com/never3ver/students_list
В свое оправдание могу сказать только то, что оно таки работает.
>>794742
#371 #778459
>>778452

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


Ты Линупс из LFS собирал? Непохоже.
А дистрибутивы Линупса об Апаче знают.
>>778576
#372 #778500
>>778575
#373 #778575
>>778500

>map


имеешь ввиду array_map?
>>778705
#374 #778576
>>778459

>3-й день на Линукс


Конечно собирал, конечно знаю!
#375 #778650
>>778164
благодарю. да, по шафлам я понял.
по форку я догадался чуть позже, но было уже поздно.
#376 #778651
>>778152
Спасибо.
20 Кб, 510x357
#377 #778654

> Цель поиска работы


> Неправильно: Работа в перспективной компании с возможностью развития, самореализации и работы на благо компании.


> Правильно: хочу найти работу



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

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

Может ну их, эти ссайты поиска работы, взять список айти-компаний и заспамить им почту своим резюме? Хочется пойти в обход этой бюрократии.
>>778903
#378 #778678
Сделал вот так задачу на палиндром http://ideone.com/Cj94h7

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

btw, оглашать две переменные в действии1\менять их в действии2 это плохо ?
ака for($i = 0, $x = 0;$i <= 123;$i++, $x++){}
>>794743
#379 #778705
#380 #778794
#381 #778812
>>778794
какого то хрена выводится то, что я убрал.
вот тот же самый код по другой ссылке http://ideone.com/Liri3Q
внезапно нагавнокодил решение за меньше строк, чем у ОПа. где мой фейл ?
>>794743
#382 #778817
>>778794

>$i <666


Плохая попытка, ацкий сотона.
Плохой ориентир для работы цикла.
В подобных циклах лучше ориентироваться на сумму кредита: когда она становится равной нулю - прекращать цикл.
Так надёжнее да и просто логичнее.
#383 #778903
>>778654
Что за говно на пикрелейтеде? Выложи своё резюме на hh.ru. Я так сделал, два раза даже мне первому написали (правда в итоге не взяли никуда), остальное время я сам оставлял заявки на работу.
#384 #778912
test
#385 #778913
ffffffff
#386 #779119
Поступил на программиста, ради бумажки. Сам начинаю дома задрачивать круглыми сутками кодинг. Вопрос - куда лучше податься - пхп или иос?
>>779165
#387 #779147
Как из php получать поисковые результаты гугла (чтобы не забанили)?
Достаточно ли подсунуть курлу/газзлу useragent, или не проканает?
(Апи платный)
>>779246
#388 #779165
>>779119
В ислам подайся, жить будучи тупым похапешником радости мало
>>779219
1868 Кб, Webm
#389 #779211
https://colorcodedlyrics.com/2012/08/crayon-pop-bing-bing
Почему box-shadow перестает работать?
>>779213
#390 #779213
>>779211

Не понял. Что значит "перестает работать"? Если ты про тень у большого блока, в котором находится страница, то она не исчезает. Может у тебя просто на мониторе яркость перекручена? Попробуй сделать очень контрастную тень и проверить снова.
>>779227
#391 #779219
>>779165
На других языках работы в сраной и нет.
#392 #779227
>>779213
Ты оказался прав. Контрастная тень отображается. Но как же тогда тень видна на темном фоне? Очень интересный эффект.
>>779236
#393 #779228
как у пыхи с песпективами поясните?
>>779231
#394 #779231
>>779228
Отсутствуют. Изучай NodeJS.
>>779233
#395 #779233
>>779231
На пхп в россии еще внуки наших внуков будут писать.
>>779234>>779235
#396 #779234
>>779233
Delphi изучай. На ней тут пишут до сих пор.
10 сообщений только за вчерашний день http://www.sql.ru/forum/delphi
#397 #779235
>>779233

>программирование


>внуки

#398 #779236
>>779227

У тебя проблемы с настройкой монитора. Погугли lcd monitor test и проверь сам.
#399 #779246
>>779147
ЛОЛ, мне однажды какие-то клоуны такое "тестовое задание" дали - типа надо написать скрипт, который будет к заглавной странице гугла посылать запросы, потом парсить ответ и извлекать из него полезные данные.

И примечание внизу - АПИ использовать нельзя.

Тогда я нифига не понял прикола (но задание делать не стал, к счастью). А оно вот оно что - АПИ, оказывается-то платное!

Анон, будь бдителен, не делай хитрожопым мудакам работы, которую они под видом тестовых заданий подсовывают
>>779330
Ответил в старом треде #400 #779256
Прошелся по неотвеченным постам и ответил в старом треде. зайдите, гляньте, может как раз на ваш вопрос ответил. Если я пропустил кого-то - напомните о себе в этом, новом, треде.

>>779251 Почему % делит неправильно большие числа, задача про номера телефонов, не могу запустить пхп под виндой, где почитать про работу с формами и базой, оптимизация сайта джейсоном

>>779252Поиск опечаток, $mapper->getTimers(), игра в кубики

>>779253 Ответы по https://github.com/someApprentice/Students

>>779254Где поичтать про ООП, про mysqli

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

Ответьте-ка, ваши задачи проверять надо? Как у вас дела с решением?

>>762502 https://github.com/foobar1643/filehosting
>>771145 https://github.com/TheSidSpears/Students

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

Напомню себе проверить позже:

>>774244

Вектор http://ideone.com/H5DCfT
Набросок Кошек-Мышек http://ideone.com/f1aQaw

>>774967 https://github.com/applejacky/students
Ответил в старом треде #400 #779256
Прошелся по неотвеченным постам и ответил в старом треде. зайдите, гляньте, может как раз на ваш вопрос ответил. Если я пропустил кого-то - напомните о себе в этом, новом, треде.

>>779251 Почему % делит неправильно большие числа, задача про номера телефонов, не могу запустить пхп под виндой, где почитать про работу с формами и базой, оптимизация сайта джейсоном

>>779252Поиск опечаток, $mapper->getTimers(), игра в кубики

>>779253 Ответы по https://github.com/someApprentice/Students

>>779254Где поичтать про ООП, про mysqli

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

Ответьте-ка, ваши задачи проверять надо? Как у вас дела с решением?

>>762502 https://github.com/foobar1643/filehosting
>>771145 https://github.com/TheSidSpears/Students

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

Напомню себе проверить позже:

>>774244

Вектор http://ideone.com/H5DCfT
Набросок Кошек-Мышек http://ideone.com/f1aQaw

>>774967 https://github.com/applejacky/students
#401 #779258
>>779256

>Ответьте-ка, ваши задачи проверять надо? Как у вас дела с решением?


>https://github.com/foobar1643/filehosting


Мою пока нет, я замечания исправил, доделаю юнит-тесты и залью всё одним коммитом.

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

>comment.text = comment.text.replace(/</g, "<").replace(/>/g, ">");

>>779260>>779262
#402 #779260
>>779258

>comment.text.replace(/</g, "& lt ;").replace(/>/g, "& gt ;");


Быстрофикс (в реальном варианте без пробелов, конечно).
>>779262
#403 #779261
Отдельный пост для https://github.com/someApprentice/Students

Я там в прошлом треде пропустил твой важный пост с вопросами и сразу не ответил, вот тут вот написал ответ >>779253

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

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

-----------

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

Стена кода это плохо. Человек в общем не способен воспринимать большие стены кода и ему надо разбивать их на относительно небольшие и законченные функции которые можно рассматривать по отдельности. Разумное ограничение - 1-2 экрана кода (30-50 строк) максимум. Некоторые считают что функция должна помещаться в распечатанном виде на листе A4, некоторые - что должна помещаться на экране без прокрутки.

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

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

-----------

Далее, классы. Есть принцип "единой ответственности" - каждый класс отвечает за свою часть задачи. Нормально для каждой новой задачи делать новый класс.

Нам нужно как-то хранить и передавать информацию о студенте - делаем модель Student
Нам нужно выполнять запросы к БД - берем готовый класс PDO
Нам нужно сохранять и загружать студента из БД - делаем маппер или Table Gateway. Будет у нас какая-то другая сущность и другая таблица в БД - сделаем для нее свой, отдельный маппер.
Нам нужно проверять правильно ли заполнена информация о студенте - делаем валидатор
Нам нужно хранить и обрабатывать данные формы регистрации - делаем класс соответствующий форме
Нам нужно сделать авторизацию, залогинивание/разлогинивание - делаем класс авторизации

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

Разумное ограничение - до 500-1000 строк в классе. Если больше - пора разбивать.

Бывает, что функцию некуда отнести. Например функция перевода байт в гигабайты. Не делать же ради нее отдельный класс ПереводчикБайтВГигабайты. Делаем класс Util или Helper и пихаем туда такие функции статическим методом.

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

Например объект PDO это "сервис" для выполнения запросов к базе данных. Модель студента - "сущность".

-----------

Далее, у классов есть зависимости. Мапперу нужен объект PDO, валидатору нужен маппер. Решаем эту проблему с помощью dependency injection. Если ты читал урок по нему, то этот способ имеет определеные преимущества.

-----------

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

Например:

- контроллер вызывает сервис валидации для проверки данных в форме
- сервис валидации использует маппер чтобы проверить уникальность email
- маппер использует PDO чтобы выполнять запросы

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

Вот можно тут почитать пример: https://habrahabr.ru/post/257677/

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

-----------

Далее, MVC. MVC подсказывает нам как именно можно

Тут идея в том, что мы разбиваем обработчик запроса пользователя на 3 части: Модель, Контроллер, Вид (представление)

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

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

Контроллер управляет процессом обработки запроса от пользователя. Он анализирует запрос пользователя (например смотрит, указано ли слово для поиска по студентам или нет), затем вызывает модель чтобы получить данные или выполнить какие-то действия над ними, затем вызывает вид чтобы отобразить страницу пользователю (или делает редирект, это не принципиально).

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

Например мы можем сделать консольную программу, выводящую список студентов в консолью Эта программа сможет повторно использовать маппер, чтобы получить список студентов, а вот вывод его - делает самостоятельно. Если бы у нас не было разделения на МВЦ, то нам пришлось бы копипастить код выборки и поиска студентов из БД.

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

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

Чем является хелпер авторизации? Очевидно что это не модель, так как модель не управляет куками и не взаимодействует с пользователем (точнее с его браузером). Очеивдно что в консоли никаких кук нет, куки есть только при взаимодействии с браузером. Значит это не часть модели.

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

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

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

Теперь задавай свои вопросы.
#403 #779261
Отдельный пост для https://github.com/someApprentice/Students

Я там в прошлом треде пропустил твой важный пост с вопросами и сразу не ответил, вот тут вот написал ответ >>779253

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

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

-----------

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

Стена кода это плохо. Человек в общем не способен воспринимать большие стены кода и ему надо разбивать их на относительно небольшие и законченные функции которые можно рассматривать по отдельности. Разумное ограничение - 1-2 экрана кода (30-50 строк) максимум. Некоторые считают что функция должна помещаться в распечатанном виде на листе A4, некоторые - что должна помещаться на экране без прокрутки.

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

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

-----------

Далее, классы. Есть принцип "единой ответственности" - каждый класс отвечает за свою часть задачи. Нормально для каждой новой задачи делать новый класс.

Нам нужно как-то хранить и передавать информацию о студенте - делаем модель Student
Нам нужно выполнять запросы к БД - берем готовый класс PDO
Нам нужно сохранять и загружать студента из БД - делаем маппер или Table Gateway. Будет у нас какая-то другая сущность и другая таблица в БД - сделаем для нее свой, отдельный маппер.
Нам нужно проверять правильно ли заполнена информация о студенте - делаем валидатор
Нам нужно хранить и обрабатывать данные формы регистрации - делаем класс соответствующий форме
Нам нужно сделать авторизацию, залогинивание/разлогинивание - делаем класс авторизации

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

Разумное ограничение - до 500-1000 строк в классе. Если больше - пора разбивать.

Бывает, что функцию некуда отнести. Например функция перевода байт в гигабайты. Не делать же ради нее отдельный класс ПереводчикБайтВГигабайты. Делаем класс Util или Helper и пихаем туда такие функции статическим методом.

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

Например объект PDO это "сервис" для выполнения запросов к базе данных. Модель студента - "сущность".

-----------

Далее, у классов есть зависимости. Мапперу нужен объект PDO, валидатору нужен маппер. Решаем эту проблему с помощью dependency injection. Если ты читал урок по нему, то этот способ имеет определеные преимущества.

-----------

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

Например:

- контроллер вызывает сервис валидации для проверки данных в форме
- сервис валидации использует маппер чтобы проверить уникальность email
- маппер использует PDO чтобы выполнять запросы

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

Вот можно тут почитать пример: https://habrahabr.ru/post/257677/

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

-----------

Далее, MVC. MVC подсказывает нам как именно можно

Тут идея в том, что мы разбиваем обработчик запроса пользователя на 3 части: Модель, Контроллер, Вид (представление)

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

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

Контроллер управляет процессом обработки запроса от пользователя. Он анализирует запрос пользователя (например смотрит, указано ли слово для поиска по студентам или нет), затем вызывает модель чтобы получить данные или выполнить какие-то действия над ними, затем вызывает вид чтобы отобразить страницу пользователю (или делает редирект, это не принципиально).

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

Например мы можем сделать консольную программу, выводящую список студентов в консолью Эта программа сможет повторно использовать маппер, чтобы получить список студентов, а вот вывод его - делает самостоятельно. Если бы у нас не было разделения на МВЦ, то нам пришлось бы копипастить код выборки и поиска студентов из БД.

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

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

Чем является хелпер авторизации? Очевидно что это не модель, так как модель не управляет куками и не взаимодействует с пользователем (точнее с его браузером). Очеивдно что в консоли никаких кук нет, куки есть только при взаимодействии с браузером. Значит это не часть модели.

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

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

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

Теперь задавай свои вопросы.
#404 #779262
>>779258

Надо написать на JS аналог htmlspecialchars. Напиши и отдельно попроси проверить (ну и сам потестируй).

>>779260

Недостаточно. Не заменяется & например. Не заменяется символ кавычки который может сломать атрибут при постановки вида <input value="{x}">. Хотя ты это не делаешь, но вдруг захочешь потом.
>>779269
#405 #779264
>>779261

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

Чем плохи "толстые" контроллеры? Почему мы не можем сделать валидацию, проверку залогиненности, и запись в базу просто отдельными методами в контроллере формы регистрации? Принцип разбиения на функции ведь соблюдается.
#406 #779268
>>779261

И еще, может тебе интересно будет почитать книгу:

Стив Макконнелл Совершенный код.

Не знаю, может она сложновата будет для тебя, но если есть время, попробуй почитать, полистать. Там многие принципы, что я кратко написал, расписываются подробно.
#407 #779269
>>779262
http://pastebin.com/Aejdtp8X а вот так?

Тестировал строками отсюда https://www.owasp.org/index.php/XSS_Filter_Evasion_Cheat_Sheet
Проверил штук 20, ни одна не сработала.
>>779270
#408 #779270
>>779269

Так хорошо.
#409 #779297
>>779256
ОП Кошек-Мышек проверять не надо. Я выложил сюда кусок кода для того, чтобы спросить как найти ближайшую кошку и как я пытался ее найти. Ответ на этот вопрос я получил.
#410 #779330
>>779246
Это и есть тестовое (они всем однотипное шлют).

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


Что ты несешь?
Гугл дает бесплатно 100 запросов в день (мизерное количество). Если превысишь, то никто с тебя не будет без спроса брать деньги, гугл просто вежливо попросит приобрести премиум (5$ за тысячу запросов в сутки).

Тут на самом деле другой подвох: если скрейпить напрямую, и делать слишком большое количество запросов, гугл тебе сначала начнет выдавать капчу вместо результата, а если не угомонишься, то и забанит по айпи.
Для этого с переменным успехом используют прокси, выдерживают тайм-аут, меняют в заголовках юзер-агента, но все равно это очень сложное дело.
Вот пытаются написать универсальный парсер http://serp-spider.github.io/ , для такой задачки с не очень активным трафиком может и сойдет.

Еще подвох в том, что гугл может изменить верстку результатов выдачи, и твой парсер сломается. Короче это очень геморрное дело, странно что дают такое на собеседовании. Наверное проверяют, что человек умеет не только копипастить чужой код, но и думать головой.
>>779338>>781807
#411 #779338
>>779330

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


А как именно может поменять? Xpath-запросы позволяют парсить страницы без привязки к классам/id/атрибутам. Можно обойтись исключительно привязкой к последовательности тегов.
>>780572>>781807
#412 #779527
С чего начать работу со студентами? Что-то я пол года код не писал. Кто тут опытный и подскажет?
>>779538>>779629
#413 #779538
>>779527
Тащемта тут ничего сложного. Просто садишься и без задней мысли пишешь код.
Разбей задачу на подзадачи (регистрация, валидация, работа с БД) и решай каждую отдельно.
>>779548
#414 #779542
>>775673

> она почему-то возвращает NULL


А должна.... а что она должна, кстати?
>>775715
попробуйте ещё толще
#415 #779548
>>779538
Да я каждую отдельно могу решить. Но как мне начать-то? Я ща понял, что хоть и писал до этого контроллеры с моделями на фреймворке, то нихуя не знаю как начать писать подобную прилажуху с 0 на pure-php.

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

Как с 0 роутинг писать блджад?
>>779629
#416 #779594
Допустим я хочу написать класс, который будет просто управлять. Объект не нужен ему.

Стало быть я пишу что-то в духе
abstract class Yoba () {
public function start() {
...
}
}

и потом в коде просто пишу Yoba::start();
и всё у меня запускается??

Я конечно понимаю, что у меня класс абстрактный, но нельзя ли как-то туда конструктор еще заебенить?
Что бы оно вообще само кароче всё запускалось.
>>779629
#417 #779629
>>779527

Прочитай этот пост вначале: >>779261

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

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

>>779548

Плохо что не можешь.

Я вижу 2 варианта роутинга:

- роутинг за счет разных имен файлов. То есть у нас есть допустим файл index.php, выводящий список и файл profile.php, обрабатывающий форму регистрации/редактирования. В этом случае роутингом по сути занимается Апач.

- написать свой кастомный роутинг. То есть анализировать URL, если он равен / то выводим список, если /profile то форму редактирования. То ест использовать паттерн Front Controller - контроллер, который запускается первым и решает какой контроллер дальше вызвать.

>>779594

У тебя по моему проблемы с пониманием ООП.

1) почему abstract? abstract это класс объекты которого нельзя создавать.
2) почему статические методы?

> который будет просто управлять. Объект не нужен ему


Нужен. Ведь мы можем захотеть сделать 2 таких класса и чтобы один никак не влиял на другой. И вообще, статические методы это плохо, я уже объяснял в уроке по DI это.
#417 #779629
>>779527

Прочитай этот пост вначале: >>779261

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

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

>>779548

Плохо что не можешь.

Я вижу 2 варианта роутинга:

- роутинг за счет разных имен файлов. То есть у нас есть допустим файл index.php, выводящий список и файл profile.php, обрабатывающий форму регистрации/редактирования. В этом случае роутингом по сути занимается Апач.

- написать свой кастомный роутинг. То есть анализировать URL, если он равен / то выводим список, если /profile то форму редактирования. То ест использовать паттерн Front Controller - контроллер, который запускается первым и решает какой контроллер дальше вызвать.

>>779594

У тебя по моему проблемы с пониманием ООП.

1) почему abstract? abstract это класс объекты которого нельзя создавать.
2) почему статические методы?

> который будет просто управлять. Объект не нужен ему


Нужен. Ведь мы можем захотеть сделать 2 таких класса и чтобы один никак не влиял на другой. И вообще, статические методы это плохо, я уже объяснял в уроке по DI это.
>>779650
#418 #779650
>>779629

>1) почему abstract? abstract это класс объекты которого нельзя создавать.



Так мне и не нужен объект.

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

Зачем мне создавать объект только ради движухи?

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


Я ничего не понял, ты имел в виду 2 объекта?

>DI


что такое DI?
>>779651
#419 #779651
>>779650

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

Не вижу никаких проблем создать объект.

Урок по DI https://github.com/codedokode/pasta/blob/master/arch/di.md
#420 #779681
Такое еще актуально?

// Данный файл всегда будит "включаться" в другие файлы
// директивой include поэтому следует запретить его самостоятельный вызов
// из строки запроса путём указания его имени
// Если не определена константа IN_ADMIN – завершаем работу скрипта
if(!defined("IN_ADMIN")) die;
>>779731>>781807
#421 #779694
Есть книга где объясняется все с самого начала?
Сервера, апач, как запускать свои скрипты на сервере и т.д?
>>781805
#422 #779728
>>769611 (OP)
Представляю сколько глистов у этих кошатниц.
>>779798
#423 #779731
>>779681
Нет. Все, кроме роутера запросов должно быть за пределами public_html.
>>780158
333 Кб, 700x704
#424 #779798
>>779728
Который раз уже это пишешь, а запятые ставить так и не научился..
>>779972
#425 #779901
>>779256

> Ответьте-ка, ваши задачи проверять надо? Как у вас дела с решением?


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

Всяко, можешь и на изменения глянуть. Я там контроллеры в классы загонял
#426 #779972
>>779798
Как вообще PHP связан с кошками? Со слонами еще понимаю.
>>779981
#427 #779981
>>779972
Да они тут просто анимубляди все...
>>779982
#428 #779982
>>779981
Всегда считал, что анимубляди пишут на этом японском бейсике... Как его там, Сапфир штоле?
>>779985
#429 #779985
>>779982
Ну это же один из диалектов PHP.
>>779990
#430 #779990
>>779985
Все 4 языка - диалекты Бейсика. В Perl вон даже ключевое слово SUB осталось.
Хотя в PHP зачем-то C/C++ синтаксис.
>>779993
#431 #779993
>>779990
sub в Perl это, скорее, наследие баша.
inb4 баш это диалект бейсика

>Хотя в PHP зачем-то C/C++ синтаксис.


А еще джаваподобное ООП. Я же говорю, анимубляди. Типа как в типичном веобушном медиа-продукте: понадергали отовсюду понемногу, в результате никакой целостности, сплошной кластерфак.
>>779998
#432 #779998
>>779993
Про баш не знаю. Виндовый скриптовый язык очень похож на Бейсик.
А PHP возможно создавался под влиянием JavaScript, это объясняет синтаксис и ООП.
>>780003
#433 #780003
>>779998
А жс под влиянием чего? Вот-вот.
Олсо, считаю большим упущением отход от практики совмещения html и php кода. Ведь такая-то киллер фича.
>>780009
#434 #780009
>>780003

> А жс под влиянием чего? Вот-вот.


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

> Олсо, считаю большим упущением отход от практики совмещения html и php кода. Ведь такая-то киллер фича.


А что в этом хорошего? Я считаю, что и html с js в одном файле смешивать плохо. Данные (тем более интерфейс) и код должны храниться отдельно.
>>780017
#435 #780017
>>780009

>А что в этом хорошего?


Можно запихнуть прямо в хтмл код какую-нибудь логику. Собственно, для большего PHP и не нужен.
>>780019
#436 #780019
>>780017
Зачем все держать в одном файле? Потом заебешься же искать эту логику.
#437 #780036
Хватит флудить
30 Кб, 1230x625
#438 #780094
А есть какие-нибудь средства, которые сами будут сканировать код и выдавать визуализацию, как например здесь - зависимости классов.

Мне вообще кажется, должна быть такая штука, которая рисует таблички, где видно, где какой объект, какого класса и какие там методы и свойства
>>780099>>780877
#439 #780099
>>780094
Graphviz. Только не знаю, работает ли он нормально под Windows или нет.
http://chapman.id.au/generate-php-class-inheritance-diagrams-in-graphviz тут есть скрипт на баше который из вывода Graphviz делает картинки.
>>780877
#440 #780158
>>779731
А js, css, img - в пределах, или тоже за?
>>780569
#441 #780214
https://github.com/TheSidSpears/Students/tree/master/app/models

> Тут в папку свалены разные классы, часть из которых точно не модели - например, FrontController никак моделью не является. Роутер явно не является частью модели. И вообще, MVC не значит что у тебя должно быть ровно 3 папки view, controller и model. Это деление приложения на 3 части, а не файлов на 3 папки.



Я просто переименовал models в classes. Просто рассовывать по папкам 9 файлов - только путаницы больше будет

>Далее, ты разбиваешь УРЛ на части и берешь последнюю, а что если УРЛ имеет вид /a/b/c/d/e/f - ты берешь только f, а остальные игнорируются?



Да, в данном коде у меня только последнее - модуль, остальное путь до индекса http://localhost/students/public/main

> if($currentPage<=0){$currentPage=1;}


> Тебе надо лучше форматировать код. Иф пишется в 3 строки, а не в одну. Также, тут можно было обойтись функцией max.



Не понял зачем и как
>>781805
#442 #780326
Чем скачивать картинки по URL?
Хочу запустить скрипт по скачиванию картинки на денвере и не знаю через какой метод.
>>780877>>781805
#443 #780353
>>773668
>>772645
такой вопрос: что делают эти строки validate($correctNumbers, $regexp);
validate($incorrectNumbers, $regexp);
и почему в foreach масив назвали numbers если есть 2 масива называемые correctNumbers и incorrectNumbers
463 Кб, 1920x1080
#444 #780539
Есть ли тут, кто уже что-то умеет?
Могу предложить работу, не регулярную, можете рассматривать как подработку.
Создание преимущественно интернет-магазинов. Знание распространённых цмс (битрикс, хостцмс и т.д. приветствуется) В будущем битрикса не будет, только зарубежные заказы.
daniilsergeewichnazarK+zowANUSgmai~UZlPUNCTUMcnA:om
>>780565
#445 #780540
Ретерны в свитче - это норма? Если да, брейк нужен после них?
миморетард с файлообменника психологически находящийся на стадии задачек с ideone
>>780546>>781805
#446 #780546
>>780540
Только в том случае, если функция объявлена с аттрибутом noreturn.
>>781805
#447 #780565
>>780539
Есть, но такие уже работают.
#448 #780569
>>780158
js, css, img - в публичной папке, от них вреда нет, там же index.php
В index.php только автозагрузчик классов, загрузчик конфигурации и загрузчик роутера, которому конфигурация передается через Dependency Injection. Сам роутер и конфигурация не лежат в паблике, они там же где и все остальные классы. Темплейты в html тоже не в паблике, потому что там можно код включать.
#449 #780572
>>779338
Можно же последовательность тегов поменять.
#450 #780584
https://github.com/3DsYND/Dreams/blob/master/application/models/user.php

Правильно хоть что-то делаю?
#451 #780585
Аноны, пишу свою первую форму. Код тут - http://pastebin.com/MDgHXrMm
Столкнулась с тем, что $title не меняется. Есть догадка, что операции, которые я считаю переопределением переменной, на самом деле создание новой, с ограниченной областью видимости. Вне зависимости от того, какое действие произведено, её значение всегда остаётся "Contact Us", Как мне сделать заебись?
>>781805
#452 #780627
https://github.com/TheSidSpears/Students/blob/master/app/models/ViewHelper.php#L63

> return self::html($url);


> Почему функция makeUrl вызывает self::html? А что если нам нужен исходный неискаженный УРЛ (например мы хотим редиректить на него)?


А редирект на htmlspecialchars($url) не сработает разве?

> https://github.com/TheSidSpears/Students/blob/master/app/models/ViewHelper.php#L57


> foreach ($blockedParams as $key => $value) {


> $url.=$key."=".$value."&";


>Что если в value содержится символ &, #, ? или какой-то еще, имеющий специальное значение в УРЛ?



Так ничего ж не происходит. Если юзер в url шнягу пишет localhost/students/public/search?page=1&find=%D0%A5%D0%B8#&sortBy=grou?&p_num&orderBy=a#sc, то скрипт выдаёт страницу c значениями этих переменных по умолчанию, сбрасывает параметры сортировки и поиска

> $token= (isset($_COOKIE['token'])) ? $_COOKIE['token'] : Util::randHash(20);


> setcookie('token',$token,time()+3600,'/',null,false,true);


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


На данный момент у меня кука token используется в Edit- и ReadController'е, а прописана она в абстрактном ERController'е. Все еще надо создавать отлельный класс ради 2х строчек?
>>781803
48 Кб, 208x331
#453 #780781
>>769611 (OP)
Cуп, посоны, думаю вот начать изучать похапеили сишарп продолжить или плюса - но это другая история - возможно подрабатывать фрилансом, может просто, вот думаю. Сколько времени нужно изучать, чтобы начать хоть что то зарабатывать фрилансом типа "запилить интернет-магазин", на что язык PHP похож, и сложен ли MySQL?
>>780852
22 Кб, 1200x630
#454 #780792
Сначала подумал что это охуенно подобранный красный на логотипе. Оказалось градиент. Вот так всегда, дрочишь на идеальные цвета, а оказывается градиент. Что за анхуманы такие идеальные градиенты рисуют? Сколько лет надо задротить колористику чтобы так рисовать градиенты?
>>780796>>780813
#455 #780796
>>780792
Пять минут в ФШ.
Кому и кобыла невеста.
>>780800>>780840
#456 #780800
>>780796
Ну сделай, умник.
>>780803
#457 #780803
>>780800
В трёх точках - внизу, в середине и вверху - возьми пипеткой цвет, проставь в настройках градиента.
И что там такого идеального? В упор не вижу, простой тёплый красный, видно, что градиент, по превьюшке.
>>780823
#458 #780806
>>780584

> public function getData()


> {


> include_once 'database.php';



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

>return null;


Это зачем?

>$base = Database::getConnection();


Тоже самое, юзай DI.

>$this->nick = $this->verifyNick($nick, $errors);


Verify функция ставит значение переменной класса? Тоже очень бредово. Verify функция должна возвращать true/false, а в вызывающем коде уже на основе полученного ответа принимается решение, кидать исключение или продолжать работу. У тебя это уже не verify функция, а нечто непонятное, код запутывается сразу.
>>781016
#459 #780813
>>780792
Слепой что ли, по углам видно же что это разные цвета.
>>781803
#460 #780823
>>780803

>возьми пипеткой цвет


Какой цвет из 16 млн?

>И что там такого идеального?


То же что и у желтого яндекса. Такие цвета наверное подбирают сканированием коры головного мозга у группы людей. Определяют сколько дофамина вырабатывается.
>>780829>>781803
#461 #780824
>>780584

>isExist($arrayValues){


Учи инглиш, или словарь хоть юзай, непонятно же сразу что за isExist. Правильно назвать было, судя по коду функции - valuesAreNotEmpty($arrayValues).

> if ($arrayValues[$i] == '') {



if (!isset($arrayValues[$i] || empty($arrayValues[$i]))
>>781803
10 Кб, 320x180
#462 #780829
>>780823

>То же что и у желтого яндекса


>То же что и у желтого яндекса


>То же что и у желтого яндекса


АртЁмий, что же вы делаете, АртЁмий!
Что же вы делаете с людьми.

А как же голубой у Гугла, фиолетовый у Яху и серый на Макабе?
>>780853
#463 #780833
>>780584

> private function verifyMail($mail, &$errors)


>array_push($errors, 'Адрес eMail некорректен.');


> $mail = htmlspecialchars($mail);


Плохо, функция выполняет две совершенно разных вещи, причем из названия это непонятно. Разнеси на 2 функции - одна mailIsValid($mail), которая возвращает true/false, а $mail = htmlspecialchars($mail) перенеси, где она нужна, видимо в registerUser перед вставкой в БД.
>>781803
#464 #780840
>>780796

>Пять минут в ФШ.


Какой еще фотожоп, это обычный CSS градиент, 2 секунды в инспекторе.
>>780861
#465 #780852
>>780781
Язык PHP похож на объектно-ориентированный язык, учить по-разному, в зависимости от способностей. Поделай уроки ОПа вводные, сразу понятно станет. MySql сложен, читай доки, делай упражнения на sql-ex.ru, помогает, и ясность появляется, но времени уходит много. Запилить интернет-магазин можно вообще без всего этого, достаточно какой-нибудь готовый фреймворк или cms для интернет-магазинов подключить, в принципе все новички так бабло и рубят, хуяк-хуяк и в продакшн. Но это будет плохой магазин для мелких конторок, с кучей дыр и ограниченным функционалом, ничего серьезного ты конечно так не сделаешь, и на работу тебя тоже с такими скиллами не возьмут. А чтобы взяли - делай задания ОПа, из тех, что посложнее, на ООП, про студентов.
#466 #780853
>>780829

>А как же голубой у Гугла, фиолетовый у Яху и серый на Макабе?


Гугл бутстраповат.
Яху всрат.
Макаба (дефолтный цвет фона сообщений на двоще) охуенна, но старперна.
#467 #780855
>>772833
Фуллстак это вообще-то называется. И их сейчас везде хотят. Чистым фронтендом сложнее устроиться, и зарплата меньше будет.
>>781803
#468 #780861
>>780840

>2 секундочки, сделаю за 5 минут, от силы полчаса


>существует миллион <sameshitname>


А я уже давно говорю что людей, которые преувеличивают и преуменьшают, надо убивать нахуй.
>>780877
#469 #780877
>>780584

>https://github.com/3DsYND/Dreams/blob/master/public_html/index.php#L2


Это за тебя может сделать Composer.

>https://github.com/3DsYND/Dreams/blob/master/public_html/index.php#L5


Это можно прописать в .htaccess или указать в локальном/глобальном php.ini

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

>>780094
Тебе преподу показать что ли? Диаграммы не для того придуманы, чтобы генерировать их на основе готового кода. Алсо, неужели есть генераторы, которые показывают ещё и типы отношений между классами, не только генерализацию, а агрегацию, композицию, зависимость, арность (1:*, 1:1 и так далее)? Генератор, предложенный >>780099-
этим аноном, ограничивается лишь генерализацией, просто потому, что она явно указывается в коде строчками "Foo extends BaseFoo".

>>780326
Если у тебя есть список готовых URL с картинками, то хватит просто file_put_contents

>>780861

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



"Я ненавижу 2 вещи: расизм и негров."
#470 #780899
Анон который https://github.com/someApprentice/Students

Напоминаю: для тебя тут отдельный пост написан >>779261

>>780584

Чем у тебя занимается класс User? Определи задачи, которые он решает и подумай, что тут не так.

Также, прочти этот пост >>779261

Также, прочти про PSR-4 и автозагрузку https://github.com/codedokode/pasta/blob/master/php/autoload.md

Лучше называть файлы по PSR-4
>>781016>>783964
#471 #781016
>>780806

> public function getData()


> {


> include_once 'database.php';


>return null;


Это код из примера MVC, я не знаю, как он сюда попал. Удалю.

>Тоже самое, юзай DI.


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

>valuesAreNotEmpty


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

>if (!isset($arrayValues[$i] || empty($arrayValues[$i]))


>>>empty - Переменная считается пустой, если она не существует или её значение равно FALSE.


Нужно ли тогда isset, если empty и так проверяет на null?

>Разнеси на 2 функции


Плодить функции тоже не очень-то хорошо, но что-нибудь придумаю.

display_errors тут, имхо, удобней, или есть другие причины прописывать в .htacess или php.ini? Про Composer не совсем понял.

Я пока сложные запросы делать не собираюсь, поэтому хватит и двух методов select, insert. Зачем тогда делать для каждой сущности свой DataMapper, если можно обойтись и, грубо говоря, одним. Да по-моему, и сложные запросы не так уж и сложно в моём случае реализовать. А если не выйдет - тогда и перейду на каноничный паттерн. Переписывать всё сначала я уже привык, хоть это и плохо.
Спасибо.

>>780899
Работает с пользователем, чем.. Если ты про verify, то я несколько раз выносил его в отдельный класс, а потом снова объединял, остановился на этом. Или ты не про это?
#471 #781016
>>780806

> public function getData()


> {


> include_once 'database.php';


>return null;


Это код из примера MVC, я не знаю, как он сюда попал. Удалю.

>Тоже самое, юзай DI.


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

>valuesAreNotEmpty


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

>if (!isset($arrayValues[$i] || empty($arrayValues[$i]))


>>>empty - Переменная считается пустой, если она не существует или её значение равно FALSE.


Нужно ли тогда isset, если empty и так проверяет на null?

>Разнеси на 2 функции


Плодить функции тоже не очень-то хорошо, но что-нибудь придумаю.

display_errors тут, имхо, удобней, или есть другие причины прописывать в .htacess или php.ini? Про Composer не совсем понял.

Я пока сложные запросы делать не собираюсь, поэтому хватит и двух методов select, insert. Зачем тогда делать для каждой сущности свой DataMapper, если можно обойтись и, грубо говоря, одним. Да по-моему, и сложные запросы не так уж и сложно в моём случае реализовать. А если не выйдет - тогда и перейду на каноничный паттерн. Переписывать всё сначала я уже привык, хоть это и плохо.
Спасибо.

>>780899
Работает с пользователем, чем.. Если ты про verify, то я несколько раз выносил его в отдельный класс, а потом снова объединял, остановился на этом. Или ты не про это?
>>781609>>781803
#472 #781135
Стоит ли юзать трейты? Позарез нужно множественное наследование сейчас.
>>781803
#473 #781169
Из опыта - делфи 2 года назад.
Подскажите годные видео курсы по пхп, чтобы как можно быстрее вкатиться в пыху и начать пилить что-то свое (ну а потом и джуном на работку).
Заранее спасибо анонам.
>>781461
184 Кб, 500x513
#474 #781215
>>787028
2031 Кб, 490x466
#475 #781369
Сижу, выполняю заказы для малосочных дебилов. В основном на цмс, но иногда появляются вкрапления на божественном пиашпи. Дворовые пацанчики подросли и мутят бизнесач. Рядом есть сеошник, годный. Какой профит можно вымутить из дворовых пацанчегов? Они занимаются строкой, сваркой ворот и прочей ебатни, сто, хуёо, химчистки. Просто задолбали с вопросами сделать им сайт. Мне конечно не жалко сбабацать им лендос за 5К, но с дизигнером я им говорю что выйдет все 50. Жлобы жалятся и не хотят ебать интернеты своей залупой. Как выдавить из жлобов процентаж? Выловить их на окуня?
>>781435>>781789
#476 #781396
Не могу решить эту задачку с учебника http://codepad.org/UOaOEgAW, помогите.
#477 #781409
#478 #781430
>>781396
Правда?
Ну тогда держи:
foreach ($classmates as $name => $height) {
echo "Имя: {$name}, рост: {$height} см.\n";
if ($height>$anonHeight) / Тут надо добавить проверку, выше или ниже этот человек, чем анон,
и подсчитать число тех, кто выше
/
{$number++;}
}
#479 #781435
>>781369
Я бы писал задешево. Просто потому что могу.
>>781444
#480 #781444
>>781435
Лениво, да и внемоготу им лендосы рисовать. Надо жир как придумать с них срисовывать за поддержку интернетов и хайпа их хреноподелий.
#481 #781461
>>781396
Ты, скорее всего, не понимаешь что такое циклы. Попробуй загуглить "циклы в PHP" и реши задачу попроще - выведи 20 раз своё имя с помощью цикла.

>>781169

>Из опыта - делфи 2 года назад.


Cлишком размыто.

>видео курсы


>годные


Поделил на 0.

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

> Они занимаются строкой, сваркой ворот


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

Лучше бы ты скиллы программирования качал.
>>781485>>781789
#482 #781485
>>781461

>>>781444


ОП, ты - хороший человек. Проверь задачи, пожалуйста. Я ремесленникам не собираюсь палки в колеса вставлять, они как я, и я как они. Надо лишь высчитать оптимальный кэш за неудобства с моей стороны.
>>781515
#483 #781515
>>781485
ОП проверит, когда будет время. Я так же как и ты жду проверки. Делай следующие задания.
117 Кб, 1600x1200
уникальный шанс #484 #781569
Как объяснить Алевтине, что веб-директория вынесена за корень сервера?
#485 #781600
>>781569
Лол. Просто пиздец, как проиграл.
#486 #781609
>>781016
https://github.com/3DsYND/Dreams/blob/master/application/models/user.php
Переписал полностью модель User, сделал всё же DataMapper, сделал обработчик сообщений не знаю как называть посмотрите тоже, не сошёл ли я с ума.
Вроде бы и лучше стало, а вроде бы и хуже.
>>781616>>781789
#487 #781616
>>781609
Модель не должна отвечать за регистрацию. Создавай внешний сервис/хелпер.
>>781619
#488 #781619
>>781616
Почему? Если имеешь ввиду, что не должна в бд лезть, то в бд лезет отдельный Database\User.
#489 #781666
>>781569
Я сам в упор не понимаю, как запускать проекты с Github.
Вечно навертят хер пойми чего и где, разбираться еще в этом.
Хоть бы в readme.txt писали, как запускать.
А по сути тестового - явно кидануть тебя хотят:

>4 дня назад принято выполненное тестовое задание


>2 часа назад только попыталась запустить

#490 #781789
>>781369

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

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

Ну либо переходи в другой сегмент, где проблем с бюджетом нет.

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

>>781461

> Вот они так же само обманут тебя с ценой за сварку ворот


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

Недавно читал например как клиентам автосалона после подписания договора на поставку договор на продажу делали на 100-200 тысяч дороже. А если отказываешься от покупки - то все равно должен неустойку.

>>781444

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

>>781569

README.md

Вот смотри как делает анон: https://github.com/foobar1643/filehosting пункт Install

Напиши ридми такого вида:

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

Насчет настройки веб-сервера - надо приложить либо конфиг виртуального хоста либо .htaccess (что может быть удобнее).

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

>>781609

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

> Работает с пользователем, чем..



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

Так и у тебя. У тебя в классе собраны функции:

- хранение информации об одном пользователе
- проверка авторизации (тут мы обращаем внимание что функция возвращает результат в случае успеха в каком-то странном ненормальном формате. Логично при отсутсиви ошибок возвращать пустой массив)
- регистрация
- экранирование html-символов (что это делает в модели?)
- валидация

Это слишком много для одного класса. Ты все свалил в кучу.

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

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

- объектом
- массивом

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

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

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

А ты кстати решал задачи про Вектор и Кошки-Мышки? Они помогают чуть лучше разобраться с ООП.

Вот еще пример неправильного представления данных:

> $ans = $database->getPassByNick($this);


> if ($ans[0] != '#DB-Succes') {


Что это за ерунда? Для ответа да/нет есть true/false. Вот как угадать, что значит эта строка и какие еще варианты есть? И почему ты возвращаешь ее еще и завернутой в массив.

То есть можно вернуть false или true
А ты выбрал вариант вернуть ['#Db-Error'] или ['#DB-Succes'] (с одной буквой s вместо двух). Какая выгода от такого усложнения?

Если надо вернуть больше 2 вариантов, есть константы. Например

return Model::STATUS_NOT_REGISTERED;
return Model::STATUS_USER_BLOCKED;

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

В общем, класс надо переделывать. Тут в каждой второй строке нарушаются принципы написания надежного, понятного, самодокументируемого кода.
#490 #781789
>>781369

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

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

Ну либо переходи в другой сегмент, где проблем с бюджетом нет.

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

>>781461

> Вот они так же само обманут тебя с ценой за сварку ворот


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

Недавно читал например как клиентам автосалона после подписания договора на поставку договор на продажу делали на 100-200 тысяч дороже. А если отказываешься от покупки - то все равно должен неустойку.

>>781444

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

>>781569

README.md

Вот смотри как делает анон: https://github.com/foobar1643/filehosting пункт Install

Напиши ридми такого вида:

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

Насчет настройки веб-сервера - надо приложить либо конфиг виртуального хоста либо .htaccess (что может быть удобнее).

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

>>781609

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

> Работает с пользователем, чем..



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

Так и у тебя. У тебя в классе собраны функции:

- хранение информации об одном пользователе
- проверка авторизации (тут мы обращаем внимание что функция возвращает результат в случае успеха в каком-то странном ненормальном формате. Логично при отсутсиви ошибок возвращать пустой массив)
- регистрация
- экранирование html-символов (что это делает в модели?)
- валидация

Это слишком много для одного класса. Ты все свалил в кучу.

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

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

- объектом
- массивом

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

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

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

А ты кстати решал задачи про Вектор и Кошки-Мышки? Они помогают чуть лучше разобраться с ООП.

Вот еще пример неправильного представления данных:

> $ans = $database->getPassByNick($this);


> if ($ans[0] != '#DB-Succes') {


Что это за ерунда? Для ответа да/нет есть true/false. Вот как угадать, что значит эта строка и какие еще варианты есть? И почему ты возвращаешь ее еще и завернутой в массив.

То есть можно вернуть false или true
А ты выбрал вариант вернуть ['#Db-Error'] или ['#DB-Succes'] (с одной буквой s вместо двух). Какая выгода от такого усложнения?

Если надо вернуть больше 2 вариантов, есть константы. Например

return Model::STATUS_NOT_REGISTERED;
return Model::STATUS_USER_BLOCKED;

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

В общем, класс надо переделывать. Тут в каждой второй строке нарушаются принципы написания надежного, понятного, самодокументируемого кода.
>>781839>>781860
#491 #781794
Какой-то анон раньше хотел изучать ноду и сетевое программирование. Ну давай, анон, начнем с простых задач:

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

node checker.js 'http://example.com/1.png' 'http://example.com/2.png'

Программа должна параллельно проверить каждую ссылку на валидность путем отправки HTTP-запроса типа HEAD и вывести (по мере поступления ответов) статус проверки и MIME тип ответа в таком формате:

200 text/html http://example.com/2.png
404 - http://example.com/1.png
Failed to resolve name: invalid.domain http://invalid.domain/1.png

Резолвинг DNS тоже надо бы делать асинхронно и параллельно.

Дополнительные пункты:

- добавить ограничение числа параллельных запросов на 1 домен верхнего уровня . Например если у нас есть ссылки http://1.example.com/ и http://2.example.com/ то они должны обрабатываться по очереди, так как там один домен (example.com)

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

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

Для тестирования я советую использовать либо сервис вроде http://httpbin.org/ либо какой-нибудь локальный скрипт где ты можешь выставлять задержку ответа и его тип.

2) Напиши сервер мемкеша. Мемкеш - это сервис, который позволяет хранить данные в памяти, сохранять их туда и доставать. Реализуй протокол мемкеша (описание есть в сети). Все команды реализовывать не надо - ограничься простейшими вроде GET, SET, STAT и еще несколькими.

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

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

Пиши, если есть вопросы.
#491 #781794
Какой-то анон раньше хотел изучать ноду и сетевое программирование. Ну давай, анон, начнем с простых задач:

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

node checker.js 'http://example.com/1.png' 'http://example.com/2.png'

Программа должна параллельно проверить каждую ссылку на валидность путем отправки HTTP-запроса типа HEAD и вывести (по мере поступления ответов) статус проверки и MIME тип ответа в таком формате:

200 text/html http://example.com/2.png
404 - http://example.com/1.png
Failed to resolve name: invalid.domain http://invalid.domain/1.png

Резолвинг DNS тоже надо бы делать асинхронно и параллельно.

Дополнительные пункты:

- добавить ограничение числа параллельных запросов на 1 домен верхнего уровня . Например если у нас есть ссылки http://1.example.com/ и http://2.example.com/ то они должны обрабатываться по очереди, так как там один домен (example.com)

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

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

Для тестирования я советую использовать либо сервис вроде http://httpbin.org/ либо какой-нибудь локальный скрипт где ты можешь выставлять задержку ответа и его тип.

2) Напиши сервер мемкеша. Мемкеш - это сервис, который позволяет хранить данные в памяти, сохранять их туда и доставать. Реализуй протокол мемкеша (описание есть в сети). Все команды реализовывать не надо - ограничься простейшими вроде GET, SET, STAT и еще несколькими.

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

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

Пиши, если есть вопросы.
>>782863
#492 #781803
>>781135

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

>>781016

> Нужно ли тогда isset, если empty и так проверяет на null?


Не нужно

> Зачем тогда делать для каждой сущности свой DataMapper, если можно обойтись и, грубо говоря, одним


Потому что так удобнее. Неудобно когда несколько классов склеены в один.

>>781016

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

>>780855

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

>>780833

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

>>780824

Не придирайся к знанию английского. У нас не филологический тред тут все же. Анон я думаю сам это понимает и в свободное время подучивает язык, читает hacker news и reddit, смотрит аниме с английскими субтитрами.

>>780823

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

>>780813

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

>>780627

> А редирект на htmlspecialchars($url) не сработает разве?



index.php?a=1&b=2

index.php?a=1& amp ; b = 2

Ну-ка, сравни-ка как распарсит php первый и вторй УРЛ (можешь проверить функцией http://php.net/manual/ru/function.parse-str.php )

> Так ничего ж не происходит. Если юзер в url шнягу пишет


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

Урок https://github.com/codedokode/pasta/blob/master/network/urls.md

> Все еще надо создавать отлельный класс ради 2х строчек?


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

И там не 2 строчки. Я вижу как минимум:

- установка/генерация токена
- проверка токена

> а прописана она в абстрактном ERController'е


Я не смотрел код но подозреваю что наследование тут применять не стоило бы.
#492 #781803
>>781135

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

>>781016

> Нужно ли тогда isset, если empty и так проверяет на null?


Не нужно

> Зачем тогда делать для каждой сущности свой DataMapper, если можно обойтись и, грубо говоря, одним


Потому что так удобнее. Неудобно когда несколько классов склеены в один.

>>781016

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

>>780855

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

>>780833

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

>>780824

Не придирайся к знанию английского. У нас не филологический тред тут все же. Анон я думаю сам это понимает и в свободное время подучивает язык, читает hacker news и reddit, смотрит аниме с английскими субтитрами.

>>780823

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

>>780813

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

>>780627

> А редирект на htmlspecialchars($url) не сработает разве?



index.php?a=1&b=2

index.php?a=1& amp ; b = 2

Ну-ка, сравни-ка как распарсит php первый и вторй УРЛ (можешь проверить функцией http://php.net/manual/ru/function.parse-str.php )

> Так ничего ж не происходит. Если юзер в url шнягу пишет


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

Урок https://github.com/codedokode/pasta/blob/master/network/urls.md

> Все еще надо создавать отлельный класс ради 2х строчек?


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

И там не 2 строчки. Я вижу как минимум:

- установка/генерация токена
- проверка токена

> а прописана она в абстрактном ERController'е


Я не смотрел код но подозреваю что наследование тут применять не стоило бы.
>>781889
#493 #781805
>>780585

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

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

$subjectMessage = $values['name'] . " writes about: " . $values['subject'];

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

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

После успешной отправки письма надо делать редирект иначе обновление страницы пошлет еще письма, почитай урок про работу с формами.

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

>>780546

В пхп нет такого атрибута. Ты ошибся тредом.

>>780540

Норма, не нужен

>>780326

Тебе нужна библиотека-http клиент например guzzle. Не забудь проверять все ошибки.

>>780214

>> Также, тут можно было обойтись функцией max.


> Не понял зачем и как


Для краткости и наглядности. Так:

номер = максимаьное из(переданный номер, 1)

>>779694

Хорошей скорее всего нету. По идее это отдельные темы:

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

Тренироваться можно на дебиане без графического интерфейса, установленном в виртуалбокс. Хватит 400-500 Мб памяти и 2 Гб на диске. Инструкция https://gist.github.com/codedokode/420c8c12a1edae25f0ec
#493 #781805
>>780585

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

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

$subjectMessage = $values['name'] . " writes about: " . $values['subject'];

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

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

После успешной отправки письма надо делать редирект иначе обновление страницы пошлет еще письма, почитай урок про работу с формами.

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

>>780546

В пхп нет такого атрибута. Ты ошибся тредом.

>>780540

Норма, не нужен

>>780326

Тебе нужна библиотека-http клиент например guzzle. Не забудь проверять все ошибки.

>>780214

>> Также, тут можно было обойтись функцией max.


> Не понял зачем и как


Для краткости и наглядности. Так:

номер = максимаьное из(переданный номер, 1)

>>779694

Хорошей скорее всего нету. По идее это отдельные темы:

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

Тренироваться можно на дебиане без графического интерфейса, установленном в виртуалбокс. Хватит 400-500 Мб памяти и 2 Гб на диске. Инструкция https://gist.github.com/codedokode/420c8c12a1edae25f0ec
#494 #781807
>>779681

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

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

>>779338

Гугл может поменять порядок тегов

>>779330

Это плохая, неинтересная, неблагодарная и плохо оплачиваемая работа. держитесь от сеошников подальше.
>>782394
#495 #781839
>>781789

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


Дико извиняюсь, писала крайне бухая и злая свинособака.
#496 #781860
>>781789

>У тебя в классе собраны функции. Это слишком много для одного класса.


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


Не, ну я не знаю, как это в РНР, но насколько я знаю, в обычных языках ООП подразумевает, что один класс описывает одну сущность (объект), а не одну функцию; и для каждого пользователя таки нужно создавать отдельный объект класса пользователя.
Экранирование - да, лажа, исправлю. Валидацию, имхо, стоит вынести в отдельный класс только если её можно будет использовать и для других классов.

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


Имеешь ввиду передавать поля ассоциативным массивом или что?

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


Я думал массивом сделать, но для одного поля может быть несколько ошибок, и строкой
array('nick-smallLength', 'nick-badMask')
ошибку вывести показалось легче, чем
array('nick' = > array('smallLength', 'nick-badMask'))
Так что-ли лучше, или ты другое имел ввиду? Попробую сделать класс.

>Что это за ерунда? Для ответа да/нет есть true/false.


БД может возвращать '#DB-Error', '#DB-Success и '#DB-Empty', но тут да, путаница, разберусь.

>Константы


Ок.
Спасибо.
#497 #781871
http://ideone.com/fFv4zN

Как сделать это правильно? (+7 меня смущает)
>>797241
#498 #781886
ОП, я тут еще раз перечитал документацию к gettext и думаю что ты был не прав в этом посте >>770094

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


Там есть функция ngettext http://php.net/manual/en/function.ngettext.php который может склонять слова с помощью переводов.
А потом я посмотрел исходники дополнения i18n к твигу, и оказалось что тег {% plural %} использует как раз эту функцию. Плохо что они этого в документации не написали.
https://github.com/twigphp/Twig-extensions/blob/master/lib/Twig/Extensions/Node/Trans.php#L41

Так вот, может лучше будет взять эту функцию, чем использовать MessageFormatter? У меня с помощью POedit получилось перевести склонения правильно.
>>782297
#499 #781889
>>781803

>Вряд ли тебе нужно множественное наследование



Расставляю костыли в очень запутанный и плохо написанный проект, хочется обойтись малой кровью.
Вот нашел для себя выход в трейтах, так то я больше не встречал их на практике. Стало интересно насколько они вообще уместны.
#500 #781909
ааа, посоны, у меня собеседование по скайпику сейчас, пожелайте мне удачи!
>>781919
#501 #781919
>>781909
Удачи.
Инкапсуляция, полиморфизм, наследование.
>>781924
#502 #781924
>>781919
Спасибо, анон! Постараюсь не забыть.
192 Кб, 1024x1024
#503 #782110
Антоши, какую умную функцию запилить для определения вхождения рандомной даты в диапозон дат. Есть куча диапазонов да, и вот елсифами не очень целесообразно проверять.
#504 #782263
Спасибо, анон.
#505 #782297
>>781886

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

>>782110

Массив + цикл.
>>782318
#506 #782318
>>782297
ну и в чем профит по времени выполнения? Кстати, все в unix time, может можно как-то хитро обрезать цифры и манипулировать числами? Я в этом смысле спрашивал.
#507 #782394
>>781807

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



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

А не проще вкаорячить в htaccess Deny from All в неугодные диры, вместо того, чтобы разбрасывать их по файловойм системе?
>>797241
#508 #782503
ПИШЕТ ЗАДРОТ ПРОГРАММИСТ

Привет Ананасы. Пишу парсер для автоматизации. Затупняк произошел на этапе авторизации
Вот сайтик
http://www.vezetvsem.ru/listing

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

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

>>


<?
function login($url,$login,$pass){

$ch = curl_init();
if(strtolower((substr($url,0,5))=='https')) { // если соединяемся с https
//моя вставка
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
//моя вставка
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}
curl_setopt($ch, CURLOPT_URL, $url);
// откуда пришли на эту страницу
curl_setopt($ch, CURLOPT_REFERER, $url);
// cURL будет выводить подробные сообщения о всех производимых действиях
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,"username=".$login."&password=".$pass);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

echo "username=".$login."&password=".$pass;
//сохранять полученные COOKIE в файл
curl_setopt($ch, CURLOPT_COOKIEJAR, $_SERVER['DOCUMENT_ROOT'].'/cookie.txt');
$result=curl_exec($ch);

// Убеждаемся что произошло перенаправление после авторизации
if(strpos($result,"Location: home.php")===false) die('Login incorrect');

curl_close($ch);

return $result;
}

// чтение страницы после авторизации
function Read($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
// откуда пришли на эту страницу
curl_setopt($ch, CURLOPT_REFERER, $url);
//запрещаем делать запрос с помощью POST и соответственно разрешаем с помощью GET
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
//отсылаем серверу COOKIE полученные от него при авторизации
curl_setopt($ch, CURLOPT_COOKIEFILE, $_SERVER['DOCUMENT_ROOT'].'/cookie.txt');
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (Windows; U; Windows NT 5.0; En; rv:1.8.0.2) Gecko/20070306 Firefox/1.0.0.4");

$result = curl_exec($ch);

curl_close($ch);

return $result;
}

$urlAut = "https://auth.vezetvsem.ru/auth/login";

login($urlAut,"XXX","XXX");

$page = Read("http://www.vezetvsem.ru/listing");

echo $page;
?>
#508 #782503
ПИШЕТ ЗАДРОТ ПРОГРАММИСТ

Привет Ананасы. Пишу парсер для автоматизации. Затупняк произошел на этапе авторизации
Вот сайтик
http://www.vezetvsem.ru/listing

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

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

>>


<?
function login($url,$login,$pass){

$ch = curl_init();
if(strtolower((substr($url,0,5))=='https')) { // если соединяемся с https
//моя вставка
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
//моя вставка
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
}
curl_setopt($ch, CURLOPT_URL, $url);
// откуда пришли на эту страницу
curl_setopt($ch, CURLOPT_REFERER, $url);
// cURL будет выводить подробные сообщения о всех производимых действиях
curl_setopt($ch, CURLOPT_VERBOSE, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,"username=".$login."&password=".$pass);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);

echo "username=".$login."&password=".$pass;
//сохранять полученные COOKIE в файл
curl_setopt($ch, CURLOPT_COOKIEJAR, $_SERVER['DOCUMENT_ROOT'].'/cookie.txt');
$result=curl_exec($ch);

// Убеждаемся что произошло перенаправление после авторизации
if(strpos($result,"Location: home.php")===false) die('Login incorrect');

curl_close($ch);

return $result;
}

// чтение страницы после авторизации
function Read($url){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_COOKIESESSION, true);
// откуда пришли на эту страницу
curl_setopt($ch, CURLOPT_REFERER, $url);
//запрещаем делать запрос с помощью POST и соответственно разрешаем с помощью GET
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
//отсылаем серверу COOKIE полученные от него при авторизации
curl_setopt($ch, CURLOPT_COOKIEFILE, $_SERVER['DOCUMENT_ROOT'].'/cookie.txt');
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (Windows; U; Windows NT 5.0; En; rv:1.8.0.2) Gecko/20070306 Firefox/1.0.0.4");

$result = curl_exec($ch);

curl_close($ch);

return $result;
}

$urlAut = "https://auth.vezetvsem.ru/auth/login";

login($urlAut,"XXX","XXX");

$page = Read("http://www.vezetvsem.ru/listing");

echo $page;
?>
>>797241
#509 #782508
ПИШЕТ ЗАДРОТ ПРОГРАММИСТ

Привет Ананасы. Пишу парсер для автоматизации. Затупняк произошел на этапе авторизации
Вот сайтик
http://www.vezetvsem.ru/listing

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

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

http://pastebin.com/Vcv7TYcG

Научился сокращать ссылки, просто игнорьте верхний
>>797241
#510 #782606
Так как всё таки перестать мыслить процедурщиной и въехать в ооп? Я так и не могу приступить к задаче на регистрацию студентов, ибо не понимаю что должно быть в центре этого всего.

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

Почему контроллеры должны быть объектами? Мне аж плохо от того какой я тупой.
>>782656>>782709
#511 #782652
Зачем в php тип resource? Чому просто объект не сделали? Где-то он при разработке как-то по-особому используется?
>>782709
#512 #782656
>>782606
Контроллеры объекты, чтобы их можно было заменять из одной точки. Был у тебя контроллер PageAController, а потом ты решил быстро поменять на другую страницу, в точке входа заменил на PageBController, и если у контроллеров был общий интерфейс, то все по-прежнему работает, а страница уже другая. Это можно использовать в роутере например.
Открой любой фреймворк типа zend, сразу понятно станет, там гора контроллеров для каждого пути в url, и нужный по цепочке вызывается. Можешь свой роутер-диспатчер подобным образом написать. Ну и кроме того, когда много контроллеров, то куда проще в коде ориентироваться, чем когда гора страниц свалена в один контроллер с кучей методов.
>>782689
#513 #782659
Как в PHP CURL перед вызовом SFTP сессии команду прокинуть? Winscp умеет, пишу sudo su -c /usr/libexec/openssh/sftp-server, и все с Amazon Cloud работает по SFTP. Клиент сразу после соединения и авторизации кидает эту команду, потос сама сессия sftp идет. Искал такое же в PHP curl, что-то не нашел сразу. Авторизацию у меня проходит и все шаги соединения по curl, только эта команда до начала sftp не вставляется. Может сталкивался кто?
>>782664
#514 #782664
>>782659
https://winscp.net/eng/docs/faq_su
Речь об этой фиче идет.

>In some cases (with Unix/Linux server) you may be able to use sudo command straight after login to change a user, before file transfer session starts.


>The SFTP and SCP protocols allow for this, but the actual method is platform dependent.


Как ее в curl включить?
>>782884
#515 #782689
>>782656
Да я ничего не понял из твоего объяснения, как же горит блин :(
>>782694
#516 #782694
>>782689
Сделай 2 страницы с 2мя контроллерами и разным контентом в них, а потом напиши роутер, и сделай, чтобы по вызову /url1 вызывалась первая страница, а по /url2 вторая. Вот решишь ты их поменять местами, чтобы наоборот вызывались, тут к тебе и придет озарение, зачем контроллеры в виде объектов с общим интерфейсом нужны.
#517 #782709
>>782652

Этот тип по моему появился раньше чем сами объекты.

>>782606

Платиновый вопрос: а ты решил кошки-мышки и вектор?

> Почему контроллеры должны быть объектами?


А почему нет? Объект который отвечает за обработку запроса:

$newsController = new NewsController;
$newsController->latestNewsAction();

Или так, в стиле Симфони:

$newsController = new NewsController;
$response = $newsController->latestNewsAction($request);

Или так, в стиле микрофрейморков:

$newsController = new NewsController;
$response = new Response;
$newsController->latestNewsAction($request, $response);
>>782735
#518 #782735
>>782709

>$newsController = new NewsController;


>$newsController->latestNewsAction();



Так а зачем ему объект то? Что бы просто было к чему обращаться? Я не могу понять как тут объекты отличаются от массивов блин в целом. Что значит состояние и пр?
Для меня создание объекта в коде это лишние телодвижения, и получается, что проще и логичнее было бы использовать абстрактные классы:
NewsController::latestNewsAction();

Что-то я совсем в общем запутался, надо с 0 всё начинать.
>>782740
#519 #782740
>>782735

Почитай про статические методы https://github.com/codedokode/pasta/blob/master/arch/di.md

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

$newsController = new NewsController;
if ($debug) {
$newsController->setDebugMode(true);
}

....

$newsController->latestNewsAction();
#520 #782863
>>781794

>- сделать кеш DNS. Если у нас несколько ссылок с одним и тем же доменом, незачем отправлять несколько запросов. Достаточно отправить только 1 DNS запрос



Как бы операционка это делает сама, дополнительно в коде такого делать не стоит. Разве что в учебных целях...
>>782894
#521 #782884
>>782664
Как вариант, тебе можно попробовать вообще забить на curl и из пхп-скрипта просто позапускать нужные консольные команды
http://php.net/manual/ru/function.shell-exec.php
#522 #782894
Аноны, интересный пост про историю CSS и какие варианты предлагались вместо него много лет назад (англ): https://eager.io/blog/the-languages-which-almost-were-css/

>>782863

Не всегда. зависит от версии ОС и конфигурации. И используемого DNS клиента. С чего ты решил что в твоей версии ОС это так? С чего ты решил что твоя библиотека DNS запросов это поддерживает?

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

>Sublime vs PHPStorm


> не стану ли макакой



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


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


В шторме есть много годноты, типа менеджера баз данных, подключения к серверу и синхронизация, гит, крутая навигация.
Накрутить все это на Атом я нормально не смог, не знаю, как с этим у саблайма.
Но для себя пока альтернатив шторму не вижу.
#524 #783027
Вопрос опу по файлообменнику! Оп дает подсказку в задании:

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



Как это понимать? В txt переименовывать любые файлы или только php формата? В первом случае у нас будет папка целиком состоящая из txt файлов, для удобства администратора нужно добавлять префикс какого этого формата файл? И каким образом менять формат на ранний из $_FILES["userfile"]["type"]? Притом там четко не написан формат, что-то в духе "text/plain", "png/jpeg", т.е. для класса модели файла нужно еще добавить свойство с точным форматом "png", "mp3" etc?

Алсо еще вопросики.

Как в PHP происходит скачка файлов? По прямому адресу example.com/file.txt?

Нужно ли хранить файлы в бд или только в папке? В последнем случае выходит так, что в бд хранится только информация о файле и комментарии?

Заранее извиняюсь за возможную расплывчатость первого вопроса.
>>783061>>784398
#525 #783061
>>783027
НЕ ОП

>переименовывание файлов при загрузке с безопасным расширением вроде .txt



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

>Как в PHP происходит скачка файлов? По прямому адресу example.com/file.txt?



Можно так, но есть и другие способы.
https://habrahabr.ru/post/151795/

>Нужно ли хранить файлы в бд или только в папке?


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

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


Да
#527 #783119
https://github.com/foobar1643/filehosting

Юнит тесты и исправление замечаний.
>>785183
#528 #783136
>>782110
так что, вариантов нет?
#529 #783140
Привет, подскажите мне надо реализовать задачу в которой запускается функция, но в зависимости от параметров которые она вернула в прошлый раз. Собственно задачу реализовал, но мне хочется поменять архитектуру с использованием какого то паттерна проектирования.
>>785089
#530 #783307
Анон, выручай. Будет ли работать код(отправка смс)?
Не могу проверить, тк договор не заключил и смски слать не могу.
Вот API
http://www.devinotele.com/resheniya/dokumentaciya-po-api/https_rest_without_sessionid/Otpravka_SMS-soobshcheny1/
вот код
https://ideone.com/Y1uObt
>>785089
#531 #783331
>>777652
ee
с емаксом тоже станешь.
173 Кб, 1366x768
#532 #783443
Народ, выручайте. Как прерывать цикл? Нужно посчитать, сколько денег будет стоить кредит от банка, а этот пидорас берет и уходит в минус, не прерывается. Куда этот break запихнуть и куда поставить условие этого самого прерывания?
>>783469>>785089
#533 #783469
>>783443
Никуда не ставь, делай цикл через while($deposit!=0) и в теле добавь проверку того, что остаток на счете больше следующего платежа.
>>785089
#534 #783745
Хочу вкатиться в програмирование. Пока выбрал PHP.
Но насколько реально зарабатывать на PHP? Или огромная конкуренция не даст шанса новичкам? Что выгоднее, фриланс или офис? Как вообще у вас с заработками?
>>783753>>784832
#535 #783753
>>783745

>вкатиться в программирование


>зарабатывать


===

>научиться читать на английском


>зарабатывать переводами

someApprentice #536 #783964
>>773648

>Вместо include __DIR__ . '/../../templates/registration.phtml'; лучше было бы сделать метод $this->render('templates/registration.phtml')


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

>>780899

>Анон который https://github.com/someApprentice/Students


>


>Напоминаю: для тебя тут отдельный пост написан >>779261


Да, простите что сразу не отписался. У меня просто не возникло вопросов по этому посту.
>>785089
#537 #784017
Почти сделал кошек-мышек, пока оценочная функция работает только для кошки, если на соседней клетке оказалась мышь. А также не сделана функция объединения мышей.

http://ideone.com/0hmsEY // Кошки-мышки
>>797241
someApprentice #538 #784215
А есть у кого-нибудь архив прошлого треда?
>>784220>>785087
#540 #784233
ОПчик и посоны, есть простой массив объектов вида
class MyStructure {
public $age;
public $canName;
public $readableName;
}

Могу ли я сортировать массив объектов по значению свойств? Например по $MyStructure->age или по другому свойству?
>>784251
#541 #784251
>>784233
сам спросил. сам ответил = usort + callback
у меня плохо с пространственными абстракциями, но раком-боком додумал.
>>785086
#542 #784258
Тада вопрсо такой: а это вообще норм - использовать объекты без методов чисто как удобное хранилище данных? и использовать методы класса ДатаМаппера чисто чтобы загружать такие объекты в базу данных?
#543 #784286
>>784220
Это 75 а нужно 77.
#544 #784330
Друзья, CodeIgniter в качестве первого Фреймворка ок?
>>784368>>785086
#545 #784368
>>784330
Критическое мышление. Ок?
#546 #784396
Есть какие-нибудь годные бесплатные онлайн-курсы по пхп и иже с ним?
>>784424>>784427
#547 #784398
>>783027
Еще вопрос от меня же >>783027. В файлообменнике надо бороться с CSRF уязвимостью, если нету регистрации?
>>784410
#548 #784410
>>784398
В форме загрузки файла не нужно, но если захочешь сделать к примеру удаление файла, то в таком случае нужно будет защитить форму удаления.
>>785086
#549 #784423
Шаблон стратегия и задача Кошки-Мышки.

Применим ли этот шаблон к оценочной функции для классов Кошка/Мышка/Собака в задаче Кошки-Мышки? Или целесообразнее создать один общий метод в суперклассе Животное, а затем в дочерних классах Кошка/Мышка/Собака расширить этот метод, добавив специфический алгоритм для каждого класса?
>>785086
#550 #784424
>>784396
нет
#551 #784427
>>784396
Борисова ищи на nmn-club (курсы специалиста). Основы разжевываются хорошо, лично я к третьему курсу бросил и сел за студентов.
#552 #784477
Куда в этой задаче надо было впаять 2 функции?

http://ideone.com/SxVvA2
>>784481>>785081
#553 #784481
>>784477
Что, простите? Какие две функции, о чём вы несёте?
#554 #784708
>>784258
Подобные обьекты называются DTO - data transfer object. И да - их часто используют, просто как удобный "контейнер" для переноса данных внутри приложения.

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

Как DTO обычно оформляют всякую фигню, типа обьектов, содержащих внутри чистую инфориацию, без поведения. Например строки из таблички статистики, или рассчитываемую каким нибудь классом-калькулятором статистику
>>785128
#555 #784832
>>783745
Конкуренция только среди новичков и есть. Если у тебя нормальные скиллы, ее не ощущается почти, везде берут, всем нужен. Но ты попробуй эти скиллы набери, почти все время на это уходит, универ проще закончить, чем хорошим программистом стать.
>>784929
#556 #784839
>>784258
Да, это называется Value Objects. Они не должны быть изменяемыми, иначе у тебя будут проблемы:
http://www.c2.com/cgi/wiki?ValueObjectsShouldBeImmutable
>>785081
#557 #784928
Что-то ОП куда-то пропал. Наверное взял отпуск и тратит свои заработанные миллиарды в компании порядочных женщин.
#558 #784929
>>784832
А в каких сферах нужны прокаченные скиллы для php, ведь 80% вакансий это клонниннг веб магазинов средней руки?
>>785428
#559 #784973
Аноны, а зачем нужны эти PSR 7 классы ServerRequestInterface и ServerResponse?
В таких фреймворках как Slim, например.
В документации написано
Слим получает HTTP запрос, выполняет коллбек функцию и возвращает HTTP ответ.

В чем удобство этого? Какие то конкретные плюсы?
Почему нужно делать $request->getQueryParams()['name'] вместо $_GET['name'] ?

И в чем удобство каждый раз очевидно изменять ( $response->getBody->write() )
и возвращать Response в конце?

И в чем вообще смысл Slim фреймворка тогда? Не только же чтобы роут и контейнер типа в комплекте получить (Tам Pimple container и nikis/fast-route) ?
>>785067>>785081
#560 #784979
Можно ли как нибудь настроить дебаггер в phpstorm так чтобы он ловил не только прямые ссылки на хост: local.site.com но и second.local.site.com и тд? Есть ли аналог *.local.site.com ?
>>797242
#561 #784985
Кто-нибудь обновлял PHP в денвере? До какой версии стоит обновиться?

Нужно установить XDebug, но на оф сайте бинарки для win для PHP 5.4 и выше. А в денвере PHP 5.3. Поэтому нужно либо обновить PHP в денвере, либо попробовать установить Vagrant+PuPHPet от сюда https://habrahabr.ru/post/212009/.
Что будет проще?

Настроить среду своими руками не предлагать, мне кажется это слишком долго, шансы на успех сомнительны, а выгода не очевидна.
#562 #784989
>>784985

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


Что там сомнительного? Ты же не собираешься это в интернет выводить, для локальной сети все будет работать уже из коробки даже на линуксе (если брать апач + php5).
>>785006
#563 #785006
>>784989
Сперва настроить апач
потом mysql
потом php
а потом обнаружить ошибку, заниматься с ней страстным сексом сутки напролет, так и не поняв, какие из пол сотни установленных программ конфликтуют.
>>785067
14 Кб, 358x397
#564 #785044
>>784985

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


Чё-т в голосяку с тебя.
Сам таким был, пока не установил за 15 минут Apache, PHP7.1.0, MySQL и PHPStorm.
А ведь вплоть до ООП по учебнику ОПа всё делал исключительно на Ideone...
Сборки не нужны абсолютно.
Но это ты сам должен дойти, я тебя не переубежу.
>>785051>>785092
128 Кб, 314x278
#565 #785051
>>785044

>PHP7.1.0


Это же дев версия, зачем ты её установил? Последняя stable 7.0.8.
>>785248
#566 #785067
>>785006

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

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

Иногда гугление помогает, но иногда выдает много лишнего.

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

>>784985

Лучше снести денвер и поставить все руками. В Оп посте есть не очень информационные, но вдохновляющие и ободряющие пасты по теме.

>>784985

Вагрант много лишнего же тянет вроде руби. Не лучше найти/сделать образ для виртуалбокса?

>>784973

Ну давай погуглим вместе. Вот что я нашел по словам PSR-7:

- https://5minphp.ru/episode2/

А теперь касательно вопроса.

> а зачем нужны эти PSR 7 классы ServerRequestInterface и ServerResponse?



Открываем PSR-7:

> RequestInterface provides the general representation of an HTTP request message. However, server-side requests need additional treatment, due to the nature of the server-side environment.


> ServerRequestInterface extends RequestInterface to provide an abstraction around these various superglobals.



RequestInterface это HTTP-запрос.
ServerRequestInterface это HTTP-запрос, который содержит дополнительную информацию, которую добавляет например PHP или Апач когда разбирает пришедший запрос. Какую? Давай глянем в код:

> https://github.com/php-fig/http-message/blob/master/src/ServerRequestInterface.php


> public function getServerParams();


> public function getCookieParams();


> public function getQueryParams();


> public function getAttribute($name, $default = null);


Как видишь тут всякие параметры которые соответствуют переменные $_GET, $_SERVER и тд.

> В чем удобство этого? Какие то конкретные плюсы?


у нас есть объект представляющий запрос. В отличие от $_GET/POST:

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

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

function doSpmething(Request $request)

А с глобальными переменными это неудобно - не будешь же ты передавать 5 переменных по отдельности.

Ну и это упрощает написание того же middleware в Слиме. Оно может что-то сделать с запросом и с ответом на него.

> $request->getQueryParams()['name'] вместо $_GET['name'] ?


как-то некрасиво выглядит.

> И в чем удобство каждый раз очевидно изменять ( $response->getBody->write() )


> и возвращать Response в конце?


В том что потом с респонсом можно что-то сделать. Например проверить соответствие ожиданию или как-то преобразовать.

Ну например у тебя есть функция которая авторизует пользователя (выставляя куки). Как ее тестировать автоматизированно если она делает setcookie? да никак. Потому что ты не можешь получить куки которые она выставила и проверить их (без хаков с перехватом вызова setcookie).

А вот с Response ты можешь взять и посмотреть что она там поставила.

> И в чем вообще смысл Slim фреймворка тогда? Не только же чтобы роут и контейнер типа в комплекте получить (Tам Pimple container и nikis/fast-route) ?


Что ты получаешь, описано в документации. Роутер, контейнер, реквест, респонс, обработчик ошибок, может еще что-то, все отлаженное и протестированное.
#566 #785067
>>785006

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

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

Иногда гугление помогает, но иногда выдает много лишнего.

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

>>784985

Лучше снести денвер и поставить все руками. В Оп посте есть не очень информационные, но вдохновляющие и ободряющие пасты по теме.

>>784985

Вагрант много лишнего же тянет вроде руби. Не лучше найти/сделать образ для виртуалбокса?

>>784973

Ну давай погуглим вместе. Вот что я нашел по словам PSR-7:

- https://5minphp.ru/episode2/

А теперь касательно вопроса.

> а зачем нужны эти PSR 7 классы ServerRequestInterface и ServerResponse?



Открываем PSR-7:

> RequestInterface provides the general representation of an HTTP request message. However, server-side requests need additional treatment, due to the nature of the server-side environment.


> ServerRequestInterface extends RequestInterface to provide an abstraction around these various superglobals.



RequestInterface это HTTP-запрос.
ServerRequestInterface это HTTP-запрос, который содержит дополнительную информацию, которую добавляет например PHP или Апач когда разбирает пришедший запрос. Какую? Давай глянем в код:

> https://github.com/php-fig/http-message/blob/master/src/ServerRequestInterface.php


> public function getServerParams();


> public function getCookieParams();


> public function getQueryParams();


> public function getAttribute($name, $default = null);


Как видишь тут всякие параметры которые соответствуют переменные $_GET, $_SERVER и тд.

> В чем удобство этого? Какие то конкретные плюсы?


у нас есть объект представляющий запрос. В отличие от $_GET/POST:

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

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

function doSpmething(Request $request)

А с глобальными переменными это неудобно - не будешь же ты передавать 5 переменных по отдельности.

Ну и это упрощает написание того же middleware в Слиме. Оно может что-то сделать с запросом и с ответом на него.

> $request->getQueryParams()['name'] вместо $_GET['name'] ?


как-то некрасиво выглядит.

> И в чем удобство каждый раз очевидно изменять ( $response->getBody->write() )


> и возвращать Response в конце?


В том что потом с респонсом можно что-то сделать. Например проверить соответствие ожиданию или как-то преобразовать.

Ну например у тебя есть функция которая авторизует пользователя (выставляя куки). Как ее тестировать автоматизированно если она делает setcookie? да никак. Потому что ты не можешь получить куки которые она выставила и проверить их (без хаков с перехватом вызова setcookie).

А вот с Response ты можешь взять и посмотреть что она там поставила.

> И в чем вообще смысл Slim фреймворка тогда? Не только же чтобы роут и контейнер типа в комплекте получить (Tам Pimple container и nikis/fast-route) ?


Что ты получаешь, описано в документации. Роутер, контейнер, реквест, респонс, обработчик ошибок, может еще что-то, все отлаженное и протестированное.
>>785273>>785674
#567 #785081
>>784973

Ну и как ты без этих объектов опишешь функцию-контроллер? С ними все логично: контроллер получает на вход request и возвращает response. Ну или получает на вход request и response и пишет в response данные.

>>784839

Модели это не value objects. Они могут меняться, для этого и сделаны.

>>784477

"впаять" вроде ничего и не требовалось.

> PHP Notice: Undefined variable: uppertext in /home/C4Oe7Z/prog.php on line 18



А вот эту ошибочку надо бы исправить. Обращаешься к еще не существующей переменной.

> mb_substr($value, -mb_strlen($value) + 1);


надо писать mb_substr($value, 1);

> foreach ($sentence as $value){


foreach ($sentences as $sentence)

> ([.,:;!?])([а-яёa-z])


Работает только с маленькими буквами, а если там большая?

Тут появляется лишняя точка: http://ideone.com/1W1G35
#567 #785081
>>784973

Ну и как ты без этих объектов опишешь функцию-контроллер? С ними все логично: контроллер получает на вход request и возвращает response. Ну или получает на вход request и response и пишет в response данные.

>>784839

Модели это не value objects. Они могут меняться, для этого и сделаны.

>>784477

"впаять" вроде ничего и не требовалось.

> PHP Notice: Undefined variable: uppertext in /home/C4Oe7Z/prog.php on line 18



А вот эту ошибочку надо бы исправить. Обращаешься к еще не существующей переменной.

> mb_substr($value, -mb_strlen($value) + 1);


надо писать mb_substr($value, 1);

> foreach ($sentence as $value){


foreach ($sentences as $sentence)

> ([.,:;!?])([а-яёa-z])


Работает только с маленькими буквами, а если там большая?

Тут появляется лишняя точка: http://ideone.com/1W1G35
#568 #785086
>>784423

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

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

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

>>784410

Совершенно верно.

>>784330

Он старый и плохо спроектированный. Лучше Слим и файлообменник, но нет информации на русском.

>>784258

Нормально.

>>784251

Верно
#569 #785087
#570 #785089
>>783964

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



Можно, так наверно даже правильнее, но там по сути render это функция из 5 строк в простейшем случае (распаковать переменные + приинклудить файл) так что стоит ли ради нее отдельный класс городить? А так, можно.

>>783469

Надежнее while ($deposit > 0)

>>783443

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

>>783307

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

>>783140

Тут не нужны паттерны. Просто надо подавать на вход функции ее предудущий результат.

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

>>782110

Попробуй отсортировать диапазоны и искать методом деления пополам. Хотя если у тебя их немного то проще обычным циклом.
#570 #785089
>>783964

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



Можно, так наверно даже правильнее, но там по сути render это функция из 5 строк в простейшем случае (распаковать переменные + приинклудить файл) так что стоит ли ради нее отдельный класс городить? А так, можно.

>>783469

Надежнее while ($deposit > 0)

>>783443

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

>>783307

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

>>783140

Тут не нужны паттерны. Просто надо подавать на вход функции ее предудущий результат.

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

>>782110

Попробуй отсортировать диапазоны и искать методом деления пополам. Хотя если у тебя их немного то проще обычным циклом.
#571 #785092
>>785044

> установил за 15 минут Apache, PHP7.1.0, MySQL


Ты ставил на *nix-систему или win?
>>785248
#572 #785128
>>784708

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


Хоть ты тресни, не пойму, какой у юзера можеь быть поведение. Ну логин, ну пароль, ну "роль" (админ\не админ).
МОжешь привести простой пример?
#573 #785129
>>785128

>>Ну логин, ну пароль, ну "роль" (админ\не админ).


Ну то есть вот это перечилсенное - это совйства, но не поведение.
https://github.com/foobar1643/filehosting/ #574 #785183
>>783119

О, тесты, это интересно.

Давай начнем с вопроса, зачем мы пишем тесты? Не потому что ОП так сказал. Есть разные причины:

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

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

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

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

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

Это же относится к функциональным тестам (эмуляции поведения человека). Мы не хотим писать тест вида "после ввода логина и пароля выставляется кука с именем X". мы хотим писать тест "после ввода логина и пароля пользователь видит личный кабинет и свое имя в углу".

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

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

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

Теперь посмотрим на твои тесты.

> https://github.com/foobar1643/filehosting/blob/master/tests/ConfigTest.php#L17


> testGetValue()


Тест полагается на знание значения по умолчанию установленного для поля db.host. Получается ты тестируешь требование "конфиг должен содержать по умолчанию значение X для поля Y", а не функцию получения знаечния. Как бы это сделать лучше? Я вижу такие варианты:

- задать значение поля и проверить что оно читается
- прочитать специально подготовленный конфиг-файл и проверить что значения из него читаются

Я бы выбрал второе. Оно близко к реальному сценарию использования класса Config. Правда это будет тест не только функции get но и чтения файла, ну да ладно. Файл можно либо положить в отдельную папку (напр. test/assets) либо создавать во временной папке на время теста. Либо попробовать использовать какую-нибудь фичу пхп вроде php://memory ( http://php.net/manual/ru/wrappers.php.php ) если она конечно заработает (а нет, там надо передавать файловый дескриптор).

> public function testFailureGetValue()


Этот сценарий написан хорошо, только я бы сделал имя не example, а более говорящее nonExistingKey.

> https://github.com/foobar1643/filehosting/blob/master/app/Translator.php


> public function translatePlural($text, $number)


Эта функция мне не нравится. Это какая-то урезанная версия $messageFormatter->format принимающая только один аргумент. Не очень понимаю, зачем она тут.

https://github.com/foobar1643/filehosting/blob/master/tests/Entity/CommentEntityTest.php#L14
Тут как-то непонятно:

> $children = self::$rootComment->getChildren();


> self::$deepComment = $children[6]->getChildren()[7]


Что-то странно, мы в rootComment вроде всего 3 комментария добавили, откуда взялась цифра 6?

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

- протестировать addChildNode() для коммента, который уже является чьим-то ребенком

> public function getDepth()


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

https://github.com/foobar1643/filehosting/blob/master/app/Entity/File.php#L29

> $this->file = $uploaded->file;


> $this->error = $uploaded->getError();


В классе нет поля error и file. Да и по моему логичнее просто запретить создавать File из битых файлов. Насчет type - его лучше не брать от клиента а определять из getId3.

> public function getFormattedSize()


Вообще конечно это надо было в хелпер статическим методом выносить. Может ведь и не для файла пригодиться. Алсо килобайт это 1024 байта.

> public function getDiskName()


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

https://github.com/foobar1643/filehosting/blob/master/tests/Entity/FileEntityTest.php#L21

> public function testGetExtension()


Тут стоило бы тестировать экзотиечские случае - имя файла, начинающееся с точки, файл без расширения, файл с несколькими расширениями, файл с расширением не из букв.

> public function testGetFolder()


Вот тут по моему мы опять начинаем тестировать внутреннюю реализацию. Я бы просто проверял что эта функция возвращает что-то похожее на имя папки.

> testGetDiskName()


> public function testGetDownloadLink()


Тут тоже идет тестирование реализации. Стоит поменять формат ссылок и все ломается. Я бы сделал так:

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

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

Конечно если у тебя ТЗ вида "ссылка должна иметь вид XXX" то такой тест ему соответствует. Но мне больше нравится тест вида "можно закачать файл и скачать его по ссылке".

> class FileEntityTest extends TestCase


> protected static $file;


Почему static? Один обший файл на любое число тестовых объектов? Тут же нет причин ставить static.
https://github.com/foobar1643/filehosting/ #574 #785183
>>783119

О, тесты, это интересно.

Давай начнем с вопроса, зачем мы пишем тесты? Не потому что ОП так сказал. Есть разные причины:

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

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

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

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

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

Это же относится к функциональным тестам (эмуляции поведения человека). Мы не хотим писать тест вида "после ввода логина и пароля выставляется кука с именем X". мы хотим писать тест "после ввода логина и пароля пользователь видит личный кабинет и свое имя в углу".

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

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

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

Теперь посмотрим на твои тесты.

> https://github.com/foobar1643/filehosting/blob/master/tests/ConfigTest.php#L17


> testGetValue()


Тест полагается на знание значения по умолчанию установленного для поля db.host. Получается ты тестируешь требование "конфиг должен содержать по умолчанию значение X для поля Y", а не функцию получения знаечния. Как бы это сделать лучше? Я вижу такие варианты:

- задать значение поля и проверить что оно читается
- прочитать специально подготовленный конфиг-файл и проверить что значения из него читаются

Я бы выбрал второе. Оно близко к реальному сценарию использования класса Config. Правда это будет тест не только функции get но и чтения файла, ну да ладно. Файл можно либо положить в отдельную папку (напр. test/assets) либо создавать во временной папке на время теста. Либо попробовать использовать какую-нибудь фичу пхп вроде php://memory ( http://php.net/manual/ru/wrappers.php.php ) если она конечно заработает (а нет, там надо передавать файловый дескриптор).

> public function testFailureGetValue()


Этот сценарий написан хорошо, только я бы сделал имя не example, а более говорящее nonExistingKey.

> https://github.com/foobar1643/filehosting/blob/master/app/Translator.php


> public function translatePlural($text, $number)


Эта функция мне не нравится. Это какая-то урезанная версия $messageFormatter->format принимающая только один аргумент. Не очень понимаю, зачем она тут.

https://github.com/foobar1643/filehosting/blob/master/tests/Entity/CommentEntityTest.php#L14
Тут как-то непонятно:

> $children = self::$rootComment->getChildren();


> self::$deepComment = $children[6]->getChildren()[7]


Что-то странно, мы в rootComment вроде всего 3 комментария добавили, откуда взялась цифра 6?

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

- протестировать addChildNode() для коммента, который уже является чьим-то ребенком

> public function getDepth()


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

https://github.com/foobar1643/filehosting/blob/master/app/Entity/File.php#L29

> $this->file = $uploaded->file;


> $this->error = $uploaded->getError();


В классе нет поля error и file. Да и по моему логичнее просто запретить создавать File из битых файлов. Насчет type - его лучше не брать от клиента а определять из getId3.

> public function getFormattedSize()


Вообще конечно это надо было в хелпер статическим методом выносить. Может ведь и не для файла пригодиться. Алсо килобайт это 1024 байта.

> public function getDiskName()


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

https://github.com/foobar1643/filehosting/blob/master/tests/Entity/FileEntityTest.php#L21

> public function testGetExtension()


Тут стоило бы тестировать экзотиечские случае - имя файла, начинающееся с точки, файл без расширения, файл с несколькими расширениями, файл с расширением не из букв.

> public function testGetFolder()


Вот тут по моему мы опять начинаем тестировать внутреннюю реализацию. Я бы просто проверял что эта функция возвращает что-то похожее на имя папки.

> testGetDiskName()


> public function testGetDownloadLink()


Тут тоже идет тестирование реализации. Стоит поменять формат ссылок и все ломается. Я бы сделал так:

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

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

Конечно если у тебя ТЗ вида "ссылка должна иметь вид XXX" то такой тест ему соответствует. Но мне больше нравится тест вида "можно закачать файл и скачать его по ссылке".

> class FileEntityTest extends TestCase


> protected static $file;


Почему static? Один обший файл на любое число тестовых объектов? Тут же нет причин ставить static.
>>785399
https://github.com/foobar1643/filehosting/ #575 #785184
https://github.com/foobar1643/filehosting/blob/master/tests/Helper/AuthHelperTest.php
О, вот тут как никогда много тестирования внутренней реализации. Чего стоит вот это место:

> $this->assertRegExp('/^[\d\w]{45}$/', CookieUtils::getResponse($response, 'auth')->getValue());


Это не тест авторизации. Это тест того что хелпер ставит куку длиной 45 символов из определенного набора.

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

Я бы предложил такой тест:

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

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

> public function testCanManageFile()


> {


> $file = $this->createMock(File::class);


> $file->method('getAuthToken')->willReturn('1234567890');


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

https://github.com/foobar1643/filehosting/blob/master/tests/Helper/CommentAdditionTest.php
Вот тут по сути идет тестирование реализации. Ну например вот этот вот код

> $mapperMock->method('getComment')->willReturn($commentMock);


даже аргументы не проверяет. Тест как итог выглядит странно:

> $expected->setId(1)->setParentId(1);


Понятно что это легко сломать если добавить проверку в Comment что parentId <> id.

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

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

https://github.com/foobar1643/filehosting/blob/master/app/Helper/CommentHelper.php#L16

> if($comment->getParentId() != NULL) {


> $parentComment = $this->commentMapper->getComment($comment->getParentId());


Ты используешь id в пути. Какая у тебя длина элемента пути? 3 символа? Это значит нельзя создать более 1000 комментариев на всем сайте. Надо использовать не id, а порядковый номер комментария среди братьев.

И кстати это позволит делать вставку одним инсертом.

Составные операции надо делать транзакцией.

В реализации комментария есть один сомнительный момент.У тебя там есть getChild() но всегда ли комментарии организованы в дерево? Что если мы выбираем один комментарий из базы? Что если мы хотим загрузить только часть дерева? В более сложном приложении стоило бы вынести древовидную структуру наружу из класса Comment либо использовать ленивую загрузку которая есть в доктрине.

> public function makeTrees($comments)


Эту функцию кстати можно тестировать.

> public function appendToPath($old, $new)


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

> public function getMargin($path)


Это не часть модели а часть вью.

https://github.com/foobar1643/filehosting/blob/master/tests/Helper/PaginationHelperTest.php#L30
Тут я бы не тестировал вид ссылки, а тестировал что она похожа на ссылку и разная для разных страниц

https://github.com/foobar1643/filehosting/blob/master/tests/Helper/TokenGeneratorTest.php
Вот по этому поводу я выше писал другому анону: http://pastebin.ru/t5Z34Uyu

> Factory::requestFactory()


Я бы назвал createRequest().

https://github.com/foobar1643/filehosting/blob/master/tests/Middleware/CsrfMiddlewareTest.php
Я бы тут тоже поменьше опирался на реализацию и тестировал бы только публичный интерфейс класса. То есть получил бы токен и попробовал бы проверить запрос с ним.

https://github.com/foobar1643/filehosting/blob/master/tests/Middleware/LocaleMiddlewareTest.php
Здесь чтобы что-то сказать надо разбираться в коде класса.

https://github.com/foobar1643/filehosting/blob/master/tests/Validation/ValidationTest.php#L37

> $this->validator = new Validation($container);


Ой, что это? serviceLocator вместо dependency injection. Заметь что здесь твой тест опирается на предположение что валидатору нужны ровно 3 зависимости.

Ну и я думаю, было бы неплохо еще сделать интеграционные (с базой) и функциональные (браузерные) тесты. Если ты не используешь яваскрипт, то можно использовать например эмулятор HTML браузера http://symfony.com/doc/current/book/testing.html#functional-tests , если нужен яваскрипт то придется использовать протокол Селениума, а в качестве эмулятора браузера подойдет phantomjs (придется повозиться с настройкой и работать будет конечно медленнее).

Браузерные тесты это отдельная сверхзадача, например как искать элементы? По классу? По id? По тексту? По имени поля формы? Какой из способов наиболее устойчив к изменениям верстки?

По локализации.

Я уже писал, что встроенная в Твиг локализация мне не нравится. Ну, твиг расширяемый, ты можешь при большом желании даже теги свои добавлять если не боишься. Мне например не нравится длинный синтаксис ({% trans %}) и отсутствие поддержки подстановок разных параметров как в formatMessage.

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

https://github.com/foobar1643/filehosting/blob/master/templates/comments.twig#L4

> <p class="pull-right"><small>{{ comment.getDatePosted }}</small></p>


В разных странах разные форматы записи дат. Твоя архитектура это не учитывает. Обычно используют объект-форматировщик дат вроде того что есть в Intl.

> <span class="comment-text">{{ comment.getCommentText }}</span>


Не сохраняются переводы строк

> <form method="post" id="fallback-reply-form" action="/{{ lang }}/file/{{ comment.fileId }}/">


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

> <h4>{% trans %}Search results for {% endtrans %} <i>&laquo;{{ query }}&raquo;</i></h4>


Вот еще одно сомнительное место. Ты предполагаешь что запрос будет идти в конце предложения, но в азиатских языках порядок слов другой и запрос может идти в начале или середине: "NNN запрос отправленный на результаты": https://translate.google.com/#en/ja/search results for query NNN (бинг выдал более точный на мой взгляд перевод где запрос идет в начале, но в нем ссылку нельзя скопировать).

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

Еще один подвох - перевод текста в JS скриптах. Для них приходится либо выносить переменные с текстом в шаблон либо писать свою систему переводов, скрипты сбора текстов, генерации файлов переводов, функции форматирования дат и тд. Кстати в JS вроде что-то было добавлено для локализации не так давно.
https://github.com/foobar1643/filehosting/ #575 #785184
https://github.com/foobar1643/filehosting/blob/master/tests/Helper/AuthHelperTest.php
О, вот тут как никогда много тестирования внутренней реализации. Чего стоит вот это место:

> $this->assertRegExp('/^[\d\w]{45}$/', CookieUtils::getResponse($response, 'auth')->getValue());


Это не тест авторизации. Это тест того что хелпер ставит куку длиной 45 символов из определенного набора.

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

Я бы предложил такой тест:

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

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

> public function testCanManageFile()


> {


> $file = $this->createMock(File::class);


> $file->method('getAuthToken')->willReturn('1234567890');


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

https://github.com/foobar1643/filehosting/blob/master/tests/Helper/CommentAdditionTest.php
Вот тут по сути идет тестирование реализации. Ну например вот этот вот код

> $mapperMock->method('getComment')->willReturn($commentMock);


даже аргументы не проверяет. Тест как итог выглядит странно:

> $expected->setId(1)->setParentId(1);


Понятно что это легко сломать если добавить проверку в Comment что parentId <> id.

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

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

https://github.com/foobar1643/filehosting/blob/master/app/Helper/CommentHelper.php#L16

> if($comment->getParentId() != NULL) {


> $parentComment = $this->commentMapper->getComment($comment->getParentId());


Ты используешь id в пути. Какая у тебя длина элемента пути? 3 символа? Это значит нельзя создать более 1000 комментариев на всем сайте. Надо использовать не id, а порядковый номер комментария среди братьев.

И кстати это позволит делать вставку одним инсертом.

Составные операции надо делать транзакцией.

В реализации комментария есть один сомнительный момент.У тебя там есть getChild() но всегда ли комментарии организованы в дерево? Что если мы выбираем один комментарий из базы? Что если мы хотим загрузить только часть дерева? В более сложном приложении стоило бы вынести древовидную структуру наружу из класса Comment либо использовать ленивую загрузку которая есть в доктрине.

> public function makeTrees($comments)


Эту функцию кстати можно тестировать.

> public function appendToPath($old, $new)


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

> public function getMargin($path)


Это не часть модели а часть вью.

https://github.com/foobar1643/filehosting/blob/master/tests/Helper/PaginationHelperTest.php#L30
Тут я бы не тестировал вид ссылки, а тестировал что она похожа на ссылку и разная для разных страниц

https://github.com/foobar1643/filehosting/blob/master/tests/Helper/TokenGeneratorTest.php
Вот по этому поводу я выше писал другому анону: http://pastebin.ru/t5Z34Uyu

> Factory::requestFactory()


Я бы назвал createRequest().

https://github.com/foobar1643/filehosting/blob/master/tests/Middleware/CsrfMiddlewareTest.php
Я бы тут тоже поменьше опирался на реализацию и тестировал бы только публичный интерфейс класса. То есть получил бы токен и попробовал бы проверить запрос с ним.

https://github.com/foobar1643/filehosting/blob/master/tests/Middleware/LocaleMiddlewareTest.php
Здесь чтобы что-то сказать надо разбираться в коде класса.

https://github.com/foobar1643/filehosting/blob/master/tests/Validation/ValidationTest.php#L37

> $this->validator = new Validation($container);


Ой, что это? serviceLocator вместо dependency injection. Заметь что здесь твой тест опирается на предположение что валидатору нужны ровно 3 зависимости.

Ну и я думаю, было бы неплохо еще сделать интеграционные (с базой) и функциональные (браузерные) тесты. Если ты не используешь яваскрипт, то можно использовать например эмулятор HTML браузера http://symfony.com/doc/current/book/testing.html#functional-tests , если нужен яваскрипт то придется использовать протокол Селениума, а в качестве эмулятора браузера подойдет phantomjs (придется повозиться с настройкой и работать будет конечно медленнее).

Браузерные тесты это отдельная сверхзадача, например как искать элементы? По классу? По id? По тексту? По имени поля формы? Какой из способов наиболее устойчив к изменениям верстки?

По локализации.

Я уже писал, что встроенная в Твиг локализация мне не нравится. Ну, твиг расширяемый, ты можешь при большом желании даже теги свои добавлять если не боишься. Мне например не нравится длинный синтаксис ({% trans %}) и отсутствие поддержки подстановок разных параметров как в formatMessage.

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

https://github.com/foobar1643/filehosting/blob/master/templates/comments.twig#L4

> <p class="pull-right"><small>{{ comment.getDatePosted }}</small></p>


В разных странах разные форматы записи дат. Твоя архитектура это не учитывает. Обычно используют объект-форматировщик дат вроде того что есть в Intl.

> <span class="comment-text">{{ comment.getCommentText }}</span>


Не сохраняются переводы строк

> <form method="post" id="fallback-reply-form" action="/{{ lang }}/file/{{ comment.fileId }}/">


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

> <h4>{% trans %}Search results for {% endtrans %} <i>&laquo;{{ query }}&raquo;</i></h4>


Вот еще одно сомнительное место. Ты предполагаешь что запрос будет идти в конце предложения, но в азиатских языках порядок слов другой и запрос может идти в начале или середине: "NNN запрос отправленный на результаты": https://translate.google.com/#en/ja/search results for query NNN (бинг выдал более точный на мой взгляд перевод где запрос идет в начале, но в нем ссылку нельзя скопировать).

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

Еще один подвох - перевод текста в JS скриптах. Для них приходится либо выносить переменные с текстом в шаблон либо писать свою систему переводов, скрипты сбора текстов, генерации файлов переводов, функции форматирования дат и тд. Кстати в JS вроде что-то было добавлено для локализации не так давно.
>>785399
#576 #785185
>>785128

Сменить пароль.
#577 #785237
>>785128
$user->logout()
#578 #785248
>>785051
Я перепутал, у меня стоит РНР7.0.7 сейчас. Всё смешалось в доме Облонских и моей голове.

>>785092
На Win8 ставил. Тут выше в треде есть мои боли при установке на Debian 8 Apache, MySQL и PHP7 по отдельности, но я просто пробовал на виртуалке запустить это всё, я не линуксоид.
PHP5 без проблем установился и на Дебиан, а вот с 7-ым были проблемы.
Остальное всё вообще двумя строками устанавливается.
Как, впрочем, и в cmd.exe.
#579 #785273
>>785067
Вау, спасибо за такой ответ развёрнутый
Сейчас намного проще начинать вникать в это будет.
#580 #785382
Это норма что в пхпшторме объекты достававаемые в дальнейшем в классе из контейнера Slim выделяются ошибкой method foobar not found in class? Притом в процессе выполнения программы ошибок нету, только визуально IDE их выделяет. По-моему в Pimple контейнере такого не было.
>>791698
#581 #785399
>>785183
>>785184
Спасибо, ОП. Есть несколько вопросов.

>Что-то странно, мы в rootComment вроде всего 3 комментария добавили, откуда взялась цифра 6?


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

>В классе нет поля error и file. Да и по моему логичнее просто запретить создавать File из битых файлов


Они наследуются из Slim\Http\UploadedFile. https://github.com/slimphp/Slim/blob/3.x/Slim/Http/UploadedFile.php

>Да и по моему логичнее просто запретить создавать File из битых файлов


Это про $this->error или про общие конструкции типа создания файла с несуществующим именем? Если про $this->error, то это поле наследуется из Slim\Http\UploadedFile и туда сохраняется константа вида UPLOAD_ERR_xxx из формы загрузки. Я потом в валидаторе использую это поле чтобы проверить, все ли успешно загрузилось. Если про создание файла с несуществующим именем - могу сделать, но мне показалось это переусложнением (все равно при попытке вызвать метод moveTo() к такому файлу выбросится исключение).

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


Тут тоже не понял каким образом они продолжат работать если имя файла на диске и в БД разное. И getDiskName вызывается только когда нужно получить путь к файлу на диске (для отдачи его пользователю или для анализа getId3).

>Вот тут по моему мы опять начинаем тестировать внутреннюю реализацию. Я бы просто проверял что эта функция возвращает что-то похожее на имя папки.


Регулярка вида ^\d+$ подойдет? Но это ведь тоже вроде как знание внутренней структуры, ведь я знаю что функция должна вернуть имя в виде числа. И я только сейчас заметил что имя функции тут странное, если бы я не знал внутреннюю структуру проекта я бы мог подумать что getFileFolder() может возвращать что угодно.

>- проверял что возвращается что-то отдаленно напоминающее ссылку


>- что для разных файлов она разная


Тут опять же не очень понимаю как сделать. Если для разных файлов можно попробовать применить assertNotEquals($file1->getDownloadLink(), $file2->getDownloadLink()), то с проверкой ссылки возникают трудности. Ссылка ведь может быть формата https://filehosting.ru/ а может и /file/get/1/. Единственная идея которая возникает - проверять регуляркой, как с именем папки, но там ситуация полегче.

> >class FileEntityTest extends TestCase


> >protected static $file;


>Почему static? Один обший файл на любое число тестовых объектов? Тут же нет причин ставить static.


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

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


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

>https://github.com/foobar1643/filehosting/blob/master/tests/Helper/CommentAdditionTest.php


>Вот тут по сути идет тестирование реализации


Мне не понравилось юнит тестирование вообще всего что как-то использует базу данных. Для тестирования добавления\удаления комментариев и файлов я хочу сделать отдельные тесты которые использую базу даных. Интеграционные тесты тоже стоит делать используя PHPUnit? У них есть раздел в документации https://phpunit.de/manual/current/en/database.html

>Ты используешь id в пути. Какая у тебя длина элемента пути? 3 символа? Это значит нельзя создать более 1000 комментариев на всем сайте.


Нули я туда добавляю чтобы правильно работала сортировка при выборке. У меня была проблема когда при выборке комментариев ломалась сортировка и они отображались в неправильном порядке. Сейчас, если комментариев будет больше 1000, все работает, я проверял. Способ порядкового номера среди братьев мне нравится, это в теории убирает id комментария из его matpath, но тут у меня возникают две проблемы:
- Как это повлияет на выборку комментариев, по какой колонке в этом случае сортировать? Не понимаю.
- Как сделать такую вставку одним INSERT я тоже не понимаю, ведь в этом случае мне нужно знать не только matpath родителя, но еще и количество его детей.
Я тут нагородил вот такую конструкцию

>INSERT INTO comments (file_id, parent_id, author, comment_text, date_posted, parent_path) VALUES (:file_id, :parent_id, :author, :text, :date, CONCAT((SELECT parent_path FROM comments WHERE parent_id = :parent_id), '.', (SELECT COUNT(*) FROM comments WHERE parent_id = :parent_id)));


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

>В реализации комментария есть один сомнительный момент.У тебя там есть getChild() но всегда ли комментарии организованы в дерево? Что если мы выбираем один комментарий из базы?


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

> > $this->validator = new Validation($container);


>Ой, что это? serviceLocator вместо dependency injection. Заметь что здесь твой тест опирается на предположение что валидатору нужны ровно 3 зависимости.


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

>Я уже писал, что встроенная в Твиг локализация мне не нравится. Ну, твиг расширяемый, ты можешь при большом желании даже теги свои добавлять если не боишься. Мне например не нравится длинный синтаксис ({% trans %}) и отсутствие поддержки подстановок разных параметров как в formatMessage.


Я не очень хочу делать свой объект для перевода, потому что тогда получить строки из файлов шаблонов будет проблематично. Плюс мне не нравится то, что нужно будет объект передавать в каждый вью, там существует проблема когда некоторые вызовы вью (например вот тут https://github.com/foobar1643/filehosting/blob/master/app/Controller/FileController.php#L51 ) выглядят большими. И даже если сам шаблон нигде не будет использовать объект перевода, его все равно нужно будет передавать для перевода текста из шапки, например. Плюс этот объект можно забыть передать, тогда будет ошибка.
#581 #785399
>>785183
>>785184
Спасибо, ОП. Есть несколько вопросов.

>Что-то странно, мы в rootComment вроде всего 3 комментария добавили, откуда взялась цифра 6?


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

>В классе нет поля error и file. Да и по моему логичнее просто запретить создавать File из битых файлов


Они наследуются из Slim\Http\UploadedFile. https://github.com/slimphp/Slim/blob/3.x/Slim/Http/UploadedFile.php

>Да и по моему логичнее просто запретить создавать File из битых файлов


Это про $this->error или про общие конструкции типа создания файла с несуществующим именем? Если про $this->error, то это поле наследуется из Slim\Http\UploadedFile и туда сохраняется константа вида UPLOAD_ERR_xxx из формы загрузки. Я потом в валидаторе использую это поле чтобы проверить, все ли успешно загрузилось. Если про создание файла с несуществующим именем - могу сделать, но мне показалось это переусложнением (все равно при попытке вызвать метод moveTo() к такому файлу выбросится исключение).

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


Тут тоже не понял каким образом они продолжат работать если имя файла на диске и в БД разное. И getDiskName вызывается только когда нужно получить путь к файлу на диске (для отдачи его пользователю или для анализа getId3).

>Вот тут по моему мы опять начинаем тестировать внутреннюю реализацию. Я бы просто проверял что эта функция возвращает что-то похожее на имя папки.


Регулярка вида ^\d+$ подойдет? Но это ведь тоже вроде как знание внутренней структуры, ведь я знаю что функция должна вернуть имя в виде числа. И я только сейчас заметил что имя функции тут странное, если бы я не знал внутреннюю структуру проекта я бы мог подумать что getFileFolder() может возвращать что угодно.

>- проверял что возвращается что-то отдаленно напоминающее ссылку


>- что для разных файлов она разная


Тут опять же не очень понимаю как сделать. Если для разных файлов можно попробовать применить assertNotEquals($file1->getDownloadLink(), $file2->getDownloadLink()), то с проверкой ссылки возникают трудности. Ссылка ведь может быть формата https://filehosting.ru/ а может и /file/get/1/. Единственная идея которая возникает - проверять регуляркой, как с именем папки, но там ситуация полегче.

> >class FileEntityTest extends TestCase


> >protected static $file;


>Почему static? Один обший файл на любое число тестовых объектов? Тут же нет причин ставить static.


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

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


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

>https://github.com/foobar1643/filehosting/blob/master/tests/Helper/CommentAdditionTest.php


>Вот тут по сути идет тестирование реализации


Мне не понравилось юнит тестирование вообще всего что как-то использует базу данных. Для тестирования добавления\удаления комментариев и файлов я хочу сделать отдельные тесты которые использую базу даных. Интеграционные тесты тоже стоит делать используя PHPUnit? У них есть раздел в документации https://phpunit.de/manual/current/en/database.html

>Ты используешь id в пути. Какая у тебя длина элемента пути? 3 символа? Это значит нельзя создать более 1000 комментариев на всем сайте.


Нули я туда добавляю чтобы правильно работала сортировка при выборке. У меня была проблема когда при выборке комментариев ломалась сортировка и они отображались в неправильном порядке. Сейчас, если комментариев будет больше 1000, все работает, я проверял. Способ порядкового номера среди братьев мне нравится, это в теории убирает id комментария из его matpath, но тут у меня возникают две проблемы:
- Как это повлияет на выборку комментариев, по какой колонке в этом случае сортировать? Не понимаю.
- Как сделать такую вставку одним INSERT я тоже не понимаю, ведь в этом случае мне нужно знать не только matpath родителя, но еще и количество его детей.
Я тут нагородил вот такую конструкцию

>INSERT INTO comments (file_id, parent_id, author, comment_text, date_posted, parent_path) VALUES (:file_id, :parent_id, :author, :text, :date, CONCAT((SELECT parent_path FROM comments WHERE parent_id = :parent_id), '.', (SELECT COUNT(*) FROM comments WHERE parent_id = :parent_id)));


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

>В реализации комментария есть один сомнительный момент.У тебя там есть getChild() но всегда ли комментарии организованы в дерево? Что если мы выбираем один комментарий из базы?


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

> > $this->validator = new Validation($container);


>Ой, что это? serviceLocator вместо dependency injection. Заметь что здесь твой тест опирается на предположение что валидатору нужны ровно 3 зависимости.


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

>Я уже писал, что встроенная в Твиг локализация мне не нравится. Ну, твиг расширяемый, ты можешь при большом желании даже теги свои добавлять если не боишься. Мне например не нравится длинный синтаксис ({% trans %}) и отсутствие поддержки подстановок разных параметров как в formatMessage.


Я не очень хочу делать свой объект для перевода, потому что тогда получить строки из файлов шаблонов будет проблематично. Плюс мне не нравится то, что нужно будет объект передавать в каждый вью, там существует проблема когда некоторые вызовы вью (например вот тут https://github.com/foobar1643/filehosting/blob/master/app/Controller/FileController.php#L51 ) выглядят большими. И даже если сам шаблон нигде не будет использовать объект перевода, его все равно нужно будет передавать для перевода текста из шапки, например. Плюс этот объект можно забыть передать, тогда будет ошибка.
>>785636>>785639
#582 #785427
>>785128
Аноны выше написали правильно
$user->changetPassword($newPass) //сменить пароль
$user->block() //заблокировать
$user->makePremium() //сделать премиум-пользователем

Спросишь, почему это не сделать обычными полями (типа $user->isPremium=true) - отвечу. ПОтому что очень редко достаточно поменять одно поле в табличке юзера. Обычно при этом надо ещё сделать мнодество всякой фигни. Типа, послать письмо юзеру, сделать запись в лог, удвоить какие нибудь дневные лимиты постинга, и прочее. Если ты начнешь всю эту логику размазывать по множеству разных мест, вместо того, чтобы собирать плотно в кучку в методе соответствующего класса - в большом проекте ты очень скоро сам перестанешь понимать, как и что у тебя вообще работает.
>>785636
#583 #785428
>>784929
вот я например щас пишу систему электронного документоооборота на PHP. Логика прохождения заявок\согласований документов - пиздец какая сложная. Без продвинутого ООП это просто нереально напиисать
111 Кб, 1280x1768
#584 #785435
Подскажите как убрать ошибку пикрелейтед? При передачи параметров в роут не хотят подключаться css файлы.
#585 #785436
>>785435
Алсо это слим.
68 Кб, 1367x458
#586 #785442
После переустановки винды не захотел ставиться XAMPP. Пофиг, поставил аналог.
Теперь такая, непонятная для меня, проблема. Что ему еще может не нравиться?

хоспаде, как же хочется программировать! Три дня не кодил с этой переустановкой
>>785515>>785601
#587 #785444
>>785435
Каким образом ты их подключаешь? В твоем случае нужно использовать абсолютные пути от корня сервера.
>>785450
#588 #785450
>>785444
Извиняюсь, не заметил самый нижний скриншот. Твой способ не будет работать, потому что в случае с точкой он ищет файлы в текущей директории, и как ты можешь видеть, в директории /file/ таких файлов нет. А когда ты переходишь по ссылке /public/file - то все еще находишься в папке public, поэтому в этом случае браузер загружает файлы нормально. Если же указать ссылку вида /public/file/ то все сломается. Решение - использовать абсолютный путь от корня /public/bootstrap/bootstrap.css.

Еще почитай урок ОПа про структуру URL https://github.com/codedokode/pasta/blob/master/network/urls.md
>>785452
30 Кб, 1254x536
#589 #785452
>>785450
Теперь вот так. Путь правильный, но почему-то новая ошибка.
>>785454>>785626
14 Кб, 963x293
#590 #785454
>>785452
Забыл показать пруф своих абсолютных путей.
>>785465
#591 #785465
>>785454
Магическая константа __DIR__ возвращает абсолютный путь к директории файла на сервере. И ты путь к файлу на сервере отдаешь пользователю, т.е. ты говоришь браузеру пользователя загрузить файл по следующему пути - C:\Apache24\ и т.д. Так как по умолчанию браузеру запрещено загружать что-то из ФС пользователя, возникает ошибка. Использовать __DIR__ в шаблонах это неправильно, корень веб-сервера со стороны браузера будет символ - /. Так же и тебе нужно указать абсолютный путь к css файлу от этого корня, в твоем случае это /file-sharing/public/bootstrap/bootstrap.css.
У ОПа в уроке наглядно показано отличие между относительными и абсолютными ссылками, так же там есть небольшие задания для закрепления, зря ты его пропускаешь.
118 Кб, 400x400
#592 #785468
>>785465
Ясно, теперь работает.. Спасибо! Обязательно прочитаю.
#593 #785475
>>785465

>браузеру запрещено загружать что-то из ФС пользователя


Кто тебе это сказал?
>>785482>>785626
#594 #785482
>>785475
Это преувеличение, конечно. Знаю только что хром выдаст ошибку при попытке загрузить локальный файл. В других браузерах с таким не сталкивался ни разу.
#595 #785515
>>785442

Лог mysql'а: который мне ни о чём не говорит

2016-07-01 20:08:03 6060 [Warning] You need to use --log-bin to make --binlog-format work.
2016-07-01 20:08:03 6060 [Note] Plugin 'FEDERATED' is disabled.
2016-07-01 20:08:03 6060 [Note] InnoDB: Using atomics to ref count buffer pool pages
2016-07-01 20:08:03 6060 [Note] InnoDB: The InnoDB memory heap is disabled
2016-07-01 20:08:03 6060 [Note] InnoDB: Mutexes and rw_locks use Windows interlocked functions
2016-07-01 20:08:03 6060 [Note] InnoDB: Memory barrier is not used
2016-07-01 20:08:03 6060 [Note] InnoDB: Compressed tables use zlib 1.2.3
2016-07-01 20:08:03 6060 [Note] InnoDB: Not using CPU crc32 instructions
2016-07-01 20:08:03 6060 [Note] InnoDB: Initializing buffer pool, size = 128.0M
2016-07-01 20:08:03 6060 [Note] InnoDB: Completed initialization of buffer pool
2016-07-01 20:08:03 6060 [Note] InnoDB: Highest supported file format is Barracuda.
2016-07-01 20:08:03 6060 [Note] InnoDB: 128 rollback segment(s) are active.
2016-07-01 20:08:03 6060 [Note] InnoDB: Waiting for purge to start
2016-07-01 20:08:03 6060 [Note] InnoDB: 5.6.30 started; log sequence number 1641273
2016-07-01 20:08:03 6060 [Note] Server hostname (bind-address): '*'; port: 3306
2016-07-01 20:08:03 6060 [Note] IPv6 is available.
2016-07-01 20:08:03 6060 [Note] - '::' resolves to '::';
2016-07-01 20:08:03 6060 [Note] Server socket created on IP: '::'.
2016-07-01 20:08:03 6060 [Warning] InnoDB: Cannot open table mysql/slave_master_info from the internal data dictionary of InnoDB though the .frm file for the table exists. See http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html for how you can resolve the problem.
2016-07-01 20:08:03 6060 [Warning] Info table is not ready to be used. Table 'mysql.slave_master_info' cannot be opened.
2016-07-01 20:08:03 6060 [Warning] InnoDB: Cannot open table mysql/slave_worker_info from the internal data dictionary of InnoDB though the .frm file for the table exists. See http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html for how you can resolve the problem.
2016-07-01 20:08:03 6060 [Warning] InnoDB: Cannot open table mysql/slave_relay_log_info from the internal data dictionary of InnoDB though the .frm file for the table exists. See http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html for how you can resolve the problem.
2016-07-01 20:08:03 6060 [Warning] Info table is not ready to be used. Table 'mysql.slave_relay_log_info' cannot be opened.
2016-07-01 20:08:03 6060 [Note] Event Scheduler: Loaded 0 events
2016-07-01 20:08:03 6060 [Note] mysql\bin\mysqld.exe: ready for connections.
Version: '5.6.30' socket: '' port: 3306 MySQL Community Server (GPL)
2016-07-01 20:11:24 164c InnoDB: Error: Table "mysql"."innodb_table_stats" not found.
2016-07-01 20:11:24 164c InnoDB: Error: Fetch of persistent statistics requested for table "students"."students" but the required system tables mysql.innodb_table_stats and mysql.innodb_index_stats are not present or have unexpected structure. Using transient stats instead.
#595 #785515
>>785442

Лог mysql'а: который мне ни о чём не говорит

2016-07-01 20:08:03 6060 [Warning] You need to use --log-bin to make --binlog-format work.
2016-07-01 20:08:03 6060 [Note] Plugin 'FEDERATED' is disabled.
2016-07-01 20:08:03 6060 [Note] InnoDB: Using atomics to ref count buffer pool pages
2016-07-01 20:08:03 6060 [Note] InnoDB: The InnoDB memory heap is disabled
2016-07-01 20:08:03 6060 [Note] InnoDB: Mutexes and rw_locks use Windows interlocked functions
2016-07-01 20:08:03 6060 [Note] InnoDB: Memory barrier is not used
2016-07-01 20:08:03 6060 [Note] InnoDB: Compressed tables use zlib 1.2.3
2016-07-01 20:08:03 6060 [Note] InnoDB: Not using CPU crc32 instructions
2016-07-01 20:08:03 6060 [Note] InnoDB: Initializing buffer pool, size = 128.0M
2016-07-01 20:08:03 6060 [Note] InnoDB: Completed initialization of buffer pool
2016-07-01 20:08:03 6060 [Note] InnoDB: Highest supported file format is Barracuda.
2016-07-01 20:08:03 6060 [Note] InnoDB: 128 rollback segment(s) are active.
2016-07-01 20:08:03 6060 [Note] InnoDB: Waiting for purge to start
2016-07-01 20:08:03 6060 [Note] InnoDB: 5.6.30 started; log sequence number 1641273
2016-07-01 20:08:03 6060 [Note] Server hostname (bind-address): '*'; port: 3306
2016-07-01 20:08:03 6060 [Note] IPv6 is available.
2016-07-01 20:08:03 6060 [Note] - '::' resolves to '::';
2016-07-01 20:08:03 6060 [Note] Server socket created on IP: '::'.
2016-07-01 20:08:03 6060 [Warning] InnoDB: Cannot open table mysql/slave_master_info from the internal data dictionary of InnoDB though the .frm file for the table exists. See http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html for how you can resolve the problem.
2016-07-01 20:08:03 6060 [Warning] Info table is not ready to be used. Table 'mysql.slave_master_info' cannot be opened.
2016-07-01 20:08:03 6060 [Warning] InnoDB: Cannot open table mysql/slave_worker_info from the internal data dictionary of InnoDB though the .frm file for the table exists. See http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html for how you can resolve the problem.
2016-07-01 20:08:03 6060 [Warning] InnoDB: Cannot open table mysql/slave_relay_log_info from the internal data dictionary of InnoDB though the .frm file for the table exists. See http://dev.mysql.com/doc/refman/5.6/en/innodb-troubleshooting.html for how you can resolve the problem.
2016-07-01 20:08:03 6060 [Warning] Info table is not ready to be used. Table 'mysql.slave_relay_log_info' cannot be opened.
2016-07-01 20:08:03 6060 [Note] Event Scheduler: Loaded 0 events
2016-07-01 20:08:03 6060 [Note] mysql\bin\mysqld.exe: ready for connections.
Version: '5.6.30' socket: '' port: 3306 MySQL Community Server (GPL)
2016-07-01 20:11:24 164c InnoDB: Error: Table "mysql"."innodb_table_stats" not found.
2016-07-01 20:11:24 164c InnoDB: Error: Fetch of persistent statistics requested for table "students"."students" but the required system tables mysql.innodb_table_stats and mysql.innodb_index_stats are not present or have unexpected structure. Using transient stats instead.
>>785601>>785622
#596 #785601
>>785515
>>785442
У тебя пароль не выставлен. Снеси это глючное говно phpmyadmin и скачай нормальный клиент баз данных HeidiSQL - http://www.heidisql.com/
В нем и заходи, проблем не будет, и все быстрее станет.
#597 #785622
>>785515

Давай начнем с анализа ситуации. Пхп пишет:

Access denied

Это значит:

- соединиться с базой данных удалось (иначе было бы что-то вроде connection failed)
- однако при отправке логина и пароля (точнее только логина, без пароля) база данных отказала в доступе. Очевидно в ней запрещен доступ пользователю root@localhost без пароля (в БД можно настраивать доступ не только по имени но еще и по IP-адресу откуда приходит соединение).

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

mysql -uroot -hlocalhost students

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

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

Как дать доступ, погугли: https://www.google.ru/search?q=mysql+управление+пользователями&newwindow=1&gbv=1&sei=pvF2V8vENaHi6ASdxpfADw

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

Из лога кстати видно что:

- используется стандартный порт 3306
- порт слушается на всех сетевых интерфейсах, то есть к нему можно подключиться снаружи. Наверно ты бы хотел слушать только на 127.0.0.1 чтобы подключаться можно было только с твоего компьютера.
#597 #785622
>>785515

Давай начнем с анализа ситуации. Пхп пишет:

Access denied

Это значит:

- соединиться с базой данных удалось (иначе было бы что-то вроде connection failed)
- однако при отправке логина и пароля (точнее только логина, без пароля) база данных отказала в доступе. Очевидно в ней запрещен доступ пользователю root@localhost без пароля (в БД можно настраивать доступ не только по имени но еще и по IP-адресу откуда приходит соединение).

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

mysql -uroot -hlocalhost students

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

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

Как дать доступ, погугли: https://www.google.ru/search?q=mysql+управление+пользователями&newwindow=1&gbv=1&sei=pvF2V8vENaHi6ASdxpfADw

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

Из лога кстати видно что:

- используется стандартный порт 3306
- порт слушается на всех сетевых интерфейсах, то есть к нему можно подключиться снаружи. Наверно ты бы хотел слушать только на 127.0.0.1 чтобы подключаться можно было только с твоего компьютера.
>>785720
#598 #785626
>>785475

Сейчас вроде запрещают, так как это может вести к уязвимостям (например злоумышленник может попытаться читать всякие системные файлы или /proc таким образом). УРЛ должен иметь вид вроде file://c:/file.png иначе не будет работать. file:// значит что браузер ищет ресурс локально на диске, а не запрашивает с сервера по протоколу HTTP.

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

Потому УРЛ должен иметь вид /some/image.png.

>>785465

Если у него public - это корень сервера то путь отсчитывается от него и будет /bootstrap/bootstrap.css

>>785452

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

>>785435

А ты посмотри внимательно какие пути написаны в консоли. Там лишнее слово file получилось. Надо либо писать путь от корня /lalala/lalala либо добавлять нужное число точек ../../lalala (сложно).
42 Кб, 702x360
#599 #785630
Попробовал сделать задание на ООП калькулятор из самого первого гиста. Репозиторий: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/test.php

Одним файлом и со всеми примерами выражений для проверки: https://ideone.com/a4aeZ4
Советую сразу скроллить вниз, классы собраны в один файл скриптом, поэтому в их последовательности нет никакой логики. Добавил на ideone, чтобы проще было тестировать код на проблемные места.

Решил исходить из того, что и int и float можно представить в виде простой дроби, поэтому у меня все числа являются частными случаями SimpleFraction. У меня вообще туго с математикой, во время решения задачи я гуглил как дроби перемножать.
Обработчик ошибок добавил свой, чтобы надпись "Ошибка: (%s/0) делить на ноль нельзя" выводилась аккуратно.

1) Каким требованиям должно удовлетворять валидное RPN-выражение? Достаточно ли просто проверить, что чисел должно быть >= 2 и количество операндов на 1 меньше чем чисел?

2) Ту часть, что на пике, я так и не смог облечь в код по-человечески, вышло огромное плохо читаемое условие: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/ShuntingYard.php#L26
Как можно улучшить?

На всякий случай напомню, что студентов исправил.
>>785646
#600 #785636
>>785427

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


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

>>785399

>>Что-то странно, мы в rootComment вроде всего 3 комментария добавили, откуда взялась цифра 6?


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


А, видимо я перепутал непосредственных детей и потомков любой глубины. Детей там вроде 3, но у них видимо еще свои дети есть.

>>В классе нет поля error и file. Да и по моему логичнее просто запретить создавать File из битых файлов


> Они наследуются из Slim\Http\UploadedFile


Тогда на мой взгляд это не совсем удачная идея наследовать. Наследование это отношение вида "А является расширенной версией Б".

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

Ну например после сохранения в БД и восстановления - у тебя получается идентичный объект исходному? У него все те же поля прописаны? Все методы вернут тот же результат?

Я не уверен что тут можно использовать наследование. Мне кажется тут может быть разве что отношение вида "А содержит в себе Б", то есть композиция.

Что-то мне кажется что наследование тут несет больше сложностей чем выгоды. Лучше наверно сделать в отдельном классе методы для конвертирования одного во второй.

> Тут тоже не понял каким образом они продолжат работать если имя файла на диске и в БД разное.


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

> Регулярка вида ^\d+$ подойдет? Но это ведь тоже вроде как знание внутренней структуры, ведь я знаю что функция должна вернуть имя в виде числа.


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

>>- проверял что возвращается что-то отдаленно напоминающее ссылку


>>- что для разных файлов она разная


> Тут опять же не очень понимаю как сделать. Если для разных файлов можно попробовать применить assertNotEquals($file1->getDownloadLink(), $file2->getDownloadLink()), то с проверкой ссылки возникают трудности.


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

Потому мы можем проверять следующее:

- что ссылка не является пустой строкой
- еще можно проверить что ссылка не содержит запрещенных символов (пробелов). При большом желании можно даже откопать какую-нибудь библиотеку проверяющую ссылку на соответствие стандартам, но это наверно излишне. Можно сделать упрощенную проверку, что ссылка начинается с http://, https:// или / (отсекаем относительные ссылки).
- еще можно проверять что ссылка указывает на правильный домен, но это опять же потребует усложнений, например закладывать список доменов в тесты

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

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


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

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

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


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


Но с другой стороны это фича которую легко сломать и не заметить.

> Для тестирования добавления\удаления комментариев и файлов я хочу сделать отдельные тесты которые использую базу даных. Интеграционные тесты тоже стоит делать используя PHPUnit?


Можно, но тебе надо решить проблему изоляции. Как гарантировать что тест А, меняя базу, не помешает тесту Б? Тут есть разные варианты, писать тесты которые гарантированно не ломают другие тесты, очищать базу перед каждым тестом, делать тест внутри транзакции которая откатывается в конце. Выбор тут будет между временем выполнения и степенью изоляции.

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

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

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

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

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

Также, тут есть выбор, использовать одно и то же соединение с БД или переподсоединяться перед каждым тестом (в твоем случае это подразумевает еще и пересоздание контейнера). Опять же выбор меду производительностью и степенью изоляции.
#600 #785636
>>785427

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


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

>>785399

>>Что-то странно, мы в rootComment вроде всего 3 комментария добавили, откуда взялась цифра 6?


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


А, видимо я перепутал непосредственных детей и потомков любой глубины. Детей там вроде 3, но у них видимо еще свои дети есть.

>>В классе нет поля error и file. Да и по моему логичнее просто запретить создавать File из битых файлов


> Они наследуются из Slim\Http\UploadedFile


Тогда на мой взгляд это не совсем удачная идея наследовать. Наследование это отношение вида "А является расширенной версией Б".

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

Ну например после сохранения в БД и восстановления - у тебя получается идентичный объект исходному? У него все те же поля прописаны? Все методы вернут тот же результат?

Я не уверен что тут можно использовать наследование. Мне кажется тут может быть разве что отношение вида "А содержит в себе Б", то есть композиция.

Что-то мне кажется что наследование тут несет больше сложностей чем выгоды. Лучше наверно сделать в отдельном классе методы для конвертирования одного во второй.

> Тут тоже не понял каким образом они продолжат работать если имя файла на диске и в БД разное.


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

> Регулярка вида ^\d+$ подойдет? Но это ведь тоже вроде как знание внутренней структуры, ведь я знаю что функция должна вернуть имя в виде числа.


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

>>- проверял что возвращается что-то отдаленно напоминающее ссылку


>>- что для разных файлов она разная


> Тут опять же не очень понимаю как сделать. Если для разных файлов можно попробовать применить assertNotEquals($file1->getDownloadLink(), $file2->getDownloadLink()), то с проверкой ссылки возникают трудности.


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

Потому мы можем проверять следующее:

- что ссылка не является пустой строкой
- еще можно проверить что ссылка не содержит запрещенных символов (пробелов). При большом желании можно даже откопать какую-нибудь библиотеку проверяющую ссылку на соответствие стандартам, но это наверно излишне. Можно сделать упрощенную проверку, что ссылка начинается с http://, https:// или / (отсекаем относительные ссылки).
- еще можно проверять что ссылка указывает на правильный домен, но это опять же потребует усложнений, например закладывать список доменов в тесты

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

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


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

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

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


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


Но с другой стороны это фича которую легко сломать и не заметить.

> Для тестирования добавления\удаления комментариев и файлов я хочу сделать отдельные тесты которые использую базу даных. Интеграционные тесты тоже стоит делать используя PHPUnit?


Можно, но тебе надо решить проблему изоляции. Как гарантировать что тест А, меняя базу, не помешает тесту Б? Тут есть разные варианты, писать тесты которые гарантированно не ломают другие тесты, очищать базу перед каждым тестом, делать тест внутри транзакции которая откатывается в конце. Выбор тут будет между временем выполнения и степенью изоляции.

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

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

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

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

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

Также, тут есть выбор, использовать одно и то же соединение с БД или переподсоединяться перед каждым тестом (в твоем случае это подразумевает еще и пересоздание контейнера). Опять же выбор меду производительностью и степенью изоляции.
>>785644
#601 #785639
>>785399

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



Плохо проверял. Допустим есть комментарий с id = 999 и с id = 1002. Они получат такие пути:

001.999
001.002

Сортировка оказвеатся нарушена. А если мы попытаемся вставить комментарий с id = 2002 то нарушится уникальность путей.

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

001.001
001.002
....
001.999

Добавить условие уникальности (файл, путь).

Как получить номер перед вставкой? Есть 2 варианта:

- сделать SELECT COUNT() WHERE parent_id = ? либо WHERE file_id = ? AND path LIKE '001.%'
- сделать SELECT MAX(path) WHERE parent_id = ? либо через file_id и path

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

Для оптимизации поиска с parent_id конечно же нужен дополнительный индекс по (parent_id, path). При поиске черз file_id и path используется существующий уникальный индекс.

Есть ли тут подвох? Ну конечно, есть. Что если 2 потока параллельно пытаются вставить комментарий, получают один и тот же номер и пытаются сделать вставку? Решение известно - блокировки, они бывают 2 видов ( https://ru.wikipedia.org/wiki/Блокировка_(СУБД) ):

- пессимистичная - на время транзакции эксклюзивно блокируем последний комментарий в ветке через SELECT FOR UPDATE
- оптимичтиная - не блокируем, пробуем вставить, а если получим ошибку уникальности ключа (то есть второй поток успел занять новый идентификатор пути), делаем небольшую паузу и повторяем попытку заново (вычисляя новый путь)

Эта важная тема, надо бы чтобы ты в ней разобрался. Вот старая паста: http://pastebin.ru/JKLyrQYw

То есть ты должен понимать:

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

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

Кстати ты знаешь, как протестировать что проблем с параллельной вставкой комментариев нет?

> Способ порядкового номера среди братьев мне нравится, это в теории убирает id комментария из его matpath, но тут у меня возникают две проблемы:



> по какой колонке в этом случае сортировать?


По path

> Как сделать такую вставку одним INSERT


предварительный select + за ним insert

> Тут целых три запроса, и оно работает, но как это потом выбирать я не знаю. Может быть я что-то не так понял.


Лучше делать отдельными запросами

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


Ну смотри, вот завтра ты захочешь сделать функцию выборки одного комментария по id. Что у него будет в getChild() ? Привязывая дерево к модели коммента, ты не даешь возможности выбирать комменатрии без учета древовидности.

>>Ой, что это? serviceLocator вместо dependency injection. Заметь что здесь твой тест опирается на предположение что валидатору нужны ровно 3 зависимости.


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


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

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


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

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


Можно передать как глобальную переменную в начале. Во втором слиме была возможность сделать $slim->view->set(...) или как-то так.
#601 #785639
>>785399

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



Плохо проверял. Допустим есть комментарий с id = 999 и с id = 1002. Они получат такие пути:

001.999
001.002

Сортировка оказвеатся нарушена. А если мы попытаемся вставить комментарий с id = 2002 то нарушится уникальность путей.

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

001.001
001.002
....
001.999

Добавить условие уникальности (файл, путь).

Как получить номер перед вставкой? Есть 2 варианта:

- сделать SELECT COUNT() WHERE parent_id = ? либо WHERE file_id = ? AND path LIKE '001.%'
- сделать SELECT MAX(path) WHERE parent_id = ? либо через file_id и path

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

Для оптимизации поиска с parent_id конечно же нужен дополнительный индекс по (parent_id, path). При поиске черз file_id и path используется существующий уникальный индекс.

Есть ли тут подвох? Ну конечно, есть. Что если 2 потока параллельно пытаются вставить комментарий, получают один и тот же номер и пытаются сделать вставку? Решение известно - блокировки, они бывают 2 видов ( https://ru.wikipedia.org/wiki/Блокировка_(СУБД) ):

- пессимистичная - на время транзакции эксклюзивно блокируем последний комментарий в ветке через SELECT FOR UPDATE
- оптимичтиная - не блокируем, пробуем вставить, а если получим ошибку уникальности ключа (то есть второй поток успел занять новый идентификатор пути), делаем небольшую паузу и повторяем попытку заново (вычисляя новый путь)

Эта важная тема, надо бы чтобы ты в ней разобрался. Вот старая паста: http://pastebin.ru/JKLyrQYw

То есть ты должен понимать:

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

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

Кстати ты знаешь, как протестировать что проблем с параллельной вставкой комментариев нет?

> Способ порядкового номера среди братьев мне нравится, это в теории убирает id комментария из его matpath, но тут у меня возникают две проблемы:



> по какой колонке в этом случае сортировать?


По path

> Как сделать такую вставку одним INSERT


предварительный select + за ним insert

> Тут целых три запроса, и оно работает, но как это потом выбирать я не знаю. Может быть я что-то не так понял.


Лучше делать отдельными запросами

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


Ну смотри, вот завтра ты захочешь сделать функцию выборки одного комментария по id. Что у него будет в getChild() ? Привязывая дерево к модели коммента, ты не даешь возможности выбирать комменатрии без учета древовидности.

>>Ой, что это? serviceLocator вместо dependency injection. Заметь что здесь твой тест опирается на предположение что валидатору нужны ровно 3 зависимости.


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


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

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


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

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


Можно передать как глобальную переменную в начале. Во втором слиме была возможность сделать $slim->view->set(...) или как-то так.
>>786912
#602 #785644
>>785636

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



В этом месте я бы поспорил...
Вот смотри. К примеру у нас проект гигантского размера, над которым работало 40 рыл кодеров на протяжении пары лет. В таком проекте обычно тысячи классов, типа что-то-там-Service, которые делают... да всё короче делают.

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

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

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

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

Выглядеть это должно примерно так:
Class User {
public function makePremium(MakeUserPremiumCommand $command)
{
return $command->execute($this);
}
}

Ну а внутри команды - там код, где и манипуляция с юзером, рассылка писем, логами, внешними АПИ и бог знает что ещё.
>>785647
#603 #785646
>>785630

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

https://github.com/applejacky/arithmetic_expression_calculator/tree/master/Classes
Многовато классов, надо разбивать на папки и неймспесы. Например все токены поместить в отдельный неймспейс.

В лексере проблема - это интерпретация знаков "минус". -1 - это "минус один" или операция "отрицание" примененная к числу один?

Также твой лексер не ловит ошибочные символы. Достаточно дописать

|.

В конец регулярки и он начнет их ловить.

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

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

Ты парсишь выражение в RPN но не удобнее ли сразу строить дерево AST ? Вот тут например есть даже примеры с кодом: https://moodle.vsu.ru/pluginfile.php?file=/80770/mod_resource/content/1/Основы синтаксического разбора.pdf

Но там используется рекурсивный спуск, то есть приоритеты операций зафиксированы в коде и много однотипного кода. Если бы твой алгоритм как-то с тем совместить, чтобы сравнивались приоритеты, но строилось бы не RPN а AST. Разве невозможно?

Вот тут какие-то алгоритмы есть: http://algolist.manual.ru/syntax/parsear.php - не подходят?

А, хотя ладно, AST при желании можно построить из RPN но это скорее будет лишний шаг.

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/ShuntingYard.php#L8
Тут мне кажется стеки незачем передавать как зависимости. У тебя нет необходимости их подменять на что-то, это просто коллекции с данными.

> set_exception_handler(function (Exception $e) {


>$e->getMessage();


>$e->getCode();


Зачем это? Это ведь игнорирует любые исключения. Это неправильно. Чтобы ловить исключения, оберни вычисление в try/catch и укажи там свой класс исключений.

Соответственно в тесте лучше писать так:

'1/0' => 'DivideByZeroException',

Вот я попробовал вычислить выражения:

')))' : https://ideone.com/283Htn
'- (- 1)' : https://ideone.com/gkdxNi
'1 2 3': https://ideone.com/Yedp3k - должна быть ошибка

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/ShuntingYard.php#L14
Тут трудно понять логику, нужны комментарии. Нету последнего else { ... }

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/SimpleFraction.php#L17
Вот тут есть подвох. Флоаты в пхп приближенные и хранятся с ограниченной точностью. int ограничен рамками от -2 млрд до +2 млрд на 32-битных системах. Попробуй дробь вроде 0.1111111111111111111111111 - там скорее всего не получится нужное число знаков и потеряется точность (то есть при компиляции программы эта дробь сконвертируется в что-то вроде 0.11111112). Для борьбы с этим есть библиотеки bcmath и GMP.

> list($integerPart, $fractionalPart) = explode('.', (string) $result);


> $valueAsString = sprintf('%s.%s', $integerPart, $fractionalPart);


sprintf("%f", $result). Либо (string)$result. зачем лишние преобразования? И кстати ты учел что результат может получиться в виде 1.2e-20?

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

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/Substraction.php#L8
Эта функция не очень аккуратно написана. Она меняет знак одного из переданных операндов что неожиданно. Надо создавать новый операнд.

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

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/Power.php#L8
Тут по моему ошибка. Что будет если возвести (9/1) в (1/2) ? Возведение в 1/2 это квадратный корень то есть получается ответ 3.Возведение в нулевую степень должно давать единицу. В единичную степень - возвращает то же число.

Вот первый попавшийся урок: http://www.algebraclass.ru/otricatelnaya-stepen/
#603 #785646
>>785630

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

https://github.com/applejacky/arithmetic_expression_calculator/tree/master/Classes
Многовато классов, надо разбивать на папки и неймспесы. Например все токены поместить в отдельный неймспейс.

В лексере проблема - это интерпретация знаков "минус". -1 - это "минус один" или операция "отрицание" примененная к числу один?

Также твой лексер не ловит ошибочные символы. Достаточно дописать

|.

В конец регулярки и он начнет их ловить.

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

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

Ты парсишь выражение в RPN но не удобнее ли сразу строить дерево AST ? Вот тут например есть даже примеры с кодом: https://moodle.vsu.ru/pluginfile.php?file=/80770/mod_resource/content/1/Основы синтаксического разбора.pdf

Но там используется рекурсивный спуск, то есть приоритеты операций зафиксированы в коде и много однотипного кода. Если бы твой алгоритм как-то с тем совместить, чтобы сравнивались приоритеты, но строилось бы не RPN а AST. Разве невозможно?

Вот тут какие-то алгоритмы есть: http://algolist.manual.ru/syntax/parsear.php - не подходят?

А, хотя ладно, AST при желании можно построить из RPN но это скорее будет лишний шаг.

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/ShuntingYard.php#L8
Тут мне кажется стеки незачем передавать как зависимости. У тебя нет необходимости их подменять на что-то, это просто коллекции с данными.

> set_exception_handler(function (Exception $e) {


>$e->getMessage();


>$e->getCode();


Зачем это? Это ведь игнорирует любые исключения. Это неправильно. Чтобы ловить исключения, оберни вычисление в try/catch и укажи там свой класс исключений.

Соответственно в тесте лучше писать так:

'1/0' => 'DivideByZeroException',

Вот я попробовал вычислить выражения:

')))' : https://ideone.com/283Htn
'- (- 1)' : https://ideone.com/gkdxNi
'1 2 3': https://ideone.com/Yedp3k - должна быть ошибка

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/ShuntingYard.php#L14
Тут трудно понять логику, нужны комментарии. Нету последнего else { ... }

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/SimpleFraction.php#L17
Вот тут есть подвох. Флоаты в пхп приближенные и хранятся с ограниченной точностью. int ограничен рамками от -2 млрд до +2 млрд на 32-битных системах. Попробуй дробь вроде 0.1111111111111111111111111 - там скорее всего не получится нужное число знаков и потеряется точность (то есть при компиляции программы эта дробь сконвертируется в что-то вроде 0.11111112). Для борьбы с этим есть библиотеки bcmath и GMP.

> list($integerPart, $fractionalPart) = explode('.', (string) $result);


> $valueAsString = sprintf('%s.%s', $integerPart, $fractionalPart);


sprintf("%f", $result). Либо (string)$result. зачем лишние преобразования? И кстати ты учел что результат может получиться в виде 1.2e-20?

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

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/Substraction.php#L8
Эта функция не очень аккуратно написана. Она меняет знак одного из переданных операндов что неожиданно. Надо создавать новый операнд.

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

https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/Power.php#L8
Тут по моему ошибка. Что будет если возвести (9/1) в (1/2) ? Возведение в 1/2 это квадратный корень то есть получается ответ 3.Возведение в нулевую степень должно давать единицу. В единичную степень - возвращает то же число.

Вот первый попавшийся урок: http://www.algebraclass.ru/otricatelnaya-stepen/
>>791074
#604 #785647
>>785644

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

Ты пишешь "добавлю в User" но в нормальном проекте с DI в юзере нет объекта для работы с базой данных и выполнять из него запросы ты не можешь.

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

> Выглядеть это должно примерно так:


> Class User {


> public function makePremium(MakeUserPremiumCommand $command)


Непонятно зачем тогда вообще эта функция. Если у тебя есть Command то проще сделать

$command->execute($user);
#605 #785674
>>785067
Тоесть я смогу например:
Отправить GET методом, например, ?game=start
В коллбэк функции проверить наличие QueryParameters, сохранить их в переменную
И дальше убрать ?game=start из URL (что-нибудь с Request объектом сделать типа header(location:www.game.com/game);
Но в респонс передать эту переменную с QueryParams (или ещё куда)

Эмулияция POST метода получается, только мы не в Request body параметры передаем а в Request header (т.к GET).
Все верно?
>>785706
#606 #785706
>>785674

Это скорее для тестов полезно. Проверить что выдаст код если ему дать определенный запрос.
#607 #785720
>>785622
Не могу в AMPPS найти командную строку. Вообще, сложный он какой-то, настроек столько.
Ошибка заключалась в том, что там пароль по-умолчанию был. А теперь вообще mysql не запускается.

Поставил Bitnami, он хоть из коробки работает. За разбор спасибо, а то в таких ситуациях чувствуешь себя беспомощной тётей Зиной
Михаил_04 #608 #785859
Привет. В учебнике для новичков есть раздел с рег.в., в нем есть задание где дан список правильных и не плевельных номеров. https://regex101.com/r/qF7vT8/3 - ссылка где можно проверить регулярку. В задании написано что не надо строить сложно выражение, но у меня получается довольно громоздкое и дибилное. Сначала я проверяю ^(\s\+\s7|\s8), а вот дальше у меня очень большое дерьмо получается ([-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()]*)$.
Я уверен что можно записать короче, но я не могу понять как, если бы не было пробелов, скобок и -, я бы написал [\d]{10} но это не прокатит. может я что то не знаю или не понял, подскажите. Спасибо.
>>797242
Михаил_04 #609 #785861
([-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()][-\s()][\d][-\s()])$, поправил.
Михаил_04 #610 #785862
корове не рисуются звездочки после каждого [-\s()], я хз поч.
>>785867>>797242
#611 #785867
>>785862

>корове не рисуются звездочки


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

>я хз поч.


Михуй, потому что ты - ньюфаг. Глянь сюда: http://noobtype.ru/wiki/Wakaba_mark
Зачем неймфажишь?
#612 #785899
https://regex101.com/r/qM3hI6/1 - с моей регуляркой.
#613 #785910
https://regex101.com/r/qM3hI6/2 - вроде бы сделал.
>>797242
#614 #785981
Аноны, есть ли возможность поднять vhost на nginx с отличающийся версией php от остальных? Или какие вообще варианты могут быть?
>>785987
#615 #785987
>>785981
Есть. Для этого тебе нужно будет запустить отдельный демон php-fpm на порту, который отличается от уже запущенного. Потом при создании конфига для vhost ты указываешь тот порт на котором у тебя запущен демон с отдельной версией. Имей ввиду что тебе нужно будет иметь две версии php, которые установлены в разные каталоги и никак между собой не конфликтуют, иначе могут быть проблемы.
>>785992
#616 #785990
Поставил bitnami. В нём такая проблема. Изменяешь файл, сохраняешь, а изменения в браузере будут видны только секунд через 30.
Как я понимаю, в apache стоит какое-то кеширование, только как его отключить не знаю
>>797242
#617 #785992
>>785987
Спасибо, буду смотреть.
>>785993
#618 #785993
>>785992
Вообще, это сложный способ. Я бы на твоем месте попробовал сначала Docker или Vagrant.
>>786023
#619 #786023
>>785993
Сейчас смутно представляю себе что это, времени изучать особо нет. Задача состоит в том чтобы работающий сервер с кучей древних, но используемых по сей день скриптов оставить в нетронутом работоспособном состоянии и параллельно с ними запустить новый приличный проект. Единственная проблема - старье работает на 5.3 и чуть его тронуть, все повалится. Вот и нужно как-то совместно с тем вхостом запустить новый на ~7 версии.
#620 #786040
Как правильно проводить валидацию объекта? Есть основной public метод validate() и несколько private методов (validate то, validate се), в эти private методы лучше передавать свойства или объект?
>>786048>>797242
#621 #786048
>>786040
Чуть по другому скажу. Есть метод validate (Foo $foo) и методы checkBla(), checkBlaBla(), в них передавать из основного метода свойства $foo или сам объект $foo?
47 Кб, 1600x900
#622 #786067
>>787028
#623 #786104
Ньюфаг в треде. Как правильно выводить переменные в тексте?
echo "bla bla $foo bla bla";
или
echo "bla bla {$foo} bla bla";
А то я начал уроки по ссылке из шапки читать, там и так и так делается.
>>786342
#624 #786239
Почему мою извращенную Лиличку не хавает IdeOne, неужели она слишком прожорлива для него?

http://ideone.com/rUhZYS
#625 #786326
>>786239
Ну у меня на линуксе был выхлоп в виде кракозябр. Подсказка из мануала:

>Note: str_split() will split into bytes, rather than characters when dealing with a multi-byte encoded string.


+ У ОПа в учебнике есть упоминание о том, как правильно разбивать строку.
Алсо, зачем там array_map, чем foreach не устроил?
#627 #786398
>>786326
Да, просто хотел выебнуться.
Получилась хуйня.
>>786745
#628 #786409
>>786326
Смею только предполагать, но возможно дело в том, что встроенные функции написаны на си и потому работают полюбому быстрее любых ухищрений с форич? Ну а то что ты с колясочными линуксами не справляешься, то эт ты прост неосилятор, азаза.
>>786649>>786691
8 Кб, 480x480
#629 #786415
>>786326
Алсо, оно же тебе говорит прямым текстом практически, что ты используешь не то, что нужно для кириллицы. Урок ОПа почитай, да.
>>786649
39 Кб, 484x604
#630 #786423
Как передавать в связку файлов в MVC какую-нибудь стороннюю переменную?
Например, вот у нас Yii2 (это не суть важно):
$customer = Customer::findOne(123);
$order = new Order();
$order->subtotal = 100;
- и так далее.
Вот как мне в findOne($id) передать из стороннего скрипта переменную?
Прописываю пространства имён, файл связываю - не видит.
Только если определяю в самом контроллере эту $id.
>>788664
#631 #786615
Привет, подскажите, кто пользуется составлением UML диаграмм при проектировании? Какой программой пользуетесь, или от руки рисуете? Мелкософт VISIO норм?
>>786649
someApprentice #632 #786633
https://github.com/codedokode/pasta/blob/master/security/xsrf.md#Способ-борьбы

>Если (у пользователя нет куки с токеном) {


> $token = генерируем случайный код;


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


А в нашем случае не будет лучше сгенеривировать токент только один раз при залогинивании, и здесь вместо этого вбрасывать исключение?
>>788434
#633 #786649
>>786615
Под сперму обычно советуют Star UML, но его сейчас воровать нужно. Бери Dia, он бесплатный.
А вообще есть ещё вот такая штука: http://yuml.me/diagram/scruffy/class/samples
Как по мне, то так удобнее и быстрее, чем мышкой.

>>786415

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


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

>>786409
Там проблема с тем, что Юникод для хранения символов использует переменное количество байт, а Windows-1251 - кодировка 8-битная. Функция str_split бъет побайтово. У анона, видимо, винда, поэтому и проблем с работой скрипта нет.
Объясни, какое отношение к этому имеет колясочность дистрибутива линукса?
>>786681>>786745
#634 #786681
>>786649
Что такое сперма?

>>обычно советуют Star UML, но его сейчас воровать нужно


Первый все еще бесплатный http://staruml.sourceforge.net/v1/

Пожалуй с него и начну. Спасибо
>>787599
#635 #786691
>>786409

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


А foreach на чём? Нужно не гадать, проверять: https://ideone.com/od1muV
>>786745
#636 #786745
>>786239
>>786326
>>786398
>>786649
>>786691

http://ideone.com/wI8aSz

Есть такой вариант, но до меня, как то не доходит, как его исправить
>>797242
46 Кб, 1919x1039
59 Кб, 1919x1039
#637 #786912
>>785639
Почитал про работу транзакций и блокировки, но видимо я чего-то не понимаю. Вот тестировал и попробовал воссоздать в командной строке ситуацию, когда два пользователя одновременно пытаются добавить комментарий.
В двух клиентах psql я начинаю две транзакции, и в одном из них выбираю из таблицы comments строку, которая имеет самый большой matpath в ветке, и блокирую эту строку через SELECT FOR UPDATE. Потом, во втором клиенте делаю то же самое, но так как строка уже заблокирована первой транзакцией, результата я не получаю, все вроде бы работает как должно (пик 1).
Затем, в клиенте который знает максимальный matpath, я добавляю новый комментарий в ветку, соответственно увеличивая максимальный matpath ветки на 1. После добавления комментария, я завершаю транзакцию, и во втором окне, я вижу что запрос который все это время был заблокирован, выбрал комментарий с старым matpath (пик 2).
Почему так происходит? Ведь я закомиттил транзакцию, значит данные должны быть доступны всем. Если после коммита первой транзакции сделать точно такую же выборку еще раз (во второй транзакции) она вернет правильный результат.
В пасте написано

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


Но почему-то тут SELECT все равно возвращает старые данные. Я предполагаю что это из-за подзапроса, который выбирает максимальный matpath из таблицы

>SELECT MAX(matpath) FROM comments WHERE NOT (parent_id IS NOT NULL) AND file_id = 3)


Так как этот подзапрос ничем не блокируется, то он в самом начале выбирает matpath максимальный на тот момент (004), и после того как основной запрос разблокирован, происходит выборка записи с старым matpath. Так как в запросах типа SELECT FOR UPDATE в постгресе нельзя использовать агрегатные функции, это наталкивает меня на мысль что тут лучше использовать оптимистичные блокировки. Или я что-то не так делаю?
>>787017
#638 #787017
>>786912

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



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

Вместо подзапроса лучше наверно писать ORDER BY mpath DESC LIMIT 1

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


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

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

Может блокировать по-другому? Берем блокировку на родительский (или последний, или все в ветке) комментарий, затем отдельным запросом спокойно считаем max path, вставляем комментарий и коммитимся.

Тут правда проблема - что блокировать, если ни одного комментария еще нет? Файл?

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

Что насчет тестирования? У тебя есть идея как проверить что все нужные блокировки реализованы корректно?
>>787081
#639 #787028
>>786067
>>781215
>>776762

> W5.1(Циклы и айфон в кредит)


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



> $paymentTotal += min($creditBalance, $monthlyPayment);


> $creditBalance -= $monthlyPayment;


> $creditBalance = max($creditBalance, 0);


Тут можно было просто сделать

плата = мин(баланс, месячная плата);
....

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

> W5.2(Циклы и айфон в кредит)


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



Все верно

> Регулярные выражения (номера телефонов)


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


Ок, все верно

> Регулярные выражения (имейлы)


> Исправлено: https://ideone.com/Plrxg7


Ок, хорошо

> Регулярные выражения (правописание)


> Исправлено: https://ideone.com/ZgaGL7


Ок, хотя я бы в правиле про а/но просто поставил бы \b. но перечислить знаки препинания тоже в общем можно.

> Регулярные выражения


> Исправлено: https://ideone.com/FypBqZ



> "rulePattern"=>"/\bзделал\b/ui",


> "rulePattern"=>"/\bзделаю\b/ui",


> "rulePattern"=>"/\bзделан\b/ui",


Это можно объединить вместе, плюс не поддерживаются слова "зделает", "зделанный". Лучше убрать \b справа.
#639 #787028
>>786067
>>781215
>>776762

> W5.1(Циклы и айфон в кредит)


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



> $paymentTotal += min($creditBalance, $monthlyPayment);


> $creditBalance -= $monthlyPayment;


> $creditBalance = max($creditBalance, 0);


Тут можно было просто сделать

плата = мин(баланс, месячная плата);
....

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

> W5.2(Циклы и айфон в кредит)


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



Все верно

> Регулярные выражения (номера телефонов)


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


Ок, все верно

> Регулярные выражения (имейлы)


> Исправлено: https://ideone.com/Plrxg7


Ок, хорошо

> Регулярные выражения (правописание)


> Исправлено: https://ideone.com/ZgaGL7


Ок, хотя я бы в правиле про а/но просто поставил бы \b. но перечислить знаки препинания тоже в общем можно.

> Регулярные выражения


> Исправлено: https://ideone.com/FypBqZ



> "rulePattern"=>"/\bзделал\b/ui",


> "rulePattern"=>"/\bзделаю\b/ui",


> "rulePattern"=>"/\bзделан\b/ui",


Это можно объединить вместе, плюс не поддерживаются слова "зделает", "зделанный". Лучше убрать \b справа.
65 Кб, 1919x1039
#640 #787081
>>787017

>Может блокировать по-другому? Берем блокировку на родительский (или последний, или все в ветке) комментарий, затем отдельным запросом спокойно считаем max path, вставляем комментарий и коммитимся.


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

>Тут правда проблема - что блокировать, если ни одного комментария еще нет? Файл?


А в таком случае запросов будет уже 4.

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


У меня есть два варианта, и для обоих нужна поддержка многопоточности.
1. Запустить два потока для добавления комментария, получить результат, сравнить что matpath одного и второго комментария не равны друг другу.
2. Запустить два потока для добавления, сделать так чтобы каждый из них задержал выполнение скрипта на n секунд. Таким образом, если блокировки работают правильно, один поток должен иметь время выполнения в два раза больше чем n. Насчет этого способа я не уверен, но можно попробовать применить функцию sleep() http://php.net/manual/en/function.sleep.php

Это просто предположения, я раньше ничего многопоточного на PHP не делал, но реализации нескольких потоков можно взять вот это https://github.com/krakjoe/pthreads например.
А еще мне кажется что я придумал какие-то велосипеды и там есть способ попроще.
>>788185
#641 #787499
Идите нахуй со своими студентами и файлообменником пидры.
Открыол документацию симфони, ларавель, йии - там блять всё по-разному совершенно и нахуй не нужны ваши эти велосипеды самописы.
Какой профит возится с самописным говном, когда везде всё другое и ради чего? Чтобы иметь свой кривопис на гитхабе?
Родина дала им фреймворки. Бери, делай что угодно.
Не хочу, хочу жрать говно.
уже написал когда заметил, что предлагается юзать фреймворки, ну да похуй, пусть будет
#642 #787502
>>787499
Делай TestHub на Symfony.
someApprentice #643 #787554
https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php#L51

>> if ($registerStudentForm->getPassword() != "") {


>> $registerStudentForm->setStudentPassword();


>Вообще, это можно было бы делать в классе формы в методе fillDataFromArray


Эта проверка делается для того чтобы понять обновлять кукисы или нет. Можно ли обновлять их в любом случае, независимо от того меняем мы пароль или нет?
>>788185
#644 #787599
>>787499
Но ты ведь не поймешь, как все устроенно и просто будешь писать код копипастой.
>>786681

>Что такое сперма?


Windows
#645 #787802
Можно ли использовать статический метод для создания экземпляров класса, например
$boss->addEmployee(Employee::recruit ("Игорь");

Какие подводные камни?
>>787960>>788185
#646 #787960
>>787802
Это вродь какой-то общепринятый паттерн, попробуй в гугле singleton и factory method
#647 #788107
Как получит список названий файлов из папки со множеством подпапок?
>>788109>>788185
#648 #788109
>>788107
Т.е. включая те файлы внутри подпапок.
>>788113
#649 #788113
>>788109
Ну погугли "PHP recursive directory path", неужели так сложно?
Вторая ссылка как раз ведёт на мануал.
>>788115
#650 #788115
>>788113
Итератор этот находил, но чтоб наверняка здесь решил спросить, спасибо.
#651 #788185
>>787081

> Так работает, только получается 3 запроса на одну вставку комментария. Не слишком ли это много?


Либо 3 запроса, либо оптимистичная блокировка.

> и для обоих нужна поддержка многопоточности.


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

exec('php some-script.php 1 &');

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

То есть можно сделать такой bash-скрипт и запускать его:

php script.php 1 &
php script.php 2 &

# ждать завершения фоновых процессов
wait

И получается сценарий тестирования такой:

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

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

>>787499

Как ты в фреймворках будешь разбираться не зная основ? Они не для начинающих.

>>787554

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

>>787802

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

>>788107

рекурсивный итератор
#651 #788185
>>787081

> Так работает, только получается 3 запроса на одну вставку комментария. Не слишком ли это много?


Либо 3 запроса, либо оптимистичная блокировка.

> и для обоих нужна поддержка многопоточности.


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

exec('php some-script.php 1 &');

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

То есть можно сделать такой bash-скрипт и запускать его:

php script.php 1 &
php script.php 2 &

# ждать завершения фоновых процессов
wait

И получается сценарий тестирования такой:

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

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

>>787499

Как ты в фреймворках будешь разбираться не зная основ? Они не для начинающих.

>>787554

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

>>787802

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

>>788107

рекурсивный итератор
#652 #788413
Какие языки стоит начать изучать новичку, после PHP, для расширения горизонтов и актуализации своих навыков, если PHP был первым языком? Или может быть гораздо полезнее будет учить базы данных или дискретную математику? Какую стратегию выбрать, изучать что-то совсем новое и сложное, практически не связанное с областью профессиональной деятельности, вроде АСМ, C++ или Haskell? Или наоборот, выбрать аналог, используемый с похожими задачами, типо Ruby/Python? Выбрать посложнее-посерьезнее C#/Java или полегче-попроще JavaScript? Расширить знания предметной области или углубить?
>>788425
#653 #788425
>>788413
Сначала выучи РНР, дальше почувствуешь, что нужно.
И дальше будет уже проще намного.
PHP+SQL+HTML+CSS+Javascript - для начала.
#654 #788434
>>786633
Разобрался.
Токены нужны чтобы не было возможности отправлять формы с чужого сайта которые доступны даже для не зарегистрированных пользователей.
#655 #788476
>>788438
Есть у шизика >>769611 (OP)
#656 #788564
А вы чего не перекатываетесь? Тред скоро смоет же.
>>788570
#657 #788570
>>788564
Как давно занимаешься изучением погромирования? Как и откуда узнал об этом треде?
Расскажи, не стесняйся, здесь все свои, а я просто собираю статистику.
Традиция всех последних тредов 1000+ постов.
>>788580>>788598
45 Кб, 248x353
#658 #788580
>>788570
Ну ладно, сделаю вид, что убедил.

Кто-нибудь читал пикрелейтед? Стоит на нее время тратить?
>>788590
62 Кб, 800x450
#659 #788590
>>788580
Я не только читал, но и всё абсолютно повторял за Никсоном, даже финальную гадость без шаблона.
Очень качественная книга для новичка.
Там объясняется и демонстрируется куча такого, о чём ОП не особо плавно рассказывает в своём учебнике.
Но рекомендую сначала разобрать учебник ОПа до ООП, а потом ещё раз закрепить Никсоном, как раз подобраться к MySQL.
Правда, я сразу ставил себе РНР7, а не РНР5, как у него, - пришлось додумывать, как некоторые функции по-другому писать (mysqli вместо mysql и ещё немного других).

Ты не ответил на вопрос: откуда узнал о треде, что подвигло заняться программированием?
#660 #788598
>>788570
Зачем? Наоборот, когда в треде 500+ постов, в нём, в общем случае, нет случайно залетных с вопросами как под копирку. Почитай первые 200 постов треда - просто обсуждение ни о чём.

>>787499
Фреймворк - не панацея, он не научит тебя писать хороший код.
В этом треде есть пост: >>775454
Обрати внимание на строки

>достался проект системы электронного документооборота на PHP+Symfony2, но при этом с процедурным кодом внутри (всё свалено в огромные классы с иманами что-то-там-Serivce, где по 20-30 публичных методов, в каждом из которых по 50-400 строк кода. Простыни по 4 экрана в среднем...).



Ещё я помню статью на хабре, туториал по созданию блога на Symfony. Так там автор вместо того, чтобы использовать связь M:M для постов и тегов ( воспользовавшись богатыми возможностями ORM), предпочёл хранить список тегов сплошной строкой в одной колонке! Это ведь даже первой нормальной форме не соответствует, не соблюдается атомарность значений.

Мне велосипедироание студентов очень помогло, я рад, что отложил фреймворки на время, с которыми работал как с чёрной коробкой. Теперь они гораздо понятней. В конце концов, тебя никто ничего не заставляет делать. Тебе дали интересные задачки, нет, не хочу, буду крудить на фреймворках, копируя бездумно код из документации, а потом сосну, когда предложат сделать TestHub.
12 Кб, 590x221
#661 #788626
Помогите разобраться с array_udiff,
нужно обойти два массива, один с вариантами хода, другой с глупыми собаками, и исключить из первого соседние с собакой варианты хода.
Сравниваю координаты ходов и собаки, и если модуль разницы обоих координат <= 1 то такие ходы соседние с собакой и их нужно исключить.
Зачем колбек-функции возвращать три аргумента -1 0 1? Просто 0 не достаточно, показать что значения в массивах одинаковы?

Код на пике
>>792640
#662 #788640
>>769611 (OP)
ОП, успокой меня. Я сейчас пошёл на hh.ru, на moikrug.ru, я смотрю вакансии и тихо охуеваю. По python, ruby, node.js не так уж мало вакансий и там есть реальные предложения за 200+к в месяц. Для php даже в вакансиях, где перечислены вообще все известные эйчару слова, в основном порог в 150. А выше идет какая-то совсем муть и почти что нет вариантов. Почему так и все ли так плохо? PHP оплачивается настолько хуже, чем другие web-языки? Это ведь еще с учетом того, что когда в вакансии написано RoR, то там и будет, скорее всего, RoR, а когда в вакансии написано PHP, там будет php, symphony, html, css, javascript (amber, backbone, angular), mysql, mongodb, apache hadoop, sas, less, bootstrap, wordpress, bitrix и стометровка за 5 секунд.
#663 #788653
>>788640
Потому что куча спроса.
Спрос делает предложение более вялым.
Не ты, так куча других РНРшников.

Я не ОП, меня такие ваши заявления раздражают только.
Родина дала им знание РНР и всего сопутствующего. Не хочу делать свой проект, хочу работать на дядю и чистить вилкой за кем-нибудь код во всякой мути...
#664 #788656
>>788640

> Это ведь еще с учетом того, что когда в вакансии написано RoR, то там и будет, скорее всего, RoR, а когда в вакансии написано PHP, там будет php, symphony, html, css, javascript (amber, backbone, angular), mysql, mongodb, apache hadoop, sas, less, bootstrap, wordpress, bitrix и стометровка за 5 секунд.


Ты думаешь если ты рубист, то тебя никто фронтэнд делать не заставит? Это от места работы зависит, есть компании которые в требованиях пишут что нужно знать PHP, а на деле ты будешь и сервера настраивать, и интерфейсы рисовать, и бэкэнд делать. На других языках то же самое, такие обнаглевшие шараги везде есть.
>>788854
116 Кб, 768x1024
#665 #788664
>>786423
Ну едритЪ, как же сделать такое?
Вот у меня есть CRUD на MVC: запускаю test/index, запускается контроллер, который из модели берёт что-то и выводит в этом index.
Как мне дополнительно подставлять ориентиры для этого вывода сторонним скриптом?
Выводится строка по id - как мне менять передаваемую из модели в контроллер $id, чтобы каждый раз выводимая строка была другой (в соответствии с тем, что там сторонний скрипт подставляет)?
#666 #788710
>>788664
Не знаю поможет ли тебе это или нет, но у нас писали так
site/controller/method/arguments

Как бы выглядел при этом урл ирл воображаемой социалочки
social.net/users/show_user/3
- просим у контроллера показать юзера с id3

social.net/users/show_friends
-показать друзей этого юзера например

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

social.net/users/show_friends?sort=name
-с сортировкой по имени

social.net/users/show_friends?sort=id
-с сортировкой по id

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

ПС. я вообще не шарю о чем ты хочешь узнать, я ракал меня джуном в новео не взяли, просто мне обидно что тебе никто не помогает
>>788771>>789475
#667 #788716
>>788664
Ты хочешь плейсхолдеры сделать что ли?
Допустим чтобы example.com/index.php?id=3 выводила пользователя с ID 3?
Это делается через получение GET переменной, в фреймворках эту переменную обычно хранит в себе класс Request, например вот - http://www.yiiframework.com/doc-2.0/yii-web-request.html
Если не используешь фреймворк, GET переменную можно получить из глобального массива $_GET http://php.net/manual/en/reserved.variables.get.php хотя это не совсем ООП подход.
>>789475
#668 #788771
>>788710

Этот подход может и годится для разработки прототипа, но в общем он плохой:

- УРЛ могут получаться слишком длинные
- одной странице соответствует бесконечное количество УРЛ:

/users/show_user/3
/users/show_user/3/
/users/show_user/3/some/1
/users/show_user/3/some/2

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

Лучше исплоьзовать роутинг который позволяет задавать произвольные УРЛ и не позволяет зайти на страницу под другим УРЛ. Например symfony routing

>>788664

> Выводится строка по id - как мне менять передаваемую из модели в контроллер $id, чтобы каждый раз выводимая строка была другой (в соответствии с тем, что там сторонний скрипт подставляет)?


Ты по моему что-то путаешь? Обычно это контроллер передает в модель id записи которая ему нужна, а не модель в контроллер.
>>789475>>789819
#669 #788773
ОП, а почему в ридми тут https://github.com/codedokode/pasta нет этого https://github.com/codedokode/pasta/blob/master/js/ajax.md урока про аякс? Это просто черновик? А то пять минут искал его в гистах, пока не додумался в папки посмотреть.
>>792640
#670 #788854
>>788653

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


Вот просто скажи, что может анон такого сделать, чтобы это кому-то надо было и анону что-то приносило? Серьезно, с монетизацией сейчас все итак хуево, а дальше только хуже будет, эпл вон уже в ОС адблок встроила, браузерные игры вымерли как класс.
>>788656
Вот именно, что на PHP их значительно больше.
#671 #789071
>>788854

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


Не слышал про такого Гоблина, который сделал аналог от слова "анал" агар.ио - Чашка Петри?
Парнишка аноним, обитает где-то в нашем разделе.
Отлично сейчас зарабатывает на продаже всяких скинов для этих молекул и на рекламе AdSense.
Браузерка.
>>790640
#672 #789373
>>788854

>>браузерные игры вымерли как класс.


Слава тебе, господи.
#673 #789374
>>788653
какой нахер свой проект? Таких стартаперов в москве как неёбаных тараканов, и все сосут, без исключения.
#674 #789451
http://ideone.com/rPhBeR – моя Лиличка. Делал недолго, думаю, можно проще. Все никак не могу сесть за студентов, читаю-читаю, а начать делать глаза боятся, хотя вроде все понимаю, скорее, для меня муть – это автозагрузка, структура проекта, правильный Front controller. Думаю, надо начать, а там пойдет, да всё прокрастинирую
#675 #789452
>>789451
Начни с плана или со списка подзадач, в процессе втянешься. Мне помогает.
>>789528
#676 #789465
>>789451
Думаю норм вышло, я сделал запутанней: https://ideone.com/Wkq2Fo

>правильный Front controller


Я разве его обязательно делать? Да и что там может быть неправильного, в твоём случае это будет индексный файл, который обрабатывает все запросы к сайту. Хорошее объяснение FC есть в (не пугайся) доках Symfony: https://symfony.com/doc/current/book/from_flat_php_to_symfony2.html
>>789528>>792640
#677 #789475
>>788771
>>788716
>>788710
Спасибо за помощь, братья и друзья!
Сейчас буду разбираться.
Я пока путаюсь в понятиях, потому что только недавно начал изучать MVC.
Просто так научился делать вывод из БД всей таблицы с помощью модели, контроллера и вида. А вот как сделать динамику и, допустим, вывод попеременно каких-нибудь строк из той же таблицы - не разобрался.
Просто подставив в контроллер id строки - пожалуйста, а вот сторонним скриптом передать не получалось.
Сейчас вникну в ваши советы, ух, как вникну сейчас!..
#678 #789528
>>789452
>>789465
Спасибо большое, попробую и почитаю
#679 #789675
>>789451

> для меня муть – это автозагрузка



Я вот так сделал, и это собственно всё.

<?php

spl_autoload_register(function ($class) {
include_once 'classes/' . $class . '.php';
});


складываешь свой файлик с классом в папку classes что бы путь выглядел по типу classes/Yoba.php

и в коде можешь писать теперь $a = new Yoba;
#680 #789819
>>788771

>Ты по моему что-то путаешь? Обычно это контроллер передает в модель id записи которая ему нужна, а не модель в контроллер


Я могу путать.
Но я имею в виду именно следующее: как в контроллер передавать переменную id, которая является primary_key у таблицы? Это нужно, чтобы вытащить строку по этому первичному ключу.
Читаю про плейсхолдеры тут - http://www.yiiframework.com/doc-2.0/yii-web-request.html - не вполне это то, к сожалению. Или я не понимаю опять.
Вот есть у нас, допустим, тест. Каждое отдельное задание содержит вопрос, варианты ответов к нему, подсказку и количество баллов за правильный ответ, а также сам правильный ответ. Все они содержатся в одной строке таблицы.
И вот мне надо, чтобы в контроллер передавался id этой строки, тогда view будет отображать остальные все моменты: вопрос, варианты ответов, подсказку и т.д.
И мне для этого нужно лишь идентификатор строки передать, дальше всё вылетит в браузер.

>Как бы выглядел при этом урл ирл воображаемой социалочки


>social.net/users/show_user/3


>- просим у контроллера показать юзера с id3


Вот так, наверное, возможно, да. Этот id передавать внутрь контроллера же можно как-то через $_GET? А дальше от тех же вопросов переходить по ссылке (там просто id++ в URL будет, например) и так далее, наверное.
Подумаю, раздумаю, спасибо.
>>789838>>789853
#681 #789838
>>789819
Вот это для начала почитай http://php.net/manual/ru/reserved.variables.get.php
В фреймворках там немного по другому реализовано, для начала тебе хватит и $_GET.
Контроллер как раз этим и занимается, что разбирает запрос от пользователя, а потом уже на этой основе что-то ему отдает.

>Этот id передавать внутрь контроллера же можно как-то через $_GET?


Если ссылка будет вида example.com/index.php?id=3 то в скрипте $_GET['id'] будет равно 3.
#682 #789853
>>789819

>Вот так, наверное, возможно, да. Этот id передавать внутрь контроллера же можно как-то через $_GET?



Ну у тебя как контроллеры написаны??? У тебя есть "умненькие урлы"?

Что бы ты мог обращаться к контроллеру через урл?
Не так что бы у тебя всегда было обращение к site/index.php

к site/controller1, site/controller2 и так далее?

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

и в контроллере проверяй пришло ли что в $_GET[];
#683 #789918
Так как у меня лютая прокрастинация и на этой почве нет никакого развития, начал пытаться писать ООП-код, похуй что я не понимаю ничего в ООП.
Просто херачить начал кошек-мышек. буду спамить своими неловкими подвижками и спрашивать всё ли я делаю правильно.

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

http://ideone.com/DgArvv
#684 #789926
>>789918
У тебя для одних и тех же мышек могут быть разные иконки? Зачем?
То есть, твой код позволяет сделать так:
$cat = new Cat('К');
$mouse = new Mouse('К');
То есть, иконки могут продублироваться.

Думаю, их можно прописывать по умолчанию в свойстве для каждого класса животного. Ну а вообще, смотреть пока нечего, пиши ещё.
>>789929>>792639
#685 #789929
>>789926
Ну да, ты прав, пока нечего. Ведь все проблемы и затупы у меня в голове. Например держать ли в классе животных координаты или только в мире?
>>792639
29 Кб, 698x523
#686 #790042
Устроился в прошлом месяце на удаленку ковырять битрикс. Думал что будет больше свободного времени за счет экономии на дороге в офис, а вот и нифига.

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

Все это время, в отличии от офиса, внезапно не затрекать. Как-то у меня получается что на 8 затреканных часов выходит 11-13 потеряных по факту - в 9 сажусь и ток к 21 вылезаю. В офисе я в лучшем случае фактически отрабатывал часов 6, а с учетом времени на дорогу и собирашки тратил часов 10-11.

Из плюсов - можно пить пиво под конец рабочего дня и не надо ручкаться с коллегами. Это круто.
#687 #790069
>>790042
По мне так это конечно лучше, чем час на дорогу в одну сторону, но 10 часов это конечно пиздец.

Учись оптимизировать процесс забивая хуй на часок другой в середине рабочего дня пока с другой стороны вся описанная тобой вата и прочее. Можно работать час через час например. Ходя в тренажерку или магазин в процессе рабочего дня. Или как там у вас устроено всё? 5 минут не отвечаешь в скайпик и тебя уже штрафуют? Вангую что если реально 12 часов сидеть дома на удаленке то через месяца 3 люто заебет.
>>790144
#688 #790110
А как ъранить массивы в бд? Вот хочу я например теги прикрутить? У 1 сущности может быть например одна тема, иэто норм. А как делать теги? Если их от 0 до целой кучи может быть? Хранить их строкой которую потом бьешь на части и выводишь, а так же перезаписываешь всю строку при правках?
>>790114>>792639
#689 #790114
>>790110
Гугли отношения в SQL. Конкретно тебе нужно многие-ко-многим, много сущностей могут иметь много тегов.
>>790158
#690 #790132
Я совсем безнадёжен, если у меня на решение задачи "Считалка" было затрачено около часа?
#691 #790144
>>790069

>как там у вас устроено всё?


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

>Можно работать час через час например.


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

>через месяца 3 люто заебет


Тоже так думаю.
>>790152>>792639
#692 #790152
>>790132
Нет, если каждый день практиковаться, то будет всё лучше получаться. Кругом одни, не гении, поверь. Просто тренькаются постоянно в чем-то и поэтому норм тащат.

>>790144
Ну может у тебя прост пока первый месяц не очень получается. А дальше получше будет. Но всё равно надо как-то оптимизировать. Опять же если за еще 1 месяц ничего не изменится, то можешь прямо сказать тимлиду, что рассчитывал на 8 часов работы, а не на 12.
>>790291>>792639
#693 #790158
>>790114
Я примерно так же на собеседовании реализовал друзей в бд, что каждая пара просто была отдельной записью и всё такое. Суть в том, что с точки зрения нормализации это ведь куча лишней инфы и все такое. Ничего лучше не придумали?
>>790240>>792639
#694 #790240
>>790158

>с точки зрения нормализации


Каждая запись - ребро графа, куда уже нормальней то?
#695 #790291
>>790152
Быть гением = иметь внутренний стержень + задрачивать основную область + иметь знания в других областях + укрепление своих слабых сторон.
#696 #790316
>>790132
Какая "Считалка"?
Я смотрю, ОП переработал весь учебник, неплохо, многое чётче выглядит.
#697 #790317
>>790132
А, увидел сейчас.
Вот мой вариант: http://ideone.com/sugCcD
Насколько помню сейчас, затратил на него не один час и даже не два.
Но я-то вполне безнадёжен, даже не интересуюсь, насколько.
>>790332>>792639
#698 #790332
>>790317
Поначалу слоупочить в новых для себя областях это более чем нормально.
Не ной, а решай, пробуй, ошибайся, совершенствуйся. Вот, смотри, человек в famous university >= 4 года отбарабанил, а простую задачку решить не может: https://workplace.stackexchange.com/questions/39004/which-weak-algorithmic-strategies-i-have-that-lead-me-to-failing-coding-this-sim
Вот у него всё плохо.
>>790496
someApprentice #699 #790355
https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php#L74

>Вместо include __DIR__ . '/../../templates/registration.phtml'; лучше было бы сделать метод $this->render('templates/registration.phtml')


Если заключить инклуд в стороннюю функцию то в шаблоне становиться нельзя обращаться к переменным в контроллере (к таким как $token, $registerStudentForm). Можно как-нибудь обойтись без передавания этих параметров на вход функции?
>>792638
#700 #790379
>>790042
Тоже устраиваюсь на удаленку, но я дизайнер. Обдумывал вот этот момент, и пришел к выводу, что если работодатель будет требовать трекать время, то во-первых, рабочий день будет на пару часов длиннее чем в офисе, за счет перерывов на обед, размяться, покурить. А во-вторых, я буду работать столько, сколька за все свои десять лет стажа не работал, ни в офисе, ни на фрилансе. Я всегда для себя трекаю свое время, это позволяет лучше оценитвать свою работу, и отлично помогает в борьбе против прокрастинации, т.к. я зараннее знаю сколько мне потребуется времени на решение конкретной задачи. Так вот в среднем, я работаю три часа в день. Иногда бывает больше два, три подхода по 2 часа, и в такие ддн я реально заебываюсь под вечер. Голова просто перестает соображать, а руки не слушаются. Но работать по 8 часов, каждый день - ты герой, скажу я тебе!
>>792638
99 Кб, 700x525
#701 #790496
>>790332
Я на пикче.
А задача интересная, кстати.
>>790551
14 Кб, 399x382
#702 #790528
Объясните нубу. Файлообменник.

У меня имеется модель с некоторыми свойствами, одно из которых "размер". Оно измеряется в байтах. Контроллер получил модель из базы данных. Теперь следующее. У меня имеется функция берущая на вход int байты и отдающая строку "столько-то мбайт/кбайт/йоттабайт". В контроллере "информация о файле" я перевожу данные в строку и отдаю переменной в шаблон. Но что делать в контроллере "n-ое число последних файлов"? Пробегать по массиву объектов-файлов и ставить в свойство модели "размер" строку "столько-то того-то" чтобы в дальнейшем в шаблоне вызывать это свойство? Или философия MVC допускает то, что в шаблоне в цикле я смогу вызвать мою функцию конвертер для каждого объекта?
>>790546>>792637
#703 #790546
>>790528
Ладно, раз я пришел за советами спрошу еще. Будут ли модели "Картинка", "Видео", "Аудио" наследники модели "Файл"? Или в этой задаче всего одна модель.
>>790551>>792637
#704 #790551
>>790546
Модель - это почти всегда отдельная таблица. Решай сам дальше.

>>790496
Там хватит просто вложенного цикла: https://ideone.com/EFAli4
>>790565>>790577
#705 #790565
>>790551
Ну вот комменатрии "У меня от этого файла брат умер" это я точно понял что будут отдельной моделью и таблицей. А с картинками, например, не понятно. У них наверное будут отличающиеся от других файлов свойства вроде "ширина/длина", т.е. получается тоже отдельно будут. Ладно, решаем дальше.
>>792637
#706 #790577
>>790551

>Там хватит просто вложенного цикла: https://ideone.com/EFAli4


Сука пиздец блядь сука блядь нахуй у меня пригорело от тебя, какой же я тупой.
>>792428
#707 #790640
>>789071
Это уже совсем другое (тут уже браузер просто площадка, ничего от форумных срачей и ролевого элемента всяких БК и даже Дваров не осталось и близко) + причем тут пхп?
>>788640
ОП, ответь плиз.
>>790650
#708 #790650
>>790640

>Это ведь еще с учетом того, что когда в вакансии написано RoR, то там и будет, скорее всего, RoR, а когда в вакансии написано PHP, там будет php, symphony, html, css, javascript (amber, backbone, angular), mysql, mongodb, apache hadoop, sas, less, bootstrap, wordpress, bitrix и стометровка за 5 секунд.


Прочитай первые ~200 постов этого треда. Вот, блин, такой же вопрос задали: >>775493
Никто тебя уговаривать и держать не будет, на чём хочешь зарабатывать - то и учи.
#709 #790722
Как определить является ли файл картинкой? getImageSize('/') вызывает ошибку у некартинок вместо false, exif_imagetype('/') требует подключение библиотеки в php.ini. Ковырять массив с информацией о файле на факт существования слова image?
#710 #790728
>>790722
По mime-type.
Его можно получить этой функцией http://php.net/manual/ru/function.mime-content-type.php
Или использовать библиотеку getId3 http://getid3.sourceforge.net/
>>790766
#711 #790766
>>790722
>>790728
Или еще вот этим можно http://php.net/manual/ru/function.finfo-file.php
Эта функция поновее будет чем mime_content_type
#712 #790773
Ньюфаг в треде. Решил задачку про айфон, считает вроде все правильно, но что-то мне подсказывает, что код написан как-то криво.
http://ideone.com/z42H7e
>>790778>>792636
#713 #790778
>>790773
Ну да, у тебя вот эта строчка

$creditBalance = ( $creditBalance * $percent ) + $servicePayment;

перед циклоv сначала высчитывает долг, а потом в конце цикла после платежей она же.
>>790795
#714 #790793
>>789918
http://ideone.com/LcPT7o

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

Похоже всё придется переделывать. Да и то, что координаты животинки хранятся и в классе животинки и в классе мир как-то неправильно ведь? Надо что бы либо там либо тут?
>>792636
#715 #790795
>>790778
Ну так перед циклом это строка нужна, чтобы процент за нулевой месяц прибавить. В цикле же я сначала выплачиваю долг, а потом уже прибавляю месячный процент. Если сделать наоборот, то может выйти так, что до проверки условия выхода из цикла сумма долга была меньше чем сумма, которую платит анон(5к в данном случае), а после прибавления процентов она станет больше и за месяц выплатить до конца не удастся, хотя цикл уже завершился. У меня был вариант внутри самого цикла сделать if с проверкой финальной суммы. Тогда бы выглядело красивее и все влезло в цикл, но мне в таком варианте не понравилось, что этот if будет лишним действием, вызываемым на каждой итеррации цикла, хотя по факту он там не нужен.
>>790847
#716 #790816
>>789451
Я начал студентов с листочка с карандашом. Нарисовал представления, какие должны быть, сразу модули повторяющиеся увидел, а там пошло-поехало.

Че-то github'у плохо и клиент не открывается. А я как раз все правки закончил(
>>792636
#717 #790838
Господа, есть возможность по человечески обработать фатальную ошибку пхп, не прибегая к парсингу буфера?
На сервере пхп 5.6
>>792636
#718 #790847
>>790795
Нет, он не будет вызываться на каждой итерации, но проверяться будет, да.
#719 #791004
Может быть уже новый тред появился, в котором все сидят обсуждают, а я его не вижу?
>>791006
#720 #791006
>>791004
Я тебе сообщу, когда появится.
31 Кб, 834x391
76 Кб, 429x189
#721 #791074
>>785646
https://ideone.com/1sNagN
https://github.com/applejacky/arithmetic_expression_calculator

>Что будет если возвести (9/1) в (1/2) ? Возведение в 1/2 это квадратный корень то есть получается ответ 3


Я гуглил, но не нашёл функции для нахождения корня n-ной степени. Везде советуют использовать pow(основание_степени, 1/показатель_степени). Проблема в том, что возводить в дробную степень может только функция pow, bcpow и gmp_pow не могут: https://ideone.com/miPWb3
Всякие матановые способы нахождения корня n-ной степени я не осилю. Пример с 9^1/2 теперь работает, но пришлось использовать pow.

Вообще с числами с произвольной точностью появились проблемы, которые просто ставят меня в тупик.
К примеру, я хочу посчитать сумму '0.111111111111111111112' и '0.22222222222222222222'. Сама функция bcadd считает её нормально, но в калькуляторе мне нужно каждое из этих чисел перевести в простые дроби, так как все операции у нас проходят над простыми дробями. Для этого нужно найти НОК. То есть для первой дроби мне нужно умножать 111111111111111111112 на 1000000000000000000000. Даже ideone не выдержал, выплюнув Time limit exceeded (пик 1), при том, что сложные расчёты на нём происходят в несколько десятков раз быстрее, чем на моём ноуте. Нижний Success относится к ситуации, когда я пытался найти НОК для 2 и 100..(много нулей), сама функция нахождения НОК работает правильно: https://ideone.com/TmuS8l

>Ты парсишь выражение в RPN но не удобнее ли сразу строить дерево AST ?


Было проще почитать статью про алгоритм сортировочной станции на вики и облечь псевдокод в код, чем читать талмуд вроде: https://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
Теперь я понимаю, что нужно было сразу браться за AST с грамматиками, причины описаны ниже. Однако всё же хотелось бы сделать задачу 2-я способами. Но и браться за один способ, не доделав другой, не хочется.

>И кстати ты учел что результат может получиться в виде 1.2e-20?


Изменил трюки с explode('.', $foo) на трюки с bcdiv и floatval, теперь экспонента появляться не должна: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/SimpleFraction.php#L59

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


Попробовал ещё использовать вместо регулярок функцию sscanf здесь: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/SimpleFraction.php#L21
Но эта функция основана на доступных типах данных, поэтому не годится для чисел с произвольным количеством цифр (пик 2).

>В лексере проблема - это интерпретация знаков "минус". -1 - это "минус один" или операция "отрицание" примененная к числу один?


Да, я погуглил насчёт унарных операторов в RPN и понял, что эта нотация не умеет отличать унарный плюс/минус от бинарного: http://wcipeg.com/wiki/Shunting_yard_algorithm#Unary_operators
Там советуют использовать отдельные знаки для унарных + и -, например # и $, для этого нужно модифицировать алгоритм распределяющей шляп сортировочной станции. Так пока что и сделал.
Ещё я вижу очень запутанный способ решения без необходимости вводить новые знаки - на этапе парсинга инфиксного выражения заменять конструкции вида -3 на (0-3), сделав минус/плюс только бинарными. Но что делать с выражением вида -(3+((+2)+2))?
Находим унарный оператор (на основе соседних символов), в данном случае это будет минус, он матчится в $1, находим его операнд, в данном случае это будет выражение (3+((+2)+2)), оно матчится в $2, заменяем всё выражение на (0 $1 $2). И тут, наверное, без рекурсии не обойтись.
Сам операнд унарного оператора нельзя просто заматчить регуляркой, так как неизвестно с какой глубиной скобочек он будет.
В общем, если я и смогу реализовать такой ужасный способ, то понятен он, наверное, будет только мне.

>Твой лексер не поточный.


Не нагуглил, что это. Как он бинарный от унарного минуса отличает, если двигается только по лексеме за раз? Чувствую, что нужно просто полностью ознакомится с содержанием ссылок, которыми ты со мной поделился.
Насчёт генераторов, то для PHP я нашёл только сомнительные проекты с устаревшим кодом лет на 5-10 и без документации.

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


То есть, чтобы была возможность сделать $fraction1->add($fraction2)?
У меня сейчас и так куча операторов/операций, да и класс SimpleFraction немаленький. Распределяя ответственности, исходил из того, что оператор оперирует операндами, используя операцию.

> Вот я попробовал вычислить выражения:


> ')))' : https://ideone.com/283Htn


> '- (- 1)' : https://ideone.com/gkdxNi


> '1 2 3': https://ideone.com/Yedp3k - должна быть ошибка


Там заглушка с неменяющимся true стояла. На основе выражений выше попробовал сформулировать требования к валидному инфиксному выражению:
- Все скобочки должны быть закрыты: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L29
- Чисел должно быть >= 1: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L44
- Количество бинарных операторов должно быть на один меньше, чем количество чисел: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L54
- унарный оператор должен быть предварён знаком (, или быть в начале строки: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L59
- Должны использоваться только операторы +-*/()#$, числа вида \d+(\.d+)? : https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L13

Ещё я сделал try/catch на уровне вычисления RPN, это позволяет в случае возникновения исключения просто переходить к вычислению следующего инфиксного выражения (чтобы не создавать на каждое выброшенное исключения отдельную ссылку на ideone).

>> https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/ShuntingYard.php#L14


> Тут трудно понять логику, нужны комментарии.


Так и не понял, где там комментарии помогут, код старался сделать максимально похожим на псевдокод здесь: https://en.wikipedia.org/wiki/Shunting-yard_algorithm#The_algorithm_in_detail
За исключением того, что проверки скобочек вынесены в лексер.

Ещё я несколько дней пытался отлепить знак дроби от числителя и знаменателя, чтобы передавать знак дроби через конструктор, а в числителе и знаменателе держать только абсолютные значения. Даже подумал, что операцию смены знака можно лаконично сделать с помощью оператора XOR вот так: public function changeSign() { $this->sign ^= true; }
Не это потребовало огромных правок в методах классов Addition, Power и прочих, так как определять знак результата операции теперь предстояло мне, а не PHP, поэтому я отбросил эту идею.

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


Лексер возвращает массив вида ['2', '+', '3'], токенайзер - [object SimpleFraction, object Addition, object SimpleFraction]. Удобно для тестов, потом солью в один класс Parser.

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


Regex-движок звучит пугающе. Я в любом случае хотел за SICP когда-нибудь сесть, там, вроде бы, как раз интерпретатор Lisp'а по ходу дела пишется. Но максимум, на что я расчитывал - прорешать хотя бы треть задачек оттуда, так как она (опять же, по слухам) перенасыщена задачами. Посмотрю, если SICP зайдёт, то возьмусь за что-нибудь из предложенного тобой.
Времени достаточно, меня ещё 2 года будет универ содержать, выходить на работу нет необходимости.

Пойду изучать AST/Recursive descent и пробовать применять его на калькуляторе.
31 Кб, 834x391
76 Кб, 429x189
#721 #791074
>>785646
https://ideone.com/1sNagN
https://github.com/applejacky/arithmetic_expression_calculator

>Что будет если возвести (9/1) в (1/2) ? Возведение в 1/2 это квадратный корень то есть получается ответ 3


Я гуглил, но не нашёл функции для нахождения корня n-ной степени. Везде советуют использовать pow(основание_степени, 1/показатель_степени). Проблема в том, что возводить в дробную степень может только функция pow, bcpow и gmp_pow не могут: https://ideone.com/miPWb3
Всякие матановые способы нахождения корня n-ной степени я не осилю. Пример с 9^1/2 теперь работает, но пришлось использовать pow.

Вообще с числами с произвольной точностью появились проблемы, которые просто ставят меня в тупик.
К примеру, я хочу посчитать сумму '0.111111111111111111112' и '0.22222222222222222222'. Сама функция bcadd считает её нормально, но в калькуляторе мне нужно каждое из этих чисел перевести в простые дроби, так как все операции у нас проходят над простыми дробями. Для этого нужно найти НОК. То есть для первой дроби мне нужно умножать 111111111111111111112 на 1000000000000000000000. Даже ideone не выдержал, выплюнув Time limit exceeded (пик 1), при том, что сложные расчёты на нём происходят в несколько десятков раз быстрее, чем на моём ноуте. Нижний Success относится к ситуации, когда я пытался найти НОК для 2 и 100..(много нулей), сама функция нахождения НОК работает правильно: https://ideone.com/TmuS8l

>Ты парсишь выражение в RPN но не удобнее ли сразу строить дерево AST ?


Было проще почитать статью про алгоритм сортировочной станции на вики и облечь псевдокод в код, чем читать талмуд вроде: https://www.engr.mun.ca/~theo/Misc/exp_parsing.htm
Теперь я понимаю, что нужно было сразу браться за AST с грамматиками, причины описаны ниже. Однако всё же хотелось бы сделать задачу 2-я способами. Но и браться за один способ, не доделав другой, не хочется.

>И кстати ты учел что результат может получиться в виде 1.2e-20?


Изменил трюки с explode('.', $foo) на трюки с bcdiv и floatval, теперь экспонента появляться не должна: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/SimpleFraction.php#L59

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


Попробовал ещё использовать вместо регулярок функцию sscanf здесь: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/SimpleFraction.php#L21
Но эта функция основана на доступных типах данных, поэтому не годится для чисел с произвольным количеством цифр (пик 2).

>В лексере проблема - это интерпретация знаков "минус". -1 - это "минус один" или операция "отрицание" примененная к числу один?


Да, я погуглил насчёт унарных операторов в RPN и понял, что эта нотация не умеет отличать унарный плюс/минус от бинарного: http://wcipeg.com/wiki/Shunting_yard_algorithm#Unary_operators
Там советуют использовать отдельные знаки для унарных + и -, например # и $, для этого нужно модифицировать алгоритм распределяющей шляп сортировочной станции. Так пока что и сделал.
Ещё я вижу очень запутанный способ решения без необходимости вводить новые знаки - на этапе парсинга инфиксного выражения заменять конструкции вида -3 на (0-3), сделав минус/плюс только бинарными. Но что делать с выражением вида -(3+((+2)+2))?
Находим унарный оператор (на основе соседних символов), в данном случае это будет минус, он матчится в $1, находим его операнд, в данном случае это будет выражение (3+((+2)+2)), оно матчится в $2, заменяем всё выражение на (0 $1 $2). И тут, наверное, без рекурсии не обойтись.
Сам операнд унарного оператора нельзя просто заматчить регуляркой, так как неизвестно с какой глубиной скобочек он будет.
В общем, если я и смогу реализовать такой ужасный способ, то понятен он, наверное, будет только мне.

>Твой лексер не поточный.


Не нагуглил, что это. Как он бинарный от унарного минуса отличает, если двигается только по лексеме за раз? Чувствую, что нужно просто полностью ознакомится с содержанием ссылок, которыми ты со мной поделился.
Насчёт генераторов, то для PHP я нашёл только сомнительные проекты с устаревшим кодом лет на 5-10 и без документации.

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


То есть, чтобы была возможность сделать $fraction1->add($fraction2)?
У меня сейчас и так куча операторов/операций, да и класс SimpleFraction немаленький. Распределяя ответственности, исходил из того, что оператор оперирует операндами, используя операцию.

> Вот я попробовал вычислить выражения:


> ')))' : https://ideone.com/283Htn


> '- (- 1)' : https://ideone.com/gkdxNi


> '1 2 3': https://ideone.com/Yedp3k - должна быть ошибка


Там заглушка с неменяющимся true стояла. На основе выражений выше попробовал сформулировать требования к валидному инфиксному выражению:
- Все скобочки должны быть закрыты: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L29
- Чисел должно быть >= 1: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L44
- Количество бинарных операторов должно быть на один меньше, чем количество чисел: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L54
- унарный оператор должен быть предварён знаком (, или быть в начале строки: https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L59
- Должны использоваться только операторы +-*/()#$, числа вида \d+(\.d+)? : https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/InfixParsing/Lexer.php#L13

Ещё я сделал try/catch на уровне вычисления RPN, это позволяет в случае возникновения исключения просто переходить к вычислению следующего инфиксного выражения (чтобы не создавать на каждое выброшенное исключения отдельную ссылку на ideone).

>> https://github.com/applejacky/arithmetic_expression_calculator/blob/master/Classes/ShuntingYard.php#L14


> Тут трудно понять логику, нужны комментарии.


Так и не понял, где там комментарии помогут, код старался сделать максимально похожим на псевдокод здесь: https://en.wikipedia.org/wiki/Shunting-yard_algorithm#The_algorithm_in_detail
За исключением того, что проверки скобочек вынесены в лексер.

Ещё я несколько дней пытался отлепить знак дроби от числителя и знаменателя, чтобы передавать знак дроби через конструктор, а в числителе и знаменателе держать только абсолютные значения. Даже подумал, что операцию смены знака можно лаконично сделать с помощью оператора XOR вот так: public function changeSign() { $this->sign ^= true; }
Не это потребовало огромных правок в методах классов Addition, Power и прочих, так как определять знак результата операции теперь предстояло мне, а не PHP, поэтому я отбросил эту идею.

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


Лексер возвращает массив вида ['2', '+', '3'], токенайзер - [object SimpleFraction, object Addition, object SimpleFraction]. Удобно для тестов, потом солью в один класс Parser.

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


Regex-движок звучит пугающе. Я в любом случае хотел за SICP когда-нибудь сесть, там, вроде бы, как раз интерпретатор Lisp'а по ходу дела пишется. Но максимум, на что я расчитывал - прорешать хотя бы треть задачек оттуда, так как она (опять же, по слухам) перенасыщена задачами. Посмотрю, если SICP зайдёт, то возьмусь за что-нибудь из предложенного тобой.
Времени достаточно, меня ещё 2 года будет универ содержать, выходить на работу нет необходимости.

Пойду изучать AST/Recursive descent и пробовать применять его на калькуляторе.
>>792428>>792629
#722 #791267
Доделал Кошек-мышек, добавил собак. Можно переходить к студентам?

https://ideone.com/R5AoPX // Кошки-мышки
>>792620>>797241
35 Кб, 1366x687
#723 #791536
Пиздец. У меня github поломался. Самое странное, что приложения тоже не открываются. Как это вообще может быть связано?

Куки, кеш чистил. Что еще сделать можно не знаю
#724 #791581
>>791536

ОП, я готов: https://github.com/TheSidSpears/Students/

На <br> не обращай внимания - когда дойдет до css, тогда формы буду
делать по уму.

Открываю теперь под проксей, а приложение перекачал.
>>791808>>792619
#725 #791642
>>791536
Не ты один такой, ждем.
#726 #791693
Ребят есть гайд по верстке мелких сайтов?. Типо сайтов визиток.
>>791867>>792619
#727 #791698
>>785382
http://stackoverflow.com/questions/6395737/how-do-i-make-my-php-ide-understand-dependency-injection-containers

Нашел для себя вот это решение. Анончики, а вы тоже в своих IDE пишите для контейнеров
/ @var YourClassType $mailer */
$mailer = $container['mailer'];
каждый раз? Может есть еще альтернативы кроме банального отключения этой валидации в ide?
>>792619
#728 #791714
>>791536
Ставропольский районный суд заблокировал часть их ип
>>791801
55 Кб, 537x549
#729 #791801
>>791714
Проорал в голос...
Закомиттил, запушил - в тюрьму!
Романтика!
#730 #791808
>>791581
Так же разобрался с PSR-4, но чё-то не вижу смысла в таком маленьком проекте его использовать
Только что усложнять лапшой
return new Router(); --> return new Project\Classes\Router();

Я так понимаю, если я через композер подключаю сторонние библиотеки и там встретится Router, то он не будет конфликтовать с моим Router, который объявлен без всяких PSR-4. Мне главное самому внутри проекта не плодить одинаково названных классов
>>792619
#731 #791867
>>791693
да мне тож надо
>>792619
#732 #792428
Здесь >>791074 устаревшая ссылка на ideone, я там с try/catch налажал. Почему-то пропала опция edit для своего же файла, поэтому создал новый: https://ideone.com/cBTzfZ

>>790577
Для задач подобного рода, как правило, достаточно отследить зависимость между счётчиками циклов и требуемым выводом. Можно на листочке просто расписывать каждую итерацию в стиле "что нужно" => "что имеем". Конкретно в той задаче на каждой итерации вложенного цикла нужно вывести либо звёздочку, либо пробел, а имеем значения 2-х счётчиков и input, определяющий сколько отрабатывать циклам.
Можешь потренироваться на более простых задачах:
1. На ввод подаётся число, к примеру 4, на вывод - рамка квадрата со стороной 4 символа в псевдографике: http://pastebin.com/raw/aaTEgvgU
2. То же самое, только на ввод подаётся нечётное число, на вывод - треугольник.
После этого задача на вывод креста никаких проблем не вызовет.

Алсо, вспомнил о рубисте с большим опытом коммерческой разработки, который месяца 3 назад создавал в /pr тред, где, как и ОП, помогал новичкам вкатиться и делал код-ревью. Предложил пару интересных задачек, которые мы можем и на PHP без проблем делать. Кому интересно: https://gist.github.com/djinn2chhk/d4889f9fbc0ecf1ec7ba
#733 #792619
>>791693
>>791867

Есть сборник задач по HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md

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

>>791808

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

> Я так понимаю, если я через композер подключаю сторонние библиотеки и там встретится Router, то он не будет конфликтовать с моим Router, который объявлен без всяких PSR-4.


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

>>791698

Проще перенастроить проверяльщик кода. Я не знаком настолько хорошо с пхпсторм, но уверен что там все настраивается.

Идея с @var мне не нравится так как если ты 4 раза получаешь какой-то сервис то 4 раза должен писать @var. Выгоднее бы на самом контейнере 1 раз пометить что это контейнер и он содердит такие-то сервисы.

Тут (по твоей же ссылке) есть такой совет: http://stackoverflow.com/questions/6395737/how-do-i-make-my-php-ide-understand-dependency-injection-containers/6418373#6418373

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

>>791581

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

>>791536

Роскомнадзор буянит.
#733 #792619
>>791693
>>791867

Есть сборник задач по HTML/CSS: https://github.com/codedokode/pasta/blob/master/html/html.md

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

>>791808

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

> Я так понимаю, если я через композер подключаю сторонние библиотеки и там встретится Router, то он не будет конфликтовать с моим Router, который объявлен без всяких PSR-4.


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

>>791698

Проще перенастроить проверяльщик кода. Я не знаком настолько хорошо с пхпсторм, но уверен что там все настраивается.

Идея с @var мне не нравится так как если ты 4 раза получаешь какой-то сервис то 4 раза должен писать @var. Выгоднее бы на самом контейнере 1 раз пометить что это контейнер и он содердит такие-то сервисы.

Тут (по твоей же ссылке) есть такой совет: http://stackoverflow.com/questions/6395737/how-do-i-make-my-php-ide-understand-dependency-injection-containers/6418373#6418373

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

>>791581

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

>>791536

Роскомнадзор буянит.
>>792624
Кошки-мышки | https://ideone.com/R5AoPX #734 #792620
>>791267

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

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

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

Мануал: http://php.net/manual/ru/language.oop5.typehinting.php

Обрати внимание, что php7 усовершенствовал систему тайп-хинтов - теперь можно в их качестве указывать примитивные типы вроде int/string, а в php7.1 стало можно указывать тайп-хинт для возвращаемого функцией значения: https://habrahabr.ru/post/267799/ (увы, возможность вернуть null пока не реализовали, так что ждем)

---------

> // Константы


> const cat = 'Cat';


Имена констант пишутся большими буквами. Более того, в твоем случае они не нужны так как имя класса само по себе константа и можно писать Cat::CLASS (это вернет строку 'Cat').

Также, проверить что объект относится к классу X или его наследнику можно через if ($x instanceof X).

> // Счетчик экземпляров класса


> protected static $counter = 1;


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

> // Кол-во пропускаемых ходов


> protected $restingTime = 0;


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

> // Координаты ХY


> protected $xy = array();


А почему массив? Почему не 2 поля, x и y? Так и писать будет короче, и логичне по моему.

> if ($weightA==$weightB) return 0;


PSR требует всегда ставить фигурные скобки и писать в 3 строки, привыкай сразу.

> $bestMoveVariantWeight


> $bestMoveVariants


Можно просто $bestVariants и $bestWeight

> // Находим животных в зоне видимости


> protected function getScope($animals)


> protected function getAnimal($animals, $animalType)


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

> protected function getDistance($target)


> {


> $target = $target;


Очень полезная команда.

> protected function getWeightsByDirections


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

> protected function removeMoveByAnimals($animals, $moveVariants)


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

> protected function getCorners ()


> // Определяем координаты углов


> $fieldSizeX = fieldSize;


Тут ошибка

> public function toDie()


> $this->hp = 0;


> return true;


Стоит добавить комментарий в каких случаях и что вернет функция, что значит false.

> // Игровой ход


> abstract function move($animals, $moveVariants, $corners);


По моему этот метод должен выглядеть так: move(). Найти других животных или углы можно с помощью Карты. Ты не сделал класс Карта, и потому теперь вынужден информацию о животных передавать с помощью кучи массивов в каждую функцию.

> // Оценка ходов


> abstract protected function setRating($animals, $moveVariants, $corners);


Вот мне кажется что из 2 абстрактных методов - setRating и move - один лишний. Я имею в виду, если все животные пользуются алгоритмом оценки хода, то должно быть достаточно функции выбора всех допустимых ходов + setRaing, верно? Для move тогда можно было бы предоставить реализацию по умолчанию в классе Animal. С другой стороны, если мы не хотим заставлять всех пользоваться алгоритмом оценки, достаточно сделать абстрактной только move.

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

> // Исключение занятых ходов


> abstract protected function removeOccupiedMove($animals, $moveVariants)


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

> $this->getWeightsByDirections


Тут не get, а set, get-функции обычно ничего не меняют.

> // Трансформирует 3х мышей в мегамышь неуязвимую для кошек


> private function transformMegaMouse ($animals)


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

Для определения расстояния между животными можно было бы сделать статический метод, например Animal::getDistance($a, $b) или Field::getDistance(). Если мы меряем в ходах и расстояние разное для разных видов животных то $a->getDistainceTo($b);

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


> public function getMoveAbility()


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

> // Если в соседней клетке есть мышь, рейтинг = INF


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

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

> $moveVariants = array_map(function ($moveVariant) {


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

В классе Animals нет проверки на генерацию не повторяющихся координат. Название класса плохое.

> // Фабрика ВариантовXода


> static public function createMoveVariants ($animal)


Мне кажется это лучше поместить в Animal. Почему? Потому что в этом случае зависимость будет однонаправленная: классу Animal нужен класс MoveVariant, а MV ничего не знает об A. Как-то более аккуратно получается.

> do {


> $start['y'] = $animalXY['y']-$animalSpeed;


> $animalSpeed--;


Не лучше ли использовать for ($i от 1 до animalSpeed) ?

> // Класс Вектор


> class Vector


Вот это вот самый нелогичный класс тут. Как представить вектор? Классический способ - это 2 числа, x и y. Зачем тут свойство $zero котороу избыточно (без него легко обойтись)?

Логично ждать и конструктор, принимающий 2 координаты. А конструктор, считающий вектор между 2 точками, сделать статическим методом.

> if ((is_int($startXY) && is_int($endXY)) |


> } else if (is_array($startXY) && is_array($endXY)) {


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

В твоем случае надо сделать несколько статических конструткоров.

> public function getAngle($vector1, $vector2)


Это судя по всему статическая функция, так как она не испоьзует поля текущего объекта.

> class Corner


Название плохое, можно подумать что это объект представляющий один угол.
Кошки-мышки | https://ideone.com/R5AoPX #734 #792620
>>791267

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

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

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

Мануал: http://php.net/manual/ru/language.oop5.typehinting.php

Обрати внимание, что php7 усовершенствовал систему тайп-хинтов - теперь можно в их качестве указывать примитивные типы вроде int/string, а в php7.1 стало можно указывать тайп-хинт для возвращаемого функцией значения: https://habrahabr.ru/post/267799/ (увы, возможность вернуть null пока не реализовали, так что ждем)

---------

> // Константы


> const cat = 'Cat';


Имена констант пишутся большими буквами. Более того, в твоем случае они не нужны так как имя класса само по себе константа и можно писать Cat::CLASS (это вернет строку 'Cat').

Также, проверить что объект относится к классу X или его наследнику можно через if ($x instanceof X).

> // Счетчик экземпляров класса


> protected static $counter = 1;


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

> // Кол-во пропускаемых ходов


> protected $restingTime = 0;


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

> // Координаты ХY


> protected $xy = array();


А почему массив? Почему не 2 поля, x и y? Так и писать будет короче, и логичне по моему.

> if ($weightA==$weightB) return 0;


PSR требует всегда ставить фигурные скобки и писать в 3 строки, привыкай сразу.

> $bestMoveVariantWeight


> $bestMoveVariants


Можно просто $bestVariants и $bestWeight

> // Находим животных в зоне видимости


> protected function getScope($animals)


> protected function getAnimal($animals, $animalType)


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

> protected function getDistance($target)


> {


> $target = $target;


Очень полезная команда.

> protected function getWeightsByDirections


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

> protected function removeMoveByAnimals($animals, $moveVariants)


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

> protected function getCorners ()


> // Определяем координаты углов


> $fieldSizeX = fieldSize;


Тут ошибка

> public function toDie()


> $this->hp = 0;


> return true;


Стоит добавить комментарий в каких случаях и что вернет функция, что значит false.

> // Игровой ход


> abstract function move($animals, $moveVariants, $corners);


По моему этот метод должен выглядеть так: move(). Найти других животных или углы можно с помощью Карты. Ты не сделал класс Карта, и потому теперь вынужден информацию о животных передавать с помощью кучи массивов в каждую функцию.

> // Оценка ходов


> abstract protected function setRating($animals, $moveVariants, $corners);


Вот мне кажется что из 2 абстрактных методов - setRating и move - один лишний. Я имею в виду, если все животные пользуются алгоритмом оценки хода, то должно быть достаточно функции выбора всех допустимых ходов + setRaing, верно? Для move тогда можно было бы предоставить реализацию по умолчанию в классе Animal. С другой стороны, если мы не хотим заставлять всех пользоваться алгоритмом оценки, достаточно сделать абстрактной только move.

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

> // Исключение занятых ходов


> abstract protected function removeOccupiedMove($animals, $moveVariants)


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

> $this->getWeightsByDirections


Тут не get, а set, get-функции обычно ничего не меняют.

> // Трансформирует 3х мышей в мегамышь неуязвимую для кошек


> private function transformMegaMouse ($animals)


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

Для определения расстояния между животными можно было бы сделать статический метод, например Animal::getDistance($a, $b) или Field::getDistance(). Если мы меряем в ходах и расстояние разное для разных видов животных то $a->getDistainceTo($b);

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


> public function getMoveAbility()


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

> // Если в соседней клетке есть мышь, рейтинг = INF


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

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

> $moveVariants = array_map(function ($moveVariant) {


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

В классе Animals нет проверки на генерацию не повторяющихся координат. Название класса плохое.

> // Фабрика ВариантовXода


> static public function createMoveVariants ($animal)


Мне кажется это лучше поместить в Animal. Почему? Потому что в этом случае зависимость будет однонаправленная: классу Animal нужен класс MoveVariant, а MV ничего не знает об A. Как-то более аккуратно получается.

> do {


> $start['y'] = $animalXY['y']-$animalSpeed;


> $animalSpeed--;


Не лучше ли использовать for ($i от 1 до animalSpeed) ?

> // Класс Вектор


> class Vector


Вот это вот самый нелогичный класс тут. Как представить вектор? Классический способ - это 2 числа, x и y. Зачем тут свойство $zero котороу избыточно (без него легко обойтись)?

Логично ждать и конструктор, принимающий 2 координаты. А конструктор, считающий вектор между 2 точками, сделать статическим методом.

> if ((is_int($startXY) && is_int($endXY)) |


> } else if (is_array($startXY) && is_array($endXY)) {


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

В твоем случае надо сделать несколько статических конструткоров.

> public function getAngle($vector1, $vector2)


Это судя по всему статическая функция, так как она не испоьзует поля текущего объекта.

> class Corner


Название плохое, можно подумать что это объект представляющий один угол.
>>797241
#735 #792624
>>792619
а что-то более сложное?
>>792627
#736 #792627
>>792624

Нету
https://github.com/applejacky/arithmeticexpressioncalculator #737 #792629
>>791074

> Я гуглил, но не нашёл функции для нахождения корня n-ной степени. Везде советуют использовать pow(основание_степени, 1/показатель_степени).


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

Получается, надо либо запретить возводить в дробные степени, либо запретить возводить в степени, которые дают иррациональное число (метод Роскомнадзора), либо придумать метод выразить результат приближенно (увы, теряя точность). То есть сделать pow(), и превратить float в SimpleFraction. Либо сделать новый тип чисел (иррациональные) и получать результаты вроде "корень из 2 делить на корень из трех" (пытаясь написать алгоритм их сложения, мы дойдем до поддержки произвольных выражений и напишем полноценную математическую систему).

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

> Для этого нужно найти НОК. То есть для первой дроби мне нужно умножать 111111111111111111112 на 1000000000000000000000. Даже ideone не выдержал, выплюнув Time limit exceeded


У тебя ужасный с точки зрения производительности алгоритм. Сложность древнегреческого алгоритма НОД небольшая так как остаток от деления всегда меньше делителя (подробнее: http://codeforces.com/blog/entry/9426?locale=ru и http://e-maxx.ru/algo/euclid_algorithm - пишут что сложность меньше логарифмеческой. Для твоих чисел это дает около 100 шагов) (кстати вперые узнал о теореме Ламе, век гугли - век учись).

Ну а НОК легко считается через НОД. Реализуй алгоритм Евклида, а то у тебя сделан брутфорс полным перебором всех значений от 1 до N - тут время работы может легко превысить время существования Вселенной. Не забывай что скорость работы компьютера ограничена и начиная с миллионов операций становится заметна глазу.

>>Ты парсишь выражение в RPN но не удобнее ли сразу строить дерево AST ?


> Было проще почитать статью про алгоритм сортировочной станции на вики и облечь псевдокод в код, чем читать талмуд вроде:


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

> Изменил трюки с explode('.', $foo) на трюки с bcdiv и floatval,


https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/SimpleFraction.php#L52
Вот такой код однозначно не будет работать как задумано. Когда ты видишь floatval, ты должен понимать что это преобразование с потерями (вроде сжатия картинки в jpeg - результат всегда будет хуже оригинала):

> return (string) floatval(bcdiv(...))


floatval делает преобразование в float. float даже в 64-битном пхп сохраняет не более 14 значащих цифр ( http://php.net/manual/ru/language.types.float.php ). float это приближенный, неточный формат с потерями.

Прочитай-ка на досуге: https://habrahabr.ru/post/112953/

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

123456789123456789123456789/100 -> 1234567891234567891234567.89
1/1000 -> 0.001
100/1 -> 100
1230/100 -> 12.3

Десятичная дробь это не только когда знаменатель равен 10, но и 1, 100, 1000 и тд. Проверить это можно посимвольным анализом строки с знаменателем, что он состоит из единицы и нулей (регулярка?).

Аналогичные потери из-за конвертации во флоат будут тут: $valueAsString = (string) ($this->numerator * $this->denominator);

> Но эта функция основана на доступных типах данных,


да, она хранит результат как флоат

> Да, я погуглил насчёт унарных операторов в RPN и понял, что эта нотация не умеет отличать унарный плюс/минус от бинарного:


> Там советуют использовать отдельные знаки для унарных + и -,


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

1-1
-1
---1
-(1+1)--1
-(-1)

> Ещё я вижу очень запутанный способ решения без необходимости вводить новые знаки - на этапе парсинга инфиксного выражения заменять конструкции вида -3 на (0-3),


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

>>Твой лексер не поточный.


> Не нагуглил, что это.


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

> То есть, чтобы была возможность сделать $fraction1->add($fraction2)?


> У меня сейчас и так куча операторов/операций, да и класс SimpleFraction немаленький.


Ну теоретически можно сделать класс с методами Math::add($a, $b), но по моему можно и в сам класс дробей засунуть. Объект это ведь данные + методы для работы с ними. Логично что дробь умеет сама себя складывать.

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


Здесь есть проблемка. Твои Addition это классы, относящиеся к парсингу выражений ведь. Потому что в математике нет операции "левая скобка". И получается, чтобы посчитать выражение с дробями, нам приходится подключать классы от парсера. Ну и синтаксис громоздкий получается, попробуй сам написать код сложения/умножения нескольких дробей. Ну можно и так оставить, я в общем не против особо.

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


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

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

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

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

> str_pad("Выражение в инфиксной нотации", 61)


Она не умеет считать русские буквы, имей в виду.

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


Это проще делать наверно в рамках упрощения дроби. Также можно сделать метод getSign(). Не думаю что есть смысл заводить поле так как потом надо будет всюду этот знак домножать и убирать обратно.

> $this->sign ^= true;


^ это не булев, а целочисленный (побитовый) оператор. Он работает с числами а не true/false.

> Regex-движок звучит пугающе. Я в любом случае хотел за SICP когда-нибудь сесть, там, вроде бы, как раз интерпретатор Lisp'а по ходу дела пишется. Но максимум, на что я расчитывал - прорешать хотя бы треть задачек оттуда,


Да, SICP неплохая идея, только учти что это очень теоретическая штука и стоит параллельно что-то практическое делать. Там надо решать задачи на языке Scheme, он простой, можно скачать интерпретатор или тупо писать код на repl.it если лень ставить.

> Regex-движок звучит пугающе.


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

- https://swtch.com/~rsc/regexp/
- https://swtch.com/~rsc/regexp/regexp1.html
- https://swtch.com/~rsc/regexp/regexp2.html
https://github.com/applejacky/arithmeticexpressioncalculator #737 #792629
>>791074

> Я гуглил, но не нашёл функции для нахождения корня n-ной степени. Везде советуют использовать pow(основание_степени, 1/показатель_степени).


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

Получается, надо либо запретить возводить в дробные степени, либо запретить возводить в степени, которые дают иррациональное число (метод Роскомнадзора), либо придумать метод выразить результат приближенно (увы, теряя точность). То есть сделать pow(), и превратить float в SimpleFraction. Либо сделать новый тип чисел (иррациональные) и получать результаты вроде "корень из 2 делить на корень из трех" (пытаясь написать алгоритм их сложения, мы дойдем до поддержки произвольных выражений и напишем полноценную математическую систему).

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

> Для этого нужно найти НОК. То есть для первой дроби мне нужно умножать 111111111111111111112 на 1000000000000000000000. Даже ideone не выдержал, выплюнув Time limit exceeded


У тебя ужасный с точки зрения производительности алгоритм. Сложность древнегреческого алгоритма НОД небольшая так как остаток от деления всегда меньше делителя (подробнее: http://codeforces.com/blog/entry/9426?locale=ru и http://e-maxx.ru/algo/euclid_algorithm - пишут что сложность меньше логарифмеческой. Для твоих чисел это дает около 100 шагов) (кстати вперые узнал о теореме Ламе, век гугли - век учись).

Ну а НОК легко считается через НОД. Реализуй алгоритм Евклида, а то у тебя сделан брутфорс полным перебором всех значений от 1 до N - тут время работы может легко превысить время существования Вселенной. Не забывай что скорость работы компьютера ограничена и начиная с миллионов операций становится заметна глазу.

>>Ты парсишь выражение в RPN но не удобнее ли сразу строить дерево AST ?


> Было проще почитать статью про алгоритм сортировочной станции на вики и облечь псевдокод в код, чем читать талмуд вроде:


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

> Изменил трюки с explode('.', $foo) на трюки с bcdiv и floatval,


https://github.com/applejacky/arithmetic_expression_calculator/blob/master/src/SimpleFraction.php#L52
Вот такой код однозначно не будет работать как задумано. Когда ты видишь floatval, ты должен понимать что это преобразование с потерями (вроде сжатия картинки в jpeg - результат всегда будет хуже оригинала):

> return (string) floatval(bcdiv(...))


floatval делает преобразование в float. float даже в 64-битном пхп сохраняет не более 14 значащих цифр ( http://php.net/manual/ru/language.types.float.php ). float это приближенный, неточный формат с потерями.

Прочитай-ка на досуге: https://habrahabr.ru/post/112953/

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

123456789123456789123456789/100 -> 1234567891234567891234567.89
1/1000 -> 0.001
100/1 -> 100
1230/100 -> 12.3

Десятичная дробь это не только когда знаменатель равен 10, но и 1, 100, 1000 и тд. Проверить это можно посимвольным анализом строки с знаменателем, что он состоит из единицы и нулей (регулярка?).

Аналогичные потери из-за конвертации во флоат будут тут: $valueAsString = (string) ($this->numerator * $this->denominator);

> Но эта функция основана на доступных типах данных,


да, она хранит результат как флоат

> Да, я погуглил насчёт унарных операторов в RPN и понял, что эта нотация не умеет отличать унарный плюс/минус от бинарного:


> Там советуют использовать отдельные знаки для унарных + и -,


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

1-1
-1
---1
-(1+1)--1
-(-1)

> Ещё я вижу очень запутанный способ решения без необходимости вводить новые знаки - на этапе парсинга инфиксного выражения заменять конструкции вида -3 на (0-3),


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

>>Твой лексер не поточный.


> Не нагуглил, что это.


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

> То есть, чтобы была возможность сделать $fraction1->add($fraction2)?


> У меня сейчас и так куча операторов/операций, да и класс SimpleFraction немаленький.


Ну теоретически можно сделать класс с методами Math::add($a, $b), но по моему можно и в сам класс дробей засунуть. Объект это ведь данные + методы для работы с ними. Логично что дробь умеет сама себя складывать.

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


Здесь есть проблемка. Твои Addition это классы, относящиеся к парсингу выражений ведь. Потому что в математике нет операции "левая скобка". И получается, чтобы посчитать выражение с дробями, нам приходится подключать классы от парсера. Ну и синтаксис громоздкий получается, попробуй сам написать код сложения/умножения нескольких дробей. Ну можно и так оставить, я в общем не против особо.

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


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

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

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

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

> str_pad("Выражение в инфиксной нотации", 61)


Она не умеет считать русские буквы, имей в виду.

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


Это проще делать наверно в рамках упрощения дроби. Также можно сделать метод getSign(). Не думаю что есть смысл заводить поле так как потом надо будет всюду этот знак домножать и убирать обратно.

> $this->sign ^= true;


^ это не булев, а целочисленный (побитовый) оператор. Он работает с числами а не true/false.

> Regex-движок звучит пугающе. Я в любом случае хотел за SICP когда-нибудь сесть, там, вроде бы, как раз интерпретатор Lisp'а по ходу дела пишется. Но максимум, на что я расчитывал - прорешать хотя бы треть задачек оттуда,


Да, SICP неплохая идея, только учти что это очень теоретическая штука и стоит параллельно что-то практическое делать. Там надо решать задачи на языке Scheme, он простой, можно скачать интерпретатор или тупо писать код на repl.it если лень ставить.

> Regex-движок звучит пугающе.


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

- https://swtch.com/~rsc/regexp/
- https://swtch.com/~rsc/regexp/regexp1.html
- https://swtch.com/~rsc/regexp/regexp2.html
#738 #792636
>>790838

разве что register_shutdown_handler . В php7 несколько фатальных ошибок переделали на исключения.

>>790816

Коммить из командной строки

>>790793

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

> } while ($animal->placed == false);


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

>>790773

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

>>790722

Функцией определения MIME типа, можно из getId3 раз уж ты все равно ее используешь.

>>788640

Я не очень хорошо ориентируюсь в рынке труда. Попробуй погуглить тематические сайты, на тостере часто устраивают флуд по теме, если ты из Украины то dou, тут есть раздел перезвонивших итд. Были какие-то сомнительные исследования на Хабре.

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

Ты как-то смешал все в кучу, я плохо представляю зачем, знающего Симфони, отправлять на поддержку битрикса.
#738 #792636
>>790838

разве что register_shutdown_handler . В php7 несколько фатальных ошибок переделали на исключения.

>>790816

Коммить из командной строки

>>790793

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

> } while ($animal->placed == false);


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

>>790773

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

>>790722

Функцией определения MIME типа, можно из getId3 раз уж ты все равно ее используешь.

>>788640

Я не очень хорошо ориентируюсь в рынке труда. Попробуй погуглить тематические сайты, на тостере часто устраивают флуд по теме, если ты из Украины то dou, тут есть раздел перезвонивших итд. Были какие-то сомнительные исследования на Хабре.

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

Ты как-то смешал все в кучу, я плохо представляю зачем, знающего Симфони, отправлять на поддержку битрикса.
#739 #792637
>>790565

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

Single Table Inheritance (Наследование с единой таблицей)
Class Table Inheritance (Наследование с таблицами классов)
Concrete Table Inheritance (Наследование с таблицами конечных классов)

( http://design-pattern.ru/ )

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

>>790546

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

>>790528

> В контроллере "информация о файле" я перевожу данные в строку и отдаю переменной в шаблон. Но что делать в контроллере "n-ое число последних файлов"?


Это замусоривает контроллер. Проще в шаблоне написать

<?= html(ViewHelper::formatFileSize($file->size)) ?>

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


Проще просто передать один объект с файлом

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


Допускает, почему нет. Функции-помощники для представления данных в какой-то форме вполне допустимы.
#739 #792637
>>790565

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

Single Table Inheritance (Наследование с единой таблицей)
Class Table Inheritance (Наследование с таблицами классов)
Concrete Table Inheritance (Наследование с таблицами конечных классов)

( http://design-pattern.ru/ )

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

>>790546

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

>>790528

> В контроллере "информация о файле" я перевожу данные в строку и отдаю переменной в шаблон. Но что делать в контроллере "n-ое число последних файлов"?


Это замусоривает контроллер. Проще в шаблоне написать

<?= html(ViewHelper::formatFileSize($file->size)) ?>

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


Проще просто передать один объект с файлом

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


Допускает, почему нет. Функции-помощники для представления данных в какой-то форме вполне допустимы.
>>792802
#740 #792638
>>790042
>>790379

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

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

Алсо сразу советую работать по обычному офисному графику (типа с 11 до 18). Избегай мыслей вроде "сделаю перерыв, посплю, побездельничаю немного, вечером/в выходные доделаю" - в итоге ты будешь вообще по 12 часов в сутки работать. Старайся искать такую работу, где будет возмодность постоянно изучать что-то новое, а не ковыряться в залежах кода под битрикс. Старайся ничего не делать в выходные и ни под каким предлогом не соглашаться на овертаймы.

>>790355

> Если заключить инклуд в стороннюю функцию то в шаблоне становиться нельзя обращаться к переменным в контроллере (к таким как $token, $registerStudentForm).


Обычно в функцию передается массив переменных, а перед инклудом извлекается с помощью extract:

$this->render('template.phtml', ['a' => 1, 'b' => 2]);
#741 #792639
>>790317

У тебя плохо сделано что переменная $i меняется в нескольких местах и трудно понять как вообще работает внешний цикл for. Лучше заменить его на while, и сделать чтобы $i++ был только в одном месте.

>>790152

Есть версия что надо потратить 10 000 часов чтобы стать профессионалом в чем-то.

>>790158

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

>>790144

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

>>790110

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

>>789929

держать данные в 2 копиях - всегда плохая идея. Ведь тебе надо постоянно будет поддерживать их согласованность. Должен быть один "источник правды".

>>789926

чтобы например кошек цифрами обозначить
#741 #792639
>>790317

У тебя плохо сделано что переменная $i меняется в нескольких местах и трудно понять как вообще работает внешний цикл for. Лучше заменить его на while, и сделать чтобы $i++ был только в одном месте.

>>790152

Есть версия что надо потратить 10 000 часов чтобы стать профессионалом в чем-то.

>>790158

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

>>790144

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

>>790110

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

>>789929

держать данные в 2 копиях - всегда плохая идея. Ведь тебе надо постоянно будет поддерживать их согласованность. Должен быть один "источник правды".

>>789926

чтобы например кошек цифрами обозначить
#742 #792640
>>789918

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

Хранить надо не бесполезную иконку, а просто например список объектов-животных.

>>789465

Это https://symfony.com/doc/current/book/from_flat_php_to_symfony2.html (англ) хорошая статья. Всем изучающим MVC советую глянуть.

>>789451

> $text=preg_split("/".PHP_EOL."/um",$text);


Не стоит так писать так как PHP_EOL это символ(ы) которыми в данной ОС принято переводить строку. Но текст программы пишется в редакторе и где гарантия что у тебя там выбран тот же символ конца строки? Употребимых варианта всего 2:

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

Разбивая по \n и делая trim для удаления \r ты получишь код, работающий в любом режиме редактора.

Кстати в echo можно использовать тоже просто \n - оно работает везде, кроме Блокнота.

> for($j=0, $count=count($text);$j<$count;$j++){


> $count=count($text)


Экономия на спичках, на мой взгляд, тем более что тут лучше бы подошел foreach

В остальном, норм.

>>788653

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

>>788773

забыл обновить

>>788854

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

>>788626

Это наверно нужно для оптимизации, она может сортировать массивы перед сравнением.
#742 #792640
>>789918

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

Хранить надо не бесполезную иконку, а просто например список объектов-животных.

>>789465

Это https://symfony.com/doc/current/book/from_flat_php_to_symfony2.html (англ) хорошая статья. Всем изучающим MVC советую глянуть.

>>789451

> $text=preg_split("/".PHP_EOL."/um",$text);


Не стоит так писать так как PHP_EOL это символ(ы) которыми в данной ОС принято переводить строку. Но текст программы пишется в редакторе и где гарантия что у тебя там выбран тот же символ конца строки? Употребимых варианта всего 2:

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

Разбивая по \n и делая trim для удаления \r ты получишь код, работающий в любом режиме редактора.

Кстати в echo можно использовать тоже просто \n - оно работает везде, кроме Блокнота.

> for($j=0, $count=count($text);$j<$count;$j++){


> $count=count($text)


Экономия на спичках, на мой взгляд, тем более что тут лучше бы подошел foreach

В остальном, норм.

>>788653

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

>>788773

забыл обновить

>>788854

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

>>788626

Это наверно нужно для оптимизации, она может сортировать массивы перед сравнением.
#743 #792641
Ребят расскажите для чего вообще нужен PHP?Там один тип, спрашивал про сайты визитки как я понял ему ответил оп и сказал что для обычных визиток хватает HTML/CSS + Javascript, а что насчет более сложных сайтов? Хочу заняться полноценной версткой более менее нормальных сайтов, чтобы в дальнейшем зарабатывать копеечку на фрилансах. Спасибо.
>>792649
#744 #792649
>>792641

Для обычных визиток достаточно HTML + CMS на которую он натягивается (а вот она уже написана на php)
>>792657
#745 #792657
>>792649

>а что насчет более сложных сайтов?

>>792658
#746 #792658
>>792657

MVC фреймворки.
>>792659
#747 #792659
>>792658
Спасибо.
42 Кб, 674x297
#748 #792802
>>792637
Оп, вот так подойдет? Длину/ширину в json или отдельным атрибутом?
>>792815
#749 #792815
>>792802
А вообще мне же наверное придется как-то идентифицировать тип файла и сохранить это в дальнейшем, т.е. наверное http://design-pattern.ru/patterns/single-table-inheritance.html хорошо подойдет.
>>792817
#750 #792817
>>792815
Ах да, у меня же это свойство уже есть.
17 Кб, 676x892
#751 #792915
Анончики кто сталкивался с кракозябрами в getID3? Почему так? Результат получен функцией analyze, на объект getID3 я кодировку UTF-8 ставил.
>>792916
16 Кб, 566x903
#752 #792916
>>792915
Алсо они встречаются дальше в массиве, везде в data.
#753 #793274
Где можно найти красивые стили для проекта с парой таблиц? студенты, который А то бутстрап наверное жирно как-то будет. самому css-ом лень заниматься, не моё это
>>793580
#754 #793580
>>793274

>бутстрап


Вполне сгодится.

>>788640

>200+


>150+



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

Еще часто пишут на высоких уровнях не опыт в ЯЗЫКНЕЙМ, а опыт в вебе например, т.к. если ты 5лет хуярил на симфони еще с каким нибудь ангуларом, то перекат на техологию у тебя будет быстрый, как у ёжика соника.
ответы #755 #793703
>>773074

ОП тут

>>774246

Второй вариант плохой. Надо делать повторяющиеся через цикл, а не копипастить. Чтобы склеить строку из частей, есть 2 варианта:

- использовать оператор точка (склеивание строки)
- складывать части в массив, который в конце склеить через implode

>>774916

Вообще, токен будет быстрее устаревать. Лучше бы все таки куки.

>>775124

При просмотре страницы анализируется УРЛ, проверяется например по базе данных, и определяется, что надо вывести на этой странице.

>>775327

Не знаю

>>775382

Соединение нужно одно, использовать DI можно и нужно.

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


Если создавать в модели, это будет не DI.

В маленьком приложении можно создать все нужные объекты в скрипте boostrap. Или сделать простой DI container.

>>775478

Пока нет на это времени.

>>777546

> Надо вызвать из php js-скрипт, лежащий на локалке, передав в него данные для нескольких переменных.



Нужна node.js если я правильно тебя понял.

>>777637

погугли free web hosting например
ответы #755 #793703
>>773074

ОП тут

>>774246

Второй вариант плохой. Надо делать повторяющиеся через цикл, а не копипастить. Чтобы склеить строку из частей, есть 2 варианта:

- использовать оператор точка (склеивание строки)
- складывать части в массив, который в конце склеить через implode

>>774916

Вообще, токен будет быстрее устаревать. Лучше бы все таки куки.

>>775124

При просмотре страницы анализируется УРЛ, проверяется например по базе данных, и определяется, что надо вывести на этой странице.

>>775327

Не знаю

>>775382

Соединение нужно одно, использовать DI можно и нужно.

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


Если создавать в модели, это будет не DI.

В маленьком приложении можно создать все нужные объекты в скрипте boostrap. Или сделать простой DI container.

>>775478

Пока нет на это времени.

>>777546

> Надо вызвать из php js-скрипт, лежащий на локалке, передав в него данные для нескольких переменных.



Нужна node.js если я правильно тебя понял.

>>777637

погугли free web hosting например
Перекат #756 #793708
Аноны, переходите в новый тред >>793705 (OP)

Здесь писать ничего не нужно, здесь будут только ответы на вопросы, которые я ответить не успел.
Ответы | Сапер #757 #794739
>>777799
>>778083

> Возник вопрос: как открыть пустые клетки, как в виндовом Сапере?


При клике в клетку смотреть, если она пустая, то обойти все еще не открытые соседние клетки и открыть их. И так далее. Тут нужна рекурсивная функция.

По коду:

У тебя какой-то странный синтаксис объявления функций:

var x = function () {};

Зачем так писать если можно писать function x() {} ?

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

Функции названы неудачно: setHeight ничего не задает и потому должна называтья checkHeight. Более того, я не понимаю, зачем это было выносить в функцию, если эти ифы можно было и так написать внутри Field().

> var getY = function(cell) {


Тоже странная функция. Не проще у cell сделать свойства x/y?

> document.head.innerHTML =


Это в общем плохая идея так как она удаляет то, что было в head до этого. В твоем случае проще вписать стили вручную. Да и вообще, что CSS код делает в JS файле?

> var generateMines = function() {


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

> if (typeof(cells) !== "undefined"


зачем копировать этот код? Зачем тут typeof? Можно просто писать if (a === undefined), или, что еще лучше, использовать оператор in. Кто-то написал в интернете неправильный код, и теперь все его копируют. В твоем случае даже in не нужен, достаточно сравнить что i меньше высоты или ширины.

> var countMines = function(c) {


Эта функция ведь не должна считать мины на центральной клеточке, только на соседних?

> for (var k = 0; k < width; k++) {


> cells[k].setMinesAround(countMines(cells[k]));


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

> var click = function(){


> table.addEventListener("click", function(event){


Название функции не соответствует тому, что она делает.

> table.addEventListener("click", function(event){


> for (var i = 0; i < height; i++) {


....

> });


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

> if (cells[k].getTd() === event.target) {


У ячеек и строк в DOM есть атрибуты rowIndex/colIndex по моему, по ним можно определить координаты ячейки.

> this.openEmptyCells = function(c) {


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

> function Cell(tdom) {


> var minesAround = 0;


Незачем это хранить, это всегда можно посчитать.

> var isEmpty = false;


Это всегда можно вывести из числа мин рядом.

> td.innerHTML = mine.getView();


Непонятно зачем тут объект mine. зачем вообще нужен класс Mine?

> this.setOpenStyle = function() {


> td.style.background = "white";


Тут лучше добавлять CSS класс. зачем тащить CSS код в яваскрипт?

Я тебе советую, кроме исправления кода, почитать еще мой урок про MVC-версию сапера.
Ответы | Сапер #757 #794739
>>777799
>>778083

> Возник вопрос: как открыть пустые клетки, как в виндовом Сапере?


При клике в клетку смотреть, если она пустая, то обойти все еще не открытые соседние клетки и открыть их. И так далее. Тут нужна рекурсивная функция.

По коду:

У тебя какой-то странный синтаксис объявления функций:

var x = function () {};

Зачем так писать если можно писать function x() {} ?

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

Функции названы неудачно: setHeight ничего не задает и потому должна называтья checkHeight. Более того, я не понимаю, зачем это было выносить в функцию, если эти ифы можно было и так написать внутри Field().

> var getY = function(cell) {


Тоже странная функция. Не проще у cell сделать свойства x/y?

> document.head.innerHTML =


Это в общем плохая идея так как она удаляет то, что было в head до этого. В твоем случае проще вписать стили вручную. Да и вообще, что CSS код делает в JS файле?

> var generateMines = function() {


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

> if (typeof(cells) !== "undefined"


зачем копировать этот код? Зачем тут typeof? Можно просто писать if (a === undefined), или, что еще лучше, использовать оператор in. Кто-то написал в интернете неправильный код, и теперь все его копируют. В твоем случае даже in не нужен, достаточно сравнить что i меньше высоты или ширины.

> var countMines = function(c) {


Эта функция ведь не должна считать мины на центральной клеточке, только на соседних?

> for (var k = 0; k < width; k++) {


> cells[k].setMinesAround(countMines(cells[k]));


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

> var click = function(){


> table.addEventListener("click", function(event){


Название функции не соответствует тому, что она делает.

> table.addEventListener("click", function(event){


> for (var i = 0; i < height; i++) {


....

> });


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

> if (cells[k].getTd() === event.target) {


У ячеек и строк в DOM есть атрибуты rowIndex/colIndex по моему, по ним можно определить координаты ячейки.

> this.openEmptyCells = function(c) {


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

> function Cell(tdom) {


> var minesAround = 0;


Незачем это хранить, это всегда можно посчитать.

> var isEmpty = false;


Это всегда можно вывести из числа мин рядом.

> td.innerHTML = mine.getView();


Непонятно зачем тут объект mine. зачем вообще нужен класс Mine?

> this.setOpenStyle = function() {


> td.style.background = "white";


Тут лучше добавлять CSS класс. зачем тащить CSS код в яваскрипт?

Я тебе советую, кроме исправления кода, почитать еще мой урок про MVC-версию сапера.
Ответы | Вектор #758 #794740
>>778029

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

>>778205

> Потому что эти поля (ставку, кофе) нужно переопределять походу выполнения программы, при повышении ставки для аналитика. Можно сделать как ты советовал, сделать переопределяемые поля в классе Employee, по умолчанию брать из класса Profession, а при смене профессии сбрасывать. > Будет норм?


Как сейчас сделано, годится. То есть абстрактные методы в классе Profession.

> Тогда нужно где-то хранить объекты профессии, чтобы потом их передать в качестве аргументов. А про константы не понятно, их нужно будет создавать в начале программы, а где гарантия, что при создании новой профессии программист создаст новую константу? А если объявлять константу внутри класса профессии, то какой тогда в этом смысл, если можно использовать названия класса? Корректно ли использовать такую конструкцию в качестве аргумента $departament->findEmployees(get_class (new Analyst)); ?


Можно использовать имя класса. Для получения имени класса есть константа SomeClass::CLASS

>>В общем-то эта строка не нужна.


> Почему не нужна? Если $analysts не определен, то данная итерация прервется, и цикл перейдет к другому департаменту, и не будет выполнятся код следующий за этой строкой.


Потому что если эту строку убрать результат будет тот же.

> Почему это ошибка именно инкапсуляции, а не логики?


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

> Я переделал, теперь метод смены работника в департаменте, которому аргументом передают работника, который если есть в депе получает статус шефа. Но деп все также обращается к методу Employee->setСhief(0); Я исправил ошибку?


Да, это и требовалось, надо чтобы в департаменте был метод смены босса.

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

По коду:

> // Назначаем работника шефом


> $this->employees[$employeeKey]->setСhief(1);


Тут можно было писать $empolyee->setChief(1) так как это тот же объект.

> // Создание департамента


> public function createDepartament($name)


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

> $engineers = $departament->findEmployees(get_class (new Engineer));


Если константа Engineer::CLASS, хранящая имя класса

> // Берем первые 40% через array_slice


> $dismissingEngineers = floor(count($engineers) * 0.6);


> $engineers = array_slice($engineers, $dismissingEngineers);


ЧТо-то странно. Почему 0.6, а не 0.4? Почему ты берешь последние 40%, а не первые?

> // Если в Департаменте нет аналитиков, переходим к след. департаменту


> if (!isset($analysts[0])) continue;


!count(...) или просто !$analysts

> public function liftManager($company)


> sort($employees);


Это не будет работать или будет работать криво. Нужен usort, а sort годится только для сортировки строк.
Ответы | Вектор #758 #794740
>>778029

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

>>778205

> Потому что эти поля (ставку, кофе) нужно переопределять походу выполнения программы, при повышении ставки для аналитика. Можно сделать как ты советовал, сделать переопределяемые поля в классе Employee, по умолчанию брать из класса Profession, а при смене профессии сбрасывать. > Будет норм?


Как сейчас сделано, годится. То есть абстрактные методы в классе Profession.

> Тогда нужно где-то хранить объекты профессии, чтобы потом их передать в качестве аргументов. А про константы не понятно, их нужно будет создавать в начале программы, а где гарантия, что при создании новой профессии программист создаст новую константу? А если объявлять константу внутри класса профессии, то какой тогда в этом смысл, если можно использовать названия класса? Корректно ли использовать такую конструкцию в качестве аргумента $departament->findEmployees(get_class (new Analyst)); ?


Можно использовать имя класса. Для получения имени класса есть константа SomeClass::CLASS

>>В общем-то эта строка не нужна.


> Почему не нужна? Если $analysts не определен, то данная итерация прервется, и цикл перейдет к другому департаменту, и не будет выполнятся код следующий за этой строкой.


Потому что если эту строку убрать результат будет тот же.

> Почему это ошибка именно инкапсуляции, а не логики?


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

> Я переделал, теперь метод смены работника в департаменте, которому аргументом передают работника, который если есть в депе получает статус шефа. Но деп все также обращается к методу Employee->setСhief(0); Я исправил ошибку?


Да, это и требовалось, надо чтобы в департаменте был метод смены босса.

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

По коду:

> // Назначаем работника шефом


> $this->employees[$employeeKey]->setСhief(1);


Тут можно было писать $empolyee->setChief(1) так как это тот же объект.

> // Создание департамента


> public function createDepartament($name)


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

> $engineers = $departament->findEmployees(get_class (new Engineer));


Если константа Engineer::CLASS, хранящая имя класса

> // Берем первые 40% через array_slice


> $dismissingEngineers = floor(count($engineers) * 0.6);


> $engineers = array_slice($engineers, $dismissingEngineers);


ЧТо-то странно. Почему 0.6, а не 0.4? Почему ты берешь последние 40%, а не первые?

> // Если в Департаменте нет аналитиков, переходим к след. департаменту


> if (!isset($analysts[0])) continue;


!count(...) или просто !$analysts

> public function liftManager($company)


> sort($employees);


Это не будет работать или будет работать криво. Нужен usort, а sort годится только для сортировки строк.
https://github.com/never3ver/studentslist #759 #794742
>>778455

https://github.com/never3ver/students_list

> https://github.com/never3ver/students_list/blob/master/students_students.sql


Тут надо добавить уникальный ключ для email

> `birthyear` int(4)


есть тип YEAR

> `cookie` varchar(45) NOT NULL,


Надо добавить комментарий (COMMENT '....') чтобы пояснить что это за поле и как используется.

> https://github.com/never3ver/students_list/blob/master/public/bootstrap/styles.css


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

> .form {


> position: relative;


> top: 60px;


Для этого используют margin. Советую посмотреть мой курс по HTML/CSS из ОП поста.

> require_once __DIR__ . '/../app/init.php';


> require_once __DIR__ . '/../autoload.php';


Вызов autoload логично поместить в init.php

https://github.com/never3ver/students_list/blob/master/public/index.php
тут смешана в кучу контроллер и шаблон (view). Прочитай про отделение шаблонов от кода. HTML код должен быть в шаблонах.

> https://github.com/never3ver/students_list/blob/master/public/index.php#L47


> $pageList = $gateway->searchStudents($search);


При поиске надо бы поддерживать сортировку и постраничность тоже.

> <?php if (!isset($_COOKIE['name'])): ?>


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

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


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

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

> $row = $gateWay->getStudent($_COOKIE['name']);


> $oldEmail = $row[5];


Что за цифра 5? Откуда она взялась?

> if (isset($_POST['name']) && isset($_POST['secondname']) && isset($_POST['sex']) && isset($_POST['group']) && isset($_POST['email']) && isset($_POST['score']) && isset($_POST['birthyear']) && isset($_POST['local'])) {


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

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

> if ($errorsOfValidation && isset($student->name)) {


зачем проверка student->name?

> foreach ($errorsOfValidation as $value) {


> echo $value . "<br>";


Вывод должен быть в шаблоне. У тебя не MVC.

> if (!$gateWay->isEmailUnique($student->email) && $oldEmail != $student->email) {


> echo 'Введенный email уже используется';


Разве это не часть валидации?

> header("Refresh: 5; url = index.php");


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

> header("Refresh: 5; url = index.php");


>echo 'Редактирование завершено. Если перенаправление не произойдет в течении 5 секунд, <a href="index.php">Главная страница</a>.';


Ты выводишь русские буквы, а где заголовок или метатег, задаюший кодировку? И где оформление?

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

https://github.com/never3ver/students_list/blob/master/app/init.php
Не задается кодировка для mysql, есть риск что это окажется не utf8.

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


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


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

> Имя группы может содержать не более 10 латинских


В условии задачи не более 5

> if (! preg_match("/M|F/", $student->sex)) {


Это регулярка посчитает правильной строку abcdefMghijk так как не привязана к краям строки

> /([a-zA-Z0-9_+.-]+)@([a-z.-]+)/ui"


В имени домена могут быть цифры, но регулярка не разрешает.

> if ((! preg_match("/[0-9]{1,3}/", $student->score)) && $student->score <= 100) {


По моему тут ошибка в условии.

> https://github.com/never3ver/students_list/blob/master/app/Pager.php#L41


> public function getLimitAndOffset($pageNumber) {


тут логичнее сделать 2 отдельнх функции

https://github.com/never3ver/students_list/blob/master/app/Helper.php#L17
Для пометки есть тег <mark>

https://github.com/never3ver/students_list/blob/master/templates/editForm.html#L3

> <head>


> <link rel='stylesheet' href='/bootstrap/css/bootstrap.min.css'


> type='text/css' media='all'>


Это (тег head) скопировано в нескольких шаблонах. Надо убрать копипасту.

> <td class="textboldleft">Фамилия</td><td>


> <input class="column-wide" type="text" name='secondname'


> value='<?=$row[2]?>' required="required">


Что за странный формат результата? ЧТо такое row[2]? Откуда эта двойка? Почему $row это не объект-модель студента, а какой-то массив с цифрами?

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

https://github.com/never3ver/students_list/blob/master/templates/editForm.html#L25

> value='<?=$row[2]?>'


Тут XSS. Почитай мой урок по этой теме.

> https://github.com/never3ver/students_list/blob/master/templates/editForm.html


> https://github.com/never3ver/students_list/blob/master/templates/registerForm.html


Эти файлы скопированы. Убери копипасту и объедини их в один файл.

https://github.com/never3ver/students_list/blob/master/templates/listOfStudents.html#L14

> <?php $value['name'] = Helper::highlightText($search, $value['name']); ?>


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

Так как ты плохо разбираешься в экранировании, реши эту задачу: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Экранирование
https://github.com/never3ver/studentslist #759 #794742
>>778455

https://github.com/never3ver/students_list

> https://github.com/never3ver/students_list/blob/master/students_students.sql


Тут надо добавить уникальный ключ для email

> `birthyear` int(4)


есть тип YEAR

> `cookie` varchar(45) NOT NULL,


Надо добавить комментарий (COMMENT '....') чтобы пояснить что это за поле и как используется.

> https://github.com/never3ver/students_list/blob/master/public/bootstrap/styles.css


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

> .form {


> position: relative;


> top: 60px;


Для этого используют margin. Советую посмотреть мой курс по HTML/CSS из ОП поста.

> require_once __DIR__ . '/../app/init.php';


> require_once __DIR__ . '/../autoload.php';


Вызов autoload логично поместить в init.php

https://github.com/never3ver/students_list/blob/master/public/index.php
тут смешана в кучу контроллер и шаблон (view). Прочитай про отделение шаблонов от кода. HTML код должен быть в шаблонах.

> https://github.com/never3ver/students_list/blob/master/public/index.php#L47


> $pageList = $gateway->searchStudents($search);


При поиске надо бы поддерживать сортировку и постраничность тоже.

> <?php if (!isset($_COOKIE['name'])): ?>


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

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


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

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

> $row = $gateWay->getStudent($_COOKIE['name']);


> $oldEmail = $row[5];


Что за цифра 5? Откуда она взялась?

> if (isset($_POST['name']) && isset($_POST['secondname']) && isset($_POST['sex']) && isset($_POST['group']) && isset($_POST['email']) && isset($_POST['score']) && isset($_POST['birthyear']) && isset($_POST['local'])) {


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

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

> if ($errorsOfValidation && isset($student->name)) {


зачем проверка student->name?

> foreach ($errorsOfValidation as $value) {


> echo $value . "<br>";


Вывод должен быть в шаблоне. У тебя не MVC.

> if (!$gateWay->isEmailUnique($student->email) && $oldEmail != $student->email) {


> echo 'Введенный email уже используется';


Разве это не часть валидации?

> header("Refresh: 5; url = index.php");


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

> header("Refresh: 5; url = index.php");


>echo 'Редактирование завершено. Если перенаправление не произойдет в течении 5 секунд, <a href="index.php">Главная страница</a>.';


Ты выводишь русские буквы, а где заголовок или метатег, задаюший кодировку? И где оформление?

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

https://github.com/never3ver/students_list/blob/master/app/init.php
Не задается кодировка для mysql, есть риск что это окажется не utf8.

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


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


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

> Имя группы может содержать не более 10 латинских


В условии задачи не более 5

> if (! preg_match("/M|F/", $student->sex)) {


Это регулярка посчитает правильной строку abcdefMghijk так как не привязана к краям строки

> /([a-zA-Z0-9_+.-]+)@([a-z.-]+)/ui"


В имени домена могут быть цифры, но регулярка не разрешает.

> if ((! preg_match("/[0-9]{1,3}/", $student->score)) && $student->score <= 100) {


По моему тут ошибка в условии.

> https://github.com/never3ver/students_list/blob/master/app/Pager.php#L41


> public function getLimitAndOffset($pageNumber) {


тут логичнее сделать 2 отдельнх функции

https://github.com/never3ver/students_list/blob/master/app/Helper.php#L17
Для пометки есть тег <mark>

https://github.com/never3ver/students_list/blob/master/templates/editForm.html#L3

> <head>


> <link rel='stylesheet' href='/bootstrap/css/bootstrap.min.css'


> type='text/css' media='all'>


Это (тег head) скопировано в нескольких шаблонах. Надо убрать копипасту.

> <td class="textboldleft">Фамилия</td><td>


> <input class="column-wide" type="text" name='secondname'


> value='<?=$row[2]?>' required="required">


Что за странный формат результата? ЧТо такое row[2]? Откуда эта двойка? Почему $row это не объект-модель студента, а какой-то массив с цифрами?

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

https://github.com/never3ver/students_list/blob/master/templates/editForm.html#L25

> value='<?=$row[2]?>'


Тут XSS. Почитай мой урок по этой теме.

> https://github.com/never3ver/students_list/blob/master/templates/editForm.html


> https://github.com/never3ver/students_list/blob/master/templates/registerForm.html


Эти файлы скопированы. Убери копипасту и объедини их в один файл.

https://github.com/never3ver/students_list/blob/master/templates/listOfStudents.html#L14

> <?php $value['name'] = Helper::highlightText($search, $value['name']); ?>


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

Так как ты плохо разбираешься в экранировании, реши эту задачу: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Экранирование
Вектор | http://ideone.com/H5DCfT #760 #794743
>>778678

сама логика праивльная, но можно было обойтись без переменной $x (да и название полуше придумать).

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


Ну например mb_substr($str, -2, 1) вернет 2-ю букву с конца. Почитай мануал.

> btw, оглашать две переменные в действии1\менять их в действии2 это плохо ?


Если код понятен и очевиден, то нет.

>>778794
>>778812

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

Ответ правильный.

>>779256

> abstract class PersonelDepartment


> {


> public function addEmployee($employee)


Создание сотрудников не задача департамента и это надо сделать отдельно. Не надо включать эту функцию в него ни явно, ни через наследование. Нельзя наследовать Департамент от ОтделаКадров, так как наследование это отношение вида "A явлется Б" и Департамент не является ОтделомКадров.

> public function fireEmployee($employee)


> {


> $employeeKey = array_search($employee, $this->employees);


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

> public function findEmployee($position, $boss, $rank)


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

> static public function firstSolution($company)


> printData($company, 1);


Антикризисный комитет не должен печатать результаты.

> $department->changeBoss($boss, $promotionApplicant);


Непонятно почему в функици смены босса надо указвать старого. Департамент сам не знает кто его босс?
Вектор | http://ideone.com/H5DCfT #760 #794743
>>778678

сама логика праивльная, но можно было обойтись без переменной $x (да и название полуше придумать).

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


Ну например mb_substr($str, -2, 1) вернет 2-ю букву с конца. Почитай мануал.

> btw, оглашать две переменные в действии1\менять их в действии2 это плохо ?


Если код понятен и очевиден, то нет.

>>778794
>>778812

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

Ответ правильный.

>>779256

> abstract class PersonelDepartment


> {


> public function addEmployee($employee)


Создание сотрудников не задача департамента и это надо сделать отдельно. Не надо включать эту функцию в него ни явно, ни через наследование. Нельзя наследовать Департамент от ОтделаКадров, так как наследование это отношение вида "A явлется Б" и Департамент не является ОтделомКадров.

> public function fireEmployee($employee)


> {


> $employeeKey = array_search($employee, $this->employees);


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

> public function findEmployee($position, $boss, $rank)


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

> static public function firstSolution($company)


> printData($company, 1);


Антикризисный комитет не должен печатать результаты.

> $department->changeBoss($boss, $promotionApplicant);


Непонятно почему в функици смены босса надо указвать старого. Департамент сам не знает кто его босс?
#761 #794955
Есть один архив:
$word1 = array('Чудесных', 'Суровых', 'Занятных', 'Внезапных');
Надо достать из него случайное слово. Я использовал array_rand, но получил только число. Может мне кто-то объяснить, как получить слово? Не хочу плодить ещё один массив через array_flip.
>>794956>>794967
#762 #794956
>>794955

>массив


самофикс
#763 #794967
>>794955

Мы уже все сидим в новом треде >>793705 (OP) , тут только ответы на старые посты.

> Надо достать из него случайное слово. Я использовал array_rand, но получил только число.


array_rand возвращает случайный ключ (а не значение) из массива. Тебе надо взять значение по ключу с помощью квадратных скобок.
67 Кб, 640x640
#764 #796727
Ребят, объясните или дайте ссылку на материал, где объясняется принцип работы алгоритма хеширования DJBX33A.
>>797240
#765 #796871
ОП, а зачем вот подобные задачи типо "задача на список студентов" писать все самому с нуля, если можно просто использовать какой-то фреймворк со всеми его свистелко перделками?
>>797240
#766 #797240
>>796871

Чтобы изучить основы, как работать с таблицами и формами, как работать с базой данных, как разбивть код на классы и тд.

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

Алсо мы давно уже в новом треде, перекатывайся.

>>796727

Гугли
Ответы #767 #797241
>>781871

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

Также, у тебя там ошибка- обращение к еще не существующей переменной:

> PHP Notice: Undefined variable: pureNum in /home/KZQmiP/prog.php on line 13



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

>>782394

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

>>782503
>>782508

Не знаю, займсиь отладкой, смотри что приходит, что уходит.
>>783071

> https://ideone.com/t2U2f3


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

В остальном верно.

> https://ideone.com/KohVif


Тут то же самое замечание, в остальном верно.

> https://ideone.com/0Ye4lY


в общем верно, хотя у тебя он не подсветит вторую опечатку в том же слове вроде тOпOр

>>784017

http://ideone.com/0hmsEY // Кошки-мышки

Константы заводить не требуется - можно использовать имя класса и получать его как Cat::CLASS

> protected $xy = array();


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

Ну и вроде по этой задаче я уже писал ниже: >>791267 >>792620
Ответы #767 #797241
>>781871

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

Также, у тебя там ошибка- обращение к еще не существующей переменной:

> PHP Notice: Undefined variable: pureNum in /home/KZQmiP/prog.php on line 13



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

>>782394

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

>>782503
>>782508

Не знаю, займсиь отладкой, смотри что приходит, что уходит.
>>783071

> https://ideone.com/t2U2f3


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

В остальном верно.

> https://ideone.com/KohVif


Тут то же самое замечание, в остальном верно.

> https://ideone.com/0Ye4lY


в общем верно, хотя у тебя он не подсветит вторую опечатку в том же слове вроде тOпOр

>>784017

http://ideone.com/0hmsEY // Кошки-мышки

Константы заводить не требуется - можно использовать имя класса и получать его как Cat::CLASS

> protected $xy = array();


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

Ну и вроде по этой задаче я уже писал ниже: >>791267 >>792620
Ответы #768 #797242
>>784979

Не знаю.

>>785859
>>785862

Надо использовать повторение. Ну например a{5} ищет 5 букв a подряд, \d{5} ищет 5 цифр подряд - тебе надо примерно то же.

> но я не могу понять как, если бы не было пробелов, скобок и -, я бы написал [\d]{10} но это не прокатит


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

>>785910

Молодец, верно.

>>785990

Я тоже не знаю.

>>786040

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

>>786745

Не, там надо по-другому. Разбиваешь стих на строки. Сначала выводишь первую букву каждой строки, затем вторую, затем третью и тд.
Ответы #768 #797242
>>784979

Не знаю.

>>785859
>>785862

Надо использовать повторение. Ну например a{5} ищет 5 букв a подряд, \d{5} ищет 5 цифр подряд - тебе надо примерно то же.

> но я не могу понять как, если бы не было пробелов, скобок и -, я бы написал [\d]{10} но это не прокатит


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

>>785910

Молодец, верно.

>>785990

Я тоже не знаю.

>>786040

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

>>786745

Не, там надо по-другому. Разбиваешь стих на строки. Сначала выводишь первую букву каждой строки, затем вторую, затем третью и тд.
Тред закрыт #769 #797246
Я ответил на все вопросы, проверил все задачи. Если я кого-то пропустил - напомните о себе в новом треде >>793705 (OP)

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

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски