Всем привет! Народ, порекомендуйте, где бы попрактиковаться чтобы набить руку по PHP. А то смотрю я вакансии веб-разработчика - и везде знания PHP нужны. А у меня только HTML, CSS, CMS WordPress и Joomla. Ну ещё jQuery-плагины я подключать умею. Но этого маловато. А вот реальной практики PHP у меня нет, тем более коммерческой. Подскажите пожалуйста где можно такую практику получить.
ставить себе задачи и решать их. компьютеры появились когда человек разумный устал считать в голове и переложил однотипные задачи на бездушную машину.
Сначала надо получить теорию. Учись, делай задачки, причем учись не "ка кнаписать бложег за 24 минуты", а программировать. Ты ведь хочешь быть разработчиком, а не попугаем, который научился чему-то конкретному, не понимая это на абстрактном уровне?
Ну теория то у меня есть. В основном это то что в универе было - по основным алгоритмам и структурам данных. Хочется получить опыт на реальных проектах, а не на тех, которые в книжках описаны.
Рано тебе на реальные проекты. Вот тебе задание, которое я даю всем, кто просит опыта: 1) Запили страничку, посередине которой форма входа с полями под логин и пароль. 2) Под ней кнопки "зарегаться" и "войти". 3) Для регистрации пользователь должен указать ник, парольку, дату рождения, это уже другая форма, как можно догадаться. 4) Если возраст пользователя окажется меньше, ну пусть, 5 лет, при попытке реги пользователю надо вывести сообщение "Too young!", над формой входа. Если окажется больше 150, то "Too old!" там же. Регистрация при этом произойти не должна. 5) Если все ок, то, форма меняется на огромное число "0", а кнопки меняются на "+1" и "Выход". 6) По клику на кнопке "+1" огромное число "0" должно увеличиться на единичку. Имеется ввиду его значение, а не размер шрифта. 7) По клику на "Выход" пользователя должно разлогинить. 8) После разлогинивания пользователь может войти на страничку со счетчиком, введя свои учетные данные. 9) Счетчик при этом должен быть равен последнему значению, которое тот накликал. У каждого пользователя свой персональный счетчик. 10) Запрещено использовать JS, все должно обрабатываться только через сервер. 11) Хранить данные в БД или на файлах - твое дело. Но, рекомендуется, в БД. 12) Требований по стилям нет - главное, чтобы работало как описано ну и чтобы все, что помечено "посередине страницы" таки висело посередине страницы. Это тривиальнейшее задание, основанное на простейших базисах, которое, при этом, охватывает довольно широкий спектр пыхо-разработки. Вперед, пробуй, набирайся опыта, по срокам лимита, пожалуй, не будет. Просто сделай. Если есть вопросы, задавай. P.S. Дальше в треде найдешь варианты решений от других людей. Заимствовать их код не нужно, а вот почитать отзывы о их работах было бы для тебя полезным. Большинство делают одни и те же ошибки.
Судя по тому, что ответа не последовало, можно поставить еще одну черточку в списке "Люди, чьи амбиции были похоронены заданием, которое делается за вечерок". Автор, скажи, что я не прав, и ты решил взяться.
Решил попробовать себя, и послушать что скажут умные люди, какие советы дадите, можно ли так делать или нельзя. 1. Запилил, но со сылками по середине, ссылка входа и регистрации. По этому поводу я выбрал максимальный год 2010, а предупреждения вывожу Реализовал еще -1 и обнулить прото увлекся. есть при нажатии выйти, пользователя разлогинивает. может обратно зайти со старыми данными счетчика(данные счетчика сохраняются) храню в XML И так. Для хранения пользовательских данных используется XML -файл https://github.com/murad0587/test_job/blob/master/test_job/ ... /users.xml обработкой xml файла занимается класс https://github.com/murad0587/test_job/blob/master/test_job/ ... mlBase.php Порядок регитрации: 1. пользователь вводит данные и нажимает кнопку, если остались пустые поля, то выводится сообщение сверху формы, с предупреждением, что данные определенного поля не введены, данные в файл не добавляются, 2. после того как данные проходят проверку, они добавляются в базу, https://github.com/murad0587/test_job/blob/master/test_job/ ... se.php#L20 прежде проверяется существование пользователя с таким username https://github.com/murad0587/test_job/blob/master/test_job/ ... se.php#L51 если такого пользователя нету, то данные успешно добавляются. $username and $password хранятся в хэшированном виде sha1 все проверки с данными проводятся в классе комманд соответствующего странице , к примеру для страницы рагистраиции https://github.com/murad0587/test_job/blob/master/test_job/view/signup.php class Command https://github.com/murad0587/test_job/blob/master/test_job/ ... ommand.php Как только пользователь зарегистрировался, он может авторизоваться. При успешной авторизации, данные из XML файла для текущего пользователя возвращаются в виде массива https://github.com/murad0587/test_job/blob/master/test_job/ ... se.php#L64 этот массив сериализуется и записывается на диск. Последующие операции с пользовательскими данными производится именно с данными которые серриализованы. Для сериализации и десерриализации, а так же перезаписи значений массива используется класс ApplicationRegistry https://github.com/murad0587/test_job/blob/master/test_job/ ... ry.php#L79 и как только пользователь заверзает сеанс новые данные записываются в XML файл для текущего пользователя. В данном случае , перезаписываем именно count, счетчик пользователя. Если пользователь не нажмет кнопку, то серриализованные данные останутся на жестком диске, подумал, пусть лежать, в лубом случае, при следующей авторизации перезапишутся. серриализованные данные хрянятся тут https://github.com/murad0587/test_job/tree/master/test_job/data Критикуйте, пинайте, только пожалуйста, не нижу пояса. Добавлено спустя 41 секунду: а страничка где это можно просмотреть и потыкать www.mahmuzar.ru
1) в ТЗ кнопки таки. И не просто так Попробуй перепилить на них. 2) в ТЗ ничего не было про почту. И тоже не просто так. Смысловой нагрузки она не несет, а париться с ней неохота, лишнее поле для заполнения. Выпили плз. Добавлено спустя 51 секунду: 3) Жмакаю на кнопки и ничегошеньки не происходит циферка не растет. Добавлено спустя 1 минуту 8 секунд: Тьфу ты. Ты сделал рост шрифта %) безумие. Имелось ввиду, что нолик должен превратиться в единичку, единичка в двоечку, ну ты понял. Счетчик должен тикать. Добавлено спустя 1 минуту 35 секунд: У тебя можно через GET назначить любое число. Это аяяй. Число должно количество кликов отображать, а не просто циферку из URL-а. Добавлено спустя 3 минуты 21 секунду: Я только что зарегался как родившийся в 1830м году. Где TooOld? Добавлено спустя 53 секунды: 2010 максимумом вижу, предупреждений не вижу. Добавлено спустя 2 минуты 3 секунды: Юзернейм-то зачем? Я, будучи админом, захочу получить список зареганных пользователей? Что увижу в таком случае? Добавлено спустя 1 минуту 35 секунд: В классе, обрабатывающем XML такая строчка: Хардкодовый путь. Это аааайййяйяйяйяйяй и линейкой по пальцам. Так делать нельзя. У тебя есть класс. Передавай путь до файла в его конструктор. Никогда не хардкодь пути. Добавлено спустя 1 минуту 29 секунд: Класс XMLbase внезапно содержит методы для работы с пользователем. Зачем? Тогда уж переименуй класс. А то по названию - это обертка для работы с XML, а по факту - это авторизатор-логонятор, который просто где-то внутри себя XML юзает. Добавлено спустя 2 минуты 30 секунд: Ты делаешь проверки на число через регулярки. Зачем? Добавлено спустя 1 минуту 34 секунды: Или вот такая конструкция: Зачем ты ставишь проверку с учетом типа при том, что боишься, как бы username не состоял из одних чисел, и, чтобы этого избежать, принудительно его кастишь в string? Может просто оставить == и не париться? Добавлено спустя 5 минут 5 секунд: Ну как-то так, в общем) Можно вообще запилить Отдельную ветку про "пробуем свои силы", но надо как-то исключить подглядунство в работы соседей, чтобы кодотыринг исключить. Добавлено спустя 2 минуты 30 секунд: И да, дюже большой проект у тебя получился одних каталогов 9 штук. Это все в работе участвует? В папке command вообще безумных 10 файлов. Зачем такая избыточность? Добавлено спустя 6 минут 16 секунд: Насчет аяяй гета, вот тебе пример. Допустим, это не просто клики, а отражение какой-то деятельности пользователя, по которой собирается статистика. Я тебе скидываю ссылку вида: http://www.mahmuzar.ru/?&count_increase=toster ты ее открываешь по своей воле или без нее (привет, кроссдоменные атаки!!11), и все. Вся статистика идет коту под хвост. Вообще, запомни, GET никогда не должен отвечать за запись чего либо. GET должен предоставлять данные только для чтения. По этому он GET, а не POST. В самом названии суть отражена. Модификация любых данных через GET - верный путь увязнуть в CSRF, я гарантирую это. Добавлено спустя 4 минуты 45 секунд: Да, есть исключения в виде, например, нашего распрекрасного форума на движке phpBB, где 95% действий завязано на GET-ах. Но тут это все разрулено через костыль в виде CSRF-токенов, вшиваемых в "опасные" GET-запросы. Их уже так просто не подделаешь.
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11 прекрасная идея, очень хотел бы увидеть её реализацию, даже с подглядунством. просто нигде не найдешь задания по пыху с, так сказать, онлайн-поддержкой
1. Перепилил на форму на главной, под которой кнопки зарегаться и войти. 2. Почту выпилил, но не совсем, как бы пользователю не придется вводить, на в пункте пользовательских данных оставил, на будущее, к примеру после регистрации, если пользователь будет пользоваться сервисом, можно попросить его ввести свою почту для связи с нами. 3. Теперь счетчик тикает. По поводу кроссдоменных атак, про такое слышал, но не знал, и не интересовался как это дело происходит. Вообще, сделал, так чтобы через гед нельзя было установить разом значение. Но что меня волнует, так или иначе, если я перейду по ссылке http://www.mahmuzar.ru/?&count_increase=toster, у меня счетчик поменяется на одно значение, хоть я и не использую значение которое было передано через ссылку. Исправил. Вначале подумал поставить даты в интервале этой возростной категории, но исправил как требовалось, поэтому в начальной версии не было, думал запилить, но как говориться голова дура. Исправление не было долгим. Код (PHP): if ((2015 - $year) < 150) { $this->year = $year; } else { $this->error[] = 'Too old!'; } if ((2015 - $year) > 5) { $this->year = $year; } else { $this->error[] = 'Too young!'; } Отредактировал класс, убрал логинятор, регистратор, и вообще теперь, кажется класс делает то, что должен делать исходя из его названия, но не совсем) стоит еще подредактировать А в качестве операций автоизации регистрации включил класс UserController Который в свою очередь будет использовать класс XMLBase ТАк, для больше безопасности:-D Убрал, оставил только пасс в закодированном виде. Запямятовал, в силу того, что нету практического опыта некоторые функции напроч забываются. А регулярку использовал, потому что использовал ее в проверке пользовательского логина и пароля, И понесло ниже:-D Исправл. Не то чтобы из чисел будет, просто было такое, что я возвращаел данные из XML $this->xml->user->username возврщался тип SImpleXMLElement а когда задал принудительно тип возвращаемой меренной, вернулся ассициативный массив. поэтому наверно и там прописал так. Вообще, убрал, и так работает. Короче, понял, зафигачить кнопки надо в форме) сделаю, переделаю) Так прописал, потому что используется в большинстве книжках которые я читал). Вроде приватное свойство, ведь безопасно, не*? А если не, почему не безоспасно? Но в любом случае, я засунул его в конструктор класса. Или использовать сеттер для этого свойства?
В проекте почти все учавствуют. Каталоги то не мешают, подумал. Разделил по каталогам для удобства навигации. А Command для каждой страницы, один Command абстрактный, один комманд который определяет какую страницу выдавать/ Всего 6 команда учавствуют один для тестов. Можно, и попроще, предложу вариант по проще тоже чуть позже Добавлено спустя 1 минуту 55 секунд: Ага, интересно было бы. Может форум тоже оживится, кто что предложит какие решения новые есть, под конец когда все выложат свое можно лучшый вариант выбрать). Я бы посмотрел на обсуждения мастерой выше уровнем)
А ты не используй GET. Гляди, объясню, почему установка интервалов нифига не панацея. Можно открыть код страницы и поправить твои интервалы, зарегав человека, который родился в -1000 году. По этому обязательно должна идти проверка на сервере. Да, на клиенте проверять или ограничивать тоже можно и нужно. Но нельзя надеяться только на клиент-валидацию. Она ненадежна. Вообще возьми за правило относиться к любым данным, которые пришли извне как к атаке. Дело не в приватности и не в безопасности. Ни то ни другое никак не связаны с хардкоденным путем. Коль уж ты пилишь ООП, то надо прикидывать, что классы должны быть максимально независимыми от контекста программы, чтобы можно было их безболезненно перемещать между проектами. По этому, все все все все все данные, используемые классом, должны либо выставляться в конструкторе, либо после создания объекта через методы-сеттеры. При этом, разумеется, можно и нужно использовать "параметры по умолчанию". Ведь всегда будет какая-то наиболее часто используемая комбинация параметров, которую нет смысла дублировать каждый раз.
Делай конечно, почему б нет Главное сразу учитывай то, что было сказано предыдущему "исполнителю", не нужно повторять чужие ошибки.
Вопросов много, но для начала хочу узнать в правильном ли направлении иду? Проверка нажатия кнопки и возраст человека делается так как у меня в коде? Форму для ввода даты рождения упростил до года, а как преобразовать данные если нужны день и месяц? Человек может ввести данные по разному ГГГГ.ММ.ДД или наоборот. как это проверить? Спасибо. Код (Text): <? /*Проверка нажатия кнопки регистрация, если не нажата то выводится первая форма*/ if(!isset($_POST[reg])){ echo '<form method="post"> <p>Логин: <input type="text" name="login"></p> <p>Пароль: <input type="text" name="password"></p> <p> <button type="submit" name="reg">Регистрация</button> <button type="submit" >Вход</button> </p> </form>'; } else{ /*иначе выводим форму регистрации*/ if(isset($_POST[date])){/*Если дата заполнена*/ $d =(int)date('Y') - (int)($_POST[date]); if($d<5) {echo '<div>Вы слишком молод</div>';} elseif($d>150) {echo '<div>Вы слишком стары</div>';} else echo '<div>Вам '.$d. ' лет</div>'; } echo '<form method="post"> <p>Логин: <input type="text" name="login"></p> <p>Пароль: <input type="text" name="password"></p> <p>Год рождения: <input type="date" name="date"></p> <p> <button type="submit" name="reg">Регистрация</button> <button type="submit" >Вход</button> </p> </form>'; } ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <style type="text/css"> form,div{margin-left:50%;} </style> </head> <body> </body> </html>
Ну, во-первых, всё-таки не стоит всё мешать в один файл. Столько файлов, как у предыдущего исполнителя, тоже не обязательно, но и кашу такую делать тоже не надо. По поводу даты - ну коль в задаче сказано, что нужно дату рождения, так и надо делать. А то деньги не заплатят. См. https://php.net/date_parse_from_format. Пользователь может ввести всё, что угодно, это правда, но вы можете проверить, чего он ввёл, и если ввёл не в том, формате, который вы ожидаете, сказать ему об этом. Почему у вас <!DOCTYPE> выводится после формы? Это что-то новенькое. Базой данных и т.п. пока и не пахнет, думали уже об этом? Все обработчики форм, которые посылаются методом $_POST, должны содержать защиту от двойной отправки данных. Погуглите, об этом много и на этом форуме писалось, и в интернете вообще.
Ты делай, чтобы работало так, как ожидается. А там уже будет видно, что верно, а что нет. Так не пойдет. Может, планируется собирать статистику по знакам зодиака, или еще какую хрень. Делать надо как в ТЗ. Оставлять для ввода строку, мол "вбей дату рождения" тоже нехорошо - пользователь банально не будет уверен, правильно ли он ее вводит. Делай как делается везде и всюду, три поля с выпадающими списками - день, месяц, год.
Понимаю что делать нужно как в задании, просто не знаю пока как это сделать, почитаю вашу ссылку и переделаю как Fell-x27 предложил. Насчет БД еще не изучал, щас буду читать, защиту поставлю. Понял, дату исправлю