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

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
88 Кб, 500x500
157 Кб, 1024x683
34 Кб, 650x384
43 Кб, 721x480
Клуб любителей изучать PHP 41 !xnn2uE3AU. #419972 В конец треда | Веб
Добро пожаловать. В этом праздничном ИТТ треде мы изучаем PHP (а также MySQL, JS, CSS, HTML), решаем задачки и даже делаем простые сайты! Зачем? Кто-то хочет научиться программировать, кто-то хочет делать сайты, кто-то хочет просто размять мозги и заняться чем-то полезным.

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

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

Предыдущий тред был тут: >>416970

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

Есть еще у нас задачки на HTML, JS, MySQL.

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

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

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

Что почитать?

Мануал по PHP — http://www.php.net/manual/ru/langref.php
Сайт phptherightway
По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл
По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования
JS: learn.javascript.ru
HTML/CSS: Путь верстальщика: https://gist.github.com/codedokode/58ebc90bd006baf4b35c
MySQL: https://gist.github.com/codedokode/10539213

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

Сайт опять упал!!!!! Не паникуй, а открой http://rghost.net/45000175

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

Где архивы предыдущих тредов? Известно, где, на mediafire: http://www.mediafire.com/download/gza5360wdzqd743/threads-archive-pr-1..17.zip (189Мб, треды 1-17 из pr), http://www.mediafire.com/download/kgzl1f9366gc6ed/threads-archive-11..20.zip (72 Мб, треды 11-20 из b). Также один анон выложил все на дропбокс: https://www.dropbox.com/sh/4sb69jrx9qwrpcw/-nY5ia__VC (ок, он иногда не работает)

Как начать пользоваться командной строкой — gist.github.com/anonymous/9378956452c8e4a72ac8

ОП, сделай за меня мою работу или домашнее задание? — Это конечно, хорошая идея, но нет.

Расскажи про поиск работы, фриланс etc Информация о фрилансе есть в /wrk . Также, походи по сайтам вроде hh.ru, hantim.ru, geekjob, fl.ru, посмотри, поизучай ситуацию. Имей в виду, кроме фриланса, где ты 2 дня ищешь заказ, полдня обсуждаешь за бесплатно суть работы, день делаешь и еще 2 дня слушаешь от заказчика что он о тебе думает, есть удаленная работа — продаешься в рабство, и занимаешься только программированием, задачи тебе будут подкидывать наготово. Ищется по слову «удаленно» на перечисленных сайтах. Зарплата на удаленной работе может быть меньше чем в офисе в столице, но больше чем в твоей деревне. На одеске зарабатывают больше, чем на русском фрилансе.

В общем, давайте начинать уже!
56 Кб, 500x644
53 Кб, 636x636
3449 Кб, 1920x1080
Стой !xnn2uE3AU. #2 #419977
Прочитай сначала этот пост.

Как и чем отформатировать код

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

Не бойся, сделать код аккуратным совсем не сложно. Самый универсальный способ — вставить его на сайт http://phpformatter.com и нажать кнопку Format. Робот сам выровняет твой код в лучших традициях.

Если ты используешь для редактирования кода IDE, то все еще проще (а если не используешь, то почему бы не начать?):

- Eclipse PDT — жми Ctrl + Shift + F для автоматического форматирования кода.
- Netbeans for PHP — жми Alt+Shift+F
- Zend Studio — жми Ctrl + A (выделить все), затем Ctrl + Shift + F
- PhpStorm — жми Ctrl+Alt+L
- PHPDesigner — поищи нужную опцию в меню, она там есть. Или жми Ctrl + Shift + F1
- Komodo IDE — правая кнопка -> Format Using...

Вот так, нажатием одной кнопки ты можешь сделать жизнь гораздо проще.

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

Подробнее: https://gist.github.com/codedokode/8759492

Основные правила

Если ты вдруг решил выровнять код вручную, запомни эти правила:
- переменные и функции пишутся с маленькой буквы, подчеркивание не используется, используется camelCase, пример: $x, $numberOfPeople, printResults()
- название функции начинается с глагола, в стиле «сделайЧтоТо»
- не знаешь английский (неужели такое бывает?) Не беда, в 21 веке есть решение этой проблемы. Не пиши транслитом, открой лучше Гугл Транслейт или slovari.yandex.ru и найди название для переменной там
- в именах классов используется CamelCase, первая буква большая, «_» может использоваться
- мы предпочитаем подстановку переменных вместо конкатенации строк: "I am $age years old" — хорошо, 'I am ' . $age . ' years old' — плохо
- мы используем для отступов 4 пробела, а не табы (нужно настроить редактор, чтобы при нажатии Tab он вставлял 4 пробела)
56 Кб, 500x644
53 Кб, 636x636
3449 Кб, 1920x1080
Стой !xnn2uE3AU. #2 #419977
Прочитай сначала этот пост.

Как и чем отформатировать код

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

Не бойся, сделать код аккуратным совсем не сложно. Самый универсальный способ — вставить его на сайт http://phpformatter.com и нажать кнопку Format. Робот сам выровняет твой код в лучших традициях.

Если ты используешь для редактирования кода IDE, то все еще проще (а если не используешь, то почему бы не начать?):

- Eclipse PDT — жми Ctrl + Shift + F для автоматического форматирования кода.
- Netbeans for PHP — жми Alt+Shift+F
- Zend Studio — жми Ctrl + A (выделить все), затем Ctrl + Shift + F
- PhpStorm — жми Ctrl+Alt+L
- PHPDesigner — поищи нужную опцию в меню, она там есть. Или жми Ctrl + Shift + F1
- Komodo IDE — правая кнопка -> Format Using...

Вот так, нажатием одной кнопки ты можешь сделать жизнь гораздо проще.

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

Подробнее: https://gist.github.com/codedokode/8759492

Основные правила

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

Что значит «в конец»? В таблицах нет какого-то особого порядка в котором идут записи.

Если ты спрашивал про поле AUTO_INCREMENT то каждый следующий сгенеирированный id больше предыдущего.
#5 #419992
Оп, ты не забыл еще про мою задачу >>419758 ?
#6 #419997
сап ребятки.
задам тупые вопросы, не агритесь сильно.
меня интересует какие языки вообще для чего предназначены? хочу программировать попробовать в качестве хобби.
#7 #420005
>>419997
Для хобби подойдет джваскрипт, поскольку простой и ничего не надо устанавливать, интерпретатор встроен прямо в твой браузер. Из минусов - придется подучить хтмл-разметку.
#8 #420009
>>420005
а вот эти руби и питон? с ними как дело обстоит?
#9 #420029
>>419961
Так я уже их связал, посмотри в моделях.
#10 #420045
>>420005

Херасе простой. Один из самых кривых и сложных языков программирования
#11 #420052
>>420045
Во-во. Я бы C советовал.
#12 #420053
>>420052

Cи без плюсов абсолютно бесполезен при том сложен, а с плюсами еще сложнее.
#13 #420056
>>420053
Си очень простой язык, просто низкоуровневый.
#14 #420057
>>420053
Так после Си на яву пусть идет! или на php
#15 #420059
>>420005

> Из минусов - придется подучить хтмл-разметку


Это ещё почему?
Во-первых, есть Node и Node-Webkit.
Во-вторых, чтобы решать алгоритмические задачки, ничего кроме ввода-вывода не нужно.
В-третьих, чтобы выводить что-то в канвас или в какой-нибудь элемент с textContent, никаких знаний хтмл не нужно вообще.

>>420045

> Херасе простой. Один из самых кривых и сложных языков программирования


Ну и что в нём сложного? Объекты? Функции? Замыкания? ок, это может быть

мимо-js-гуру
#16 #420060
>>420059

> Node-Webkit


ок, это я глупость сморозил
#17 #420077
>>420059

>Во-вторых, чтобы решать алгоритмические задачки, ничего кроме


...Си не нужно.
19 Кб, 409x265
sage #18 #420078
>>419997

> хобби


Sikuli
пиздец как весело
вот тред >>419136
по сути это есть питон, так что на нём тоже сможешь кодить

С - скучная поебота
джяваскрипт - кривой пиздец
рнр - тоже
82 Кб, 1895x868
#19 #420079
Это я туплю, или что не так?
кстати, уже два урока нихрена не понимаю, что я делаю.
#20 #420080
Вопрос по кошкам-мышкам, хранится ли где-нибудь экземпляр объекта кошки или мышки или сразу же присваивается элементу массива доски? Я пытаюсь понять алгоритм: сперва создается экземпляр класса животного(кошки либо мышки) который присваивается переменной, потом переменная помещается в массив доски на которой происходит движение, потом вычисляется направление движения и шаг, потом новому элементу массива в зависимости от направления и шага присваивается значение переменной в которой хранится экземпляр класса, а старый элемент ансетится? Или другой принцип?
#21 #420086
>>420079
Бамп.
Я в упор ошибки не вижу, лол. Что-то не так, а спросить неукого.
#22 #420087
>>420077

По моему ты пишешь глупость. Расскажи мне про библиотеку коллекций или ООП в Си?
#23 #420089
>>420080

Все проще. У доски есть массив животные[] который хранит все объекты-животные на ней. Они добавляются туда когда ты ставишь животное на доску и удаляются когда например когда ты убираешь съеденнную мышку. Больше ничего с этим массивом делать не требуется.
#24 #420090
>>419992

Нет, не забыл, а ты пока посмотри что я тут написал и что ты из этого можешь исправить:>>419761 >>419762
#25 #420091
>>420080

То есть я предлагаю не хранить вообще массив клеточек, а только массив животных. Ну хотя если ты хочешь, можешь сделать дополнительно массив клеточек и передвигать животных в нем.
#26 #420100
>>420089
Ну я заполнил массив объектами(животными), а пустые места просто звездочками, чтобы графически проследить. Но я так и не понял, какой алгоритм перемещения?
#27 #420111
>>420100

Ты не понял что я советовал. Должен быть либо один обычный массив с животными без всяких звездочек либо массив с животными + двухмерный массив с клеточками карты.
49 Кб, 600x606
sage #28 #420113
>>420100
массив массивов
#29 #420121
Привет, Оп. Я ньюфаг ничего незнающий. И я вот по основам учусь, что есть в опике. Но вот с циклами незадача. Укажешь на ошибки? http://ideone.com/jr5j6g
121 Кб, 700x1050
Воннаби #30 #420125
Котаны, я в полной жопе. Уже несколько месяцев топчусь на месте. Постоянно начинаю и бросаю. Но у меня нет четкой системы, и регулярных занятий. Страдаю полной хуйней после того как вышел из дошкольных задач в учебнике, которые до и включая регулярки. Уже умудрился устраиваться на работу пхп-макакой без знаний в прекрасное место 3-4 тредами ранее, вы еще бугуртили что такое дно кто-то взял но дропнул спустя неделю из-за того что дорога в 1 сторону занимала полтора-два часа, о чем сейчас жалею, поступил как инфантильный уебок, который не мог немного потерпеть лучше бы хотя бы 1 месяц полноценно поработал, ведь там голова хотя бы немного работала, да и всем было похуй что я медленный, просто давали задачу и я сидел над ней и делал себе, пока не умудрялся её решить. В общем совершил ошибку, но щито поделать.

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

Как с этим говном справиться? Нужна какая-то система видимо, ну и перестать хвататься за всё. Спасибо что выслушали моё нытье. Всем спокойной ночи.
#31 #420126
>>420121

>PHP Parse error: syntax error, unexpected '{' in /home/VUsJpz/prog.php on line 18


у тебя в той строчке стоит else (условие) {

А так не должно быть, после else не нужно условие а сразу идут скобки, если у тебя есть второе условие альтернативное первому указанному после if () {, то используй elseif () {

Из меня наверное не очень объяснятель, вот просто исправил синтаксис твой не проверяя логику: http://ideone.com/BLxobc
Но лучше иди про условия главу перечитай прямо сейчас, и напиши с нуля задачу.
#32 #420137
>>420121
Что-то у тебя вообще не так всё.
Я вот сам нубас, но эту задачу за 2 дня через кучу багета и подсказок с тредика прошел. Там суть, что начальный код изменить нужно немного.
Суть, что сначала капает кредит, потом оцениваешь, можешь-ли ты заплатить полную сумму, или-же не полную, и аж потом платишь.
Активная часть кода у меня в 12 строк влезла.
А ты сначала начал платить, потом сам себе 0 в оплату поставил, а потом опять начал платить, как-то так.
Мне прямым текстом не подсказывали, но я смог дотупить до решения - ты тоже сможешь.
#33 #420138
>>420121

>Привет, Оп. Я ньюфаг ничего незнающий. И я вот по основам учусь, что есть в опике. Но вот с циклами незадача. Укажешь на ошибки? http://ideone.com/jr5j6g


>



>- напиши код, который каждый месяц только увеличивает долг (и выводит его на экран)


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


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


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



Это мне помогло, попробуй и ты по этому алгоритму сделать.
#34 #420143
>>419997

Есть языки работающие в браузере (JS + HTML/CSS), есть серверные (чтобы делать динамические сайты) вроде PHP, Ruby, Python, есть языки для десктопных приложений вроде C++, есть мало где использующиеся языки типа Си (некоторые на них микрконтроллеры программируют, но я слышал что С++ на них тоже давно уже запускается), есть языки для мобильных приложений (Java, Obj-C), есть языки из маковской экосистемы (Obj-C), языки для написания крупных и корпоративных приложений (C#/.NET, Java), и есть применяющиеся энтузиастами новые языки для обкатки новых подходов в программировании вроде Haskell, Scala, D, Rust, Go.

>>420009

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

>>420029

Ну ладно, посмотрим что получится.

>>420059

> есть Node


Какое отношение серверный язык имеет к верстке? Думаю, никакого.

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


Поддержки JS может не быть на сайте где проверяются решения

>>420079

Если ты не понимаешь ООП, у меня есть простой урок: http://archive-ipq-co.narod.ru/l1/pasta.html

Насчет codeacademy, он ничего не пишет? Там код проверки решений довольно кривой и иногда глючит. Сохрани текст программы и попробуй перезагрузить страницу.

Алсо ты по моему echo забыл

>>420100

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

для каждого животного которое есть на карте:
животное->сделатьХод()
#34 #420143
>>419997

Есть языки работающие в браузере (JS + HTML/CSS), есть серверные (чтобы делать динамические сайты) вроде PHP, Ruby, Python, есть языки для десктопных приложений вроде C++, есть мало где использующиеся языки типа Си (некоторые на них микрконтроллеры программируют, но я слышал что С++ на них тоже давно уже запускается), есть языки для мобильных приложений (Java, Obj-C), есть языки из маковской экосистемы (Obj-C), языки для написания крупных и корпоративных приложений (C#/.NET, Java), и есть применяющиеся энтузиастами новые языки для обкатки новых подходов в программировании вроде Haskell, Scala, D, Rust, Go.

>>420009

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

>>420029

Ну ладно, посмотрим что получится.

>>420059

> есть Node


Какое отношение серверный язык имеет к верстке? Думаю, никакого.

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


Поддержки JS может не быть на сайте где проверяются решения

>>420079

Если ты не понимаешь ООП, у меня есть простой урок: http://archive-ipq-co.narod.ru/l1/pasta.html

Насчет codeacademy, он ничего не пишет? Там код проверки решений довольно кривой и иногда глючит. Сохрани текст программы и попробуй перезагрузить страницу.

Алсо ты по моему echo забыл

>>420100

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

для каждого животного которое есть на карте:
животное->сделатьХод()
#35 #420144
>>420121

Ну здравствуй анон. Давай посмотрим код.

> else ($creditBalance > $monthlyPayment) {


Тут надо либо elseif либо else без условий. Посмотри внимательно урок про игру в кубики. там вроде есть пример if/elseif.

>>420125

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

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

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

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

> есть мало где использующиеся языки типа Си



http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
#37 #420159
>>419997
>>420143
Сука, бомбануло так, что решил угробить себе жизнь, зашкворившись об ваш клуб PHP-шников.

> есть серверные


> Ruby, Python


Нет. Это языки общего назначения. Можно использовать как замену PHP на сервере, так и на клиенте. Можно автоматизировать простенькие задачи, типа массового переименования файлов (собственно, Ruby для этого и проектировался изначально). У них только две беды: 1) они динамически типизированы; 2) под них есть только интерпретаторы. На самом деле, это гибридные интерпретаторы, так называемые виртуальные машины, но от этого скорости исполнения не прибавляется, и не исчезает необходимость ставить эту самую виртуальную машину.

> C++


> языки для десктопных приложений


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

> есть мало где использующиеся языки типа Си


Сука, вторично бомбануло. Анончик ниже правильно ссылку дал, C был, есть и будет самым распространённым языком в мире. Есть компиляторы в высокооптимизированный машинный код практически подо всё, что может включаться. Так что это самый кроссплатформенный язык на планете («write once, compile everywhere»). У него только две беды: 1) семантически он довольно близок к Ассемблеру; 2) у него хуёвые средства абстракции. Вместе эти две беды делают его непригодным ни для чего, кроме прошивок для микроконтроллеров, ядер операционок и низкоуровневых библиотек расширения других ЯП. Собственно, он и создавался Керниганом и Ритчи как язык для написания операционных систем. Нет, на нем можно, конечно, написать и гуёвину и даже серверное приложение (и запускать его через FCGI или unix domain sockets), но написание на нем очень быстро превращается в жонглирование указателями и segmentation fault-ами. Даже быстрее, чем на C++. Алсо, так как он семантически близок к Ассемблеру, скомпилированные программы получаются предельно производительными. Если уметь.

> Java


> для мобильных приложений


Анус твой — для мобильных приложений! Java выпускается в трех редакциях: 1) Java ME, которая действительно нужна только для мобилок; 2) Java SE, которая есть платформа общего назначения, но на которой в силу её недостатков можно писать только кровавый энтерпрайз с ебическими требованиями («86 ГБ памяти хватит всем!»); 3) Java EE, которая суть Java SE с дополнительными библиотеками для так называемых серверов приложений (application servers). Бед у неё только две: 1) очень тяжелые и тормозные виртуальные машины, принципиально неоптимизируемые из-за косяков в спецификации языка; 2) многословность, превращающая даже самую простую утилитку для раздербанивания списка покупок в громадную кучу AbstractSingletonFactoryProxyBean-ов. Алсо, её хвалёная кроссплатформенность — это миф, C++ и C имеют компиляторы под такие кофемолки, на которые ВМ Java в принципе не влезет.

> Obj-C


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

> C#/.NET


> для написания крупных и корпоративных приложений


И опять нет. C# и вообще весь .NET — это платформа для написания программ общего назначения. Была запилен как замена для Java (потому что у Java есть фатальный недостаток, Луркоморье тебе в помощь). Минусов два: 1) виртуальная машина (хоть и шустрая); 2) нормальная инфраструктура есть только под сперму. Впрочем, если не нужны шибко развесистые GUI и ограничиваться только десктопом, то имеющейся инфраструктуры хватит с головой.

А PHP — говно ссаное, да.
#37 #420159
>>419997
>>420143
Сука, бомбануло так, что решил угробить себе жизнь, зашкворившись об ваш клуб PHP-шников.

> есть серверные


> Ruby, Python


Нет. Это языки общего назначения. Можно использовать как замену PHP на сервере, так и на клиенте. Можно автоматизировать простенькие задачи, типа массового переименования файлов (собственно, Ruby для этого и проектировался изначально). У них только две беды: 1) они динамически типизированы; 2) под них есть только интерпретаторы. На самом деле, это гибридные интерпретаторы, так называемые виртуальные машины, но от этого скорости исполнения не прибавляется, и не исчезает необходимость ставить эту самую виртуальную машину.

> C++


> языки для десктопных приложений


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

> есть мало где использующиеся языки типа Си


Сука, вторично бомбануло. Анончик ниже правильно ссылку дал, C был, есть и будет самым распространённым языком в мире. Есть компиляторы в высокооптимизированный машинный код практически подо всё, что может включаться. Так что это самый кроссплатформенный язык на планете («write once, compile everywhere»). У него только две беды: 1) семантически он довольно близок к Ассемблеру; 2) у него хуёвые средства абстракции. Вместе эти две беды делают его непригодным ни для чего, кроме прошивок для микроконтроллеров, ядер операционок и низкоуровневых библиотек расширения других ЯП. Собственно, он и создавался Керниганом и Ритчи как язык для написания операционных систем. Нет, на нем можно, конечно, написать и гуёвину и даже серверное приложение (и запускать его через FCGI или unix domain sockets), но написание на нем очень быстро превращается в жонглирование указателями и segmentation fault-ами. Даже быстрее, чем на C++. Алсо, так как он семантически близок к Ассемблеру, скомпилированные программы получаются предельно производительными. Если уметь.

> Java


> для мобильных приложений


Анус твой — для мобильных приложений! Java выпускается в трех редакциях: 1) Java ME, которая действительно нужна только для мобилок; 2) Java SE, которая есть платформа общего назначения, но на которой в силу её недостатков можно писать только кровавый энтерпрайз с ебическими требованиями («86 ГБ памяти хватит всем!»); 3) Java EE, которая суть Java SE с дополнительными библиотеками для так называемых серверов приложений (application servers). Бед у неё только две: 1) очень тяжелые и тормозные виртуальные машины, принципиально неоптимизируемые из-за косяков в спецификации языка; 2) многословность, превращающая даже самую простую утилитку для раздербанивания списка покупок в громадную кучу AbstractSingletonFactoryProxyBean-ов. Алсо, её хвалёная кроссплатформенность — это миф, C++ и C имеют компиляторы под такие кофемолки, на которые ВМ Java в принципе не влезет.

> Obj-C


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

> C#/.NET


> для написания крупных и корпоративных приложений


И опять нет. C# и вообще весь .NET — это платформа для написания программ общего назначения. Была запилен как замена для Java (потому что у Java есть фатальный недостаток, Луркоморье тебе в помощь). Минусов два: 1) виртуальная машина (хоть и шустрая); 2) нормальная инфраструктура есть только под сперму. Впрочем, если не нужны шибко развесистые GUI и ограничиваться только десктопом, то имеющейся инфраструктуры хватит с головой.

А PHP — говно ссаное, да.
#38 #420166
>>420052

>Во-во. Я бы C советовал.


Оче толсто.
>>420059

>Во-первых, есть Node и Node-Webkit.


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

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


Ну тащем-то да, Ctrl+Shift+I и вперед, наверное, самый оптимальный вариант.

>В-третьих, чтобы выводить что-то в канвас или в какой-нибудь элемент с textContent, никаких знаний хтмл не нужно вообще.


Как минимум нужно знать, что этот твой канвас существует, что на него можно что-то выводить и т.д.
#39 #420167
>>420159
А когда я в прикрепленном треде спрашивал подобное расписать по всем языкам, то никто не ответил. Зато он пхп тред мониторит, ты посмотри на него, причем похоже только что бы макать других в говно, плюс

>А PHP — говно ссаное, да.


вот без этого конечно никуда. Больше нечего было сказать? Или не можешь?
#40 #420176
>>420159

>А PHP — говно ссаное, да.



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

>>420005

Если я освою джаваскрипт, а потом захочу обычную джаву освоить, мне будет легче, чем если бы я с нуля сразу джаву начал?
Не ругайтесь, если сморозил глупость, я ньюфаг просто и вообще из вёрстка-треда.
#41 #420177
>>420167
Одно дело промолчать, другое дело — написать хуйню. В первом случае ньюфаг может, наконец, перестать маяться хуйнёй, заказывая консалтинг на Харкаче (!), и начать изучать самому (ведь ему всё равно придётся, если он действительно решил изучить ремесло программиста); во-втором случае будет страдать сам, забивая гвозди микроскопом, и компенсировать свои страдания, заставляя других забивать гвозди так же.
sage #42 #420180
>>420177

> Одно дело промолчать, другое дело — написать хуйню. В первом случае ньюфаг может, наконец, перестать маяться хуйнёй, заказывая консалтинг на Харкаче (!), и начать изучать самому


всё верно
#43 #420181
>>420177
начнет изучать сам
self-fix
#44 #420206
Я впервые в треде. Просто хотел сказать, что у вас очень ламповая шапка. Если бы треды были домами, я бы остался жить у вас.
#45 #420212
>>420166

> Delphi,


Pascal изначально был придуман для обучения, а не для реализации каких-то практических задач. Дельфи устарел лет 15 назад и нигде кроме бывшего СССР не был попуоярен. Не советую тратить на него время.
#46 #420213
>>420212

Ну и вдобавок, дельфи намертво завязан на WinAPI как я понимаю. Используйте лучше С++/Qt если не боитесь c++
#47 #420216
>>420212
Лол. Ты сам до этого додумался, или повторяешь за всеми мантру "делфи нинужон!11"?
119 Кб, 795x576
#48 #420229
Пробую сделать вот эту игру (пик) , ну конечно без такой вот оболочки, просто написать её и чтобы просто в виде таблицы 10х10 отображало доску и положение игроков на ней после каждого хода, так вот, у меня некоторые проблемы с выходом из цикла в случае победы одного из игроков, цикл продолжается после того как один из игроков уже стал победителем и второй при совпадении может тоже стать победителем( этого быть не должно). И главная проблема с выводом на экран таблицы, создал сам массив с клетками (может не надо было двумерный можно наверное было обойтись и одномерным) не пойму как влепить в него позиции игроков для отображения - собственно сам код http://ideone.com/DISjEo
sage #49 #420254
>>420212

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


Проиграл с толстяка.
#50 #420294
>>420144

>Если ты дошел только до регулярок то этого мало вообще-то.


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

>Надо бы пройти учебник до конца + решить пару доплоьнительных задач тогда у тебя будет гораздо больше практики и навыков.


Да, надо. Плюс еще очень много чего нужно сделать. А как я могу показывать вам сложные и большие задачи если они уже не влазят в 1 файл (на ideone), значит время регаться на гитхабе и учиться им пользоваться?
#51 #420316
>>419992
>>419758

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

По базе данных:

> `sex` varchar(4) COLLATE utf8_unicode_ci DEFAULT NULL,


Погугли по слвоам MySQL ENUM

Также, почитай какие есть типы колонок в MySQL:

http://phpclub.ru/mysql/doc/column-types.html (рус, кратко)
http://dev.mysql.com/doc/refman/5.6/en/data-types.html (англ, подробно)

> `groupindex` int(11) DEFAULT NULL,


Номер группы не надо делать числом, вдруг будет группа 2106M или 212-20?

> `birthdate` int(11) DEFAULT NULL,


Тут надо использовать более подходящий тип

Обычно в базе с помощью NOT NULL помечают обязательные поля, а DEFAULT NULL - те, которые можно не заполнять. У тебя все почему-то помечены как необязательные.

По коду:

Каждый класс должен быть в своем файле, и в это файле не должно быть ничего постороннего. Классы пишутся с большой буквы, и файл должен называться как и класс: Student -> Student.php. Файлы классов можно положить в папку с названием app или lib.

Вот такого быть не должно:

> $isRegistered = "<a href='register.php' class=\"navigation\">Зарегистрироваться</a>";


Весь HTML-код должен быть помещен в шаблоны, как описано тут: http://www.phpinfo.su/articles/practice/shablony_v_php.html

Файлы шаблонов стоит называть с расширением .phtml, .php или .tpl и поместить в отдельную папку templates.

> if(isset($_COOKIE['studentscookie']['name'])){


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

$id = getUserId( );
if ($id) ...

Работу с БД надо вынести в отдельный класс или функции. Чтобы SQL-код не был размазан по всему приложению, а находился в одном месте. Чтобы можно было написать что-то вроде

$students = $mapper->find($text);

Для поиска студентов по строке текста. Или хотя бы так:

$students = findStudents($text);

Вот мой урок про способы работы с базой данных: https://gist.github.com/codedokode/c4cbc4d7dc8e45ea074a (он может быть сложным для начинающего, что поделать).

> WHERE name LIKE '%$search%'


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

> header('Location: http://www.students.ru/profile.php');


Лучше не вписывать имя хоста явно, а вынести в конфиг или брать из $_SERVER['HTTP_HOST']

> try{


> $DBH= new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);


Лучше сделать функцию типа getPdo(). Также, try/catch тут не нужен, при ошибке текст исключения и так выведется если включено display_errors. Вот если что мой урок про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

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

В общем, давай пока с этим разберемся, а дальше посмотрим. Если есть вопросы, задавай, если все ясно, пиши код.
#51 #420316
>>419992
>>419758

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

По базе данных:

> `sex` varchar(4) COLLATE utf8_unicode_ci DEFAULT NULL,


Погугли по слвоам MySQL ENUM

Также, почитай какие есть типы колонок в MySQL:

http://phpclub.ru/mysql/doc/column-types.html (рус, кратко)
http://dev.mysql.com/doc/refman/5.6/en/data-types.html (англ, подробно)

> `groupindex` int(11) DEFAULT NULL,


Номер группы не надо делать числом, вдруг будет группа 2106M или 212-20?

> `birthdate` int(11) DEFAULT NULL,


Тут надо использовать более подходящий тип

Обычно в базе с помощью NOT NULL помечают обязательные поля, а DEFAULT NULL - те, которые можно не заполнять. У тебя все почему-то помечены как необязательные.

По коду:

Каждый класс должен быть в своем файле, и в это файле не должно быть ничего постороннего. Классы пишутся с большой буквы, и файл должен называться как и класс: Student -> Student.php. Файлы классов можно положить в папку с названием app или lib.

Вот такого быть не должно:

> $isRegistered = "<a href='register.php' class=\"navigation\">Зарегистрироваться</a>";


Весь HTML-код должен быть помещен в шаблоны, как описано тут: http://www.phpinfo.su/articles/practice/shablony_v_php.html

Файлы шаблонов стоит называть с расширением .phtml, .php или .tpl и поместить в отдельную папку templates.

> if(isset($_COOKIE['studentscookie']['name'])){


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

$id = getUserId( );
if ($id) ...

Работу с БД надо вынести в отдельный класс или функции. Чтобы SQL-код не был размазан по всему приложению, а находился в одном месте. Чтобы можно было написать что-то вроде

$students = $mapper->find($text);

Для поиска студентов по строке текста. Или хотя бы так:

$students = findStudents($text);

Вот мой урок про способы работы с базой данных: https://gist.github.com/codedokode/c4cbc4d7dc8e45ea074a (он может быть сложным для начинающего, что поделать).

> WHERE name LIKE '%$search%'


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

> header('Location: http://www.students.ru/profile.php');


Лучше не вписывать имя хоста явно, а вынести в конфиг или брать из $_SERVER['HTTP_HOST']

> try{


> $DBH= new PDO("mysql:host=$host;dbname=$dbname", $user, $pass);


Лучше сделать функцию типа getPdo(). Также, try/catch тут не нужен, при ошибке текст исключения и так выведется если включено display_errors. Вот если что мой урок про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

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

В общем, давай пока с этим разберемся, а дальше посмотрим. Если есть вопросы, задавай, если все ясно, пиши код.
#52 #420317
>>420151

Это индекс по числу упоминаний в гугле: http://www.tiobe.com/index.php/content/paperinfo/tpci/programminglanguages_definition.html

Причем там много странностей:

Поиск в ютубе для С дает 682000, а PHP 640 000 результатов
Поиск в Гугле для С дает 93M результатов, для PHP 157M.

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

Ну и плюс:

> Yandex: SOURCES_NOT_PARSABLE



В общем, странный индекс.

>>420159

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

> Это языки общего назначения.


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

> под них есть только интерпретаторы


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

Кстати, для PHP есть JIT интерпретатор — HipHop VM. Понятно, что динамические языки компилировать бесползено, а вот JIT подход позволяет неплохо их ускорить — например Гугл ускорил JS за счет JIT в v8.

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


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

> Анус твой — для мобильных приложений!


Я упомянул ее еще в ентерпайзных приложениях. А под мобильными я имел в виду конечно не давно умерший ME, а Android.

> Бед у неё только две: 1) очень тяжелые и тормозные виртуальные машины


Тяжелые они только в том плане что медленно запускаются (что для серверных приложений нормально), а работают они нормально: https://www.techempower.com/benchmarks/ при том что в яве есть и JIT и умные сборщики мусора и инструменты для профайлинга и анализа.

(заметь там в топе С++, а не Си. Потому что что-то сложнее лабы1 написать на Си нереально. Вот вконтактовцы писали — и на это больно смотреть: https://github.com/vk-com/kphp-kdb )

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


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

> Минусов два: 1) виртуальная машина


Ты опять скатываешься в байтолюбство. Насколько я понимаю, с VM там код получается компактнее, надежнее (никаких проблем с указателями, а ведь писать корпоративный софт будут миллионы индусов) и переносимее, а для MS это важно так как проданный проприетарный код никто не будет перекомпилировать под новые платформы.
#52 #420317
>>420151

Это индекс по числу упоминаний в гугле: http://www.tiobe.com/index.php/content/paperinfo/tpci/programminglanguages_definition.html

Причем там много странностей:

Поиск в ютубе для С дает 682000, а PHP 640 000 результатов
Поиск в Гугле для С дает 93M результатов, для PHP 157M.

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

Ну и плюс:

> Yandex: SOURCES_NOT_PARSABLE



В общем, странный индекс.

>>420159

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

> Это языки общего назначения.


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

> под них есть только интерпретаторы


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

Кстати, для PHP есть JIT интерпретатор — HipHop VM. Понятно, что динамические языки компилировать бесползено, а вот JIT подход позволяет неплохо их ускорить — например Гугл ускорил JS за счет JIT в v8.

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


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

> Анус твой — для мобильных приложений!


Я упомянул ее еще в ентерпайзных приложениях. А под мобильными я имел в виду конечно не давно умерший ME, а Android.

> Бед у неё только две: 1) очень тяжелые и тормозные виртуальные машины


Тяжелые они только в том плане что медленно запускаются (что для серверных приложений нормально), а работают они нормально: https://www.techempower.com/benchmarks/ при том что в яве есть и JIT и умные сборщики мусора и инструменты для профайлинга и анализа.

(заметь там в топе С++, а не Си. Потому что что-то сложнее лабы1 написать на Си нереально. Вот вконтактовцы писали — и на это больно смотреть: https://github.com/vk-com/kphp-kdb )

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


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

> Минусов два: 1) виртуальная машина


Ты опять скатываешься в байтолюбство. Насколько я понимаю, с VM там код получается компактнее, надежнее (никаких проблем с указателями, а ведь писать корпоративный софт будут миллионы индусов) и переносимее, а для MS это важно так как проданный проприетарный код никто не будет перекомпилировать под новые платформы.
#53 #420319
>>420176

> Если я освою джаваскрипт, а потом захочу обычную джаву о


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

>>420206

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

>>420229

> return $this->isWinner = 1;


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

> while ($player->isWinner == 0) {


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

бесконечно повторять {
для каждого игрока {
- сделать ход
- если игрок победил, выходим из функции
}
}

Вот и PHP тебе говорит про ошибку внизу:

> PHP Notice: Undefined variable: player in /home/tqO7cS/prog.php on line 132



> return $player->name;


> break;


return выходит из функции (и из цикла соответственно) так что break не нужен.

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


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

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

В этом случае правда символ игрока заменит цифру, которая в клеточке, это годится? Если нет то можно клеточку с игроком сделать строкой вида 45(#)

> foreach (range($x 10 + 1, $x 10 + 10) as $point) {


Ерунда какая-то. Почему нельзя сделать цикл по j от 0 до 9? И зачем ты кладешь цифры

> unset($line);


Лучше класть в line пустой массив
#53 #420319
>>420176

> Если я освою джаваскрипт, а потом захочу обычную джаву о


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

>>420206

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

>>420229

> return $this->isWinner = 1;


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

> while ($player->isWinner == 0) {


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

бесконечно повторять {
для каждого игрока {
- сделать ход
- если игрок победил, выходим из функции
}
}

Вот и PHP тебе говорит про ошибку внизу:

> PHP Notice: Undefined variable: player in /home/tqO7cS/prog.php on line 132



> return $player->name;


> break;


return выходит из функции (и из цикла соответственно) так что break не нужен.

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


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

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

В этом случае правда символ игрока заменит цифру, которая в клеточке, это годится? Если нет то можно клеточку с игроком сделать строкой вида 45(#)

> foreach (range($x 10 + 1, $x 10 + 10) as $point) {


Ерунда какая-то. Почему нельзя сделать цикл по j от 0 до 9? И зачем ты кладешь цифры

> unset($line);


Лучше класть в line пустой массив
#54 #420321
>>420229

А, я понял, зачем ты кладешь цифры в массив. Так подписаны клеточки. Все равно, заполнять лучше без range, а примерно так:

для i от 0 до 9 {
для j от 0 до 9 {
k = посчитать номер клеточки;
положить k в массив;
}
}

>>420254

Проиграй еще и с википедии: https://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D1%81%D0%BA%D0%B0%D0%BB%D1%8C_(%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)

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

>>420294

> время регаться на гитхабе и учиться им пользоваться?


Да. Есть книга по гиту: http://git-scm.com/book/ru/v1

А гитхаб это лишь публичный git репозиторий для проектов.

Ты наверно сейчас тогда будешь калькулятор и задачи на ООП делать? Если что-то непонятно, покажи код и задай вопрос или попроси подсказку.
#54 #420321
>>420229

А, я понял, зачем ты кладешь цифры в массив. Так подписаны клеточки. Все равно, заполнять лучше без range, а примерно так:

для i от 0 до 9 {
для j от 0 до 9 {
k = посчитать номер клеточки;
положить k в массив;
}
}

>>420254

Проиграй еще и с википедии: https://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D1%81%D0%BA%D0%B0%D0%BB%D1%8C_(%D1%8F%D0%B7%D1%8B%D0%BA_%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)

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

>>420294

> время регаться на гитхабе и учиться им пользоваться?


Да. Есть книга по гиту: http://git-scm.com/book/ru/v1

А гитхаб это лишь публичный git репозиторий для проектов.

Ты наверно сейчас тогда будешь калькулятор и задачи на ООП делать? Если что-то непонятно, покажи код и задай вопрос или попроси подсказку.
!xnn2uE3AU. #55 #420322
http://habrahabr.ru/post/246905/

> Почему вам НЕ стоит использовать AngularJs



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

С другой стороны, у него удобный синтаксис. Я подумал, может кто-то хочет попробовать сделать шаблонизатор с дата-байнлингом с синтаксисом ангулара, при этом выкинув все остальное, что там навязывается в довесок? То есть все эти их сервисы, контроллеры, наследованием скоупов и сами скоупы? Этакий knockout c синтаксисом ангулара, не фреймворк а просто шаблонизатор, который можно использовать сам по себе или вместе с Backbone. Назовем его например Bracketed. Заодно исправим все упомянутые в статье недостатки.

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

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

Мне кажется то, что получится, могло бы быть вполне популярно при дложном пиаре.
#56 #420339
В джавасриптаче никто не подсказал, может, у вас получится, хотя и не совсем в сторону PHP.

У меня есть форма, к которой я перед отправкой с помощью JS добавляю скрытые поля с доп. данными, так: <input type="hidden" name="field_array[]" value="name">; на странице есть список, я прохожу по нему циклом и на каждой итерации добавляю вот это скрытое поле.

Но теперь у меня появилась необходимость для каждого такого элемента списка добавлять не одно значение, а 3, они у меня закреплены у элемента списка атрибутом data-value, но это, наверное, можно как–то иначе сделать. То есть, нужно уже не одно скрытое поле добавлять, а три, и так, чтобы они были связаны друг с другом при получении на сервере, как это сделать?

Например, вот добавлял я на каждой итерации цикла инпут с названием кино (где атрибут value="название_кино"), а теперь нужно название, имя режиссёра и год выпуска. Таким образом, должен получиться двумерный массив или вроде того.

Спасибо!
#57 #420340
>>420322

Я слышал, что когда–то должен выйти Ангъюлар 2 и он очень сильно будет отличаться от оригинального, настолько, что даже знания по первому мало пригодятся, считай, новый фреймворк.
#58 #420367
>>420216
Это паста, причем старая.
#59 #420369
>>420339
Звучит как то сложно. С наскоку вижу только добавлять все это дело единой строкой в value, а потом обратно распарсивать на отдельные элементы.
#60 #420375
>>420369

Я об этом подумал, но это какая–то идиотия. А что сложно, в смысле, что я делаю что–то не то и должен быть какой–то более простой способ передать доп. данные на сервер вместе с формой?
sage #61 #420392
>>420375
это рнр, детка
#62 #420398
>>420317

> индекс по числу упоминанй в гугле


> Поиск в Гугле для С дает 93M результатов, для PHP 157M.


Это говорит о том, что пыходауны чаще остальных практикуют GDD (Google-driven development).

На количество кода на конкретном ЯП тоже смотреть бессмысленно, потому что больше всего кода до сих пор написано на COBOL.

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

> PHP


> высоконагруженных


> масштабируемых


Вот тут я просрался по полной. Пиздуй читать, как «масштабировали» ВКонтакте, и как разрабатывается Google. А Википедия вообще высоконагруженным проектом не является.

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


И не удивляйся. Чем тупее и ленивее человек, тем выше вероятность, что он возьмет что попроще и спросит у кого-нибудь конкретный вопрос, вместо того чтобы читать доки самому. Я также не удивлюсь, если http://php.net/manual/en/ никто из этого треда в глаза не видел.

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


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

> Ты любитель переставлять байты [без «не»?]? Тогда ты изначально загоняешь себя в рамки требованием к похожести на Си.


Логика уровня PHP-треда. Нет, спасибо, я предпочитаю OCaml.

> Php не компилируется и это не мешает создавать на нем гостевухи.


Поправил. Алсо, как одно соотносится с другим?

> Кстати, для PHP есть JIT интерпретатор…


Я сравнивал ЯП с точностью до наличия JIT-ирующих VM и компиляторов. И да, HipHop VM положение не спасает (погугли, по-моему, им удалось ускорить выполнение всего лишь где-то в 2 раза, плюс HHVM JIT справляется только с каким-то подмножеством PHP, в остальном сваливается в обычную интерпретацию), потому что семантика PHP многократно уёбищнее семантики Java.

А YARV даже JIT-ить не пришлось.

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


…Если речь не идет о highload.

> Тяжелые они [VM Java]


…потому, что жрут много памяти. Пидорасы из Sun и Oracle предпочли послать нахуй менеджер памяти ядра, тупо отхавав у него максимум RAM, и перевелосипедить свой менеджер памяти со сборщиком мусора и шлюхами. Алсо, уже на старте в память грузится просто ебическое количество классов и ресурсов.

> Это есть, да, но она все же лаконичнее чем ее предшественник Си++.


Нет. У Java средства абстракции по гибкости примерно как у C. Просто для пидорения scalable robust yoba enterprise solutions этих средств зачастую достаточно (ибо enterprise solutions сами по себе есть примитивные CRUD-ы, просто очень большие). Но если вылезать за рамки use case-ов, предусмотренных Sun и Oracle, начинается ад, боль и унижение.

> ради более удобного синтаксиса там делаются языки поверх JVM вроде Скалы.


Получается CCAHNHA, которая сворачивает голову JIT и выдает перлы вроде выбрасывания исключения при выполнении return из лямбды. JVM, в отличие от .NET, заточена только и исключительно под Java, и любая попытка скомпилировать в байткод JVM что-то, отличное от «public static cherez static» или «AbstractSingletonFactoryProxyBean» приводит к длиннющей лапше опкодов, после JIT-а не укладывающихся ни в какой кеш и ссущих на голову branch predictor-у.

> C#


> Насколько я понимаю, с VM там [в C#] код получается <…> переносимее


В теории — да, как и у Oracle. На практике переносимость получилась еще хуже, чем у Oracle — только в пределах семейства ШИНДОШС. То есть, это даже не все десктопы.
#62 #420398
>>420317

> индекс по числу упоминанй в гугле


> Поиск в Гугле для С дает 93M результатов, для PHP 157M.


Это говорит о том, что пыходауны чаще остальных практикуют GDD (Google-driven development).

На количество кода на конкретном ЯП тоже смотреть бессмысленно, потому что больше всего кода до сих пор написано на COBOL.

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

> PHP


> высоконагруженных


> масштабируемых


Вот тут я просрался по полной. Пиздуй читать, как «масштабировали» ВКонтакте, и как разрабатывается Google. А Википедия вообще высоконагруженным проектом не является.

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


И не удивляйся. Чем тупее и ленивее человек, тем выше вероятность, что он возьмет что попроще и спросит у кого-нибудь конкретный вопрос, вместо того чтобы читать доки самому. Я также не удивлюсь, если http://php.net/manual/en/ никто из этого треда в глаза не видел.

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


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

> Ты любитель переставлять байты [без «не»?]? Тогда ты изначально загоняешь себя в рамки требованием к похожести на Си.


Логика уровня PHP-треда. Нет, спасибо, я предпочитаю OCaml.

> Php не компилируется и это не мешает создавать на нем гостевухи.


Поправил. Алсо, как одно соотносится с другим?

> Кстати, для PHP есть JIT интерпретатор…


Я сравнивал ЯП с точностью до наличия JIT-ирующих VM и компиляторов. И да, HipHop VM положение не спасает (погугли, по-моему, им удалось ускорить выполнение всего лишь где-то в 2 раза, плюс HHVM JIT справляется только с каким-то подмножеством PHP, в остальном сваливается в обычную интерпретацию), потому что семантика PHP многократно уёбищнее семантики Java.

А YARV даже JIT-ить не пришлось.

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


…Если речь не идет о highload.

> Тяжелые они [VM Java]


…потому, что жрут много памяти. Пидорасы из Sun и Oracle предпочли послать нахуй менеджер памяти ядра, тупо отхавав у него максимум RAM, и перевелосипедить свой менеджер памяти со сборщиком мусора и шлюхами. Алсо, уже на старте в память грузится просто ебическое количество классов и ресурсов.

> Это есть, да, но она все же лаконичнее чем ее предшественник Си++.


Нет. У Java средства абстракции по гибкости примерно как у C. Просто для пидорения scalable robust yoba enterprise solutions этих средств зачастую достаточно (ибо enterprise solutions сами по себе есть примитивные CRUD-ы, просто очень большие). Но если вылезать за рамки use case-ов, предусмотренных Sun и Oracle, начинается ад, боль и унижение.

> ради более удобного синтаксиса там делаются языки поверх JVM вроде Скалы.


Получается CCAHNHA, которая сворачивает голову JIT и выдает перлы вроде выбрасывания исключения при выполнении return из лямбды. JVM, в отличие от .NET, заточена только и исключительно под Java, и любая попытка скомпилировать в байткод JVM что-то, отличное от «public static cherez static» или «AbstractSingletonFactoryProxyBean» приводит к длиннющей лапше опкодов, после JIT-а не укладывающихся ни в какой кеш и ссущих на голову branch predictor-у.

> C#


> Насколько я понимаю, с VM там [в C#] код получается <…> переносимее


В теории — да, как и у Oracle. На практике переносимость получилась еще хуже, чем у Oracle — только в пределах семейства ШИНДОШС. То есть, это даже не все десктопы.
#63 #420408
>>420321
>>420319
http://ideone.com/DL57oA вот переделал, это правда не задача ОПа
#64 #420409
>>420375
Я не понимаю до конца что у тебя за страница, но полагаю самым правильном данном случае создать силами твоего же скрипта на основе анализа списка нормальный json и отправить его серверу. Ну то есть создать массив, в нем хранить элементы списка, соответсвенно отслеживать изменение списка, как то так.
#65 #420414
>>420398

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


Ну так хуле, чем в итоге будем измерять ЯП? Попугаями?
#66 #420441
>>420409

Да, про json я и забыл, ладно, спасибо, поковыряюсь там с этим.

>>420392

Ну прости, я уже даже не знаю, кому эту парашу принести.
#67 #420451
>>420441
Ты не понял. Он решил, что ты тут с пхп гавном разбираешься и на автомате унизил с сажей. Это залетный пидор из хаскель треда, он тут часто появляется.
#68 #420504
>>420339

Добавляй по 3 поля с номерами чтобы их связать, в чем проблема?

input director[0] = 'Кубрик'
input name[0] = 'Одиссея'
input year[0] = '2004'
input director[1] = 'Лукас'
...

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

Алсо еще вариант закодировать все это в JSON и слать одним полем.

>>420392

При чем тут PHP? При использовании другого серверного языка вроде Си++ решение потребует меньше кода?

>>420398

> Это говорит о том, что пыходауны чаще остальных практикуют GDD


Ты же сам этот тест на основе гугла и привел в пример, а теперь отрицаешь этот подход. Ну ты смешной.

> больше всего кода до сих пор написано на COBOL.


Пруф? По моему это городская легенда.

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


Тогда веб языки будут в огромном перевесе. Ибо на 1 Си++ программиста приходится человек 50-100 из веба.

> Пидорасы из Sun и Oracle предпочли послать нахуй менеджер памяти ядра, тупо отхавав у него максимум RAM, и перевелосипедить свой менеджер памяти со сборщиком мусора и шлюхами


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

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

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

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


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

> У Java средства абстракции по гибкости примерно как у C.


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

Да и еще, как я понимаю, в Си толком не работает автодополнение и навигация по коду, кроме может быть каких-нибудь платных IDE, так как там синтаксис к этому не располагает.

Ну и еще там есть препроцессор для отстреливания себе ног.

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

> scalable robust yoba enterprise solutions


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

Ну а слои абстракции и SOA появляются из-за нежелания разбираться в коде предшественников.

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

> на голову branch predictor-у.


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

Ну и еще раз напомню что тут https://www.techempower.com/benchmarks/ в тесте, имитирующем аспекты работы реального веб приложения, Ява занимает со 2 по 7 место (отставая от 1 места лишь на 15%). Вполне неплохо.
#68 #420504
>>420339

Добавляй по 3 поля с номерами чтобы их связать, в чем проблема?

input director[0] = 'Кубрик'
input name[0] = 'Одиссея'
input year[0] = '2004'
input director[1] = 'Лукас'
...

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

Алсо еще вариант закодировать все это в JSON и слать одним полем.

>>420392

При чем тут PHP? При использовании другого серверного языка вроде Си++ решение потребует меньше кода?

>>420398

> Это говорит о том, что пыходауны чаще остальных практикуют GDD


Ты же сам этот тест на основе гугла и привел в пример, а теперь отрицаешь этот подход. Ну ты смешной.

> больше всего кода до сих пор написано на COBOL.


Пруф? По моему это городская легенда.

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


Тогда веб языки будут в огромном перевесе. Ибо на 1 Си++ программиста приходится человек 50-100 из веба.

> Пидорасы из Sun и Oracle предпочли послать нахуй менеджер памяти ядра, тупо отхавав у него максимум RAM, и перевелосипедить свой менеджер памяти со сборщиком мусора и шлюхами


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

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

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

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


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

> У Java средства абстракции по гибкости примерно как у C.


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

Да и еще, как я понимаю, в Си толком не работает автодополнение и навигация по коду, кроме может быть каких-нибудь платных IDE, так как там синтаксис к этому не располагает.

Ну и еще там есть препроцессор для отстреливания себе ног.

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

> scalable robust yoba enterprise solutions


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

Ну а слои абстракции и SOA появляются из-за нежелания разбираться в коде предшественников.

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

> на голову branch predictor-у.


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

Ну и еще раз напомню что тут https://www.techempower.com/benchmarks/ в тесте, имитирующем аспекты работы реального веб приложения, Ява занимает со 2 по 7 место (отставая от 1 места лишь на 15%). Вполне неплохо.
#69 #420505
>>420398

Ах да, насчет этого твоего Си. Говорят большие проекты вроде Фаерфокса, вебкита или Опенофиса надо несколько дней компилировать? Как в таких условиях вообще заниматься разработкой?
#70 #420509

>>420408

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

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

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

Если ты сделаешь вывод в несколько строк, то надо будет наверно сделать несколько функций вроде вывестиПервуюСтрочку, вывестиВторуюСтрочку.

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

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

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

$jumps = array(
array('from' => 10, 'to' => 16),
...
);

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

> $this->x = 2;


> $this->y = 4;


> $this->position = 42;


Как я понимаю, position вычисляется из x и y? Если так, незачем вообще хранить это свойство, надо сделать метод getPosition который будет ее считать. Запомни: меньше свойств — меньше геморроя с их обновлением.

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

Ну вот пример, как эту функцию можно сделать короче:

move() {
step = случайное число;
сдвинутьсяНа(step);
}

сдвинутьсяНа(step) {
увеличить x;
если x переполнился, увеличить y;
если (карта->можноСделатьпереход) {
сделатьПереход;
}
}

> $zone[$i][$j] = $k++;


Это ненадежно. Лучше вычислять k из i и j.

Если что-то непонятно, справшивай. Если понятно, пиши код.
#70 #420509

>>420408

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

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

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

Если ты сделаешь вывод в несколько строк, то надо будет наверно сделать несколько функций вроде вывестиПервуюСтрочку, вывестиВторуюСтрочку.

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

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

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

$jumps = array(
array('from' => 10, 'to' => 16),
...
);

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

> $this->x = 2;


> $this->y = 4;


> $this->position = 42;


Как я понимаю, position вычисляется из x и y? Если так, незачем вообще хранить это свойство, надо сделать метод getPosition который будет ее считать. Запомни: меньше свойств — меньше геморроя с их обновлением.

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

Ну вот пример, как эту функцию можно сделать короче:

move() {
step = случайное число;
сдвинутьсяНа(step);
}

сдвинутьсяНа(step) {
увеличить x;
если x переполнился, увеличить y;
если (карта->можноСделатьпереход) {
сделатьПереход;
}
}

> $zone[$i][$j] = $k++;


Это ненадежно. Лучше вычислять k из i и j.

Если что-то непонятно, справшивай. Если понятно, пиши код.
#71 #420510
>>420408

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

Вот хороший рецепт (как должен выглядеть код):

- налить в кастрюлю литр воды
- положить 200 гр мяса
- насыпать ложку соли
...

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

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

То есть надо уметь разбивать большие поледовательности команд на шаги, и выносить подробности в отдельные функции.
#73 #420538
Прохожу курсы на кодакадемии. Нихера не понятно. Вот поясните, что делает этот кусок кода? http://jsfiddle.net/cx5mmvrr/
Во-первых, friends - это же объект. А bill и steve, получается - свойства объекта? Но что же тогда firstName и lastName? Свойства свойств? И что делает функция list? Я не понимат. Я вообще не понимат, что делает in в for. Может кто доступно объяснить?
#74 #420541
>>420538

>Но что же тогда firstName и lastName? Свойства свойств?


Почему бы и нет?
#75 #420544
>>420538

>А bill и steve, получается - свойства объекта?


yep

>Но что же тогда firstName и lastName? Свойства свойств?


yep

>Но что же тогда firstName и lastName? Свойства свойств?


выводит свойства friends

>Я вообще не понимат, что делает in в for


http://javascript.ru/for..in
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in
Воннаби #76 #420552
Задача на банкомат легким способом. Перед решением подумал, что она решается методом ветвей и границ, но так как я его оче плохо помню, то и сказать толком не могу. Вот после небольшого гугления начал делать простым жадным перебором: сначала выдаем наибольшие купюры, пока остаток не будет меньше чем купюра, переходим на купюру поменьше, и так далее.
http://deone.com/BlvWit
#77 #420557
Оп, я остановился на таком виде:
https://github.com/sqghub/TestHub/blob/master/migrations/m141219_140813_create_tables.php
Что думаешь?
#78 #420569
>>420504

> Ты же сам этот тест на основе гугла и привел в пример


Теги: ad hominem, нерепрезентативная выборка

> > больше всего кода до сих пор написано на COBOL.


> Пруф?


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

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


Верю. Ибо ебанутая эпоха тормозных веб-приложений.

> Ибо на 1 Си++ программиста приходится человек 50-100 из веба.


А это тут причем?

> Сервер не десктоп и лучше всего когда серверное приложение потребляет один и тот же объем памяти.


А если бы ты был чуть умнее и опытнее, то понимал бы, что если в конфиге (или, еще правильнее, в квотах) прописано «-Xmx:16GB», то это не значит, что JVM не будет потреблять больше 16 GB. Это значит, что она упадёт, если будет пробит потолок в 16 GB. К уёбищности аллокаторов и уебанству кодеров, не могущих объявить память как буфер, это не имеет никакого отношения.

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


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


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

> В Яве есть объекты, коллекции, куча библиотек и не надо описывать одну функцию в 2 файлах…


…и больше ничего.

> в Си толком не работает автодополнение и навигация по коду


Работает. В C++ и в динамически типизированных ЯП она невозможна в принципе.

> Не, Ява однозначно лучше.


…для scalable enterprise robust yoba solutions. Для пердоления драйверов C таки удобнее.

> > scalable robust yoba enterprise solutions


> Очевидно там есть свои проблемы


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

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


Я бы тоже не удивился, но оказывается, что нет. По закону Питера эти пидорасы идут в проджект-менеджеры. Даже не в тимлиды.

> Но на Си все это будет писать во много раз дольше, из-заотстутвия ООП


Нет. Из-за гуманитарного склада ума кодеров. А ООП можно реализовать в любом ЯП, полном по Тьюрингу (по крайней мере, его самое необходимое подмножество).

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


Если среда разработки не позволяет оптимизировать код на всех уровнях абстракции вплоть до использования кешей процессора, то это не среда, а слабанная в срочном порядке на коленке студентом-гуманитарием за еду или взятая с GitHub-оподобной помойки нахуяченная чисто из спортивного интереса, без всякой мысли о её сопровождении или вообще каком-либо использовании запускалка для софта.
#78 #420569
>>420504

> Ты же сам этот тест на основе гугла и привел в пример


Теги: ad hominem, нерепрезентативная выборка

> > больше всего кода до сих пор написано на COBOL.


> Пруф?


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

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


Верю. Ибо ебанутая эпоха тормозных веб-приложений.

> Ибо на 1 Си++ программиста приходится человек 50-100 из веба.


А это тут причем?

> Сервер не десктоп и лучше всего когда серверное приложение потребляет один и тот же объем памяти.


А если бы ты был чуть умнее и опытнее, то понимал бы, что если в конфиге (или, еще правильнее, в квотах) прописано «-Xmx:16GB», то это не значит, что JVM не будет потреблять больше 16 GB. Это значит, что она упадёт, если будет пробит потолок в 16 GB. К уёбищности аллокаторов и уебанству кодеров, не могущих объявить память как буфер, это не имеет никакого отношения.

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


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


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

> В Яве есть объекты, коллекции, куча библиотек и не надо описывать одну функцию в 2 файлах…


…и больше ничего.

> в Си толком не работает автодополнение и навигация по коду


Работает. В C++ и в динамически типизированных ЯП она невозможна в принципе.

> Не, Ява однозначно лучше.


…для scalable enterprise robust yoba solutions. Для пердоления драйверов C таки удобнее.

> > scalable robust yoba enterprise solutions


> Очевидно там есть свои проблемы


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

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


Я бы тоже не удивился, но оказывается, что нет. По закону Питера эти пидорасы идут в проджект-менеджеры. Даже не в тимлиды.

> Но на Си все это будет писать во много раз дольше, из-заотстутвия ООП


Нет. Из-за гуманитарного склада ума кодеров. А ООП можно реализовать в любом ЯП, полном по Тьюрингу (по крайней мере, его самое необходимое подмножество).

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


Если среда разработки не позволяет оптимизировать код на всех уровнях абстракции вплоть до использования кешей процессора, то это не среда, а слабанная в срочном порядке на коленке студентом-гуманитарием за еду или взятая с GitHub-оподобной помойки нахуяченная чисто из спортивного интереса, без всякой мысли о её сопровождении или вообще каком-либо использовании запускалка для софта.
#79 #420570
>>420505

> Ах да, насчет этого твоего Си. Говорят большие проекты вроде Фаерфокса, вебкита или Опенофиса надо несколько дней компилировать? Как в таких условиях вообще заниматься разработкой?


Компилируется только один раз. Потом просто перекомпилируются изменившиеся модули.
#80 #420572
>>420505

>несколько дней


Бред, полная сборка любого из названных тобой проектов на обычной домашней ЭВМ займёт не больше нескольких часов, не говоря уже о том, что билд-серверы куда мощнее обычных ПК и что по ходу разработки полностью проекты никто не пересобирает без особой необходимости.
!xnn2uE3AU. #81 #420575
>>420526

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

> После нажатия кнопки ваш код будет протестирован на правильность.



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

> Ваш код должен состоять из функции с именем sequence. Именно она будет тестироваться.



Или может добавить ссылку «как проверяется код» раскрывающую блок с пояснениями.

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

И я бы сделал сигнализацию об ошибках более явной — например добавил галочки/крестик перед пунктом при правильном/неправильном прохождении теста (это можно сделать даже css через generated content). А то не очень ясно что значит результат.

Для исключений хорошо бы выводить информацию о нем, а не просто «произошла какая-то ошибка»:

> encountered a declaration exception



В цифры 1 2 3 4 трудно попасть мышью, я бы добавил к ним невидимый паддинг справа/слева который тоже кликабелен и делает площадь ссылки больше. Чтобы было видно что паддинг относится к ссылке можно подсвечивать его при наведении.

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

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

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

Но вообще, очень хорошо сделано.
!xnn2uE3AU. #81 #420575
>>420526

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

> После нажатия кнопки ваш код будет протестирован на правильность.



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

> Ваш код должен состоять из функции с именем sequence. Именно она будет тестироваться.



Или может добавить ссылку «как проверяется код» раскрывающую блок с пояснениями.

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

И я бы сделал сигнализацию об ошибках более явной — например добавил галочки/крестик перед пунктом при правильном/неправильном прохождении теста (это можно сделать даже css через generated content). А то не очень ясно что значит результат.

Для исключений хорошо бы выводить информацию о нем, а не просто «произошла какая-то ошибка»:

> encountered a declaration exception



В цифры 1 2 3 4 трудно попасть мышью, я бы добавил к ним невидимый паддинг справа/слева который тоже кликабелен и делает площадь ссылки больше. Чтобы было видно что паддинг относится к ссылке можно подсвечивать его при наведении.

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

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

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

Но вообще, очень хорошо сделано.
#82 #420576
>>420575

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


Мы сделаем свой кодакадеми, с аниме и залетными с хаскельтреда?
#83 #420578
>>420526

А, еще, «неправильно» пишется слитно.

>>420538

В объекте (или хеше, словаре) можно хранить что угодно, в том числе другой объект. То есть свойством может быть не только число или строка, но и другой объект, массив, функция. Посмотри на такой код:

// делаем один объект
var person = { name: 'Ivan', age: 20 };

// делаем второй объект и помещаем внутрь него первый
var smth = { man: person };

// Делаем массив и помещаем внутрь него person
var arr = [ person ];

// обращаемся к разным полям так:
person.name
person['name']
smth.man.name
smth.man.age
arr[0].name
arr[0]['name']

Ну и хочу тебе посоветовать параллельно читать сайт learn.javascript.ru гле вроде неплохо все объясняетя. И могу также предложить свои задачки на JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0

Проверить первые 4 можно тут: http://dkab.github.io/jasmine-tests

> Я вообще не понимат, что делает in в for.


for .. in это цикл по всем свойствам объекта. Он выполняется столько раз сколько есть свойств у объекта (вложенные не считаютя, только свойства первого уровня так сказать), и в переменную firstName каждый раз кладется имя свойства. ну например

for (k in person) {
console.log(k);
}

Выведет 2 строки (не обязательно в том же порядке, порядок может быть любой):

name
age

> И что делает функция list?


Выводит ключи объекта friend, то есть bill и steve

Если на кодеакадеми непонятно, читай параллельно learn.javascript.ru
#83 #420578
>>420526

А, еще, «неправильно» пишется слитно.

>>420538

В объекте (или хеше, словаре) можно хранить что угодно, в том числе другой объект. То есть свойством может быть не только число или строка, но и другой объект, массив, функция. Посмотри на такой код:

// делаем один объект
var person = { name: 'Ivan', age: 20 };

// делаем второй объект и помещаем внутрь него первый
var smth = { man: person };

// Делаем массив и помещаем внутрь него person
var arr = [ person ];

// обращаемся к разным полям так:
person.name
person['name']
smth.man.name
smth.man.age
arr[0].name
arr[0]['name']

Ну и хочу тебе посоветовать параллельно читать сайт learn.javascript.ru гле вроде неплохо все объясняетя. И могу также предложить свои задачки на JS: https://gist.github.com/codedokode/ce30e7a036f18f416ae0

Проверить первые 4 можно тут: http://dkab.github.io/jasmine-tests

> Я вообще не понимат, что делает in в for.


for .. in это цикл по всем свойствам объекта. Он выполняется столько раз сколько есть свойств у объекта (вложенные не считаютя, только свойства первого уровня так сказать), и в переменную firstName каждый раз кладется имя свойства. ну например

for (k in person) {
console.log(k);
}

Выведет 2 строки (не обязательно в том же порядке, порядок может быть любой):

name
age

> И что делает функция list?


Выводит ключи объекта friend, то есть bill и steve

Если на кодеакадеми непонятно, читай параллельно learn.javascript.ru
#84 #420579
>>420552

> \twhile ($amount >= $nominal) {


> $amount -= $nominal;


Повторяющееся вычитание заменяется делением (а сложение — умножением), забыл?

Избавься от внутреннего цикла while.

> после небольшого гугления начал делать простым жадным перебором:


Для простого вариант его хватит. Для сложного гугли «задача сдача банкомат» или «задача о ранце»

>>420557

Ну норм. Я вижу ты Concrete TI реализовал? ну ок, давай посмотрим что выйдет.

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

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

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

Например для погрешности можно прокомментировать что это погрешность и в чем она задается — абсолютно или в процентах.

> name` VARCHAR(6500)


Издеваешься? Давай более реалистичное значение

> `added_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,


По моему по дефолту проставляется только колонка типа TIMESTAMP так как TIMESTAMP привязан к часовому поясу а DATETIME нет. Изучи-ка различия между TIMESTAMP и DATETIME.

> `allow_errors` BOOLEAN,


нужно добавлять NOT NULL DEFAULT X а то у тебя получается 3 значения для поля

> `type` INT(11) UNSIGNED NOT NULL,


Используй ENUM. Что-то у меня ощущение что ты плохо знаешь типы MySQL, перечитай-ка:

http://dev.mysql.com/doc/refman/5.0/en/data-types.html (англ)
http://phpclub.ru/mysql/doc/column-types.html

Дальше тогда модель делай, с учетом всех связей, а потом к этой модели интерфейс для редактирования теста.
#84 #420579
>>420552

> \twhile ($amount >= $nominal) {


> $amount -= $nominal;


Повторяющееся вычитание заменяется делением (а сложение — умножением), забыл?

Избавься от внутреннего цикла while.

> после небольшого гугления начал делать простым жадным перебором:


Для простого вариант его хватит. Для сложного гугли «задача сдача банкомат» или «задача о ранце»

>>420557

Ну норм. Я вижу ты Concrete TI реализовал? ну ок, давай посмотрим что выйдет.

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

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

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

Например для погрешности можно прокомментировать что это погрешность и в чем она задается — абсолютно или в процентах.

> name` VARCHAR(6500)


Издеваешься? Давай более реалистичное значение

> `added_date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,


По моему по дефолту проставляется только колонка типа TIMESTAMP так как TIMESTAMP привязан к часовому поясу а DATETIME нет. Изучи-ка различия между TIMESTAMP и DATETIME.

> `allow_errors` BOOLEAN,


нужно добавлять NOT NULL DEFAULT X а то у тебя получается 3 значения для поля

> `type` INT(11) UNSIGNED NOT NULL,


Используй ENUM. Что-то у меня ощущение что ты плохо знаешь типы MySQL, перечитай-ка:

http://dev.mysql.com/doc/refman/5.0/en/data-types.html (англ)
http://phpclub.ru/mysql/doc/column-types.html

Дальше тогда модель делай, с учетом всех связей, а потом к этой модели интерфейс для редактирования теста.
#85 #420580
>>420576

Кодеакадеми? Судя по комменту анона выше, объясняют там так себе. Мы сделаем гораздо лучше. только вот инвестиции многомиллионные и известность в отличие от них мы не получим
#86 #420581
>>420580

>Мы сделаем гораздо лучше.


Так-то у нас уже лучше!
Ну и объясняют там нормально. Просто в силу того, что задания проверяет не человек, а компьютер, задания приходится делать в формате теста, что накладывает целый ряд ограничений и тележку нюансов подкидывает. Один из нюансов - достаточно сомнительная ценность педагогического тестирования для отработки практических навыков.
#87 #420583
>>420579

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


Самое смешное, что наследования у меня то и нет. А вообще эти три паттерна достаточно простые для понимания.

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


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

>Издеваешься? Давай более реалистичное значение


Я, честно говоря, не знаю, какое взять.

>По моему по дефолту проставляется только колонка типа TIMESTAMP так как TIMESTAMP привязан к часовому поясу а DATETIME нет.


В uppu у меня тоже было `date` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP. Проставляется она.

>нужно добавлять NOT NULL DEFAULT X а то у тебя получается 3 значения для поля


Оу, я как-то забыл, что еще и нуль вставить можно.

>Дальше тогда модель делай, с учетом всех связей


Да там связей на десять строчек кода, я сделал уже.

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


Я сейчас думаю над тем, как сделать вывод теста для правки, после его отправки на сервер и не прохождения валидации. Но у меня там отвратительно вышла форма через кривой яваскрипт, так что я почти в тупике здесь. Может быть посоветуешь, как лучше выводить форму при создании теста?
#88 #420590
Возникла такая проблема. Как известно в русском языке хватает падежей. Допустим я хочу подсчитать в тексте какое количество раз встречается каждое из слов, включая его падежные формы (то есть если в тексте есть слова "база", "базы" и "базами" это должно вывести как три совпадения слова база, вот например как здесь http://1y.ru/text.php ). Для отдельного случая можно написать регулярку, но как это продумать для каждого случая, я никакой системы углядеть не могу, конечно она есть но там очень много степеней свободы, то есть вариантов окончаний, причём основа тоже везде может быть разной. Я в недоумении как это сделать, но вот например http://1y.ru/text.php это всё реализовано, значит есть возможность это сделать. Может кто то что то подсказать по этому поводу? Или кроме как прописывания всех возможных вариантов в регулярках нет выхода?
#89 #420592
>>420583

> Самое смешное, что наследования у меня то и нет.


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

> Я, честно говоря, не знаю, какое взять.


Ну под заголовок можно отвести 200 символов с учетом того что больше 150 там вряд ли будет. Ну можно попробовать придумать какое-нибудь длинное название типа

> Электродинамика и переходные незатухающие процессы в незамкнутом волноводе с фрауэнгоферовским рассеянием при температуре абсолютного нуля



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

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



Храни данные в элементах форм и используй поля с ключами:

input type=hidden name="questionId[1]" value="100"
textarea name="questionName[1]" value="текст вопроса 1"
input type=radio name="questionType[1]" ...

Ну или может questions[name][1]

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

А добавлять/удалять/перетаскивать вопросы яваскриптом конечно (но если хочется хардкора может попробовать сделать фоллбек на отправку обычной формы при отсутствии/ошибке в JS).
#90 #420593
>>420590

Это называется стемминг — приведение слова к основе. Стеммеры бывают на основе алгоритма (гугли стеммер Портера для русского) которые просто отрезают окончания по шаблону или умные на основе словаря - гугли phpmorphy.

Стемминг встроен в поисковые движки типа sphinx

Подробнее

google: стемминг
google: phpmorphy
http://aot.ru/
http://habrahabr.ru/post/49421/

> то есть если в тексте есть слова "база", "базы" и "базами"


Еще есть «базочка», «базушка», «базонька» и прочие забавные формы.
#91 #420596
>>420593
О, спасибо, это то что я давно искал! Совет просто бесценный!
#92 #420597
>>420592

>Храни данные в элементах форм и используй поля с ключами:


Пока что все так и выглядит.

>PHP поддерживает массивы но стоит проверить не упремся ли мы в ограничение на число элементов в POST и не будем ли терять из-за этого данные.


А сколько это ограничение? И что нас спасет в этом случае? Не аякс же?
Ну и да. Я в ожидании критики моего яваскрипта.
#93 #420600
>>420597

http://php.net/manual/ru/info.configuration.php#ini.max-input-vars
http://php.net/manual/ru/info.configuration.php#ini.max-input-nesting-level (это вроде не грозит)

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

Код проверю но уже наверно завтра.
#94 #420601
>>420600

>http://php.net/manual/ru/info.configuration.php#ini.max-input-nesting-level (это вроде не грозит)


Я планирую максимальную вложенность ~3.
#95 #420607
>>418985

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


>


>------------


>


>$values = значения по умолчанию (пустые);


>$errors = пустой массив;


>


>Если (форма отправлена через POST) {


>Читаем значения полей в $values;


>


>Если (все заполнено верно) {


>Делаем требуемое действие (например вставляем запись в БД);


>Редиректим куда-нибудь;


>Выходим;


>}


>


>Кладем ошибки в $errors;


>}


>


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


>


>-------------



Подскажи как здесь быть, конкретно вот здесь:

>Если (все заполнено верно) {



Делаю вот таким вот образом:

$name = preg_match('/^[\\w\\.]+$/', $_FILES["file"]["name"]) ? $_FILES["file"]["name"] : '';
$extension = $upload->getExtension($_FILES["file"]["name"]) ? $upload->getExtension($_FILES["file"]["name"]) : '';
$size = (($_FILES["file"]["size"] / 1024) < 20000000) ? $size : '';
$temp = isset($_FILES["file"]["tmp_name"]) ? $_FILES["file"]["tmp_name"] : '';

Дальше не знаю как сделать по лаконичней, либо проверять самостоятельно, складывая значения в массив а потом искать пустые значения, либо пилить новую функцию вида проверитьЗначения($name, $extension, $size, $temp) где выполняется тоже самое и возвращается массив $errors. Все это очень не красиво, на мой взгляд. Посоветуй как сделать красивей и понятней.
#95 #420607
>>418985

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


>


>------------


>


>$values = значения по умолчанию (пустые);


>$errors = пустой массив;


>


>Если (форма отправлена через POST) {


>Читаем значения полей в $values;


>


>Если (все заполнено верно) {


>Делаем требуемое действие (например вставляем запись в БД);


>Редиректим куда-нибудь;


>Выходим;


>}


>


>Кладем ошибки в $errors;


>}


>


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


>


>-------------



Подскажи как здесь быть, конкретно вот здесь:

>Если (все заполнено верно) {



Делаю вот таким вот образом:

$name = preg_match('/^[\\w\\.]+$/', $_FILES["file"]["name"]) ? $_FILES["file"]["name"] : '';
$extension = $upload->getExtension($_FILES["file"]["name"]) ? $upload->getExtension($_FILES["file"]["name"]) : '';
$size = (($_FILES["file"]["size"] / 1024) < 20000000) ? $size : '';
$temp = isset($_FILES["file"]["tmp_name"]) ? $_FILES["file"]["tmp_name"] : '';

Дальше не знаю как сделать по лаконичней, либо проверять самостоятельно, складывая значения в массив а потом искать пустые значения, либо пилить новую функцию вида проверитьЗначения($name, $extension, $size, $temp) где выполняется тоже самое и возвращается массив $errors. Все это очень не красиво, на мой взгляд. Посоветуй как сделать красивей и понятней.
#96 #420634
>>420607
Сделай себе отдельный класс для этой формы. И отдельные методы для получения полей из поста и валидации.
И будет у тебя что-то вроде.
форма = новая форма
Если (это пост) {
форма->взять поля из пост;
ошибки = форма->валидация
Если (все верно) {бла бла бла}
}
Вывод формы (форма, ошибки);
#97 #420651
>>420409

Это снова я. Оказывается, двухмерный массив можно отправлять формой с клиентской стороны таким образом:

<input type="hidden" name="list_name[' + i + '][]" value="' + currentListElementsValue + '">

Где i — автоувеличивающийся индекс цикла. То есть, вместо list_name[], как обычно принято делать при комбинировании информации одного типа, в начале вставляется индекс, а потом вот эта фича PHP с добавлением квадратных скобок в конце. Я понятия не имел, что так можно делать.
#98 #420664
После двух дней ничегонеделанья я снова пришел. Сейчас смотрю на функцию, решаю задачку с кредитами.
Посчитал два банка, потом понял, что на 0 умножать нельзя. С третьим банком проблема. Сейчас думаю, как её решить.
#99 #420666
>>420664
Блин, а ведь мне и не надо на 0 умножать, я перепутал платёж и процент, хех.
#100 #420668
>>420666
Начал проверять, а оно, скорее всего, не считает проценты.
http://ideone.com/AAWmgo
Не понимаю, что там не так.
#101 #420669
>>420544
>>420578
Спасибо, теперь понятнее стало. Последний вопрос. Вот допустим функция for(key in object). Что делает key? С object понятно, указывает на объект, который обрабатывается. А что за key? На что он указывает?
#102 #420670
>>420668
Ну да, ведь проценты через запятую назначил. Переделал задачу, проверьте, если не влом.
345 Кб, 2305x945
sage #103 #420695
сколько часов в день нужно потратить на изучение рнр чтобы к след зиме зарабатывать 100к
?
#104 #420696
3062 Кб, Webm
sage #105 #420697
>>420696
я на земляшке
#106 #420700
>>420695
В гривнах?
#107 #420729
Котаны, подскажите книгу где подробно и пошагово описывается написание своей CMS?
#108 #420737
>>420695
Работать на работе по 9 часов в день, причем это должна быть не говноработа. А у тебя должен быть просто поток постепенноусложняющихся задач на ней, и так же крутой коллектив, в котором уже будут сидеть дружелюбные к тебе гуру пхп и смежных областей, к которым ты будешь обращаться каждый день и спрашивать у них кучу всякой хуйни. Далее после прихода домой ты будешь читать хорошие годные технические книжки и статьи и делать параллельно какие-нибудь штуки, осваивать новые для себя технологии. Сон и повторять по новой 6 дней в неделю. Через 9 месяцев ты все это дропаешь и уебываешь в ДС, там в рассказе с умными людьми показываешь на реальных примерах какой ты ниибаться спец и получаешь свои 100к к след зиме.
#109 #420738
>>420737
С дивана пишешь?
#110 #420742
#111 #420743
>>420742
Жаль. Я уже было вдохновился.
#112 #420801
Аноны, я сегодня с нуля написал примитивный блог. Он умеет добавлять и редактировать записи с учётом категорий, позволяет оставлять комментарии, выводит постранично, сортирует записи по нужному параметру, может выводить только записи определённой категории, есть примитивная разметка и дизайн. Что ещё туда можно добавить?
#113 #420831
Аноны, мне сегодня некогда, давайте может завтра со всем разберемся. Решайте задачки пока.

>>420801

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

>>420695

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

Открой сайт с вакансиями вроде hh.ru, geekjob, brainstorage и посмотри какие требования предъявляются к разработчикам (также можешь в /wrk открыть одеск-тред и почитать мнения там).

>>420729

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

Да и зачем вдруг тебе понабобилось писать свою? Их же сотни уже написаны. И CMS это инструмент для непрограммистов. для тех кто сайты делает выбирая галочки в админке. Программисты делают сайты на фреймворках вроде Silex, Yii2, Symfony 2.

>>420670

> PHP Notice: Undefined variable: paymentTotal in /home/DKY5mW/prog.php on line 10


У тебя ошибка - обращение к несуществующей переменной. Надо ее исправить. В остальном вроде выглядит нормально.

>>420669

Это подробнее расписано на learn.javascript.ru. В переменную key на каждом шаге цикла помещается имя очередного ключа (свойства) объекта.

>>420607

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


> >Если (все заполнено верно) {


> Делаю вот таким вот образом:


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

if (validateForm(...))

или

if ($form->validate(...))

Проверка правильности файла наверно будет из нескольких шагов вроде:

Если (файл не загрузился) то ...
Если (файл слишком большой ) то ...
Если (файл не того типа) то ...

Сохраняем файл.

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

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

>>420801

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

>>420695

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

Открой сайт с вакансиями вроде hh.ru, geekjob, brainstorage и посмотри какие требования предъявляются к разработчикам (также можешь в /wrk открыть одеск-тред и почитать мнения там).

>>420729

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

Да и зачем вдруг тебе понабобилось писать свою? Их же сотни уже написаны. И CMS это инструмент для непрограммистов. для тех кто сайты делает выбирая галочки в админке. Программисты делают сайты на фреймворках вроде Silex, Yii2, Symfony 2.

>>420670

> PHP Notice: Undefined variable: paymentTotal in /home/DKY5mW/prog.php on line 10


У тебя ошибка - обращение к несуществующей переменной. Надо ее исправить. В остальном вроде выглядит нормально.

>>420669

Это подробнее расписано на learn.javascript.ru. В переменную key на каждом шаге цикла помещается имя очередного ключа (свойства) объекта.

>>420607

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


> >Если (все заполнено верно) {


> Делаю вот таким вот образом:


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

if (validateForm(...))

или

if ($form->validate(...))

Проверка правильности файла наверно будет из нескольких шагов вроде:

Если (файл не загрузился) то ...
Если (файл слишком большой ) то ...
Если (файл не того типа) то ...

Сохраняем файл.

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

Ничего страшного, если ты где-то ошибешься, это всегда можно поправить.
#114 #420832
>>420669

for это не функция. for это оператор.

Функция это то что определено со словом function, например:

function x(y) {
return y + 1;
}
#115 #420841
>>420832

fopen это функция или оператор?
#116 #420846
>>420841

>fopen это функция или оператор?


>http://php.net/manual/ru/function.fopen.php


>Руководство по PHP > Справочник функций > Расширения для работы с файловой системой > Функции для работы с файловой системой > Файловая система


Сложный был вопрос, да.
#117 #420859
Только сейчас елочку заметил на оп-пике.
52 Кб, 1661x436
#118 #420872
Ничего не понимаю. Он видит переменную из другого файла, но класс из него же не замечает.
#119 #420878
>>420872
Содержимое второго файла тоже заскринь.
#120 #420882
>>420878
Я уже изменил его, но там, помимо всего прочего было описание класса:

class test{
public function test(){
echo "ТЕСТ";
}
}

Сейчас сделал еще один отдельный файл под класс и все работает, однако я не понимаю, почему не работало когда класс был в PDO.
#121 #420886
>>420882

>Я уже изменил его, но там, помимо всего прочего было описание класса:


Думаю, что проблема где-то здесь.
#122 #420943
Скачал фреймворк YII
Но по адресу yii/requirements/index.php высветило:

Проверка на соответствие требованиям Yii

И другое в таком же стиле, проблема с кодировкой видимо, где надо исправить, не подскажете?
Mymik #123 #420949
Посоны не подскажите ли как поставить Локалку на windows8
Локалка это:php my squl apache
sage #124 #420955
>>420943
head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
#125 #420962
>>420955
Спасибо.
#126 #420966
Аноны, сегодня совершенно случайно скачал фреймворк yii. Всегда слышал что надо учить фреймворки, иначе это всё не то. Но я вот думаю дорос ли я до фреймворка, с ООП знаком весьма поверхностно, могу написать самые простые вещи, синтаксис более менее запомнил, но вот глубины пока не понимаю. На обычном ПХП могу написать например примитивный блог или интернет магазин с стандартным функционалом. Стоит браться? Я так понимаю в случае поиска работы джуниору без фреймворка никуда?
#127 #421050
>>420966
Ну а когда ты будешь браться? После того, как запорешь несколько проектов на работе? Когда они будут прогорать по срокам, а ты не будешь мочь реализовывать какие бы то ни было изменения в ТЗ, когда проект уже будет готов? Учи ООП и фреймворки, да. Можешь впрочим учить один битрикс и всё, так мало что надо знать, но лучше ничего кроме сайтов-визиток, блогов и максимально стандартных интерет-магазинов на нём не делать. И какие, блядь, в синтаксисе глубины могут быть?
#128 #421054
>>421050
Ооп - это не синтаксис, ооп - это парадигма. Он наоборот может в синтаксис, но не может в парадигму.
sage #129 #421055
что есть "парадигма"?
sage #131 #421072
>>421064

> Своим современным значением в научно-технической области термин «парадигма» обязан, по-видимому, Томасу Куну и его книге «Структура научных революций»


лолблядь
по делу кто может ответить?
sage #132 #421076
>>421072
Первую строчку не осилил что ли?
sage #133 #421080

>Клуб любителей изучать PHP 41


>что есть "парадигма"?


Вся суть всего.
#134 #421083
>>419972

> Клуб любителей изучать PHP 41


А вы никак не связаны с этим клубом https://2ch.hk/biz/res/636913.html ?
#135 #421086
>>421083
У меня там членский билет.
!xnn2uE3AU. #136 #421092
Анон просил проверить TestHub. Проверяю что успел.

Модели: вот тут вот есть такой код

https://github.com/sqghub/TestHub/blob/master/models/Question.php#L54

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

Вот тут https://github.com/yiisoft/yii2/blob/master/docs/guide/db-active-record.md#working-with-relationships описаны функции link/unlink для создания связей. Может они подойдут?

Также написано вроде возможность подключить транзакции уже есть: https://github.com/yiisoft/yii2/blob/master/docs/guide/db-active-record.md#transactional-operations (может это даже включено по умолчанию).

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

Далее, вот тут ты определяешь отношение в зависимости от типа вопроса:

https://github.com/sqghub/TestHub/blob/master/models/Question.php#L24

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

Еще, ты определяешь свойство

> private $answers = [ ];



Но как я понимаю из документации https://github.com/yiisoft/yii2/blob/master/docs/guide/db-active-record.md#working-with-relational-data там обращение к answers должно перехватываться Юи, и добавляя поле ты возможно ломаешь этот механизм.

В общем, опять же надо проверить, работает ли загрузка вопроса из БД, ответов, и их удаление и сохранение. Там документация скудная, так что если что сразу лезь в исходники Юи и смотри там.

> https://github.com/sqghub/TestHub/blob/master/controllers/TestController.php#L33


Я бы вынес questionTypes и questionTypeLabels в модель, то есть можно сделать метод getAllQuestionTypes и например getQuestionLabel($type). Тогда эти названия можно будет в нескольких местах использовать.

> return $this->render('createTest.twig', [


Это у тебя скопипастено 2 раза, лучше сделать без копипасты, например:

если (пост) {
обрабатываем пост данные;
редиректим если ок;
}

выводим форму;

https://github.com/sqghub/TestHub/blob/master/controllers/TestController.php#L60

> $question = new Question( );


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

> as $questionNumber => $formQuestion


Советую номер передавать отдельным скрытым или видимым инпутом — а то ты намучаешься при переупорядочивании вопросов переименовывать все эти поля.

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

По яваскрипту:

Тут есть другие варианты решения. Например, можно посмотреть в сторону knockout. Это шаблонизатор с дата биндингом, то есть при изменении например типа вопроса в объекте, он сам будет менять DOM и не нужен будет весь этот код с кучей getElementById.

Второй вариант использовать jQuery ради экономии времени на код работы с DOM — он будет чуть короче (но суть особо не поменяется).

Пока в принципе можно так оставить.

Ну или еще один вариант — вообще не делать объекты Question/Answer, а просто сделать несколько отдельных функций вроде поменятьТипВопроса, добавитьВопрос и писать в HTML разметке так:

<button onclick="addQuestion(...)" type="button">Добавить Вопрос</button>

То есть не делать на стороне JS ООП-модель. Если логика простая то это может сработать.

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

> document.getElementById('questions[' + this.number + '][number]')


сделать метод вроде getQuestionNode()

> if (source.id == ("questions[" + this.question.number + "][answers][" + this.number + "][delButton]")) {


Лучше ставить обработчик на саму кнопку:
onEvent(this.getDeleteButton(), 'click', function () { ... });

> function extend(Child, Parent) {


Тут стоит использовать более хороший Object.create если он есть в браузере, а если нет то хак с функцией.

> this.number = question.answers.length + 1;


Инкапсуляцию по моему нарушаешь, ты сделал выделение нового номера ответа не в классе Вопрос, а вынес наружу. Лучше сделать метод question.getNextAnswerNumber() или сделать чтобы при вызове question.addAnswer он сам проставлялся.

> var answerHtml = document.getElementById("questionType" + typeNumber).innerHTML;


> answerHtml = answerHtml.replace(/questionNumber/g, question.number);


Это надо вынести в функцию такого вида:

html = renderTemplate(tpl, { a: 1, b: 2 });

> this.node.onclick = function (event) {


> this.parent.clickFunction(event);


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

Но вообще хорошо что ты ООП используешь, это да.

> document.getElementById('questions[' + this.number + '][number]').innerHTML = newNumber;


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

> document.getElementById("questions").getAttribute("count");


Не надо передавать данные через аттрибуты. Вместо этого лучше непосредственно передавать данные в шаблоне, например в виде JSON:

var questions = <?= json_encode($questions) ?>;
initTest(questions);

Остальное я еще проверю, когда будет время.

Шаблоны:

https://github.com/sqghub/TestHub/blob/master/views/test/createTest.twig#L30
ЧТобы не копипастить шаблон вопроса 2 раза, вынеси его в макрос.
!xnn2uE3AU. #136 #421092
Анон просил проверить TestHub. Проверяю что успел.

Модели: вот тут вот есть такой код

https://github.com/sqghub/TestHub/blob/master/models/Question.php#L54

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

Вот тут https://github.com/yiisoft/yii2/blob/master/docs/guide/db-active-record.md#working-with-relationships описаны функции link/unlink для создания связей. Может они подойдут?

Также написано вроде возможность подключить транзакции уже есть: https://github.com/yiisoft/yii2/blob/master/docs/guide/db-active-record.md#transactional-operations (может это даже включено по умолчанию).

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

Далее, вот тут ты определяешь отношение в зависимости от типа вопроса:

https://github.com/sqghub/TestHub/blob/master/models/Question.php#L24

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

Еще, ты определяешь свойство

> private $answers = [ ];



Но как я понимаю из документации https://github.com/yiisoft/yii2/blob/master/docs/guide/db-active-record.md#working-with-relational-data там обращение к answers должно перехватываться Юи, и добавляя поле ты возможно ломаешь этот механизм.

В общем, опять же надо проверить, работает ли загрузка вопроса из БД, ответов, и их удаление и сохранение. Там документация скудная, так что если что сразу лезь в исходники Юи и смотри там.

> https://github.com/sqghub/TestHub/blob/master/controllers/TestController.php#L33


Я бы вынес questionTypes и questionTypeLabels в модель, то есть можно сделать метод getAllQuestionTypes и например getQuestionLabel($type). Тогда эти названия можно будет в нескольких местах использовать.

> return $this->render('createTest.twig', [


Это у тебя скопипастено 2 раза, лучше сделать без копипасты, например:

если (пост) {
обрабатываем пост данные;
редиректим если ок;
}

выводим форму;

https://github.com/sqghub/TestHub/blob/master/controllers/TestController.php#L60

> $question = new Question( );


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

> as $questionNumber => $formQuestion


Советую номер передавать отдельным скрытым или видимым инпутом — а то ты намучаешься при переупорядочивании вопросов переименовывать все эти поля.

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

По яваскрипту:

Тут есть другие варианты решения. Например, можно посмотреть в сторону knockout. Это шаблонизатор с дата биндингом, то есть при изменении например типа вопроса в объекте, он сам будет менять DOM и не нужен будет весь этот код с кучей getElementById.

Второй вариант использовать jQuery ради экономии времени на код работы с DOM — он будет чуть короче (но суть особо не поменяется).

Пока в принципе можно так оставить.

Ну или еще один вариант — вообще не делать объекты Question/Answer, а просто сделать несколько отдельных функций вроде поменятьТипВопроса, добавитьВопрос и писать в HTML разметке так:

<button onclick="addQuestion(...)" type="button">Добавить Вопрос</button>

То есть не делать на стороне JS ООП-модель. Если логика простая то это может сработать.

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

> document.getElementById('questions[' + this.number + '][number]')


сделать метод вроде getQuestionNode()

> if (source.id == ("questions[" + this.question.number + "][answers][" + this.number + "][delButton]")) {


Лучше ставить обработчик на саму кнопку:
onEvent(this.getDeleteButton(), 'click', function () { ... });

> function extend(Child, Parent) {


Тут стоит использовать более хороший Object.create если он есть в браузере, а если нет то хак с функцией.

> this.number = question.answers.length + 1;


Инкапсуляцию по моему нарушаешь, ты сделал выделение нового номера ответа не в классе Вопрос, а вынес наружу. Лучше сделать метод question.getNextAnswerNumber() или сделать чтобы при вызове question.addAnswer он сам проставлялся.

> var answerHtml = document.getElementById("questionType" + typeNumber).innerHTML;


> answerHtml = answerHtml.replace(/questionNumber/g, question.number);


Это надо вынести в функцию такого вида:

html = renderTemplate(tpl, { a: 1, b: 2 });

> this.node.onclick = function (event) {


> this.parent.clickFunction(event);


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

Но вообще хорошо что ты ООП используешь, это да.

> document.getElementById('questions[' + this.number + '][number]').innerHTML = newNumber;


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

> document.getElementById("questions").getAttribute("count");


Не надо передавать данные через аттрибуты. Вместо этого лучше непосредственно передавать данные в шаблоне, например в виде JSON:

var questions = <?= json_encode($questions) ?>;
initTest(questions);

Остальное я еще проверю, когда будет время.

Шаблоны:

https://github.com/sqghub/TestHub/blob/master/views/test/createTest.twig#L30
ЧТобы не копипастить шаблон вопроса 2 раза, вынеси его в макрос.
#137 #421094
Аноны, я наверно буду первого числа, забегу в тред.

>>420949

Наверно так же как и на другеи версии Windows. У меня есть кое что

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

>>420966

ООП нужен и фреймворки тоже. без них только самая примитивная работа. У меня есть урок по ООП

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

Также ООП описан в книгах Зандстры и Шлосснейгла из ОП поста
#138 #421095
>>421055

Подход.
#139 #421112
Привет анон, у меня возникла одна проблема, мне очень нужно что бы ты дал мне правильное направление в том как это реализовать если тебе это не сложно. Есть одна такая пирамидка http://rich-birds.com/. Суть её состоит в том , что можно покупать птицы которые несут яйца и менять их на золото, а уже золото на деньги, само собой пирамида обман чистой воды, но меня заинтересовала её математическая модель. Там при регистрации дают 1000 бонусного серебра за которые можно купить ровно одну птицу, которая приносит 24 серебра в сутки. (там можно вкладывать деньги, но меня интересует именно вариант без вложения реальных средств).
Я решил написать скрипт который будет рассчитывать сколько будет приносить серебра птицы, например на 50 день, или на 300 день. С учётом того что как только мы набираем нужную сумму для покупки птицы, мы сразу же её покупаем (птиц пять видов, цены на все разные). И вот мне показалось что я уже всё написал: http://ideone.com/odXis7 и результат мне показался правильным. Но потом я заметил как это часто бывает недочёты, а недочёты заключаются в том что каждый день я покупаю только один вид птиц, и если у меня остаётся определённые деньги от покупки птиц которых не хватает на птицу того вида которого я покупаю в этот день, но хватает на птицу другого вида, я её покупаю. И не знаю как исправить свой скрипт, варианта исправления есть три:

1) Попробовать через рекурсию
2) Попробовать сделать при помощи ООП
3) Сделать всё через функции и при том или ином случае в функциях ссылаться на другие функции.

Извини если я не понятно объяснил, чувствую что объяснил недостаточно понятно, но мне главное бы узнать какой путь выбрать, через который это можно реализовать. Вот код того что я написал: http://ideone.com/odXis7 может быть он лучше пояснить что я хочу сказать.
#140 #421113
>>421112
Одним словом, каждый день у меня есть некоторая сумма, которая хранится в переменной $gold и зависит от количества птиц которые я уже купил. И вот у меня есть варианты покупки птиц в зависимости от размера этого $gold.

Допусти на 90-ый день у меня $gold=24000 серебра, я могу купить 4 птицы по 5000 серебра каждая (делаю я это через блоки if в которых проверяется значение $gold), у меня остаётся 4000 серебра, я могу купить ещё 4 птицы стоимостью по 1000 серебра, но скрипт этого не делает а переходит $i++ в цикле.
#141 #421117
>>421112
Раньше был аналогичный хайп, назывался golden eggs. Не помню сколько прожил правда. Может запилить такой?
#142 #421151
>>421117
Сначала пишешь это несколько месяцев, отлаживаешь, разбираешься с серыми и черными схемами работы с баблом. Потом рекламируешь везде, тратишь на это кучу денег, сил и времени. Во время работы борешься не покладая рук с ботами и "халявщиками". Потом упускаешь момент и все бабло уходит, пирамида рушится с нулевым балансом. Ты с ужасом понимаешь, что просрал год времени, минимум несколько сот тыр, потратил много сил и не приобрел абсолютно ничего: ни денег, ни сколько-нибудь полезного опыта. В резюме годовая дыра, сам ты - лысеющий задрот в обносках с нервно бегающими глазками, не способный сложить три слова на собеседовании и ничего полезного не умеющий. Собеседующие хмурят брови и раз за разом ты слышишь сакраментальную фразу.
#143 #421167
>>421112
>>421113
Всё очень просто решается:
нужно изменить порядок if-блоков, в которых происходит покупка птиц, т.е.
начать нужно с самой дорогой птицы:
if ($gold >= price5) { //Купить 5 птицу/ц }
if ($glod >= price4) { //Купить 4 птицу/ц }
if ($glod >= price3) { //Купить 3 птицу/ц }
И т.д.
"&& $gold<$price4" и аналогичные хуевины следует убрать из if-блоков, так как в них нет необходимости.

Ну и еще рекомендую, во-первых нуучится использовать массивы, которые бы позволили в данном конкретном случае заменить все эти if-блоки одним.
#144 #421190
Ребят, сводная таблица, объединяющая многие–ко–многим, может содержать доп. информацию, это нормально? Ну вроде:

Таблица 1 | Таблица 2 | Что–нибудь общее для связи
#145 #421198
Все сидите программируете? Сходили бы пробздеться, новый год как-никак.
#146 #421216
>>419972

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

http://ideone.com/0kHLTr
#147 #421250
http://jsfiddle.net/q72b4btd/
Первое задания из курса html/css. Что-то неверно?
#148 #421254
>>421167
Ха, Спасибо, оказывается всё намного проще чем я думал. У меня прям глаза открылись. Часто так бывает что всё намного проще чем думаешь, не знаю как с этим бороться, я уже и пробовал рекурсию как-то применить или даже ООП попробовать.

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



Извини, если не сложно можешь намекнуть как это сделать? Сделать три массива 1 с количество птиц, 2 с суммой которую они приносят, 3 с их ценой. А потом просто в одном блоке (если $gold больше 1000) просто выполнять математические действия начиная с самой дорогой птицы?
#149 #421261
Котоны, не могу поставить ни один опкод кэш под Windows, перебрал уже 20 dll-ок. Ну че за хуйня?

не было ни у кого такого?
#150 #421262
>>421113

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

24 000 / 5 000 = 4 птицы

(первый раз слышу про игру где надо покупать каких-то птиц)

>>421250

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

array(
'bird1' => array('price' => 2000, 'profit' => 100, 'weight' => 6),
'bird2' => ...
);

А информацию о купленных птицах в обычном массиве вида

array(
'bird1' => 20,
'bird2' => 5
);

Если же у птиц есть какие-то индивидуальные свойства типа возраста, настроения, веса, и т.д. то придется на каждую птицу отдельный элемент массива, а лучше объект, заводить.
#151 #421263
>>421261

Для локальной разработки он не обязателен. В новом php 5.5 и выше кстати кешер уже встроен, надо только в конфиге включить.

Ну и искать надо не абы где, а на http://windows.php.net/downloads/pecl/releases/ и искать по соответсвию с версией php и Апача. Например если Апач ts (многопоточный) то и версия должна быть ts а не nts. И компилятор желательно тот же.

Расшифровка обозначений:

php_apcu-4.0.7-5.5-nts-vc11-x64.zip

apcu — нгазвание расширения
4.0.7 - версия
5.5 - версия php
nts/ts — однопоточный/многопоточный (под виндой и апачем нужен наверно ts)
vc11 — версия компилятора (желательно та же что у Апача)
x64 — под 64 битную ОС
#152 #421264
>>421261

Под 32 битную ось надо x86 (а не x32 как можно подумать).
#153 #421265
>>421250

> margin-right:34%-10px;


Это не работает, это ошибка. Нельзя писать выражения (точнее можно но с помощью CSS3 и функции calc, гугли по словам "css3 calc". Но в этой задаче calc использовать нельзя).

> left:10px;


left используется только с позиционированием. Тут оно ничего не делает.

Не ставь свойства наугад, а ставь осознанно. Там дана ссылка к задаче http://softwaremaniacs.org/blog/2005/08/27/css-layout-flow/ — убедись что прочел и понял то что там написано.

> \t\tmargin-left:34%;


>\t\tmargin-top:10px;


>\t\twidth:66%;


У тебя в сумме получилось больше 100% и одно из свойств будет не применено.

Почитай ссылку выше и исправь ошибки.
#154 #421271
>>421198

Мне интересно, куда можно идти 1 января днем? Я был на улице, город как будто вымер, все закрыто. Алсо, лужи и слякоть везде.

>>421190

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

>>421216

И тебя с новым годом, анон. Версия работает, да.

> for ($i=1; $i <= $words; $i++, $girl++) {


Этот цикл можно заменить на сложение же.

> while (count($girls)>3) {


Тут надо поставить не цифру 3, а число слогов.

> $girl--;


Хорошо бы переделать чтобы жтого не было, например не прибавлять лишнюю единицу изначально.
#155 #421274
Котаны, кто то пользовался библиотекой pChart ? Я только скачал, подключаю файл с классами, и высвечивается много такого в разных строчках:

Warning: imagettftext() [function.imagettftext]: Invalid font filename in Z:\home\test_sait\www\pChart1\pChart\pChart.class on line 566

Пишет что ошибка именно в скачанном файле как я понимаю.
#156 #421276
>>421265

>> \t\tmargin-left:34%;


>>\t\tmargin-top:10px;


>>\t\twidth:66%;


Так ведь top - отступ сверху, зачем его сумировать к ширине и отступу слева?
http://jsfiddle.net/q72b4btd/2/
#157 #421286
>>421274
Уже решил проблему, кстати, анончики не у кого нет документации на русском для pChart?
#158 #421310
>>421276

Ты прав. Но все равно, это непраивльно.
#159 #421328
>>421310
Офигеть. Дай угадаю, надо сделать один элемент, который будет отсупать 10рх от границ экрана, а внутри него запилить два блока, так? Других идей нет, как сделать 34 и 66 + 10 рх
#160 #421361
>>421328
Алсо, хотелось спросить по поводу второй задачи, а как там без width сделать, хех?
#161 #421363
>>421167
Спасибо тебе ещё раз. Оказывается если бы эта пирамида rich-birds.com реально выдавала бы деньги (и если я не ошибся в расчётах) то примерно через 300 дней, без начальных вложений реальных денег, можно было бы получать 1500-2000 рублей в день, а через год можно выйти на 19000 рублей (там экспоненциальный рост). Но только эта пирамида денег не платит. Вот скрипт если вдруг кому интересно http://ideone.com/RSSLq9 там можно даже график посмотреть, но он закомментирован.
#162 #421461
>>421328
И для отступов есть ещё одно свойство - padding.
Используй его тоже.
#163 #421462
>>421092

>Это стоит хотя бы в транзакцию завернуть, чтобы не было полусохраненных ответов.


Это да.

>Ну и еще, ты не удаляешь старые вопросы по моему.


Эту функцию я планирую использовать только при создании. Хотя можно и при редактировании, только там при создании этого массива нужно будет делать связку из взять из базы -> проставить новые атрибуты -> save. Save работает как инсерт для новых записей и как апдейт для тех, что взяли из бд.

>описаны функции link/unlink для создания связей


Я так понял, они нужны при добавлении связи для связанных уже по hasOne/hasMany классов. Т.е. классы уже связаны, а линк/анлинк нужен для уже объектов.

>Далее, вот тут ты определяешь отношение в зависимости от типа вопроса:


>Будет ли это работать, если мы загрузили вопрос из БД, поменяли его тип, поменяли ответы и сохраняем?


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

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


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

>там обращение к answers должно перехватываться Юи, и добавляя поле ты возможно ломаешь этот механизм.


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

>Я бы вынес questionTypes и questionTypeLabels в модель


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

>если (пост) {


Дело в том, что в блоке "если пост" кода больше, чем в остальном. Это я так перевернул по странному.

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


Пока что это создание нового теста, а не редактирование уже имеющегося, т.е. у вопросов нет id. А в редактировании все равно new Question() делать придется, только в нем каждый раз будет $question -> findOne и затем save.

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


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

>По яваскрипту:


>Например, можно посмотреть в сторону knockout.


Это как-то очень круто. Или рано. Или и то, и другое.

>Ну или еще один вариант — вообще не делать объекты Question/Answer, а просто сделать несколько отдельных функций


Думал об этом, но в итоге пришел к выводу, что объектами проще.

>Ну и еще, надо выносить код работы с DOM в функции.


Даже для функций в одну строчку?

>Лучше ставить обработчик на саму кнопку:


>onEvent(this.getDeleteButton(), 'click', function () { ... });


ВОУ, А ТАК МОЖНО!?
Это же круто. Правда надо прерывать всплытие в каждой функции. Этим я займусь.

>Тут стоит использовать более хороший Object.create если он есть в браузере, а если нет то хак с функцией.


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

>Инкапсуляцию по моему нарушаешь, ты сделал выделение нового номера ответа не в классе Вопрос, а вынес наружу. Лучше сделать метод question.getNextAnswerNumber() или сделать чтобы при вызове question.addAnswer он сам проставлялся.


Унесу в addAnswer. Это, пожалуй, логичнее будет.

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


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

>Но вообще хорошо что ты ООП используешь, это да.


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

>Остальное я еще проверю, когда будет время.


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

>ЧТобы не копипастить шаблон вопроса 2 раза, вынеси его в макрос.


С ним можно впихнуть что-то в середине шаблона?
#163 #421462
>>421092

>Это стоит хотя бы в транзакцию завернуть, чтобы не было полусохраненных ответов.


Это да.

>Ну и еще, ты не удаляешь старые вопросы по моему.


Эту функцию я планирую использовать только при создании. Хотя можно и при редактировании, только там при создании этого массива нужно будет делать связку из взять из базы -> проставить новые атрибуты -> save. Save работает как инсерт для новых записей и как апдейт для тех, что взяли из бд.

>описаны функции link/unlink для создания связей


Я так понял, они нужны при добавлении связи для связанных уже по hasOne/hasMany классов. Т.е. классы уже связаны, а линк/анлинк нужен для уже объектов.

>Далее, вот тут ты определяешь отношение в зависимости от типа вопроса:


>Будет ли это работать, если мы загрузили вопрос из БД, поменяли его тип, поменяли ответы и сохраняем?


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

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


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

>там обращение к answers должно перехватываться Юи, и добавляя поле ты возможно ломаешь этот механизм.


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

>Я бы вынес questionTypes и questionTypeLabels в модель


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

>если (пост) {


Дело в том, что в блоке "если пост" кода больше, чем в остальном. Это я так перевернул по странному.

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


Пока что это создание нового теста, а не редактирование уже имеющегося, т.е. у вопросов нет id. А в редактировании все равно new Question() делать придется, только в нем каждый раз будет $question -> findOne и затем save.

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


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

>По яваскрипту:


>Например, можно посмотреть в сторону knockout.


Это как-то очень круто. Или рано. Или и то, и другое.

>Ну или еще один вариант — вообще не делать объекты Question/Answer, а просто сделать несколько отдельных функций


Думал об этом, но в итоге пришел к выводу, что объектами проще.

>Ну и еще, надо выносить код работы с DOM в функции.


Даже для функций в одну строчку?

>Лучше ставить обработчик на саму кнопку:


>onEvent(this.getDeleteButton(), 'click', function () { ... });


ВОУ, А ТАК МОЖНО!?
Это же круто. Правда надо прерывать всплытие в каждой функции. Этим я займусь.

>Тут стоит использовать более хороший Object.create если он есть в браузере, а если нет то хак с функцией.


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

>Инкапсуляцию по моему нарушаешь, ты сделал выделение нового номера ответа не в классе Вопрос, а вынес наружу. Лучше сделать метод question.getNextAnswerNumber() или сделать чтобы при вызове question.addAnswer он сам проставлялся.


Унесу в addAnswer. Это, пожалуй, логичнее будет.

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


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

>Но вообще хорошо что ты ООП используешь, это да.


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

>Остальное я еще проверю, когда будет время.


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

>ЧТобы не копипастить шаблон вопроса 2 раза, вынеси его в макрос.


С ним можно впихнуть что-то в середине шаблона?
#164 #421463
И в конце-то концов: как выглядит спам-лист двача, мне регулярно не дает отправить сообщение.
#165 #421492
>>421463
Анимцо. Хуеблядь.
#166 #421493
>>421492
Хм, отправилось. А в /а/ и /дев/ не отправляется.
#167 #421538
Решаю первую задачу по регулярным выражениям.
Хочу совета спросить. Как его искать? Одним выражением, или-же несколькими?
#168 #421575
>>421538
http://ideone.com/xnAot6
Сделал по пути наименьшего сопротивления, надеюсь, что правильно.
#169 #421582
Оп, что скажешь насчет IIS. Сегодня полез качать php(купил себе ssd, мего вещь) и попалось на глаза сообщения о том что php прекрасно работает с iis, вплоть до того что там пару галочек при установке ставишь и пользуешься(в общем как и вся винда - максимум юзабельности из коробки). Так вот сейчас сижу и думаю - снова ставить апач, или же попробовать детище от мелкософта. Для разработки использую phpstorm+xdebug.
#170 #421633
>>419972
Аноны есть кто работал с PChart? Почему по осям не подписываются цифры, даже в примерах которые шли вместе с библиотекой, во всех браузерах такое.
#171 #421646
>>421582

>в общем как и вся винда - максимум юзабельности из коробки


> phpstorm


> xdebug



Категория: выебанные и обоссаные
324 Кб, 382x417
#172 #421658
>>419972
Анон, в шапке написано что можно почитать

>>По PHP: Профессиональное программирование на PHP Джордж Шлосснейгл


>>По PHP: Мэтт Зандстра — PHP: Объекты, шаблоны, методики программирования


Но в первой книге 2006 года написано, что она на версию 5.0, вторая как раз на последнюю вроде. Стоит ли читать первую, не сильно она устарела, или сразу обмазываться второй?
#173 #421662
>>421658
Алсо полный ньюфаг в пхп, прочитал в гугле, что во второй порог вхождения для новичка высокий и надо знать хотя бы ООП и сам язык более менее. Таки начинать с первой?
38 Кб, 1000x500
#174 #421667
Извините анончики, я наверное уже всем надоел с этим pChart, но очень надо. Может кто знает как делать масштабирование по осям? Получается пикрилейтед, а надо что бы по Оси Х был другой шаг. Вот даже нашёл про масштабирование в этой библиотеке, но всёравно разобраться не могу http://wiki.pchart.net/doc.doc.draw.scale.html

Судя по всему там используется метод ->drawScale но пробовал по разному но не выходит.
#175 #421668
>>421667
Странно как то график отобразился здесь, одним словом там по Оси Х примерно 200 значений, надо изменить шаг, что бы был не 1 а хотя бы 10
45 Кб, 400x400
#176 #421771
>>421667
Немчура
#177 #421777
>>421662
когда читал вторую уже понимал более-менее ооп, но некоторые страницы приходилось перечитывать по 5 раз чтобы понять суть.
#179 #421982
Гребанный псевдокласс checked, похож на какое-то шаманство, а я сижу и пытаюсь разагадать как он работает в этом примере. Мои тщетные попытки запилить код для трех вкладов не удались. Может кто-то пояснить подробно?

http://jsfiddle.net/dh4s5q7c/
#180 #422067
Опять нубоанон вещает, всё про Регулярки. Первую задачу, со скрипом, решил. Даже к второй приступил.

Обдумываю, как её решить. Допустим, я смогу проверить на те ошибки, что заданы. А как вывести сообщение, что именно в том месте ошибка - не знаю. Сейчас гуглить буду.
#181 #422073
>>422067
preg_replace('/(ж|ш)(ы)/', '[$2]', $string).
Как то так, давно уже с регулярками дела не имел, может чего путаю - гугли сохраняющие скобки(есть и не сохраняющие кстати)
#182 #422074
>>422073

>'[$2]'


А что эта штука делает?
#183 #422077
>>422074
Прости, наебал. http://ideone.com/1w3yzQ
Вот работающая регулярка. Я же сказал - гугли сохраняющие скобки regexp узнаешь что за $2
#184 #422081
>>422077
Нашел такую штуку:

>preg_replace('/\.(?!\.)/')



Если сменить те точки на любой другой знак - он и заменится в исходном тексте. А зачем тогда скобки, знак вопроса и восклицания?
Что-то я не понимаю.
#185 #422087
>>422081
Гугл молчит по этому поводу. Там это само собой разумеющееся, а я не понимаю. Удалил тот код, попробовал свой поставить - а он даже близко не подходит.
Про скобки нашел, что они за вложенные выражения отвечают. Погуглил вложенные выражения - а они вообще не относятся к тексту вроде-бы. Так что не знаю, зачем поставили их. Про тот знак вопроса и восклицания - ничего не понимаю. Вторую точку можно на рандомный знак менять -- ничего не изменится. Если убрать её -- код работать не будет. Наверное, это я дурак, и очевидные вещи не могу понять.
#186 #422107
>>420509
Всех с наступившим.
Я переделал задачку свою, я вдруг проснулся после Нового года и подумал - зачем мне там координаты X и Y если у меня есть номер позиции от 1 до 100 и массив с такими же элементами, я могу просто размещать игроков прямо в элементы при совпадении. Плюс переделал код по советам.
http://ideone.com/KMw0OT
#187 #422111
>>422077
Платить за это два доллара? Да ну нахуй.
#188 #422140
>>422107

>4 января


>проснулся после Нового года

#189 #422144
>>422140
Да не, просто сделал себе каникулы от изучения Php на праздники.
#190 #422153
>>422144

Сколько часов тратишь в день на изучение?
#191 #422154
>>422087
Учитель из меня тот еще, но попробую объяснить. $0, $1, $2 это особые переменные создаваемые в процессе прогона строки через регулярку. $0 соответствует всему регулярному выражению, а $1, $2 и так далее соответствуют скобкам в порядке их открывания. В случае если регулярка /he(l)l(o)/, а строка hello, то в $0 будет - "hello", в $1- "l". http://ideone.com/o8fTAw
В общем если тебе нужно сохранить какой то кусок символов, для того что бы потом выделить его скобками например как в примере с жы шы то просто ставишь скобки, и у тебя появляется переменная(которая обрати внимание обязательно должна быть в кавычках как и регулярка). Если же содержимое скобки сохранять в переменную не надо то используются такие скобки (?:наша_регулярка). Вообще есть еще такие ништяки как вперед смотрящие и назад утверждения. Вообще, вот годная книга на эту тему, в сочетании с объяснениями опа разобраться труда не составит http://rutracker.org/forum/viewtopic.php?t=32748
#192 #422171
>>421982
Какая то запутанная фигня. Но ни чего сложного для понимания.

Возможно у тебя пробел в теории.
http://htmlbook.ru/css/checked
http://htmlbook.ru/samcss/sosednie-selektory

Чуть поправил.
http://jsfiddle.net/dh4s5q7c/1/
#193 #422172
>>421982
Какая то запутанная фигня. Но ни чего сложного для понимания.

Возможно у тебя пробел в теории.
http://htmlbook.ru/css/checked
http://htmlbook.ru/samcss/sosednie-selektory

Чуть поправил.
http://jsfiddle.net/dh4s5q7c/1/
#194 #422179
Я хотел спросить у вас, на ПХП пишут браузерные игры? Насколько удобный язык для этого?
#195 #422186
>>422153
Выбираю 1-3 задачки на день и решаю, как решил - значит остальное время занимаюсь другими делами.
#196 #422218
>>421982
>>422171

Шаманизм не нужен. Давно введены в CSS родственные селекторы.

http://htmlbook.ru/css/selector/sibling

http://jsfiddle.net/avLdmruy/
#197 #422232
Сделал вывод текста по кругу.

http://ideone.com/m5GTZH

Правда тут уже версия со спиралью, но думаю что по ней тоже можно оценить / критиковать, там различия в 2 строчках.
#198 #422273
Друзья, Yii все еще торт для фриланса, или уже на Yii2 смотреть?
А то моя мега-связка CI+Kohana+ZF что-то перестает мне вкусные заказы подбрасывать
#199 #422328
>>422232

Неплохо.

> \tfor ($x=0; $x<$dx; $x++) {


> echo " {$screen[$y][$x]} ";


тут можно цикл заменить на implode

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


> $letters[] = mb_substr($phrase, $i, 1);


Так тоже можно, но вообще строку разбить на массив символов можно таким хаком:

$letters = preg_split("//u", $text, null, PREG_SPLIT_NO_EMPTY);

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

Обрати внимание на флаг u. Он говорит что текст в utf-8 и заставляет разбивать строку именно на буквы по границам utf-8 символов, а не на куски по 1 байту.
#200 #422329
>>422273

Не знаю

>>422179

Одного Php мало так как это серверный язык и на нем ты можешь только написать серверную часть игры (при условии что у тебя будет не очень много игроков). А клиентскую надо писать на HTML/CSS/JS.
#201 #422333
>>422154

$0 это даже не настоящая переменная, так как ты не можешь написать например

echo $0;

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

>>422107

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

> global $desk;


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

Также, вот этот код

> oreach ($desk->cases as $key => $value) {


> if ($this->position == $key) {


Стоит перенести в Desk и сделать методом такого вида:

$target = $desk->getJumpPosition($pos)

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

> if (100 - $lastPosition < $roll) {


Если записать условие в виду $lastposition + $roll > 100 то понять будет гораздо проще.

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


> $zone[] = $k++;


Есть функция range для этого

Функцию getShow можно сделать частью объекта-карты, то есть карта умеет создавать строку, изображающую ее.

> foreach ($zone as &$square) {


> foreach ($players as $player) {


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

> global $round;


> global $players;


Это надо передавать явно, а не использовать глобальные переменные.

> } while ($player->isWinner == 0);


это условие не сработат так как там стоит return выше, а если бы ретурна не было, оно было бы неприавльным так как проверяет только последнего игрока. а не всех.
#201 #422333
>>422154

$0 это даже не настоящая переменная, так как ты не можешь написать например

echo $0;

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

>>422107

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

> global $desk;


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

Также, вот этот код

> oreach ($desk->cases as $key => $value) {


> if ($this->position == $key) {


Стоит перенести в Desk и сделать методом такого вида:

$target = $desk->getJumpPosition($pos)

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

> if (100 - $lastPosition < $roll) {


Если записать условие в виду $lastposition + $roll > 100 то понять будет гораздо проще.

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


> $zone[] = $k++;


Есть функция range для этого

Функцию getShow можно сделать частью объекта-карты, то есть карта умеет создавать строку, изображающую ее.

> foreach ($zone as &$square) {


> foreach ($players as $player) {


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

> global $round;


> global $players;


Это надо передавать явно, а не использовать глобальные переменные.

> } while ($player->isWinner == 0);


это условие не сработат так как там стоит return выше, а если бы ретурна не было, оно было бы неприавльным так как проверяет только последнего игрока. а не всех.
#202 #422339
>>422087

Скобки в регулярке нужны, во-первых, чтобы сгруппировать символы, смотри:

abc+ значит «a», за ней «b», за ней 1 или больше «с». То есть соответствует строкам abc, abcc, abccc, abccccccc

Теперь добавим скобки:

a(bc)+ значит «a», за ней одна или больше пар букв «bc» то есть это строки abc, abcbc, abcbcbc, abcbcbcbcbc

Другой пример:

abc|d|e значит «или abc, или d или e»

Добавим скобки:

ab(c|d|e) — это значит буквы «ab», за ними либо c либо d либо e. То есть соответтсвует строкам abc, abd, abe.

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

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

ab(c|d|e) — напомню, она ищет строки abc, abd, abe

После того как регулярка найдет текст, она запомнит то, что попало в скобки (то есть одну из букв c, d, e). Если ты в выраждении для замены напишешь $1 то вместо этого подставится текст запомненный первой парой скобок:

$text = "hhhh abd hhhh";

// заменяет строки abc, abd, abe на cxy, dxy, exy cоответственно
$result = preg_replace('/ab(c|d|e)/u', '$1xy', $text);
echo $result; // hhhhhh dxy hhhhh

То есть $1 заменилось на букву, которая попала в скобки.

Если у тебя больше пар скобок, то $2 соответствует вторым скобкам, $3 третьим, и тд. А $0 соответствует всему найденному регуляркой тексту.

Попробуй выполнить этот пример на ideone и поменять там что-нибудь чтобы понять как эти $1, $2 работают.

Если что-то непонятно, задавай вопросы.
#202 #422339
>>422087

Скобки в регулярке нужны, во-первых, чтобы сгруппировать символы, смотри:

abc+ значит «a», за ней «b», за ней 1 или больше «с». То есть соответствует строкам abc, abcc, abccc, abccccccc

Теперь добавим скобки:

a(bc)+ значит «a», за ней одна или больше пар букв «bc» то есть это строки abc, abcbc, abcbcbc, abcbcbcbcbc

Другой пример:

abc|d|e значит «или abc, или d или e»

Добавим скобки:

ab(c|d|e) — это значит буквы «ab», за ними либо c либо d либо e. То есть соответтсвует строкам abc, abd, abe.

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

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

ab(c|d|e) — напомню, она ищет строки abc, abd, abe

После того как регулярка найдет текст, она запомнит то, что попало в скобки (то есть одну из букв c, d, e). Если ты в выраждении для замены напишешь $1 то вместо этого подставится текст запомненный первой парой скобок:

$text = "hhhh abd hhhh";

// заменяет строки abc, abd, abe на cxy, dxy, exy cоответственно
$result = preg_replace('/ab(c|d|e)/u', '$1xy', $text);
echo $result; // hhhhhh dxy hhhhh

То есть $1 заменилось на букву, которая попала в скобки.

Если у тебя больше пар скобок, то $2 соответствует вторым скобкам, $3 третьим, и тд. А $0 соответствует всему найденному регуляркой тексту.

Попробуй выполнить этот пример на ideone и поменять там что-нибудь чтобы понять как эти $1, $2 работают.

Если что-то непонятно, задавай вопросы.
#203 #422341
>>422087

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

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

http://php.net/manual/ru/regexp.reference.subpatterns.php
http://php.net/manual/ru/function.preg-replace.php
#204 #422345
>>422067

> А как вывести сообщение, что именно в том месте ошибка - не знаю.


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

Советую также глянуть мануал по этой функции.

>>421982

Псевдокласс :checked соответвуте нажатому input. То есть тут

input {
стили применяются ко всем инпутам;
}

а тут

input:checked {
стили применяются только к нажатым инпутам;
}

Насчет знака +, это селектор соседей, то есть

a + b { стили }

Применит стили к b только если его предыдущий сосед это a. Соответственно

a + b + c + d { .. }

Применяет стили к d если если прыдыдущий сосед в DOM это c, предыдущий для с это b, предыдущий сосед для b это a.

Если тебе не очень понятно «предыдущий сосед», то почитай тут про DOM и как узлы в нем относятся друг к другу: http://learn.javascript.ru/traversing-dom#parentnode-previoussibling-и-nextsibling

previousNode из той статтьи это и есть «предыдущий сосед».

Ну например вот в этом дереве правило a + b { стили } применится только к одному из тегов b:

<x>...</x>
<b>сюда не применится</b>
<a> ... <x> ... </x> ... </a>
<b> сюда применится </b>
<a> ... </a>
<d> ... </d>
<b> сюда нет </b>
#204 #422345
>>422067

> А как вывести сообщение, что именно в том месте ошибка - не знаю.


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

Советую также глянуть мануал по этой функции.

>>421982

Псевдокласс :checked соответвуте нажатому input. То есть тут

input {
стили применяются ко всем инпутам;
}

а тут

input:checked {
стили применяются только к нажатым инпутам;
}

Насчет знака +, это селектор соседей, то есть

a + b { стили }

Применит стили к b только если его предыдущий сосед это a. Соответственно

a + b + c + d { .. }

Применяет стили к d если если прыдыдущий сосед в DOM это c, предыдущий для с это b, предыдущий сосед для b это a.

Если тебе не очень понятно «предыдущий сосед», то почитай тут про DOM и как узлы в нем относятся друг к другу: http://learn.javascript.ru/traversing-dom#parentnode-previoussibling-и-nextsibling

previousNode из той статтьи это и есть «предыдущий сосед».

Ну например вот в этом дереве правило a + b { стили } применится только к одному из тегов b:

<x>...</x>
<b>сюда не применится</b>
<a> ... <x> ... </x> ... </a>
<b> сюда применится </b>
<a> ... </a>
<d> ... </d>
<b> сюда нет </b>
#205 #422349
>>421854

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

По SQL коду

> `sex` enum('М','Ж')


Принято для ENUM использовать латинницу, так как это что-то вроде константы. Например MALE/FEMALE или M/F

> sname


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

`sname` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Фамилия студента' ....

> DEFAULT NULL,


Обычно NOT NULL значит что поле обязательно для заполнения, а NULL что необязательно. У тебя имя и фамилию необязатаельно указывать?

> ENGINE=MyISAM


Лучше использовать тип хранилища InnoDB. Она новее и имеет больше возможностей, поддерживает внешние ключи и транзакции. Подробное сравнение:

http://itif.ru/otlichiya-myisam-innodb/

По коду:

> $student = new student;


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

Класс должен быть описан в файле, совпадающем с его именем. Например класс Student уместно положить в файл Student.php. В одном файле должен описываться ровно один класс. Класс StudentMapper должен быть в файле StudentMapper.php

В файле с классом не должно быть постороннего кода вроде такого: https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L105

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L22


> ORDER BY $sort");


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

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L26


Это непраивльно с точки зрения архитектуры. Класс DataMapper умеет делать только одну вещь: загружать студентов из базы и сохранять ихз в базу. Ни при каких обстоятельствах он не должен ничего выводить на экран. Также, весь HTML код должен располагаться в шаблонах. За их пределами не должно быть ни одного echo.

Разумеется, Mapper также не должен обращаться к кукам.

> public function showStudents($sort, $class){


Здесь тоже архитектурная ошибка: ты не должен передавть аргумент class. Зачем его передавать? Эта функция создает только студентов и никакие другие объекты она создавать не должна.

Также, ошибка, ты создал 2 класса, обозначающих одно и то же: student и profile. Они оба содержат информацию о студенте. Раз так, надо объединить их в один класс, соответствующий студенту, незачем делать 2 класса для одной и той же сущности.

> https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L3


Есди ты хочешь сделать константу, делай не глобальную константу, а константу внутри класса: http://php.net/manual/ru/language.oop5.constants.php

https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L16 — тут слишком длинная строка, запиши массив вертикально на несколько строк.

Также, в файле profileclass съехало форматирование, надо пропустить его через phpformatter.com ибо читать тяжело (и другие файлы где съехало форматирование тоже). Если ты используешь IDE, там есть горячие клавиши для форматирования: https://gist.github.com/codedokode/8759492

> https://github.com/MindiMakridi/Students/blob/master/index.php#L38


Я думаю, лушче тут оставить только один include, а первый файл подключить из main.html

> https://github.com/MindiMakridi/Students/blob/master/lib/functions.php#L4


Не надо тут писать return $x = $y; Надо писать либо так:

return $y;

либо так:

$x = $y;
return $x;

То есть не надо складывать 2 команды в одну строку.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L59


Здесь ты передаешь информацию о студенте в массиве. Но у нас же есть класс (точнее 2 класса) описывающих студента. Значит, незачем использовать массив, надо передавать объект класса Student.

> https://github.com/MindiMakridi/Students/blob/master/templates/main.html#L14


Шаблон предназначен для вывода переданных ему данных. Он не должен лезть в другие данные типа POST/GET и тем более не должен ничего загружать из базы — это не его задача. Это должно делаться в index.php

Это https://github.com/MindiMakridi/Students/blob/master/templates/template.html#L2 тоже надо вынести из шаблона куда-нибудь в index.php или аналогичный файл.

> <?php echo


Это лучше писать короче как <?= $x ?> (короткие теги используются только для вывода, а для остального исплоьзуй длинные <?php)

Шаблоны Students/templates/profile.html и Students/templates/register.html содержат копипасту. Надо избавиться от дублирования похожего кода, так как это очень плохая вещь, и объединить их в один файл без повторов.

Куки выставляются, как известно, отдачей HTTP-заголовка Set-Cookie. Заголовки в протоколе HTTP идут до тела ответа, потому если ты вывел хоть один пробел, заголовок (и куки) выставить уже нельзя. Потому вот эта строчка: https://github.com/MindiMakridi/Students/blob/master/profile.php#L46 работать не будет.

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

Пока как-то так. Жду исправлений и вопросов если что-то непонятно. Это наверно непросто все исправить, но зато твой код станет гораздо лучше, а это самое важное.
#205 #422349
>>421854

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

По SQL коду

> `sex` enum('М','Ж')


Принято для ENUM использовать латинницу, так как это что-то вроде константы. Например MALE/FEMALE или M/F

> sname


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

`sname` varchar(20) COLLATE utf8_unicode_ci DEFAULT NULL COMMENT 'Фамилия студента' ....

> DEFAULT NULL,


Обычно NOT NULL значит что поле обязательно для заполнения, а NULL что необязательно. У тебя имя и фамилию необязатаельно указывать?

> ENGINE=MyISAM


Лучше использовать тип хранилища InnoDB. Она новее и имеет больше возможностей, поддерживает внешние ключи и транзакции. Подробное сравнение:

http://itif.ru/otlichiya-myisam-innodb/

По коду:

> $student = new student;


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

Класс должен быть описан в файле, совпадающем с его именем. Например класс Student уместно положить в файл Student.php. В одном файле должен описываться ровно один класс. Класс StudentMapper должен быть в файле StudentMapper.php

В файле с классом не должно быть постороннего кода вроде такого: https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L105

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L22


> ORDER BY $sort");


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

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L26


Это непраивльно с точки зрения архитектуры. Класс DataMapper умеет делать только одну вещь: загружать студентов из базы и сохранять ихз в базу. Ни при каких обстоятельствах он не должен ничего выводить на экран. Также, весь HTML код должен располагаться в шаблонах. За их пределами не должно быть ни одного echo.

Разумеется, Mapper также не должен обращаться к кукам.

> public function showStudents($sort, $class){


Здесь тоже архитектурная ошибка: ты не должен передавть аргумент class. Зачем его передавать? Эта функция создает только студентов и никакие другие объекты она создавать не должна.

Также, ошибка, ты создал 2 класса, обозначающих одно и то же: student и profile. Они оба содержат информацию о студенте. Раз так, надо объединить их в один класс, соответствующий студенту, незачем делать 2 класса для одной и той же сущности.

> https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L3


Есди ты хочешь сделать константу, делай не глобальную константу, а константу внутри класса: http://php.net/manual/ru/language.oop5.constants.php

https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L16 — тут слишком длинная строка, запиши массив вертикально на несколько строк.

Также, в файле profileclass съехало форматирование, надо пропустить его через phpformatter.com ибо читать тяжело (и другие файлы где съехало форматирование тоже). Если ты используешь IDE, там есть горячие клавиши для форматирования: https://gist.github.com/codedokode/8759492

> https://github.com/MindiMakridi/Students/blob/master/index.php#L38


Я думаю, лушче тут оставить только один include, а первый файл подключить из main.html

> https://github.com/MindiMakridi/Students/blob/master/lib/functions.php#L4


Не надо тут писать return $x = $y; Надо писать либо так:

return $y;

либо так:

$x = $y;
return $x;

То есть не надо складывать 2 команды в одну строку.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L59


Здесь ты передаешь информацию о студенте в массиве. Но у нас же есть класс (точнее 2 класса) описывающих студента. Значит, незачем использовать массив, надо передавать объект класса Student.

> https://github.com/MindiMakridi/Students/blob/master/templates/main.html#L14


Шаблон предназначен для вывода переданных ему данных. Он не должен лезть в другие данные типа POST/GET и тем более не должен ничего загружать из базы — это не его задача. Это должно делаться в index.php

Это https://github.com/MindiMakridi/Students/blob/master/templates/template.html#L2 тоже надо вынести из шаблона куда-нибудь в index.php или аналогичный файл.

> <?php echo


Это лучше писать короче как <?= $x ?> (короткие теги используются только для вывода, а для остального исплоьзуй длинные <?php)

Шаблоны Students/templates/profile.html и Students/templates/register.html содержат копипасту. Надо избавиться от дублирования похожего кода, так как это очень плохая вещь, и объединить их в один файл без повторов.

Куки выставляются, как известно, отдачей HTTP-заголовка Set-Cookie. Заголовки в протоколе HTTP идут до тела ответа, потому если ты вывел хоть один пробел, заголовок (и куки) выставить уже нельзя. Потому вот эта строчка: https://github.com/MindiMakridi/Students/blob/master/profile.php#L46 работать не будет.

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

Пока как-то так. Жду исправлений и вопросов если что-то непонятно. Это наверно непросто все исправить, но зато твой код станет гораздо лучше, а это самое важное.
#206 #422352
>>421667

Я погуглил по «pchart tick interval», «tick step» и вот что нашел:

http://stackoverflow.com/a/11170944
http://stackoverflow.com/questions/10436596/pchart-x-axis-too-many-ticks

Посмотри там примеры кода, может поможет?

>>421662

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

Насчет ООП, в принципе он там объясняется, у Зандстры, довольно подробно.

>>421658

> Но в первой книге 2006 года написано, что она на версию 5.0


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

>>421582

С Апачем проще так как большинство используют php именно так и легче найти ответы на вопросы. а с IIS я никогда не работал.

>>421575

Это задача на понимание регулярок, так что давай для интереса сделаем ее чисто на регулярке? Без str_replace?

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

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

Правильные: 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' // нет +
);

Сделай чтобы программа брала по очереди номера и проверяла их.
#206 #422352
>>421667

Я погуглил по «pchart tick interval», «tick step» и вот что нашел:

http://stackoverflow.com/a/11170944
http://stackoverflow.com/questions/10436596/pchart-x-axis-too-many-ticks

Посмотри там примеры кода, может поможет?

>>421662

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

Насчет ООП, в принципе он там объясняется, у Зандстры, довольно подробно.

>>421658

> Но в первой книге 2006 года написано, что она на версию 5.0


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

>>421582

С Апачем проще так как большинство используют php именно так и легче найти ответы на вопросы. а с IIS я никогда не работал.

>>421575

Это задача на понимание регулярок, так что давай для интереса сделаем ее чисто на регулярке? Без str_replace?

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

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

Правильные: 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' // нет +
);

Сделай чтобы программа брала по очереди номера и проверяла их.
#207 #422354
>>421538

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

>>421462

Насчет яваскрипта, я еще немного подумал, и все же не уверен, нужны ли нам там класссы Вопрос/Ответ. Я думаю так: у нас вся информация о вопросах/ответов фактически хранится в множестве инпутов. Стоит ли делать класс который ее будет дублировать, писать сложные методы для синхронизации этой информации в обе стороны(между классом и формой)? Не проще ли тут сделать несколько функций типа ПереключитьТипВопроса, ДобавитьВариантОтвета, без построения дерева всех вопросов и ответов?

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

Ну и насчет сложной работы с id, это надо как-то убирать в функции вроде такой:

var deletBtn = getQuestionDeleteButton(questionNode);

Ну и искать наверно все же удоюнее не по сложному id, а по классу. Для этого конечно придется написать функцию поиска в DOM элемента с определенным классом. То есть например все кнопки удаления у нас помечены классом

js-delete-button (js значит что это не для CSS а для JS класс)

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

var deletBtn = findFirstByClass(question, 'js-delete-button');

В новых браузерах для поиска по классу есть querySelector и getElementsByClassName, в старых IE придется обходить все узлы-потомки и сравнивать класс.

В jQuery это пишется например так (аналогично примеру выше):

var deleteBtn = $('.js-delete-button', question);

То есть ищем узел с определенным классом внутри узла-вопроса.

> Эту функцию я планирую использовать только при создании. Хотя можно и при редактировании


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

> Я так понял, они нужны при добавлении связи для связанных уже по hasOne/hasMany классов. Т.е. классы уже связаны, а линк/анлинк нужен для уже объектов.


Я так понимаю, что link для связи один-ко-многим проставляет в одном объекте (или в табице БД?) id другого то есть как раз связывает их.

Глянь в исходники, может там можно понять?

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


Ну редактирвоать существующий удобнее:

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

> Я думаю оно перехватывается для имеющихся методов.


Если ты создал свойство answers то при обращении к нему из класса перехват работать не будет. Он же на магических методах вроде _ _ get основан: http://php.net/manual/ru/language.oop5.overloading.php#object.get

> Даже для функций в одну строчку?


У тебя там раз 10 скопирован код склеивания id с номером вопроса. Это копипаста логики, и ее не должно быть — жолжна быть функция например вычисляющая id для элемента.

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


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

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


Да это е так сложно, по моему. делаешь скрытое или видимое поле «Номер вопроса» и при смене порядка вопросов перепроставляешь все эти поля заново по возрастанию. Соответственно в PHP скрипт для каждого вопроса приходит его порядковый номер и он может их отсортировать.

> а собирать данные скриптом в json-строку и получать на сервере готовый массив по сути


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

Ну и при ошибке в JS скрипте форма все равно отправится и данные не потеряются.

Ну вообще, давай посомтрим что ты там в коде напишешь, и еще тогда подумаем, делай пока как считаешь правильным.
#207 #422354
>>421538

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

>>421462

Насчет яваскрипта, я еще немного подумал, и все же не уверен, нужны ли нам там класссы Вопрос/Ответ. Я думаю так: у нас вся информация о вопросах/ответов фактически хранится в множестве инпутов. Стоит ли делать класс который ее будет дублировать, писать сложные методы для синхронизации этой информации в обе стороны(между классом и формой)? Не проще ли тут сделать несколько функций типа ПереключитьТипВопроса, ДобавитьВариантОтвета, без построения дерева всех вопросов и ответов?

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

Ну и насчет сложной работы с id, это надо как-то убирать в функции вроде такой:

var deletBtn = getQuestionDeleteButton(questionNode);

Ну и искать наверно все же удоюнее не по сложному id, а по классу. Для этого конечно придется написать функцию поиска в DOM элемента с определенным классом. То есть например все кнопки удаления у нас помечены классом

js-delete-button (js значит что это не для CSS а для JS класс)

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

var deletBtn = findFirstByClass(question, 'js-delete-button');

В новых браузерах для поиска по классу есть querySelector и getElementsByClassName, в старых IE придется обходить все узлы-потомки и сравнивать класс.

В jQuery это пишется например так (аналогично примеру выше):

var deleteBtn = $('.js-delete-button', question);

То есть ищем узел с определенным классом внутри узла-вопроса.

> Эту функцию я планирую использовать только при создании. Хотя можно и при редактировании


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

> Я так понял, они нужны при добавлении связи для связанных уже по hasOne/hasMany классов. Т.е. классы уже связаны, а линк/анлинк нужен для уже объектов.


Я так понимаю, что link для связи один-ко-многим проставляет в одном объекте (или в табице БД?) id другого то есть как раз связывает их.

Глянь в исходники, может там можно понять?

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


Ну редактирвоать существующий удобнее:

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

> Я думаю оно перехватывается для имеющихся методов.


Если ты создал свойство answers то при обращении к нему из класса перехват работать не будет. Он же на магических методах вроде _ _ get основан: http://php.net/manual/ru/language.oop5.overloading.php#object.get

> Даже для функций в одну строчку?


У тебя там раз 10 скопирован код склеивания id с номером вопроса. Это копипаста логики, и ее не должно быть — жолжна быть функция например вычисляющая id для элемента.

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


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

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


Да это е так сложно, по моему. делаешь скрытое или видимое поле «Номер вопроса» и при смене порядка вопросов перепроставляешь все эти поля заново по возрастанию. Соответственно в PHP скрипт для каждого вопроса приходит его порядковый номер и он может их отсортировать.

> а собирать данные скриптом в json-строку и получать на сервере готовый массив по сути


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

Ну и при ошибке в JS скрипте форма все равно отправится и данные не потеряются.

Ну вообще, давай посомтрим что ты там в коде напишешь, и еще тогда подумаем, делай пока как считаешь правильным.
#208 #422355
>>421361

Если width не указывать то он равен auto и для блочных элементов это значит занять всю доступную ширину (за вычетом маргинов). Тебе явно надо прочесть и понять например эту статью:

http://softwaremaniacs.org/blog/2005/08/27/css-layout-flow/
http://softwaremaniacs.org/blog/2005/07/08/css-boxes/

>>421328

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

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

Задавай вопросы. если что непонятно.
#209 #422356
Все аноны, увидимся завтра вечером. Решайте задачки.
#210 #422397
>>422349

>Также, ошибка, ты создал 2 класса, обозначающих одно и то же: student и profile.


>Здесь ты передаешь информацию о студенте в массиве. Но у нас же есть класс (точнее 2 класса) описывающих студента. Значит, незачем использовать массив, надо передавать объект класса Student


Так мне удалять класс Student или нет? Если да, то наверное массив все-таки нужен?

>Шаблоны Students/templates/profile.html и Students/templates/register.html содержат копипасту. Надо избавиться от дублирования похожего кода, так как это очень плохая вещь, и объединить их в один файл без повторов.


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

Кстати, слышал про такую штуку - Smarty. Ей вообще пользуются, или уже неактуально?
#211 #422463
>>422328
Да, я помню этот хинт из твоего учебника, но решил здесь воспользоваться вот этим способом для нубов, просто потому что лень было открывать учебник в поисках решения через preg_split
#212 #422665
ОП и другие прошаренные. Что нужно прочесть и задрочить, чтобы пойти на собеседование на эту вакансию? http://career.ru/vacancy/11974106
#213 #422667
>>422665

Там же ясно написано в требованиях.
#214 #422668
>>422667
Ну я к тому, что должно входить в этот начальный уровень? Вот берем php, что мне нужно знать, чтобы был этот начальный уровень?
#215 #422669
>>422668
Пройти учебник ОПа, например (есть подозрения, что ты даже не открывал его). Если осилишь, можно пробовать ходить на собеседования.
В идеале: хотя бы половину из того, что пишет оп здесь http://archive-ipq-co.narod.ru/tsuzuke.html
#216 #422671
>>422669
открывал, как раз и хочу его пройти.
Есть еще пол года времени, думаю хоть что-то выучить, сраная бизнес-информатика.
#217 #422672
>>422671
Кстати это еще скромные требования в той вакансии.
Я из Украины, тут ситуация похуже: или ищут суперопытного мидла/сеньора, или контент-манагеры с гребанными cms.
Планирую в феврале пойти поумолять кого-нибудь взять меня джуниором за еду. Буду работать за копейки, лишь бы получить реальный опыт.
#218 #422677
>>422397

> Так мне удалять класс Student или нет?


Объединить классы profile и student в один класс Student

> Если да, то наверное массив все-таки нужен?


Не нужен

> Я пока представляю как это сделать только вставкой внутрь тегов переменных пхп,


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



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

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

При редактировании передаем взятого из базы студента. При создании нового − создаем нового пустого (и потому поля тоже будут пустые). При отправке формы с ошибками мы из POST данные переносим в студента и передаем его + список ошибок.

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


Перенести вывод шаблона в самый конец

> Кстати, слышал про такую штуку - Smarty. Ей вообще пользуются, или уже неактуально?


Это шаблонизатор. Им пользуются, но есть более новые и удобные вроде twig. Лучше его изучать. Если есть желание, можно потом переделать эту задачу на использование твига или сделать следующую, на файлообменник, с твигом. Думаю, лучше в следующем задании его использовать.

>>422463

Тогда ок. Я написал на тот случай, если ты не знал.
#218 #422677
>>422397

> Так мне удалять класс Student или нет?


Объединить классы profile и student в один класс Student

> Если да, то наверное массив все-таки нужен?


Не нужен

> Я пока представляю как это сделать только вставкой внутрь тегов переменных пхп,


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



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

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

При редактировании передаем взятого из базы студента. При создании нового − создаем нового пустого (и потому поля тоже будут пустые). При отправке формы с ошибками мы из POST данные переносим в студента и передаем его + список ошибок.

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


Перенести вывод шаблона в самый конец

> Кстати, слышал про такую штуку - Smarty. Ей вообще пользуются, или уже неактуально?


Это шаблонизатор. Им пользуются, но есть более новые и удобные вроде twig. Лучше его изучать. Если есть желание, можно потом переделать эту задачу на использование твига или сделать следующую, на файлообменник, с твигом. Думаю, лучше в следующем задании его использовать.

>>422463

Тогда ок. Я написал на тот случай, если ты не знал.
#219 #422678
>>422665

Я думаю надо знать указанные технологии на уровне «сделать простой сайтик вроде такого»: https://gist.github.com/codedokode/d7e7f11449fc3bcb24b4

Также, могут на собеседовании поспрашивать теоретические вопросы вроде «что выведет этот код» или «что такое транзакция». Насчет PHP, стоит просто прочесть раздел «справочник по языку» в мануале php чтобы знать ответы на каверзные вопросы.

Ну и ООП надо знать, и хорошо бы иметь опыт работы с каким-нибудь фреймворком (в задании на файлообменник мы например используем Слим, в задании на testHub - Yii 2).

Вообще, у меня ощущение что там требования будут не очень высокие, так как грамотного человека найти сложно. Те, кто прошел мой учебник и дополнительные задания, наверняка бы прошли собеседования.
#220 #422680
>>422672

Имей в виду, что если ты кроме работы не будшь читать документацию и что-то изучать, скорее всего много знаний у тебя не отложится.
#221 #422684
>>422680
Это я понимаю. Но и без опыта практической работы сложно надеяться куда-то устроиться.
Согласитесь, что если меня на собеседовании попросят написать к примеру корзину магазина или rss-ленту, а я скажу, что умею только решать задачки про японских девочек со считалочкой, то, как говорят в Одессе, с меня таки смеяться будут!

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

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


Звучит обнадеживающе.
А вот вам пример вакансии, травмирующей психику бедного хикки:

Junior(!) PHP Developer
Требуется:
PHP 5/LAMP
HTML, CSS
ООП
Zend Framework
SQL development
Linux command line
JavaScript, Ajax/JSON, jQuery
PHPUnit; Subversion (SVN)
Приветствуется:
- опыт работы с любой системой распределения версий
- опыт администрирования Linux / FreeBSD.
- базовые навыки работы с графическими редакторами
- английский на уровне чтения тех.документации
- любовь к спорту: футболу, страйкболу (и играть, и смотреть)
/ ну это вообще бомба, у меня корпоративный дух в пятки ушел /

Мама, роди меня обратно! Шо такое sql development, php unit, subversion?
Пойду выпью свои капли...
#223 #422700
>>422678
ОП, а что особенного в твоем учебнике? Чем он лучше например Котерова/Костарева? Не развожу срач, мне интересно.
#224 #422709
А можно ссылку на задачки по MySQL?
#225 #422710
>>422684

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


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

https://gist.github.com/codedokode/d7e7f11449fc3bcb24b4

или такого

https://gist.github.com/codedokode/9424217

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

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

- учебник (основы PHP и ООП)
- задание на список студентов (учимся работать с формами, БД, выводить данные)
- задание на файлообменник (изучаем MVC и микрофреймворк Slim, учимся работать с файлами, может быть изучаем шаблонизатор Twig)
- какое-нибудь задание на большой фреймворк вроде Yii/Yii2/Symfony
- автоматизированное тестирование
- задания на HTML/CSS/JS/SQL (можно делать параллельно с другими) чтобы подтянуть их уровень

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

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


Наверно, но я бы назвал это «вот пример веб-приложения которое я сделал»

> я Вам на почту отписался


Ок, я там подробнее отвечу потом. Насчет заданий, что насчет 2 примеров заданий выше? Задание на список студентов выглядит просто, но даже на нем можно много разных интересных вещей изучить. А на файлообменник посложнее.
#225 #422710
>>422684

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


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

https://gist.github.com/codedokode/d7e7f11449fc3bcb24b4

или такого

https://gist.github.com/codedokode/9424217

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

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

- учебник (основы PHP и ООП)
- задание на список студентов (учимся работать с формами, БД, выводить данные)
- задание на файлообменник (изучаем MVC и микрофреймворк Slim, учимся работать с файлами, может быть изучаем шаблонизатор Twig)
- какое-нибудь задание на большой фреймворк вроде Yii/Yii2/Symfony
- автоматизированное тестирование
- задания на HTML/CSS/JS/SQL (можно делать параллельно с другими) чтобы подтянуть их уровень

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

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


Наверно, но я бы назвал это «вот пример веб-приложения которое я сделал»

> я Вам на почту отписался


Ок, я там подробнее отвечу потом. Насчет заданий, что насчет 2 примеров заданий выше? Задание на список студентов выглядит просто, но даже на нем можно много разных интересных вещей изучить. А на файлообменник посложнее.
#226 #422711
>>422689

> sql development


думаю это значит «работа с базами данных», скорее всего не с любыми а MySQL или PostgreSQL. У нас есть задания на MySQL c полезными ссылками: https://gist.github.com/codedokode/10539213

> php unit


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

Там вообще есть много видов тестирования. Вот мой урок про автоматизированное тестирование: https://gist.github.com/codedokode/a455bde7d0748c0a351a

> subversion


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

Подробнее: http://svnhowto.com
https://ru.wikipedia.org/wiki/Subversion

SVN довольно старый, сейчас чаще использут git, по нему есть хорошая книга: http://git-scm.com/book/ru/v1

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

В общем, не надо пугаться, все это реально изучить. Да и там вряд ли требуются глубокие знания.
#227 #422715
>>422689

Алсо, странно сочтается «требуется знать SVN» и «приветствуется опыт работы с любой системой распределения версий».

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

> ну это вообще бомба, у меня корпоративный дух в пятки ушел


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

Насчет linux command line, можно установить debian (или ubuntu если все плохо) в VirtualBox и там осваивать команды bash + базовые команды вроде cat/grep и тд.

>>422700

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

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

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

>>422709

https://gist.github.com/codedokode/10539213
#228 #422721
Посоны, есть два стула: на одном фронтенд точеный, на другом бэкенд дроченый. На какой самому сесть, на какой коллегу посадить?
#229 #422725
>>422715
Я уже учил по другому, но думаю полистать твой. Может обнаружу для себя что-то новое.
#230 #422731
>>422721

> на одном фронтенд точеный, на другом бэкенд дроченый


Ты всё перепутал.
#231 #422737
>>422725
Если ты обнаружишь что-то новое в задачках на условия/циклы/основы ооп - то ты очень плохо читал предыдущий учебник.
#232 #422768
Ничего не понимаю. Все работало с query и прямой подставкой переменных. Почему вот так не работает:

$STH = $this->DBH->prepare("SELECT name, sname, groupindex, points FROM students ORDER BY :sort");
\t
\t$STH->bindparam(":sort", $sort);
\t
\t
\t$STH->execute();
#233 #422771
>>422768
А что в $sort хранится-то?
#234 #422772
>>422771
В $sort поле, по которому сортируем. Оно передается методу.
#235 #422773
Так же я не пойму вот этого

>Это непраивльно с точки зрения архитектуры. Класс DataMapper умеет делать только одну вещь: загружать студентов из базы и сохранять ихз в базу. Ни при каких обстоятельствах он не должен ничего выводить на экран



fetch никуда не сохраняет данные, вернуть их через return я тоже не могу, потому-что он отдаст мне только первую строку. Как же без echo внутри метода выводить всю таблицу?
#236 #422778
>>422768
А еще вангую, что bindparam содержимое $sort в кавычках вставит в запрос.
#238 #422782
>>422779
Можно еще привязать поля результата выборки к локальным переменным, с которыми и манипулировать. Например, в этом кусочке у меня фетчится результат выборки последних записей в базе данных чатика и массив наполняется объектами, потом массив преобразуется в json-строку:
mysqli_stmt_execute($this->stmt);
mysqli_stmt_bind_result($this->stmt, $id, $name, $msg, $date);
while(mysqli_stmt_fetch($this->stmt)){
$this->response[] = new Post($id, $name, $msg, date('d-m-Y H:i:s', $date));
}
//...
echo json_encode($db->response);

Извиняюсь за суржик из проц. и ооп-стиля.

>>422710
Аригато! Не видел, что есть еще дополнительные уроки в блоге на гитхабе.
Этого должно хватить на пару дней.

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


Я так понимаю, base64 для сайта вуза за глаза хватит? Тем более вроде бы даже md5 можно расшифровать. Какую технику сейчас используется для безопасности?
#239 #422785
>>422782

>Этого должно хватить на пару дней


hahaohlol.jpg
#240 #422790
>>422333
Мне уже много раз говорили, что глобальные переменные это плохо, но никто не пишет почему :<
#241 #422793
>>422790
Напиши в гугле "почему глобальные переменные плохо" и читай любую ссылку.
#242 #422798
>>422790
Ну например, чтобы если вдруг захочется взять и вынести какую-нибудь функцию в отдельную библиотеку. В этом суть юникс-вея - писать маленькие программы, которые могут принимать что-то на вход и так же выдают на выход. Как видишь, никаким глобальным переменным тут места не остается.
#243 #422801
>>422779
Ну так это на одну итерацию. Короче, я так понял, нужно создавать массив, и в каждой итерации добавлять в этот массив данные. Но, если таблица большая, не многовато ли будет для массива?
#244 #422804
>>422801

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


http://php.net/manual/ru/pdostatement.fetchall.php
Ты же даже не пытаешься, да?
#245 #422806
>>422798

>никаким глобальным переменным тут места не остается


А глобальным константам?
#246 #422807
>>422806
Константы класса тебя чем-то не устраивают?
#247 #422818
>>419972
ОП, думаю как реализовать прохождение теста, а конкретней - отображение вопросов при прохождении, на тестхабе. Понравилось как это сделал яндекс https://ege.yandex.ru/chemistry/game/#question=1. То есть, как я понял, применяется AJAX и hash-навигация. Пока что не нашел ничего нормального и нового почитать по этой теме. И да, что-то мне подсказывает, IE будет против таких замечательных технологий. Можешь что-то посоветовать, какие-то статьи хотя бы.
#248 #422841
А где условие testHub? Хочу сделать за выходные
#249 #422843
>>422841
https://gist.github.com/codedokode/8733007

>Хочу сделать за выходные


У меня для тебя плохие новости.
#250 #422846
>>422354

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


Сложные методы для синхронизации номера вопроса и его айди в $_POST['questions'].
Я забил на это и переделал все без классов. Ну и по мелочи изменения в контроллере и моделях.
https://github.com/sqghub/TestHub
#251 #422857
>>422843
Лол да
Мне наверное тупо лень будет столько кода писать бесплатно
Но попробую чо
#252 #422875
>>422333
http://ideone.com/e3aBs4

> } while ($player->isWinner == 0);


Я не придумал как можно зациклить бесконечно, сделал так, но чтобы изнутри цикл завершался так как мне нужно.
#253 #422884
Задача поиска пути последняя из алгоритмических и нубских? Что-то она мне кажется очень сложной на фоне нескольких предыдущих, особенно на фоне окружности.
#254 #422886
>>422884
Довольно сложная. Сложнейшая в учебнике по моему, на ряду с кошкомышками.
#255 #422905
Может кто в двух словах про параметризованные запросы к mysql в двух словах пояснить?
#256 #422921
>>422905
что тебе непонятно?
#257 #422936
Ребята, подскажите у кого есть опыт.

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

Вопрос такой, не наебнется ли активация если разрешать программе обновляться? А то ссу чето после боев с Adobe.
#258 #422939
#259 #422941
ОП и прошаренные, почему "трупогромисты" так хейтят пхп и за яп не считают? Выебываются? Давайте со всей самокритикой пж.
#260 #422942
>>422721

Оба. Начать можно с фронтенда.

>>422737

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

>>422768

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

ORDER BY 'name'

вместо правильного

ORDER BY name

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

> fetch никуда не сохраняет данные


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

>>422782

> Можно еще привязать поля результата выборки к локальным переменным,


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

Ну и насчет json_encode примененного прямо к массиву Post — я не уверен, надежно ли это? Завтра у тебя там появится какое-то поле в классе Post которое не должен видеть пользователь и что ты будешь делать? Я бы сделал у Post метод toArray который возвращает только разрешенные поля в нужном виде.

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

> Этого должно хватить на пару дней.


У тебя все в порядке с самооценкой, я смотрю. Решения покажешь?

> Я так понимаю, base64 для сайта вуза за глаза хватит? Тем более вроде бы даже md5 можно расшифровать. Какую технику сейчас используется для безопасности?


Ты неправильно мыслишь. base64 это не шифрование, это просто способ закодировать произвольные данные с помощью 64 символов.

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

Если речь о сайте про регистрацию абитуриентов то там надо применить надежную защиту. Я бы сделал так: при регистрации мы генерируем длинный уникальный код (например 32 символа), и сохраняем его в базу и в куки. Также, в куки кладем id абитуриента. Соответственно когда абитуриент заходит на сайт повтороно, по паре id + секретный код из кук мы можем определить что это именно он. Злоумышленник не сможет притвориться кем-то еще так как не знает секретный код.
#261 #422943
>>422773

> fetch никуда не сохраняет данные


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

>>422782

> Можно еще привязать поля результата выборки к локальным переменным,


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

Ну и насчет json_encode примененного прямо к массиву Post — я не уверен, надежно ли это? Завтра у тебя там появится какое-то поле в классе Post которое не должен видеть пользователь и что ты будешь делать? Я бы сделал у Post метод toArray который возвращает только разрешенные поля в нужном виде.

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

> Этого должно хватить на пару дней.


У тебя все в порядке с самооценкой, я смотрю. Решения покажешь?

> Я так понимаю, base64 для сайта вуза за глаза хватит? Тем более вроде бы даже md5 можно расшифровать. Какую технику сейчас используется для безопасности?


Ты неправильно мыслишь. base64 это не шифрование, это просто способ закодировать произвольные данные с помощью 64 символов.

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

Если речь о сайте про регистрацию абитуриентов то там надо применить надежную защиту. Я бы сделал так: при регистрации мы генерируем длинный уникальный код (например 32 символа), и сохраняем его в базу и в куки. Также, в куки кладем id абитуриента. Соответственно когда абитуриент заходит на сайт повтороно, по паре id + секретный код из кук мы можем определить что это именно он. Злоумышленник не сможет притвориться кем-то еще так как не знает секретный код.
#262 #422946
Поясните пожалуйста ОП и кротаны, как правильно написать тест в ООП который написал ОП в своём учебнике, только при помощи __construct, у меня возникает целый ряд проблем, так как надо вызывать функцию только в виде название_объекта->имя_функции не удаётся подсчитать в функции все необходимые суммы баллов, приходится считать уже после вызова функции. Вот код http://ideone.com/7SvP4Z
#263 #422949
>>422790

Недостатки становятся видны только когда кода много.

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

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

Если функция использует глобальные переменные:

$x = someFunction($a, $b, $c);

то труднее понять что окажется в $x, так как это зависит не только от a, b, c а еще и от других переменных.

Тестировать автоматизированми тестами такой код разумеется тоже становится сложнее если вообще возможно.

Потому, чтобы не запутаться по мере увеличения программы, ее стараются разбивать на маленькие независимые блоки: функции (при процедурном подходе) или классы (при ООП подходе). Без глобальных переменных.
#264 #422952
>>422801

> не многовато ли будет для массива?


нет

>>422818

hash-навигация это хорошо, так как при перезагрузке страницы не пропадает текущий номер вопроса.

Но использовать яваскрипт не обязательно, ты можешь просто сделать вопрос формой, которая постит ответ на URL вроде

/test/123456/q/12

То естьa action формы содержит id теста и номер вопроса.

В новых браузерах можно обойтись без хеша, а менять яваскриптом сам URL например /test/q/23 (а также получать событие когда пользователь переходит вперед/назад) — это называется HTML 5 History: http://habrahabr.ru/post/123106/

> IE будет против таких замечательных технологий


hash навигация работает во всех старых IE. Она вообще везде работает. Также как и классические формы.

Посоветовать, не знаю, можешь html 5 history api глянуть, но вообще тут можно сделать так, чтобы и без JS работало.А при наличии JS — работало лучше. Например, чтобы шел отсчет времени (а без JS оно бы обновлялось только при отправки формы).

Мне кажется полезно было бы реализовать «graceful degradation» то есть если нет JS все работает по простой схеме, если есть то с улучшенным удобством. Это позволяет нам сделать сайт более надежным на случай ошибки в JS или проблемах с интернетом. Ну и полезно усложнять себе жизнь.
#265 #422953
>>422941
Бамп
#266 #422970
>>422818

Только вот не уверен что хорошо объединять в одну кнопки «пропустить» и «ответить» — это может путать пользователя.

(алсо я прошел тест по химии и набрал 13%. Не мой это предмет)
#267 #422971
>>422846

Советы и замечания

> 'test' => new Test(),


> 'questionTemplate' => new Question(),


> 'answerTemplates' => Answer::getAnswersTemplates(),


> 'questionTypes' => Question::getQuestionTypes(),


> 'questionTypeLabels' => Question::getQuestionTypeLabels(),


Что-то слишком много переменных. Я думаю, можно перенести часть кода в Test (например сделать в нем метод test->getQuestionTemplate()). Также, если getQuestionTypes будет не-статическим, его тоже можно вызывать из шаблона. Ну это так, мысли, делать так не обязательно.

> <link href="/css/test-create.css" rel="stylesheet">


Запиши на будущее: разобраться со статикой (assets) в Юи. Там есть что-то встроенное чтобы подключить CSS файл к странице, есть возможности склеивания статики и много чего еще.

> id="questionType{{ questionTypes.QUESTION_WITH_ONE_CHOICE }}"


> set answerTemplatePath = "answer_type_#{questionTypes.QUESTION_WITH_ONE_CHOICE}.twig" %}


Здесь наверно не стоило использовать константу, а просто название. А то у тебя получается имя файла от значения константы зависит. И понять что значит 1 или 2, трудно. Лучше answer_type_with_one_choice.twig. Но если это сложно переделать, можешь оставить как есть.

> function addForeword(event) {


> div.innerHTML = '{{ form.field


Не стоит наверно так сложно делать, лучше наверно просто сделать див и прописать ему display:none или класс вроде js-hidden, который снимается при нажатии на кнопку. Это же меньше кода потребует и проще устроено. И можно легко сделать скрытие при повторном нажатии на ссылку.

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

// Насчет расчета curId, там нет ошибок вроде того что мы удалили первые 5 вопросов из 10, осталось 5 вопросов но у них id = 6 ... 10?

В TestController я бы перенумеровывал вопросы заново. А то от пользователя может придти (в том числе из-за какой-то ошибки) несколько вопросов с одинаковым номером или без номеров или с текстом вместо номера. Надежнее наверно отсортировать массив и перепроставить номера на стороне сервера. Также, стоит код разобра вопросов из POST вынести в отдельный метод/методы, а не писать все в один метод.

Вот тут вот нехорошо, магические числа пошли:

> https://github.com/sqghub/TestHub/blob/2a3f0471563b410adc8cfbc967ebddc22d7df801/views/test/question_with_answer.twig#L12


Достучаться до константы из твига вроде можно функцией constant: http://twig.sensiolabs.org/doc/tests/constant.html

> https://github.com/sqghub/TestHub/blob/2a3f0471563b410adc8cfbc967ebddc22d7df801/views/test/question.twig#L36


тут лучше кнопку в div завернуть

Насчет смены типа вопроса. Можно сделать еще так: разбить вопрос на несколько блоков, при смене типа вопроса менять css класс на вопросе, и из-за смена класса блоки будут скрываться/появляться. Но не знаю, будет ли это проще чем сейчас? Если нет то наверно не стоит делать.

Еще: ты удаляешь ответы при смене типа вопроса. Но мне кажется лучше, когда при смене с множественного на одиночный варианты ответов сохраняются те же (можно их копировать яваскриптом), а при смене с числового на вопрос с выбором и обратно введенный ранее ответ не теряется. Это можно сделать при использовании схемы со скрытием блоков (вместо удаления из DOM) и разных именах input для разных типов ответов. То есть на мой взгляд, скрытие вместо удаления выгоднее. Это дает нам сохранение введенных данных и проще реализуется: надо всего лишь поменять один класс. Обычно в формах, где надо скрыть/показать поля так и делают.

> var span = event.toElement;


Странное какое-то свойство. Оно стандартное (тут http://www.quirksmode.org/dom/w3c_events.html написано оно относится к mouseover)? Если ты хочешь получить ссылку на span надо писать либо

var span = event.target || event.srcElement; // w3c и старые IE соответсвенно

Либо же передавать ее через this:

<span onclick="addForeword(this)"

> function getElementsByClass(node, className) {


В новых браузерах есть querySelector, querySelectorAll, getElementsByClassName, стоит их тоже использовать если они доступны.

> https://github.com/sqghub/TestHub/blob/2a3f0471563b410adc8cfbc967ebddc22d7df801/web/js/test-create.js#L30


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

Также, плохо что переменные curId и curNumber инициализируются не в файле create-test.js (где они используются), а в другом месте. Это усложняет код. Лучше создавать их там же, и сделать функцию вроде init которую можно вызвать из шаблона чтобы задать начальные значения.

Насчет массива questionsData, а он нужен? Я вижу что там немало строк написано чтобы поддерживать его в актуальном состоянии, но если эта информация есть в DOM, может проще ее брать из инпутов чем поддерживать массив? А то у нас появляется лишняя проблема: синхронизировать этот массив с изменениями в DOM. Хотя без него, конечно, придется как-то считать questionsCount.

> event.toElement.parentNode.insertBefore


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

> https://github.com/sqghub/TestHub/blob/2a3f0471563b410adc8cfbc967ebddc22d7df801/models/Test.php#L29


Там есть удобная функция transaction http://www.yiiframework.com/doc-2.0/yii-db-connection.html для этого.

Вообще, похоже, что TestHub получилась довольно сложной задачей. Может быть на уровне опытного джуниора, может даже чуть выше. Ну что поделать, тяжело в учении. Ты пока что хорошо справляешься.
#267 #422971
>>422846

Советы и замечания

> 'test' => new Test(),


> 'questionTemplate' => new Question(),


> 'answerTemplates' => Answer::getAnswersTemplates(),


> 'questionTypes' => Question::getQuestionTypes(),


> 'questionTypeLabels' => Question::getQuestionTypeLabels(),


Что-то слишком много переменных. Я думаю, можно перенести часть кода в Test (например сделать в нем метод test->getQuestionTemplate()). Также, если getQuestionTypes будет не-статическим, его тоже можно вызывать из шаблона. Ну это так, мысли, делать так не обязательно.

> <link href="/css/test-create.css" rel="stylesheet">


Запиши на будущее: разобраться со статикой (assets) в Юи. Там есть что-то встроенное чтобы подключить CSS файл к странице, есть возможности склеивания статики и много чего еще.

> id="questionType{{ questionTypes.QUESTION_WITH_ONE_CHOICE }}"


> set answerTemplatePath = "answer_type_#{questionTypes.QUESTION_WITH_ONE_CHOICE}.twig" %}


Здесь наверно не стоило использовать константу, а просто название. А то у тебя получается имя файла от значения константы зависит. И понять что значит 1 или 2, трудно. Лучше answer_type_with_one_choice.twig. Но если это сложно переделать, можешь оставить как есть.

> function addForeword(event) {


> div.innerHTML = '{{ form.field


Не стоит наверно так сложно делать, лучше наверно просто сделать див и прописать ему display:none или класс вроде js-hidden, который снимается при нажатии на кнопку. Это же меньше кода потребует и проще устроено. И можно легко сделать скрытие при повторном нажатии на ссылку.

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

// Насчет расчета curId, там нет ошибок вроде того что мы удалили первые 5 вопросов из 10, осталось 5 вопросов но у них id = 6 ... 10?

В TestController я бы перенумеровывал вопросы заново. А то от пользователя может придти (в том числе из-за какой-то ошибки) несколько вопросов с одинаковым номером или без номеров или с текстом вместо номера. Надежнее наверно отсортировать массив и перепроставить номера на стороне сервера. Также, стоит код разобра вопросов из POST вынести в отдельный метод/методы, а не писать все в один метод.

Вот тут вот нехорошо, магические числа пошли:

> https://github.com/sqghub/TestHub/blob/2a3f0471563b410adc8cfbc967ebddc22d7df801/views/test/question_with_answer.twig#L12


Достучаться до константы из твига вроде можно функцией constant: http://twig.sensiolabs.org/doc/tests/constant.html

> https://github.com/sqghub/TestHub/blob/2a3f0471563b410adc8cfbc967ebddc22d7df801/views/test/question.twig#L36


тут лучше кнопку в div завернуть

Насчет смены типа вопроса. Можно сделать еще так: разбить вопрос на несколько блоков, при смене типа вопроса менять css класс на вопросе, и из-за смена класса блоки будут скрываться/появляться. Но не знаю, будет ли это проще чем сейчас? Если нет то наверно не стоит делать.

Еще: ты удаляешь ответы при смене типа вопроса. Но мне кажется лучше, когда при смене с множественного на одиночный варианты ответов сохраняются те же (можно их копировать яваскриптом), а при смене с числового на вопрос с выбором и обратно введенный ранее ответ не теряется. Это можно сделать при использовании схемы со скрытием блоков (вместо удаления из DOM) и разных именах input для разных типов ответов. То есть на мой взгляд, скрытие вместо удаления выгоднее. Это дает нам сохранение введенных данных и проще реализуется: надо всего лишь поменять один класс. Обычно в формах, где надо скрыть/показать поля так и делают.

> var span = event.toElement;


Странное какое-то свойство. Оно стандартное (тут http://www.quirksmode.org/dom/w3c_events.html написано оно относится к mouseover)? Если ты хочешь получить ссылку на span надо писать либо

var span = event.target || event.srcElement; // w3c и старые IE соответсвенно

Либо же передавать ее через this:

<span onclick="addForeword(this)"

> function getElementsByClass(node, className) {


В новых браузерах есть querySelector, querySelectorAll, getElementsByClassName, стоит их тоже использовать если они доступны.

> https://github.com/sqghub/TestHub/blob/2a3f0471563b410adc8cfbc967ebddc22d7df801/web/js/test-create.js#L30


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

Также, плохо что переменные curId и curNumber инициализируются не в файле create-test.js (где они используются), а в другом месте. Это усложняет код. Лучше создавать их там же, и сделать функцию вроде init которую можно вызвать из шаблона чтобы задать начальные значения.

Насчет массива questionsData, а он нужен? Я вижу что там немало строк написано чтобы поддерживать его в актуальном состоянии, но если эта информация есть в DOM, может проще ее брать из инпутов чем поддерживать массив? А то у нас появляется лишняя проблема: синхронизировать этот массив с изменениями в DOM. Хотя без него, конечно, придется как-то считать questionsCount.

> event.toElement.parentNode.insertBefore


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

> https://github.com/sqghub/TestHub/blob/2a3f0471563b410adc8cfbc967ebddc22d7df801/models/Test.php#L29


Там есть удобная функция transaction http://www.yiiframework.com/doc-2.0/yii-db-connection.html для этого.

Вообще, похоже, что TestHub получилась довольно сложной задачей. Может быть на уровне опытного джуниора, может даже чуть выше. Ну что поделать, тяжело в учении. Ты пока что хорошо справляешься.
#268 #422974
>>422857

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

>>422875

> зациклить бесконечно,


do { } while (true);

> for ($i = 0; $i <= 99; $i++)


> $zone = range(1, 100, 1);


for по моему тут лишний

Ну и еще хорошо бы при выводе карты добивать там пробелами чтобы она была ровной (а у тебя первый ряд съехал).

И еще, тут

> foreach ($this->zone as &$square) {


> foreach ($this->players as $player) {


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

А так, вообще, общее впечатление от программы хорошее, видно что все работает.
#269 #422975
>>422884

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

http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D1%83%D1%82%D0%B8

Тебе надо лишь реализовать этот алгоритм на php.

>>422886

Кошкомышки сложнее.

>>422905

Тут описано: http://habrahabr.ru/post/137664/ (prepared statements)

>>422936

Я на вопросы про взлом программ не отвечаю (да у меня и phpstorm нет). Может кто из анонов знает.

Кстати, у jetBrains можно (или уже нет?) получить бесплатную лицензионную тестовую версию, но она может быть с багами так как самая новая.

>>422941

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

У php есть конечно недостатки, но для нчинающего язык вполне подходит, и на него очень много вакансий.
#269 #422975
>>422884

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

http://ru.wikipedia.org/wiki/%D0%9F%D0%BE%D0%B8%D1%81%D0%BA_%D0%BF%D1%83%D1%82%D0%B8

Тебе надо лишь реализовать этот алгоритм на php.

>>422886

Кошкомышки сложнее.

>>422905

Тут описано: http://habrahabr.ru/post/137664/ (prepared statements)

>>422936

Я на вопросы про взлом программ не отвечаю (да у меня и phpstorm нет). Может кто из анонов знает.

Кстати, у jetBrains можно (или уже нет?) получить бесплатную лицензионную тестовую версию, но она может быть с багами так как самая новая.

>>422941

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

У php есть конечно недостатки, но для нчинающего язык вполне подходит, и на него очень много вакансий.
#270 #422976
>>422946

> не удаётся подсчитать в функции все необходимые суммы баллов


Это потому что у тебя есть класс Quest (Вопрос) объект которого представляет один вопрос. И разумеется этот объект-вопрос может посчитать только число баллов за себя, он не может приплюсовать баллы за другие вопросы так как за них отвечают другие объекты. Так что ничего не поделать, надо считать сумму отдельно, а не внутри класса.

> PHP Notice: Undefined variable: totalPoints in /home/2y8gpV/prog.php on line 51


У тебя там ошибка, ты не задал для переменной начальное значение

Ну и не стоит сокращать названия, тяжело становится читать код. Если тебе неудобно писать большие решения на ideone то скачай редактор или IDE с функцией автодополнения и пиши там.

Также, пропусти код через phpformatter.com, а то все куда-то съехало.

В остальном, вроде все верно.
#271 #422999
Пацаны, стоит ли учить пхп в 2015 году?
sage #272 #423006
>>422975
Википидор, что ли? Какая мерзость...
#273 #423014
>>422971

>// Насчет расчета curId, там нет ошибок вроде того что мы удалили первые 5 вопросов из 10, осталось 5 вопросов но у них id = 6 ... 10?


Это не ошибка. Я отвязал id вопросов от их номеров. За номер вопроса другая переменная отвечает. И просто инпут.

>В TestController я бы перенумеровывал вопросы заново.


Это и планируется. Просто я вчера только с js разбирался.

>Также, стоит код разобра вопросов из POST вынести в отдельный метод/методы, а не писать все в один метод.


Вот только к чему приткнуть этот метод?

>Достучаться до константы из твига вроде можно функцией constant


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

>Но не знаю, будет ли это проще чем сейчас?


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

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


Да, наверное так и сделаю.

>Там есть удобная функция transaction


Что-то я профукал её.

>Ты пока что хорошо справляешься.


Неправда. Я пока с яваскриптом воюю, а вместо php кода у меня одна заглушка сплошная.
#274 #423020
>>422974

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


Ок, уговорил
#275 #423033
Подскажете в чем различие между этими аргументами.

'w' Открывает файл только для записи; помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует - пробует его создать.
'w+' Открывает файл для чтения и записи; помещает указатель в начало файла и обрезает файл до нулевой длины. Если файл не существует - пытается его создать.

В описании разница только в одном слове, да и те синонимы. А в чем различия на самом деле?
#276 #423037

> почему "трупогромисты" так хейтят пхп и за яп не считают? Выебываются?



Потому что на пыхе много таких вот "программистов", хотя это и не вина языка.

>>423033

'w'\tOpen for writing only; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
'w+'\tOpen for reading and writing; place the file pointer at the beginning of the file and truncate the file to zero length. If the file does not exist, attempt to create it.
#277 #423040
>>422349
Вот еще с одной проблемой столкнулся. Когда я поставил в setFetchMode строку с именем класса вместо функции getClassName мне стал выдавать ошибку Object of class student could not be converted to string. Не понимаю с чего бы это? И так и так там была строка с именем класса, только до этого она вставлялась из переменной, а сейчас я пишу её напрямую.
#278 #423045
>>422974
Спасибо, доделал. Попробую со своими скудными знаниями в html запилить какую-никакую оболочку
#279 #423047
>>423040
А все разобрался, дело вообще в другом было.
#280 #423056
>>423037
Пиздец я засиделся. Минуту вчтитывался прежде чем запостить, а сейчас увидел что первый только пишет.

А ты конечно мудак, мда. Раз выебываешься здесь, среди чайников.
87 Кб, 720x480
#281 #423057
>>423056
Я конечно мудак, с этим я согласен. Но документацию надо глазами читать а не жопой. Не можешь осилить английский язык - пиздуй из профессии. Deal with it.

Ты конечно извини меня за грубость выражений. Вообще ты няша, и я когда то был точно таким нубом и точно так же тупил.
#282 #423058
>>423057
Он русский не осилил, а не английский. Так, между прочим.
#283 #423062
>>422976
Спасибо за ответ, а как например подсчитать другие параметры, например общее количество возможных балов и т.д.? Надо менять класс? И если не сложно можешь досказать как реализовать данный тест интерактивно на ПХП? Я примерно понимаю как сделать все вопросы на одной странице при помощи форм, но как в ООП сделать переход от вопроса к вопросу на странице (например при помощи action в форме) насколько я понимаю при переходе на другую страницу вся ООП конструкция просто исчезнет.
sage #284 #423066
>>423057
Соооооооооол, битрикс протек!
45 Кб, 444x460
#285 #423072
#286 #423076
Котаны, попытался сделать реализацию парадокса Монти Холла на ПХП https://ru.wikipedia.org/wiki/Парадокс_Монти_Холла, вот что вышло: http://ideone.com/CXX7LS кажется считает, скажите если не сложно есть ли ошибка и слишком ли кривой скрипт?
#287 #423085
>>423045
Переделал, но не выходит запускать следующий раунд кнопкой, игра начинается с нуля видимо потому, что заново создаются объекты http://ideone.com/pUZhed и index.html http://codepad.org/1hYdoEkB
как запускать игру кнопкой чтобы использовало те данные которые остались после предыдущего раунда?
286 Кб, 1145x723
#288 #423092
Я продолжаю свое супер медленное выполнение задач ОПа и вот еще один вариант задачи номер 12 по JavaScript, добавил удаление ингредиента и проверку на наличие добавляемого, добавить можно не более одного ингредиента каждого типа:

http://jsbin.com/qozajoyawe/1/edit
#289 #423093
#290 #423126
>>423014

> Вот только к чему приткнуть этот метод?


в контроллере сделать методы типа parseQuestions, parseAnswers

> С статическими методами и константами класса твиг не дружит (как где-то написали, это шаблонизатор и оно ему не надо).


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

> Но тогда же мне на сервер приедет массив с хламом по каждому типу вопроса, так?


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

Мне просто показалось что скрывать/показывать элементы проще чем писать код добавления/удаления из DOM. И данные не теряются при переключении.
#291 #423129
>>423126

>в контроллере сделать методы типа parseQuestions, parseAnswers


А я его в тест унес.

>Мне просто показалось что скрывать/показывать элементы проще чем писать код добавления/удаления из DOM. И данные не теряются при переключении.


С этим разберусь чуть позже. Меня немного подташнивает от js, честно говоря.

Я там немного пораскидал хлам из контроллера. И по мелочи методов сделал.
#292 #423131
>>423040

Покажи код

>>423045

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

>>423057

Понять действительно трудно. Я сам раза 2 или 3 перечитал прежде чем заметил разницу. Тут стоило бы различающуюся часть выделить например жирным шрифтом иначе трудно заметить.

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

>>423062

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


Сделать функцию для этого. Или сделать класс Тест который содержит массив вопросов и считает что надо для них.

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


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

> как реализовать данный тест интерактивно на ПХП?


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

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

Тебе надо знать основы HTML ( http://htmlbook.ru/samhtml ), формы, и как из php выводить html и читать данные форм:

http://php.net/manual/ru/language.basic-syntax.phpmode.php
http://php.net/manual/ru/tutorial.php

Также, тебе понадобится веб-сервер, например, Апач. Так как именно он взаимодействует с браузером, принимая и отвечая на запросы. Вот инструкция по установке:

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

Если что-то непонятно, спрашивай, я подскажу.
#292 #423131
>>423040

Покажи код

>>423045

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

>>423057

Понять действительно трудно. Я сам раза 2 или 3 перечитал прежде чем заметил разницу. Тут стоило бы различающуюся часть выделить например жирным шрифтом иначе трудно заметить.

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

>>423062

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


Сделать функцию для этого. Или сделать класс Тест который содержит массив вопросов и считает что надо для них.

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


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

> как реализовать данный тест интерактивно на ПХП?


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

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

Тебе надо знать основы HTML ( http://htmlbook.ru/samhtml ), формы, и как из php выводить html и читать данные форм:

http://php.net/manual/ru/language.basic-syntax.phpmode.php
http://php.net/manual/ru/tutorial.php

Также, тебе понадобится веб-сервер, например, Апач. Так как именно он взаимодействует с браузером, принимая и отвечая на запросы. Вот инструкция по установке:

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

Если что-то непонятно, спрашивай, я подскажу.
#293 #423132
>>423076

Код ужасно отформатирован и трудно понять что к какому циклу относится. Тебе надо было пропустить его через сайт phpformatter.com

Также, я вижу ты поставил много комментариев. Но если бы ты давал понятные названия переменным (а не c или h) то может быть эти комментарии и не потребовались бы.

Насчет выбора варианта, какую дверь открыть: надо делать проще. Копируем массив всех вариантов в новую переменную. Удаляем из него (array_diff) правильный ответ. Удаляем из него выбранный игроком ответ. Остается 1 ли 2 элемента. Выбираем случайно любой из них (например с помощью array_rand).

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

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

То есть цикл вот этот:

> for($j=0; $j<=2; $j++) {


> if($option!=$allOption[$j] &&


> $select!=$allOption[$j]) {


> $change=$allOption[$j];


По моему не нужен вообще.

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

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

> //Обнулим все переменные


это не требуется так как команда «=» вот тут

> $p1=$replace/$exp;


Удаляет старое значение p1 и заменяет новым

Аналогично, массив очищать не надо. Вместо этого надо написать в начале цикла forOpt = array( );

Вот какие можно поставить имена:

$h -> experimentCount
exp -> testsCount
replace -> winIfReplace/winIfChange
noReplace -> loseIfChange
forOpt -> удалить или переименовать нормально
p1/p2 -> winIfChangeProbability/loseIfChangeProbability

> if($correct!=$option) {


> if($correct==$option) {


Вместо второго if можно поставить else
#293 #423132
>>423076

Код ужасно отформатирован и трудно понять что к какому циклу относится. Тебе надо было пропустить его через сайт phpformatter.com

Также, я вижу ты поставил много комментариев. Но если бы ты давал понятные названия переменным (а не c или h) то может быть эти комментарии и не потребовались бы.

Насчет выбора варианта, какую дверь открыть: надо делать проще. Копируем массив всех вариантов в новую переменную. Удаляем из него (array_diff) правильный ответ. Удаляем из него выбранный игроком ответ. Остается 1 ли 2 элемента. Выбираем случайно любой из них (например с помощью array_rand).

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

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

То есть цикл вот этот:

> for($j=0; $j<=2; $j++) {


> if($option!=$allOption[$j] &&


> $select!=$allOption[$j]) {


> $change=$allOption[$j];


По моему не нужен вообще.

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

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

> //Обнулим все переменные


это не требуется так как команда «=» вот тут

> $p1=$replace/$exp;


Удаляет старое значение p1 и заменяет новым

Аналогично, массив очищать не надо. Вместо этого надо написать в начале цикла forOpt = array( );

Вот какие можно поставить имена:

$h -> experimentCount
exp -> testsCount
replace -> winIfReplace/winIfChange
noReplace -> loseIfChange
forOpt -> удалить или переименовать нормально
p1/p2 -> winIfChangeProbability/loseIfChangeProbability

> if($correct!=$option) {


> if($correct==$option) {


Вместо второго if можно поставить else
#294 #423133
>>423076

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

>>423085

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

Сессия - это хранилище данных на сервере, которое для тебя выглядит как массив $_SESSION. В начале выполнения скрипта по команде session_start() php загружает данные из хранилища в массив _SESSION (а если сессии пока не существует, то он создает пустой массив), а в конце сохраняет из массива в хранилище. Сессия уникальна для каждого пользователя (точнее для каждого браузера, если у пользователя открыта игра в 2 браузерах то будет 2 сессии), так как использует куку чтобы хранить id сесиии.

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

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

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

Неактивные в течение 15-30 минут сессии удаляются. Сессия — это временное, а не постоянное хранилище данных.

Мануал:

http://php.net/manual/ru/book.session.php

Если есть какие-то вопросы, задавай.
#295 #423135
>>423085

В общем тебе надо создавать сессию и в нее сохранять ник игрока, и позиции игроков (проще всего сохранить сам массив игроков целиком. PHP сериализует его сам с помощью serialize при сохранении сессии, и сам восстановит в следующий раз).

То есть если сессия пуста, значит игрок только что зашел в игру и надо показать стартовую страницу и спросить его ник.

Если не пуста, значит игра уже начата, надо достать из сессии массив игроков, сделать следующий ход, отобразить карту.
#296 #423137
>>423129

Работу с POST/GET не стоит класть в модель так как это не ее задача, взаимодействовать с пользователем. Это должно быть в контроллере или классе-помощнике контроллера.

> Меня немного подташнивает от js, честно говоря.


Задачки на js порешал бы. У нас там для первых 4 даже автоматическая проверялка есть.

Код гляну попозже тогда.
#297 #423140
>>423137

>Задачки на js порешал бы. У нас там для первых 4 даже автоматическая проверялка есть.


Я делал их. Первых штук 16.

>Это должно быть в контроллере или классе-помощнике контроллера.


Тогда уж в контроллере надо сделать массив нужных значений, а разгребать их в объект уже в модели.
#298 #423141
>>423132
Спасибо, не знал про array_diff, если бы знал может сразу написал бы компактнее код.
#299 #423143
https://github.com/MindiMakridi/Students
Исправил код. Правда столбцы до сих пор выводятся через echo в перемешку с хтмл кодом. Могу еще конечно вставлять foreach для каждой ячейки, больше я не знаю как вывести это таблицей.
#300 #423144
>>423143
А хотя нет, я щас подумал, через foreach в каждой ячейке не получится. Так что то, как я сделал, это единственный известный мне способ вывода таблицы. Жду предложений.
#301 #423146
>>423143

> <?php include "/templates/template.html"; ?>


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

> foreach ($table as $student) { ... }


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

> <?php echo


Желательно использовать <?=

Мимо джун
#302 #423147
>>423146

>Желательно использовать <?=


Я так делал и у меня ошибку выдавало. Видимо я что-то не так делаю, либо это нужно настраивать в php.ini
#304 #423151
>>423150
<?= ?>не есть <? ?>
#305 #423152
>>423151

> Начиная с PHP 5.4 короткий тег echo <?= всегда распознается и действует, несмотря на значение опции short_open_tag.



Ответ на твой вопрос - нет, но только с версии 5.4 и выше. Для более ранних версий - да.
#306 #423153
>>423152
А это был не вопрос.
23 Кб, 1142x324
#307 #423154
Анон, если тебе не сложно то можешь помочь мне разобраться с одной проблемой. Дело в том что я кривой по жизни во всём, в ПХП проявляется тоже самое, я просто не умею кратко писать код как не пытаюсь, может есть какая-нибудь методика? Вот например сейчас пытался написать шифр Бэкона, суть в том что надо сделать как на пикрелейтед. Вот что вышло: http://ideone.com/pBYKzr Код читается ужасно, я сейчас попытаюсь объяснить что делал

Тут всё ясно как бы в массиве $bacon храним кодировку, в переменной $word текст для раскодирования:

$bacon=array('a'=>'AAAAA', 'b'=>'AAAAB', 'c'=>'AAABA', 'd'=>'AAABB', 'e'=>'AABAA', 'f'=>'AABAB');
$word="the jOs to kIll fAr";

Здесь удаляем пробелы в слове для раскодировки и добавляем пробелы после каждой пятой буквы
$word=str_replace(" ","",$word);
$word=wordwrap($word,5," ",true);

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

$word=preg_replace("![A-Z]!", "B", $word);
$word=preg_replace("![a-z]!", "A", $word);

Начинается хуета, добавляем в конец строки " B", так как будем разбивать на массив по пробелу полученную строку
что бы все элементы попали в массив полученный через explode. Также меняем в массиве $bacon ключи и значения местами
$word.=" B";
$word1=explode(" ",$word);
$bacon=array_flip($bacon);

$baconWord="";

Теперь записываем в переменную $baconWord элементы массива которые можно найти по ключу который можно найти через массив $word1
for($i=0; $i<count($word1); $i++) {
$baconWord.=$bacon[$word1[$i]];
}

echo $baconWord;

Это очень тупой код, но я не знаю как справиться иначе, несмотря на то что работает скрипт очень лажовый. Можешь подсказать анон если не сложно, как можно написать этот код более компактнее
23 Кб, 1142x324
#307 #423154
Анон, если тебе не сложно то можешь помочь мне разобраться с одной проблемой. Дело в том что я кривой по жизни во всём, в ПХП проявляется тоже самое, я просто не умею кратко писать код как не пытаюсь, может есть какая-нибудь методика? Вот например сейчас пытался написать шифр Бэкона, суть в том что надо сделать как на пикрелейтед. Вот что вышло: http://ideone.com/pBYKzr Код читается ужасно, я сейчас попытаюсь объяснить что делал

Тут всё ясно как бы в массиве $bacon храним кодировку, в переменной $word текст для раскодирования:

$bacon=array('a'=>'AAAAA', 'b'=>'AAAAB', 'c'=>'AAABA', 'd'=>'AAABB', 'e'=>'AABAA', 'f'=>'AABAB');
$word="the jOs to kIll fAr";

Здесь удаляем пробелы в слове для раскодировки и добавляем пробелы после каждой пятой буквы
$word=str_replace(" ","",$word);
$word=wordwrap($word,5," ",true);

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

$word=preg_replace("![A-Z]!", "B", $word);
$word=preg_replace("![a-z]!", "A", $word);

Начинается хуета, добавляем в конец строки " B", так как будем разбивать на массив по пробелу полученную строку
что бы все элементы попали в массив полученный через explode. Также меняем в массиве $bacon ключи и значения местами
$word.=" B";
$word1=explode(" ",$word);
$bacon=array_flip($bacon);

$baconWord="";

Теперь записываем в переменную $baconWord элементы массива которые можно найти по ключу который можно найти через массив $word1
for($i=0; $i<count($word1); $i++) {
$baconWord.=$bacon[$word1[$i]];
}

echo $baconWord;

Это очень тупой код, но я не знаю как справиться иначе, несмотря на то что работает скрипт очень лажовый. Можешь подсказать анон если не сложно, как можно написать этот код более компактнее
#308 #423166
Что сложней - JS или PHP?
#309 #423167
Делаю блог на php, куча url вида /krokodil.php?zalupa=syr news.php?action=showall. Можно ли придать им приятный вид? Например через htaccess? Под приятным видом я имею в виду, например, /krokodil/zalupa/syr или krokodil/syr и прочие варианты. А также чтоб не возникало дублей страниц (со слешем и без).
#310 #423171
Скажите, я правильно понял, что суть DataMapper в том, чтобы отделить код, в котором осуществляются манипуляции с базой?
К примеру, для задания https://gist.github.com/codedokode/d7e7f11449fc3bcb24b4
я бы написал классы таким образом
http://ideone.com/QhfaPC
Правильно, или лучше как-то по-другому?
#311 #423173
>>423133
>>423135
Благодарю, буду пробовать.
#312 #423174
>>423167
гугли ЧПУ
#313 #423178
>>423132
Вроде бы изменил http://ideone.com/ba5QRf но от того куска кода так и не смог избавиться, не получается ничего другого кроме метода исключения, иначе у меня считает либо просто количество вариантов не равных выбранному, а если удалить из общего массива вариант который был удалён ведущим, то не знаю как в блоках if сделать указать условие что бы он правильно всё считал.
#314 #423208
Что сложней - JS или PHP?
#315 #423209
>>423208
JS. Почему по твоему у него миллион библиотек?
#316 #423246
>>423140

> Первых штук 16.


Это на сам яваскрипт? Вообще, многовато, конечно, я потом переделаю, чтобы их было меньше. Я там не так давно еще задачи на DOM сократил и добавил jQuery и jQuery UI, так что если ты хочешь их освоить, задачи есть.

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

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


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

>>423147

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

<?= $x ?>

>>423154

О, шифр Бэкона? Интересная штука, искатели тайн средневековые книги в свое время перерыли в поисках шифрованных сообщений.

> $word=wordwrap($word,5," ",true);


Можно разбить на группы по 5 по-другому. Сначала заменяем буквы на A/B, хаком с preg_split разбиваем текст на массив букв, затем с помощью array_chunk разбиваем массив букв на группы по 5 букв (которые потом можно склеить в строку с помощью implode).

Что за хак я упоминаю? Он есть в моем учебнике.

Для разбиения на буквы можно использовать

$letters = preg_split("//u", $text, null, PREG_SPLIT_NO_EMPTY);

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

Обрати внимание на флаг u. Он говорит что текст в utf-8 и заставляет разбивать строку именно на буквы по границам utf-8 символов, а не на куски по 1 байту.

Также, есть функция http://php.net/manual/ru/function.str-split.php но учти что она работает только с латинницей (подробнее мой мини-урок про то, какие функции работают с utf8 а какие нет и почему: https://gist.github.com/codedokode/ff99e357e9860ea169b8 )

Ошибка у тебя из-за оставшейся в конце буквы B. Не надо ее добавлять наверно.
#316 #423246
>>423140

> Первых штук 16.


Это на сам яваскрипт? Вообще, многовато, конечно, я потом переделаю, чтобы их было меньше. Я там не так давно еще задачи на DOM сократил и добавил jQuery и jQuery UI, так что если ты хочешь их освоить, задачи есть.

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

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


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

>>423147

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

<?= $x ?>

>>423154

О, шифр Бэкона? Интересная штука, искатели тайн средневековые книги в свое время перерыли в поисках шифрованных сообщений.

> $word=wordwrap($word,5," ",true);


Можно разбить на группы по 5 по-другому. Сначала заменяем буквы на A/B, хаком с preg_split разбиваем текст на массив букв, затем с помощью array_chunk разбиваем массив букв на группы по 5 букв (которые потом можно склеить в строку с помощью implode).

Что за хак я упоминаю? Он есть в моем учебнике.

Для разбиения на буквы можно использовать

$letters = preg_split("//u", $text, null, PREG_SPLIT_NO_EMPTY);

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

Обрати внимание на флаг u. Он говорит что текст в utf-8 и заставляет разбивать строку именно на буквы по границам utf-8 символов, а не на куски по 1 байту.

Также, есть функция http://php.net/manual/ru/function.str-split.php но учти что она работает только с латинницей (подробнее мой мини-урок про то, какие функции работают с utf8 а какие нет и почему: https://gist.github.com/codedokode/ff99e357e9860ea169b8 )

Ошибка у тебя из-за оставшейся в конце буквы B. Не надо ее добавлять наверно.
#317 #423247
>>423092

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

> if (gam.filling.name == fill.name) {


Вообще можно сравнивать и сами объекты. Ты знаешь как работает сравнение объектов в JS? Вот тут например что будет?

var a = { x: 1};
var b = { x: 1};
var c = { x:1, y: 2};

console.log(a == b); // ?
console.log(a === b); // ?
console.log(a == c); // ?

> for (var i = 0; i < this.filling.length; i++) {


> if (this.filling.name == fill.name) {


Этот цикл у тебя повторяется в 2 местах. Вынеси-ка его в функцию, которая ищет в массиве добавку и возвращает либо ее индекс либо -1

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

Не, я глянул код, createTestFromPost надо перенести из модели в другой класс. Модель ни при каких обстоятельствах не должна лезть в ПОСТ, тем более еще и через эти глобальные ссылки типа Yii->request.

Вот еще замечания:

> $test = Test::getTestFromPost( );


Лучше не создавать тест из ПОСТ а набивать данные в существующий тест из ПОСТ. Тогда такой код будет работать и для создания и для редактирования.

Вот это

> $this->render('createTest.twig',



У тебя аж 3 раза повторяется. Одного недостаточно? Сделай лучше так:

тест = загружаем/создаем тест;
если (форма запощена) {
набиваем данные в тест;
если (все верно) {
....
}
}

выводим форму;

Это общепринятый алгоритм для любых форм.

Ну и при редактировании хорошо бы сохранять id вопросов/ответов. Для этого достаточно добавить скрытый инпут с id. Интуиция подсказывает мне что это поможет например не потерять ссылки на них в других таблицах если такие появятся. Ну и вообще, редактирование != удаление + создание заново.

В функции валидации стоит предусмотреть не только return false/true но и сохранять текст ошибки и элемент к которому она относится. Для этого можно использовать либо встроенные возмжности Юи если таковые есть, либо сделать свой класс ErrorMessages и может быть хелперы для отображения сообщений в форме.

> if ($a->number == $b->number) {


> return 0;


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

return $a->number - $b->number;
#318 #423248
>>423140

Не, я глянул код, createTestFromPost надо перенести из модели в другой класс. Модель ни при каких обстоятельствах не должна лезть в ПОСТ, тем более еще и через эти глобальные ссылки типа Yii->request.

Вот еще замечания:

> $test = Test::getTestFromPost( );


Лучше не создавать тест из ПОСТ а набивать данные в существующий тест из ПОСТ. Тогда такой код будет работать и для создания и для редактирования.

Вот это

> $this->render('createTest.twig',



У тебя аж 3 раза повторяется. Одного недостаточно? Сделай лучше так:

тест = загружаем/создаем тест;
если (форма запощена) {
набиваем данные в тест;
если (все верно) {
....
}
}

выводим форму;

Это общепринятый алгоритм для любых форм.

Ну и при редактировании хорошо бы сохранять id вопросов/ответов. Для этого достаточно добавить скрытый инпут с id. Интуиция подсказывает мне что это поможет например не потерять ссылки на них в других таблицах если такие появятся. Ну и вообще, редактирование != удаление + создание заново.

В функции валидации стоит предусмотреть не только return false/true но и сохранять текст ошибки и элемент к которому она относится. Для этого можно использовать либо встроенные возмжности Юи если таковые есть, либо сделать свой класс ErrorMessages и может быть хелперы для отображения сообщений в форме.

> if ($a->number == $b->number) {


> return 0;


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

return $a->number - $b->number;
#319 #423250
>>423143

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

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

А email может меняться, что создает дополнительные проблемы.

Также, важная вещь: ты должен использовать htmlspecialchars при выводе данных в шаблоне. Иначе у тебя получается XSS уязвимость: злоумышленник может вписать в имя любые HTML теги и они выведутся. Подробнее: https://gist.github.com/anonymous/52adda0113428b274c64

> https://github.com/MindiMakridi/Students/blob/master/index.php#L68


Это надо вынести в шаблон, например footer.html

> ?>


Не надо ставить это если этот маркер в самом конце файла

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L22


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

> die ("Не верный запрос к базе данных");


В мире Ооп используют исключения:

https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
http://php.net/manual/ru/language.exceptions.php

замени die на throw

else там не нужен так как после die или throw выполнение функции завершается.

Алсо, у тебя в файле https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php форматирование поплыло, пропусти код через phpformatter

> "/lib/profileclass.php";


Имена классов пишутся с большой буквы и должны совадать с именем файла то есть должно быть Profile.php

Класс StudentMapper должен быть в StudentMapper.php

> public function addStudent($profile){


Тут нужен тайп хинт: http://php.net/manual/ru/language.oop5.typehinting.php

Это делает код надежнее и понятнее.

> $STH->bindparam(":name", $name);


> $name = $profile->showName( );



Можно использовать bindValue и обойтись без промежуточной переменной:

$STH->bindValue(':name', $profile->getName( ));

Также, можно передавать массив значений в execute.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L85


> WHERE email=:prevMail


Индентифицировать студента удобнее не по email, а по id так как он не меняется никогда.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L109


В файле с классом не должно быть постороннего кода

> https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L8


этот html код надо перенести куда-нибудь в шаблон

> https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L29


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

> if ($this->checkField($data['name'], $regExp)) {


> $this->name = $this->checkField($data['name'], $regExp);


Во второй строчке по моему checkField лишний

> https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L82


hello@003.ru не пройдет.

Вот интересные статьи на тему проверки email:

http://habrahabr.ru/post/55820/
http://habrahabr.ru/post/175375/

(у нас пропускать наркоманские адреса вроде "hello world"@[ff01::0] конечно не требуется)

> public function showName()


Везде обычно такие методы назваются getName

Насчет register.php и profile.php, там много похожего кода, надо бы объединить их в один файл. Примерно так:

-------------
если (идет редактирование) {
загружаем студента из БД;
} иначе {
создаем пустого студента;
}

если (форма запощена) {
записываем данные из ПОСТ в студента;
проверяем все ли верно;

если (все верно) {
сохраняем студента (вставкой или редактированием);
если надо ставим куки;
редиректим;
}

}

выводим форму;
----------------

> <<?php echo $tag ?>


А зачем менять вид тега при регистрации/редактировании? Я не понимаю. Нельзя и там и там инпут использовать?

Чтобы в инпуте уже было сохранено введенное значение достаточно подставить его в value:

<input name="..." value="<?= htmlspecialchars($name) ?>">

А в твоем варианте, как я понимаю, в форме регистрации данные теряются при ошибке.

Также надо чтобы в форме выводился выбранные ранее пол. Для этого у option есть атрибут selected: http://htmlbook.ru/html/option

Я вижу, ты не очень знаешь HTML формы. Почитай-ка самоучитель по ним:

http://htmlbook.ru/samhtml5/formy
http://htmlbook.ru/html/type/form

Если что-то там непонятно, задавай вопросы.

> order=name&direction


В HTML & это спецсимвол и чтобы вставить знак & надо писать

&amp;

подробнее: https://ru.wikipedia.org/wiki/%D0%9C%D0%BD%D0%B5%D0%BC%D0%BE%D0%BD%D0%B8%D0%BA%D0%B8_%D0%B2_HTML
http://htmlbook.ru/samhtml/tekst/spetssimvoly

> <?php foreach ($table as $student) {


В шаблонах применяется версия с двоеточием: http://php.net/manual/ru/control-structures.alternative-syntax.php

> echo "<tr><td>{$student->showName()}


Это делается так:

<td><?= htmlspecialchars($student->showName()) ?></td>

Мануал: http://php.net/manual/ru/language.basic-syntax.phpmode.php

Ну и код выровняй еще, где он съехал. Нормальные редакторы обычно сохраняют отступ при переходе на новую строку, ты случайно не в блокноте его пишешь?
#319 #423250
>>423143

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

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

А email может меняться, что создает дополнительные проблемы.

Также, важная вещь: ты должен использовать htmlspecialchars при выводе данных в шаблоне. Иначе у тебя получается XSS уязвимость: злоумышленник может вписать в имя любые HTML теги и они выведутся. Подробнее: https://gist.github.com/anonymous/52adda0113428b274c64

> https://github.com/MindiMakridi/Students/blob/master/index.php#L68


Это надо вынести в шаблон, например footer.html

> ?>


Не надо ставить это если этот маркер в самом конце файла

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L22


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

> die ("Не верный запрос к базе данных");


В мире Ооп используют исключения:

https://gist.github.com/codedokode/65d43ca5ac95c762bc1a
http://php.net/manual/ru/language.exceptions.php

замени die на throw

else там не нужен так как после die или throw выполнение функции завершается.

Алсо, у тебя в файле https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php форматирование поплыло, пропусти код через phpformatter

> "/lib/profileclass.php";


Имена классов пишутся с большой буквы и должны совадать с именем файла то есть должно быть Profile.php

Класс StudentMapper должен быть в StudentMapper.php

> public function addStudent($profile){


Тут нужен тайп хинт: http://php.net/manual/ru/language.oop5.typehinting.php

Это делает код надежнее и понятнее.

> $STH->bindparam(":name", $name);


> $name = $profile->showName( );



Можно использовать bindValue и обойтись без промежуточной переменной:

$STH->bindValue(':name', $profile->getName( ));

Также, можно передавать массив значений в execute.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L85


> WHERE email=:prevMail


Индентифицировать студента удобнее не по email, а по id так как он не меняется никогда.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L109


В файле с классом не должно быть постороннего кода

> https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L8


этот html код надо перенести куда-нибудь в шаблон

> https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L29


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

> if ($this->checkField($data['name'], $regExp)) {


> $this->name = $this->checkField($data['name'], $regExp);


Во второй строчке по моему checkField лишний

> https://github.com/MindiMakridi/Students/blob/master/lib/profileclass.php#L82


hello@003.ru не пройдет.

Вот интересные статьи на тему проверки email:

http://habrahabr.ru/post/55820/
http://habrahabr.ru/post/175375/

(у нас пропускать наркоманские адреса вроде "hello world"@[ff01::0] конечно не требуется)

> public function showName()


Везде обычно такие методы назваются getName

Насчет register.php и profile.php, там много похожего кода, надо бы объединить их в один файл. Примерно так:

-------------
если (идет редактирование) {
загружаем студента из БД;
} иначе {
создаем пустого студента;
}

если (форма запощена) {
записываем данные из ПОСТ в студента;
проверяем все ли верно;

если (все верно) {
сохраняем студента (вставкой или редактированием);
если надо ставим куки;
редиректим;
}

}

выводим форму;
----------------

> <<?php echo $tag ?>


А зачем менять вид тега при регистрации/редактировании? Я не понимаю. Нельзя и там и там инпут использовать?

Чтобы в инпуте уже было сохранено введенное значение достаточно подставить его в value:

<input name="..." value="<?= htmlspecialchars($name) ?>">

А в твоем варианте, как я понимаю, в форме регистрации данные теряются при ошибке.

Также надо чтобы в форме выводился выбранные ранее пол. Для этого у option есть атрибут selected: http://htmlbook.ru/html/option

Я вижу, ты не очень знаешь HTML формы. Почитай-ка самоучитель по ним:

http://htmlbook.ru/samhtml5/formy
http://htmlbook.ru/html/type/form

Если что-то там непонятно, задавай вопросы.

> order=name&direction


В HTML & это спецсимвол и чтобы вставить знак & надо писать

&amp;

подробнее: https://ru.wikipedia.org/wiki/%D0%9C%D0%BD%D0%B5%D0%BC%D0%BE%D0%BD%D0%B8%D0%BA%D0%B8_%D0%B2_HTML
http://htmlbook.ru/samhtml/tekst/spetssimvoly

> <?php foreach ($table as $student) {


В шаблонах применяется версия с двоеточием: http://php.net/manual/ru/control-structures.alternative-syntax.php

> echo "<tr><td>{$student->showName()}


Это делается так:

<td><?= htmlspecialchars($student->showName()) ?></td>

Мануал: http://php.net/manual/ru/language.basic-syntax.phpmode.php

Ну и код выровняй еще, где он съехал. Нормальные редакторы обычно сохраняют отступ при переходе на новую строку, ты случайно не в блокноте его пишешь?
#320 #423252
>>423166

Оба сложные.

>>423167

гугли ЧПУ. Вообще, при использовании фреймворков вроде Slm, Yii2, Symfony 2 проблема уже решена в них, а если ты пишешь на чистом php то ты можешь с помощью htaccess перенаправить все обращения на index.php а уже в нем писать:

$uri = $_SERVER['REQUEST_URI'];

if (preg_match("!^/some/url!", $uri)) {
....
}

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

>>423171

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

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

Если что вот еще инфа от автора (Мартина Фаулера) придумавшего этот паттерн:

http://design-pattern.ru/patterns/data-mapper.html

Вот по коду:

> $name = strip_tags(trim($name));


Ой-ой, код из старых непраивльных учебников? Почитай про правильную защиту от XSS: https://gist.github.com/anonymous/52adda0113428b274c64

> $this->properties = array('name'=>$name, 'age'=>$age, 'email'=>$email);


Это нехорошо. Зачем ты используешь классы если в итоге хранишь все в массиве? Надо сделать 3 свойства name, age, email и хранить все в них.

> \tfunction getInfo(){


надо сделать 3 функции getName/Age/Email

> (Student &$student){


Не надо писать & . Объекты и так передаются (почти) как по ссылке: http://php.net/manual/ru/language.oop5.references.php

> \t$stmt->bindParam(':name', $this->db->quote($info['name']));


не надо делать quote, bindParam делает quote сам. Также, лучше использовать bindValue, bindParam предназначен для двухсторонней связи.

В функции insert обычно еще делают чтобы после вставки в базу проставлялся сгенерированный базой id в объект студента.
#320 #423252
>>423166

Оба сложные.

>>423167

гугли ЧПУ. Вообще, при использовании фреймворков вроде Slm, Yii2, Symfony 2 проблема уже решена в них, а если ты пишешь на чистом php то ты можешь с помощью htaccess перенаправить все обращения на index.php а уже в нем писать:

$uri = $_SERVER['REQUEST_URI'];

if (preg_match("!^/some/url!", $uri)) {
....
}

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

>>423171

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

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

Если что вот еще инфа от автора (Мартина Фаулера) придумавшего этот паттерн:

http://design-pattern.ru/patterns/data-mapper.html

Вот по коду:

> $name = strip_tags(trim($name));


Ой-ой, код из старых непраивльных учебников? Почитай про правильную защиту от XSS: https://gist.github.com/anonymous/52adda0113428b274c64

> $this->properties = array('name'=>$name, 'age'=>$age, 'email'=>$email);


Это нехорошо. Зачем ты используешь классы если в итоге хранишь все в массиве? Надо сделать 3 свойства name, age, email и хранить все в них.

> \tfunction getInfo(){


надо сделать 3 функции getName/Age/Email

> (Student &$student){


Не надо писать & . Объекты и так передаются (почти) как по ссылке: http://php.net/manual/ru/language.oop5.references.php

> \t$stmt->bindParam(':name', $this->db->quote($info['name']));


не надо делать quote, bindParam делает quote сам. Также, лучше использовать bindValue, bindParam предназначен для двухсторонней связи.

В функции insert обычно еще делают чтобы после вставки в базу проставлялся сгенерированный базой id в объект студента.
#321 #423253
>>423178

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

Если пользователь изначально выбрал правильный ответ if ($option == $truth) то при смене ответа он очевидно проигрывает.

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

Получается, можно сделать так:

if (пользователь изначально выбрал правильный ответ) {
при смене он проиграет;
} иначе {
при смене он выиграет;
}

Или я где-то ошибся?
#322 #423255
Если я кого-то пропустил, напомните о себе.
#323 #423256
>>423253

>if ($option == $truth)



Говнокод ! Сравнение нужно делать с помощью точного сравнения "===" с учитыванием типов.
#324 #423257
>>423248

>Не, я глянул код, createTestFromPost надо перенести из модели в другой класс.


Я просто не хочу набивать массив вопросов в контроллере.

>Лучше не создавать тест из ПОСТ а набивать данные в существующий тест из ПОСТ.


Если метод будет не в модели - то оно и понятно.

>Вот это $this->render('createTest.twig',


Два раза. Один раз там - заглушка, пока я не уверен в валидации.

>Это общепринятый алгоритм для любых форм.


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

>Ну и при редактировании хорошо бы сохранять id вопросов/ответов.


Айди пока нет. Они будут после сохранения. То я айди обозвал при создании / редактировании, а по сути это лишь номер в $_POST['questons']. А так да, при редактировании теста будет скрытый инпут с id.

>Есть еще такой интересный хак (использовать его разумеется не обязательно):


Знаю и лучше оставлю как есть.

>В функции валидации стоит предусмотреть не только return false/true но и сохранять текст ошибки и элемент к которому она относится.


Та часть, которая делается с validate() сама создают такой текст в элементе. А остальное я да, добавлю. Ошибки вроде "ни одного верного ответа", "ни одного вопроса в тесте", etc. Надо, наверное, поле в модели предусмотреть для этого, как сам Yii и делает.
#325 #423258
>>423257

> Айди пока нет. Они будут после сохранения. То я айди обозвал при создании / редактировании, а по сути это лишь номер в $_POST['questons']. А так да, при редактировании теста будет скрытый инпут с id.


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

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

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


Так ведь план такой и был изначально.
#327 #423260
>>423258
Я там поигрался с валидацией немного и унес из модели парсинг теста из запроса.
#328 #423262
ОП или кто-нибудь, кому процесс понятен, помогите пожалуйста с настройкой xdebug https://2ch.hk/web/res/52671.html
#329 #423263
>>423262

Ты IDE настроил? Там тоже надо настройки прописать. Какие именно написано в документации по IDE, вот пример для phpstorm: https://www.jetbrains.com/phpstorm/help/php-debugging-session.html

Также вопрос, где ты пытаешься отлаживать код? На своем компьюетере? На удаленном сервере? Если на сервере то настройки явно неправильные.
#330 #423265
>>423262

Насчет опции connect_back. Она значит что xdebug на сервере пытается соединиться с тем IP с которого пришел запрос. Но если ты находишься за Nat (то есть если у тебя нет выделенного внешнего белого адреса, и сервер не в локальной сети) то соединиться не получится.
#331 #423266
>>423265

Единственный вариант если тебя и сервер разделяет NAT это соединиться по SSH c сервером, сделать проброс портов через SSH и настроить в отладчике соединение с лоакалхостом. Но в этом случае стоило бы протестировать сначала рабоатет ли этот проброс вообще.
#332 #423273
>>423266
>>423265
Вот спасибо, как с души камень. Да за NAT и не одним. Зато проброс с того же vps точно работает, проверял на mysql workbench. Но правильный ли будет проброс вида
ssh -L 9000:localhost:9000? Там есть еще параметр -R и если читать маны по диагонали, то они похожи.

>>423263
Вот хз. Костыли для браузеров вообще настроек не имеют, но также не работают.
#333 #423274
Пыханы, а на одеске много заказов конкретно по пхп?
#334 #423276
>>423246
Спасибо, сделал как ты сказал, теперь код компактнее http://ideone.com/xEvlXG Правда на 11 строчке возникла ошибка, кажется из-за того что неизвестная переменная, не подскажешь случайно если не сложно как избавиться от этой ошибки, она довольно часто у меня возникает, хоть и не влияет не скрипт но всёравно это же плохо что она возникает?
#335 #423277
>>423253
Мне почему то показалось что так он будет просто подсчитывать количество угаданных раз из трёх вариантов, то есть всегда будет вероятность 1\3 что правильно назвал с самого начала и 2\3 что неправильно назвал, почему то и сейчас так кажется, я наверное где-то что-то не уловил.
#336 #423296
>>423140

>Задачки на js порешал бы. У нас там для первых 4 даже автоматическая проверялка есть.


>Я делал их. Первых штук 16.


Это где их найти?
#337 #423297
>>423247

>Вообще можно сравнивать и сами объекты.


Сделал

>Ты знаешь как работает сравнение объектов в JS? Вот тут например что будет?


Везде false, как я понял потому что при сравнении объектов они сравниваются на идентичность а не на равенство, то есть являются ли операнды одной сущностью или разными.
Инфа отсюда: http://bonsaiden.github.io/JavaScript-Garden/ru/#types.equality

>Этот цикл у тебя повторяется в 2 местах. Вынеси-ка его в функцию, которая ищет в массиве добавку и возвращает либо ее индекс либо -1


Запилил: http://jsbin.com/musafimuli/3/edit?js,console

Про объект в константе понял, но не вижу преимуществ, может позже сделаю.
#339 #423303
>>423298
Спасибо.
#340 #423305
Не как не могу решить задание "Палиндром". Вот к чему пришел http://ideone.com/pUohS4
#341 #423306
>>423305
Мне кажется ты не совсем понимаешь как substr работает. Алсо, для чего там цикл, если ты на каждой итерации одно и тоже значение проверяешь, не используя $i? И я бы советовал результат выводить не внутри условия, а в самом конце, чтобы он выводился в любом случае. А внутри условия просто менять его, например на "не палиндром".
#342 #423309
>>423131
>>423173
Вот короче простенький вывод сделал.
http://rghost.ru/60205213
С JS буду разбираться в скором времени, опасаюсь, что как начну в Css html JS уходить так забуду половину в php
#343 #423311
Странно, мой вчерашний ночной пост про udacity пропал. Или я спьяну не туда запостил, или кто-то подтирает здесь.
#344 #423326
>>423309
В этом варианте там куча багов конечно, переделал немного сессию, чтобы при повторной отправке данных из index.html чтобы начиналась новая сессия с новым ником, но как предотвратить выполнение скрипта путем нажатия f5?
#345 #423333
>>423326
Точнее, если без захода на index.html сразу запустить страницу php-скрипта, как сделать редирект на index.html если через $_POST не были отправлены данные в сессию? на isset($_SESSION['name']) проверять бесполезно, всегда возвращает true, есть ещё варианты?
#346 #423340
>>423333
!empty
#347 #423343
>>423340
Премного благодарен, сработало
#348 #423355
Странно, у меня DBH->lastInsertId() 0 возвращает. С чего бы это?
#349 #423361
>>423355
Контекст давай.
#350 #423363
>>423361

>Ошибка постинга: В сообщений присутствует слово из спам листа.


http://ideone.com/VB856m
#351 #423368
>>423363
Так ты сначала вставь что-нибудь, а потом айди бери.
#352 #423385
>>423305

Два чаю, никак не могу допереть до решения.
Понятно, что нужно делать с условием несовпадения и типа как только буква не совпадёт - прервать цикл и заменить результ на "не палиндром". Но как именно?
#353 #423387
>>423385

>прервать цикл и заменить результ на "не палиндром". Но как именно?


А что не понятно?
Если(переменная А не равна переменной Б){
результат = "не палиндром"
}

в конце выводим результат.
#354 #423389
>>423387

Да до этого я допёр, но у меня почему то, если делать (длина слова-i) последним символом пустой выводит символ, а первым букву "а". А если просто с отрицательного i начинать, то выводит, естественно, сначала первую "а", а потом уже последнюю, что логично, ибо (-0) = 0. Я вот с этим присваиванием букв запутался.
#355 #423391
>>423389

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


В смысле при проверке с конца слова сначала идёт какой-то пустой символ, а потом "а". Естественно "" != "а" и выводится, что не палиндром.
#356 #423392
>>423391
>>423389
Код покажи.
#357 #423396
>>423392

http://ideone.com/zgVyHK
и
http://ideone.com/MSH1nx

Вывел символы просто для примера, ибо понимаю как там надо завершать цикл.
#358 #423401
>>423396
Ну да, у тебя 0 будет на первом шаге цикла во второй переменной, на втором шаге -1, то есть отставание по буквам от первой переменной. Не вижу ничего сложного в том, чтобы это исправить, тут простая арифметика. Что касается второго скрипта, то ты зачем-то отнимаешь $i от длинны слова. Если длинна слова 4 буквы, то позиция 4ой буквы в mb_substr будет под номером 3, т.к они начинаются с нуля, как в массиве. Соответственно на первом шаге у тебя substr обращается к несуществующему индексу.
#359 #423425
>>423401

Точно, чувствую себя теперь дураком. Я и до этого догадывался, но после того, как сообщение твоё прочитал всё прямо очевидно стало, лол.
Выполнил, спасибо.
#360 #423427
>>423273

У SSH есть 2 режима проброса:

- когда порт открывается на локальном компьютере и при соединении с ним (локально) ssh-сервер открывает соединение с сервера на указанный адрес и пробрасывает данные.

- когда порт открывается на удаленном хосте и пробрасывается локально на ssh-клиент

-L это первый режим
-R это второй

Почитай внимательно описание в мануале например тут http://www.opennet.ru:8101/man.shtml?topic=ssh&category=1&russian=0

Тебе надо чтобы php на сервере мог соединиться с IDE на локалхосте. Значит тебе надо открыть порт на сервере, пробросить его на свой комп и в настройках xdebug указать localhost и открытый порт.

Видимо тебе нужно

ssh -R 9000:localhost:9000

то есть открываем удаленно порт 9000 (к которому подсоединится xdebug) и при соединении с ним ssh будет коннектиться к 9000 на локальном компьютере где ждет соединения IDE.

Если у тебя линукс то ты можешь поставить утилиту nc (netcat, https://ru.wikipedia.org/wiki/Netcat ) и тестировать соединение ей. На лоакльном компьютере пишешь

nc -vv -l -p 9000 # слушать порт 9000

На удаленном сервере пишешь

echo hello | nc -vv localhost 9000 # подсоединиться и переслать строку

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

> Вот хз. Костыли для браузеров вообще настроек не имеют, но также не работают.


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

Ну и по моему конечно удобнее отлаживать что тебе надо локально, а не мучаться с пробросами. И уж тем более не стоит запускать наверно отладчик на продакшен сервере.
#360 #423427
>>423273

У SSH есть 2 режима проброса:

- когда порт открывается на локальном компьютере и при соединении с ним (локально) ssh-сервер открывает соединение с сервера на указанный адрес и пробрасывает данные.

- когда порт открывается на удаленном хосте и пробрасывается локально на ssh-клиент

-L это первый режим
-R это второй

Почитай внимательно описание в мануале например тут http://www.opennet.ru:8101/man.shtml?topic=ssh&category=1&russian=0

Тебе надо чтобы php на сервере мог соединиться с IDE на локалхосте. Значит тебе надо открыть порт на сервере, пробросить его на свой комп и в настройках xdebug указать localhost и открытый порт.

Видимо тебе нужно

ssh -R 9000:localhost:9000

то есть открываем удаленно порт 9000 (к которому подсоединится xdebug) и при соединении с ним ssh будет коннектиться к 9000 на локальном компьютере где ждет соединения IDE.

Если у тебя линукс то ты можешь поставить утилиту nc (netcat, https://ru.wikipedia.org/wiki/Netcat ) и тестировать соединение ей. На лоакльном компьютере пишешь

nc -vv -l -p 9000 # слушать порт 9000

На удаленном сервере пишешь

echo hello | nc -vv localhost 9000 # подсоединиться и переслать строку

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

> Вот хз. Костыли для браузеров вообще настроек не имеют, но также не работают.


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

Ну и по моему конечно удобнее отлаживать что тебе надо локально, а не мучаться с пробросами. И уж тем более не стоит запускать наверно отладчик на продакшен сервере.
#361 #423428
>>423273

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

>>423274

Там же есть поиск и категории, посмотри сам

>>423276

> всёравно это же плохо что она возникает?


Да, плохо. Ошибок вообще не должно быть никаких.

Чтобы ошибки не было, надо до цикла присвоить переменной letters какое-то значение, например, пустую строку.

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


Для перебора массива удобнее использовать foreach :

foreach ($words as $word)

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

заодно стоит добавить проверку, если встретилась комбинация для которой нет шифра например BBBBB то вставлять вместо нее знак вопроса.
#362 #423432
>>423296

Автоматическая проверялка для первых 7 (ого, а было только 4): http://dkab.github.io/jasmine-tests/

Разумеется даже если проверялка пишет что все ок, стоит все равно запостить ссылку на свой код в тред. Если ты проверил код проверялкой, упомяни это.
#363 #423447
>>423311

Я ничего не удалял. Поста про udacity не видел.

>>423297

> Везде false, как я понял потому что при сравнении объектов они сравниваются на идентичность а не на равенство, то есть являются ли операнды одной сущностью или разными.


Да, все верно. Хорошо, что ты это знаешь.

> if (this.findFilling(fill) != -1) {


> this.filling.splice(fillIndex, 1);


Опечатка же. переменная не существует такая

> Про объект в константе понял, но не вижу преимуществ, может позже сделаю.


Ладно, тогда можешь не делать. Я лучше потом подумаю, может можно как-то условия задачи поменять чтобы это не работало :)
#364 #423450
>>423363

Анон правильно пишет. lastInsertId как следует из названия, возвращает число после выполнения INSERT.
#365 #423451
>>423447
Ты можешь удалять посты?
#366 #423455
>>423451

Свои вроде могу
#367 #423456
>>423455
Что-то я сомневаюсь в этом.
#368 #423465
Роберт Стронг лучше обоих.
/discuss
#369 #423468
>>423465
Неа, не лучше.
#370 #423469
>>423465
Блядь, угораздило. Сейчас функция удаления постов пришлась бы очень кстати.
#371 #423486
>>423447

>Опечатка же. переменная не существует такая


Да, точно, упустил, поправил: http://jsbin.com/hunuxugaru/1/edit?js,console
В общем приступаю к 13 задаче
#372 #423567
Сделал выражение для валидации почты. Ничего не упустил?
(preg_match('~^([0-9a-zA-Z_\.-]+@[0-9a-zA-Z_\.-]+\.[0-9a-zA-Z_\.-]+)$~', $string)
#373 #423568
>>423567
Любишь велосипеды?
#374 #423569
>>420053
Поссал на тебя.
момомикроконтроллер
#375 #423570
>>423569

>мимо


починка
#376 #423571
>>423309

Советую освоить git и github чтобы постить туда код. Книга на русском по гиту: http://git-scm.com/book/ru/v1/

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

session_start в index.html не нужен так как сессия там все равно не используется.

> if (!isset($_SESSION['name']))


>\t$_SESSION['name']= $_POST['name1'];


Тут стоило бы проверять есть ли вообще в POST такое поле и не пустое ли оно, если нету то редиректить на index

Смесь html и php в одном файле смотрится не очень — лучше вынести html код в шаблоны в папочке templates и подключать черехз require.

Классы по идее тоже стоит вынести в отдельный файлы lib/Desk.php и lib/Player.php

> <META HTTP-EQUIV='Refresh' CONTENT='5; URL=http://localhost/php/chess/index.html'>


Лучше использовать header("Location ...") для редиректа.

> if (isset($_POST['reset1']))


Кнопка reset не отправляет форму а только очищает поля в ней.

Также, хорошо бы убрать копипасту шапки страницы и вынести ее в отдельный шаблон.

Введенный ник нигде не отображается.

Также, раз уж ты сделал HTML ты бы мог сделать отображение более наглядным. Например сделать таблицу table для игрового поля, а игроков отображать кружочками разных цветов или картинками. Разумеется для этого надо убрать все echo из классов и выводить поле по-другому.

В общем, тут есть что развивать.
#376 #423571
>>423309

Советую освоить git и github чтобы постить туда код. Книга на русском по гиту: http://git-scm.com/book/ru/v1/

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

session_start в index.html не нужен так как сессия там все равно не используется.

> if (!isset($_SESSION['name']))


>\t$_SESSION['name']= $_POST['name1'];


Тут стоило бы проверять есть ли вообще в POST такое поле и не пустое ли оно, если нету то редиректить на index

Смесь html и php в одном файле смотрится не очень — лучше вынести html код в шаблоны в папочке templates и подключать черехз require.

Классы по идее тоже стоит вынести в отдельный файлы lib/Desk.php и lib/Player.php

> <META HTTP-EQUIV='Refresh' CONTENT='5; URL=http://localhost/php/chess/index.html'>


Лучше использовать header("Location ...") для редиректа.

> if (isset($_POST['reset1']))


Кнопка reset не отправляет форму а только очищает поля в ней.

Также, хорошо бы убрать копипасту шапки страницы и вынести ее в отдельный шаблон.

Введенный ник нигде не отображается.

Также, раз уж ты сделал HTML ты бы мог сделать отображение более наглядным. Например сделать таблицу table для игрового поля, а игроков отображать кружочками разных цветов или картинками. Разумеется для этого надо убрать все echo из классов и выводить поле по-другому.

В общем, тут есть что развивать.
#377 #423572
>>423309

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

Задания по HTML/CSS советую прорешать и запостить тут решения.

>>423486

Ок, хорошо, приступай.

>>423567

http://habrahabr.ru/post/55820/
http://habrahabr.ru/post/175375/

Читал?
#378 #423576
>>423572

>http://habrahabr.ru/post/175375/


>


>Читал?



>Если же вы все равно не можете успокоиться, пока не проверите адрес на корректность, просто проверьте на наличие в нем символа @. А если чувствуете, что способны на большее — добавьте проверку на точку:



>/.+@.+\..+/i



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

Ну тогда верну как было и прицеплю экранирование к sql-запросу.
#379 #423591
не пойму почему ругается на последнюю строку http://ideone.com/d8xrsr
#380 #423592
>>423591
все понял, $ не нужна при обращении к полю объекта, а еще скобочки забыл прои создании экземпляра класса
141 Кб, 1789x1080
#381 #423597
Почему функция выводится не там где надо?
#382 #423604
>>423597
может там return нужен у функции, чтобы сумму эту возвращал?
210 Кб, 1789x1080
#383 #423629
>>423597
Где ты её вызываешь, там она и выводится
52 Кб, 700x516
#384 #423630
Можете бить меня, но...

Я не понимаю где можно применять пхп, объясните аутисту.

i4b:в тред для ньюфагов.
#385 #423639
>>423571
>>423572
Благодарю.
#386 #423647
>>423571
Очень сухо описано в http://git-scm.com/book/ru/v1/ плохо воспринимается, есть ли более краткое и более содержательное объяснение сути git и инструкций по пользованию? Видеогайд какой-нибудь годный может
4 Кб, 344x163
#387 #423651
>>423647
Почему когда я пытаюсь связать локальный рипозиторий и github у меня логин вводится нормально, а в строке где просит ввести пароль у меня ничего не набирается на любой раскладке?
#388 #423656
Ананасы, у меня вопрос по JS, но совсем нубский, тут мне помогут или уебывать в JS-тред?
#389 #423657
>>423651
Только с этим и разобрался, ничего не ясно с git, я один начинаю беситься когда ничего не ясно и не ясно даже с чего начать?
#391 #423663
Поясните, вот создал я паблик переменные в классе, а еще в этом классе есть метод, так как мне с помощью метода этого менять поля объекта этого класса?
Т.е. я создал новый объект этого класса, запустил для него метод, пишет что переменная (я использовал поле свойства объекта класса, тот который как паблик объявлен) не определена.

Можно как-то вывести из функции больше одного значения?
#392 #423664
>>423663

>Поясните, вот создал я паблик переменные в классе, а еще в этом классе есть метод, так как мне с помощью метода этого менять поля объекта этого класса?


Имел в виду не поля у класса менять, а у ЭКЗЕМПЛЯРА класса.
#393 #423665
>>423664
$this->field = "Whatever";
У опа же все понятно в учебнике написано.
#394 #423674
>>423665
$this->$clientDebt = $creditSumm;

$creditSumm - аргумент метода,
$clientDebt - поле объекта класса

пишет Cannot redeclare
#395 #423675
>>423674

>$this->$clientDebt


Зачем два доллара? К полям вот так обращаются $this->clientDebt
#396 #423678
>>423675
$this->clientDebt = $this->clientDebt + $a+$b

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

И я не понял, поля меняться будут у объекта класса или у класса? Что если вызвать метод сам по себе без привязки к классу?
#397 #423679
>>423678

>И я не понял, поля меняться будут у объекта класса или у класса?


У объекта конечно. Класс это просто описание. Вызвать метод без привязки к классу? Ты наверное имел ввиду без привязки к объекту? Вроде бы можно, только я не понимаю зачем это нужно.
#398 #423685
>>423679

>Ты наверное имел ввиду без привязки к объекту? Вроде бы можно, только я не понимаю зачем это нужно.



Ну как же , просто передаем аргументы, получаем возвращаемое значение - профит.
#399 #423686
>>423685
Зачем тебе вообще класс тогда? То, что ты хочешь делается обычной функцией.
#400 #423688
>>423686

>делается обычной функцией.


Мне надо в результате работы функции получить более чем 1 значение. Так я могу сохранить их в поле класса и получить к ним доступ.
#401 #423689
>>423688
Про массивы слышал?
#402 #423692
>>423689
Чорт, я знал что что-то забыл.
53 Кб, 829x405
#403 #423731
ОП, в статье про phpunit ниполучается.
Пытаюсь повторить пример из урока, а оно мне пишет то, что на пикрелейтед.
ЧЯДНТ?
#404 #423754
>>423647
Так и должно быть, вводи пароль и жмакай ентер
#405 #423755
>>423754
Ошибка, это сюда >>423651
ОПЕЧАТКА #406 #423774
ОП, очепятка

>то есть есть панели


вот тут в 13 задаче: https://gist.github.com/codedokode/ce30e7a036f18f416ae0
#407 #423777
>>423774
Там дохуя опечаток, но мы же тебе не гуманитарии.

з.ы. Конкретно в этом случае опечатки нет, аффтар так и хотел сказать:
"... то есть есть панели, которые генерируют 1 мегаватт, (а) есть (панели) которые (генерируют) 2".
Будь я граммар-наци, я бы лучше приебался к отсутствию запятой перед "которые".
#408 #423799
>>423731

<?php не забыл написать? PHP выполняет код только после того маркера иначе он просто его выводит.

>>423774

Имеется в виду «то есть существуют панели»

>>423777

Сейчас прочел и ужаснулся. Корявый стиль изложения, конечно, как будет время, попробую написать аккуратнее. Я так-то знаю, как ставить запятые, но когда спешу, то могу пропустить. Также, раньше я читал книжки, а сейчас читаю интернет и когда целый день видишь примеры неграмотного написания, сам начинаешь так же писать.
#409 #423800
>>423651

Пароль не отображается чтобы его не прочла твоя мама, брат или агенты ЦРУ.

>>423656

Зависит от вопроса.

>>423657

Собирай все вопросы и пиши сюда. Я рано или поздно приду и объясню. Алсо, читай git book если еще не читал.

Гит для начинающего может быть сложен, но со временем ты привыкнешь.
#410 #423806
>>423800
Хорошо, спасибо. Вопрос: у меня есть папка с проектом, как мне её добавить в репозиторий локальный и как потом перенести её на мой аккаунт в github
#411 #423809
>>423799

> <?php не забыл написать?


Оу, вот оно че, михалыч!

чсх, сначала написал шорт опен тег, не проканало. а с полным тегом <?php работает, да.

К слову, раз уж затронули короткие теги, шо вы можете сказать по этому поводу, сэнсэй? Их наверное лучше вообще не использовать, да?
Вот в юнит-тестировании с ним проблемка оказалась, вдруг еще где-нибудь всплывет.
#412 #423811
>>423806
Удвою этого лентяя.
Пожалуйста, не посылайте нас штудировать этот талмуд http://git-scm.com/book/ru/v1, там слишком много буков!
Нам бы кратенько пару основных команд.
#413 #423815
>>423806

>как мне её добавить в репозиторий локальный


git init
git add .
git commit -m "твой комментарий"

>как потом перенести её на мой аккаунт в github


Прости, еще не выучил наизусть это
#414 #423818
Имеет смыл читать книги по алгоритмам?(напр. Томас Кормен-Алгоритмы, Вводный курс). Что они могут дать?
#415 #423820
>>423818
Если ты ньюфаг, до того как пройдешь весь учебник ОПа, смысла точно нет.
#417 #423823
>>423820
Я когда-то давно почти весь прошел, теперь надо заново пройти.
А почему смысла нет?
#418 #423825
>>423823
Ну в моем понимании если ты ньюфаг, то и переменную от массива не отличишь, куда уж тут до алгоритмов
#419 #423827
>>423825
Алгоритмы надо было учить еще в школе на информатике.
мимо
#420 #423828
>>423809

<? никогда не использовать
<?php использовать
<?= использовать для вывода в шаблонах

>>423811

Гит не управляет папками. Он управляет файлами. Чтобы добавить пустую папку, создай в ней пустой файл .placeholder и добавь его через

git add .
git commit -m "...."

git init писать не надо, это только для создания нового репозитория.
#421 #423830
>>423827

>на информатике


Насмешил, содомит. А в экселе поработать не хочешь?
#422 #423833
>>423825
Но это ведь объясняется в книгах как раз.>>423827 А школоинформатичных знаний достаточно?
#423 #423835
>>423833
Что, это? Чтобы отличить переменную от массива, учебника ОПа хватит с головой.
#424 #423840
>>423663

> Можно как-то вывести из функции больше одного значения?



массив

return array(
'a' => 1,
'b' => 2
);

или

return array(1, 2, 3);
#425 #423841
>>423630

Для создания сайтов и веб приложений. Вконтакте, фейсбук, википедия.
#426 #423842
>>423835

> отличить переменную от массива


Что ты несёшь?
#427 #423849
>>423842
Хуйню, в том и соль
#428 #423897
>>423597

У тебя нет ретурна и не совсем по условиям задачи. Для третьего банка, например, надо начислять 7777 после того, как проценты насчитаешь, если я правильно понял условия задачки.
И ещё над условием завершения цикла. Ты подумай, ведь за последний месяц тоже нужно внести ежемесячный платеж.

Вот моё решение:http://ideone.com/Ya9GnQ
Знаю, что называю переменные как мразь.
#429 #423925
>>423260

Вроде норм, посмотрим потом еще.

>>423647

Это хорошая книга. Если что-то непонятно, напиши какое именно предложение непонятно, разъясним. Видеогайд не поможет так как надо не нажимать кнопочки а понимать как git работает.

>>423663

> так как мне с помощью метода этого менять поля объекта этого класса?



Через $this ($this это псевдопеременная представляющая собой текущий объект, на котором и вызвана функция).

....
public $x = 0;

public function doSmth()
{
$this->x = 1; // меняем поле x
}
.....

>>423678

Можно писать через +=

> поля меняться будут у объекта класса или у класса?


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

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


Нельзя вызвать. Ошибка будет.

>>423679

Нельзя же.

>>423688

Массив можно использовать.

>>423774

Переформулировал предложение, спасибо за внимательность. Действительно, 2 слова «есть» подряд сбивают с толку.

>>423777

Но ведь слово «панели» пропущено, точно ли нужна запятая?

>>423806

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

Насчет папки с проектом есть 2 варианта. В любом случае сначала надо создать пустой репозиторий на гитхабе.

- создать новый репозиторий через git init и закоммитить файлы проекта. После чего добавить remote origin указывающий на гитхаб. Описано тут https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/

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

То есть всего есть 2 варианта создания репозитория:

- создать в любой папке через git init (фактически это только создаст папку .git с пустым репозиторием)
- склонировать другой репозиторий через git clone (при этом связь с исходным сохраняется). При этом файлы из репозитория будут автоматически выгружены в папку. Так стоит делать только в пустой папке.
#429 #423925
>>423260

Вроде норм, посмотрим потом еще.

>>423647

Это хорошая книга. Если что-то непонятно, напиши какое именно предложение непонятно, разъясним. Видеогайд не поможет так как надо не нажимать кнопочки а понимать как git работает.

>>423663

> так как мне с помощью метода этого менять поля объекта этого класса?



Через $this ($this это псевдопеременная представляющая собой текущий объект, на котором и вызвана функция).

....
public $x = 0;

public function doSmth()
{
$this->x = 1; // меняем поле x
}
.....

>>423678

Можно писать через +=

> поля меняться будут у объекта класса или у класса?


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

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


Нельзя вызвать. Ошибка будет.

>>423679

Нельзя же.

>>423688

Массив можно использовать.

>>423774

Переформулировал предложение, спасибо за внимательность. Действительно, 2 слова «есть» подряд сбивают с толку.

>>423777

Но ведь слово «панели» пропущено, точно ли нужна запятая?

>>423806

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

Насчет папки с проектом есть 2 варианта. В любом случае сначала надо создать пустой репозиторий на гитхабе.

- создать новый репозиторий через git init и закоммитить файлы проекта. После чего добавить remote origin указывающий на гитхаб. Описано тут https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/

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

То есть всего есть 2 варианта создания репозитория:

- создать в любой папке через git init (фактически это только создаст папку .git с пустым репозиторием)
- склонировать другой репозиторий через git clone (при этом связь с исходным сохраняется). При этом файлы из репозитория будут автоматически выгружены в папку. Так стоит делать только в пустой папке.
#430 #423928
>>423811

Прочитать все равно стоит. Если не понимаешь как устроен гит, работать с ним тяжело.

>>423815

Добавить удаленный репозиторий через git remote add ... и сделать pull / push

>>423818

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

>>423822

> var objectType = Object.prototype.toString.call(variable).split(" ")[1].substr(0, Object.prototype.toString.call(variable).split(" ")[1].length - 1);



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

case '[object Date]':

> case "Function":


>\t\t\t\t\t\t\treturn "Function";


Функцию можно определять через typeof

> if (variable.length >= 0 && variable.splice(


У псевдомассивов нет методов массива вроде splice, потому они и псевдомассивы. Также, проверяющая функция не должна что-то менять в массиве (а splice меняет).

А так, идея решения правильная.
#430 #423928
>>423811

Прочитать все равно стоит. Если не понимаешь как устроен гит, работать с ним тяжело.

>>423815

Добавить удаленный репозиторий через git remote add ... и сделать pull / push

>>423818

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

>>423822

> var objectType = Object.prototype.toString.call(variable).split(" ")[1].substr(0, Object.prototype.toString.call(variable).split(" ")[1].length - 1);



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

case '[object Date]':

> case "Function":


>\t\t\t\t\t\t\treturn "Function";


Функцию можно определять через typeof

> if (variable.length >= 0 && variable.splice(


У псевдомассивов нет методов массива вроде splice, потому они и псевдомассивы. Также, проверяющая функция не должна что-то менять в массиве (а splice меняет).

А так, идея решения правильная.
#431 #423929
>>423823

У нас кроме учебника есть задачи (мозголомные) на HTMl/CSS, JS, MySQL. А также продвинутые задания вроде сделать страничку или сайт. Может их лучше решать?

>>423830

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

>>423597

Код лучше на ideone постить
#432 #423930
Аноны, я напомню, для тех, кто решает JS задачки, у нас тут есть проверялка для первых 7 из них: http://dkab.github.io/jasmine-tests/

Учтите, что она пока в тестовом режиме и может ошибаться. И разумеется, даже если она пишет что все верно, лучше все равно запостить ссылку на решение в тред.
#433 #423951
А тут есть работающие ПХП-программистами? В чем работа заключается, сколько платят? Мотивируйте что-ли.
#434 #423954
Аноны, допустим на сайте есть ссылка на другой сайт, как сделать на ПХП подсчёт переходов по этой ссылке?
#435 #423974
>>423951
Да, тут все прям пару задачек порешали и го бабло закалачивать. Сейчас накидают ответов, погоди немного.
#436 #423976
Расскажите, чем отличается mb_substr от mb_strcut? Нужен ли EREG или сейчас все PCRE используют?
#437 #423985
Всем спасибо кто помогал разобраться с git и github, вышло добавить проект в репозиторий в github на своем аккаунте, теперь с функционалом буду разбираться.
#438 #423997
>>423985
Вот наконец-то решился сделать кошек-мышек, https://github.com/Si0n/CatNmouse/blob/master/catnmouse.php пока что наброски, есть ли какие-нибудь замечания?
#439 #424009
>>419972
Оп, буду очень благодарен, если поможешь провести расследование.
В общем нарыл я галерею( http://tympanus.net/Development/GammaGallery/ исходники тут можно найти http://tympanus.net/codrops/2012/11/06/gamma-gallery-a-responsive-image-gallery-experiment/ ) , которая подходит мне для проекта. Перепидарил многое под себя, даже исправил пару косяков в коде. И тут заметил одну раздражающую меня вещь: при клике на стрелочку смены фотографии на следующую ширина изображения на пару пикселей меняется(справа) прежде чем переключиться. И получается, что изображение немного дергается. Причем в мозиле такого нет, а в хроме и опере случается. Ума не приложу что за хуйня такая. Когда при смене картинки смотришь в инструменты разработчика - параметры ширины там не меняются. Ума не приложу что это за такое.
#440 #424026
>>423997
Зачем всё в паблике? Зачем можно создать экземпляр класса Animal? В __construct Desk'а заполнение доски выноси в приватный метод. Циклы в getAnimalsOnBoard выноси в приватный метод. В getClosiestEnemy тоже плохо понятно что происходит внутри цикла, дроби на мелкие методы. Не знаю как в php это делается, но возможно стоит хранить максимальный number в Animal в виде переменной класса и обновлять при создании экземпляра, чтоб не заморачиваться с присвоением номера очередному животному.
#441 #424044
Можно ли со строками вести себя как с массивами? То есть например работать с ними через цикл, и в цикле выполнять всякие операции с ними? Если нет, то почему?
#442 #424049
>>424026
Область видимости перепишу, а номера я ввел для того чтобы быстрее проверить - правильно ли ищет ближайшего врага, номера наверное уберу потом когда отпадет надобность в такого рода визуальной проверке.
#443 #424063
>>423974
Ну и где обещанные тобой ответы? Или в моем вопросе что-то не то?
#444 #424064
>>424063
У тебя детектор сарказма неисправен.
#445 #424155

>подскажи пожалуйста милый друг,знаком ли ты вот с этими курсами? http://rutracker.org/forum/viewtopic.php?t=4620353 .Стоит ли учиться по ним?

#446 #424158
>>424155

>Расширение MySQLi


Есть теория, что они уже устарели.
#447 #424162
>>424155
Учебник ОПа получше будет.
мимо-знакомый-с-курсами
#448 #424164
>>424158
MySQL устарели, а MySQLi продвигается как новое решение. Хотя PDO обычно удобнее.
#449 #424167
>>424164
MySQL это СУБД, а mysqli и pdo - расширения похапе для работы с mysql. Сравниваешь теплое с мягким
#450 #424168
>>424155
Неплохие курсы, но не для новичков.
Вот я по ним учился, было очень-очень сложно.
И там голая теория, практически нет примеров, а если есть то ненаглядные и непонятные.
Курсы специально растянуты на много часов, чтобы оправдать те деньги, которые люди за них платят, много воды, паузы (это запись вебинаров).
С другой стороны, послушать Борисова не помешает, уважаемый опытный человек.

Короче, если ты полный новичок, то качни оттуда только первые два курса из четырех. Остальные два (а там есть реально ценная инфа) посмотришь после прохождения уроков ОПа.
#451 #424178
>>424044
Ты имеешь ввиду с каждым символом по отдельности?
Почему бы и нет.

$str = 'hello world';
for($i=0; $i<mb_strlen($str); $i++){
echo $str{$i}.'<br>';
}

Можно и разбить строку на символы через str_split.
Аноним #452 #424190
Сап. Застрял на функциях решил опробовать тот код, который в уроке.
<?php
function getBalanceInFuture($deposit, $percent, $years) {
\tfor ($i = 0\t, $i < $years; $i++;)
\t{
\t\t$deposit = $deposit $percent;
\t}
\t
\treturn $deposit;
}
$balance = getBalanceInFuture(10000, 1.05, 7);
echo "Через 7 лет у нас будет {$balance} рублей на счету\n";

По итогу все равно выводит 10 000 рублей.
В чем ошибка?
Аноним #453 #424191
>>424190
Опаньки. В идеуане есть знак умножения, а сюда скопировалось без него. Чому?
#454 #424193
>>424190
Всё, понял, неправильно оформил тело цикла.
#455 #424214
>>419972
Подскажите как сделать такое:
у меня три больших дива на странице. При большом разрешении они умещаются на экране в ряд.
При маленьком наезжают друг на друга.
Как сделать, чтобы вместо того, чтобы наезжать друг на друга -- они в столбик.
просто не знаю как загуглить такое
#456 #424215
>>424214
становились в столбик.
#457 #424218
>>424214
Попробуй twitter bootstrap заюзать.
#458 #424223
>>424155
После первых двух уровней будешь делать свои сайтики как бох. За третий и четвертый лучше не браться пока не доведешь до совершенства процедурное программирование, которое и излагается в первых двух полностью.
#459 #424227
>>424214
медиазапросы гугли
86 Кб, 1600x900
#460 #424229
Нуб в треде.
Анон, начал мутить уроки, расположенные по этйо ссылке. Сделал первый, покритикуй, все правильно сделал, или нет.
#461 #424230
>>424229
http://archive-ipq-co.narod.ru/ ссылку забыл вставить.
#462 #424233
>>424229
Нет. Кавычки нужны одинарные.
#463 #424236
>>424178

>Ты имеешь ввиду с каждым символом по отдельности?


Да именно это я и имел ввиду. Мне кажется где-то натыкался и не раз что это крайний метод, лучше так не поступать, я правда не знаю почему, может это медленнее?
#464 #424237
>>424155
Это же отличные курсы как мне кажется, они+учебник ОПа+мануал это как раз то что надо, спасибо что поделился ссылкой, буду качать. Там есть очень ценная вещь, пошаговое создание интернет-магазина и т.д
#466 #424270
>>424214
Сделай плавающими, например:
\t\tdiv {
\t\t\twidth: 300px;
\t\t\theight: 300px;
\t\t\tbackground: #ccc;
\t\t\tborder: 1px solid #000;
\t\t\tfloat: left;
\t\t}
#467 #424337
Помогайте кто может!
Что-то не могу догнать, почему не проходит подготовленный запрос. Если подставить параметры ручками, все прекрасно фетчится.
А подставляю плейсхолдеры, возвращается пустой массив.

Вот это фетчится
$query = 'SELECT name, surname, group, mark FROM info ORDER BY mark LIMIT 0, 10';

А это нет
$query = 'SELECT name, surname, group, mark FROM info ORDER BY mark LIMIT :offset, 10';

https://gist.github.com/krbn/dd3040adc8cd6f813647
#468 #424340
>>424337

Для начала, включи отображение ошибок приходязих от БД если оно еще не включено:

http://php.net/manual/ru/pdo.error-handling.php

Тебе нужен режим PDO::ERRMODE_EXCEPTION

Заметь что по умолчанию там стоит SILENT то есть молча игнорировать все ошибки (я не понимаю чем думали разработчики PDO, если честно).
#469 #424342
>>424337
исправь $stmt->bindParam(':offset', $offset);
на $stmt->bindParam(':offset', $offset, PDO::PARAM_INT);
#470 #424343
>>424337

Далее, ты передаешь вот тут значение аргумента

$stmt->bindParam(':field', $order);

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

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

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

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

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

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

- ошибки сохраняются в лог ошибок. Можно открыть его и почитать. Если ты запускаешь код на локалхосте, у себя, то лог хранится в папке Апача (обычно она называется logs) и имеет название вроде error.log (в линуксе в папку /var/log/apache2 ). Если на хостинге — там либо есть файл error.log либо раздел в панели управления, где лог можно посмотреть

- также, ты можешь включить отображение ошибок. Открой файл php.ini, поставь там display_errors = On и error_reporting = E_ALL и перезапусти сервер. Теперь ошибки должны выводиться на экран.

Проверить, работает ли вывод ошибок, можно запустив скрипт содержающий обращение к несуществующей переменной вроде echo $sdgasdad; и проверив, выведется ошибка или нет. Если все верно, то должна вывестись.
#471 #424345
>>424342

Да, может быть у него число в кавычки заключается по умолчанию. Но при этом должна выводиться ошибка MySQL.
#472 #424346
>>424340
Спасибо.
Вот она, ошибка.
SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''0', 10' at line 1
>>424342
Да, дело было в типе передаваемой переменной. Он ожидал число, а пришла строка (или наоборот, что-то я путаюсь).
>>424343
Ох, чувак, ты быстрее пишешь, чем я читаю.
#473 #424347
>>424346

Да, у тебя в запросе получилось

LIMIT '0', 10

Так как по умолчанию bindParam вставляет параметр как строку.
#474 #424348
>>424229

Все верно. Молодец, делай следующие задания.
8 Кб, 362x262
#475 #424351
>>424343

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


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

>проверить на белый список


Я в курсе, собирался сделать следующим шагом эту проверку.

>bindValue вместо bindParam


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

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

Сейчас допиливаю этот квест. https://gist.github.com/codedokode/d7e7f11449fc3bcb24b4
Если не споткнусь еще на чем-то, то завтра надеюсь закончить.
Вот кусок кода с основными классами. Может посмотрите, вдруг еще какие-нибудь замечания, чтоб не пришлось еще раз переделывать (а таки наверняка придется).
https://gist.github.com/krbn/1b1681e85ccca3b0d96f
И еще вопрос по MVC. Я правильно понял, что смысл ее в том, чтобы распихать код по файлам контроллеры - файлы моделей - шаблоны с хтмл?
На пике прикрепляю грубую схему сайта с регистрацией абитуриентов (там еще куча мелких контроллеров на самом деле).
Основную идею я правильно понял?
426 Кб, 1600x1200
#476 #424359
Няши, помогите с небольшой проблеммкой. Я уже месяц ладно - полтора как начинающий вебпогроммист и мне необходимо передать из пхп в жс трехмерный массив. Массив я этот с горем пополам составил на пхп. Сначала преобразовывал в строку, записав вначале параметры массивов и подмассивов, а в жаваскрипте разбирал. Массив, с очень хуевой структурой. Все подмассивы разных размеров и заполнены очень разным говном. Но стоило мне поменять чуть-чуть структуру и я уже зарыдал как маленькая девочка от того, что предстоит сделать. Решить надо в максимально кратчайшие сроки.
#477 #424369
>>424359
Что?
Массив можно сериализовать многими способами, через функции json, например. Пока непонятно, что ты хочешь.
Кидай свой код на gist.github.com или ideone.com, потом сюда ссылку, разберемся.
#478 #424376
>>424359
ну епта, гугол наше все
http://php.net/manual/ru/ref.json.php
#480 #424396
>>424376
>>424369
Я когда гуглил, то испугался страшных слов "сериализация" и "json". Решил, что это опять какие-то языки жуткие, опять три дня мануалы курить и сделал по-своему. Оказывается, >>424393 тут это есть и сделано элементарно. И у меня работает! Спасибо.
#481 #424400
>>424396
Мануалы все-равно курить придется, и не три дня, а три месяца.
Завтра тебе скажут передать данные обратно из js в php, ты опять сюда придешь за готовым решением?

>тут это есть


Это я написал решение твоей задачи. Пост анонимный кстати, не знаю, сколько они хранятся на гитхабе. Так что скопируй, пока не удалили.
#482 #424404
>>419972
Простой сайтик.

https://github.com/tokotun/matriculant/blob/master/app/functions.php#L55
Вот тут в GET-запрос попадает только 'name'. Остальное почему то не записывается :(

Ебать я ленивый. Заставить себя что либо делать удаётся только раз в неделю, а то и реже.
Наверно боги те, кто может управлять собой.
#483 #424405
>>424400

>js в php


Это я уже умею. POST/GET
Я просто решил пока сосредоточиться на одном языке. Жаваскрипте. Когда я натяну его до должного уровня, то крепко займусь пхп. Так я решил. Возможно, для кого-то это покажется глупым и неправильным, но я по такой методе овладел уже двумя различными сложными для меня навыками на нужном мне уровне. А это английский и рисование.

>Так что скопируй, пока не удалили.


Я оттуда взял всего пару строчек. Да и их я запомнил уже. Спасибо на том.
#484 #424411
>>424236
>>424178
>>424044
Со строчками нельзя вести себя как с массивами, если используется мультибайтовая кодировка как utf-8, так как каждый символ весит разное количество байт, а для использования [] нужно, чтобы символы весили равное количество байт.
Попробуй mb_substr($str,$pos,1,'UTF-8');

Вот паста ОПа про работу со строками. https://gist.github.com/codedokode/ff99e357e9860ea169b8
#485 #424432
А как бы правильно сделать редирект после отправки формы?
Чтобы пользователь дважды не отправил пост/рег.данные при обновлении f5.
Видел такой заголовок, но не совсем понял, в каком месте его лепить.
header('Location: '.$_SERVER['REQUEST_URI']);

Вот у меня после отправки формы через шаблонизатор подгружается содержимое if($_SERVER['REQUEST_METHOD'] == 'POST'){ первая вьюха } else { вторая вьюха }.
Если я допишу хедер локейшн то меня же перекинет методом гет, и прорисуется совсем другой контент. Как быть?
#486 #424461
>>423954

Один из вариантов — сделать переход через скрипт подсчета на своем сайте например

http://example.com/goto/site.com/page.html

>>423976

> чем отличается mb_substr от mb_strcut


http://php.net/manual/ru/function.mb-strcut.php

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



Тебе она скорее всего никогда не понадобится.

> Нужен ли EREG или сейчас все PCRE используют?


pcre. ereg вроде даже удалять собирались.

>>423997

Как советует анон, давай на этой задаче освоим что такое доступ private/protected. Сделай все свойства private/protected, а не public, чтобы они быди доступны только из своего класса. Также, все методы которые не должны вызываться снаружи, пометь закрытыми.

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

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

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

Свойство this->board лучше заменить на переменную, так как его не требуетс хранить, оно временное.

Методы поиска врагов и выбор хода должны быть в кошке/мышке, а не в карте.
#486 #424461
>>423954

Один из вариантов — сделать переход через скрипт подсчета на своем сайте например

http://example.com/goto/site.com/page.html

>>423976

> чем отличается mb_substr от mb_strcut


http://php.net/manual/ru/function.mb-strcut.php

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



Тебе она скорее всего никогда не понадобится.

> Нужен ли EREG или сейчас все PCRE используют?


pcre. ereg вроде даже удалять собирались.

>>423997

Как советует анон, давай на этой задаче освоим что такое доступ private/protected. Сделай все свойства private/protected, а не public, чтобы они быди доступны только из своего класса. Также, все методы которые не должны вызываться снаружи, пометь закрытыми.

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

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

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

Свойство this->board лучше заменить на переменную, так как его не требуетс хранить, оно временное.

Методы поиска врагов и выбор хода должны быть в кошке/мышке, а не в карте.
#487 #424462
>>424009

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

>>424158

Сам по себе mysqli позиционируется как замена mysql функциям и не устарел. Проблема в том, что преподаватели вместо того чтобы написать новые уроки, берут старые уроки по mysql c ошибками и уязвимостями и приписывают там буковку i. Это разумеется плохо.

Потому лучше изучать PDO чтобы не наткнуться на такие уроки: http://habrahabr.ru/post/137664/

Вот статья по mysqli: http://habrahabr.ru/post/141127/

Я советую не использовать процедурные методы, а ООП-вариант mysqli. Ну и PDO удобнее хотя бы тем что умеет кидать исключения (хотя есть места где он проигрывает mysqli).
#488 #424463
>>424158

То есть если вы видите в уроке mysqli_query(), mysqli_fetch_..., не используются плейсхолдеры то 99% что это старый неграмотный урок в котором приписана буква i к быдлокоду из mysql-функций.
#489 #424464
>>424167

Он имел в виду php-расширение mysql предоставляющее функции клиента MySQL.

>>424044

Не стоит, так как в PHP строка это не набор символов, а набор байт. И ты получишь в итоге разорванные на куски буквы (в utf-8 буква занимает несколько байт). Если тебе хочется то лучше разбить строку на массив букв и с ним работать:

Для разбиения на буквы можно использовать

$letters = preg_split("//u", $text, null, PREG_SPLIT_NO_EMPTY);

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

Обрати внимание на флаг u. Он говорит что текст в utf-8 и заставляет разбивать строку именно на буквы по границам utf-8 символов, а не на куски по 1 байту.
#490 #424465
>>424190

В след раз пости ссылку на ideone а не сам код.

>>424191

Разметка

>>424214

У тебя изначаьно сверстано неправильно скорее всего, не видя кода трудно дать совет. Если хочешь могу дать задачи на HTML/CSS, полезные.

>>424218

bootstrap не заменяет необходимость знать CSS

>>424251

Гляну но наверно завтра, пока что некогда

>>424270

Не стоит давать такие советы если человек не знает флоатов так как он все равно не поймет что к чему и почему текст ниже уехал вверх. Лучше прорешать задачки на HTML/CSS.

>>424351

> И еще вопрос по MVC. Я правильно понял, что смысл ее в том, чтобы распихать код по файлам контроллеры - файлы моделей - шаблоны с хтмл?



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

> На пике прикрепляю грубую схему сайта с регистрацией абитуриентов (там еще куча мелких контроллеров на самом деле).


> Основную идею я правильно понял?



Боюсь то не совсем. require для классов не надо ставить в if а надо ставить в самое начало файла.

По коду:

Синглтоны не очень хорошая штука, лучше вообще без них делать тем более в учебной задаче (если интересно почему почитай мой урок про внедрение зависимостей и связи между объектами: https://gist.github.com/codedokode/e1d31a31b37d5f635057 Учти что уровень урока довольно сложный).

Если одному классу нужен экземпляр другого напрмер объект PDO то лучше всего передавать его через конструктор.

> \tfunction insertIntoDB(Student &$student){


& не нужен: http://php.net/manual/ru/language.oop5.references.php (кстати я уже второй раз пишу это замечание, не тебе ли в прошлый раз писал?)

try/catch писать не надо, вот мой урок про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Даже если твой код пока не работает, лучше все равно его показывать, так как в этом случае меньше исправлять потом придется.
#490 #424465
>>424190

В след раз пости ссылку на ideone а не сам код.

>>424191

Разметка

>>424214

У тебя изначаьно сверстано неправильно скорее всего, не видя кода трудно дать совет. Если хочешь могу дать задачи на HTML/CSS, полезные.

>>424218

bootstrap не заменяет необходимость знать CSS

>>424251

Гляну но наверно завтра, пока что некогда

>>424270

Не стоит давать такие советы если человек не знает флоатов так как он все равно не поймет что к чему и почему текст ниже уехал вверх. Лучше прорешать задачки на HTML/CSS.

>>424351

> И еще вопрос по MVC. Я правильно понял, что смысл ее в том, чтобы распихать код по файлам контроллеры - файлы моделей - шаблоны с хтмл?



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

> На пике прикрепляю грубую схему сайта с регистрацией абитуриентов (там еще куча мелких контроллеров на самом деле).


> Основную идею я правильно понял?



Боюсь то не совсем. require для классов не надо ставить в if а надо ставить в самое начало файла.

По коду:

Синглтоны не очень хорошая штука, лучше вообще без них делать тем более в учебной задаче (если интересно почему почитай мой урок про внедрение зависимостей и связи между объектами: https://gist.github.com/codedokode/e1d31a31b37d5f635057 Учти что уровень урока довольно сложный).

Если одному классу нужен экземпляр другого напрмер объект PDO то лучше всего передавать его через конструктор.

> \tfunction insertIntoDB(Student &$student){


& не нужен: http://php.net/manual/ru/language.oop5.references.php (кстати я уже второй раз пишу это замечание, не тебе ли в прошлый раз писал?)

try/catch писать не надо, вот мой урок про исключения: https://gist.github.com/codedokode/65d43ca5ac95c762bc1a

Даже если твой код пока не работает, лучше все равно его показывать, так как в этом случае меньше исправлять потом придется.
#491 #424466
>>424359

json_encode

>>424396

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

>>424393

Учти что в старом ИЕ нет JSON.parse и JSON вообще.
#492 #424467
>>424404

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

> Вот тут в GET-запрос попадает только 'name'


Попробуй через var_dump вывести все переменные, а заодно и _GET и _SERVER.

Код гляну, но позже.

>>424405

У меня если что есть задачки на яваскрипт, а один анон даже запилил проверялку для первых 7: http://dkab.github.io/jasmine-tests/

>>424432

После location надо делать die так как при редиректе выводить ничего не требуется, хватит заголовка.
#493 #424558
Я вот не очень понимаю, а как сделать так, чтоб выводилось предложение, в котором ошибка? Ну я так понимаю, что под фрагментом имеется в виду предложение.
Речь идет об уроках "Регулярные выражения"(http://archive-ipq-co.narod.ru/l1/regexp.html).
Вот то, что я наговнокодил на данный момент: http://ideone.com/p3nTVR.
#494 #424559
>>424558

Со ссылкой на урок обосрался, но вы поняли, я думаю.
http://archive-ipq-co.narod.ru/l1/regexp.html
#495 #424571
>>424405
>>424405

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


По какой методике-то?
#496 #424574
>>424571
Не обращай внимания. Я ему посоветовал учить теорию и не использовать готовые решения, а он обиделся и начал нести ахинею про саморазвитие.
Видно, я грубовато выражаюсь, привык ведь к мамоебству на бе.
Надо будет тщательнее подбирать слова, чтобы не травмировать мнительных омег.
#497 #424575
>>424465

>& не нужен: http://php.net/manual/ru/language.oop5.references.php (кстати я уже второй раз пишу это замечание, не тебе ли в прошлый раз писал?)


nyet. Просто в задачнике стоит ссылка на хабру http://habrahabr.ru/post/198450/, там в примере стоит эта козявка public function saveFoo(Foo &$foo), вот все и копипастят.
#498 #424587
>>424465

>require для классов не надо ставить в if а надо ставить в самое начало файла


Дак это же у меня не классы, а модели.
Если одно условие, то подключить одну модель и соответственный шаблон, если другое условие, то другая модель.
Ну ладно, сейчас я уже до конца допилю, потом сверимся, каким должен быть правильный порядок файлов.
#499 #424612
>>424575

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

>>424574

> травмировать мнительных омег.


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

>>424558

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


Это не так просто. Один из вариантов — разбить строку на массив предложений, обходить их циклом и тогда мы можем при нахождении ошибки вывести текущее предложение.

Но вообще можно и просто вывести место с ошибкой.

Алсо

> PHP Notice: Use of undefined constant PREG_SPLIN_NO_EMPTY - assumed 'PREG_SPLIN_NO_EMPTY' in /home/yiEQbo/prog.php on line 10


Не сплин, а сплит.

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

Ну и в регулярке не уверен что все верно:

> [.]\\s


Что плохого в пробеле после точки?

> [жы]


Это ищет не послежовательность «жы» а любую из букв то есть «ж» или «ы». Квадратные скобки значат «один из указанных символов».
#499 #424612
>>424575

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

>>424574

> травмировать мнительных омег.


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

>>424558

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


Это не так просто. Один из вариантов — разбить строку на массив предложений, обходить их циклом и тогда мы можем при нахождении ошибки вывести текущее предложение.

Но вообще можно и просто вывести место с ошибкой.

Алсо

> PHP Notice: Use of undefined constant PREG_SPLIN_NO_EMPTY - assumed 'PREG_SPLIN_NO_EMPTY' in /home/yiEQbo/prog.php on line 10


Не сплин, а сплит.

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

Ну и в регулярке не уверен что все верно:

> [.]\\s


Что плохого в пробеле после точки?

> [жы]


Это ищет не послежовательность «жы» а любую из букв то есть «ж» или «ы». Квадратные скобки значат «один из указанных символов».
#500 #424613
Аноны, всем кому обещал проверить код, сегодня не успеваю, проверю завтра. Решайте ока задачки дальше, не ждите меня.

>>424587

Хорошо, ждем.
#501 #424698
>>424465

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


пока так
https://github.com/krbn/students
не сделал еще: обработку заполнения полей в js, страницу редактирования профиля

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

500 постов, тред не утонет?
#502 #424718
http://ideone.com/1PWLAQ говно ебаное, а не язык.
#503 #424730
>>424587

>Дак это же у меня не классы, а модели.


Нет такого в php. Для классов, которые могут вызваться, а могут не вызваться используется __autoload(). При этом каждый класс кладется в отдельный файл и обзывается таким же именем. В результате избавляемся от лишних веток с условиями.
#504 #424821
>>419972
у меня содержимое элемента не умещается и я использую overflow: auto; всё бы хорошо, но он размещается не в ту сторону, в которую я бы хотел. т. е скроллить можно в низ, а я хочу, чтобы вправо. как быть? спасибки заранее
#505 #424822
А ведь natsort или sort с флагом SORT_NATURAL нельзя использовать с многобайтовыми строками вроде utf-8? Только через установку локалей с преобразованиями кодировки?
#506 #424825
>>424718
Ты бы хоть почитал про работу с массивами и параметры in_array(), а потом приходил.
#507 #424833
>>424821
Непонятно, как у тебя контент отпозиционирован.
Я так понял, что у тебя куча дивов (типа галерея с картинками), которые должны прокручиваться горизонтально.

Сделай эти дивы плавающими (float: left), засунь их себе в другой див, типа контейнер, у которого захардкодь высоту и ширину. Потом эту матрешку суешь в еще один див, у которого указываешь свойство overflow-x: scroll.
Что-то типа такого: https://gist.github.com/anonymous/2a61745087023226ebe4

А вообще учи матчасть.
Сейчас вернется оп треда, даст мне пизды за то что я вам раздаю вредные советы, а тебе вручит коллекцию уроков по хатемелю и css.
#508 #424846
>>424698
оп, не смотри это говно, я уже понял, что обосрался.
Сейчас переделаю (пятый раз, пристрелите меня кто-нибудь!)
#509 #424847
>>424846
Поздно, лол. Он сначала смотрит смотрит пост и проверяет всё, что в нем, а потом только читает следующие.
#510 #424891

Суп, пхпшеры. Замыслил я одно дело. Раскритикуйте и отговорите. В пхп я очень не очень, но основы понимаю. Решил для себя написать удобную управлялку для личинки от анона из набигача. Кратко опишу принцип работы этой личинки. Запускается батник у жертвы, затем батник по таймеру проверяет текстовый документик на управляющем сайте строго прописаном в настройках. Список команд весьма большой, от информации о машине, до записи с вебки. Каждой личинке дается уникальное имя. Личинка может отвечать на команды 4 типами: фтп, смтп, бэйс64 в гет запросе, или просто гет запрос. Вот тут и врывается пхп. Мой план таков: на интерфейсе кнопуля: "проверить онлайн" действия которой будут -
а) поменять командный файлик в котором теперь будет запрашиваться команда "hey". Ответить по специальному адресу.
б) Начать ждать гет запросы по специальному адресу.
в) Отсчитать минуту молчания это чтобы все личинки успели ответь и сообщить результат.

И это кнопка "проверить онлайн". Все ничего, но у меня в голове сразу увиделись недостатки:
а) В нынешней версии личинки, которой пользуюсь я не работают просто ГЕТ запросы. Работает только зашифрованный в бейс64. От чего одна личинка шлет ~5 ответов в base64 на команду hey.
б) Если одна личинка шлет по 5 ответов с разными интервалами, то как мне ловить ответы от 5 таких личинок? Они же все в куче будут.
в) Долго. У всех личинок разный таймер в зависимости от ситуации. Они не видят командный файлик сразу же как он изменен.

Таки что не так в моем наивно-ньюфажном плане? И как мне решить проблемы выше?
#511 #424922
>>424822

Сравнение юникодных строк (collation на английском) — сложная тема. Проблема не в том, что там много букв из разных алфавитов, а в том что одни и те же буквы имеют разный порядок в разных языках. Например, буквы с точечками и черточками: http://en.wikipedia.org/wiki/Alphabetical_order#Language-specific_conventions

В некоторых языках буквы вроде å идут после z, в некоторых после a. В некорых (английский) они имеют одинаковый вес с «a». То есть сортировка зависит от языка.

В немецком, ß равносильно ss по моему.

В японском есть 2 алфавита (хирагана/катакана), обозначающих одни и те же слоги.

Лигатуры вроде Œ могут быть равносильны комбинации oe, а могут и не быть.

Также, одна буква (упомянутая выше å) может храниться в строке как один символ либо как комбинация 2 символов: кружочек + a (чтобы избежать проблем из-за этого, строки перед сравнением можно нормализовать, приведя к еждиному виду).

Как ты надеюсь, догадался, сравнение строк очень нетривиальная вещь. Потому для этого есть специальные библиотеки, самая известная из них это открытая ICU. В PHP ты можешь воспользоваться ее возможностями с помощью расширения Intl (которое умеет не только сравнение строк, но и многое другое): http://php.net/manual/ru/book.intl.php

В этом расширении есть класс Collator для сравнения строк по правилам указанного языка: http://php.net/manual/ru/class.collator.php

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

Если локаль не указана, то по моему применяются общие правила. подробно это все описано в стандарте UNICODE COLLATION ALGORITHM: http://www.unicode.org/reports/tr10/ (англ). Там в начале есть примеры всех этих сложностей со сравнением, интересно почитать.

Без него (расширения Intl), например в выражении if ($x > $y), php сравнивает строки побайтово, по кодам символов. То есть у кого код больше тот и ниже в списке. Вот получающийся порядок символов, например, для кириллицы: http://unicode-table.com/ru/#cyrillic

Видно что буква Ё там идет раньше чему буква А (а маленькая ё наоборот ниже чем я).

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


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

Кстати вопрос про сравнение строк хорошо задавать на собеседовании, мне кажется, чтобы посмотреть ход мыслей кандидата.
#511 #424922
>>424822

Сравнение юникодных строк (collation на английском) — сложная тема. Проблема не в том, что там много букв из разных алфавитов, а в том что одни и те же буквы имеют разный порядок в разных языках. Например, буквы с точечками и черточками: http://en.wikipedia.org/wiki/Alphabetical_order#Language-specific_conventions

В некоторых языках буквы вроде å идут после z, в некоторых после a. В некорых (английский) они имеют одинаковый вес с «a». То есть сортировка зависит от языка.

В немецком, ß равносильно ss по моему.

В японском есть 2 алфавита (хирагана/катакана), обозначающих одни и те же слоги.

Лигатуры вроде Œ могут быть равносильны комбинации oe, а могут и не быть.

Также, одна буква (упомянутая выше å) может храниться в строке как один символ либо как комбинация 2 символов: кружочек + a (чтобы избежать проблем из-за этого, строки перед сравнением можно нормализовать, приведя к еждиному виду).

Как ты надеюсь, догадался, сравнение строк очень нетривиальная вещь. Потому для этого есть специальные библиотеки, самая известная из них это открытая ICU. В PHP ты можешь воспользоваться ее возможностями с помощью расширения Intl (которое умеет не только сравнение строк, но и многое другое): http://php.net/manual/ru/book.intl.php

В этом расширении есть класс Collator для сравнения строк по правилам указанного языка: http://php.net/manual/ru/class.collator.php

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

Если локаль не указана, то по моему применяются общие правила. подробно это все описано в стандарте UNICODE COLLATION ALGORITHM: http://www.unicode.org/reports/tr10/ (англ). Там в начале есть примеры всех этих сложностей со сравнением, интересно почитать.

Без него (расширения Intl), например в выражении if ($x > $y), php сравнивает строки побайтово, по кодам символов. То есть у кого код больше тот и ниже в списке. Вот получающийся порядок символов, например, для кириллицы: http://unicode-table.com/ru/#cyrillic

Видно что буква Ё там идет раньше чему буква А (а маленькая ё наоборот ниже чем я).

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


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

Кстати вопрос про сравнение строк хорошо задавать на собеседовании, мне кажется, чтобы посмотреть ход мыслей кандидата.
#512 #424923
>>424922

Сделал из поста мини-урок про сравнение строк: https://gist.github.com/codedokode/ea09d0224a4df0c4442f
#513 #424924
>>424891

В нашем треде не обсуждается разработка вредоносного ПО.
#514 #424926
>>424891

Ну и конечно воспользуюсь возможностью послать лучи поноса разработчикам популярных ОС которые не хотят сделать их надежными и безопасными вроде той же iOS от Эппл. Если вы даете возможность пользователю кликом запустить троян по ссылке или из письма (а не ставить только подписанные приложения из магазина), то найдется дурак который его запустит. Если вы не помещаете приложения в контейнеры (вроде приложений на iOS или процессов вкладок в Google Chrome) и используете языки без проверки границ строк, то через них взломают всю систему.
MindiMakridi #515 #424939
>>424251

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

Насчет кук, ты не задаешь на путь к кукам, ни время жизни. Это значит что будет поставлена временная кука, которая при закрытии браузера удалится. Почитай мануал http://php.net/manual/ru/function.setcookie.php В качестве path лучше указать '/' чтобы куки были доступны на всем сайте. Также на всякий случай стоит поставить httponly = true, чтобы куку нельзя было украсть при XSS узявимости яваскриптом.

> $id = 'Регистрация';


Выглядит странно. Наверно, лучше завести булеву переменную $isRegistered или как-то так.

> if(isset($_POST['exit'])){


> setcookie('studentscookie[email]', "", time()-3600);


Разлогинивание (удаление кук) логично сделать отдельной функцией, то есть

if (isset($_POST['exit'])) {
logout( );
}

> ?>


Не надо ставить этот маркер в конце файла

> https://github.com/MindiMakridi/Students/blob/master/lib/functions.php#L26


> $mapper=new StudentMapper($DBH);


Почему этот код в файле functions? Логично что в файле functions должны быть только функции. Вынеси код оттуда.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L39


> throw new Exception("Íå âåðíûé çàïðîñ ê áàçå äàííûõ");


Сохраняй файлы в utf-8 без BOM

> profile


Имена классов должны писаться с большой буквы.

> $salt1 = "pineapple";


> $secretcode = md5($salt1 . $email . $salt2);


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

Сами секретные слова хорошо бы вынести из кода в конфиг чтобы их было легко менять.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L80


такие длинные строки надо переносить (в PHP и в SQL запросах можно делать переносы внутри строки).

> public function getLastId()


> public function getCode()


Лучше не делать 2 дополнительных функции, а просто при сохранении студента в addStudent прописывать id и код в переданный объект profile.

> if ($mapper->fetchMail($email) && $email != $_COOKIE['studentscookie']['email']) {


Что это? Запрет менять email? Почему так?

> https://github.com/MindiMakridi/Students/blob/master/profile.php#L56


Это лучше вынести в функцию updateStudentCookie(Profile $profile);

> https://github.com/MindiMakridi/Students/blob/master/lib/Profile.php#L40


HTML теги должны быть в шаблоне, а не тут.

Насчет секретного кода, тут https://github.com/MindiMakridi/Students/blob/master/profile.php#L14 надо сделать проверку что если профиль не выбрался, то вывести ошибку вроде «редактирование данных невозможно из-за технической ошибки».

Вот тут https://github.com/MindiMakridi/Students/blob/master/profile.php#L9 в обоих ветках условия находится почти одинаковый код обработки формы. Подумай, как объединить его в один общий код.

> header("Location: $redirect");


После редиректа надо делать die так как выведенную страницу все равно никто не увидит. Также, откуда берется переменная redirect? Что-то не очевидно. Может надо вверху страницы подключить конфиг? Или сделать функцию вроде getConfig('redirect')? Ну и переменную хорошо бы назвать вроде configRedirect чтобы было очевидно откуда она.

> <?php echo $student->showName()." ".$student->showSname() ?>


В шаблоне короче писать <?= вместо <?php echo

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

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

> https://github.com/MindiMakridi/Students/blob/master/templates/main.html#L3


Для поиска принято использовать не POST а GET так как поиск не изменяет никакие данные на сервере + появляется возможность получить ссылку на результаты поиска.

> https://github.com/MindiMakridi/Students/blob/master/templates/main.html#L15


В шаблоне надо использовать версию foreach с двоеточием: http://php.net/manual/ru/control-structures.alternative-syntax.php
MindiMakridi #515 #424939
>>424251

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

Насчет кук, ты не задаешь на путь к кукам, ни время жизни. Это значит что будет поставлена временная кука, которая при закрытии браузера удалится. Почитай мануал http://php.net/manual/ru/function.setcookie.php В качестве path лучше указать '/' чтобы куки были доступны на всем сайте. Также на всякий случай стоит поставить httponly = true, чтобы куку нельзя было украсть при XSS узявимости яваскриптом.

> $id = 'Регистрация';


Выглядит странно. Наверно, лучше завести булеву переменную $isRegistered или как-то так.

> if(isset($_POST['exit'])){


> setcookie('studentscookie[email]', "", time()-3600);


Разлогинивание (удаление кук) логично сделать отдельной функцией, то есть

if (isset($_POST['exit'])) {
logout( );
}

> ?>


Не надо ставить этот маркер в конце файла

> https://github.com/MindiMakridi/Students/blob/master/lib/functions.php#L26


> $mapper=new StudentMapper($DBH);


Почему этот код в файле functions? Логично что в файле functions должны быть только функции. Вынеси код оттуда.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L39


> throw new Exception("Íå âåðíûé çàïðîñ ê áàçå äàííûõ");


Сохраняй файлы в utf-8 без BOM

> profile


Имена классов должны писаться с большой буквы.

> $salt1 = "pineapple";


> $secretcode = md5($salt1 . $email . $salt2);


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

Сами секретные слова хорошо бы вынести из кода в конфиг чтобы их было легко менять.

> https://github.com/MindiMakridi/Students/blob/master/lib/DataMapper.php#L80


такие длинные строки надо переносить (в PHP и в SQL запросах можно делать переносы внутри строки).

> public function getLastId()


> public function getCode()


Лучше не делать 2 дополнительных функции, а просто при сохранении студента в addStudent прописывать id и код в переданный объект profile.

> if ($mapper->fetchMail($email) && $email != $_COOKIE['studentscookie']['email']) {


Что это? Запрет менять email? Почему так?

> https://github.com/MindiMakridi/Students/blob/master/profile.php#L56


Это лучше вынести в функцию updateStudentCookie(Profile $profile);

> https://github.com/MindiMakridi/Students/blob/master/lib/Profile.php#L40


HTML теги должны быть в шаблоне, а не тут.

Насчет секретного кода, тут https://github.com/MindiMakridi/Students/blob/master/profile.php#L14 надо сделать проверку что если профиль не выбрался, то вывести ошибку вроде «редактирование данных невозможно из-за технической ошибки».

Вот тут https://github.com/MindiMakridi/Students/blob/master/profile.php#L9 в обоих ветках условия находится почти одинаковый код обработки формы. Подумай, как объединить его в один общий код.

> header("Location: $redirect");


После редиректа надо делать die так как выведенную страницу все равно никто не увидит. Также, откуда берется переменная redirect? Что-то не очевидно. Может надо вверху страницы подключить конфиг? Или сделать функцию вроде getConfig('redirect')? Ну и переменную хорошо бы назвать вроде configRedirect чтобы было очевидно откуда она.

> <?php echo $student->showName()." ".$student->showSname() ?>


В шаблоне короче писать <?= вместо <?php echo

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

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

> https://github.com/MindiMakridi/Students/blob/master/templates/main.html#L3


Для поиска принято использовать не POST а GET так как поиск не изменяет никакие данные на сервере + появляется возможность получить ссылку на результаты поиска.

> https://github.com/MindiMakridi/Students/blob/master/templates/main.html#L15


В шаблоне надо использовать версию foreach с двоеточием: http://php.net/manual/ru/control-structures.alternative-syntax.php
#516 #424943
>>424822

Забыл сказать, в классе Collator есть метод asort для сортировки массива строк. Если тебе нужна более хитрая сортировка (например объектов-студентов по имени) то можно использовать usort c использованием пользовательской функции сравнения.
#517 #424946
>>424698

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

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

В случае MVC модель (M) (обычно это один или несколько классов) отвечает за хранение данных (например в базе), обработку этих данных. Представление (или вид, V) отвечает за отображение данных. А контроллер (C) обрабатывает пользовательские запросы и дает команды модели и представлению сделать какое-то действие и что-то отобразить.

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

Контроллер, обычный php файл index.php:
-------------

// Создаем объект модели для работы со студентами
$mapper = new StudentMapper( );

// Получаем студентов
$students = $mapper->findStudents( );

// Выводим список
require 'templates/index.phtml';

Модель, StudentMapper.php
-------------
class StudentMapper
{
....
}

Модель, Student.php
-------------
class Student
{
public $name;
}

Представление templates/index.phtml
-------------

<?php require 'header.phtml' ?>
<h1>Наши студенты</h1>

<ul>
<?php foreach ($students as $student) ?>
<li><?= html($student->name) ?></li>
<?php endforeach ?>
</ul>

<?php require 'footer.phtml' ?>

Как видишь, у нас каждый занимается своим делом: StudentMapper загружает список объектов-студенов из БД, Student представляет одного студента, представление index.phtml их отображает.

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

Вот статья про другой вариант реализации MVC на PHP: http://habrahabr.ru/post/150267/ но в нем довольно много сомнительных мест. Не копируй код оттуда, а думай своей головой.

Вот мой урок про работу с БД и мапперы: https://gist.github.com/codedokode/c4cbc4d7dc8e45ea074a

Если что-то непонятно или есть вопросы, задавай.
#517 #424946
>>424698

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

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

В случае MVC модель (M) (обычно это один или несколько классов) отвечает за хранение данных (например в базе), обработку этих данных. Представление (или вид, V) отвечает за отображение данных. А контроллер (C) обрабатывает пользовательские запросы и дает команды модели и представлению сделать какое-то действие и что-то отобразить.

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

Контроллер, обычный php файл index.php:
-------------

// Создаем объект модели для работы со студентами
$mapper = new StudentMapper( );

// Получаем студентов
$students = $mapper->findStudents( );

// Выводим список
require 'templates/index.phtml';

Модель, StudentMapper.php
-------------
class StudentMapper
{
....
}

Модель, Student.php
-------------
class Student
{
public $name;
}

Представление templates/index.phtml
-------------

<?php require 'header.phtml' ?>
<h1>Наши студенты</h1>

<ul>
<?php foreach ($students as $student) ?>
<li><?= html($student->name) ?></li>
<?php endforeach ?>
</ul>

<?php require 'footer.phtml' ?>

Как видишь, у нас каждый занимается своим делом: StudentMapper загружает список объектов-студенов из БД, Student представляет одного студента, представление index.phtml их отображает.

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

Вот статья про другой вариант реализации MVC на PHP: http://habrahabr.ru/post/150267/ но в нем довольно много сомнительных мест. Не копируй код оттуда, а думай своей головой.

Вот мой урок про работу с БД и мапперы: https://gist.github.com/codedokode/c4cbc4d7dc8e45ea074a

Если что-то непонятно или есть вопросы, задавай.
#518 #424947
>>424833

Не, ты молодец что как-то помогаешь анонам. Но тому анону, конечно, надо подучить HTML/CSS.

Чтобы не вычислять ширину руками, можно попробовать использовать display table на враппере и display table cell на картинке.Тогда все картинки выстроятся в одну длинную линию и это должно работать даже с разными размерами картинок. Плюс, мы получаем возможность выравнивать их вертикально.

Минус — display table не работает в IE6/7.

Не хочешь проверить этот вариант?

>>424821

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

>>424846

ну почитай мой совет, надеюсь поможет

>>424847

Это да, чтобы никого не пропустить.
#519 #424948
>>424833

Еще один вариант который может быть сработает везде — использовать для картинок display inline block + white-space nowrap на враппере чтобы картинки не переносились а шли одной строкой. Опять же, инлайн блоки можно выравнивать вертикально. Но тут надо проверять, заработает ли.

На тему выравнивания блоков у меня есть задача 4 отсюда: https://gist.github.com/codedokode/58ebc90bd006baf4b35c#%D0%97%D0%B0%D0%B4%D0%B0%D0%BD%D0%B8%D0%B5-4
#520 #424950
Новый тред сделаем вечером или завтра, у меня тут работа еще и от того что мы повисим денек на второй странице. ничего страшного не случится.
#521 #424951
Если я кого-то пропустил, напомните о себе, отвечу вечером или завтра.
#522 #424953
>>424846

Не беда. Со временем у тебя будет получаться все лучше и лучше, особенно если ты будешь показывать код и следовать моим советам. Наш тред для этого и предназначен.
#523 #424974
Можно ли как-то сделать поиск по значениям переменных\объектов в js? Особенно актуально при подключении сторонних плагинов\библиотек, когда приходится перелопачивать значения сотни переменных, чтобы найти нужную и что-то с ней сделать. В phpstorm такового не нашел. Вернее он есть, но только в тех объектах, которые уже открыты.
#524 #424977
>>424974
сорьки, уже нашел.
#525 #424981
>>424891
Возьми за основу ICQ|jabber, чтобы твои скрипты показывали кто из прокаженных онлайн. Разбери основательно принципы работы и алгоритм, чтобы реализовать это на php, который заведется хоть на шареде. Че велосипеды то лепить, ну.
#526 #424983
>>424939

>> if ($mapper->fetchMail($email) && $email != $_COOKIE['studentscookie']['email']) {


Что это? Запрет менять email? Почему так?

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

>В шаблоне надо использовать версию foreach с двоеточием:



У меня там в комментарии написано: версия с двоеточием почему-то вызывает ошибку, тогда как обычная прекрасно работает. Так же и с <?= вместо <?php echo. Такая конструкция у меня не работает и все что внутри <?= ?> отображается как хтмл код, вместе с самим тегом.
#527 #424989
>>424983

> ерсия с двоеточием почему-то вызывает ошибку, тогда как обычная прекрасно работает.


Значит надо разобраться почему. Покажи код и текст ошибки

> Запрещает ставить уже существующий в бд почтовый адрес


Ясно. А почему она не вместе с другими проверками в check что-то там? И есть ли такая проверка при регистрации?
#528 #424990
>>424989

>И есть ли такая проверка при регистрации?


Да
https://github.com/MindiMakridi/Students/blob/master/profile.php#L46

Она не вместе с другими check, потому-что тут в отличие от остальных нужно делать запрос к бд.
#529 #424995
Парни, пилю парсер профилей с google+. Проблема в том, что, когда я получаю код страницы через:

file_get_contents('https://plus.google.com/' . $id . '/about');

То на выходе вижу, что спарсился профиль на немецком. Гугл как-то определил, что я якобы немец. Как мне ему показать, что я из России?

header("Content-Type:text/plain; charset=utf-8");
$html = file_get_contents('https://plus.google.com/' . $id . '/about');

Что еще дописать можно?
#530 #424996
>>424995
$html = file_get_contents_for_pidarashka('https://plus.google.com/' . $id . '/about');
#531 #425001
>>424948
>>424947
почему-то не работает
#532 #425003
>>425001
наверное, придется мне в jquery вычислять ширину
#533 #425006
>>425001

Без примера кода я помочь не могу
#534 #425035
>>424825
Дальше второй строчки не осилил?
#535 #425120
>>424951
напоминию про себя.

сайтик про студентиков.

https://github.com/tokotun/matriculant
#536 #425161
>>424996
Хохол в треде!
#537 #425173
Ребята подсобите раку советом, как реализовать следующее.

mysql+php

$pole = 'как@блядь@это@сделать'; (на самом деле это находится в базе данных - в одном текстовом поле)

$m = preg_split("/@/i", $pole);

for($i = 0; $i < 4; ++$i) {
echo '<br><input type="text" name="lol" value="' . $m[$i] . '" /><br>';
}

Юзер заполняет эти четыре поля так:
1) очень
2) легко
3) это
4) сделать

Как соединить эти инпуты и UPDATE базу данных? Так чтобы в базе данных (в поле) стало: 'очень@легко@это@сделать'.
16 Кб, 1173x255
#539 #425248
Можно ли приинклюдить файл так чтобы отработал его код? Или только оборачивать и дергать функции? Просто интересно, потому что в мануале ничего такого не нашел.
#540 #425249
>>425248

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

Потому я не очень понимаю твой вопрос. В твоем коде должны сначала сработать print из одключенного файла, потом из основного.
#541 #425252
>>425249
Все так. А у меня почему то пехапа не исполняет прикрепленный файл. Ну то есть я его в браузере прям открываю, а там чистый лист без ошибок. Гмм.
17 Кб, 714x265
#542 #425253
>>425252
И тут он на пустом месте заработал. Хотя вру. Первое что пришло в голову - сделать его исполняемым, но заработал он лишь через минуту. А еще что-то мне подсказывает, что php пофигу на флаг execute.
#543 #425257
>>425240
Спасибо, брат.

Кому интересно:

$pole = 'как@блядь@это@сделать';
$m = explode("@", $pole);

for($i = 0; $i < 4; ++$i) {
echo '<br><input type="text" name="lol[]" value="' . $m[$i] . '" /><br>';
}

обработка:
$in = implode("@", $_POST['form_nsc']);
#544 #425258
>>425257
то есть $in = implode("@", $_POST['lol']);
#545 #425261
>>425120

Вообще, неплохо. Я вижу что в сравнении с первыми версиями код стал намного аккуратнее. Правда, к нему по прежнему есть некоторые замечания. Я думаю, что после их исправления останется сделать еще одну большую проверку (и исправить ее замечания) и все будет готово. Не знаю, какие у тебя планы, но я бы советовал дальше делать задачку на файлообменник с шаблонизатором Twig, и может быть параллельно потихоньку решать задачки на SQL/JS/HTML/CSS чтобы подтянуть знания по ним. А дальше браться за фреймворки Yii2 и Symfony 2.

Советы и замечания.

Что-то у тебя с индексами перебор:

> PRIMARY KEY (`id`),


> UNIQUE KEY `id` (`id`),


Уникальный индекс не нужен так как PRIMARY KEY и так является уникальным индексом. Первичный ключ — это колонка которая однозначно идентифицирует запись и значения первичного ключа не могут повторяться.

> `code` int(16) NOT NULL,


Число в скобках для int это не максимальное число цифр в колонке. Это сколько места оставлять под число при выводе таблицы. int позволяет хранить число от -2 млрд до +2 млрд., а это не более 12 цифр. Чтобы было 16, тебе нужен bigint. Прочти в мануале, какие типы чисел существуют: http://phpclub.ru/mysql/doc/column-types.html

> ENGINE=MyISAM


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

> generate_page_links


HTML-код все же лучше генерировать в шаблоне. Иначе получается каша. А в этой функции можно генерировать просто массив вида:

array(
подпись к кнопке => ссылка,
подпись к кнопке => ссылка,
....
);

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

// Передаем общий шаблон ссылки, и дополнительно ссылку для первой станицы если она отличается по виду
$pager = new Pager('/students/page/{page}', '/students');
// передаем номер страницы и сколько всего страниц
$pager->setPage(3, 34);

// Передаем объект $pager в шаблон

....

// В шаблоне выводим пагинацию
<?php foreach ($pager->getLinks() as $text => $link): ?>
<a href="<?= html($link) ?>"><?= html($text) ?></a>
<?php endforeach ?>

> https://github.com/tokotun/matriculant/blob/master/app/functions.php#L27


В HTML коде вместо & надо писать & amp; так как & это спецсимвол для кодирования HTML-сущностей.

> https://github.com/tokotun/matriculant/blob/master/app/functions.php#L17


Чтобы вставить знак < надо писать & lt;

Я вижу, у тебя пробелы в знании HTML. Прочти-ка эти статьи:

http://htmlbook.ru/samhtml/tekst/spetssimvoly
http://ru.wikipedia.org/wiki/%D0%9C%D0%BD%D0%B5%D0%BC%D0%BE%D0%BD%D0%B8%D0%BA%D0%B8_%D0%B2_HTML

Чтобы вставить в HTML код символы < > & (эти 3 символа и их мнемоники надо выучить наизусть) надо использовать мнемоники. Также, можно использовать мнемоники если тебе надо вставить кавычку внутрь аттрибута: <a title="test " test" ...

> generate_sort_link


Эту функцию лучше переделать чтобы она генерировала только URL ссылки, а не тег A целиком. А заголовок таблицы со ссылками выводить в шаблоне например на основе массива с названиями колонок. Главная мысль, что надо стараться держать HTML код в шаблоне. Оттуда же можно и вызывать эти функции.

> https://github.com/tokotun/matriculant/blob/master/app/autoloader.php#L3


правильнее писать автолоадер так:

опредеяем путь к файлу
если (файл существует) то подключаем иначе ничего не делаем

Так как автолоадеров может быть несколько (например у библиотек бывают свои автолоадеры) и не должно возникать ошибки вроде «файл не найден».

Я вижу, у тебя есть повторяющийся в index.php и loin.php код, который подключает файлы, создает PDO и т.д. Удобно вынести этот код в отдельный файл, например app/boostrap.php и подключать только его (через require_once чтобы 2 раза не подключить).

> https://github.com/tokotun/matriculant/blob/master/index.php#L17


> $pdo = null;


А это зачем?

> https://github.com/tokotun/matriculant/blob/master/login.php#L55


> $name = htmlspecialchars($matriculant->name);


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

Также, не надо передавать 10 переменных. Передавай в шаблон только объект matriculant.

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

> https://github.com/tokotun/matriculant/blob/master/app/Matriculant.php#L24


Модель не должна работать с POST данными. Надо переделать функцию чтобы она брала данные не из POST а из переданного массива (и переименовать ее). И разумеется, прежде чем брать $_POST['name'] надо проверить что этот элемент существует иначе получим ошибку.

> public function getName($name)


Это надо назвать setName а не getName

Еще. У тебя не очень удачно смешаны заполнение объекта данными из POST и проверка правильности данных (валидация). Лучше сделать 2 отдельных функции: одна загружает данные из массива в поля объекта, другая их проверяет и заполняет массив ошибок. Это делает функцию проверки более универсальной.

> public function notUniqueEmail()


Имя функции начинается с глагола: setNotUniqueEmailError

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L14


> if (isset($matriculant->id)) $statment->bindParam(':id', $matriculant->id);


Это не очень надежно, такие проверки делать. лучше передавать в функцию bindField дополнительный параметр, который говорит надо ли передавать id/code или нет. Кстати, кроме bindParam есть еще bindValue который позволяет передавать любые выражения.

Также, функция bindField явно не должна вызываться снаружи. Значит, она должна быть private/protected. Если ты не знаешь что такое private, прочти тут: http://php.net/manual/ru/language.oop5.visibility.php Вообще, старайся все что можно делать закрытым. Чем меньше public свойств и методов тем лучше код.

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L32


> $matriculant->code = mt_rand ( 0 , 2097151 );


Давай защиту сделаем понадежнее, сделаем чтобы там хотя бы цифр 15-16 было. Можно сгенерировать три 5-значных числа и склеить их в строку. Разумеется, генерация кода должна быть в отдельной функции.

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L95


> $total = $statment->rowCount( );


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

Если ты плохо знаешь MySQL могу посоветовать почитать мануалы по ссылкам и решить задачки отсюда: https://gist.github.com/codedokode/10539213 Там есть ссылка на учебник Пирамидина, он вполне неплохо объясняет разные виды запросов. Советую параллельно потихоньку читать его и решать задачки.

> https://github.com/tokotun/matriculant/blob/master/login.php#L27


> if (!$matriculantMapper->uniqueEmail($matriculant->email)){


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

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

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

при редактировании {
загрузить объект из БД
} иначе {
создать пустой объект
}

если форма отправлена {
обновить объект данными из POST

проверить на правильность;

если (ошибок нет) {
сохранить данные в БД;
сделать редирект и умереть;
}
}

вывести форму;

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

Соответвенно, я тебе советую сделать одну функцию проверки, например в M.Mapper, которой передается объект Matriculant и которая возвращает результат в виде true/false.

> https://github.com/tokotun/matriculant/blob/master/templates/profile.php#L17


Тут у тебя почему-то мужской пол всегда checked

> https://github.com/tokotun/matriculant/blob/master/templates/profile.php#L52


Закрывающие теги body/html лучше вынести в footer.php

А, там еще узявимоcть XSRF есть. Злоумышленник может создать страницу, поместить на нее невидимую заполненную форму, у которой action указывает на твой сайт, и сделать яваскрипт который при заходе отправляет форму. Заманив абитуриента на свою страницу злоумышленник может отредактировать его данные, например занизить ему результат ЕГЭ. Для борьбы с XSRF форму надо защитить каким-то кодом или токенов неизвестным злоумышленнику. Если не догадаешься сам как это сделать, попроси подсказку.

XSRF довольно серьезная уязвимость. С помощью нее можно отправлять любые формы от имени пользователя, например рассылать спам или делать переводы денег в платежной системе.
#545 #425261
>>425120

Вообще, неплохо. Я вижу что в сравнении с первыми версиями код стал намного аккуратнее. Правда, к нему по прежнему есть некоторые замечания. Я думаю, что после их исправления останется сделать еще одну большую проверку (и исправить ее замечания) и все будет готово. Не знаю, какие у тебя планы, но я бы советовал дальше делать задачку на файлообменник с шаблонизатором Twig, и может быть параллельно потихоньку решать задачки на SQL/JS/HTML/CSS чтобы подтянуть знания по ним. А дальше браться за фреймворки Yii2 и Symfony 2.

Советы и замечания.

Что-то у тебя с индексами перебор:

> PRIMARY KEY (`id`),


> UNIQUE KEY `id` (`id`),


Уникальный индекс не нужен так как PRIMARY KEY и так является уникальным индексом. Первичный ключ — это колонка которая однозначно идентифицирует запись и значения первичного ключа не могут повторяться.

> `code` int(16) NOT NULL,


Число в скобках для int это не максимальное число цифр в колонке. Это сколько места оставлять под число при выводе таблицы. int позволяет хранить число от -2 млрд до +2 млрд., а это не более 12 цифр. Чтобы было 16, тебе нужен bigint. Прочти в мануале, какие типы чисел существуют: http://phpclub.ru/mysql/doc/column-types.html

> ENGINE=MyISAM


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

> generate_page_links


HTML-код все же лучше генерировать в шаблоне. Иначе получается каша. А в этой функции можно генерировать просто массив вида:

array(
подпись к кнопке => ссылка,
подпись к кнопке => ссылка,
....
);

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

// Передаем общий шаблон ссылки, и дополнительно ссылку для первой станицы если она отличается по виду
$pager = new Pager('/students/page/{page}', '/students');
// передаем номер страницы и сколько всего страниц
$pager->setPage(3, 34);

// Передаем объект $pager в шаблон

....

// В шаблоне выводим пагинацию
<?php foreach ($pager->getLinks() as $text => $link): ?>
<a href="<?= html($link) ?>"><?= html($text) ?></a>
<?php endforeach ?>

> https://github.com/tokotun/matriculant/blob/master/app/functions.php#L27


В HTML коде вместо & надо писать & amp; так как & это спецсимвол для кодирования HTML-сущностей.

> https://github.com/tokotun/matriculant/blob/master/app/functions.php#L17


Чтобы вставить знак < надо писать & lt;

Я вижу, у тебя пробелы в знании HTML. Прочти-ка эти статьи:

http://htmlbook.ru/samhtml/tekst/spetssimvoly
http://ru.wikipedia.org/wiki/%D0%9C%D0%BD%D0%B5%D0%BC%D0%BE%D0%BD%D0%B8%D0%BA%D0%B8_%D0%B2_HTML

Чтобы вставить в HTML код символы < > & (эти 3 символа и их мнемоники надо выучить наизусть) надо использовать мнемоники. Также, можно использовать мнемоники если тебе надо вставить кавычку внутрь аттрибута: <a title="test " test" ...

> generate_sort_link


Эту функцию лучше переделать чтобы она генерировала только URL ссылки, а не тег A целиком. А заголовок таблицы со ссылками выводить в шаблоне например на основе массива с названиями колонок. Главная мысль, что надо стараться держать HTML код в шаблоне. Оттуда же можно и вызывать эти функции.

> https://github.com/tokotun/matriculant/blob/master/app/autoloader.php#L3


правильнее писать автолоадер так:

опредеяем путь к файлу
если (файл существует) то подключаем иначе ничего не делаем

Так как автолоадеров может быть несколько (например у библиотек бывают свои автолоадеры) и не должно возникать ошибки вроде «файл не найден».

Я вижу, у тебя есть повторяющийся в index.php и loin.php код, который подключает файлы, создает PDO и т.д. Удобно вынести этот код в отдельный файл, например app/boostrap.php и подключать только его (через require_once чтобы 2 раза не подключить).

> https://github.com/tokotun/matriculant/blob/master/index.php#L17


> $pdo = null;


А это зачем?

> https://github.com/tokotun/matriculant/blob/master/login.php#L55


> $name = htmlspecialchars($matriculant->name);


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

Также, не надо передавать 10 переменных. Передавай в шаблон только объект matriculant.

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

> https://github.com/tokotun/matriculant/blob/master/app/Matriculant.php#L24


Модель не должна работать с POST данными. Надо переделать функцию чтобы она брала данные не из POST а из переданного массива (и переименовать ее). И разумеется, прежде чем брать $_POST['name'] надо проверить что этот элемент существует иначе получим ошибку.

> public function getName($name)


Это надо назвать setName а не getName

Еще. У тебя не очень удачно смешаны заполнение объекта данными из POST и проверка правильности данных (валидация). Лучше сделать 2 отдельных функции: одна загружает данные из массива в поля объекта, другая их проверяет и заполняет массив ошибок. Это делает функцию проверки более универсальной.

> public function notUniqueEmail()


Имя функции начинается с глагола: setNotUniqueEmailError

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L14


> if (isset($matriculant->id)) $statment->bindParam(':id', $matriculant->id);


Это не очень надежно, такие проверки делать. лучше передавать в функцию bindField дополнительный параметр, который говорит надо ли передавать id/code или нет. Кстати, кроме bindParam есть еще bindValue который позволяет передавать любые выражения.

Также, функция bindField явно не должна вызываться снаружи. Значит, она должна быть private/protected. Если ты не знаешь что такое private, прочти тут: http://php.net/manual/ru/language.oop5.visibility.php Вообще, старайся все что можно делать закрытым. Чем меньше public свойств и методов тем лучше код.

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L32


> $matriculant->code = mt_rand ( 0 , 2097151 );


Давай защиту сделаем понадежнее, сделаем чтобы там хотя бы цифр 15-16 было. Можно сгенерировать три 5-значных числа и склеить их в строку. Разумеется, генерация кода должна быть в отдельной функции.

> https://github.com/tokotun/matriculant/blob/master/app/MatriculantMapper.php#L95


> $total = $statment->rowCount( );


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

Если ты плохо знаешь MySQL могу посоветовать почитать мануалы по ссылкам и решить задачки отсюда: https://gist.github.com/codedokode/10539213 Там есть ссылка на учебник Пирамидина, он вполне неплохо объясняет разные виды запросов. Советую параллельно потихоньку читать его и решать задачки.

> https://github.com/tokotun/matriculant/blob/master/login.php#L27


> if (!$matriculantMapper->uniqueEmail($matriculant->email)){


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

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

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

при редактировании {
загрузить объект из БД
} иначе {
создать пустой объект
}

если форма отправлена {
обновить объект данными из POST

проверить на правильность;

если (ошибок нет) {
сохранить данные в БД;
сделать редирект и умереть;
}
}

вывести форму;

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

Соответвенно, я тебе советую сделать одну функцию проверки, например в M.Mapper, которой передается объект Matriculant и которая возвращает результат в виде true/false.

> https://github.com/tokotun/matriculant/blob/master/templates/profile.php#L17


Тут у тебя почему-то мужской пол всегда checked

> https://github.com/tokotun/matriculant/blob/master/templates/profile.php#L52


Закрывающие теги body/html лучше вынести в footer.php

А, там еще узявимоcть XSRF есть. Злоумышленник может создать страницу, поместить на нее невидимую заполненную форму, у которой action указывает на твой сайт, и сделать яваскрипт который при заходе отправляет форму. Заманив абитуриента на свою страницу злоумышленник может отредактировать его данные, например занизить ему результат ЕГЭ. Для борьбы с XSRF форму надо защитить каким-то кодом или токенов неизвестным злоумышленнику. Если не догадаешься сам как это сделать, попроси подсказку.

XSRF довольно серьезная уязвимость. С помощью нее можно отправлять любые формы от имени пользователя, например рассылать спам или делать переводы денег в платежной системе.
#546 #425262
>>425173

У тебя поля называются одинаково и перезапишут друг дуга. Используй поля-массивы с именем вроде lol[]

мануал

http://php.net/manual/ru/faq.html.php#faq.html.arrays
http://php.net/manual/ru/language.variables.external.php
#547 #425263
>>425253

PHP пофигу на флаг. Ошибка была в чем-то другом. Кстати, у тебя случайно не выключен вывод ошибок? Может там была ошибка а ты просто ее не видел?

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

- ошибки сохраняются в лог ошибок. Можно открыть его и почитать. Если ты запускаешь код на локалхосте, у себя, то лог хранится в папке Апача (обычно она называется logs) и имеет название вроде error.log (в линуксе в папку /var/log/apache2 ). Если на хостинге — там либо есть файл error.log либо раздел в панели управления, где лог можно посмотреть

- также, ты можешь включить отображение ошибок. Открой файл php.ini, поставь там display_errors = On и error_reporting = E_ALL и перезапусти сервер. Теперь ошибки должны выводиться на экран.

Проверить, работает ли вывод ошибок, можно запустив скрипт содержающий обращение к несуществующей переменной вроде echo $sdgasdad; и проверив, выведется ошибка или нет. Если все верно, то должна вывестись.
#548 #425264
>>424995

Может быть по IP сервера в Германии с которого ты делал запрос? Тогда остается только делать азпрос залогиненным.
#549 #425265
>>424995

Твой header ни на что не влияет так как отдается в твой браузер а не передается гуглу.
#550 #425276
>>425263

>Кстати, у тебя случайно не выключен вывод ошибок?


Работает да так, чтобы на нотисы ругаться. Прописано в /etc/apach2/sites-available/default.conf что-то типа такого
ErrorLog /var/www/log/error.log
CustomLog /var/www/log/access.log combined

# Custom php settings
php_flag log_errors on
php_flag display_errors on
php_value error_reporting 6143

И сейчас вот нарочно убрал ; и получил ошибку, а тогда был просто белый экран. Мистика, в общем. Ну да фиг с ней. Может хостер баловался чем-то.
#551 #425279
>>425276

Вместо странного числа 6143 лучше писать E_ALL
#552 #425282
допустим у меня есть таблица, в которой есть столбец, в котором появляется красный кружочек, спустя 7 дней после того как была добавлена запись. как лучше реализовать проверку времени?
#553 #425283
>>425282

Если (сейчас - дата создания больше 7 дней) нарисовать красный кружочек.
#554 #425284
>>425283
как дату проверить?
#555 #425285
>>424939
Кстати, насчет полностью случайно сгенерированного кода:
Я сначала пытался сделать вот так:
$cypher = "abcdefghiklmnopqrstuvwxyz";
$length = count($cypher);
$string = mb_substr($cypher, mt_rand(0, $length-1), mt_rand(0, $length-1));
И хешировал эту строку вместо введенного эмейла. Но код одинаковый получался. Почему так?
#556 #425286
>>425284
Вычесть из даты сейчас дату создания.
#557 #425287
>>425286
Он наверное имел ввиду где взять дату создания.
#558 #425288
>>425284
Дату создания естественно нужно сохранять в бд. Текущее время возвращает time().
#559 #425291
>>425287
>>425286
а они как числа отнимаются?
#560 #425294
>>425291
да, time() возвращает временную метку в секундах прошедших с 70го года. Дату создания тоже храни в этом формате. Вычитаешь из первого второе, 7 дней переводишь в секунды и сравниваешь, вроде так.
#561 #425299
>>425294
спасибо!
а я то думал нахуя они такое сделали со временем, а ведь реально удобно.
#562 #425302
Уважаемые посетители треда, я с вами пробыл около двух месяцев решая задачи, хотел сказать спасибо ОПу и всем неравнодушным. Хочу задать вопрос: знаком ли кто с 1с, и есть ли какие-то годные курсы? В моем мухосранске нет возможности устроиться на Пхп, но есть возможность устроиться на 1с, в связи с этим, хочу изучить основы 1с и изучать Пхп в свободное время. У кого какие мысли на этот счет, так как на вики статья довольно маленькая по 1с, думаю там не особо сложно будет?
#563 #425304
>>425285

Добавь пару var_dump и увидишь сам: http://ideone.com/sHVftz

Алсо, мануал: https://php.net/manual/ru/function.count.php

> count — Подсчитывает количество элементов массива или что-то в объекте


> Возвращает количество элементов в array_or_countable. Если параметр не является массивом или объектом, реализующим интерфейс Countable, будет возвращена 1. За одним исключением: если array_or_countable - NULL, то будет возвращён 0



А ты передаешь строку вместо массива.
#564 #425310
>>425291

Урок о работе с датой/временем: https://gist.github.com/codedokode/10539805

>>425302

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

Для тех кто не знает, поясню что 1С это что-то вроде фреймворка, объединенного с файловой базой данных, графическим интерфейсом и средой разработки (IDE). Язык 1С напоминает русифицированный Visual Basic. Также, есть русифицированный аналог SQL для работы с их встроенной базой данных. Чистым 1С никто не пользуется, а обычно покупают написанную под нее программу (которая наызвается конфигуация). Все вещи, для которых есть общепринятые названия, в 1С называются по-своему. Например, та же «конфигурация», которая на самом деле является программой. Есть стандатные конфигуации типа программы учета товаров на складе или программы учета товаров в магазине, есть нестандатные котоые делают сторонние разработчики, есть перепиленные стандартные.

Надо понимать что в 1С есть разные уровни обучения:

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

Потому насчет

> думаю там не особо сложно будет?



я не знаю.
#565 #425311
>>425294

Дату создания надо хранить в DATETIME/TIMESTAMP так как они специально для того придуманы, а не интом. Не надо помойку в базе создавать.
#566 #425320
Ребята, посоветуйте, пожалуйста, появилась задача сделать 3 примерно одинаковых презентационных сайта, то есть, там даже база не нужна, но хочется красивых рестфул–ссылочек, ну и на будущее тоже, вдруг база всё–таки понадобится. Хочу писать на фреймворке, который будет выполнять роль рестфул–клиента — фреймворк в данном случае не оверкил? С другой стороны, CMS — еще больший оверкил, с ней ебаться дольше, всё настраивая, включая вёрстку под шаблон, а с фреймворком просто вывел виды по путям, и готово.

Алсо, мне кажется, у вас тред тонет.
someApprentice #567 #425358
https://github.com/someApprentice/ThumbnailService

Поздравьте меня, я снова запрострировал. Прострация начинается с того как у меня начинается ступор в очевидных вещах. Ты не будешь против, если я буду спрашивать в треде о них? Вот например:
Здесь >>420607>>420831, я не смог придумать проверку на тип. В итоге, через месяц, я решил просто отказаться от этой проверки в методе формы и добавил проверку в файле с отправкой формы.
https://github.com/someApprentice/ThumbnailService/blob/master/Classes/Form.php
https://github.com/someApprentice/ThumbnailService/blob/master/upload.php#L30-L32
#568 #425369
>>425358

> Ты не будешь против, если я буду спрашивать в треде о них?


Этот тред специально для этого и создан. Задавай тут любые вопросы.

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


Это действительно непросто догадаться самому. Проверки стоит сделать 2:

- проверка по расширению, что расширение (без учета регистра букв) находится в списке разрешенных. Для JPEG может быть 2 расширения, .jpeg или .jpg

- проверка по содержимому, что файл является картинкой в одном из разрешенных форматов. Для этого удобно использовать http://php.net/manual/ru/function.getimagesize.php — она умеет определять настоящий формат картинки (ну и размеры заодно) по содержимому.
#569 #425398
>>425358

И еще один совет:

> https://github.com/someApprentice/ThumbnailService/blob/master/upload.php#L48


В имени файла могут быть спецсимволы, потому лучше обработать его функцией urlencode которая заменит их процентным кодированием (которое используется в параметрах в URL): https://ru.wikipedia.org/wiki/URL#.D0.9A.D0.BE.D0.B4.D0.B8.D1.80.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D0.B5_URL
28 Кб, 667x416
#570 #425458
Только присоединился к вашему кружку. Меня ждет успех в этом деле? Какие перспективы у пхп-знатока? Работает ли ОП в этой сфере, сколько получает, если да?
#571 #425510
>>425261
Ох, ё маё. Какой анализ для одного меня.

Спасибо. Буду постигать.
#572 #425513
http://ideone.com/ej4eOy
Рейт ми. Насиловал мозг час или два, решение оказалось проще раза в три, чем я думал.
#573 #425518
>>425458

Думаю, что ждет, если будешь стараться. Насчет перспектив, лучше всего открыть сайты вроде hh.ru или http://brainstorage.me/ или odesk и посмотреть самому.

ОП работает, но сколько получает никому не расскажет.

По коду программы: лучше постить не картинкой, а ссылкой на ideone. Ты сделал проверку на случай ничьи?
#574 #425523
>>425320

Ох, как у тебя все в голове смешалось.

> хочется красивых рестфул–ссылочек,


Ты не путаешь REST и ЧПУ? «рестфул»-ссылочки обычно в АПИ используются.

> Хочу писать на фреймворке, который будет выполнять роль рестфул–клиента — фреймворк в данном случае не оверкил?


Опять же, ты не путаешь? Клиент это тот кто делает запрос, а тот кто отдает страницу это сервер.

Если тебе база не нужна, не проще ли просто сверстать страницы статически и вынести отдельно повторяющиеся части вроде шапки/подвала?

> фреймворк в данном случае не оверкил?


Смотря какой. Скорее всего нет.
#575 #425524
>>425518
Не сделал, сейчас сделал. А вот допустим овладею я на нормальном таком уровне РНР, что дальше? У меня мечта детская - роботов делать, радиотехникой занимаюсь, вот решил еще и погроммированием. Не подскажешь на этот счет ничего?
#576 #425525
>>425513

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

Также, вместо 2 переменных $earningsTotal и $depositBalance можно использовать одну.
#577 #425526
>>425524

Роботов не на PHP программируют. Там обычно микроконтроллер и Си/Си++. PHP все же больше для сайтов и веб-приложений.

С другой стороны, после изучения PHP тебе другие языки включая Си учить будет куда как легче.
#578 #425529
>>425524

Я немного знаю Си и Си++ так что если захочешь что-то спросить или овеить решение задачи, можешь заходить в наш тред.

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

[code]
$data1 = x;

foreach ($array1 as $data2 => $data3) {
if ($data3 > data1) {
$array2 = array($data3 > $data1);
}
}[/code]
Вижу, чего не хватает, но как оформить по-нормальному?
#580 #425532
>>425526>>425529
Там разве не ассемблер вообще? Все прошивки для микросхем, которые я использовал, пока что, были на чем-то, похожем на ассемблер.
#581 #425540
Приглашаю всех в новый тред >>425537
#582 #425543
>>425525
Да, я после попытки самоизнасилования через перезапись двух переменных по очереди просто все стер и взял решение предыдущей задачи, а потом модифицировал под новые нужды. Или это неправильно?
#583 #425547
>>425532

Ассемблер используют только на самых простых микроконтроллерах, где очень мало памяти (и где ничего серьезного не сделаешь). А на контроллерах помощнее на Си писать удобнее будет (+ ты получаешь доступ к множеству готовых библиотек). Плюс, есть тот же распберри в котором по моему то ли 128 то ли 256 Мб, запускается Линукс и можно хоть на Питоне писать и куча аналогичных китайских нонейм плат.

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

>>425531

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

$a = array( );

Затем добавляешь данные либо через

$a[$x] = $y;

либо через

$a[] = $y;

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

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

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

А у тебя куча ошибок

> $data1 = x;


Непонятно что такое x

> $array2 = array($data3 > $data1);


Ты наверно хотел написать => а не >
#583 #425547
>>425532

Ассемблер используют только на самых простых микроконтроллерах, где очень мало памяти (и где ничего серьезного не сделаешь). А на контроллерах помощнее на Си писать удобнее будет (+ ты получаешь доступ к множеству готовых библиотек). Плюс, есть тот же распберри в котором по моему то ли 128 то ли 256 Мб, запускается Линукс и можно хоть на Питоне писать и куча аналогичных китайских нонейм плат.

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

>>425531

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

$a = array( );

Затем добавляешь данные либо через

$a[$x] = $y;

либо через

$a[] = $y;

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

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

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

А у тебя куча ошибок

> $data1 = x;


Непонятно что такое x

> $array2 = array($data3 > $data1);


Ты наверно хотел написать => а не >
#584 #425548
>>425543

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

Так например:

$money = $money * $percent;
#585 #425570
>>425523

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

>Если тебе база не нужна, не проще ли просто сверстать страницы статически и вынести отдельно повторяющиеся части вроде шапки/подвала?


См. выше.

>Смотря какой. Скорее всего нет.


Думал о Ларавеле.
#586 #425639
>>425570

Тогда феймворк не помешает

> Думал о Ларавеле.


Не разбиаюсь в нем потому ничего не могу сказать.
11 Кб, 181x280
#587 #425709
>>419972
ОП, зачем ты это делаешь? Мне правда интересно. Такое-то волонтерство. Ты сослан в сибирь, или просто агентуру вербуешь?
#588 #425757
>>425709
Доброчановцы они такие, самоутверждаются за счет помощи другим. "Я совершил хороший поступок, я хороший человек" — такова их мантра.
Они получают позитивные эмоции, когда слышат благодарность, достигают душевного равновесия из альтруизма.
А чем еще им жить? Любви к себе у них особой нет, они не могут жить эгоизмом, прославляя имя свое.
Да и просто скучно, наверное.
Мне как питурду они враждебны, потому что я не признаю деления людей на плохих и хороших, поэтому автоматически попадаю в отряд плохих.
Но определенный респект все-таки чувствую.
Во всяком случае, поиметь с них профит можно и нужно.
#589 #425758
>>425757
Оп с доброчана?
#590 #425760
>>425758
Хз, я так называю всех, кто размахивает моралью и "добром" как флагом.
Это не привязка к конкретной борде, а alignment.

Тред утонул кстати, он тебя не слышит. Перекатывайся в новый.
#591 #426338
>>425709

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

>>425757

ой-ой. Добрым быть выгоднее же.

>>425758

Нет, но в общем тамошняя атмосфера мне нравится. Правда, людей там маловато.
#592 #428018
Анон, где я хуй?
http://codepad.viper-7.com/E5NrKq
#593 #428121
>>428018

Кавычку забыл закрыть
#594 #430748
>>419972
Оп, http://codepad.org/nm9jPcpd не работает
Обновить тред
Двач.hk не отвечает.
Вы видите копию треда, сохраненную 6 февраля 2015 года.

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

Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
« /pr/В начало тредаВеб-версияНастройки
/a//b//mu//s//vg/Все доски