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

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

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

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

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

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

Предыдущий тред был тут: >>619873 (OP) (почти 1000 постов!)

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

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

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

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

Учебник дает основы языка PHP, но чтобы делать сайты, этого недостаточно. Если ты его прошел, то надо переходить в более серьезным задачкам, которые научат тебя как выдавать страницы в браузер, работе с таблицами в БД, работе с формами, MVC.

- Простая, но полезная задача сделать список студентов: https://github.com/codedokode/pasta/blob/master/student-list.md
- Более сложная задача сделать файлообменник на микрофреймворке Slim: https://gist.github.com/codedokode/9424217
- Еще более сложная и долгая задача на Yii/Yii2: https://gist.github.com/codedokode/8733007
- После нее можно изучать автоматизированное тестирование
- Если ты все решил, переходи к Symfony 2/Doctrine 2

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

https://gist.github.com/codedokode/10774100
https://gist.github.com/codedokode/7054af4a03865c4cc863

Может тебе понадобится пользоваться командной строкой, вот гайд https://gist.github.com/codedokode/10539568

Вот небольшой туториал по тому как начать использовать PHP на сервере для отдачи странички в браузер: https://php.net/manual/ru/tutorial.php Увы, уроков плавно подводящих к тому, как сделать задачи выше, пока нет, так что если что, задавай вопросы.

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

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

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

Что почитать

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

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

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

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

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

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

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

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

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

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

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

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

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

Объясняй

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

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

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

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

Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
56 Кб, 500x644
187 Кб, 853x480
93 Кб, 561x800
Важно #2 #629824
Код нужно писать не как попало, а аккуратно и по правилам. Почему? Потому, что на неакуратно написанный код не хочется даже смотреть.

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

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

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

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

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

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

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

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

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

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

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

Объясняй

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

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

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

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

Ах да. Если тебе кажется, что что-то в учебнике или задачах можно сделать лучше — пиши, обратная связь всегда очень полезна.
#3 #629825
Ответы на посты и решения по 17 января - в старом треде >>619873 (OP) в конце. Если вас пропустили, не ответили, не проверили, не дали совет - напомните о себе в этом треде.

Ответы на посты с 18 по 20 января наверно будут запощены в старом треде завтра или послезавтра.
23 Кб, 1903x949
#4 #629826
https://github.com/foobar1643/student-list
Сделал вот задачу из ОП-поста на список студентов, реализовал все что нужно было, код все равно получился говном (но работает). Подскажите что переделать, что сделано не так.

Поддержки mysql нет потому что мне лень было её ставить на сервер. Взял вместо неё postgresql, хотя в теории если поменять одну строчку в конфиге, то всё должно заработать и с mysql (дамп базы очевидно не подойдет).
50 Кб, 502x370
#5 #629829
8 Кб, 274x184
#6 #629857
>>629822 (OP)
реквестирую урок по сессиям.
#7 #629862
https://github.com/toppestkek/GuestBook
мое тестовое не забудь проверить плз.
102 Кб, 800x518
#8 #629883
ОП, переделал Лиличку. Проверь, пожалуйста

http://ideone.com/bpClfZ
#9 #629939
Блядь, я забыл, на какой хоткей в PHPStorm я форматировал код, просто взял и за секунду забыл часть патерна который всегда делаю перед переходом в другое окно

ctrl+a
ТУТ ЕБУЧИЕ ФОРМАТРОВАНИЕ
ctrl+s
alt+shift+q

Что я нажимал подскажите, всегда это одной левой рукой делал точно
#10 #629941
>>629939
Вот у меня тоже такие провалы в памяти бывают, иногда хочу что-то сделать, начинаю делать, а потом на половине пути уже забываю зачем я это делаю.

Это первый знак того что я ОБДВАЧЕВАЛСЯ?
#11 #629942
>>629941
Блять последнее время все чаще такое
И депрессия ебаная хз, как жить
#12 #629943
Есть возможность кодить и решать задачи и из под андройд?
#13 #629946
>>629943
Есть, подключай клавиатуру и ставь какой-нибудь веб-сервер (из бесплатных kWS, Palapa Web Server).
#14 #629949
Насколько оправданно учить регулярки, если есть такие сайты, как http://regexp-online.com/ и в принципе, они легко гуглятся?
#15 #629951
>>629949
Там и учить нечего, за день можно все осилить.
#16 #629954
>>629946

Круто. Спасибо. Какой нибудь IDE посоветуешь?
#17 #629962
>>629954
Про IDE не знаю, все что я делал это запускал на андроиде скрипты написанные на компьютере. Может быть кто-нибудь другой подскажет.
#18 #629968
>>629939
а я напиздел

руки вспомнили ctrl +alt+ i это было
и тут нужно 2 руки
#19 #629989
>>629954
ideone.com, азаза
#20 #630081
Кстати. на том же хабре есть статья о том, что никакая соль тебя от взлома не защитит, ибо она ломается так же легко теми, кто знает про соль, а про нее все знают.
#21 #630090
http://pastebin.ru/YE0nSJpt
https://github.com/toppestkek/Test/blob/master/index.php#L5

> substr($_SERVER['REQUEST_URI'], 5)


что за магическое число 5?

>Почему имя класса с маленькой буквы? Почему оно не совпадает с именем файла? Во втором посте треда написана ссылка на рекомендации PSR, почитай-ка их.



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

>Инициализацию всяких объектов лучше вынести из контроллера.


Куда это их вынести? В новый объект?

>Ты файл почему-то загружаешь до валидации данных. Более того, тут как я понимаю можно загрузить php или htaccess файл и захватить твой сервер?



В аплоадс у меня стоит хтаксесс с таким кодом, поэтому нельзя.
php_flag engine 0
php_value upload_max_filesize 1G
php_value post_max_size 1G

>Непарвильное использование иключений


А какое правильное?

>Это правило применяется только к php скриптам расположенным внутри uploads


Так у меня же файлы только туда и грузятся

>формы все введенные значения теряются


лень писать было. эта валидация жиесом итак меня выбесила.
#21 #630090
http://pastebin.ru/YE0nSJpt
https://github.com/toppestkek/Test/blob/master/index.php#L5

> substr($_SERVER['REQUEST_URI'], 5)


что за магическое число 5?

>Почему имя класса с маленькой буквы? Почему оно не совпадает с именем файла? Во втором посте треда написана ссылка на рекомендации PSR, почитай-ка их.



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

>Инициализацию всяких объектов лучше вынести из контроллера.


Куда это их вынести? В новый объект?

>Ты файл почему-то загружаешь до валидации данных. Более того, тут как я понимаю можно загрузить php или htaccess файл и захватить твой сервер?



В аплоадс у меня стоит хтаксесс с таким кодом, поэтому нельзя.
php_flag engine 0
php_value upload_max_filesize 1G
php_value post_max_size 1G

>Непарвильное использование иключений


А какое правильное?

>Это правило применяется только к php скриптам расположенным внутри uploads


Так у меня же файлы только туда и грузятся

>формы все введенные значения теряются


лень писать было. эта валидация жиесом итак меня выбесила.
#22 #630102
1) Задача про миллион в банке

http://ideone.com/2CZC21

2) Генератор стихов:

http://ideone.com/Wqtqet

Иногда пропадают некоторые слова, как это пофиксить?
(Про array_rand из предыдущего поста не особо понял)

3) Про палиндром

http://ideone.com/7n6pqZ
#23 #630103
>>630081
Статью можно посмотреть?
А чому тогда не всё на свете ломается, как-то же защищаются?
#24 #630116
Я в 2016 году НЕ ЗНАЮ как валидировать данные, вы представляете?? Надо срочно регулярки для школьников порешать, авось узнаю. да и в твоем говно урок про XSS инъекции вообще нихуя не написано, как на практике от них защищаться, написано только как их внедрять И ПРО htmlchars который у меня стоит, скотина ты тупая. так и будешь сидеть училкой информатики в своей шаражке, мерзкий пидор с анальной фиксацией.
#25 #630117
>>630103
в гугле забанили? ну вот так не ломается, потому что нахуй не всралось никому ломать шаражку рога и копыта.
да и автоматический ввод - дело дорогое и времязатратное для ломания всякого говна.

http://habrahabr.ru/post/145667/
#26 #630118
>>630102

>1) Задача про миллион в банке


Так интереснее с кредитом жи есть: http://ideone.com/TU9s96
echo просто внутрь цикла поставить, чтобы пронаблюдать за работой.
Считает верно всё.

>2) Генератор стихов:


Неправильно рассчитывается конечное число для функции mt_rand.
Чтобы понять ошибку, вспомни, начиная с какой цифры нумеруются ключи у значений в массивах.
Вот так можно исправить - переходи только после нахождения ошибки в своём коде! - : http://ideone.com/Ybpcko
Громоздко и неизящно, с array_rand всё проще выходит.

>3) Про палиндром


Нормально, всё работает и на слове "поп".
#27 #630213
Сейчас прохожу задание про циклы. Друзья, для чего переменная заключена в фигурные скобки echo " {$} "? Пробовал их убрать - ошибка. Чёт не помню по этому поводу разъяснений в предыдущих заданиях.
#28 #630249
ОП, вот ты мне очень много тут писал - http://pastebin.ru/mzp3Ex5d

Я практически все с нуля переписал - https://github.com/lexdss/shop

ps: опять же интересует только код, на верстку можешь не смотреть, чисто для вида на скорую руку сделал.

И некоторые мелочи в функционал пока не допилил (типа проверки статуса заказа пользователем), но это позже, вдруг опять придется заново переписывать все
#29 #630254
>>630213
Обработка переменных ¶

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

Существует два типа синтаксиса: простой и сложный. Простой синтаксис более легок и удобен. Он дает возможность обработки переменной, значения массива (array) или свойства объекта (object) с минимумом усилий.

Сложный синтаксис может быть определен по фигурным скобкам, окружающим выражение.

http://php.net/manual/ru/language.types.string.php
#30 #630257
Ах да, я вспомнил, почему не вывел данные формы при валидации через пхп, потому что при клиентской валидации они сохраняются в полях, быдло ты тупое. И таких берут в преподы, пиздец, неудивительно, что рашкообразование сосет.
#31 #630270
>>630257
Препод по РНР?
#32 #630287
>>630102
Про палиндром не работает, сравнивает только 1 и последний символы в строке, а в середину хоть хуй напиши он всё равно палиндромом сочтёт.
#33 #630330
>>630287
Ох лол, действительно.
А я проверил только на "попе", код посмотрел - вроде всё логичным показалось.
Цикл не выдерживается до конца. Первые совпадающие буквы его сразу обрывают.
#34 #630338
>>630102
Короче, обрати внимание на то, как ты отсчитываешь буквы с конца строки.
Не читай подсказки, пробуй решить самостоятельно.
Подсказка: там должен быть знак минус, ты же должен с конца идти, а ты идёшь с начала строки. Там должна быть переменная опять же, потому что идёт это всё в цикле, переменная изменяется и буквы передвигаются в этом сравнении
Ещё одна подсказка: не существует такого выражения, как "минус ноль". Поэтому подумай, как там можно обойтись с отниманиями и прибавлениями единиц от переменной $i
Исправленный вариант (не открывать без попыток решить самостоятельно!): http://ideone.com/9wZnM9
#35 #630376
>>630338
А если я сделал через strrev но поправил кодировку в новой функции, меня всё равно пидорнут за такое?
http://ideone.com/htP10c
someApprentice #36 #630433
>>625339
>>629817
Замечаний по коду никаких нету? Мне продолжать выполнять задание?
#37 #630434
>>630376
Забавное решение.
Но так-то задача на разбор циклов всё-таки, ОП вряд ли одобрит именно в плане подхода.
#38 #630469
На странице которую я собираюсь парсить, есть много table в которых в одних и тех же тегах, хранится большое количество разной информации, у тегов нет классов и ID. Как мне указать то что я например хочу спарсить информацию с третьей таблицы по счёту на странице, то есть если парсить так:

$search = $html->find('table tr td font');

То я получаю всю информацию, которая соответствует этому пути, из всех таблиц, как указать что инфа нужна только с третьей по счёту таблицы.
#39 #630471
>>630469
Парсинг делаю при помощи simple_html_dom.php
#40 #630547
>>629817

>Не понял о чем ты. В аргументе нелзя писать PDO Init::$pdo.


В смысле просто __construct(PDO $pdo), а потом просто передавал бы статически new DataGateway(Init::$pdo)
#41 #630602
Велосипедный звонок
http://ideone.com/NIWEZS
#42 #630610
>>630433
Кстати, мне тут мысль пришла. Создать вторую ветку в проекте. Выслал решение ОПу, и во второй ветке продолжаешь пилить. Потом мержишь дорабатываешь. Годно?
#43 #630629
Сделал задачку на проверку телефона, реализовано по моему несколько убого, если я правильно понял то должны только цифры учитываться,а возможные пробелы и символы кроме букв и лишних цифр игнорироваться.Решение чужое не смотрел, проверьте кто-нибудь сначала.
http://ideone.com/GnrR0S
#44 #630637
погромисты, а что лучше сначала учить: хтмл, а после пхп, либо же наоборот?
или разницы нет?
#45 #630650
>>630433

Нельзя.
#46 #630655
>>630602
Неправильный второй ориентир для функции mt_rand. В массиве нумерация начинается с нуля.
#47 #630664
>>630629
http://ideone.com/hdiflZ - внутри телефонного номера можно траллить телефонисток, я проверял.
Подумай, как можно улучшить это:

>\\W*([0-9]{1})


Номер в фигурных скобках не имеет смысла, потому что в квадратных скобках "один любой указанный символ". После кода все цифры должны быть в одной регулярке, а также возможность ставить пробелы, минусы в любом порядке.
Также у ОПа есть паста для проверки тучи номеров. В предыдущем треде была тоже.
#48 #630715
>>630655
А можно прям лицом в строчку, а то я не очень умный?
#49 #630719
>>630715

>$random1 = mt_rand(1, count($word1));


Что считает функция count($word1)?
С какого числа начинается нумерация в массиве?
13 Кб, 200x179
#50 #630726
>>630719
Кол-во элементов в эрэе, а нумерация с 0.
#51 #630734
>>630726
Лучше через array_rand делать, кстати.
#52 #630737
>>630734
О! Прям то, что нужно, а то как-то громоздко код выглядит. Спасибо.
#53 #630765
Почему в большинстве вакансий 1сбитрикс\друпл и другое цмс говно?
#54 #630780
>>630765
пхп-алхимия - сродство говна к говну.
#55 #630784
Если мне надо запускать скрипт автоматически, например каждый час, для этого надо использовать cron? Это можно сделать если у меня Windows?
#56 #630786
>>630784
Можно в Windows. Win+R > taskschd.msc
Внимание: может понадобится пердолинг.
#57 #630825
>>630469
Я недавно сталкивался с подобной задачей, только почему-то мне хватило страницы документации, чтобы её решить.
http://simplehtmldom.sourceforge.net/manual.htm
#58 #630865
Можно ли как-нибудь элемент view передать в callback функцию в слиме?
#59 #630879
Кто-то делал задачи по SQL ОПовские? Пиздец даж первая задача что-то совсем не идет, хотя вроде все знаю, что может понадобится для ее решения.
#60 #630921
Я окончательно заебался.

Смотрите: задача про айфон в кредит W5.1 (надо сделать костыль, чтоб в минус не уходил банк). Решил с помощью такой конструкции:

if ($creditBalance <= $monthlyPayment) { / типа если кредита осталось меньше, чем ОП на завтраках экономит /

$monthlyPayment = $monthlyPayment - ($monthlyPayment - $creditBalance); / высчитали, какой будет месячный платёж в данном случае /

echo "последний платёж - $monthlyPayment"; / это чтоб программа показала, что всё сработало и платёж высчитался /
break; } /* закрыли конструкцию

Вот как сделать, чтоб после этого вышла надпись "всё заебок, долг $creditBalance" (ноль)? Час сижу, отложил работу, нибуя не получается. Пробовал решить через конструкцию elseif ($creditBalance = 0) - нихуя. Пробовал писать новый if - тоже не катит. break переносил. В каком направлении думать?
#61 #630931
Господа, а нахуя сделано так, что нумерация элементов массива начинается с гуля? Ну вот нахуя?
#62 #630932
>>630931
Нуля
#63 #630937
>>630931
Потому что нумерация с нуля это единственная верная нумерация. Посмотри на любую линейку или термометр. Нумерацию с единицы делают только ебаные гуманитарии.
#64 #630962
>>630937
Неправда. Нумеровать что-либо с единицы настолько естественно, что даже ты об этом не задумываешься. Термометр и линейка это шкала, которая служит для измерения и её начало в нуле, как и у любой числовой прямой. Элементы массива не вписываются в эту аналогию
#65 #631003
>>630825
А у меня не получается что-то, ты имеешь в виду решить её вот так?
$ret = $html->find('a', 0);
Где 0 порядковый номер элемента в дереве ДОМ?
#66 #631004
Как при помощи cURL сабмитить формы которые передаются через аякс? И формы у полей которых даже нет параметра name а есть только например ID? Надо лазить по странице и всем подключённым к ней страницам и искать где в аяксе описываются параметры запроса?
#67 #631035
>>630921
Код на Идеоне вбрось, в каком он у тебя виде находится, а то не всё понятно.
Но могу пованговать, потому что несколько дней возился с этой задачей, переписывал её много раз с нуля, а потом и другим анончикам помогал решить правильно.
Короче, скорее всего, главная ошибка в том, что ты не различаешь $creditBalance (который у тебя учитывает и минус $monthlyPayment) и не проверяешь состояние кредита до всяческих условий с if и else. Для этого можно ввести дополнительную переменную.
Алгоритм такой:
1. Имеем сумму кредита.
2. Прибавляем к ней нужный процент и прибавляем комиссию за обслуживание кредита.
3. Проверяем, получившаяся сумма больше или меньше 5000, которые может выплачивать Анончик в месяц.
4. В соответствии с результатом проверки или продолжаем цикл выплат, или выплачиваем имеющуюся сумму и обрываем цикл (не забывай про пункт 1, что она у нас уже должна быть умножена на процент и к ней уже должна быть прибавлена комиссия за обслуживание кредита).
Всё.
Пробуй решить, каждый раз вбрасывай ссылку на код, так нагляднее.
Отличная задача для понимания работы циклов.
Там всё на поверхности, тем приятнее будет решение, когда уже успел намучиться.
#70 #631082
>>631079
Это на данный момент, когда я совета спрашивал
38 Кб, 400x284
#71 #631098
Шёл третий день битвы с задачей на числа прописью.
С усталой, но довольной улыбкой Аноним нажимал на кнопку "Submit" на ideone.com и не мог остановиться...

"99" - это "девяносто девять рублей"
"45" - это "сорок пять рублей"
"3" - это "три рубля"
"361" - это "триста шестьдесят один рубль"
"316" - это "триста шестнадцать рублей"
"421" - это "четыреста двадцать один рубль"
"124" - это "сто двадцать четыре рубля"
"787" - это "семьсот восемьдесят семь рублей"
"102" - это "сто два рубля"
"863" - это "восемьсот шестьдесят три рубля"
"160" - это "сто шестьдесят рублей"
"0" - это "ноль рублей"
"911" - это "девятьсот одиннадцать рублей"
"892" - это "восемьсот девяносто два рубля"
"749" - это "семьсот сорок девять рублей"
"150" - это "сто пятьдесят рублей"
"140" - это "сто сорок рублей"
"990" - это "девятьсот девяносто рублей"
"186" - это "сто восемьдесят шесть рублей"
"716" - это "семьсот шестнадцать рублей"
"524" - это "пятьсот двадцать четыре рубля"
"802" - это "восемьсот два рубля"

Как много уже было сделано, а сколько ещё предстояло сделать!
Аноним крепко сжимал ладонь свободной левой руки в кулак, а правой уверенной рукой продолжал настойчиво нажимать на кнопку "Submit"...
На его губах играла усталая довольная улыбка...
38 Кб, 400x284
#71 #631098
Шёл третий день битвы с задачей на числа прописью.
С усталой, но довольной улыбкой Аноним нажимал на кнопку "Submit" на ideone.com и не мог остановиться...

"99" - это "девяносто девять рублей"
"45" - это "сорок пять рублей"
"3" - это "три рубля"
"361" - это "триста шестьдесят один рубль"
"316" - это "триста шестнадцать рублей"
"421" - это "четыреста двадцать один рубль"
"124" - это "сто двадцать четыре рубля"
"787" - это "семьсот восемьдесят семь рублей"
"102" - это "сто два рубля"
"863" - это "восемьсот шестьдесят три рубля"
"160" - это "сто шестьдесят рублей"
"0" - это "ноль рублей"
"911" - это "девятьсот одиннадцать рублей"
"892" - это "восемьсот девяносто два рубля"
"749" - это "семьсот сорок девять рублей"
"150" - это "сто пятьдесят рублей"
"140" - это "сто сорок рублей"
"990" - это "девятьсот девяносто рублей"
"186" - это "сто восемьдесят шесть рублей"
"716" - это "семьсот шестнадцать рублей"
"524" - это "пятьсот двадцать четыре рубля"
"802" - это "восемьсот два рубля"

Как много уже было сделано, а сколько ещё предстояло сделать!
Аноним крепко сжимал ладонь свободной левой руки в кулак, а правой уверенной рукой продолжал настойчиво нажимать на кнопку "Submit"...
На его губах играла усталая довольная улыбка...
#72 #631102
>>631079
Делай по алгоритму, там у тебя как раз то, что я и предугадывал:

>$creditBalance = ( $creditBalance * $percent ) + $servicePayment - $monthlyPayment;


От $creditBalance уже отнята $monthlyPayment, когда $creditBalance попадает в условие.
То есть, например, $creditBalance у тебя 3000, а ты прибавляешь к нему комиссию и проценты, а потом отнимаешь $monthlyPayment, вот в минус и уходит.
#73 #631103
>>631102
И только после этого сравниваешь:

>if ($creditBalance <= $monthlyPayment)


Это неверно.
#74 #631120
И все-таки подскажите по задаче о лайках по SQL.
Вот есть две таблице в одной - user(id, name) в другой - (id, user_id(кто поставил), like_user(кому поставил)). Как тут можно подсчитать одновременно сколько юзер поставил лайков и сколько ему? Если я сгруппирую так GROUP BY user.id (или user_id, неважно), то через COUNT смогу соответственно подсчитать сколько он лайков поставил, но не смогу подсчитать сколько ему поставили потому что COUNT зависит от GROUP BY. А еесли так GROUP BY like_user, то смогу подсчитать сколько пользователю поставили лайков, но теперь не смогу подсчитать сколько он поставил.
#75 #631145
Допустим вы решили установить линукс, допустим дебиан с гномом. Допустим, запустив гном, вы теперь хотите Хромиум (как же без браузера?), флеш (как же без флеша?) и скайп. Для начала вы ищете где тут play market, software center или что-то аналогичное, долго и мучительно, пока наконец не находите невзрачную иконку с картонными коробками и надписью "пакеты". Она точно не выглядит как плей маркет, а скорее как какая-то ненужная системная утилита. Вы запускаете ее, видите пикрелейтед, только на русском ( https://help.gnome.org/users/gnome-packagekit/stable/add-remove.html.en ) и ищете там:

- chromium - вываливается куча непонятных пакетов, среди них есть нужный
- skype - нету
- flash - вываливается куча хлама, оказывается надо писать flashplugin в поиске

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

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

Разумеется на самом деле ничего не установилось, иконок хромиума нет, самого пакета в dpkg -l тоже нет.

Предлагаю любителям линукса попробовать разгадать эту загадку. В /var/log/messages ничего нет.

Я конечно не удивлен, в линуксе всегда все было так, сколько раз я не пробовал им пользоваться. Но так сломать все надо еще постараться. В сравнении с гномом/дебиан тот же андроид на несколько порядков продуманнее - по крайней мере установка пакетов там работает из коробки.
#76 #631147
>>631145
Хуйней занимаешься. Качай исходники и компилируй сам. Скайп под линукс майкрософты не обновляли уже лет пять, я удивлюсь если он вообще там работает. В качестве флэша можно взять гугловский pepperflash. Ах да, забудь про гуй, он не нужен и для инвалидов.
#77 #631153
>>631147

Зачем мне качать исходники? В том же андроиде все ставится через менеджер пакетов, в дебиане без гнома - тоже. Только в дебиане с гномом и ГУИ все сломано.
#78 #631159
>>631153
В debian? Все сломано? В Debian?
В дистрибутиве, в котором по определению в репозиториях только стабильные версии ПО.
Может тебе Убунту попробывать?
#79 #631161
>>631159
Он просто криворукий виндузяткик, который ничего кроме как МЕНЕДЖЕР ПАКЕТОВ не может. Завтра он побежит создавать тред в /s/ какой этот ваш линукс говно и как там все неудобно.
#80 #631163
>>631161
У меня арч сам по себе упал. Просто сам по себе. До сих пор лень поднимать, стоит второй системой шиндовс.
#81 #631165
>>631163
Он не может сам по себе упасть. Упасть могли иксы, плазма и даже Аллах. Смотри и читай логи, отслеживай из-за чего это происходит.

На втором компьютере стоит центОС, не выключал его с сентября. Ни единого падения или тормоза, все работает идеально.
#82 #631167
>>631120

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


Логично иметь для такого две разные таблицы для разных лайков, не?
Отдельно лайки юзера, отдельно лайки юзеру.
Я хз.
#83 #631168
>>631167
А разве это будет не избыточность в БД?
другой-анон
#84 #631169
>>631120
У тебя и так две таблицы, ну да пох, я все равно пока не дошел.
Хз, в чем сложность дважды по разным параметрам группировать тогда.
#85 #631171
>>631168
Ну а как по-другому возможно?
Для большого дела всего пару таблиц - это норма.
#86 #631173
>>631145
Нужно в sources.list добавить non-free. А вообще, для этого есть /s/.
#87 #631174
>>631167
Здесь связь одни ко многим, достаточно две таблицы. Кроме того если сделать как ты говоришь, то будет непонятно кто кому ставил лайки
#88 #631175
>>631169

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


Сложности нет, но у ОПа написано, что это можно сделать одной группировкой и двумя джоинами
#89 #631183
>>631165
Ну может я разик обновился до перезагрузки, пол года назад было лол. До сих пор висит.
#90 #631192
Не понимаю, почему аргумент в пользовательскую функцию не передается в слиме? Если передавать вторым аргументов анонимую функцию, то она видит переменную из плейсхолдера, а если функцию записать в переменную, то уже нет.
$app->get("/files/:id", $test($id));
#91 #631201
>>631192
Забудьте, оказывается аргументы передавать не нужно.
#92 #631210
>>631147

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


У меня в Убунту 12.04 работает. Поставлен он был еще во времена 10.04 ни разу не обновлялся, пережил апгрейд на 12.04.
#93 #631214
>>631153
Никто тебе не мешает в Дебиана с Гномом и Гуи пользоваться командной строкой для установки пакетов.
#94 #631220
>>631210
Там новые облачные чатики не работают.
#95 #631230
Вы зарегистрированы на фриланс-биржах под своими реальными данными? Это на что-нибудь влияет?
#96 #631232
>>631230
Как заказчик скажу: на лояльность влияет.
Идентифицированный пользователь, безопасная сделка.
А так будешь жумлу с вротперсом устанавливать, а точнее - грызться с кучами школьников ради этого.
#97 #631239
>>630664
Поправил выражение, но всё равно слишком громоздко вышло, не знаю как ещё упростить, взгляните кто шарит.
http://ideone.com/AhNYfb
sage #98 #631243
реквест от ньюфага
ОП проверь, пожалуйста задание на js про ООП и гамбургеры

https://jsbin.com/pakonaseho/1/edit?js,console
#99 #631245
>>631243
сажа случайно прицепилась
#100 #631251
Проанализировав апворк я сделал вывод, что надо учить еще и вордпрес, чтобы хоть урвать хоть какой-то заказ.
#101 #631258
>>630610
Ты уже пробовал так делать?

Ты же тот кун что как и я делает задачу со студентами?
Как насчет обменяться контактами чтобы в будущем были совместные проекты?
#102 #631271
>>631251
Так лучше сначала в контору какую пойти работать за просто так, набраться опыта и потом вкатываться на апворк. Сам с нуля ты наврядли сможешь конкуренцию составить там кому-либо
#103 #631274
>>631258
Нет, я тот кун со студентами, а он нет. И я уже знаю вордпрессы. Контакты еще актуальны?
#104 #631316
>>631274

>Контакты еще актуальны?


Да, вот моя фейкопочта someapp( `renticeANUSopGP+enmailboxPUNCTUM=-]org
#105 #631323
>>631316
А что вы будете вместе делать?
зависть-кун
#106 #631326
>>631316
Отписал.
#107 #631344
Аноны, за сколько времени вы до студентов дошли и прошли их? Я с нового года мучаюсь, только до ХТМЛ дошёл, я совсем туп и безнадёжен? Или это не медленный темп?
#108 #631349
>>631344
С прошлого НГ?
#109 #631350
>>631344
Какая тебе разница? Не забивай себе мозги ненужной информацией.
#110 #631351
>>631349
С этого же.

>>631350
Да интересно же :(
#111 #631358
>>631344
Чего ты там дошёл до хтмл, где в треде куча сложных заданий типа калькулятора или чисел прописью?
Дошел он, посмотрите на него..
#112 #631363
>>631358
Да я уже скидывал их в прошлые треды, за исключением 1 или 2 задач все выполнил
#113 #631364
>>631363
А задачки на ООП? Вектор и Кошки-Мышки
#114 #631366
>>631363
Да ладно, где калькулятор и числа прописью, например?
Лиличку и всякие клавиши шифт я видел, разные аноны делали.
А что посложнее - не было ни одного.
#115 #631369
>>631364
А ООП это же следующая глава после ХТМЛ, вот скоро подойду к ней. Ну так ответит кто-нибудь, сколько времени у него уходил на всё про всё?

>>631366
Калькулятор точно кидал.
#116 #631370
>>631366
И кстати, лиличка мне мозг вынесла намного сильней, нежели калькулятор
#117 #631385
>>631369

>Калькулятор точно кидал.


А числа прописью? Калькулятор увидел сейчас, да.
Мне-то все равно, просто не раз уже видел, как перескакивают через задачи, а потом потыкаются со студентами и пропадают.
#118 #631387
>>631370
Значит, ты просто пока еще не делал числа прописью, азаза!!1
#119 #631407
>>631385
Числа прописью было тем, что пропустил, ты прав. Примерный принцип я разобрал, но не было времени нормально решить задачу, т.к. жрёт много времени она, а у меня работа. Думаю, на выходных я вернусь к ней
#120 #631444
>>631407
А с чем работа связана? Вообще какой бэкграунд, образование, левел и т.п.?
Для чего решил изучать программирование?
#121 #631460
>>631444
С перекладыванием бумажек с одного места на другое.

>Для чего решил изучать программирование?


чтобы вырваться из этого круга пиздеца и уныния
#122 #631481
>>631159

Это 100% баг. Я установил чистую систему + из нее гном + gdm3, никаких настроек не менял, ничего не устанавливал, версия дебиана №8 (в названиях я путаюсь так как в них нет никакой логики).

И я знаю причину бага.

Алсо линукс я знаю не так и плохо.

>>631167

Нет, нелогично. Хватит одной, обычная связь многие-ко-многим.

>>631173

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

>>631210

Работает в 15-й убунте, скайп 4 версии без рекламы, фейсбука и прочей дряни.

Кстати кто не умеет отключать фейсбук и рекламу в скайпе на винде: прописываете в хостс apps.skype.com на 127.0.0.1 и перезапускаете скайп.

>>631214

Зачем мне лезть в командную строку если я хочу пользоваться удобным приложением наподобие маркета? Командная строка удобна ели у тебя например есть список пакетов для установки, их кодовые названия. А если ты не знаешь как называется пакет, а просто хочешь скайп или хромиум то аналог маркета был бы удобнее.
#122 #631481
>>631159

Это 100% баг. Я установил чистую систему + из нее гном + gdm3, никаких настроек не менял, ничего не устанавливал, версия дебиана №8 (в названиях я путаюсь так как в них нет никакой логики).

И я знаю причину бага.

Алсо линукс я знаю не так и плохо.

>>631167

Нет, нелогично. Хватит одной, обычная связь многие-ко-многим.

>>631173

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

>>631210

Работает в 15-й убунте, скайп 4 версии без рекламы, фейсбука и прочей дряни.

Кстати кто не умеет отключать фейсбук и рекламу в скайпе на винде: прописываете в хостс apps.skype.com на 127.0.0.1 и перезапускаете скайп.

>>631214

Зачем мне лезть в командную строку если я хочу пользоваться удобным приложением наподобие маркета? Командная строка удобна ели у тебя например есть список пакетов для установки, их кодовые названия. А если ты не знаешь как называется пакет, а просто хочешь скайп или хромиум то аналог маркета был бы удобнее.
#123 #631489
>>630610

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

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

https://git-scm.com/book/ru/v1/%D0%9E%D1%81%D0%BD%D0%BE%D0%B2%D1%8B-Git-%D0%A0%D0%B0%D0%B1%D0%BE%D1%82%D0%B0-%D1%81-%D0%BC%D0%B5%D1%82%D0%BA%D0%B0%D0%BC%D0%B8

Гит очень крутая штука, я все время удивляюсь сколько в нем всего есть.
#124 #631637
Из за новогоднего угара и вакханалии только узнал что вышел PHP7.
И поскольку мне лень вникать.
Дайте мне, пожалуйста, максималистское ревью, что нового и круто ли там?
#125 #631640
>>631637
Новая цифарка
#126 #631678
Так что можно ли в сессию записать, чтобы с каждого айпишника можно было сделать только один лайк или обязательно таблицы со статистикой по лайкам и айпи создавать?
#127 #631680
>>631678
Каким образом ты это в сессию записывать собрался? Ты вообще понимаешь как сессии работают?
#128 #631695
>>631680
вот так берешь и записываешь. все работает.
#129 #631696
>>631695
И что ты собрался записывать в сессию?
#130 #631698
>>631239
http://ideone.com/GC1nHL - не работает.
Вспомни, что означают квадратные кавычки, как ведут себя в них все символы, как действуют символы ?, + и после квадратных кавычек. Это поможет избавиться от конструкции (\\s|\\(|\\)|\\"|-?), например.
Также тут же поймёшь, почему конструкция ([\\s
\\-\\)\\"]) вообще нелепо выглядит
Вот паста ОПа, как минимум, все эти номера должно проверять верно:
----------

Задачу про номера телефонов надо проверить на большом числе телефонов, чтобы убедиться что твой код правильный. Но руками подставлять номера — долго и скучно. Пусть работает робот, а не человек!

Для этого давай добавим в программу тесты, чтобы сразу было видно, верно все работает или нет. Сделай 2 списка номеров (правильные и нет), добавь их в программу и напиши цикл, который их по очереди прогоняет через регулярку и проверяет что они определяются как надо (если нет — надо вывести какой именно номер не распознается правильно).

Вот список номеров:

Правильные: array('84951234567', '+74951234567', '8-495-1-234-567', ' 8 (8122) 56-56-56', '8-911-1234567', '8 (911) 12 345 67', '8-911 12 345 67', '8 (911) - 123 - 45 - 67', '+ 7 999 123 4567', '8 ( 999 ) 1234567', '8 999 123 4567');

Неправильные: array('02', '84951234567 позвать люсю', '849512345', '849512345678',
'8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88',
'84951a234567', '8495123456a',
'+1 234 5678901', // неверный код страны
'+8 234 5678901', // либо 8 либо +7
'7 234 5678901' // нет +
);
#131 #631699
>>631695
А потом сессия обрывается и лайки пропадают?
#132 #631700
>>631696
айди и кол-во лайков и айпи.
#133 #631702
>>631698
Блин, звёздочки всю разметку порушили.
Ну ты там увидишь фрагменты своей регулярки, всё поймёшь, я думаю.
#134 #631703
>>631700
А я возьму и получу новую сессию. И буду так делать когда хочу поставить новый лайк. В итоге накручу себе лайков сколько захочу.
136 Кб, 686x543
#135 #631726
>>629822 (OP)
Сап, чуваки. Извините, если не в тот тред, но у вас в шапке вроде CSS упомянут. У меня пара вопросов по нему, ответы на которые чёт не гуглятся.

1. Что делаете с уродливыми чекбоксами и радио в Firefox-based браузерах? Хочется рамки в 1px и никаких больше теней и обводок. Перепробовал разные варианты. В поиске громадные фидлы с jquery и анимацией.

2. Насколько уместно в глобальном CSS (через Stylish) добавлять проверку на имена/классы? Например чтобы ютуб не ломался от background-color как на прирепленом скрине. Насколько в целом бьёт по производительности? Если есть опыт, пишите браузер. Я на своей пеке с i5 и 8 Gb оперативки совсем перестал понимать эти вещи (не хвастаюсь, кек).
#136 #631735
>>631703
Кстати, поэтому лайки от анонима - дохлый номер априори.
Сессии-то ладно, но и тупо IP можно менять и ставить лайки, скрипт какой-нибудь с проксями.
Если только как-то проверять конфигурацию системы, я даже хз.

Хотя нет. Есть знакомый админ на Питоне, он говорит, что можно тупо воровать данные об аккаунтах в соцсетях. Когда заходишь на страницу и при этом залогинен в какой-нибудь соцсети -система видит тебя и собирает инфу обо всех твоих профилях в соцсетях, чтобы потом продажники донимали тебя ещё и там. Жестоко и по-пидорски, но вот такие дела, такое возможно.
Есть даже какой-то сервис, который траллит тебя тем, что всю инфу о твоих соцсетях выдаёт - чекает, что там у тебя в браузере связано с ними.
Вот по такому можно ещё отслеживать реального юзера, получается. Только сложнота, наверное, я пока до такого не дошёл ещё.
#137 #631740
>>631735

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


А если я выйду из всех соц. сетей и каждый раз буду менять проксю и удалять все сессии? Плюс к этому прикрутить еще смену юзерагента и тогда только капчей можно будет защитить от накрутки (да и то капчу можно через антигейт прогнать, если деньги есть).
#138 #631759
>>631740
А если по конфигу системы?
#139 #631761
>>631740

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


Как раз может быть сигналом для срабатывания условия, при котором лайки перестают засчитываться. Я это и имею в виду.
Хоть в одной соцсети, но юзер зареган обычно. При этом аккаунты на Google или Yandex тоже ведь проверяются.
#140 #631767
>>631243
бамп
ну же анон
#141 #631769
>>631759
Тут уже зависит от способа получения конфига системы. Насколько я знаю, без анальных плагинов на джаве (не джаваскрипте) его нормально не получить.
#142 #631772
>>631769
Тогда >>631761: сигнал для срабатывания условия при накрутке.
#143 #631773
>>631772
Все равно лучше регистрацию сделать, чем такие велосипеды строить.
#144 #631781
>>631703
куки каждый раз чистить будешь?
#145 #631782
#146 #631789
>>631773
Так я думал, что мы говорим только про отдельные анонимные лайки. Что лайки при регистрации - это само собой.
Так-то можно ещё сказать, что тогда проще для накрутки лайков и зарегистрироваться 100500 раз...
Но опять же можно и прочие моменты включать: аккаунты в соцсетях, IP, куки и т.п.
Это так-то болезнь программистов - доводить всё до ситуаций, которые могут и не произойти никогда, при этом не думать о капитальных вещах для пользователей. Аллан Купер об этом пишет хорошо в "Психбольнице...".
#147 #631807
>>631789
Если активность аккаунта нулевая в течение какого-либо периода времени - удалять его и все лайки.
#148 #631812
>>631726
1. http://cssdeck.com/labs/css-checkbox-styles

Иди лучше в /wrk в верстку, там помогут лучше
#149 #631985
>>631035
ОП, я всё-таки сделал это: http://ideone.com/SpWx7K
#150 #631992
>>631985
Я отдельно посчитал баланс кредита (просто не стал отнимать месячный платёж) и ввёл новую переменную olbigation, которая считает не размер кредита, а размер обязательства анона перед банком. Т.е. если у него, к примеру, кредит - 100, а уплатил он 80, то размер обязательства - 20.

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

Таким образом, на последнем этапе вычисленный lastPay заменит месячный платёж анона (5000) - lastPay прибавится к тому, что анон уже заплатил. Итого (схематично):
долг анона - 100;
анон внёс суммарно - 100;
размер обязательств перед банком: 100 - 100 = 0
эхо "$размер обязательства"
71 Кб, 1280x720
#151 #631997
>>631985
>>631992

Блядь, как же я долго дня ебался с этим кодом. Сначала выполнил твою задачу, потом решил немного усложнить с этим нулём и 2,5 дня мозгоебли. Наконец-то победа!
#152 #632007
>>631992
>>631997
Бро, вынужден тебя дважды огорчить: я не ОП хотя и польщён тем, что меня за него приняли и калькулятор считает неправильно...
Там должна сумма всех выплат ($paymentTotal) составить 61270 рублей со многими копейками.

>долг анона - 100;


>анон внёс суммарно - 100;


>размер обязательств перед банком: 100 - 100 = 0


>эхо "$размер обязательства"


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

>Блядь, как же я долго дня ебался с этим кодом.


Я сам почти неделю всех терроризировал в треде, но в итоге решил практически в пару строк.
Обрати внимание на алгоритм вот тут ещё раз: >>631035
Просто отбрось всё и попробуй его реализовать. Тем более, что это и есть алгоритм задачи на самом сайте ОПа, только более развёрнутый.
#154 #632013
>>632011
Ахаха, ты - это я месяц назад...
Я просто даже сон и аппетит потерял в тот момент.
У меня там, правда, сумма почти сразу получилась верная, но уходило в минус, вот я посношался с этим...
После седьмого раза перестал считать, сколько переписывал ВЕСЬ скрипт с нуля, включая error_reporting(-1), блиять.
#155 #632175
https://github.com/MindiMakridi/filehosting исправления по файлообменнику.
#156 #632199
>>629822 (OP)
регулярка исправления по номеру телефона
http://ideone.com/NuO5fo
регулярка тест на граммар наци
http://ideone.com/I2Q3I9
#157 #632214
В задаче про айфон 3% - это процент от начальной суммы 40к или процент от оставшегося долга?
#158 #632218
>>632199
http://ideone.com/jhtZ7c - неправильно показывает некоторые номера. Паста ОПа для проверки: >>631698.

http://ideone.com/MdRvFa - неправильно в некоторых местах. Также почему оставшихся моментов нет? Там много всего помимо этого должно быть.
Также надо показывать как минимум слово до ошибки и слово после - чтобы было понятно, где именно ошибка в тексте. Таковы условия задачи.
#159 #632220
>>632214
Процент от 40к и дальше от того, что остаётся после каждой выплаты.
#160 #632247
>>632218
почувствовал себя студентом которго заебывает препод при принятии лабы.
#161 #632250
>>632247
Что поделать, Десу, но вот такие задачки у ОПа.
Зато потом начинаешь себя чувствовать вполне себе способным на многое.
46 Кб, 600x450
#162 #632254
>>632250

>Зато потом начинаешь себя чувствовать вполне себе способным на многое.


Ненадолго.
#163 #632400
Поясните по поводу Ajax, когда стоит его использовать а когда не стоит? Например в контакте при переходе по вкладкам осуществляется перезагрузка страницы, на многих других сайтах тоже. Почему они не используют Ajax причина кроется в большом количество информации которую выводят такие сайты как контакт, или ещё есть какая-нибудь причина?
#164 #632428
>>632254
Подтверждаю так-то.
Шёл четвёртый день битвы с задачей на числа прописью...
#165 #632510
>>630471
Внешня библиотека не нужна. Из коробки идет встроенный html DOM document. Для парсинга лучше использовать xpath селектор, вместо CSS. Он более гибкий, но может показаться сложнее по началу.

запрос xpath будет типа:
.//table[3]//tr/td

Проверит можно в хроме, через меню разработчика, на панели HTML нажимаешь ctrl+f и вводишь xpath. На мозиле нужно ставить файрбаг + файрпав.
#166 #632515
>>632400
На мой взгляд так.
Если ты выполняешь какое либо действие над элементом на странице, не меняя контекст, то это аякс.
#167 #632520
>>631004
Самое простое: в браузере при открытой менюшке разработчика, при открытой вкладке запросов, отправить эту форму. Пото, правой кнопкой щелкаешь на запрос, и выбираешь "копировать как curl". Все необходимое у тебя теперь в буфере обмена.
Я буду долго тыкать на Submit... #168 #632529
"602" - это "шестьсот две тысячи".
"672" - это "шестьсот семьдесят две тысячи".
"351" - это "триста пятьдесят одна тысяча".
"354" - это "триста пятьдесят четыре тысячи".
"2" - это "две тысячи".
"1" - это "одна тысяча".
"681" - это "шестьсот восемьдесят одна тысяча".
"11" - это "одиннадцать тысяч".
"886" - это "восемьсот восемьдесят шесть тысяч".
"808" - это "восемьсот восемь тысяч".
"110" - это "сто десять тысяч".
"847" - это "восемьсот сорок семь тысяч".
"200" - это "двести тысяч".

Осталось миллионы вот так же разложить и собрать воедино всё. С миллионами должно быть просто, а вот собирать воедино будет непросто.
Для нулей поставлю условие, которое будет проверять, нет ли цифр больше нуля, а затем либо переводить дальше, либо выявлять имеющиеся цифры.
Очень много говнокода, просто очень много говнокода. Я думал, гораздо лучше будет это всё.
Я кода задачу на кредит для Айфона де-е-елал...
#169 #632548
Проверьте Льва Толстого пожалуйста.
http://ideone.com/uimaxJ
#170 #632557
>>631323

>зависть-кун


Прости анончик, я не заходил в тред после того как оставил почту. Можешь оставить свои контакты тоже - я рад любым знакомствам!
#171 #632567
Проверьте задачу по айфону - http://ideone.com/4jT4Ql
#172 #632569
Блять, только что заметил, что в документации для функции implode аргументы стоят не в том порядке в котором я их всегда ставил, но при этом у меня она всегда корректно работала. Как такое может быть?
Можете сами убедиться http://ideone.com/DXVHsD
Ответы за 18-19 января в старом треде #173 #632579
>>628328

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

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

>>628329

На гитхабе написано: скачать полный пакет + подключить autoload из папки vendor. Зачем ты свои способы изобретаешь? В других туториалах очевидно предполагается что ты его ставил через композер, потому и код другой. Возможно даже тебе надо подключить 2 файла автолад: один из папки вендор, другой как в примере.

Если это не поможет то надо лезть в код и разбираться.

>>628393

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

>>628490

ВО-первых, ты зря испольузешь левые сборки вместо оригинальных программ, ведь в этом случае никто не гарантирует работоспособность и совместимость. Да и теряешь ценный опыт возни с конфигами. Во-вторых, как ты открываешь консоль? Через меню опенсервера? В нем по моему своя, отдельная консоль и команды в обычной консоли вводить бесполезно - там нет некоторых переменных окружения.
Ответы за 18-19 https://github.com/nsdvw/PreviewGenerator #174 #632580
>>628521

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

АПИ адаптера не очень удачное:

> merge($background, $overlay, $left, $top, $opacity = 100);


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

> public function getWidth($image);


> public function getHeight($image);


> public function resizeDown($image, $width = null, $height = null);


У тебя нет ощущения что логичнее было бы так:

$image->getWidth();
$image->getHeight();
$image->resizeDown(....);

Но это не самое важное, самое важное - это вопрос:

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

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

Ну и это наверно не совсем по теме, но почитай (если ты еще не читал) статью про выпечку хлеба: https://habrahabr.ru/post/153225/ (хотя там по моему сломались картинки)

Алсо придерусь немного к английскому, в порядке исключения:

> add to your ... next code:


add the following code to your ...

В общем пока мое мнение: не нужно, надо просто сделать в проекте класс который будет вызывать WideImage с требуемыми настройками. Если это виджет с неизвестными заранее размерами то эти размеры надо сделать свойствами виджета и передавать ниже лежащей библиотеке. Зачем может понадобиться использовать несколько библиотек для уменьшения картинок, мне неясно.
Ответы за 18-19 https://github.com/nsdvw/PreviewGenerator #174 #632580
>>628521

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

АПИ адаптера не очень удачное:

> merge($background, $overlay, $left, $top, $opacity = 100);


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

> public function getWidth($image);


> public function getHeight($image);


> public function resizeDown($image, $width = null, $height = null);


У тебя нет ощущения что логичнее было бы так:

$image->getWidth();
$image->getHeight();
$image->resizeDown(....);

Но это не самое важное, самое важное - это вопрос:

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

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

Ну и это наверно не совсем по теме, но почитай (если ты еще не читал) статью про выпечку хлеба: https://habrahabr.ru/post/153225/ (хотя там по моему сломались картинки)

Алсо придерусь немного к английскому, в порядке исключения:

> add to your ... next code:


add the following code to your ...

В общем пока мое мнение: не нужно, надо просто сделать в проекте класс который будет вызывать WideImage с требуемыми настройками. Если это виджет с неизвестными заранее размерами то эти размеры надо сделать свойствами виджета и передавать ниже лежащей библиотеке. Зачем может понадобиться использовать несколько библиотек для уменьшения картинок, мне неясно.
Ответы за 18-19 января старый тред #175 #632581
>>628558

Попробуй порешать наши задачи, показывать решения, исправлять замечания - я уверен, что будет прогресс. Тем более что ты не совсем начинающий, тебе легче чем другим. Вуз вузу рознь, если тебя интересуют информационные технологии, то надо искать такие программы: https://park.mail.ru/pages/index/ или например ШАД Яндекса. Ну и есть большая разница, сдавать зачеты или сидеть разбираться в заданиях.

>>628704

Названия неудачные и затрудняют чтение кода.

$totalAr -> $girls, $positions (и не пиши слово array в названии переменной, и тем более не сокращай его)
$e -> $number, $current
as $k => $v -> $key => $position

Заполнение массива проще сделать функцией range (или хотя бы циклом for).

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

>>628710

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

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

>>628770

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

>>628775

> w1: https://ideone.com/sgIZfu


Все правильно!

> w2: https://ideone.com/DBu62z


Верно.

> w3: https://ideone.com/7hEeAu


Тут тоже верно.

> w4: https://ideone.com/rdAHwD


Верно, но тут

> $anonDice1 + $anonDice2) > ($compDice1 + $compDice2))


можно было использовать compSum/anonSum, и иф принято писать с маленькой букв.

>>628800

Молодец, верно.
Ответы за 18-19 января старый тред #175 #632581
>>628558

Попробуй порешать наши задачи, показывать решения, исправлять замечания - я уверен, что будет прогресс. Тем более что ты не совсем начинающий, тебе легче чем другим. Вуз вузу рознь, если тебя интересуют информационные технологии, то надо искать такие программы: https://park.mail.ru/pages/index/ или например ШАД Яндекса. Ну и есть большая разница, сдавать зачеты или сидеть разбираться в заданиях.

>>628704

Названия неудачные и затрудняют чтение кода.

$totalAr -> $girls, $positions (и не пиши слово array в названии переменной, и тем более не сокращай его)
$e -> $number, $current
as $k => $v -> $key => $position

Заполнение массива проще сделать функцией range (или хотя бы циклом for).

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

>>628710

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

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

>>628770

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

>>628775

> w1: https://ideone.com/sgIZfu


Все правильно!

> w2: https://ideone.com/DBu62z


Верно.

> w3: https://ideone.com/7hEeAu


Тут тоже верно.

> w4: https://ideone.com/rdAHwD


Верно, но тут

> $anonDice1 + $anonDice2) > ($compDice1 + $compDice2))


можно было использовать compSum/anonSum, и иф принято писать с маленькой букв.

>>628800

Молодец, верно.
18-19 января старый тред #176 #632582
>>628812

О, интересно, но можно улучшить код:

> elseif ($height == $anonHeight) {


Лучше просто else без условия

> foreach ($ending as $keys => $value){


> foreach ($value as $i => $o) {


Какие плохие и нечитаемые имена переменных:

keys -> word
value -> digits
o -> digit
as $i -> убрать

Да и код трудно понять. Такие вещи обычео пишут через операцию деления с остатком:

if ($x % 10 == 1) ...

Ну и алгоритм неверный, твой код для числа 12 напишет "12 человека". Числа от 11 до 19 идут как исключение (видимо древнию люди умели считать только до 20).

А еще, не хочешь число человек через array_filter? Это тоже интересно будет, если ты конечно знаешь анонимные функции.

>>628913

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

>>628914

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

>>628977

Решение покажешь?
18-19 января старый тред #176 #632582
>>628812

О, интересно, но можно улучшить код:

> elseif ($height == $anonHeight) {


Лучше просто else без условия

> foreach ($ending as $keys => $value){


> foreach ($value as $i => $o) {


Какие плохие и нечитаемые имена переменных:

keys -> word
value -> digits
o -> digit
as $i -> убрать

Да и код трудно понять. Такие вещи обычео пишут через операцию деления с остатком:

if ($x % 10 == 1) ...

Ну и алгоритм неверный, твой код для числа 12 напишет "12 человека". Числа от 11 до 19 идут как исключение (видимо древнию люди умели считать только до 20).

А еще, не хочешь число человек через array_filter? Это тоже интересно будет, если ты конечно знаешь анонимные функции.

>>628913

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

>>628914

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

>>628977

Решение покажешь?
https://github.com/foobar1643/student-list #177 #632583
>>629061

Файлы names/surnames лучше убрать в папку, например data.

> name text NOT NULL,


> surname text NOT NULL,


Тут надо varchar с разумным ограничением длины. Тебе надо прочитать в мануале главу про типы колонок (всю!) и выучить названия не менее 5 разных типов (INT и BIGINT считаются за один). Также, ответь на вопрос, в чем разница между REAL и NUMERIC? Где может пригодиться нумерик? Какой тип использовать для хранения телефонного номера? Номера паспорта?

> status text NOT NULL,


> gender text NOT NULL,


Тут нужен enum (который судя по документации в постгрессе даже лучше чем в майскул: http://www.postgresql.org/docs/9.1/static/datatype-enum.html , перевод http://postgresql.ru.net/manual/datatype-enum.html )

> sgroup text NOT NULL,


> email text NOT NULL,


варчар нужен

> byear text NOT NULL,


В майскул есть тип YEAR, а в пострес нужен либо инт, либо децимал (для него можно задать длину).

Также, в постргресе есть очень крутая штука, ограничение на значение поля CHECK: http://postgresql.ru.net/manual/ddl-constraints.html#AEN2554

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

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

> CREATE TABLE tokens (


А почему отдельной таблицей? И почему нет внешнего ключа? И почему ид текстом?

Также, я вижу ты не очень знаешь SQL, советую порешать задачи на него из ОП-поста.

> CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;


> REVOKE ALL ON SCHEMA public FROM PUBLIC;


> REVOKE ALL ON SCHEMA public FROM postgres;


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

https://github.com/foobar1643/student-list/blob/master/public/design/template/form.html
Это не должно быть в публичной папке, так как это код, не предназначеннный для вызова пользователем напрямую.

https://github.com/foobar1643/student-list/blob/master/app/AutoLoader.php
Не надо копипастить, копипаста - зло, сделай список путей в массиве, и их перебор в автозагрузчике. Более того, если указать эти папки в include_path то можно использовать встроенный в пхп автозагрузчик spl_autoload (детали в мануале).

А лучше конечно освой неймспейсы, урок https://github.com/codedokode/pasta/blob/master/php/autoload.md

> https://github.com/foobar1643/student-list/blob/master/app/AppCore.php#L11


> $this->view_settings = new stdClass();


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

> } catch(PDOException $e) {


> print("Database connection error. " . $e->getMessage()


Неправильная работа с исклчениями. ВОт паста.

--------

Как надо обрабатывать исключения:

- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс

Как сделано у тебя:

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

Как будет если просто не ловить исключение:

- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)

Но даже так лучше чем твой вариант.

Почитай также урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

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

Неправильно что ты создаешь PDO в контроллере. Заечм он там? Его надо создавать например в файле bootstrap.php одитн раз и использовать для создания классов работающих с БД. А ты в каждом контроллере создаешь свой ПДО.

Название странное AppCore. Что еще за коре? Это базовый класс контродлера, ControllerBase.

> protected $connection_error;


Зачем поле? Зачем хранить строку с ошибкой?

> $this->view_settings->page_data = new stdClass();


> $this->view_settings->error = array();


> $this->view_settings->page_data->student = array();


Не очень понятно зачем это. Например зачем в базовом классе создавать поле student - он нужен на всех страницах? И что значит page_data? Название ничего не говорит мне.

> https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerIndex.php


> private $pager;


> private $total_pages;


> private $offset;


> private $sorting_pattern;


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

> process_get_request


У нас в пхп в рекомендации PSR принято функции и переменные именовать кемел кейсом: processGetRequest()

> if($get_data['page']


А если нет гет-параметра page то мы получаем ошибку доступа к несуществующему элементу массива? У тебя включено отображения ошибок? Ты видишь, что они есть? Если нет, выставь error_reporting = -1, display_errors = On в php.ini у себя локально.

> $index = array_search($get_data['sort'], $this->sorting_patterns);


> if($this->sorting_patterns[$index]) {


Тут нужен in_array()

Также, не вижу смысла разделять контроллер на process_get_request и run, так как непонятно по какому принципу код разделен на 2 части. Лучше сделать одну функцию.

https://github.com/foobar1643/student-list/blob/master/app/View/ViewIndex.php
Не очень понятен смысл этого класса, не проще ли этот код поместить в контроллер?

https://github.com/foobar1643/student-list/blob/master/app/AppConfig.php
Конфиг лучше сделать обычным php- или ini-файлом:

$config['x'] = 1;

или

[db]
host=localhost
username = 1

https://github.com/foobar1643/student-list/blob/master/public/design/template/form.html#L2

> Проверьте правильность вводимых данных и попробуйте еще раз.


А где текст ошибки?

https://github.com/foobar1643/student-list/blob/master/public/design/template/form.html#L23
Вместо print надо использовать <?= ... ?>. Также, нужна защита от XSS (htmlspecialchars). У меня есть урок. Также нужна клиентская HTML5 валидация.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L28

> $this->student->name = $this->form_validator->process_field($post_data["name_field"]);



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

Работу с авторизацией и токенами надо вынести в отдельный класс.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L43

> header("Location: form.php?notify=success"); /


После этого не надо выводить страницу. Ее все равно никто не увидит.
https://github.com/foobar1643/student-list #177 #632583
>>629061

Файлы names/surnames лучше убрать в папку, например data.

> name text NOT NULL,


> surname text NOT NULL,


Тут надо varchar с разумным ограничением длины. Тебе надо прочитать в мануале главу про типы колонок (всю!) и выучить названия не менее 5 разных типов (INT и BIGINT считаются за один). Также, ответь на вопрос, в чем разница между REAL и NUMERIC? Где может пригодиться нумерик? Какой тип использовать для хранения телефонного номера? Номера паспорта?

> status text NOT NULL,


> gender text NOT NULL,


Тут нужен enum (который судя по документации в постгрессе даже лучше чем в майскул: http://www.postgresql.org/docs/9.1/static/datatype-enum.html , перевод http://postgresql.ru.net/manual/datatype-enum.html )

> sgroup text NOT NULL,


> email text NOT NULL,


варчар нужен

> byear text NOT NULL,


В майскул есть тип YEAR, а в пострес нужен либо инт, либо децимал (для него можно задать длину).

Также, в постргресе есть очень крутая штука, ограничение на значение поля CHECK: http://postgresql.ru.net/manual/ddl-constraints.html#AEN2554

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

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

> CREATE TABLE tokens (


А почему отдельной таблицей? И почему нет внешнего ключа? И почему ид текстом?

Также, я вижу ты не очень знаешь SQL, советую порешать задачи на него из ОП-поста.

> CREATE EXTENSION IF NOT EXISTS plpgsql WITH SCHEMA pg_catalog;


> REVOKE ALL ON SCHEMA public FROM PUBLIC;


> REVOKE ALL ON SCHEMA public FROM postgres;


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

https://github.com/foobar1643/student-list/blob/master/public/design/template/form.html
Это не должно быть в публичной папке, так как это код, не предназначеннный для вызова пользователем напрямую.

https://github.com/foobar1643/student-list/blob/master/app/AutoLoader.php
Не надо копипастить, копипаста - зло, сделай список путей в массиве, и их перебор в автозагрузчике. Более того, если указать эти папки в include_path то можно использовать встроенный в пхп автозагрузчик spl_autoload (детали в мануале).

А лучше конечно освой неймспейсы, урок https://github.com/codedokode/pasta/blob/master/php/autoload.md

> https://github.com/foobar1643/student-list/blob/master/app/AppCore.php#L11


> $this->view_settings = new stdClass();


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

> } catch(PDOException $e) {


> print("Database connection error. " . $e->getMessage()


Неправильная работа с исклчениями. ВОт паста.

--------

Как надо обрабатывать исключения:

- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс

Как сделано у тебя:

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

Как будет если просто не ловить исключение:

- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)

Но даже так лучше чем твой вариант.

Почитай также урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

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

Неправильно что ты создаешь PDO в контроллере. Заечм он там? Его надо создавать например в файле bootstrap.php одитн раз и использовать для создания классов работающих с БД. А ты в каждом контроллере создаешь свой ПДО.

Название странное AppCore. Что еще за коре? Это базовый класс контродлера, ControllerBase.

> protected $connection_error;


Зачем поле? Зачем хранить строку с ошибкой?

> $this->view_settings->page_data = new stdClass();


> $this->view_settings->error = array();


> $this->view_settings->page_data->student = array();


Не очень понятно зачем это. Например зачем в базовом классе создавать поле student - он нужен на всех страницах? И что значит page_data? Название ничего не говорит мне.

> https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerIndex.php


> private $pager;


> private $total_pages;


> private $offset;


> private $sorting_pattern;


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

> process_get_request


У нас в пхп в рекомендации PSR принято функции и переменные именовать кемел кейсом: processGetRequest()

> if($get_data['page']


А если нет гет-параметра page то мы получаем ошибку доступа к несуществующему элементу массива? У тебя включено отображения ошибок? Ты видишь, что они есть? Если нет, выставь error_reporting = -1, display_errors = On в php.ini у себя локально.

> $index = array_search($get_data['sort'], $this->sorting_patterns);


> if($this->sorting_patterns[$index]) {


Тут нужен in_array()

Также, не вижу смысла разделять контроллер на process_get_request и run, так как непонятно по какому принципу код разделен на 2 части. Лучше сделать одну функцию.

https://github.com/foobar1643/student-list/blob/master/app/View/ViewIndex.php
Не очень понятен смысл этого класса, не проще ли этот код поместить в контроллер?

https://github.com/foobar1643/student-list/blob/master/app/AppConfig.php
Конфиг лучше сделать обычным php- или ini-файлом:

$config['x'] = 1;

или

[db]
host=localhost
username = 1

https://github.com/foobar1643/student-list/blob/master/public/design/template/form.html#L2

> Проверьте правильность вводимых данных и попробуйте еще раз.


А где текст ошибки?

https://github.com/foobar1643/student-list/blob/master/public/design/template/form.html#L23
Вместо print надо использовать <?= ... ?>. Также, нужна защита от XSS (htmlspecialchars). У меня есть урок. Также нужна клиентская HTML5 валидация.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L28

> $this->student->name = $this->form_validator->process_field($post_data["name_field"]);



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

Работу с авторизацией и токенами надо вынести в отдельный класс.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L43

> header("Location: form.php?notify=success"); /


После этого не надо выводить страницу. Ее все равно никто не увидит.
#178 #632584
>>629822 (OP)
Бля, это та картинка, где она говорит: "Ну как, в очках я выгляжу умной?))". Как раз та причина, по которой я не хочу линзы, а люблю очки))
18-19 января #179 #632586
>>629116

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

>>629158

Не, надо знать раза в 2-3 боьше чем ты перечислил, ветки еще, мерджи, конфликты, пул/пуш. Советую почитать git-book, есть на русском и там достаточно просто все.

>>629279

Для этого надо знать языки HTML, CSS, JS, PHP, работу с базой данных. Довольно много знаний надо.

> посоветовали бесплатное амазноновское хранилище.


Оно не бесплатное. Особенно с нынешним-то курсом.

>>629285

> private function chooseProfession($post) {


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

> public function countTotalSalary($qty, $rank, $post, $boss) {


Это не очень правльная функция, должно быть так:

public function countTotalSalary() { ... }

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

> abstract class Employee extends Department {


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

У тебя же неправильно: Сотрудник это не разновидност Департамента, значит наследование использовать так нельзя.

> class Manager extends Employee {


> protected function countSalary() {


Ты скопипастил тут код 4 раза.

>>629306

Будем считать этот косяк ОПа тестом на сообразительность.
18-19 января #179 #632586
>>629116

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

>>629158

Не, надо знать раза в 2-3 боьше чем ты перечислил, ветки еще, мерджи, конфликты, пул/пуш. Советую почитать git-book, есть на русском и там достаточно просто все.

>>629279

Для этого надо знать языки HTML, CSS, JS, PHP, работу с базой данных. Довольно много знаний надо.

> посоветовали бесплатное амазноновское хранилище.


Оно не бесплатное. Особенно с нынешним-то курсом.

>>629285

> private function chooseProfession($post) {


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

> public function countTotalSalary($qty, $rank, $post, $boss) {


Это не очень правльная функция, должно быть так:

public function countTotalSalary() { ... }

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

> abstract class Employee extends Department {


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

У тебя же неправильно: Сотрудник это не разновидност Департамента, значит наследование использовать так нельзя.

> class Manager extends Employee {


> protected function countSalary() {


Ты скопипастил тут код 4 раза.

>>629306

Будем считать этот косяк ОПа тестом на сообразительность.
#180 #632588
>>632584

Та :3
20 Кб, 604x477
#181 #632594
>>629061

Первый файл открыл и сразу ахуел. Что у тебя кол-во элементов на странице в КОНФИГЕ ДБ делает, дурень?
Этот параметр должен быть в классе Pager.
40 Кб, 419x419
#182 #632595
Четвертый год безработный, юбилейный, рейт авку.
#183 #632596
>>632595
У мамки на шее сидишь?
#184 #632597
Так писать легально?
$dsn = AppConfig::db_type . ":dbname=" . AppConfig::db_name . ";host=" . AppConfig::db_host; //"pgsql:dbname=students;host=127.0.0.1"
try {
$this->pdo = new PDO($dsn, AppConfig::db_user, AppConfig::db_pswd);
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
print("Database connection error. " . $e->getMessage());
exit();
}
#185 #632598
>>632597
Нет, мне ОП уже пояснил за исключения. Это >>632594 тоже переделаю.
#186 #632600
>>629061
И класс работы с бд должен лежать отдельно и называться Data Mapper, а не в вперемешку с моделями. И что там за работа с файлом тхт, зачем это?
Вот в этот лучше массив записать, а не повторять, как быдлокодер. И зачем ты exit() везде пишешь? лол, нуб.

$this->student->id = $this->form_validator->process_field($post_data["id_field"]);
$this->student->name = $this->form_validator->process_field($post_data["name_field"]);
$this->student->surname = $this->form_validator->process_field($post_data["surname_field"]);
$this->student->gender = $this->form_validator->process_field($post_data["gender_field"]);
$this->student->group = $this->form_validator->process_field($post_data["group_field"]);
$this->student->email = $this->form_validator->process_field($post_data["email_field"]);
$this->student->byear = $this->form_validator->process_field($post_data["byear_field"]);
$this->student->status = $this->form_validator->process_field($post_data["status_field"]);
$this->student->rating = $this->form_validator->process_field($post_data["rating_field"]);

И кто так пишет? не нужно столько вложенных методов или что там.
$this->view_settings->page_data->next_page
#187 #632601
>>632597

>$dsn = AppConfig::db_type . ":dbname=" . AppConfig::db_name . ";host=" . AppConfig::db_host; //"pgsql:dbname=students;host=127.0.0.1"


>try {


>$this->pdo = new PDO($dsn, AppConfig::db_user, AppConfig::db_pswd);



Я про это.
#188 #632605
>>632594

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

>>632597

Не, лучше не использовать класс для конфига. Ведь по идее конфиг предназначен для не-программистов и стоит испольозовать что-то попроще, например ini, xml, json, yml, на худой конец пхп файл с переменными. Идея конфига чтобы вынести настройки из кода. А тут они и не вынесены.

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

>>632600

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

Ну и это первая попытка анона, так что это нормально. И не надо резкие выражения использовать.
#189 #632608
>>631812

Нет, мы тоже поможем.

>>631726

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

> 2. Насколько уместно в глобальном CSS (через Stylish) добавлять проверку на имена/классы? Например чтобы ютуб не ломался от background-color как на прирепленом скрине.


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

> Насколько в целом бьёт по производительности? Если есть опыт, пишите браузер


Не знаю, надо делать измерения (например сравнивать время и потребление памяти со стилями и без или с плагином и без). Вообще, по моим ощущениям фаерфакс сам по себе не очень быстрый, а с расширениями и того медленнее.
#190 #632610
>>632600

>И класс работы с бд должен лежать отдельно


Сделаю.

>и называться Data Mapper


В условии задачи не DataMapper, а TableDataGateway

>И что там за работа с файлом тхт, зачем это?


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

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


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

>И зачем ты exit() везде пишешь?


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

Спасибо за помощь.
#191 #632644
Добрый день, в вебаче не спрашиваю, там .5 анона сидит и те проходят мимо. Есть инет-магазин и есть стандартный шаблон сверстанный на основе бутстраповской сетки opencart, так вот, как задать сайту минимальную ширину при сохранении адаптивности? (с 1300 до 850 будет адаптивность, до 850 просто скролл бар и элементы перестают прыгать, двигаться, уменьшаться/увеличиваться)? Пока что этого достичь не вышло, при указании min-width 850, всё равно всякие xs, lg, sm в зависимости от бутстраповских медиа - изменяют свои свойства. Помогай, пхпач.
#192 #632646
Нашёл свой говнокод написанный в далёком 2007.
http://pastebin.com/Nb3nztp9
#193 #632651
Антоны поясните сколько в среднем времени уйдёт вкатиться в Junior PHP Developer'ы. Полгода-Год?
#194 #632654
>>632651
Зависит от человека, есть такие, что дропают по 20 раз в процессе и потом наверстывают, есть такие что не от фрустрации бросают вовсе.
#195 #632655
>>632651
Зависит от твоих текущих знаний. Список необходимых технологий для джуниора можно задрочить и за три месяца (это если ты вообще ничего не знаешь), если ты каждый день по 8 - 10 часов будешь учить. А если размазать на 3 часа в день + выходные, тогда полгода-год, да.
#196 #632656
>>632654

>что от фрустрации


selffix
#197 #632660
>>632654
>>632655
Баловался в этом треде сам сисадмин, не так давно, дошел до "Бонусные задачки", калькулятор и числа прописью написал без особого труда и съебался админить, сейчас администов в конец доебало. Сколько там последний срок по возрасту последний шанс вкатиться? 22 мне
#198 #632661
>>632660

>Сколько там последний срок по возрасту последний шанс вкатиться?


Такого нет. Я знал людей которые в 27 - 28 начинали джуниорами работать. Им уже за 30, один стал тимлидом, другой синьером в каком-то Московском бодишопе.

Успех уровня /pr/, ага.
#199 #632662
>>632660

>долбоёб может стать девопсом


>нет, не хочу, хочу шаблоны на жоомлу за 40к натягивать

#200 #632663
>>632662
В этом то и по сути основная проблема. Буду гнаться за двумя зайцами, потом на одного забью.
#201 #632664
>>632660
Я бы хоть админом пошел бы. Что там знать надо для сисадмина, линукс?
#202 #632665
>>632664
ОФИС НАСТРОИТЬ
ВИРУСЫ УБРАТЬ
АДИНЭС НЕ РАБОТАЕТ
#203 #632666
>>632664
В зависимости от того, что админишь - линукс или серверную венду.
Энивей, вангую что поциент сверху - типичный втыкатель мышек.
#204 #632669
>>632660
Ты это, не бухти, тут и люди с похуже данными входными есть, а ты сразу "поздно".

25-лвл, экономист-кун
#205 #632670
>>632669
Двачую.

охранник-кун
#206 #632672
>>632605
Вот же у него прямо в валидаторе метод работы с ДБ запихан, никакого принципа солид.
https://github.com/foobar1643/student-list/blob/master/app/FormValidator.php
#207 #632673
>>632670
>>632669
Поддвачну
бомж-нелегал-кун
#208 #632675
>>632665
В местных вакансиях написано, что чуть ли не телефонию надо уметь прокладывать, чинить оргтехнику и знать TCP-протоколы. Я один раз звонил, спросили: как вы будете работать сисадмином, если у вас опыта нет?
#209 #632676
>>632675
Так надо было сказать что опыт есть. А потом уже по ходу дела научился бы телефонию прокладывать и чиить оргтехнику.
#210 #632679
>>632673
поддвачну
гейшлюха
#211 #632681
>>632610

>= $this->form_validator->process_field($post_data["id_field"]);


А что это вообще обозначает? Это ты так пост запрос принял что ли? конструкция прост слишком длинная, выглядит некрасиво. Для валидации лучше передавать данные массивом или через экземпляр класса.
#212 #632688
>>632605
У меня вот такой класс для PDO.

class Db {
private static $instance = null;
public static function get()
{
if(self::$instance == null)
{
try
{
self::$instance = new PDO('mysql:host=localhost;dbname=guestbook;charset=utf8', 'root', '');
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
return self::$instance;
}
}

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

AppConfig::db_type . ":dbname=" . AppConfig::db_name . ";host=" . AppConfig::db_host;
#212 #632688
>>632605
У меня вот такой класс для PDO.

class Db {
private static $instance = null;
public static function get()
{
if(self::$instance == null)
{
try
{
self::$instance = new PDO('mysql:host=localhost;dbname=guestbook;charset=utf8', 'root', '');
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
echo $e->getMessage();
}
}
return self::$instance;
}
}

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

AppConfig::db_type . ":dbname=" . AppConfig::db_name . ";host=" . AppConfig::db_host;
13 задача #213 #632704
#214 #632709
>>632688

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


Нет. ОП выше писал что константами хранить не стоит. Конфиг должен быть в .ini, .txt или в крайнем случае в php формате ($config['x'] = y), чтобы любой не программист смог легко отредактировать данные.
#215 #632732
>>632580

> какой смысл делать библиотеку работы с картинками заменяемой


Чтобы иметь возможность заменить одну библиотеку для работы с графикой на другую.
Может она устареет через 3-4 года? Может мне ночальники без аргументации прикажут "WideImage говно, юзай Imagine" (хотя такая ситуация ближе сосачу а не IRL).
В приложении мне понадобится поменять одну строчку кода (заменить new WideImageAdapter на другой), плюс дописать эту обертку-адаптер, если она еще не включена в основной пакет, а она скорее всего будет включена.

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

>У тебя нет ощущения что логичнее было бы так:


>$image->getWidth();


>вместо


>$adapter->getWidth($image)


Нет такого ощущения. Я не знаком с другими графическими библиотеками, но там этот метод может называться по-другому, или принадлежать другому объекту, не $image.
В конце концов в качестве $image можно использовать вовсе не объект, а ресурс. Тогда getWidth адаптера будет вызывать уже не метод объекта, а функцию типа imagesx.

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

>зачем это нужно


Чтобы попрактиковать ооп.

Посмотри еще верстку
https://jsfiddle.net/tLwp60qh/3/
похоже на 8 задание. Во всяком случае я использовал тот же трюк с большим левым полем-паддингом и отрицательным марджином для превью.
Семантичны ли теги типа strong/small, или использовать css для этих целей? Уместно ли абсолютное позиционирование, или это дурной тон (мало ли)?
#216 #632746
>>632582

>Решение покажешь?


Обязательно!
Но у меня пока три разных решения: для первых 999 с возвратом "рублей", для тысяч с возвратом "тысяч" и для миллионов с возвратом "миллионов".
Сейчас вот думаю, как всё соединить. Но это уже не так всё сложно, хотя код разросся катастрофически. Чую - ругать и поносить последними словами меня будешь...
Вообще изначально неправильно начал делать через преобразование числа в строку и подсчёт количества символов в ней.
Куча повторяющегося кода, который, правда, убрал в функции, куча условий - можно запутаться. Ты, братишка-ОП, такое не одобряешь. Но я часто сначала делаю говнокодом, а потом преобразую в более-менее человеческое.
На первом же часу работы над задачей понял, что решать её надо делением чисел на 10, 100, 1000 - и так до 100 миллионов с последующим округлением, однако продолжил именно с преобразованием в строку.
Потом попробую и так.
Я никуда не тороплюсь, мне это нравится.
Я вообще забалдел от самого твоего учебника, не хочу ничего пропускать.
#217 #632748
>>632644
Бамп вопросу, есть ли общее какое-нибудь решение?
#218 #632764
#219 #632896
>>632644

1) Ксс в бутстрапе генерируется по моему из ЛЕСС файла. Измени исходники и скомпилируй свою версию бутстрапа, с нужными тебе параметрами сетки.

2) поиграй с параметрами теги meta viewport, может там модно задать минимальную ширину вьюпорта. Но то что ты делаешь это глупость так как при адаптивной верстке сайт должен работать на любой ширине страницы, а ты фактически для пользователей смартфонов и вертикальных планшетов делаешь сайт не адаптивным.
#220 #632906
>>632672

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

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

Что касается валидатора, это анон перепутал, он функцию экранирования спецсимволов в хтмл (htmlspecialchars) вызывает не в шаблоне, а в контроллере. Еще и назвал неудачно, "process_field" вместо escapeHtmlCharacters, и объединил с полезными функциями trim/strval (которые как раз вызываются из контроллера). Не беда, многие начинающие делают такую ошибку, и что хуже, в некоторых курсах советуют так делать. Вот паста с описанием уязвимости XSS и как с ней бороться:

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

Ну и урок про работу с формами тоже может пригодится: https://github.com/codedokode/pasta/blob/master/forms.md
#221 #632909
>>632688

А объясни, в чем смысл твоего класса? Я вижу, что он использует ПДО, а какие возможности он к нему добавляет? Зачем нужен этот твой класс? Нельзя ли объект ПДО напрямую использовать без него?
#222 #632953
>>632732

> Может она устареет через 3-4 года


Ну поменяешь код в своем классе. Может устареет, а может и нет. Да и даже если она устареет, она ведь по-прежнему будет уменьшать картинки.

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

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

Главные проблемы такие:

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

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

Ну и погуглить, может же что-то такое есть.

> В конце концов в качестве $image можно использовать вовсе не объект, а ресурс. Тогда getWidth адаптера будет вызывать уже не метод объекта, а функцию типа imagesx.


Это потому что у тебя в базовом классе не указан тип, возвращемый функцией load. Укажи его, и ресурс уже вернуть будет нельзя. Конечно, до PHP7 указывать тип возврата нельзя, но семерка уже выпущена, да и в "правильном" ООП этот тип должен быть определен, пусть даже через phpDoc.

ИЗображение тут явно выглядит как объект. Я считаю, ради ресурсов отказываться от ООП подхода неправильно. Проще ресурс обернуть в класс и тогда на нем тоже можно будет делать $image->getWidth(). А передавать $image в каждый метод как раз напоминает больше процедурный, а не ООП подход.

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


Да. Потому что там не прописано никаких фреймворкоспецифичных настроек, и код сделан универсально. И тоже куча адаптеров, кстати.
#222 #632953
>>632732

> Может она устареет через 3-4 года


Ну поменяешь код в своем классе. Может устареет, а может и нет. Да и даже если она устареет, она ведь по-прежнему будет уменьшать картинки.

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

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

Главные проблемы такие:

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

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

Ну и погуглить, может же что-то такое есть.

> В конце концов в качестве $image можно использовать вовсе не объект, а ресурс. Тогда getWidth адаптера будет вызывать уже не метод объекта, а функцию типа imagesx.


Это потому что у тебя в базовом классе не указан тип, возвращемый функцией load. Укажи его, и ресурс уже вернуть будет нельзя. Конечно, до PHP7 указывать тип возврата нельзя, но семерка уже выпущена, да и в "правильном" ООП этот тип должен быть определен, пусть даже через phpDoc.

ИЗображение тут явно выглядит как объект. Я считаю, ради ресурсов отказываться от ООП подхода неправильно. Проще ресурс обернуть в класс и тогда на нем тоже можно будет делать $image->getWidth(). А передавать $image в каждый метод как раз напоминает больше процедурный, а не ООП подход.

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


Да. Потому что там не прописано никаких фреймворкоспецифичных настроек, и код сделан универсально. И тоже куча адаптеров, кстати.
#223 #632982
>>632732

> <div><strong>Moscow</strong></div>


Такие ошибки:

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

<div class="offer offer__special">
<img class="offer-image" src alt>
<div class="offer-city">Москва</div>
<div class="offer-price">100 Тугр.</div>
</div>

Смотри как логично: есть блок предложения (причем не обычного, а special), в нем есть картинка, город и цена. Прекрасная разметка!

Это семантично:

<ul class="main-menu">
<li><a href>Первый урок</a></li>
...
</ul>

Это в общем тоже:

Переменная <var>$x</var> равна 10, потому код <code>echo $x;</code> выведет <samp>10</samp>.

Это несемантично:

<div class="blue-text">Москва</div>
Переменная <span class="monospace-font">$x</span>

Так как тут в разметку закладывается внешний вид (но такое все равно бывает на практике, например классы вроде margin-top-10 или width-100, но лучше этого избегать).

Это неправильное использование тега:

Переменная <pre>$x</pre>

Советую найти и прочесть список HTML5 тегов (что они обозначают). Учить наизусть не надо. Также советую прочитать про систему именования классов БЭМ от Яндекса.

Для разметки даты и времени есть тег time.

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

div без класса это очень плохо так как непонятно, что он значит? div и span это универсальные блочный и строчный теги и без атрибутов они ничего не значат.

Теперь по CSS

> .price {


> position: absolute;


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

Также нужен тест где в блоке есть длинное описание, по высоте больше чем высота картинки. И тест что будет если убрать картинку (не наедет ли цена на город?).

Пока решение требует доработки. Пока все плохо.

А, и еще, бросается в глаза:

> 123$


или $123 или 123 долл.
#223 #632982
>>632732

> <div><strong>Moscow</strong></div>


Такие ошибки:

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

<div class="offer offer__special">
<img class="offer-image" src alt>
<div class="offer-city">Москва</div>
<div class="offer-price">100 Тугр.</div>
</div>

Смотри как логично: есть блок предложения (причем не обычного, а special), в нем есть картинка, город и цена. Прекрасная разметка!

Это семантично:

<ul class="main-menu">
<li><a href>Первый урок</a></li>
...
</ul>

Это в общем тоже:

Переменная <var>$x</var> равна 10, потому код <code>echo $x;</code> выведет <samp>10</samp>.

Это несемантично:

<div class="blue-text">Москва</div>
Переменная <span class="monospace-font">$x</span>

Так как тут в разметку закладывается внешний вид (но такое все равно бывает на практике, например классы вроде margin-top-10 или width-100, но лучше этого избегать).

Это неправильное использование тега:

Переменная <pre>$x</pre>

Советую найти и прочесть список HTML5 тегов (что они обозначают). Учить наизусть не надо. Также советую прочитать про систему именования классов БЭМ от Яндекса.

Для разметки даты и времени есть тег time.

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

div без класса это очень плохо так как непонятно, что он значит? div и span это универсальные блочный и строчный теги и без атрибутов они ничего не значат.

Теперь по CSS

> .price {


> position: absolute;


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

Также нужен тест где в блоке есть длинное описание, по высоте больше чем высота картинки. И тест что будет если убрать картинку (не наедет ли цена на город?).

Пока решение требует доработки. Пока все плохо.

А, и еще, бросается в глаза:

> 123$


или $123 или 123 долл.
#224 #632994
Пишу парсер, который может работать с большим количеством сайтов. Правила парсинга разных сайтов, подключаются из других файлов в середине скрипта, для каждого сайта свой файл с правилами парсинга, однако, все они возвращают массив, со спарсенными данными и у всех них, структура этого массива одинакова, сам массив заносится в базу данных. Возникла проблема с кодировками, на всех сайтах они разные, если использовать iconv то всё нормально, данные перекодируются в utf-8 и нормально вносятся в базу данных, но, на всех сайтах разные кодировки, поэтому прописывать такое надо для каждого сайта, а перед этим уточнить какая у него кодировка. как автоматизировать этот процесс и не писать каждый раз одно и тоже?
#225 #633021
Всё пропало, шеф...
Всё, что нажито непосильным трудом...
Три скрипта отечественных: один считает три цифры и подставляет "миллионы", второй считает три цифры и подставляет "тысячи", третий считает три цифры и подставляет "рубли".
Столкнулся с тем, что если поставить $number = 012, то число переводится в какую-то другую систему (это вот считает как 10), от этого всё рушится.
В порыве отчаяния закрыл вкладку с Идеоне, где скрипт был для подсчёта миллионов, а остальные сохранились.
Вот для подсчёта с подстановкой "рублей": http://ideone.com/UJLA5U
Вот для подсчёта с подстановкой "тысяч": http://ideone.com/Fx2fbW
Там можно многое вынести в функции, можно расчёт сократить в строчку (я просто делал для наглядности многое) - теперь уже не имеет смысла.
Всё удаляю и забываю.
Начинаю решать эту задачу через деление чисел на 10, 100, 1000 и так далее до 100 миллионов. Всё должно быть в цикле, ориентация на целые числа, в соответствии с чем будут включаться разные условия для вывода числа прописью. Примерный алгоритм мысленно представляю.
Такой вот я тормоз, однако, здравствуйте.
#226 #633023
>>633021
И да: увидевшие скрипт буду или смеяться, или плакать. Первые - опытные, вторые - только ещё начинающие разбираться в РНР.
Ну вы поняли.
#227 #633035
>>633021
Еще одна из ошибок - даю переменным имена как функциям: $findLastNumber и т.п.
ОП об этом сказал, когда я уже начал решать эту задачу, думал потом всё исправить, но такие вот дела.
Это я учту тоже.
#228 #633110
>>632567
Бамп
#229 #633130
>>632994
Во первых, можно в парвила паосинга добавить два параметра. Типа из какой кодировки в какую.
Во вторых, можно прямо из штмл считывать meta encoding тэг.
someApprentice #230 #633141
ОПчик, прокомментируй это пожалуйста >>630433>>630650. Я в замешательстве.
#231 #633167
Палиндром
http://ideone.com/lq9U91
#232 #633185
>>632909
Класс создает объект пдо один раз, чтобы использовать пдо без этого класса, пришлось бы создавать подключение каждый раз в новом контроллере, как тот быдлошкольник выше.
#233 #633204
>>633185

Не вижу связи. Ты читал этот урок? https://gist.github.com/codedokode/e1d31a31b37d5f635057

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

И не надо тут всех обзывать школьниками если сам плохо разбираешься.
#234 #633205
>>633185

Также, неприавльно обрабатываются исключения, catch а тем более эхо там не нужны.
Решения за 19-20 января из старого треда #235 #633207
>>629523

Тебе я написал советы и замечания выше

>>629589

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

- через ФТП, 1С будет выклаыдвать новые данные, например новые товары, на ФТП сервер и оттуда же забирать обновления с сайта, например заказы.
- через HTTP, 1с будет отправлять запросы с данными на какой-то URL

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

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

>>629605

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

>>629631

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

>>629732

Неправильно считает если взять сумму кредита = 1000: http://ideone.com/B81a83

Должно быть всего выплачено 2030 (1000 + процент + комиссия)

Также, выражение повторяется 3 раза, избавься от повторов: $creditBalance x $percent + $servicePayment

>>629735

Босюь что никто не станет решать твою задачу, решай сам.
Решения за 19-20 января из старого треда #235 #633207
>>629523

Тебе я написал советы и замечания выше

>>629589

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

- через ФТП, 1С будет выклаыдвать новые данные, например новые товары, на ФТП сервер и оттуда же забирать обновления с сайта, например заказы.
- через HTTP, 1с будет отправлять запросы с данными на какой-то URL

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

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

>>629605

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

>>629631

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

>>629732

Неправильно считает если взять сумму кредита = 1000: http://ideone.com/B81a83

Должно быть всего выплачено 2030 (1000 + процент + комиссия)

Также, выражение повторяется 3 раза, избавься от повторов: $creditBalance x $percent + $servicePayment

>>629735

Босюь что никто не станет решать твою задачу, решай сам.
#236 #633208
Напомню себе глянуть >>629749

https://github.com/toppestkek/GuestBook
#237 #633210
Решил "Айпад в кредит" .
И мне кажется, что у меня там плохое решение.
http://ideone.com/PfjBQC
#238 #633217
>>633185
Внедрение зависимостей гугли и не надо будет ничего создавать
#239 #633236
>>629822 (OP)

В прошлом треде пропустил меня >>629285

Вот код http://ideone.com/flCff0
#240 #633240
>>633210
Всё отлично.
Через while так-то удобнее её решить. Но ОП предлагает через for - попробуй ещё и через for для верности.
#241 #633241
>>633167
Отлично.
#242 #633242
>>633205

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


Почему? Ведь если это исключение не ловить, пользователю просто покажет белую страницу.
#243 #633266
Хм, отличная всё-таки находка у ОПа: сделать информацию на сайте в виде изображений.
Я про это говорил уже пару тредов назад, что это не очень хорошо в плане SEO, потом ещё хотел сказать, что это не очень удобно и в плане обучения - приходится всё просматривать, весь материал страницы, чтобы найти что-то интересующее, удобнее было бы ввести это в "Поиск" и получить результат.
А теперь для меня очевидно, что это практически идеально: ты каждый раз просматриваешь информацию, в голове откладывается, что верно сделано, а что неверно. Ну или я просто привык изучать всё по книгам, там практически то же самое, тот же эффект.
Я вот уже давно не смотрел на регулярки - отвлёкся на другие сложные задачи, а сейчас решил проверку номера телефона ещё раз написать с нуля и с подстановкой номеров из массивов в пасте ОПа (вот тут её вставлял: >>631698): http://ideone.com/cPUmGT
Сделал без подглядываний (я сто раз смотрел это всё уже, многое успел крепко запомнить).
Также стоит читать ответы ОПа другим братишкам, смотреть на их ошибки и т.п.
Также способствует всему самостоятельный разбор и исправление ошибок в решении задач у братишек - лишний раз всё отпечатывается в голове.
Просто так это пишу всё пока отдыхаю от решения сложной задачи, которую впоследствии надеюсь так же просто и разнообразно решать, как первые задачки
#244 #633278
>>633021
Вообще не всё ещё и пропало!
Можно вот как сделать в этой моей ситуации.
Числа с нулём в самом начале у нас просто и не будет - mt_rand(0,999999999) нам такое число не выдаст. А дальше мы можем просто проверять, нет ли нуля в третьей позиции числа и в шестой - проверять эту строку.
То есть, например, у нас число 50 012.
50 у нас идёт в тот скрипт, где тысячи - выдаёт "50 тысяч".
А далее включается проверка третьего числа с конца. Если оно равно нулю, то берём только последние два числа с конца - это уже есть и оно выдаст "12 рублей".
Так что не всё ещё было потеряно, муахаха!

Но попробую освежить голову и сделать с помощью деления и округления в цикле, посмотрю, как пойдёт.
75 Кб, 577x600
#245 #633286
>>629822 (OP)
Взываю к среднелевельным анонам. Выполнил задачу Grammar Nazi v2. Всё получилось, но каждую замену мне пришлось гарантировать индивидуальным условием, выглядит как-то не очень грамотно. Думал прибегнуть к функциям, но не придумал, как, да и не уверен, что так можно в данном случае. Полагаю, есть возможность реализовать это с помощью массивов, немного погуглил, но так и не придумал, как правильно сформулировать запрос. Прокомментируйте, пожалуйста.
http://ideone.com/sLeIRY
#246 #633295
>>633286
Можно сделать два массива - $regexp и $replace: в одном все регулярки с ошибками, которые должны быть разделены круглыми скобками и знаками "или", а в другой исправляемые моменты, который будут нумероваться как $1, $2 и так далее - то, что у нас в регулярках, но с добавлением пробела или с исправлением на другое слово.
Посмотри этот момент на странице с регулярными выражениями - как заменяются регулярки с помощью $1 и так далее.
Тогда потом достаточно будет подставить в foreach с разложением массива с регулярками на ключи и значения, ещё один массив с разложением реплейсмента на ключи и значения, а потом с помощью preg_replace подставлять регулярки из массива и заменяемые места из реплейсмента, ахаха, я поехал уже...
Но всё тогда будет вообще в несколько строк и без условий каких-либо.
Понятно ли объяснил?
#247 #633302
>>633204
Как ты себе это представляешь?

class Mapper {
__construct($db PDO)
$db = new PDO('mysql:host=localhost;dbname=guestbook;charset=utf8', 'root', '');
}

или быть может при каждом создании маппера задавать новый $db = new PDO('mysql:host=localhost;dbname=guestbook;charset=utf8', 'root', '');?
Хуйню несешь короче.
#248 #633305
>>633302

>class Mapper {


>__construct($db PDO)


>$db = new PDO('mysql:host=localhost;dbname=guestbook;charset=utf8', '>root', '');


>}


Вообще-то так и надо делать
#249 #633307
>>633305
лол, долбоеб, зачем тогда в конструктор пдо передавать. иди задачки порешай, тут взрослые люди общаются.
#250 #633309
>>633307

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


Чтоб его использовать как поле класса.
#251 #633324
>>633305

нью в конструкторе тогда не нужен.
#252 #633325
>>633324
Ну да, предпологается, что в конструктор передается уже готовый объект, а сам конструктор просто присвоит его полю.
#253 #633331
I'm done, аноны. Щито делать с этим палиндромом?
http://ideone.com/cnFoMy
#254 #633362
Задачи на проверку кидать начиная с рублей и кубика?

А то я в целом не совсем ньюфаг в этом деле, но прохожу.
#255 #633406
Вот первые задачки на проверку:

W2(перевод долларов в рубли) - http://ideone.com/5zHXdu
W3(имитация броска кубика) - http://ideone.com/2QvVvX
W4.1(дописать кубик) - http://ideone.com/ckuYdx
W4.2(рулетка что смотрит последнюю цифру) - http://ideone.com/TKuvUB

Пойду делать дальше.
#256 #633417
>>633406
Задачку W4.1 неправильно написал(был невнимателен и не написал когда победит дружба), вот правильный(как я думаю) вариант - http://ideone.com/hGYwZs
#257 #633419
тест
#258 #633436
>>633331

>mb_substr($text, $length, $halfLength);


Щито сие означает? Посмотри, как там у ОПа или в мануале описано, что там должно стоять вместо $length и $halfLength.
Также надо все буквы сделать строчными, ты упустил этот момент с самого начала.
Алгоритм такой, частично он у тебя соблюдён:
1. Делаем все буквы строчными.
2. Убираем регуляркой все пробелы между словами.
3. Подсчитываем количество символов в получившемся тексте.
4. Подсчитываем середину текста.
5. В цикле проходим по буквам от начала текста и до середины. Здесь получше уясни себе, как работает функция mb_substr. Также вспомни, для чего мы используем $i в циклах с for.
6. Если буква с начала строки и конца строки не совпадают - возвращаем результат "Не палиндром" и обрываем цикл.
7. Если буквы с начала и конца и далее совпадают - продолжаем цикл до того момента, когда будет проверена половина текста. Здесь мы можем выводить каждую букву с конца и начала, чтобы сравнивать их.
8. Если у нас цикл был пройден до конца, то возвращаем echo "Палиндром".
Твой код я поправил. Если совсем будет сложно, то буду подсказывать или просто покажу твой же исправленный код.
#259 #633437
>>633406
>>633417
Да норм всё.
#260 #633443
>>633362
Начиная с того момента, когда будет непонятно.
#261 #633450
>>632953
Ладно, пусть так. Я рассчитывал именно на то, чтобы избавиться от зависимости от библиотеки, плюс может быть использовать код повторно в других проектах.
Но тут пожалуй действительно не тот случай. Библиотеку менять не нужно, и код не такой сложный, чтобы выносить его в отдельный пакет.
Тогда такая реализация: http://ideone.com/wNwIh1

>>632982
Не использовать лишние теги, стараться использовать html5-теги по возможности, или классы с семантичным именем, ок.

> position: absolute;


> Такие вещи удобнее делать флоатом


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

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

>что будет если убрать картинку (не наедет ли цена на город?).


Добавил min-height внешнему контейнеру. Вообще мне не хватает опыта, чтобы просчитать наперед все "что будет если". Я вижу дизайн и реализовываю. Думаю дальновидность придет с опытом, когда придется такой код поправлять под изменившиеся требования (убрать картинку, добавить текст описания и т.д.)
https://jsfiddle.net/tLwp60qh/6/
#262 #633455
>>633362
Все сбрасывай, оп найдет к чему придраться даже в коде из одной строчки.

>не совсем ньюфаг


Какие фреймворки знаешь? Сколько проектов написал? В каких конторах работал?

>>633443
Нет, так рождается быдлокод. Php за это и не любят, что на нем можно написать неподдерживаемый код, который тем не менее будет работать.
Если работает и вроде все понятно, это не значит, что решено правильно.
#263 #633459
Блин, мне нужно искать какую-нибудь нормальную работу, но я просто не понимаю, как можно работать в мужском коллективе и НЕ ТРАХАТЬСЯ С НИМИ ВСЕМИ. Я просто шлюхой долго проработала, я не могу вообще общаться с мужиками, если они мне не дают деньги, а потом не трахают во все дырочки. Нет, серьезно, я когда звоню по вакансиям и там мужской голос берет - я просто кидаю трубку и не могу с собой ничего поделать. Как избавиться от этой проф. деформации и начать жить?
Шлюхой ща работать не могу.
#264 #633460
Вопрос по задачке с кредитом на айфон:
получается строка "С меня хватит" будет просто не нужна после исправления ошибки? Ведь идеальным решением задачки есть полный вычет денег без переплаты. А то условие не до конца понял.
#265 #633464
>>633460
И еще вопрос вдогонку - не понял, нужно ли насчитывать проценты когда долг меньше 5000.
#266 #633465
>>633460
Нет, она может остаться и выйти тогда, когда выплачен весь кредит.
Полная выплата кредита с процентами и комиссиями - и далее "С меня хватит!".
#267 #633467
>>633464
Конечно. Кредит не выплачен до конца, а новый месяц уже пошёл.
#268 #633471
>>633467
А какой тогда вообще смысл?
Вот я что-то запутался с условием задачки.
Под спойлер заглядывал.

Какой смысл проверять больше ли 5000, если потом эта же цифра всё-равно увеличится и чисто теоретически может быть больше чем 5к?
Или проверять надо не просто долг а долг с процентом на следующий месяц?
#269 #633473
>>633471

>больше ли 5000


точнее меньше ли.
#270 #633483
>>633471
Такое уж сферическое условие в вакууме, сумма возможных выплат Анончика меньше и больше не может становиться.

>Или проверять надо не просто долг а долг с процентом на следующий месяц?


А как по-другому? Конечно!
#271 #633486
>>633483
Ещё и оплату комиссии за пользование кредитом не забудь!
#272 #633489
>>633483
Чёт я вообще запутался с этим условием, не знаю почему, но очень туго само условие до меня доходит, хотя с циклами давно знаком. Пойду проветрюсь, отвлекусь и чуть позже вернусь к задачке.
100 Кб, 312x718
ЗАМЕНА #273 #633524
Помогите глупому анону, пожулуйста. Как можно записать это более коротко?
#274 #633525
>>633524
Про массивы и циклы слышал что-нибудь?
#275 #633526
>>633524
Создаешь массив, заполняешь его твоими регулярками, прогоняешь цикл n раз.
56 Кб, 225x220
#276 #633527
#277 #633531
212 Кб, Webm
#278 #633548
>>633436

>mb_substr($text, $length, $halfLength);


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

1. Строчные буквы mb_strtolower($text);
2. Убрать пробелы $text = str_replace(' ', '', $text);
3. Кол-во символов $length = mb_strlen($text);
4. Середина $halfLength = floor($length/ 2);
5. Вот тут я и не знаю, а 6,7,8 нужны только после выполнения 5.

Короче, давай подсказку.
#279 #633561
>>633548

>mb_substr($text, $length, $halfLength);


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


У нас есть цикл с for и в нём переменная $i - она меняется каждый раз при прохождении цикла.
Если поставить вот так, то переменная каждый раз будет способствовать передвижению по тексту на один символ:

>mb_substr($text, $i, 1)


Чтобы то же самое получить, но с конца текста, надо эту переменную поставить в отрицательном значении: >mb_substr($text, -$i, 1)
Каждый раз делай var_dump($variable), чтобы понять, что там происходит. variable - это конкретное название твоей переменной или массива

>1. Строчные буквы mb_strtolower($text);


Нет, сработает не само по себе, а если ты поставишь вот так, например:
$text = mb_strtolower($text);
2, 3, 4 у тебя правильно сделаны.
5 у тебя получится, если сделаешь с переменной $i в mb_substr().
Давай, пробуй, всё получится.
#280 #633581

>твоей переменной или массива


Твоей переменной, в которой строка, число или массив, ну ты понял.
#281 #633583
>>633561
Спасибо за разжевывание.
Ночью сделаю.
#282 #633610
>>633583
Var_dump просто на каждом шагу делай, смотри, что там получается. Всегда помогает это.
#283 #633628
>>633610
Открой для себя дебаггер.
#284 #633631
>>633628
Мне лень.
#285 #633637
>>633628

>дебаггер.


Тот, что в PHPStorm?
#286 #633642
Тогда вопрос ко всем знающим: какими инструментами лучше всего пользоваться для отладки?
https://habrahabr.ru/post/210202/ прочитал, но так и не понял, куда копать.
#287 #633646
>>633642
xdebug + phpstorm, для javascript дебагер в firefox
Больше ничего не надо, хватает даже для крупных проектов.
#288 #633648
>>633628
где почитать что такое дебал и вообще зачем он?
#289 #633650
>>633646
Спасибо, как раз статью нашёл: https://habrahabr.ru/post/209024/
#290 #633666
Нужен ли будет такой скрипт кому-нибудь вообще, полезен ли он будет?

Есть поле формы, в которое можно вести адрес какой-нибудь текстовой информации (пост блога, статья на сайте и т.д.) скрипт спарсевает всю нужную информацию (Заголовок, Текст, Дата и т.д.), заносит её в базу данных и формирует из этого RSS XML. Спарсивать можно не с любого сайта конечно, а только для тех, для каких я напишу парсер, но таких сайтов может быть много.
#291 #633741
>>633561
Всё что сделал, но, очевидно, работает только для этой фразы.
http://ideone.com/nHsCfe
#292 #633854
А для Sublime Text есть какие-нибудь плагины-дебаггеры?
#293 #633856
>>633854
Есть. Можно плагином настроить работу xDebug в Sublime Text.
Если интересно почитай тут http://www.sitepoint.com/debugging-xdebug-sublime-text-3/
#294 #633857
Интереесно не лучше ли вместо isset(var) проверять переменные всегда !empty(var) там мы сращу проверяем существует ли переменная и не пуста ли она
#295 #633861
>>633741

>$new = (-19);


>$symbolRev = mb_substr($text, $new, 1);


Братишка, ну почитай ты, что у ОПа написано про mb_substr, как с конца текста надо получить символ!
Ты же так и разобрался в этом простом моменте!
Почему у тебя $new там сразу -19, она должна точно так же идти в цикле - а буквы будут браться с начала и конца текста и сравниваться друг с другом.
Вот как будет всё выглядеть, если цикл вытянуть и показать его работу ($i заменил на те цифры, которые как раз будут там при изменении этой переменной во время работы цикла):

Первое прохождение цикла.
$symbol = mb_substr($text, 0, 1);
$symbolRev = mb_substr($text, -1, 1);
- берутся "а" с начала текста (текст уже приведён к нижнему регистру) и "а" с конца - первые символы с обеих сторон текста, далее у тебя условия с if и else, в которых эти символы сравниваются.

Второе прохождение цикла.
$symbol = mb_substr($text, 1, 1);
$symbolRev = mb_substr($text, -2, 1);
- берутся "р" с начала текста и "р" с конца - вторые символы с начала и с конца текста, снова сравниваются, равны ли друг другу.

Третье прохождение цикла.
$symbol = mb_substr($text, 2, 1);
$symbolRev = mb_substr($text, -3, 1);
- берутся "о" с начала текста и "о" с конца - третьи символы с одной и другой стороны текста, сравниваются в условиях.

...

Девятнадцатое прохождение цикла.
$symbol = mb_substr($text, 19, 1);
$symbolRev = mb_substr($text, -19, 1);
- берутся "а" в середине текста и "а" в середине (там центральная буква в тексте - это "м" в слове "манит", она не попадает в этот цикл, а вот буквы с обеих сторон проверяются, это как раз обе "а"), сравниваются.

И вот если переменная $i к этому моменту становится равной длине половины текста - то есть цикл работал, а не оборвался сразу, - то срабатывает условие, что это палиндром.

Говорю же - делай var_dump каждый раз - смотри на изменения переменных, чтобы осознать работу скрипта.
У тебя сейчас $symbol = mb_substr($text, $i, 1); даёт букву за буквой с начала текста - если бы цикл вообще работал, а $symbolRev = mb_substr($text, -19, 1); (там же $new у тебя без изменений и всегда равна -19) даст только одну букву из середины текста, как раз букву "а". Поэтому у тебя сейчас случайно показывает верно, что текст палиндром: сравнивает начальную "а" и вот эту 19-ю с конца "а".
Подсказка первая - совсем уже понятная должна быть к этому моменту: В $symbolRev = mb_substr($text, $new, 1); точно так же должна стоять переменная $i. Перед переменной можно ставить минус - всё работает. От переменной можно отнимать или к ней можно прибавлять прямо в функции - всё работает.
Подсказка ещё одна: Числа -0 не бывает.
#295 #633861
>>633741

>$new = (-19);


>$symbolRev = mb_substr($text, $new, 1);


Братишка, ну почитай ты, что у ОПа написано про mb_substr, как с конца текста надо получить символ!
Ты же так и разобрался в этом простом моменте!
Почему у тебя $new там сразу -19, она должна точно так же идти в цикле - а буквы будут браться с начала и конца текста и сравниваться друг с другом.
Вот как будет всё выглядеть, если цикл вытянуть и показать его работу ($i заменил на те цифры, которые как раз будут там при изменении этой переменной во время работы цикла):

Первое прохождение цикла.
$symbol = mb_substr($text, 0, 1);
$symbolRev = mb_substr($text, -1, 1);
- берутся "а" с начала текста (текст уже приведён к нижнему регистру) и "а" с конца - первые символы с обеих сторон текста, далее у тебя условия с if и else, в которых эти символы сравниваются.

Второе прохождение цикла.
$symbol = mb_substr($text, 1, 1);
$symbolRev = mb_substr($text, -2, 1);
- берутся "р" с начала текста и "р" с конца - вторые символы с начала и с конца текста, снова сравниваются, равны ли друг другу.

Третье прохождение цикла.
$symbol = mb_substr($text, 2, 1);
$symbolRev = mb_substr($text, -3, 1);
- берутся "о" с начала текста и "о" с конца - третьи символы с одной и другой стороны текста, сравниваются в условиях.

...

Девятнадцатое прохождение цикла.
$symbol = mb_substr($text, 19, 1);
$symbolRev = mb_substr($text, -19, 1);
- берутся "а" в середине текста и "а" в середине (там центральная буква в тексте - это "м" в слове "манит", она не попадает в этот цикл, а вот буквы с обеих сторон проверяются, это как раз обе "а"), сравниваются.

И вот если переменная $i к этому моменту становится равной длине половины текста - то есть цикл работал, а не оборвался сразу, - то срабатывает условие, что это палиндром.

Говорю же - делай var_dump каждый раз - смотри на изменения переменных, чтобы осознать работу скрипта.
У тебя сейчас $symbol = mb_substr($text, $i, 1); даёт букву за буквой с начала текста - если бы цикл вообще работал, а $symbolRev = mb_substr($text, -19, 1); (там же $new у тебя без изменений и всегда равна -19) даст только одну букву из середины текста, как раз букву "а". Поэтому у тебя сейчас случайно показывает верно, что текст палиндром: сравнивает начальную "а" и вот эту 19-ю с конца "а".
Подсказка первая - совсем уже понятная должна быть к этому моменту: В $symbolRev = mb_substr($text, $new, 1); точно так же должна стоять переменная $i. Перед переменной можно ставить минус - всё работает. От переменной можно отнимать или к ней можно прибавлять прямо в функции - всё работает.
Подсказка ещё одна: Числа -0 не бывает.
#296 #633862
>>633861
*так и не разобрался в этом простом моменте
#297 #633868
>>633861
Я напутал - там не 19 циклов, а восемь будет всего...
19 - это вообще количество букв в этом палиндроме про Аргентину.
#298 #633926
Стоит ли использовать БЭМ? Вроде прикольная штука, но теряется смысл каскадности.
#299 #633946
>>633524

Тут проще заменять через массив и strtr, помнишь задачу про шифровку?

>>633926

Принцип именования классов - стоит, код будет лучше. Никто и не говорит что ты обязан использовать принцип каскадности.
#300 #633968
Числа прописью - мрак, мрак, кладбище, гуманитарий...
#301 #634026
Анон, подскажи как в Yii2 можно остановить выполнение текущего вида.
Т.е. например приходят неполные данные и мне нет смысла отображать всю верстку данного вида, а отобразить кусочек из него и все.
Можно ли использовать return; ?
Или есть что то от фреймоврка
по типу current_view->хватитВыполнятьДавайУжеГлавныйЛэйаутПоказывай();
#302 #634030
Есть на странице например 10 ссылок с атрибутом ahref="#", у всех них один и тот-же класс, при нажатии на ссылку надо добавлять ссылке ещё один класс, именно добавлять, делаю это вот так:

$("a").click(function() {
$(this).addClass('active');
});

Класс добавляется, но проблема в том, что он добавляется у всех ссылок, если нажимать по нескольким из них, как сделать так, чтобы класс active был только у одной ссылки, при этом при нажатии на другую ссылку класс ей добавлялся, а у той у которой он был раньше удалялся.
#303 #634033
>>634030
Запоминать предыдущую и ставить ей тоггл на класс актив, при добавлении этого класса к следующей ссылкею
#304 #634034
>>634030
$("a").click(function() {
$("a").removeClass('active');
$(this).addClass('active');
});
#305 #634037
>>634034
так может чуть побыстрее будет -
$("a.active").removeClass('active');
#306 #634039
>>634030
$("a").click(function() {
$("a").not(this).removeClass('active');
$(this).addClass('active');
});
#307 #634045
Посоны, помогите.
Такая ситуация: есть много .xsls шаблонов, мне нужно выгрузить в них товары.
Не хочу чтобы этим меня заебывали в дальнейшем, поэтому пытаюсь написать такую вещь:
-Выбираешь файл, он загружается.
Из строк в нем только заголовки.
Эти заголовки выводяться на страничке.
Внизу под заголовками селекты со списком полей(там вся инфа о товарах).
Затем можно выбрать соответствующие поля и захуярить файл в который всё это запишется.
воот.
С помощью phpExcell я сделал, чтобы шаблон считывался и отображался в браузере.
Но phpExcell так же убирать все хтмл теги, поэтому в ячейки селекты я записать не могу, а как отключить экранирование я не нашел.
Думаю, что буду писать в ячейки какой-то определенный текст, потом с помощью jquery его парсить, получать номер столбца и заменять на селекты.
Может кто посоветует что получше?

Да, ещё хотел спросить. Можно ли часть страницы отобразить в одной кодировке а вторую часть в другой?
#308 #634070
Алгоритм перевода чисел в пропись.
Гладко выходит на бумаге, но натыкаюсь на РНР-овраги, пока не получается реализовать.
Не хотел бы отнимать время у ОПа и братишек на проверку этого алгоритма, но был бы рад замечаниям.
Ну и просто чтобы не потерять.

1. Имеем число, например, 123123.
2. Проверяем, на соответствие числам в массиве $spelling - нельзя ли его сразу вывести прописью. Если можно – выводим его. Если нельзя – идём далее.
3. Проходим по числу циклом с делением на 100000000, 10000000, 1000000, 100000, 10000, 1000, 100 и 10 и округляем результат.
4. Когда результат деления становится равным целому числу (от 1 до 9) – уточняем, на какое число делили, чтобы получился такой результат.
5. Далее всё идёт для уточнённого числа, у нас это 100000. Если основное число было разделено на сто тысяч до целого, то умножаем результат на 100, чтобы получить соответствие с числами в массиве $spelling.
6. Если у нас получившаяся сумма соответствует числу в $spelling (у нас это будет 100), то выводим (она будет соответствовать в любом случае, всё это есть в массиве).
7. Далее проверяем, есть ли другие цифры после 1 в реально имеющемся у нас числе. Для этого 123123 делим на 1000, округляем до целого числа, а затем отнимаем 100. В нашем случае – с 123 тысячами 123-мя - получится 23.
8. Проверяем результат на соответствие массиву $spelling. Если соответствие есть ("11", "12" и так далее) – выводим. Если соответствия нет – раскладываем дальше.
9. Раскладываем 23: делим его на 10, округляем до целого и умножаем на 10 – получается двадцать.
10. Проверяем результат на соответствие массиву $spelling. Соответствие обязательно есть.
11. Далее находим последнее число в 123: от 123 отнимаем сумму первого числа и второго числа (100 + 20). Проверяем результат на соответствие массиву $spelling. Соответствие обязательно есть.
12. Далее проверяем, не является ли последнее число "1" или "2": проводим число по массиву $femaleSpelling. Если соответствует - выводим результат "одна" либо "две". Если не соответствует – выводим предыдущий общий результат.
13. Собираем первое число, второе число и третье число: "сто", "двадцать" и "три". При этом у нас изначально всё связано с тысячами, поэтому выводим строку «сто двадцать три» и проверяем последнее полученное число на соответствие массиву с формами слова «тысяча». Соответствующую форму "тысяч" выводим.
14. Далее находим три оставшихся числа от 123123. У нас имеются три первых числа – 123, также мы знаем, что общее число – 123nnn. Поэтому умножаем 123 на 1000, а затем от начального числа $number отнимаем получившиеся 123000. Получается 123.
15. Раскладываем 123 по такому же алгоритму, как и 123000, только в самом конце не активируем шаг с $femaleSpelling. Последнее готовое число проверяется на соответствие в массиве для вывода правильной формы слова «рубли».
Алгоритм для вывода миллионов соответствующий, полностью повторяет алгоритм для вывода последних 123, только "рубли" меняются на "миллионы".
Большинство действий укладываются в функции, целые куски кода могут быть спрятаны в функции. Поиск от тысячи до 999 тысяч, поиск от 1 до 999, поиск от миллиона до 999 миллионов убираются в функции и подставляются в те условия, когда целое число получилось у нас при делении на соответствующие тысячи, десятки тысяч и так далее.
Когда у нас число, например, 20, или 20000, или 20000000, то выявление чисел идёт по этой же схеме – по сокращённой на поиск первого числа из тройки. Для этого вводим сокращённые функции и подставляем их в соответствующие места.

Вроде бы всё логично.
Буду биться и сражаться с ветряными РНР-мельницами далее.
Me Gusta.
#308 #634070
Алгоритм перевода чисел в пропись.
Гладко выходит на бумаге, но натыкаюсь на РНР-овраги, пока не получается реализовать.
Не хотел бы отнимать время у ОПа и братишек на проверку этого алгоритма, но был бы рад замечаниям.
Ну и просто чтобы не потерять.

1. Имеем число, например, 123123.
2. Проверяем, на соответствие числам в массиве $spelling - нельзя ли его сразу вывести прописью. Если можно – выводим его. Если нельзя – идём далее.
3. Проходим по числу циклом с делением на 100000000, 10000000, 1000000, 100000, 10000, 1000, 100 и 10 и округляем результат.
4. Когда результат деления становится равным целому числу (от 1 до 9) – уточняем, на какое число делили, чтобы получился такой результат.
5. Далее всё идёт для уточнённого числа, у нас это 100000. Если основное число было разделено на сто тысяч до целого, то умножаем результат на 100, чтобы получить соответствие с числами в массиве $spelling.
6. Если у нас получившаяся сумма соответствует числу в $spelling (у нас это будет 100), то выводим (она будет соответствовать в любом случае, всё это есть в массиве).
7. Далее проверяем, есть ли другие цифры после 1 в реально имеющемся у нас числе. Для этого 123123 делим на 1000, округляем до целого числа, а затем отнимаем 100. В нашем случае – с 123 тысячами 123-мя - получится 23.
8. Проверяем результат на соответствие массиву $spelling. Если соответствие есть ("11", "12" и так далее) – выводим. Если соответствия нет – раскладываем дальше.
9. Раскладываем 23: делим его на 10, округляем до целого и умножаем на 10 – получается двадцать.
10. Проверяем результат на соответствие массиву $spelling. Соответствие обязательно есть.
11. Далее находим последнее число в 123: от 123 отнимаем сумму первого числа и второго числа (100 + 20). Проверяем результат на соответствие массиву $spelling. Соответствие обязательно есть.
12. Далее проверяем, не является ли последнее число "1" или "2": проводим число по массиву $femaleSpelling. Если соответствует - выводим результат "одна" либо "две". Если не соответствует – выводим предыдущий общий результат.
13. Собираем первое число, второе число и третье число: "сто", "двадцать" и "три". При этом у нас изначально всё связано с тысячами, поэтому выводим строку «сто двадцать три» и проверяем последнее полученное число на соответствие массиву с формами слова «тысяча». Соответствующую форму "тысяч" выводим.
14. Далее находим три оставшихся числа от 123123. У нас имеются три первых числа – 123, также мы знаем, что общее число – 123nnn. Поэтому умножаем 123 на 1000, а затем от начального числа $number отнимаем получившиеся 123000. Получается 123.
15. Раскладываем 123 по такому же алгоритму, как и 123000, только в самом конце не активируем шаг с $femaleSpelling. Последнее готовое число проверяется на соответствие в массиве для вывода правильной формы слова «рубли».
Алгоритм для вывода миллионов соответствующий, полностью повторяет алгоритм для вывода последних 123, только "рубли" меняются на "миллионы".
Большинство действий укладываются в функции, целые куски кода могут быть спрятаны в функции. Поиск от тысячи до 999 тысяч, поиск от 1 до 999, поиск от миллиона до 999 миллионов убираются в функции и подставляются в те условия, когда целое число получилось у нас при делении на соответствующие тысячи, десятки тысяч и так далее.
Когда у нас число, например, 20, или 20000, или 20000000, то выявление чисел идёт по этой же схеме – по сокращённой на поиск первого числа из тройки. Для этого вводим сокращённые функции и подставляем их в соответствующие места.

Вроде бы всё логично.
Буду биться и сражаться с ветряными РНР-мельницами далее.
Me Gusta.
#309 #634078
В пункт 14 добавить: если полученное число оказывается нулём - уходим и ничего не выводим, кроме формы слова "рубли".
#310 #634083
>>632548
Для чего там цикл? Всё работает и без условия, что $i == 2.
#311 #634084
>>634070

1) математикой разбиваем число на группы по 3 цифры (миллионы, тысячи, рубли)
2) для каждой группы вызываем функцию печати 3-значного числа + функцию склонения слова, получается например "сто пятьдесят миллионов"
3) в этой функции разбиваем число математически на сотни, десятки, единицы.
4) еслит в числе есть сотни, добавляем нужное слово
5) если есть десятки, добавляем их
6) если число заканчивается на 11-19, добавляем слово
7) добавляем слово для единиц

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

Собирать слова в фразу удобно через массив, добавляя слова в массив и потом склеивая его.
#312 #634087
>>634070
Ты писателем работаешь? Уже пол задачи бы написал, пока простыню строчил.
#313 #634123
>>634084
Спасибо, интересно выглядит.
Я просто не знаком абсолютно с математическими возможностями определения числа, поэтому начал делать через определение числа, на которое делится с целым числом после округления.
Буду искать, как это можно реализовать. Явно как-то проще, чем я расписал.
В массив можно, действительно, спасибо. Через array_push, наверное.

>>634087
Главным редактором в издательстве.
Люблю основательность.
И просто я уже реализовал части этой задачи через перевод числа в строку, вот тут: >>633021.
Хочу сделать более правильно и до конца.
Там так-то тоже можно было бы извратиться и соединить эти части: искать символ "ноль" в строке перед переходом к разложению тройки или складывать три последних числа, чтобы было понятно, нужно ли вообще запускать разложение очередной тройки (если там ноль получается, то не нужно).
Но это совсем уж.
#314 #634127
Парни, решил вкатиться в пхп, где стянуть пхпсторм? чтоб не триал и последняя версия
#315 #634130
>>634123

>Главным редактором в издательстве.


ахаха лущер блять, иди простыни строчи, редактор блять.
#316 #634134
>>634127
Саму иде берешь на сайте у джетбрейнс, потом идешь сюда http://www.rover12421.com/ и качаешь его кейген (это не вишня, исходники лежали на гитхабе, но их заблочили).
#317 #634150
>>634134
THank's!
#318 #634152
>>634150
Если китайский обменник по каким-то причинам не даст тебе скачать файл, можешь попробовать взять иде с кряком отсюда (нужна регистрация).
http://nnm-club.me/forum/viewtopic.php?t=974883
#319 #634156
>>634152
Я так понял, качать надо вот по этой ссылочке, да?
Download Jar : http://pan.baidu.com/s/1gdw7T0v
#320 #634158
>>634156
Да вроде бы, я активировал этим кейгеном месяцев 6 назад, еще работает со всеми обновлениями.
#321 #634186
>>634158
Бля, эт говно какое-то, полностью на китайском.
заебался уже систему чистить, хуй знает куда оно полезло
#322 #634188
>>634186
Значит ты не то скачал, смотри тут >>634152
#323 #634217
Может кто-то работал с Silex, поясните зачем вот тут в примере http://silex.sensiolabs.org/doc/organizing_controllers.html в самом низу в 5-й строке (return $blog;) нужно возвращать этот контроллер? Если все-равно выполнится "return 'Blog home page'" и по идее дальше уже код не будет выполняться. Но если не прописать return $blog; то вылезает ошибка.
#324 #634233
>>634188
Я скачал сам китайский облачный обменник, как я понял. Вычищать его - отдельный ад)
#325 #634238
Совершенно не понимаю что надо делать в задачке с кредитом на айфон, как быть?
#326 #634241
>>634238
Подумать головой. Там и делать-то нечего.
#327 #634242
>>634188
Короче, с переводчиком понял, что сайт будет выпрашивать скачать эту Байду.
лучше крякнутую с ннм стяну с регой)
89 Кб, 932x554
#328 #634243
Проблема с базами. Устанавливал MySql, сделал все как в этом гайде: http://www.softtime.ru/article/index.php?id_article=98. В браузере ошибка Fatal error: Call to undefined function mysqli_connect() in C:\Users\User\PhpstormProjects\kurs2\demo\test.php on line 9, хотя в консоли пхпшторма все работает. В чем проблема?

Алсо подскажите как импортировать данные из одной базы в другую (первая называется web, вторая web2). Пробовал CREATE DATABASE web; mysql -uroot web < web2.sql, не работает, как указать консоли расположение второй базы?
#329 #634245
>>634243

>В браузере ошибка Fatal error: Call to undefined function mysqli_connect()


Апач и Пхпсторм один и тот же интерпретатор используют? Создай в корневой директории апача файл с phpinfo() и посмотри, есть ли там расширение mysqli.
#330 #634248
>>634238
А что именно не понятно? Там же всё несложным кажется на первый взгляд.
#331 #634253
>>634248

>\t


Я видимо даже в математику не могу, потому что совсем не понимаю что там надо сделать, чтобы не переплачивать банку. Даже идей нет никаких.
228 Кб, 1280x962
#332 #634265
>>634245
Как посмотреть это расширение? Так? Алсо в браузере 404ая, у меня так часто бывает с новыми проектами в phpstorm, помогает, если положить их в отдельную папку проектов.
#333 #634267
>>634245
Это странно, но ошибка исчезла сама собой, после создания нового файла, когда я снова открыл проект. Короче я молодой шутливый с ide пока что.
#334 #634269
>>634245
Однако, вопрос про расположение второй базы в консоли остается. Это второй вопрос у меня был.
79 Кб, 1919x703
#335 #634270
>>634265
Создай файл в корневой директории твоего апача, без пхпсторма. Я не знаю где она на винде, должно быть что-то вроде C:\Apache\www.

Потом заходишь в браузере по адресу 127.0.0.1 и видишь там всю информацию о пхп, ищешь на странице расширение mysqli, должно быть что-то вроде пикрелейтед.
#336 #634271
Вкатываюсь в тред со своим списком студентов:
https://github.com/disbeliever/php_training/tree/master/students
#337 #634272
>>634253
Что значит не переплачивать банку?
Покажи пробы свои на Идеоне.
Там переплата больше 50% будет так-то.
#338 #634273
>>634217
Почитай, что такое анонимная функция и callback.
#339 #634284
>>632567
Может таки кто-то уже проверит задачу по айфону в кредит?
#340 #634287
>>634271
Почему защиту от csrf не сделал? Еще некоторые ссылки неправильно работают, если поместить скрипт в какую-нибудь папку, он будет перенаправлять в корень сервера.
25 Кб, 1919x633
#341 #634289
>>634271
Алсо, если редактировать свою информацию, у меня происходит пикрелейтед.
#342 #634294
>>634284

>по айфону в кредит


Надо было покупать Xiaomi. Топовый айфон сосет по железу у китаебогов. Алсо, в айфоне нет божественного MIUI.
#343 #634311
>>634287

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

href="/register.php"

писать просто

href="register.php"

Урок про относ.ссылки есть:

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

И про CSRF тоже https://github.com/codedokode/pasta/blob/master/security/xsrf.md
#344 #634314
>>634284
>>632567

> $start = false; //Для выхода из цикла


Для этого есть команда break

> if($debt <= $pay){


Этот иф можно заменить на функцию min/max, возможно код станет короче, попробуй-ка.

В условии в уайл лучше написать "пока долг больше нуля"

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

> PHP Notice: Undefined variable: total_pay in /home/krtLNc/prog.php on line 18


Эту ошибку обращения к несуществующей в тот момент переменной надо исправить.
#345 #634316
ОП, ответь на вот это >>633242
Почему там catch не нужен?
#346 #634317
>>634294

А разве в китайских прошивках нет троянов и штуки которая записывает координаты, названия вайфай точек, ИМЕИ, номер телефона и отсылает в байду?
#347 #634320
>>634287
>>634289
Спасибо, пилю.

>>634311
Благодарю. Да, со ссылками я что-то тупанул. Про CSRF читаю.
#348 #634323
>>634316

Давай начнем с теории. Знаешь ли ты зачем придуманы исключения? Читал ли урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Если нет, прочитай.

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

try {
$app->run();
} catch (..) {
$app->showErrorPage();
}

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

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

Теперь прочти пасту про то что должно происходить при исключении:

------

Как надо обрабатывать исключения:

- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс

Что получается при catch + echo:

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

Как будет если просто не ловить исключение:

- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)

--------

Теперь посмотри на свой код и попробуй понять, правильно ли в нем сделана работа с исключениями.
#348 #634323
>>634316

Давай начнем с теории. Знаешь ли ты зачем придуманы исключения? Читал ли урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Если нет, прочитай.

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

try {
$app->run();
} catch (..) {
$app->showErrorPage();
}

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

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

Теперь прочти пасту про то что должно происходить при исключении:

------

Как надо обрабатывать исключения:

- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс

Что получается при catch + echo:

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

Как будет если просто не ловить исключение:

- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)

--------

Теперь посмотри на свой код и попробуй понять, правильно ли в нем сделана работа с исключениями.
#349 #634326
>>634271

Прочитай еще этот пункт: https://github.com/codedokode/pasta/blob/master/student-list.md#Выносим-код-за-корень-сервера

Сейчас у тебя куча файлов свалена в корне. Это никуда не годится, да еще и небезопасно. Сделай отдельно публичную папку и положи в нее файлы, к которым можно обращаться снаружи. Классы тоже положи в отдельную папку, например app или src.
#350 #634327
>>634243

> Пробовал CREATE DATABASE web; mysql -uroot web < web2.sql, не работает, как указать консоли расположение второй базы?



Где ты это набирал? В командной строке системы или в командной строке майэскуэл? Что пишет?

Чтобы перенести одну базу в другую, надо сделать дамп командой mysqldump и залить его в базу командой mysql ... < dump.sql

Можно даже без промежуточного файла:

mysqldump ... | mysql ....
#351 #634330
>>634152

Зачем так унижаться? Если нет денег, можно попробовать найти EAP версию пхпсторма, она бесплатна, либо поставить бесплатный netbeans.
#352 #634341
Если здесь присутствует пхп-дед-кун из вчерашнего треда "30 лет - ума нет", то скинь, пожалуйста, своё фейкомыло (ты его предлагал, если возникнут вопросы), а то тред сразу смыло после того, как я тебе ответил.
#353 #634365
>>634284

>$start = true;


>$start = false;


>PHP_EOL


Каков бэкграунд у тебя? Что-то уже изучал?
Про обилие точек и кавычек пояснили.
Считает правильно, что, кстати, бывает достаточно редко - чтобы сразу считал верно.
#354 #634399
>>634341
Парнишка начал изучать РНР в 30+ лет? Как же он дошёл до жизни такой?

31летний новичок, завсегдатай последних нескольких тредов
#355 #634468
Не работают строки, хотя в php.ini всё нужное раскомментировано (--enable-mbstring что-то такое), с чем может быть связано ещё?
#356 #634478
>>634399
ОП того треда просто поныть пришёл, и явно ничего делать/менять не собирается. Я же просто мимо проходил и наткнулся там на годные советы от пхп-деда.
#357 #634580
бляя, устанавливаю уии композером под линуксом, все устанавливается (среда нетбинс) , проект открывается на локалке НО я не могу в нетбинсе пофиксить код вообще, с другими пхп файлам такой хуйни не было, что это?
#358 #634582
>>634399
Мне тоже скоро 30, я потратил несколько лет на изучение php, работу так и не нашел естественно по этой профе, сейчас ищу в сфере обслуживания. Грустно, конечно, но жизнь она такая.
#359 #634587
Господа, а когда учится то?
Я вот работаю 5.2 ну пишу там стандартные штуки стандартными методами. Процесс изучения нового сильно замедлился. К тому же я в довольно ретророградом коллективе работаю.
После работы не так много свободного времени остаётся понятное дело и отдохнуть хоть чуть хочется.
Как жить то? Превозмогать, в сеньерах на том свете отдохнем?
#360 #634601
>>634582

>работу так и не нашел естественно по этой профе


А что естественного, вакансий довольно же много? Зарплаты на среднем уровне по региону даже у джунов. Чому бы не найти?

>>634587
Я после работы всё изучаю. Иногда в перерывах немного посматриваю и пробую.
Всё-таки это личное дело каждого.
У меня знатный САМОПОДДУВ сейчас идёт, поэтому я иногда и до ночи засиживаюсь.
#361 #634607
>>634587
Я например с работы приезжаю и учу. Плюс выходные полностью за задрачиванием фреймворков провожу. Если ты работаешь 12 часов в день, задумайся о том чтобы найти работу получше.
#362 #634609
>>634601
>>634607

А я видимо просто ленивое хуйло и прокрастенирую после работы, в цивилизацию сижу играю и думаю надо прекращать не прекращаю
42 Кб, 1069x350
#363 #634613
>>634609
Я тоже так делал, потом понял что теряю очень много времени и удалил все игры с компьютера, до лучших времен. Еще очень помогает отслеживание активности, пик статистика за вчерашний день.
#364 #634614
>>634613

>отслеживание активности



Это через что? Вручную всё забивается?
Чувствую я буду забывать про такое
#365 #634616
>>634614
Нет, ставишь программу и она записывает всю твою активность к ним на сервер. На сайте есть дашборд который показывает сколько времени ты на что тратишь.

Специально для параноиков сделали open source таймтрекер https://habrahabr.ru/post/275447/.
183 Кб, 540x521
#366 #634620
>>634616
Спасибо. Будем исправляться.
#367 #634623
>>633861
http://ideone.com/kUDIO4
Я не понимаю, как сделать во второй строчке в if $i = -1.
В этой версии она -$++, но она в теле цикла и уже на второй проход становится 0.
#368 #634624
>>634130
Кто такой "лущер"?
#369 #634625
>>634623
А последнюю подсказку ты смотрел?
Я специально для этого и оставил её!
Числа -0 не бывает, а именно так у тебя получается при первом прохождении цикла.
Подсказка, которая всё должна разрешить:
$i изначально надо определить как "1", а в функциях или отнимать единицу, чтобы получился ноль, или просто поставить минус перед $i, чтобы получилась "-1".
#370 #634626
>>634601
>>634587
>>634609
Тоже прокраситериновал и играл то в циву, то просто от усталости сидел на ютубе видео смотрел. Всё надоело, после работы вообще невозможно учить ничего(по крайней мере мне), слишком устаю и скилл постоянно теряю(вот сейчас забыл уже всё почти). Уволился, теперь буду дома 24/7 учить.

Сейчас сел и понял, что почти с начала надо повторять
197 Кб, 3000x1688
#371 #634628
>>634625
http://ideone.com/audvNJ
Теперь работает, спасибо.
Впереди функции worst is still to come
#372 #634629
>>634623
Также обрати внимание, как ты проверяешь равенство переменных в одном из if.
Там есть ошибка.
if ($i = $halfLength) - это присваивание, а не проверка на равенство
#373 #634630
>>634628
Ну вот и ладненько, молодца!
$i часто будет использоваться и дальше, так что это надо уяснить.
А вот моё первое исправление твоей задачи: http://ideone.com/sL7aTo
#374 #634631
>>634626
Неновичку проще, так что лучше с самого начала учебника ОПа.
32 Кб, 791x396
#375 #634659
Вы тут програмилируете за своими кантенбухтерами, а мне потом ваш говнокод запускать. Всем добра.
мимо админ
#376 #634672
>>634659
Насколько быстр этот диск?
#377 #634676
>>634672
Заявлено до 1000 iops, на деле чуть меньше (800), задержка 40 ms.
Скорость чтения - несколько сотен мегабайт/сек.

Для СХД это весьма неплохой показатель.
#378 #634679
>>634659
Это же сколько бабла можно сэкономить если выносить большую часть логики на клиента?
#379 #634681
>>634679
Пёрнул в лужу как боженька. Как ты на своём хипстерском ангуляре планируешь реализовать хранение заказов интернет-магазина?
#380 #634683
>>634679
Для компании, зарабатывающей два лярда в год - 70к за сервер не деньги.
Мы на корпоративные телефоны в месяц тратим в 10-15 раз больше.
#381 #634689
>>634681
Я про angular/магазины и не говорил (я вообще мобильный разработчик).
А вот для сайтов с высокой нагрузкой на сеть, можно было бы сэкономить.

>>634683
Но тут все равно сложно поддерживать отказоустойчивость/балансировку.
Да и код написать который сможет нормально маштабироваться не просто.
Хотя это php, там наверное просто логическая прокладка над бд.
#382 #634690
>>634689
Тебе лучше не знать, как у нас всё работает.
Новый код масштабируется, легаси-говно нет. Постепенно всё, что делает легаси-говно, переносится в новый код.
Полный уход от легаси планируется только в конце этого года.
#383 #634691
>>634689

>отказоустойчивость


Как раз уровня два пальца обоссать - corosync не вчера придумали.
#384 #634697
>>634689
Нагрузки на сеть там как раз особой нет. Когда гоняли нагрузочное тестирование (siege) - хостер машины с которой запускался сидж, сказал что мы охуели засирать им канал 4 гигабитами трафика.
#385 #634698
>>634690
ЧЕРЕЗ ДВА ГОДА НОВЫЙ КОД СТАЛ ЛЕГАСИ
@
ЦИКЛ ЗАМКНУЛСЯ
#386 #634699
>>634698
Бери больше, кидай дальше. Легаси - уже 4 года, и писали его большей частью не мы. После ревью архитектуры стало ясно, что проще выкинуть его нахуй и написать заново, что и делается постепенно.
#387 #634707
>>634631
Да я не совсем новичок
#388 #634722
Привет, пыхари. Говорят, у вас можно взять задачек на ООП? Можете подкинуть?
#389 #634723
>>634722
ОП-пост читай.
#390 #634725
>>634722
Что делал слон когда пришёл Наполеон?
#391 #634763
>>634725
Травку жувал.
#392 #634766
>>634763
Спасибо. Мы вам перезвоним.
#393 #634791
>>634707
Имел в виду, что тебе проще будет всё делать, поэтому лучше с самого начала учебника и пойти - освежить всё в памяти.
#394 #634829
>>634791
Так грустно всё это. Неделю не открывал - открываю и я ВСЁ забыл. Что за хуйня? Даже руки опускаются
#395 #634859
>>634829
За неделю забыл, что такое циклы и массивы, регулярки и тому подобное?
Тогда действительно не весело.
А мелочь разную, функции и подобное - и вообще можно не запоминать, не обязательно помнить.
#396 #634863
>>634859
Да нет, забыл только мелочь разную, но всё равно как-то я раздосадован. Сижу, смотрю и разбираю свои решения старых задач - вроде, восстанавливаю.
#398 #634937
>>634601

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


Не вижу вакансий, в моем городе их всего две и я туда уже ходил. Меня естественно послали.
#399 #634944
>>634937
В обл. центр едь.
#400 #634947
Кто-нибудь сделал задачу "построение маршрута"?
#401 #634960
>>634944
что сразу не на марс?
#402 #634962
>>634960
Туда лететь надо.
#403 #634964
Подскажите с маршрутом. Делаю по подсказке ОПа, но не могу понять, как превратить функцию, считающую 1 шаг в считающую несколько.
http://ideone.com/XuzycW

если убрать
} else {
foreach($paths[$point] as $key => $value){
makeStep($paths, $pathDone, $time, $paths[$key], $target);
}

то будет считать 1 шаг нормально, но я не понимаю, как рекурсию сделать
#404 #634986
>>634960
Обл.Центр так не доступен?

Пробуй на апворке тогда, в wrk есть годный гайд
25 Кб, 500x667
#405 #634989
Аноны, подскажите:
Накатал скриптец, который разбирает json, приходящий с трекера и сохраняет его, куда мне надо.
1) Как заставить этот скрипт постоянно слушать определенный порт?
2) Два (двадцать два/две тысячи два) трекера одновременно шлют данные на один порт - какие основные моменты мне нужно знать и учитывать, чтобы скрипт корректно обрабатывал входящие данные от многих источников? Это называется многопоточность?
3) Киньте годной инфы по работе с бинарными данными - не получается написать такой же скрипт для трекера, который шлет данные в бинарном режиме.
#406 #634990
https://github.com/foobar1643/student-list
Исправления по списку студентов.
#407 #635012
>>634722

В ОП-посте есть ссылка на учебник.

В нем есть последняя глава про ООП: http://archive-ipq-co.narod.ru/l1/pasta.html

В ней есть 2 задачи, про Вектор и Кошки-Мышки. Вот их и решай и выкладывай сюда ссылку на код, мы посмотрим.

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

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

### Антикризисные меры

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

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

1. Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров, преимущественно самого низкого ранга. Если инженер является боссом, вместо него надо уволить другого инженера, не босса.

2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков, а количество выпиваемого им кофе с 50 до 75 литров. В тех департаментах, где руководитель не является аналитиком, заменить его на аналитика самого высшего ранга из этого департамента (а бывшего руководителя вернуть к обычной работе)

3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга на один ранг с целью расширить их полномочия.

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

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

Если запутаешься, покажи код и попроси подсказку - эти задачи для новичка довольно сложные.
#407 #635012
>>634722

В ОП-посте есть ссылка на учебник.

В нем есть последняя глава про ООП: http://archive-ipq-co.narod.ru/l1/pasta.html

В ней есть 2 задачи, про Вектор и Кошки-Мышки. Вот их и решай и выкладывай сюда ссылку на код, мы посмотрим.

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

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

### Антикризисные меры

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

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

1. Сократить в каждом департаменте 40% (округляя в большую сторону) инженеров, преимущественно самого низкого ранга. Если инженер является боссом, вместо него надо уволить другого инженера, не босса.

2. Увеличить в целях стимуляции умственной деятельности базовую ставку аналитика с 800 до 1100 тугриков, а количество выпиваемого им кофе с 50 до 75 литров. В тех департаментах, где руководитель не является аналитиком, заменить его на аналитика самого высшего ранга из этого департамента (а бывшего руководителя вернуть к обычной работе)

3. В каждом департаменте повысить 50% (округляя в большую сторону) менеджеров 1-го и 2-го ранга на один ранг с целью расширить их полномочия.

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

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

Если запутаешься, покажи код и попроси подсказку - эти задачи для новичка довольно сложные.
#408 #635013
>>635012
Ты ОП?
#409 #635018
>>634964

Погугли "алгоритмы поиска пути". Там можно исплоьзовать готовый алгоритм, например алогритм Дейкстры довольно простой.
#410 #635019
#411 #635027
>>635019
Когда посмотришь задачу>>629883

И поясни про алгоритмы, у тебя в комментариях-подсказках ничего про них не сказано и я шёл в решении чётко по ним.
Т.е. надо через алгоритмы? Я просто погуглил и ужаснулся, никогда не имел с ними дело и оче непонятно и страшно.
#412 #635055
>>634986
пробовал, расценки не устраиват.
#413 #635065
>>629822 (OP)
Рейквестирую инфу. Работа на ПХП. Какой фреймворк учить? И если можно сразу гайдецов.
#414 #635107
>>635065
ОП пост то прочитай сначала.
#415 #635118
Если в поле базы данных содержится строка со списком id в таком виде: 2,5,8,9,15,27 Можно ли как-нибудь в один запрос, без дополнительных функций (вроде получения строки, потом разбивки её на массив и вызов для каждого элемента массива, функции вывода по id) вытащить все записи у которых такие id, но в другой таблице? Впринципе вариант с двумя функциями подходит, мне интересно как сформулировать запрос, который вытащит все записи по id в виде строчки
#416 #635131
JS петух в треде, какие фреймворки учить для backend'а на этом вашем php? Или делать backend тоже на JS?
#417 #635169
Бывают такие случаи, что без куки никак не обойтись, во всяком случае мне так кажется. Но что если куки у пользователя отключены? Как поступать в этом случае? Возможно я ошибаюсь, но кажется многие сайты, и очень хорошие сайты используют куки в своей работе, причём не имеют альтернативных вариантов выполнения тех функций, для которых необходимы куки.
#418 #635179
>>635107
А можно без выебонов ответить?
#419 #635215
>>635169

Ничего не делать. Те, кто отключают куки, должны быть готовы что авторизация и сохранение настроек может перестать работать. Но может им это просто не нужно?
#420 #635236
Что-то я не особо понял что сделал http://ideone.com/9g8R4o
#421 #635238
>>635215

>Те, кто отключают куки


В последнее время постоянно вижу предупреждения на сайтах, что с выключенными куками многое недоступно, можно вот такое предупреждение выводить.
Все равно таких поехавших не так уж и много, скорее всего, от общего количества пользователей.
#422 #635246
>>635236
Когда кредитбаланс меньше манслипеймент, надо выплатить и оборвать цикл, иначе он закрутится надолго.
Также логика не чувствуется: когда кредитбаланс меньше 5000 - месячная выплата становится кредитбалансом - а дальше-то что?
А дальше её надо бы выплачивать и обрывать цикл как раз, а у тебя всё закручивается.
#423 #635259
Как я могу упростить это? Как-то много кода получилось по моему. http://ideone.com/Skje0K
#424 #635261
>>635246
Я пытался сделать чтоб месячная выплата была столько, сколько осталось кредитбаланса, но не получается ничего.
#425 #635284
>>635261
А зачем именно месячную выплату менять?
Можно просто заплатить столько, сколько осталось - выйти из того круга, где отнимается месячная выплата.
Ты хотел, чтобы она поменялась, а потом цикла заново прошёлся и всё выплатилось, я правильно понял?
Так-то интересный подход, такого пока ещё не встречал.
Ошибка там в том, что цикл надо после этого последнего прохождения уже после изменения манслипеймент оборвать - иначе он снова попадает в условие "если кредитбаланс меньше 5000".
Попробуй разделить на if и else, например.
В else помести это всё, что у тебя до условий, а в if то же, что и есть, плюс вывод последнего echo с окончательной суммой.
#426 #635296
>>635284
в общем получилось как-то так http://ideone.com/9g8R4o Опять же не уверен, что сделал правильно, потому что не могу на 100% понять что делаю. Только в последний месяц он заплатил 5262.
#427 #635306
Почему в шапке нет сравнений IDE для PHP и советы лично от ОПа?
#428 #635316
>>635296
Нет, неверно считает. Должно получиться 61270 и много цифр после точки.
Также неверно считает, если поставить сумму кредита 1000 - http://ideone.com/Ud7IPy
Должно ведь быть 2030 - сумма кредита, тысяча за обслуживание кредита и 30 - проценты от суммы кредита.
Смотрю на сам алгоритм: если осталось выплатить, например, 4000 уже после умножения на проценты и прибавления - у тебя от этого ещё раз отнимается сначала 5000 манслипеймент, уже в минусе попадает в условие, там меняется манслипеймент и ещё раз идёт в цикл.
В какой-то момент, короче, у тебя в минус уходит, этого не должно быть.
#429 #635320
>>635306
Да, скажите правду, какой самый лучший редактор.
Когда-то пробовал Sublime text, было про охуительно, есть ли что лучше?
#430 #635333
>>635320
шторм
#431 #635348
>>635316
Таки правильно? http://ideone.com/9g8R4o
#432 #635353
>>635316
Хотя считает все равно не правильно.
#433 #635358
>>635333
Эх блин, он платный, воровать не хочется. А из бесплатных редакторов какой лучше?
#434 #635373
#435 #635393
>>635358
он бесплатно активируется, поищи на рутрекере.
#436 #635402
#437 #635406
>>635358
netbeans
#438 #635408
>>635358
Ставь шторм. Не повторяй моих ошибок.
#439 #635412
>>635358
notepad++
#440 #635429
>>635393
Рубисты в соседнем треде на китайском сервере активируются, может и со штормом заработает:
http://idea.lanyus.com/
#441 #635442
>>635348
>>635353
Ноуп, неправильно - ты и сам видишь.
Совет: введи дополнительную переменную для подсчёта долга без отнимания манслипеймент и проверяй в if, чтобы именно она была меньше 5000. Если именно этот долг (а не с отнятой месячной платой) меньше месячной платы - выплачивай именно его и прибавляй его к пейменттотал.
#442 #635460
>>635429
Все работает.
https://github.com/toppestkek/GuestBook #443 #635485
>>629862

Папки nbproject и vendor надо убрать из репозитория и добавить в .gitignore.

https://github.com/toppestkek/GuestBook/blob/master/.htaccess
Вот тут я бы убрал <IfModule mod_rewrite.c>. Без него, если модуля нет, то будет ошибка 500. А с ним ошибка будет тихо проигнорирована, хотя приложение работать не будет.

Далее: http://pastebin.ru/98nq0FN7 так как сервер думает что это я его взломать пытаюсь текстом.
Немного за 20 января #444 #635486
>>629883

> $sentences = explode(PHP_EOL, $text);


Не советую. Надеюсь, ты знаешь что в разных ОС и разных редакторах конец строки кодируется по-разному: как \n или как \r\n (были еще варианты с \r на старых маках, но сейчас это неактуально). PHP_EOL на винде равен \r\n, под линуксом равен \n. Но где гарантия что в твоей программе использован тот же символ конца строки что и на платформе где она запускается? Гарантий нет. Значит, этот код может не сработать.

Правильнее всего бить на строки по символу \n (так как он входит в оба варианта), а потом отрезать \r если он есть, через trim. Либо бить регуляркой которая вырежет любой из вариантов (надо написать выражение "\n, перед которым может быть, а может не быть, \r").

> foreach($sentences as $key => &$value) {


Зачем тут & ? Также, называй переменные нормально, $value ничего не значит и ее надо переименовать.

> '/(?<!^)(?!$)/u'


Сложновато, по моему проще сделать preg_split("//u", $text, null, PREG_SPLIT_NO_EMPTY). //u соответствует границам между буквами, а константа в конце убирает пустые элементы в начале и конце массива.

> /заполняем остальные массивы пробелами, чтобы все стали равны/


Проще при выводе проверять в массиве мы или нет, и если нет то выводить пробел

> for ($c = 0; $c < $max; $c++){


> for ($e = 0; $e < count($letters); $e++ ){


Названия неудачные у переменных, может лучше было x/y?

> $max


maxLength

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

> $print = "";


Тут наверно проще сразу echo писать.

>>629943

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

Вот есть такое https://play.google.com/store/apps/details?id=ru.kslabs.ksweb , но это просто сервер (пхп + майэскуэл), без редактора и браузера (то есть нужен сторонний редактор кода и например встроенный браузер для запуска скрипта).

Есть такое https://play.google.com/store/apps/details?id=org.kidinov.awd но это редактор с браузером без сервера (в качестве него можно использовать приложение выше).

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

В любом случае, тебе надо (по отдельности или в одном приложении):

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

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

>>629949

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

>>630081

Слышал звон, да не знаю, где он. Соль сильно замедляет перебор паролей, защищает от использования заранее вычисленных таблиц хешей и скрывает факт наличия одинаковых паролей в базе. Она нужна однозначно.
Немного за 20 января #444 #635486
>>629883

> $sentences = explode(PHP_EOL, $text);


Не советую. Надеюсь, ты знаешь что в разных ОС и разных редакторах конец строки кодируется по-разному: как \n или как \r\n (были еще варианты с \r на старых маках, но сейчас это неактуально). PHP_EOL на винде равен \r\n, под линуксом равен \n. Но где гарантия что в твоей программе использован тот же символ конца строки что и на платформе где она запускается? Гарантий нет. Значит, этот код может не сработать.

Правильнее всего бить на строки по символу \n (так как он входит в оба варианта), а потом отрезать \r если он есть, через trim. Либо бить регуляркой которая вырежет любой из вариантов (надо написать выражение "\n, перед которым может быть, а может не быть, \r").

> foreach($sentences as $key => &$value) {


Зачем тут & ? Также, называй переменные нормально, $value ничего не значит и ее надо переименовать.

> '/(?<!^)(?!$)/u'


Сложновато, по моему проще сделать preg_split("//u", $text, null, PREG_SPLIT_NO_EMPTY). //u соответствует границам между буквами, а константа в конце убирает пустые элементы в начале и конце массива.

> /заполняем остальные массивы пробелами, чтобы все стали равны/


Проще при выводе проверять в массиве мы или нет, и если нет то выводить пробел

> for ($c = 0; $c < $max; $c++){


> for ($e = 0; $e < count($letters); $e++ ){


Названия неудачные у переменных, может лучше было x/y?

> $max


maxLength

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

> $print = "";


Тут наверно проще сразу echo писать.

>>629943

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

Вот есть такое https://play.google.com/store/apps/details?id=ru.kslabs.ksweb , но это просто сервер (пхп + майэскуэл), без редактора и браузера (то есть нужен сторонний редактор кода и например встроенный браузер для запуска скрипта).

Есть такое https://play.google.com/store/apps/details?id=org.kidinov.awd но это редактор с браузером без сервера (в качестве него можно использовать приложение выше).

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

В любом случае, тебе надо (по отдельности или в одном приложении):

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

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

>>629949

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

>>630081

Слышал звон, да не знаю, где он. Соль сильно замедляет перебор паролей, защищает от использования заранее вычисленных таблиц хешей и скрывает факт наличия одинаковых паролей в базе. Она нужна однозначно.
Немного за 20 января #445 #635488
>>630090

> В аплоадс у меня стоит хтаксесс с таким кодом, поэтому нельзя.


Ты по моему не очень понял как работает htaccess. Загрузка файла идет через скрипт index.php, потому настройки из htaccess вроде uploads_max_size в папке uploads не применяются. Настройки из uploads/.htaccess применяются только если из браузера запустить расположенный в этой папке скрипт. Также, у тебя есть php_flag engine 0 который запрещает выполнение скриптов из этой папки, но это мало:

- злоумышленник может загрузить свой htaccess и перезаписать твой
- на некоторых хостингах настройка php_flag игнорируется и твоя защита отключится

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

>>Непарвильное использование иключений


> А какое правильное?



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

----------

Давай начнем с теории. Знаешь ли ты зачем придуманы исключения? Читал ли урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Если нет, прочитай.

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

try {
$app->run();
} catch (..) {
$app->showErrorPage();
}

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

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

----------

Как надо обрабатывать исключения:

- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс

Что будет если использовать catch + echo:

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

Как будет если просто не ловить исключение:

- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)

-----------

> А хз, лень было писать заново мвк, взял из какого-то старого примера, в тестовом условием было не использовать фреймворки, так-то бы я взял нормальный роутер от микрофреймворка.


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

>>Инициализацию всяких объектов лучше вынести из контроллера.


> Куда это их вынести? В новый объект?


В файл где инициализаируется приложение - там можно создать нужные объекты-сервисы один раз и после этого везде их использовать.
Немного за 20 января #445 #635488
>>630090

> В аплоадс у меня стоит хтаксесс с таким кодом, поэтому нельзя.


Ты по моему не очень понял как работает htaccess. Загрузка файла идет через скрипт index.php, потому настройки из htaccess вроде uploads_max_size в папке uploads не применяются. Настройки из uploads/.htaccess применяются только если из браузера запустить расположенный в этой папке скрипт. Также, у тебя есть php_flag engine 0 который запрещает выполнение скриптов из этой папки, но это мало:

- злоумышленник может загрузить свой htaccess и перезаписать твой
- на некоторых хостингах настройка php_flag игнорируется и твоя защита отключится

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

>>Непарвильное использование иключений


> А какое правильное?



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

----------

Давай начнем с теории. Знаешь ли ты зачем придуманы исключения? Читал ли урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Если нет, прочитай.

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

try {
$app->run();
} catch (..) {
$app->showErrorPage();
}

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

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

----------

Как надо обрабатывать исключения:

- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс

Что будет если использовать catch + echo:

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

Как будет если просто не ловить исключение:

- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)

-----------

> А хз, лень было писать заново мвк, взял из какого-то старого примера, в тестовом условием было не использовать фреймворки, так-то бы я взял нормальный роутер от микрофреймворка.


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

>>Инициализацию всяких объектов лучше вынести из контроллера.


> Куда это их вынести? В новый объект?


В файл где инициализаируется приложение - там можно создать нужные объекты-сервисы один раз и после этого везде их использовать.
Немного за 20 января #446 #635489
>>630102

> 1) Задача про миллион в банке


> $sum <= 1000000;


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

И форматирование поплыло, плохо, почитай второй пост треда. Ответ получился правильный.

> 2) Генератор стихов:


> [mt_rand(0,count($word1))]


Тут ошибка, в массиве нет элемента с индексом count(...).

Вот внизу видно это:

> PHP Notice: Undefined offset: 9 in /home/hS3YjN/prog.php on line 17


> PHP Notice: Undefined offset: 7 in /home/hS3YjN/prog.php on line 19



> палиндром


> $lower = mb_strtolower($text);


> $str = str_replace(" ", "", $lower);


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

> $secondHalf = mb_substr($str, -1, 1);


Это берет всегда последнюю букву, а не N-ю с конца.

> if ($i = $halfLenght) {


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

Эта задача пока решена неправильно.

>>630116

С такой манерой общаться ты ответа не дождешься.
Немного за 20 января #446 #635489
>>630102

> 1) Задача про миллион в банке


> $sum <= 1000000;


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

И форматирование поплыло, плохо, почитай второй пост треда. Ответ получился правильный.

> 2) Генератор стихов:


> [mt_rand(0,count($word1))]


Тут ошибка, в массиве нет элемента с индексом count(...).

Вот внизу видно это:

> PHP Notice: Undefined offset: 9 in /home/hS3YjN/prog.php on line 17


> PHP Notice: Undefined offset: 7 in /home/hS3YjN/prog.php on line 19



> палиндром


> $lower = mb_strtolower($text);


> $str = str_replace(" ", "", $lower);


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

> $secondHalf = mb_substr($str, -1, 1);


Это берет всегда последнюю букву, а не N-ю с конца.

> if ($i = $halfLenght) {


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

Эта задача пока решена неправильно.

>>630116

С такой манерой общаться ты ответа не дождешься.
#447 #635582
>>635489
ОП-чик, помоги с алгоритмами и с маршрутом>>635027
#448 #635588
>>634989

>PHP


>слушать порт


Дуин ит вронг.

>многопоточность


Можно тредами, можно просто рожать новые процессы (подобный подход в апаче и прогах написанных на erlang), можно poll/epoll/kqueue (так делает nginx).
#449 #635597
>>635588
К слову, в php есть pecl event (обёртка над libevent), а в его доках есть примеры).
http://docs.php.net/manual/en/event.examples.php - третий семпл, Echo server.
Но всё равно, писать сетевые сервисы на похапе - изврат лютый.
#451 #635614
>>635611
Какая-то таблица не существует, соррян, типа, азаза))0)))
#452 #635616
>>634873

>Если вас пропустили, не ответили, не проверили, не дали совет - напомните о себе в этом треде.



Меня пропустили. Анлаки.
#453 #635618
>>635611
Тебе же написало, таблицы не существует.
#454 #635702
Как закрыть страницу на которой обрабатывается форма и подключаются все классы? Чтобы при этом она работала, как надо. То есть как сделать так, чтобы на неё нельзя было попасть, а при попытке ввести её урл в браузерной строке, что-то выводилось.
#455 #635705
>>635702
Вынести код обработки формы в тот же файл, который отправляет форму.

Или вынести страницу обработки формы за корень сервера (тогда её нужно будет подключать через include).
#456 #635746
>>635442
А чему должна быть равна дополнительная переменная?
#457 #635770
>>635618
я понимаю что ты тупая школота и лишь бы ответить, но почему к ней вообще идет запрос - подумай над этим, мидлом станешь базарю.
#458 #635773
>>635770

>МАМ СМОТРИ все школота а я взрослый

#459 #635783
Проверьте задачку на кредит на айфон: http://ideone.com/CvzJ2a

Чёт я сомневаюсь но всё же, вроде верно. Проверку на меньше ли нуля я убрал так как по идее оно должно(?) тютелька в тютельку забирать весь долг. Но сомнительно.
#460 #635795
>>635783

>$creditBalance = ( $creditBalance * $percent ) + $servicePayment - $creditBalance;


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

>if ($creditBalance >= 5000)


Не вполне правильно основные действия сразу связывать с подобным условием. Ведь $creditBalance у нас к моменту попадания в подобное условие уже должен быть умножен на 1.03 и с прибавленной комиссией за пользование кредитом.
#461 #635798
>>635795
Ок, буду снова думать.

Я писал $creditBalance = ( $creditBalance * $percent ) + $servicePayment - $creditBalance;
с логики мол если остаётся меньше 5000 после всех процентов и прибавлений, то просто отнимаем это всё финальным ходом.
Какая-то дурная задача, ну да ладно, я её-таки решу.
#462 #635802
>>635798
Вообще советую дополнительную переменную ввести для баланса кредита - баланс, умноженный на процент и с прибавленной комиссией, но без отниманий месячной выплаты и тому подобного.
Вот именно когда она становится меньше 5000 - нужно просто её выплатить и прибавить к общим выплатам, оборвать цикл.
247 Кб, 604x478
#463 #635809
>>635588
>>635597
На чем могу, мяш, на том и приходится писать. Спасибо тебе.
#464 #635811
>>635770

>но почему к ней вообще идет запрос


очевидно, потому что ты его делаешь
#465 #635828
Почему меня игнорируют с просьбой помочь с навигатором? >>634964
#466 #635831
Кто работал с третьим слимом, подскажите где взять подробную документацию к нему.
У них на сайте нашел только этот http://www.slimframework.com/docs/ юзергайд, но там нет и половины того, что было в документации ко второй версии.
#467 #635833
>>635831
http://docs.slimframework.com/ есть только такой, но это вроде ко второму.
#468 #635839
>>635833
Да, это ко второму, но все равно спасибо.

Просто я невнимательный, уже нашел то что мне нужно тут http://www.slimframework.com/docs/handlers/error.html
#470 #635859
>>635852
Но я уже спрашивал насчёт алгоритмов. Можно ли решить без них(как предполагается по подсказке ОПа), а если нет, то где почитать вообще вводное что-либо про алгоритмы?

Я даже не слышал про них, погуглив - это кромешный ужас и пиздец, НИЧЕГО не понятно
#471 #635861
>>635811
Неправильный ответ, я делаю обычный селект, не стать тебе програмиздом, пиздуй в ашан.
119 Кб, 421x404
#472 #635862
#473 #635865
>>635861
Сделай необычный селект, вдруг поможет
#474 #635877
Бля, я здаюсь. Как делается эта грёбанная задачка на айфон? У меня уже мозг кипит, всё никак не выходит.
#475 #635886
>>635877
5.1 которая?
#476 #635889
>>635877
Не отвечайте, ушел дальше ебаться с этим айфоном, то был приступ отчаянья.
#477 #635890
>>635889
Её вроде бы можно решить одним условием, если мне не изменяет память. Подумай каким.
#478 #635901
>>635890
Ну я думал сделать алгоритм, мол стандартный цикл, а в цикле идёт проверка - если долг с процентами и прибавкой за саму услугу больше или равно 5к, то стандартная выплата долга, если меньше, то вместо 5к мы отнимаем тот остаток вместе с процентами и прибавкой 1к. Потом смотрим если долг меньше 0, то значит завершаем брейком цикл и пишем "Хватит". Но что-то не то, надо нарисовать себе.
#479 #635910
>>635611
Это скриншот с ошибкой phpmyadmin. А что?

Если тебя интересует причина, гугли по тексту ошибки.
Из того что я нашел, вроде есть несколько вариантов:
1. Для использования некоторых специальных опций нужно создать дополнительные таблицы (Linked-tables infrastructure). Скрипт для создания этих таблиц лежит где-то в phpmyadmin/scripts/create_tables.sql
2. Баг pma на убунте.
3. Конфликт со сборкой.

Выводы: не пользоваться pma, wamp-сборками и прочими инструментами быдлокодера.
#480 #635916
>>635910
А чем админят базы данных небыдлокодеры?
9 Кб, 229x220
#481 #635918
>>635916
Консолькой.
#482 #635923
#483 #635927
можно подумать для быдло пхп придумали какие-то небыдло инструменты работы с майсоклом, кроме быдло пхпадмина. вот с жавой у меня таких проблем нет. оче удобно работать с бд в жаве из консоли да. вывод? пхп-быдло яп и инструменты у него быдло-tier.
#484 #635928
>>635916
https://www.mysql.com/products/workbench/ из бесплатного например. Может с ним у тебя проще пойдет.
#485 #635929
>>635927
Ваше мнение очень важно для нас. Оставайтесь на линии.
#487 #635941
>>635901

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


>Потом смотрим если долг меньше 0, то значит завершаем брейком цикл и пишем "Хватит".


Всё абсолютно верно. Только если ты тот анон, которому я объяснял выше - у тебя от суммы кредита ещё и месячная выплата каждый раз отнимается, что путает всё, когда ты сравниваешь её с 5000 в одном условии.
#488 #635945
Парни, проверьте задачку на ипхон.
Теперь то кажись правильно! http://ideone.com/NUiAXY

Пасибо анону, что посоветовал придумать новую переменную . Сам тогда об этом думал, но казалось что ничего нового не надо. И да, сначала выводило херню, думал ДА ЧТО ЖЕ ЭТО ТАКОЕ, а оказалось что надо в цикл впихнуть обьявление переменной. И то правильно - чтоб оно не 40000 постоянно брало а постоянно менялось.
#489 #635946
>>635941
Тот анон и был я:)
Вот проверь - >>635945
#490 #635948
>>635945
Считает правильно, но код можно было написать получше.
#491 #635949
>>635945
Алсо, тут может быть небольшая ошибка когда я ставил условие проверки если будет меньше 0. Тупо не нужны эти строки наверное. Но хз.
upd
#493 #635951
Помогите выбрать нормальный бесплатный редактор:
vim/atom/brackets/ваши приложения
Сублим не понравился.
#494 #635952
>>635951
Блокнот++
#495 #635954
>>635950

>$creditBalance = ($creditBalance * $percent) + $servicePayment - $monthlyPayment;


>$paymentTotal= $paymentTotal + $monthlyPayment;


>echo "{$month} месяц спустя: долг = {$creditBalance} руб, выплачено всего {$paymentTotal} руб. \n";


Ты копипастишь один и тот же код два раза. Я не понимаю зачем это.
#496 #635957
>>635954
Ну там не прям копипаста, один раз добавляет обычные 5к а другой - monthlyPayment.

Алсо, а что ты предлагаешь?
#497 #635961
>>635951
А что такое "нормальный" редактор?
Какой функционал тебе нужен?
Чем "сублим" не понравился?

Попробуй загуглить и проанализировать преимущества и недостатки.
Ну или подождать пока в этом треде проголосует каждый даун, которому понравилась цветовая схема конкретного редактора.
#498 #635964
>>635931
жава намного быстрее пхп работает кстати.
#499 #635966
>>635964
Cool story, bro
#500 #635967
>>635957
Редактировать значение переменной monthlyPayment, вместо того чтобы вводить новую переменную и сравнивать её каждый раз.
#501 #635980
>>635961
Сублим не приятен внешне, темы на него хуёвые, шрифты там говно, больше половины плагинов уёбищный, другая половина ебанутая.
Жрёт как атом (а атом лучше него в разы).
#502 #635981
>>635980
Notepad++
#503 #635982
>>635981
Я с макбука.
#504 #635984
>>635982
Если любишь по вечерам пердолить консольку - vim
Если не любишь - brackets, atom
#505 #635985
>>635945
>>635946
Ну молодца! Я каждый раз радуюсь, когда кто-нибудь справляется с этой задачей - как будто я сам снова пережил то, как с ней справился.
Другой анон верно говорит: от копипасты надо избавляться, особенно, когда в цикле всё крутится и несколько раз считает одно и то же.

>$variable = ($creditBalance умножить $percent)


>$creditBalance = ($creditBalance умножить $percent) + $servicePayment - $monthlyPayment;


Это ведь тоже можно сократить.
Вообще всё условие if ($variable >= 5000) не особо и нужно - цикл сам по себе будет работать и всё делать, а должен среагировать только тогда, когда $variable < 5000.
Это можно даже не в else убрать, а просто так оставить в теле цикла.
>>635967
Можно и так, действительно.
#506 #635987
>>635985
Я тоже прям приток мотивации получил, как решил. Весь день думал да что ж не так. Аж с души камень.
21 Кб, 400x369
#507 #635993
>>635987
Я вот так же сейчас сражаюсь с задачей на числа прописью.
Но у тебя до неё ещё несколько подобных будут: Grammar Nazi с исправлением текста, проверка телефонного номера, клавиша Shift.
Зато потом можно будет не глядя многое раскладывать, приобретается какой-то небольшой опыт.
#508 #636071
>>635597
Node.js для этого подойдет лучше?
#509 #636079
>>636071
Можно на пайтоне за пару часов написать скрипт который будет это делать на всех ОС. node.js нужен будет только если ты собираешься к этому парсеру еще и веб-сервер прикручивать.
#510 #636102
Я вчерашний анон который не мог решить задачу с айфоном http://ideone.com/wvluld Мне предлагали ввести новую переменную, но что-то я не особо понял что куда вводить и как считать, помогите, а то я уже устал от нее, чувствую скоро дропну.
#511 #636104
>>636102

>if ($creditBalance < 5000)


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

если оплата за текущий месяц меньше переменной monthlyPayment {
monthlyPayment = оплата за текущий месяц
}
#512 #636115
Никак не могу разобраться с составными индексами.

Попробуем на таком примере: есть таблица для хранения nested sets.
CREATE TABLE `category` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lft` int(10) unsigned NOT NULL,
`root` int(10) unsigned NOT NULL,
`level` int(10) unsigned NOT NULL,
...
PRIMARY KEY (`id`),
KEY `ix_level_root_lft` (`level`,`root`,`lft`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8

В таблице 1 000 000 записей.
Запрос:
SELECT id, lft, root, level FROM category WHERE level IN (1,2) ORDER BY root, lft; // наверное таки лучше between, но не суть важно

Explain:
id: 1
select_type: SIMPLE
table: category
type: range
possible_keys: ix_level_root_lft
key: ix_level_root_lft
key_len: 4
ref: NULL
rows: 39458
Extra: Using where; Using index; Using filesort

Здесь непонятен момент с filesort. Как говорит документация,

>MySQL must do an extra pass to find out how to retrieve the rows in sorted order. The sort is done by going through all rows according to the join type and storing the sort key and pointer to the row for all rows that match the WHERE clause. The keys then are sorted and the rows are retrieved in sorted order.


Если я правильно понял, будет совершен дополнительный проход, чтобы отсортировать данные в нужном порядке. Но зачем? Разве в индексе они не хранятся в отсортированном виде? Судя по key_len = 4, вторая и третья часть индекса вообще не используется.
Хотя судя по времени выполнения запроса, очень даже используется: с индексом только на (level) запрос 0.20с, индекс (level, root, lft) занимает 0.06с.

Что-то я не понимаю, как это работает.
#512 #636115
Никак не могу разобраться с составными индексами.

Попробуем на таком примере: есть таблица для хранения nested sets.
CREATE TABLE `category` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`lft` int(10) unsigned NOT NULL,
`root` int(10) unsigned NOT NULL,
`level` int(10) unsigned NOT NULL,
...
PRIMARY KEY (`id`),
KEY `ix_level_root_lft` (`level`,`root`,`lft`)
) ENGINE=InnoDB AUTO_INCREMENT=1000001 DEFAULT CHARSET=utf8

В таблице 1 000 000 записей.
Запрос:
SELECT id, lft, root, level FROM category WHERE level IN (1,2) ORDER BY root, lft; // наверное таки лучше between, но не суть важно

Explain:
id: 1
select_type: SIMPLE
table: category
type: range
possible_keys: ix_level_root_lft
key: ix_level_root_lft
key_len: 4
ref: NULL
rows: 39458
Extra: Using where; Using index; Using filesort

Здесь непонятен момент с filesort. Как говорит документация,

>MySQL must do an extra pass to find out how to retrieve the rows in sorted order. The sort is done by going through all rows according to the join type and storing the sort key and pointer to the row for all rows that match the WHERE clause. The keys then are sorted and the rows are retrieved in sorted order.


Если я правильно понял, будет совершен дополнительный проход, чтобы отсортировать данные в нужном порядке. Но зачем? Разве в индексе они не хранятся в отсортированном виде? Судя по key_len = 4, вторая и третья часть индекса вообще не используется.
Хотя судя по времени выполнения запроса, очень даже используется: с индексом только на (level) запрос 0.20с, индекс (level, root, lft) занимает 0.06с.

Что-то я не понимаю, как это работает.
#513 #636122
Какой уровень знаний надо иметь в похапе, чтоб взяли джуном?
#514 #636123
>>636122
бальшой
#515 #636124
>>636102
Не вздумай дропать!
тоже думал, но взял яйца в кулак и засел, пошевелил мозгами и решил
#516 #636125
>>636123
не траль:(
#517 #636172
>>636115
Кажется, понял (вернее, догадываюсь): чтобы работала сортировка по индексу, нужно поставить колонки из order by в начало (root, lft, level). Но меня это не устраивает, потому что тогда индекс не будет использован для where, вернее мы получим jointype = index вместо range, что означает фуллскан по индексу и увеличение времени в десятки раз (0.93с).

В общем, получается тут по-другому никак, индекс на (level, root, lft) оптимальный. Сортировка будет выполнена вторым проходом, но это не страшно, потому что данные берутся прямо из индекса (using index), к таблице вообще нет обращений.
Если же сделать индекс только на (level), то using index уже не будет, данные браться из таблицы а не индекса, а время увеличится в 3-4 раза.

Совсем хорошо было бы, если бы мне вообще не нужна была сортировка в запросе. В индексе (level, root, lft) данные уже отсортированы в соответствующем порядке. Меня правда этот порядок не очень устраивает, потому что я получу сначала все категории первого уровня, а потом уже все дочерние. Задача состояла именно в получении блоков вида корень+дети.
Или прямо в php отсортировать массив? Черт его знает.
#518 #636195
http://ideone.com/Bsg7kH я уже потерял какую либо логику. Написал такого, что уже и сам перестал разбираться.
#519 #636210
>>636195
Тебе нужно было сделать одно условие в начале цикла, как я написал тут >>636104

Зачем ты начал велосипеды строить?

>$creditBalance = ( $creditBalance * $percent ) + $servicePayment - $monthlyPayment;


>$paymentTotal = $paymentTotal + $monthlyPayment;



Вот это два раза копипастишь, когда этого делать совсем не нужно.
#520 #636215
>>636210
Я в этих велосипедах пытался найти выход, но все равно ничего не получилось )
#521 #636243
>>636215
Просто описывай жизненный процесс в программе.
Один проход цикла это один месяц.
Что происходит вначале месяца? Банк начисляет проценты:
$creditBalance = ( $creditBalance * $percent ) + $servicePayment;
Что потом? Мамка дает школотрону 5000. Он идет в банк и узнает сколько осталось выплатить, если больше его 5000 платит сколько может (т.е. все 5000) если меньше платит сколько нужно и забывает про это все. (Выходит из цикла).
Тут был код, но я его удалил. Нужно все таки самому сделать условие.
#522 #636252
>>636102

>$creditBalance = ( $creditBalance $percent ) + $servicePayment - $monthlyPayment;


Когда у тебя $creditBalance становится, допустим, 3000 - ты отнимаешь от него $monthlyPayment, сумма уходит в минус, так не должно быть.
Тебе надо либо ввести переменную для подсчёта только ( $creditBalance
$percent ) + $servicePayment, либо отнимать от$creditBalance эти самые 5000 в $monthlyPayment в основном условии, когда цикл продолжает работу.
А когда именно эта вот сумма ( $creditBalance $percent ) + $servicePayment становится меньше $monthlyPayment - именно тогда надо её выплатить, посчитать $paymentTotal и оборвать цикл.
И это можно сделать как изменением $monthlyPayment, так и простой выплатой вот этого окончательного ( $creditBalance
$percent ) + $servicePayment (той самой переменной, о которой я и говорил).
>>636124
Советую помогать братишкам - так сам ещё лучше разберёшься в задаче, я базарю.
#523 #636268
>>636252
Чёртовы звёздочки опять.

>>636195
Аа, вот тут уже ближе, неплохо!
Ты на верном пути.
#524 #636272
Аноним #525 #636273
>>629822 (OP)
W4.2 Сделай рулетку, то есть генерируется 6-значный номер поста, и, в зависимости от последней цифры, что-то пишется (что, придумай сам). Подсказка: чтобы найти последнюю цифру числа, возьми остаток от деления на 10: $lastDigit = $number % 10
Аноним #526 #636274
>>636273
как это решать, я не могу понять ((
#527 #636277
>>636274
Подсказка - случайное число в PHP генирирует функция rand.

http://php.net/manual/en/function.rand.php мануал
#528 #636279
>>635859
Блять, такое ощущение, что игнорируют. Просто игнорируют вопросы про алгоритмы!
#529 #636280
Насколько сильно нужно погружаться в HTML? Поверхностные знания достаточны или надо зубрить всё это?
#530 #636281
>>636195
В последнем if ошибка: там должно быть равно нулю, а не меньше.
Совет, который всё решит: просто вынеси в else то, что у тебя стоит в условии if ($gg > 5000). Попробуй, базарю - ещё захочешь.
#531 #636284
>>636280
Если хочешь в будущем быть fullstack разработчиком тебе обязательно нужно будет знать HTML и уметь верстать шаблоны любой сложности.
#532 #636285
>>636284
Я просто увяз в ХТМЛ и никак не дойду до главы с ООП и проч. Вот и думаю дропнуть пока этот ХТМЛ и вернуться к нему позже, если потребуется
Аноним #533 #636287
>>636277
спасибо няш:*
#534 #636288
>>636285
Можешь и так попробовать, но для задачи на список студентов, например, уже нужно будет уметь сверстать простой шаблон.
458 Кб, 429x604
#535 #636289
>>636285
Увяз в HTML после Лилички, чисел пропись, калькулятора, ещё кучи сложных задач?..
Я не понимат.
#536 #636290
>>636289
так тема-то обширная последние две задачи пропустил, чересчур сложные для меня
#537 #636292
>>636288
поясни за такую терминологию. Сверстать шаблон - это чё?
#538 #636297
И ещё сразу: что лучше для HTML - html academy или codeacademy?
#539 #636300
>>636290

>последние две задачи пропустил, чересчур сложные для меня


Последние две страницы с задачами, наверное?
Куда так торопишься-то? Получай удовольствие от того, что можешь, успеешь ещё во всём разобраться.
А то будешь как многие в треде: уже изучал, но всё забыл, на прошлой неделе писал сложный скрипт, а сейчас не могу вспомнить, как разложить массив в цикле.
Неосновательно как-то.
#540 #636301
>>636252
Я на правильном пути? http://ideone.com/wvluld Просто будет грустно если я опять делаю совсем не то.
#541 #636303
>>636292
Шаблон это визуальное представление в веб-приложении. Т.е. то, что видит и с чем взаимодействует пользователь.
#542 #636306
>>636300
Да нет, именно задачи. Ту, где буквы в круг встают - вообще убил мозг тригонометрией (не моё, сука, не моё).

И последнюю с навигатором. Оче долго пытал и мучал задачу, в итоге тут ОП посоветовал сделать по алгоритмам, а я впервые о них слышу и вообще не имею представления о них. Более внятной помощи не добился (посмотри по треду). Вот так и живу.
#543 #636307
>>636301
Братишка, вот тут правильный путь: >>636281
У тебя там путаница с лишними прохождениями цикла, это всё решит.
Ну и $creditBalance = 0 - это не сравнение, а присваивание.
Не elseif, а просто else - сам по себе будет цикл крутиться, пока не попадёт сначала в условие, что оставшаяся сумма меньше 5000, а потом в условие, что $creditBalance равняется 0.
#544 #636311
>>636306
Я знаю это чувство, бро.
Вторая неделя идёт битвы с числами прописью, хочется сделать по-человечески, а не через задницу.
Буквы в круге - мне бы хоть дойти...
#545 #636316
Кто-нибудь пытается зарабатывать на фриланс-сайтах? Такое ощущение что большинство заданий там, это поправить какую-то CMS, которую впервые слышишь и информации о которой в интернете не так и много. Я знаю php, jQuery, на базовом уровне javascript, css, html, на базовом уровне знаю вордпресс, могу верстать из ПСД и натягивать на вордпресс, но вообще никакой работы не могу найти на фрилансах сайтах.
#546 #636324
>>636316
На базовом уровне знаний недостаточно. Учи симфони, юи, ларваель и вордпресс до нормального уровня.
Иди на upwork.com и получай свои $500 в месяц.
Работа там в основном что-нибудь типа: Сверстать шаблон для вордпресса, натянуть шаблон на вордпресс, написать плагин для вордпресса, пофиксить баги в плагине для вордпресса, пофиксить баги в приложении на юи или симфони.
В /wrk/ есть годный тред по апворку, о русскоязычных фриланс-биржах даже не думай, там одно наебалово и зарплата в рублях.
#547 #636326
>>636324
И еще помни что фриланс на подобных сайтах это не сколько твои навыки в программировании, сколько твои социоблядские скиллы и умение себя продать, умение убедить клиента почему он должен нанять именно тебя, а не какого-нибудь индуса, который еще и денег меньше просит.
#548 #636329
>>636326
То есть упор на вордпресс нужно делать, чтобы туда влиться?
#549 #636334
>>636329

Я, кстати, недавно об этом же писчал, когда смотрел заказы >>631251
#550 #636337
>>636334
Щито такое вордпресс?
#551 #636338
>>636329
Можешь зайти и почитать описание заданий в категории web development. Большая половина там это вордпресс или какие-нибудь приложения на модных фреймворках. Бывают и заказчики которые абсолютно ничего не понимают в в вебе, и сами не знают чего они хотят.
138 Кб, 677x934
#552 #636340
>>636329
>>636334
>>636338
Вот открыл рандомную страницу в категории веб разработки.

На каждое задание там уже 50+ кандидатов, лол.
#553 #636343
>>636340
Проорал со скрина на всю квартиру.
#554 #636345
>>636343
Это еще нормально, там есть азиаты которые пытаются по английски писать, но у них это получается еще хуже чем у русских. В итоге уже на стадии описания задачи ты не понимаешь что от тебя нужно.
#555 #636355
Кстати, а вот по поводу английского, само собой он очень нужен. Но я его в свои 25 лет, не знаю вовсе, есть ли какой-нибудь лёгкий вариант изучения английского необходимый программистам? Или тут так не обойтись, надо знать досконально?
#556 #636358
>>636355
Cмотри сериалы, читай книжки. Где ты был все 25 лет, живёшь в чайнике?
#557 #636361
>>636358
Я вот смотрю ( не читаю правда, как-то пробовал осилить престолы в оригинале, дропнул после 250 страниц, слишком часто в словарь приходилось заглядывать). Воспринимать текст (ну и речь худо-бедно) и переводить могу, а вот говорить и выражать свои мысли очень туго выходит. Так что тут нужно еще и практиковаться с кем-нибудь или где-нибудь.
#558 #636363
>>636358
Вряд ли мне помогут сериалы, так как английский я не знаю вообще, знаю только на уровне человека, который постоянно сталкивается с английскими словами в рекламе и в интернете, но всё равно ничего не знаю. Есть ли какие-нибудь сервисы, есть ли в языках, вообще какая-то основа, поняв которую можно хоть немного понимать текст на английском? Например как правильно строить предложения и т.д. мне бы вот это узнать, а дальше уже буду каждый день обогащать словарный запас.
#559 #636364
>>636363
Ну тут уж тебе в /fl
#560 #636365
>>636364
и говорю без шуток, там много на эту тему есть инфы
#561 #636368
>>636363
http://lingualeo.com/ тут есть тренировки и словарь. Еще советую поставить их одноименное расширение для браузера, которое по двойному клику на слове на любом сайте переводит его, потом ты можешь добавить его в свой словарь и потом тренировать.
#562 #636391
>>636364
>>636368
Спасибо
#563 #636395
Повторю вопрос, много ли надо знать, чтоб взяли джуном.
Реквестирую - что надо знать и уметь для джуна.
#564 #636399
>>636395
Забудь об этом, ты слишком тупой, если не можешь додуматься открыть вакансии и посмотреть требования.
#565 #636468
Если сделать что-то вроде такого чата http://drrrchat.com только не на фреймворке, а при помощи обычного ООП PHP, это будет нормально для портфолио при приёме на работу?
#566 #636477
>>636468
Конечно, если ты можешь написать приложение с соблюдением современных стандартов разработки, это похвально. Но от знания фреймворков, если вакансия того требует (а они все требуют), не освобождает.
#567 #636486
>>636340

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

>>636297

кодеакадеми очень ознакомительного уровня.

Ну и у нас в ОП посте есть задания по ХТМЛ, тоже неплохие, обрати внимание.

>>636279

> Можно ли решить без них(как предполагается по подсказке ОПа), а если нет, то где почитать вообще вводное что-либо про алгоритмы?


Алгоритм это просто последовательность действий. Он есть в любой программе, даже если ты об этом не догадывался.

По поводу поиска пути, я сказал погуглить, ты гуглил?

Есть такая страница

https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D1%83%D1%82%D0%B8

И еще такая, интересная и подробная: http://pmg.org.ru/ai/stout.htm

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

Почитай все это. затем смотри сюда:

https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%94%D0%B5%D0%B9%D0%BA%D1%81%D1%82%D1%80%D1%8B

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

Если что непонятно, задавай уточняющие вопросы. Можно использовтаь и другой алгоритм, можно попытаться понять что написал ОП в подсказках к задаче.
#567 #636486
>>636340

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

>>636297

кодеакадеми очень ознакомительного уровня.

Ну и у нас в ОП посте есть задания по ХТМЛ, тоже неплохие, обрати внимание.

>>636279

> Можно ли решить без них(как предполагается по подсказке ОПа), а если нет, то где почитать вообще вводное что-либо про алгоритмы?


Алгоритм это просто последовательность действий. Он есть в любой программе, даже если ты об этом не догадывался.

По поводу поиска пути, я сказал погуглить, ты гуглил?

Есть такая страница

https://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D1%83%D1%82%D0%B8

И еще такая, интересная и подробная: http://pmg.org.ru/ai/stout.htm

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

Почитай все это. затем смотри сюда:

https://ru.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%94%D0%B5%D0%B9%D0%BA%D1%81%D1%82%D1%80%D1%8B

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

Если что непонятно, задавай уточняющие вопросы. Можно использовтаь и другой алгоритм, можно попытаться понять что написал ОП в подсказках к задаче.
#568 #636488
>>636395

hh.ru

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

Ищи уроки для начинающих, там как раз структуру предложений и разбирают. Английский за пару месяцев не выучить, так что готовься к долгому пути.
https://github.com/lexdss/shop #570 #636492
>>630249

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

https://github.com/lexdss/shop/blob/master/dump.sql#L92

> CONSTRAINT `order_product_ibfk_2` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`) ON DELETE CASCADE


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

https://github.com/lexdss/shop/blob/master/dump.sql#L122

> CONSTRAINT `product_ibfk_1` FOREIGN KEY (`category`) REFERENCES `category` (`code`) ON DELETE CASCADE


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

> `role` enum('user','admin') DEFAULT NULL,


Может логичнее по дефолту ставить user? А нулл запретить?

https://github.com/lexdss/shop/blob/master/dump.sql#L151

> `date` datetime


Непонятно дата чего это. Название поля неудачное.

https://github.com/lexdss/shop/blob/master/app/autoloader.php
Тут унылая копипаста. Надо эти 5 функций объединить в одну. Ну, к примеру, ты можешь сделать массив с именами папок и перебирать их в цикле, ища в них файл. Более того, ты можешь добавить эти 5 папок в include_path ( http://php.net/manual/ru/function.set-include-path.php ) и тогда файл можно будет загрузить обычным require (а найти в какой именно папке файл через http://php.net/manual/ru/function.stream-resolve-include-path.php ). Более того, если у тебя папки включены в include_path и имя файла соответствует определенному шаблону то можно использовать стандартный автозагрузчик в функции spl_autoload. Почитай мануал на все эти темы.

Или ты мог бы освоить неймспейсы из этого урока: https://github.com/codedokode/pasta/blob/master/php/autoload.md и сделать автозагрузку с использованием PSR-4.

https://github.com/lexdss/shop/blob/master/app/config.php
Я думаю, использовать константы для конфига не очень хорошая идея. Константы доступны глобально, зачем нам это? Нам это не нужно. ЛУчше использовать обычные переменные.

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

https://github.com/lexdss/shop/blob/master/index.php#L10

> include VIEW_DIR.'503page.tpl.php';


Тут не очень понятно какой получается путь к файлу:

/app/view/503page.tpl.php

Это что, файл должен лежать в корне файловой системы? Ты проверял, работает ли это?

https://github.com/lexdss/shop/blob/master/index.php#L8

> error_log($e->getMessage());


Неправильно. Ты записываешь только текст ошибки, а имя файла, строку, где она произошла, стектрейс, УРЛ страницы - не запсиываешь. Какая польза от такого лога, по нему ты не найдешь даже что это за ошибка была. Надо как минимум записывать то что вернет $e->__toString(), там больше подробностей + УРЛ страницы добавить.

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

https://github.com/lexdss/shop/blob/master/app/controller/FrontController.php
Код не рекомендации PSR отформатирован. После имени класса и функции скобка ставится на новой строке, а не на той же.

Нехорошо что у тебя в конструкторе фронт контроллера вызывается 404 и exit. Ненормально как-то завершать скрипт при попытке создать объект. Я думаю, код разбора надо поместить в метод вроде route(). Свойства controller, action можно выпилить и заменить на обычные переменные.

Далее, насчет сервисов. Сервисами я называю классы вроде PDO, Auth, мапперов. Видно, что они создаются у тебя где попало и как попало, такж видно что у тебя почему-то у всех контроллеров есть зависимость от Db что тоже не очень логично: может база данных ему и не нужна.

Эта проблема решается так: надо сделать класс, например Container или ServiceLocator, который умеет создавать сервисы по требованию, а при повторном вызове возвращать ранее созданный экземпляр. У этого класса будут методы вроде getPdo(), getSomeMapper(), getAuthManager() и тд. Он будет передаваться в конструктор контроллера, и тот из него получает нужные ему сервисы.

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

$container = new Container($settings);

можно через анонимную функцию, так:

$container->setPdoFactory(function () use ($settings) {
$pdo = new Pdo(...);
$pdo->setAttribute...
return $pdo;
});

Почитай про контейнер в Симфони - можно идею брать с него, он тоже там хранит в себе настройки и создает сервисы:

(рус) http://symfony-gu.ru/documentation/ru/html/book/service_container.html
(англ) http://symfony.com/doc/current/book/service_container.html
https://github.com/lexdss/shop #570 #636492
>>630249

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

https://github.com/lexdss/shop/blob/master/dump.sql#L92

> CONSTRAINT `order_product_ibfk_2` FOREIGN KEY (`product_id`) REFERENCES `product` (`id`) ON DELETE CASCADE


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

https://github.com/lexdss/shop/blob/master/dump.sql#L122

> CONSTRAINT `product_ibfk_1` FOREIGN KEY (`category`) REFERENCES `category` (`code`) ON DELETE CASCADE


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

> `role` enum('user','admin') DEFAULT NULL,


Может логичнее по дефолту ставить user? А нулл запретить?

https://github.com/lexdss/shop/blob/master/dump.sql#L151

> `date` datetime


Непонятно дата чего это. Название поля неудачное.

https://github.com/lexdss/shop/blob/master/app/autoloader.php
Тут унылая копипаста. Надо эти 5 функций объединить в одну. Ну, к примеру, ты можешь сделать массив с именами папок и перебирать их в цикле, ища в них файл. Более того, ты можешь добавить эти 5 папок в include_path ( http://php.net/manual/ru/function.set-include-path.php ) и тогда файл можно будет загрузить обычным require (а найти в какой именно папке файл через http://php.net/manual/ru/function.stream-resolve-include-path.php ). Более того, если у тебя папки включены в include_path и имя файла соответствует определенному шаблону то можно использовать стандартный автозагрузчик в функции spl_autoload. Почитай мануал на все эти темы.

Или ты мог бы освоить неймспейсы из этого урока: https://github.com/codedokode/pasta/blob/master/php/autoload.md и сделать автозагрузку с использованием PSR-4.

https://github.com/lexdss/shop/blob/master/app/config.php
Я думаю, использовать константы для конфига не очень хорошая идея. Константы доступны глобально, зачем нам это? Нам это не нужно. ЛУчше использовать обычные переменные.

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

https://github.com/lexdss/shop/blob/master/index.php#L10

> include VIEW_DIR.'503page.tpl.php';


Тут не очень понятно какой получается путь к файлу:

/app/view/503page.tpl.php

Это что, файл должен лежать в корне файловой системы? Ты проверял, работает ли это?

https://github.com/lexdss/shop/blob/master/index.php#L8

> error_log($e->getMessage());


Неправильно. Ты записываешь только текст ошибки, а имя файла, строку, где она произошла, стектрейс, УРЛ страницы - не запсиываешь. Какая польза от такого лога, по нему ты не найдешь даже что это за ошибка была. Надо как минимум записывать то что вернет $e->__toString(), там больше подробностей + УРЛ страницы добавить.

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

https://github.com/lexdss/shop/blob/master/app/controller/FrontController.php
Код не рекомендации PSR отформатирован. После имени класса и функции скобка ставится на новой строке, а не на той же.

Нехорошо что у тебя в конструкторе фронт контроллера вызывается 404 и exit. Ненормально как-то завершать скрипт при попытке создать объект. Я думаю, код разбора надо поместить в метод вроде route(). Свойства controller, action можно выпилить и заменить на обычные переменные.

Далее, насчет сервисов. Сервисами я называю классы вроде PDO, Auth, мапперов. Видно, что они создаются у тебя где попало и как попало, такж видно что у тебя почему-то у всех контроллеров есть зависимость от Db что тоже не очень логично: может база данных ему и не нужна.

Эта проблема решается так: надо сделать класс, например Container или ServiceLocator, который умеет создавать сервисы по требованию, а при повторном вызове возвращать ранее созданный экземпляр. У этого класса будут методы вроде getPdo(), getSomeMapper(), getAuthManager() и тд. Он будет передаваться в конструктор контроллера, и тот из него получает нужные ему сервисы.

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

$container = new Container($settings);

можно через анонимную функцию, так:

$container->setPdoFactory(function () use ($settings) {
$pdo = new Pdo(...);
$pdo->setAttribute...
return $pdo;
});

Почитай про контейнер в Симфони - можно идею брать с него, он тоже там хранит в себе настройки и создает сервисы:

(рус) http://symfony-gu.ru/documentation/ru/html/book/service_container.html
(англ) http://symfony.com/doc/current/book/service_container.html
https://github.com/lexdss/shop #571 #636493
>>630249

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

> if(isset($_GET['act']) | $_GET['act'] == 'logout'){


| - это битовый оператор, а тебе нужно логическое или ||

Также, выражение написано неверно. Там явно должно быть И, а не ИЛИ.

> header('Location: '.$_SERVER['HTTP_REFERER']);


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

Ну и логаут логичнее делать через ПОСТ так как он изменяет состояние залогиненности.

https://github.com/lexdss/shop/blob/master/app/controller/AController.php#L31

> //Перебрасываем на 404 если в контроллерах нет нужного экшена


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

https://github.com/lexdss/shop/blob/master/app/controller/AController.php#L15
Вот тут видна необходимость в контейнере служб.

> AController{


Название никуда не годится, что такое A?

https://github.com/lexdss/shop/blob/master/app/controller/CatController.php#L11

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


> public function __call($name, $args){


Какие-то костыли. По моему, тебе надо либо поменять УРЛ на формат /cat/index/some-category либо переделать роутинг чтобы он умел выделять имя категории как параметр. А не лепить костыли, делая вид как будто у тебя 20 разных экшенов.

> //Вместо categoryAction делаем category


> $this->category_code = str_replace('Action', '', $name);


someCategoryActionActionAction тоже будет тогда работать.

> FrontController::page404();


Имя метода должно начинаться с глагола. Также, мне не нравится тут статисеский метод, почему бы не сделать через $this->showErrorPage(404) или $this->showNotFoundPage()?

> if($_GET['add']){


Непонятно, почему добавление товара сделано методом ГЕТ, а не ПОСТ. Выучи-ка какие есть методы в HTTP и для чего они применяются. Также, непонятно, почему добавление товара делается через контроллер вывода товаров в категории. Это явно должно быть в другом месте.

Редирект обратно надо делать не через реферер, а через УРЛ, указанный в форме добавления в корзину.

Также, если в ГЕТ нет параметра add то тут будет ошибка. Ты ее не видишь скорее всего потмоу, что у тебя отключено отображение ошибок в конфиге пхп - надо его включить. Либо постоянно читать логи.

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


> if(!empty($_GET['item_id'])){


Это должно делаться не тут, а в роутере в фронт контроллере. Сделай отдельный УРЛ для товара вида /product/view/1234 либо /cat/guitar/123 и научи роутер его понимать.

> $user_validate->valid($_POST);


Имя функций начинается с глагола

> //В случае не пройденной валидации приходит массив ошибок, если пройдена - объект пользователя


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

$errors = validate(User $user); // Возвр. массив ошибок
$errorList = validate($user); // возвращает объект списка ошибок
$trueOrFalse = validate($user, &$errors); // заполняет массив ошибок
$trueOrFalse = validate($user, ErrorList $errors); // заполняет объект ошибок

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

> $this->view->value = $_POST;


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

> $this->user_mapper->save($result);


> //Получаем ID нового пользователя и сохраняем его в сессионной переменной


> $user = $this->user_mapper->getUserFromEmail($result->email)


Для получения id только что вставленной записи есть метод lastInsertId(). Получение надо делать сразу после вставки, в методе save, и записывать этот ид в объект пользователя.

Там наверно еще есть замечания, но на сегодня хватит этого, исправишь, будем смотреть дальше.
https://github.com/lexdss/shop #571 #636493
>>630249

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

> if(isset($_GET['act']) | $_GET['act'] == 'logout'){


| - это битовый оператор, а тебе нужно логическое или ||

Также, выражение написано неверно. Там явно должно быть И, а не ИЛИ.

> header('Location: '.$_SERVER['HTTP_REFERER']);


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

Ну и логаут логичнее делать через ПОСТ так как он изменяет состояние залогиненности.

https://github.com/lexdss/shop/blob/master/app/controller/AController.php#L31

> //Перебрасываем на 404 если в контроллерах нет нужного экшена


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

https://github.com/lexdss/shop/blob/master/app/controller/AController.php#L15
Вот тут видна необходимость в контейнере служб.

> AController{


Название никуда не годится, что такое A?

https://github.com/lexdss/shop/blob/master/app/controller/CatController.php#L11

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


> public function __call($name, $args){


Какие-то костыли. По моему, тебе надо либо поменять УРЛ на формат /cat/index/some-category либо переделать роутинг чтобы он умел выделять имя категории как параметр. А не лепить костыли, делая вид как будто у тебя 20 разных экшенов.

> //Вместо categoryAction делаем category


> $this->category_code = str_replace('Action', '', $name);


someCategoryActionActionAction тоже будет тогда работать.

> FrontController::page404();


Имя метода должно начинаться с глагола. Также, мне не нравится тут статисеский метод, почему бы не сделать через $this->showErrorPage(404) или $this->showNotFoundPage()?

> if($_GET['add']){


Непонятно, почему добавление товара сделано методом ГЕТ, а не ПОСТ. Выучи-ка какие есть методы в HTTP и для чего они применяются. Также, непонятно, почему добавление товара делается через контроллер вывода товаров в категории. Это явно должно быть в другом месте.

Редирект обратно надо делать не через реферер, а через УРЛ, указанный в форме добавления в корзину.

Также, если в ГЕТ нет параметра add то тут будет ошибка. Ты ее не видишь скорее всего потмоу, что у тебя отключено отображение ошибок в конфиге пхп - надо его включить. Либо постоянно читать логи.

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


> if(!empty($_GET['item_id'])){


Это должно делаться не тут, а в роутере в фронт контроллере. Сделай отдельный УРЛ для товара вида /product/view/1234 либо /cat/guitar/123 и научи роутер его понимать.

> $user_validate->valid($_POST);


Имя функций начинается с глагола

> //В случае не пройденной валидации приходит массив ошибок, если пройдена - объект пользователя


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

$errors = validate(User $user); // Возвр. массив ошибок
$errorList = validate($user); // возвращает объект списка ошибок
$trueOrFalse = validate($user, &$errors); // заполняет массив ошибок
$trueOrFalse = validate($user, ErrorList $errors); // заполняет объект ошибок

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

> $this->view->value = $_POST;


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

> $this->user_mapper->save($result);


> //Получаем ID нового пользователя и сохраняем его в сессионной переменной


> $user = $this->user_mapper->getUserFromEmail($result->email)


Для получения id только что вставленной записи есть метод lastInsertId(). Получение надо делать сразу после вставки, в методе save, и записывать этот ид в объект пользователя.

Там наверно еще есть замечания, но на сегодня хватит этого, исправишь, будем смотреть дальше.
Ответы за 20-23 января #572 #636494
>>630376

Кодировка виндоуз содержит 256 символов, утф-8 - десятки тысяч. Очевидно твоя функция будет терять символы, не входящие в кодировку виндоуз и лучше бы ее не использовать, чем потом разгребать эти проблемы. Если тебе надо перевернуть строку, ты можешь разбить ее на массив символов хаком с preg_split('//u'), перевернуть массив стандартной функцией и склеить обратно.

А про strrev лучше забыть - она безнадежно устарела.
https://github.com/someApprentice/Students #573 #636495
>>630433

https://github.com/someApprentice/Students/blob/master/app/config.php
В конфиге лучше не использовать DSN, а просто указать в массиве отдельно хост, базу, имя, пароль. Ведь редактировать конфиг может быть будет незнакомый с программированием человек. Еще лучше - вообще сделать конфиг в формате ini напрмиер, он очень простой и читабельный.

https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php
В контроллерах надо отказаться от статических методов. Код на статических методах - это процедурщина, а не ООП.

https://github.com/someApprentice/Students/blob/master/app/Model/Gateway/TableDataGateway.php#L15

> public function addUser(User $user) {


Непонятно зачем эта функция в базовом классе, а не в UserTableGateway.

> Essence


то обычно назвают Entity

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

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

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

Далее, насчет сервисов. Сервисами я называю классы вроде PDO, Auth, мапперов. Видно, что они создаются у тебя где попало и как попало.

Эта проблема решается так: надо сделать класс, например Container или ServiceLocator, который умеет создавать сервисы по требованию, а при повторном вызове возвращать ранее созданный экземпляр. У этого класса будут методы вроде getPdo(), getSomeMapper(), getAuthManager() и тд. Он будет передаваться в конструктор контроллера, и тот из него получает нужные ему сервисы.

Контейнер существует в 1 экземпляре, создается в бутстрапе (инит.пхп). Как передать в него настройки из конфига? Можно через конструктор

$container = new Container($settings);

можно через анонимную функцию, так:

$container->setPdoFactory(function () use ($settings) {
$pdo = new Pdo(...);
$pdo->setAttribute...
return $pdo;
});

Почитай про контейнер в Симфони - можно идею брать с него, он тоже там хранит в себе настройки и создает сервисы:

(рус) http://symfony-gu.ru/documentation/ru/html/book/service_container.html
(англ) http://symfony.com/doc/current/book/service_container.html

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

Ну а продолжать писать код тебе надо в любом случае, не дожидаясь меня.
https://github.com/someApprentice/Students #573 #636495
>>630433

https://github.com/someApprentice/Students/blob/master/app/config.php
В конфиге лучше не использовать DSN, а просто указать в массиве отдельно хост, базу, имя, пароль. Ведь редактировать конфиг может быть будет незнакомый с программированием человек. Еще лучше - вообще сделать конфиг в формате ini напрмиер, он очень простой и читабельный.

https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php
В контроллерах надо отказаться от статических методов. Код на статических методах - это процедурщина, а не ООП.

https://github.com/someApprentice/Students/blob/master/app/Model/Gateway/TableDataGateway.php#L15

> public function addUser(User $user) {


Непонятно зачем эта функция в базовом классе, а не в UserTableGateway.

> Essence


то обычно назвают Entity

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

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

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

Далее, насчет сервисов. Сервисами я называю классы вроде PDO, Auth, мапперов. Видно, что они создаются у тебя где попало и как попало.

Эта проблема решается так: надо сделать класс, например Container или ServiceLocator, который умеет создавать сервисы по требованию, а при повторном вызове возвращать ранее созданный экземпляр. У этого класса будут методы вроде getPdo(), getSomeMapper(), getAuthManager() и тд. Он будет передаваться в конструктор контроллера, и тот из него получает нужные ему сервисы.

Контейнер существует в 1 экземпляре, создается в бутстрапе (инит.пхп). Как передать в него настройки из конфига? Можно через конструктор

$container = new Container($settings);

можно через анонимную функцию, так:

$container->setPdoFactory(function () use ($settings) {
$pdo = new Pdo(...);
$pdo->setAttribute...
return $pdo;
});

Почитай про контейнер в Симфони - можно идею брать с него, он тоже там хранит в себе настройки и создает сервисы:

(рус) http://symfony-gu.ru/documentation/ru/html/book/service_container.html
(англ) http://symfony.com/doc/current/book/service_container.html

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

Ну а продолжать писать код тебе надо в любом случае, не дожидаясь меня.
Ответы 20-23 янв #574 #636496
>>630602

> mt_rand(1, count($word1));


Индексы идут от 0 до каунт - 1.

>>630629

Выражение слишком сложное, попробуй записать так:

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

Ну и проверь свой код на списке номеров:

Правильные: array('84951234567', '+74951234567', '8-495-1-234-567', ' 8 (8122) 56-56-56', '8-911-1234567', '8 (911) 12 345 67', '8-911 12 345 67', '8 (911) - 123 - 45 - 67', '+ 7 999 123 4567', '8 ( 999 ) 1234567', '8 999 123 4567');

Неправильные: array('02', '84951234567 позвать люсю', '849512345', '849512345678',
'8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88',
'84951a234567', '8495123456a',
'+1 234 5678901', // неверный код страны
'+8 234 5678901', // либо 8 либо +7
'7 234 5678901' // нет +
);

Также, есть такой сайт: https://regex101.com/r/qF7vT8/3 - там уже вбиты номера и на нем можно простестировать свою регулярку и проверить что она соответствует правильным и не соответствует неправильным номерам. Помни что на этом сайте надо писать бекслеш один раз, например \s, а не \\s. Флаг m там стоит чтобы ^ и $ в регулярке обозначали «начало и конец любой строки», а не «начало и конец всего текста». Флаг g (его нет в PHP, он только на этом сайте) значит что надо искать все совпадения с регуляркой, а не только первое.

>>630637

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

>>630765

Всегда есть не требующие высокой квалификации должности.

>>630865

Так нельзя?

function () use ($x) {
echo $x;
}
Ответы 20-23 янв #574 #636496
>>630602

> mt_rand(1, count($word1));


Индексы идут от 0 до каунт - 1.

>>630629

Выражение слишком сложное, попробуй записать так:

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

Ну и проверь свой код на списке номеров:

Правильные: array('84951234567', '+74951234567', '8-495-1-234-567', ' 8 (8122) 56-56-56', '8-911-1234567', '8 (911) 12 345 67', '8-911 12 345 67', '8 (911) - 123 - 45 - 67', '+ 7 999 123 4567', '8 ( 999 ) 1234567', '8 999 123 4567');

Неправильные: array('02', '84951234567 позвать люсю', '849512345', '849512345678',
'8 (409) 123-123-123', '7900123467', '5005005001', '8888-8888-88',
'84951a234567', '8495123456a',
'+1 234 5678901', // неверный код страны
'+8 234 5678901', // либо 8 либо +7
'7 234 5678901' // нет +
);

Также, есть такой сайт: https://regex101.com/r/qF7vT8/3 - там уже вбиты номера и на нем можно простестировать свою регулярку и проверить что она соответствует правильным и не соответствует неправильным номерам. Помни что на этом сайте надо писать бекслеш один раз, например \s, а не \\s. Флаг m там стоит чтобы ^ и $ в регулярке обозначали «начало и конец любой строки», а не «начало и конец всего текста». Флаг g (его нет в PHP, он только на этом сайте) значит что надо искать все совпадения с регуляркой, а не только первое.

>>630637

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

>>630765

Всегда есть не требующие высокой квалификации должности.

>>630865

Так нельзя?

function () use ($x) {
echo $x;
}
Ответы 20-23 янв #575 #636497
>>630879

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

>>630931

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

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

>>630937

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

>>631098

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

>>631079

Держи готовый алгоритм:

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

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

>>631120

> в другой - (id, user_id(кто поставил), like_user(кому поставил))


В качестве первичного ключа можно использовать пару (user_id, like_user), а id выпилить.

> Как тут можно подсчитать одновременно сколько юзер поставил лайков и сколько ему? Если я сгруппирую так GROUP BY user.id (или user_id, неважно), то через COUNT смогу соответственно подсчитать сколько он лайков поставил, но не смогу подсчитать сколько ему поставили потому что COUNT зависит от GROUP BY. А еесли так GROUP BY like_user, то смогу подсчитать сколько пользователю поставили лайков, но теперь не смогу подсчитать сколько он поставил.


Да, верно. Более того, если ты попытаешься к таблице юзеров приджойнить таблицу лакйов 2 раза (полученные и отданные лайки) то ты вообще получишь в COUNT число всех комбинаций отданных и полученных лайков (например для 4 полученных и 5 отданных получится 20 комбинаций).

Казалось бы, выхода нет. Но на деле надо просто внимательно изучить синтаксис функции COUNT:

http://phpclub.ru/mysql/doc/group-by-functions.html

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

>>631145

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

>>631168

Конечно будет, достаточно одной таблицы связи
Ответы 20-23 янв #575 #636497
>>630879

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

>>630931

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

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

>>630937

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

>>631098

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

>>631079

Держи готовый алгоритм:

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

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

>>631120

> в другой - (id, user_id(кто поставил), like_user(кому поставил))


В качестве первичного ключа можно использовать пару (user_id, like_user), а id выпилить.

> Как тут можно подсчитать одновременно сколько юзер поставил лайков и сколько ему? Если я сгруппирую так GROUP BY user.id (или user_id, неважно), то через COUNT смогу соответственно подсчитать сколько он лайков поставил, но не смогу подсчитать сколько ему поставили потому что COUNT зависит от GROUP BY. А еесли так GROUP BY like_user, то смогу подсчитать сколько пользователю поставили лайков, но теперь не смогу подсчитать сколько он поставил.


Да, верно. Более того, если ты попытаешься к таблице юзеров приджойнить таблицу лакйов 2 раза (полученные и отданные лайки) то ты вообще получишь в COUNT число всех комбинаций отданных и полученных лайков (например для 4 полученных и 5 отданных получится 20 комбинаций).

Казалось бы, выхода нет. Но на деле надо просто внимательно изучить синтаксис функции COUNT:

http://phpclub.ru/mysql/doc/group-by-functions.html

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

>>631145

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

>>631168

Конечно будет, достаточно одной таблицы связи
Ответы 20-23 янв #576 #636498
>>631192

У тебя неправильный код, должно быть так:

$app->get("/files/:id", $test);

А ты вместо функции передаешь результат ее вызова, это не то.

https://jsbin.com/pakonaseho/1/edit?js,console
>>631243

> designationSize


Имена функций начинаются с глагола.

try/catch делать не надо, ловить исключение должен тот, кто использует твой класс, а не ты сам. А то исключение до него просто не дойдет. Почитай-ка урок про исключения https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

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

> hamburger.addTopping("MAYO");


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

В полях объекта не надо хранить цены и прочее, храни только тип гамбургера, а цену можно потом найти по нему.

> for(var key in this.settingsHamburger["topping"]) {


> if(topping === key) {


> this.topping.push(this.settingsHamburger["topping"][topping]);


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

> if(this.stuffing === undefined || this.size === undefined) throw new Error("Недостаточно данных");


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

> (this.topping[0] ? this.topping[0]["calories"] : 0) +


> (this.topping[1] ? this.topping[1]["calories"] : 0);


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

>>631637

Гугл даст

>>631735

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

>>631761

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

>>631985

Что-то у тебя тут многовато кода. Неужели нельзя это упростить? Конечно, можно.

И считает оно как-то неправильно. Должно получиться - всего выплачено 61270 р. А у тебя там больше почему-то.

Давай начнем с простого примера: анон берет кредит на 1000 р и через месяц выплачивает 2030р с учетом всех накруток: http://ideone.com/7uWggK

Твоя программа ушла куда-то в минус. Правильный алгоритм такой:

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

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
Ответы 20-23 янв #576 #636498
>>631192

У тебя неправильный код, должно быть так:

$app->get("/files/:id", $test);

А ты вместо функции передаешь результат ее вызова, это не то.

https://jsbin.com/pakonaseho/1/edit?js,console
>>631243

> designationSize


Имена функций начинаются с глагола.

try/catch делать не надо, ловить исключение должен тот, кто использует твой класс, а не ты сам. А то исключение до него просто не дойдет. Почитай-ка урок про исключения https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

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

> hamburger.addTopping("MAYO");


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

В полях объекта не надо хранить цены и прочее, храни только тип гамбургера, а цену можно потом найти по нему.

> for(var key in this.settingsHamburger["topping"]) {


> if(topping === key) {


> this.topping.push(this.settingsHamburger["topping"][topping]);


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

> if(this.stuffing === undefined || this.size === undefined) throw new Error("Недостаточно данных");


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

> (this.topping[0] ? this.topping[0]["calories"] : 0) +


> (this.topping[1] ? this.topping[1]["calories"] : 0);


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

>>631637

Гугл даст

>>631735

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

>>631761

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

>>631985

Что-то у тебя тут многовато кода. Неужели нельзя это упростить? Конечно, можно.

И считает оно как-то неправильно. Должно получиться - всего выплачено 61270 р. А у тебя там больше почему-то.

Давай начнем с простого примера: анон берет кредит на 1000 р и через месяц выплачивает 2030р с учетом всех накруток: http://ideone.com/7uWggK

Твоя программа ушла куда-то в минус. Правильный алгоритм такой:

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

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
https://github.com/MindiMakridi/filehosting #577 #636500
>>632175

https://github.com/MindiMakridi/filehosting/blob/master/files.sql#L29

> `upload_time` int(11) NOT NULL,


Почему тип поменял? В БД есть специальный тип для дат, надо использовать его, а не лепить числа. Преобразование типов можно делать в маппере.

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L51

> $files = $app->filesMapper;


> $lastUploadedFiles = $files->fetchLastUploadedFiles();


> $app->render("main.html.twig", array(


> 'files' => $lastUploadedFiles,


> 'filesHelper' => $app->filesHelper


Нехорошо что ты тут одинаковые вещи называешь разными именами. Это путает.

> $app->get("/files/:id", $pageFunc);


> $app->post("/files/:id", $pageFunc);


Это можно сделать без вынесения функции в переменную, через $app->map(...)->via(..): http://docs.slimframework.com/routing/custom/

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L67

> $file = new Filehosting\File;


> $file->setComment($app->request->post('comment'));


> $file->setToken($app->request->post('token'));


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

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L79

> if (!$file = $files->fetchFile($id)) {


> $app->notFound();


Это наверно в начале функции, а не в середине должно идти.

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L82

> if (!isset($comment)) {



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

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L116

> $app->get("/thumbs/:id/:fileName"


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

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L119

> $thumbName = "thumb." . $app->filesHelper->getFileExtension($file);


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

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L133
Валидацию файла при загрузке хорошо бы сразу вынести в функцию, чтобы код тут не разрастался. При ошибке надо повторно вывести форму с сообщением.

Обработчик загрузки файла можно объединить с обработчиком вывода главной страницы.

> $files->beginTransaction();


> $id = $files->addFile($file);


> $file->setId($id);


> $tmpName = $_FILES['userfile']['tmp_name'];


> if ($app->filesHelper->saveFile($tmpName, $file)) {


> $files->commit();


> } else {


> $files->rollBack();


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

https://github.com/MindiMakridi/filehosting/blob/master/models/File.php
Я тут подумал, выбрасывать исключение для пустого свойства не очень логично. Может мы хотим проверить, заполнен ли id, а как это сделать? Непонятно.

https://github.com/MindiMakridi/filehosting/blob/master/models/FilesMapper.php#L24

> $id = $this->dbh->lastInsertId();


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

https://github.com/MindiMakridi/filehosting/tree/master/models/helpers
Нейсмпейсы принято писать с большой буквы, надо переименовать папку. под виндой это придется делать через 2 переименования, так как она не видит разницы между буквами разного регистра.

https://github.com/MindiMakridi/filehosting/blob/master/models/helpers/FilesHelper.php#L48
Тут надо проверять не только является ли он какртинкой, но и можно ли для него сгенерировать превью. Причем проверка поддерживаемых форматов по логике должна быть в классе-генераторе превьюшек.
https://github.com/MindiMakridi/filehosting #577 #636500
>>632175

https://github.com/MindiMakridi/filehosting/blob/master/files.sql#L29

> `upload_time` int(11) NOT NULL,


Почему тип поменял? В БД есть специальный тип для дат, надо использовать его, а не лепить числа. Преобразование типов можно делать в маппере.

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L51

> $files = $app->filesMapper;


> $lastUploadedFiles = $files->fetchLastUploadedFiles();


> $app->render("main.html.twig", array(


> 'files' => $lastUploadedFiles,


> 'filesHelper' => $app->filesHelper


Нехорошо что ты тут одинаковые вещи называешь разными именами. Это путает.

> $app->get("/files/:id", $pageFunc);


> $app->post("/files/:id", $pageFunc);


Это можно сделать без вынесения функции в переменную, через $app->map(...)->via(..): http://docs.slimframework.com/routing/custom/

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L67

> $file = new Filehosting\File;


> $file->setComment($app->request->post('comment'));


> $file->setToken($app->request->post('token'));


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

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L79

> if (!$file = $files->fetchFile($id)) {


> $app->notFound();


Это наверно в начале функции, а не в середине должно идти.

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L82

> if (!isset($comment)) {



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

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L116

> $app->get("/thumbs/:id/:fileName"


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

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L119

> $thumbName = "thumb." . $app->filesHelper->getFileExtension($file);


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

https://github.com/MindiMakridi/filehosting/blob/master/public/index.php#L133
Валидацию файла при загрузке хорошо бы сразу вынести в функцию, чтобы код тут не разрастался. При ошибке надо повторно вывести форму с сообщением.

Обработчик загрузки файла можно объединить с обработчиком вывода главной страницы.

> $files->beginTransaction();


> $id = $files->addFile($file);


> $file->setId($id);


> $tmpName = $_FILES['userfile']['tmp_name'];


> if ($app->filesHelper->saveFile($tmpName, $file)) {


> $files->commit();


> } else {


> $files->rollBack();


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

https://github.com/MindiMakridi/filehosting/blob/master/models/File.php
Я тут подумал, выбрасывать исключение для пустого свойства не очень логично. Может мы хотим проверить, заполнен ли id, а как это сделать? Непонятно.

https://github.com/MindiMakridi/filehosting/blob/master/models/FilesMapper.php#L24

> $id = $this->dbh->lastInsertId();


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

https://github.com/MindiMakridi/filehosting/tree/master/models/helpers
Нейсмпейсы принято писать с большой буквы, надо переименовать папку. под виндой это придется делать через 2 переименования, так как она не видит разницы между буквами разного регистра.

https://github.com/MindiMakridi/filehosting/blob/master/models/helpers/FilesHelper.php#L48
Тут надо проверять не только является ли он какртинкой, но и можно ли для него сгенерировать превью. Причем проверка поддерживаемых форматов по логике должна быть в классе-генераторе превьюшек.
Ответы 20-23 янв #578 #636501
>>632199

http://ideone.com/NuO5fo
Надо проверить это на списке номеров, скорее всего работать не будет так как у тебя жестко задано как цифры сгруппированы в номере, лучше этого не делать, а просто разрешить любое число пробелов, минусов, скобок между цифрами.

> регулярка тест на граммар наци


> http://ideone.com/I2Q3I9


> $regexp1 = '/[+7]/';


Тут неправильно, квадратные скобки значат "любой один из символов, либо + либо 7", а не последовательность 2 символов.

>>632214

От оставшегося, невыплаченного долга.

>>632400

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

>>632510

По моим ощущениям, внешние библиотеки удобнее, а ксс селекторы нагляднее xpath

>>632548

Все верно работает, только в условии в цикле лучше писать $i <= 2, а то можно подумать что цикл 3 раза выполняется.

>>632569

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

>>632704

> if (this._elements.getPowerProduction) {


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

> return profit result;


Я думаю, лучше бы сделать функцию, которая бы вычисляла и возвращала в виде словаря:

- избыток ли у нас энергии
- недостаток ли энергии
- величину избытка/недостатка
- цену покупки или прибыль от продажи
- удалось ли закупить или продать

А потом можно сделать вывод этой информации в любом виде.

> if (powerExcess > this._powerCapacity) {


> return this._powerCost (this._powerCapacity / PowerLine.MW);


Тут можно использовать min/max вместо if.

А так, пока получается неплохо, почти все сделано уже.

>>632746

ЧТобы не было копипасты, надо код разбить на функции, например:

- функция записи числа от 0 до 999 слвоами
- функция выбора формы слова (тысяча/тысяч)
- функция которая разобъет число на группы по 3 цифры и запишет словами

>>633021

Код надо разбивать на функции, такая стена текста это перебор.

Определение формы слова не стоит делать так:

> 'рубль' => array(1),


> 'рубля' => array(2, 3, 4),


> 'рублей' => array(0, 5, 6, 7, 8,


Вообще форма слова в русском зависит только от последней цифры, исключение - это если число заканчивается на 11-19. Соответственно надо ифами это проверять. Всего может быть 3 формы слова: 1 рубль, 2 рубля, 5 рублей.

Разбивать число на цифры надо математически, есть такие варианты:

// получить последние 3 цифры числа:
echo 1234567 % 1000; // выведет 567

// получить число миллионов
echo floor(1234678 / 1000000); // выведет 12

Комбинируя их, можно получить что угодно.

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

- если есть слово для сотен, ставим его
- если есть десятки, ставим
- если число оканчиваетя на 11-19, ставим слово
- если есть единицы, ставим слово для них

>>633167

Решено правильно.
Ответы 20-23 янв #578 #636501
>>632199

http://ideone.com/NuO5fo
Надо проверить это на списке номеров, скорее всего работать не будет так как у тебя жестко задано как цифры сгруппированы в номере, лучше этого не делать, а просто разрешить любое число пробелов, минусов, скобок между цифрами.

> регулярка тест на граммар наци


> http://ideone.com/I2Q3I9


> $regexp1 = '/[+7]/';


Тут неправильно, квадратные скобки значат "любой один из символов, либо + либо 7", а не последовательность 2 символов.

>>632214

От оставшегося, невыплаченного долга.

>>632400

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

>>632510

По моим ощущениям, внешние библиотеки удобнее, а ксс селекторы нагляднее xpath

>>632548

Все верно работает, только в условии в цикле лучше писать $i <= 2, а то можно подумать что цикл 3 раза выполняется.

>>632569

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

>>632704

> if (this._elements.getPowerProduction) {


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

> return profit result;


Я думаю, лучше бы сделать функцию, которая бы вычисляла и возвращала в виде словаря:

- избыток ли у нас энергии
- недостаток ли энергии
- величину избытка/недостатка
- цену покупки или прибыль от продажи
- удалось ли закупить или продать

А потом можно сделать вывод этой информации в любом виде.

> if (powerExcess > this._powerCapacity) {


> return this._powerCost (this._powerCapacity / PowerLine.MW);


Тут можно использовать min/max вместо if.

А так, пока получается неплохо, почти все сделано уже.

>>632746

ЧТобы не было копипасты, надо код разбить на функции, например:

- функция записи числа от 0 до 999 слвоами
- функция выбора формы слова (тысяча/тысяч)
- функция которая разобъет число на группы по 3 цифры и запишет словами

>>633021

Код надо разбивать на функции, такая стена текста это перебор.

Определение формы слова не стоит делать так:

> 'рубль' => array(1),


> 'рубля' => array(2, 3, 4),


> 'рублей' => array(0, 5, 6, 7, 8,


Вообще форма слова в русском зависит только от последней цифры, исключение - это если число заканчивается на 11-19. Соответственно надо ифами это проверять. Всего может быть 3 формы слова: 1 рубль, 2 рубля, 5 рублей.

Разбивать число на цифры надо математически, есть такие варианты:

// получить последние 3 цифры числа:
echo 1234567 % 1000; // выведет 567

// получить число миллионов
echo floor(1234678 / 1000000); // выведет 12

Комбинируя их, можно получить что угодно.

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

- если есть слово для сотен, ставим его
- если есть десятки, ставим
- если число оканчиваетя на 11-19, ставим слово
- если есть единицы, ставим слово для них

>>633167

Решено правильно.
#579 #636512
>>636477
С фреймворками разберусь, пробовал YII 2 понял всё то что касается работы с базами данных и некоторые другие вопросы, однако, общей сути всёравно не понял. Что ты имеешь в виду под стандартами современной разработки приложений?
88 Кб, 973x300
#580 #636528
Дошел до этого задания, вроде сделал, но не уверен что я правильно понял его условия. Правильно ли я его решил? http://ideone.com/3RZSd2
#581 #636540
>>636528

Имена функций должны начинаться с глагола.

Возвращаемые значения должны быть осмысленные, например true/false, а не непонятные строки.

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

Ну и наконец задача решается без циклов.
#582 #636555
А ОПчик даст годные ресусры для изучения вёрстки (джаваскрипт сам знаю где трогать).
#583 #636567
>>636555

>(джаваскрипт сам знаю где трогать).


делись:?
#584 #636570
>>636495

>https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php


>В контроллерах надо отказаться от статических методов. Код на статических методах - это процедурщина, а не ООП.


А что тогда писать сначала $registeraction = new RegusterAction();? Зачем? Ведь тоже самое будет. Что плохого в такой "процедурщине"? Тем более init тоже процедурно написан. Не понимаю.

>>636495

>https://github.com/someApprentice/Students/blob/master/app/Model/Gateway/TableDataGateway.php#L15


>> public function addUser(User $user) {


>Непонятно зачем эта функция в базовом классе, а не в UserTableGateway.


Просто как пример для самого себя.
А если бы, например, за место студентов у нас были простые юзеры, и, при этом, я бы не хотел наследовать и писать новый класс как бы приходилось писать эту функцию? public function addRecord(Record $record)? Или всегда обязательно писать новый класс?
#585 #636575
C какого момента я готов к понимаю классов, конструкторов, объектов, медодов и MVC?
Накидайте задачек для вхождения. (Учебник смотрел, а войти в ООПне смог)
#586 #636626
>>631035

Если ты помнишь:

Алгоритм такой:
1. Имеем сумму кредита.
2. Прибавляем к ней нужный процент и прибавляем комиссию за обслуживание кредита.
3. Проверяем, получившаяся сумма больше или меньше 5000, которые может выплачивать Анончик в месяц.
4. В соответствии с результатом проверки или продолжаем цикл выплат, или выплачиваем имеющуюся сумму и обрываем цикл (не забывай про пункт 1, что она у нас уже должна быть умножена на процент и к ней уже должна быть прибавлена комиссия за обслуживание кредита).
Всё.

Я опять ебусь с этой задачей. Если в п.1 только считаем сумму, то когда вычитать месячный платёж?
#587 #636636
>>636626
Решил в итоге вот так. По-моему в описанный тобой алгоритм опять не уложился - http://ideone.com/J7rb0R
#588 #636639
>>636636
Считает неправильно. В этой задаче конечный результат будет 61270 рублей с копейками.
#589 #636640
>>636636
Не, не так. Щас...
#590 #636645
>>636640
>>636639
>>636636

Вот. Теперь не баланс отнимается от баланса, а высчитывается последний платёж - http://ideone.com/J7rb0R
#591 #636648
>>636645
Балять
#592 #636650
>>636645

>Всего выплачено 50000


А должно быть

>61270 рублей с копейками



Зачем ты там $creditBalance делишь на 100? Насколько я помню, там такого делать не нужно.
#593 #636660
>>636650
Чтоб процент узнать. В итоге получается так: имеющаяся сумма + процент + платёж за обслуживание. Нет?
#594 #636664
>>636660
Вот же у тебя переменная $percent, это и будет твой процент. В данном случае это 3%, значит тебе нужно

$creditBalance умножить на $percent + платеж за обслуживание - оплата за месяц
85 Кб, 950x750
#595 #636668
>>636664
Смотри, у ОПа $percent задан как 1,03 вот на этом скрине. Это опечатка? Должно быть 0,03?
#596 #636669
>>636668
Нет, не опечатка. Так и должно быть.

Таким образом считаются проценты за месяц. Текущая сумма умноженная на 1,03 (03 - 3%). Т.е. каждый месяц к сумме кредита начисляются 3%.
#597 #636671
>>636668
А, я всё понял. Это чтоб лишнее действие не делать, можно сразу умножить на 1,03
#598 #636684
>>636540
http://ideone.com/PlG2VP
Насколько плохи такие решения?
другой анон
#599 #636714
Блин, какая же ХТМЛ-КСС тема - хуита скучная.
#600 #636721
ОП, поясни про задачу 11 на КСС
Задание 11. Сверстай изображенный на картинке текст. Обрати внимание, размер картинки должен определятся так: большая картинка — ужимается до ширины окна (с учетом полей конечно), маленькая — выводится как есть. HTML-код добрый дядя уже написал и выложил тут: http://pastebin.com/s1P96nVA, тебе надо лишь добавить свой CSS.

Но там только 1 картинка в коде. И что делать с текстом? Не очень ясно
#601 #636740
Хочу сделать приложение, которое ищет треды по тэгам и линкует их. Но ведь для этого (чтобы ввести в поиск параметры и сделать запрос) нужно исопльзовать curl, а для этого его нужно устанавливать. А я хочу, чтобы приложение работало на компе у любого пользователя и чтобы он никаких пхп библиотек не качал и не устанавливал. Что делать?
#602 #636741
>>636740
Если ты хочешь сделать декстопное приложение, причем тут пхп тред?
#603 #636743
>>636740
Бери какой-нибудь пайтон, там есть все что тебе нужно для этого. На пхп для такого приложения можно было бы сделать бэкэнд, а фронт на каком-нибудь модном реакте или ангуляре. Но это веб-приложение, если ты хочешь сделать на десктоп, тебе в другой тред.
#604 #636753
W5.2 Некто кладет в банк 10000 р. Банк начисляет 10% годовых
(то есть, каждый год на счету становится на 10% больше, чем в прошлом году).
Напиши программу, считающую, через сколько лет в банке будет миллион?
Сколько лет будет этому некто? Доживет ли некто до этого дня, если сегодня ему 16 лет?


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

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

Можно сделать цикл с 10000 и вплоть до ляма, это подойдет? И тут цикл надо обязательно for? While как-то посимпатичнее выглядит для этого.
#605 #636758
В одном из полей базы данных, содержатся id в таком формате: 32, 67, 89, 92 Каким образом совершать обновление этого поля? Надо при помощи одной функции вызвать содержимое это поля, дописать к нему средствами пхп нужный id после чего другой функцией обновить прошлое значение на новое? Вариантов в одну функцию нет?
#606 #636763
>>636741
Но я только на пхп знаю, как вводить параметры в запрос.
#607 #636799
http://sqlzoo.net/wiki/SQLZOO:SELECT_from_WORLD_Tutorial
что я делаю не так в последнем задании (#13)?
мой говнозапрос
http://pastebin.com/Pvfu9h4j
#608 #636803
>>636636

>2. Прибавляем к ней нужный процент и прибавляем комиссию за обслуживание кредита.


>$creditBalance = $creditBalance + ($creditBalance / 100 звёздочка $percent) + $servicePayment - $monthlyPayment;


>По-моему в описанный тобой алгоритм опять не уложился


Yep. Не надо отнимать месячную плату в основном цикле, потому что у нас всё улетит в минус.
В какой-то момент получится, допустим, $creditBalance = 3000, а ты тут же отнимешь от этой суммы 5000 $monthlyPayment - всё уйдёт в минус и в таком виде попадёт в условие if ($creditBalance < $monthlyPayment).
Совет тот же, который я давал другому братишке: попробуй либо ввести дополнительную переменную для проверки $creditBalance без вычета $monthlyPayment, либо ставь в условии, что $monthlyPayment в последний момент становится равной чистому $creditBalance (без отнятой $monthlyPayment!), а потом выплачивается, после чего цикл обрывается.
Первый вариант как-то естественнее.
>>636668

>у ОПа $percent задан как 1,03 вот на этом скрине


Да, это чтобы сразу получить $creditBalance с прибавленными 3%.

>>636753

>Можно сделать цикл с 10000 и вплоть до ляма, это подойдет?


Конечно. Нам же важно узнать, когда именно сумма вклада станет равной 1млн, к этому и стоит привязать цикл.

>И тут цикл надо обязательно for? While как-то посимпатичнее выглядит для этого.


Попробуй сначала, как проще, а потом поменяй циклы, например.
#609 #636806
>>636501

>Вообще форма слова в русском зависит только от последней цифры, исключение - это если число заканчивается на 11-19. Соответственно надо ифами это проверять. Всего может быть 3 формы слова: 1 рубль, 2 рубля, 5 рублей.


Там у меня столько разных if и else получается, что лишнего не хотелось бы.
Спасибо за советы, ОП, постараюсь применить.
Вчера вот только сделал полное разложение трёх чисел с подстановкой "рублей" - уже с помощью деления.
Хороший совет математически разбивать на тройки, я думал опять с помощью перевода числа в строку решить. Попробую и так, и так.
Тот код со стеной текста я просто не стал оптимизировать, там многое можно сократить - махнул рукой, потому что в тот момент не подумал, как можно было продолжить соединение этих частей для разложения.
#610 #636814
>>636636
Кстати, правильно сделал, что так всё наглядно разложил - сколько в какой месяц выплачивается. Я тоже так делал, когда решал.
Но вот поэтому сразу видно, что у тебя в первом же действии ошибка:

>Месяц 1


>Баланс кредита \t36412


А должно быть 37200.
40000 + 3% + 1000 - 5000 = 37200.
#611 #636822
Test
& !HU.rCDH8oU #612 #636827
test
#613 #636895
>>636799
есть кто живой?
#614 #636901
В чем проблема алгоритма http://ideone.com/8Eqcuz ?
Задача 5.2. Делаю цикл - начиная с 10к и вплоть до цифры что больше или равно миллиону(момент когда Некто всё-таки получает нужную сумму) мы выводим на экран цифры переменных и останавливаем цикл. В самом цикле повышение годов(возраст Некто и срок депозита) идёт после проверки, чтоб не добавлять в нулевой год и месяц.

Что не так?
#615 #636904
>>636495

>Почитай про контейнер в Симфони - можно идею брать с него, он тоже там хранит в себе настройки и создает сервисы:



>$container->setDefinition(...);



Вот я не понимаю такие статьи - как я могу понять как настраивать контейнер, если я не знаю что делает эта функция? Дальше просто комом становиться непонятно что написано в статье. ОП, я нормален?
#616 #636913
>>636743
Так на пхп тоже можно написать десктопное приложение, не?
#617 #636916
>>636913
Можно, но пхп не для этого сделан.
#618 #636936
>>636901
Ахаха, бро, ты отжёг!
Я тоже путаю знаки "больше" и "меньше".
Подсказка (сначала сам всё-таки поищи ошибку): цикл и не работает из-за того, что в условии внутри цикла то же выражение стоит, что и в условии для работы самого цикла. Он же должен работать, когда вклад меньше миллиона...
#619 #636942
>>636901
Также каждый раз при прохождении цикла баланс у тебя становится 10000 - это у тебя определяется в самом цикле ведь.
Это надо вынести за пределы цикла, поставить перед ним.
#620 #636949
>>636936

>Я тоже путаю знаки "больше" и "меньше".


Используй хинт: С какой стороны символ больше, с такой и значение больше
min < max
max > min
#621 #636950
>>636901
Также после условий с if ставить изменения переменных - неправильно.
Надо или перед условием, или в else.
#622 #636951
>>636950
Тогда получается что в самом начале прибавляется плюс один год и там и там, но вклад остаёся 10к.
#623 #636952
>>636949
Я почти серьёзен был в тот момент.
Ну, каждый раз представляю первое число и второе, какое больше и какое меньше, чтобы определить, в какую сторону повернуть знак.
#624 #636955
>>636951
Для этого и нужен else.
Массив регулярка #625 #636958
Анончик, объясни, пожалуйста, почему в этом коде нумерация $replacements с конца?

<?php

$string = 'The quick brown fox jumped over the lazy dog.';

$patterns = array();
$patterns[0] = '/quick/';
$patterns[1] = '/brown/';
$patterns[2] = '/fox/';

$replacements = array();
$replacements[2] = 'bear';
$replacements[1] = 'black';
$replacements[0] = 'slow';

echo preg_replace($patterns, $replacements, $string);
?>
#626 #636961
>>636721
Кто-нибудь, объясните, а
#627 #636963
>>636949
пиздец что за дауны тут сидят. шли бы в 1 цээ что ли.
#628 #636964
>>636958
Чтобы показать, что и в этом случае будет замена идти по порядку ключей, а не расположения.
Или наоборот - я с телефона и не проверю сейчас.
#629 #636965
>>636952
Лайфхак - в чью сторону "рот" открыт, тот и больше.

Лол, это классе в 3-4 учат.
#630 #636979
>>636964

>Или наоборот.


This. Замена по порядку расположения, а не нумерации ключей.
#631 #636980
>>636965
А что делать, если я привык смотреть на "острие" треугольной скобки, а не на "рот"?
Не надо меня путать, пожалуйста!
#632 #636981
Помогите с осознанием таких баз как: сервер, дебаг.

Я вот пользуют Штормом и сейчас наткнулся на статью, как прикрутить Опен Сервер на него и Хдебаг. Для чего это? Может кто-нибудь как дауну разжевать? Вообще не понимаю
#634 #637005
>>636984
Пиздец я даун, как же худо даётся всё это. А с сервером как? Зачем какой-то Апач или ОпенСервер ставить на Шторм, если и так программы запускает? Зачем?!
#635 #637012
>>637005
А человеку который далек от программирования ты тоже будешь советовать шторм ставить для запуска твоих скриптов? Я вот например не пользуюсь ИДЕ, пишу в редакторе, поэтому мне необходим сервер чтобы тестировать то что получилось. Точно так же сервер будет необходим чтобы запускать твои скрипты для использования.
#636 #637020
>>637005
Помимо IDE, а не на неё. Сервер будет ещё одним диском в "Компьютере".
РНРStorm запускает скрипты без установки сервера? Ох щи, а я думал, что тут как и с другими IDE - устанавливать сервер.
#637 #637023
>>637020

>РНРStorm запускает скрипты без установки сервера? Ох щи, а я думал, что тут как и с другими IDE - устанавливать сервер.


Там у них какой-то свой интерпретатор стоит, который криво работает. Для комфортной работы лучше поставить сервер.
#638 #637025
Реквестирую оповскую пасту по мультиверсионированию в innodb. Еще по видам джойнов: помню шо имеет значение порядок объединения таблиц, но не помню почему. Оптимизатор запроса что-то там выбирает оптимальный план, как-то так. Сохранял когда-то эти пасты на старый комп, но там окончательно умер винчестер.

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

p.s. Как на сосаче происходит автообновление? Сижу набираю пост, тут раз, и все подвисает на секунду, потому что очередной дебил что-то запостил.
Джаваскрипт блокирует ввод на время выполнения запроса? Не могу найти это место в коде.

https://2ch.hk/makaba/templates/js/swag.js (М)

> (621) var that = this;


Каков затейник.

> (4949) function updatePosts


Непонятная мешанина колбеков и прочего добра. Я вот не знаю, как буду работать. Скажут пофиксить такой код, буду наверное дня три только сидеть и разбирать последовательность вызовов.
#639 #637026
>>637012
Хм. А зачем люди тогда ставят сервер НА шторм? Это меня больше всего вымораживает

>>637020
Да всё запускается спокойно, жил не тужил и только тут понимаю, что какие-то сервера, малафья есть ещё.

И по поводу дебаггера - вроде поставил его на Шторм. ЗАЧЕМ ОН? Да, статью на вики видел и читал, но зачем? Показывать ошибки в синтаксисе? Так ИДЕ же это исполняет.
#640 #637030
>>637026

>А зачем люди тогда ставят сервер НА шторм?


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

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


Чтобы отлаживать программу в процессе её работы. С помощью дебаггера ты сможешь остановить выполнение скрипта в любой момент, и посмотреть текущее значение любой переменной. Так же, с помощью дебаггера можно выполнять программу по шагам и смотреть что происходит в нужных тебе ситуациях. Это очень полезно когда у тебя какая-то ошибка в скрипте и ты не можешь понять почему она возникает.
#641 #637042
>>637030
Cпасибо, хоть что-то проясняется. В итоге у меня как-то криво хдебаг встал на Шторм и теперь он пишет, что нет дебагера, но кое-как его запускает(по крайней мере, перестал ругаться на его отсутствие при запуске). Хуй знает, короче, не понимаю нихуя, сейчас компьютер буду ебашить кулаком
#642 #637043
>>637023

>который криво работает


Помню, аноны просили ОПа установить РНРСторм, чтобы проверить, что в их скриптах всё работает.
А на Идеоне не работало в тот же момент.
#643 #637064
>>637030

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


То есть таки можно на шторм поставить сервер? Я не понимаааат.
#644 #637069
>>637064
Можно, читай
https://www.jetbrains.com/phpstorm/help/creating-a-local-server-configuration.html для локального сервера
https://www.jetbrains.com/phpstorm/help/creating-a-remote-server-configuration.html для удаленного сервера
Алсо, начиная с версии 5.4 в пхп есть встроенный веб-сервер, у JetBrains и это в справке есть.
https://www.jetbrains.com/phpstorm/help/php-built-in-web-server.html
#645 #637076
>>637069
Спасибо, годно, надо вникнуть.
#646 #637108
Реально ли без опыта работы в офисе пойти во фриланс?
#647 #637111
>>637108
Если у тебя есть опыт в написании больших приложений - реально.
#648 #637114
>>637111
Ну я хочу для практики что-то наподобии форума написать. Хватит или нет?
#649 #637115
>>637114
Хватит, только я бы на твоем месте делал уклон в вордпресс. Я вчера уже объяснял одному анону.
>>636324
>>636326
>>636340
#650 #637123
>>637069
То есть можно и не ставить? Какие преимущества будут, если поставить?
#651 #637124
>>637114
Потом ссылочку скинь на Гитхаб, ага, спасибо.
Интересно будет посмотреть.
#652 #637125
>>637115
Сколько нужно учить пхп, чтобы сделать такое? Что вообще такое вордпресс?
#653 #637134
Оп, можешь написать пример того, как частое использование статических методов делает код процедурщиной? И в каких тогда случаях нужно юзать статик?
#654 #637146
>>637115
Всего 500 долларов? А как на такие деньги жить (живу не в СНГ, тут ни в одну контору без образования не берут, уже 5 контор прошёл).
#655 #637152
>>637146
Можно и больше, зависит от твоих скиллов и от того, сколько времени ты этому будешь уделять.
#656 #637158
>>636567
javascript.ru?
мимо другой анон
#657 #637170
>>637158
learn.javascript.ru
#658 #637181
>>637152
У меня в стране чтобы не мереть с голода надо хотя бы 2к долларов в месяц зарабатывать. Лол
#659 #637183
>>637181
Что за страна такая?
#660 #637185
>>637181
Тогда это скорее всего не для тебя. Можешь искать в офисах стажировки и превозмогать.
#661 #637187
>>637185
Так всё плохо на апворке и индусы поработили отрасль?
#662 #637194
>>637187
Скорее в вебе платят недостаточно. На каких-нибудь плюсах или шарпе платят побольше, но там вакансий меньше и работа сложнее.
16 Кб, 425x282
Задача Shift #663 #637198
ОП, проверь задачу shift, пожалуйста.

http://ideone.com/IZOcPl
#664 #637208
>>634613
>>634587

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


C 9 до 18 работа, потом допоздна обучение + без выходных, а жить то когда при таком графике?
Аноним #665 #637210
>>629822 (OP)
Ребят помогите пожалуйста "W5.1 Исправь и переделай программу, чтобы она работала нормально. Например, эта версия позволяет школьнику переплатить за кредит, так, что банк ему становится должен — это плохо! Подсказка: перед тем, как платить, надо проверять, сколько осталось долга, и если он меньше 5000, то платить только остаток и завершать цикл через break" как заставить его платить остаток ??
#666 #637216
>>637198

>foreach($offers as &$sentence)


Объясни, плиз, как работает такая конструкция?
Что даёт & перед $sentence?
А так очень хорошо решено ОП потом что-нибудь найдёт наверняка - у него дельные замечания обычно.
Но вот массив с регулярками и реплейсментом сразу можно было готовым сделать, а не набивать его после начала работы скрипта.
Вот так:
$regexp = array('/[ ][,][ ]/u', '/[ ][!][ ]/u', '/[ ][?][ ]/u', '/[ ][.][ ]/u');
$replacements = array(', ', '! ', '? ', '. ');
Эффект будет тот же, разумеется.
#667 #637217
>>637216
Едритские звёздочки, всё время забываю.
http://pastebin.com/1iYpcSXF - твои массивы с регулярками и заменами.
#668 #637227
>>635408
Не мог бы ты поподробней ответить каких именно?
#669 #637259
>>637216

>Объясни, плиз, как работает такая конструкция?


>Что даёт & перед $sentence?


foreach ($arr as &$value) == foreach ($arr as $key => $value)
Ясно, неплохо, спасибо, не дошёл ещё до этого, хотя читал уже про & для ссылок внутри скрипта.
Многое проще будет удаваться записывать.
2964 Кб, 360x288
#670 #637319
>>636803
Я по ходу сказочный долбоёб. 4 дня без отрыва решаю задачу с циклом и до сих пор не решил её. Какой пиздец, товарищи...
#671 #637353
>>637319
Я сам решал не меньше, базарю.
При этом я каждый раз с самого начала переписывал скрипт полностью. После седьмого переписывания перестал считать.
У меня там было одно решение, в котором я расписал отдельно в echo, сколько прибавляется процентов именно каждый месяц, как всё отнимается ближе к концу, чтобы понять, где я промахиваюсь.
Но общая плата у меня почти сразу стала верной, не получалось от минуса избавиться, в который всё неизбежно уходило, пока анон не надоумил ввести дополнительную переменную для расчёта кредита без вычета месячной платы.
А сейчас я буквально с закрытыми глазами могу написать решение, при этом до сих пор помню некоторые цифры из решения - типа 262 рублей под конец, общей выплаты в 61270 и т.п.
Цикл как любой проходит - просто с закрытыми глазами вижу, многое стал предугадывать в работе циклов - благодаря ОПу и этой задачке.
#672 #637367
В веб не секу, в пхп тоже.
Короч надо сделать что-то типо интернет магазина, который не имеет собственного склада, а формирует ассортимент из других магазинов.
Инфу о товарах других магазов можно брать по сути только с их страниц.
Сколько такая хуита обойдётся в деньгах и часах работы?
#673 #637374
>>637367
http://www.youtube.com/watch?v=mnT2zCXunuc
Не такое?
А так, скорее всего, надо будет магазин свой поднять, а дальше подключить парсер. Тысяч около 20 за установку, настройку купленного ContentDownloader'а какого-нибудь.
Только толку от такого будет немного, базарю.
#674 #637383
>>637374
Типо такого, но можно намного проще.
Толк понятно, что никакой, один мудак хочет сделать приложение, которое будет давать инфу по другим магазам, скидкам, хуиткам, понятное дело, что человеку проще в гугле погуглить пол часа, чем платить за какое-то приложение и искать что-то в нём пол часа.
Меня интересовал чисто ценовой вопрос, потому что в вебе не секу.
#675 #637387
>>637383

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


Идея хорошая, но уже реализована Яндексом.
У него есть какой-то бар, который даже когда ты находишься на магазине Эльдорадо, покажет тебе, что на магазине М.Видео этот товар дешевле на столько-то рублей.
Тогда даже не скажу, сколько бы стоила такая система.
Нужен парсер по основным магазинам, собственная база, на которой будет размещаться информация.
В пределах 20к рублей - по самым скромным подсчётам. Но давно не заказывал ничего, не знаю теперешних цен.
#676 #637396
Кто-нибудь тут?
ОП, у меня к тебе важный вопрос. Он не из "стандартных".

В общем, как узнать ширину/длинну и пр. параметры WebM? TinyIB использует mediainfo и ffmpegthumbnailer, с которыми у меня не срослось (точнее, у моего бесплатного хостинга не срослось с shell_exec и установкой ПО)
Если-ли способы узнать как минимум ширину и длину, но без всяких ненужных библиотек и пр.?
#677 #637397
>>637396

В библиотеке getId3 нет парсера заголовков WebM? А вообще, это несерьезно, из-за хостинга переделвать код.
#678 #637399
>>637396

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


Почитать спецификации на формат файла и понять где она хранится. Учти что в видеофайлах часто есть отдельно форма контейнера и формат в котором кодируются видеоданные.
#679 #637452
Как можно сократить
... = "/(\\.[а-я])|(\\,[а-я])|(![а-я])|(\\?[а-я])|(;[а-я])|(:[а-я])/u"
#680 #637457
>>637210
остаток на каждый ход тебе известен, он записан в $creditBalace, как только он стал меньше 5000:
$paymentTotal = $paymentTotal + $creditBalance; //вместо 5000 платишь остаток
$creditBalance = $creditBalance - $creditBalance; //кредит погашен без переплат
break;
#681 #637462
>>637457
сначало>>637457
поправка! проверяем условие $creditBank < 5000 после всех операций банка со счетом (процент и комиссия)
Аноним #682 #637491
>>637457
все понел спасибо
#683 #637503
>>637259

Там есть подвохи, например надо делать после цикла unset($value) иначе можно получить баги. Не используй ссылки, пока не прочтешь внимательно раздел в мануале про них.

>>637134

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

Почему это плохо можно почитать в уроке про зависимости https://gist.github.com/codedokode/e1d31a31b37d5f635057

Статические методы нужны в редких случаях, когда методу не нужны поля объекта, обычно это вспомогательные функции вроде вывода объема файла словами "2,1 Гб". В большинстве случаев нам нужны нормальные объекты с обычными методами. Иначе это не ООП. Так как суть ООП как раз в том что мы создаем классы для описания объектов используемых в программе. А со статическими методами объектов нет.

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

>>637146

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

>>637125

Вордпресс это CMS. Погугли.

>>637064

ЧТо значит на шторм? Как я понимаю, он умеет запускать интерпретатор пхп и Апач еси их установить и прописать нужные настройки.

>>637043

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

>>637042

Надо разобраться как это все работает, а не следовать вслепую советам с разных формуов. Как минимум, надо установить расширение к пхп, включить его в php.ini, проверить что оно соединяется с ИДЕ, проверить что в браузер или ком. строку передается нужный признак для запуска отладчика.
#683 #637503
>>637259

Там есть подвохи, например надо делать после цикла unset($value) иначе можно получить баги. Не используй ссылки, пока не прочтешь внимательно раздел в мануале про них.

>>637134

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

Почему это плохо можно почитать в уроке про зависимости https://gist.github.com/codedokode/e1d31a31b37d5f635057

Статические методы нужны в редких случаях, когда методу не нужны поля объекта, обычно это вспомогательные функции вроде вывода объема файла словами "2,1 Гб". В большинстве случаев нам нужны нормальные объекты с обычными методами. Иначе это не ООП. Так как суть ООП как раз в том что мы создаем классы для описания объектов используемых в программе. А со статическими методами объектов нет.

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

>>637146

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

>>637125

Вордпресс это CMS. Погугли.

>>637064

ЧТо значит на шторм? Как я понимаю, он умеет запускать интерпретатор пхп и Апач еси их установить и прописать нужные настройки.

>>637043

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

>>637042

Надо разобраться как это все работает, а не следовать вслепую советам с разных формуов. Как минимум, надо установить расширение к пхп, включить его в php.ini, проверить что оно соединяется с ИДЕ, проверить что в браузер или ком. строку передается нужный признак для запуска отладчика.
#684 #637507
>>637025

> Еще по видам джойнов: помню шо имеет значение порядок объединения таблиц, но не помню почему.


Для обычных джойнов не имеет, для LEFT JOIN имеет значение так как он несимметричен и выполняется в определенном порядке.

> Я вот не знаю, как буду работать. Скажут пофиксить такой код, буду наверное дня три только сидеть и разбирать последовательность вызовов.


Отладчик надо освоить, на learn.javascript есть статья.

Паста про иннодб, неформатированная

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

> Как вообще работает транзакция? Можно ли вставить миллион записей одной транзакцией, или оно пишется куда-то (в память, на диск, во временную таблицу), где есть лимит?


Транзакция это изолированный набор изменений, соответствующий принципам ACID:

https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D1%8F_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)
https://ru.wikipedia.org/wiki/ACID

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

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

В реальном мире частью требований можно жертвовать (менять уровень изоляции транзакций) в пользу производительности: https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D1%8F_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)
https://ru.wikipedia.org/wiki/%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_%D0%B8%D0%B7%D0%BE%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%82%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D0%B9
http://habrahabr.ru/post/135217/

Вопросы по транзакциям любят задавать на собеседованиях. Я считаю это правильно.

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

В MySQL в InnoDB используется так назваемая мультиверсионность:

https://en.wikipedia.org/wiki/Multiversion_concurrency_control
https://dev.mysql.com/doc/refman/5.0/en/innodb-multi-versioning.html

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

Также, еще одна вещь, которую надо понимать, это то, что MySQL гарантирует сохранность данных после успешного коммита. То есть перед тем как отчитаться что команда COMMIT завершена успешно, mysql сбрасывает данные (данные таблицы, а также изменившиеся индексы) на диск и дожидается от ОС подтверждения что они физически сохранены. Даже если питание выключится, коммит не пропадет (если оно выключится до коммита, то он пропадет, но база останется в согласованном состоянии которое было до коммита, а такого что половина данных записалась, а половина нет, быть не может. Это называется атомарность транзакции).

Соответственно если ты выполняешь запросы по одному, каждый идет отдельной транзакцией и mysql после каждого должна ждать диск. Это неэффективно. Если ты делаешь 100 запросов одной транзакцией, то mysql имеет право накапливать данные в памяти (или писать на диск без подтверждения и без ожидания), а сбросить на диск только в конце транзакции, и это работает быстрее.

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

Возвращаясь к MVCC - там для каждой строчки таблицы добавляется несколько скрытых полей, вроде таймстампа (время добавления) и номера транзакции. При изменениях в таблице (update/delete/insert) исходные данные не удаляются, а просто добавляются новые строчки. При выборке если есть несколько версий строки, по id транзакции и таймстампу выбирается самая новая видимая данному пользователю версия. При коммите новая версия становится видна всем, старая становится неактуальной и специальный фоновый тред очищает такие строки и помечает занимаемое ими место как свободное.

Условно говоря, у нас есть таблица такого вида:

id | text
1 | hello

В InnoDB она хранится с id транзакции которая ее вставила и таймстампом:

txn | timestamp | id | text
1000 | 12:00:00 | 1 | hello

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

Допустим 3 пользователя подключенных к базе параллельно открывают 3 транзакции. Первый (транзакция 1001) удаляет строчку (и пока не закоммитил транзакцию), второй (1002) и третий (1003) добавляют вторую строчку.Таблица выглядит так:

txn | timestamp | id | text
1000 | 12:00:00 | 1 | hello
1001 | 13:00:00 | 1 | (deleted)
1002 | 13:00:00 | 2 | world1
1003 | 13:00:00| 3 | world2

Пользователь внутри транзакции видит только закоммиченные чужие изменения, а также все свои. То есть транзакция 1001 видит изменения из закомиченной транзакции 1000 и незакомиченной 1001. Если пользователь сделает SELECT из этой транзакции, то база будет брать только строки транзакций 1000 и 1001, причем если эти строки соответствуют одному id, то база берет самую новую версию.

Транзакция 1001 видит только эти строки:

txn | timestamp | id | text
1000 | 12:00:00 | 1 | hello
1001 | 13:00:00 | 1 | (deleted)

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

Транзакция 1002 видит только строки от транзакций 1000 и свои, 1002. Транзакция 1003 видит строки от транзакций 1000 и 1003. Что они получат при выборке всех строк, подумай сам.

Допустим теперь транзакции 1002 и 1003 отменяются, а 1001 коммитится. Строки для отмененных транзакций стали неактуальными, и их позже удалит сборщик мусора. А так как 1001 теперь закоммичена то любой пользователь видит эту строку. При выборке он получит такие строки:

txn | timestamp | id | text
1000 | 12:00:00 | 1 | hello
1001 | 13:00:00 | 1 | (deleted)

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

Строка транзакции 1000 после коммита тран. 1001 стала неактуальной, и ее позже удалит сборщик мусора. А также строку 1001 которую после этого нет смысла хранить.

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

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

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

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

.... продолжение далее ...
#684 #637507
>>637025

> Еще по видам джойнов: помню шо имеет значение порядок объединения таблиц, но не помню почему.


Для обычных джойнов не имеет, для LEFT JOIN имеет значение так как он несимметричен и выполняется в определенном порядке.

> Я вот не знаю, как буду работать. Скажут пофиксить такой код, буду наверное дня три только сидеть и разбирать последовательность вызовов.


Отладчик надо освоить, на learn.javascript есть статья.

Паста про иннодб, неформатированная

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

> Как вообще работает транзакция? Можно ли вставить миллион записей одной транзакцией, или оно пишется куда-то (в память, на диск, во временную таблицу), где есть лимит?


Транзакция это изолированный набор изменений, соответствующий принципам ACID:

https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D1%8F_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)
https://ru.wikipedia.org/wiki/ACID

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

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

В реальном мире частью требований можно жертвовать (менять уровень изоляции транзакций) в пользу производительности: https://ru.wikipedia.org/wiki/%D0%A2%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D1%8F_(%D0%B8%D0%BD%D1%84%D0%BE%D1%80%D0%BC%D0%B0%D1%82%D0%B8%D0%BA%D0%B0)
https://ru.wikipedia.org/wiki/%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_%D0%B8%D0%B7%D0%BE%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%82%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D0%B9
http://habrahabr.ru/post/135217/

Вопросы по транзакциям любят задавать на собеседованиях. Я считаю это правильно.

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

В MySQL в InnoDB используется так назваемая мультиверсионность:

https://en.wikipedia.org/wiki/Multiversion_concurrency_control
https://dev.mysql.com/doc/refman/5.0/en/innodb-multi-versioning.html

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

Также, еще одна вещь, которую надо понимать, это то, что MySQL гарантирует сохранность данных после успешного коммита. То есть перед тем как отчитаться что команда COMMIT завершена успешно, mysql сбрасывает данные (данные таблицы, а также изменившиеся индексы) на диск и дожидается от ОС подтверждения что они физически сохранены. Даже если питание выключится, коммит не пропадет (если оно выключится до коммита, то он пропадет, но база останется в согласованном состоянии которое было до коммита, а такого что половина данных записалась, а половина нет, быть не может. Это называется атомарность транзакции).

Соответственно если ты выполняешь запросы по одному, каждый идет отдельной транзакцией и mysql после каждого должна ждать диск. Это неэффективно. Если ты делаешь 100 запросов одной транзакцией, то mysql имеет право накапливать данные в памяти (или писать на диск без подтверждения и без ожидания), а сбросить на диск только в конце транзакции, и это работает быстрее.

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

Возвращаясь к MVCC - там для каждой строчки таблицы добавляется несколько скрытых полей, вроде таймстампа (время добавления) и номера транзакции. При изменениях в таблице (update/delete/insert) исходные данные не удаляются, а просто добавляются новые строчки. При выборке если есть несколько версий строки, по id транзакции и таймстампу выбирается самая новая видимая данному пользователю версия. При коммите новая версия становится видна всем, старая становится неактуальной и специальный фоновый тред очищает такие строки и помечает занимаемое ими место как свободное.

Условно говоря, у нас есть таблица такого вида:

id | text
1 | hello

В InnoDB она хранится с id транзакции которая ее вставила и таймстампом:

txn | timestamp | id | text
1000 | 12:00:00 | 1 | hello

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

Допустим 3 пользователя подключенных к базе параллельно открывают 3 транзакции. Первый (транзакция 1001) удаляет строчку (и пока не закоммитил транзакцию), второй (1002) и третий (1003) добавляют вторую строчку.Таблица выглядит так:

txn | timestamp | id | text
1000 | 12:00:00 | 1 | hello
1001 | 13:00:00 | 1 | (deleted)
1002 | 13:00:00 | 2 | world1
1003 | 13:00:00| 3 | world2

Пользователь внутри транзакции видит только закоммиченные чужие изменения, а также все свои. То есть транзакция 1001 видит изменения из закомиченной транзакции 1000 и незакомиченной 1001. Если пользователь сделает SELECT из этой транзакции, то база будет брать только строки транзакций 1000 и 1001, причем если эти строки соответствуют одному id, то база берет самую новую версию.

Транзакция 1001 видит только эти строки:

txn | timestamp | id | text
1000 | 12:00:00 | 1 | hello
1001 | 13:00:00 | 1 | (deleted)

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

Транзакция 1002 видит только строки от транзакций 1000 и свои, 1002. Транзакция 1003 видит строки от транзакций 1000 и 1003. Что они получат при выборке всех строк, подумай сам.

Допустим теперь транзакции 1002 и 1003 отменяются, а 1001 коммитится. Строки для отмененных транзакций стали неактуальными, и их позже удалит сборщик мусора. А так как 1001 теперь закоммичена то любой пользователь видит эту строку. При выборке он получит такие строки:

txn | timestamp | id | text
1000 | 12:00:00 | 1 | hello
1001 | 13:00:00 | 1 | (deleted)

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

Строка транзакции 1000 после коммита тран. 1001 стала неактуальной, и ее позже удалит сборщик мусора. А также строку 1001 которую после этого нет смысла хранить.

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

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

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

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

.... продолжение далее ...
#685 #637511
>>637025

продолжение пасты

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

.....

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

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

Обрати внимание что речь тут шла о блокировках для модификации данных. MVCC (почти) не требует их наличия. Но MySQL все равно блокирует строки, которые изменяются или удаляются. Это делается для того чтобы 2 транзакции не могли сделать противоречащие изменения (например записать разные значения в одну и ту же строку) и нарушить ACID. MySQL делает блокировки как минимум в таких случаях:

- есть 2 писателя (UPDATE/DELETE) для 1 и той же строки
- есть писатель + читатель (SELECT) для 1 и той же строки

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

https://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-model.html
http://webew.ru/articles/1383.webew

В особо тяжелых слуаях можно словить взаимную блокировку - deadlock:

https://ru.wikipedia.org/wiki/%D0%92%D0%B7%D0%B0%D0%B8%D0%BC%D0%BD%D0%B0%D1%8F_%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0

Например транзакция A хочет апдейтить строку 1, за ней строку 2. Транзакия B хочет апдейтить сначала 2, потом 1. Каждая их них захватит блокировку по одной строке и никогда не получит блокировку по второй. MySQL обнаруживает дедлоки и решает их принудительным откатом одной из транзакций.

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

Подробности о работе и состоянии движка InnoDB можно получить запросом (попробуй это сделать):

SHOW ENGINE InnoDB STATUS\G

Увидеть список соединений и выполняющихся запросов можно командой SHOW FULL PROCESSLIST\G. Убить поток-воркер можно командой KILL 123; (принципы ACID и целостность данных это не нарушит).

Наконец, вернемся к этому вопросу:

> Можно ли вставить миллион записей одной транзакцией, или оно пишется куда-то (в память, на диск, во временную таблицу), где есть лимит?


В InnoDB есть пул страниц (InnoDB buffer pool) в памяти: https://dev.mysql.com/doc/refman/5.5/en/innodb-buffer-pool.html

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

Потому ответ на твой вопрос: данные пишутся в память пока есть место и на диск. Размер базы ограничен местом на диске, настройками конфига и встроенными ограничениями (вроде того что размер строки ограничен 65536 байтами).

Как ты понимаешь, от объема пула зависит часто ли базе придется обращаться к диску, а диск очень медленный. На серверах БД под пул выделяют 80-90% свободной памяти, также есть мнение что размер пула должен быть не меньше чем размер индексов (и «горячих» данных). Не редкость иметь например 100 Гб пула если на сервере много памяти.

А теперь вопросы для проверки.

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

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

2) Почему MVCC позволяет это не делать?

3) Более сложный вопрос, почему InnoDB блокирует строки, хотя MVCC позволяет это не делать? Почему строки блокируются на все время транзакции (а не на время выполнения запроса)? Что будет если не блокировать?

4) И еще, если программа выбирает какие-то данные (SELECT), меняет их и записывает назад в базу (UPDATE), как запретить другим в это время их менять?
#685 #637511
>>637025

продолжение пасты

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

.....

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

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

Обрати внимание что речь тут шла о блокировках для модификации данных. MVCC (почти) не требует их наличия. Но MySQL все равно блокирует строки, которые изменяются или удаляются. Это делается для того чтобы 2 транзакции не могли сделать противоречащие изменения (например записать разные значения в одну и ту же строку) и нарушить ACID. MySQL делает блокировки как минимум в таких случаях:

- есть 2 писателя (UPDATE/DELETE) для 1 и той же строки
- есть писатель + читатель (SELECT) для 1 и той же строки

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

https://dev.mysql.com/doc/refman/5.0/en/innodb-transaction-model.html
http://webew.ru/articles/1383.webew

В особо тяжелых слуаях можно словить взаимную блокировку - deadlock:

https://ru.wikipedia.org/wiki/%D0%92%D0%B7%D0%B0%D0%B8%D0%BC%D0%BD%D0%B0%D1%8F_%D0%B1%D0%BB%D0%BE%D0%BA%D0%B8%D1%80%D0%BE%D0%B2%D0%BA%D0%B0

Например транзакция A хочет апдейтить строку 1, за ней строку 2. Транзакия B хочет апдейтить сначала 2, потом 1. Каждая их них захватит блокировку по одной строке и никогда не получит блокировку по второй. MySQL обнаруживает дедлоки и решает их принудительным откатом одной из транзакций.

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

Подробности о работе и состоянии движка InnoDB можно получить запросом (попробуй это сделать):

SHOW ENGINE InnoDB STATUS\G

Увидеть список соединений и выполняющихся запросов можно командой SHOW FULL PROCESSLIST\G. Убить поток-воркер можно командой KILL 123; (принципы ACID и целостность данных это не нарушит).

Наконец, вернемся к этому вопросу:

> Можно ли вставить миллион записей одной транзакцией, или оно пишется куда-то (в память, на диск, во временную таблицу), где есть лимит?


В InnoDB есть пул страниц (InnoDB buffer pool) в памяти: https://dev.mysql.com/doc/refman/5.5/en/innodb-buffer-pool.html

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

Потому ответ на твой вопрос: данные пишутся в память пока есть место и на диск. Размер базы ограничен местом на диске, настройками конфига и встроенными ограничениями (вроде того что размер строки ограничен 65536 байтами).

Как ты понимаешь, от объема пула зависит часто ли базе придется обращаться к диску, а диск очень медленный. На серверах БД под пул выделяют 80-90% свободной памяти, также есть мнение что размер пула должен быть не меньше чем размер индексов (и «горячих» данных). Не редкость иметь например 100 Гб пула если на сервере много памяти.

А теперь вопросы для проверки.

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

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

2) Почему MVCC позволяет это не делать?

3) Более сложный вопрос, почему InnoDB блокирует строки, хотя MVCC позволяет это не делать? Почему строки блокируются на все время транзакции (а не на время выполнения запроса)? Что будет если не блокировать?

4) И еще, если программа выбирает какие-то данные (SELECT), меняет их и записывает назад в базу (UPDATE), как запретить другим в это время их менять?
#686 #637515
>>637012

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

>>637005

Он их в консоли ведь запускает? А с веб-сервером можно через браузер запускать.

>>636981

Про сервер - почитай урок про Апач в ОП посте. Может поможет.

>>636721
>>636961

> Но там только 1 картинка в коде. И что делать с текстом? Не очень ясно


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

С текстом особо ничего и не надо делать.
#687 #637520
Знаком тут кто с YouTube API ?
#688 #637521
>>636904

Можно почитать мануал/погуглить, можно попробовать так понять. Там сделан универальный контейнер, то есть изначально в нем нет никаких сервисов. Соответственно методом setDefinition ты задаешь правила создания сервиса (объекта):

- как создать объект: через new, через вызов метода-фабрики или еще как-то
- объект какого класса создать
- что передать в конструктор
- есть ли зависимость от других сервисов (т.е. надо ли их передать в конструктор)

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

Но в твоем приложении ты можешь упростить задачу и сделать не универсальный контейнер + конфиг к нему, а заточенный под твою задачу, где все сервисы прописаны в классе и не требуется его настраивать. То есть с методами типа getPdo(), getUserMapper() и тд.
#689 #637522
>>636904

Также есть очень простой и тоже универсальный контейнер pimple

https://habrahabr.ru/post/199296/
http://pimple.sensiolabs.org/

А вот его код, совсем немного: https://github.com/silexphp/Pimple/blob/master/src/Pimple/Container.php
#690 #637523
Перекат будет? Почти 700 постов уже.
#691 #637524
А для Javascript и html+css нормально использовать phpstorm? Очень важно автодополнение и автоподстановка.
#692 #637526
>>636895
>>636799

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

>>636806

3 формы = 3 ифа, немного

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


На функции надо разбивать.

>>636763

Значит надо идти учить Си++, C#, java.

>>636758

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

>>636753

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

>>636714

А ты порешай наши задчки из ОП поста и покажи решения.

>>636684

> function isArrayOk($arr)


Копипаста, почему бы не сделать массив со списком полей и не сравнить их готовой функцией?

> function isArrayOk2($arr)


Это уже лучше, хотя мне кажется проще сделать через 2 вызова array_diff. Ну и не надо число 10 прописывать, надо его вычислять автоматом.
#692 #637526
>>636895
>>636799

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

>>636806

3 формы = 3 ифа, немного

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


На функции надо разбивать.

>>636763

Значит надо идти учить Си++, C#, java.

>>636758

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

>>636753

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

>>636714

А ты порешай наши задчки из ОП поста и покажи решения.

>>636684

> function isArrayOk($arr)


Копипаста, почему бы не сделать массив со списком полей и не сравнить их готовой функцией?

> function isArrayOk2($arr)


Это уже лучше, хотя мне кажется проще сделать через 2 вызова array_diff. Ну и не надо число 10 прописывать, надо его вычислять автоматом.
#693 #637530
>>636575

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

>>636570

Плохо то что не используются возможности ООП, а классы намертво связаны друг с другом. Попробуй почитать урок про DI https://gist.github.com/codedokode/e1d31a31b37d5f635057

Статические вызовы связывают классы намертво и не дают возможности что-то менять.

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


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

> Или всегда обязательно писать новый класс?


Каждый маппер работает со своей таблицей, так что да. Это делается для того чтобы инкапуслировать все запросы к 1 таблице в 1 классе. И если что-то меняется в этой таблице то в идеале достаточно поменять только этот класс.
#694 #637531
>>636555

В задачах в ОП посте на ХТМЛ есть несколько ссылок.
#695 #637532
>>637523

Пока нет, горим тут.
#696 #637535
>>637526

>3 формы = 3 ифа, немного


Хм, я думал, что надо больше.
Ведь у нас 1 даёт одну форму, 2, 3, 4 дают другую, а все остальные числа дают третью.
Допустим, у нас первое вот так пойдёт:
if ($lastThousandNum == 1) {
$rouble = 'рубль';
echo $rouble;
} else {
$rouble = 'рублей';
echo $rouble;
}
А дальше я вот не знаю, как можно заставить работать вот такое нечто:
if ($lastThousandNum == 2|3|4) {
$rouble = 'рубля';
echo $rouble;
}
Такое просто не работает! Можно ли как-нибудь этот момент представить? Пробовал по-разному представлять там "или это, или то, или сё". Гуглил-шмуглил - ничего не нашёл.
Иначе можно будет только копипастить:
if ($lastThousandNum == 2) {
$rouble = 'рубля';
echo $rouble;
} elseif ($lastThousandNum == 3) {
$rouble = 'рубля';
echo $rouble;
} elseif ($lastThousandNum == 4) {
$rouble = 'рубля';
echo $rouble;
}
Наверняка же какой-то способ должен быть.
#696 #637535
>>637526

>3 формы = 3 ифа, немного


Хм, я думал, что надо больше.
Ведь у нас 1 даёт одну форму, 2, 3, 4 дают другую, а все остальные числа дают третью.
Допустим, у нас первое вот так пойдёт:
if ($lastThousandNum == 1) {
$rouble = 'рубль';
echo $rouble;
} else {
$rouble = 'рублей';
echo $rouble;
}
А дальше я вот не знаю, как можно заставить работать вот такое нечто:
if ($lastThousandNum == 2|3|4) {
$rouble = 'рубля';
echo $rouble;
}
Такое просто не работает! Можно ли как-нибудь этот момент представить? Пробовал по-разному представлять там "или это, или то, или сё". Гуглил-шмуглил - ничего не нашёл.
Иначе можно будет только копипастить:
if ($lastThousandNum == 2) {
$rouble = 'рубля';
echo $rouble;
} elseif ($lastThousandNum == 3) {
$rouble = 'рубля';
echo $rouble;
} elseif ($lastThousandNum == 4) {
$rouble = 'рубля';
echo $rouble;
}
Наверняка же какой-то способ должен быть.
#697 #637537
>>637535

>$lastThousandNum


*$lastNum
Исправил.
Это я сейчас думаю с тысячами как быть - не получается без костылей исправить момент с женским родом 1 и 2 тысяч.

>"452" - это "четыреста пятьдесят два тысячи"


Я могут просто сделать в этом случае ещё одну функцию именно для тысяч, которая 1 и 2 в последней цифре тройки переведёт в "одна" и "две", либо сделать массив $menSpelling, который будет подставляться в функцию вместо $femaleSpelling - и менять то, что и так должно выходить правильно.
Не получается изменить внутри общей функции, чтобы всё было компактно.
#698 #637538
>>637396
getId3 версии 1.9.4 может давать подробную информацию о всех медиафайлах, включая webm.
Аноним #699 #637551
в обще не могу понять как это делать
W5.1
W5.2
у меня есть шансы?
79 Кб, 486x600
#700 #637556
Выручайте, ребята. Пхп в последний раз видел в 2006.
А тут надо было по-быстрому одну хуету сделать, и что-то даже с ней обосрался
Есть хтмл форма с одним полем и сабмитом, нужно по сабмиту отправлять мейл с содержимым формы на определённый адресс

Форма:
<form action='form.php' method="post">
<fieldset>
<input id="field" name="field" type="text" placeholder="Координаты" class="form-control input-md" required="">
<button id="submit" name="submit" class="btn btn-primary btn-lg">Отправить</button>
</fieldset>
</form>

Скрипт:
<?php
if(isset($_POST["submit"]) and ($_POST["field"]=="")) {
echo "Пусто";
} else {
$subject = 'New Customer from DoorsLandingPage'
$message = $_POST['field'];
$message = addslashes($message);
$headers = "From: Landing"; // Sender's Email
mail("тут_е_мейл", $subject, $message, $headers);
echo "Отправлено";
sleep(2);
echo "<meta http-equiv=\"refresh\" content=\"0; url=\"адрессайта\"/>";
}
?>

Чому оно всё время мне Еррор 500 даёт?
79 Кб, 486x600
#700 #637556
Выручайте, ребята. Пхп в последний раз видел в 2006.
А тут надо было по-быстрому одну хуету сделать, и что-то даже с ней обосрался
Есть хтмл форма с одним полем и сабмитом, нужно по сабмиту отправлять мейл с содержимым формы на определённый адресс

Форма:
<form action='form.php' method="post">
<fieldset>
<input id="field" name="field" type="text" placeholder="Координаты" class="form-control input-md" required="">
<button id="submit" name="submit" class="btn btn-primary btn-lg">Отправить</button>
</fieldset>
</form>

Скрипт:
<?php
if(isset($_POST["submit"]) and ($_POST["field"]=="")) {
echo "Пусто";
} else {
$subject = 'New Customer from DoorsLandingPage'
$message = $_POST['field'];
$message = addslashes($message);
$headers = "From: Landing"; // Sender's Email
mail("тут_е_мейл", $subject, $message, $headers);
echo "Отправлено";
sleep(2);
echo "<meta http-equiv=\"refresh\" content=\"0; url=\"адрессайта\"/>";
}
?>

Чому оно всё время мне Еррор 500 даёт?
#701 #637558
>>637556

>Еррор 500


Это ведь северу пиздец, и от самого скрипта не зависит, насколько я помню.
#702 #637559
>>637556
ПХП твой тут непричём
www.jino.ru/help/faq/problems/error-500/
#703 #637562
>>637551

>ыфвфывфывфвv3KфыANUSmaixTflPUNCTUMr.b[u


>2016


>у меня есть шансы?


Нет.
2883 Кб, 354x349
#704 #637563
>>637558
>>637559
Вот блин. Всё нахуй в айти всегда через сраку, сука.
Спасибо, тем не менее, парни. Добра!
#705 #637565
>>637558
>>637559
Вы тролите или дауны? Там просто точка с запятой пропущена.
Пятисотый статус здесь как раз из-за ошибки в php скрипте.
#706 #637566
Друзья, а как сделать в пхп ввод строки пользователем? Или это сделать невозможно?
3530 Кб, 500x321
#707 #637569
>>637565
Ох ё! Спасибо тебе огромное, товарищ! Починил и говно это заработало.
Держи дочку Бори Немцова
Аноним #708 #637570
>>637562
ну и что мне теперь делать я не хочу быть агрономам(
#709 #637578
>>637570
Если ты идешь в айти ради денег у тебя ничего не получится.
Аноним #710 #637580
>>637578
не совсем так , мне это интересно но видимо я глуповат
Аноним #711 #637582
>>637578
да и все что я умею это сидеть за компутиром,
это единственное в чем я хоть как-то разбираюсь
#712 #637586
>>637580
>>637582
Тогда учи и превозмогай. В задачах нет ничего сложного, главное подумать немного.
Аноним #713 #637589
>>637586
наверно просто плохо старался, спасибо тебе теперь я что-то понел.
#714 #637592
Абу негодуе

swag.js:4984
post.comment = post.comment.replace('<script ', '<!--<textarea '); //какой-то УМНИК решил, что будет гениальной идеей в посты вставлять кривой <script> с document.write
post.comment = post.comment.replace('</script>', '</textarea>-->');
#715 #637623
>>637592
swag.js:4984
post.comment = post.comment.replace('<script ', '<!--<textarea ');
document.write
post.comment = post.comment.replace('</script>', '</textarea>-->');
#716 #637642
У кого-нибудь есть простенький круд или гостевуха на друпале? Заебало по хеллоуворду на каждом цмс-фреймворке пистаь, все равно они все однотипные.
#717 #637665
>>637569
Это не она.
69 Кб, 768x730
#718 #637695
Никак не могу понять, в чем проблема в моем массиве.
Хром выкидывает ошибку непредвиденного ДАББЛ АРРОУ unexpected T_DOUBLE_ARROW.

Сначала делал по новой схеме:
<?php
$leftMenu = [
['link' => 'Домой', 'href' => 'index.php'],
['link'=>'О нас', 'href'=>'about.php'],
['link'=>'Контакты', 'href'=>'contact.php'],
['link'=>'Таблица умножения', 'href'=>'table.php],
['link'=>'Калькулятор', 'href'=>'calc.php']
];
?>

Потом, задумался, что у меня старая версия ПХП установлена и сделал по-старинке, но все равно та же херня.

<?php
$leftMenu = array(
('link' => 'Домой', 'href' => 'index.php'),
('link'=>'О нас', 'href'=>'about.php'),
('link'=>'Контакты', 'href'=>'contact.php'),
('link'=>'Таблица умножения', 'href'=>'table.php'),
('link'=>'Калькулятор', 'href'=>'calc.php')
);
?>

Где проблема? Кто-нибудь ее видит?
69 Кб, 768x730
#718 #637695
Никак не могу понять, в чем проблема в моем массиве.
Хром выкидывает ошибку непредвиденного ДАББЛ АРРОУ unexpected T_DOUBLE_ARROW.

Сначала делал по новой схеме:
<?php
$leftMenu = [
['link' => 'Домой', 'href' => 'index.php'],
['link'=>'О нас', 'href'=>'about.php'],
['link'=>'Контакты', 'href'=>'contact.php'],
['link'=>'Таблица умножения', 'href'=>'table.php],
['link'=>'Калькулятор', 'href'=>'calc.php']
];
?>

Потом, задумался, что у меня старая версия ПХП установлена и сделал по-старинке, но все равно та же херня.

<?php
$leftMenu = array(
('link' => 'Домой', 'href' => 'index.php'),
('link'=>'О нас', 'href'=>'about.php'),
('link'=>'Контакты', 'href'=>'contact.php'),
('link'=>'Таблица умножения', 'href'=>'table.php'),
('link'=>'Калькулятор', 'href'=>'calc.php')
);
?>

Где проблема? Кто-нибудь ее видит?
#719 #637696
>>637695
Точнее, даже не так, когда делал по новой схеме, то у меня интерпретатор даже не распознавал массив и показывал анэкпектед "[".
23 Кб, 1919x143
#720 #637699
>>637695
$leftMenu = array(
array('link' => 'Домой', 'href' => 'index.php'),
array('link'=>'О нас', 'href'=>'about.php'),
array('link'=>'Контакты', 'href'=>'contact.php'),
array('link'=>'Таблица умножения', 'href'=>'table.php'),
array('link'=>'Калькулятор', 'href'=>'calc.php')
);
#721 #637702
>>637695

>['link'=>'Таблица умножения', 'href'=>'table.php],


table.php не закрыл кавычкой, например.
#722 #637703
>>637695
http://ideone.com/RC7NY1
А в какой IDE делаешь, почему не показало, что отсутствует кавычка?
#723 #637705
>>637696
Аа, ну вот и ответ: IDE ожидает ', а получает неожиданную ].
#724 #637708
>>637703
>>637702
Кавычкой закрыл, просто стер ее случайно, когда скобки менял.

>>637699
Что ты хочешь сказать?
#725 #637709
Насколько оправданно самому возиться с установкой Апаче, его настройкой вместо сборки типа Хамп?
#726 #637712
>>637705
Так в чем проблема-то тогда? У меня сейчас истерика начнется. Программа ни единой ошибки не засекла, сам я их тоже не вижу.
#727 #637714
>>637709
Хамп хуита, попробуй накатить опен сервер.
#728 #637715
>>637714
В чём отличие? И стоит ли вообще делать, как говорит ОП - самому поочерёдно ставить апач, настраивать и его тп?
#729 #637717
>>637712
Так у тебя не заработало, что ли?
Вот же ссылку я на Идеоне дал, в которой массив нормально читается: http://ideone.com/RC7NY1
Проблема и была в не закрытой кавычке, разве нет?
52 Кб, 582x465
43 Кб, 1919x136
#730 #637718
>>637708
В первом варианте не закрыл кавычку, во втором неправильно объявляешь массив в массиве.

У меня пхп версии 5.6, оба варианта работают.
#731 #637720
>>637714
Опенсервер говно, денвер рулет.

>>637715
Если ты на работе собираешься каждый раз ставить и настраивать апач, то ставь и настраивай.
#732 #637721
>>637715
А зачем? Если ты любишь красноглазить и разбираться во всяких штуках низкоуровневых, то пожалуйста. Если любит нажать комбинацию кнопок, и чтобы все работало - ставь опен сервер. Отличие в стабильности, мультиверсионности и удобства интерфейса как такового.
#733 #637722
>>637718
Няшный тёмный скриншот из какой IDE?
#734 #637723
>>637721
Блин, где вы были два часа назад, когда я муторно возился с каждой ошибкой апача... Его теперь сносить лучше и ставить опен или поверх можно поставить и не будет проблем?

И надо ли ставить опенсервер на phpstorm или нет?
#735 #637724
>>637722
все IDE имеют одинаковые цветовые гаммы, если что
#736 #637725
>>637722
Это Атом с темой One Dark.
#737 #637726
>>637717
Проблема решена и была вот в чем => >>637718
Я не правильно объявлял массив в массиве. Спасибо за участие, анончик.

>>637718 - тебе особое огромное спасибо.
#738 #637727
>>637723
Эм, попробуй все снести и поставить опен сервер. Тебе он понравится, гарантирую.

>И надо ли ставить опенсервер на phpstorm или нет?


Не понял вопроса. Пхпшторм это же редактор, да? Как на него можно сервер ставить?
#739 #637728
#740 #637730
>>637718
Ах, да, у меня 5.3 стоит, на ней не работает вариант первый.
#741 #637731
>>637727
Да не совсем редактор, это IDE полноценная, у него есть свой сервер и интерпретатор и т.п., просто из настроек я вижу, что можно сервер поставить сторонний, но не знаю, надо ли
#742 #637747
>>637731
Задай себе вопрос. У тебя пыха работает во встроенном сервере? Дальше следуй алгоритму: if (true) { echo "Нахуя мне что-то еще?"; } elseif (false) { echo "Поставлю-ка я опен сервер."; } else { echo "Зачем мне вообще программирование? Лучше пойду займусь чем-нибудь интеллектуальным"; }.
#743 #637748
>>637623
Ты даже скопировал неправильно

>>637507

>Отладчик надо освоить, на learn.javascript есть статья.


Распиши подробно, как этим пользоваться. На learn.javascript описано только как
он выглядит, и как ставить точки останова.
Все равно ведь придется ползать по коду и искать, где ставить эти точки останова.
Вот я хочу отследить, как на сосаче происходит обновление треда.
Либо при нажатии на кнопку "обновить", либо по таймеру.
На кнопке "обновить тред" функция updatePosts на строке 4949.
В ней метод объекта Post.download(function(data){...}).
В data приходит объект с массивом постов, полем с ошибкой и т.д.
Дальше на строке 4968 в цикле $.each для каждого элемента в data вызывается
appendPost(tmpost.getJSON())
appendPost объявлена на 5081.
В ней вызывается generatePostBody, объявленная на 4982. В ней на лету склеивается
корявый html из строк, вместо того чтобы использовать шаблон.
Затем пост добавляется через $('#thread').append()

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

Так все-таки, какая польза от отладчика кроме возможности остановить исполнение
в определенный момент (а этот момент еще надо вычислить) и посмотреть значение переменных?
#744 #637758
Вангую, что пошлете меня читать мануалы, но почему в случае, когда двойные кавычки входят в другие двойные выскакивает ошибка T_LNUMBER? Неужто их нужно экранировать? В экмаскриптах такого не было.
#745 #637759
#746 #637764
>>637526

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


А как осуществить хранение idишников пользователей, которые находятся в данное место в определённом месте сайта (в комнате чата), не создавать же для каждого отдельное поле в таблице. Или надо было создать отдельную таблицу, в которой бы просто хранились айдишники и принадлежость их к той или иной комнате чате?
#747 #637767
>>637764
Второй способ.
#748 #637781
>>637520
Уже познакомился.
Задавайте свои ответы.
#749 #637784
>>637759
У тебя там Успешный статус.
В чем проблема то?

И как двойные кавычки вставить в двойные кавычки, то? Это же 2 пары получится, конечно нужно экранировать.
#750 #637791
>>637784

>У тебя там Успешный статус.


Что, прости?
Про кавычки понял.
#751 #637792
>>637791
Твой код выполнялся без ошибок
6 Кб, 408x288
#752 #637796
Поясните, кто делал задания на КСС, что тут требуется?

Какая-то наркомания, какой-то родитель, 10 пикселей всюду разные, 34% - 10 пикселей, что это вообще такое? Вообще ничего не понятно.
#753 #637799
>>637796
Что такое margin?
Что такое padding?
Что такое width?
#754 #637801
>>637799
Это я нагуглил и понял, но вот что требуется в задании? Сделать эти два прямоугольника?
#755 #637802
#756 #637804
>>637792
А, ну, я просто сначала по привычке две в две закинул по принципу js. Потом понял ошибку и изменил на одинарные.
#757 #637813
>>637804
Какому "принципу js"? В яваскрипте все точно так же. Нажми ctrl+j и скопируй в консоль var str = "abc"def"ghi";

>>637796
Что тут может быть непонятно? Желтый блок занимает две трети ширины родительского блока (серый прямоугольник), прижат к левому краю контейнера.
Фиолетовый блок то же самое, прижат вправо.
Между блоками 10px по вертикали. У родительского контейнера (серый прямоугольник) поля по 10px.
#758 #637833
>>637813

>ctrl+j


Ты хотел сказать ctrl+f12.
#759 #637837
>>637833
В Лисе просто F12.
#760 #637841
>>637726
Теперь я не понимаю, какие проблемы в первом твоём варианте были после исправления той кавычки.
Там массив правильно сам по себе определён же!
>>637730
Аа, теперь понимаю.
А второй вариант я даже не посмотрел, в чём там дело.
#761 #637848
>>637841
Я уже сменил на 5.6 и апач 2.4 накатил.
#762 #637858
>>637813

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


в задании сказано, что серые прямоугольники верстать не надо. Что будет родителем в таком случае?
#763 #637872
>>637858
Блок <body></body>
#764 #637878
>>637872
спасибо
#765 #637879
>>637878
пожалуйста
#766 #637881
>>637879
Не благодари за меня.
#767 #637889
>>622151
Если бы ты его внимательно слушал, то понял бы, что он вообще с формочек на делфи начинал.
#768 #637893
>>622151

>но боюсь пхп-макаке о таком и мечтать нельзя


Чего это нельзя? Всякие Epam и Softserve набирают PHP миддлов и синьеров. Да и вакансий на PHP за рубежом не меньше чем в СНГ.
#769 #637900
>>637893
Какая разница сколько там вакансий? Кто возьмет на них простого хуя из другой страны, когда и в своей пхп девелоперов полно?
#770 #637905
>>637900
Лол, точно такое же можно сказать про все остальные ИТ вакансии. Тем не менее очень много людей уезжают по H1B. Да и по L1 тебя так же могут перевести как PHP девелопера.
#771 #637908
>>637905

>Человек без высшего образования может быть нанят по визе H1B в США, если он сможет подтвердить, что является специалистом, эквивалентным дипломированному, на основании опыта двенадцати или более лет в определенной отрасли занятий.


Пиздос
#772 #637911
>>637908
Да, для визы H1B нужно иметь вышку (как минимум бакалавр) которую признают как Computer Science degree. Для визы L1 это требование отсутствует, но её обычно получить сложнее чем H1B.

А вообще если интересно, проследуй в /em/, там есть тред с пояснениями.
#773 #637913
>>637908
Средний возраст иммигранта 28-32 года.
Тебе сейчас 16-20 лет, так что если устроишься на работку в ближайщее время, то вполне впишешься в график.
#774 #637917
>>637913
12 лет это уж слишком, полжизни пройдет, мне уже к земле надо будет готовиться, а не к эмиграции.
#775 #637918
>>637917
Лол, а я думал, что один, кто умрет до 40.
#776 #637919
>>637913

>Тебе сейчас 16-20 лет


но мне 25
#777 #637920
>>637917
Так опыт 12+ лет обязателен если у тебя нет высшего образования. Если оно у тебя есть, и служба которая выдает визы признает его как Computer Science degree, тогда на опыт работы будет смореть только твой работодатель.
#778 #637923
>>637920
У бОльшей части пхп-треда нет высшего образования в области IT.
#779 #637924
>>637920
Я бы даже сказал, у всех.
#780 #637948

>2016


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


Свои приложения надо пилить, сервисы, сайты для людей.
А не надеяться на дядю.
#781 #637949
>>637948
Много уже своих приложений запилил, бизнесмен?
#782 #637951
Четвертая версия select2 еще зеленая что ли?
https://jsfiddle.net/v699fwb3/1/
Странное позиционирование списка это баг, или так и должно быть?

В 3.5 этой фигни нет.
https://jsfiddle.net/v699fwb3/3/

Ну елки зеленые, как же это утомляет.
inb4: сейчас оп посоветует перечитать пять тысяч строк исходников, чтобы пофиксить эту мелочь.
#783 #637967
>>637951

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


Таки придется, если ты велосипедов не нагуглил.
#784 #637973
>>637919
Есть тут ещё такие?
#785 #637976
>>637919
Мне скоро 22. Знаю очень мало.
#786 #637982
У меня в задаче написано что если кредитбаланс будет меньше, или равен нулю, то цикл надо брейкать, почему он продолжает считать 0 рублей до 20 месяца?
#787 #637983
>>637982
А твой код где увидеть?
#788 #637985
>>637982
Либо кредитбаланс никогда не становится меньше или равен нулю.
Либо ты как те два дебила выше путаешь знаки больше/меньше.

Код выкладывай.
#789 #638028
Ляпаю тут несколько страничек, особое внимание тому, чтобы леваков не ходило, поэтому было решено сделать авторизацию.
Делаю через сессии.
При старте сессии на каждой из страниц вроде всё нормально. Авторизовался ранее - работаешь. Не авторизовался - редиректит на логин страницу. В качестве значений есть $_SESSION['userlogin'] и $_SESSION['userid']. Отсюда же вопрос. Подсунуть эти значения посетитель как-то может? Надо ли проверять их валидность на каждой из открываемых страниц с сессиями или же достаточно просто проверки на их наличие?
#790 #638036
>>638028

>Подсунуть эти значения посетитель как-то может?


Подсунуть эти значения из ничего никак не выйдет. Подсунуть можно айди сессии другого пользователя, но тут уже нужен доступ к его кукам, который не так-то просто получить. Ну и еще можно будет формы отправлять с других сайтов под именем пользователя, это называется csrf и у ОПа на эту тему есть урок.
https://github.com/codedokode/pasta/blob/master/security/xsrf.md
#791 #638037
Пилите перекат, господа
#793 #638039
>>638036
>>638028
Кстати, чисто в теории можно будет написать скрипт, который сможет угадать чей-то айди сессии, но это уже оверкилл и такого делать никто не будет, я думаю. Если ты делаешь какую-то очень защищенную систему, можешь при логине записывать айпи пользователя и айди сессии, потом на каждой странице проверять, если айпи пользователя поменялся - удалять сессию и отправлять его на страницу логина. Конечно, у этой системы будет недостаток, например если пользователь переподключился к интернету и у него сменился айпи - его перенаправит на страницу логина.
#794 #638042
Как внести в базу данных значения при помощи Аякса я понял, а как вывести эти значения на страницу без перезагрузки страницы? Нашёл два варианта подобного, и оба делаются через setInterval, так и должно быть? Или есть другие варианты? Это нормально вообще, запускать функцию каждую секунду всё время работы?
#795 #638048
>>638038
Попробуй в условие поставить именно $pain.
Потому что $creditBalance же у тебя в минус уходит к тому моменту, когда тот-же $pain становится меньше $monthlyPayment (ты же сразу там же от $creditBalance отнимаешь $monthlyPayment), да сколько же можно? Или ты другой анон?
#796 #638049
>>638036
Хм, т.е. xsrf пройдёт в любом случае, если пользователь залогинен и токен хранится в $_SESSION, проверяй я валидность userid (некоторое значение под sha512) или не проверяй?
То есть вариант - тупо вынести из сессии в качестве передаваемого параметра?

>>638039
Не думаю, что ip прямо так часто меняется.
#797 #638051

>тот-же


тот же
#798 #638053
>>638049

>т.е. xsrf пройдёт в любом случае, если пользователь залогинен и токен хранится в $_SESSION, проверяй я валидность userid (некоторое значение под sha512) или не проверяй?


Да.

>То есть вариант - тупо вынести из сессии в качестве передаваемого параметра?


Да.

>Не думаю, что ip прямо так часто меняется.


На телефонах может связь с сетью пропасть например. Меня бы раздражали постоянные вылеты на страницу логина из-за плохого интернета или связи.
#799 #638055
Кто решал задачи на КСС? Никак не возьму в толк задачу 6, как добиться правильного решения?
#800 #638056
>>638053
Либо переключаешься от одного бесплатного Wi-fi к другому, попивая чай в кафе.

Мимо
#801 #638058
>>638048
Я два дня назад спрашивал как решать, просто время за задачу взяться есть только ночью, а вчера вообще не получилось, пытаюсь вот разобрать потихоньку.
#802 #638062
>>638058
Ну, у тебя всё есть же для этого.
Вот какой совет: попробуй добиться правильной работы при первом прохождении скрипта при сумме, меньшей 5000.
Вот чтобы раз - и тут же выплатилась эта сумма.
Вот как бы ты это реализовал с помощью переменной $pain?
А дальше или сам уже всё увидишь, или опять будем вместе думать.
#803 #638064
>>638053
Спасибо.

>На телефонах может связь с сетью пропасть например


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

Кстати, а global не прокатит, чтобы не передавать каждый раз? Или global он будет для всех пользователей одинаков?
#804 #638089
>>638058
Также не ставь в условие $creditBalance < 0, там никогда не должно такого получиться при правильном решении!
Ставь $creditBalance <= 0 тогда уж или просто "равняется нулю".
#805 #638130
>>638042

Тебе надо изучить язык яваскрипт и DOM.
#806 #638132
>>638042

Вообще, ненормально. А зачем запускать ее каждую секунду? И зачем вообще такая скорость обновления? Так конечно есть вебсокет, но интуиция мне подсказывает что тебе не нужно ничего обновлять в реальном времени.
#807 #638137
>>638039

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

Ну и это все равно не поможет от случая когда например владелец вайфай точки ворует ид сессии и делает что-то от своего имени, так как айпи будет тот же самый. От таких случаев поможет использование https.
#808 #638253
а так можно? http://ideone.com/VK7Qia
Ответы за 24 января #809 #638259
>>633210

Вполне нормальное решение, ответ верный.

>>633236

Тебе в прошлом треде написал:

> private function chooseProfession($post) {


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

> public function countTotalSalary($qty, $rank, $post, $boss) {


Это не очень правльная функция, должно быть так:

public function countTotalSalary() { ... }

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

> abstract class Employee extends Department {


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

У тебя же неправильно: Сотрудник это не разновидност Департамента, значит наследование использовать так нельзя.

> class Manager extends Employee {


> protected function countSalary() {


Ты скопипастил тут код 4 раза.

>>633240

Это не обязательно
Ответы за 24 января #809 #638259
>>633210

Вполне нормальное решение, ответ верный.

>>633236

Тебе в прошлом треде написал:

> private function chooseProfession($post) {


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

> public function countTotalSalary($qty, $rank, $post, $boss) {


Это не очень правльная функция, должно быть так:

public function countTotalSalary() { ... }

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

> abstract class Employee extends Department {


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

У тебя же неправильно: Сотрудник это не разновидност Департамента, значит наследование использовать так нельзя.

> class Manager extends Employee {


> protected function countSalary() {


Ты скопипастил тут код 4 раза.

>>633240

Это не обязательно
Ответы за 24 января #810 #638260
>>633266

В общем верно, но регулярку можно еще упростить, объединив группу из 3 цифр и из 7 цифр в одну группу из 10 цифр.

Ну и круглые скобки тут не нужны:

([\\s-(]*)

>>633278

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

$x = 012;

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

>>633286

Ошибки:

> /$


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

> [а-я]


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

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

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

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

>>633307

Нет, ты уходи.
Ответы за 24 января #810 #638260
>>633266

В общем верно, но регулярку можно еще упростить, объединив группу из 3 цифр и из 7 цифр в одну группу из 10 цифр.

Ну и круглые скобки тут не нужны:

([\\s-(]*)

>>633278

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

$x = 012;

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

>>633286

Ошибки:

> /$


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

> [а-я]


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

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

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

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

>>633307

Нет, ты уходи.
Ответы за 24 января #811 #638261
>>633331

> $symbol = mb_substr($text, $i, $halfLength);


Это непраивльно, ты берешь не первый символ, а первую половину строки и сравниваешь с пустой строкой (так как mb_substr($text, $length, $halfLength) даст пустую строку).

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

>>633406

> W2(перевод долларов в рубли) - http://ideone.com/5zHXdu


Верно, но строка $roubles = 0; лишняя.

> W3(имитация броска кубика) - http://ideone.com/2QvVvX


Правильно.

> W4.1(дописать кубик) - http://ideone.com/ckuYdx


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

> W4.2(рулетка что смотрит последнюю цифру) - http://ideone.com/TKuvUB


Тут верно, но exit писать не требуется, так как после блока if/else все равно ничего нет. Ну и форматирование неправильное, скобки и elseif пишутся на одной строке:

} elseif (...) {
..
} else {
..

>>633417

Теперь верно, только exit там ставить не надо, в скрипте все равно после if/else ничего нету.

>>633450

Вроде генератор выглядит верно, но не уверен насчет этих полей:

> private $previewWidth;


> private $previewHeight;



Нужны ли они? Есть ли гарантия что они всегда заданы? Не уверен, нужны ли они как свойства и не лучше ли сделать их просто переменными. Также, функции должны начинаться с глагола: tooSmall -> isTooSmall.

По верстке:

- нехорошо что ты флоатишь влево картинку, а ссылку в которую она вложена, оставляешь - тут не очень понятно какую форму примет она. По идее у инлайн-элементов нет своей формы, они окружают содержимое. Но лучше бы флоатить ссылку.
- ты используешь абс. поз. для прижатия к низу города и времени, но учел ли ты сценарий когда название города переносится на новую строку? С абс. поз. ты не можешь это предусмотреть и оставить нужное количество места. Если говорить про максимально безопасную верстку, то я вижу только один вариант (без использования всяких флексбоксов): сделать таблицу из 2 колонок, слева поместить картинку, правую колонку сделать из 2 строк, сверху описание, снизу город и время. Город и время прижать вниз за счет vertical-align. Таблицу естественно средствами css, через display: table. Изучи-ка эту возможность, помни что там есть свои подвохи: у строк и ячеек таблицы нет маргинов, относительно элементов таблицы нельзя применять абс. позиционирование, для таблиц width/height обозначают min-width/height, а не реальные размеры.

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

> time {


надо писать .item time иначе это правило будет действовать на все такие теги на странице. Да и то, не очень хорошая идея, вдруг этот тег будет в описании?

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


Если код семантично сверстан и все стили в css, то поправлять должно быть не очень сложно.

>>что будет если убрать картинку (не наедет ли цена на город?).


> Добавил min-height внешнему контейнеру


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

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


СЕО это темная магия, которую мы не можем проверить, так что опираться на нее особо не стоит.

> Только с флотами получается странный порядок "слоев": у меня теперь идет сначала блок с ценой, а за ним заголовок, город и время. Хотя визуально сначала должен идти заголовок, а за ним цена (если смотреть слева направо).


Контент в HTML не обязан идти в том же порядке что выводится. Просто хорошо бы чтобы HTML код нормально читался.
Ответы за 24 января #811 #638261
>>633331

> $symbol = mb_substr($text, $i, $halfLength);


Это непраивльно, ты берешь не первый символ, а первую половину строки и сравниваешь с пустой строкой (так как mb_substr($text, $length, $halfLength) даст пустую строку).

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

>>633406

> W2(перевод долларов в рубли) - http://ideone.com/5zHXdu


Верно, но строка $roubles = 0; лишняя.

> W3(имитация броска кубика) - http://ideone.com/2QvVvX


Правильно.

> W4.1(дописать кубик) - http://ideone.com/ckuYdx


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

> W4.2(рулетка что смотрит последнюю цифру) - http://ideone.com/TKuvUB


Тут верно, но exit писать не требуется, так как после блока if/else все равно ничего нет. Ну и форматирование неправильное, скобки и elseif пишутся на одной строке:

} elseif (...) {
..
} else {
..

>>633417

Теперь верно, только exit там ставить не надо, в скрипте все равно после if/else ничего нету.

>>633450

Вроде генератор выглядит верно, но не уверен насчет этих полей:

> private $previewWidth;


> private $previewHeight;



Нужны ли они? Есть ли гарантия что они всегда заданы? Не уверен, нужны ли они как свойства и не лучше ли сделать их просто переменными. Также, функции должны начинаться с глагола: tooSmall -> isTooSmall.

По верстке:

- нехорошо что ты флоатишь влево картинку, а ссылку в которую она вложена, оставляешь - тут не очень понятно какую форму примет она. По идее у инлайн-элементов нет своей формы, они окружают содержимое. Но лучше бы флоатить ссылку.
- ты используешь абс. поз. для прижатия к низу города и времени, но учел ли ты сценарий когда название города переносится на новую строку? С абс. поз. ты не можешь это предусмотреть и оставить нужное количество места. Если говорить про максимально безопасную верстку, то я вижу только один вариант (без использования всяких флексбоксов): сделать таблицу из 2 колонок, слева поместить картинку, правую колонку сделать из 2 строк, сверху описание, снизу город и время. Город и время прижать вниз за счет vertical-align. Таблицу естественно средствами css, через display: table. Изучи-ка эту возможность, помни что там есть свои подвохи: у строк и ячеек таблицы нет маргинов, относительно элементов таблицы нельзя применять абс. позиционирование, для таблиц width/height обозначают min-width/height, а не реальные размеры.

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

> time {


надо писать .item time иначе это правило будет действовать на все такие теги на странице. Да и то, не очень хорошая идея, вдруг этот тег будет в описании?

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


Если код семантично сверстан и все стили в css, то поправлять должно быть не очень сложно.

>>что будет если убрать картинку (не наедет ли цена на город?).


> Добавил min-height внешнему контейнеру


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

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


СЕО это темная магия, которую мы не можем проверить, так что опираться на нее особо не стоит.

> Только с флотами получается странный порядок "слоев": у меня теперь идет сначала блок с ценой, а за ним заголовок, город и время. Хотя визуально сначала должен идти заголовок, а за ним цена (если смотреть слева направо).


Контент в HTML не обязан идти в том же порядке что выводится. Просто хорошо бы чтобы HTML код нормально читался.
Ответы за 24 и немного за 25 января #812 #638262
>>633460

Эту строку можно не писать, она там просто как символ того что анон наконец-то выплатил весь кредит.

>>633464

Разумеется нужно.

>>633471

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

> Или проверять надо не просто долг а долг с процентом на следующий месяц?


На текущий, почему на следующий?

>>633648

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

>>633666

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

>>633857

В твоем коде не должно быть isset($var) так как это ненормально если ты сам не знаешь, есть такая переменная или нет. isset надо применять только с элементами массива.

>>634026

Насчет ретурн - надо проверять, а вообще можно все обернуть в большой иф.

>>634030

Можно сохранять ссылку с добавленным классом в переменную.
Ответы за 24 и немного за 25 января #812 #638262
>>633460

Эту строку можно не писать, она там просто как символ того что анон наконец-то выплатил весь кредит.

>>633464

Разумеется нужно.

>>633471

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

> Или проверять надо не просто долг а долг с процентом на следующий месяц?


На текущий, почему на следующий?

>>633648

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

>>633666

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

>>633857

В твоем коде не должно быть isset($var) так как это ненормально если ты сам не знаешь, есть такая переменная или нет. isset надо применять только с элементами массива.

>>634026

Насчет ретурн - надо проверять, а вообще можно все обернуть в большой иф.

>>634030

Можно сохранять ссылку с добавленным классом в переменную.
Ответы за 24 и немного за 25 января #813 #638263
>>634045

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


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

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


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

>>634217

Возвращаемое значение передается в метод mount, без return там передастся null и работать не будет. От того что ты создал переменную $blog, silex не начнет ее использовать.

>>634238

Алгоритм такой

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

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
#814 #638298
Сделайте перекат, Друзья!
#815 #638321
>>638298

потерпи еще денек.
#816 #638324
>>638321
восемьсот постов, куда дальше? Я просто задачки свои выгрузить хочу, а в конец старого умирающего треда не хочется. т.к. следить за проверкой опа будет трудней и вообще
#817 #638330
>>638324
В чем выражается "труднее"? Что такое "вообще"?
#818 #638337
>>638324

Ну подожди тогда денек, и в новый тред выгрузишь.
#819 #638383
>>638132
Чтобы обновлять вывод из базы данных без перезагрузки, который может обновляться очень быстро.
#820 #638394
Глав. ред., ты еще тут? Как писать хорошо? Что посоветуешь почитать на эту тему?
#821 #638407
Пиздец прошел тест на манагера в связном, результаты вывели, что мне не очень подходит эта вакансия.
#822 #638411
>>638407
Скинь тест, плиз.
#823 #638415
https://github.com/MindiMakridi/filehosting исправления. Кстати, как принято называть коммиты? У меня не очень с фантазией, я просто называю их по порядковому номеру коммита.
#824 #638418
>>638415
Так и принято.
#825 #638419
>>638415
А почему ты используешь старый слим? В третьей версии появилась возможность передавать все запросы контроллерам, из-за этого роутер будет выглядеть вот так

>$app->get('/file/{id}', 'FileViewController:__invoke');


>$app->get('/file/{id}/delete', '\app\Controller\FileEditController');

#826 #638420
>>638419
Так он вроде только недавно появился.
#827 #638421
>>638420
Уже есть релизная версия и хорошая документация.
http://www.slimframework.com/
#828 #638424
>>638260

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


>$x = 012;


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


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

>>638394
Что ты имеешь в виду под "писать хорошо"?
Голуб и Розенталь - для правописания, стилистики, речевой грамотности (хотя последние два раздела там обзорно даются). Желательно периодически восстанавливать в памяти правила языка.
Начинать писать что-то более-менее серьёзное лучше после чтения хороших книг: художественных, научно-популярных. При этом во время чтения желателен анализ прочитанного, языковых конструкций, отслеживание речевых оборотов и общей стилистики написанного.
"Слово живое и мёртвое" Норы Галь - одна из лучших книг для того, кто хочет орудовать словом и вызывать отклик в читателях.
Для начинающих писателей, журналистов, блогеров такое было бы полезным.
#829 #638427
>>638424

>"Слово живое и мёртвое" Норы Галь - одна из лучших книг для того, кто хочет орудовать словом и вызывать отклик в читателях.


Для начинающих писателей, журналистов, блогеров такое было бы полезным.
Вот это я имел ввиду, спасибо большое.
#830 #638430
>>638427
Не за что, самому приятно хоть как-то помогать братишкам в хороших стремлениях.
13 задача #831 #638432
28 Кб, 581x349
#832 #638435
Давно тут так?
#833 #638442
>>638435
С тех пор, как ты сменил Макабу на Нейтрон, возможно?
#834 #638443
>>638442
Всегда сидел на нейтроне, никогда такого не было.
#835 #638456
>>638443
Какого?
#836 #638457
ОП, напомни, почему мы пользуемся двойными кавычками и не участвуем в срачах на эту тему? Одинарные реально же быстрее!
#837 #638459
>>638456
Чтобы поля желтым подсвечивались
#838 #638462
>>638457
Двойные кавычки смотрятся гармоничнее, одинарные у меня ассоциируются с апострофами.
мимо-лягушатник
#839 #638469
>>637530

>Плохо то что не используются возможности ООП, а классы намертво связаны друг с другом. Попробуй почитать урок про DI https://gist.github.com/codedokode/e1d31a31b37d5f635057


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

В моей голове представляется такое решение:

https://github.com/someApprentice/Students/blob/master/app/Controller/RegisterAction.php

В этом классе делать метод setRegistrationHelper(RegistrationHelper $reghelper) и вызывать его далее:

СТОП НЕТ

Мне все равно придется писать где-то в начале $reghelper = new RegistrationHelper()

Я не хочу так делать, я хочу чтобы я вызвал одну единственную функцию и все было готово как я это сделал здесь https://github.com/someApprentice/Students/blob/master/public/index.php#L6
ОП, я многого хочу? Это вообще входит в рамки задачи? И правильно ли будет так делать? Неужели я обречен всегда пользоваться инъекциями и забыть про статические методы? Зачем их тогда вообще сделали, будут ли от них избавляться(или уже избавились)?
Извиняюсь что так много вопросов, просто я совсем не понимаю это.
#840 #638474
>>637521

> То есть с методами типа getPdo(), getUserMapper() и тд.


Здесь мне тоже нужно будет пользоваться инъекциями зависимостей?

public function addStudent(Student $student, Container $container) {
$connect = $container->getPdo();

...
}

Естественно, в идеале, контейнер должен будет внедрятся через конструктор __construct(Container $container) {$this->container = $container;}
#841 #638488
>>638457
А я использую одинарные чтобы написать что-то понимает только машина, например названия ключей массива или регулярные выражения, а двойные какой-нибудь текст на вывод который понимает человек, например echo "Hello World";
#842 #638500
>>637521

>Можно почитать мануал/погуглить, можно попробовать так понять.


Мне просто кажется что все что ты кидаешь должно быть обязательно к прочтению, видит б-г я согласен с этим на 150%, но мне сложно читать много сразу. И так сложно все понять за раз. Просто не люблю растягивать что-то на долго - проще все за раз понять.
#843 #638511
Массивы=то в жаве после пхп не оче.
http://stackoverflow.com/questions/10856397/associative-arrays-and-java
Аноним #844 #638524
что не так я делаю ??

http://ideone.com/0WtQc8#stdin
someApprentice #845 #638545
>>638524
У тебя в 15 строке точка с запятой лишняя.

Еще у тебя небольшие проблемы с форматированием кода. Старайся не ставить лишних пробелов и переносов на новую строку. Вот так код выглядит читабельнее https://ideone.com/3jI4yW
Аноним #846 #638548
>>638545
так проблема не только в этом, он не работает как надо.
someApprentice #847 #638553
>>638548

>PHP Notice: Undefined variable: mothlyPayment in /home/xcylPL/prog.php on line 21


Букву n пропустил в слове moNthly, наверно
Аноним #848 #638554
>>638553
и опять не в этом дело, что-то с самим кодом не так, я не могу понять что я делаю не так, теперь он нечего не выводит :Успешно\ttime: 0.02 memory: 52472 signal:0
someApprentice #849 #638556
Аноним #850 #638557
>>638556
нууу не платит этот школьник остаток
что с ним не так 12 месяц спустя: долг = 262.31722768997 руб, выплачено всего 60000 руб.
Аноним #851 #638567
тут есть кто живой?
someApprentice #852 #638568
>>638554
Еще ты должен исправить условие в 27 строке чтобы и при нулевом значении долга программа останавливалась, а не только при отрицательном.

>>638557
Даже со своим знанием php я не могу понять что не так. Натыкай echo после каждого изменения переменной и смотри где ошибка.

Ну и ну, даже простую задачу не могу понять. Я никогда не смогу заработать деньги умственным трудом. Зачем я живу(((
#853 #638569
Вопрос к джавистам. В чем разница между .jar и .jad?
someApprentice #854 #638570
>>638567
Похоже сейчас даже я выпилюсь
#855 #638572
>>638569

>вопрос к джавистам


>PHP тред


Ты делаешь это неправильно.

jad это мидлет отдельным файлом, нигде не видел кроме устаревшей платформы j2me.
Аноним #856 #638574
>>638568
не так она не работает
Успешно\ttime: 0.02 memory: 52472 signal:0
Не выводит нечего
#857 #638577
>>638574
http://ideone.com/BmD8eV видимо все дело в первом условии, которое выполняется на первом же шаге, сам посмотри. Перед ним эхо показывается, после - нет. Лень разбирать, сам смотри, что не так с твоим условием.
#858 #638579
>>638570
Зачем?
#859 #638580
>>638577
Он там точку с запятой поставил зачем-то. Условие нормальное, но считает неправильно.
http://ideone.com/2TF12j
Аноним #860 #638581
>>638580
да где опять точка с запятой, я ее убрал уже давно.
#861 #638583
>>638581
Вот в этом посте >>638580 код выводит (хоть и неправильно). Сравни его со своим.
Аноним #862 #638585
>>638583
да это я исправил, сейчас я не могу понять почему он не платит остаток
#863 #638587
>>638585
Потому что ты завершаешь цикл если условие выполняется, таким образом скрипт не выводит данные за последний месяц.
#864 #638592
Вижу тут еще одного анона который мучается на задаче с айфоном, добро пожаловать. Тем временем я пытаюсь выкрутиться и понять что я делаю не так http://ideone.com/VK7Qia
#865 #638594
>>638592
Считает правильно, но ты скопипастил одинаковый код два раза. Так делать не желательно, ОПу бы не понравилось. Эту задачу можно решить по другому, в форме покороче. Подумай как.
Аноним #866 #638595
>>638587
ну все я запутался полностью
http://ideone.com/mMPN2T
Аноним #867 #638596
>>638595
я все сломал
#868 #638598
>>638594
вы про $paymentTotal = $paymentTotal-2868?
#869 #638599
>>637511
Пытаюсь свести концы с концами в вопросе об уровнях изоляции транзакций и их
реализациям в движках mysql, в частности виды блокировок и мультиверсионность.
Поправь если что не так.

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

Аналогично блокировка на запись. Пока один клиент осуществляет запись, другие не
могут читать и писать. Либо только эту запись в случае InnoDB, либо всю таблицу
в случае MyISAM.

Это блокировки только на время одного запроса. Чтобы объединить несколько
запросов в транзакцию в myisam используется явная блокировка таблиц LOCK
TABLE.

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

Можно запретить другим транзакциям перезаписывать те строки, которые охватывает
условие данной выборки.
SELECT ... LOCK IN SHARE MODE

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

От потерянного обновления innodb защищен благодаря мультиверсинности. Строки не
перезаписываются, каждая транзакция создает новую запись.
От грязного чтения защищает тот же механизм mvcc, потому что каждая транзакция
не видит "грязных", незакоммиченных данных других транзакций.
Чтобы защититься от неповторяющегося чтения, придется явно использовать LOCK IN
SHARE MODE.

Для борьбы с фантомным чтением используется алгоритм Next-key locking.
http://dev.mysql.com/doc/refman/5.7/en/innodb-next-key-locking.html
Если я правильно понял, при использовании FOR UPDATE вызывается блокировка всего
промежутка (gap):
SELECT cols FROM tbl WHERE id > 100 FOR UPDATE;
Будет наложена next-key блокировка на все ключи с id > 100, в том числе на те,
которые еще не существуют. Ну то есть если у нас 110 записей в базе, и селект
вернет соответственно 10, то другие транзакции не могут вставить 111 запись.
Короче какое-то мутное место.

>Почему MyISAM блокирует таблицу на время апдейта одной строки?


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

>Почему MVCC позволяет это не делать?


При обновлении строки не перезаписываются старые данные, а добавляется в конец
файла с таблицей новая строка. Идет запись в разные места файла.

>почему InnoDB блокирует строки, хотя MVCC позволяет это не делать?


Нарушится согласованность данных. Например одна транзакция выполнит
SET field = field + 10 (видит закоммиченное значение 100)
вторая
SET field = field + 20 (видит то же самое закоммиченное значение 100)
Затем обе транзакции коммитятся, первая запишет 110, а вторая 120, хотя мы
ожидали 130. Похоже на потерянное обновление.

>если программа выбирает какие-то данные (SELECT), меняет их и записывает назад


>в базу (UPDATE), как запретить другим в это время их менять?


LOCK IN SHARE MODE. Если нужно блокировать и на чтение, то SELECT ... FOR UPDATE.
#869 #638599
>>637511
Пытаюсь свести концы с концами в вопросе об уровнях изоляции транзакций и их
реализациям в движках mysql, в частности виды блокировок и мультиверсионность.
Поправь если что не так.

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

Аналогично блокировка на запись. Пока один клиент осуществляет запись, другие не
могут читать и писать. Либо только эту запись в случае InnoDB, либо всю таблицу
в случае MyISAM.

Это блокировки только на время одного запроса. Чтобы объединить несколько
запросов в транзакцию в myisam используется явная блокировка таблиц LOCK
TABLE.

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

Можно запретить другим транзакциям перезаписывать те строки, которые охватывает
условие данной выборки.
SELECT ... LOCK IN SHARE MODE

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

От потерянного обновления innodb защищен благодаря мультиверсинности. Строки не
перезаписываются, каждая транзакция создает новую запись.
От грязного чтения защищает тот же механизм mvcc, потому что каждая транзакция
не видит "грязных", незакоммиченных данных других транзакций.
Чтобы защититься от неповторяющегося чтения, придется явно использовать LOCK IN
SHARE MODE.

Для борьбы с фантомным чтением используется алгоритм Next-key locking.
http://dev.mysql.com/doc/refman/5.7/en/innodb-next-key-locking.html
Если я правильно понял, при использовании FOR UPDATE вызывается блокировка всего
промежутка (gap):
SELECT cols FROM tbl WHERE id > 100 FOR UPDATE;
Будет наложена next-key блокировка на все ключи с id > 100, в том числе на те,
которые еще не существуют. Ну то есть если у нас 110 записей в базе, и селект
вернет соответственно 10, то другие транзакции не могут вставить 111 запись.
Короче какое-то мутное место.

>Почему MyISAM блокирует таблицу на время апдейта одной строки?


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

>Почему MVCC позволяет это не делать?


При обновлении строки не перезаписываются старые данные, а добавляется в конец
файла с таблицей новая строка. Идет запись в разные места файла.

>почему InnoDB блокирует строки, хотя MVCC позволяет это не делать?


Нарушится согласованность данных. Например одна транзакция выполнит
SET field = field + 10 (видит закоммиченное значение 100)
вторая
SET field = field + 20 (видит то же самое закоммиченное значение 100)
Затем обе транзакции коммитятся, первая запишет 110, а вторая 120, хотя мы
ожидали 130. Похоже на потерянное обновление.

>если программа выбирает какие-то данные (SELECT), меняет их и записывает назад


>в базу (UPDATE), как запретить другим в это время их менять?


LOCK IN SHARE MODE. Если нужно блокировать и на чтение, то SELECT ... FOR UPDATE.
Аноним #870 #638600
вот он еще более менее живой
http://ideone.com/mMPN2T
но я все равно не могу понять что с ним делать
#871 #638606
>>638598
Я про это условие в общем, там можно сделать код компактнее.

>if($creditBalance < 5000)



>вы про $paymentTotal = $paymentTotal-2868?


Вот тут я не понял зачем ты это делаешь.

>>638600
У тебя ошибка в расчетах если это условие

>if($creditBalance < 5000)


выполняется. Подумай как её исправить.
someApprentice #872 #638607
>>638579
Не знаю, я просто не верю что у меня что-то получится. Я сейчас писал большую стену текста, но потом понял что не хочу говорить об этом, просто не хочу чтобы твой интерес оставался не удовлетворенным.

Обсуждение на анонимных бордах личных проблем не помогут решить их!
#873 #638615
>>638600
Убери первый break, а вот это
$creditBalance = $creditBalance - $monthlyPayment;
\t$paymentTotal = $paymentTotal + $monthlyPayment;
\techo "{$month} месяц спустя: долг = {$creditBalance} руб, выплачено всего {$paymentTotal} руб. \n";
засунь в else
#874 #638617
>>638606
если не отнимать 2868, то ответ не правильный получится, а я и не понимаю почему ответ не правильный. А без if($creditBalance < 5000) я вообще не знаю как обойтись.
#875 #638620
>>638600
Ну и ещё echo в этот if добавь, чтобы окончательный результат выводился
#876 #638621
>>638617

>если не отнимать 2868, то ответ не правильный получится


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

Вообще эту задачу можно решить двумя строками.
#877 #638627
>>638621
вот я и пытаюсь выяснить из чего прибавляется 2868, что приходится это отнимать
#879 #638634
>>638631
Старый кусок кода-то убери
#880 #638637
Чёт я не понимаю как делать 5.2
http://ideone.com/SKdNSl
Аноним #881 #638638
>>638634

http://ideone.com/GaB9k4

12 месяц спустя: долг = 262.31722768997 руб, выплачено всего 60000 руб.
С меня хватит
#882 #638639
>>638638
Всё правильно. Только ты в первом if не вывел конечный результат
Аноним #883 #638641
>>638639
всм, а как я должен его вывести ?*
чт я уже совсем попутал.
#884 #638642
>>638641
Строчку с echo из else скопируй и вставь в конец if
#885 #638643
>>638641
Чувак, я сначала тоже все путал и не мог разобраться, но сейчас уже почти решил, борись до конца.
Аноним #886 #638647
>>638642
ниичесии
http://ideone.com/GaB9k4
13 месяц спустя: долг = 0 руб, выплачено всего 61270.186744521 руб.
С меня хватит!
Спасибо всем кто помог мне в это не простом сражении.
Аноним #887 #638651
теперь буду ебать мозги с
W5.2 Некто кладет в банк 10000 р. Банк начисляет 10% годовых (то есть, каждый год на счету становится на 10% больше, чем в прошлом году). Напиши программу, считающую, через сколько лет в банке будет миллион? Сколько лет будет этому некто? Доживет ли некто до этого дня, если сегодня ему 16 лет?
#888 #638657
>>638647
Поздравляю, сколько времени ушло не решение?
#889 #638659
>>638651
Я сам с этим не разобрался >>638637
Не совсем пойму каким должен быть цикл
Аноним #890 #638660
>>638647
ну где-то 2 дня
#891 #638663
>>638660
Лол, я ее уже 5-ый день мучаю, до сих пор остались вопросы.
#892 #638664
>>638659
Ну как бы у тебя цикл работает пока баланс меньше некоторой суммы, а условие внутри рассчитано на то, что он будет больше. Очевидно, что оно никогда не сработает.
Аноним #893 #638665
>>638659
for ($year=16;$year <100;$year++)
#894 #638666
>>638664
А каким должен быть тогда алгоритм? Я вообще эту задачку понять не могу.
#895 #638667
>>638665
Так здесь цикл не по деньгам, а по возрасту?!
Ну если так, то это всё обьясняет!
Аноним #896 #638668
>>638663
да я сделал только с помощью великих анонов, но еще много чего не понял.
Аноним #897 #638670
>>638667
вроде так
#898 #638675
>>638607
Но, тем не менее, ты неймфажишь. Выпиливайся, если хочешь, чем черт не шутит. Я не из-за интереса спросил, если б ты хотел выпилиться, ты бы это уже сделал, а не спрашивал тут разрешение на это.

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

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

Когда меня отчислили из двух вузов подряд, я сначала отчаялся, но потом нашел в себе силы сделать себе распорядок дня какой был во время моего обучения. Напридумывал себе предметов, которые учил как в вузе и даже усерднее! и сейчас продолжаю, потому что в вузике было ламповое время, как не крути.
На этой ноте я прерываю свою короткую речь и даю право высказаться тебе.
#898 #638675
>>638607
Но, тем не менее, ты неймфажишь. Выпиливайся, если хочешь, чем черт не шутит. Я не из-за интереса спросил, если б ты хотел выпилиться, ты бы это уже сделал, а не спрашивал тут разрешение на это.

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

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

Когда меня отчислили из двух вузов подряд, я сначала отчаялся, но потом нашел в себе силы сделать себе распорядок дня какой был во время моего обучения. Напридумывал себе предметов, которые учил как в вузе и даже усерднее! и сейчас продолжаю, потому что в вузике было ламповое время, как не крути.
На этой ноте я прерываю свою короткую речь и даю право высказаться тебе.
#899 #638676
>>638667
>>638670
Решил эту задачу за 2 минуты, лол.
Аноним #900 #638678
>>638676
ты супер герой
#901 #638680
>>638678
Она правда простая, в отличие от той с гейфоном.
Аноним #902 #638681
>>638680
я пока что не могу понять
#903 #638684
Объясните мне почему он платит 64к? http://ideone.com/cOBwEZ
Аноним #904 #638687
чт я не то опять делаю
http://ideone.com/fjJUwP
#905 #638689
>>638687
Смотри.
У тебя деньги лежат на депозите под 10%. Очевидно, что ты должен увеличивать денежную сумму раз в год, умножая на 1.1.
#906 #638692
>>638689
А ты умножаешь на 0.1. Т.е. получается, что у тебя от суммы остаётся 10% а не выходит 110%
Аноним #907 #638693
>>638692
хорошо но тут чего-то не хватает
http://ideone.com/fjJUwP
#908 #638699
>>638693
Может сравнение ставится вот так - "== "а не "=". = это присвоение, попробуй исправить.
#909 #638700
Вот 5.2 задачка http://ideone.com/0uXpMk .
Проверьте.
#910 #638703
>>638700
error-reporting не поставил, это да.
Аноним #911 #638710
>>638700
блин я был на верном пути
Аноним #912 #638712
пойду читать массивы
someApprentice #913 #638718
>>637522

>https://habrahabr.ru/post/199296/


>return new $c['session_storage_class']($c['cookie_name']);


А что это за способ записи такой? Первый раз вижу чтобы при создании объекта что-то писалось в квадратных скобках перед передачей аргументов.
#914 #638721
>>638700
Хотя всё же наверное правильно будет так http://ideone.com/EzCByL
#915 #638726
>>638718
Так это обращение по индексу массива, чтобы достать оттуда имя класса.
http://ideone.com/OAbxeE
#916 #638793
>>638415

Принято писать что изменено, например "добавлена возможность комментировать файлы" или "fixed bug with uploading large files". По идее каждая фича или исправленный баг - это отдельный коммит. В этом случае история коммитов смотрится хорошо.

>>638419

А зачем контроллеры в микрофреймворке? На то он и микрофреймворк чтобы код контроллеров был в index.php
#917 #638840
>>638680
Так это и есть она, задача с Айфоном.
#918 #638844
>>638840
Нет, это не она, это подпункт это задачи, но это не она.
#919 #638847
>>638684
Блин, бро, ты не читаk предыдущие разъясняющие сообщения?
>>638062

>Вот какой совет: попробуй добиться правильной работы при первом прохождении скрипта при сумме, меньшей 5000.


>Вот чтобы раз - и тут же выплатилась эта сумма.


>Вот как бы ты это реализовал с помощью переменной $pain?


>А дальше или сам уже всё увидишь, или опять будем вместе думать.


Попробуй добиться выплаты сразу, чтобы попала в цикл сумма меньше 5000 (уже после умножения кредитбаланс на персент и с прибавлением кредитсервис) и тут же выплатилась.
Давай-давай, пробуй. Дальше только цикл надо будет заставить работать с суммой 40к.
#920 #638848
*не читал
#921 #638849
Такс, пока разбираю задачу с айфоном сделал следующую задачу - http://ideone.com/0DRyth
Он должен каждый год просчитывать, или ничего что он сразу все посчитал?
#922 #638883
>>638849
Главное, что посчитал всё верно.
Так-то просто echo внутрь цикла помести - выдаст при каждом проходе цикла сумму за каждый год.
#923 #638909
Надо сделать какую-то универсальную подсказку для задачи про Айфон, что ли.
Несколько способов, как не топтаться на месте с этой задачей.
1. Ввести переменную для подсчёта $creditBalance с $percent и $servicePayment. Не отнимать от неё никакие $monthlyPayment.
2. Заставить программу выплатить $creditBalance с $percent и $servicePayment (или введённую переменную) при первом же прохождении цикла. Для этого $creditBalance или введённая для этого переменная должны быть сразу меньше 5000 и должны уже содержать умножение $creditBalance на проценты и с прибавленной комиссией за обслуживание кредита. Итоговая цифра должна быть меньше 5000.
3. Обрывать цикл при сумме, равной нулю, а не меньшей нуля. Отрицательного $creditBalance не должно получиться при верном решении этой задачи.
#924 #638949
>>638909

>Подсказка: перед тем, как платить, надо проверять, сколько осталось долга, и если он меньше 5000, то платить только остаток и завершать цикл через break.


Оп по моему разжевал уже дальше некуда.

А что сейчас в школах/универах по убирали информатику? Просто я это все на турбо паскале в школе делал в до двачевскую эпоху.
#925 #638969
Где можно почитать про вордпресс: что это, зачем это и как этим пользоваться?
#926 #639020
>>638969
Вдогонку к этому, я только сейчас понимаю (спустя месяц после начала занятий по учебнику ОПа), что я до сих пор не совсем представляю себе роль ПХП в работе сайтов, что вообще мне предстоит делать и как использовать пхп. Я тут один такой даун?
#927 #639032
Сап, pr. Снова на связи с глуповатым вопросом.
Если в рамках работы страницы по какому-то условию останавливаю работу кода через exit(), то надо ли ручками переменные подчищать вида unset($thesisid, $usrdoc). Так делаю постоянно, но задумался, а надо ли?
#928 #639043
>>639020

При попытке заходе пользователя на страницу сайта браузер отправляет запрос ("а дай-ка мне страницу http://example.com/page") на сервер, там запускается пхп скрипт, который достает нужные данные из базы и формирует HTML код, который отправляется назад в браузер и отображается там. Так что без знания php никак.

>>639032

Ты занимаешь глупостью. В PHP автоматическое управление памятью и ест сборка мусора. Ты лишь усложняешь чтение и поддержку твоего скрипта.
#929 #639045
>>639032

Алсо переменные надо назвать кемелкейсом, $thesisId, $userDocument.
#930 #639050
>>639043

>на сервер, там запускается пхп скрипт, который достает нужные данные из базы и формирует HTML код


но что всё это означает? После учебника ты получаешь общие сведения о языке и о том, как делать кредитные калькуляторы, я в глаза не видел вордпрессы, сервера и прочее, я даже не знаю, пишешь ли программу отдельным файлом или внутри хтмл-кода. Как всё это постичь? Ничего не понятно, честное слово, я в агонии
sage #931 #639051
>>639043
>>639045
Спасибо.
#932 #639066
>>639050

После учебника освоишь основы HTML, установишь Апач и будешь запускать код там. Все равно без самого PHP ничего не сделать. Ну а скорость изучения уже от тебя зависит.
#933 #639067
>>639050

Если тебе интересно, в ОП посте есть паста по установке Апача и интерпретатора PHP, а в офиц. мануале в начале есть про то, как вставлять php в html код. Можешь попробовать.
43 Кб, 400x681
#934 #639092
Знаю отличия сессий и куки, одна не понимаю, это 2 разные технологии которые взаимозаменяемы и делают одно и тоже?
#935 #639100
В пхп вообще используют ТДД, как то ни разу не слышал?
#936 #639114
Задача по айфону
http://ideone.com/QAkV91
https://github.com/disbeliever/phptraining/tree/master/students #937 #639127
>>634271

https://github.com/disbeliever/php_training/blob/master/students/db.sql
В postgres есть интересная возможность - можно с помощью ограничения CHECK ставить проверки для вставляемых в колонку значений. Ну например, можно ограничить символы, которые разрешено использовать в имени и фамилии, или макс. и мин. число баллов за ЕГЭ, указав допустимые значения для года рождения. Это защищает базу от вставки неправильных данных. Продемонстрируй знание этой особенности, добавив ограничения в соответствие с логикой задачи.

Число баллов стоит сделать неотрицательным (unsigned).

https://github.com/disbeliever/php_training/blob/master/students/src/init.php#L9

> if ($config['debug']) {


> error_reporting(-1);


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

> $STG = new StudentTableGateway($PDO, $config['studentsPerPage']);


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

https://github.com/disbeliever/php_training/blob/master/students/public/index.php
Плохо, что у тебя прямо в index.php какие-то посторонние функции. Зачем они тут? Лучше всего сделать класс вроде UrlHelper и поместить их туда. Таким образом ты вынесешь все, что относится к формрованию УРЛ в отдельный класс.

Также, не используй глобальные переменные, тем более через global $x. Все, что нужно функции, можно передать через аргументы.

Также, лучше не использовать при формировании URL конструкции вроде {$_SERVER['SCRIPT_NAME']} - надежнее просто прописать конкретное название скрипта. Ведь лучше когда результат вызова функции возвращает один и тот же URL, а не надеется на то, что скрипт называется определенным образом.

Также, я думаю, в маппер лучше передавать не номер страницы, а offset + limit. Ведь по идее мы можем в выводить записи с разным числом записей на страницу, лучше не закладывать разбиение на страницы в маппер, а сделать универсальный код, получающий любое число записей.

https://github.com/disbeliever/php_training/blob/master/students/public/index.php#L49
Строки длиннее 80 символов надо переносить. В рекомендации PSR-3 написано как разбить вызов функции на несколько строк.

https://github.com/disbeliever/php_training/blob/master/students/public/ControllerStudent.php
Немного странное название, не лучше ли назвать скрипт вроде profile.php или register.php? Впрочем, это не ошибка, можно и так оставить.

https://github.com/disbeliever/php_training/blob/master/students/src/autoloader.php#L2
Эта функция давно устарела, переделывай на spl_autoload_register, погугли, есть статья на хабре + есть мануал. Функцию canClassBeAutloaded мне кажется можно выпилить, так как проверить наличие класса можно через class_exists.

https://github.com/disbeliever/php_training/blob/master/students/src/config.php
В конфиг должны идти только параметры, которые меняет пользователь. Я думаю, AUTH_LENGTH сюда явно не относится, и эта константа должна быть в классе или функции, отвечающей за авторизацию.

https://github.com/disbeliever/php_training/blob/master/students/src/registerHelpers.php
И тут функции! Давай-ка переделывать на ООП. Функции, которые не относятся ни к одному объекту, можно сделать статическими методами в классе Util или Helper. Функции, относящиеся к регистрации студента, помещаем в обычный класс StudentHelper, StudentService, как-то так. Функции отвечающие за авторизацию и проверку токенов, можно либо засунуть туда же, либо в отдельный класс, отвечающий за авторизацию.

https://github.com/disbeliever/php_training/blob/master/students/src/registerHelpers.php#L21

> foreach (array_keys(get_object_vars($student))


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

> ["class" => "danger", "text" => "Ошибка CSRF токена"];


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

> isCSRFTokenSet() && isFormTokenSet() && $_COOKIE['csrf'] == $_POST['csrfToken']


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

https://github.com/disbeliever/php_training/blob/master/students/public/ControllerStudent.php#L44

> catch (PDOException $e) {


Ну что же вы все делаете эту ошибку с catch? Ты обрабатываешь исключения неправильно, держи пасту:

----------

Как надо обрабатывать исключения:

- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс

Что будет если использовать catch + echo:

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

Как будет если просто не ловить исключение:

- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)

Почитай также урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

----------

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

try {
$app->run();
} catch (..) {
$app->showErrorPage();
}

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

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

----------

В общем, надо либо сделать нормальный обработчик исключений, охватывающий весь контроллер, либо не ловить их и положиться на php (который завершит скрипт и покажет белую страницу с кодом 200). Оборачивать большой скрипт в try/catch неудобно, потому код контроллера может понадобиться вынести в функцию или класс.

> else if ($_SERVER['REQUEST_METHOD'] == "GET") {


Я думаю лучше просто else

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

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

https://github.com/disbeliever/php_training/blob/master/students/public/ControllerStudent.php#L55

> if ($id > 0) {


> $student = $STG->getStudent($id);


Это позволяет загрузить данные любого студента в форму? Уверен, что это правильно? Мне кажется там должна быть проверка auth куки.

https://github.com/disbeliever/php_training/blob/master/students/public/ControllerStudent.php#L67

> if ((isset($student->id) && $student->id > 0) || isset($_COOKIE['auth'])) {


Условие неправильное: кука может быть не пуста, но не соответствовать никому в базе.

https://github.com/disbeliever/php_training/blob/master/students/src/StudentTableGateway.php#L48

> if (is_string($key) && strlen($key) == CONFIG_AUTH_LENGTH) {


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

https://github.com/disbeliever/php_training/blob/master/students/src/StudentTableGateway.php#L69
Странный алгроритм, не лучше тут in_array использовать? Или комментарий написать как это работает.

> return Student::fromRow($row);


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

> $arr[] = Student::fromRow($row);


$arr -> $students или $result

...продолжение далее ...
https://github.com/disbeliever/phptraining/tree/master/students #937 #639127
>>634271

https://github.com/disbeliever/php_training/blob/master/students/db.sql
В postgres есть интересная возможность - можно с помощью ограничения CHECK ставить проверки для вставляемых в колонку значений. Ну например, можно ограничить символы, которые разрешено использовать в имени и фамилии, или макс. и мин. число баллов за ЕГЭ, указав допустимые значения для года рождения. Это защищает базу от вставки неправильных данных. Продемонстрируй знание этой особенности, добавив ограничения в соответствие с логикой задачи.

Число баллов стоит сделать неотрицательным (unsigned).

https://github.com/disbeliever/php_training/blob/master/students/src/init.php#L9

> if ($config['debug']) {


> error_reporting(-1);


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

> $STG = new StudentTableGateway($PDO, $config['studentsPerPage']);


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

https://github.com/disbeliever/php_training/blob/master/students/public/index.php
Плохо, что у тебя прямо в index.php какие-то посторонние функции. Зачем они тут? Лучше всего сделать класс вроде UrlHelper и поместить их туда. Таким образом ты вынесешь все, что относится к формрованию УРЛ в отдельный класс.

Также, не используй глобальные переменные, тем более через global $x. Все, что нужно функции, можно передать через аргументы.

Также, лучше не использовать при формировании URL конструкции вроде {$_SERVER['SCRIPT_NAME']} - надежнее просто прописать конкретное название скрипта. Ведь лучше когда результат вызова функции возвращает один и тот же URL, а не надеется на то, что скрипт называется определенным образом.

Также, я думаю, в маппер лучше передавать не номер страницы, а offset + limit. Ведь по идее мы можем в выводить записи с разным числом записей на страницу, лучше не закладывать разбиение на страницы в маппер, а сделать универсальный код, получающий любое число записей.

https://github.com/disbeliever/php_training/blob/master/students/public/index.php#L49
Строки длиннее 80 символов надо переносить. В рекомендации PSR-3 написано как разбить вызов функции на несколько строк.

https://github.com/disbeliever/php_training/blob/master/students/public/ControllerStudent.php
Немного странное название, не лучше ли назвать скрипт вроде profile.php или register.php? Впрочем, это не ошибка, можно и так оставить.

https://github.com/disbeliever/php_training/blob/master/students/src/autoloader.php#L2
Эта функция давно устарела, переделывай на spl_autoload_register, погугли, есть статья на хабре + есть мануал. Функцию canClassBeAutloaded мне кажется можно выпилить, так как проверить наличие класса можно через class_exists.

https://github.com/disbeliever/php_training/blob/master/students/src/config.php
В конфиг должны идти только параметры, которые меняет пользователь. Я думаю, AUTH_LENGTH сюда явно не относится, и эта константа должна быть в классе или функции, отвечающей за авторизацию.

https://github.com/disbeliever/php_training/blob/master/students/src/registerHelpers.php
И тут функции! Давай-ка переделывать на ООП. Функции, которые не относятся ни к одному объекту, можно сделать статическими методами в классе Util или Helper. Функции, относящиеся к регистрации студента, помещаем в обычный класс StudentHelper, StudentService, как-то так. Функции отвечающие за авторизацию и проверку токенов, можно либо засунуть туда же, либо в отдельный класс, отвечающий за авторизацию.

https://github.com/disbeliever/php_training/blob/master/students/src/registerHelpers.php#L21

> foreach (array_keys(get_object_vars($student))


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

> ["class" => "danger", "text" => "Ошибка CSRF токена"];


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

> isCSRFTokenSet() && isFormTokenSet() && $_COOKIE['csrf'] == $_POST['csrfToken']


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

https://github.com/disbeliever/php_training/blob/master/students/public/ControllerStudent.php#L44

> catch (PDOException $e) {


Ну что же вы все делаете эту ошибку с catch? Ты обрабатываешь исключения неправильно, держи пасту:

----------

Как надо обрабатывать исключения:

- записать информацию в лог
- показать пользователю заглушку
- на заглушке выставить HTTP 503 код ответа для роботов
- на компьютере разработчика (при display_errors = 1) показать подробности и стектрейс

Что будет если использовать catch + echo:

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

Как будет если просто не ловить исключение:

- информация пишется в лог (ок)
- на компьютере разработчика выводятся подробности (ок)
- пользователь видит белую страницу (не ок)
- отдается код 200 (не ок)

Почитай также урок https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

----------

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

try {
$app->run();
} catch (..) {
$app->showErrorPage();
}

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

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

----------

В общем, надо либо сделать нормальный обработчик исключений, охватывающий весь контроллер, либо не ловить их и положиться на php (который завершит скрипт и покажет белую страницу с кодом 200). Оборачивать большой скрипт в try/catch неудобно, потому код контроллера может понадобиться вынести в функцию или класс.

> else if ($_SERVER['REQUEST_METHOD'] == "GET") {


Я думаю лучше просто else

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

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

https://github.com/disbeliever/php_training/blob/master/students/public/ControllerStudent.php#L55

> if ($id > 0) {


> $student = $STG->getStudent($id);


Это позволяет загрузить данные любого студента в форму? Уверен, что это правильно? Мне кажется там должна быть проверка auth куки.

https://github.com/disbeliever/php_training/blob/master/students/public/ControllerStudent.php#L67

> if ((isset($student->id) && $student->id > 0) || isset($_COOKIE['auth'])) {


Условие неправильное: кука может быть не пуста, но не соответствовать никому в базе.

https://github.com/disbeliever/php_training/blob/master/students/src/StudentTableGateway.php#L48

> if (is_string($key) && strlen($key) == CONFIG_AUTH_LENGTH) {


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

https://github.com/disbeliever/php_training/blob/master/students/src/StudentTableGateway.php#L69
Странный алгроритм, не лучше тут in_array использовать? Или комментарий написать как это работает.

> return Student::fromRow($row);


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

> $arr[] = Student::fromRow($row);


$arr -> $students или $result

...продолжение далее ...
https://github.com/disbeliever/phptraining/tree/master/students #938 #639128
>>634271

https://github.com/disbeliever/php_training/blob/master/students/src/StudentValidator.php#L15

> if (($length = mb_strlen($fieldValue)) > $maxLength) {


Присваивание стоит вынести из ифа, не надо городить такие сложные выражения, так как тут явно 2 отдельных действия (присваивание и иф).

> !ctype_alnum($fieldValue)


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

https://github.com/disbeliever/php_training/blob/master/students/src/StudentValidator.php#L32

> mb_strlen($fieldValue) > 5


Не используется переменная maxLength

https://github.com/disbeliever/php_training/blob/master/students/src/StudentValidator.php#L39

> if (!($fieldValue == "male" || $fieldValue == "female"))


Надо сделать обозначения пола константами в модели студента, Student::GENDER_MALE, а то это магические строки и это плохо (а, они уже даже сделаны).

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

https://github.com/disbeliever/php_training/blob/master/students/src/Pager.php#L21

> str_replace("_page_",


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

https://github.com/disbeliever/php_training/blob/master/students/src/registerHelpers.php#L15

> md5(rand());


В чем смысл от мд5 здесь? Она не увеличивает число вариантов (около 4 млрд), оно только увеличивает длину токена не добавляя защищенности. Делай честный случайный токен, а не видимость защиты.

Даже если у пользователя стоит CSRF кука, надо ее продлевать - иначе она может умереть.

https://github.com/disbeliever/php_training/blob/master/students/src/views/ViewStudent.php#L21

> />


В HTML не ставится слеш в конце тега.

В пагинации надо выделять текущую страницу. Не показывать пагинацию если всего 1 страница.
https://github.com/disbeliever/phptraining/tree/master/students #938 #639128
>>634271

https://github.com/disbeliever/php_training/blob/master/students/src/StudentValidator.php#L15

> if (($length = mb_strlen($fieldValue)) > $maxLength) {


Присваивание стоит вынести из ифа, не надо городить такие сложные выражения, так как тут явно 2 отдельных действия (присваивание и иф).

> !ctype_alnum($fieldValue)


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

https://github.com/disbeliever/php_training/blob/master/students/src/StudentValidator.php#L32

> mb_strlen($fieldValue) > 5


Не используется переменная maxLength

https://github.com/disbeliever/php_training/blob/master/students/src/StudentValidator.php#L39

> if (!($fieldValue == "male" || $fieldValue == "female"))


Надо сделать обозначения пола константами в модели студента, Student::GENDER_MALE, а то это магические строки и это плохо (а, они уже даже сделаны).

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

https://github.com/disbeliever/php_training/blob/master/students/src/Pager.php#L21

> str_replace("_page_",


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

https://github.com/disbeliever/php_training/blob/master/students/src/registerHelpers.php#L15

> md5(rand());


В чем смысл от мд5 здесь? Она не увеличивает число вариантов (около 4 млрд), оно только увеличивает длину токена не добавляя защищенности. Делай честный случайный токен, а не видимость защиты.

Даже если у пользователя стоит CSRF кука, надо ее продлевать - иначе она может умереть.

https://github.com/disbeliever/php_training/blob/master/students/src/views/ViewStudent.php#L21

> />


В HTML не ставится слеш в конце тега.

В пагинации надо выделять текущую страницу. Не показывать пагинацию если всего 1 страница.
Ответы за 25-27 января #939 #639129
>>634272

Имеется в виду в последний месяц платить не 5000, а сколько осталось.

>>634580

В чем это проявляется? Какая-то ошибка показывается?

>>634607

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

>>634628

> if ($i == $halfLength) {


> echo $result;


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

>>634679

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

>>634689

Большинство данных нужны именно на сервере, так что вряд ли.

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


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

>>634863

Надо больше писать код, тогда не забудешь.

>>634964

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

>>634989

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


Запускать из консоли.

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

> Киньте годной инфы по работе с бинарными данными


В пхп строка содержит любые байты, так что тебе нужны функции работы со строками (strlen, substr и тд). Получить код байта или строку по коду можно функциями ord, chr. Для более сложных случаев есть pack/unpack.
Ответы за 25-27 января #939 #639129
>>634272

Имеется в виду в последний месяц платить не 5000, а сколько осталось.

>>634580

В чем это проявляется? Какая-то ошибка показывается?

>>634607

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

>>634628

> if ($i == $halfLength) {


> echo $result;


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

>>634679

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

>>634689

Большинство данных нужны именно на сервере, так что вряд ли.

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


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

>>634863

Надо больше писать код, тогда не забудешь.

>>634964

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

>>634989

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


Запускать из консоли.

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

> Киньте годной инфы по работе с бинарными данными


В пхп строка содержит любые байты, так что тебе нужны функции работы со строками (strlen, substr и тд). Получить код байта или строку по коду можно функциями ord, chr. Для более сложных случаев есть pack/unpack.
https://github.com/foobar1643/student-list/ #940 #639131
>>634990

> CHECK (((rating > 0) AND (rating < 151)))


А больше 151 что нельзя набрать? Алсо, есть же оператор BETWEEN для этого.

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

Алсо, глянь-ка дамп другого анона, может что полезное найдешь https://github.com/disbeliever/php_training/blob/master/students/db.sql

https://github.com/foobar1643/student-list/blob/master/app/Config.php
При отсутсвии ключа в конфиге лучше бросать исключение. И еще, я тут подумал, лучше сделать так: сделать для каждой настройки поле в классе (вместо массива), так будет лучше так как можно задать значения по умолчанию и сразу видно какие есть настройки. Можно сделать эти поля публичными, можно нет.

https://github.com/foobar1643/student-list/blob/master/app/ExceptionHandler.php
Нет логгирования исключений в лог PHP. Как ты о них узнаешь? Используй error_log().

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

$config = new ...
$config->loadFromFile...
$container = new Container($config);

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

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

Соответвенно StudentDataGateway должен создаваться через контейнер.

Что-то у тебя контроллер index большой. Это значит что ты туда засунул код который лучше разместить в другом месте.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerIndex.php#L23

> if($_GET) {


Думаю это условие не нужно.

Насчет генерации URL: может проще сделать просто функцию типа getListUrl($serach, $page, $order) чем долго заполнять свойства объекта? Ну хотя можно и так оставить конечно.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerIndex.php#L42

> $viewSettings["totalPages"] = $pager->get_total_pages();


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

> if($viewSettings['currentPage'] > $viewSettings['totalPages']) $viewSettings['currentPage'] = 1;


Это лучше перенести в пейджер.

> foreach(array_keys(get_object_vars($viewSettings["students"][$i])) as $key) {


> $viewSettings["students"][$i]->$key = htmlspecialchars($viewSettings["students"][$i]->$key


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

> include_once("../templates/header.html");


> include_once("../templates/index.html");


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

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L17

> if(!isset($_POST['csrf_field']) && !isset($_COOKIE['token']) && $_POST['csrf_field'] != $_COOKIE['token']) {


Лучше сделать единую функцию проверки csrf токена.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L58
выставление токена надо вынести в функцию. Наверно надо сделать просто отдельный класс, отвечающий за CSRF, или отдельные методы.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L22

> foreach(array_keys(get_object_vars($student))


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

> $errors = $formValidator->validateForm($_POST);


Не лучше ли валидировать модель, а не массив непонятного вида?

https://github.com/foobar1643/student-list/blob/master/app/Database/StudentDataGateway.php#L30

> $result = $query->fetch();


> return $result['id'];


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

> $query->bindValue(':byear_bind', $student->byear, \PDO::PARAM_STR);


Почему строка?

> SE LE CT CO UNT(*) FR OM students WH ERE CON CAT(name, ' ', surname)


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

https://github.com/foobar1643/student-list/blob/master/app/Database/StudentDataGateway.php#L58

> public function select_students($offset, $sorting_pattern, $sorting_type, $search_pattern) {


В функции аргументы без проверки вставляются прямо в SQL запрос, это ведь SQL инъекция получается?

> public function selectToken($token) {


А почему тут не объект возвращается?

> $row = $query->fetchAll(\PDO::FETCH_CLASS, "\App\Model\Student");


> return $row[0];


Есть метод чтобы прочитать одну запись.

https://github.com/foobar1643/student-list/tree/master/app/Model/Helper
Я бы вынес эту папку из Model вверх.

https://github.com/foobar1643/student-list/blob/master/app/Model/Helper/FormHelper.php#L10
В фамилии-имени могут быть символы дефиса, пробела и апострофа. Д`Артаньян например.

> if($data['gender_field'] != "male" && $data['gender_field'] != "female")


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

Ошибки надо бы сделать более информативными. Не "неправильно заполнено поле" и не подкрасить красным цветом, а написать например "Имя может содержать не более X символов, вы ввели Y".

> if(!preg_match("/[А-ЯЁA-Z]{1}[а-яёa-z]{1,15}$/u"


> preg_match("/[1][9][0-9]{2}$/",


Нету привязки к началу строки

https://github.com/foobar1643/student-list/blob/master/app/Model/Helper/LinkHelper.php#L34

> $link .= "&search=" . $this->search_pattern;


Не кодируются вставляемые в параметр спецсимволы.

https://github.com/foobar1643/student-list/blob/master/app/Model/Helper/TokenHelper.php#L11

> $source[rand(0, count($source))];


В массиве нет элемента с индексом count(...).

https://github.com/foobar1643/student-list/blob/master/templates/index.html#L24

> for($i = 0; $i < count($viewSettings['students']); $i++): ?>


Нужен foreach

> <?php if($viewSettings['totalPages'] > 1): ?>


Я думаю дописывание везде $viewSettings замусоривает код. Попробуй обойтись без него. Либо как $totalPages либо $this->totalPages.

https://github.com/foobar1643/student-list/blob/master/templates/index.html#L9
Поле поиска наверно надо пометить обязательным к заполнению.

> <?php print


лучше <?=

Добавь также HTML5 валидацию в форму регистрации.
https://github.com/foobar1643/student-list/ #940 #639131
>>634990

> CHECK (((rating > 0) AND (rating < 151)))


А больше 151 что нельзя набрать? Алсо, есть же оператор BETWEEN для этого.

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

Алсо, глянь-ка дамп другого анона, может что полезное найдешь https://github.com/disbeliever/php_training/blob/master/students/db.sql

https://github.com/foobar1643/student-list/blob/master/app/Config.php
При отсутсвии ключа в конфиге лучше бросать исключение. И еще, я тут подумал, лучше сделать так: сделать для каждой настройки поле в классе (вместо массива), так будет лучше так как можно задать значения по умолчанию и сразу видно какие есть настройки. Можно сделать эти поля публичными, можно нет.

https://github.com/foobar1643/student-list/blob/master/app/ExceptionHandler.php
Нет логгирования исключений в лог PHP. Как ты о них узнаешь? Используй error_log().

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

$config = new ...
$config->loadFromFile...
$container = new Container($config);

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

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

Соответвенно StudentDataGateway должен создаваться через контейнер.

Что-то у тебя контроллер index большой. Это значит что ты туда засунул код который лучше разместить в другом месте.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerIndex.php#L23

> if($_GET) {


Думаю это условие не нужно.

Насчет генерации URL: может проще сделать просто функцию типа getListUrl($serach, $page, $order) чем долго заполнять свойства объекта? Ну хотя можно и так оставить конечно.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerIndex.php#L42

> $viewSettings["totalPages"] = $pager->get_total_pages();


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

> if($viewSettings['currentPage'] > $viewSettings['totalPages']) $viewSettings['currentPage'] = 1;


Это лучше перенести в пейджер.

> foreach(array_keys(get_object_vars($viewSettings["students"][$i])) as $key) {


> $viewSettings["students"][$i]->$key = htmlspecialchars($viewSettings["students"][$i]->$key


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

> include_once("../templates/header.html");


> include_once("../templates/index.html");


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

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L17

> if(!isset($_POST['csrf_field']) && !isset($_COOKIE['token']) && $_POST['csrf_field'] != $_COOKIE['token']) {


Лучше сделать единую функцию проверки csrf токена.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L58
выставление токена надо вынести в функцию. Наверно надо сделать просто отдельный класс, отвечающий за CSRF, или отдельные методы.

https://github.com/foobar1643/student-list/blob/master/app/Controller/ControllerForm.php#L22

> foreach(array_keys(get_object_vars($student))


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

> $errors = $formValidator->validateForm($_POST);


Не лучше ли валидировать модель, а не массив непонятного вида?

https://github.com/foobar1643/student-list/blob/master/app/Database/StudentDataGateway.php#L30

> $result = $query->fetch();


> return $result['id'];


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

> $query->bindValue(':byear_bind', $student->byear, \PDO::PARAM_STR);


Почему строка?

> SE LE CT CO UNT(*) FR OM students WH ERE CON CAT(name, ' ', surname)


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

https://github.com/foobar1643/student-list/blob/master/app/Database/StudentDataGateway.php#L58

> public function select_students($offset, $sorting_pattern, $sorting_type, $search_pattern) {


В функции аргументы без проверки вставляются прямо в SQL запрос, это ведь SQL инъекция получается?

> public function selectToken($token) {


А почему тут не объект возвращается?

> $row = $query->fetchAll(\PDO::FETCH_CLASS, "\App\Model\Student");


> return $row[0];


Есть метод чтобы прочитать одну запись.

https://github.com/foobar1643/student-list/tree/master/app/Model/Helper
Я бы вынес эту папку из Model вверх.

https://github.com/foobar1643/student-list/blob/master/app/Model/Helper/FormHelper.php#L10
В фамилии-имени могут быть символы дефиса, пробела и апострофа. Д`Артаньян например.

> if($data['gender_field'] != "male" && $data['gender_field'] != "female")


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

Ошибки надо бы сделать более информативными. Не "неправильно заполнено поле" и не подкрасить красным цветом, а написать например "Имя может содержать не более X символов, вы ввели Y".

> if(!preg_match("/[А-ЯЁA-Z]{1}[а-яёa-z]{1,15}$/u"


> preg_match("/[1][9][0-9]{2}$/",


Нету привязки к началу строки

https://github.com/foobar1643/student-list/blob/master/app/Model/Helper/LinkHelper.php#L34

> $link .= "&search=" . $this->search_pattern;


Не кодируются вставляемые в параметр спецсимволы.

https://github.com/foobar1643/student-list/blob/master/app/Model/Helper/TokenHelper.php#L11

> $source[rand(0, count($source))];


В массиве нет элемента с индексом count(...).

https://github.com/foobar1643/student-list/blob/master/templates/index.html#L24

> for($i = 0; $i < count($viewSettings['students']); $i++): ?>


Нужен foreach

> <?php if($viewSettings['totalPages'] > 1): ?>


Я думаю дописывание везде $viewSettings замусоривает код. Попробуй обойтись без него. Либо как $totalPages либо $this->totalPages.

https://github.com/foobar1643/student-list/blob/master/templates/index.html#L9
Поле поиска наверно надо пометить обязательным к заполнению.

> <?php print


лучше <?=

Добавь также HTML5 валидацию в форму регистрации.
#941 #639133
>>635118

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

>>635131

Slim/Silex, Yii2, Symfony 2. Это от простых к сложным.

>>635259

Названия переменных никуда не годятся. Названия должны обозначать то, что в них хранится, а не представлять бессмысленный набор букв. Пееремнные называются с маленькой буквы. Названия вроде "массив", "строка" и названия из 1-2 букв тоже не годятся. Хорошие названия: $words, $sentences, $firstLetter и так далее. Пока читать код очень тяжело, так как ничего не понятно.

Имена функций начинаются с глагола: сделайЧтоТо(). Названия типа commas не годятся.

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

> $i = 0;


> foreach($part as $num){


в таких случаях лучше писать foreach ($parts as $key => $part)

> $last = mb_substr($string, 1, $nums);


можно просто mb_substr($string, 1);

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

> $result = mb_substr($result, 0, -3);


Откуда магическое число -3? Это что-то странное.

>>635296

> Только в последний месяц он заплатил 5262.


У него нет столько денег.

>>635306

Оп не очень в них рабирается и не считает это принципиально важным вопросом.

>>635616

Ответил где-то выше, смотри по ссылкам с поста.

>>635746
>>635877

Вот какой у меня получился алгоритм решения:

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

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

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

>>635131

Slim/Silex, Yii2, Symfony 2. Это от простых к сложным.

>>635259

Названия переменных никуда не годятся. Названия должны обозначать то, что в них хранится, а не представлять бессмысленный набор букв. Пееремнные называются с маленькой буквы. Названия вроде "массив", "строка" и названия из 1-2 букв тоже не годятся. Хорошие названия: $words, $sentences, $firstLetter и так далее. Пока читать код очень тяжело, так как ничего не понятно.

Имена функций начинаются с глагола: сделайЧтоТо(). Названия типа commas не годятся.

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

> $i = 0;


> foreach($part as $num){


в таких случаях лучше писать foreach ($parts as $key => $part)

> $last = mb_substr($string, 1, $nums);


можно просто mb_substr($string, 1);

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

> $result = mb_substr($result, 0, -3);


Откуда магическое число -3? Это что-то странное.

>>635296

> Только в последний месяц он заплатил 5262.


У него нет столько денег.

>>635306

Оп не очень в них рабирается и не считает это принципиально важным вопросом.

>>635616

Ответил где-то выше, смотри по ссылкам с поста.

>>635746
>>635877

Вот какой у меня получился алгоритм решения:

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

«Платим» здесь значит уменьшаем долг и увеличиваем общую сумму выплаченного.
Ответы 25-27 янв #942 #639134
>>635945

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

Выражение ($creditBalance * $percent) + $servicePayment повторяется 3 раза, попробуй убрать повторы и сократить код.

>>635980

Саблайм не может есть столько же ресурсов сколько Атом, так как он на Си/питоне, а Атом на HTML. Но конечно если много плагинов поставить, все может поменяться. Попробуй редактор без плагинов.

>>635588

В PHP есть и асинхроннсть (reactPHP), и многопоточность.

>>636102

Проверку баланса надо делать не в начале месяца а после прибавления процентов и комиссии.
Ответы 25-27 янв #943 #639135
>>636115

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

a | b
-----------
Андрей | 1
Андрей | 5
Иван | 1
Иван | 1
Иван | 2
Иван | 20
Юрий | 7

> SELECT id, lft, root, level FROM category WHERE level IN (1,2) ORDER BY root, lft;


По видимому из-за IN здесь используется только начало индекса, чтобы найти все записи с level = 1 или 2. Конец индекса не используется для сортировки, вместо этого записи выбираются и сортируются в памяти.

Это можно увидеть по этой записи:

> key: ix_level_root_lft


> key_len: 4


Видишь, из индекса используются только первые 4 байта, то есть одно поле типа int. Если бы он использовался весь, там бы было большее число. Проверь, заменив IN на WHERE level = 1.

> Но зачем? Разве в индексе они не хранятся в отсортированном виде? Судя по key_len = 4, вторая и третья часть индекса вообще не используется.


Видимо из-за IN. Ведь записи отсортированы по 2 и 3 полю только там где первое поле одинаково, смотри рисунок выше. Если мы сделаем выборку WHERE a IN ('Иван', 'Юрий'), значения колонки b не отсортированы. А если сделать WHERE a = 'Иван' ORDER BY b то можно использовать индекс целиком.

> Разве в индексе они не хранятся в отсортированном виде?


В индексе они отсортированы по ORDER BY level, root, lft.

> наверное таки лучше between


Не должно помочь.

> Хотя судя по времени выполнения запроса, очень даже используется: с индексом только на (level) запрос 0.20с, индекс (level, root, lft) занимает 0.06с.


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

>>636122

Открой сайт вакансий.

>>636172

> Совсем хорошо было бы, если бы мне вообще не нужна была сортировка в запросе.


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

Ну и еще есть такая хитрость. Можно ввести поле isLevelBelow3 куда записать 1 для записей где level < 3 и сделать индекс по (isLevelBelow3, root, lft). Но не уверен что стоит с этим заморачиваться.

> Или прямо в php отсортировать массив? Черт его знает.


Я бы сортировал в SQL. Оно ведь закеширует запрос, если тебя беспокоит производительнсоть. И если таблица нечасто меняется.

>>636285

Решай параллельно c php. Или попроси подсказку по HTML.

>>636292

Написать HTML и CSS код.

>>636306

Я же вроде что-то выше подсказал. Если непонятно, задавай уточняющие вопросы.
Ответы 25-27 янв #943 #639135
>>636115

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

a | b
-----------
Андрей | 1
Андрей | 5
Иван | 1
Иван | 1
Иван | 2
Иван | 20
Юрий | 7

> SELECT id, lft, root, level FROM category WHERE level IN (1,2) ORDER BY root, lft;


По видимому из-за IN здесь используется только начало индекса, чтобы найти все записи с level = 1 или 2. Конец индекса не используется для сортировки, вместо этого записи выбираются и сортируются в памяти.

Это можно увидеть по этой записи:

> key: ix_level_root_lft


> key_len: 4


Видишь, из индекса используются только первые 4 байта, то есть одно поле типа int. Если бы он использовался весь, там бы было большее число. Проверь, заменив IN на WHERE level = 1.

> Но зачем? Разве в индексе они не хранятся в отсортированном виде? Судя по key_len = 4, вторая и третья часть индекса вообще не используется.


Видимо из-за IN. Ведь записи отсортированы по 2 и 3 полю только там где первое поле одинаково, смотри рисунок выше. Если мы сделаем выборку WHERE a IN ('Иван', 'Юрий'), значения колонки b не отсортированы. А если сделать WHERE a = 'Иван' ORDER BY b то можно использовать индекс целиком.

> Разве в индексе они не хранятся в отсортированном виде?


В индексе они отсортированы по ORDER BY level, root, lft.

> наверное таки лучше between


Не должно помочь.

> Хотя судя по времени выполнения запроса, очень даже используется: с индексом только на (level) запрос 0.20с, индекс (level, root, lft) занимает 0.06с.


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

>>636122

Открой сайт вакансий.

>>636172

> Совсем хорошо было бы, если бы мне вообще не нужна была сортировка в запросе.


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

Ну и еще есть такая хитрость. Можно ввести поле isLevelBelow3 куда записать 1 для записей где level < 3 и сделать индекс по (isLevelBelow3, root, lft). Но не уверен что стоит с этим заморачиваться.

> Или прямо в php отсортировать массив? Черт его знает.


Я бы сортировал в SQL. Оно ведь закеширует запрос, если тебя беспокоит производительнсоть. И если таблица нечасто меняется.

>>636285

Решай параллельно c php. Или попроси подсказку по HTML.

>>636292

Написать HTML и CSS код.

>>636306

Я же вроде что-то выше подсказал. Если непонятно, задавай уточняющие вопросы.
#944 #639136
И кстати спасибо анону, котоый помогает начинающим с задачкой про айфон. Вот тебе стандартная паста с алгоритмом решения, если нужно.

-----------

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

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

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

------------
перекот #945 #639140
Аноны, переходите в новый тред >>639138 (OP)

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

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

Здесь ничего не пишите, идите в новый тред >>639138 (OP)

Если вас забыли, пропустили - напомните о себе в новом треде.
#946 #639142
>>637748

> Не знаю почему у меня подвисает ввод во время обновления треда,


> вроде никакой явной блокировки не нашлось



Яваскрипт однопоточный и блокирует интерфейс браузера на время работы. Возможно дело в этом. Что подвисает - можно посмотреть профайлером в Хроме на вкладке Timeline и Profiles. Можешь попробовать. Включи автообновление, запись и набирай текст. После первого же подвисания можешь оставновить запись.

> Вот я хочу отследить, как на сосаче происходит обновление треда.


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

> Так все-таки, какая польза от отладчика кроме возможности остановить исполнение


в определенный момент (а этот момент еще надо вычислить) и посмотреть значение переменных?
В этом и польза что можно посмотреть и например увидеть что в переменной что-то не то.
#947 #639145
>>638599

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


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

> В innodb блокировка на уровне строк благодаря мультиверсионности.


MVCC позволяет работать без блокировок, блокировки там добавлены ради соблюдения требований к транзакциям. А вот MyISAM требует блокировок (а транзакции вообще не поддерживает).

> Чтобы объединить несколько


запросов в транзакцию в myisam используется явная блокировка таблиц LOCK

> TABLE.


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

> Это значит что выбираться будут только данные,


актуальные на момент начала данной транзакции. Если параллельная транзакция

> закоммитила изменения, например добавила новые строки, то в рамках текущей


> транзакции мы никогда не увидим эти новые строки.


Так и должно быть. Пока изменения не закоммичены, их нет.

> От потерянного обновления innodb защищен благодаря мультиверсинности.


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

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

> Будет наложена next-key блокировка на все ключи с id > 100, в том числе на те,


которые еще не существуют. Ну то есть если у нас 110 записей в базе, и селект

> вернет соответственно 10, то другие транзакции не могут вставить 111 запись.


> Короче какое-то мутное место.


Нет. Там блокируется диапазон в индексе. Вот допустим у нас есть индекс по id и там идут записи (в индексе они отсортированы):

10
20
90
105
130

Допустим мы делаем запрос SELECT cols FROM tbl WHERE id > 100 FOR UPDATE;

innodb пройдется по индексу, найдет записи > 100 (105 и 130) и поставит на них блокировку. А также, на промежутки рядом с ними, то есть на промежуток между 90 и 105, между 105 и 130 и между 130 и концом индекса. Таким образом, другие транзакции при потытке вставить запись с id > 90 попадут в эти промежутки, будут заблокированы и будут ждать освобождения этой блокировки.

Таким образом избегается фантомное чтение.

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

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

> Потому что там нет мультиверсионности, при апдейте не создается новая версия, а


> идет перезапись. Короче, без блокировки будет потерянное обновление. Или даже


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


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


другой.

Верно.

> При обновлении строки не перезаписываются старые данные, а добавляется в конец


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


Верно

> Затем обе транзакции коммитятся, первая запишет 110, а вторая 120, хотя мы


> ожидали 130. Похоже на потерянное обновление.


Верно.

> LOCK IN SHARE MODE. Если нужно блокировать и на чтение, то SELECT ... FOR UPDATE.


Верно.
#947 #639145
>>638599

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


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

> В innodb блокировка на уровне строк благодаря мультиверсионности.


MVCC позволяет работать без блокировок, блокировки там добавлены ради соблюдения требований к транзакциям. А вот MyISAM требует блокировок (а транзакции вообще не поддерживает).

> Чтобы объединить несколько


запросов в транзакцию в myisam используется явная блокировка таблиц LOCK

> TABLE.


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

> Это значит что выбираться будут только данные,


актуальные на момент начала данной транзакции. Если параллельная транзакция

> закоммитила изменения, например добавила новые строки, то в рамках текущей


> транзакции мы никогда не увидим эти новые строки.


Так и должно быть. Пока изменения не закоммичены, их нет.

> От потерянного обновления innodb защищен благодаря мультиверсинности.


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

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

> Будет наложена next-key блокировка на все ключи с id > 100, в том числе на те,


которые еще не существуют. Ну то есть если у нас 110 записей в базе, и селект

> вернет соответственно 10, то другие транзакции не могут вставить 111 запись.


> Короче какое-то мутное место.


Нет. Там блокируется диапазон в индексе. Вот допустим у нас есть индекс по id и там идут записи (в индексе они отсортированы):

10
20
90
105
130

Допустим мы делаем запрос SELECT cols FROM tbl WHERE id > 100 FOR UPDATE;

innodb пройдется по индексу, найдет записи > 100 (105 и 130) и поставит на них блокировку. А также, на промежутки рядом с ними, то есть на промежуток между 90 и 105, между 105 и 130 и между 130 и концом индекса. Таким образом, другие транзакции при потытке вставить запись с id > 90 попадут в эти промежутки, будут заблокированы и будут ждать освобождения этой блокировки.

Таким образом избегается фантомное чтение.

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

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

> Потому что там нет мультиверсионности, при апдейте не создается новая версия, а


> идет перезапись. Короче, без блокировки будет потерянное обновление. Или даже


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


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


другой.

Верно.

> При обновлении строки не перезаписываются старые данные, а добавляется в конец


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


Верно

> Затем обе транзакции коммитятся, первая запишет 110, а вторая 120, хотя мы


> ожидали 130. Похоже на потерянное обновление.


Верно.

> LOCK IN SHARE MODE. Если нужно блокировать и на чтение, то SELECT ... FOR UPDATE.


Верно.
Перекот #948 #639147
Переходите в новый тред, переходите в новый тред >>639138 (OP)
#949 #639162
>>638949

>Оп по моему разжевал уже дальше некуда.


Однако всё равно натыкаются на разные преграды и запутываются. Подсказки для того, чтобы им распутаться и новым взглядом окинуть задачу.
#950 #639203
>>639100
Грамотные программисты используют очень активно. Но грамотных мало, потому и дурная слава за языком.
#951 #639233
>>639203

переходите в новый тред >>639138 (OP)
Ответы за 27-31 января #952 #641538
>>637198

> $regexp[0] = '/[ ][,][ ]/u';


> $regexp[1] = '/[ ][!][ ]/u';



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

> $sentence = mb_strtoupper(mb_substr($sentence, 0, 1)).mb_substr($sentence, 1, mb_strlen($sentence));


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

>>637452

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

>>637535

> А дальше я вот не знаю, как можно заставить работать вот такое нечто:


> if ($lastThousandNum == 2|3|4) {


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

если число == 2 ИЛИ число == 3 ИЛИ число == 4
если число больше/равно 2 И меньше/равно 4
если число содержится в массиве [2, 3, 4]

И не путай операторы: | это битовое ИЛИ (не то что нужно), || это логическое ИЛИ (то что нужно)
#953 #641539
>>637537

> либо сделать массив $menSpelling, который будет подставляться в функцию вместо $femaleSpelling - и менять то, что и так должно выходить правильно


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

>>637551

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

>>637566

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

>>637709

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

>>637715

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

>>637721

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

>>637764

Погугли про связи в БД, один к одному, многие ко многим. Не зная этого нельзя проектировать базы данных.
#953 #641539
>>637537

> либо сделать массив $menSpelling, который будет подставляться в функцию вместо $femaleSpelling - и менять то, что и так должно выходить правильно


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

>>637551

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

>>637566

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

>>637709

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

>>637715

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

>>637721

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

>>637764

Погугли про связи в БД, один к одному, многие ко многим. Не зная этого нельзя проектировать базы данных.
ответы 27-31 янв #954 #641540
>>637951

Это баг. Советую для начала взять developer tools (Ctrl + Shift + I) в Хроме или ФФ и изучить ситуацию. Я подозреваю, это связано с тем что верстку там поменяли, а js код определения позиции остался старый. Возможно из-за box-sizing: border-box.

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

>>638039

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

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


Лучше использовать https - это само по себе даст больше надежности.

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

>>638055

Запости код, напиши что именно ты не можешь понять?

>>638064

Что такое global? Глобальная переменная? Нет.

>>638253

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

Да и кода много, надо упростить, например выражение ($creditBalance * $percent ) + $servicePayment зачем-то повторяется 2 раза.
ответы 27-31 янв #954 #641540
>>637951

Это баг. Советую для начала взять developer tools (Ctrl + Shift + I) в Хроме или ФФ и изучить ситуацию. Я подозреваю, это связано с тем что верстку там поменяли, а js код определения позиции остался старый. Возможно из-за box-sizing: border-box.

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

>>638039

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

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


Лучше использовать https - это само по себе даст больше надежности.

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

>>638055

Запости код, напиши что именно ты не можешь понять?

>>638064

Что такое global? Глобальная переменная? Нет.

>>638253

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

Да и кода много, надо упростить, например выражение ($creditBalance * $percent ) + $servicePayment зачем-то повторяется 2 раза.
ответы 27-31 #955 #641541
>>638432

> throw new Error("Аргумент "+ arguments+" не является элементом сети");


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

> if (this._elements.getPowerProduction) {


Что-то мне не очень нравится, что функция может быть, может не быть. Не проще ли в базовом классе сделать эту функцию и возвращать ей ноль? Ну или если у тебя все завязано на классы Generator/Consumer то сделать проверку что объект является их наследником. Хотя мне кажется проще функции сделать в базовом классе.

>>638457

Пруфы?

>>638469

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


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

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


Отказаться от статических методов.

> В этом классе делать метод setRegistrationHelper(RegistrationHelper $reghelper) и вызывать его далее:


> Мне все равно придется писать где-то в начале $reghelper = new RegistrationHelper()


Верно, где-то нам все равно надо создать объекты. Тут есть такие варианты:

1) создавать их в скрипте инициализации, bootstrap или init, если их немного
2) сделать контейнер или сервис локатор, который умеет их создавать. Создать контейнер в скрипте инициализации и передавать в контроллер. А контролллер из контейнера получает нужные ему объекты-сервисы. Только не злоупотребляй этим - не надо контейнер передавать везде, иначе мы опять получаем что неясно от чего зависит класс.

> Я не хочу так делать, я хочу чтобы я вызвал одну единственную функцию и все было готово как я это сделал здесь


Тогда тебе нужен контейрнер, который умеет сам создавать нужные объекты.

> Это вообще входит в рамки задачи?


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

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


Неужели ты обречен писать хороший код, а не спутанную лапшу?

> Зачем их тогда вообще сделали,


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

Смотри как статические методы отравляют код. Если тебе в RegisterHelper нужен например маппер, тебе придется его создавать там внутри. А тому нужен ПДО - надо опять же его создавтаь. Вот так все получается намертво спутано - мы не можем взять и вместо PDO передать какой-нибудь объект который например логгирует все походящие через него запросы.

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

Я же писал в уроке, DI позволяет нам разделить классы, это как устройства с разъемами, которые соединены проводами и которые можно переподключать. А статические методы это когда все намертво припаяно друг у другу.

> будут ли от них избавляться(или уже избавились)?


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

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


Задавай еще. Важно разобраться.

>>638474

> Здесь мне тоже нужно будет пользоваться инъекциями зависимостей?


> public function addStudent(Student $student, Container $container) {


Это какая-то странная зависимостей. Ты пока не понял принцип. Какой смысл в addStudent передавать какие-то лишние объекты? Контейнер всегда один и тот же, значит незачем его передавать каждый раз, можно один раз его передать при создании объекта.

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

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

То есть давай я попробую повторить принципы хорошего кода:

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

Часть этих принципов не относится к контроллеру. Например, в контроллер можно передавать конейтнер и не обозначать четко его зависимости (хотя есть и те кто считает что это плохо).
ответы 27-31 #955 #641541
>>638432

> throw new Error("Аргумент "+ arguments+" не является элементом сети");


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

> if (this._elements.getPowerProduction) {


Что-то мне не очень нравится, что функция может быть, может не быть. Не проще ли в базовом классе сделать эту функцию и возвращать ей ноль? Ну или если у тебя все завязано на классы Generator/Consumer то сделать проверку что объект является их наследником. Хотя мне кажется проще функции сделать в базовом классе.

>>638457

Пруфы?

>>638469

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


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

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


Отказаться от статических методов.

> В этом классе делать метод setRegistrationHelper(RegistrationHelper $reghelper) и вызывать его далее:


> Мне все равно придется писать где-то в начале $reghelper = new RegistrationHelper()


Верно, где-то нам все равно надо создать объекты. Тут есть такие варианты:

1) создавать их в скрипте инициализации, bootstrap или init, если их немного
2) сделать контейнер или сервис локатор, который умеет их создавать. Создать контейнер в скрипте инициализации и передавать в контроллер. А контролллер из контейнера получает нужные ему объекты-сервисы. Только не злоупотребляй этим - не надо контейнер передавать везде, иначе мы опять получаем что неясно от чего зависит класс.

> Я не хочу так делать, я хочу чтобы я вызвал одну единственную функцию и все было готово как я это сделал здесь


Тогда тебе нужен контейрнер, который умеет сам создавать нужные объекты.

> Это вообще входит в рамки задачи?


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

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


Неужели ты обречен писать хороший код, а не спутанную лапшу?

> Зачем их тогда вообще сделали,


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

Смотри как статические методы отравляют код. Если тебе в RegisterHelper нужен например маппер, тебе придется его создавать там внутри. А тому нужен ПДО - надо опять же его создавтаь. Вот так все получается намертво спутано - мы не можем взять и вместо PDO передать какой-нибудь объект который например логгирует все походящие через него запросы.

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

Я же писал в уроке, DI позволяет нам разделить классы, это как устройства с разъемами, которые соединены проводами и которые можно переподключать. А статические методы это когда все намертво припаяно друг у другу.

> будут ли от них избавляться(или уже избавились)?


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

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


Задавай еще. Важно разобраться.

>>638474

> Здесь мне тоже нужно будет пользоваться инъекциями зависимостей?


> public function addStudent(Student $student, Container $container) {


Это какая-то странная зависимостей. Ты пока не понял принцип. Какой смысл в addStudent передавать какие-то лишние объекты? Контейнер всегда один и тот же, значит незачем его передавать каждый раз, можно один раз его передать при создании объекта.

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

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

То есть давай я попробую повторить принципы хорошего кода:

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

Часть этих принципов не относится к контроллеру. Например, в контроллер можно передавать конейтнер и не обозначать четко его зависимости (хотя есть и те кто считает что это плохо).
Ответы 27-31 #956 #641542
>>638595

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

>>638647

Хорошо, а теперь убери еще строчки которые повтряются 2 раза:

> $paymentTotal = $paymentTotal + $creditBalance;


> $creditBalance = $creditBalance - $creditBalance;



>>638700

Решено верно. Но можно еще улучшить код, если проверку на то что набран миллион поставить в шапку цикла (внутрь круглых скобок), а вывод информации поставить после цикла.

>>638849

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

>>639092

Нет, не одно и то же. Видимо, плоховато знаешь. Куки - данные, которые хранятся в браузере пользователя. Сессия- данные, которые хранятся на сервере, а идентификатор сессии хранится у пользователя в куке.

>>639114

> PHP Notice: Undefined variable: paymentTotal in /home/LwUcTo/prog.php on line 9


> PHP Notice: Undefined variable: paymentTotal in /home/LwUcTo/prog.php on line 9


Ошибка из-за обращения к еще не существующей переменной. Надо исправить.

Выражение ($credit * $percent) + $commission повторяется 3 раза, надо бы избавиться от повтора.

Если поставить сумму в 1000 р то считает неправильно - во втором банке должно быть 2030 р, а не 2940: http://ideone.com/kzHxKh

Пока не годится.
Ответы 27-31 #956 #641542
>>638595

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

>>638647

Хорошо, а теперь убери еще строчки которые повтряются 2 раза:

> $paymentTotal = $paymentTotal + $creditBalance;


> $creditBalance = $creditBalance - $creditBalance;



>>638700

Решено верно. Но можно еще улучшить код, если проверку на то что набран миллион поставить в шапку цикла (внутрь круглых скобок), а вывод информации поставить после цикла.

>>638849

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

>>639092

Нет, не одно и то же. Видимо, плоховато знаешь. Куки - данные, которые хранятся в браузере пользователя. Сессия- данные, которые хранятся на сервере, а идентификатор сессии хранится у пользователя в куке.

>>639114

> PHP Notice: Undefined variable: paymentTotal in /home/LwUcTo/prog.php on line 9


> PHP Notice: Undefined variable: paymentTotal in /home/LwUcTo/prog.php on line 9


Ошибка из-за обращения к еще не существующей переменной. Надо исправить.

Выражение ($credit * $percent) + $commission повторяется 3 раза, надо бы избавиться от повтора.

Если поставить сумму в 1000 р то считает неправильно - во втором банке должно быть 2030 р, а не 2940: http://ideone.com/kzHxKh

Пока не годится.
Тред закрыт #957 #641543
Все, тред закрыт. На все вопросы даны ответы. Если кого-то пропустиили или забыли - напомните о себе в новом треде >>639138 (OP)

Не пишите здесь. Никто вам не ответит. Идите в новый тред.
Обновить тред
Двач.hk не отвечает.
Вы видите копию треда, сохраненную 19 февраля 2016 года.

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски