PDA

View Full Version : آموزش: آموزش طراحي سيستم ثبت نام و ورود



pejman_view
جمعه 18 آذر 1390, 21:55 عصر
با نام خدا

اين آموزش را بخاطر دوستان که پيام دادند و آموزشي در اين رابطه خواستند شروع کردم به نوشتن،
اين آموزش بصورت گام به گام است و گام به گام موارد پيچيده تر اضافه مي شود و حتي فيلدها و جداول مربوطه تغيير خواهد کرد بنابراين از دوستان خواهشمندم قبل از اينکه پست بدهند به من پيام بدهند تا تغييرات را با نام خودشان وارد نمايم.

گام اول:

براي شروع نيازهاي خودمان را مي نويسيم:

فيلدهايي که در ديتابيس نيازمنديم:
1- شناسه کاربر (عددي)
2- نام کاربري (کاراکتر و عدد)
3- ايميل
4- رمزعبور
5- زمان ساخت اکانت
6- وضعيت کاربر

خوب حالا کد SQL آن را مي نويسيم.

CREATE DATABASE dbname;
CREATE TABLE `users` (
user_id INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
username VARCHAR( 25 ) NOT NULL ,
password CHAR( 32 ) NOT NULL ,
email VARCHAR( 60 ) NOT NULL ,
creation_date INT( 11 ) UNSIGNED NOT NULL ,
status INT( 1 ) UNSIGNED NOT NULL ,
INDEX ( username , password) ,
UNIQUE (email)
);

فقط dbname را با نام دلخواه خود براي ديتبايس تغيير دهيد.
خوب الان ممکن است تک تک خط هاي بالا براي شما سوال شود، در آخر هر گام سوالات را جواب مي دهم.
حالا نوبت به وارد کردن record ها مي آيد فعلاً من به يک رکورد ساده بسنده مي کنم.

INSERT INTO users (user_id,username,password,email,cdate,status) VALUES ('test',md5('test'),'test@localhost','1323455986') ;

تا اينجا ما اولين گام را برداشتيم حالا مي رسيم به بخش سوالات متداول اين بخش را براي پاسخگويي به سوالات دوستان گذاشتم لطفاً بجاي پست کردن به من پيام دهيد من سوال شما را در پست ها جواب خواهم داد.

سوالات متداول:
1- چرا در رمز عبور از CHAR استفاده کرديد اما براي نام کاربري VARCHAR؟
در حقيقت CHAR و VARCHAR تفاوت ناچيزي دارند اما خيلي مهم است به زماني فکر کنيم که ديتابيس خيلي بزرگي داريم و مي خواهيم هر چه آن را بهينه تر کنيم.
تفاوت CHAR و VARCHAR:
در ارزش اشغال مموري:
Char = طول رشته
VARCHAR = طول رشته + 1 بايت
خوب طبق ضرب المثل معروف قطره قطره جمع گردد وانگهي دريا شود ما هم در آن يک بايت صرفه جويي کرديم که در پروژه بزرگ مقدارش زياد نشود.

2- چرا طول password را 32 انتخاب کرديد؟
چون من مي خواهم در آينده از روش کدگذاري md5 استفاده کنم که هر رشته متني را به يک رشته 32 کاراکتري تبديل مي کند.

3- وظيفه INDEX چيست؟
اين تابع به MYSQL مي فهماند که بعداً ما مي خواهيم بيشترين جستجو و انتخاب رکوردها را بر اساس اين فيلدها انجام دهيد در نتيجه جستجويي سريعتر خواهيم داشت.

4- وظيفه UNIQUE چيست؟
اين تابع به MYSQL مي فهماند که ما فقط يک ايميل يکتا خواهيم داشت و اجازه ثبت يک ايميل مشابه در در چند رکورد مختلف را ندهد. و اين کاملاً سليقه ايي است.

با آرزوي موفقيت.

css-man
شنبه 19 آذر 1390, 21:55 عصر
داداش ادامه بده منتظریم

mohsen_31369
شنبه 19 آذر 1390, 22:17 عصر
خواهشمند است در ادامه ی آموزش، لاگین از طریق غیر از سسشن استفاده بفرمایید تا با شیوه ی جدید آشنا شویم.

css-man
یک شنبه 20 آذر 1390, 09:31 صبح
اگر امکان داره سشن رو هم توضیح بدید روش جدید تری هم وجود داشت توضیح بدید

pejman_view
دوشنبه 21 آذر 1390, 01:01 صبح
به نام خدا

همانطور که تقاضا کردم لطفاً پيام خصوصي بدهید تا گام ها پشت سر هم بصورت مطلب آموزشي باشند. ضمناً بخاطر تاخيرها متاسفم جديداً درگير يک پروژه نسبتاً بزرگ شدم که تمام وقتم را گرفته اما سعي مي کنم زود به زود مطالب را آپديت کنم.

گام دوم: ساخت فرم ثبت نام

خوب در گام اول ديتابيس مورد نياز خودمان را طراحي کرديم. اما در اين گام قصد داريم که براي ورود اطلاعات به ديتابيس فرمي طراحي کنيم.
براي اين کار اول فرم خود را بصورت HTML مي نويسيم. و در فايل login.php وارد مي کنيم نمونه کد html استفاده شده توسط خودم را در پايين آوردم مي توانيد از اين استفاده کنيد:
اين فرم شامل فيلدهاي متني نام کاربري، ايميل، رمزعبور و تاييديه رمزعبور است با يک دکمه ثبت اطلاعات:



