В общем вот этот вот код нижеприведенный вставляется в пустой php файл и запускается на сервере в корневом каталоге. PHP: <?php /** * @author fomiash * @copyright 2017 */ header("Content-Type: text/html; charset=windows-1251"); $bd_pass="<--xXx-->"; $postValue=$_POST["input"]; $postExit=$_POST["exit"]; $loginValue=$_POST["login"]; $passValue=$_POST["pass"]; $dateValue=$_POST["date"]; $thisPage = $_SERVER['PHP_SELF']; $formReg=<<<_REG <form id='form' method='post' action="$thisPage"> <div align=center> <input id='login' name='login' type='text' placeholder='ник' value=''> <input id='pass' name='pass' type='password' placeholder='паролька' value=''> <input id='date' name='date' type='text' placeholder='дата рождения (xx.xx.xxxx)' value=''> <button type='submit' name='input' value='set' >зарегистрироваться</button> </div> </form> _REG; $formInput=<<<_INPUT <div align=center> <form method='post' action="$thisPage"> <button type='submit' name='input' value='reg'>зарегаться</button> </form> <form method='post' action="$thisPage"> <button type='submit' name='input' value='input'>войти</button> </form> </div> _INPUT; $formIn=<<<_REG <div align=center> <form id='form' method='post' action="$thisPage"> <input id='login' name='login' type='text' placeholder='ник' value=''> <input id='pass' name='pass' type='password' placeholder='паролька' value=''> <button type='submit' name='input' value='enter'>войти</button> </form> </div> _REG; if (isset($postExit)) { // выход из аккаунта $file = '.'.$_SERVER['PHP_SELF']; $current = file_get_contents($file); $current = str_replace($postExit, "EXIT_".str_shuffle($postExit), $current); file_put_contents($file, $current); } else if(!isset($postValue)){ // выбор между входом и регистрацией addContent($formInput); } else if ($postValue=='enter'){ // процесс авторизации $array = file('.'.$_SERVER['PHP_SELF']); $len=count($array); for ($t=0; $t<$len; $t++){ $stroke = explode($bd_pass, $array[$t]); if ($stroke[0]==$loginValue && $stroke[1]==$passValue ) { $formClick = addPlusForm($stroke[3], $stroke[2], $thisPage ); addContent($formClick); } } addContent('<red>несовпадение ника и паролька</red>'.$formIn); } else if ($postValue=='input'){ // форма входа addContent($formIn); } else if ($postValue=='reg'){// форма регистрации addContent($formReg); } else if($postValue=='set'){ // проверка регистрационных данных if(($loginValue)==''){ addContent('<red>не указан ник</red>'.$formReg); } if(($passValue)=='') { addContent('<red>не указан паролька</red>'.$formReg); } if(($dateValue)=='') { addContent('<red>не указана дата рождения</red>'.$formReg); } if (!test5_150_str($loginValue) || !test5_150_str($passValue)) { addContent('<red>от 5 до 150 символов</red>'.$formReg); } if (strpos($loginValue, '>') !== false || strpos($loginValue, '<') !== false || strpos($passValue, '>') !== false || strpos($passValue, '<') !== false){ addContent('<red>недопустимые символы > < </red>'.$formReg); } $year=explode(".", $dateValue); if (!checkdate($year[1],$year[0],$year[2])){ addContent('<red>неправильный формат даты</red>'.$formReg); } $array = file('.'.$_SERVER['PHP_SELF']); $len=count($array); for ($i=0; $i<$len; $i++){ $stroke = explode($bd_pass, $array[$i]); if ($stroke[0]==$loginValue) { addContent('<red>пользователь уже зарегистрирован</red>'.$formReg); } } $newsess="ZZZ_".rand(99, 99999999999999); $newuser=$loginValue.$bd_pass.$passValue.$bd_pass.$newsess.$bd_pass.'0'.$bd_pass; $fp=fopen('.'.$_SERVER['PHP_SELF'],"a"); fwrite($fp, $newuser."\r\n"); fclose($fp); $now = new DateTime('now'); $interval = $now->diff( new DateTime($dateValue) ); $itog = $interval->format('%y'); if ($itog>150) {addContent('<b>Too old!</b'.$formReg);} if ($itog<5) {addContent('<b>Too young!</b>'.$formReg);} $formClick = addPlusForm('0', $newsess, $thisPage ); addContent($formClick); } else if (isset($postValue) && $postValue!=''){ // вход в приватную часть со счетчиком $array = file('.'.$_SERVER['PHP_SELF']); $len=count($array); for ($i=0; $i<$len; $i++){ $stroke = explode($bd_pass, $array[$i]); if ($stroke[2]==$postValue) { $newsess = "ZZZ_".rand(99, 99999999999999); $newnum = intval($stroke[3])+1; if($stroke[4]==""){ $stroke[4]="\r\n"; } $array[$i] = $stroke[0].$bd_pass.$stroke[1].$bd_pass.$newsess.$bd_pass.$newnum.$bd_pass.$stroke[4]; } $newtxt.=$array[$i]; } if($newnum==""){ addContent($formInput); } $formClick = addPlusForm($newnum, $newsess, $thisPage ); $fp=fopen('.'.$_SERVER['PHP_SELF'],"w+"); fwrite($fp, $newtxt); fclose($fp); addContent($formClick); } addContent($formInput); // все остальные действия function addPlusForm($newnum, $newsess, $thisPage ){ $formClick=<<<_CLICK <div align=center> <H1>$newnum</H1> <form method='post' action="$thisPage"> <button type='submit' name='input' value='$newsess'>+1</button> </form> <form method='post' action="$thisPage"> <button type='submit' name='exit' value='$newsess'>Выход</button> </form> </div> _CLICK; return $formClick; } function test5_150_str ($str){ $str = str_replace(array("\r","\n"),"",$str); if(strlen($str)>4 && strlen($str)<150 ){ return true; } return false; }//test5_150_str function addContent($cont){ print <<<_CONT <html> <head> <style> html, body, form, h1, div, input, red { margin: 0; padding: 0; display: block} red {color: red;} input {width: 200px;} </style> </head> <body style='width: 100%; height: 100%; position: relative; '> <div style='border: 1px solid #cccccc; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); -webkit-transform: translate(-50%, -50%); -moz-transform: translate(-50%, -50%); -ms-transform: translate(-50%, -50%); -o-transform: translate(-50%, -50%); '> $cont </div> </body> </html> _CONT; exit(); }//addContent ?>
Код это здорово, но хотелось бы все же лафв-версию. Хоть на каком-нибудь бесплатном говнохостинге, но чтоб у себя не разворачивать. Тыжвебразработчик. --- Добавлено --- А чего не UTF-8 то? Код по качеству, на вскидку, ниже среднего. Но сначала запили лайв-версию, а там видно будет и проблемы рассмотрим, до каких дотянемся, как и способы их избежать.
Надеюсь ты не против, я развернул твой код на своём тестовом хостинге, получилось это http://frai.surikat-project.kl.com.ua/ --- Добавлено --- С заданием, честно говоря, совпадений мало)
Цели обкакивать у меня нет. Прошу от моего имени никаких действий впредь не озвучивать. Критика будет только по существу. Автор, поехали, рассмотрим ТЗ по пунктам. Красное - на принято, зеленое - принято. Если в пункте не выполнена хотя бы часть, весь пункт не принят. 1) Запили страничку, посередине которой форма входа с полями под логин и пароль. 2) Под ней кнопки "зарегаться" и "войти". 3) Для регистрации пользователь должен указать ник, парольку, дату рождения, это уже другая форма, как можно догадаться. 4) Если возраст пользователя окажется меньше, ну пусть, 5 лет, при попытке реги пользователю надо вывести сообщение "Too young!", над формой входа. Если окажется больше 150, то "Too old!" там же. 5) Если все ок, то, форма меняется на огромное число "0", а кнопки меняются на "+1" и "Выход". 6) По клику на кнопке "+1" огромное число "0" должно увеличиться на единичку. Имеется ввиду его значение, а не размер шрифта. 7) По клику на "Выход" пользователя должно разлогинить. 8) После разлогинивания пользователь может войти на страничку со счетчиком, введя свои учетные данные. 9) Счетчик при этом должен быть равен последнему значению, которое тот накликал. У каждого пользователя свой персональный счетчик. 10) Запрещено использовать JS, все должно обрабатываться только через сервер. 11) Хранить данные в БД или на файлах - твое дело. Но, рекомендуется, в БД. 12) Требований по стилям нет - главное, чтобы работало как описано ну и чтобы все, что помечено "посередине страницы" таки висело посередине страницы. Итого...11 из 12, все не так плохо, я бы даже сказал - хорошо. Пункт 1 не принят, потому что не выполнен как таковой. Поля под логин и пароль должны быть видны сразу, а не находиться на другой странице, до которой еще один клик. Далее, проблемы реализации: 1) Ввод даты. Та же ошибка что и у всех предыдущих исполнителей. В задании не просто так указан ввод даты рождения. Дата - это крайне геморройная тема. Под нее надо правильно организовать поле ввода, ее надо правильно обработать и вообще никто не любит дату. По этому она в задании специально используется. Ввод, который ты предложил - неудобный. Во-первых, ты указал формат хх.хх.хххх, так не делают. Первые два икса - это день или месяц? Обычно форматы даты пишут как dd.mm.yyyy или дд.мм.гггг, но все равно это не здорово. Пользователь должен вводить синтаксически корректную строку, в которой можно допустить ошибку. Я уже не раз говорил, делай как делают гугл, стим и прочие гиганты - под дату отводи три выпадающих списка. В одном 31 день, в другом 12 месяцев, в третьем - года, плюс минус сотня от текущего. Проверено, работает. На стороне сервера, разумеется, надо проверить, не ввел ли пользователь там 31 февраля или типа того. Но это не сложно. Переделай, пожалуйста, чтобы знать, как это работает. 2) После получения ошибки Too Old/Too young сайт форма просто перестала реагировать. И при этом попытка регистрации прошла. Я понимаю, что явно не было написано, что регистрация должна заворачиваться, но, думал, что это понятно, иначе не было бы смысла выводить ошибку... Я, внесу это уточнение в текст задачи. Но тоже, было бы желательно, чтобы регистрация не проходила. У тебя там сейчас зареганы пользователи 1789 года рождения и 2017 соответственно. Ограничение по возрасту на то и ограничение, чтобы не допускать подобного. Код ревью - тут, увы, только завтра. Сегодня вечером нет времени.
Благодарю за разбор, по первому пункту каюсь - разделил по собственному алгоритму, как в ТЗ проще, собственно меня и заинтересовала идея сделать это максимально просто, по дате наверное так же пытался упростить, посмотрю, что можно сделать, просто не читал все обсуждение топика, где это уточняется, чтобы не наткнутся на уже реализованные варианты. Что касается возраста, то да, у меня это не ошибка, а сообщение, ошибки красным выводятся. Буду иметь ввиду.
Один момент непонятен - по какому условию задавать, что по возрасту не подошел, если в выпадающем списке я задам интервал от -5 до -150 лет. Специально увеличить интервал? Но это как то не интуитивно)
@Fell-x27 а разве в учете даты не должны сравниваться месяц и день? допустим я введу 10.10.2012 и проверка покажет что мне можно регаться, а по условию же нельзя, так как 4 года
Всё равно реализуй проверку, мало ли что ты там в списке задал? Данные-то из вне приходят. Сурикат откроет инспектор объектов в браузере и твой списочек подредактирует Всегда на стороне сервера надо проверять, что приходит от клиента, даже если на клиенте стоит супер-пупер javascript-валидация Если ты не понял, смысл задания Суриката в том, что он взял самые типичные задачи, которые веб-программисту приходится решать каждый день и упростил их, чтоб не было лишних подробностей, а осталась только самая соль. --- Добавлено --- Должны. Класс DateTime php с этим прекрасно справляется.
Да, все так, как сказал @mkramer. И про проверку на сервере и про даты и про суть задачки. Я ведь в тз ничего не сказал про то, что проверять надо только год, верно? Проверять надо возраст. А как ты это сделаешь, вскроется в коде. По-правильному, подразумевается использование встроенных функций для работы с датой. К слову, пока что ни разу не видел, чтобы кто-то считал только года в чистом виде, а не по дате целиком. С датой обычно у всех проблемы только на уровне пользовательского ввода. В тз этот пункт явно не прописан. Но так и задумано. Зато потом будет понятнее, как с этим бороться. На грабли иногда надо наступить, чтобы потом о них помнить.
Так, ну..тут все совсем не так радужно, как снаружи. Для начала, попробуйте поставить в самое начало кода вот это PHP: error_reporting(E_ALL); Будете неприятно удивлены. У вас код, ориентированный на работу с register_globals. Но эта опция уже много лет как не используется, а в новых версиях попросту отсутствует, потому как создает дыру в безопасности. Далее, я уже спрашивал, а кодировка почему не UTF-8 то? UTF-8 наше все. На этом пока остановимся. Постарайтесь исправить все, чтобы никаких ошибок не всплывало. Для этого необходимо делать проверки на существование присваиваемых значений.
Что именно не понятно. Ты не знаешь что это, или не знаешь, почему не работает у меня? --- Добавлено --- А тестировать локально пробовал? Вот что у меня xDebug выдает. И такого добра там на семь экранов. В какой версии PHP ты работаешь?
Выставляю в настройках обычно register_globals=off , насколько знаю - защищает от инициализации переменных извне без их явного обозначения в коде и защищает - проверял. Локально запускаю на Денвере, PHP 5 , вывод ошибок смотрю там-же. На сайте если выложено, то вывод отключен ошибок Но в целом интересно, о чем там эти семь экранов. Подозреваю, что не объявлен тип переменных и начальное значение, но насколько это нужно делать, если register_globals=off ? Кода меньше же
Денвер древний уже. И PHP там, по дефолту 5.1.12. Если с бубном потанцевать, будет 5.3 но 5.3 тоже очень старая версия. Нужна минимум 5.6. А лучше 7. На винде это решается через OpenServer, но я советую попробовать развернуть окружение на линуксе в виртуалочке. Однако, у тебя каша. 1) Нет типов в PHP. По крайней мере в PHP 5.1.12 точно. В седьмой версии они почти есть. 2) Тут подозревать нечего, в ошибке ясным текстом написано, что у тебя беда из-за обращения к данным по несуществующему индексу. Ты открываешь страницу и сразу пытаешься что-то тянуть из $_POST, хотя никакого $_POST нет. Никто не посылал запрос. И у тебя, как следствие, идет попытка чтения несуществующей ячейки массива. PHP на это ругается. Это надо исправлять. 3) Это нужно делать. Отключенный регистр глобалс это хорошо, но в коде не должно быть ошибок, предупреждений и нотисов. Некоторые пренебрегают теми же нотисами, некоторые втыкают @ везде и всюду и типа все ок. Но это хреновый стиль. Проблемы нужно решать, а не закрывать на них глаза. Так что решай. 4) Количество кода никак не связано с его качеством или с грамотностью программиста. Кода должно быть столько, сколько нужно, а не "чем меньше, тем лучше". Не гонись за этим. Более того, если тебе нужна избыточность для улучшения понимания того, что ты делаешь, пили избыточность. Не можешь сходу читать тернарные операторы? Пили if...else, даже ради одной переменной. В коде образовалась сложная конструкция из нагромождения вызовов всякой хрени? Дели ее на логические части, каждую часть присваивай переменной, потом оперируй этими переменными. Этого не надо стесняться. Код должен быть поддерживаемый и читабельный. И, в первую очередь, для тебя самого.