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

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

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

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

Клуб изучающих PHP и webdev #91 9 июля, 13:54 #1019301 В конец треда | Веб

33 Кб, 500x500

157 Кб, 1024x683

194 Кб, 1024x768

3,4 Мб, 1920x1080

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

Пожалуйста, пишите один большой пост вместо нескольких маленьких и не флудите не по теме.

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

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

Предыдущий тред был тут: >>1000416 (OP) ( http://arhivach.org/thread/266631/ ). Еще предыдущие треды ищутся в гугле по словам "клуб php" или в архиваче. Еще есть такой архив тредов: phpclub.rf.gd

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Что почитать

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

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

У ОПа нет аккаунтов и групп вконтакте, в фейсбуке, в твиттере, все "пхп-треды" там поддельные.

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

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

Ответы198682050620834209282217330184

56 Кб, 500x644

Важно 9 июля, 13:55 #2 #1019303

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Объясняй

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

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

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

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

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

56 Кб, 500x644

Важно 9 июля, 13:55 #2 #1019303

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Объясняй

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

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

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

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

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

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

9 июля, 13:56 #3 #1019307

Если вы писали что-то в прошлом треде, и вам не ответили, напомните тут о себе.

Этот проект https://github.com/Merkalov/Students я проверил тут >>1005550 (если тред утонул, ищите в архиваче)

9 июля, 14:33 #4 #1019372

Не заметил что уже перекат. Извините.

>>1019368

9 июля, 15:00 #5 #1019419

подписался

17 Кб, 159x159

IDE 9 июля, 15:23 #6 #1019450

Какже мне горит, от моего старого ноута куплен в 2009 году. Решился установить PHPStorm - какаяже годнота, именно то, что нужно, но пиздец как тормозит, пришлось снести.

Юзаю codelobster. Пытался в netbeans, но во-первых: он тоже притормаивает, а во вторых - нет нормального автодополнения для laravel и blade.

Может кто-то посоветовать, что-то годной для старых компухтеров?

Ответы1959319622

9 июля, 15:30 #7 #1019464

Есть ли пхпшнику профит от изучения C++?
Я имею в виду, есть ли проекты, требующие навыков написания кода на обоих этих языках. И насколько это экзотика?

Ответы19562

9 июля, 16:44 #8 #1019562

>>1019464

хайлоад (хотя сейчас там чаще посматривают в сторону Го или Раста, но их без знания Си изучать трудно).

9 июля, 17:15 #9 #1019593

>>1019450
субллайм + плагины

Ответы19597

9 июля, 17:22 #10 #1019597

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

Ответы2036420370

58 Кб, 540x542

9 июля, 17:47 #11 #1019622

>>1019450
>нет нормального автодополнения для laravel и blade
https://www.google.ru/search?q=netbeans+blade+syntax+highlighting&gws_rd=cr&ei=jEFiWaPzFcbC6QTpvrqoCA
Жёсткий диск заменил на ССД?

Ответы19646

9 июля, 18:16 #12 #1019646

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

Ответы19750

9 июля, 20:16 #13 #1019750

>>1019646
Для блейда есть плагин, емнип

9 июля, 20:24 #14 #1019755

>>1002548

А почему тогда не сделаны сеттеры на ранг или на лидера?

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

9 июля, 20:31 #15 #1019760

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

Ответы19771

9 июля, 21:01 #16 #1019770

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

Ответы1977219896

sage 9 июля, 21:01 #17 #1019771

>>1019760
Есть миллион готовых библиотек для иконок.
Если заказчик дает тебе эскиз (макет), то иконки все есть.
Если в студии с кем-то, то также - картинки даны.
Верстальщику рисовать не очень нужно.

sage 9 июля, 21:02 #18 #1019772

>>1019770
Гуглишь курсхантерс, оплачиваешь подписку на Хекслете.

Ответы19773

9 июля, 21:03 #19 #1019773

>>1019772
а обязательно платить,мож на английском че есть?

Ответы19814

9 июля, 21:41 #20 #1019814

>>1019773
https://coursehunters.net/source/hexlet

92 Кб, 688x460

9 июля, 22:05 #21 #1019868

>>1019301 (OP)

>
- сделать для каждой формы свой URL, который и выводит ее (при GET), и обрабатывает запрос (при POST). И форма с главной шлет запрос на этот URL, при ошибке выводится только сама форма с ошибкой.

Не понял. Допустим обработался некоторый не-главный-экшн, который работает с формой, допустим комментария...

> При ошибке выводится только сама форма с ошибкой

...это что, будет вью только с этой формой комментария? Т.е. шаблон без ничего (ну кроме шапки и подвала, которые везде инклюдятся), только эта форма?
Или же, если я правильно понял, эти две формы выводятся и в local.app/controller/indexAction и в local.app/controller/someAction, но как второй экшн вернет главному список ошибок? Можно немного псевдокода, что-то я давно мучаюсь с этими второстепенными экшнами и мой код сейчас выглядит как пикрелейтед (функции delFile, addComment, checkAccessPass являются не экшнами, а просто уменьшают толщину контроллера).

Ответы19871

9 июля, 22:05 #22 #1019871

>>1019868
>>1019251

9 июля, 22:16 #23 #1019896

>>1019770
Тебе надо работать с БД, в которой ты будешь хранить юзеров и данные.
Для авторизации пользователя тебе надо куки.
Загрузка файлов - обычная работа с файлами, вида
...
<form enctype="multipart/form-data" action="addres" method="POST">
<input type="hidden" name="MAX_FILE_SIZE" value="44444" />
<input name="userfile" type="file" />
<p><input type="submit" value="Загрузить"></p>
</form>
...
$uploaddir = 'dir';
$uploadfile=$uploaddir.basename($_FILES['userfile']['name']);
...

Ответы1993519948

9 июля, 22:27 #24 #1019935

>>1019896
почему везде все это дается кусками и приходить потом дрочить что бы все это собрать в одно?

Ответы19948

9 июля, 22:35 #25 #1019948

>>1019896
сессии+куки
>>1019935
я бы дал тебе годных видеоуроков, блягодаря которым я это все постиг, но ты ведь не будешь смотреть, ибо там 200+ часов

Ответы19988

9 июля, 23:48 #26 #1019988

>>1019948
Ну ты кинь линк, а там уже смотреть или нет - дело каждого.

Ответы20006

10 июля, 00:24 #27 #1020006

>>1019988
Давно смотрел видосы от этого васяна: https://school-php.com/video
Они всратые, старые, в них много воды и они примитивные, но после них я научился строить какую-никакую архитектуру сайта, понял как делаются все эти авторизации и пр. Рекомендую их только потому, что не знаю смог бы я научится всему тому, по следующим урокам...
... а это уроки для илиты, это реально ахуенная хуйня, тут есть все: от самых основ (переменные, массивы, циклы и пр.) до ООП, паттернов, MVC, обзора по фреймворкам и т.пр. Качество плоховатое, но я реально ничего лучше не видел, просто посмотри на программу Кликни на "дополнительная информация" каждого из уроков:
1 уровень: http://nnm-club.me/forum/viewtopic.php?t=889322
2 уровень: http://nnm-club.me/forum/viewtopic.php?t=889427
3 уровень: http://nnm-club.me/forum/viewtopic.php?t=889601
4 уровень: http://nnm-club.me/forum/viewtopic.php?t=1014639

Ответы20018

10 июля, 00:31 #28 #1020018

>>1020006
Спасибо.

10 июля, 00:40 #29 #1020029

254 Кб, 1920x1080

195 Кб, 1920x1080

Я сегодня у мамы быдло-верстальшик. Собираю Франкенштейна из деталек бутстрапа.

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

А вы что творите, аноны?

Ответы2013928374

10 июля, 03:43 #30 #1020111

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

И вообще, есть тут те, кто работает пхп джуном? Что вы вообще делаете?

Ответы2014321018

10 июля, 08:20 #31 #1020139

>>1020029
ты так все время пердолишь окно?
и в фф и в хромиум-* вроде же есть эмуляция
и почему шиндовс?

Ответы20161

10 июля, 08:34 #32 #1020143

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

10 июля, 08:42 #33 #1020145

антоны помогите плизке
сайт pisos.ru
как сделать, чтобы файл
/folderWithCandies/dick.html
открывался по адресу pisos.ru/dick ?
через редирект 301 или что-то типа того

Ответы2016620739

2,7 Мб, 1440x1080

10 июля, 09:53 #34 #1020161

>>1020139
Какая эмуляция?

На мак денег пока нет. А в лиуксе интерфейс громоздкий, сжирает много экранного места по вертикали, и безбожно томозит, всё это в сравнении с виндой. Хостинг - выделенный на убунте, пердолю через ssh, гуй там не нужен.

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

Ответы2078922010

10 июля, 10:00 #35 #1020166

>>1020145
>/folderWithCandies/
На выделенном хостинге настроить апач или нгникс так чтобы корневой папкой была "/folderWithCandies/"

На виртуальном можно создать в корне dick.php который будет подтягивать "/folderWithCandies/dick.html" с помощью require или include. В адресной строке тогда останется "pisos.ru/dick"

htaccess может только перенаправить с "pisos.ru/dick" на "/folderWithCandies/dick.html" В адресной строке тогда будет "/folderWithCandies/dick.html" и ничего с этим не поделать

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

Ответы20712

10 июля, 12:39 #36 #1020292

> в сообщении присутствует слово из спам-листа

https://pastebin.com/ZZ687D7q

Ответы20317

10 июля, 13:15 #37 #1020317

>>1020292

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

date | ok | wait | cancel
------------------------

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

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

Там ведь разные сервисы, хранилища файлов, базы данных, и тд.

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

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

> В этом и состоит суть паттерна, что изменения в сущностях отслеживаются автоматически и сохраняются в базу при коммите?
Вроде примерно это (судя по https://martinfowler.com/eaaCatalog/unitOfWork.html ). Но там написано, что главное преимущество UOW это запись изменений атомарно, одной транзакцией, а не кучей мелких транзакций.

Доктрина содержит в UOW ссылки на все управляемый ей сущности (загруженные из БД, а также добавленные через persist), а также их исходное состояние и при flush() сравнивает их текущее состояние с исходным, находит различия, формирует пакет изменений и сбрасывает эти изменения в базу одной транзакцией.

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

> Ну то есть в классе UOW имеется маппер и репозиторий для каждой сущности,
Нету там ни мапперов, ни репозиториев.

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

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

> при извлечении из бд в репозиторий
В репозитории ничего не хранится.

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

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

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

10 июля, 13:15 #37 #1020317

>>1020292

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

date | ok | wait | cancel
------------------------

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

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

Там ведь разные сервисы, хранилища файлов, базы данных, и тд.

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

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

> В этом и состоит суть паттерна, что изменения в сущностях отслеживаются автоматически и сохраняются в базу при коммите?
Вроде примерно это (судя по https://martinfowler.com/eaaCatalog/unitOfWork.html ). Но там написано, что главное преимущество UOW это запись изменений атомарно, одной транзакцией, а не кучей мелких транзакций.

Доктрина содержит в UOW ссылки на все управляемый ей сущности (загруженные из БД, а также добавленные через persist), а также их исходное состояние и при flush() сравнивает их текущее состояние с исходным, находит различия, формирует пакет изменений и сбрасывает эти изменения в базу одной транзакцией.

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

> Ну то есть в классе UOW имеется маппер и репозиторий для каждой сущности,
Нету там ни мапперов, ни репозиториев.

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

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

> при извлечении из бд в репозиторий
В репозитории ничего не хранится.

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

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

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

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

10 июля, 14:11 #38 #1020356

У меня тоже вопрос про .htacces есть.
Как закрыть папку, чтобы извне никто не мог смотреть/исполнять файлыы, а сам сервер мог к ним оборащаться?

Экспериментировал с такими конструкциями и либо не блокируется ничего, либо блокируется для всех:
<FilesMatch ".(htaccess|php|jpg)$">
Order Allow,Deny
Deny from all
</FilesMatch>

Order deny,allow
Deny from all
<Files ~ ".(xml|css|jpe?g|php)$">
Allow from all
</Files>

Ответы22010

10 июля, 14:27 #39 #1020364

>>1019597
>отсутствие проводника
Open folder побывал ?
>черный цвет
white theme sublime text в гугл
>все на горячих клавишах
разве в шторме не тоже самое ?
>настройки через пизду
кто то не может в json объекты ?

не говорю что он пизже всех или замена IDE но имхо для моих задач хватает с головой и не жрёт 1000 ГБ рама , Atom есть , Brackets но они все чёрные , что при желании можно легко изменить

Ответы21072

10 июля, 14:37 #40 #1020370

>>1019597

Зачем тулбар? Я наоборот рад, что в нем нет этих дурацких кнопок. Цвет меняется, я сам не могу читать на темном фоне, тем более на моей плохой матрице. Файлы открываются через Ctrl + P либо через Ctrl + O с вписыванием пути вручную (в Windows в диалоге открытия файла можно писать путь и он дополняется).

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

Ответы21072

10 июля, 14:45 #41 #1020373

Помогите пожалуйста, как скачать апач?

Ответы20375

10 июля, 14:47 #42 #1020375

>>1020373
Нашел

53 Кб, 493x387

10 июля, 15:35 #43 #1020408

Анончики, решаю задачу про компанию "Вектор". Только начал, пытался проверить вывод имени департамента в терминале, а оно ничего не пишет, что я делаю не так?
https://pastebin.com/8NkvceWp

Ответы2043420445

10 июля, 15:59 #44 #1020434

>>1020408
Я не пхпшник, но разве buy->name не должно возвращать значение, например, с помощью return, как в других ЯП?

Ответы20443

10 июля, 16:07 #45 #1020443

>>1020434
в учебнике все вроде также было.
создаю объект, вызываю свойство, без всяких return

10 июля, 16:07 #46 #1020445

>>1020408
Потому что у тебя у объекта поле name пустое.

Ответы20457

10 июля, 16:21 #47 #1020457

>>1020445
но я же его с помощью конструктора создаю

Ответы20463

10 июля, 16:28 #48 #1020463

>>1020457
Нет.

Ответы20465

27 Кб, 343x256

10 июля, 16:33 #49 #1020465

>>1020463
сорян, я constructor пишу, а надо construct

58 Кб, 1014x948

10 июля, 17:10 #50 #1020506

>>1019301 (OP)
ОП, смотри на что наткнулся по пыхе и по ноде нашел такое же
https://phpschool.io/
Есть идея твои уроки перепилить в формат подачи воркшопов. Стоит ли?

Ответы22010

10 июля, 20:40 #51 #1020712

>>1020166
хочу сокращатель ссылок сделать
только теперь еще больше запутался и не пойму как это сделать нормально

Ответы207222073320739

10 июля, 21:03 #52 #1020722

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

Ответы20728

10 июля, 21:09 #53 #1020728

>>1020722
генерировать каждый раз новый хтмл?

Ответы20732

10 июля, 21:19 #54 #1020732

>>1020728
Не обязательно.

10 июля, 21:21 #55 #1020733

>>1020712
Используй фреймворки. Попробуй Slim, он простой.

10 июля, 21:31 #56 #1020739

>>1020145
>>1020712
if ($url == >'dick') {
//render dick
}

// for more information
Google: php router

23 Кб, 921x117

10 июля, 21:33 #57 #1020741

граждане, кто то пользовался вагрантом?
ставлю коробку под ларавел, запускаю виртуалку, но проблема - не установлен в ней mcrypt. захожу по ssh, устанавливаю через apt php7.1-mcrypt и хуяк! все ломается, все к едрени бабушки перекосоебливается и не работает. Версия php на виртуалке 7.1

Ответы22010

10 июля, 22:11 #58 #1020789

>>1020161
>Вчера открыл для себя, что вместо копирвоания файлов на хостинг через ftp или ssh можно просто сделать там пулл реквести из гит.
Да пребудет с тобой git clone.

10 июля, 22:30 #59 #1020821

Как можно определить 100% что кравлер попал в бан? Получаю 403 код, хотя из cli курлом получил 200 ответ один раз, пробовал полностью менять шапку реквеста, если использую прокси - в зависимости от работоспособности оной получаю 200 код. Мне админ доказывает, что забанили по какому-то параметру в реквеста, и говорит что у него в консоли все ок всегда и 403 ни разу не получил.
И второй вопрос, можно ли спуфить IP курлом при запросе из cli с параметром interface с учетом что использованный IP куплен и установлен на сервере тоже

10 июля, 22:56 #60 #1020834

>>1019301 (OP)
Как правильно использовать php. Писать html в php коде, или php код в html странице? Или может как то еще можно?

Ответы2085721023

10 июля, 23:23 #61 #1020857

>>1020834
Если что-то простое, то юзать PageController, если посерьезнее - FrontController и ApplicatiobController
я у мамы зандстраёб

Ответы2087021023

10 июля, 23:41 #62 #1020870

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

И еще кое что, как делают так, что при запросе www.host.ru/page открывается страница без окончания index.php? Знаю что во фреймворках такое, но как сделать без фреймворков не могу нагуглить.

Ответы20902

10 июля, 23:48 #63 #1020876

Ничего не понимаю, везде пишут только про обработку форм php. Запросы на страницы как обрабатывать? Хелп анончики.

Ответы2090420950

11 июля, 00:18 #64 #1020900

ОП проверь плз. Задача про компанию вектор. http://ideone.com/UZfro9

Тайпхинты не использовал, смысл в них вообще.

А еще ошибки не знаю как исправить.

Ответы20903209452133221692

11 июля, 00:21 #65 #1020902

>>1020870
гугли ЧПУ , rewrite mod apache2

Ответы20908

11 июля, 00:23 #66 #1020903

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

11 июля, 00:24 #67 #1020904

>>1020876
либо ajax либо POST GET с перезагрузкой страницы , то есть отсылаешь все данные с формы на какой то скрипт обрабатываешь и получаешь результат

Ответы20911

11 июля, 00:26 #68 #1020908

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

Ответы20922

11 июля, 00:29 #69 #1020911

>>1020904
Не понятно. Вот открыл юзер в браузере www.host.ru/page, предположим это главная страница, значит GET запрос, как этот запрос обработать?
Не пойму зачем мне форма, если нужно гет запросы обрабатывать.

Ответы209202092520950

513 Кб, 3840x2160

11 июля, 00:32 #70 #1020914

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

https://ideone.com/FWNxh4

Ответы21023

11 июля, 00:36 #71 #1020920

>>1020911
а в этом смысле www.host.ru/page пофакту должно быть www.host.ru/page.php но всякие мод реврайты умеют обрезать эту .php или например www.host.ru/index.php/page тоже умеют обрезать index.php

скрипт выполняется скрипт из этого самого page.php

11 июля, 00:38 #72 #1020922

>>1020908
так то да , по нормальному у тебя должен быть всего 1 входная точка это index.php и она обработает запрос на тот же page но тогда гугли простейшие route pattern

11 июля, 00:40 #73 #1020925

>>1020911
RewriteEngine on
RewriteRule page page.php

RewriteRule vasya/pupkin/khuy/zalupkin user.php?id=1488

Там много есть почитать.
https://habrahabr.ru/company/sprinthost/blog/129560/
http://htaccess.ru/
Мне лично вот этот помог разобраться на примерах:
http://ruseller.com/lessons.php?id=1916

Ответы20932

11 июля, 00:46 #74 #1020928

>>1019301 (OP)
Кто нибудь может объяснить что не так с php. Можно ли как в ноде или в других языках запустить php файл на выполнение и чтобы он обрабатывал все запросы? Если я правильно понял, то нельзя, из-за того что php отрабатывает код файла и умирает.

Ответы20950

11 июля, 00:50 #75 #1020932

>>1020925
Спасибо анон. Просто я хожу разобраться с тем как работает интерпретатор php, и как устроена работа с http. Не хочу ставить апач. Мне не горит решать это, мне нужно понять как работает сам php. Похоже в строке запроса php может получать только параметры после знака ?, это вообще печаль, как жить то???

Ответы2093720947

11 июля, 01:03 #76 #1020937

>>1020932
это если передавать GET запрос , есть же ещё POST запросы
http://phpfaq.ru/newbie/na_tanke

11 июля, 01:42 #77 #1020945

>>1020900

### Тайп хинты

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

Мануал: http://php.net/manual/ru/language.oop5.typehinting.php

Обрати внимание, что php7 усовершенствовал систему тайп-хинтов - теперь можно в их качестве указывать примитивные типы вроде int/string, а в php7.1 стало можно указывать тайп-хинт для возвращаемого функцией значения: https://habrahabr.ru/post/267799/ (увы, возможность вернуть null пока не реализовали, так что ждем)

Ответы21023

11 июля, 01:46 #78 #1020947

>>1020932

Здесь нет нужной информации? http://php.net/manual/ru/reserved.variables.server.php

Когда приходит HTTP запрос, PHP анализирует его и кладет информацию о нем в суперглобальные переменные $_SERVER, $_GET, $_POST, $_COOKIE, $_FILES, $_ENV - они описаны в документации.

Все, что выводит программа (echo и подобными функциями), PHP отправляет в теле HTTP ответа.

На заголовки HTTP ответа можно повлиять с помощью функций header, set_cookie и некоторых ini-настроек.

11 июля, 01:51 #79 #1020950

>>1020928

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

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

С PHP все в порядке.

>>1020876

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

>>1020911

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

Вообще-то у меня это описано в уроке для встроенного в PHP сервера, почему не прочел? https://github.com/codedokode/pasta/blob/master/soft/web-server.md

Ссылка в ОП посте стоит.

11 июля, 02:12 #80 #1020958

Что вот это вот?
PHP Fatal error: Uncaught Error: Call to undefined function mb_internal_encoding() in /home/hIt56v/prog.php:5

Везде, даже в самых простых вещах вылезает эта лажа на ideone. Я косячу или такова воля Божья?

Ответы20961

11 июля, 02:20 #81 #1020961

>>1020958
Все mb_* это дополнительная, не обязательная библиотека, видно на ideone она не установлена , оттуда и проблемы.
http://php.net/manual/en/book.mbstring.php

Ответы20973

11 июля, 02:47 #82 #1020973

>>1020961
Раньше работала. А что же делать?

Ответы21023

215 Кб, 1021x681

11 июля, 07:56 #83 #1021013

какого хуя это говно не работает я хочу выбрать все iblock_element у которых есть VALUE 423 и 408 в iblock_element_property
SELECT
`iblock_element`.`ID` AS `ID`
FROM `b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_element_property` `iblock_element_property` ON `iblock_element_property`.`IBLOCK_ELEMENT_ID` = `iblock_element`.`ID`
WHERE (`iblock_element_property`.`VALUE` = '423') AND (`iblock_element_property`.`VALUE` = '408')

Ответы21017

160 Кб, 850x850

11 июля, 08:15 #84 #1021017

>>1021013
неужели так? а если у меня пиздец сложная логика на каждое значение по джоину?
SELECT
`iblock_element`.`ID` AS `ID`
FROM `b_iblock_element` `iblock_element`
LEFT JOIN `b_iblock_element_property` `iblock_element_property` ON `iblock_element_property`.`IBLOCK_ELEMENT_ID` = `iblock_element`.`ID`
LEFT JOIN `b_iblock_element_property` `iblock_element_property2` ON `iblock_element_property2`.`IBLOCK_ELEMENT_ID` = `iblock_element`.`ID`
WHERE (`iblock_element_property`.`VALUE` = '423' AND `iblock_element_property2`.`VALUE` = '408')

11 июля, 08:20 #85 #1021018

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

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

пхп-джун

Ответы21195

11 июля, 08:30 #86 #1021023

ОП, в пасте про студентов ссылка http://www.phpinfo.su/articles/practice/shablony_v_php.html стала битой (встречается в нескольких местах).

>>1020945
В PHP 7.1 есть возвращаемый тип void: https://3v4l.org/0kuHL

>>1020973
https://3v4l.org/

>>1020914
Можешь объяснить, чем плохи чистые функции, зачем городить эти Utility service? Юнит-тесты ты ведь всё равно писать не будешь. Какое-то слепое следование паттернам ради усложнений.

>>1020834
Хороший вопрос, тут есть ответ: http://www.php.su/articles/?cat=examples&page=014

>>1020857
Эти паттерны не отвечают на вопрос как увязывать HTML и PHP.

Ответы2105022010

Задачи 11 июля, 09:21 #87 #1021030

ОП, проверь задачи, пожалуйста

Изменение номера - https://ideone.com/KJxmSg
Автозамена - https://ideone.com/LaOqC8
Вывод email - https://ideone.com/NCD54g
Grammar Nazi - https://ideone.com/BR95EM

Ответы22009

11 июля, 10:17 #88 #1021050

>>1021023
Мне казалось, всякий код должен быть на своем месте. Что если мне понадобится вот этот rand() в любом месте кода, я позову его из сервиса и всё.

Предлагаешь лучше просто собрать их все в файл и подключать прямо к window?

sage 11 июля, 10:48 #89 #1021061

Напоминаю, что если вы хотите потрогать SQL, то почитайте
стайлгайд http://www.sqlstyle.guide/ru/
Инфа от ОПа https://github.com/codedokode/pasta/blob/master/db/databases.md
https://youtu.be/REbsxmE5h4M проектирование базы в MySQL Workbench

Ответы22009

11 июля, 11:16 #90 #1021072

>>1020364
>Open folder побывал ?
Что это? Папка как проект? Мне нужен проводник по всей системе - в notepad++, например, он сделан идеально.
>разве в шторме не тоже самое ?
я его не юзал толком, но там вроде есть возможность влепить тулбар
>кто то не может в json объекты ?
а че ты в дефолтном виндовом блокноте не кодишь? Не можешь в него?

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

Ответы21170

11 июля, 12:29 #91 #1021099

Привет всем.
Последнее время, перед собеседованием просят показать небольшой файл с примером кода.
Я хочу отправлять это: https://pastebin.com/F9Cv1eXm
Рейт ми, как говорится. Может чего подправить стоит?

Ответы22009

11 июля, 13:54 #92 #1021170

>>1021072
>а че ты в дефолтном виндовом блокноте не кодишь? Не можешь в него?
м манёвры ? сравнить json объекты с кучей формочек ? имхо мне даже удобнее поправить в файле нежели бегать по файл -> правка -> опция залупки

Ответы21184

11 июля, 14:13 #93 #1021184

>>1021170

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

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

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

11 июля, 14:26 #94 #1021195

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

Ответы21975

11 июля, 15:49 #95 #1021262

Это снова https://github.com/tsubaku
Я поработал над указанными ошибками, но исправил не все.
Во-первых, что исправил:
>Советую убрать опцию переименования таблиц через конфиг, это требует много усилий, а выгода неочевидна.
Убрал из конфига, в PDO обращаюсь к таблицам по имени. Теперь их названия прибиты гвоздями. Не уверен, что это лучше, но сделал.
>Советую убрать реальные даты, названия компаний, номера и фамилии из скриншота, заменить на вымышленные.
Убрал
>Тут код отформатирован ужасно: https://github.com/tsubaku/flights/blob/master/submit.php
Переформатировал. Теперь правильно? Перевёл в camelCase названия пхп-функций. Переменные не переводил, их слишком много.
>Если ты отдаешь JSON, то тип ответа должен быть application/json, не надо изобретать свои стандарты. И логично заголовки ставить не в начале скрипта, а перед отдачей самого JSON
Заменил text/plain на application/json везде, где возвращается JSON. Перенёс хидеры к echo json_encode. Нужны ли хидеры там, где только echo? А там, где вообще ничего нет, просто вызов функции?
> $pass = md5(md5(trim($pass)));
>Безопаснее использовать соленый хеш, как описано в моем уроке https://github.com/codedokode/pasta/blob/master/security/password-hashing.md
Заменил md5 на password_hash/password_verify
>При загрузке картинок нет проверки типа файла, человек загрузит .png или .txt, а ты его переименуешь в .jpg например.
Сделал проверку и корректное расширение для jpg, png, gif, остальным типам скрипт отказывает в загрузке.
> https://github.com/tsubaku/flights/blob/master/show_list_clients.php#L10
> while(list ($key, $val) = each ($_POST)){
>Это давно устарело, нужно использовать foreach тут
Переделал
>Название функции должно начинаться с глагола, то есть не protection, а redirectIfNoPrivileges(...)
Заменил на verifyAuthorization
> <a href='#' class='a_button_delete'
Ссылка должна куда-то вести. Для создания кнопки есть тег button.
Оформил в виде button. Немного поехала вёрстка кнопки, потом поправить.
> while ($i <= count($ru_rows_array)-1){
Тут нужно использовать foreach. Ты сишник наверно? Не надо тянуть плохие практики из Си в язык, где есть foreach.
Заменил в нескольких местах count на foreach
> if (is_null($_COOKIE['id'])
Это неправильно и вызовет ошибку, если в массиве нет ключа 'id'. У тебя наверно включено игнорирование предупреждений, или же ты не смотришь в логи ошибок, раз этого не видишь. Нужно использовать array_key_exists или isset здесь.
Хм, никаких ошибок в логах. Хотя, может быть я просто проверил не все случаи. Заменил is_null на empty.
https://github.com/tsubaku/flights/blob/master/functions.php#L187
> $info = getimagesize($path);
>Тут не проверяется вариант, когда функция вернет вместо массива false.
Добавил проверку

Что исправил с оговорками:
>В шаблонах у тебя вроде бы есть повторяющиеся куски - шапка страницы.
Шапки немного повторяются, но всё же есть различия и не думаю, что сливать общие части имеет смысл. Плюс, так их легче воспринимать. Я разделил скрипт core.js, вынеся в отдельные файлы скрипты менеджера и охранника, а в шаблонах убрал загрузку лишних скриптов.
>https://github.com/tsubaku/flights/blob/master/index.php#L10
> if ($user_level == 9) {
>Тут нужно ииспользовать константу с понятным названием вместо цифры
> $level = 'manager';
>И тот тоже желательно константу.
Немного переписал функцию проверки, теперь она возвращает ид, уровень доступа и фамилию. Проверку оставил по тому же условию.
> echo "<br />";
В HTML слеш в конце тега не ставится, в отличие от XML/XHTML.
Так у меня как раз XHTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> https://github.com/tsubaku/flights/blob/master/functions.php#L292
> header("Location: status_codes.php?result=403");
Если ты хочешь отдать код ответа HTTP, то надо его отдавать сразу. Потому что редирект - это код вроде 302. То есть ты вместо отдачи кода 403 отдаешь код 302 в ответ на запрос. И вместо "доступ запрещен" говоришь "страница переехала на другой адрес".
Я так и не понял, как сделать так, чтобы браузер при ошибках показывал суть ошибки. Ну или хотя бы стандартные коды. Так что просто заменил все редиректы на header("Location: login.php");

Что не удалось:
>Выделить публичную папку (т.е. папку для файлов, которые можно запросить снаружи) отдельно. Сейчас у тебя по сути все лежит в публичной папке веб-сервера, что небезопасно. Например, можно скачать шаблоны и увидеть их исходный код, а также скачать конфиг.
Выделил папку core, в неё перенёс все НЕ публичные пхп, шаблоны и закачиваемые фотографии. Но как закрыть её, не понимаю. .httaccess полностью рубит доступ и скрипты просто не работают. Как сделать так, чтобы сервер обращаться к ним мог, а левый юзер нет, я не нашёл информации.
>Тут https://github.com/tsubaku/flights/blob/master/show_list_clients.php в одном файле смешана логика и вывод данных в HTML, почитай про шаблоны http://web.archive.org/web/20161119062218/www.phpinfo.su/articles/practice/shablony_v_php.html
Немного переписал и упростил вывод таблиц охранников и клиентов, но как их шаблонизировать, я не знаю (статью читал). Данные в ячейки подставляются в цикле, имена ячеек тоже. При шаблонизации для каждой ячейки придётся писать отдельный вызов, получится монструозно.

>https://github.com/tsubaku/flights/blob/master/functions.php#L5
>Тут слишком сложная функция с слишком большой глубиной отступов
Да, функция монструозная. Я не знаю, как её изменить, ведь приходится обрабатывать каждую ячейку таблицы и обрабатывать дня неё данные, которые она содержит, и правила их отображения.

Что скажете?

11 июля, 15:49 #95 #1021262

Это снова https://github.com/tsubaku
Я поработал над указанными ошибками, но исправил не все.
Во-первых, что исправил:
>Советую убрать опцию переименования таблиц через конфиг, это требует много усилий, а выгода неочевидна.
Убрал из конфига, в PDO обращаюсь к таблицам по имени. Теперь их названия прибиты гвоздями. Не уверен, что это лучше, но сделал.
>Советую убрать реальные даты, названия компаний, номера и фамилии из скриншота, заменить на вымышленные.
Убрал
>Тут код отформатирован ужасно: https://github.com/tsubaku/flights/blob/master/submit.php
Переформатировал. Теперь правильно? Перевёл в camelCase названия пхп-функций. Переменные не переводил, их слишком много.
>Если ты отдаешь JSON, то тип ответа должен быть application/json, не надо изобретать свои стандарты. И логично заголовки ставить не в начале скрипта, а перед отдачей самого JSON
Заменил text/plain на application/json везде, где возвращается JSON. Перенёс хидеры к echo json_encode. Нужны ли хидеры там, где только echo? А там, где вообще ничего нет, просто вызов функции?
> $pass = md5(md5(trim($pass)));
>Безопаснее использовать соленый хеш, как описано в моем уроке https://github.com/codedokode/pasta/blob/master/security/password-hashing.md
Заменил md5 на password_hash/password_verify
>При загрузке картинок нет проверки типа файла, человек загрузит .png или .txt, а ты его переименуешь в .jpg например.
Сделал проверку и корректное расширение для jpg, png, gif, остальным типам скрипт отказывает в загрузке.
> https://github.com/tsubaku/flights/blob/master/show_list_clients.php#L10
> while(list ($key, $val) = each ($_POST)){
>Это давно устарело, нужно использовать foreach тут
Переделал
>Название функции должно начинаться с глагола, то есть не protection, а redirectIfNoPrivileges(...)
Заменил на verifyAuthorization
> <a href='#' class='a_button_delete'
Ссылка должна куда-то вести. Для создания кнопки есть тег button.
Оформил в виде button. Немного поехала вёрстка кнопки, потом поправить.
> while ($i <= count($ru_rows_array)-1){
Тут нужно использовать foreach. Ты сишник наверно? Не надо тянуть плохие практики из Си в язык, где есть foreach.
Заменил в нескольких местах count на foreach
> if (is_null($_COOKIE['id'])
Это неправильно и вызовет ошибку, если в массиве нет ключа 'id'. У тебя наверно включено игнорирование предупреждений, или же ты не смотришь в логи ошибок, раз этого не видишь. Нужно использовать array_key_exists или isset здесь.
Хм, никаких ошибок в логах. Хотя, может быть я просто проверил не все случаи. Заменил is_null на empty.
https://github.com/tsubaku/flights/blob/master/functions.php#L187
> $info = getimagesize($path);
>Тут не проверяется вариант, когда функция вернет вместо массива false.
Добавил проверку

Что исправил с оговорками:
>В шаблонах у тебя вроде бы есть повторяющиеся куски - шапка страницы.
Шапки немного повторяются, но всё же есть различия и не думаю, что сливать общие части имеет смысл. Плюс, так их легче воспринимать. Я разделил скрипт core.js, вынеся в отдельные файлы скрипты менеджера и охранника, а в шаблонах убрал загрузку лишних скриптов.
>https://github.com/tsubaku/flights/blob/master/index.php#L10
> if ($user_level == 9) {
>Тут нужно ииспользовать константу с понятным названием вместо цифры
> $level = 'manager';
>И тот тоже желательно константу.
Немного переписал функцию проверки, теперь она возвращает ид, уровень доступа и фамилию. Проверку оставил по тому же условию.
> echo "<br />";
В HTML слеш в конце тега не ставится, в отличие от XML/XHTML.
Так у меня как раз XHTML
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
> https://github.com/tsubaku/flights/blob/master/functions.php#L292
> header("Location: status_codes.php?result=403");
Если ты хочешь отдать код ответа HTTP, то надо его отдавать сразу. Потому что редирект - это код вроде 302. То есть ты вместо отдачи кода 403 отдаешь код 302 в ответ на запрос. И вместо "доступ запрещен" говоришь "страница переехала на другой адрес".
Я так и не понял, как сделать так, чтобы браузер при ошибках показывал суть ошибки. Ну или хотя бы стандартные коды. Так что просто заменил все редиректы на header("Location: login.php");

Что не удалось:
>Выделить публичную папку (т.е. папку для файлов, которые можно запросить снаружи) отдельно. Сейчас у тебя по сути все лежит в публичной папке веб-сервера, что небезопасно. Например, можно скачать шаблоны и увидеть их исходный код, а также скачать конфиг.
Выделил папку core, в неё перенёс все НЕ публичные пхп, шаблоны и закачиваемые фотографии. Но как закрыть её, не понимаю. .httaccess полностью рубит доступ и скрипты просто не работают. Как сделать так, чтобы сервер обращаться к ним мог, а левый юзер нет, я не нашёл информации.
>Тут https://github.com/tsubaku/flights/blob/master/show_list_clients.php в одном файле смешана логика и вывод данных в HTML, почитай про шаблоны http://web.archive.org/web/20161119062218/www.phpinfo.su/articles/practice/shablony_v_php.html
Немного переписал и упростил вывод таблиц охранников и клиентов, но как их шаблонизировать, я не знаю (статью читал). Данные в ячейки подставляются в цикле, имена ячеек тоже. При шаблонизации для каждой ячейки придётся писать отдельный вызов, получится монструозно.

>https://github.com/tsubaku/flights/blob/master/functions.php#L5
>Тут слишком сложная функция с слишком большой глубиной отступов
Да, функция монструозная. Я не знаю, как её изменить, ведь приходится обрабатывать каждую ячейку таблицы и обрабатывать дня неё данные, которые она содержит, и правила их отображения.

Что скажете?

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

11 июля, 16:57 #96 #1021332

>>1020900
http://ideone.com/lI5U84
Кто то может подсказать почему не работает функция увольнения. 168 Строка начала функции, в конце неё делаю ансет трём работникам. А в итоге все равно 101 работник.

Ответы21359

11 июля, 17:32 #97 #1021359

>>1021332
>get_Workers_For_Destruction
:)

http://php.net/unset

>// удаляем один элемент массива
>unset($array['element']);

Больше Разрушителей в энтот тред!

Ответы21692

11 июля, 19:10 #98 #1021421

ОП, какие есть способы оптимизировать вставку большого количества данных в БД, при условии использования доктрины? Я нагуглил это: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/batch-processing.html#bulk-inserts
Ещё что-то помню про отключение проверки внешних ключей на уровне СУБД. Это вопрос по поводу парсера старых/новых тредов: https://github.com/someApprentice/phpClub/tree/master/tests/ThreadParser
Прошу не проверять xpath-запросы, они скорее всего будут переписаны.

Ответы21824

11 июля, 19:27 #99 #1021432

Как сделать конструктор лэндига для вордпресса в виде плагина с драг и дропом секций?

Ответы21823

11 июля, 19:37 #100 #1021439

Кто-то под линупсом сидит? Все хочу перекатиться с винды, друг советует mint, посмотрел скрины - мне понравилось.

Удобно ли пхп-макаке кодить под линуксом? Есть некий аналог open server? Чтобы можно было легко переключаться между версиями апача, пхп, майэскьюэль без дрочки в консоле?

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

Ответы214822150421505215092176121823

11 июля, 20:17 #101 #1021482

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

Ответы2152621823

11 июля, 20:38 #102 #1021504

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

11 июля, 20:40 #103 #1021505

>>1021439
Если есть деньги, то можешь купить мак. Это считай линукс, только удобный и красивый. Там тебе и МАМП будет, и нжинкс будет в родной среде вариться, и права доступа к файлам по человечески. В общем, все плюсы линукса в приятной оболочке.

Ответы21823

11 июля, 20:42 #104 #1021509

>>1021439
хз что такое опенсервер, но по описанию унреал подходит генту
немного поебаться с установкой, если ты вообще не шаришь (но нужно уметь читать)
всякое лишнее говно супер легко убирается юз флагами
переключение между пхп\руби\питон\ядрами\видеодрайверами\почти-чем-угодно за 2 клика типа:
>eselect php list
>eselect php set 2
сам на линуксе <год, генту единственный юзабельный дистр

Ответы21526

11 июля, 20:58 #105 #1021526

>>1021482
>если будешь переустанавливать, то софт тоже постигнет сия участь
да ну нах. Если я захочу перебить систему с линукса на линукс, то софтине пизда?
>Без консоли в линуксе никак
Я умею в консоль и понимаю, что пользоваться консолью это конечно круто, но я в рот ебал эти понты, когда можно два раза мышкой кликнуть
>>1021509
Я не шарю. Для меня дистрибутивы линукса отличаются только внешним видом

Ответы21580

11 июля, 21:57 #106 #1021580

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

Ответы21590

11 июля, 22:07 #107 #1021590

>>1021580
Причем тут композер?

Ответы21591

11 июля, 22:07 #108 #1021591

>>1021590
Имеет отношение к понтам.

Ответы21594

11 июля, 22:08 #109 #1021594

>>1021591
это я понял, но как он поможет мне также быстро сменить версию пхп или апача, как я делаю это в опен сервере?

Ответы2160921613

11 июля, 22:21 #110 #1021609

>>1021594
меньше всего ебли из коробки с этим в генте
ставь генту

Ответы21649

11 июля, 22:26 #111 #1021613

>>1021594
= тому сколько ебли поставить memcache в опенсервере , алсо для смены можно сделать скрипт который так же по запуску будет менять как и 2 щелчка в GUI

Ответы21649

11 июля, 23:14 #112 #1021649

>>1021613
>>1021609
Спасибо за бесполезные советы, ребят

Ответы21684

12 июля, 00:06 #113 #1021671

Как можно удалить элемент массива по ключу?
unset($arrays[1]);?

Ответы21823

12 июля, 00:36 #114 #1021684

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

Ответы2168821823

12 июля, 00:49 #115 #1021688

>>1021684
спасибо, добра

12 июля, 01:08 #116 #1021692

>>1021359
Спасибо.

>>1020900
>ОП проверь плз. Задача про компанию вектор
Теперь еще с одной антикризисной мерой.
http://ideone.com/4zGFfs

Ответы2180321821

12 июля, 09:37 #117 #1021761

>>1021439
Линукс > Виндовс для разработчика
Бери mint с ним будет меньше всего мороки
С gentu тебя тролят, mac оверпрайс

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

Ответы21921

12 июля, 11:33 #118 #1021803

>>1021692
>Departament
Незачет тебе по английскому.

12 июля, 12:06 #119 #1021821

>>1021692

> add_departament
> get_Count_Workers
Что за нестандартный стиль названий функций? PSR рекомендует camelCase для методов:

- https://svyatoslav.biz/misc/psr_translation/#_PSR-1
- https://svyatoslav.biz/misc/psr_translation/#_PSR-2

> public function print_Info()
Вот это лучше бы вынести из Компании наружу, так как у каждого класса должна быть своя зона ответственности. Если у Компании зона отвественности - хранить список департаментов и считать по ним статистику, то вывод информации - это какая-то другая деятельность, которая явно должна делаться в другом месте.

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

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

> //Cократить в каждом департаменте 40% (округляя в большую сторону) инженеров,
> //преимущественно самого низкого ранга.
> public function Destruction_Workers
Тут та же проблема. Это сильно специфический метод, написанный под одну конкретную задачу (антикризисные меры), и его лучше вынести в отдельный класс. А так, ты по сути взял код, который должен быть в отдельном классе и размазал по Компании и Департаменту.

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

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

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

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

> Destruction_Workers
Имена функций начинаются с глаголов, сделатьЧтоТо

> public function add_Workers($count, $rank, $proffesion, $is_Head)
Этот метод сам создает работников, и не позволяет добавить уже созданного где-то в другом месте работника. Лучше сделать добавление именно готового объекта, это будет универсальнее.

> public function get_Workers_And_Destruction($count_in_percent,$proffesion)
Тут функция просто создана методом копирования кода. Так не годится. Нужно убрать повторяющийся код.

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

Также, у тебя выводятся предупреждения, которые надо исправить:

> PHP Notice: Undefined variable: sum_salary in /home/UH8YEW/prog.php on line 139
> PHP Notice: Undefined variable: sum_pages in /home/UH8YEW/prog.php on line 155
> PHP Notice: Undefined variable: sum_salary in /home/UH8YEW/prog.php on line 139
> PHP Notice: Undefined variable: sum_coffee in /home/UH8YEW/prog.php on line 147
> PHP Notice: Undefined variable: sum_pages in /home/UH8YEW/prog.php on line 155

12 июля, 12:06 #119 #1021821

>>1021692

> add_departament
> get_Count_Workers
Что за нестандартный стиль названий функций? PSR рекомендует camelCase для методов:

- https://svyatoslav.biz/misc/psr_translation/#_PSR-1
- https://svyatoslav.biz/misc/psr_translation/#_PSR-2

> public function print_Info()
Вот это лучше бы вынести из Компании наружу, так как у каждого класса должна быть своя зона ответственности. Если у Компании зона отвественности - хранить список департаментов и считать по ним статистику, то вывод информации - это какая-то другая деятельность, которая явно должна делаться в другом месте.

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

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

> //Cократить в каждом департаменте 40% (округляя в большую сторону) инженеров,
> //преимущественно самого низкого ранга.
> public function Destruction_Workers
Тут та же проблема. Это сильно специфический метод, написанный под одну конкретную задачу (антикризисные меры), и его лучше вынести в отдельный класс. А так, ты по сути взял код, который должен быть в отдельном классе и размазал по Компании и Департаменту.

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

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

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

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

> Destruction_Workers
Имена функций начинаются с глаголов, сделатьЧтоТо

> public function add_Workers($count, $rank, $proffesion, $is_Head)
Этот метод сам создает работников, и не позволяет добавить уже созданного где-то в другом месте работника. Лучше сделать добавление именно готового объекта, это будет универсальнее.

> public function get_Workers_And_Destruction($count_in_percent,$proffesion)
Тут функция просто создана методом копирования кода. Так не годится. Нужно убрать повторяющийся код.

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

Также, у тебя выводятся предупреждения, которые надо исправить:

> PHP Notice: Undefined variable: sum_salary in /home/UH8YEW/prog.php on line 139
> PHP Notice: Undefined variable: sum_pages in /home/UH8YEW/prog.php on line 155
> PHP Notice: Undefined variable: sum_salary in /home/UH8YEW/prog.php on line 139
> PHP Notice: Undefined variable: sum_coffee in /home/UH8YEW/prog.php on line 147
> PHP Notice: Undefined variable: sum_pages in /home/UH8YEW/prog.php on line 155

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

12 июля, 12:06 #120 #1021823

>>1021684

Не надо добавлять бесполезные посты в этот тред

>>1021671

да

>>1021505

Это не линукс, например, там нет неймспейсов тех же.

>>1021439

> Есть некий аналог open server? Чтобы можно было легко переключаться между версиями апача, пхп, майэскьюэль без дрочки в консоле?
не знаю, может и нет, я сам привык консолью пользоваться и GUI видеть не могу.

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

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

Насчет разных версий PHP - в линуксе есть штука https://github.com/phpbrew/phpbrew которая умеет скачивать и компилировать нужные версии PHP, а потом переключать переменные окружения, чтобы их использовать. Разумеется, тебе придется изучить, как она работает. А так, большинство версий линукса не поддерживают стандартным способом установку 2 версий одной программы.

>>1021482

Только Debian лучше ставить Testing, а то в Stable софт стабильный, но старый.

>>1021432

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

12 июля, 12:06 #120 #1021823

>>1021684

Не надо добавлять бесполезные посты в этот тред

>>1021671

да

>>1021505

Это не линукс, например, там нет неймспейсов тех же.

>>1021439

> Есть некий аналог open server? Чтобы можно было легко переключаться между версиями апача, пхп, майэскьюэль без дрочки в консоле?
не знаю, может и нет, я сам привык консолью пользоваться и GUI видеть не могу.

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

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

Насчет разных версий PHP - в линуксе есть штука https://github.com/phpbrew/phpbrew которая умеет скачивать и компилировать нужные версии PHP, а потом переключать переменные окружения, чтобы их использовать. Разумеется, тебе придется изучить, как она работает. А так, большинство версий линукса не поддерживают стандартным способом установку 2 версий одной программы.

>>1021482

Только Debian лучше ставить Testing, а то в Stable софт стабильный, но старый.

>>1021432

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

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

12 июля, 12:06 #121 #1021824

>>1021421

Вообще, в MySQL есть раздел мануала на эту тему https://dev.mysql.com/doc/refman/5.5/en/optimizing-innodb-bulk-data-loading.html

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

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

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

Пример, который приведен в мануале, использует flush для группы записей, чтобы вставлять N записей одной транзакцией, и clear, чтобы очистить память (так как Доктрина хранит ссылки на все управляемые ей объекты и потребление памяти без этого будет быстро расти, а также будет змедляться flush, так как он обходит все объекты). Недостаток clear в том,что он убирает все объекты из-под управления доктрины (то есть делает на них detach) и его нельзя применять, если какой-то другой код держит ссылки на эти объекты, и планирует дальше с ними работать. То есть clear годится только для каких-то скриптов импорта, но его не стоит использовать в середине приложения, так как он сломает загруженные ранее сущности.

Ответы22181

12 июля, 14:57 #122 #1021921

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

12 июля, 16:32 #123 #1021975

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

Ответы21998

12 июля, 16:45 #124 #1021978

>>1021262

https://github.com/tsubaku

Сначала отвечу на пост:

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

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

> Переформатировал. Теперь правильно?
Не очень:

https://github.com/tsubaku/flights/blob/master/login.php
Тут нужно убрать самый первый отступ (после <?php), то есть строка require_once('./core/php/functions.php'); идет без отступа. Для отступов лучше использовать 4 пробела, а не таб.

https://github.com/tsubaku/flights/blob/master/core/php/submit.php
Тут отступы вообще разные. Почему отступ в строке 22 - 8 пробелов? должно быть 4. И почему там так много пустых строк? Пока что плохо.

Рекомендации PSR можно почитать тут в переводе

- https://svyatoslav.biz/misc/psr_translation/#_PSR-1
- https://svyatoslav.biz/misc/psr_translation/#_PSR-2

Код можно форматировать автоматически, через сайт или IDE, вот ссылка https://gist.github.com/codedokode/8759492

Не понимаю, в чем проблема прогнать файл через сайт или нажать комбинацию клавиш в IDE.

> Нужны ли хидеры там, где только echo? А там, где вообще ничего нет, просто вызов функции?
header логично ставить радом с echo так как они относятся к одной задаче, и header должен срабатывать только когда выводится JSON. А когда ты их ставишь в разных местах, то это во-первых нелогично (мы сначала сообщаем, что будет выведен JSON, а только потом где-то в другом месте его выводим), во-вторых может вести к ошибкам, когда выводится header с application/json а потом выводится не JSON, а обычный текст или например сообщение об ошибке.

То есть нелогично функцию вывода JSON разделять на 2 части и разбрасывать их в разные места кода.

Кстати, тут тоже нелогично: https://github.com/tsubaku/flights/blob/master/core/php/show_list_clients.php
В заголовках указан тип text/plain, а затем идет вывод HTML кода.

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

> Сделал проверку и корректное расширение для jpg, png, gif, остальным типам скрипт отказывает в загрузке.
Пока не очень удачно. Тут https://github.com/tsubaku/flights/blob/master/core/php/submit.php#L25 ты проверяешь тип файла, который берется из тела POST запроса и указывается браузером. Но браузер может там указать что угодно. Надежднее проверить расширение.

>> if (is_null($_COOKIE['id'])
>> Это неправильно и вызовет ошибку, если в массиве нет ключа 'id'.
> Хм, никаких ошибок в логах.
Вот пример, показывающий ошибку: http://ideone.com/bMeVWL

Возможно у тебя в php.ini включено игнорирование ошибок с помощью настройки error_reporting (зачем так делать??) или отключено их логгирование. Или у тебя всегда есть эта кука.

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

> Я так и не понял, как сделать так, чтобы браузер при ошибках показывал суть ошибки. Ну или хотя бы стандартные коды. Так что просто заменил все редиректы на header("Location: login.php");
Ты выводишь HTTP заголовок, затем тело страницы. Что тут сложного?

header("HTTP/1.0 500 Internal Error");
echo "Everything is broken, sorry\n";
die();

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

> Выделил папку core, в неё перенёс все НЕ публичные пхп, шаблоны и закачиваемые фотографии. Но как закрыть её, не понимаю.
У сервера есть такая настройка, как "корневая папка" (в Апаче она называется document root, в нгинксе root). Ты создаешь у себя папку public и в настройках веб-севрера прописываешь путь к ней как document root, например в Апаче:

DocumentRoot /var/www/example.com/public/

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

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

$guards = getGuardsList();
// подключаем шаблон
require 'templates/guards.phtml';

В шаблоне формируешь и выводишь HTML страницу:

<?php require __DIR__ . '/header.php'; ?>

<h1>Охранники</h1>
<ul>
<?php foreach ($guards as $guard): ?>
<li><?= htmlspecialchars($guard['name']) ?></li>
<?php endforeach ?>
</ul>

<?php require __DIR__ . '/footer.php'; ?>

> https://github.com/tsubaku/flights/blob/master/core/php/functions.php#L224
> unset($row_content); // разорвать ссылку на последний элемент
Эта строчка вообще смысла не несет, так как она стоит в конце функции, а все локальные переменную удаляются при выходе из функции.

Вот еще проблемное место:

> function showTable($year, $month)
> ...
> $stmt = $pdo->query('INSERT INTO flights () VALUES()'); //Добавляем пустую строку
Функция вывода таблицы не должна ее модифицировать.

> https://github.com/tsubaku/flights/blob/master/core/php/write_in_table.php
Тут нечитаемая стена кода, надо выносить из нее отдельные функции.

> Вопрос про функцию showTable()
> Да, функция монструозная. Я не знаю, как её изменить, ведь приходится обрабатывать каждую ячейку таблицы и обрабатывать дня неё данные, которые она содержит, и правила их отображения.
Сначала нужно разделить получение данных и их вывод. Сначала получаем все данные из БД, только потом выводим.

При этом часть кода можно выносить в отдельные функции. Вот например вначале идет кусок лапши, получающий список рейсов между 2 датами. Его легко вынести в отдельную функцию:

$flights = getFlightsInRange($fromDate, $toDate);

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

Точно так же можно вынести например получение списка охранников (getGuardList()), получение названия месяца по номеру (getMonthName()), и тд.

После того, как все данные выбраны в переменные, вызываем шаблон для вывода HTML кода.

HTML код выводить, как у тебя, с помощью echo, очень неудобно и неэффективно.

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

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

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

Соответственно, сейчас тебе надо работать над разделением:

- вынести весь HTML код в шаблоны
- вынести весь SQL-код в функции в отдельном файле или файлах, то есть сделать отдельный слой доступа к базе данных, а не размазывать это по всему коду

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

12 июля, 16:45 #124 #1021978

>>1021262

https://github.com/tsubaku

Сначала отвечу на пост:

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

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

> Переформатировал. Теперь правильно?
Не очень:

https://github.com/tsubaku/flights/blob/master/login.php
Тут нужно убрать самый первый отступ (после <?php), то есть строка require_once('./core/php/functions.php'); идет без отступа. Для отступов лучше использовать 4 пробела, а не таб.

https://github.com/tsubaku/flights/blob/master/core/php/submit.php
Тут отступы вообще разные. Почему отступ в строке 22 - 8 пробелов? должно быть 4. И почему там так много пустых строк? Пока что плохо.

Рекомендации PSR можно почитать тут в переводе

- https://svyatoslav.biz/misc/psr_translation/#_PSR-1
- https://svyatoslav.biz/misc/psr_translation/#_PSR-2

Код можно форматировать автоматически, через сайт или IDE, вот ссылка https://gist.github.com/codedokode/8759492

Не понимаю, в чем проблема прогнать файл через сайт или нажать комбинацию клавиш в IDE.

> Нужны ли хидеры там, где только echo? А там, где вообще ничего нет, просто вызов функции?
header логично ставить радом с echo так как они относятся к одной задаче, и header должен срабатывать только когда выводится JSON. А когда ты их ставишь в разных местах, то это во-первых нелогично (мы сначала сообщаем, что будет выведен JSON, а только потом где-то в другом месте его выводим), во-вторых может вести к ошибкам, когда выводится header с application/json а потом выводится не JSON, а обычный текст или например сообщение об ошибке.

То есть нелогично функцию вывода JSON разделять на 2 части и разбрасывать их в разные места кода.

Кстати, тут тоже нелогично: https://github.com/tsubaku/flights/blob/master/core/php/show_list_clients.php
В заголовках указан тип text/plain, а затем идет вывод HTML кода.

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

> Сделал проверку и корректное расширение для jpg, png, gif, остальным типам скрипт отказывает в загрузке.
Пока не очень удачно. Тут https://github.com/tsubaku/flights/blob/master/core/php/submit.php#L25 ты проверяешь тип файла, который берется из тела POST запроса и указывается браузером. Но браузер может там указать что угодно. Надежднее проверить расширение.

>> if (is_null($_COOKIE['id'])
>> Это неправильно и вызовет ошибку, если в массиве нет ключа 'id'.
> Хм, никаких ошибок в логах.
Вот пример, показывающий ошибку: http://ideone.com/bMeVWL

Возможно у тебя в php.ini включено игнорирование ошибок с помощью настройки error_reporting (зачем так делать??) или отключено их логгирование. Или у тебя всегда есть эта кука.

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

> Я так и не понял, как сделать так, чтобы браузер при ошибках показывал суть ошибки. Ну или хотя бы стандартные коды. Так что просто заменил все редиректы на header("Location: login.php");
Ты выводишь HTTP заголовок, затем тело страницы. Что тут сложного?

header("HTTP/1.0 500 Internal Error");
echo "Everything is broken, sorry\n";
die();

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

> Выделил папку core, в неё перенёс все НЕ публичные пхп, шаблоны и закачиваемые фотографии. Но как закрыть её, не понимаю.
У сервера есть такая настройка, как "корневая папка" (в Апаче она называется document root, в нгинксе root). Ты создаешь у себя папку public и в настройках веб-севрера прописываешь путь к ней как document root, например в Апаче:

DocumentRoot /var/www/example.com/public/

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

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

$guards = getGuardsList();
// подключаем шаблон
require 'templates/guards.phtml';

В шаблоне формируешь и выводишь HTML страницу:

<?php require __DIR__ . '/header.php'; ?>

<h1>Охранники</h1>
<ul>
<?php foreach ($guards as $guard): ?>
<li><?= htmlspecialchars($guard['name']) ?></li>
<?php endforeach ?>
</ul>

<?php require __DIR__ . '/footer.php'; ?>

> https://github.com/tsubaku/flights/blob/master/core/php/functions.php#L224
> unset($row_content); // разорвать ссылку на последний элемент
Эта строчка вообще смысла не несет, так как она стоит в конце функции, а все локальные переменную удаляются при выходе из функции.

Вот еще проблемное место:

> function showTable($year, $month)
> ...
> $stmt = $pdo->query('INSERT INTO flights () VALUES()'); //Добавляем пустую строку
Функция вывода таблицы не должна ее модифицировать.

> https://github.com/tsubaku/flights/blob/master/core/php/write_in_table.php
Тут нечитаемая стена кода, надо выносить из нее отдельные функции.

> Вопрос про функцию showTable()
> Да, функция монструозная. Я не знаю, как её изменить, ведь приходится обрабатывать каждую ячейку таблицы и обрабатывать дня неё данные, которые она содержит, и правила их отображения.
Сначала нужно разделить получение данных и их вывод. Сначала получаем все данные из БД, только потом выводим.

При этом часть кода можно выносить в отдельные функции. Вот например вначале идет кусок лапши, получающий список рейсов между 2 датами. Его легко вынести в отдельную функцию:

$flights = getFlightsInRange($fromDate, $toDate);

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

Точно так же можно вынести например получение списка охранников (getGuardList()), получение названия месяца по номеру (getMonthName()), и тд.

После того, как все данные выбраны в переменные, вызываем шаблон для вывода HTML кода.

HTML код выводить, как у тебя, с помощью echo, очень неудобно и неэффективно.

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

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

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

Соответственно, сейчас тебе надо работать над разделением:

- вынести весь HTML код в шаблоны
- вынести весь SQL-код в функции в отдельном файле или файлах, то есть сделать отдельный слой доступа к базе данных, а не размазывать это по всему коду

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

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

12 июля, 17:26 #125 #1021991

>>1021978
>https://github.com/tsubaku/flights/blob/master/login.php
>Тут нужно убрать самый первый отступ (после <?php), то есть строка require_once('./core/php/functions.php'); идет без отступа. Для отступов лучше использовать 4 пробела, а не таб.
Блин, про manager.php, index.php, guard.php и login.php я забыл. Сделаю.
>https://github.com/tsubaku/flights/blob/master/core/php/submit.php
>Тут отступы вообще разные. Почему отступ в строке 22 - 8 пробелов? должно быть 4. И почему там так много пустых строк? Пока что плохо.
Хм, submit.php тоже забыл. Странно. Вроде я все файлы по очереди переформатировал.
>Код можно форматировать автоматически, через сайт или IDE, вот ссылка https://gist.github.com/codedokode/8759492
Через него и делал.
>То есть нелогично функцию вывода JSON разделять на 2 части и разбрасывать их в разные места кода.
Не понял. Там же только одна команда вывода json. В каком смысле "разбивать на 2 части"?
>Кстати, тут тоже нелогично:
>https://github.com/tsubaku/flights/blob/master/core/php/show_list_clients.php
>В заголовках указан тип text/plain, а затем идет вывод HTML кода.
А html - это не text/plain?
>И еще, у тебя по прежнему остается проблема копипасты. Например антикеширующие заголовки ты копипастишь из файла в файл, а надо сделать функцию с понятным названием и вызывать ее. Копипаста это плохо, от нее надо избавляться.
Хорошо, функцию сделаю. Но вот именно проблему копипасты не понимаю. Если что-то работает, и работает правильно, то как это переписывать?
>Но браузер может там указать что угодно. Надежднее проверить расширение.
Я гуглил на эту тему и когда кто-то в похожей ситуации делал проверку по расширению, ему так же указывали, что "клиент может послать что угодно, надёжнее проверять по типу". Олсо, не всё ли равно? Законопослушный юзер отправить jpg под видом jpg и всё будет нормально. А незаконопослушный отправит какую-нибудь НЁХ, но сервер переименует её в jpg и при обращении просто не откроет.
>>1021978
>Возможно у тебя в php.ini включено игнорирование ошибок с помощью настройки error_reporting (зачем так делать??) или отключено их логгирование. Или у тебя всегда есть эта кука.
Не включено. Я вручную удалял из браузера куки, ошибок не было, браузер корректно перенаправлял на страницу логина.
>Очевидно же, что у страниц в твоем проекте будут общая шапка, и может быть, подвал.
Но они не одинаковые. В шапке подключаются разные скрипты, выводится разные title, у охранника там дополнительно прописывается срока для мобильных устройств.
>Ты выводишь HTTP заголовок, затем тело страницы. Что тут сложного?
>Я вообще не понимаю, что сложного так сделать и зачем тут понадобился редирект.
А, так это пишется вручную. Теперь понятно. А редирект для удобства юзера.
>и в настройках веб-севрера прописываешь путь к ней как document root, например в Апаче:
У меня нет доступа к настройкам сервера. Вернее, на локалхосте есть, а вот на продакшене всё крутится у хостера (там всего-то статичный сайт нашей конторы, а этот сервис я делаю как бы его подсистемой).
Я посмотрю, как там это устроено.
>Элементарно это делается. В скрипте-контроллере ты подготавливаешь данные:
Я попробую.
> unset($row_content); // разорвать ссылку на последний элемент
>Эта строчка вообще смысла не несет
Блин, точно.
> function showTable($year, $month)
> ...
> $stmt = $pdo->query('INSERT INTO flights () VALUES()'); //Добавляем пустую строку
>Функция вывода таблицы не должна ее модифицировать.
Ну, в общем, да. Я тоже думал вынести скрипт добавления строки в отдельную функцию, а потом вызывать её, но вызывать-то всё равно придётся. Если в указанном месяце нет ни одного рейса, то должна втоматически создаваться пустая строка для нового рейса и после этого показываться таблица, состоящая из пустой строки.
> https://github.com/tsubaku/flights/blob/master/core/php/write_in_table.php
>Тут нечитаемая стена кода, надо выносить из нее отдельные функции.
Большая часть стены - case. В зависимости от того, куда вставлены данные, скрипт должен либо просто их прописать в базу, либо пересчитать связанные с этой ячейкой другие ячейки строки. Разделить на функции, конечно, можно, и я сделаю, раз так надо.

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

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

12 июля, 17:26 #125 #1021991

>>1021978
>https://github.com/tsubaku/flights/blob/master/login.php
>Тут нужно убрать самый первый отступ (после <?php), то есть строка require_once('./core/php/functions.php'); идет без отступа. Для отступов лучше использовать 4 пробела, а не таб.
Блин, про manager.php, index.php, guard.php и login.php я забыл. Сделаю.
>https://github.com/tsubaku/flights/blob/master/core/php/submit.php
>Тут отступы вообще разные. Почему отступ в строке 22 - 8 пробелов? должно быть 4. И почему там так много пустых строк? Пока что плохо.
Хм, submit.php тоже забыл. Странно. Вроде я все файлы по очереди переформатировал.
>Код можно форматировать автоматически, через сайт или IDE, вот ссылка https://gist.github.com/codedokode/8759492
Через него и делал.
>То есть нелогично функцию вывода JSON разделять на 2 части и разбрасывать их в разные места кода.
Не понял. Там же только одна команда вывода json. В каком смысле "разбивать на 2 части"?
>Кстати, тут тоже нелогично:
>https://github.com/tsubaku/flights/blob/master/core/php/show_list_clients.php
>В заголовках указан тип text/plain, а затем идет вывод HTML кода.
А html - это не text/plain?
>И еще, у тебя по прежнему остается проблема копипасты. Например антикеширующие заголовки ты копипастишь из файла в файл, а надо сделать функцию с понятным названием и вызывать ее. Копипаста это плохо, от нее надо избавляться.
Хорошо, функцию сделаю. Но вот именно проблему копипасты не понимаю. Если что-то работает, и работает правильно, то как это переписывать?
>Но браузер может там указать что угодно. Надежднее проверить расширение.
Я гуглил на эту тему и когда кто-то в похожей ситуации делал проверку по расширению, ему так же указывали, что "клиент может послать что угодно, надёжнее проверять по типу". Олсо, не всё ли равно? Законопослушный юзер отправить jpg под видом jpg и всё будет нормально. А незаконопослушный отправит какую-нибудь НЁХ, но сервер переименует её в jpg и при обращении просто не откроет.
>>1021978
>Возможно у тебя в php.ini включено игнорирование ошибок с помощью настройки error_reporting (зачем так делать??) или отключено их логгирование. Или у тебя всегда есть эта кука.
Не включено. Я вручную удалял из браузера куки, ошибок не было, браузер корректно перенаправлял на страницу логина.
>Очевидно же, что у страниц в твоем проекте будут общая шапка, и может быть, подвал.
Но они не одинаковые. В шапке подключаются разные скрипты, выводится разные title, у охранника там дополнительно прописывается срока для мобильных устройств.
>Ты выводишь HTTP заголовок, затем тело страницы. Что тут сложного?
>Я вообще не понимаю, что сложного так сделать и зачем тут понадобился редирект.
А, так это пишется вручную. Теперь понятно. А редирект для удобства юзера.
>и в настройках веб-севрера прописываешь путь к ней как document root, например в Апаче:
У меня нет доступа к настройкам сервера. Вернее, на локалхосте есть, а вот на продакшене всё крутится у хостера (там всего-то статичный сайт нашей конторы, а этот сервис я делаю как бы его подсистемой).
Я посмотрю, как там это устроено.
>Элементарно это делается. В скрипте-контроллере ты подготавливаешь данные:
Я попробую.
> unset($row_content); // разорвать ссылку на последний элемент
>Эта строчка вообще смысла не несет
Блин, точно.
> function showTable($year, $month)
> ...
> $stmt = $pdo->query('INSERT INTO flights () VALUES()'); //Добавляем пустую строку
>Функция вывода таблицы не должна ее модифицировать.
Ну, в общем, да. Я тоже думал вынести скрипт добавления строки в отдельную функцию, а потом вызывать её, но вызывать-то всё равно придётся. Если в указанном месяце нет ни одного рейса, то должна втоматически создаваться пустая строка для нового рейса и после этого показываться таблица, состоящая из пустой строки.
> https://github.com/tsubaku/flights/blob/master/core/php/write_in_table.php
>Тут нечитаемая стена кода, надо выносить из нее отдельные функции.
Большая часть стены - case. В зависимости от того, куда вставлены данные, скрипт должен либо просто их прописать в базу, либо пересчитать связанные с этой ячейкой другие ячейки строки. Разделить на функции, конечно, можно, и я сделаю, раз так надо.

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

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

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

12 июля, 17:43 #126 #1021998

>>1021975
>оперативными хранилищами, серверами очереди
шо это за хуйня?

Ответы22011

12 июля, 18:11 #127 #1022009

>>1021099

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

> try { }
> catch (\Exception $e) {
> Yii::warning($e->getMessage());
> return $this->redirect(Yii::$app->request->referrer);

Что за бред? В приложении происходит ошибка, и ты просто редиректишь на referer (а кстати, что если он пустой?). При ошибке надо вывести страницу ошибки, а не скрывать этот факт. Это ведь тебе самому потом усложнит поиск причин.

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

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

Вот простой пример, чем плох твой код. У тебя есть действие контроллера для рассылки сообщений actionMassSend(). Но что, если нам понадобится вызвать это действие где-то программно? У тебя нет функции вроде sendMassMessage($message, $users) и нам придется писать код заново. Ты не почему-то не додумался вынести это действие в отдельную функцию, а вписал в контроллер, перемешав с кодом получения данные из формы и кодом отдачи ответа пользователю.

>>1021061

Спасибо, сайтгайд хороший.

>>1021030

> Изменение номера - https://ideone.com/KJxmSg
Ок, верно

> Автозамена - https://ideone.com/LaOqC8
Ок, тоже верно

> Вывод email - https://ideone.com/NCD54g
Не найдется email i[|JvanANUS0sqi2PUNCTUMcX,#om

> Grammar Nazi - https://ideone.com/BR95EM

Эти однотипные строки надо объединить в одну регулярку:
$text = preg_replace('/[,](\\S)/ui', ', $1', $text);
$text = preg_replace('/[;](\\S)/ui', '; $1', $text);
$text = preg_replace('/[!](\\S)/ui', '! $1', $text);

И эти объединить:
> $text = preg_replace('/жы/ui','жи', $text);
> $text = preg_replace('/шы/ui','ши', $text);

> $text = preg_replace('/(\\S) а /', '$1, а ', $text);
Нужно еще правило для "но"

12 июля, 18:11 #127 #1022009

>>1021099

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

> try { }
> catch (\Exception $e) {
> Yii::warning($e->getMessage());
> return $this->redirect(Yii::$app->request->referrer);

Что за бред? В приложении происходит ошибка, и ты просто редиректишь на referer (а кстати, что если он пустой?). При ошибке надо вывести страницу ошибки, а не скрывать этот факт. Это ведь тебе самому потом усложнит поиск причин.

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

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

Вот простой пример, чем плох твой код. У тебя есть действие контроллера для рассылки сообщений actionMassSend(). Но что, если нам понадобится вызвать это действие где-то программно? У тебя нет функции вроде sendMassMessage($message, $users) и нам придется писать код заново. Ты не почему-то не додумался вынести это действие в отдельную функцию, а вписал в контроллер, перемешав с кодом получения данные из формы и кодом отдачи ответа пользователю.

>>1021061

Спасибо, сайтгайд хороший.

>>1021030

> Изменение номера - https://ideone.com/KJxmSg
Ок, верно

> Автозамена - https://ideone.com/LaOqC8
Ок, тоже верно

> Вывод email - https://ideone.com/NCD54g
Не найдется email i[|JvanANUS0sqi2PUNCTUMcX,#om

> Grammar Nazi - https://ideone.com/BR95EM

Эти однотипные строки надо объединить в одну регулярку:
$text = preg_replace('/[,](\\S)/ui', ', $1', $text);
$text = preg_replace('/[;](\\S)/ui', '; $1', $text);
$text = preg_replace('/[!](\\S)/ui', '! $1', $text);

И эти объединить:
> $text = preg_replace('/жы/ui','жи', $text);
> $text = preg_replace('/шы/ui','ши', $text);

> $text = preg_replace('/(\\S) а /', '$1, а ', $text);
Нужно еще правило для "но"

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

12 июля, 18:11 #128 #1022010

>>1021023

> Можешь объяснить, чем плохи чистые функции, зачем городить эти Utility service?
Я думаю, ради DI, если тебе нужна ссылка на другой сервис, то надо использовать DI. Если не нужна, можно наверно и обычные функции.

>>1020161

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

>>1020741

Какая версия дистрибутива? И почему версия PHP какая-то левая, что еще за blackfire? ты каких-то странных патчей туда наустанавливал, возможно в этом проблема?

Что значит "все ломается"

Из твоего поста ничего понять нельзя.

>>1020506

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

Ну и она не на русском.

А ты видел это? https://github.com/codedokode/task-checker

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

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

>>1020356

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

12 июля, 18:11 #128 #1022010

>>1021023

> Можешь объяснить, чем плохи чистые функции, зачем городить эти Utility service?
Я думаю, ради DI, если тебе нужна ссылка на другой сервис, то надо использовать DI. Если не нужна, можно наверно и обычные функции.

>>1020161

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

>>1020741

Какая версия дистрибутива? И почему версия PHP какая-то левая, что еще за blackfire? ты каких-то странных патчей туда наустанавливал, возможно в этом проблема?

Что значит "все ломается"

Из твоего поста ничего понять нельзя.

>>1020506

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

Ну и она не на русском.

А ты видел это? https://github.com/codedokode/task-checker

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

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

>>1020356

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

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

12 июля, 18:11 #129 #1022011

>>1021991

> Не понял. Там же только одна команда вывода json. В каком смысле "разбивать на 2 части"?
Вывод JSON ответа состоит из 2 действий:

- добавить заголовок Content-Type с значением application/json
- вывести тело ответа (JSON код)

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

> А html - это не text/plain?
Это text/html: https://ru.wikipedia.org/wiki/Список_MIME-типов

text/plain значит "обычный текст без тегов и форматрования". Браузер отобразит его просто черным текстом на белов фоне как есть.

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

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

Также, в плане чтения кода строка

setNoCacheHeaders();

гораздо понятнее и читабельнее чем 2 строки с header.

> Я гуглил на эту тему и когда кто-то в похожей ситуации делал проверку по расширению, ему так же указывали, что "клиент может послать что угодно, надёжнее проверять по типу
Имя файла присылается всегда, а где гарантия, что браузер правильно определит и пришлет тип? У тебя есть информация, какие типы файлов какой браузер "знает", а какие нет? У меня нет такой информации например. Никто не запрещает прислать браузеру тип application/octet-stream например.

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

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

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

Как костыль ты можешь попробовать загружать свой код на 1 папку выше корня сайта на сервере.

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

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

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

>>1021998

видимо redis/rabbitmq

12 июля, 18:11 #129 #1022011

>>1021991

> Не понял. Там же только одна команда вывода json. В каком смысле "разбивать на 2 части"?
Вывод JSON ответа состоит из 2 действий:

- добавить заголовок Content-Type с значением application/json
- вывести тело ответа (JSON код)

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

> А html - это не text/plain?
Это text/html: https://ru.wikipedia.org/wiki/Список_MIME-типов

text/plain значит "обычный текст без тегов и форматрования". Браузер отобразит его просто черным текстом на белов фоне как есть.

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

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

Также, в плане чтения кода строка

setNoCacheHeaders();

гораздо понятнее и читабельнее чем 2 строки с header.

> Я гуглил на эту тему и когда кто-то в похожей ситуации делал проверку по расширению, ему так же указывали, что "клиент может послать что угодно, надёжнее проверять по типу
Имя файла присылается всегда, а где гарантия, что браузер правильно определит и пришлет тип? У тебя есть информация, какие типы файлов какой браузер "знает", а какие нет? У меня нет такой информации например. Никто не запрещает прислать браузеру тип application/octet-stream например.

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

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

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

Как костыль ты можешь попробовать загружать свой код на 1 папку выше корня сайта на сервере.

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

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

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

>>1021998

видимо redis/rabbitmq

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

12 июля, 19:27 #130 #1022062

>>1021821
>Что за нестандартный стиль названий функций? PSR рекомендует camelCase для методов:

Думал что стиль названия для всего один. А оказывается для всего разные. fixed

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

А нормально что он будет в функции которая не в классе, а сама по себе?

>Гораздо аккуратнее будет если Компания будет заведовать списком департаментов, а специфичные вещи вроде "найти и уволить 40% рабочих" будут в отдельном классе для антикризисных мер.

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

>Имена функций начинаются с глаголов, сделатьЧтоТо

Заменил на destroy. А как я понимаю этот глагол пишется с маленькой буквы.

>> public function get_Workers_And_Destruction($count_in_percent,$proffesion)
>Тут функция просто создана методом копирования кода. Так не годится. Нужно убрать повторяющийся код.

Как я понял это про копирование foreach 3 раза. Сделал адекватно.

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

Добавил метод для поштучного добавления и для массива с кучей рабочих.

>Гораздо аккуратнее будет если Компания будет заведовать списком департаментов, а специфичные вещи вроде "найти и уволить 40% рабочих" будут в отдельном классе для антикризисных мер.

Я сделал отдельный класс. В нем функцию. и дальше если я пытаюсь эту фунецию на компанию использовать то ошибка. Не понимаю как сделать.

Есть еще вопрос насчет того что все переменные в классах закрыты и из за этого приходится делать кучу функций геттеров и сеттеров. Это нормально так делать? Всегда так надо делать? Почему бы не сделать все паблик и тогда код сократится в 2-3 раза, потому что не будет этих бесполезных функций getRank и тд.

Еще вопрос что плохого в классе монстре. Хочешь использовать функцию или сделать. Через поиск проверяешь нет ли такой и используешь/делаешь.

12 июля, 19:27 #130 #1022062

>>1021821
>Что за нестандартный стиль названий функций? PSR рекомендует camelCase для методов:

Думал что стиль названия для всего один. А оказывается для всего разные. fixed

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

А нормально что он будет в функции которая не в классе, а сама по себе?

>Гораздо аккуратнее будет если Компания будет заведовать списком департаментов, а специфичные вещи вроде "найти и уволить 40% рабочих" будут в отдельном классе для антикризисных мер.

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

>Имена функций начинаются с глаголов, сделатьЧтоТо

Заменил на destroy. А как я понимаю этот глагол пишется с маленькой буквы.

>> public function get_Workers_And_Destruction($count_in_percent,$proffesion)
>Тут функция просто создана методом копирования кода. Так не годится. Нужно убрать повторяющийся код.

Как я понял это про копирование foreach 3 раза. Сделал адекватно.

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

Добавил метод для поштучного добавления и для массива с кучей рабочих.

>Гораздо аккуратнее будет если Компания будет заведовать списком департаментов, а специфичные вещи вроде "найти и уволить 40% рабочих" будут в отдельном классе для антикризисных мер.

Я сделал отдельный класс. В нем функцию. и дальше если я пытаюсь эту фунецию на компанию использовать то ошибка. Не понимаю как сделать.

Есть еще вопрос насчет того что все переменные в классах закрыты и из за этого приходится делать кучу функций геттеров и сеттеров. Это нормально так делать? Всегда так надо делать? Почему бы не сделать все паблик и тогда код сократится в 2-3 раза, потому что не будет этих бесполезных функций getRank и тд.

Еще вопрос что плохого в классе монстре. Хочешь использовать функцию или сделать. Через поиск проверяешь нет ли такой и используешь/делаешь.

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

12 июля, 19:50 #131 #1022071

>>1022062
забыл код приложить
http://ideone.com/Vt2gpt

12 июля, 22:37 #132 #1022173

>>1019301 (OP)
Всем привет. Застрял в самом начале :с
Вот код:

1) <?php
2)
3) error_reporting(-1)
4)
5) echo "Бросаем кубик... \n";
6) $random = mt_rand(1,6) ;
echo "Выпало $random\n";

Выдает ошибку:
PHP Parse error: syntax error, unexpected 'echo' (T_ECHO) in /home/jZlt7x/prog.php on line 4

Я так понимаю у меня что-то не так с кавычками, а что сними не так? Или что не так?

Ответы22181

12 июля, 22:49 #133 #1022181

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

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

Ответы23903

12 июля, 22:52 #134 #1022184

объясните дауну как решить задачу с сайта для начинающих из оп поста
http://codepad.org/nm9jPcpd
перебрал дохуа вариантов, боюсь окончательно ебанутся

Ответы22265

12 июля, 23:15 #135 #1022194

>>1022009
>При ошибке надо вывести страницу ошибки
Ну она ругается в лог, а пользователю об это знать и не обязательно, хотя я наверное хотел проставлять там flash message ибо просто редирект это хрень конечно
Это единственная ошибка с исключениями?
> типичный толстый контроллер
Об этом я тоже думал, но я хз, как оценивают код и что там хотят увидеть те люди которые его просят ("Контроллер строк на 300, максимально написанных вами")
Вот я и запихнул туда этот метод, а то в контролере только вызовы сервисов и методов моделей и будут.
Или они хотят видеть патернизацию всего, а логика не так важна...
Увы у меня особо нет времени запилить годный большой резюме-проект, а на текущей работе говнокод и суровая реальность

Ответы22273

12 июля, 23:45 #136 #1022210

>>1022010
>Какая версия дистрибутива? И почему версия PHP какая-то левая, что еще за blackfire? ты каких-то странных патчей туда наустанавливал, возможно в этом проблема?
Что значит "все ломается"
Из твоего поста ничего понять нельзя.

это версия пхп, который в коробке хомстед в вагранте скрин с терминала под ссх, там все настроено и установлено заранее, в этом и понт этого вагранта. а вот мкрипта нет. устанавливаю туда, по ссх мкрипт и вылазит при просмотре в браузере: No input file specified везде

13 июля, 01:13 #137 #1022265

>>1022184
https://ideone.com/waKUEZ

Ответы23888

13 июля, 01:51 #138 #1022273

>>1022194
>Или они хотят видеть патернизацию всего, а логика не так важна...
this

13 июля, 05:54 #139 #1022830

Но за большее количество раз и при этом
смотреть на нее

13 июля, 05:58 #140 #1023120

Рассердился на такое дело царевич, и как даст ему крапивой по правому яйцу!

13 июля, 09:04 #141 #1023888

>>1022265
спасибо,один в один делал так же, видимо ебаный синтаксис

Ответы23904

13 июля, 09:48 #142 #1023903

>>1022181
Спасибо за ответ :)

13 июля, 09:49 #143 #1023904

>>1023888
я тоже тупил на этом месте чето
это математика, а не синтаксис, лол
выплатил 60000 = $paymentTotal
тебе нужно отдать 1270 = $creditBalance
ты отдаешь 5к $paymentTotal = 65k
долг $creditBalance = -3630
if ($creditBalance < 0)
тебе дают сдачу
$paymentTotal= $paymentTotal + $creditBalance;

Ответы23912

13 июля, 09:56 #144 #1023912

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

13 июля, 11:02 #145 #1023957

антоны есть какой-нибудь изи способ добавлять записи с какого-нибудь фейсбука\да и вообще любого сайта к себе на через пхп+мускл?
тупо в текстовом варианте
какие вообще есть способы для этого?

Ответы23987

13 июля, 11:56 #146 #1023987

>>1023957
С фейсбука ты можешь воспользоваться их API, благо у них неплохая документация с Explorer'ом.

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

13 июля, 14:21 #147 #1024084

я не смог осилить пхп...

Ответы24090

13 июля, 14:34 #148 #1024090

>>1024084
Я осилил php, когда мне было 11. Сейчас мне 26.
Тебе 10?

Ответы2409424104

13 июля, 14:47 #149 #1024094

>>1024090
24

13 июля, 15:01 #150 #1024104

>>1024090
А когда мне было десять лет ПХП еще не изобрели и программировать я мол разве что на БЭСМ

13 июля, 15:02 #151 #1024105

какая разница между передачей по значению и по ссылке?

Ответы24114

13 июля, 15:11 #152 #1024114

>>1024105
https://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value

13 июля, 16:47 #153 #1024189

Кто-нибудь использует в продакшене?

https://github.com/nikic/scalar_objects

Ответы24652

13 июля, 16:49 #154 #1024192

Господа, как сделать, чтобы strpos работало под кириллицей?
<?
$what="буквы";
$where="здесь буквы кириллицы";
echo mb_strpos($where, $what, 0, 'UTF-8');
?>
Этот код не хочет работать. PHP 7.

Ответы2420024202

13 июля, 17:17 #155 #1024200

>>1024192
><?
>$what="буквы";
>$where="здесь буквы кириллицы";
>echo mb_strpos($where, $what, 0, 'UTF-8');
>?>

Попробуй

<?php
$what="буквы";
$where="здесь буквы кириллицы";
echo mb_strpos($where, $what, 0, 'UTF-8');

Ответы24205

13 июля, 17:20 #156 #1024202

>>1024192

Если на ideone, то там не поддерживаются mb-функции, ищи другой сервис выполнения PHP кода.

Ответы24205

13 июля, 17:23 #157 #1024205

>>1024202
>>1024200
Не работает.
Я на своем сервере запускаю, не ideone.
Может надо как-то настроить php-fpm?

Ответы24211

13 июля, 17:33 #158 #1024211

>>1024205

В чем проявляется "не работает"? Ошибка какая-то пишется или что? Что в логах? Установлено ли расширение mbstring (можно посмотреть в phpinfo())?

Ответы24219

13 июля, 17:45 #159 #1024217

фреймворки ставятся только на линукс?

Ответы24231

13 июля, 17:52 #160 #1024219

>>1024211
FastCGI sent in stderr: "PHP message: PHP Fatal error: Uncaught Error: Call to undefined function mb_strpos() in /var/www/html/test.php:38

И где там посмотреть установлено ли оно? Ввел в поиск ctrf-f - не нашло mbstring.
У меня чистый php-fm на убунте. Как установить mbstring?

Ответы24248

13 июля, 18:19 #161 #1024231

>>1024217
Только на macOS. Для установки необходимо смузи

13 июля, 18:30 #162 #1024242

изучаю пхп по этому курсу
https://www.w3schools.com/php/default.asp

Ответы24244

13 июля, 18:34 #163 #1024244

>>1024242
Этого должно хватить http://php.net/manual/en/langref.php

Ответы24247

13 июля, 18:40 #164 #1024247

>>1024244
знаю.но он у меня тяжелее пошел

Ответы24255

13 июля, 18:41 #165 #1024248

>>1024219

Посмотреть с помощью php -m или функции phpinfo()

Установить так:

apt-cache search php

найти там mbstring и установить с помощью sudo apt-get install

Ответы24253

13 июля, 18:53 #166 #1024253

>>1024248
Спасибо, установил через
sudo apt-get install php7.0-mbstring
Всё заработало.

13 июля, 18:56 #167 #1024255

>>1024247
От твоего учебника у тебя только мусор в голове останется.
w3schools не объясняет такие базовые вещи как
foreach ($arr as &$value) {
$value = $value * 2;
}
обрати внимание на амперсанд перед $value

Не говоря про темы, которые ты пропустишь, например:

http://php.net/manual/ru/language.oop5.autoload.php
http://php.net/manual/ru/language.namespaces.php
http://php.net/manual/ru/language.oop5.late-static-bindings.php

Ответы24266

13 июля, 19:08 #168 #1024266

>>1024255
так этот курс не претендует на объемное изучение.но для быстрой базы самый раз

Ответы24278

13 июля, 19:21 #169 #1024278

>>1024266
Базы для чего? Для натягивания шаблонов на вордпресс - возможно. Для уверенного пользования современными PSR фреймворками - нет не достаточно. Да и вообще, как я указал в начале, w3schools не дает правильного понимания php. Официальная документация методически правильно излагает материал от простого к сложному.

Ответы24293

13 июля, 19:35 #170 #1024293

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

13 июля, 19:48 #171 #1024308

как в ХAMPP вручную через консоль, командами работать с БД?

13 июля, 20:17 #172 #1024337

<input type="hidden" name="the_checkbox" value="0" />
<input type="checkbox" name="the_checkbox" value="1" />

Можно ли писать такой код чтобы потом удобнее обрабатывать было в php форму? А то isset'ом проверять не очень как-то.

13 июля, 21:31 #173 #1024423

>Сколько времени надо изучать все это? - все зависит от тебя, но не меньше 6-8 месяцев
Это ебаша по пять часов в день? Сколько мне понадобится времени, если уделять по два часа в день, чтобы достигнуть такого уровня, чтобы взяли на работу хотя бы "за еду"?

Зачачи 13 июля, 22:40 #174 #1024516

ОП, проверь задачи, пожалуйста

На словах ты Лев Толстой - https://ideone.com/S7Xrez
Поиск email - https://ideone.com/d2N8d6
Grammar Nazi - https://ideone.com/925aB2
Опечаточник - https://ideone.com/mpNbLd

Ответы2455525479

13 июля, 23:22 #175 #1024555

>>1024516
>Опечаточник - https://ideone.com/mpNbLd

если в слове больше 1 енг буквы. то не показывает остальные

Ответы24989

13 июля, 23:35 #176 #1024561

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

Ответы25469

14 июля, 06:37 #177 #1024652

>>1024189
БАМП

14 июля, 15:23 #178 #1024904

>>1022062
с антикризисными мерами
http://ideone.com/gap02Z

Ответы25469

14 июля, 15:29 #179 #1024908

Почему symfony3 запущенный в dev моде работает с очень большой задержкой. Запускал на был в build-in сервере и на nginx+fpm

Ответы25319

14 июля, 17:48 #180 #1024989

>>1024555
Так в задании написано "выделяет квадратными скобками первую замененную букву". Разве нужно остальные выделят?

14 июля, 23:00 #181 #1025212

Аноны, посоветуйте пожалуйста идеи для портфолио на гитхаб. Я только только выучил основы ооп php, хочу че нибудь сделать, что бы потом показать на собеседовании на стажера, но вобще ни одной мысли. Хелп!

Ответы2524725319

14 июля, 23:54 #182 #1025247

>>1025212
Та же хуйня. Взялся делать хайп, мимо из прошлого треда

Ответы25319

15 июля, 00:35 #183 #1025277

>>1022011
Я после твоих последних постов так и не смог найти силы переписывать программу. Руки опустились.

Ответы2529925479

15 июля, 01:01 #184 #1025299

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

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

Ответы25304

15 июля, 01:06 #185 #1025304

>>1025299
Ценю. Реально дотошный разбор ошибок (это положительная оценка, если что).

Ответы25305

15 июля, 01:07 #186 #1025305

>>1025304
Так делай, если не хочешь чтобы оно было потрачено зря.

15 июля, 03:09 #187 #1025319

>>1025212
>>1025247

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

>>1024908

Ну, если у сайта один пользователь то особой разницы между fpm и built-in сервером и нет.

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

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

Стоит помнить только, что включение отладки повлияет на код и он будет работать еще медленнее.

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

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

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

Я тебе советую сделать какой-то тестовый контроллер, который просто выводит hello world, чтобы исключить проблемы в твоем коде.

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

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

15 июля, 03:09 #187 #1025319

>>1025212
>>1025247

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

>>1024908

Ну, если у сайта один пользователь то особой разницы между fpm и built-in сервером и нет.

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

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

Стоит помнить только, что включение отладки повлияет на код и он будет работать еще медленнее.

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

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

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

Я тебе советую сделать какой-то тестовый контроллер, который просто выводит hello world, чтобы исключить проблемы в твоем коде.

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

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

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

15 июля, 12:37 #188 #1025359

53 Кб, 820x683

37 Кб, 726x185

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

Ответы2536125394

15 июля, 12:38 #189 #1025361

>>1025359
add
https://ideone.com/F8zpHo

Ответы25394

CSS Animation goes back slower than forward. A html class toggles with delay. 15 июля, 12:51 #190 #1025364

Hello,
I did a roll up/down menu with CSS transitions. It's based on toggling classes with different "max-height". Very simple case, but it doesn't work in a way I expect it to.

The problem is: the menu goes back only after a certain delay, (which is depends on an animation time). Maybe something wrong with my JS, bc it seems like the browser toggles the class with delay (and only then the animation fires).

Here's codepen. You click to open it - it rolls down fast, you click to close it - it waits 2 seconds and only then rolls down: https://codepen.io/anon/pen/dRrwQB

Ответы254232543225478

15 июля, 14:11 #191 #1025391

>Нихуя не понял генераторы
>первая же js задача ввела ступор
дайте решение.

Ответы2541925477

15 июля, 14:27 #192 #1025394

>>1025359
>>1025361
Неактуально

15 июля, 15:46 #193 #1025419

>>1025391
Там не нужно использовать ES6 генераторы, если ты о них. Достаточно написать функцию, возвращающую функцию, которая в свою очередь инкрементирует и возвращает значение из замыкания. Почитай learn.javascript.ru

Ответы25428

15 июля, 15:54 #194 #1025423

>>1025364
transition: cubic-bezier(0.17, 0.04, 0.03, 0.94);

15 июля, 16:08 #195 #1025428

>>1025419
В итоге это сделал

50 Кб, 843x202

15 июля, 16:10 #196 #1025430

Что ему не нравится-то?

100 $key = $_POST['key'];
101 $query="SELECT * FROM posts WHERE text LIKE '$key' OR WHERE title LIKE '$key' ORDER BY id DESC";
102 $result=$pdo->query($query)or die("Запрос не выполнен");

Ответы254332544025477

15 июля, 16:10 #197 #1025432

>>1025364
стыдно за тебя

15 июля, 16:12 #198 #1025433

>>1025430
>Что ему не нравится-то?
102я строка

Ответы2543425452

15 июля, 16:14 #199 #1025434

>>1025433
Очень информативно. Обращаю внимание, что в посте указана 102-я строка.

15 июля, 16:29 #200 #1025440

>>1025430
У тебя 2 раза WHERE в запросе. Пиши так: "WHERE text LIKE :key OR title LIKE :key"

Ещё у тебя SQL-инъекция в коде (исправляй срочно) и дурацкий вызов die после $pdo->query
Читай пасты ОПа:
https://github.com/codedokode/pasta/blob/master/student-list.md#Работа-с-базой-данных-из-php
https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

Ответы25446

15 июля, 16:56 #201 #1025446

>>1025440
Спасибо, заработало.

Еще вопрос, как вынести подключение к БД за пределы страницы?У меня сейчас код вида
<? соединение с БД ?>
<html>
<? вывод данных из БД?>

но по логике пользователь не должен видеть операции с БД же.

Ответы2545025452

15 июля, 17:02 #202 #1025450

64 Кб, 1280x720

64 Кб, 1280x720

>>1025446
Выбирай 2 стула

Ответы25452

15 июля, 17:08 #203 #1025452

>>1025446
Да, хорошим тоном считается разделять PHP-код от шаблонов: http://web.archive.org/web/20161119062218/http://www.phpinfo.su/articles/practice/shablony_v_php.html
Видно, что ты начинающий и c MVC не знаком, советую почитать/выполнить эту задачу, сам многому научился: https://github.com/codedokode/pasta/blob/master/student-list.md

>>1025450
>>1025433
Зачем вы тут? Не хотите помогать - не засоряйте тред.

15 июля, 18:06 #204 #1025469

>>1024561

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

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

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

>>1024904

> public function addDepartament($departament)
Тут нужен тайп-хинт. Вот короткая копипаста:

--------
### Тайп хинты

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

Мануал: http://php.net/manual/ru/language.oop5.typehinting.php

Обрати внимание, что php7 усовершенствовал систему тайп-хинтов - теперь можно в их качестве указывать примитивные типы вроде int/string, а в php7.1 стало можно указывать тайп-хинт для возвращаемого функцией значения: https://habrahabr.ru/post/267799/ , причем можно указать тип void, значащий, что функция ничего не возвращает (увы, возможность вернуть null пока не реализовали, так что ждем)
--------

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

> public function deleteWorker($number)
Вот это неудачно спректированная функция. Чтобы удалить работника, надо узнать его номер в приватном списке внутри департамента. Как его узнать? Надо вместо номера передавать самого работника, которого надо уволить. Объект - это сам по себе уникальный идентификатор.

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

> $is_Head,
Стиль названия не соответствует другим переменным

> public function getSalary($worker)
Зачем сюда передается worker? Он еще и не используется никак.

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

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

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

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

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

Отбор кандидатов на увольнение/повышени лучше сделать так:

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

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

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

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

15 июля, 18:06 #204 #1025469

>>1024561

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

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

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

>>1024904

> public function addDepartament($departament)
Тут нужен тайп-хинт. Вот короткая копипаста:

--------
### Тайп хинты

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

Мануал: http://php.net/manual/ru/language.oop5.typehinting.php

Обрати внимание, что php7 усовершенствовал систему тайп-хинтов - теперь можно в их качестве указывать примитивные типы вроде int/string, а в php7.1 стало можно указывать тайп-хинт для возвращаемого функцией значения: https://habrahabr.ru/post/267799/ , причем можно указать тип void, значащий, что функция ничего не возвращает (увы, возможность вернуть null пока не реализовали, так что ждем)
--------

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

> public function deleteWorker($number)
Вот это неудачно спректированная функция. Чтобы удалить работника, надо узнать его номер в приватном списке внутри департамента. Как его узнать? Надо вместо номера передавать самого работника, которого надо уволить. Объект - это сам по себе уникальный идентификатор.

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

> $is_Head,
Стиль названия не соответствует другим переменным

> public function getSalary($worker)
Зачем сюда передается worker? Он еще и не используется никак.

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

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

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

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

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

Отбор кандидатов на увольнение/повышени лучше сделать так:

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

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

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

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

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

15 июля, 18:20 #205 #1025473

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

Ответы2547425481

15 июля, 18:26 #206 #1025474

>>1025473
> зачем нужен интерфейс Итератор?
Чтобы обходить объект в цикле.

> Реализован ли он в современных фреймах?
Да, любой класс коллекций, например коллекции ошибок валидации в symfony/form, коллекции сущностей в доктрине, коллекции HTTP-заголовков и т.д

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

15 июля, 18:32 #207 #1025477

>>1025430

Вместо or die нужно включить в PDO режим выброса исключений (PDO::ERRMODE_EXCEPTION).

>>1025430

Обрати внимание на текст "right syntax to use near ..." - это значит, что ошибка в указанном месте, то есть лишний WHERE.

>>1025391

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

Test 15 июля, 18:37 #208 #1025478

>>1025364

Posted answer here because of spam filter: https://pastebin.com/4JXyVf0w

Ответы25501

15 июля, 18:38 #209 #1025479

>>1025277

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

>>1024516

> На словах ты Лев Толстой - https://ideone.com/S7Xrez
Ок, верно

> Поиск email - https://ideone.com/d2N8d6
Все правильно

> Grammar Nazi - https://ideone.com/925aB2
> '/[,](\\S)/ui', '/[;](\\S)/ui', '/[!](\\S)/ui'
Эти регулярки очень похожи и их надо объединить в одну. То же касается регулярок с жы/шы и зделал/зделаю

> Опечаточник - https://ideone.com/mpNbLd
Твоя программа просто ищет латинские буквы. Но надо искать слова, составленные из букв разных алфавитов. Слова вроде "HELLO" не должны вызывать ошибку.

15 июля, 18:46 #210 #1025481

>>1025473

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

foreach ($primeIterator as $number) {
echo "Число: $number\b";
}

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

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

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

Я советую изучить список встроенных итераторов: http://php.net/manual/ru/spl.iterators.php

Писать итераторы не очень удобно, удобнее сделать функцию-генератор, которая при вызове возвращает итератор: http://php.net/manual/ru/language.generators.overview.php

15 июля, 19:19 #211 #1025501

>>1025478
Да, проблема была с анимацией была именно в том, что CSS анимирует свойство max-height полностью, т.е несмотря на то, что размеры меню 200px, оно анимирует все 900px.

Ответы25519

15 июля, 19:36 #212 #1025519

>>1025501
Why are you stopped speaking on english? That's weird.

Ответы25558

15 июля, 19:48 #213 #1025530

В файлообменнике сущность файл должна агрегировать массив сущностей комментариев? Если да, то класс FileGateway должен агрегировать CommentGateway?

15 июля, 19:58 #214 #1025540

>>1007389
>>>Ну и подсчет высоты сообщений - это явно что-то неправильное. Это нужно для выравнивания сообщений вертикально? Неужели это нельзя было сделать средствами CSS? Задание размеров и расположения элементов через JS работает плохо, может влиять на производительность и работать с задержками.
>> Это нужно сделать отступ сверху, если сообщений слишком мало, и они начинались как бы снизу вверх, а не сверху вниз.
>Это называется "вертикальное выравнивание". Я бы поискал варианты сделать это средствами CSS. Вот что приходит в голову:
>
>- flex, новая технология, которая не везде есть. С ее помощью можно выделить часть экрана под область сообщений, и задать выравнивание блока сообщений по нижнему краю. Ну и не забыть про overflow, чтобы при большом числе сообщений блок не растягивался, а появлялась бы прокрутка. Минус - работает в новых браузерах
>- display: table - работает начиная с ИЕ8 и древних фаерфоксов. Это как flex, только слабее по возможностям и со своими недостатками. Табличное отображение позволяет прижать содержимое ячейки (зоны сообщений) вниз. Тут есть проблемка - чтобы сделать прокрутку, блоку сообщений надо задать высоту, и задать ее в виде 100% (=высоте окна) наверно не получится, значит придется этот момент сделать через JS (определение доступной высоты блока и изменение ее при измнеении размера окна)
>- прижать блок сообщений вниз с помощью абс. поз. Работает тоже везде, и можно задать высоту как 100% от зоны для вывода сообщений (при условии что не используется display: table, так как абс. поз. не работает с элементами таблиц).
>
>Я бы советовал попробовать сделать отдельный пример (примеры) в jsfiddle или аналогичном сервисе, и потестировать его на маленьком и большом числе сообщений (когда должна появляться прокрутка).
>
>Я могу подсказать по CSS, но имея частично работающий код, сделать это проще.
С точки зрения дизайна интерфейса, критично ли будет то, что даже если все сообщения получены, то они всё равно будут прижиматься вниз, оставляя пустое пространство в верху? Я не вижу в этом ничего плохого, но кому-то пустое пространство может показаться не красивым.

https://jsfiddle.net/55khok9f/1/

15 июля, 19:58 #214 #1025540

>>1007389
>>>Ну и подсчет высоты сообщений - это явно что-то неправильное. Это нужно для выравнивания сообщений вертикально? Неужели это нельзя было сделать средствами CSS? Задание размеров и расположения элементов через JS работает плохо, может влиять на производительность и работать с задержками.
>> Это нужно сделать отступ сверху, если сообщений слишком мало, и они начинались как бы снизу вверх, а не сверху вниз.
>Это называется "вертикальное выравнивание". Я бы поискал варианты сделать это средствами CSS. Вот что приходит в голову:
>
>- flex, новая технология, которая не везде есть. С ее помощью можно выделить часть экрана под область сообщений, и задать выравнивание блока сообщений по нижнему краю. Ну и не забыть про overflow, чтобы при большом числе сообщений блок не растягивался, а появлялась бы прокрутка. Минус - работает в новых браузерах
>- display: table - работает начиная с ИЕ8 и древних фаерфоксов. Это как flex, только слабее по возможностям и со своими недостатками. Табличное отображение позволяет прижать содержимое ячейки (зоны сообщений) вниз. Тут есть проблемка - чтобы сделать прокрутку, блоку сообщений надо задать высоту, и задать ее в виде 100% (=высоте окна) наверно не получится, значит придется этот момент сделать через JS (определение доступной высоты блока и изменение ее при измнеении размера окна)
>- прижать блок сообщений вниз с помощью абс. поз. Работает тоже везде, и можно задать высоту как 100% от зоны для вывода сообщений (при условии что не используется display: table, так как абс. поз. не работает с элементами таблиц).
>
>Я бы советовал попробовать сделать отдельный пример (примеры) в jsfiddle или аналогичном сервисе, и потестировать его на маленьком и большом числе сообщений (когда должна появляться прокрутка).
>
>Я могу подсказать по CSS, но имея частично работающий код, сделать это проще.
С точки зрения дизайна интерфейса, критично ли будет то, что даже если все сообщения получены, то они всё равно будут прижиматься вниз, оставляя пустое пространство в верху? Я не вижу в этом ничего плохого, но кому-то пустое пространство может показаться не красивым.

https://jsfiddle.net/55khok9f/1/

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

15 июля, 20:33 #215 #1025558

>>1025519
Просто учусь формулировать предложения на англ. Спасибо за помощь с вопросом.

Ответы2555925560

15 июля, 20:42 #216 #1025559

>>1025558

Зарегистрируйся на Hacker News (новости IT) и участвуй там в дискуссиях.

15 июля, 20:43 #217 #1025560

>>1025558

Или на stack overflow. Или на lang-8 который специально для этого предназначен.

21 Кб, 429x454

15 июля, 21:35 #218 #1025582

Здравствуйте, у меня есть Many To Many связь между Link и Tag. Форма Link (на пике) позволяет редактировать теги для каждой ссылки. Это норма, что приходится извращаться с array_diff'ами при редактировании тегов, при условии что:
- теги можно удалять (значит нужно как использовать unlink)
- при добавлении новых тегов в БД нужно сначала их создать (save), а только потом присоединять к Link
- уже существующие теги не должны создаваться заново, Link нужно связывать с уже существующими тегами

Тут код: https://pastebin.com/56qq7Zdj

Ответы25585

15 июля, 21:45 #219 #1025585

>>1025582

Ты зря все это пишешь в контроллере. Лучше сделать в модели функцию updateTags($newTags) и пусть она проверяет что там где изменилось.

Ну а вообще, если лень делать diff то можно просто очищать связь и создавать заново.

Ответы25819

245 Кб, 600x1024

15 июля, 22:44 #220 #1025613

ПХП макаки, самые нищеброды. Golang разработчики самые оплачиваемые! Переходите на Go пока не поздно. Вся инфа в треде
https://2ch.hk/pr/res/1020995.html (М)

Ответы2578127487

mb 15 июля, 23:40 #221 #1025658

Аноны, на ideone не работает mb_strlen, mb_substr и т.д. не работают?

Ответы25819

16 июля, 02:50 #222 #1025781

>>1025613
а на node уже переходить не надо?

Ответы25969

16 июля, 08:51 #223 #1025819

>>1025585
Спасибо, это уменьшит количество diff'ов. А нормально ли для Active Record делать save() в цикле для новых сущностей? Ещё мой в транзакцию нужно обернуть.

>>1025658
Да, там обновили PHP до 7-й версии, а про расширение mbstring забыли. Как вариант можно использовать https://3v4l.org/
Ещё мне кажется, что этот вопрос за последние треды бьёт все рекорды популярности и может быть стоит об этом написать в ОП-посте. Или что хуже - редактировать сайт на народе, там ведь ссылки на ideone.

25 Кб, 600x391

16 июля, 09:35 #224 #1025828

Вскроем тему.
Что такое URI?
URL - ссылка, но нееет, это всё детские шалости, ссылкой это называют только не знающие.
URI - унифицированное имя ресурса.
URL - местонахождение ресурса(location)
URN(che za huiny?) - имя ресурса(name)

Так вот URL и URN являются частями URI.
Так блядь в чём смысл? URL - устарело, так? Теперь любые ссылки называть URI?

"http://docs.slimframework.com/request/paths/ "
ЭТО URI? Говорить URL не тру и вообще не правильно?

А вопрос встал ввиду не понимания информации ниже.
Root URI

The root URI is the physical URL path of the directory in which the Slim application is instantiated and run. If a Slim application is instantiated in index.php within the top-most directory of the virtual host’s document root, the root URI will be an empty string. If a Slim application is instantiated and run in index.php within a physical subdirectory of the virtual host’s document root, the root URI will be the path to that subdirectory with a leading slash and without a trailing slash pidor.

(поясните о чём тут)

Ответы2583825839

16 июля, 10:18 #225 #1025838

>>1025828
url описывает МЕСТОНАХОЖДЕНИЕ ресурса.
uri - это не имя, а идентификатор ресурса. он может быть как и url так и urn, так и все в перемешку

url частный случай uri
у одного uri может быть множество url и urn

urn не описывает где лежит ресурс. а url не обязан отражать имя ресурса.

Ответы25845

16 июля, 10:19 #226 #1025839

>>1025828
>"http://docs.slimframework.com/request/paths/ "
>ЭТО URI? Говорить URL не тру и вообще не правильно?

Человек играющий на скрипке - это музыкант? Говорить, что он скрипач вообще не правильно?

16 июля, 10:26 #227 #1025845

>>1025838
>у одного uri может быть множество url и urn
Вот тут по-подробней пожалуйста.

Ответы25846

16 июля, 10:34 #228 #1025846

>>1025845
Что не ясного. URI это сам ресурс. Например какая-то книга. Представлена она тебе можеть быть либо ввиде URN (например isbn:NOMER_KNIGI), либо ввиде URL (ссылки туда где эта книга лежит). И то и другое ты потом передаешь нужной программе, и она тебе вытаскивает данные о твоей книге.

URI это АБСТРАКТНЫЙ КЛАСС. URN и URL классы, от него наследующиеся. Инстансов у URL быть не может. Но в то же время каждый инстанс URN или URL - это URI

Ответы2584725869

16 июля, 10:35 #229 #1025847

>>1025846
>Инстансов у URL быть не может
у URI*

16 июля, 11:20 #230 #1025869

>>1025846
Ты пример может привести URI? Что значит сам ресурс? Я знаю адрес сайта - foobar.ru, это URL. URL часть URI, значит foobar.ru - это URI? Но URI может иметь несколько URL, и как блядь? Если имя уникально.

Ответы258842588825892

16 июля, 11:46 #231 #1025884

>>1025869
Ты дебил, нет?

http://foobar.ru - это как и URL так и URI
А http://www.foobar.ru или https://foobar.ru - это тебе примеры еще пары URL ссылающихся НА ТОТ ЖЕ САМЫЙ ресурс.

При этому у твоего foobar.ru URN может быть каким-нибудь website:foobarcompany

URL показывает где лежит ресурс. URN его уникальное имя в КАКОЙ-ТО СИСТЕМЕ. И то и другое это URI этого ресурса. Это ОБЩЕЕ ТВОЯ СУКА МАТЬ НАЗВАНИЕ . И у любого ресурса может быть миллионы URL или URN

Сука, ты понимаешь, что такое АБСТРАКТНЫЙ КЛАСС - нет?

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

Ответы25895

16 июля, 11:52 #232 #1025888

>>1025869
>уникально
Уникальность - это когда по завпросу идентификатора тебе предоставляется один и только один ресурс. При этом у ресурса может быть хуева туча таких уникальных идентификаторов. Если бы один и тот же идентификатор мог описывать разные ресурсы одновременно - вот тогда он не уникален.

URI - это уникальный идентификатор ресурса. Представлен он тебе может либо ввиде URL либо в виде URN. И то и другое это URI.

Ответы25894

16 июля, 12:00 #233 #1025892

>>1025869

URI это обобщенное название для URL (обычных ссылок) и URN (всяких странных идентификаторов вроде номера книги или телефона) и может быть каких-то еще других видов ссылок на ресурсы. То есть любой URL или URN является URI.

Вот определения:

URL:
> A Uniform Resource Locator (URL), colloquially termed a web address,[1] is a reference to a web resource that specifies its location on a computer network and a mechanism for retrieving it.
> URLs occur most commonly to reference web pages (http), but are also used for file transfer (ftp), email (mailto), database access (JDBC), and many other applications.

Вот URN:
> In computing, a Uniform Resource Name (URN) is a Uniform Resource Identifier (URI) that uses the urn scheme.

URI:
> A URI is a string of characters used to identify or name a resource.

И вот еще:

> Since RFC 3986[5] in 2005, use of the terms "Uniform Resource Name" and "Uniform Resource Locator" has been deprecated in technical standards in favor of the term Uniform Resource Identifier (URI), which encompasses both

Дальше можно почитать статью https://en.wikipedia.org/wiki/Uniform_Resource_Name и сам RFC, если хочется точных определений.

Хоть авторы и пишут URI, там имеется в виду именно URL, причем не любой, а только URL с использованием протоколов HTTP/HTTPS. Так как это веб-фреймворк.

16 июля, 12:04 #234 #1025894

>>1025888

Вообще-то уникальность подразумевает, что у ресурса один URI, а не множество.

16 июля, 12:05 #235 #1025895

>>1025884

> А http://www.foobar.ru или https://foobar.ru - это тебе примеры еще пары URL ссылающихся НА ТОТ ЖЕ САМЫЙ ресурс.

Это как раз плохой пример, так как у ресурса должен быть один URI, а не несколько. Адреса http://www.foobar.ru или http://foobar.ru должны вместо отдачи контента редиректить на https://foobar.ru

Ответы2590125906

16 июля, 12:16 #236 #1025901

>>1025895
>должен быть один URI, а не несколько
Потому что ты так сказал?
Ты идиот.

Ответы25935

16 июля, 12:22 #237 #1025906

>>1025895
В твоем манямирке ресурсы должны быть доступны только по одному протоколу и только на одном хосте, ip? А со всех остальных надо редиректить?

Ответы25997

16 июля, 13:06 #238 #1025935

>>1025901

Все понятно, не засоряй тогда дальше тред.

16 июля, 13:29 #239 #1025947

Делаю к файлообменнику регистрацию, есть сущности RegisteredUser, Admin и Visitor унаследованные от абстрактного класса User. Создал для каждой сущности свой TableDataGateway и свою таблицу sql. В классе AuthHelper все эти TDG агрегируются и в методе login($login, $pass) я обращаюсь к каждому чтобы проверить существует ли пользователь с данным логином. Мне кажется, я делаю что-то неправильно, потому что получается 3 запроса, а в sql запросах можно объединять таблицы. Есть ли альтернатива моему способу?

Ответы259492597725997

16 июля, 13:33 #240 #1025949

>>1025947

Если что, сущность Admin наследуется от RegisteredUser, и есть еще сущность SuperAdmin наследуемая соответственно от Admin.

Ответы2595125977

16 июля, 13:35 #241 #1025951

>>1025949

А еще для Visitor я не создавал таблицу и TDG, гость у меня только куку получает без записи в таблице, так что мы говорим о сущностях Admin, SuperAdmin и RegisteredUser, вот.

16 июля, 14:08 #242 #1025969

>>1025781
Сравнил жопу с пальцем. JS в любом случае придётся учить. С ним на ноде и монге можно ебашить изоморфные приложения без ебли с парсингом. Смысл пхп - разбираться в чужих легаси конюшнях в разных мусохрансках за гроши.

Ответы26390

16 июля, 14:17 #243 #1025977

>>1025947
>>1025949
Кажется, что ты переусложнил с четырьмя классами. Что мешает в таблице User держать колонку-дискриминатор, которая будет обозначать тип пользователя? В приложении может быть куча ролей у пользователей и неудобно создавать по классу для каждой роли. Наследование удобно использовать, когда у каждого наследника свой набор колонок в бд / свойств класса (советую почитать про STI, Class TI и Concrete TI).

Ответы25978

12 Кб, 500x329

16 июля, 14:20 #244 #1025978

>>1025977

Я знаю про >STI, Class TI и Concrete TI. Разве не мой случай http://design-pattern.ru/patterns/concrete-table-inheritance.html ?

Ответы25982

16 июля, 14:22 #245 #1025982

>>1025978

Хотя наверное не мой. Мой - это когда у перечисленных спортсменов определенные роли на поле.

8 Кб, 504x226

16 июля, 14:25 #246 #1025988

В чем проблема?
>
Parse error: syntax error, unexpected T_VARIABLE, expecting T_FUNCTION on line 40

Ответы25997

16 июля, 14:43 #247 #1025997

>>1025906

Почитай справку для вебмастеров у Яндекса или Гугла.

>>1025947

А зачем таблица для Visitor? Вообще, мне кажется, ты переусложнил все это и удобнее было использовать Single TI.

>>1025988

public/private забыл

Ответы2600126151

16 июля, 14:53 #248 #1026001

>>1025997
>URI
>вебмастеров
Все с тобой понятно.

16 июля, 16:18 #249 #1026061

В VS Code подсветка кода пыхи не работает. Может кто знает, как починить?

Ответы26143

16 июля, 18:38 #250 #1026143

>>1026061
<?php или <? перед пыха кодом написал?

Ответы26243

6 Кб, 543x133

16 июля, 18:52 #251 #1026151

>>1025997
Спасибо, все заработало. Но появилась следующая проблема, как присвоить значение которое возвращает метод класса данной переменной? Вот мой говнокод http://ideone.com/igRnFF

Ответы26317

16 июля, 20:33 #252 #1026198

ОП, что скажешь? https://habrahabr.ru/post/333398/
Как раз начинать проект новый буду, собирался на Yii2 но теперь немного сомневаюсь

Ответы3000730199

16 июля, 22:10 #253 #1026243

>>1026143
Есть такое. Я разобрался сам, но всё равно спасибо ещё миллион часов потратил,
чтобы xDebug настроить.

16 июля, 22:36 #254 #1026257

Где в MVC вызывать session_start(), в начале каждого контроллере? И где проверять может ли пользователь находиться на странице, private метод контроллера checkAuth() в каждом экшне?

Ответы2625830007

16 июля, 22:38 #255 #1026258

>>1026257
> private метод контроллера checkAuth()

Метод AuthHelper, а не контроллера, фикс.

17 июля, 02:42 #256 #1026317

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

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

17 июля, 03:19 #257 #1026318

Привет, аноны.

Работал ли кто с композитными формами (nested forms)? Такая фича точно есть симфони, но нечто подобное хочу реализовать Yii. Суть в чем, что у меня есть форма для регистрации пользователя, также используется точно такая же форма для регистрации пользователя от имени админа, вполне возможно что впоследствии нечто подобное нужно будет использовать для регистрации пользователя через апи. В общем, чтобы не плодить кучу разных моделей форм и дублировать код, хочу использовать как раз композитные формы, и в экшенах всех контроллеров как раз везде подставлять эту композитную форму, что было бы крайне удобно.

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

Ответы30007

17 июля, 11:51 #258 #1026390

>>1025969
>Сравнил жопу с пальцем
С хяльцем. Уже несколько лет слышу про ноду - убийцу ПХП, да чет все никак не не взлетает. Теперь вот стал все чаще слышать по Go, а с нодой все как-то тише и тише. При этом пхп сколько занимал информационного пространства - столько и занимает если не больше. Ах да, пхп узко-направленный язык, уступающий модным разваливающимся свистоперделкам, срок жизни которых - несколько лет, после чего прийдет новая хайпо-развалюха.

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

Ответы26460

17 июля, 14:07 #259 #1026460

>>1026390
>да чет все никак не не взлетает.
Это ты так решил?
>а с го и нодой, ты хуй работу найдешь
Тож сам так решил?))Может стоит зайти хотя бы на hh и увидеть 900~ вакансий?

>то срок актуальности твоих знаний и умений - 2-3 года
И еще раз, ecma тебе в любом случае придется уметь.

Ответы26470

17 июля, 14:36 #260 #1026470

>>1026460
>сам так решил?))
ага)))))
>увидеть 900~ вакансий
и эти 900 высосаных из пальца и возникших на волне хайпа вакансии количество которых не сравнится с пхп уже меняются на то же количество но теперь для го, а через пару лет будут актуальны для новой йобы. А для пхп как было дохуя, так дохуя остается и растет, причем вакансии как для низкооплачиваемых макак, так и высокооплачиваемые для гуру господ. И если ты зеленый, то ты можешь не ссаться, что через 2 года твои знания никому нахуй не нужны будут, а спокойно развиваться.

>ecma тебе в любом случае придется уметь
Хуекма. Одна из особенностей джаваскрипта в том, что ты можешь писать на нем, его не зная, т.к. изучение одного из 100500 жс фреймворков сродни изучению нового языка.

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

Ответы26496

62 Кб, 275x417

17 июля, 15:14 #261 #1026496

>>1026470
>и эти 900 высосаных из пальца и возникших на волне хайпа вакансии
А какой процент из этого является "знать пых 3 и 5, терпение и умение разбираться в чужом коде"?
Или "мы слышали что на пхп делают сайтики, но нам на самом деле нам абсолютно похуй чем ты там занимаешься, лишь бы было"

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

Ответы26510

17 июля, 15:42 #262 #1026510

>>1026496
>Лол
Треснул квадратно-гнездовой шаблон? Бывает

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

Ответы26513

17 июля, 15:47 #263 #1026513

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

Ответы26515

17 июля, 15:54 #264 #1026515

>>1026513
хайпошкольник порвался

17 июля, 19:37 #265 #1026920

можно ли силами CSS сделать симпотичный дизайн или все на фотошопе щас?
вопрос нуба

Ответы30007

17 июля, 19:45 #266 #1027168

что такое статическая переменная?

Ответы2724530007

17 июля, 19:47 #267 #1027245

>>1027168
это такой пруф

Ответы27379

17 июля, 19:52 #268 #1027379

>>1027245
что?

Ответы27482

17 июля, 20:13 #269 #1027482

>>1027379
пруф

17 июля, 20:21 #270 #1027487

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

17 июля, 20:29 #271 #1027490

Зацените задачку на пыхе:
https://www.codewars.com/kata/remove-first-and-last-character/

17 июля, 21:10 #272 #1027509

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

https://m.habrahabr.ru/company/zfort/blog/333458/

17 июля, 21:16 #273 #1027510

почему нет замены php в в современных реалиях?

Ответы275692816431753

17 июля, 22:50 #274 #1027569

>>1027510
почему нет? Есть, вон нода, го. Скоро пхп пизда

18 июля, 04:48 #275 #1027651

https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L82
Что можно сделать после успешной отправки сообщения?

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

https://arhivach.org/thread/261841/#1000396
>Ты не обрабатываешь ошибки. Видимо, уроки, которые ты читал, упускают такие важные вещи. Вот тебе тогда мои маленькие советы про использование аякса: https://github.com/codedokode/pasta/blob/master/js/ajax.md
https://github.com/someApprentice/chat/blob/master/public/js/chat.js#L59-L69
https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L85-L92

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

Почему у меня не вбрасываются эти ошибки (ошибки не появляются в консоле)? Это из-за асинхронного кода?

https://arhivach.org/thread/266631/#1010744
>> Кстати, это нормально делать перевод на новую строку в цикле https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L280-L284 ?
>Это какие-то кривые костыли. Получается, логика отображения разбросана между шаблоном и JS кодом. Мы ведь в PHP не пытаемся так делать после генерации HTML из шаблона? И тут не надо. Наверняка там есть какие-нибудь хелперы для таких преобразований. В чем проблема сделать какой-нибудь хелпер для преобразования текстов сообщений?
К сожалению, у меня не получилось найти в ejs аналог функции nl2br и при этом чтобы экранировались тэги. В таком случае, будет приемлемым оставить этот костыль?
Или лучше, можете посоветовать какой-нибудь шаблонизатор который справиться с этой задачей?

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

https://github.com/someApprentice/chat/blob/master/src/Controller/ConversationController.php#L78-L115
Это нормально, что у меня такая простыня с обработкой ошибок?

https://arhivach.org/thread/261841/#1000396
>Также, некоторые разработчики активно используют возможности HTTP (дополнительные заголовки, методы вроде PUT/DELETE, коды ответов), а некоторые не используют.
>Также, перед проектированием АПИ, советую почитать про REST и HATEOS (и далее, стандарт про шаблоны URL https://tools.ietf.org/html/rfc6570 ), но тут конечно есть разные мнения, ну к примеру в иделогии REST одним запросом нельзя получить несколько несвязанных массивов данных, а HATEOS раздувает размер ответа.
Я плохо понял что такое REST. Это просто архитектура которая позволяет обрабатывать запросы с методами вроде PUT\DELETE?

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

https://arhivach.org/thread/266631/#1010325
>Пересоздавать полный список сообщений неэффективно.
Я никак не могу придумать как выводить только новые сообщения. Определенно, нужен setTimeout\setInterval чтобы постоянно обновлять данные с сервера, но как при этом выводить только те сообщения которые ещё не выведены в шаблон?

https://github.com/someApprentice/chat/blob/master/src/Model/Database/MessageGateway.php#L25
Поскольку, я теперь вывожу сообщения за определённый период времени, то если за этот промежуток не было сообщений, при открытии диалога выведиться пустое окно сообщений из-за чего вытекает баг с автоматической подрузкой более старых сообщений, из-за того что отсутвует скролл блока сообщений. Это можно исправить увеличивая отрезок времени и повторном обращении к БД, до тех пор пока не получим нужное количество сообщений:

$count = $db->getMessagesCount();

$offset = 1;

if ($count > 10) {
while(count($messages) < 10) {
$offset++;
$messages = $db->getMessages(..., $offset);
}
}

Не будет ли это лишней нагрузкой на БД?

У меня есть идея как при отключенном js опускать окно диалога до последнего сообщения - использовать якори. Я уже делаю что-то подобное при получении более старых сообщениях (при выключенном js):

https://github.com/someApprentice/chat/blob/master/templates/chat.phtml#L24
><a ... href="conversation.php? ... #message-ID">Получить больше сообщений</a>

https://github.com/someApprentice/chat/blob/master/templates/chat.phtml#L32
><div id="message-ID ... class="message">

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

Но для этого нужно сделать несколько лишних запросов к БД:

$contacts = $db->getContacts();

$c = array();

foreach ($contacts as $contact) {
$lastMessage = $db->getLastMessage(...);

$c[] = array(
'contact' => $contact,
'lastMessage' => $lastMessage
);
}

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

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

https://github.com/someApprentice/chat/blob/master/src/Controller/AuthController.php#L101-L103
https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L217
Не подвергаю ли я пользователей опасности, открывая кукисы для js?

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

У меня есть переменные, которые пишутся ни как camelCase или snake_case, например moremessages. Я знаю, что это плохой плохой вариант, но мне он кажется вполне читабельным. Лучше будет переимновать?

18 июля, 04:48 #275 #1027651

https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L82
Что можно сделать после успешной отправки сообщения?

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

https://arhivach.org/thread/261841/#1000396
>Ты не обрабатываешь ошибки. Видимо, уроки, которые ты читал, упускают такие важные вещи. Вот тебе тогда мои маленькие советы про использование аякса: https://github.com/codedokode/pasta/blob/master/js/ajax.md
https://github.com/someApprentice/chat/blob/master/public/js/chat.js#L59-L69
https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L85-L92

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

Почему у меня не вбрасываются эти ошибки (ошибки не появляются в консоле)? Это из-за асинхронного кода?

https://arhivach.org/thread/266631/#1010744
>> Кстати, это нормально делать перевод на новую строку в цикле https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L280-L284 ?
>Это какие-то кривые костыли. Получается, логика отображения разбросана между шаблоном и JS кодом. Мы ведь в PHP не пытаемся так делать после генерации HTML из шаблона? И тут не надо. Наверняка там есть какие-нибудь хелперы для таких преобразований. В чем проблема сделать какой-нибудь хелпер для преобразования текстов сообщений?
К сожалению, у меня не получилось найти в ejs аналог функции nl2br и при этом чтобы экранировались тэги. В таком случае, будет приемлемым оставить этот костыль?
Или лучше, можете посоветовать какой-нибудь шаблонизатор который справиться с этой задачей?

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

https://github.com/someApprentice/chat/blob/master/src/Controller/ConversationController.php#L78-L115
Это нормально, что у меня такая простыня с обработкой ошибок?

https://arhivach.org/thread/261841/#1000396
>Также, некоторые разработчики активно используют возможности HTTP (дополнительные заголовки, методы вроде PUT/DELETE, коды ответов), а некоторые не используют.
>Также, перед проектированием АПИ, советую почитать про REST и HATEOS (и далее, стандарт про шаблоны URL https://tools.ietf.org/html/rfc6570 ), но тут конечно есть разные мнения, ну к примеру в иделогии REST одним запросом нельзя получить несколько несвязанных массивов данных, а HATEOS раздувает размер ответа.
Я плохо понял что такое REST. Это просто архитектура которая позволяет обрабатывать запросы с методами вроде PUT\DELETE?

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

https://arhivach.org/thread/266631/#1010325
>Пересоздавать полный список сообщений неэффективно.
Я никак не могу придумать как выводить только новые сообщения. Определенно, нужен setTimeout\setInterval чтобы постоянно обновлять данные с сервера, но как при этом выводить только те сообщения которые ещё не выведены в шаблон?

https://github.com/someApprentice/chat/blob/master/src/Model/Database/MessageGateway.php#L25
Поскольку, я теперь вывожу сообщения за определённый период времени, то если за этот промежуток не было сообщений, при открытии диалога выведиться пустое окно сообщений из-за чего вытекает баг с автоматической подрузкой более старых сообщений, из-за того что отсутвует скролл блока сообщений. Это можно исправить увеличивая отрезок времени и повторном обращении к БД, до тех пор пока не получим нужное количество сообщений:

$count = $db->getMessagesCount();

$offset = 1;

if ($count > 10) {
while(count($messages) < 10) {
$offset++;
$messages = $db->getMessages(..., $offset);
}
}

Не будет ли это лишней нагрузкой на БД?

У меня есть идея как при отключенном js опускать окно диалога до последнего сообщения - использовать якори. Я уже делаю что-то подобное при получении более старых сообщениях (при выключенном js):

https://github.com/someApprentice/chat/blob/master/templates/chat.phtml#L24
><a ... href="conversation.php? ... #message-ID">Получить больше сообщений</a>

https://github.com/someApprentice/chat/blob/master/templates/chat.phtml#L32
><div id="message-ID ... class="message">

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

Но для этого нужно сделать несколько лишних запросов к БД:

$contacts = $db->getContacts();

$c = array();

foreach ($contacts as $contact) {
$lastMessage = $db->getLastMessage(...);

$c[] = array(
'contact' => $contact,
'lastMessage' => $lastMessage
);
}

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

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

https://github.com/someApprentice/chat/blob/master/src/Controller/AuthController.php#L101-L103
https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L217
Не подвергаю ли я пользователей опасности, открывая кукисы для js?

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

У меня есть переменные, которые пишутся ни как camelCase или snake_case, например moremessages. Я знаю, что это плохой плохой вариант, но мне он кажется вполне читабельным. Лучше будет переимновать?

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

18 июля, 14:08 #276 #1027835

Котаны,вкатываюсь в ваш уютный клуб,проверьте задачки про кубы http://ideone.com/LitWO1 и айфон http://ideone.com/lHOqEL. Заранее пасяб.
З.Ы. А зачем в эхо выделять переменные фигурными скобками?

Ответы29997

18 июля, 18:08 #277 #1027942

Расскажите пожалуйста про
>$example = function () use ($variable) { ... }

В мануале http://php.net/manual/ru/functions.anonymous.php
не понял что значит этот use, и когда надо и не надо его употреблять.

Ответы280032851028550

18 июля, 18:53 #278 #1027953

$STH->setFetchMode(PDO::FETCH_CLASS | PDO::FETCH_PROPS_LATE, 'secret_person');
Объясните, пожалуйста, что значит символ "|"? Это оператор? Гугл не помог. Я нашел только || - логическое ИЛИ.

Ответы27969

18 июля, 19:28 #279 #1027968

Спрашивал уже раньше, но не могу найти свой пост: какие подводные камни в том, чтобы делать небольшой сайт в виде одной страницы, где весь контент разбит по динамически подгружающимся вкладкам? Просто у меня горит очко от мысли, что я буду копипастить кучу одинакового кода в разные страницы, шапку там, подвал. А если в них что-то нужно поменять будет? Это же пиздец.
Вот пример такого сайта: https://goo.gl/n7bfuT Сократил, потому что макака-пидор.

Ответы27970

18 июля, 19:28 #280 #1027969

>>1027953

Чтобы разобраться в этой теме, придется почитать про двоичные числа. Любое число можно представить не только в обычной (10-ной) системе счисления, но и в двоичной. Например, 19 в десятичной = 10011 в двоичной.

https://ru.wikipedia.org/wiki/Двоичная_система_счисления

Двоичная система используется потому, что внутри компьютера все числа представлены как раз в двоичном виде. Например, если в ячейке памяти есть электрический заряд, то это обозначает 1, а если нет - то там хранится 0. Одно такое значение - 0 или 1 - называется бит. Используя несколько ячеек, мы можем с помощью этих битов кодировать произвольные числа. То есть двоичная система "родная" для компьютера и внутри числа представлены и обрабатываются в этой системе.

С числами в двоичной форме кроме обычных математических операций можно делать битовые операции вроде И или ИЛИ: https://ru.wikipedia.org/wiki/Битовые_операции

http://php.net/manual/ru/language.operators.bitwise.php

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

Тогда с помощью операции ИЛИ мы можем объединять эти опции: OPTION1 | OPTION2 = 0000011

В общем-то константы вроде PDO::FETCH_CLASS - это числа (можно проверить echo или var_dump), каждое из которых содержит одну единицу в двоичном виде, а с помощью операции ИЛИ их объединяют.

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

Чтобы проверить и закрепить знания, реши задачку:

- сделай набор из нескольких констант, каждая из которых будет представлять какую-то опцию, которая кодируется с помощью двоичных флагов (то есть константа хранит число, в двоичном виде содержащее ровно одну единицу)
- сделай функцию setBit, которая принимает на вход число и опцию, и возвращает число где установлен в единицу соответствующий опции бит
- сделай функцию clearBit, которая принимает на вход число и опцию, и возращает число, где соответствующий опции бит сброшен
- сделай функцию toggleBit, которая принимает на вход число и опцию и меняет соответствующий бит в числе на противоположный
- сделай функцию testBit, которая принимает на вход число и одну опцию и возвращает true/false в зависимости от того, включен в этом числе соответствующий флаг или нет
- сделай функцию countBits, которая принимает на вход число и возвращает число единиц в его двоичном представлении

Пример использования:

const OPTION_A= ...;
const OPTION_B = ...;
const OPTION_C = ...;

$flags = 0;
$flags = setBit($flags, OPTION_A);
$flags = setBit($flags, OPTION_B);

var_dump(testBit($flags, OPTION_A)); // true
var_dump(testBit($flags, OPTION_C)); // false

$flags = clearBit($flags, OPTION_A);
var_dump(testBit($flags, OPTION_A)); // false
var_dump(testBit($flags, OPTION_B)); // true

var_dump(countBits($flags)); // 1

Если что-то непонятно, уточняй.

18 июля, 19:28 #280 #1027969

>>1027953

Чтобы разобраться в этой теме, придется почитать про двоичные числа. Любое число можно представить не только в обычной (10-ной) системе счисления, но и в двоичной. Например, 19 в десятичной = 10011 в двоичной.

https://ru.wikipedia.org/wiki/Двоичная_система_счисления

Двоичная система используется потому, что внутри компьютера все числа представлены как раз в двоичном виде. Например, если в ячейке памяти есть электрический заряд, то это обозначает 1, а если нет - то там хранится 0. Одно такое значение - 0 или 1 - называется бит. Используя несколько ячеек, мы можем с помощью этих битов кодировать произвольные числа. То есть двоичная система "родная" для компьютера и внутри числа представлены и обрабатываются в этой системе.

С числами в двоичной форме кроме обычных математических операций можно делать битовые операции вроде И или ИЛИ: https://ru.wikipedia.org/wiki/Битовые_операции

http://php.net/manual/ru/language.operators.bitwise.php

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

Тогда с помощью операции ИЛИ мы можем объединять эти опции: OPTION1 | OPTION2 = 0000011

В общем-то константы вроде PDO::FETCH_CLASS - это числа (можно проверить echo или var_dump), каждое из которых содержит одну единицу в двоичном виде, а с помощью операции ИЛИ их объединяют.

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

Чтобы проверить и закрепить знания, реши задачку:

- сделай набор из нескольких констант, каждая из которых будет представлять какую-то опцию, которая кодируется с помощью двоичных флагов (то есть константа хранит число, в двоичном виде содержащее ровно одну единицу)
- сделай функцию setBit, которая принимает на вход число и опцию, и возвращает число где установлен в единицу соответствующий опции бит
- сделай функцию clearBit, которая принимает на вход число и опцию, и возращает число, где соответствующий опции бит сброшен
- сделай функцию toggleBit, которая принимает на вход число и опцию и меняет соответствующий бит в числе на противоположный
- сделай функцию testBit, которая принимает на вход число и одну опцию и возвращает true/false в зависимости от того, включен в этом числе соответствующий флаг или нет
- сделай функцию countBits, которая принимает на вход число и возвращает число единиц в его двоичном представлении

Пример использования:

const OPTION_A= ...;
const OPTION_B = ...;
const OPTION_C = ...;

$flags = 0;
$flags = setBit($flags, OPTION_A);
$flags = setBit($flags, OPTION_B);

var_dump(testBit($flags, OPTION_A)); // true
var_dump(testBit($flags, OPTION_C)); // false

$flags = clearBit($flags, OPTION_A);
var_dump(testBit($flags, OPTION_A)); // false
var_dump(testBit($flags, OPTION_B)); // true

var_dump(countBits($flags)); // 1

Если что-то непонятно, уточняй.

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

18 июля, 19:29 #281 #1027970

>>1027968

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

105 Кб, 881x637

18 июля, 20:06 #282 #1027976

Кароч.
Я нихуя не понимаю что ему надо.
REEEE

Ответы279872800829108

18 июля, 20:27 #283 #1027987

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

Ответы28010

18 июля, 20:57 #284 #1028003

>>1027942
Забирает себе значение $variable на время определения функции для дальнейшего использования. То есть если ты создал функцию, а $variable не определил ещё, то будет у твоей функции $variable будет всегда NULL. Иначе нужно &$variable писать, чтобы по ссылке передавало. Тогда берёт значение на момент выполнения.

Ответы28470

18 июля, 21:03 #285 #1028008

>>1027976

Если ты вызываешь функцию sequence без указания step или start то они должны быть равны 1 и 0 соответственно.

Ответы28026

18 июля, 21:05 #286 #1028010

>>1027987

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

98 Кб, 870x593

18 июля, 21:32 #287 #1028026

>>1028008
У меня почему-то в голове переклинило, что требования были к возвращаемой функции, и моск завис.

Ответы28153

19 июля, 01:00 #288 #1028153

>>1028026

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

19 июля, 01:22 #289 #1028155

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

Ответы28161

19 июля, 01:44 #290 #1028161

>>1028155

Читал эти 4 статьи? https://github.com/codedokode/pasta/tree/master/security

Ответы28171

19 июля, 02:25 #291 #1028164

>>1027510

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

Ответы28172

19 июля, 03:51 #292 #1028171

>>1028161
Годно, есть ещё?

Ответы28178

19 июля, 03:54 #293 #1028172

>>1028164
Чем отличается какой нибудь питон/руби/ещё что то фреймворк от пхп?
Лёгкостью? А в чем эта легкость заключается?
сорре за тупой вопрос

Ответы28488

19 июля, 04:16 #294 #1028178

>>1028171

Можно еще взять советы отсюда:

- https://github.com/codedokode/pasta/blob/master/student-list.md#Выносим-код-за-корень-сервера
- https://gist.github.com/codedokode/9424217#Безопасность

someApprentice 19 июля, 07:19 #295 #1028199

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

https://arhivach.org/thread/261841/#1000397
>Насчет проектирования БД - там тоже много тонкостей есть, можно делать нормальзованную схему, но лучше денормализовывать ради повышения производительности. Ну например, возьмем то же сообщение. Можно хранить его в одном экземпляре, а можно в двух - в inbox получателя и в outbox отправителя. Это может облегчить выборку последних N сообщений, так как твой запрос с OR вряд ли хорошо ложится на индексы (вдобавок у тебя еще и сортировки там нет).
Безусловно, нужно хранить сообщения в нескольких экземплярах для отправителя и для получателя, чтобы в дальнейшем было удобно шифровать их для каждого пользователя соответственно. Но я не понимаю как хранить ID сообщений - получается что для каждого пользователя оно теперь будет своё. Из этого вытекает, что нельзя будет как-то преобразовывать эти сообщения т.е. редактировать или удалять. В принципе от этой идеи можно оказаться, как это сделано в популярных мессенджерах А я всё думал, почему же они это не сделали, просто странно иметь разные ID.
Хотя, можно сделать отдельную колонку, которая не имеет PRIMARY_KEY, и заполнять ID как-то программно.

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

Такой же вопрос, и с inbox и outbox - в них те же самые сообщения будут иметь разные ID. Это неизбежно делать отдельную колонку и генерировать ID программно?

Или я не правильно понял структуру этих таблиц?

Никак не могу сформулировать структуру при реализации конференций... Попробую представить это здесь

Conferences
id
tete-a-tete //true or false (приватные переписки тоже будут представлены как конференции из двух человек для унификации кода)

Participants
id //Не уверен что от этой колонки будет толк, обычно всегда делают id
conferenceID
userID

Contacts
id
userID
conferenceID

Inbox
id
conferenceID
userID // ID пользователя которому принадлежит ящик
messageID
authorID
content
...

Outbox
id
conferenceID
userID // ID пользователя которому принадлежит ящик
messageID
authorID
content
...

Соответственно получение сообщений происходит одним запросом SELECT FROM Inbox WHERE conferenceID = :conferenceID AND userID = :userID UNION SELECT FROM Outbox WHERE conferenceID = :conferenceID AND userID = :userID

Вроде должно быть так?

----

Забыл ещё спросить в предыдущем посте

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

https://jsfiddle.net/jsqt57hz/

MVC style:
https://jsfiddle.net/hmgz7200/

Чтобы это пификсить нужно убрать с элемента обработчик функцией .off()

//Странно что не получилось написать $('body).off('submit', form, handleFormSubmit), как в примере мануала
https://jsfiddle.net/jsqt57hz/1/

Я всё правильно делаю?

>>1027651
>У меня есть идея как при отключенном js опускать окно диалога до последнего сообщения - использовать якори. Я уже делаю что-то подобное при получении более старых сообщениях (при выключенном js):
>Но для этого нужно сделать несколько лишних запросов к БД:
Это должно быть сделано с помощью функций JOIN и GROUP:

SELECT Contacts.userID, Messages.messageID as lastMessage
FROM Contacts
INNER JOIN Messages ON Contacts.userID= Messages.userID
GROUP BY Contacts.userID
ORDER BY Messages.date DESC

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

someApprentice 19 июля, 07:19 #295 #1028199

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

https://arhivach.org/thread/261841/#1000397
>Насчет проектирования БД - там тоже много тонкостей есть, можно делать нормальзованную схему, но лучше денормализовывать ради повышения производительности. Ну например, возьмем то же сообщение. Можно хранить его в одном экземпляре, а можно в двух - в inbox получателя и в outbox отправителя. Это может облегчить выборку последних N сообщений, так как твой запрос с OR вряд ли хорошо ложится на индексы (вдобавок у тебя еще и сортировки там нет).
Безусловно, нужно хранить сообщения в нескольких экземплярах для отправителя и для получателя, чтобы в дальнейшем было удобно шифровать их для каждого пользователя соответственно. Но я не понимаю как хранить ID сообщений - получается что для каждого пользователя оно теперь будет своё. Из этого вытекает, что нельзя будет как-то преобразовывать эти сообщения т.е. редактировать или удалять. В принципе от этой идеи можно оказаться, как это сделано в популярных мессенджерах А я всё думал, почему же они это не сделали, просто странно иметь разные ID.
Хотя, можно сделать отдельную колонку, которая не имеет PRIMARY_KEY, и заполнять ID как-то программно.

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

Такой же вопрос, и с inbox и outbox - в них те же самые сообщения будут иметь разные ID. Это неизбежно делать отдельную колонку и генерировать ID программно?

Или я не правильно понял структуру этих таблиц?

Никак не могу сформулировать структуру при реализации конференций... Попробую представить это здесь

Conferences
id
tete-a-tete //true or false (приватные переписки тоже будут представлены как конференции из двух человек для унификации кода)

Participants
id //Не уверен что от этой колонки будет толк, обычно всегда делают id
conferenceID
userID

Contacts
id
userID
conferenceID

Inbox
id
conferenceID
userID // ID пользователя которому принадлежит ящик
messageID
authorID
content
...

Outbox
id
conferenceID
userID // ID пользователя которому принадлежит ящик
messageID
authorID
content
...

Соответственно получение сообщений происходит одним запросом SELECT FROM Inbox WHERE conferenceID = :conferenceID AND userID = :userID UNION SELECT FROM Outbox WHERE conferenceID = :conferenceID AND userID = :userID

Вроде должно быть так?

----

Забыл ещё спросить в предыдущем посте

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

https://jsfiddle.net/jsqt57hz/

MVC style:
https://jsfiddle.net/hmgz7200/

Чтобы это пификсить нужно убрать с элемента обработчик функцией .off()

//Странно что не получилось написать $('body).off('submit', form, handleFormSubmit), как в примере мануала
https://jsfiddle.net/jsqt57hz/1/

Я всё правильно делаю?

>>1027651
>У меня есть идея как при отключенном js опускать окно диалога до последнего сообщения - использовать якори. Я уже делаю что-то подобное при получении более старых сообщениях (при выключенном js):
>Но для этого нужно сделать несколько лишних запросов к БД:
Это должно быть сделано с помощью функций JOIN и GROUP:

SELECT Contacts.userID, Messages.messageID as lastMessage
FROM Contacts
INNER JOIN Messages ON Contacts.userID= Messages.userID
GROUP BY Contacts.userID
ORDER BY Messages.date DESC

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

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

19 июля, 13:55 #296 #1028309

>>1028199
Обратись в баз данных тред, может там помогут.

19 июля, 16:33 #297 #1028373

в Yii2 нельзя использовать CamelCase в названии контроллера с prettyUrl ? Если можно то как получить доступ к контроллеру SomeCamelCaseController к actionIndex ?

Ответы28510

19 июля, 16:38 #298 #1028374

>>1020029
Хммм, феласаф

19 июля, 19:46 #299 #1028469

помогите решить задачку

Ответ на любой вопрос это же google!

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

Подсказка: здесь тебе могла бы помочь функция array_rand()

http://ideone.com/eyM8V0

главная проблема не выводится значение массива

Ответы28510

19 июля, 19:46 #300 #1028470

>>1028003

>Тогда берёт значение на момент выполнения

Как это понять? Если у меня выше по коду например вообще нет такой переменной, что будет взято в &$variable?

Ответы284732851030006

19 июля, 19:52 #301 #1028473

>>1028470
NULL же.

19 июля, 20:28 #302 #1028488

>>1028172
>Чем отличается какой нибудь питон/руби/ещё что то фреймворк от пхп?
>Лёгкостью? А в чем эта легкость заключается?
>сорре за тупой вопрос

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

19 июля, 21:24 #303 #1028510

>>1028373
Дефисы у меня работали. Первая же ссылка в гугле подтверждает: https://github.com/yiisoft/yii2/issues/493

>>1028469
> главная проблема не выводится значение массива
В документации array_rand написано "returns the key (or keys) of the random entries.", то есть функция возвращает ключ (индекс элемента), а не значение: http://php.net/manual/en/function.array-rand.php
Тебе нужно обратиться к элементу массива под этим новым случайным индексом, тогда получишь значение.

>>1027942
В PHP, в отличии от JS, функция не может обращаться к внешним переменным, то есть к тем, которые существуют за пределами этой функции. Такой код вызовет ошибку:

$n = 3;
array_filter([1,2,3,4,5], function ($el) { return $el > $n; });

PHP скажет, что $n не определена внутри функции.
А с этим кодом всё ок:

$n = 3;
array_filter([1,2,3,4,5], function ($el) use ($n) { return $el > $n; });

>>1028470
Тебе же никто не запрещает просто взять и проверить.

>>1027969
Интересные задачи, нужно порешать.

Ответы2867328685

19 июля, 22:51 #304 #1028550

>>1027942

use описан тут http://php.net/manual/ru/functions.anonymous.php

Он позволяет передать копию значения переменной снаружи внутрь анонимной функции (по умолчанию в функции доступны только созданные внутри нее переменные). Если использовать &$foo вместо $foo, то передается не копия значения, а ссылка на саму переменную, и код внутри функции может менять эту переменную.

>>1028199

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

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

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

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

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

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

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

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

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

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

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

В общем, есть 2 варианта, предлагаю сравнить их преимущества и недостатки.

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

Также, вопрос еще, где хранить ключи. Можно иметь единый ключ пользователя, хранящийся на сервере и зашифрованный паролем (устройства скачивает шифрованный ключ и расшифровывает локально). Либо же можно для каждого устройства иметь свой ключ и не сохранять его на сервер. Но тогда отправитель или сервер должен шифровать каждое сообщение всеми пользовательскими ключами, чтобы его можно было прочесть на любом устройстве. По моему так сделано в iMessage: https://images.apple.com/business/docs/iOS_Security_Guide.pdf , страница 43:

> When a user turns on iMessage on a device, the device generates two pairs of keys for
use with the service: an RSA 1280-bit key for encryption and an ECDSA 256-bit key on
the NIST P-256 curve for signing. The private keys for both key pairs are saved in the
device’s Keychain and the public keys are sent to Apple’s directory service (IDS), where
they are associated with the user’s phone number or email address, along with the
device’s APNs address.

> The user’s outgoing message is individually encrypted for each of the receiver’s
devices.

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

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

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

> Никак не могу сформулировать структуру при реализации конференций..
Таблица "чаты": chat.id, chat.name, таблица для хранения списка участников (с периодом времени): participant.userId, participant.chatId, participant.since, participant.till. Ну и соответственно таблицы для хранения сообщений, вид которых зависит от выбранной схемы.

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

Что касается твоей схемы, вместо 2 таблиц inbox/outbox можно сделать одну с полем типа сообщения.

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

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

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

В твоем примере кода, когда ты вставляешь HTML код из template в DOM, тогда же надо и ставить обработчики, и делать это только один раз. То есть сделать например так:

Widget.prototype.handleShowFormButton = function() {
this.view.button.click(this.showForm.bind(this));
}

Widget.prototype.showForm = function () {
if (!this.view.isFormCreated()) {
this.view.createForm(); // создает форму без проверки, есть она или нет
this.handleFormSubmit(); // ставит на нее обработчики
}
};

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

> Чтобы это пификсить нужно убрать с элемента обработчик функцией .off()
Выглядит как костыль. Проще просто не ставить обработчик несколько раз.

> У меня есть идея как при отключенном js опускать окно диалога до последнего сообщения - использовать якори.
> Это должно быть сделано с помощью функций JOIN и GROUP:
Я не очень понял, как выравнивание сообщений связано с SQL-запросами?

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

19 июля, 22:51 #304 #1028550

>>1027942

use описан тут http://php.net/manual/ru/functions.anonymous.php

Он позволяет передать копию значения переменной снаружи внутрь анонимной функции (по умолчанию в функции доступны только созданные внутри нее переменные). Если использовать &$foo вместо $foo, то передается не копия значения, а ссылка на саму переменную, и код внутри функции может менять эту переменную.

>>1028199

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

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

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

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

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

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

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

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

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

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

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

В общем, есть 2 варианта, предлагаю сравнить их преимущества и недостатки.

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

Также, вопрос еще, где хранить ключи. Можно иметь единый ключ пользователя, хранящийся на сервере и зашифрованный паролем (устройства скачивает шифрованный ключ и расшифровывает локально). Либо же можно для каждого устройства иметь свой ключ и не сохранять его на сервер. Но тогда отправитель или сервер должен шифровать каждое сообщение всеми пользовательскими ключами, чтобы его можно было прочесть на любом устройстве. По моему так сделано в iMessage: https://images.apple.com/business/docs/iOS_Security_Guide.pdf , страница 43:

> When a user turns on iMessage on a device, the device generates two pairs of keys for
use with the service: an RSA 1280-bit key for encryption and an ECDSA 256-bit key on
the NIST P-256 curve for signing. The private keys for both key pairs are saved in the
device’s Keychain and the public keys are sent to Apple’s directory service (IDS), where
they are associated with the user’s phone number or email address, along with the
device’s APNs address.

> The user’s outgoing message is individually encrypted for each of the receiver’s
devices.

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

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

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

> Никак не могу сформулировать структуру при реализации конференций..
Таблица "чаты": chat.id, chat.name, таблица для хранения списка участников (с периодом времени): participant.userId, participant.chatId, participant.since, participant.till. Ну и соответственно таблицы для хранения сообщений, вид которых зависит от выбранной схемы.

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

Что касается твоей схемы, вместо 2 таблиц inbox/outbox можно сделать одну с полем типа сообщения.

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

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

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

В твоем примере кода, когда ты вставляешь HTML код из template в DOM, тогда же надо и ставить обработчики, и делать это только один раз. То есть сделать например так:

Widget.prototype.handleShowFormButton = function() {
this.view.button.click(this.showForm.bind(this));
}

Widget.prototype.showForm = function () {
if (!this.view.isFormCreated()) {
this.view.createForm(); // создает форму без проверки, есть она или нет
this.handleFormSubmit(); // ставит на нее обработчики
}
};

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

> Чтобы это пификсить нужно убрать с элемента обработчик функцией .off()
Выглядит как костыль. Проще просто не ставить обработчик несколько раз.

> У меня есть идея как при отключенном js опускать окно диалога до последнего сообщения - использовать якори.
> Это должно быть сделано с помощью функций JOIN и GROUP:
Я не очень понял, как выравнивание сообщений связано с SQL-запросами?

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

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

19 июля, 23:15 #305 #1028560

>>1028199

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

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

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

Ну и если есть желание, то почитать информацию о протоколе Tox:

- https://en.wikipedia.org/wiki/Tox_(protocol)
- https://github.com/Tox-Docs/Text/tree/master/src_text

и Signal:

- https://en.wikipedia.org/wiki/Signal_Protocol
- https://whispersystems.org/docs/

Ответы28568

19 июля, 23:28 #306 #1028568

>>1028560
>Вообще, мне тут пришла в голову мысль
http://graphql.org ???

7 Кб, 225x225

20 июля, 00:04 #307 #1028581

нахуя вы изучаете эту парашу?вам делать нехуй?

Ответы28589

20 июля, 00:18 #308 #1028589

>>1028581
Так некуда деваться, в мухосрансках есть только два стула, 1C и сладкий хлебушек. Но 1C это вообще не программирование.
На фрилансе тоже хуй найдешь заказы на Java ну или desktop разработку.

Ответы28769

20 июля, 00:29 #309 #1028597

А вообще у человека гибкая психика, он ко всему привыкает. Можно привыкнуть жрать тухлятину с червями. Можно привыкнуть к сидению у параши и ебле в жопу. А уж писать код на PHP это вообще ерунда, как нехуй делать. Только первый месяц неприятно, потом привыкаешь ко всему: и к доллару, и к переменным без объявления, и к другому порядку тернарного оператора, и к отсутствию code style в стандартных функциях... Главное, что за это тебе деньги платят.

Ответы2865530006

20 июля, 01:03 #310 #1028606

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

20 июля, 01:17 #311 #1028612

Аноны помогите пожалауйста не могу понять.

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

Гуглил но как то ничего не поняля тупой

Ответы29522

20 июля, 07:24 #312 #1028655

>>1028597
Ваистену!

мимо 110k php-джун

20 июля, 09:30 #313 #1028673

>>1028510
> главная проблема не выводится значение массива
В документации array_rand написано "returns the key (or keys) of the random entries.", то есть функция возвращает ключ (индекс элемента), а не значение: http://php.net/manual/en/function.array-rand.php
Тебе нужно обратиться к элементу массива под этим новым случайным индексом, тогда получишь значение.

спасибо гуру

20 июля, 10:09 #314 #1028685

>>1028510
Теперь понятно.

Без use — undefined

use ($variable) — только внутрь

use (&$variable) — внутрь и наружу

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

Ответы30006

20 июля, 13:50 #315 #1028769

>>1028589
Много работы по верстке и жсу.

Ответы2878028781

68 Кб, 500x657

20 июля, 14:10 #316 #1028780

>>1028769
А фронтенд прям не параша, да?

Ответы28818

33 Кб, 720x304

20 июля, 14:11 #317 #1028781

>>1028769
>верстке и жсу.
Увлекательно.

Ответы28818

20 июля, 15:08 #318 #1028818

>>1028780
>>1028781
а жаба типа круче?

Ответы28838

20 июля, 15:43 #319 #1028838

>>1028818
При чём здесь жаба? Тут пхп-тред.

21 июля, 03:00 #320 #1029108

>>1027976
Это ПХП? Если так то синтаксис так на С похож.
Я нуфак, только вкатился в ваш тред.

Ответы29521

21 июля, 08:02 #321 #1029130

Повесил функцию из замыкания на листенер, следящий за нажатиями клавиш. Она должна вызывать другую функцию из этого же замыкания, но не видит её. Теперь по this ей передаётся window!
Решил проблему, сославшись в функции на глобальную переменную самого замыкания. А как это сделать нормально?

Ответы29147

21 июля, 09:45 #322 #1029147

>>1029130
https://learn.javascript.ru/bind

Ответы29274

1 Кб, 511x32

21 июля, 09:52 #323 #1029149

Как передавать в конструктор значение с поля класса? Мне лень в каждый объект ручками все добавлять, когда все эти значения и так есть в классе. Делаю задачу ОПа. http://ideone.com/1z228K

Ответы291612951930004

21 июля, 10:15 #324 #1029161

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

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

21 июля, 11:25 #325 #1029194

хочу сделать запись реквестов несуществующих страниц
по типу
кто-то пытается зайти на
site.com/analplugs
его редиректит на главную
site.com
а site.com/analplugs записывается в бд
редирект понятно через какой-нибудь htaccess можно сделать, но как это совместить с записью в бд?

Ответы292212951830004

21 июля, 13:31 #326 #1029221

>>1029194
Сервак и без тебя ведет логи запросов ко всем ресурсам, в том числе и несуществующим.

Ответы29262

21 июля, 13:58 #327 #1029230

Привет, что почитать по паттернам?

И может кто, предложить решение этой задачи?
https://pastebin.com/Mmiz1HDU
Я смог наваять только такое:
https://pastebin.com/bwMZHvkg
Понимаю что криво, но куда копать не пойму.
Может, подскажите чего?

Ответы2951530004

21 июля, 14:52 #328 #1029262

>>1029221
хочу именно через бд

21 июля, 15:18 #329 #1029274

>>1029147
Да, похоже, оно. Благодарю.

someApprentice 21 июля, 15:43 #330 #1029290

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

>> Но я не понимаю как хранить ID сообщений - получается что для каждого пользователя оно теперь будет своё. Из этого вытекает, что нельзя будет как-то преобразовывать эти сообщения т.е. редактировать или удалять.
>Можно сделать 2 таблицы, одна для хранения id сообщений, другая для хранения зашифрованных копий сообщений для каждого получателя.
>При этом, чтобы связать сообщения, можно сделать какой-нибудь добавочный id. Можно например сделать таблицу сообщений (где и будет этот id), и отдельно таблицу, которая хранит копию сообщения для конкретного получателя.
Действительно, можно создать таблицу специально чтобы только хранить id, а ящики Inbox и Outbox будут хранить ещё и всё остальное (автора, контент, дату и т.д.).

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

Шифрование

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

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

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

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

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

>либо же (если есть много однотипных элементов) выгоднее ставить не много обработчиков, а один обработчик на родительский элемент и ловить всплывающие снизу дерева DOM события.
Вот так https://jsfiddle.net/jsqt57hz/2/ ?

>В твоем примере кода, когда ты вставляешь HTML код из template в DOM, тогда же надо и ставить обработчики, и делать это только один раз.
А я приводил в пример такой вариант, вы сказали что у виджета может быть свой обработчик событий:

https://arhivach.org/thread/266631/#1018809
>> А что если элемент появляется не сразу? Логично будет задать тогда при его выводе элемента (то есть обработчик будет частью отображения) или в контроллере?
>Во-первых, "установка обработчика" не обязательно значит "установка обработчика на DOM элемент". В виджете может быть своя система событий, и ставится обработчик на внутреннее событие виджета, а не на DOM элемент.

> У меня есть идея как при отключенном js опускать окно диалога до последнего сообщения - использовать якори.
> Это должно быть сделано с помощью функций JOIN и GROUP:
Я не очень понял, как выравнивание сообщений связано с SQL-запросами?
Не выравнивание, а опускание скролла сообщений до последнего сообщения, если я правильно понял терминологию.

Мы с помощью SQL-запросов получаем контакты и последние сообщения, и в ссылку контакта вставляем якорь на id последнего сообщения:

><a class="contact" ... href="conversation.php? ... #message-ID">someUser</a>
><div id="message-ID ... class="message">

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

someApprentice 21 июля, 15:43 #330 #1029290

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

>> Но я не понимаю как хранить ID сообщений - получается что для каждого пользователя оно теперь будет своё. Из этого вытекает, что нельзя будет как-то преобразовывать эти сообщения т.е. редактировать или удалять.
>Можно сделать 2 таблицы, одна для хранения id сообщений, другая для хранения зашифрованных копий сообщений для каждого получателя.
>При этом, чтобы связать сообщения, можно сделать какой-нибудь добавочный id. Можно например сделать таблицу сообщений (где и будет этот id), и отдельно таблицу, которая хранит копию сообщения для конкретного получателя.
Действительно, можно создать таблицу специально чтобы только хранить id, а ящики Inbox и Outbox будут хранить ещё и всё остальное (автора, контент, дату и т.д.).

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

Шифрование

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

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

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

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

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

>либо же (если есть много однотипных элементов) выгоднее ставить не много обработчиков, а один обработчик на родительский элемент и ловить всплывающие снизу дерева DOM события.
Вот так https://jsfiddle.net/jsqt57hz/2/ ?

>В твоем примере кода, когда ты вставляешь HTML код из template в DOM, тогда же надо и ставить обработчики, и делать это только один раз.
А я приводил в пример такой вариант, вы сказали что у виджета может быть свой обработчик событий:

https://arhivach.org/thread/266631/#1018809
>> А что если элемент появляется не сразу? Логично будет задать тогда при его выводе элемента (то есть обработчик будет частью отображения) или в контроллере?
>Во-первых, "установка обработчика" не обязательно значит "установка обработчика на DOM элемент". В виджете может быть своя система событий, и ставится обработчик на внутреннее событие виджета, а не на DOM элемент.

> У меня есть идея как при отключенном js опускать окно диалога до последнего сообщения - использовать якори.
> Это должно быть сделано с помощью функций JOIN и GROUP:
Я не очень понял, как выравнивание сообщений связано с SQL-запросами?
Не выравнивание, а опускание скролла сообщений до последнего сообщения, если я правильно понял терминологию.

Мы с помощью SQL-запросов получаем контакты и последние сообщения, и в ссылку контакта вставляем якорь на id последнего сообщения:

><a class="contact" ... href="conversation.php? ... #message-ID">someUser</a>
><div id="message-ID ... class="message">

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

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

21 июля, 16:28 #331 #1029314

Привет, помогите советом

Как дебажить Request/Response между React+Redux и Silex?

Я пытаюсь отправить POST запрос с помощью метода Fetch() на api своего приложения.
В хроме я вижу что запрос отправлен, и содержит некоторые данные, которые я отправляю.
Но, не могу получить эти данные в контроллере из Request с помощью all() и записать их в лог,
Monolog пишет пустую строку (или ноль).
Данные перед отправкой обрабатываю JSON.stringify(data) https://github.com/enotocode/birthday_reminder/blob/master/src/client/Login/actions.js#L49
на сервере массив из реквеста превращаю в строку implode() и пишу info(printf(data)) https://github.com/enotocode/birthday_reminder/blob/master/src/server/Controllers/SignupController.php#L23
Лог https://github.com/enotocode/birthday_reminder/blob/master/src/server/public/development.log#L51
Почему не получается вытянуть из реквеста данные? В чем может быть проблема?

Ответы293192933529339

159 Кб, 1304x768

21 июля, 16:33 #332 #1029319

>>1029314
Скрин из Chrome Devtools

Ответы29322

21 июля, 16:37 #333 #1029322

>>1029319
а что в $_POST то ?

Ответы29324

21 июля, 16:48 #334 #1029324

>>1029322
А как посмотреть?
Monolog выводит в лог пустую строку: log=implode($_POST); info(log)

Ответы2932730002

21 июля, 17:00 #335 #1029327

>>1029324
просто сделай
var_dump($_POST, $_GET);exit;
и глянь в хроме ответ сервера

Ответы2933229335

21 июля, 17:14 #336 #1029332

>>1029327
>var_dump($_POST, $_GET);exit;

array(size=0)
array(size=0)

21 июля, 17:23 #337 #1029335

>>1029314
>>1029327
После того как указал заголовки для запроса в аргументах к fetch ('Content-type', 'application/json; charset=utf-8'), монолог записал данные из запроса в лог. Но $_POST все равно пустой на момент срабатывания request->all()

21 июля, 17:28 #338 #1029339

>>1029314

Смотреть надо в инструментах разработчика - на тип запроса, на Content-Type и тело запроса (можно нажать view source рядом с request payload).

PHP при поступлении POST-запроса разбирает тело запроса и помещает параметры в переменную $_POST, откуда их берет Request.

Но PHP разбирает не любые данные, а только данные в 2 форматах (которые использует браузер для форм):

http://php.net/manual/ru/reserved.variables.post.php

> Ассоциативный массив данных, переданных скрипту через HTTP метод POST в случае использования в запросе в качестве HTTP Content-Type application/x-www-form-urlencoded или multipart/form-data .

Ты передаешь данные в каком-то своем придуманном формате и естественно что PHP их игнорирует. Причем формат у тебя странный - данные передаешь как JSON но с типом plain/text.

Проще всего не использовать JSON, а использовать один из стандартных способов кодирования. Либо использовать JSON и в PHP самому разбирать тело запроса.

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

Также, завис на этом коде, пока не понял, что тут 2 функции:

> .then(
> response => response.json(),
> error => console.log('An error occured.', error)
> )

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

Также, по моему у тебя ошибка в обработчике ошибок. error => console.log('An error occured.', error) возвращает null и это значит что дальше выполнится блок then с этим null ( json => dispatch(recieveInputs(json)) ). То есть ты как бы "обработал" ошибку и превратил ее в успешный результат. Если ты не выбросил исключение то это значит что ошибка полностью обработана.

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

Чтобы проверить, что ты разбираешься, вот тебе вопрос.

Что если сервер вернет неправильный JSON? В этом случае response => response.json выкинет исключение, then() его перехватит и что будет дальше? Выведется ли сообщение об ошибке или будет потеряно?

21 июля, 17:28 #338 #1029339

>>1029314

Смотреть надо в инструментах разработчика - на тип запроса, на Content-Type и тело запроса (можно нажать view source рядом с request payload).

PHP при поступлении POST-запроса разбирает тело запроса и помещает параметры в переменную $_POST, откуда их берет Request.

Но PHP разбирает не любые данные, а только данные в 2 форматах (которые использует браузер для форм):

http://php.net/manual/ru/reserved.variables.post.php

> Ассоциативный массив данных, переданных скрипту через HTTP метод POST в случае использования в запросе в качестве HTTP Content-Type application/x-www-form-urlencoded или multipart/form-data .

Ты передаешь данные в каком-то своем придуманном формате и естественно что PHP их игнорирует. Причем формат у тебя странный - данные передаешь как JSON но с типом plain/text.

Проще всего не использовать JSON, а использовать один из стандартных способов кодирования. Либо использовать JSON и в PHP самому разбирать тело запроса.

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

Также, завис на этом коде, пока не понял, что тут 2 функции:

> .then(
> response => response.json(),
> error => console.log('An error occured.', error)
> )

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

Также, по моему у тебя ошибка в обработчике ошибок. error => console.log('An error occured.', error) возвращает null и это значит что дальше выполнится блок then с этим null ( json => dispatch(recieveInputs(json)) ). То есть ты как бы "обработал" ошибку и превратил ее в успешный результат. Если ты не выбросил исключение то это значит что ошибка полностью обработана.

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

Чтобы проверить, что ты разбираешься, вот тебе вопрос.

Что если сервер вернет неправильный JSON? В этом случае response => response.json выкинет исключение, then() его перехватит и что будет дальше? Выведется ли сообщение об ошибке или будет потеряно?

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

21 июля, 19:22 #339 #1029394

>>1029339
>Но PHP разбирает не любые данные, а только данные в 2 форматах (которые использует браузер для форм)
Значит переменные $_POST и $_GET будут всегда пусты, если передавать данные в JSON формате? Существуют еще удобные способы проверять данные, которые получил PHP в теле запроса POST?

>Причем формат у тебя странный - данные передаешь как JSON но с типом plain/text.
Исправил, добавив заголовок ('Content-type', 'application/json; charset=utf-8');

>Проще всего не использовать JSON, а использовать один из стандартных способов кодирования.
Почему так проще? Для urlenencoded и form-data нужно специально кодировать данные менее удобным способом, чем JSON.stringify(). Или ты имеешь ввиду если передавать их из формы?

>Также, по коду я бы советовал вынести работу с API в отдельный слой, а не мешать все в кучу в actions.
>Также, по моему у тебя ошибка в обработчике ошибок.
Это условный код из мануала Redux, я еще не смотрел как сделаны реальные приложения. Но написано, что тут в конце цепочки не следует добавлять блок catch во избежание цикла с ошибкой 'Unexpected batch number' если рендеришь результат. Каменистое дно.

>Что если сервер вернет неправильный JSON? В этом случае response => response.json выкинет исключение, then() его перехватит и что будет дальше? Выведется ли сообщение об ошибке или будет потеряно?
Браузер вероятно выведет ошибку в консоли, и наверное она попадет в качестве аргумента в recieveInputs(json)

Ответы29411295232958130002

21 июля, 19:36 #340 #1029411

>>1029394

charset добавляется только для содержимого с типом text/＊. В JSON кодировка определена стандартом и указывать ее не надо.

Ответы29583

21 июля, 23:53 #341 #1029508

test

21 июля, 23:57 #342 #1029515

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

ну и точно нужно делить расчёт балов в модель\AR

Ответы29823

21 июля, 23:58 #343 #1029518

>>1029194
нужно писать хендлер , и когда реквест будет на не существ страницу , ловить это и записывать в бд после делать редирект на главную

22 июля, 00:00 #344 #1029519

>>1029149
если они уже есть в классе то в методе класса ты можешь ими оперировать через $this->foo , очевидно если это не статический метод

22 июля, 00:02 #345 #1029521

>>1029108
это js , синтаксис на c похож у многих языков , так как они почти все дети с языка

Ответы29579

22 июля, 00:04 #346 #1029522

>>1028612
запихнуть их очевидно в форму и делать сабмит
https://stackoverflow.com/questions/2309801/how-to-submit-checkbox-values-with-php-post-method

Ответы29537

22 июля, 00:09 #347 #1029523

>>1029394
>Значит переменные $_POST и $_GET будут всегда пусты, если передавать данные в JSON формате? Существуют еще удобные способы проверять данные, которые получил PHP в теле запроса POST?
>
пост будет пуст да , способы есть https://stackoverflow.com/questions/40108736/php-get-json-post-data

22 июля, 00:55 #348 #1029537

>>1029522
пиздец. Просто пиздец всё оказалось настолько просто. Спасибо тебе огромнейшее я столько думал над этим.

22 июля, 00:57 #349 #1029538

Скока надо дрочиться, чтобы получать 100 к ? За год полтора так вырасти можно ??

Ответы29540295532956930066

22 июля, 01:02 #350 #1029540

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

Всё в твоих руках.

Ответы29614

22 июля, 02:01 #351 #1029553

>>1029538

Маловероятно. Если бы все было так просто, все бы давно уже устроились работать программистами. Так как в РФ средняя зарплата за апр. 2017 - 38906 руб, а медианная (50% людей получают меньше этой цифры) - около 30 000 р

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

Ответы29613

22 июля, 02:40 #352 #1029569

>>1029538
если дрочиться только ради 100к то примерно никогда ...

Ответы29610

22 июля, 04:35 #353 #1029579

>>1029521
Ну так то да.

22 июля, 07:00 #354 #1029581

>>1029394
>>1029339
>>Что если сервер вернет неправильный JSON? В этом случае response => response.json выкинет исключение, then() его перехватит и что будет дальше? Выведется ли сообщение об ошибке или будет потеряно?
>Браузер вероятно выведет ошибку в консоли, и наверное она попадет в качестве аргумента в recieveInputs(json)

Прочитал про промисы статью кантора внимательнее, и провел эксперимент, если метод response.json() выкинет ошибку, то она не будет отображаться в консоли пишет кантор (но Chrome ее выводит), и поскольку следующий блок then() не имеет функции rejected, чтобы его вызвать, и в конце цепочки нет catch, то можно считать, шибка будет потеряна.

Ответы2983930000

22 июля, 07:35 #355 #1029583

>>1029411
>charset добавляется только для содержимого с типом text/＊. В JSON кодировка определена стандартом и указывать ее не надо.
Лол, пример взял из учебника Кантора. Проверил сам, действительно в стандарте написано что JSON text SHALL be encoded in UTF-8, UTF-16, or UTF-32, и UTF-8 по дефолту. Но разве это не подходит под случай "явное лучше не явного"?

Ответы29999

22 июля, 10:21 #356 #1029610

>>1029569
Почему ты так считаешь?

22 июля, 10:25 #357 #1029613

>>1029553
>средняя зарплата за апр. 2017 - 38906 руб
Чиво, блядь? Я про ДС, есличо. Тут стажёр эти ёбаные 40к будет получать уже в первый месяц работы.

Ответы29999

22 июля, 10:27 #358 #1029614

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

Ответы2962229999

22 июля, 10:31 #359 #1029617

Поцаны смотрите че сделал
file:///C:/Users/microwavenovka/Desktop/HTML5/Learning/Learn1.html

Ответы2968129997

22 июля, 10:36 #360 #1029622

>>1029614
>конечно если хватит ума
Помимо ума ещё нужны soft skills. За 200к их от тебя будут требовать, ибо выполняемые тобой функции будут выходить за рамки тупого кодинга.

22 июля, 13:29 #361 #1029681

>>1029617
круто))))0000

someApprentice 22 июля, 15:17 #362 #1029721

>>1028550
>Что касается твоей схемы, вместо 2 таблиц inbox/outbox можно сделать одну с полем типа сообщения.
А можно вообще не указывать этот тип. Зачем это может пригодиться?

Ответы29997

22 июля, 18:36 #363 #1029807

Начал вкатываться, какую версию php ставить?
Пятую или седьмую?

Ответы2981329997

22 июля, 18:43 #364 #1029813

>>1029807
можешь начать с 5.6 базовые знания применимы и для 7 , но на 5.6 ещё много легаси кода что == работе

Ответы29817

22 июля, 18:46 #365 #1029817

>>1029813
А 7 и 5.6 совместимы или нет?

Ответы29818

22 июля, 18:49 #366 #1029818

>>1029817
Всё, что написано на 5.6, будет работать на 7.

22 июля, 18:57 #367 #1029823

>>1029515
>сохранение через сингелтон очевидно
Я подумал, что подразумевается, что будет использоваться фрейворк и такое можно опустить.
>через фабрику
Зачем фабрику, почему не декоратор?

>ну и точно нужно делить расчёт балов в модель\AR
Это вообще не понял.

Ответы29845

69 Кб, 879x681

22 июля, 19:09 #368 #1029832

Аноны, почему ideone ничего не выводит?

Ответы2984629847

22 июля, 19:49 #369 #1029839

>>1029581

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

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

22 июля, 20:09 #370 #1029845

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

22 июля, 20:13 #371 #1029846

>>1029832
Потому что тело твоего цикла не выполняется ни разу. Уже в самом начале условие продолжения цикла $credit <= 5000 ложно.

Ответы29859

22 июля, 20:14 #372 #1029847

>>1029832
так как 1 всегда будет меньше 5000 , перечитай как работают циклы

Ответы29859

22 июля, 20:14 #373 #1029848

Почему здесь все таки няши, Рика в ОПпосте и хорошая шапка? Спасибо вам за то, что вы есть

22 июля, 20:35 #374 #1029859

>>1029846
>>1029847
Бля пиздец. Спасибо

22 июля, 20:38 #375 #1029861

Аноны, а как сделать, что бы вместо локалхост в адресной строке было название папки, в которой лежит сайт? Wamp сервер

Ответы2987829997

22 июля, 21:28 #376 #1029878

>>1029861
1. Настроить сервер и C:\Windows\System32\drivers\etc\hosts
2. Использовать протухший денвер
3. Перестать насиловать мозг бессмысленной херней и использзваь php -S 127.0.0.1:8888

Ответы2988229891

22 июля, 21:30 #377 #1029880

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

22 июля, 21:30 #378 #1029882

>>1029878
>использзваь
использовать

22 июля, 21:51 #379 #1029891

>>1029878
Про последнее не понял, что это такое, анон?
В денвере, кстати, тоже локалхост

Ответы29916

49 Кб, 900x450

22 июля, 21:52 #380 #1029892

Анон, такое дело. Первый день вообще пытаюсь делать скрипты из мануала. Решил улучшить задание на "условия", сделав дополнительный 3-ий кубик. Дополнительное условие на "дабл" получилось, на трипл - нет. Подскажи, пожалуйста, как лучше вбить 3 параметра в условие. Алсо, может есть какие замечания по имеющемуся коду?

Ответы3111731220

22 июля, 22:48 #381 #1029906

Аноны, как прикрутить дебаггер к phpStorm?

Ответы29911

22 июля, 22:55 #382 #1029911

>>1029906
https://www.jetbrains.com/help/phpstorm/configuring-xdebug.html

Ответы29914

22 июля, 23:04 #383 #1029914

>>1029911
Ебать, я такое в жизни не осилю

348 Кб, 800x599

22 июля, 23:07 #384 #1029916

>>1029891
Учи матчасть. Браузер узнает ip адрес сайта c благодаря dns или файлу hosts. Денвер перезаписывал на лету hosts в соответствии с именем папки. Но это все мхом поросло, c тех пор как в php встроили сервер и все современные фреймворки умеют запускать сайт в режиме разработки через него. Это обязательная часть скафолдинга. Ты сам можешь сам запускать php -S ip:port из папки с сайтом. Открой папку в проводнике и введи адресной строке cmd, нажми enter. Появится консоль. Введи в нее php -S 127.0.0.1:8080, жми enter.
Открой в браузере адрес 127.0.0.1:8080 или пропиши в hosts:
название_сайта 127.0.0.1.
Тогда можешь открывать сайт по имени. Главное необходимо прописать путь к php в переменную среды Path, как на пике.

Ответы29930

22 июля, 23:44 #385 #1029930

>>1029916
лол править hots , говорить что всё мхом поросло
не проше использовать тот же OpenServer который делает это всё автоматом при запуске

Ответы29938

23 июля, 00:00 #386 #1029938

>>1029930
Нахуя вооще что-то править, превращать десктоп в сервер. Запускай laravel через artisan, попивая смузи.
Если надо больше - используй VM и готовые аплиансы или vargant https://app.vagrantup.com/boxes/search

Ответы2994129943

23 июля, 00:05 #387 #1029941

>>1029938
vagrant

23 июля, 00:11 #388 #1029943

>>1029938
можно то и doker но проблема в том что зачем мне пердолиться с всей этой штукой день , если я могу поставить опен сервер и запустить вс в 2 клика ?

Ответы29948

23 июля, 00:18 #389 #1029948

>>1029943
А зачем тогда сервер? Достаточно только php, ну и composer. В php есть сервер для разработки, есть sqlite

Ответы29993

ОП, проверь задачи, пожалуйста 23 июля, 00:55 #390 #1029961

Grammar Nazi - https://ideone.com/zli0sE
Опечаточник - https://ideone.com/eumFsz
Yoda Speak - https://3v4l.org/46mlk
Пиши верно - https://3v4l.org/OU9Ru
Сумма прописью - https://3v4l.org/GLjK8
Я у мамы калькулятор - https://3v4l.org/3O7ng

23 июля, 03:45 #391 #1029993

>>1029948
редисы , постгресы и тд

23 июля, 06:24 #392 #1029997

>>1027835

Про фигурные скобки - тут http://php.net/manual/ru/language.types.string.php#language.types.string.parsing

> кубы http://ideone.com/LitWO1

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

> айфон http://ideone.com/lHOqEL
Ок, тоже верно.

>>1029861

В случае с Апачем это делается так. Придумать домен, вписать его в hosts (чтобы браузер мог преобразовать домен в IP адрес), затем добавить VirtualHost в конфиг Апача, чтобы он знал, в какой папке лежит этот сайт. Но в слусае WAMP может это как-то по-другому делается, ты документацию смотреть не пробовал?

>>1029807

Любую, можно 7, только выучи отличия между этими версиями.

>>1029721

Не знаю, если ты можешь без этого обойтись, то можно и не делать.

>>1029617

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

23 июля, 06:24 #392 #1029997

>>1027835

Про фигурные скобки - тут http://php.net/manual/ru/language.types.string.php#language.types.string.parsing

> кубы http://ideone.com/LitWO1

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

> айфон http://ideone.com/lHOqEL
Ок, тоже верно.

>>1029861

В случае с Апачем это делается так. Придумать домен, вписать его в hosts (чтобы браузер мог преобразовать домен в IP адрес), затем добавить VirtualHost в конфиг Апача, чтобы он знал, в какой папке лежит этот сайт. Но в слусае WAMP может это как-то по-другому делается, ты документацию смотреть не пробовал?

>>1029807

Любую, можно 7, только выучи отличия между этими версиями.

>>1029721

Не знаю, если ты можешь без этого обойтись, то можно и не делать.

>>1029617

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

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

23 июля, 06:25 #393 #1029999

>>1029614

Сильно захотеть недостаточно.

>>1029613

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

>>1029583

Я посмотрел RFC, который определяет тип application/json: https://tools.ietf.org/html/rfc4627

Там написано:

> The MIME media type for JSON text is application/json.
> Required parameters: n/a
> Optional parameters: n/a
charset - это именно parameter и тут он не определен.

Также, там написано, что кодировка определяется по кодированию первых 2 символов в JSON-данных.

Также, для надежности, я глянул еще RFC по MIME-типам: https://tools.ietf.org/html/rfc2046#section-4.1.2

> Charset Parameter
> A critical parameter that may be specified in the Content-Type field
> for "text/plain" data is the character set
> ....
> The specification for any future subtypes of "text" must specify
> whether or not they will also utilize a "charset" parameter, and may
> possibly restrict its values as well.
> ...
> Other media types than subtypes of "text" might choose to employ the
> charset parameter as defined here, but with the CRLF/line break
> restriction removed.
> ....
> The "charset" parameter has been defined primarily for the purpose of
> textual data, and is described in this section for that reason.
> However, it is conceivable that non-textual data might also wish to
> specify a charset value for some purpose, in which case the same
> syntax and values should be used.

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

23 июля, 06:25 #393 #1029999

>>1029614

Сильно захотеть недостаточно.

>>1029613

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

>>1029583

Я посмотрел RFC, который определяет тип application/json: https://tools.ietf.org/html/rfc4627

Там написано:

> The MIME media type for JSON text is application/json.
> Required parameters: n/a
> Optional parameters: n/a
charset - это именно parameter и тут он не определен.

Также, там написано, что кодировка определяется по кодированию первых 2 символов в JSON-данных.

Также, для надежности, я глянул еще RFC по MIME-типам: https://tools.ietf.org/html/rfc2046#section-4.1.2

> Charset Parameter
> A critical parameter that may be specified in the Content-Type field
> for "text/plain" data is the character set
> ....
> The specification for any future subtypes of "text" must specify
> whether or not they will also utilize a "charset" parameter, and may
> possibly restrict its values as well.
> ...
> Other media types than subtypes of "text" might choose to employ the
> charset parameter as defined here, but with the CRLF/line break
> restriction removed.
> ....
> The "charset" parameter has been defined primarily for the purpose of
> textual data, and is described in this section for that reason.
> However, it is conceivable that non-textual data might also wish to
> specify a charset value for some purpose, in which case the same
> syntax and values should be used.

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

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

23 июля, 06:25 #394 #1030000

>>1029581

> и поскольку следующий блок then() не имеет функции rejected, чтобы его вызвать
Вот тут неточность. Ошибка теряется не поэтому.

Если ты не передаешь функцию onRejected в then, то вместо нее будет подставлена функция function Thrower(e) { throw e; }. Это не вызывает потерю ошибки.

Ошибка в твоем коде в том, что функция-обработчик ошибки error => console.log(error) не выкидывает исключение, а возвращает null и это значит, что ошибка обработана и новый промис резолвится в это значение, и этот null передается дальше по цепочке then.

То есть, разберем такой пример:

var p = new Promise(function (resolve, reject) {
reject(new Error);
});

var p2 = p.then(function () {}, function (e) {
console.log(e);
return null; // ошибка, должно быть throw
});

p2.then(....);

В данном примере - p будет rejected, но p2 будет resolved в значение null, так как мы обработали ошибку в then и вернули новое значение. Чтобы p2 также была rejected, мы должны вместо return null поставить throw e; то есть перевыбросить исключение.

То есть функция-обработчик (onFullfilled, onRejected) может либо выбросить исключение - в этом случае p2 будет rejected, либо что-то вернуть - в этом случае p2 ресолвится в это значение.

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

Вообще, может быть, тебе стоит разобрать пример реализации промисов вот тут: https://www.promisejs.org/implementing/ ?

----

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

var result = array.filter(function (x) { return x > 0; });
var result = array.filter(x => x > 0);

В этом примере код со стрелочной функцией короче и читабельнее.

Но в твоем примере, error => console.log(error) - я не уверен, что использование стрелочной функции тут улучшает читабельность кода. Хотя бы потому, что в твоем коде подразумевается { return console.log(error); } и я не понимаю, зачем тут return.

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

К сожалению, и в официальных мануалах этого не понимают. Вот пример из документации MDN ( https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions ):

> // Destructuring within the parameter list is also supported
> var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
Это какой-то антипример, как писать ни в коем случае не надо, так как я это даже прочесть не могу. Что это вообще такое?

К тому же они умудрились создать конфликт в синтаксисе стрелочных функций с синтаксисом литералов-объектов:

> var func = () => { foo: 1 };
> // Вызов func() возвращает undefined!

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

23 июля, 06:25 #394 #1030000

>>1029581

> и поскольку следующий блок then() не имеет функции rejected, чтобы его вызвать
Вот тут неточность. Ошибка теряется не поэтому.

Если ты не передаешь функцию onRejected в then, то вместо нее будет подставлена функция function Thrower(e) { throw e; }. Это не вызывает потерю ошибки.

Ошибка в твоем коде в том, что функция-обработчик ошибки error => console.log(error) не выкидывает исключение, а возвращает null и это значит, что ошибка обработана и новый промис резолвится в это значение, и этот null передается дальше по цепочке then.

То есть, разберем такой пример:

var p = new Promise(function (resolve, reject) {
reject(new Error);
});

var p2 = p.then(function () {}, function (e) {
console.log(e);
return null; // ошибка, должно быть throw
});

p2.then(....);

В данном примере - p будет rejected, но p2 будет resolved в значение null, так как мы обработали ошибку в then и вернули новое значение. Чтобы p2 также была rejected, мы должны вместо return null поставить throw e; то есть перевыбросить исключение.

То есть функция-обработчик (onFullfilled, onRejected) может либо выбросить исключение - в этом случае p2 будет rejected, либо что-то вернуть - в этом случае p2 ресолвится в это значение.

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

Вообще, может быть, тебе стоит разобрать пример реализации промисов вот тут: https://www.promisejs.org/implementing/ ?

----

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

var result = array.filter(function (x) { return x > 0; });
var result = array.filter(x => x > 0);

В этом примере код со стрелочной функцией короче и читабельнее.

Но в твоем примере, error => console.log(error) - я не уверен, что использование стрелочной функции тут улучшает читабельность кода. Хотя бы потому, что в твоем коде подразумевается { return console.log(error); } и я не понимаю, зачем тут return.

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

К сожалению, и в официальных мануалах этого не понимают. Вот пример из документации MDN ( https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions ):

> // Destructuring within the parameter list is also supported
> var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
Это какой-то антипример, как писать ни в коем случае не надо, так как я это даже прочесть не могу. Что это вообще такое?

К тому же они умудрились создать конфликт в синтаксисе стрелочных функций с синтаксисом литералов-объектов:

> var func = () => { foo: 1 };
> // Вызов func() возвращает undefined!

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

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

23 июля, 06:26 #395 #1030002

>>1029394

> Существуют еще удобные способы проверять данные, которые получил PHP в теле запроса POST?
Ты можешь прочитать тело POST и распарсить его самостоятельно или используя какую-нибудь библиотеку (а можешь даже написать и опубликовать свою): http://php.net/manual/ru/wrappers.php.php#wrappers.php.input

> Для urlenencoded и form-data нужно специально кодировать данные менее удобным способом, чем JSON.stringify().
Некоторые библиотеки (jQuery) умеют кодировать их автоматически, также доступен объект FormData, который умеет их кодировать. Наверно, кодировать на стороне клиента их было бы проще, чем впиливать поддержку на стороне PHP, но я в общем-то ничего против передачи JSON не имею - стандартам это никак не противоречит при указании корректных Content-Type/Content-Length

> Но написано, что тут в конце цепочки не следует добавлять блок catch во избежание цикла с ошибкой 'Unexpected batch number' если рендеришь результат.
Лучше бы разобраться, что это значит, так как я, например, вообще ничего не понял и первый раз слышу про эту ошибку.

В любом случае, ошибки нужно обрабатывать. Ты не должен полагаться на то, что сервер будет доступен в 100% случаев и всегда выдавать корректные ответы. Вот мой урок про аякс, перечитай его, если еще не читал, там упоминаются ошибки: https://github.com/codedokode/pasta/blob/master/js/ajax.md

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

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

>>1029324

Для дампа данных лучше использовать не implode, а print_r(..., true) или var_export или (внезапно) json_encode. Я обычно просто ставлю var_dump(); die() и смотрю в отладчике ответ.

Кстати, в отладчике Хрома в Network есть несколько полезных функций, вызываемых через правую кнопку. Это replay request и возможность скопировать командную строку для curl для отправки такого же запроса со всеми заголовками из консоли.

23 июля, 06:26 #395 #1030002

>>1029394

> Существуют еще удобные способы проверять данные, которые получил PHP в теле запроса POST?
Ты можешь прочитать тело POST и распарсить его самостоятельно или используя какую-нибудь библиотеку (а можешь даже написать и опубликовать свою): http://php.net/manual/ru/wrappers.php.php#wrappers.php.input

> Для urlenencoded и form-data нужно специально кодировать данные менее удобным способом, чем JSON.stringify().
Некоторые библиотеки (jQuery) умеют кодировать их автоматически, также доступен объект FormData, который умеет их кодировать. Наверно, кодировать на стороне клиента их было бы проще, чем впиливать поддержку на стороне PHP, но я в общем-то ничего против передачи JSON не имею - стандартам это никак не противоречит при указании корректных Content-Type/Content-Length

> Но написано, что тут в конце цепочки не следует добавлять блок catch во избежание цикла с ошибкой 'Unexpected batch number' если рендеришь результат.
Лучше бы разобраться, что это значит, так как я, например, вообще ничего не понял и первый раз слышу про эту ошибку.

В любом случае, ошибки нужно обрабатывать. Ты не должен полагаться на то, что сервер будет доступен в 100% случаев и всегда выдавать корректные ответы. Вот мой урок про аякс, перечитай его, если еще не читал, там упоминаются ошибки: https://github.com/codedokode/pasta/blob/master/js/ajax.md

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

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

>>1029324

Для дампа данных лучше использовать не implode, а print_r(..., true) или var_export или (внезапно) json_encode. Я обычно просто ставлю var_dump(); die() и смотрю в отладчике ответ.

Кстати, в отладчике Хрома в Network есть несколько полезных функций, вызываемых через правую кнопку. Это replay request и возможность скопировать командную строку для curl для отправки такого же запроса со всеми заголовками из консоли.

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

23 июля, 06:27 #396 #1030003

>>1029290

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

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

> Действительно, можно создать таблицу специально чтобы только хранить id, а ящики Inbox и Outbox будут хранить ещё и всё остальное (автора, контент, дату и т.д.).
Еще можно рассмотреть вариант - добавить в сообщение внутренний id, который генерируется на клиенте, шифруется и не виден серверу. При редактировании сообщения мы просто посылаем второе сообщение с таким же внутренним id, и контакт понимает, что оно было отредактировано.

> Я уже немного знаком с ним, но почему-то даже не могу придумать функцию которая будет шифровать сообщения.
Поискать готовую в библиотеке openssl: http://php.net/manual/ru/book.openssl.php

Вот статья например https://www.devco.net/archives/2006/02/13/public_-_private_key_encryption_using_openssl.php - можно то же самое делать с использованием функций openssl.

Погугли по "openssl encrypt data asymmetric"

Также, можно посмотреть протоколы Tox, Signal, и расширение OTR для Jabber и посмотреть как поступают они.

> Меня сначала смутило что без js тогда не будет работать приложение,
Чтобы приложение работало без JS, мы должны доверить операции шифрования/расшифровки (и все наши ключи) серверу. То есть поступиться безопасностью.

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

То есть чтобы работать без JS, нужно снизить степень защищенности и доверять серверу.

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

Я тут не вижу проблемы. Вот допустим, у нас есть кнопка на странице. Мы нашли ее, поставили на нее обработчик DOM события и больше не добавляем. Или мы создаем кнопку, вставляем в DOM, ставим один раз обработчик и больше не добавляем его. Не важно, контроллер это или view делает, лишь бы DOM-обработчик ставился один раз. Нужно это так спроектировать. MVC тут вообще не при чем.

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

>>либо же (если есть много однотипных элементов) выгоднее ставить не много обработчиков, а один обработчик на родительский элемент и ловить всплывающие снизу дерева DOM события.
> Вот так https://jsfiddle.net/jsqt57hz/2/ ?
да. Это обычно применяют для каких-то списков, где много однотипных элементов.

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

Когда я говорил, про "свои" события, я имел в виду систему, когда view сам ставит DOM-обработчик (например, клика на контакт в списке), обрабатывает это событие и генерирует свое, искуственное событие вроде onContactSelect. И контроллер подписывается именно на это искуственное событие, а не лезет в DOM.

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

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

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

> Заодно можно сделать и сортировку контактов по последним полученным сообщениям.
Через группировку это будет неэффективно, так как будет обзодиться большое число записей (все сообщения для каждого контакта). Такую сортировку лучше сделать денормализацией, добавив поле lastMessageTime в таблицу контактов. Опять же, стоит помнить что это лишняя незащищенная информация.

23 июля, 06:27 #396 #1030003

>>1029290

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

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

> Действительно, можно создать таблицу специально чтобы только хранить id, а ящики Inbox и Outbox будут хранить ещё и всё остальное (автора, контент, дату и т.д.).
Еще можно рассмотреть вариант - добавить в сообщение внутренний id, который генерируется на клиенте, шифруется и не виден серверу. При редактировании сообщения мы просто посылаем второе сообщение с таким же внутренним id, и контакт понимает, что оно было отредактировано.

> Я уже немного знаком с ним, но почему-то даже не могу придумать функцию которая будет шифровать сообщения.
Поискать готовую в библиотеке openssl: http://php.net/manual/ru/book.openssl.php

Вот статья например https://www.devco.net/archives/2006/02/13/public_-_private_key_encryption_using_openssl.php - можно то же самое делать с использованием функций openssl.

Погугли по "openssl encrypt data asymmetric"

Также, можно посмотреть протоколы Tox, Signal, и расширение OTR для Jabber и посмотреть как поступают они.

> Меня сначала смутило что без js тогда не будет работать приложение,
Чтобы приложение работало без JS, мы должны доверить операции шифрования/расшифровки (и все наши ключи) серверу. То есть поступиться безопасностью.

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

То есть чтобы работать без JS, нужно снизить степень защищенности и доверять серверу.

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

Я тут не вижу проблемы. Вот допустим, у нас есть кнопка на странице. Мы нашли ее, поставили на нее обработчик DOM события и больше не добавляем. Или мы создаем кнопку, вставляем в DOM, ставим один раз обработчик и больше не добавляем его. Не важно, контроллер это или view делает, лишь бы DOM-обработчик ставился один раз. Нужно это так спроектировать. MVC тут вообще не при чем.

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

>>либо же (если есть много однотипных элементов) выгоднее ставить не много обработчиков, а один обработчик на родительский элемент и ловить всплывающие снизу дерева DOM события.
> Вот так https://jsfiddle.net/jsqt57hz/2/ ?
да. Это обычно применяют для каких-то списков, где много однотипных элементов.

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

Когда я говорил, про "свои" события, я имел в виду систему, когда view сам ставит DOM-обработчик (например, клика на контакт в списке), обрабатывает это событие и генерирует свое, искуственное событие вроде onContactSelect. И контроллер подписывается именно на это искуственное событие, а не лезет в DOM.

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

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

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

> Заодно можно сделать и сортировку контактов по последним полученным сообщениям.
Через группировку это будет неэффективно, так как будет обзодиться большое число записей (все сообщения для каждого контакта). Такую сортировку лучше сделать денормализацией, добавив поле lastMessageTime в таблицу контактов. Опять же, стоит помнить что это лишняя незащищенная информация.

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

23 июля, 06:28 #397 #1030004

>>1029230

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

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

В checkAnswer ничего не передается - что он проверяет? Та же проблема в CalcScore.

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

В твоем коде я вижу проблемные места - например, статический метод работы с БД, который не позволит тут использовать DI (урок по DI https://github.com/codedokode/pasta/blob/master/arch/di.md ). Мануалов по Юи перечитался?

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

>>1029194

При заходе на несущ. страницу надо показывать страницу 404, а не редиректить. Редирект значит "эта страница есть, но по другому адресу".

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

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

>>1029149

> Как передавать в конструктор значение с поля класса?
Обычным образом. Какого-то специального синтаксиса для этого нет.

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

Прокомментирую еще:

> public $endStavka; // окончательная ставка, вычисляется через функцию EndStavka
Не стоит хранить данные, которые вычисляются из других полей, так как в этом случае ты обязан их обновлять при изменении любого из исходных полей и тут легко что-то пропустить. Храни только исходные данные, а вычисляемые не храни вообще. То есть сделай метод для вычисления зарплаты.

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

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

23 июля, 06:28 #397 #1030004

>>1029230

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

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

В checkAnswer ничего не передается - что он проверяет? Та же проблема в CalcScore.

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

В твоем коде я вижу проблемные места - например, статический метод работы с БД, который не позволит тут использовать DI (урок по DI https://github.com/codedokode/pasta/blob/master/arch/di.md ). Мануалов по Юи перечитался?

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

>>1029194

При заходе на несущ. страницу надо показывать страницу 404, а не редиректить. Редирект значит "эта страница есть, но по другому адресу".

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

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

>>1029149

> Как передавать в конструктор значение с поля класса?
Обычным образом. Какого-то специального синтаксиса для этого нет.

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

Прокомментирую еще:

> public $endStavka; // окончательная ставка, вычисляется через функцию EndStavka
Не стоит хранить данные, которые вычисляются из других полей, так как в этом случае ты обязан их обновлять при изменении любого из исходных полей и тут легко что-то пропустить. Храни только исходные данные, а вычисляемые не храни вообще. То есть сделай метод для вычисления зарплаты.

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

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

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

23 июля, 06:28 #398 #1030006

>>1028685

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

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

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

>>1028597

У тебя такие аналогии, я надеюсь, они не на твоем жизненном опыте основаны.

>>1028470

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

>>1027651

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

> Как-то не хочется оставлять пустую функцию
Не вижу в чем тут проблема.

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

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

> Почему у меня не вбрасываются эти ошибки (ошибки не появляются в консоле)? Это из-за асинхронного кода?

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

// p резолвится в значение 1
var p = new Promise(function (resolve, reject) {
resolve(1);
});

// обработчик выбрасывает исключение, потому p2 реджектится в эту ошибку
var p2 = p.then(function (val) {
throw new Error();
});

Что-то ты не очень знаешь, как работают промисы. Может быть, тебе стоит разобрать пример реализации вот тут: https://www.promisejs.org/implementing/ ?

И еще, напомню, что промисы jQuery не соответствуюют спецификации Promise/A+, которая используется в языке JS. У них свои несовместимые промисы.

И еще, у тебя обработка ошибок странно сделана:

> that.backend.postMessage(to, message, token).then(
> ....
> function(jqXHR, textStatus) {
> ...
> that.backend.handleError(jqXHR, textStatus);
> }

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

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

> К сожалению, у меня не получилось найти в ejs аналог функции nl2br и при этом чтобы экранировались тэги. В таком случае, будет приемлемым оставить этот костыль?
nl2br не экранирует теги, она только заменяет \n на <br>, если я не путаю.

Насколько я понял, у тебя проблема в том, что ejs экранирует данные и твой <br> выводится как текст? В документации ( https://github.com/mde/ejs/blob/master/docs/syntax.md ) написано что есть 2 вида тегов, один принимают текст, экранируют его и выводят, другой тег принимает HTML код и вставляет его как есть.

В чем именно сложность-то? Можно сделать так <%- convertMessageToHtml(message) %>

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

Сам метод public function send($apiMode = false) явно нарушает MVC и представляет пример "толстого" контроллера. Метод отправки должен быть в модели.

Что касается if ($apiMode), тут тоже все как-то странно, тут можно было бы это обобщить, например, сделать специальное исключение ApiError, ловить его и в зависимости от режима выдавать разный ответ.

То есть нет, сделано конечно неудачно. Стена кода какая-то с 7 уровнями вложенности.

> Я плохо понял что такое REST. Это просто архитектура которая позволяет обрабатывать запросы с методами вроде PUT\DELETE?

Это набор принципов, которые можно использовать при проектировании API. Что есть ресурсы (URL), с которыми можно делать разные действия (выражаемые методами). Ну например, PUT /user/ivan/inbox - отправить сообщение Ивану. Лучше посмотреть на примере REST API Яндекс-диска например.

Чистый REST не для каждой задачи хорошо подходит, конечно.

> Я никак не могу придумать как выводить только новые сообщения. Определенно, нужен setTimeout\setInterval чтобы постоянно обновлять данные с сервера, но как при этом выводить только те сообщения которые ещё не выведены в шаблон?
Для этого клиент должен "знать", какие сообщения выведены, и запрашивать с сервера только новые, и добавлять только новые. Чтобы это реализовать, нужно спроектировать изменения в нескольких компонентах:

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

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

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

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

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

> Не подвергаю ли я пользователей опасности, открывая кукисы для js?
Нет наверно.

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

И конечно, странно, что у тебя token хранится в view.

> У меня есть переменные, которые пишутся ни как camelCase или snake_case, например moremessages. Я знаю, что это плохой плохой вариант, но мне он кажется вполне читабельным. Лучше будет переимновать?
Да, переименовать. Я бы не сказал, что это читабельно.

23 июля, 06:28 #398 #1030006

>>1028685

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

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

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

>>1028597

У тебя такие аналогии, я надеюсь, они не на твоем жизненном опыте основаны.

>>1028470

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

>>1027651

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

> Как-то не хочется оставлять пустую функцию
Не вижу в чем тут проблема.

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

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

> Почему у меня не вбрасываются эти ошибки (ошибки не появляются в консоле)? Это из-за асинхронного кода?

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

// p резолвится в значение 1
var p = new Promise(function (resolve, reject) {
resolve(1);
});

// обработчик выбрасывает исключение, потому p2 реджектится в эту ошибку
var p2 = p.then(function (val) {
throw new Error();
});

Что-то ты не очень знаешь, как работают промисы. Может быть, тебе стоит разобрать пример реализации вот тут: https://www.promisejs.org/implementing/ ?

И еще, напомню, что промисы jQuery не соответствуюют спецификации Promise/A+, которая используется в языке JS. У них свои несовместимые промисы.

И еще, у тебя обработка ошибок странно сделана:

> that.backend.postMessage(to, message, token).then(
> ....
> function(jqXHR, textStatus) {
> ...
> that.backend.handleError(jqXHR, textStatus);
> }

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

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

> К сожалению, у меня не получилось найти в ejs аналог функции nl2br и при этом чтобы экранировались тэги. В таком случае, будет приемлемым оставить этот костыль?
nl2br не экранирует теги, она только заменяет \n на <br>, если я не путаю.

Насколько я понял, у тебя проблема в том, что ejs экранирует данные и твой <br> выводится как текст? В документации ( https://github.com/mde/ejs/blob/master/docs/syntax.md ) написано что есть 2 вида тегов, один принимают текст, экранируют его и выводят, другой тег принимает HTML код и вставляет его как есть.

В чем именно сложность-то? Можно сделать так <%- convertMessageToHtml(message) %>

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

Сам метод public function send($apiMode = false) явно нарушает MVC и представляет пример "толстого" контроллера. Метод отправки должен быть в модели.

Что касается if ($apiMode), тут тоже все как-то странно, тут можно было бы это обобщить, например, сделать специальное исключение ApiError, ловить его и в зависимости от режима выдавать разный ответ.

То есть нет, сделано конечно неудачно. Стена кода какая-то с 7 уровнями вложенности.

> Я плохо понял что такое REST. Это просто архитектура которая позволяет обрабатывать запросы с методами вроде PUT\DELETE?

Это набор принципов, которые можно использовать при проектировании API. Что есть ресурсы (URL), с которыми можно делать разные действия (выражаемые методами). Ну например, PUT /user/ivan/inbox - отправить сообщение Ивану. Лучше посмотреть на примере REST API Яндекс-диска например.

Чистый REST не для каждой задачи хорошо подходит, конечно.

> Я никак не могу придумать как выводить только новые сообщения. Определенно, нужен setTimeout\setInterval чтобы постоянно обновлять данные с сервера, но как при этом выводить только те сообщения которые ещё не выведены в шаблон?
Для этого клиент должен "знать", какие сообщения выведены, и запрашивать с сервера только новые, и добавлять только новые. Чтобы это реализовать, нужно спроектировать изменения в нескольких компонентах:

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

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

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

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

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

> Не подвергаю ли я пользователей опасности, открывая кукисы для js?
Нет наверно.

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

И конечно, странно, что у тебя token хранится в view.

> У меня есть переменные, которые пишутся ни как camelCase или snake_case, например moremessages. Я знаю, что это плохой плохой вариант, но мне он кажется вполне читабельным. Лучше будет переимновать?
Да, переименовать. Я бы не сказал, что это читабельно.

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

23 июля, 06:29 #399 #1030007

>>1027168

Тут написано http://php.net/manual/ru/language.variables.scope.php

>>1026920

Рисуют дизайн в графическом редакторе, а затем его верстают, то есть переводят в HTML/CSS/картинки. Браузер фотошопные файлы не отображает, и они фиксированного размера, не подстраиваются под размер экрана например. В отличие от HTML/CSS.

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

>>1026318

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

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

Наверно, тебе подойдут сценарии. Погугли.

>>1026257

В фронт-контроллере (или входном скрипте). Хочу только предупредить, что сессии плохо подходят для авторизации так как умирают через 30 минут неактивности.

> И где проверять может ли пользователь находиться на странице, private метод контроллера checkAuth() в каждом экшне?
Можно метод в базовом контроллере, можно отдельный класс для этого сделать.

>>1026198

Я Юи2 не использовал, так что сказать, увы, ничего не могу.

23 июля, 06:29 #399 #1030007

>>1027168

Тут написано http://php.net/manual/ru/language.variables.scope.php

>>1026920

Рисуют дизайн в графическом редакторе, а затем его верстают, то есть переводят в HTML/CSS/картинки. Браузер фотошопные файлы не отображает, и они фиксированного размера, не подстраиваются под размер экрана например. В отличие от HTML/CSS.

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

>>1026318

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

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

Наверно, тебе подойдут сценарии. Погугли.

>>1026257

В фронт-контроллере (или входном скрипте). Хочу только предупредить, что сессии плохо подходят для авторизации так как умирают через 30 минут неактивности.

> И где проверять может ли пользователь находиться на странице, private метод контроллера checkAuth() в каждом экшне?
Можно метод в базовом контроллере, можно отдельный класс для этого сделать.

>>1026198

Я Юи2 не использовал, так что сказать, увы, ничего не могу.

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

23 июля, 07:53 #400 #1030018

>>1029999
>Сильно захотеть недостаточно.
Поэтому ты на том уровне где ты и есть.

someApprentice 23 июля, 10:01 #401 #1030039

>>1030003
>> Меня сначала смутило что без js тогда не будет работать приложение,
>Чтобы приложение работало без JS, мы должны доверить операции шифрования/расшифровки (и все наши ключи) серверу. То есть поступиться безопасностью.
>То есть чтобы работать без JS, нужно снизить степень защищенности и доверять серверу.
Можно сделать режим для шифрования\расшифровки сообщений.

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

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

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

Иметь собственное приложение - это хорошо.

Если взломать сервер, то может произойти всё что угодно.

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

https://github.com/someApprentice/chat/blob/master/public/js/contacts.js#L71

Я вывожу окно переписки

и вот здесь

https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L121-L124

я вывожу форму и ставлю на неё обработчики.

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

someApprentice 23 июля, 10:01 #401 #1030039

>>1030003
>> Меня сначала смутило что без js тогда не будет работать приложение,
>Чтобы приложение работало без JS, мы должны доверить операции шифрования/расшифровки (и все наши ключи) серверу. То есть поступиться безопасностью.
>То есть чтобы работать без JS, нужно снизить степень защищенности и доверять серверу.
Можно сделать режим для шифрования\расшифровки сообщений.

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

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

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

Иметь собственное приложение - это хорошо.

Если взломать сервер, то может произойти всё что угодно.

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

https://github.com/someApprentice/chat/blob/master/public/js/contacts.js#L71

Я вывожу окно переписки

и вот здесь

https://github.com/someApprentice/chat/blob/master/public/js/conversation.js#L121-L124

я вывожу форму и ставлю на неё обработчики.

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

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

23 июля, 11:51 #402 #1030066

>>1029538
Можно.

мимо 110k php-джун

someApprentice 23 июля, 12:15 #403 #1030074

>>1030003
>> Я уже немного знаком с ним, но почему-то даже не могу придумать функцию которая будет шифровать сообщения.
>Поискать готовую в библиотеке openssl: http://php.net/manual/ru/book.openssl.php
А шифровать копию сообщения собеседника, если его ключ зашифрован паролем?

Ответы3007530299

someApprentice 23 июля, 12:16 #404 #1030075

>>1030074
как*

23 июля, 12:32 #405 #1030078

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

Ответы31757

23 июля, 14:00 #406 #1030104

ОП, выручай, вот мой говнокод по Вектору http://ideone.com/FMRyCa.
но функция которая возвращает окончательную ставку сотрудника работает неправильно, подскажи что не так

Ответы3010630117301493015233109

23 июля, 14:04 #407 #1030106

>>1030104
Откуда берётся ранг?

Ответы30124

23 июля, 14:35 #408 #1030117

>>1030104
404

Ответы30124

23 июля, 14:52 #409 #1030124

>>1030117
http://ideone.com/FMRyCa
>>1030106
из класса Департамент

Ответы30132

23 июля, 15:29 #410 #1030132

>>1030124
А в какой момент ранг появляется в сотруднике? А в какой момент считается endStavka? А в какой момент в поле сотрудника записывается endStavka?

Ответы3015330176

23 июля, 16:04 #411 #1030149

>>1030104
Честно говоря, ничего не понятно. Сам почему не можешь найти? xDebug не настроил?

23 июля, 16:12 #412 #1030152

>>1030104
Хотя. Ошибка в том, что ты создаёшь работника, не передавая ему ранг. Конструктор считает уже конечную ставку с коэффициентом 1, т.к. ранг у тебя не 2 и не 3 (null). Потом ты уже назначаешь работнику ранг (зп после этого, конечно, не пересчитывается) и загоняешь работника в массив.

Ответы30153

23 июля, 16:15 #413 #1030153

>>1030152
Разобрался сам? Молодец!
Помог анону? Сомневаюсь.
Он получил бы больше, если бы нашёл свою ошибку сам, ответив на вопросы: >>1030132

23 июля, 16:49 #414 #1030174

Что лучше xDebug или ZenDebug?

Ответы30199

23 июля, 16:52 #415 #1030176

>>1030132
Ранг присваивается в цикле, после создания объекта,но как заставить работать именно после присвоения ранга я не знаю, только если всегда повторно вызывать метод

23 июля, 17:00 #416 #1030184

>>1019301 (OP)
Няши,есть задача: распарсить при помощи xgettext все строки и создать словарь, но эта мразь парсит все,что в двойных кавычках. Как заставить эту пиздоту хватать только то, что обрамлено в _("хуй пизда сковорода")?

Ответы3019933109

23 июля, 18:10 #417 #1030198

69 Кб, 700x700

37 Кб, 451x387

Пытаюсь заставить работать gettext и пока абсолютно безуспешно.
Что имею: OpenServer 5.2.2, PHP Version 5.5.38
Код скрипта: https://gist.github.com/anonymous/2a2fccdb72f02fef15847fbc633a24aa

Скрипт index.php, рядом с ним папка locale/en_EN/LC_ALL/mydomain.po и mydomain.po

Также есть папка с русскими переводами: locale/ru_RU
Содержимое po файлов: https://gist.github.com/anonymous/677ae340489f3db983c1270b194931b5

mo компилирую при помощи https://po2mo.net/

Практика показала, что локали ru_RU не существует, но есть ru, потому я переименовал папки ru_RU в ru и не помогло - всегда gettext возвращает английский текст.

Пробовал папку LC_ALL переименовывать в LC_MESSAGES - толку никакого.

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

Надеюсь мудрый анон подскажет где здесь косяк.

Ответы3024433108

23 июля, 18:11 #418 #1030199

>>1030174
Разные вещи, если ты об этом: https://github.com/zendframework/zend-debug
Эта штука по сути var_dump для HTML, но тот же symfony/var-dumper гораздо мощнее. xdebug это PHP расширение на Cи, которое позволяет отслеживать выполнение программы и изменять значения переменных во время исполнения кода. Пользуются им обычно через IDE.

>>1026198
Я не ОП, но то, что описано в статье - всем давно известно, странно что подобная статья тебя останавливает. Мне тоже в Yii не нравятся пустые интерфейсы, их собственные сеттеры/геттеры, доступность Yii::$app отовсюду и прочее, но Yii по-прежнему остаётся инструментом, с помощью которого можно быстро и эффективно решать задачи.

>>1030184
> мразь
> пиздоту
> хуй пизда
Ты из /b вылез?

Ответы30200

23 июля, 18:12 #419 #1030200

>>1030199
>Ты из /b вылез?
С хуевыми инструментами только так и получается.

23 июля, 19:55 #420 #1030244

>>1030198
Не работает на винде, хоть и ошибок не выдает.
Вопрос решен.

23 июля, 21:27 #421 #1030299

>>1030074

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

Этот же подход позволяет передавать сообщения вообще без сервера, напрямую через p2p.

Возникает вопрос - а где взять открытый ключ (ключи, если устройств несколько) пользователя B? Тут есть 2 варианта: либо сервер ведет реестр открытых ключей и клиент запрашивает его с сервера, либо при добавлении в контакты клиенты обмениваются ключами.

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

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

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

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

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

23 июля, 21:27 #421 #1030299

>>1030074

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

Этот же подход позволяет передавать сообщения вообще без сервера, напрямую через p2p.

Возникает вопрос - а где взять открытый ключ (ключи, если устройств несколько) пользователя B? Тут есть 2 варианта: либо сервер ведет реестр открытых ключей и клиент запрашивает его с сервера, либо при добавлении в контакты клиенты обмениваются ключами.

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

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

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

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

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

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

Задание на побитовые операторы 23 июля, 22:11 #422 #1030326

>>1027969
https://3v4l.org/GNWKP

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

Ответы30330

23 июля, 22:18 #423 #1030330

>>1030326

clearBit сделан неправильно: clearBit(0, 0b001) должен давать 0.

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

https://stackoverflow.com/questions/109023/how-to-count-the-number-of-set-bits-in-a-32-bit-integer
http://www.geeksforgeeks.org/count-set-bits-in-an-integer/
https://www.google.ru/search?q=count+bits&newwindow=1&gbv=1&sei=zvV0WdeIC4XI6ATBj6DICg

24 июля, 14:00 #424 #1030557

Неплохая практика для нубов. MVC проект магазина с нуля https://www.youtube.com/watch?v=ba3M3_Myrqg&list=PLSdH7dYnlGYgQ6ElbHRpG2zRXbkgkO3zQ

Ответы30799

24 июля, 19:49 #425 #1030786

Я только вкатываюсь, мне нужен XAMPP?
Или можно без него обойтись?

Ответы307993143231474

24 июля, 19:51 #426 #1030787

Аноны, я уже заебался. Решил поизучать Laravel.
В рот его топтать, это слишком тяжело - просто взять и установить эту хуету.
Устанавливал на мак.
С горем пополам у меня это получилось, я использовал их Homestead, для которого понадобился Vagrant и VirtualBox

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

Но как мне войти в свой проект-то?
Я смог написать php artisan serve и захожу на сайт через localhost:8000/.
Как это пофиксить? Что надо сделать?

Как мне подключиться к БД? Как использовать ебаный phpMyAdmin?

Почему все так сложно, а в документации этого нет?

Ответы307983079933106

24 июля, 20:12 #427 #1030798

>>1030787
The Hosts File

You must add the "domains" for your Nginx sites to the hosts file on your machine. The hosts file will redirect requests for your Homestead sites into your Homestead machine. On Mac and Linux, this file is located at /etc/hosts. On Windows, it is located at C:\Windows\System32\drivers\etc\hosts. The lines you add to this file will look like the following:

192.168.10.10 homestead.app
Make sure the IP address listed is the one set in your Homestead.yaml file. Once you have added the domain to your hosts file and launched the Vagrant box you will be able to access the site via your web browser:

http://homestead.app

https://laravel.com/docs/5.4/homestead
--------------------------------------------------------------------------------

ssh https://www.vagrantup.com/docs/cli/ssh.html

sudo apt-get install phpmyadmin

Ответы3080633107

25 Кб, 329x104

24 июля, 20:12 #428 #1030799

>>1030557
Я толком не смотрел, но с ООП у автора серьёзные проблемы (пик).

>>1030786
Для начинающего гораздо проще встроенный в PHP веб-сервер, который не требует установки и настройки: https://github.com/codedokode/pasta/blob/master/soft/web-server.md#Встроенный-в-php-сервер/

>>1030787
> В рот его топтать, это слишком тяжело - просто взять и установить эту хуету.
Одна строчка в терминале, куда уже проще?

> я использовал их Homestead, для которого понадобился Vagrant и VirtualBox
Для новичка это лишние стены абстракций, зачем они тебе? Читай о том, с чем работаешь и думай, нужно ли оно тебе. Бездумным перепечатыванием команд ничего не добьёшься.

> Я смог написать php artisan serve и захожу на сайт через localhost:8000/.
> Как это пофиксить?
Что фиксить? Команда artisan serve запускает встроенный веб-сервер в PHP, там нет виртуальных хостов как в апаче.

> Как использовать ебаный phpMyAdmin?
Laravel не имеет вообще никакого отношения к phpMyAdmin.

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

Ответы308023080330872

24 июля, 20:24 #429 #1030802

>>1030799
у меня просто случился бугурт
тяжело это дается как-то

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

>Для новичка это лишние стены абстракций, зачем они тебе? Читай о том, с чем работаешь и думай, нужно ли оно тебе. Бездумным перепечатыванием команд ничего не добьёшься.
Полностью согласен. Но я читал документацию с начала. Русскую. Там ребята начали с того, что хорошо было бы поставить homestead.
К слову, я на маке недавно и вполне представляю, как настраивается обычный AMP на винде. А для своих целей, так я бы вообще не парился и поставил Open Server, потому что у меня ничего, кроме самообразования особо-то и нет.

>Что фиксить? Команда artisan serve запускает встроенный веб-сервер в PHP, там нет виртуальных хостов как в апаче.
Ну хорошо, допустим. Но как мою проблему решить, я так и не догнал. У меня не работает http://homestead.app
Точнее, он как бы работает и пишет No input file specified.

>Laravel не имеет вообще никакого отношения к phpMyAdmin.
Ну и что? Я хочу использовать MySQL, а там привык юзать phpMyAdmin. Хотел бы знать, как это использовать в связке с Laravel. Как установить, как начать пользоваться.

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

Ответы3143133107

24 июля, 20:26 #430 #1030803

>>1030799
>с ООП у автора серьёзные проблемы (пик).
А как для нубов лучше реализовать M в паттерне MVC?
ActiveRecords? Новички в страхе убегут...

Ответы33106

24 июля, 20:31 #431 #1030806

>>1030798
В /etc/hosts у меня добавлен 192.168.10.10 homestead.app все по гайду
Толку от этого?
У меня есть проект, который я создал через composer. Но он никак не связан с тем, что в hosts

Ответы3081333107

24 июля, 20:37 #432 #1030813

>>1030806
Где добавлен? На маке или в убунте хомстид?

Ответы30830

24 июля, 20:42 #433 #1030814

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

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

В main.php для всех кнопок (на самом деле это ссылки, но неважно) написан путь "php/скриптнейм1.php", "php/скриптнейм2.php" и т.д. Если я, будучи в одном из этих скриптов, захочу переместится в какой-либо из других оставшихся скриптов (или в main.php), браузер пошлет меня нахуй, ибо т.к я нахожусь уже в папке php, ссылку мне нужно задавать относительно нее, а она имеет вид "php/..." (такая же, как была загружена через require 'main.php').

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

Ответы3081830957

24 июля, 20:49 #434 #1030818

>>1030814
Не делай так
http://yournet.kz/blog/project/koncepciya-edinoj-tochki-vxoda
Концепция «единой точки входа»

Ответы31428

24 июля, 21:07 #435 #1030830

>>1030813
на маке

Ответы30834

24 июля, 21:16 #436 #1030834

>>1030830
Может не будешь создавать себе трудности и установишь php и composer на мак. Ларавел устанавливай через композер. Апач не нужен.

Ответы30863

24 июля, 21:28 #437 #1030840

Почему не работает? Как изъять элемент из массива, если его ключ равен нулю? https://ideone.com/Dtw40D

Ответы30844

24 июля, 21:33 #438 #1030844

>>1030840
>for($z = 0; $z++; $z <= count($bills)) {
Чиво?

Ответы30847

24 июля, 21:36 #439 #1030847

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

Ответы30850

24 июля, 21:38 #440 #1030850

>>1030847
Перечитай еще раз мурзилку как пользоваться for.

Ответы30925

24 июля, 21:49 #441 #1030863

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

Ответы33106

24 июля, 21:57 #442 #1030872

>>1030799
>Для начинающего гораздо проще встроенный в PHP веб-сервер, который не требует установки и настройки
Я хочу PhpStorm использовать, хз как там встроенный сервер. Он подойдет?

Ответы33105

24 июля, 23:48 #443 #1030925

>>1030850
https://ideone.com/f5V9KI
Превышено ограничение на время
Значит массив бесконечный?

Ответы3092933105

25 июля, 00:07 #444 #1030929

>>1030925
>if($bills[$z] = 0){
Чиво?

Ответы31009

100 Кб, 960x640

25 июля, 00:08 #445 #1030930

Антоны, поясните ньюфагу за синтаксис:
$actionName = isset($_GET['action']) ? $_GET['action'] : 'index';

Если переданный гет парамент не null, то устанавливаем переменной его значение, иначе - индекс.
Почему условие прописано так? "?", ":" - dgthdst cnfkrbdf.cm

Ответы30934

25 июля, 00:13 #446 #1030934

>>1030930
http://php720.com/lesson/19
Учи пхп с помощью учебник, а не двачей

25 июля, 01:29 #447 #1030957

>>1030814

Тебе правильно советуют сделать единую точку входа, и уже в этом скрипте смотреть, какой URL и что надо вызвать. Но советую тебе также почитать про относительные ссылки и научиться собирать любые виды ссылок: https://github.com/codedokode/pasta/blob/master/network/urls.md

26 Кб, 451x485

25 июля, 04:47 #448 #1030994

Почему он не умножает?

Ответы30999

25 июля, 05:07 #449 #1030999

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

Ответы31001

25 июля, 05:13 #450 #1031001

>>1030999
Спасибо, туплю-торможу.

25 июля, 07:48 #451 #1031009

>>1030929
Если z элемент массива равен нулю, то изымает.

Ответы31010

25 июля, 07:52 #452 #1031010

>>1031009
Перечитай еще раз мурзилку как пользоваться = и ==

25 июля, 12:17 #453 #1031117

>>1029892
В даблах забыл сравнение кубов анон1 == анон3.
На трипл единственное, что приходит в голову - чтобы строка не была вырвиглазно большой, можно вынести сравнения в отдельные переменные и потом в проверку условия подставлять только их.
Мимо-3-день-в-клубе-кун

Ответы31139

25 июля, 12:23 #454 #1031120

Как пофиксить ошибку 502 Bad Gateway когда запускаешь php сервер в phpstorm?
Делал по этому мануалу
https://www.jetbrains.com/help/phpstorm/php-built-in-web-server.html#d147912e141

Ответы3141733105

25 июля, 12:28 #455 #1031122

Получается background-image запилить только для body, если делаю для какого-нибудь div'a, то оно не отображается. Как с этим разобраться, аноны?

Ответы33105

9 Кб, 1186x117

25 июля, 12:41 #456 #1031129

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

Ответы3113231204

25 июля, 12:47 #457 #1031132

>>1031129
Ну и что? Тут перекатывальщики тредов иногда пытаются всю шапку в заголовок запихнуть

Ответы31136

25 июля, 12:52 #458 #1031136

>>1031132
?

Ответы31141

25 июля, 12:53 #459 #1031138

Обязательно ли нужны регулярки в вебе?
Они нужны в каждом проекте?

Ответы3114531148

25 июля, 12:53 #460 #1031139

>>1031117
насмотрелся чет на вас и вот такую хуетень написал: http://ideone.com/t1raXp

Ответы31188

25 июля, 12:54 #461 #1031141

>>1031136
Очевидно первая строчка - заголовок сообщения, а вторая - само сообщение

Ответы31144

25 июля, 12:56 #462 #1031144

>>1031141
Так в заголовке написано то же самое, что и в сообщении. Я хочу что-нибудь одно.

25 июля, 12:57 #463 #1031145

>>1031138
Какие проекты, если ты не знаешь даже регулярки

Ответы31146

25 июля, 13:01 #464 #1031146

>>1031145
Ну так я и спрашиваю: они часто используются или нет?

Ответы31149

25 июля, 13:04 #465 #1031148

>>1031138
Помню дрочил задачи по регуляркам уже почти 3 года назад, жаловался другу который уже работал в яндексе или еще где на тот момент, что мол хуево и сложно. Он сказал что нахуй их, они ирл не нужны почти, а если и нужны то простые которые за 3 сек гуглятся по типу https://code.tutsplus.com/tutorials/8-regular-expressions-you-should-know--net-6149

или заменяются знанием вот этой вот хуйни
http://php.net/manual/ru/function.filter-var.php

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

25 июля, 13:05 #466 #1031149

>>1031146
Тебя просто уволят за некомпетентность, если не "Рога и копыта"

Ответы31157

25 июля, 13:13 #467 #1031157

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

Ответы31171

25 июля, 13:19 #468 #1031171

>>1031157
Что за галера? Там код пишут?

Ответы31176

25 июля, 13:25 #469 #1031176

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

25 июля, 13:27 #470 #1031179

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

Ответы311803118233105

25 июля, 13:28 #471 #1031180

>>1031179
Какую задачу ты не можешь решить?

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

Ответы31183

25 июля, 13:30 #472 #1031182

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

52 Кб, 800x560

25 июля, 13:31 #473 #1031183

>>1031180
Почти все, лол.
Вот, например, вот эту.
Как вообще разбивать задачу на несколько маленьких? Я даже не могу придумать алгоритма к этой задаче.

Ответы3119431914

25 июля, 13:40 #474 #1031188

>>1031139
А зачем арсорт?
3-день-кун

Ответы31196

25 июля, 13:51 #475 #1031194

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

Я вот сейчас хуй решу наверное опять его.

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

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

Остался остаток 4650, смотришь какие другие купюры идут следом у тебя, если тысячные есть в наличии, то ими выдаешь 4 * 1000, и далее остаток в виде 550 рублей добить.

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

Например: передаешь в неё, что разменять надо 12345 рублей пятитысячными, если в наличии много пятитысячных, то она тебе в ответ: 2, 2345
если у тебя одна пятитысячная, то она тебе: 1, 7345
ну и если нету, то: 0, 12345.

Далее думаю сообразишь, что остаток в виде 2345 можно отдавать опять же этой функции но уже с другими купюрами, и так далее пока всё не сойдется или не сойдется :(

2 Кб, 219x55

25 июля, 13:53 #476 #1031196

>>1031188
Там я игрался с большим количеством костей в процессе, и ели вардамп раскоментить, то что бы по возрастанию красиво всё выдавало (просто так кароче он там)

32 Кб, 643x356

25 июля, 13:57 #477 #1031198

Анончики, что не так?

Ответы31199

25 июля, 14:01 #478 #1031199

>>1031198
Первым аргументом в preg_match() должна идти регулярка, а вторым - строка, к которой применяется регулярка.

Ответы31202

25 июля, 14:07 #479 #1031202

>>1031199
Опять я обсираюсь на невнимательности.
Спасибо, анон

25 июля, 14:17 #480 #1031204

>>1031129

Это из-за настройки display_errors = 1 в php.ini. При ее включении, PHP выводит текст ошибки на экран (в данном случае в консоль). Плюс, в командной строке в качестве лога (журнала) ошибок используется стандартный поток ошибок, потому ошибка дополнительно еще раз логгируется в консоль.

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

Исправить сиутацию можно отключив display_errors только для консоли (иначе в браузере тоже перестанет отображаться ошибка). Это можно сделать с помощью настроек в php.ini или ключа командной строки -d error_reportng=0 в настройках, где указывается команда для запуска интерпретатора в командной строке.

Ответы31207

25 июля, 14:34 #481 #1031207

>>1031204
>-d error_reportng=0
Это отключит все сообщения об ошибках.
Я же сделал -d log_errors=Off, чтобы лог не велся.

Ответы31221

25 июля, 14:57 #482 #1031220

>>1029892

Тройного сравнения нет, потому надо сравнить

(кубик1 == кубик2) && (кубик2 == кубик3)

Для удобства (чтобы if не был гигантским) можно вынести результат сравнения (true/false) в переменную:

$isTripleAnon = ($кубик1 == $кубик2) && ($кубик2 == $кубик3);
$isTripleRobot = ...;

if ($isTripleAnon && $isTRipleRobot) { ... }

Но если это сложно, то можно все в if писать.

У тебя на скриншоте в проверке на трипл почему-то стоит "или" (||) в условии вместо "и".

А вообще, правильно делаешь, что усложняешь задачи.

25 июля, 14:57 #483 #1031221

>>1031207

А, перепутал, правильно display_error=0, точно, не надо писать error_reporting=0.

Ответы31223

25 июля, 14:58 #484 #1031223

>>1031221

display_errors конечно: http://php.net/manual/ru/errorfunc.configuration.php#ini.display-errors

Логичнее отключать именно их.

25 июля, 15:12 #485 #1031227

я эти селекторы никогда не пройду

25 июля, 15:35 #486 #1031246

Делал кто телеграм бота?
Если да, то подскажите, как мне отправлять $bot->command каждую минуту бесконечно?
Если нет, то подскажите, почему while($i < 300){ $i++; code.... } не работает, а зависает?

Ответы31372

25 июля, 16:58 #487 #1031372

>>1031246
>while($i < 300){ $i++; code.... }
http://ideone.com/0rBwBa
У меня не зависает. Ты вопрос неправильно задаешь.

25 июля, 17:12 #488 #1031384

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

Ответы31397314003149533104

25 июля, 17:25 #489 #1031397

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

Ответы31410

25 июля, 17:27 #490 #1031400

>>1031384
Лол. По хорошему, надо ещё и файлы на хостинге тереть, а домен разделегировать.

Ответы31402

25 июля, 17:30 #491 #1031402

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

Ответы31408

25 июля, 17:36 #492 #1031408

>>1031402
Да шучу я, шучу.

25 июля, 17:39 #493 #1031410

>>1031397
Ну на видосах у челика не удаляется ничего после тестов, и да я в phpunit.xml вот такие строчки добавил:
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>

Ответы33104

25 июля, 17:46 #494 #1031417

>>1031120
Ищи причину ошибки в логе, например. Или выведи их (подробные сообщения об ошибках) на экран.

Ответы31457

47 Кб, 600x337

25 июля, 17:54 #495 #1031428

>>1030818
Народная казахская мудрость

25 июля, 18:01 #496 #1031431

>>1030802
Кто тебе вообще сказал, что будет легко? Приготовься учиться лет 10 до нормального уровня или сразу уёбывай.

25 июля, 18:04 #497 #1031432

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

Ответы3147333105

25 июля, 18:46 #498 #1031457

>>1031417
Собственно все в порядке, даже обычный хеловорлд не работает.

Ответы31467

25 июля, 19:19 #499 #1031467

>>1031457
А так https://stackoverflow.com/questions/23896638/how-to-setup-built-in-webserver-in-phpstorm ?

Ответы31475

25 июля, 19:24 #500 #1031473

>>1031432
И чем же он удобнее чем OpenServer, например?

Ответы31477

25 июля, 19:25 #501 #1031474

>>1030786
https://ospanel.io/

Лучше не найдешь.

Ответы3147733104

25 июля, 19:26 #502 #1031475

>>1031467
Нихуя не помогло. Обычные скрипты работают нормально, а вот встроенные в phpstorm сервер никак не хочет работать.

25 июля, 19:28 #503 #1031477

>>1031473
>>1031474
Хуй знает, во всем мире используют XAMPP, а тут какая-то руснявая сборка

Ответы3147931490

25 июля, 19:33 #504 #1031479

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

ОпенСерверу уже хуй знает сколько лет и пришел он как раз на смену денверу.

25 июля, 19:38 #505 #1031490

>>1031477
>руснявая сборка
Ни один xampp/lamp/wamp не сравнится с этой сборкой по возможностям.

Ответы3153433104

25 июля, 19:49 #506 #1031495

>>1031384
ап

25 июля, 20:21 #507 #1031533

Сколько данных можно записывать в сессии? Через сколько мегабайт сервер начнет писать в штанишки?

Ответы3155833104

25 июля, 20:21 #508 #1031534

>>1031490
>lamp
>не сравнится с этой сборкой по возможностям.
LoL. Прочувствовал расхожее мнение про пхпешников

Ответы31585

25 июля, 20:29 #509 #1031558

>>1031533
сессия это просто файл
sessid - это просто кука

25 июля, 20:50 #510 #1031585

>>1031534
И не говори!
К нам джун из битриксоидов пришёл — такие темы задвигает, шояебал..

25 июля, 22:28 #511 #1031671

как мне печет,что много важной инфы только на ангельском

Ответы3174033104

25 июля, 22:48 #512 #1031689

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

Ответы3170531769

25 июля, 22:52 #513 #1031692

нахуя нужны массивы на практике в вебе?

Ответы317393190733103

25 июля, 23:20 #514 #1031705

>>1031689
Зависит от:
- твоего уровня знаний
- объёма, по которому надо искать
- качества поиска

В простом случае это должна делать ровно 1 процедура (или запрос, в случае sqlite) в БД и 15 условно, мамкины оптимизаторы, спокойно строк на рнр

Ответы31769

26 июля, 00:41 #515 #1031739

>>1031692
Для того же, для чего в реальной жизни полезны перечисления, то есть, для всего.

Например, результаты запроса из БД (например, список пользователей/страниц/аллахов) в большинстве случаев будет преобразован в массив для удобства работы.

В РНР все запросы от пользователя тоже хранятся в глобальных массивах $_GET и $_POST:
в скрипте myscript.php
по адресу myscript.php?foo=bar&page=2
будет доступен массив
$_GET[
'foo'=>'bar',
'page'=>2,
];

А поле ввода <form action="script.php" method="POST"><input name='myfield'></form>
отправит информацию в массив
$_POST['myfield'];

Вывести массив на страницу можно так:
echo '<pre>'.print_r( $_GET, true ).'<pre>';

Ответы31742

26 июля, 00:42 #516 #1031740

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

26 июля, 00:44 #517 #1031742

>>1031739
>в массив $_POST['myfield'];
в значение массива $_POST по ключу 'myfield', если точнее

26 июля, 01:13 #518 #1031753

>>1027510
Вообще-то новые версии выходят каждые пару лет, язык развивается постоянно. Такие реалии.

26 июля, 01:31 #519 #1031757

>>1030078
Если так https://developers.google.com/custom-search/json-api/v1/reference/cse/list то да

26 июля, 02:09 #520 #1031769

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

26 июля, 10:25 #521 #1031845

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

Ответы31866

26 июля, 11:00 #522 #1031866

>>1031845
PHP работает на сервере: принимает и разбирает пользовательские запросы, работает с БД и сессиями.

Сейчас, в 2009, js тоже пытается это делать (node.js), но основная его роль -- выполнение прямо в браузере клиента: визуально изобразить что-нибудь (меняя html и css у клиента), отправить со страницы запрос к тому же РНР скрипту.

Ответы31943

10 Кб, 416x180

26 июля, 11:24 #523 #1031873

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

Ответы31882

26 июля, 11:55 #524 #1031882

>>1031873
Можешь сразу атом пропустить.

Ответы3188431897

51 Кб, 656x431

26 июля, 11:56 #525 #1031884

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

26 июля, 12:06 #526 #1031889

для новичков советую потыкать данный фреймворк - https://phalconphp.com/ru/,
самый простой из всех mvc, достаточно чтобы познакомиться с WebMVC, и потом перейти на тотже Laravel. хотя самому всеравно больше нравится именно Phalcon

Ответы3189031950

26 июля, 12:08 #527 #1031890

>>1031889
Туториалы есть? Туториалов нет. А значит для новичков это крайне плохой вариант. Сравни со слимом https://www.youtube.com/watch?v=RhcQXFeor9g&list=PLfdtiltiRHWGc_yY90XRdq6mRww042aEC&spfreload=10

Ответы31893

26 июля, 12:16 #528 #1031893

>>1031890
это что по твоему?
https://docs.phalconphp.com/ru/3.2/installation
https://docs.phalconphp.com/ru/latest/tutorial-base

Ответы31894

26 июля, 12:22 #529 #1031894

>>1031893
Это официальная документация, которая есть у всех фреймворков, а не туториалы для ньюфагов с объяснением нюансов. Кроме того все видео на ютубе, которые я только что нашел, двухлетней давности, что многое говорит о его состоянии.

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

Ответы31902

33 Кб, 714x261

26 июля, 12:26 #530 #1031897

>>1031882
Атом тоже идет нахуй, не может в банальный extends и автокомплит имен файлов. Хоспаде, неужели пхпсторм единственный нормальный вариант.

Ответы31922

26 июля, 12:32 #531 #1031902

>>1031894
я не пойму, шутишь ты или нет, вот пошаговый туториал как хелло ворлд сделать
https://olddocs.phalconphp.com/en/3.0.0/reference/tutorial.html
не смотри то что написано olddocs, текущая версия 3.3 полностью совместима с 3.0
вот тебе скелеты под приложения на все случаи жизни https://github.com/phalcon/mvc
просто не понятно, как ты искал, если это не нашел

Ответы31905

8 Кб, 863x28

26 июля, 12:37 #532 #1031905

>>1031902
>пошаговый туториал как хелло ворлд сделать
Вот именно, хеллоу ворлд. А я хочу взять и сделать регистрацию на сайте, с валидацией и прочим CSRF. Зачем мне жрать кактус и гуглить в поисках крупиц информации на эту тему с фальконом, если я просто открою ссылку выше для слима, и там уже всё готовое с пояснением всех мелочей? А если мне не будет понятно, то я просто спрошу в треде, поскольку даже в шапке этот фреймворк рассматривается.

Ответы31908

26 июля, 12:38 #533 #1031907

>>1031692
вот тебе псевдо код примерный, страницы каталога товаров
$products = SQL(SELECT * FROM PRODUCTS);
foreach $products as $product {
print product_card
}

26 июля, 12:40 #534 #1031908

>>1031905
а ты ниже смотрел?))) вторая часть туториала про форму регистрации с валидацией?

Ответы31910

26 июля, 12:45 #535 #1031910

>>1031908
Нет, не заметил.

Ответы31917

26 июля, 12:50 #536 #1031914

>>1031183
1) Смотришь делится ли число на 100, если нет -> еррор, если да -> п.2
2) далее смотришь хватает ли у тебя денег выдать, сумма всех купюр сравнивается с запрошенной суммой, если нет -> еррор, если да -> п.3
3) Идешь от большей купюры в меньшую, 23550 - 5000 - 5000, параллельно чекаешь чтобы купюр хватало, ну и тут либо не хватит соток например либо хватит, если нет -> еррор, если да -> то все ок

26 июля, 12:52 #537 #1031917

>>1031910
ну вот и я про то же, фв очень простой, дело освоения пары часов(если знаком с пхп хотябы на 4/10), если не знаком ну 1-2 дня(максимум около недели, зависит от общего понимания программирования и WebMVC паттерна)

Ответы31919

26 июля, 12:54 #538 #1031919

>>1031917
А на слиме ты делал что-то? Можешь сравнить*?

Ответы3195631962

26 июля, 13:08 #539 #1031922

>>1031897
Ну ты перебираешь блокноты какие-то.
Из бесплатных IDE можешь ещё помучиться с Eclipse, а так да -- плати за PHPStorm, это норма.

26 июля, 13:45 #540 #1031943

>>1031866
Спасибо анон, добра.

26 июля, 13:56 #541 #1031950

>>1031889
>данный фреймворк
пхалькон не фреймворк

Ответы31957

26 июля, 13:58 #542 #1031956

>>1031919
Сам не писал, но почитал документацию сейчас, слим посложнее фалкона будет, да и выглядит слим как странная песочница а не фреймворк, тотже фалкон или ларавел, сразу написано что и как по структуре, есть дефолтный роутинг, который не нужно расписывать(SITEName/ControllerName/ActionName). в фалконе довольно хорошая орм, и querybuilder прекрасный просто. пишется очень легко и проблемы редко возникают с ним.

26 июля, 13:59 #543 #1031957

>>1031950
https://phalconphp.com/ru/
прочитай то что написано по центру экрана

Ответы320373203832063

26 июля, 14:05 #544 #1031962

>>1031919
вообще советую сильно не увлекаться ТОЛЬКО бэкендом, а посмотреть в сторону фронта еще, например Vue или React(ангулар кал)

Ответы31963

26 июля, 14:08 #545 #1031963

>>1031962
Я планирую вью использовать.

26 июля, 14:18 #546 #1031967

анончики, кто писал бота под телеграм? Подскажите, где гуглить вопросы.
Интересует момент такой
$bot->command с аргументом, обрабатывая этот аргумент

26 июля, 15:07 #547 #1032002

Ребят, у меня очень странная проблема.

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

Это похоже на то, что я просто указал путь к файлу который не изменяется, а к тому файлу, который я изменяю, никаких путей подключения не проложено. Но это не так!. Этот styles.css единственный css файл в моем проекте, и только его удаление приводит к выводу на странице чистого html.

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

Ответы32004320073244933103

26 июля, 15:11 #548 #1032004

>>1032002
Хотя сейчас даже при его удалении выводятся его стили.

26 июля, 15:15 #549 #1032007

>>1032002
Ну обычно это кеш браузера, как бы ничего странного. Обновление по ctrl+f5 (без кеша) работает же?

Ответы32008

26 июля, 15:18 #550 #1032008

>>1032007
Блять я дебил. Спасибо. Я блять даже про это не знал.

Ответы32019

26 июля, 15:33 #551 #1032019

>>1032008
Для того и тред... Двуч образовательный

26 июля, 16:04 #552 #1032037

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

26 июля, 16:05 #553 #1032038

>>1031957
алсо покажи мне ещё 1 фреймворк который надо устанавливать через php.ini в лучшем случае а то и компилить с его

Ответы3204132059

26 июля, 16:08 #554 #1032041

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

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

Ответы3204733103

26 июля, 16:16 #555 #1032047

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

26 июля, 16:33 #556 #1032059

>>1032038
пожалуйста - https://www.iceframework.org/

26 июля, 16:36 #557 #1032063

>>1031957
использую фалкон, конкретно как апишку для фронта на реакте, он быстро позволяет реализовать нормальную апишку

50 Кб, 400x400

26 июля, 19:08 #558 #1032158

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

Ответы32192322083227832307

26 июля, 19:53 #559 #1032192

>>1032158
В контроллере

Ответы32208

26 июля, 20:08 #560 #1032208

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

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

Ответы32222

26 июля, 20:31 #561 #1032222

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

Ответы33103

26 июля, 20:51 #562 #1032235

Какие книги почитать про PHP7?

Ответы3224132255

26 июля, 21:03 #563 #1032241

>>1032235
Никакие, почитай migration guide для PHP 7.0 и 7.1 на php.net или выжимки вроде этих:
- https://github.com/tpunt/PHP7-Reference
- https://github.com/tpunt/PHP7-Reference/blob/master/php71-reference.md

26 июля, 21:27 #564 #1032249

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

Например я написал автолоад через
spl_autoload_register
В нем указал 1 папку с файлами, допустим это папка Core
Теперь у меня подгружаются Классы из папки Core

Но как использователь неймспейсы вместе с этим всем? Я проставил классам неймспейсы, и всё сломалось.
Классу роутер который лежит в Core/Router.php например я пишу namespace Core;
Но если я пишу в файле индекс, который лежит снаружи папки Core такую штуку как:
use Core\Router;
то всё ломается. Не понимаю чего-то.

Ответы3225333103

26 июля, 21:39 #565 #1032253

>>1032249

Почитай урок про автозагрузку и неймспейсы https://github.com/codedokode/pasta/blob/master/php/autoload.md

26 июля, 21:44 #566 #1032255

>>1032235
про РНР вообще или РНР7?

кстати, странно что в шапке нет http://www.phptherightway.com/

Ответы32276

sage 26 июля, 22:46 #567 #1032276

>>1032255
Есть, там ссылка на русскую версию.

26 июля, 22:49 #568 #1032278

>>1032158
Бамп

Ответы32307

26 июля, 22:53 #569 #1032281

Заметил, что тут есть пара матёрых дядек,
кто-нибудь может подсказать:

в PHP 7.1 на этапе исполнения есть ли какая-то разница
между [] и array() //для совместимости со старым PHP5 ?

Ответы3229232300

26 июля, 23:15 #570 #1032292

>>1032281
только для совместимости с <5.4

Ответы32296

26 июля, 23:24 #571 #1032296

>>1032292
ну для выполнения на РНР7 или 7.1 будет какая-то разница, или нет (просто написание)?

26 июля, 23:32 #572 #1032300

>>1032281

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

Информации про это расширение на русском мало:

- рус https://habrahabr.ru/company/mailru/blog/305906/
- рус https://habrahabr.ru/post/211156/
- англ https://derickrethans.nl/more-source-analysis-with-vld.html

Запустим 2 варианта кода и посмотрим на результат компиляции:

php -dvld.active=1 -r '$a = array();'

INIT_ARRAY ~0
ASSIGN !0, ~0
RETURN null

php -dvld.active=1 -r '$a = [];'

INIT_ARRAY ~0
ASSIGN !0, ~0
RETURN null

результат в PHP5, как мы видим, идентичен.

Также, VLD-дизассемблер есть на сайте 3v4l.org, там я тоже попробовал сделать 2 варианта кода:

https://3v4l.org/lKUHM/vld#output
https://3v4l.org/fnVqn/vld#output

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

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

26 июля, 23:32 #572 #1032300

>>1032281

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

Информации про это расширение на русском мало:

- рус https://habrahabr.ru/company/mailru/blog/305906/
- рус https://habrahabr.ru/post/211156/
- англ https://derickrethans.nl/more-source-analysis-with-vld.html

Запустим 2 варианта кода и посмотрим на результат компиляции:

php -dvld.active=1 -r '$a = array();'

INIT_ARRAY ~0
ASSIGN !0, ~0
RETURN null

php -dvld.active=1 -r '$a = [];'

INIT_ARRAY ~0
ASSIGN !0, ~0
RETURN null

результат в PHP5, как мы видим, идентичен.

Также, VLD-дизассемблер есть на сайте 3v4l.org, там я тоже попробовал сделать 2 варианта кода:

https://3v4l.org/lKUHM/vld#output
https://3v4l.org/fnVqn/vld#output

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

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

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

26 июля, 23:36 #573 #1032301

>>1032300
Спасибо, буду пробовать

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

26 июля, 23:44 #574 #1032306

Блять, когда перекат?

Ответы33102

26 июля, 23:45 #575 #1032307

>>1032158
>>1032278

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

Куда поместить класс, генерирующий картинку? Такие классы называют сервисы (или хелперы), логично поместить его в папку App/Service или App/Helper.

Ответы32308

26 июля, 23:51 #576 #1032308

>>1032307
ларавел - не мвц фреймворк

Ответы3231432315

26 июля, 23:58 #577 #1032314

>>1032308
прочитай как расшифровывается mvc, а потом подумай еще раз, пожалуйста

Ответы32317

26 июля, 23:59 #578 #1032315

>>1032308
а так же посмотри, что есть несколько интерпретаций mvc паттерна

Ответы32317

27 июля, 00:14 #579 #1032317

>>1032315
>>1032314
а знаю что, что в MVC обработка данных происходит в моделе. Ларавел не соответствует этому

Ответы32319

27 июля, 00:16 #580 #1032319

>>1032317

А что-то запрещает реализовать MVC в Ларавеле и поместить бизнес-логику в отдельные классы?

Ответы32324

27 июля, 00:38 #581 #1032324

>>1032319
Ничто не запрещает, только MVC оно от этого не станет, т.к. бизнес-логика должна быть не в "отдельных классах", а в моделях

Ответы32329

27 июля, 00:45 #582 #1032329

>>1032324

Так а чем эти "отдельные" классы отличаются от "модели"? У тебя по моему путаница в терминологии.

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

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

В Симфони например вообще классов с названием "модель" нет.

Что ты подразумеваешь под "моделью"?

Ответы32333

27 июля, 00:53 #583 #1032332

78 Кб, 823x555

280 Кб, 1920x1080

Аноны, выручайте.
Решаю задачку на проверку телефонов
http://archive-ipq-co.narod.ru/l1/regexp.html
Какой метод и как мне использовать, чтобы сформировать новый массив просто с цифрами, чтобы потом отсортировать номера?
match_all через цикл я прогоняю в новый массив, но он туда вписывает ересь на пиках.
Может я пропустил что-то?

Ответы323343235432446

27 июля, 00:53 #584 #1032333

>>1032329
>Что ты подразумеваешь под "моделью"?
Класс содержащий бизнес-логику. А ларавел под моделью подразумевает класс являющийся ссылкой на таблицу БД, а классы в которых должна быть логика, называет контроллерами

Ответы33102

27 июля, 00:54 #585 #1032334

>>1032332
А как делается "или" чтобы стоял вначале?
Типа ab?c но только чтобы выбирал между 7 и 8 вначале.

Ответы32446

113 Кб, 820x680

27 июля, 02:22 #586 #1032354

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

Ответы3238132446

27 июля, 07:26 #587 #1032381

>>1032354
Вроде воспользовался. Другое дело, что эта функция возвращает строку, а не присваивает ее. Попробуй сдампить implode(parts)
http://ideone.com/BgpC6G

Ответы32446

302 Кб, 757x1136

27 июля, 09:31 #588 #1032398

Зашел в ваш тред от скуки, пока ничего интересного для себя не нашел. Давно пишу на ПОХАПЕ различные темы и плагины на продажу (wordpress, themeforest). Общаюсь с клиентами каждый день, работаю в качестве техсаппорта. Отвечу на любые вопросы если есть (о клиентах, разработке, о чем угодно).

Ответы3244832454

27 июля, 10:47 #589 #1032446

>>1032332
Твое регулярное выражение ищет просто одну цифру в любом месте строки. Не удивительно, что у тебя каждое число помещается в массив $совпаден(ие)ий.
Тебе нужно добавить в регулярное выражение метасимвол означающий повторение один или несколько раз +

http://php.net/manual/ru/regexp.reference.meta.php
>+ квантификатор, означающий 1 или более вхождений

Ещё ты при каждом обходе итерации цикла выводишь массив совпадений, а не выводишь его один раз при завершении цикла.

Почитай ещё про оформление кода >>1019303

>>1032334
http://php.net/manual/ru/regexp.reference.alternation.php

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

http://php.net/manual/ru/regexp.reference.subpatterns.php
>1. Локализирует набор альтернатив. Например, шаблон cat(aract|erpillar|) соответствует одному из слов "cat", "cataract" или "caterpillar". Без использования скобок он соответствовал бы строкам "cataract", "erpillar" или пустой строке.

>>1032354
Почему ты пользуешься функцией preg_split, когда для нахождения совпадений есть preg_match?

http://php.net/manual/ru/function.preg-match.php

Функция implode() объединяет массив в строку, а ты пытаешься передать в эту функцию строку.

http://php.net/manual/ru/function.implode.php

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

$variable = implode(...);

27 июля, 10:47 #589 #1032446

>>1032332
Твое регулярное выражение ищет просто одну цифру в любом месте строки. Не удивительно, что у тебя каждое число помещается в массив $совпаден(ие)ий.
Тебе нужно добавить в регулярное выражение метасимвол означающий повторение один или несколько раз +

http://php.net/manual/ru/regexp.reference.meta.php
>+ квантификатор, означающий 1 или более вхождений

Ещё ты при каждом обходе итерации цикла выводишь массив совпадений, а не выводишь его один раз при завершении цикла.

Почитай ещё про оформление кода >>1019303

>>1032334
http://php.net/manual/ru/regexp.reference.alternation.php

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

http://php.net/manual/ru/regexp.reference.subpatterns.php
>1. Локализирует набор альтернатив. Например, шаблон cat(aract|erpillar|) соответствует одному из слов "cat", "cataract" или "caterpillar". Без использования скобок он соответствовал бы строкам "cataract", "erpillar" или пустой строке.

>>1032354
Почему ты пользуешься функцией preg_split, когда для нахождения совпадений есть preg_match?

http://php.net/manual/ru/function.preg-match.php

Функция implode() объединяет массив в строку, а ты пытаешься передать в эту функцию строку.

http://php.net/manual/ru/function.implode.php

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

$variable = implode(...);

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

27 июля, 10:50 #590 #1032448

>>1032398
Изучать PHP можно сразу после того как изучишь html5/css3?

Ответы32995

27 июля, 10:50 #591 #1032449

>>1032002
Как выше обяснили это браузер кеширует стили. И например он зашел на твой сайт hueta.loc, скачал твой style.css и всё. Потом если ты вносишь правки в стили, но может смотреть что ситил уже скачаны и подгружать те что скачивал когда-то давно.

Причем если ты шарящий чел, то какие-нибудь клиенты нихуя не такие и что бы избежать того, что бы отвечать в последствии на звонки с разъяснениями ЭС как доллар и нажмите CTRL+F5, ты в шапке или где у тебя там подгружается стиль дописывай ему версию.

<link rel="stylesheet" type="text/css" href="style.css?ver=111" />

А после того как внес изменения в файл то эту версию в шапке обновляй

<link rel="stylesheet" type="text/css" href="style.css?ver=112" />

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

Ответы33102

27 июля, 10:57 #592 #1032454

>>1032398
>бя не нашел. Давно пишу на ПОХАПЕ различные темы и плагины на продажу (wordpress, themeforest). Общаюсь с клиентами каждый день, работаю в качес
Очень интересно было бы кулстори про themeforest послушать. А дизайн тем сами пилите? Или просто сотрудничаете с дизайнерами?

Ответы32995

27 июля, 11:11 #593 #1032460

Стоит ли заморачиваться с ларавелом для хобби проекта? Или это из пушки по воробьям и для работы с ним нужна целая команда?

Ответы3254832663

27 июля, 14:03 #594 #1032548

>>1032460
отвечу так: почему бы и нет?
в свое время ларавел,вуе,реакт,ангулар,фалкон сидел тыкал как хобби, потом уже пилил коммерс проекты на них

Ответы3268633021

27 июля, 16:01 #595 #1032659

>>1030299
Я придумал алгоритм шифрования, но у меня есть несколько вопросов

При регистрации пользователя мы генерируем закртый\открытый ключ

$privateKey = openssl_pkey_new(array(
"digest_alg" => $method,
"private_key_bits" => 4096
));

$publicKey = openssl_pkey_get_details($privateKey)['key'];

Закрытый ключ шифруем паролем

$encryptedKey = openssl_encrypt($privateKey, $method, str2hex($password));

И помещаем их в БД

http://php.net/manual/ru/function.openssl-get-cipher-methods.php#refsect1-function.openssl-get-cipher-methods-examples
Почему нету метода RSA? Однако, в опциях создания ключа можно указать этот тип Что это вообще может значить??. Эти все методы сделаны на его основе?

Какой метод лучше выбрать?

http://php.net/manual/ru/function.openssl-public-encrypt.php#118466
В комментариях сказано, что RSA начинает устаревать и пора переходить на ECDH вместе с EdDSA. Что вы думаете по этому поводу?

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

Такой алгоритм подошел бы если бы мы реализовывали вариант с шифрованием сообщений конференции общим ключем.

Далее

Сообщения шифруются но основе открытых ключей собеседников

// Ничего особенно за исключением опции добавления OPENSSL_PKCS1_OAEP_PADDING,
// которое рекомендуется из комментария выше
openssl_public_encrypt($message, $crypted, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);

Расшифровка происходит аналогичным способом

openssl_private_decrypt($message, $decrypted, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);

Остается только найти js библиотеку для шифровки\дешифровки аналогичным способом.

Я нашел вот эту http://www-cs-students.stanford.edu/~tjw/jsbn/ , но я не уверен что библиотека которая содержится в PHP использует алгоритм RSA (там какие-то методы (ссылаюсь на тот же вопрос выше о методах)).

К тому же, я не знаю как с помощью RSA т.е. js библиотеки реализующей его расшифровать ключ который мы шифровали паролем, потому что нет возможности получить пары {e, n}\{d, n} из произвольной hex-строки.
Я бы смог решить эту проблему, если бы знал каким образом функция openssl_encrypt() шифрует данные из этой строки. Всё ещё запутан вопросом о методах шифрования Вы случайно не знаете что-нибудь об этом?

http://php.net/manual/ru/function.openssl-encrypt.php

>jsbn.js
>jsbn2.js
Зачем разделять код на две части? Это не более чем прихоть автора?

27 июля, 16:01 #595 #1032659

>>1030299
Я придумал алгоритм шифрования, но у меня есть несколько вопросов

При регистрации пользователя мы генерируем закртый\открытый ключ

$privateKey = openssl_pkey_new(array(
"digest_alg" => $method,
"private_key_bits" => 4096
));

$publicKey = openssl_pkey_get_details($privateKey)['key'];

Закрытый ключ шифруем паролем

$encryptedKey = openssl_encrypt($privateKey, $method, str2hex($password));

И помещаем их в БД

http://php.net/manual/ru/function.openssl-get-cipher-methods.php#refsect1-function.openssl-get-cipher-methods-examples
Почему нету метода RSA? Однако, в опциях создания ключа можно указать этот тип Что это вообще может значить??. Эти все методы сделаны на его основе?

Какой метод лучше выбрать?

http://php.net/manual/ru/function.openssl-public-encrypt.php#118466
В комментариях сказано, что RSA начинает устаревать и пора переходить на ECDH вместе с EdDSA. Что вы думаете по этому поводу?

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

Такой алгоритм подошел бы если бы мы реализовывали вариант с шифрованием сообщений конференции общим ключем.

Далее

Сообщения шифруются но основе открытых ключей собеседников

// Ничего особенно за исключением опции добавления OPENSSL_PKCS1_OAEP_PADDING,
// которое рекомендуется из комментария выше
openssl_public_encrypt($message, $crypted, $publicKey, OPENSSL_PKCS1_OAEP_PADDING);

Расшифровка происходит аналогичным способом

openssl_private_decrypt($message, $decrypted, $privateKey, OPENSSL_PKCS1_OAEP_PADDING);

Остается только найти js библиотеку для шифровки\дешифровки аналогичным способом.

Я нашел вот эту http://www-cs-students.stanford.edu/~tjw/jsbn/ , но я не уверен что библиотека которая содержится в PHP использует алгоритм RSA (там какие-то методы (ссылаюсь на тот же вопрос выше о методах)).

К тому же, я не знаю как с помощью RSA т.е. js библиотеки реализующей его расшифровать ключ который мы шифровали паролем, потому что нет возможности получить пары {e, n}\{d, n} из произвольной hex-строки.
Я бы смог решить эту проблему, если бы знал каким образом функция openssl_encrypt() шифрует данные из этой строки. Всё ещё запутан вопросом о методах шифрования Вы случайно не знаете что-нибудь об этом?

http://php.net/manual/ru/function.openssl-encrypt.php

>jsbn.js
>jsbn2.js
Зачем разделять код на две части? Это не более чем прихоть автора?

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

27 июля, 16:09 #596 #1032663

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

Ответы33021

27 июля, 16:52 #597 #1032686

Можете помочь с составлением eloquent запроса в ларавеле?

>>1032548
И ты тоже.

70 Кб, 787x572

27 июля, 17:24 #598 #1032703

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

Ответы32711

27 июля, 17:28 #599 #1032705

3-день-в-клубе-кун репортинг.
Проверьте пжлст задачки:
Имя кошки - http://ideone.com/9gYMJD
Лев Толстой: http://ideone.com/c7jA9P
Палиндром: http://ideone.com/k76YfM (внезапно на ideone не работает утф-8, на пхптестере вроде все норм)
Заранее пасяб.

Ответы33102

27 июля, 17:39 #600 #1032711

>>1032703
>>1032446
>сначала идет +7 или 8, за ними ровно 10 цифр, между которыми может быть любое число скобок, минусов, пробелов
(+7|8)
Ну а как написать чтобы между ними может быть любое число скобок и прочего дерьма я не нашел в уроке

Ответы32720

27 июля, 17:49 #601 #1032720

>>1032711
Там есть про поиск специальных символов и как искать "любой символ, кроме" каретом ^

Ответы3272932731

27 июля, 17:57 #602 #1032729

>>1032720
Нет, как мне написать, что между цифрами может быть S+-_ и т д

Ответы3273133100

27 июля, 17:58 #603 #1032730

https://ideone.com/4M2YGS
Это опять я, короче все збс работает, теперь мне нужно обратиться к свойству объекта, который находится в массиве $workers, а это в cвою очередь свойство объекта $quest, как это реализовывается?

Ответы33100

27 июля, 17:58 #604 #1032731

>>1032729
>>1032720
([+7]|8)[0-9(\/S+)?]{10}
Вот такое не работает.

Ответы33100

27 июля, 21:48 #605 #1032881

Есть одна таблица в PostgreSQL - id SERIAL PRIMARY KEY, data JSONB NOT NULL. Есть один запрос, который пытается пихнуть в таблицу json-строку и достать её уникальный идентификатор:

if(isset($_POST['data']) && !empty($_POST['data'])) {
$data = json_encode($_POST['data'], JSON_UNESCAPED_UNICODE);
//DB
$db = getdb();
$query = "INSERT INTO searches (data) VALUES ('$data') RETURNING id";
$result = pg_query($query) or die('Query failed: ' . pg_last_error());
pg_close($db);
echo $result;
}

Так вот какого-то хуя echo $result возвращает мне не id, а какую-то хуйню вроде Resource id #4 или Resource id #5. Какого хуя блядь?

Ответы3288732888

27 июля, 22:01 #606 #1032887

>>1032881
всё правильно , что бы получить результат нужно использовать ещё функцию

Ответы32988

27 июля, 22:02 #607 #1032888

>>1032881
Возвращается резалтсет, как и при обычном селекте. Его надо разобрать
http://php.net/manual/en/pdostatement.fetchall.php

Ответы3289332988

27 июля, 22:05 #608 #1032893

>>1032888
Вот это оно? $result = $sth->fetchAll();

И почему оно мне возвращает то 4, то 5?

Ответы33100

27 июля, 22:10 #609 #1032902

Почему он не работает? Он не должен 1000 показывать? https://ideone.com/6VKG0m

Ответы32906

27 июля, 22:12 #610 #1032906

>>1032902
Потому что у тебя нет в массиве элемента с ключём 0

Ответы329103291232917

27 июля, 22:14 #611 #1032910

>>1032906
Как нет? 1000 => 0, почему не считается? Ключ первым должен идти?

Ответы33099

27 июля, 22:14 #612 #1032912

>>1032906
Всё.

27 июля, 22:19 #613 #1032917

>>1032906
А если у меня ключи числами, то будет ли работать действие с указанием элемента массива? Смогу ли я изъять третий по счёту массив, или он будет изничтожать элемент с ключом 3?

Ответы3292332927

27 июля, 22:24 #614 #1032923

>>1032917
Переформулируй вопрос пожалуйста, вообще не понятно как-то что ты хочешь?

Ответы32928

27 июля, 22:28 #615 #1032927

>>1032917
Можешь вот так хранить значения если тебе именно нужно обращаться к элементам.
https://ideone.com/5nE5SR

27 июля, 22:28 #616 #1032928

>>1032923
Я задал элементам массива ключи числами, 1, 2 и т.д. Но мне нужно изъять третий элемент массива. Если я напишу unset($arrays{3}); то что будет изъято? Третий по счёту элемент, или тот, что имеет ключ 3? Чому не работает? https://ideone.com/H6wN3Y

Ответы3296033099

27 июля, 22:42 #617 #1032941

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

Ответы35984

323 Кб, 410x600

27 июля, 22:44 #618 #1032947

Нормальный? Если я немного глуповат, то пойму?
Автор: Игорь Симдянов, Дмитрий Котеров Издательство: БХВ-Петербург Год: 2016 Язык: Русский ISBN: 978-5-9775-3725-4 Страниц: 1073

Ответы33016

27 июля, 23:01 #619 #1032960

>>1032928

unset($array[0]) - удаляет элемент массива с ключом 0;

if($bills[$z] == 0){
unset($bills[$z]);
}
если элемент массива с ключом $z равен нулю, то удаляем его.

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

Ответы32967

27 июля, 23:13 #620 #1032967

>>1032960
Я их проходил, но давно. Забыл, видать.

27 июля, 23:57 #621 #1032988

>>1032887
>>1032888
Разобрался.

$row = pg_fetch_row($result);
$user_id = $row[0];

28 июля, 00:14 #622 #1032995

>>1032448
Чем раньше начнешь изучать ПОХАПЕ, тем лучше. Даже не обязательно пхп, а просто любой серверный язык программирования, хоть перл, хоть руби, хоть джаваскрипт. Я бы посоветовал изучать что-нибудь асинхронное. Потому что бекэнд намного интереснее фронтэнда (хоть на фронтэнде тоже интересно бывает, иногда).

Фронтэнд это:
Надо сделать обработчик для кнопки, а тут чет анимация хреновая, надо допилить. А тут у формы съехали стили, а тут навбар дергается, надо пофиксить. По сути ты пишешь кучу разных компонентов и правильно подключаешь их к кнопкам и крутилкам, чтобы при нажатии всё правильно крутилось, запрашивало данные с сервера и отображало.

Бекэнд:
Как организовать структуру проекта? Как реализовать алгоритм разбивки по страницам? Как вынести повторяющийся функционал в отдельный класс? Как реализовать rest api? Кеширование? Оптимизировать скорость работы?

И т.д. То есть он интереснее для программистов, да и многие бекэндщики - это матерые фронтэндщики, перекатившиеся на server-side.

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

Про клиентов я писал тут >>935109 >>935303 >>938423. Вкратце, работенка пиздец. Любая хуйня что случится - винят автора темы. Например, купили хостинг за 3 копейки, там оперативной памяти меньше, чем в калькуляторе. А это всё автор виноват! Хуле ты не мог сделать так, чтобы сайт даже на калькуляторе работал?! ИЛИ я поставили плагин и страница вылетает с фатальной ошибкой, скрипты не загружаются. ПОЧЕМУ ВЫ НЕ МОГЛИ СДЕЛАТЬ ЧЕЛОВЕКОПОНЯТНЫЕ СООБЩЕНИЯ ОБ ОШИБКАХ?

Постоянная ебля с обновлениями - Visual Composer обновляется и там постоянно что-то отваливаются, то шорткоды, то настройки pricing table пропадут, то ещё что. WooCommerce обновляется практически каждые две недели, заебешься его шаблоны обновлять. У них там то конфликт с ACF, то ещё че...

+ Конкуренция + у самого themeforest'a ещё и комиссии пиздецовые + он душит своей политикой. Они запускают хуйню, что-то вроде Envato Elements, там оформляешь подписку на год по-моему за 50-60 долларов и весь год качаешь любые темы. Нам это вообще не выгодно, собираемся уйти с тимфореста, открывать свой сайт-магазин.

28 июля, 00:14 #622 #1032995

>>1032448
Чем раньше начнешь изучать ПОХАПЕ, тем лучше. Даже не обязательно пхп, а просто любой серверный язык программирования, хоть перл, хоть руби, хоть джаваскрипт. Я бы посоветовал изучать что-нибудь асинхронное. Потому что бекэнд намного интереснее фронтэнда (хоть на фронтэнде тоже интересно бывает, иногда).

Фронтэнд это:
Надо сделать обработчик для кнопки, а тут чет анимация хреновая, надо допилить. А тут у формы съехали стили, а тут навбар дергается, надо пофиксить. По сути ты пишешь кучу разных компонентов и правильно подключаешь их к кнопкам и крутилкам, чтобы при нажатии всё правильно крутилось, запрашивало данные с сервера и отображало.

Бекэнд:
Как организовать структуру проекта? Как реализовать алгоритм разбивки по страницам? Как вынести повторяющийся функционал в отдельный класс? Как реализовать rest api? Кеширование? Оптимизировать скорость работы?

И т.д. То есть он интереснее для программистов, да и многие бекэндщики - это матерые фронтэндщики, перекатившиеся на server-side.

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

Про клиентов я писал тут >>935109 >>935303 >>938423. Вкратце, работенка пиздец. Любая хуйня что случится - винят автора темы. Например, купили хостинг за 3 копейки, там оперативной памяти меньше, чем в калькуляторе. А это всё автор виноват! Хуле ты не мог сделать так, чтобы сайт даже на калькуляторе работал?! ИЛИ я поставили плагин и страница вылетает с фатальной ошибкой, скрипты не загружаются. ПОЧЕМУ ВЫ НЕ МОГЛИ СДЕЛАТЬ ЧЕЛОВЕКОПОНЯТНЫЕ СООБЩЕНИЯ ОБ ОШИБКАХ?

Постоянная ебля с обновлениями - Visual Composer обновляется и там постоянно что-то отваливаются, то шорткоды, то настройки pricing table пропадут, то ещё что. WooCommerce обновляется практически каждые две недели, заебешься его шаблоны обновлять. У них там то конфликт с ACF, то ещё че...

+ Конкуренция + у самого themeforest'a ещё и комиссии пиздецовые + он душит своей политикой. Они запускают хуйню, что-то вроде Envato Elements, там оформляешь подписку на год по-моему за 50-60 долларов и весь год качаешь любые темы. Нам это вообще не выгодно, собираемся уйти с тимфореста, открывать свой сайт-магазин.

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

28 июля, 00:16 #623 #1032996

>>1032995
https://2ch.hk/biz/res/927632.html (М) вот ссылка на тред, в конце мои ответы.

28 июля, 00:26 #624 #1033000

>>1032995
>перл
>руби
Да ну в пизду это хипстерское поделие.

Другой анон

Я пару дней назад решил начать вкатываться в MongoDB и вообще в базы данных. Последний раз я базу данных видел в универе в прошлом году, где мы изучали азы БД на примере Access, а потом MySQL и phpMyAdmin. Мне казалось, что MySQL старьё, и все эти реляционные БД - нахуй их, миром правит NoSQL и JSON. Это всё лирика. Боже, блядь, как же я ошибался. Я за двое суток так люто наебался с Mongo, что теперь я даже лучше говна сожру, чем буду пытаться в этой поделке что-то разобрать. Поставил PostgreSQL, пару часов курения доки, пару вопросов на StackOverflow, 1 вопрос в /pr/ и у меня всё закрутилось-завертелось. Та же хуйня с Ruby/Perl/etc. Лучше выбирать классический джентельменский набор - PHP + MySQL/Postgre + JS на фронте. А то напридумывают свои какие-то моднявые связки Go + TypeScript, а потом молодняк приходят на StackOverflow с каким-то вопросом и ждёт ответа по 6-7 часов от того несчастного мелкого комьюнити, которое образовалось в следствие саздания новага язига, каторый, сматрите, бистрее пыхыпы на 5%!. Фу блять.

Ответы3301835984

28 июля, 00:35 #625 #1033005

MariaDB-что скажете?

Ответы33019

28 июля, 00:51 #626 #1033008

Ссылки для унижения пистонистов,
современный PHP 7 в среднем в 2-3 раза быстрее Python:

https://benchmarksgame.alioth.debian.org/u64q/php.html

https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=php&lang2=hack

https://benchmarksgame.alioth.debian.org/u64q/compare.php?lang=php&lang2=yarv

(выше в тестах сложные алгоритмы, а на базовых операция -- циклы, динамические массивы, простые мат.операции PHP быстрее в 3 раза)

Ответы3302033039

28 июля, 01:26 #627 #1033016

>>1032947
Ну как-то поймёшь, вопрос -- на каком уровне. Не попробуешь -- не узнаешь, опять же.

28 июля, 01:27 #628 #1033017

>>1032995
Проиграл с матёрого фронтендщика

28 июля, 01:30 #629 #1033018

>>1033000
Так он и не быстрее, как правило... Там выше есть ссылки.

Ответы33029

28 июля, 01:30 #630 #1033019

>>1033005
Юзаю в конторе, всё нормально, подводных не обнаружено.

28 июля, 01:32 #631 #1033020

>>1033008
А теперь давай то же для жс на ноде.

Ответы33037

28 июля, 01:35 #632 #1033021

>>1032548
>>1032663
Вы заебали, помогите нуфагу с ларавелем. Допустим есть несколько связанных таблиц, в чистом пхп я бы сделал по классу на каждую таблицу с полями колонок, а потом имел массивы объектов. Как это делается правильно в ларавеле???

Ответы33040

28 июля, 02:01 #633 #1033029

>>1033018
Я не столько хотел заострить внимание на производительности, сколько на объёме комьюнити. На PHP уже столько гайдов и мануалов, столько собак съедено, что в него достаточно просто войти имея желание, терпение и умение правильно формировать поисковые запросы в гугле. А они продолжают создавать Ruby, Go, Rust, Perl, etc тем самым разбивая комьюнити на меньшие группки.

Ответы3304133099

28 июля, 03:43 #634 #1033037

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

Ответы3306833211

28 июля, 03:44 #635 #1033039

>>1033008
я думаю ты же понимаешь в чём разница работы ужа и пыхи ?

28 июля, 03:45 #636 #1033040

>>1033021
гугли доктрину , или Eloquent

Ответы33064

28 июля, 03:49 #637 #1033041

>>1033029
Ruby вышел в том же году что и php , но как не странно на борту у него уже тогда был бест практис , что и стало даже + ибо не было тонны говнокода

Go мимо ибо он убийца С\С++ потому ниша в вебе у него не велика

Rust туда же к GO

Perl - старый пережиток был ранее PHP

Ответы330683309933211

28 июля, 08:32 #638 #1033064

>>1033040
Я спрашиваю о логике, а он меня посылает гуглить синтаксис.

Ответы33187

28 июля, 09:07 #639 #1033068

>>1033041
>>1033037
Хорошь флеймить, идите в срач-тред

28 июля, 09:54 #640 #1033093

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

28 июля, 10:08 #641 #1033099

>>1033041

Руби (точнее популярный фреймворк Руби он Рейлс) за образец точно брать не стоит, там были приняты такие вещи, как патчинг одним модулем другого: https://habrahabr.ru/company/Voximplant/blog/269467/

Ну и вообще там много неоднозначного, везде статические вызовы, в тех же моделях замешаны active record, валидация, генерация ссылок.

>>1033029

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

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

>>1032928

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

> for($z = 0; $z <= count($bills); $z++) {
> if($bills[$z] == 0){
Ты в цикле ищешь элементы с ключами 0, 1, 2 ..., а у тебя в массиве таких ключей нет. Для перебора массива лучше использовать foreach, а не for.

>>1032910

Ключ элемента массива указан слева, значение элемента справа.

28 июля, 10:08 #642 #1033100

>>1032893

Посмотри мануал по функции pg_query: http://php.net/manual/ru/function.pg-query.php

> Возвращаемые значения
> Ресурс результата запроса в случае успеха или FALSE в случае возникновения ошибки

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

Я советую почитать про то, как пользоваться pg-функциями, начать можно отсюда: http://php.net/manual/ru/pgsql.examples-basic.php

Вот инфа про ресурсы, если надо: http://php.net/manual/ru/language.types.resource.php

Также, у тебя в коде SQL инъекция, нельзя вставлять данные прямо в запрос: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

>>1032731

Потому что неправильно написано. Давай на это посмотрим:

[+7] - это обозначает "ровно один символ из набора '+' или '7'". Перечитай, что обозначают разные виды скобок. Квадратные скобки обозначают "один любой из указанных символов".

>>1032730

> foreach ($quest->workers->w as $w->endStavka = $value)
так писать нельзя, справа от as нужно указать одну или две переменных, а не выражение. Перечитай пожалуйста про цикл foreach: http://php.net/manual/ru/control-structures.foreach.php

И тогда наверно ошибка исчезнет.

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

>>1032729

А ты попробуй написать такое выражение:

- цифра, за ней любой из символов \s ( ) -, повторяющийся любое число раз

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

28 июля, 10:08 #642 #1033100

>>1032893

Посмотри мануал по функции pg_query: http://php.net/manual/ru/function.pg-query.php

> Возвращаемые значения
> Ресурс результата запроса в случае успеха или FALSE в случае возникновения ошибки

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

Я советую почитать про то, как пользоваться pg-функциями, начать можно отсюда: http://php.net/manual/ru/pgsql.examples-basic.php

Вот инфа про ресурсы, если надо: http://php.net/manual/ru/language.types.resource.php

Также, у тебя в коде SQL инъекция, нельзя вставлять данные прямо в запрос: https://github.com/codedokode/pasta/blob/master/security/sql-injection.md

>>1032731

Потому что неправильно написано. Давай на это посмотрим:

[+7] - это обозначает "ровно один символ из набора '+' или '7'". Перечитай, что обозначают разные виды скобок. Квадратные скобки обозначают "один любой из указанных символов".

>>1032730

> foreach ($quest->workers->w as $w->endStavka = $value)
так писать нельзя, справа от as нужно указать одну или две переменных, а не выражение. Перечитай пожалуйста про цикл foreach: http://php.net/manual/ru/control-structures.foreach.php

И тогда наверно ошибка исчезнет.

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

>>1032729

А ты попробуй написать такое выражение:

- цифра, за ней любой из символов \s ( ) -, повторяющийся любое число раз

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

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

28 июля, 10:09 #643 #1033102

>>1032705

> Имя кошки - http://ideone.com/9gYMJD
Верно

> Лев Толстой: http://ideone.com/c7jA9P
Верно, но слишком длинные конструкции вроде $word1[array_rand($word1)] лучше было бы не писать прямо в строке, а вынести в отдельную переменную.

> Палиндром: http://ideone.com/k76YfM
Ок, верно

>>1032449

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

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

>>1032333

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

>>1032306

После 700-900 постов

28 июля, 10:09 #644 #1033103

>>1032249

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

>>1032222

Заголовки отдавать - это дело контроллера в MVC.

>>1032041

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

Ну и вопрос еще, сколько ты процентов времени сэкономишь, перенеся класс Request в C++. Может быть, большая часть времени не в нем теряется.

>>1032002

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

https://developer.mozilla.org/ru/docs/Web/HTTP/Кэширование

Ну а также научиться чистить кеш в браузере.

>>1031692

- для хранения списка чего-либо, каких-то значений или сущностей
- для задания соответствия между одними значениями и другими (код ошибки -> текст ошибки, фамилия ученика -> оценка по математике)

28 июля, 10:09 #644 #1033103

>>1032249

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

>>1032222

Заголовки отдавать - это дело контроллера в MVC.

>>1032041

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

Ну и вопрос еще, сколько ты процентов времени сэкономишь, перенеся класс Request в C++. Может быть, большая часть времени не в нем теряется.

>>1032002

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

https://developer.mozilla.org/ru/docs/Web/HTTP/Кэширование

Ну а также научиться чистить кеш в браузере.

>>1031692

- для хранения списка чего-либо, каких-то значений или сущностей
- для задания соответствия между одними значениями и другими (код ошибки -> текст ошибки, фамилия ученика -> оценка по математике)

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

28 июля, 10:09 #645 #1033104

>>1031671

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

>>1031533

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

>>1031384

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

>>1031410

А эти строчки влияют на выбор БД Ларавелем? И не переопределяются ли параметры где-то в коде?

>>1031490

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

>>1031474

Что-то по набору программ это ZverCD напоминает, он случайно винду не заменяет при установке?

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

28 июля, 10:09 #645 #1033104

>>1031671

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

>>1031533

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

>>1031384

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

>>1031410

А эти строчки влияют на выбор БД Ларавелем? И не переопределяются ли параметры где-то в коде?

>>1031490

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

>>1031474

Что-то по набору программ это ZverCD напоминает, он случайно винду не заменяет при установке?

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

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

28 июля, 10:10 #646 #1033105

>>1031120

Для начала, можешь ли ты запустить встроенный в PHP сервер без PhpStorm (из командной строки)? работает ли он?

Если да, то правильно ли в настройках PHPStorm указан путь к интерпретатору PHP?

Какая версия PHP?

>>1031432

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

>>1031179

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

>>1031122

Открыть отладчик (Ctrl + Shift + I), посмотреть свойства, примененные к диву, его размеры.

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

>>1030925

Знак = добавляет новый элемент массива, массив постоянно растет и цикл никогда не закончится. тут правильнее использовать == вместо = и foreach вместо for.

>>1030872

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

28 июля, 10:10 #646 #1033105

>>1031120

Для начала, можешь ли ты запустить встроенный в PHP сервер без PhpStorm (из командной строки)? работает ли он?

Если да, то правильно ли в настройках PHPStorm указан путь к интерпретатору PHP?

Какая версия PHP?

>>1031432

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

>>1031179

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

>>1031122

Открыть отладчик (Ctrl + Shift + I), посмотреть свойства, примененные к диву, его размеры.

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

>>1030925

Знак = добавляет новый элемент массива, массив постоянно растет и цикл никогда не закончится. тут правильнее использовать == вместо = и foreach вместо for.

>>1030872

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

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

28 июля, 10:10 #647 #1033106

>>1030863

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

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

>>1030803

Если изучить сначала ООП, а потом почитать мое описание паттернов работы с БД, то, наверно, не убегут.

>>1030787

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

Чтобы пользоваться Homestead (образом для виртуальной машины) нужно разумеется знать основы командной строки, основные команды линукса, администрирование сервера на линуксе, наверно немного прочесть про сам Вагрант, а также изучить документацию по образу: https://laravel.com/docs/5.4/homestead#introduction

Прочел ли ты эту документацию?

Что касается файлов, там предлагается расшарить папку с хоста в виртуальную машину. Хотя, можно и копировать файлы в виртуальную машину через scp, sftp или другие протоколы. Опять же, из-за того что ты не изучал линукс и возможности расшаривания папок/копирования файлов, ты и путаешься.

Кроме виртуальной машины, в PHP можно использовать разные варианты серверов:

- встроенный в PHP веб-сервер
- Апач + mod_php
- Нгинкс + php-fpm

Проще всего, конечно, встроенный в PHP веб-сервер. Для его использования надо знать лишь основы командной строки.

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

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

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

Я всегда готов помочь, если после чтения документации что-то осталось непонятно.

> Как мне подключиться к БД?
Через какой клиент? Где у тебя установлена БД и какая?

> Как использовать phpMyAdmin?
А ты его установил? Куда и как он настроен?

28 июля, 10:10 #647 #1033106

>>1030863

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

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

>>1030803

Если изучить сначала ООП, а потом почитать мое описание паттернов работы с БД, то, наверно, не убегут.

>>1030787

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

Чтобы пользоваться Homestead (образом для виртуальной машины) нужно разумеется знать основы командной строки, основные команды линукса, администрирование сервера на линуксе, наверно немного прочесть про сам Вагрант, а также изучить документацию по образу: https://laravel.com/docs/5.4/homestead#introduction

Прочел ли ты эту документацию?

Что касается файлов, там предлагается расшарить папку с хоста в виртуальную машину. Хотя, можно и копировать файлы в виртуальную машину через scp, sftp или другие протоколы. Опять же, из-за того что ты не изучал линукс и возможности расшаривания папок/копирования файлов, ты и путаешься.

Кроме виртуальной машины, в PHP можно использовать разные варианты серверов:

- встроенный в PHP веб-сервер
- Апач + mod_php
- Нгинкс + php-fpm

Проще всего, конечно, встроенный в PHP веб-сервер. Для его использования надо знать лишь основы командной строки.

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

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

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

Я всегда готов помочь, если после чтения документации что-то осталось непонятно.

> Как мне подключиться к БД?
Через какой клиент? Где у тебя установлена БД и какая?

> Как использовать phpMyAdmin?
А ты его установил? Куда и как он настроен?

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

28 июля, 10:10 #648 #1033107

>>1030798

Я подозреваю, что просто apt-get install для phpmyadmin может быть недостаточно, там еще может понадобиться что-то настроить, например, включить демон веб-сервера.

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

>>1030806

> У меня есть проект, который я создал через composer. Но он никак не связан с тем, что в hosts
Я не очень понял, а что значит "не связан с тем, что в hosts"? hosts используется для добавления доменов без использования DNS-сервера. Там не пишутся названия проектов, а только доменные имена и соответсвующие им IP адреса.

Ты бы почитал хоть немного про то, что это за файл.

>>1030802

> Но я читал документацию с начала. Русскую. Там ребята начали с того, что хорошо было бы поставить homestead.
Чтобы им пользоваться, нужно изучить теорию сначала, линукс и его особенности, администрирование линукса, почитать документацию по самому homestead. Плохо, если документация об этом умолчала, это говорит о низком ее качестве.

> У меня не работает http://homestead.app
> Точнее, он как бы работает и пишет No input file specified.
Нужно смотреть логи веб-сервера либо php-fpm, в зависимости от того, как там это настроено (внутри виртуальной машины).

> Я хочу использовать MySQL, а там привык юзать phpMyAdmin. Хотел бы знать, как это использовать в связке с Laravel. Как установить, как начать пользоваться.
phpmyadmin устанавливается отдельно от лаправель, никак с ним не связан. Тебе надо его установить и настроить.

> Но как мне войти в свой проект-то?
Не понял что значит "войти в проект". Подсоединиться по SSH к виртуальной машине с веб-сервером? Или что?

28 июля, 10:10 #648 #1033107

>>1030798

Я подозреваю, что просто apt-get install для phpmyadmin может быть недостаточно, там еще может понадобиться что-то настроить, например, включить демон веб-сервера.

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

>>1030806

> У меня есть проект, который я создал через composer. Но он никак не связан с тем, что в hosts
Я не очень понял, а что значит "не связан с тем, что в hosts"? hosts используется для добавления доменов без использования DNS-сервера. Там не пишутся названия проектов, а только доменные имена и соответсвующие им IP адреса.

Ты бы почитал хоть немного про то, что это за файл.

>>1030802

> Но я читал документацию с начала. Русскую. Там ребята начали с того, что хорошо было бы поставить homestead.
Чтобы им пользоваться, нужно изучить теорию сначала, линукс и его особенности, администрирование линукса, почитать документацию по самому homestead. Плохо, если документация об этом умолчала, это говорит о низком ее качестве.

> У меня не работает http://homestead.app
> Точнее, он как бы работает и пишет No input file specified.
Нужно смотреть логи веб-сервера либо php-fpm, в зависимости от того, как там это настроено (внутри виртуальной машины).

> Я хочу использовать MySQL, а там привык юзать phpMyAdmin. Хотел бы знать, как это использовать в связке с Laravel. Как установить, как начать пользоваться.
phpmyadmin устанавливается отдельно от лаправель, никак с ним не связан. Тебе надо его установить и настроить.

> Но как мне войти в свой проект-то?
Не понял что значит "войти в проект". Подсоединиться по SSH к виртуальной машине с веб-сервером? Или что?

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

28 июля, 10:13 #649 #1033108

>>1030198

В такой ситуации проще всего с помощью strace (под линукс) или procmon (винда) посмотреть, к каким файлам идет обращение при вызове gettext().

На винде в PHP5.4 у меня твой скрипт выдает:

> setlocale failed: locale function is not available on this platform....

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

Например, у меня в винде var_dump(setlocale(LC_ALL, null)); выдает:

> string(26) "English_United States.1252"

В MSDN наверно можно найти, какие конкретно локали есть в винде.

Также, PHP5.3 не выдает ошибку, но сообщение не переводит. procmon не запускается и падает с ошибкой, потому посмотреть, куда он лезет, не могу.

На линуксе выдается ошибка в setlocale, из-за того, что у меня нет русской локали. Исправил локаль на "C", и увидел через strace, что код пытается лезть в /locale за сообщениями.

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

Я вижу такие ссылки на MSDN:

- https://msdn.microsoft.com/en-us/library/x99tb11d.aspx
- https://msdn.microsoft.com/en-us/library/hzz3tw78.aspx

И вот тут интересная инфорамция на русском: https://anton-pribora.ru/articles/php/locales/

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

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

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

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

Переменные окружения хорошо подходят для задания локали по 2 причинам:

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

Увы, тут есть и недостаток: переменные окружения общие для всех тредов многотредового процесса, то есть в случае с многопотоным PHP (например в mod_php) нельзя ставить независимо разные локали для разных потоков.

Локали влияют и на работу PHP, так как он использует библиотеки, которые смотрят на переменные окружения LC_.... и используют функции, зависящие от текущей локали. Локаль можно задавать через переменную LANG (общая настройка), LC_ALL или отдельно для каждой категории вроде LC_TIME.

То есть в Линуксе эти локали хорошо интегрированы, и разработчики программ ими пользуются. Что касается винды, надо читать доки по setlocale в MSDN.

Вернемся к gettext.

Если что, документация по сишной библиотеке gettext (а в PHP функции расширения gettext по сути просто вызывают эту библиотеку) есть тут: https://www.gnu.org/software/gettext/manual/gettext.html#gettext

Конкретно, вот документация по пути к файлам gettext: https://www.gnu.org/software/gettext/manual/gettext.html#Locating-Catalogs

> Because many different languages for many different packages have to be stored we need some way to add these information to file message catalog files. The way usually used in Unix environments is have this encoding in the file name. This is also done here. The directory name given in bindtextdomains second argument (or the default directory), followed by the name of the locale, the locale category, and the domain name are concatenated:

> dir_name/locale/LC_category/domain_name.mo

> The default value for dir_name is system specific. For the GNU library, and for packages adhering to its conventions, it’s:

> /usr/local/share/locale

> locale is the name of the locale category which is designated by LC_category. For gettext and dgettext this LC_category is always LC_MESSAGES. The name of the locale category is determined through setlocale (LC_category, NULL). When using the function dcgettext, you can specify the locale category through the third argument.

То есть самый надежный способ, получается такой:

- ставить дефолтную локаль (чтобы все встроенные функции работали одинаково независимо от внешних настроек)
- задать язык с помощью выбора домена (например: myapp-ru)
- задать базовый путь для сообщений в bindtextdomain (например /x/y/z/messages/)

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

Я проверил, локаль "C" работает и в линуксах, и в винде. Однако, при ее использовании gettext даже не пытается искать файл с сообщениям.

При выборе локали en_US.utf8 (только линукс, в винде не поддерживается), домена mydomain, папки /tmp, strace показывает, что gettext ищет файл переводов по следующим путям:

- /tmp/en_US/LC_MESSAGES/mydomain.mo
- /tmp/en/LC_MESSAGES/mydomain.mo

(так как в линуксе есть еще синонимы (алиасы) локалей и он их тоже перебирает).

То, что gettext не выводит никаких ошибок, это конечно, неудачное решение.

Также можно попробовать не использовать gettext, а например, стороннюю библиотеку Symfony Translator: https://symfony.com/doc/current/components/translation.html

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

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

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

Для форматирования строк (вставки чисел, подстрок, изменния формы слов в зависимости от числа или пола) стоит использовать возможности MessageFormatter в расширении Intl. То, что есть в gettext (ngettext) и в Symfony (transChoice) - это пародия на нормальный форматтер сообщений.

Я, признаюсь, сколько-то лет назад не знал про Intl и изобретал свои форматтеры со своим синтаксисом.

Также, я не уверен, что putenv на что-то влияет, так как она может быть только переопределяет переменные окружения внутри PHP для процессов-потомков и для getenv(), но не влияет на то, что прочитает библиотека gettext. Но я не уверен.

28 июля, 10:13 #649 #1033108

>>1030198

В такой ситуации проще всего с помощью strace (под линукс) или procmon (винда) посмотреть, к каким файлам идет обращение при вызове gettext().

На винде в PHP5.4 у меня твой скрипт выдает:

> setlocale failed: locale function is not available on this platform....

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

Например, у меня в винде var_dump(setlocale(LC_ALL, null)); выдает:

> string(26) "English_United States.1252"

В MSDN наверно можно найти, какие конкретно локали есть в винде.

Также, PHP5.3 не выдает ошибку, но сообщение не переводит. procmon не запускается и падает с ошибкой, потому посмотреть, куда он лезет, не могу.

На линуксе выдается ошибка в setlocale, из-за того, что у меня нет русской локали. Исправил локаль на "C", и увидел через strace, что код пытается лезть в /locale за сообщениями.

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

Я вижу такие ссылки на MSDN:

- https://msdn.microsoft.com/en-us/library/x99tb11d.aspx
- https://msdn.microsoft.com/en-us/library/hzz3tw78.aspx

И вот тут интересная инфорамция на русском: https://anton-pribora.ru/articles/php/locales/

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

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

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

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

Переменные окружения хорошо подходят для задания локали по 2 причинам:

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

Увы, тут есть и недостаток: переменные окружения общие для всех тредов многотредового процесса, то есть в случае с многопотоным PHP (например в mod_php) нельзя ставить независимо разные локали для разных потоков.

Локали влияют и на работу PHP, так как он использует библиотеки, которые смотрят на переменные окружения LC_.... и используют функции, зависящие от текущей локали. Локаль можно задавать через переменную LANG (общая настройка), LC_ALL или отдельно для каждой категории вроде LC_TIME.

То есть в Линуксе эти локали хорошо интегрированы, и разработчики программ ими пользуются. Что касается винды, надо читать доки по setlocale в MSDN.

Вернемся к gettext.

Если что, документация по сишной библиотеке gettext (а в PHP функции расширения gettext по сути просто вызывают эту библиотеку) есть тут: https://www.gnu.org/software/gettext/manual/gettext.html#gettext

Конкретно, вот документация по пути к файлам gettext: https://www.gnu.org/software/gettext/manual/gettext.html#Locating-Catalogs

> Because many different languages for many different packages have to be stored we need some way to add these information to file message catalog files. The way usually used in Unix environments is have this encoding in the file name. This is also done here. The directory name given in bindtextdomains second argument (or the default directory), followed by the name of the locale, the locale category, and the domain name are concatenated:

> dir_name/locale/LC_category/domain_name.mo

> The default value for dir_name is system specific. For the GNU library, and for packages adhering to its conventions, it’s:

> /usr/local/share/locale

> locale is the name of the locale category which is designated by LC_category. For gettext and dgettext this LC_category is always LC_MESSAGES. The name of the locale category is determined through setlocale (LC_category, NULL). When using the function dcgettext, you can specify the locale category through the third argument.

То есть самый надежный способ, получается такой:

- ставить дефолтную локаль (чтобы все встроенные функции работали одинаково независимо от внешних настроек)
- задать язык с помощью выбора домена (например: myapp-ru)
- задать базовый путь для сообщений в bindtextdomain (например /x/y/z/messages/)

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

Я проверил, локаль "C" работает и в линуксах, и в винде. Однако, при ее использовании gettext даже не пытается искать файл с сообщениям.

При выборе локали en_US.utf8 (только линукс, в винде не поддерживается), домена mydomain, папки /tmp, strace показывает, что gettext ищет файл переводов по следующим путям:

- /tmp/en_US/LC_MESSAGES/mydomain.mo
- /tmp/en/LC_MESSAGES/mydomain.mo

(так как в линуксе есть еще синонимы (алиасы) локалей и он их тоже перебирает).

То, что gettext не выводит никаких ошибок, это конечно, неудачное решение.

Также можно попробовать не использовать gettext, а например, стороннюю библиотеку Symfony Translator: https://symfony.com/doc/current/components/translation.html

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

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

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

Для форматирования строк (вставки чисел, подстрок, изменния формы слов в зависимости от числа или пола) стоит использовать возможности MessageFormatter в расширении Intl. То, что есть в gettext (ngettext) и в Symfony (transChoice) - это пародия на нормальный форматтер сообщений.

Я, признаюсь, сколько-то лет назад не знал про Intl и изобретал свои форматтеры со своим синтаксисом.

Также, я не уверен, что putenv на что-то влияет, так как она может быть только переопределяет переменные окружения внутри PHP для процессов-потомков и для getenv(), но не влияет на то, что прочитает библиотека gettext. Но я не уверен.

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

28 июля, 10:14 #650 #1033109

>>1030184

В документации xgettext нет параметра, описывающего метку, по которой надо искать строки?

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

>>1030104

Функция getEndStavka вызывается когда значение поля $this->rang еще не задано.

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

28 июля, 10:16 #651 #1033111

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

28 июля, 12:41 #652 #1033187

>>1033064
с начало нужно погуглить , а потом уже говорить такие глупости

Ответы33411

28 июля, 13:23 #653 #1033211

>>1033037
>>1033041
https://habrahabr.ru/post/274099/

Ответы332293323733241

28 июля, 14:19 #654 #1033229

>>1033211
>Фишка в том, что наши программисты гуглеры, а не ученые. Это обычно молодые, только выпустившиеся пацаны, которые возможно выучили Java, возможно даже C/C++ и может быть Python. Они не в состоянии понимать пробздетый язык, но мы все равно хотим, чтобы они делали хороший софт. Таким образом, мы даем им легкопонимаемый язык, к которому они быстро привыкнут.

и чем это отменяет что он легче чем кресты но сохраняет их профит ?

28 июля, 14:30 #655 #1033237

>>1033211

Я сильно сомневаюсь в том, что там написано, про корпорации. По моим ощущениям, Го сделан на замену Си, а не Си++ (он отличается от Си в первую очередь добавлением ООП, классов, нейсмпейсов, исключений).

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

Насчет больших приложений (убийца Явы и PHP конечно) - тут я не уверен, там пока банально дженериков нет, то есть вы например не можете объявить тип "Коллекция объектов класса Пользователь". Исключений нет, ООП есть, но немного странный. Я писал небольшую утилиту на Го ( https://github.com/codedokode/guarddog ) но напрочь позабыл, что там неудобно.

А, вспомнил, одна из неудачных имхо фич - это разделение функций на public/private по регистру первой буквы метода. Сильно портит код, имхо.

Ответы33263

28 июля, 14:34 #656 #1033241

>>1033211

> Посудите: можно нанять 100 посредственных программистов, дать им в руки Go и эта армия обезьян будет генерить вам много «неплохого» и очень даже поддерживаемого кода!

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

Там много низкоуровневых моментов, без знания Си будет тяжко.

Ответы33269

28 июля, 15:28 #657 #1033263

>>1033237
Нет ничего лучше Си и С++ в совокупности. Двачую бро.
Можно нубский вопрос, елси С++ так шикарно работает, производительность - Великая и т.д Почему на нем пишут мало корпорации и игроделов? На нем же можно отлично оптимизироваться.

Ответы332753328035979

28 июля, 15:30 #658 #1033269

>>1033241
Если выучишь Си - С легкостью выучишь и С++, зачем тратить время на Го, когда ты уже считай профи?

Ответы332723327535979

28 июля, 15:31 #659 #1033272

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

Нас потрут за оффтоп

Ответы33275

28 июля, 15:32 #660 #1033275

>>1033272
>>1033269
>>1033263
Если что это все писал один анон.

28 июля, 15:42 #661 #1033280

>>1033263

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

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

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

Ну и много неудобных оставшихся по наследству вещей:

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

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

Ответы33757

28 июля, 16:35 #662 #1033316

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

Ответы33375

28 июля, 16:41 #663 #1033322

Есть 2 файла: 1.php 2.php. В первом я написал:

<a href="2.php?name=1">LINK</a>

Во втором написано:

$name;
echo $name;

Пишет: Undefined variable: name. Как я понял, он значение не передает. Вопрос: почему?

Ответы33323

28 июля, 16:43 #664 #1033323

>>1033322
$name = $_GET['name'];

Ответы33332

28 июля, 16:55 #665 #1033332

>>1033323
Благодарю.

28 июля, 17:38 #666 #1033375

>>1033316
уже не надо. сам додумался:

foreach ($foo as $key => $value) {
if (count($value) >= n ) {
$bar[$key] = $value;
}
}

28 июля, 17:49 #667 #1033386

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

Ответы3530335979

28 июля, 17:49 #668 #1033387

Нашёл учебник, издание от 2008. Он актуален ещё?

Ответы35303

28 июля, 18:04 #669 #1033411

9 Кб, 553x106

10 Кб, 614x145

>>1033187
Что гуглить, мань, если у меня документация по ларавелю по умолчанию открыта на элоквенте? Я умею в зависимости one2one, one2many и тд. Я задал вопрос по архитектуре, логике, а не синтаксису.

Ответы3344333454

28 июля, 18:30 #670 #1033443

>>1033411
а что по логике ? на каждую таблицу делаешь по модели , конектишь их через отношения , там где нужно взять что то зависимое делаешь $model->find(10)->sense(); и получаешь тот же массив всех связанных ? Какая ещё тебе архитектура нужна поверх MVC ?

Ответы33466

28 июля, 18:35 #671 #1033454

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

Ответы33466

28 июля, 18:42 #672 #1033466

>>1033443
>>1033454
Может я и правда плохо сформулировал вопрос, прошу прощения, попробую переформулировать.

В самом конце я бы хотел иметь объект (или массив объектов), например user с полями id:int, firstName:string, secondName:string, rentedBooks:object[]. Здесь первые три поля из таблички юзеров, а арендованные книжки из таблички книжек. Хочу обращаться потом к объекту user->rentedBooks[7], например, ну вы поняли.

В обычном пхп я бы создал класс User и класс Book, а потом вытаскивал данные и создавал бы инстансы этих классов. Но как это сделать в ларавеле? Где прописывать запросы к БД и создавать инстансы?

Ответы3352935979

28 июля, 19:19 #673 #1033513

Делаю запрос к Postgre:

$query = "SELECT data FROM searches WHERE id = $id";
$result = pg_query($query) or die('Query failed: ' . pg_last_error());

Если ID существует, то выводится JSON-массив, записанный мною ранее под этим ID. Если ID нет, то на фронте тригерится .fail().

Чо делать?

Ответы35303

28 июля, 19:57 #674 #1033529

>>1033466
по классике MVC вся работа с бизнес логикой должна быть в моделе , выходи так ты делаешь модель User делаешь отношение что у 1 User может быть много книг (я думаю с этим ты разобрался) , так как книга арендованная (видно так) то в модели Book ты ставишь что у книги может быть 1 User , в контроллере ты создаёшь инстанс пользователя , находишь пользователя по id например и через эти отношения получаешь массив объектов Book вот пример кода
$user->book();

28 июля, 20:28 #675 #1033565

ПЕРЕКАТ!!!

https://2ch.hk/pr/res/1033564.html (М)
https://2ch.hk/pr/res/1033564.html (М)
https://2ch.hk/pr/res/1033564.html (М)
https://2ch.hk/pr/res/1033564.html (М)
https://2ch.hk/pr/res/1033564.html (М)
https://2ch.hk/pr/res/1033564.html (М)

Ответы335723369333764

28 июля, 20:41 #676 #1033572

>>1033565
Нет

Ответы3357533603

28 июля, 20:50 #677 #1033575

>>1033572
Тред давно ушел в бамплимит, его уже тяжело найти.

Ответы33596

28 июля, 21:13 #678 #1033596

>>1033575
Ты тут новенький?

Ответы3360233603

28 июля, 21:16 #679 #1033602

>>1033596
Нет, а что?

28 июля, 21:17 #680 #1033603

>>1033596
>>1033572
В предыдущем было 939 постов, мы будем ждать?

28 июля, 22:16 #681 #1033626

Стрим PHP с решением задачек ОПа.

Ответы33628

28 июля, 22:16 #682 #1033628

>>1033626
http://www.twitch.tv/feycot

Ответы33712

29 июля, 01:09 #683 #1033693

>>1033565

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

29 июля, 02:27 #684 #1033710

Помогите, пожалуйста.
Сказано, что если заключить регулярное выражение между % и $, то оно будет искать только фразу в регулярном выражении и не будет искать фразу, где есть лишние символы(ну например не найдет "кот" в слове "скотина", как написал ОП-доброкун, нувыпонели).
Если я пишу вот так:

$regexp = '/^[(+7)|8][0-9]{4}$/u';

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

Ответы3371533717

29 июля, 02:34 #685 #1033712

>>1033628

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

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

Также, немного неудобно, что там у автора высокое разрешение и мелкие буквы и даже в 720p символы вроде "равно" плохо видны. Я бы советовал, если это нетрудно, увеличивать шрифт в редакторе, да и в браузере, раза в полтора-два.

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

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

---

Ну и еще, может автор не знает, но можно заставить браузер отображать текст со всеми пробелами и переводами строк:

---

Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить

header("Content-Type: text/plain; charset=utf-8");

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

Иначе перенос строки будет в исходном коде страницы (его можно увидеть нажав Ctrl + U), но на самой странице его не будет.

---

Также, оператора из 2 звездочек нет, для возведения в степень (в том числе дробную, возведение в 1/3 = корень третьей степени и отрицательную, x ^ -3 = 1 / (x ^ 3)) есть функция pow() , но по моему она не умеет возводить в степень отрицательные числа.

29 июля, 02:34 #685 #1033712

>>1033628

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

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

Также, немного неудобно, что там у автора высокое разрешение и мелкие буквы и даже в 720p символы вроде "равно" плохо видны. Я бы советовал, если это нетрудно, увеличивать шрифт в редакторе, да и в браузере, раза в полтора-два.

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

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

---

Ну и еще, может автор не знает, но можно заставить браузер отображать текст со всеми пробелами и переводами строк:

---

Чтобы переносы строк нормально работали и в браузере и в ideone (и в консоли), можно использовать для этого \n, а в начале программы поставить

header("Content-Type: text/plain; charset=utf-8");

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

Иначе перенос строки будет в исходном коде страницы (его можно увидеть нажав Ctrl + U), но на самой странице его не будет.

---

Также, оператора из 2 звездочек нет, для возведения в степень (в том числе дробную, возведение в 1/3 = корень третьей степени и отрицательную, x ^ -3 = 1 / (x ^ 3)) есть функция pow() , но по моему она не умеет возводить в степень отрицательные числа.

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

29 июля, 02:42 #686 #1033715

>>1033710

Не так. Не %, а ^.

^ обозначает "в этом месте должно быть начало строки". То есть ^abc ищет abc только если эти буквы идут в самом начале строки.

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

Внутри квадратных скобок ^ имеет другой смысл и значит "любой символ, кроме указанных".

$ обозначает "здесь должен быть конец строки", и abc$ найдет abc только если они идут в самом конце строки.

По твоей регулярке, ты не понял, как работают квадратные скобки. Они значат "один любой из указанных символов". Соответственно [(+7)|8] значит "один любой символ из набора: круглые скобки, плюс, семерка, вертикальная черта. восьмерка". Внутри квадратных скобок почти все символы, кроме ^ - \ ] не имеют специального значения и обозначают сами себя.

Мануал http://php.net/manual/ru/regexp.reference.character-classes.php

Ответы33722

29 июля, 02:47 #687 #1033717

>>1033710
>цифры начинающиеся на +7 валидность проходят, и на 8 тоже
забыл сказать: но валидность проходят и наборы символов, где в начале и в конце стоят другие символы.

29 июля, 02:57 #688 #1033722

>>1033715
>Соответственно [(+7)|8] значит "один любой символ из набора: круглые скобки, плюс, семерка, вертикальная черта. восьмерка"
А если экранировать круглые скобки, то будет искаться либо +7, либо 8?

Ответы33725

29 июля, 03:02 #689 #1033725

>>1033722

Экранирование лишает символ специального смысла. Например, + значит повторение, а \+ просто символ "плюс".

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

Ответы3372633732

29 июля, 03:07 #690 #1033726

>>1033725
Ну вроде понял, спасибо большое.

29 июля, 03:33 #691 #1033732

>>1033725
Все, я окончательно понял.
Спасибо большое, ты очень добр. ^____^

29 июля, 03:38 #692 #1033733

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

Ответы3374933764

29 июля, 05:37 #693 #1033742

>>1033712
Спасибо за замечание, в следующей трансляции постараюсь исправить.

29 июля, 05:59 #694 #1033749

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

Ответы33764

29 июля, 07:13 #695 #1033757

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

29 июля, 08:53 #696 #1033764

>>1033712
> Также, оператора из 2 звездочек нет, для возведения ...
https://3v4l.org/u4Gnp

>>1033733
Оно-то реально, но подумай как ты себя в коллективе чувствовать будешь, насколько комфортно будет другим учить великовозрастного дядю. У нас есть тимлиды в 25-27 лет с 7+ годами коммерческого опыта, джунов обычно набирают молодыми.

>>1033749
> 40+ мужики
> джунами
Мне было бы некомфортно с таким джуном общаться, сильный возрастной разрыв, как я буду учить такого человека, если он почти в 2 раза старше меня?

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

>>1033565
Никогда больше не перекатывай треды, лентяй. Шапку на pastebin никто читать не будет + ты забыл про этот >>1019303 пост.

Ответы3383135979

29 июля, 12:17 #697 #1033797

Что скажете про книгу
PHP 7. В подлиннике ?

Ответы33854

29 июля, 12:30 #698 #1033799

Котаны, я взял основы HTML 5.1, CSS3. Преподаватель сказал изучать дальше ASP.NET чтобы понять как работают сервера.
Щас буду практиковать верстку. Когда можно будет начать ПХП?

Ответы33800

29 июля, 12:30 #699 #1033800

>>1033799
Перед асп.нет

Ответы33801

29 июля, 12:34 #700 #1033801

>>1033800
Спасибо, добра.

29 июля, 13:32 #701 #1033831

>>1033764
>как ты себя в коллективе чувствовать будешь
А хуле мне их дискомфорт? Пусть учат

29 июля, 14:06 #702 #1033854

>>1033797
Просмотрел.
1000+ страниц и ни одного приличного листинга с кодом. В основном это краткий пересказ мануала, который ничему не учит.
Можно купить на рутрекере и листать иногда на предмет незнакомых слов если гугль отключили, денег за такое платить конечно не нужно.

Ответы33889

29 июля, 14:31 #703 #1033876

Задача про l33t speak в учебнике из шапки, что там надо исправить? На первый взгляд и так все работает, заданная фраза переводится в литспик. Добавить буквы недостающие в массив?

Ответы33904

29 июля, 15:04 #704 #1033889

>>1033854
А какие есть годные книги по PHP, которые надо читать после уроков опа?

Ответы33911

29 июля, 15:45 #705 #1033904

>>1033876
TaM 6ykBbI "JI", HaIIPuMeP, HeT.
Я просто дописал некоторые буквы, которые захотел, например.
Там, мне кажется, все равно ничего более сложного и не придумаешь. Иди лучше дальше.

29 июля, 15:57 #706 #1033908

А у меня вопрос назрел такой.
Скажем, есть чел, который не получил образования в сфере IT, учился там на какого-нибудь юриста, но знал php, вертску, js, mysql, вот это все, и фрилансом выполнил овер9000 заказов. Он будет считаться джуниором, если он пойдет на постоянную работу, где его деятельность не будет отличаться от той, когда он фрилансил? Почему?

Ответы3392333926

29 июля, 16:00 #707 #1033911

>>1033889
Ты задачи Студенты и Файлообменник делал?
Если нет, то делай студентов, ОП написал к ней кучу статей.
По книгам: классика жанра Мэтт Зандстра "Объекты, Шаблоны и Методики Программирования". Потом думаю Фаулер.

29 июля, 16:11 #708 #1033923

>>1033908
У него нет опыта командной разработки.
Его код с большой долей вероятности, будет "попахивать", т.к. нет постоянного контроля качества.
Конечно зависит от конторы и реального уровня фрилансера. Понятно, что между 3 у.е час крудошлепом и 30 у.е. час лара/симфони ангуляр/реакт специалистом довольно чувствительная разница.

Ответы33943

29 июля, 16:15 #709 #1033926

>>1033908

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

Ответы33943

29 июля, 16:50 #710 #1033943

>>1033923
>>1033926
Ясно, понятно.

31 июля, 14:09 #711 #1034845

есть одна страница stranica.com
1. пишешь туда ссылку ssilka.com
2. генерирует рандом 4 символа и записывает в бд ссылку\символы asdf
3. апачь редиректет 404 запросы на страницу с пхп кодом stranica.com/asdf -> stranica.com/phpscript
4. смотрит _$SERVER[HTTP_REQUEST] = asdf и из бд вытаскивает ssilka.com
5. выводит на страницу жс скрипт с редиректом на ssilka.com

Как это сделать без редиректа на stranica.com/phpscript, через htaccess?
И что вообще еще можно поменять?

Ответы35979

31 июля, 16:21 #712 #1034927

Сделал вам шапку на гитхабе:

https://github.com/phpguron/php_thead/wiki

Ответы35222

31 июля, 23:33 #713 #1035222

>>1034927

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

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

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

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

31 июля, 23:46 #714 #1035234

5 Кб, 294x167

8 Кб, 383x223

10 Кб, 546x213

4 Кб, 1298x60

>>1033103
>Если не смог решить проблему, дай минимальный пример кода и напиши, какую ошибку он выдает.

Не понимаю до сих пор почему так.

Еси закоментить строчки:

namespace Core;
use Core\Router;

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

Ответы3528435285

1 авг, 00:36 #715 #1035284

>>1035234

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

Также, в линуксе важен регистр букв в имени файлов и папок. Должно быть именно Core, с большой буквы.

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

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

Ответы35289

1 авг, 00:37 #716 #1035285

>>1035234

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

1 авг, 00:49 #717 #1035289

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

Если я пишу в index.php use Core\Router;

То он ищет его вот так:
string(51) "C:\OpenServer\domains\link.loc\Core\Core\Router.php"

Что делать то в итоге с этим?

Ответы35290

1 авг, 00:56 #718 #1035290

>>1035289

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

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

Также, в PHP уже есть реализация похожего на PSR-4 автозагрузчика: http://php.net/manual/ru/function.spl-autoload.php . По моему он не на 100% соответствует спецификации PSR-4. Было бы хорошо, если бы ты прочел документацию и проверил, соответствует он PSR-4 или нет, если нет, то в чем.

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

Ответы35296

1 авг, 01:10 #719 #1035296

>>1035290
Спасибо, сейчас попытаюсь въехать. Алсо иметь в итоге в ооп-проекте старую добрую functions.php считается зашкваром или как? Или делают какой-то статический класс с глобальной видимостью что бы ему кормить когда нужно переменные?

И еще, пытаюсь тут понять про Dependency Injection, и у меня вопрос. А чем это по сути отличается от процедурной лапши?

Вместо обычной functionname() влюбом месте кода мы просто пишем в итоге
$this->someshit->functionname()

Как и всевозможные
$a = $this->config->get('varname);

по сути ни что иное как сделать:
global $config = array(...);
и писать в коде
$a = $config['varname'];

Ответы35714

1 авг, 01:43 #720 #1035303

>>1033386
Нет, этим занимается планировщик ос

>>1033387
Азы -- да, в целом по-хорошему -- нет

>>1033513
А что надо делать?

Ррррряяяягулярки 1 авг, 14:30 #721 #1035461

Котаны,объясните пжлст дебилу, что с моей регуляркой (задача про номера телефонов) не так?

(\+\-\ 7|8\-\ \()(\d?\-\ \(\)*){10}

Вот как это вижу я:
первая часть: символ +, возможные пробелы-тире, 7 ИЛИ 8, возможные пробелы-тире-скобки;
вторая часть: цифра 0-9, возможные пробелы-тире-скобки, всё это повторить 10 раз.

ЧЯДНТ?

Ответы3554235687

1 авг, 14:32 #722 #1035463

Звёздочки съелись, лучше ссылкой https://regex101.com/r/t0lc8H/1

Ответы35542

1 авг, 17:03 #723 #1035542

>>1035461
>>1035463
Уже сам неспортивно нагуглил,косяк в том,что надо писать все воможные символы одним куском в квадратных скобках,а уже к нему применять *

1 авг, 18:27 #724 #1035603

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

Ответы3561235683

1 авг, 18:36 #725 #1035612

>>1035603
А, дошло:
(?!\w+$)

1 авг, 19:21 #726 #1035650

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

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

Ответы3568335695

1 авг, 20:03 #727 #1035683

>>1035650

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

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

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

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

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

>>1035603

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

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

По фрагменту регулярки (?!\w+$), трудно понять, праивльно ли она будет работать или нет.

1 авг, 20:06 #728 #1035687

>>1035461

У тебя код для поиска дополнительных символов (минусов, пробелов) задает определенный порядок, в котором они должны идти:

\-＊\ ＊\(＊\)＊

Это значит "сначала любое число минусов, потом любое число пробелов, ..". Но если между цифрами идет последовательность "пробел, минус, пробел" то она не будет соответствовать этому выражению.

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

Также, минус вне квадратных скобок не требует экранирования бекслешем. Пробел не требует бекслеша.

Спецсимволы, которые надо экранировать, перечислены тут: http://php.net/manual/ru/regexp.reference.meta.php

Ответы36016

1 авг, 20:15 #729 #1035695

>>1035650
Если у тебя каждый юзер постоянно влияет на других юзеров, и 1 его клик в системе вызывает цепную реакцию, то нагрузка на бд будет расти очень быстро. С поправкой конечно на то что число активных юзеров тоже постоянно растет. Если у тебя проект на 2000 тел то там не важно даже наверное как ты сделаешь. В статистике хостинга будешь видеть 1-5% нагрузку на бд в любом случае в пиковые моменты.

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

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

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

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

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

Всё зависит в итоге только какая нужна актуальность. Если у тебя подобие биржи какой-нибудь, и инфа должна всегда быть без задержки, то тогда и надо вокруг этого плясать - тут я хз.

1 авг, 20:15 #729 #1035695

>>1035650
Если у тебя каждый юзер постоянно влияет на других юзеров, и 1 его клик в системе вызывает цепную реакцию, то нагрузка на бд будет расти очень быстро. С поправкой конечно на то что число активных юзеров тоже постоянно растет. Если у тебя проект на 2000 тел то там не важно даже наверное как ты сделаешь. В статистике хостинга будешь видеть 1-5% нагрузку на бд в любом случае в пиковые моменты.

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

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

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

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

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

Всё зависит в итоге только какая нужна актуальность. Если у тебя подобие биржи какой-нибудь, и инфа должна всегда быть без задержки, то тогда и надо вокруг этого плясать - тут я хз.

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

1 авг, 20:56 #730 #1035714

>>1035296

Функции можно использовать, но стоит также рассмотреть возможность использовать utility-класс ( https://en.wikipedia.org/wiki/Helper_class ). Интересно, что при попытке погуглить "utility class" выпадает много результатов вроде "utility class pattern is evil", предлагаю читателю самостоятельно изучить указанные статьи и решить, веские ли аргументы там указаны.

Ну например, utility class дает возможность группировать функции по смыслу (впрочем, простые функции можно группировать по неймспейсам), автозагрузку.

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

ООП:

$form = new RegisterForm;
$form->parseData($request);
if ($form->isValid()) { ..

То же самое на функциях писать будет неудобно:

$form = createRegisterForm();
formParseData($form, $request);
if (formIsValid($form)) { ...

Получается какая-то неуклюжая имитация ООП, где информация о форме ($form) передается первым аргументом.

> Или делают какой-то статический класс с глобальной видимостью что бы ему кормить когда нужно переменные?
Это называется utility class

> И еще, пытаюсь тут понять про Dependency Injection, и у меня вопрос. А чем это по сути отличается от процедурной лапши?
> В чем разница между
> $a = $this->config->get('varname');
> $a = getConfig('varname');

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

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

> global $config = array(...);
> $a = $config['varname'];
Этот вариант обладает всеми недостатками подхода с функцией, но еще хуже, чем функция, так как труднее разбирать код. Например, непонятно, как вообще найти место, где задается эта переменная, когда кода много. Также, поскольку переменная доступна глобально, мы не можем быть уверены, что где-то на полпути ее не меняют (например, какой-нибудь начинающий разработчик вполне может влепить такой хак). Также, непонятно, как проверить, в данном файле, существуют ли эта переменная или она еще не создана и надо что-то вызвать сначала, чтобы ее заполнить?

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

Ну и я могу привести другие примеры, когда DI полезна. Ну например, возьмем объект соединения с БД. Допустим, у нас он самостоятельно берет параметры подключения из функции:

$dbal = new Dbal();
$dbal->makeQuery('SELECT .. FROM ...');

Вопрос: как с таким объектом сделать подключение к 2 разным БД? Тут как раз и поможет DI:

$dbal1 = new Dbal('db1', 'password1');
$dbal2 = new Dbal('db2', 'password2');

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

Вот тебе задачка для размышлений. Допустим, нам в приложении нужна функция конвертации валют: на вход даем сумму в одной валюте (например, рубль), на выходе получаем сумму в долларах. Курс перевода необходимо брать с удаленного сервера (например, ЦБ РФ предоставляет API для получения курса). Однако, мы не хотим при каждой конвертации делать запрос в сеть, так как курс меняется раз в сутки, мы хотим сохранять этот курс локально (например, в файл или кеш вроде redis) и использовать его в течение суток.

Также, мы хотим протестировать эти функции по отдельности, а именно:

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

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

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

Также, в моем уроке есть пункт "Пример использования преимуществ DI". Посмотри на написанный там код и предложит альтернативные варианты, как можно сделать такое же без DI или без ООП.

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

1 авг, 20:56 #730 #1035714

>>1035296

Функции можно использовать, но стоит также рассмотреть возможность использовать utility-класс ( https://en.wikipedia.org/wiki/Helper_class ). Интересно, что при попытке погуглить "utility class" выпадает много результатов вроде "utility class pattern is evil", предлагаю читателю самостоятельно изучить указанные статьи и решить, веские ли аргументы там указаны.

Ну например, utility class дает возможность группировать функции по смыслу (впрочем, простые функции можно группировать по неймспейсам), автозагрузку.

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

ООП:

$form = new RegisterForm;
$form->parseData($request);
if ($form->isValid()) { ..

То же самое на функциях писать будет неудобно:

$form = createRegisterForm();
formParseData($form, $request);
if (formIsValid($form)) { ...

Получается какая-то неуклюжая имитация ООП, где информация о форме ($form) передается первым аргументом.

> Или делают какой-то статический класс с глобальной видимостью что бы ему кормить когда нужно переменные?
Это называется utility class

> И еще, пытаюсь тут понять про Dependency Injection, и у меня вопрос. А чем это по сути отличается от процедурной лапши?
> В чем разница между
> $a = $this->config->get('varname');
> $a = getConfig('varname');

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

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

> global $config = array(...);
> $a = $config['varname'];
Этот вариант обладает всеми недостатками подхода с функцией, но еще хуже, чем функция, так как труднее разбирать код. Например, непонятно, как вообще найти место, где задается эта переменная, когда кода много. Также, поскольку переменная доступна глобально, мы не можем быть уверены, что где-то на полпути ее не меняют (например, какой-нибудь начинающий разработчик вполне может влепить такой хак). Также, непонятно, как проверить, в данном файле, существуют ли эта переменная или она еще не создана и надо что-то вызвать сначала, чтобы ее заполнить?

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

Ну и я могу привести другие примеры, когда DI полезна. Ну например, возьмем объект соединения с БД. Допустим, у нас он самостоятельно берет параметры подключения из функции:

$dbal = new Dbal();
$dbal->makeQuery('SELECT .. FROM ...');

Вопрос: как с таким объектом сделать подключение к 2 разным БД? Тут как раз и поможет DI:

$dbal1 = new Dbal('db1', 'password1');
$dbal2 = new Dbal('db2', 'password2');

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

Вот тебе задачка для размышлений. Допустим, нам в приложении нужна функция конвертации валют: на вход даем сумму в одной валюте (например, рубль), на выходе получаем сумму в долларах. Курс перевода необходимо брать с удаленного сервера (например, ЦБ РФ предоставляет API для получения курса). Однако, мы не хотим при каждой конвертации делать запрос в сеть, так как курс меняется раз в сутки, мы хотим сохранять этот курс локально (например, в файл или кеш вроде redis) и использовать его в течение суток.

Также, мы хотим протестировать эти функции по отдельности, а именно:

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

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

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

Также, в моем уроке есть пункт "Пример использования преимуществ DI". Посмотри на написанный там код и предложит альтернативные варианты, как можно сделать такое же без DI или без ООП.

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

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

2 авг, 05:16 #731 #1035881

>>1035714
Я может что-то не понимаю, но мне казалось, что депенденси инджекшн - это когда допустим работаешь с фреймворком, и прямо внутри контроллера можешь обратиться к модели через:
$this->modelName->methodName();
Ну и прочие встроенные во фреймворк штуки обычно точно так же уже доступны как я выше писал:
> $a = $this->config->get('varname');

Так вот для меня это как раз всё выглядит как тупо функциональный код.
Когда вместо
saveUserToDb($user);

тупо пишется:
$this->userModel->saveUser($user);

Теперь я вообще запутался

Ответы3589435896

2 авг, 06:57 #732 #1035894

>>1035881

А прочел ли ты урок, ссылку на который я дал? Там многое объясняется.

Во-вторых, а прочел ли ты внимательно мой пост? Я же тебе написал, в чем разница.

В-третьих, это назывеатся, не функциональный, а процедурный код ( https://ru.wikipedia.org/wiki/Парадигма_программирования )

То, что ты упоминаешь, к DI отношения не имеет.

Ответы35901

2 авг, 07:09 #733 #1035896

>>1035881

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

Ответы35901

2 авг, 07:40 #734 #1035901

>>1035894
>>1035896
Спасибо за ответы, попробую вдумчиво сейчас разобрать всё снова и задачу обдумать.

33 Кб, 720x304

2 авг, 08:30 #735 #1035915

После студентов таки взялся за Файлообменик. Буду писать на Слиме, с twig, monolog, может Medoo(хотя надо бы наконец выучить PDO). Так вот, сижу блядь и не знаю с чего начать. Почитал документацию по слиму, вроде можно разобраться.
Так вот, собираюсь уже написать стартовую страницу но возникла проблема со структурой проекта.
Пожалуйста напишите ТОЧНУЮ файловую-структуру. Где какие папки и где что должно лежать, используя MVC.

Например:
Slim.loc (название проекта)
/scr/public
/scr/public/css
/scr/public/fonts
/scr/public/js
/scr/templates(он же views?)
/scr/models
/vendor

Пожалуйста.

Ответы359163598135983

2 авг, 08:36 #736 #1035916

>>1035915
А так же index.php(точка входа) и .htaccess должны лежать я так понимаю в /scr/public
Туда же скинуть и composer.json and composer .lock and .ignore?

5 Кб, 275x183

2 авг, 10:21 #737 #1035955

>Самоучитель HTML4

2 авг, 10:54 #738 #1035979

>>1034845

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

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

>>1033764

Действительно, добавили такой оператор, я ошибся.

>>1033466

А ты читал вообще мануал по Eloquent?

Задаешь отношения между моделями как, например, описано тут: https://laravel.ru/docs/v5/eloquent-relationships

После чего легко можно получить связанные сущности, как описано в мануале. Затем делаешь метод $user->getRentedBooks() который получает, что тебе нужно. Это в любом случае лучше, чем публично доступное поле. Писать запросы и создавать объекты вручную скорее всего не надо, ORM сделает это за тебя.

>>1033386

Используй крон

>>1033269

В Го есть сборщик мусора например и синтаксис в некоторых местах более удобный, чем в Си++. И не надо писать деструкторы например.

>>1033263

Что значит "на Си++ мало пишут"? Откуда такая информация? Многие (топовые, а не от мамкиных самодельщиков) игры на Си++, офисные программы вроде Openoffice на Си++, браузер Хром на Си++, и еще куча софта.

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

2 авг, 10:54 #738 #1035979

>>1034845

Почему бы тебе не изучить документацию по Апачу (если ты его используешь)? Она правда большая и запутанная, но может дать какие-то идеи. Ну например, если нет возможности использовать htaccess, то можно вписать правила в конфиг Апача (хотя и этой возможности наверно не будет, если речь о каком-то нищехостинге с ограниченными правами).

Ну и непонятно, зачем там нужен яваскрипт, редирект делается через HTTP заголовки ответа.

>>1033764

Действительно, добавили такой оператор, я ошибся.

>>1033466

А ты читал вообще мануал по Eloquent?

Задаешь отношения между моделями как, например, описано тут: https://laravel.ru/docs/v5/eloquent-relationships

После чего легко можно получить связанные сущности, как описано в мануале. Затем делаешь метод $user->getRentedBooks() который получает, что тебе нужно. Это в любом случае лучше, чем публично доступное поле. Писать запросы и создавать объекты вручную скорее всего не надо, ORM сделает это за тебя.

>>1033386

Используй крон

>>1033269

В Го есть сборщик мусора например и синтаксис в некоторых местах более удобный, чем в Си++. И не надо писать деструкторы например.

>>1033263

Что значит "на Си++ мало пишут"? Откуда такая информация? Многие (топовые, а не от мамкиных самодельщиков) игры на Си++, офисные программы вроде Openoffice на Си++, браузер Хром на Си++, и еще куча софта.

Как я уже писал выше, производительность у него хорошая, но код на нем писать и отлаживать долго. Код быстро писать на HTML/JS, но производительность получается минимальная.

Показать весь текст

2 авг, 11:00 #739 #1035981

>>1035915

Ошибки в твоем варианте:

- public должен быть отдельно от src, в src мы держим код, который не отдаем наружу
- папку models лучше не делать. В MVC почти все, кроме контроллеров и вида относится к модели, соответственно не имеет смысла условно говоря делать папку для 75% кода. Лучше сделать отдельно папку для валидаторов, отдельно для классов работы с БД и тд.

Если классов мало, можно вообще свалить их в src без подпапок.

Также, прочти про PSR-4. У меня есть урок на гитхабе.

> А так же index.php(точка входа) и .htaccess должны лежать я так понимаю в /scr/public
Да, в public

> Туда же скинуть и composer.json and composer .lock and .ignore?
Ты хочешь всем пользователя сайта раздавать эти файлы? Зачем?

Эти файлы обычно кладут в корень.

Идея папки public в том, чтобы сделать публично доступной только одну папку (ради безопасности), а не весь проект. И в нее мы кладем только то, что хотим раздавать через веб-сервер пользователям.

> и не знаю с чего начать.
Начни с вывода страницы с текстом Hello World используя Слим.

Ответы36070

2 авг, 11:01 #740 #1035983

>>1035915

Еще часто templates делают отдельной папкой, чтобы в src был php-код, а в tenplates - шаблона на твиге.

Ответы36018

2 авг, 11:02 #741 #1035984

>>1033000

Справедливости ради, проблема ведь не в том, что Го или Монго "плохие". Проблема в том, что это инструменты со своими особенностями, которые хорошо работают в одной ситуации и не очень хорошо - в другой. Но блогеры-идиоты вместо объективного сравнения засоряют интернет высказываниями вроде "в 2017 году вместо A все используют B", а пользователи-идиоты бездумно следуют этим советам.

Изучите технологии, их сильные и слабые стороны, сделайте сравнительное тестирование и после этого выбирайте.

Я уверен, что на каких-то задачах Го в умелых руках будет работать идеально. Не уверен, правда, что в руках начинающего.

>>1032941

Не знаю, но знаю что официальный мануал PHP можно скачать в формате chm, имея соответствующий просмотрщик, можно читать его без интернета.

Также, на тот же андроид реально установить PHP/MySQL/Апач (но надо помучаться), редактор кода и что-то пытаться кодить, хотя конечно на маленькой клавиатуре будет печатать неудобно.

2 авг, 11:02 #742 #1035985

>>1032659

Для начала, стоит почитать ответы на эти вопросы:

- https://unix.stackexchange.com/questions/12260/how-to-encrypt-messages-text-with-rsa-openssl
- https://stackoverflow.com/questions/7143514/how-to-encrypt-a-large-file-in-openssl-using-public-key

(нашел гуглением по openssl rsa).

Там в частности написано, что RSA шифрует одно число, а не сообщение. Чтобы зашифровать большое сообщение, его разбивают на блоки и шифруют их симметричным шифрованием, причем есть несколько вариантов (режимов), как связать эти блоки между собой, вроде CBC, ECB.

И вот это: https://www.sitepoint.com/encrypt-large-messages-asymmetric-keys-phpseclib/

> The nature of the RSA algorithm is such that it is only able to encrypt a limited amount of plaintext. For example, if your key size is 2048 bits, then you are limited to 256 bytes (at most) of plaintext data that can be encrypted
> The solution to the problem is to encrypt the message with a symmetric key, then asymmetrically encrypt the key and attach it to the message.

Также, гуглением я нашел такие функции:

- http://php.net/manual/ru/function.openssl-public-encrypt.php
- http://php.net/manual/ru/function.openssl-private-encrypt.php

Обрати внимание на комментарии под ними. Расширение openssl является лишь интерфейсом к библиотеке openssl, потому подробности стоит смотреть еще и в описании этой библиотеки, например https://wiki.openssl.org/index.php/Main_Page

Также, я еще нашел вот это: https://en.wikipedia.org/wiki/Public-key_cryptography#Examples

Тут есть примеры конкретных методов ( Examples of protocols using asymmetric key algorithms include ): S/MIME, GPG, Off-the-record-messaging. Посмотри их - так как всегда лучше брать проверенную схему шифрования, чем с нуля изобретать свою. GPG - известная программа для шифрования почты, OTR используется в джаббере.

То есть, придется еще немного поковыряться в теории, прежде чем браться за практику (если что, я сам эти протоколы толком не знаю).

--------------

> При регистрации пользователя мы генерируем закртый\открытый ключ
Это значит мы должны доверять серверу, раз сервер генерирует пару ключей, а не клиент.

> Почему нету метода RSA? Однако, в опциях создания ключа можно указать этот тип
Думаю, потому, что RSA это не поточный шифр (не шифр, которым можно зашифровать произвольно большое сообщение).

Если у тебя установлена библиотека (не расширение PHP) openssl, то там есть команды:

openssl list-cipher-algorithms - дает тот же список что функция в PHP, без RSA
openssl list-public-key-algorithms - дает список с RSA, DH, DSA, EC, HMAC, CMAC

То есть это алгоритм не поточного шифрования, а чего-то другого.

> Эти все методы сделаны на его основе?
Стоит погуглить названия методов и посмотреть в общих чертах, как они работают. Ну например, AES-128-CBC, гуглим:

- AES: симметричный алгоритм блочного шифрования (размер блока 128 бит, ключ 128/192/256 бит), принятый в качестве стандарта шифрования правительством США по результатам конкурса AES
- 128: очевидно, размер ключа
- CBC: Cipher block chaining - режим шифрования, определяющий правила шифрования большого сообщения из нескольких блоков ( https://ru.wikipedia.org/wiki/Режим_шифрования )

Или SEED-CBC - SEED is a block cipher developed by the Korea Information Security Agency (KISA)...SEED is a 16-round Feistel network with 128-bit blocks and a 128-bit key

> В комментариях сказано, что RSA начинает устаревать и пора переходить на ECDH вместе с EdDSA. Что вы думаете по этому поводу?

Это по моему немного разные вещи, RSA это протокол асимметричного шифрования, DH - обмен ключами. Увы, не знаю, что лучше. Может быть стоит погуглить и посмотреть.

> Насколько я помню, протокол Диффи - Хеллмана генерирует общий ключ на основе закрытых\открытых ключей. Можно ли сказать, что этот протокол приводит асимметричное шифрование к симметричному?
Нет, лучше говорить что это протокол обмена ключами (собеседники получают общий ключ, не раскрывая свои ключи и не позволяя перехватить общий ключ).

> Эллиптические кривые только добавляют надёжности, я правильно понимаю?
Не знаю.

> но я не уверен что библиотека которая содержится в PHP использует алгоритм RSA (там какие-то методы (ссылаюсь на тот же вопрос выше о методах)).
ну там упомянуто, что она предназначена для взаимодействия с openssl, так что наверно должно работать.

> каким образом функция openssl_encrypt() шифрует данные из этой строки.
Судя по коду расширения https://github.com/php/php-src/blob/master/ext/openssl/openssl.c , строка 6523, там идет примерно такой алгоритм:

> cipher_type = EVP_get_cipherbyname(method);
> cipher_ctx = EVP_CIPHER_CTX_new();
> php_openssl_load_cipher_mode(&mode, cipher_type);
> php_openssl_cipher_init(...)
> EVP_EncryptFinal(cipher_ctx, (unsigned char )ZSTR_VAL(outbuf) + outlen, &i)
> base64_str = php_base64_encode((unsigned char)ZSTR_VAL(outbuf), outlen);
> RETVAL_STR(base64_str);

Функции, начинающиеся с EVP - это сишные функции библиотеки OpenSSL, документация по которым есть например тут: https://www.openssl.org/docs/man1.1.0/crypto/EVP_EncryptFinal.html

php_openssl_load_cipher_mode() и php_openssl_cipher_init() описаны в том же файле расширения (openssl.c) и являются обертками над функциями OpenSSL.

Тут конечно лучше попробовать найти статью "как зашифровать что-нибудь библиотекой OpenSSL".

> Зачем разделять код на две части? Это не более чем прихоть автора?
Чтобы те, кому не нужна вторая часть, не грузили ее.

2 авг, 11:02 #742 #1035985

>>1032659

Для начала, стоит почитать ответы на эти вопросы:

- https://unix.stackexchange.com/questions/12260/how-to-encrypt-messages-text-with-rsa-openssl
- https://stackoverflow.com/questions/7143514/how-to-encrypt-a-large-file-in-openssl-using-public-key

(нашел гуглением по openssl rsa).

Там в частности написано, что RSA шифрует одно число, а не сообщение. Чтобы зашифровать большое сообщение, его разбивают на блоки и шифруют их симметричным шифрованием, причем есть несколько вариантов (режимов), как связать эти блоки между собой, вроде CBC, ECB.

И вот это: https://www.sitepoint.com/encrypt-large-messages-asymmetric-keys-phpseclib/

> The nature of the RSA algorithm is such that it is only able to encrypt a limited amount of plaintext. For example, if your key size is 2048 bits, then you are limited to 256 bytes (at most) of plaintext data that can be encrypted
> The solution to the problem is to encrypt the message with a symmetric key, then asymmetrically encrypt the key and attach it to the message.

Также, гуглением я нашел такие функции:

- http://php.net/manual/ru/function.openssl-public-encrypt.php
- http://php.net/manual/ru/function.openssl-private-encrypt.php

Обрати внимание на комментарии под ними. Расширение openssl является лишь интерфейсом к библиотеке openssl, потому подробности стоит смотреть еще и в описании этой библиотеки, например https://wiki.openssl.org/index.php/Main_Page

Также, я еще нашел вот это: https://en.wikipedia.org/wiki/Public-key_cryptography#Examples

Тут есть примеры конкретных методов ( Examples of protocols using asymmetric key algorithms include ): S/MIME, GPG, Off-the-record-messaging. Посмотри их - так как всегда лучше брать проверенную схему шифрования, чем с нуля изобретать свою. GPG - известная программа для шифрования почты, OTR используется в джаббере.

То есть, придется еще немного поковыряться в теории, прежде чем браться за практику (если что, я сам эти протоколы толком не знаю).

--------------

> При регистрации пользователя мы генерируем закртый\открытый ключ
Это значит мы должны доверять серверу, раз сервер генерирует пару ключей, а не клиент.

> Почему нету метода RSA? Однако, в опциях создания ключа можно указать этот тип
Думаю, потому, что RSA это не поточный шифр (не шифр, которым можно зашифровать произвольно большое сообщение).

Если у тебя установлена библиотека (не расширение PHP) openssl, то там есть команды:

openssl list-cipher-algorithms - дает тот же список что функция в PHP, без RSA
openssl list-public-key-algorithms - дает список с RSA, DH, DSA, EC, HMAC, CMAC

То есть это алгоритм не поточного шифрования, а чего-то другого.

> Эти все методы сделаны на его основе?
Стоит погуглить названия методов и посмотреть в общих чертах, как они работают. Ну например, AES-128-CBC, гуглим:

- AES: симметричный алгоритм блочного шифрования (размер блока 128 бит, ключ 128/192/256 бит), принятый в качестве стандарта шифрования правительством США по результатам конкурса AES
- 128: очевидно, размер ключа
- CBC: Cipher block chaining - режим шифрования, определяющий правила шифрования большого сообщения из нескольких блоков ( https://ru.wikipedia.org/wiki/Режим_шифрования )

Или SEED-CBC - SEED is a block cipher developed by the Korea Information Security Agency (KISA)...SEED is a 16-round Feistel network with 128-bit blocks and a 128-bit key

> В комментариях сказано, что RSA начинает устаревать и пора переходить на ECDH вместе с EdDSA. Что вы думаете по этому поводу?

Это по моему немного разные вещи, RSA это протокол асимметричного шифрования, DH - обмен ключами. Увы, не знаю, что лучше. Может быть стоит погуглить и посмотреть.

> Насколько я помню, протокол Диффи - Хеллмана генерирует общий ключ на основе закрытых\открытых ключей. Можно ли сказать, что этот протокол приводит асимметричное шифрование к симметричному?
Нет, лучше говорить что это протокол обмена ключами (собеседники получают общий ключ, не раскрывая свои ключи и не позволяя перехватить общий ключ).

> Эллиптические кривые только добавляют надёжности, я правильно понимаю?
Не знаю.

> но я не уверен что библиотека которая содержится в PHP использует алгоритм RSA (там какие-то методы (ссылаюсь на тот же вопрос выше о методах)).
ну там упомянуто, что она предназначена для взаимодействия с openssl, так что наверно должно работать.

> каким образом функция openssl_encrypt() шифрует данные из этой строки.
Судя по коду расширения https://github.com/php/php-src/blob/master/ext/openssl/openssl.c , строка 6523, там идет примерно такой алгоритм:

> cipher_type = EVP_get_cipherbyname(method);
> cipher_ctx = EVP_CIPHER_CTX_new();
> php_openssl_load_cipher_mode(&mode, cipher_type);
> php_openssl_cipher_init(...)
> EVP_EncryptFinal(cipher_ctx, (unsigned char )ZSTR_VAL(outbuf) + outlen, &i)
> base64_str = php_base64_encode((unsigned char)ZSTR_VAL(outbuf), outlen);
> RETVAL_STR(base64_str);

Функции, начинающиеся с EVP - это сишные функции библиотеки OpenSSL, документация по которым есть например тут: https://www.openssl.org/docs/man1.1.0/crypto/EVP_EncryptFinal.html

php_openssl_load_cipher_mode() и php_openssl_cipher_init() описаны в том же файле расширения (openssl.c) и являются обертками над функциями OpenSSL.

Тут конечно лучше попробовать найти статью "как зашифровать что-нибудь библиотекой OpenSSL".

> Зачем разделять код на две части? Это не более чем прихоть автора?
Чтобы те, кому не нужна вторая часть, не грузили ее.

Показать весь текст
Ответы36395

2 авг, 12:13 #743 #1036016

>>1035687
Я вчера сам уже понял, но все равно спасибо,добра тебе ^_^

2 авг, 12:18 #744 #1036018

>>1035983
Твиг вообще актуален?
В чём реальное, а не рекламное преимущество перед шаблонами на обычном рнр?

Ответы3603840028

2 авг, 12:58 #745 #1036038

>>1036018
Преимущество в удобстве. И какая реклама, он разве платный?

1. Наследование.
Допустим, есть две страницы, на одной выводятся 5 самых популярных записей, сайдбар, на второй странице эти же записи с пагинацией и сайдбар с другим контентом/стилями.
С твигом создаешь один общий шаблон и обозначаешь в нем блоками места, которые можно переопределить в дочернем шаблоне.
Без твига будет либо копипаст, либо дикие джунгли с условными операторами.
2. Множество функций и фильтров, например вместо
<?php echo htmlspecialchars($var, ENT_QUOTES, 'UTF-8') ?>
{{ var|e }}
Или вообще включить экранирование по умолчанию (в последних версиях оно и так включено).
Еще вспомнил фичу, обращение через точку {{ variable.property }} работает как с массивами, так и с объектами, так что если понадобится извлекать из бд массивы, а не объекты, не придется переписывать представление (скобки и кавычки вместо стрелочек).

А, главное преимущество наверное в том, что писать на шаблонизаторе сможет верстальщик, который не знает PHP (бывает и такое разделение труда).

Но по сути да, это синтаксический сахар.

2 авг, 14:19 #746 #1036070

10 Кб, 230x80

22 Кб, 870x280

>>1035981
Спасибо. Начал.

Ответы36511

someApprentice 2 авг, 22:44 #747 #1036395

>>1035985
>Тут есть примеры конкретных методов ( Examples of protocols using asymmetric key algorithms include ): S/MIME, GPG, Off-the-record-messaging. Посмотри их - так как всегда лучше брать проверенную схему шифрования, чем с нуля изобретать свою. GPG - известная программа для шифрования почты, OTR используется в джаббере.
>То есть, придется еще немного поковыряться в теории, прежде чем браться за практику (если что, я сам эти протоколы толком не знаю).
Ок.

Может даже не придётся сильно погружаться в теорию, а изучить только библиотеку реализующую их.

Я нашёл вот эти вот:

http://php.net/manual/ru/ref.gnupg.php

Только почему-то я не вижу методов генерации ключей. Нужно найти другую в таком случае?

http://php.net/manual/ru/function.gnupg-import.php
http://php.net/manual/ru/function.gnupg-addencryptkey.php
http://php.net/manual/ru/function.gnupg-adddecryptkey.php
Почему несколько методов для добавления ключей?

Вообще, функции add..cryptkey выглядят довольно странно, в аргументы принимают отпечаток, а не сам ключи. Это и есть функции генерации ключей?

Отпечаток и подпись служат для одной цели - идентификации владельца ключа. Вы ранее советовали предусмотреть подпись, поэтому, имея возможность легко получить отпечаток, следует ли предусматривать ещё и подпись?

http://php.net/manual/ru/function.gnupg-addencryptkey.php#112979
>When you've successfully installed gnupg, you should define the GNUPGHOME environment variable and make sure the directory is writeable by the Apache user.
>putenv("GNUPGHOME=/var/www/example.com/.gnupg");
Почему ключи должны храниться где-то на диске?

https://openpgpjs.org/
https://github.com/openpgpjs/openpgpjs

https://github.com/openpgpjs/openpgpjs#getting-started
>Or just fetch a minified build under dist.
Они же предлагают это сделать в случае браузерной версии?
Я пробежался по этому коду (https://github.com/openpgpjs/openpgpjs/blob/master/dist/openpgp.js) и вроде там есть нужные функции. Сложно разобраться в их коде, очень всё запутанно, а в документации вообще некоторые страницы выдают 404.

https://openpgpjs.org/openpgpjs/doc/module-openpgp.html
https://openpgpjs.org/openpgpjs/doc/module-key.html
>encrypt(..., signature)
В отличии от php-библиотеки, js-библиотека использует подпись. Это одно и тоже, в этом случае?

https://openpgpjs.org/openpgpjs/doc/module-signature.html
>armoredText
Что такое armoredText?

http://php.net/manual/ru/function.gnupg-adddecryptkey.php
https://openpgpjs.org/openpgpjs/doc/module-openpgp.html (generateKey)
Обе эти функции используют passphrase, этой фразой шифруется приватный ключ и можно использовать эту опции в нашем случае?

https://openpgpjs.org/openpgpjs/doc/
>openpgp.encrypt(options).then
Зачем здесь может быть нужен Promise?

>> При регистрации пользователя мы генерируем закртый\открытый ключ
>Это значит мы должны доверять серверу, раз сервер генерирует пару ключей, а не клиент.
Для этого придётся усложнить код. Я оставлю это на дальнейшую реализацию (обмен ключами и др. данными через p2p), а пока пусть будет так.

someApprentice 2 авг, 22:44 #747 #1036395

>>1035985
>Тут есть примеры конкретных методов ( Examples of protocols using asymmetric key algorithms include ): S/MIME, GPG, Off-the-record-messaging. Посмотри их - так как всегда лучше брать проверенную схему шифрования, чем с нуля изобретать свою. GPG - известная программа для шифрования почты, OTR используется в джаббере.
>То есть, придется еще немного поковыряться в теории, прежде чем браться за практику (если что, я сам эти протоколы толком не знаю).
Ок.

Может даже не придётся сильно погружаться в теорию, а изучить только библиотеку реализующую их.

Я нашёл вот эти вот:

http://php.net/manual/ru/ref.gnupg.php

Только почему-то я не вижу методов генерации ключей. Нужно найти другую в таком случае?

http://php.net/manual/ru/function.gnupg-import.php
http://php.net/manual/ru/function.gnupg-addencryptkey.php
http://php.net/manual/ru/function.gnupg-adddecryptkey.php
Почему несколько методов для добавления ключей?

Вообще, функции add..cryptkey выглядят довольно странно, в аргументы принимают отпечаток, а не сам ключи. Это и есть функции генерации ключей?

Отпечаток и подпись служат для одной цели - идентификации владельца ключа. Вы ранее советовали предусмотреть подпись, поэтому, имея возможность легко получить отпечаток, следует ли предусматривать ещё и подпись?

http://php.net/manual/ru/function.gnupg-addencryptkey.php#112979
>When you've successfully installed gnupg, you should define the GNUPGHOME environment variable and make sure the directory is writeable by the Apache user.
>putenv("GNUPGHOME=/var/www/example.com/.gnupg");
Почему ключи должны храниться где-то на диске?

https://openpgpjs.org/
https://github.com/openpgpjs/openpgpjs

https://github.com/openpgpjs/openpgpjs#getting-started
>Or just fetch a minified build under dist.
Они же предлагают это сделать в случае браузерной версии?
Я пробежался по этому коду (https://github.com/openpgpjs/openpgpjs/blob/master/dist/openpgp.js) и вроде там есть нужные функции. Сложно разобраться в их коде, очень всё запутанно, а в документации вообще некоторые страницы выдают 404.

https://openpgpjs.org/openpgpjs/doc/module-openpgp.html
https://openpgpjs.org/openpgpjs/doc/module-key.html
>encrypt(..., signature)
В отличии от php-библиотеки, js-библиотека использует подпись. Это одно и тоже, в этом случае?

https://openpgpjs.org/openpgpjs/doc/module-signature.html
>armoredText
Что такое armoredText?

http://php.net/manual/ru/function.gnupg-adddecryptkey.php
https://openpgpjs.org/openpgpjs/doc/module-openpgp.html (generateKey)
Обе эти функции используют passphrase, этой фразой шифруется приватный ключ и можно использовать эту опции в нашем случае?

https://openpgpjs.org/openpgpjs/doc/
>openpgp.encrypt(options).then
Зачем здесь может быть нужен Promise?

>> При регистрации пользователя мы генерируем закртый\открытый ключ
>Это значит мы должны доверять серверу, раз сервер генерирует пару ключей, а не клиент.
Для этого придётся усложнить код. Я оставлю это на дальнейшую реализацию (обмен ключами и др. данными через p2p), а пока пусть будет так.

Показать весь текст
Ответы40027

3 авг, 02:16 #748 #1036511

>>1036070

Не scr, а src (от source, сокращенное до 3 букв на манер линуксовых директорий).

Кстати, я думаю, можно писать и source, сейчас ведь нет таких ограничений на длину имени файлов.

6 авг, 16:09 #749 #1039102

В задаче на регулярки, где надо телефоны заменить на единый формат(заменить +7 на 8, убрать все скобки, пробелы и т.д.) я нашел решение только с помощью двух разных регулярок: одна заменяет +7 на 8, вторая ищет пробелы, скобки etc между цифрами и заменяет их на пустые строки. У меня вопрос: а можно ли это сделать с помощью одной регулярки?

Ответы40025

someApprentice 6 авг, 20:35 #750 #1039350

>>1030006
>> К сожалению, у меня не получилось найти в ejs аналог функции nl2br и при этом чтобы экранировались тэги. В таком случае, будет приемлемым оставить этот костыль?
>nl2br не экранирует теги, она только заменяет \n на <br>, если я не путаю.
>
>Насколько я понял, у тебя проблема в том, что ejs экранирует данные и твой <br> выводится как текст? В документации ( https://github.com/mde/ejs/blob/master/docs/syntax.md ) написано что есть 2 вида тегов, один принимают текст, экранируют его и выводят, другой тег принимает HTML код и вставляет его как есть.
>
>В чем именно сложность-то? Можно сделать так <%- convertMessageToHtml(message) %>
Проблема в том что ejs вообще не переводит с помощью \n на новую строку. Нужно заменять его на <br>, но ejs экранирует его тоже.
Можно не экранировать, а фильтровать с помощью какого-нибудь стороннего html-фильтра, но всё равно нужно как-то заменить \n на <br>.

>> Я никак не могу придумать как выводить только новые сообщения. Определенно, нужен setTimeout\setInterval чтобы постоянно обновлять данные с сервера, но как при этом выводить только те сообщения которые ещё не выведены в шаблон?
>Для этого клиент должен "знать", какие сообщения выведены, и запрашивать с сервера только новые, и добавлять только новые. Чтобы это реализовать, нужно спроектировать изменения в нескольких компонентах:
>Для этого клиент должен "знать", какие сообщения выведены
Мне эта идея сразу пришла на ум, перед тем как я столкнулся с проблемой асинхронного получения данных - мы не можем сохранить список сообщений, а только их обещание. Вероятно, мы не можем даже к этому обещанию добавить ещё результаты, потому что, вероятно, если мы напишем

var messages = getMessages(...).then(...);

messages.then(...);

мы выполним тот же самый запрос getMessages(...) и получим тот же самый результат.

Поэтому, очевидным решением мне показалось взять "знание" о выведенных сообщениях прямо из DOM.

Ещё есть вариант сохранять сообщения в sessionStorage, где ключем будет ID сообщения, а значением сам его объект. Затем сравнивать программно результаты запросов и sessionStorage, и выводить\сохранять уникальные значения.

>> Не подвергаю ли я пользователей опасности, открывая кукисы для js?
>Нет наверно.
>> Я сомневаюсь что это будет правильным решением, но с другой стороны не вижу никакой проблемы. Как лучше поступить?
>А зачем тебе нужна кука в JS коде? Ведь при отправке аякс-запроса куки и так отправляются на сервер.
Чтобы вывести токен в шаблон формы для csrf-защиты.

>И конечно, странно, что у тебя token хранится в view.
Конечно, я вынесу его из view.

someApprentice 6 авг, 20:35 #750 #1039350

>>1030006
>> К сожалению, у меня не получилось найти в ejs аналог функции nl2br и при этом чтобы экранировались тэги. В таком случае, будет приемлемым оставить этот костыль?
>nl2br не экранирует теги, она только заменяет \n на <br>, если я не путаю.
>
>Насколько я понял, у тебя проблема в том, что ejs экранирует данные и твой <br> выводится как текст? В документации ( https://github.com/mde/ejs/blob/master/docs/syntax.md ) написано что есть 2 вида тегов, один принимают текст, экранируют его и выводят, другой тег принимает HTML код и вставляет его как есть.
>
>В чем именно сложность-то? Можно сделать так <%- convertMessageToHtml(message) %>
Проблема в том что ejs вообще не переводит с помощью \n на новую строку. Нужно заменять его на <br>, но ejs экранирует его тоже.
Можно не экранировать, а фильтровать с помощью какого-нибудь стороннего html-фильтра, но всё равно нужно как-то заменить \n на <br>.

>> Я никак не могу придумать как выводить только новые сообщения. Определенно, нужен setTimeout\setInterval чтобы постоянно обновлять данные с сервера, но как при этом выводить только те сообщения которые ещё не выведены в шаблон?
>Для этого клиент должен "знать", какие сообщения выведены, и запрашивать с сервера только новые, и добавлять только новые. Чтобы это реализовать, нужно спроектировать изменения в нескольких компонентах:
>Для этого клиент должен "знать", какие сообщения выведены
Мне эта идея сразу пришла на ум, перед тем как я столкнулся с проблемой асинхронного получения данных - мы не можем сохранить список сообщений, а только их обещание. Вероятно, мы не можем даже к этому обещанию добавить ещё результаты, потому что, вероятно, если мы напишем

var messages = getMessages(...).then(...);

messages.then(...);

мы выполним тот же самый запрос getMessages(...) и получим тот же самый результат.

Поэтому, очевидным решением мне показалось взять "знание" о выведенных сообщениях прямо из DOM.

Ещё есть вариант сохранять сообщения в sessionStorage, где ключем будет ID сообщения, а значением сам его объект. Затем сравнивать программно результаты запросов и sessionStorage, и выводить\сохранять уникальные значения.

>> Не подвергаю ли я пользователей опасности, открывая кукисы для js?
>Нет наверно.
>> Я сомневаюсь что это будет правильным решением, но с другой стороны не вижу никакой проблемы. Как лучше поступить?
>А зачем тебе нужна кука в JS коде? Ведь при отправке аякс-запроса куки и так отправляются на сервер.
Чтобы вывести токен в шаблон формы для csrf-защиты.

>И конечно, странно, что у тебя token хранится в view.
Конечно, я вынесу его из view.

Показать весь текст
Ответы40025

7 авг, 13:56 #751 #1039991

>>1035714
Сори что долго не отвечал, то как я бы решал задчу значит в реальном проекте (у меня опыт работы только в небольших проектах)

Для начала в базе заводим табличку с курсом обмена в которой есть как минимум такие столбцы как: курс, дата выставления.

Далее пишу 3 функции, будь это просто в functions.php или методы модельного класса который будет отвечать за работу с баблом.

1. Добавляет в эту табличку новую запись курса обмена
2. Взять из таблички последнюю запись курса обмена.
3. Спросить с удаленного сервера текущий курс.

Далее значит такой код:
Спрашиваем с удаленного сервера курс
Спрашиваем последнюю запись с таблицы курсов.
Если курсы различаются, то добавляем новый курс в таблицу.

Это всё будет повешано на крон, и будет вызываться сколько-то там раз в сутки, в зависимости от того как часто на удаленном ресурсе меняется курс.

Ну а дальше всё просто.
Функция конвертации рубли в доллары в 2 строчки:
На вход курс и рубли, на выходе доллары.

В приложении когда юзер будет что-то хотеть сконвертить, то в контроллере который принимает юзерский инпут с рублями, будет примерно так всё:
Если есть инпут то валидируем инпут, если ок то:
Спрашиваем последнюю запись с таблицы курсов.
Кормим инпут и курс функции конвертации
Отдать ответ в массив инфы который полетит во вьюху.
иначе отдать сообщение что инпут неверен.

7 авг, 13:56 #751 #1039991

>>1035714
Сори что долго не отвечал, то как я бы решал задчу значит в реальном проекте (у меня опыт работы только в небольших проектах)

Для начала в базе заводим табличку с курсом обмена в которой есть как минимум такие столбцы как: курс, дата выставления.

Далее пишу 3 функции, будь это просто в functions.php или методы модельного класса который будет отвечать за работу с баблом.

1. Добавляет в эту табличку новую запись курса обмена
2. Взять из таблички последнюю запись курса обмена.
3. Спросить с удаленного сервера текущий курс.

Далее значит такой код:
Спрашиваем с удаленного сервера курс
Спрашиваем последнюю запись с таблицы курсов.
Если курсы различаются, то добавляем новый курс в таблицу.

Это всё будет повешано на крон, и будет вызываться сколько-то там раз в сутки, в зависимости от того как часто на удаленном ресурсе меняется курс.

Ну а дальше всё просто.
Функция конвертации рубли в доллары в 2 строчки:
На вход курс и рубли, на выходе доллары.

В приложении когда юзер будет что-то хотеть сконвертить, то в контроллере который принимает юзерский инпут с рублями, будет примерно так всё:
Если есть инпут то валидируем инпут, если ок то:
Спрашиваем последнюю запись с таблицы курсов.
Кормим инпут и курс функции конвертации
Отдать ответ в массив инфы который полетит во вьюху.
иначе отдать сообщение что инпут неверен.

Показать весь текст
Ответы40028

7 авг, 13:59 #752 #1039992

Компетентный ОП в этом треде, или писать в новый, где чат?

Сделал первую часть TestHub.
https://github.com/pricklynut/testhub

Накопилось некоторое кол-во вопросов.

Симфони странно себя ведет после установки, я имею ввиду точки входа.
Если сначала запросить корень сайта / напрямую, выдает 500.
Однако если зайти на /app.php, редиректит на /, и с этого момента
/ доступен напрямую. Однако если почистить кеш, та же фигня. Что он там
кеширует, это так и должно быть?
Странно, больше не повторяется.
update: развернул на другом компе, теперь наоборот редиректит с / на /app.php.
htaccess стандартный, который идет в комплекте с фреймворком.

через раз (буквально) вылетает ошибка
php bin/console cache:clear --no-warmup -e prod
PHP Notice: Undefined index: host in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 6
PHP Notice: Undefined index: port in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 7
PHP Notice: Undefined index: user in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 9
PHP Notice: Undefined index: pass in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 10
PHP Fatal error: Uncaught PDOException: SQLSTATE[08006] [7] ВАЖНО: база данных "connect_timeout=30" не существует in /home/inside/www/testhub.com/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:43
Я понял, что он не может подключиться к бд, но почему через раз, что за магия? Там настройки подключения к бд берутся из переменной среды, но почему один раз эта переменная доступна, другой нет? Переменная среды объявлена в конфиге виртуального хоста.

Как в симфони делать виджеты? В yii виджет это просто класс, который подставляет
переменные из своего конфига в шаблон и возвращает эту строку.
Например echo SidebarWidget::widget(['class' => 'abc', 'title' => 'asdfad']);
В симфони не понимаю, как из модели вызвать render какого-нибудь шаблона.
Допустим, я хотел сделать виджет для пагинации. Класс написал, шаблон пришлось положить
к общим шаблонам, хотя как бы он относится именно к виджету, а не к проекту.

Странно, что в бутстрапе в пагинации текущая страница и неактивная ссылка на предыдущую
содержат кликабельную ссылку. По-моему эти ссылки вообще нужно удалить, но если
это сделать, ломается верстка.

По структуре проекта на симфони: куды вообще что писать?
Представления-вьюшки кидать в app/Resources, или в аналогичную папку AppBundle?
Стили, js, тоже в AppBundle/Resources?
Еще в контроллерах у меня скопилось много логики, не знаю куда ее вынести. В модели (entity)
не получится, там нет доступа в бд.
В репозитории тоже как-то неуместно, по сути репозитории должны только извлекать из бд сущности,
желательно одноименные с названием репозитория или связанные.

Короче нужны советы по рефакторингу этого дела.

Пока почитаю, как сделать добавление новых тестов.
Нужно именно одной формой, сам тест, все его вопросы, все варианты ответов на каждый вопрос?
Какая-то жесть получается, а если в тесте сто вопросов по 8 вариантов на каждый? И если на 69 вопросе
пользователь случайно закроет браузер, начинать все сначала? Может, сохранять куда-то (куда?)
промежуточные данные в процессе редактирования?
Пока не представляю как это делать.

7 авг, 13:59 #752 #1039992

Компетентный ОП в этом треде, или писать в новый, где чат?

Сделал первую часть TestHub.
https://github.com/pricklynut/testhub

Накопилось некоторое кол-во вопросов.

Симфони странно себя ведет после установки, я имею ввиду точки входа.
Если сначала запросить корень сайта / напрямую, выдает 500.
Однако если зайти на /app.php, редиректит на /, и с этого момента
/ доступен напрямую. Однако если почистить кеш, та же фигня. Что он там
кеширует, это так и должно быть?
Странно, больше не повторяется.
update: развернул на другом компе, теперь наоборот редиректит с / на /app.php.
htaccess стандартный, который идет в комплекте с фреймворком.

через раз (буквально) вылетает ошибка
php bin/console cache:clear --no-warmup -e prod
PHP Notice: Undefined index: host in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 6
PHP Notice: Undefined index: port in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 7
PHP Notice: Undefined index: user in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 9
PHP Notice: Undefined index: pass in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 10
PHP Fatal error: Uncaught PDOException: SQLSTATE[08006] [7] ВАЖНО: база данных "connect_timeout=30" не существует in /home/inside/www/testhub.com/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:43
Я понял, что он не может подключиться к бд, но почему через раз, что за магия? Там настройки подключения к бд берутся из переменной среды, но почему один раз эта переменная доступна, другой нет? Переменная среды объявлена в конфиге виртуального хоста.

Как в симфони делать виджеты? В yii виджет это просто класс, который подставляет
переменные из своего конфига в шаблон и возвращает эту строку.
Например echo SidebarWidget::widget(['class' => 'abc', 'title' => 'asdfad']);
В симфони не понимаю, как из модели вызвать render какого-нибудь шаблона.
Допустим, я хотел сделать виджет для пагинации. Класс написал, шаблон пришлось положить
к общим шаблонам, хотя как бы он относится именно к виджету, а не к проекту.

Странно, что в бутстрапе в пагинации текущая страница и неактивная ссылка на предыдущую
содержат кликабельную ссылку. По-моему эти ссылки вообще нужно удалить, но если
это сделать, ломается верстка.

По структуре проекта на симфони: куды вообще что писать?
Представления-вьюшки кидать в app/Resources, или в аналогичную папку AppBundle?
Стили, js, тоже в AppBundle/Resources?
Еще в контроллерах у меня скопилось много логики, не знаю куда ее вынести. В модели (entity)
не получится, там нет доступа в бд.
В репозитории тоже как-то неуместно, по сути репозитории должны только извлекать из бд сущности,
желательно одноименные с названием репозитория или связанные.

Короче нужны советы по рефакторингу этого дела.

Пока почитаю, как сделать добавление новых тестов.
Нужно именно одной формой, сам тест, все его вопросы, все варианты ответов на каждый вопрос?
Какая-то жесть получается, а если в тесте сто вопросов по 8 вариантов на каждый? И если на 69 вопросе
пользователь случайно закроет браузер, начинать все сначала? Может, сохранять куда-то (куда?)
промежуточные данные в процессе редактирования?
Пока не представляю как это делать.

Показать весь текст
Ответы40029

7 авг, 15:26 #753 #1040025

>>1039350

> Проблема в том что ejs вообще не переводит с помощью \n на новую строку.
А почему он должен? Он просто выводит этот \n в итоговый HTML, а дальше уже браузер его игнорирует.

Нужно использовать функцию, заменяющую \n на <br> и экранирующую спецсиволы, и выводить результат через неэкранирующий тег (<%- ... ). Либо, как альтернативу, можно использовать свойство CSS white-space, чтобы переводы строк выводились как в исходном коде: https://developer.mozilla.org/ru/docs/Web/CSS/white-space

> Нужно заменять его на <br>, но ejs экранирует его тоже.
Нужно использовать неэкранирующий тег для вывода (разумеется, тогда спецсимволы нужно экранировать самостоятельно).

> Вероятно, мы не можем даже к этому обещанию добавить ещё результаты, потому что, вероятно, если мы напишем
> var messages = getMessages(...).then(...);
> messages.then(...);
> мы выполним тот же самый запрос getMessages(...) и получим тот же самый результат.
Нет, второй раз запрос не выполнится. Просто последний then() получит на вход значение, которое вернул через return предпоследний then.

> Ещё есть вариант сохранять сообщения в sessionStorage, где ключем будет ID сообщения, а значением сам его объект. Затем сравнивать программно результаты запросов и sessionStorage, и выводить\сохранять уникальные значения.
Вообще, мне кажется, ты немного все переусложняешь. Достаточно с сервера вместе с сообщениями присылать время получения данных, и при следующем запросе просить сервер прислать только сообщения, добавленные/обновленные после этого времени.

>>А зачем тебе нужна кука в JS коде?
> Чтобы вывести токен в шаблон формы для csrf-защиты.
Можно брать данные из куки, или можно просто с сервера присылать токен при авторизации и дальше его использовать.

>>1039102

Я думаю, что нет.

7 авг, 15:26 #753 #1040025

>>1039350

> Проблема в том что ejs вообще не переводит с помощью \n на новую строку.
А почему он должен? Он просто выводит этот \n в итоговый HTML, а дальше уже браузер его игнорирует.

Нужно использовать функцию, заменяющую \n на <br> и экранирующую спецсиволы, и выводить результат через неэкранирующий тег (<%- ... ). Либо, как альтернативу, можно использовать свойство CSS white-space, чтобы переводы строк выводились как в исходном коде: https://developer.mozilla.org/ru/docs/Web/CSS/white-space

> Нужно заменять его на <br>, но ejs экранирует его тоже.
Нужно использовать неэкранирующий тег для вывода (разумеется, тогда спецсимволы нужно экранировать самостоятельно).

> Вероятно, мы не можем даже к этому обещанию добавить ещё результаты, потому что, вероятно, если мы напишем
> var messages = getMessages(...).then(...);
> messages.then(...);
> мы выполним тот же самый запрос getMessages(...) и получим тот же самый результат.
Нет, второй раз запрос не выполнится. Просто последний then() получит на вход значение, которое вернул через return предпоследний then.

> Ещё есть вариант сохранять сообщения в sessionStorage, где ключем будет ID сообщения, а значением сам его объект. Затем сравнивать программно результаты запросов и sessionStorage, и выводить\сохранять уникальные значения.
Вообще, мне кажется, ты немного все переусложняешь. Достаточно с сервера вместе с сообщениями присылать время получения данных, и при следующем запросе просить сервер прислать только сообщения, добавленные/обновленные после этого времени.

>>А зачем тебе нужна кука в JS коде?
> Чтобы вывести токен в шаблон формы для csrf-защиты.
Можно брать данные из куки, или можно просто с сервера присылать токен при авторизации и дальше его использовать.

>>1039102

Я думаю, что нет.

Показать весь текст
Ответы40147

7 авг, 15:28 #754 #1040027

>>1036395

> Только почему-то я не вижу методов генерации ключей. Нужно найти другую в таком случае?

Для начала, надо разобраться, что это за расширение и как оно вообще работает. Идем сюда: http://php.net/manual/ru/gnupg.installation.php , отсюда сюда: http://pecl.php.net/package/gnupg и тут видим "wrapper around the gpgme library". Находим мануал к этой библиотеке: https://www.gnupg.org/documentation/manuals/gpgme/

К сожалению, в мануале разобраться сложно, потому пойдем другим путем. Упомянутая там библиотека GPGME - это библиотека, которая позволяет выполнять те же функции, что и команда gpg, только вызывая их программно. Потому почитаем мануал по gpg ( https://www.gnupg.org/gph/en/manual.html ). Там это явно не написано (видимо все и так должны это знать), но можно догадаться, что у этой программы есть хранилище ключей (keyring) - по сути просто файл в домашнем каталоге пользователя. И ты можешь генерировать новые ключи, а также импортировать ключи других людей в этот самый keyring. И при подписывании/шифровании/проверке подписи/расшифровке испоьзуются именно ключи из keyring.

То есть если ты хочешь с кем-то вести зашифрованную переписку, ты добавляешь его (публичный) ключ в свой keyring сначала. Для удобства обмена ключами там есть специальные серверы ключей и программа умеет сама получать публичный ключ контакта с такого сервера (например по email или по отпечатку ключа).

Теперь принцип работы функций из gnupg становится понятен. Если мы откроем пример кода из мануала: http://php.net/manual/ru/gnupg.examples-clearsign.php

> // добавить ключ для подписания с паролем 'test'
> $gnupg->addsignkey("8660281B6051D071D94B5B230549F9DC851566DC", "test");
Эта команда загружает ключ с указанным отпечатком (отпечаток - это по сути хеш от содержимого ключа, который можно считать его уникальным идентификатором, так как у разных ключей они будут разные) из keyring в память (куда-то внутрь объекта $gnupg) и позволяет использовать его в следующей строке:

> $signed = $gnupg->sign("просто тест");

Соответственно, вот что получается:

> Только почему-то я не вижу методов генерации ключей.
Это можно сделать утилитой командной строки gpg. Вообще, в самой сишной библиотеке есть функция генерации ключа, но в расширении она не доступна.

> Почему несколько методов для добавления ключей?
Наверно потому что это ключи для разных целей.

> Вообще, функции add..cryptkey выглядят довольно странно, в аргументы принимают отпечаток, а не сам ключи
Они ищут ключ внутри keyring по отпечатку.

> Почему ключи должны храниться где-то на диске?
Потому что так задумано, это программа для одного пользователя, с помощью которой он подписывает и шифрует файлы и переписку.

>>Or just fetch a minified build under dist.
> Они же предлагают это сделать в случае браузерной версии?
Думаю, что там код универсальный, который работает и в ноде и в браузере.

> В отличии от php-библиотеки, js-библиотека использует подпись. Это одно и тоже, в этом случае?
Нет. PHP библиотека использовала отпечаток (fingerprint), чтобы идентифицировать ключ в keyring, а здесь другое:

> signature Signature (optional) a detached signature to add to the encrypted message
Это подпись в отдельном файле (сгенерированная ранее из документа, который мы хотим зашифровать), которую можно прикрепить к зашифрованному документу.

> Что такое armoredText?
Нужно почитать мануал к gpg:

> Create ASCII-armored output that can be safely e-mailed, instead of binary output:
> -a, --armor

Это значит, что данные представлены в виде печатаемых символов (текста), и их можно например скопировать и переслать в письме или опублировать (то есть вроде кодировки base64). Другой вариант - это использовать бинарное кодирование, когда данные представлены просто в виде набора байт, которые могут не соответствовать тексту (так как в utf-8 например не все последовательности байт соответствуют символам, и при попытке скопировать кракозябры что-то может потеряться). Бинарный формат компактнее.

> Обе эти функции используют passphrase, этой фразой шифруется приватный ключ и можно использовать эту опции в нашем случае?
Не знаю, возможно, что да. Эта библиотека позволяет шифроватьт данные в браузере, что конечно хорошо, так как не требует передавать сами сообщения на сервер. Но не знаю, как там будет с производительностью.

> Зачем здесь может быть нужен Promise?
Там шифрование делается в Web Worker. Вебворкер - это скрипт, выполняющийся в отдельном изолированном окружении, не имеющий доступа к DOM, который может общаться с основным скриптом на странице с помощью сообщений. Вебворкеры позволяют задействовать несколько ядер процессора, так как их код может выполняться параллельно с основным скриптом и не блокирует интерфейс браузера (в отличие от обычного яваскрипт кода, который выполняется в контексте страницы). Так как шифрование может быть тяжелым в вычислительном плане, в библиотеке используются вебворкеры, чтобы выполнять его параллельно с другими действиями.

Так как код шифрования выполняется где-то в другом потоке, он выполняется асинхронно, мы посылаем сообщение в тот поток, и через какое-то время в ответном сообщении приходит результат. Потому и промисы.

Почитай про веб воркеры: https://developer.mozilla.org/ru/docs/DOM/Using_web_workers

То есть, тебе стоило бы для начала хотя бы немного изучить теорию про gpg (может даже попробовать что-нибудь ей зашифровать), и почитать про веб-воркеры.

Вообще, opengpg мне кажется хорошей идеей, можно испоьзовать отлаженные алгоритмы вместо изобретения своих. Просто прикрутить к этому удобный, человеческий интерфейс. И вроде у них испоьзуется Asm.JS, который в фаерфоексе позволяет получить производительсноть близкую к производительности нативного кода (увы, вебкит его не поддерживает).

Плюс, я тут подумал, может это позволит как-то интегрироваться с GPG, то есть, например, обмениваться сообщениями с теми, кто использует обычную почту с шифрованием через gpg.

7 авг, 15:28 #754 #1040027

>>1036395

> Только почему-то я не вижу методов генерации ключей. Нужно найти другую в таком случае?

Для начала, надо разобраться, что это за расширение и как оно вообще работает. Идем сюда: http://php.net/manual/ru/gnupg.installation.php , отсюда сюда: http://pecl.php.net/package/gnupg и тут видим "wrapper around the gpgme library". Находим мануал к этой библиотеке: https://www.gnupg.org/documentation/manuals/gpgme/

К сожалению, в мануале разобраться сложно, потому пойдем другим путем. Упомянутая там библиотека GPGME - это библиотека, которая позволяет выполнять те же функции, что и команда gpg, только вызывая их программно. Потому почитаем мануал по gpg ( https://www.gnupg.org/gph/en/manual.html ). Там это явно не написано (видимо все и так должны это знать), но можно догадаться, что у этой программы есть хранилище ключей (keyring) - по сути просто файл в домашнем каталоге пользователя. И ты можешь генерировать новые ключи, а также импортировать ключи других людей в этот самый keyring. И при подписывании/шифровании/проверке подписи/расшифровке испоьзуются именно ключи из keyring.

То есть если ты хочешь с кем-то вести зашифрованную переписку, ты добавляешь его (публичный) ключ в свой keyring сначала. Для удобства обмена ключами там есть специальные серверы ключей и программа умеет сама получать публичный ключ контакта с такого сервера (например по email или по отпечатку ключа).

Теперь принцип работы функций из gnupg становится понятен. Если мы откроем пример кода из мануала: http://php.net/manual/ru/gnupg.examples-clearsign.php

> // добавить ключ для подписания с паролем 'test'
> $gnupg->addsignkey("8660281B6051D071D94B5B230549F9DC851566DC", "test");
Эта команда загружает ключ с указанным отпечатком (отпечаток - это по сути хеш от содержимого ключа, который можно считать его уникальным идентификатором, так как у разных ключей они будут разные) из keyring в память (куда-то внутрь объекта $gnupg) и позволяет использовать его в следующей строке:

> $signed = $gnupg->sign("просто тест");

Соответственно, вот что получается:

> Только почему-то я не вижу методов генерации ключей.
Это можно сделать утилитой командной строки gpg. Вообще, в самой сишной библиотеке есть функция генерации ключа, но в расширении она не доступна.

> Почему несколько методов для добавления ключей?
Наверно потому что это ключи для разных целей.

> Вообще, функции add..cryptkey выглядят довольно странно, в аргументы принимают отпечаток, а не сам ключи
Они ищут ключ внутри keyring по отпечатку.

> Почему ключи должны храниться где-то на диске?
Потому что так задумано, это программа для одного пользователя, с помощью которой он подписывает и шифрует файлы и переписку.

>>Or just fetch a minified build under dist.
> Они же предлагают это сделать в случае браузерной версии?
Думаю, что там код универсальный, который работает и в ноде и в браузере.

> В отличии от php-библиотеки, js-библиотека использует подпись. Это одно и тоже, в этом случае?
Нет. PHP библиотека использовала отпечаток (fingerprint), чтобы идентифицировать ключ в keyring, а здесь другое:

> signature Signature (optional) a detached signature to add to the encrypted message
Это подпись в отдельном файле (сгенерированная ранее из документа, который мы хотим зашифровать), которую можно прикрепить к зашифрованному документу.

> Что такое armoredText?
Нужно почитать мануал к gpg:

> Create ASCII-armored output that can be safely e-mailed, instead of binary output:
> -a, --armor

Это значит, что данные представлены в виде печатаемых символов (текста), и их можно например скопировать и переслать в письме или опублировать (то есть вроде кодировки base64). Другой вариант - это использовать бинарное кодирование, когда данные представлены просто в виде набора байт, которые могут не соответствовать тексту (так как в utf-8 например не все последовательности байт соответствуют символам, и при попытке скопировать кракозябры что-то может потеряться). Бинарный формат компактнее.

> Обе эти функции используют passphrase, этой фразой шифруется приватный ключ и можно использовать эту опции в нашем случае?
Не знаю, возможно, что да. Эта библиотека позволяет шифроватьт данные в браузере, что конечно хорошо, так как не требует передавать сами сообщения на сервер. Но не знаю, как там будет с производительностью.

> Зачем здесь может быть нужен Promise?
Там шифрование делается в Web Worker. Вебворкер - это скрипт, выполняющийся в отдельном изолированном окружении, не имеющий доступа к DOM, который может общаться с основным скриптом на странице с помощью сообщений. Вебворкеры позволяют задействовать несколько ядер процессора, так как их код может выполняться параллельно с основным скриптом и не блокирует интерфейс браузера (в отличие от обычного яваскрипт кода, который выполняется в контексте страницы). Так как шифрование может быть тяжелым в вычислительном плане, в библиотеке используются вебворкеры, чтобы выполнять его параллельно с другими действиями.

Так как код шифрования выполняется где-то в другом потоке, он выполняется асинхронно, мы посылаем сообщение в тот поток, и через какое-то время в ответном сообщении приходит результат. Потому и промисы.

Почитай про веб воркеры: https://developer.mozilla.org/ru/docs/DOM/Using_web_workers

То есть, тебе стоило бы для начала хотя бы немного изучить теорию про gpg (может даже попробовать что-нибудь ей зашифровать), и почитать про веб-воркеры.

Вообще, opengpg мне кажется хорошей идеей, можно испоьзовать отлаженные алгоритмы вместо изобретения своих. Просто прикрутить к этому удобный, человеческий интерфейс. И вроде у них испоьзуется Asm.JS, который в фаерфоексе позволяет получить производительсноть близкую к производительности нативного кода (увы, вебкит его не поддерживает).

Плюс, я тут подумал, может это позволит как-то интегрироваться с GPG, то есть, например, обмениваться сообщениями с теми, кто использует обычную почту с шифрованием через gpg.

Показать весь текст

7 авг, 15:29 #755 #1040028

>>1036018

Меньше писать приходится, синтакси более лаконичный. А вообще, это подробно разобрано на сайте самого твига: https://twig.symfony.com/

>>1039991

Ну, табличку и функции работы с ней можно вместе назвать "кеш курсов валют". Там при желании можно и другое хранилище использовать, это не принципиально. Но у меня там были еще дополнительные пожелания к коду:

> Также, мы хотим протестировать эти функции по отдельности, а именно:
> - проверить, что конвертация работает, с указанным явно в тесте курсом, не делая запросов
> - проверить, что функция запроса курса с сервера работает, то есть возвращает адекватное число, при этом не сохранять результат никуда
> - проверить, что кеширование работает, что курс в течение дня запрашивается только один раз

То есть я хотел чтобы ты разбил код на 3 отдельных независимых модуля - модуль конвертации, модуль кеширования курса (который хранит курс в табличке) и модуль для получения курса с сервера. Чтобы эти модули можно было бы тестировать по отдельности. Очевидно, что в предложенном тобой коде такого разбиения нет, все эти функции взаимосвязаны и их нельзя использовать по отдельности.

Один из вариантов реализовать код как несколько независимых модулей - использовать ООП и упоминавшийся где-то выше Dependeny Injection. В моем уроке по DI ( https://github.com/codedokode/pasta/blob/master/arch/di.md ) есть похожий пример кода, с разбиением на отдельные классы.

Вообще, это можно сделать и без ООП, на функциях, но выглядеть это все равно будет именно как имитация объектов на функциях и массивах. Хотя, может, есть и какие-то другие подходы, не знаю.

Если ты хочешь понять, как именно, то для начала нужно хорошо разобраться в ООП, потом изучить DI, ну а потом наверно у тебя появятся идеи, что можно сделать. Чтобы разобраться в ООП, я тебе могу посоветовать взять мой учебник из ОП поста, и там прочитать главу про ООП и решить задачи в ней (если только ты их уже не решил).

Ответы40638

7 авг, 15:30 #756 #1040029

>>1039992

Пока в этом, но я думаю, что надо переходить в новый тред, а тут останутся только ответы на старые посты.

> Однако если зайти на /app.php, редиректит на /, и с этого момента / доступен напрямую. Однако если почистить кеш, та же фигня. Что он там кеширует, это так и должно быть?

Нет, не должно быть, это баг либо у тебя, либо в коде Симфони, хорошо бы добиться его устойчивого повторения и разобраться в причине.

Ну вообще да, Симфони много чего кеширует, в том числе в файлах. Например, кешируется содержание конфигов, метаданные сущностей Доктрины, шаблоны twig. В dev-режиме Симфони отслеживает даты модификации исходного кода и обновляет кеши при их изменении, а в продакшен-режиме не отслеживает, и рассчитывает, что ты запустишь специальную команду (по моему cache:warmup или как-то так), чтобы принудительно обновить кеш. Соответственно, скорее всего ты использовал у себя продакшен-режим, и работал с кешем, основанным на старых версиях файлов.

Ну и конечно нужно разобраться, по документации или исходникам, что именно кешируется, как и когда обновляется. Без этого Симфони пользоваться вообще нельзя. Ты должен по памяти знать все кеши.

> PHP Notice: Undefined index: host in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 6

Я догадываюсь в чем причина, но полезнее будет, если ты сам разберешься.

> Там настройки подключения к бд берутся из переменной среды, но почему один раз эта переменная доступна, другой нет? Переменная среды объявлена в конфиге виртуального хоста.
То есть эта переменная доступна только внутри Апача и процессов, которые из него запускаются. А когда ты в командной строке запускаешь код, откуда она там возьмется? Очевидно, ее там нет.

> Как в симфони делать виджеты?
Нет готового решения? Нельзя виджет представить в виде объекта с данными, и отдельного шаблона twig, в который мы передаем этот объект?

> В симфони не понимаю, как из модели вызвать render какого-нибудь шаблона.
В MVC за отображение данных отвечает Вид, а модель ничего не рендерит.

> Допустим, я хотел сделать виджет для пагинации. Класс написал, шаблон пришлось положить к общим шаблонам, хотя как бы он относится именно к виджету, а не к проекту.
Можно сделать для таких шаблонов отдельную папку, например, views/widgets/. И сделать объект, содержащий информацию о пагинации (число страниц, текущая страница и тд). Я вижу, у тебя есть класс, представляющий пагинацию.

Также, в Симфони есть бандлы, можно сделать бандл и в него класть виджеты, но не вижу выгоды.

> Странно, что в бутстрапе в пагинации текущая страница и неактивная ссылка на предыдущую содержат кликабельную ссылку
Можно вместо <a> использовать <span> для текущей страницы и ссылки не будет.

> По-моему эти ссылки вообще нужно удалить, но если это сделать, ломается верстка.
Нужно спан поставить, смотри мануал по бутстрапу.

> Представления-вьюшки кидать в app/Resources, или в аналогичную папку AppBundle?
Насчет бандлов, там не все так просто. Вообще бандлы - это что-то вроде библиотек, или даже мини-приложений, так как бандл может содержать свои шаблоны, сущности доктрины, контроллеры, сервисы, параметры конфига. Ну например, можно форум или блог оформить как бандл так, что его можно добавить на любой сайт на Симфони и все будет работать из коробки. Это описано тут: https://symfony.com/doc/current/bundles/best_practices.html

Если тебе такая возможность не требуется, то по идее ты оформляешь свое приложение как один AppBundle. Но в новых версиях Симфони все идет к тому, чтобы вообще отказаться от AppBundle и испоьзовать просто папку app или src, вот почитай:

- https://knpuniversity.com/screencast/symfony3-upgrade/new-dir-structure
- http://fabien.potencier.org/symfony4-directory-structure.html

То есть бандлы останутся только для библиотек. Приложение будет писаться без бандлов.

По поводу твоего вопроса, ответ на него тут: http://symfony.com/doc/current/quick_tour/the_architecture.html

> app/
> The application configuration, templates and translations.
Шаблоны в Симфони 3 должны быть тут.

> Стили, js, тоже в AppBundle/Resources?
Можно в web, если ты не используешь управление статикой (assetic например).

> Еще в контроллерах у меня скопилось много логики, не знаю куда ее вынести.
В сервисы (они же хелперы). Прочитай внимательно мой урок по MVC: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Ну вот например createAndPersistUser(), createAndPersistAttempt - явно не в контроллере должны быть. Только желательно придумать аккуратную архитектуру, чтобы функции не были в беспорядке раскиданы по классам, а как-то логично организованы.

Условно говоря, должна быть возможность сделать любые действия, которые делаются через веб-интерфейс, программно. Например: создать тест, удалить, ответить на него, и тд. То есть сервисы - это что-то вроде внутреннего API, через которое можно делать нужные действия. Задача контроллера лишь интерпретировать запрос пользователя и вызвать требуемое действие.

Потому я бы советовал сесть и спроектировать это внутреннее АПИ, решить, какие будут сервисы, за что каждый будет отвечать, какие в них будут действия.

> В модели (entity) не получится, там нет доступа в бд.
модель это не только entity и не только код работы с БД, почитай мой урок про MVC

> Нужно именно одной формой, сам тест, все его вопросы, все варианты ответов на каждый вопрос?
Лучше сделать так, как будет удобнее пользователю. То есть на одной странице с яваскриптом. У меня там есть пример страницы с тестом вроде бы.

> Какая-то жесть получается, а если в тесте сто вопросов по 8 вариантов на каждый?
Согласен, тут надо подумать. Можно например как-то сворачивать вопросы. Это ведь наверно удобнее, чем перезагружать страницу несколько раз, пока не найдешь вопрос.

> Может, сохранять куда-то (куда?) промежуточные данные в процессе редактирования?
Можно в localStorage, можно на сервер в фоновом режиме.

-----

По коду: если у тебя требуется PHP7, то напиши это в composer.json, сейчас там указан php5.

По поводу Симфони: там есть одна вещь, которая мне не нравится. Они в продакшене (в отличие от dev) не превращают ошибки в исключения и не используют strict_variables в твиге. Я думаю, это плохая идея и надо переделать это. Это идет вразрез в принципом fail fast и способствует более низкому качеству кода.

По роутеру: не советую использовать аннотации, когда роуты собраны в одном месте, намного удобнее.

В модели данных не увидел наследования, ты не думал, что для разных типов вопросов/ответов можно было бы использовать разные классы?

Если в таблицах у колонок есть значения по умолчанию, они должны быть продублированы в сущностях.

В Postgres можно использовать CHECK на колонках для ограничения вставляемых значений.

Поиск данных через связи не всегда эффективен.

Пока код выгодит нормально, надо только контроллер разгрузить.

Также, если есть время и возможность, советую подумать про добавление автоматизированных тестов, в ОП посте есть урок. Раз за Симфони взялся, надо бы и тестирование подучить.

7 авг, 15:30 #756 #1040029

>>1039992

Пока в этом, но я думаю, что надо переходить в новый тред, а тут останутся только ответы на старые посты.

> Однако если зайти на /app.php, редиректит на /, и с этого момента / доступен напрямую. Однако если почистить кеш, та же фигня. Что он там кеширует, это так и должно быть?

Нет, не должно быть, это баг либо у тебя, либо в коде Симфони, хорошо бы добиться его устойчивого повторения и разобраться в причине.

Ну вообще да, Симфони много чего кеширует, в том числе в файлах. Например, кешируется содержание конфигов, метаданные сущностей Доктрины, шаблоны twig. В dev-режиме Симфони отслеживает даты модификации исходного кода и обновляет кеши при их изменении, а в продакшен-режиме не отслеживает, и рассчитывает, что ты запустишь специальную команду (по моему cache:warmup или как-то так), чтобы принудительно обновить кеш. Соответственно, скорее всего ты использовал у себя продакшен-режим, и работал с кешем, основанным на старых версиях файлов.

Ну и конечно нужно разобраться, по документации или исходникам, что именно кешируется, как и когда обновляется. Без этого Симфони пользоваться вообще нельзя. Ты должен по памяти знать все кеши.

> PHP Notice: Undefined index: host in /home/pricklynut/www/testhub.com/app/config/parameters_prod.php on line 6

Я догадываюсь в чем причина, но полезнее будет, если ты сам разберешься.

> Там настройки подключения к бд берутся из переменной среды, но почему один раз эта переменная доступна, другой нет? Переменная среды объявлена в конфиге виртуального хоста.
То есть эта переменная доступна только внутри Апача и процессов, которые из него запускаются. А когда ты в командной строке запускаешь код, откуда она там возьмется? Очевидно, ее там нет.

> Как в симфони делать виджеты?
Нет готового решения? Нельзя виджет представить в виде объекта с данными, и отдельного шаблона twig, в который мы передаем этот объект?

> В симфони не понимаю, как из модели вызвать render какого-нибудь шаблона.
В MVC за отображение данных отвечает Вид, а модель ничего не рендерит.

> Допустим, я хотел сделать виджет для пагинации. Класс написал, шаблон пришлось положить к общим шаблонам, хотя как бы он относится именно к виджету, а не к проекту.
Можно сделать для таких шаблонов отдельную папку, например, views/widgets/. И сделать объект, содержащий информацию о пагинации (число страниц, текущая страница и тд). Я вижу, у тебя есть класс, представляющий пагинацию.

Также, в Симфони есть бандлы, можно сделать бандл и в него класть виджеты, но не вижу выгоды.

> Странно, что в бутстрапе в пагинации текущая страница и неактивная ссылка на предыдущую содержат кликабельную ссылку
Можно вместо <a> использовать <span> для текущей страницы и ссылки не будет.

> По-моему эти ссылки вообще нужно удалить, но если это сделать, ломается верстка.
Нужно спан поставить, смотри мануал по бутстрапу.

> Представления-вьюшки кидать в app/Resources, или в аналогичную папку AppBundle?
Насчет бандлов, там не все так просто. Вообще бандлы - это что-то вроде библиотек, или даже мини-приложений, так как бандл может содержать свои шаблоны, сущности доктрины, контроллеры, сервисы, параметры конфига. Ну например, можно форум или блог оформить как бандл так, что его можно добавить на любой сайт на Симфони и все будет работать из коробки. Это описано тут: https://symfony.com/doc/current/bundles/best_practices.html

Если тебе такая возможность не требуется, то по идее ты оформляешь свое приложение как один AppBundle. Но в новых версиях Симфони все идет к тому, чтобы вообще отказаться от AppBundle и испоьзовать просто папку app или src, вот почитай:

- https://knpuniversity.com/screencast/symfony3-upgrade/new-dir-structure
- http://fabien.potencier.org/symfony4-directory-structure.html

То есть бандлы останутся только для библиотек. Приложение будет писаться без бандлов.

По поводу твоего вопроса, ответ на него тут: http://symfony.com/doc/current/quick_tour/the_architecture.html

> app/
> The application configuration, templates and translations.
Шаблоны в Симфони 3 должны быть тут.

> Стили, js, тоже в AppBundle/Resources?
Можно в web, если ты не используешь управление статикой (assetic например).

> Еще в контроллерах у меня скопилось много логики, не знаю куда ее вынести.
В сервисы (они же хелперы). Прочитай внимательно мой урок по MVC: https://github.com/codedokode/pasta/blob/master/arch/mvc.md

Ну вот например createAndPersistUser(), createAndPersistAttempt - явно не в контроллере должны быть. Только желательно придумать аккуратную архитектуру, чтобы функции не были в беспорядке раскиданы по классам, а как-то логично организованы.

Условно говоря, должна быть возможность сделать любые действия, которые делаются через веб-интерфейс, программно. Например: создать тест, удалить, ответить на него, и тд. То есть сервисы - это что-то вроде внутреннего API, через которое можно делать нужные действия. Задача контроллера лишь интерпретировать запрос пользователя и вызвать требуемое действие.

Потому я бы советовал сесть и спроектировать это внутреннее АПИ, решить, какие будут сервисы, за что каждый будет отвечать, какие в них будут действия.

> В модели (entity) не получится, там нет доступа в бд.
модель это не только entity и не только код работы с БД, почитай мой урок про MVC

> Нужно именно одной формой, сам тест, все его вопросы, все варианты ответов на каждый вопрос?
Лучше сделать так, как будет удобнее пользователю. То есть на одной странице с яваскриптом. У меня там есть пример страницы с тестом вроде бы.

> Какая-то жесть получается, а если в тесте сто вопросов по 8 вариантов на каждый?
Согласен, тут надо подумать. Можно например как-то сворачивать вопросы. Это ведь наверно удобнее, чем перезагружать страницу несколько раз, пока не найдешь вопрос.

> Может, сохранять куда-то (куда?) промежуточные данные в процессе редактирования?
Можно в localStorage, можно на сервер в фоновом режиме.

-----

По коду: если у тебя требуется PHP7, то напиши это в composer.json, сейчас там указан php5.

По поводу Симфони: там есть одна вещь, которая мне не нравится. Они в продакшене (в отличие от dev) не превращают ошибки в исключения и не используют strict_variables в твиге. Я думаю, это плохая идея и надо переделать это. Это идет вразрез в принципом fail fast и способствует более низкому качеству кода.

По роутеру: не советую использовать аннотации, когда роуты собраны в одном месте, намного удобнее.

В модели данных не увидел наследования, ты не думал, что для разных типов вопросов/ответов можно было бы использовать разные классы?

Если в таблицах у колонок есть значения по умолчанию, они должны быть продублированы в сущностях.

В Postgres можно использовать CHECK на колонках для ограничения вставляемых значений.

Поиск данных через связи не всегда эффективен.

Пока код выгодит нормально, надо только контроллер разгрузить.

Также, если есть время и возможность, советую подумать про добавление автоматизированных тестов, в ОП посте есть урок. Раз за Симфони взялся, надо бы и тестирование подучить.

Показать весь текст

7 авг, 15:31 #757 #1040030

Аноны, переходите в новый тред >>1033564 (OP)

Также, те, кому я еще не ответил, напомните о себе в новом треде

Ответы41219

someApprentice 7 авг, 18:29 #758 #1040147

>>1040025
>> Ещё есть вариант сохранять сообщения в sessionStorage, где ключем будет ID сообщения, а значением сам его объект. Затем сравнивать программно результаты запросов и sessionStorage, и выводить\сохранять уникальные значения.
>Вообще, мне кажется, ты немного все переусложняешь. Достаточно с сервера вместе с сообщениями присылать время получения данных, и при следующем запросе просить сервер прислать только сообщения, добавленные/обновленные после этого времени.
У меня приходила подобная мысль, только использовать не время, а ID последнего сообщения, но у меня, как всегда, возникают трудности с обработкой обещаний.

>> Вероятно, мы не можем даже к этому обещанию добавить ещё результаты, потому что, вероятно, если мы напишем
>> var messages = getMessages(...).then(...);
>> messages.then(...);
>> мы выполним тот же самый запрос getMessages(...) и получим тот же самый результат.
>Нет, второй раз запрос не выполнится. Просто последний then() получит на вход значение, которое вернул через return предпоследний then.
Значит можно будет написать так

function chat() {
this.messages;
}

chat.runMessages(...) {
this.messages = getMessages(...).then(...);

refreshMessages(...);
}

chat.refreshMessages(...) {
this.messages.then(

function(messages) {
// Получаем дату\ID последнего сообщения
var lastDate = messages.lastMessage.date;

// Получаем новые сообщения
getNewMessages(lastDate).then(

function(data) {
//Выводим новые сообщения
showMessages(data);

// и добавляем их к остальным
messages.lastMessage = data.lastMessage;

var length = Object.keys(messages.m).length; // m - хэш с самими сообщениями

for (var key in data.m) {
messages.m[length] = data.m[key];

length++;
}

return messages;
},

...
);

return messages;
},

...
);
}

Я ведь правильно объединил массивы сообщений из двух разных обещаний?

someApprentice 7 авг, 18:29 #758 #1040147

>>1040025
>> Ещё есть вариант сохранять сообщения в sessionStorage, где ключем будет ID сообщения, а значением сам его объект. Затем сравнивать программно результаты запросов и sessionStorage, и выводить\сохранять уникальные значения.
>Вообще, мне кажется, ты немного все переусложняешь. Достаточно с сервера вместе с сообщениями присылать время получения данных, и при следующем запросе просить сервер прислать только сообщения, добавленные/обновленные после этого времени.
У меня приходила подобная мысль, только использовать не время, а ID последнего сообщения, но у меня, как всегда, возникают трудности с обработкой обещаний.

>> Вероятно, мы не можем даже к этому обещанию добавить ещё результаты, потому что, вероятно, если мы напишем
>> var messages = getMessages(...).then(...);
>> messages.then(...);
>> мы выполним тот же самый запрос getMessages(...) и получим тот же самый результат.
>Нет, второй раз запрос не выполнится. Просто последний then() получит на вход значение, которое вернул через return предпоследний then.
Значит можно будет написать так

function chat() {
this.messages;
}

chat.runMessages(...) {
this.messages = getMessages(...).then(...);

refreshMessages(...);
}

chat.refreshMessages(...) {
this.messages.then(

function(messages) {
// Получаем дату\ID последнего сообщения
var lastDate = messages.lastMessage.date;

// Получаем новые сообщения
getNewMessages(lastDate).then(

function(data) {
//Выводим новые сообщения
showMessages(data);

// и добавляем их к остальным
messages.lastMessage = data.lastMessage;

var length = Object.keys(messages.m).length; // m - хэш с самими сообщениями

for (var key in data.m) {
messages.m[length] = data.m[key];

length++;
}

return messages;
},

...
);

return messages;
},

...
);
}

Я ведь правильно объединил массивы сообщений из двух разных обещаний?

Показать весь текст

8 авг, 14:02 #759 #1040638

>>1040028
Не понимаю что значит модули. Это когда библиотеку типа пишешь, а потом её подгружают все кто хочет и в коде у себя использует?

Под каждый модуль писать класс?

И всё таки не понятно что такое DI и DI-контейнер. В двух словах можно описать как-нибудь какую он проблему именно решает и что делает?

Очень сложно когда все кругом говорят языком продакшена или другими заумными терминами, а по факту от тебя хотят не такие уж и сложные вещи, но ты просто не можешь понять.

Ответы41109

9 авг, 01:15 #760 #1041109

>>1040638

Модуль здесь значит "обособленная часть приложения". "Обособленная" - значит как-то отделенная от других частей, не спутанная с ними и выполняющая свою, отдельную задачу. Способная работать отдельно.

Я не стал писать "класс", так как это подразумевало бы использование ООП, а код на фукциях тоже по идее можно поделить на модули (например, разложив функции по разным файлам или неймспейсам).

Соответственно, если код разбит на обособленные модули, то с ним может быть проще работать. Можно изучать и править отдельный модуль, не трогая другие модули и не боясь сломать что-то еще.

То есть модуль может быть файлом с функциями, классом, набором классов и тд, в зависимости от ситуации. Главное чтобы у него была какая-то своя задача и он был обособлен от других модулей, не спутан с ними слишком сильно. В ООП обычно один модуль - это один класс (но не всегда).

И конечно, если хочется оформить модуль в виде библиотеки, то это нетрудно сделать. Но это не обязательно.

Соответственно, если вернуться к задаче про конвертер валют, я бы хотел, чтобы отдельные части этого конвертера были обособлены.

Ну например, чтобы "загрузчик курсов с внешнего API" был отдельным модулем и мы могли бы использовать или тестировать его отдельно. Чтобы мы могли например вызвать какую-то функцию и она бы сделала нужные запросы и вернула нам курс, полученный с сервера.

И я хотел, чтобы сам конвертер был бы отделен от кеша курсов и загрузчика курсов. Чтобы мы могли например дать ему жестко заданный курс, и протестировать, как он конвертирует суммы по этому курсу, не используя кеш и внешний сервис.

А то, что ты описал, не разбито на модули. У тебя по твоему описанию все эти части спутаны и зависят одна от другой.

------

DI (dependency injection) - это внедрение зависимостей в ООП. Это подход, когда классу передают его зависимости снаружи ("внедряют"), а не он ищет или получает их самостоятельно. Что такое "зависимость", описано в моем уроке про DI ( https://github.com/codedokode/pasta/blob/master/arch/di.md )

Чтобы понять DI, нужно сначала изучить и понять ООП. Скорее всего ты пока его не понимаешь, потому для тебя все, что описано в том уроке, звучит непонятно. Потому, я тебе могу предложить решить задачу про Вектор и Кошки-мышки из учебника в ОП посте, если ты их еще не решал.

Или, может быть, ты решил эти задачи, и понимаешь ООП, но ты пока не сталкивался со случаями, когда надо передавать зависимости. В таком случае, могу предложить задачу про студентво из ОП поста - там DI понадобится.

> Очень сложно когда все кругом говорят языком продакшена или другими заумными терминами, а по факту от тебя хотят не такие уж и сложные вещи, но ты просто не можешь понять.
Ты скорее всего просто пропустил какие-то базовые вещи, берешься сразу за сложное, оттого и не понимаешь.

9 авг, 01:15 #760 #1041109

>>1040638

Модуль здесь значит "обособленная часть приложения". "Обособленная" - значит как-то отделенная от других частей, не спутанная с ними и выполняющая свою, отдельную задачу. Способная работать отдельно.

Я не стал писать "класс", так как это подразумевало бы использование ООП, а код на фукциях тоже по идее можно поделить на модули (например, разложив функции по разным файлам или неймспейсам).

Соответственно, если код разбит на обособленные модули, то с ним может быть проще работать. Можно изучать и править отдельный модуль, не трогая другие модули и не боясь сломать что-то еще.

То есть модуль может быть файлом с функциями, классом, набором классов и тд, в зависимости от ситуации. Главное чтобы у него была какая-то своя задача и он был обособлен от других модулей, не спутан с ними слишком сильно. В ООП обычно один модуль - это один класс (но не всегда).

И конечно, если хочется оформить модуль в виде библиотеки, то это нетрудно сделать. Но это не обязательно.

Соответственно, если вернуться к задаче про конвертер валют, я бы хотел, чтобы отдельные части этого конвертера были обособлены.

Ну например, чтобы "загрузчик курсов с внешнего API" был отдельным модулем и мы могли бы использовать или тестировать его отдельно. Чтобы мы могли например вызвать какую-то функцию и она бы сделала нужные запросы и вернула нам курс, полученный с сервера.

И я хотел, чтобы сам конвертер был бы отделен от кеша курсов и загрузчика курсов. Чтобы мы могли например дать ему жестко заданный курс, и протестировать, как он конвертирует суммы по этому курсу, не используя кеш и внешний сервис.

А то, что ты описал, не разбито на модули. У тебя по твоему описанию все эти части спутаны и зависят одна от другой.

------

DI (dependency injection) - это внедрение зависимостей в ООП. Это подход, когда классу передают его зависимости снаружи ("внедряют"), а не он ищет или получает их самостоятельно. Что такое "зависимость", описано в моем уроке про DI ( https://github.com/codedokode/pasta/blob/master/arch/di.md )

Чтобы понять DI, нужно сначала изучить и понять ООП. Скорее всего ты пока его не понимаешь, потому для тебя все, что описано в том уроке, звучит непонятно. Потому, я тебе могу предложить решить задачу про Вектор и Кошки-мышки из учебника в ОП посте, если ты их еще не решал.

Или, может быть, ты решил эти задачи, и понимаешь ООП, но ты пока не сталкивался со случаями, когда надо передавать зависимости. В таком случае, могу предложить задачу про студентво из ОП поста - там DI понадобится.

> Очень сложно когда все кругом говорят языком продакшена или другими заумными терминами, а по факту от тебя хотят не такие уж и сложные вещи, но ты просто не можешь понять.
Ты скорее всего просто пропустил какие-то базовые вещи, берешься сразу за сложное, оттого и не понимаешь.

Показать весь текст

9 авг, 08:13 #761 #1041166

антоны стоит ли учиться навечку в cms?
или забить и вкатиться в ворпресс\т.п.?

Ответы41219

9 авг, 11:06 #762 #1041219

>>1041166
Вам в новый тред,вьюноша
>>1040030
>>>1033564 (OP)

11 авг, 12:16 #763 #1042467

Норот.
Помогите с проблемой.
Кароч есть скрипт для CLI. Изначально был сделан для работы в связке с AJAX. AJAX продолжал вызывать скрипт с разными параметрами, пока не было встречено определенное условие. Затем поставили задачу переделать под работу с CRON. CRON подходит в качестве инициатора, но не связующего звена, т.к. может выполняться не чаще раза в минуту, а скрипт должен вызывать сам себя, как только текущая операция завершена.
Сделал следующее:
передал register_shutdown_function коллбэк, в котором делаю дисконнект с БД и затем использую команду passthru, чтобы начать следующую итерацию.
В итоге столкнулся с проблемой "открыто слишком много файлов". Скрипт выполняет под рутом и где-то на 50-ой итерации php крашится, т.к. рут превышает ulimit использования файлов.
Подозреваю, что это вызвано тем, что изначальный скрипт никогда толком не завершается и ждет результата выполнения passthru. По сути, получается рекурсия, которая сжирает ресурсы.
Вопрос: как решить задачу связывания вызовов скрипта и при этом высвобождать ресурсы?

Обновить тред
Двач.hk не отвечает.
Вы видите копию треда, сохраненную 11 августа 2017 года.

Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.

« /pr/В начало тредаВеб-версияНастройки/a//b//mu//s//vg/Все доски

Пользуетесь скринридером — пишите, что можно улучшить.
Host-Food.ru — надёжный хостинг от 12 руб/мес | Free DNS
Зеркала М.Двача: m2ch.hk, m2ch.lib, m2chfapiswfw2wcakptqp4o6ltgchvjuxfab7urxlduraomtlnhw5xad.onion