<html>
<head>
<title>Submit</title>
</head>
<body>
<form method="POST">
<p>Username:<input type="text" name="username" size="20" /></p>
<p>Email:<input type="text" name="email" size="20" /><br /></p>
<p>Password:<input type="password" name="pass" size="20" /></p>
<p>Verify Password:<input type="password" name="verifypass" size="20" />
<input type="hidden" name="submitted" value="1" />
<p><input type="submit" value="Submit" /></p>
</form>
</body>
</html>حالا در بالاي تگ HTML شروع به نوشتن کدهاي PHP خود مي کنيم.

براي دريافت فرم ارسالي در PHP ما از دو آرايه درون ساخته PHP استفاده مي کنيم $_GET و $_POST اين دو متغير هر کدام براي متد خاص ارسال شده هم نام خود استفاده مي شود مثلاً براي دريافت فيلدهاي ارسالي از طريق متد POST بايستي از آرايه $_POST استفاده کنيم.

اول کد مورد نظر خودم را مينويسم در خود کد PHP تک تک خطها را توضيح خواهم داد.


<?php
if (isset($_POST['submitted'])){ //check mikone bebine form ersal shode ya na?
$dbc= mysqli_connect('localhost','root','','test');
$error = array(); //arraye khali baraye error misazim
if (!empty($_POST['username'])){ //check mikone bebine username por shode ast ya na?
$u = $_POST['username']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your username'; //payame ro dar arraye error beriz
}
if (!empty($_POST['email'])){ //check mikone bebine email por shode ast ya na?
$e = $_POST['email']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your email'; //payame ro dar arraye error beriz
}
if (!empty($_POST['pass'])){ //check mikone bebine password por shode ast ya na?
$p = $_POST['pass']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your password'; //payame ro dar arraye error beriz
}
if (!empty($_POST['verifypass'])){ //check mikone bebine verify password tayeediye por shode ast ya na?
if($_POST['verifypass']!=$_POST['pass']){ //agar password moshabeh ba verify shodash nabood
$error[] = 'Your both passwords are not matched.'; //khata ro dar error beriz
}
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your verify Password'; //payame ro dar arraye error beriz
}

if (empty($error)){
$now = time();
$q = "INSERT INTO users (username, email, password, creation_date,status ) VALUES ('$u', '$e', md5('$p'), $now, 0 )";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad

if ($r){//agar dorost bood
echo $msg = "Registration done successfully. thank you very much."; //namayeshe successful message.
}else{
echo $msg = "<p>An uknown system error is occured. if this error persist please contact admin.</p>"; //namayeshe error message.
}
}else{
echo '<p class="error"> Below errors encounter:<br />';
foreach ($error as $val){//print each error in a new line.
echo " -$val<br/>\n";
}
echo '<br />Please try again</p>';
}
mysqli_close($dbc);
}
?>

تا اينجا فقط کارهاي اوليه را انجام داديم همانطور که متوجه شديد ما نه رشته هاي ارسالي را بررسي کرديم و نه خطاها را نمايش داديم، اين ها را در گام هاي بعدي توضيح خواهم داد به نظر من فعلاً براي اين گام کافي است. به اميد خدا مي خواهيم روش ساخت فرم لاگين را توضيح بدهم. (البته نگران نباشيد گام هاي بعد از فرم لاگين هم هست مانند ساخت CAPTCHA بالا بردن امنيت و ...)


و در آخر کد نهايي:

