Что же у меня не правильно??
<head>
<title>Create account</title>
<link type="text/css" rel="stylesheet" href="styles.css">
</head>
<?
require("funcs.php");
db_connect();
?>
<body>
<?
include("form.inc");
if($seenform != "y"){print "$form";}
else{
$error="n";
if($login==""){
print "<font color=\"red\">* You forgot to enter your Login name!</font></br>";
$error="y";}
if($mail==""){
print "<font color=\"red\">* You forgot to enter your E-mail address!</font></br>";
$error="y";}
else{
$mail=strtolower(trim($mail));
if(! @eregi('^[[:alnum:]]+.+@([[:alnum:]]+\.)+([[:alnum:]]){2,4}$',$mail)){
print "<font color=\"red\">* You enter invalid E-mail address!</font></br>";
$error="y";}
}
if($pass==""){
print "<font color=\"red\">* You forgot to enter your Password!</font></br>";
$error="y";}
if($pass_confirm==""){
print "<font color=\"red\">* You forgot to enter your Password confirmation!</font></br>";
$error="y";}
if($pass != $pass_confirm){
print "<font color=\"red\">* Your password and confirmation are not identical!</font></br>";
$error="y";}
//} //else end.
if($error=="y"){
print "$form";}
else{
srand((double) microtime()*1000000);
$uniq_id=uniqid(rand());
$pass=md5($pass);
$query="SELECT login FROM users";
$result=mysql_query($query);
$row=mysql_fetch_array($result);
$userlogin=$row["login"];
if($login==$userlogin){
print "Username $login already exsist! Choose another!";
print "$form";
}else{
$query="INSERT INTO users(login,pass,mail,code,status) VALUES(\"$login\",\"$pass\",\"$mail\",\"$uniq_id\",\"0\")";
$result=mysql_query($query);
print "Go to the <a href=\"http://localhost/auth/lite/confirm.php?login=$login&pass=$pass&code=$uniq_id\">Confiramtion page</a>
";
//Section for mailing
$rcpt=$mail;
$subject="Registration confirm.";
$body="Dear friend!
You have just registered at XXX.com.
You registration info below:
login: $mail
password: $pass
Confirmation Code: $uniq_id
Go to the http://localhost/auth/lite/confirm.php?login=$login&pass=$pass&code=$uniq_id to confirm your registration.";
mail($rcpt,$subject,$body);
print "Your data insert successfully";
}
}
} //end else.
?>
</body>
</html>
Это просто форма, которая заносит данные в базу mySQL, криптуя пароль через md5.
Так вот, работодатель сказал мне, что весь мой код - одна большая ошибка. Я не могу понять почему??? Объясните мне тупому, почему же это одна большая ошибка.
Заранее благодарен.
не вижу проверки введенных данных на опасные символы... знаю что php может сам защищает... но это может быть отключенно
странная генерация ID пользователя...
Хромает общий стиль: код отдельно html отдельно...
слишком много print и прочее прочее
нет обработки системных ошибок...
Это просто форма, которая заносит данные в базу mySQL, криптуя пароль через md5.
Так вот, работодатель сказал мне, что весь мой код - одна большая ошибка. Я не могу понять почему??? Объясните мне тупому, почему же это одна большая ошибка.
Заранее благодарен.
самое главное правило это то, что sql запросы должны быть отдельно от основного кода программы и вообще код должен быть максимально унифицирован для модернизации. и тд и тп... все в таком духе!
По второму, я всегда смотрел на это таким образом, что нежуели можно введя в поле формы какие-нибудь управляющие символы и таким образом хакнуть сервак? Но если так, хорошо, надо добавить проверку на всякие гадости.
По третьему, а что странного в генерации id. На самом деле, он мне был нужен только для того, чтобы получить какой либо случайный номер (в дальнейшем после регистрации человек должен был подтвердить ее введя логин, пароль и этот код). Мне кажется, что более рандомного номера, чем такой не получить. Но может я и заблуждаюсь.
Насчет общего стиля, тут вопрос спорный. На самом деле, каждый заказчик считает по разному, один любит, чтобы html и код были отдельно, другой нет, третий вообще требует шаблоны, чтобы его дизайнер не заморачивался. Так что, этот вопрос скользкий.
Что значит, слишком много print. Я понимаю, что можно использовать echo. Но какая принципиальная разница???
Про обработку системных ошибок, не мог бы ты пояснить, что имел ввиду?
Вопрос к LSD:
т.е. как я писал выше - шаблоны? Или, как бы ты написал этот код? Чтобы это выглядело профессионально.
2. да можно это называется sql-inject если не взломать то хотябы превести к крашу скрипта если пользователь случайно введет "
3. я бы ввел AUTO_INCREMENT тебеже нужен не рандомный а уникальный хотя это и не принципиально
4. нет не скользкий стиль либо есть либо нет :)
я за несколько лет еще не видел заказчика каторый былбы рад смешиванию кода и HTML более того жесткое требование только TMPL.
5. :) нет я имелл веду представь если заказчик захочет поменять цвет выводимой ошибки в скольки местах прийдется править? правильно а это еще простой код.
правильнее собирать ошибки в одну переменную и в одном месте проверив наличае ошибки вывести её(их)
да и еще опиши что делает такой блок по пунктам а так же сравни с тем что ты хотел от него...
$result=mysql_query($query);
$row=mysql_fetch_array($result);
$userlogin=$row["login"];
5. :) нет я имелл веду представь если заказчик захочет поменять цвет выводимой ошибки в скольки местах прийдется править? правильно а это еще простой код.
правильнее собирать ошибки в одну переменную и в одном месте проверив наличае ошибки вывести её(их)
Т.е. создать функцию, которая будет универсальна в любой проверке ошибок?
да и еще опиши что делает такой блок по пунктам а так же сравни с тем что ты хотел от него...
Тут закидываем запрос в переменную.
$result=mysql_query($query);
Тут понятно, выполняем команду SELECT.
$row=mysql_fetch_array($result);
Результат запроса записываем в массив.
$userlogin=$row["login"];
Выбираем из массива нужное нам поле
И что здесь не правильно? Согласен, что первые две строки можно объединить в одну. А последние две неужели не верны?
Т.е. создать функцию, которая будет универсальна в любой проверке ошибок?
И что здесь не правильно? Согласен, что первые две строки можно объединить в одну. А последние две неужели не верны?
у меня сложилось ощущение что это валидатор на уникальность логина... но только почему проверяется на уникальность только с одной строкой?
$result=mysql_query($query);
if (mysql_num_rows($result)>0)
{
//такой логин уже есть
}
проблема в следующем. mysql_fetch_array() кладет в переменную ОЧЕРЕДНУЮ строку а не весь массив, и для считыванию всех результатов нужно писать
{
//bla-bla-bla
}
Вопрос к LSD:
т.е. как я писал выше - шаблоны? Или, как бы ты написал этот код? Чтобы это выглядело профессионально.
по возможности (это касается не только пхп и mysql, а вообще программирования с использованием бд) нужно все запросы к бд прятать либо в отдельные ф-ии либо в методы класса. это считается хорошим стилем, потому что иначе твой код говорит о твоем не профессионализме... и вообще нужно по максимуму использовать шаблоны: в веб программировании шаблоны вывода страниц, в обычном программировании шаблоны типов данных, иначе тебе придеться переписывать куски кода под отдельный проект - бесполезная и глупая работа.
что касаемо твоего примера, то я скорее всего писал бы через 2 класса:
1) класс обработки ошибок (допустим TError)
2) класс работы с пользователем (допустим TUserGate)
class TUserGate extend TError
плюсы этой схемы:
1) обработка ошибок сводиться к минимуму.. заводишь несколько кодов с ошибками, после каждого действия в твоей пхп программе генеришь нужный код (например 100 если все ок, 101 если unknown login, 102 если unknown password и т.д.).
2) дальнейшая расширяемость: от класса TUserGate наследуешь остальные например новости и и таким образом получаешь единую систему управления контентом
3) все основные действия с бд (файлами) спрятаны в методы класса, следовательно сама исполняемая программа легко читается.
4) автоматически получаешь все плюсы ООП :)).
ну и все в таком духе...
ИМХО все выше написанное не претендует конечно на профессионализм, особенно учитывая объектную модель пхп4.0. Все выше описанное расчитано на развитие этой самой объектной модели! :))
по возможности (это касается не только пхп и...ripped...развитие этой самой объектной модели! :))
Вот этого я и боялся - ООП...у меня оно идет со страшным скрипом, ибо я ни разу не применял его, т.е. не програмил таким образом.
Посему, не мог бы ты мне подскзать, где можно найти в сети статьи по ООП для чайников, чтобы было доходчивым языком с примерами расписано.
Заранее благодарен.
методов. И везде применительно к машине. Я думаю, что все не раз это читали.
Но у меня бошка чего-то совсем не фурычит. С машинами - тут все понятно, а касательно моего примера. Например,
класс обработки ошибок TError. Объектом будет являться форма, в которую вводятс данные или что? Не могу
представить. Потом надо записать туда функцию обработки этих самых ошибок. Я это представляю себе следующим
образом.
$query="SELECT * FROM users WHERE login='$login' AND pass='$pass'";
$result=mysql_query($query);
while($row=mysql_fetch_array($result)){
if($row["login"]!=$login){
$error=101;
}
if($row["pass"]!=$pass){
$error=102;
}
if($row["login"]=="$login"&&$row["pass"]=="$pass"){
$error=100;
}
}
mysql_close();
switch($error){
case("100"): print "Welcome $login to you page!";
break;
case("101"): print "Your login: $login is invalid!";
break;
case("102"): print "Your password: $pass is invalid!";
break;
}
}//end function
В тексте же самой программы просто после формы вызываем функцию obrabotka($login,$pass);.
Я прав или нет? И в принципе это же будет универсальная функция для всех последующих форм проверки на входе, так?
Но все равно у меня остается вопрос:
1) Что является объектом в классе обработки ошибок TError?
2) В файле funcs.php находится информация коннекта с базой данных и сервером. Но почему, когда я делаю в файле, в
котором описана функция obrabotka($login, $pass), require("funcs.php");, то выдается предупреждение:
естественно, ничего не работает. А если вписать в функцию obrabotka($login, $pass) соединение с сервером и базой, то
все ок. Почему так?
3)И еще, как бы сделать так, чтобы после ошибок 101 и 102 форма появлялась еще раз, а после 100 - нет. У меня в
голове есть только один вариант, который я в книге видел, загнать всю форму в переменную $form, в саму форму
добавить <input type=\"hidden\" name=\"seenform\" value=\"y\"> и потом проверять:
print $form;}
else{
//делаем проверку
}
Но так мне кажется не удобно и не красиво. Таким образом и шаблоны не применишь, придется вставлять куски
PHP-кода в HTML. Наверняка можно по другому это реализовать. Как?
В общем, я очень нуждаюсь в вашей помощи. Если не сложно помогите мне в этом разобраться. Заранее спасибо.
>данные или что?
объектом будет переменная!!!
>3)И еще, как бы сделать так, чтобы после ошибок
>101 и 102 форма появлялась еще раз, а после 100 -
> нет.
просто выводи сообщение "Wrong password or login" и ставь ссылку для возврата. Криво.. но если подумать, то можно до ума довести.
вот пример класса работы с ошибками:
// RetCode class. Базовый для всех.
// 100 - ok
// 101 - could not connect to MySQL Server
// 102 - could not select data base
// 103 - could not connect to data base
// 104 - query error
class TRetCode {
var $RetCode;
function TRetCode(){ // конструктор класса
$this->RetCode="100";
}
function SetRetCode($code){ // установить код ошибки
$this->RetCode=$code;
}
function GetRetCode(){ // получить код ошибки
return $this->RetCode;
}
function ClearRetCode(){ // очистить код
$this->RetCode="100";
}
function RetCodeParser(){ // ф-ия вывода пояснения кода ошибки
switch($this->RetCode){
case 100: return "All ok!
"; break;
case 101: return "Cannot Connect to the Data Base
"; break;
case 102: return "Cannot select data base
"; break;
case 103: return "Not Connected to db!
"; break;
case 104: return "Query Error!
"; break;
}
}
} // end of the class
разберись с этим.. "потыкай" его везде.. только так можно разобраться..
function db_connect(){
$result=mysql_pconnect("localhost","login","pass");
if(!$result){
return false;
}
if(!mysql_select_db("new_db")){
return false;
}
return $result;
}//end function db_connect
function obrabotka($login, $pass){
db_connect();
$query="SELECT * FROM users WHERE login='$login' AND pass='$pass'";
$result=mysql_query($query);
if(mysql_num_rows($result)>0){
$error="100";
}else{
$query="SELECT login FROM users WHERE login='$login'";
$result=mysql_query($query);
if(mysql_num_rows($result)>0){
$error="101";//login is valid
}else{
$query="SELECT pass FROM users WHERE pass='$pass'";
$result=mysql_query($query);
if(mysql_num_rows($result)>0){
$error="102";//pass is valid
}else{
$error="103";//login and pass are invalid
}
}
}
if($login==""&&$pass==""){
$error="104";
}
mysql_close();
switch($error){
case("100"): print "Welcome $login to you page!";
break;
case("101"): print "Your password: $pass is invalid!";
break;
case("102"): print "Your login: $login is invalid!";
break;
case("103"): print "Your login: $login and password: $pass are invalid!";
break;
case("104"): void;
break;
}
}//end function obrabotka
?>
Кстати, я тут усовершенствовал функцию проверки пароля и логина на входе. Посмотри, пожалуйста, и выскажи свое мнение.
вот моё мнение :D
делай как предложил gufy и не изобретай велосипед
с точки зрения логики и безопасности это бред и сам подумай почему
вот моё мнение :D
делай как предложил gufy и не изобретай велосипед
с точки зрения логики и безопасности это бред и сам подумай почему
НУ, я вроде так и сделал, как gufy написал, только чуть разветвил структуру.
А LSD помогает мне освоить ООП. За что ему большое спасибо.
НУ, я вроде так и сделал, как gufy написал....
Не... gufy правильную проверку написал а твоя не очень правильная...
например что будет если я попытаюсь зарегить акки с такими параметрами:
log pass1
log pass2
проверка на пустоту login/pass почемуто в конце и не правильная
и опятьже нет защиты на спецуху.
$error="101";//login is valid
}else{
$query="SELECT pass FROM users WHERE pass='$pass'";
$result=mysql_query($query);
if(mysql_num_rows($result)>0){
$error="102";//pass is valid
если логин правельный то $error="101" иначе и т.д. зачем тебе проверять иначе.. если логин не прошел!!!!!!!!!!!!!
это первое.
Второе: зачем порождать множество кодов для обработки ошибок... оставь 100 если ошибок не было.. не надо делать 101 если логин правельный.... лишний гемор имхо!
третье: зачем писать столько запросов к бд если можно только одним обойтись:
SELECT *FROM table WHERE login='$login'
а потом через тот же mysql_fetch_array проверить пароль полученный из этого запроса.... впрочем это тебе уже guffy советовал....
в принципе весь твой код, как заметил Alone, работает корректно только если в базе 1 пользователь с заданным логином. Подумай об этом.
2Allone: вопрос конечно справедливо поставлен, но он скорее относиться к занесению юзеров в базу, нежели к проверке валидности введенных данных.
привыеденный мной пример может немного искусственный, но позваляет немного снизить кол-во ошибок и обеспечивает более простой потход к написанию тестов.
2All: а почему бы не использовать вместо пхпешной md5() майскюлевскую password()? быстрее и надежней имхо (системный crypt).
2Alone: Проверку на пустоту я ввел, т.к. не знаю как сделать так, чтобы когда юзер первый раз заходит на старницу (имеется ввиду, что он еще не вводил логин и пароль), то выводилась бы только форма. А то у меня выводится и форма и сразу сообщение об ошибке, что такой логин и пароль не правильны. Я и спрашивал ранее, как сделать так, чтобы при первом заходе (т.е. когда еще не вводились логин и пароль) выводилаь только форма (скрипт не выполнялся), а после ввода пароля и логина запускался скрипт?
2Lsd[52r]: Я сделал проверку на логин и пароль в отдельности, чтобы проверить самого себя. А вообще логично делать так, как ты писал. Т.е. код будет следующим:
$query="SELECT * FROM users WHERE login='$login'";
$result=mysql_query($query);
$row=mysql_fetch_row($result);
if(mysql_num_rows($result)>0){
if($row["pass"]==$pass){
$error=100;
}else{
$error=101;
}
}else{
$error=101;
}
mysql_close();
switch($error){
case("100"): print "Welcome $login to you page!";
break;
case("101"): print "Your authentication are invalid!";
break;
}
Тут, как я понимаю можно использовать mysql_fetch_row($result) без while, т.к. при запросе $query="SELECT * FROM users WHERE login='$login'" логину будет соответствовать только один запрос (т.к. я писал выше одному паролю соответствует один логин)?
2. после того как ты применил эту самую функцию незачем применять mysql_num_rows(), т.к. не-fetch'енных рядов уже может и не остаться..
1. функция называется mysql_fetch_array() а не mysql_fetch_row(). во всяком случае в дщоке так...
2. после того как ты применил эту самую функцию незачем применять mysql_num_rows(), т.к. не-fetch'енных рядов уже может и не остаться..
mysql_fetch_array() отличается от mysql_fetch_row() только тем, что в первом данные хранятся в ассоциативном массиве.
Относительно всего кода. Моя логика строилась следующим образом:
1)Делаем запрос с выборкой по логину, получаем что кол-во записей больше нуля (при совпадении).
2)Проверяем пароль. Именно для этого я сделал mysql_fetch_row или mysql_fetch_array - это не принципиально. По другому я не понимаю, как можно выбрать по логину и найти соответсвующий пароль.
$query="SELECT * FROM users WHERE login='$login'";
$result=mysql_query($query);
if($row=mysql_fetch_array($result)){
if($row["pass"]==$pass){
$error=100;
}
}else
{
$error=101;
}
mysql_close();
switch($error){
case("100"): print "Welcome $login to you page!";
break;
case("101"): print "Your authentication are invalid!";
break;
}
Cпасибо.
И все таки остается вопрос:
как при первом заходе на страницу (еще не вводились пароль и логин) выводилаь только форма безе запуска скрипта на проверку (чтобы строчка не вылезала, что не правильный логин пароль)?
//уже из формы
}else{
выводить пустую форму
|
ну конечно если форма get'ом передается, то $_GET