<?php
if (isset($_POST['submitted'])){ //check mikone bebine form ersal shode ya na?
$dbc= mysqli_connect('localhost','root','','test');
$error = array(); //arraye khali baraye error misazim
if (!empty($_POST['username'])){ //check mikone bebine username por shode ast ya na?
$u = $_POST['username']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your username'; //payame ro dar arraye error beriz
}
if (!empty($_POST['email'])){ //check mikone bebine email por shode ast ya na?
$e = $_POST['email']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your email'; //payame ro dar arraye error beriz
}
if (!empty($_POST['pass'])){ //check mikone bebine password por shode ast ya na?
$p = $_POST['pass']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your password'; //payame ro dar arraye error beriz
}
if (!empty($_POST['verifypass'])){ //check mikone bebine verify password tayeediye por shode ast ya na?
if($_POST['verifypass']!=$_POST['pass']){ //agar password moshabeh ba verify shodash nabood
$error[] = 'Your both passwords are not matched.'; //khata ro dar error beriz
}
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your verify Password'; //payame ro dar arraye error beriz
}

if (empty($error)){
$now = time();
$q = "INSERT INTO users (username, email, password, creation_date,status ) VALUES ('$u', '$e', md5('$p'), $now, 0 )";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad

if ($r){//agar dorost bood
echo $msg = "Registration done successfully. thank you very much."; //namayeshe successful message.
}else{
echo $msg = "<p>An uknown system error is occured. if this error persist please contact admin.</p>"; //namayeshe error message.
}
}else{
echo '<p class="error"> Below errors encounter:<br />';
foreach ($error as $val){//print each error in a new line.
echo " -$val<br/>\n";
}
echo '<br />Please try again</p>';
}
mysqli_close($dbc);
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Submit</title>
</head>
<body>
<form method="POST">
<p>Username:<input type="text" name="username" size="20" /></p>
<p>Email:<input type="text" name="email" size="20" /><br /></p>
<p>Password:<input type="password" name="pass" size="20" /></p>
<p>Verify Password:<input type="password" name="verifypass" size="20" />
<input type="hidden" name="submitted" value="1" />
<p><input type="submit" value="Submit" /></p>
</form>
</body>
</html>
سوالات رايج :

1- چرا در فرم از يک فيلد مخفي به نام submitted استفاده کرديد؟
من مي خواستم از طريق اين فيلد تاييد کنم که آيا فرم ثبت شده است يا نه و اگر به اولين خط PHP که در بالا نوشتم نگاه کرده باشيد. با يک شرط if چک کردم آيا اين فيلد ثبت شده يا نه اگر ثبت شده بود که عمليات را ادامه مي داد. در غير اينصورت فقط به نشان دادن فرم بسنده مي کرد.

2- چرا براي ارور از آرايه استفاده کرديد؟
اين کار تقريباً بصورت سليقه ايي است چون مي خواستم بعداً خطاها را با يک حلقه به راحتي نمايش بدهم.

3- آيا اين کد موارد امنيتي عمومي را رعايت کرده است؟
خير! فقط بصورت مثال است به اميد خدا در گام هاي بعدي کدها را پيچيده و قوي تر خواهم کرد.

4- دقيقاً کار فيلد status چيست؟
در گام هاي بعدي مي خواهم روش سطح بندي و حذف کاربران را توضيح دهم و نکاتي در اين باره بگويم. بخاطر همين وضعيت کاربر را گذاشتم.

pejman_view
دوشنبه 21 آذر 1390, 22:34 عصر
به نام خدا

گام سوم: ساخت سيستم ورود به سايت

اميدوارم تا اينجا آموزش ها خوب و مفيد واقع شده باشند. از استادان تقاضا دارم لطفاً اگر سوالي و انتقادي دارند به من پيام خصوصي بدهيد خوشحال خواهم شد که انتقاد استادان را براي هر چه بهتر شدن کارم در اموزشم استفاده کنم.

همانطور که از عنوان گام هم معلوم است امروز مي خواهم ساخت لاگين با سشن را آموزش بدهم البته بعضي ها پرسيدند که آيا راهي به غير از استفاده از سشن هست؟ متاسفانه بايد بگويم من هنوز راهي جديد نديدم و فعلاً همين سشن بهترين راه است.

خوب اول فرم HTML آن را مي سازيم.

<html>
<head>
<title>Login</title>
</head>
<body>
<form method="POST">
<p>Username:<input type="text" name="username" size="20" /></p>
<p>Password:<input type="password" name="pass" size="20" /></p>
<input type="hidden" name="submitted" value="1" />
<p><input type="submit" value="Submit" /></p>
</form>
</body>
</html>

اينجاي کار تقريباً مانند فرم ثبت نام است در بالاي کد HTML تگ PHP را باز مي کنيم.
و کد زير را مي نويسيم تمام توضيحات را در کد بصورت کامنت نوشتم:

if (isset($_POST['submitted'])){ //check mikone bebine form ersal shode ya na?
$dbc= mysqli_connect('localhost','root','','test');
$error = array(); //arraye khali baraye error misazim
if (!empty($_POST['username'])){ //check mikone bebine username por shode ast ya na?
$u = $_POST['username']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your username'; //payame ro dar arraye error beriz
}
if (!empty($_POST['pass'])){ //check mikone bebine password por shode ast ya na?
$p = $_POST['pass']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your password'; //payame ro dar arraye error beriz
}
if (empty($error)){
$q = "SELECT user_id,status FROM users WHERE username='$u' AND password=md5('$p') AND status!=3 ";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad

if (mysqli_num_rows($r)==1){//agar karbar vojood dasht hatman faghat 1karbar ham vojood dare pas bayad tedade record ha mosaviye 1 bashad
$row = mysqli_fetch_assoc($r); //maghadir record ra dar moteghayere row khahad rikht
if ($row['status']==0){
echo $msg = "<p class='msg'>Your Account is inactive, First of all reactive your account.</p>"; //namayeshe error message.
}else{
$_SESSION['userid'] = $row['user_id']; //user_id ro dar session vared mikonim
$_SESSION['level'] = $row['status']; //status ro dar session vared mikonim
header ('location: profile.php');
}
}else{
echo $msg = "<p class='msg'>There is no such this user</p>"; //namayeshe error message.
}
}else{
echo $msg = "<p class='msg'>An uknown system error is occured. if this error persist please contact admin.</p>"; //namayeshe error message.
}
}

?>

در بين کدها شايد متوجه سشن ها شده باشيد. يکي از سشن ها level نام داشت آن را براي اين گذاشتم که کاربران را سطح بندي کنم و سطح مانند زير است:
سطح 0 = کاربر هنوز ايميل خود را فعال ننموده است (بنابراين پيامي با اين مضمون نمايش داده خواهد شد)
سطح 1 = کاربر ايميل خود را فعال کرده (کاربر فعال است)
سطح 2 = کاربر مدير سايت است (مدير سايت)
سطح 3 = کاربر اکانت خود را حذف کرده است

حالا مي خواهيم سشن ها را بررسي کنيم، براي اينکار من از يک تابع استفاده مي کنم و براي اينکه در تمام صفحات استفاده اش کنم در يک فايل جداگانه اين تابع را خواهم نوشت اسم اين فايل را بصورت فرضي functions.php گذاشتم.
حالا در فايل functions.php کد زير را مي نويسم:


<?php
function checkLogin(){
session_start(); //dar har safheyee ke mikhahyeed che maghdare session ro check konid va ya che dar session chizi berizid bayad in tabe ro ejra konid.
if (isset($_SESSION['userid']) AND isset($_SESSION['level'])){ //agar session username meghdar dasht yani login karde
if ($_SESSION['level']==2){ //agar sath = 2 bood admin ast be safhe admin miravad
header ('location: admin.php'); //be safhe admin.php bebare karbaro.
exit(); //dg baghiye code ro nemizare ejra beshe
}elseif($_SESSION['level']==1){//agar sath = 2 bood karbar ast be safhe karbar miravad
header ('location: profile.php');
exit();
}
}
}

?>

سپس اين کدها را در صفحات سايتمان استفاده مي کنيم. فعلاً مي خواهم براي تست در صفحه ورود به سيستم قرارش بدهم. براي وارد کردن تابع در از تابع include استفاده مي کنيم.
include('functions.php');
و در آخر تابع checkLogin() را فراخواني مي کنم.
بنابراين بر اساس اين تابع اگر سطح کاربر 1 بود به صفحه profile.php و اگر 2 بود به صفحه admin.php منتقل خواهد شد.

انشاء الله که اين آموزش هم به درد شما عزيزان خورده باشد. در گام هاي بعدي سعي مي کنم بحث امنيت و تابع نويسي و حتي ساخت کلاس را توضيح بدهم.

login.php :


<?php
include('functions.php');
checkLogin();
if (isset($_POST['submitted'])){ //check mikone bebine form ersal shode ya na?
$dbc= mysqli_connect('localhost','root','','test');
$error = array(); //arraye khali baraye error misazim
if (!empty($_POST['username'])){ //check mikone bebine username por shode ast ya na?
$u = $_POST['username']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your username'; //payame ro dar arraye error beriz
}
if (!empty($_POST['pass'])){ //check mikone bebine password por shode ast ya na?
$p = $_POST['pass']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your password'; //payame ro dar arraye error beriz
}
if (empty($error)){
$q = "SELECT user_id,status FROM users WHERE username='$u' AND password=md5('$p') AND status!=3 ";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad

if (mysqli_num_rows($r)==1){//agar karbar vojood dasht hatman faghat 1karbar ham vojood dare pas bayad tedade record ha mosaviye 1 bashad
$row = mysqli_fetch_assoc($r); //maghadir record ra dar moteghayere row khahad rikht
if ($row['status']==0){
echo $msg = "<p class='msg'>Your Account is inactive, First of all reactive your account.</p>"; //namayeshe error message.
}else{
$_SESSION['userid'] = $row['user_id']; //user_id ro dar session vared mikonim
$_SESSION['level'] = $row['status']; //status ro dar session vared mikonim
header ('location: profile.php');
}
}else{
echo $msg = "<p class='msg'>There is no such this user</p>"; //namayeshe error message.
}
}else{
echo $msg = "<p class='msg'>An uknown system error is occured. if this error persist please contact admin.</p>"; //namayeshe error message.
}
}

?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Login</title>
</head>
<body>
<form method="POST">
<p>Username:<input type="text" name="username" size="20" /></p>
<p>Password:<input type="password" name="pass" size="20" /></p>
<input type="hidden" name="submitted" value="1" />
<p><input type="submit" value="Submit" /></p>
</form>
</body>
</html>


functions.php :


<?php
function checkLogin(){
session_start(); //dar har safheyee ke mikhahyeed che maghdare session ro check konid va ya che dar session chizi berizid bayad in tabe ro ejra konid.
if (isset($_SESSION['userid']) AND isset($_SESSION['level'])){ //agar session username meghdar dasht yani login karde
if ($_SESSION['level']==2){ //agar sath = 2 bood admin ast be safhe admin miravad
header ('location: admin.php'); //be safhe admin.php bebare karbaro.
exit(); //dg baghiye code ro nemizare ejra beshe
}elseif($_SESSION['level']==1){//agar sath = 2 bood karbar ast be safhe karbar miravad
header ('location: profile.php');
exit();
}
}
}

?>

سوالات متداول:

1- چرا سطح 3 را بعنوان حذف کاربر قرار داديد؟
حفظ اطلاعات بسيار مهم است و بنابراين سعي کنيد آنها را براي هميشه نگه داريد و فقط وضعيت آنها را به يک عدد تغيير دهيد که معناي حذف را براي شما داشته باشد.

2- کار @ قبل از mysql_query چيست؟
اگر خطايي در اجراي کوئري ديتابيس رخ دهد ديگر به کاربر نمايش داده نمي شود و اينگونه به راحتي مي توانيد خطا را بدست بگيريد.

css-man
شنبه 26 آذر 1390, 12:04 عصر
دیگه ادامه نمیدی پژمان جان منتظریما

pejman_view
یک شنبه 04 دی 1390, 02:33 صبح
به نام خدا

بعد از يک مدت طولاني وقت شد که دوباره اين موضوع آموزشي را ادامه بدهم. در اين گام مي خواهم آخرين بخش (نه گام!) اين سيستم را توضيح بدهم.
در آخرين گام روش ورود به سيستم را توضيح دادم اما هم اکنون مي خواهم خروج کاربر از سيستم را توضيح دهم.

گام چهارم: خروج از سايت
براي خروج ما بايستي تمام سشن ها را که ايجاد کرديم پاک کنيم براي اينکار بازهم مثالي مي زنم و در مثال تمامي موارد را توضيح مي دهم


<?php
session_start(); //dar har safheyee ke mikhahyeed che maghdare session ro check konid va ya che dar session chizi berizid ya an ra pak konid bayad in tabe ro farakhani konid.
session_destroy(); //in tabe kole session ro az beyn mibarad shayad bazi oghat nemikhayd kole session ro nabood konid banabarin az tabe zire estefade konid.

unset($_SESSION['userid']);//in tabe faghat meghdare andise userid ra nabood mikonad
unset($_SESSION['level']);//in tabe faghat meghdare andise level ra nabood mikonad

header('location: index.php');

?>

فکر کنم اين گام خيلي کوتاه و آسان بود و نيازي به توضيح اضافي ديگر نداشته باشد.


با آرزوي موفقيت
پژمان

css-man
جمعه 15 اردیبهشت 1391, 14:03 عصر
پژمان جان

از این مبحث ها ی آموزشی تو انجمن بزار خیلی خوبه هااا
ما استقبال میکنیم

css-man
دوشنبه 18 اردیبهشت 1391, 17:22 عصر
طبق این آموزش هر اکانتی که ساخته میشه غیره فعاله
چی کار باید بکنیم؟؟؟

kh_rouhi
چهارشنبه 31 خرداد 1391, 11:00 صبح
خیلی آموزش مفیدی بود خواهش می کنم ادامه بدین.
اگه امکان داره استفاده از کد امنیتی رو توضیح بدین.

pejman_view
چهارشنبه 31 خرداد 1391, 13:53 عصر
سلام

در حال انجام یک پروژه هستم و کمتر وقت می کنم که به انجمن سر بزنم اما جدیداً کمی وقتم آزاد شده می خواهم بجای گشت و گذار در فضای سایبر بیشتر وقت آموزش کنم تا انشاء الله زکات علم خودم را پرداخت کرده باشم.
همانطور که می دانید این آموزش مربوط به خیلی وقت پیش بوده تا حدودی یادم نمیاد چی نوشتم و دقیقاً حضور ذهن ندارم (این هم بخاطر درگیری با زندگی و پروژه جدید و بدی حافظه من در برنامه نویس البته خیلی ها به من شباهت دارند حداقل استثنا نیستم.) و مجبور شدم دوباره آموزش را مطالعه کنم.
در گام سوم توضيح دادم که اگر کاربر ايميل خود را فعال نکرده بود اکانتش فعال نمي شود. حال مي خواهم توضيح بدهم چگونه ايميل را بفرستيم و چطوري فعالش کنيم يا اصلاً چه راه هايي من انتخاب کردم برای فعال سازی اکانت.
اول توضیح بدهم که در این گام کمی کدهای گام سوم را دستکار خواهم کرد یکم با تابع های امنیتی آشنا می شویم، و کمی در مورد تابع ایمیل توضیح خواهم داد.

گام پنجم:
حال به ویرایش گام سوم می پردازیم و کدها را کمی ارتقاء می دهیم. از اینجا به بعد من فقط کدها رو ارتقاء می دهم تا کم کم به سطح امنیتی بالا برسد.
در خط 21 چنین آمده:

echo $msg = "<p class='msg'>Your Account is inactive, First of all reactive your account.</p>";
همانطور که یکی از دوستان اشاره کرد اکانت در هنگام ثبت نام غیر فعال است. حالا اول می خواهیم یک تابع برای کد فعال سازی بسازیم بخاطر همین آمدم در فایل functions.php یک تابع ساختم نام این تابع را mkActivation گذاشتم و کد تابع مانند زیر است:


حالا می خواهیم به دیتابیس یک جدول اضافه کنیم برای فعال سازی.

CREATE TABLE `test`.`users_act` (

`act_id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`user_id` INT NOT NULL ,
`act_code` CHAR( 32 ) NOT NULL ,
`creation_date` INT NOT NULL

) ENGINE = MYISAM ;


تغییراتی در register.php از خط 28 به بعد دادم لطفا به این تغییرات توجه کنید:


<?php
include('functions.php');
if (isset($_POST['submitted'])){ //check mikone bebine form ersal shode ya na?
$dbc= mysqli_connect('localhost','root','','test');
$error = array(); //arraye khali baraye error misazim
if (!empty($_POST['username'])){ //check mikone bebine username por shode ast ya na?
$u = $_POST['username']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your username'; //payame ro dar arraye error beriz
}
if (!empty($_POST['email'])){ //check mikone bebine email por shode ast ya na?
$e = $_POST['email']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your email'; //payame ro dar arraye error beriz
}
if (!empty($_POST['pass'])){ //check mikone bebine password por shode ast ya na?
$p = $_POST['pass']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your password'; //payame ro dar arraye error beriz
}
if (!empty($_POST['verifypass'])){ //check mikone bebine verify password tayeediye por shode ast ya na?
if($_POST['verifypass']!=$_POST['pass']){ //agar password moshabeh ba verify shodash nabood
$error[] = 'Your both passwords are not matched.'; //khata ro dar error beriz
}
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your verify Password'; //payame ro dar arraye error beriz
}

if (empty($error)){
$now = time();
$q = "INSERT INTO users (username, email, password, creation_date,status ) VALUES ('$u', '$e', md5('$p'), $now, 0 )";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad
$uid = @mysqli_insert_id($dbc); // be dast avardane shomare user_id query bala
$actCode = mkActivation($e); // sakhte yek code fa'al saaziye monhaser befard
$q = "INSERT INTO users_act (user_id, act_code, creation_date ) VALUES ('$uid', '$actCode', $now)";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad
if ($r){//agar dorost bood
if(sendVerificationMail($u,$e,$actCode)){
echo $msg = "Registration done successfully. Thank you very much."; //namayeshe successful message.
}else{
echo $msg = "Your account has been created. But an error has been occured that activation link doesn't send."; //namayeshe successful message.ama az be anha gofte mishe email fa'al saazi ersal nashode dobare talash konand.
}
}else{
echo $msg = "<p>An uknown system error is occured. if this error persist please contact admin.</p>"; //namayeshe error message.
}
}else{
echo '<p class="error"> Below errors encounter:<br />';
foreach ($error as $val){//print each error in a new line.
echo " -$val<br/>\n";
}
echo '<br />Please try again</p>';
}
mysqli_close($dbc);
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Submit</title>
</head>
<body>
<form method="POST">
<p>Username:<input type="text" name="username" size="20" /></p>
<p>Email:<input type="text" name="email" size="20" /><br /></p>
<p>Password:<input type="password" name="pass" size="20" /></p>
<p>Verify Password:<input type="password" name="verifypass" size="20" />
<input type="hidden" name="submitted" value="1" />
<p><input type="submit" value="Submit" /></p>
</form>
</body>
</html>



اگر دقت کرده باشید در تغییرات من از یک تابع به نام mkActivation و sendVerificationMail استفاده کردم که این تابع ها را در فایل functions.php اضافه کردم و کدها را در اینجا با توضیح می آورم:

function mkActivation($string=""){ // be soorate kamelan ebtekari man oomadam ye tabe sakhtam ke baraye shoma ye activation code besaze
$key = array ('Q','q','W','w','r','R','T','t','z','Z','1','3',' 2','@','-','_','!'); //16ta charachter ro be soorate random entekhab kardam mitunid in ro bast bedid va tedad characterasho bishtar konid.
$randomString = NULL;
for($i=0;$i<5;$i++){ //mikhaym ba ye halghe ye reshteye random az characterhaye bala dorost konim kare kheyli asooniye man toole reshtero hamooontor ke mibinid 5 entekhab kardam
$rnd = rand(0,16); //in tabe karash sakhte adade random ast va hamoontor ke inja mibinid man be tabe goftam adadi beyne 0 ta 16 (bar migarde be tedade characterha dar moteghayere $key) behemoon bargarde.
$randomString .= $key[$rnd]; //dar inja oon adade moteghayero gozashtam too $key farzan $key['3'] baraye ma W ro bar migardoone.
}
return md5($string.$key[$rnd]);
}

function mkurl($dir){ //in tabe gharar ast ke url filetoon ro bargardoone ke shoma harbar lazem nabashe esme sitetoon ro dar script taghir bedahid.
define('DS',DIRECTORY_SEPARATOR); //in tabe ba tavajoh be system ameletoon slash joda konande ro vared mikonad baraye windows farzan 'home\land.php' baraye linux 'home/land.php' ama windows har do halat ro support mikonad banabarin mitavan faghat az forward slash estefade kard
$rootDir= dirname($_SERVER['REQUEST_URI']); //in file directory asliye function.php ro bar migardoone ke farzan agar localhost/test/function.php bashe faghat localhost/test ro bar khahad gardoond ama agar localhost bashe \ ya / barkhahad gardoond banabarin ba yek if slash e ezafi ra pak khaham kard.
if (substr(dirname($_SERVER['REQUEST_URI']),-1)==DS){
$url="http://".$_SERVER['HTTP_HOST'].'/'.$dir;
return $url; //dar akhar farzan agar $dir ke voroodiye in tabe hast index.php bashad, khorooji: localhost/index.php
}else{
$url="http://".$_SERVER['HTTP_HOST'].$rootDir.'/'.$dir;
return $url; //dar akhar farzan agar $dir ke voroodiye in tabe hast index.php bashad, khorooji: localhost/test/index.php farghe in ba balayee dashtane yek foldere ezafe dar url sitetoon hast.
}
}

function sendVerificationMail($username,$email,$act_code){
$act_addss = mkurl('activate.php'); //farzan baraye man http://localhost/login/actiavte.php ro bargardoond.
$link = $act_addss.'?mail='.$email.'&act_code='.$act_code; //be moteghayere act_address ke haviye yek addresse yek parametre get miferestim ke haviye activation code hast. ke ghalebash mesle rooberoost : localhost/login/activate.php?mail=pejman@yahoo.com&act_code=xyz123123123zfd

$subject = "Activating Account"; //in onvane name ast.
$body= "Hello {$username},<br />
I would like to inform your registration was completed successfully.
Just click on Your Activation link is below to Activate your account in order to use my website:<br />
<a href='{$link}'>$link</a>
"; //in ham matne name name ast.

$headers = "MIME-Version: 1.0\n";
$headers .= "Content-type: text/html; charset=utf-8\n";
$headers .= "X-Priority: 3\n";
$headers .= "X-MSMail-Priority: Normal\n";
$headers .= "X-Mailer: php\n";
$headers .= "From: \"EMAIL\" <noreply@{$_SERVER['HTTP_HOST']}>\n";
$headers .= "Return-Path: noreply@{$_SERVER['HTTP_HOST']}\n";
$headers .= "Return-Receipt-To: noreply@{$_SERVER['HTTP_HOST']}\n"; //in header, codehaye standardi hastan ke behtar ast dar balaye emaile khod begozarid ke be mail service provider begid ke bale in emaile ma farzan encoding utf-8 dare agar khast reply kone be folan email reply kone va ...


return mail($email,$subject,$body,$headers);//hamoontor ke mibinid be tartib emaile mokhatab, onvane email, matne email, va header ha ro vared mikonid (header be soorate ekhtiyariye), va dar natije TRUE ya FALSE bar migardanad!
}



خوب ببخشید بعلت ضیق وقت دیگر در توانم نیست بیشتر از این، این گام را توضیح بدهم اما این گام ادامه دارد. تا اینجا فقط ایمیل فعال سازی را فرستادیم با تابع ایمیل و نحوه ساخت یک کد امنیتی و روش آدرس دهی آشنا شدید. در نوشته بعدی که امیدوارم طی امروز و فردا آماده شود. می خواهیم نحوه فعال سازی از طریق لینک، و ارسال دوباره کد فعال سازی را یاد بگیریم.
در اینجا کدهای فایل ها خودم را بصورت HTML می گذارم که بتوانید راحت کپی و پیست کنید:


فایل register.php :

<?php
include('functions.php');
if (isset($_POST['submitted'])){ //check mikone bebine form ersal shode ya na?
$dbc= mysqli_connect('localhost','root','','test');
$error = array(); //arraye khali baraye error misazim
if (!empty($_POST['username'])){ //check mikone bebine username por shode ast ya na?
$u = $_POST['username']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your username'; //payame ro dar arraye error beriz
}
if (!empty($_POST['email'])){ //check mikone bebine email por shode ast ya na?
$e = $_POST['email']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your email'; //payame ro dar arraye error beriz
}
if (!empty($_POST['pass'])){ //check mikone bebine password por shode ast ya na?
$p = $_POST['pass']; //agar por shode bood dakhele moteghayer rikhte shavad
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your password'; //payame ro dar arraye error beriz
}
if (!empty($_POST['verifypass'])){ //check mikone bebine verify password tayeediye por shode ast ya na?
if($_POST['verifypass']!=$_POST['pass']){ //agar password moshabeh ba verify shodash nabood
$error[] = 'Your both passwords are not matched.'; //khata ro dar error beriz
}
}else{ //agar por nashode bood...
$error[] = 'You forgot to enter your verify Password'; //payame ro dar arraye error beriz
}

if (empty($error)){
$now = time();
$q = "INSERT INTO users (username, email, password, creation_date,status ) VALUES ('$u', '$e', md5('$p'), $now, 0 )";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad
$uid = @mysqli_insert_id($dbc); // be dast avardane shomare user_id query bala
$actCode = mkActivation($e); // sakhte yek code fa'al saaziye monhaser befard
$q = "INSERT INTO users_act (user_id, act_code, creation_date ) VALUES ('$uid', '$actCode', $now)";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad
if ($r){//agar dorost bood
if(sendVerificationMail($u,$e,$actCode)){
echo $msg = "Registration done successfully. Thank you very much."; //namayeshe successful message.
}else{
echo $msg = "Your account has been created. But an error has been occured that activation link doesn't send."; //namayeshe successful message.ama az be anha gofte mishe email fa'al saazi ersal nashode dobare talash konand.
}
}else{
echo $msg = "<p>An uknown system error is occured. if this error persist please contact admin.</p>"; //namayeshe error message.
}
}else{
echo '<p class="error"> Below errors encounter:<br />';
foreach ($error as $val){//print each error in a new line.
echo " -$val<br/>\n";
}
echo '<br />Please try again</p>';
}
mysqli_close($dbc);
}

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Submit</title>
</head>
<body>
<form method="POST">
<p>Username:<input type="text" name="username" size="20" /></p>
<p>Email:<input type="text" name="email" size="20" /><br /></p>
<p>Password:<input type="password" name="pass" size="20" /></p>
<p>Verify Password:<input type="password" name="verifypass" size="20" />
<input type="hidden" name="submitted" value="1" />
<p><input type="submit" value="Submit" /></p>
</form>
</body>
</html>


فایل functions.php:

function mkActivation($string=""){ // be soorate kamelan ebtekari man oomadam ye tabe sakhtam ke baraye shoma ye activation code besaze
$key = array ('Q','q','W','w','r','R','T','t','z','Z','1','3',' 2','@','-','_','!'); //16ta charachter ro be soorate random entekhab kardam mitunid in ro bast bedid va tedad characterasho bishtar konid.
$randomString = NULL;
for($i=0;$i<5;$i++){ //mikhaym ba ye halghe ye reshteye random az characterhaye bala dorost konim kare kheyli asooniye man toole reshtero hamooontor ke mibinid 5 entekhab kardam
$rnd = rand(0,16); //in tabe karash sakhte adade random ast va hamoontor ke inja mibinid man be tabe goftam adadi beyne 0 ta 16 (bar migarde be tedade characterha dar moteghayere $key) behemoon bargarde.
$randomString .= $key[$rnd]; //dar inja oon adade moteghayero gozashtam too $key farzan $key['3'] baraye ma W ro bar migardoone.
}
return md5($string.$key[$rnd]);
}

function mkurl($dir){ //in tabe gharar ast ke url filetoon ro bargardoone ke shoma harbar lazem nabashe esme sitetoon ro dar script taghir bedahid.
define('DS',DIRECTORY_SEPARATOR); //in tabe ba tavajoh be system ameletoon slash joda konande ro vared mikonad baraye windows farzan 'home\land.php' baraye linux 'home/land.php' ama windows har do halat ro support mikonad banabarin mitavan faghat az forward slash estefade kard
$rootDir= dirname($_SERVER['REQUEST_URI']); //in file directory asliye function.php ro bar migardoone ke farzan agar localhost/test/function.php bashe faghat localhost/test ro bar khahad gardoond ama agar localhost bashe \ ya / barkhahad gardoond banabarin ba yek if slash e ezafi ra pak khaham kard.
if (substr(dirname($_SERVER['REQUEST_URI']),-1)==DS){
$url="http://".$_SERVER['HTTP_HOST'].'/'.$dir;
return $url; //dar akhar farzan agar $dir ke voroodiye in tabe hast index.php bashad, khorooji: localhost/index.php
}else{
$url="http://".$_SERVER['HTTP_HOST'].$rootDir.'/'.$dir;
return $url; //dar akhar farzan agar $dir ke voroodiye in tabe hast index.php bashad, khorooji: localhost/test/index.php farghe in ba balayee dashtane yek foldere ezafe dar url sitetoon hast.
}
}

function sendVerificationMail($username,$email,$act_code){
$act_addss = mkurl('activate.php'); //farzan baraye man http://localhost/login/actiavte.php ro bargardoond.
$link = $act_addss.'?mail='.$email.'&act_code='.$act_code; //be moteghayere act_address ke haviye yek addresse yek parametre get miferestim ke haviye activation code hast. ke ghalebash mesle rooberoost : localhost/login/activate.php?mail=pejman@yahoo.com&act_code=xyz123123123zfd

$subject = "Activating Account"; //in onvane name ast.
$body= "Hello {$username},<br />
I would like to inform your registration was completed successfully.
Just click on Your Activation link is below to Activate your account in order to use my website:<br />
<a href='{$link}'>$link</a>
"; //in ham matne name name ast.

$headers = "MIME-Version: 1.0\n";
$headers .= "Content-type: text/html; charset=utf-8\n";
$headers .= "X-Priority: 3\n";
$headers .= "X-MSMail-Priority: Normal\n";
$headers .= "X-Mailer: php\n";
$headers .= "From: \"EMAIL\" <noreply@{$_SERVER['HTTP_HOST']}>\n";
$headers .= "Return-Path: noreply@{$_SERVER['HTTP_HOST']}\n";
$headers .= "Return-Receipt-To: noreply@{$_SERVER['HTTP_HOST']}\n"; //in header, codehaye standardi hastan ke behtar ast dar balaye emaile khod begozarid ke be mail service provider begid ke bale in emaile ma farzan encoding utf-8 dare agar khast reply kone be folan email reply kone va ...


return mail($email,$subject,$body,$headers);//hamoontor ke mibinid be tartib emaile mokhatab, onvane email, matne email, va header ha ro vared mikonid (header be soorate ekhtiyariye), va dar natije TRUE ya FALSE bar migardanad!
}


با آرزوی موفقیت

abbas3zaar
سه شنبه 18 اسفند 1394, 14:51 عصر
ممنون خیلی عالی بود

abbas3zaar
جمعه 21 اسفند 1394, 08:29 صبح
$q = "INSERT INTO users (username, email, password, creation_date,status ) VALUES ('$u', '$e', md5('$p'), $now, 0 )";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad
$uid = @mysqli_insert_id($dbc); // be dast avardane shomare user_id query bala
$actCode = mkActivation($e); // sakhte yek code fa'al saaziye monhaser befard
$q = "INSERT INTO users_act (user_id, act_code, creation_date ) VALUES ('$uid', '$actCode', $now)";
$r = @mysqli_query($dbc,$q); //Query ra ejra mikonad

اینجا چرا دو تا insert میشه؟ خب توی همون جدول users یه فیلد active_code میزاشتین و بعد از تایید ایمیل اون فیلد UPDATE میشد مثلا اولش 0 و وقتی تایید شد مقدارش 1 بشه که یعتی اکتیو شده. میشه توضیح بدید؟ چرا یه جدولusers_act درست کردید؟

numberone1
شنبه 22 اسفند 1394, 07:35 صبح
1- چرا در رمز عبور از CHAR استفاده کرديد اما براي نام کاربري VARCHAR؟
در حقيقت CHAR و VARCHAR تفاوت ناچيزي دارند اما خيلي مهم است به زماني فکر کنيم که ديتابيس خيلي بزرگي داريم و مي خواهيم هر چه آن را بهينه تر کنيم.
تفاوت CHAR و VARCHAR:
در ارزش اشغال مموري:
Char = طول رشته
VARCHAR = طول رشته + 1 بايت
خوب طبق ضرب المثل معروف قطره قطره جمع گردد وانگهي دريا شود ما هم در آن يک بايت صرفه جويي کرديم که در پروژه بزرگ مقدارش زياد نشود.



سلام
مرسی بابت آموزش
این نکته اشتباه هست لطفا اصلاح کنید
CHAR

Used to store character string value of fixed length.

The maximum no. of characters the data type can hold is 255 characters.

It's 50% faster than VARCHAR.

Uses static memory allocation.

VARCHAR

Used to store variable length alphanumeric data.

The maximum this data type can hold is up to


Pre-MySQL 5.0.3: 255 characters.
In MySQL 5.0.3+: 65,535 characters shared for the row.


It's slower than CHAR.

Uses dynamic memory allocation.


حافظه اشغال شده توسط char ثابت هست. چه یک بایت داخلش باشه چه 255 بایت.
ولی varchar مدیریت حافظه به اندازه ی مورد نیاز هست.اگر یک بایت برای ذخیره فرستاده باشه یک بایت هم اشغال میشه

wp-ammar
یک شنبه 22 فروردین 1395, 19:13 عصر
سلام لطفا یکی لینک دانلود سورس پروژه رو بزاره