آرایه جهانی $_SERVER در PHP. ساده ترین و منطقی ترین CNC برای PHP نحوه استفاده از این سیستم

ابتدا صفحه ثبت نام را با افزودن قابلیت آپلود آواتار بهبود خواهیم داد. تصویر منبع باید با فرمت jpg، gif یا png باشد. همچنین نباید بیش از 2 مگابایت باشد. نگران نباشید، پس از فشرده شدن توسط اسکریپت، اندازه آواتار حدود 3 کیلوبایت و فرمت jpg خواهد بود. صفحه reg را باز کنید. php و آن را در تگ اضافه کنید< form >line enctype="multipart/form-data"، مانند مثال:


ثبت

رمز عبور شما *:




یک آواتار را انتخاب کنید. تصویر باید با فرمت jpg، gif یا png باشد:




حالا reg.php را ذخیره کنید

2.بعد باید فیلد دیگری در جدول کاربران ایجاد کنید. به phpmyadmin رفته، دیتابیس و جدول مورد نظر را انتخاب کنید.


تمام مقادیر را مانند شکل تنظیم می کنیم:

مسیر آواتار در این فیلد ثبت می‌شود و در یک پوشه جداگانه ذخیره می‌شود، بگذارید آن را «آواتار» بنامیم. پوشه در همان دایرکتوری که بقیه فایل های اسکریپت هستند قرار می گیرد.

3. به فایل save_user بروید. php کنید و پس از حذف فاصله از لاگین و رمز عبور کد زیر را اضافه کنید:

//حذف فضاهای اضافی
$login = trim($login);

// جدید اضافه کن ********************************************

//یک بررسی برای طول لاگین و رمز عبور اضافه کنید
if (strlen($login)< 3 or strlen($login) > 15) {
exit("ورود باید حداقل از 3 کاراکتر و بیش از 15 کاراکتر تشکیل شود.");
}
if (strlen($password)< 3 or strlen($password) > 15) {
exit ("رمز عبور باید حداقل 3 کاراکتر و بیش از 15 کاراکتر باشد.");
}

if (!empty($_POST["fupload"])) //بررسی کنید که آیا کاربر تصویر را ارسال کرده است
{
$fupload=$_POST["fupload"]; $fupload = trim($fupload);
اگر ($fupload =="" یا خالی ($fupload)) (
unset($fupload);// اگر متغیر $fupload خالی است، آن را حذف کنید
}
}
اگر (!isset($fupload) یا خالی ($fupload) یا $fupload =="")
{
//اگر متغیر وجود نداشته باشد (کاربر تصویری ارسال نکرده است)، یک تصویر از پیش آماده شده با کتیبه "بدون آواتار" به آن اختصاص دهید.
$avatar = "avatars/net-avatara.jpg"; //شما می توانید net-avatara.jpg را بکشید یا آن را از منبع بگیرید
}
دیگر
{
//در غیر این صورت - تصویر کاربر را بارگیری کنید
$path_to_90_directory = "avatars/";//پوشه ای که تصویر اولیه و کپی فشرده آن بارگذاری می شود

If(preg_match("/[.](JPG)|(jpg)|(gif)|(GIF)|(png)|(PNG)$/",$_FILES["fupload"]["نام"])) //بررسی فرمت تصویر منبع
{
$filename = $_FILES["fupload"]["name"];
$source = $_FILES["fupload"]["tmp_name"];
$target = $path_to_90_directory . $filename;
move_uploaded_file($source, $target);//آپلود اصلی در پوشه $path_to_90_directory
if(preg_match("/[.](GIF)|(gif)$/"، $filename)) (
$im = imagecreatefromgif($path_to_90_directory.$filename) ; //اگر نسخه اصلی با فرمت گیف بود، یک تصویر با همان فرمت ایجاد کنید. برای فشرده سازی بعدی لازم است
}
if(preg_match("/[.](PNG)|(png)$/"، $filename)) (
$im = imagecreatefrompng($path_to_90_directory.$filename) ;//اگر نسخه اصلی با فرمت png بود، تصویر را با همان فرمت ایجاد کنید. برای فشرده سازی بعدی لازم است
}

If(preg_match("/[.](JPG)|(jpg)|(jpeg)|(JPEG)$/، $filename)) (
$im = imagecreatefromjpeg($path_to_90_directory.$filename); //اگر نسخه اصلی با فرمت jpg بود، یک تصویر با همان فرمت ایجاد کنید. برای فشرده سازی بعدی لازم است
}
//ایجاد یک تصویر مربعی و فشرده سازی بعدی آن برگرفته از سایت www.codenet.ru
// یک مربع 90x90 ایجاد کنید
// dest - تصویر حاصل
// w - عرض تصویر
// نسبت - ضریب تناسب
$w = 90; // مربع 90x90. قابل عرضه در سایزهای دیگر
// تصویر اصلی را بر اساس ایجاد کنید
// فایل منبع و اندازه آن را تعیین کنید
$w_src = imagesx($im); //عرض را محاسبه کنید
$h_src = imagesy($im); // ارتفاع تصویر را محاسبه کنید
// یک تصویر مربع خالی ایجاد کنید
// truecolor مهم است!، در غیر این صورت نتیجه 8 بیتی خواهیم داشت
$dest = imagecreatetruecolor($w,$w);
// اگر عکس افقی است، مرکز مربع را در امتداد x ببرید
اگر ($w_src>$h_src)
imagecopyresampled($dest، $im، 0، 0،
دور((حداکثر($w_src،$h_src)-min($w_src،$h_src))/2)،
0، $w، $w، min($w_src،$h_src)، min($w_src،$h_src));
// بالای مربع را در امتداد y برش دهید،
// اگر عکس عمودی است (البته می توانید از وسط هم استفاده کنید)
اگر ($w_src

4. باید یک جدول را به همان پایگاه داده اضافه کنید. آدرس های IP را که هنگام ورود به سیستم دچار خطا شده اند ذخیره می کند. به این ترتیب می‌توانیم دسترسی به کسانی را که بیش از سه بار متوالی اشتباه کرده‌اند، برای حدود 15 دقیقه محدود کنیم.
بیایید به phpmyadmin برویم و یک جدول جدید با 3 فیلد ایجاد کنیم:


ip - آدرس IP.
date - تاریخ ورود ناموفق در 15 دقیقه گذشته برای کاربر با این آی پی. col - تعداد خطاهای 15 دقیقه گذشته برای کاربر با این IP.
عالی! تمام شد، حالا بیایید فایل تأیید ورود و رمز عبور را تغییر دهیم، زیرا اکنون رمز عبور ما رمزگذاری شده است. testreg.php را باز کنید و همه مواردی را که خارج از حذف فاصله از لاگین و رمز عبور است حذف کنید. سپس کد زیر را اضافه می کنیم:

//حذف فضاهای اضافی
$login = trim($login);
$password = trim($password);

// با یک جدید جایگزین کنید******************************************* *******
// به پایگاه داده متصل شوید
include("bd.php");// فایل bd.php باید در همان پوشه ای باشد که همه پوشه های دیگر وجود دارد، اگر اینطور نیست، فقط مسیر را تغییر دهید.
// مینی چک برای انتخاب رمز عبور
$ip=getenv("HTTP_X_FORWARDED_FOR");
if (خالی($ip) || $ip=="ناشناس") ($ip=getenv("REMOTE_ADDR"); )//extract ip
mysql_query ("DELETE FROM oshibka WHERE UNIX_TIMESTAMP() - UNIX_TIMESTAMP(تاریخ) > 900")؛//آدرس های IP کاربرانی را که هنگام ورود به سیستم اشتباه کرده اند پس از 15 دقیقه حذف کنید.
$result = mysql_query("SELECT col FROM oshibka WHERE ip="$ip"",$db)؛ // بازیابی از پایگاه داده تعداد تلاش های ناموفق برای ورود به سیستم طی 15 بار گذشته برای یک کاربر با IP داده شده
$myrow = mysql_fetch_array($result);
اگر ($myrow["col"] > 2) (
//اگر بیش از دو خطا، یعنی سه خطا وجود داشته باشد، پیامی صادر می کنیم.
exit("شما 3 بار نام کاربری یا رمز عبور خود را اشتباه وارد کردید. لطفا قبل از تلاش مجدد 15 دقیقه صبر کنید.");
}
$password = md5($password);//رمزگذاری رمز عبور
$password = strrev($password);// برای قابلیت اطمینان، معکوس را اضافه کنید
$password = $password."b3p6f";
//می توانید چند کاراکتر خود را به سلیقه خود اضافه کنید، مثلاً با وارد کردن "b3p6f". اگر این رمز عبور در همان سرور md5 هک شود، بدیهی است که هیچ چیز خوبی از آن حاصل نخواهد شد. اما من به شما توصیه می کنم شخصیت های دیگری را، شاید در ابتدای خط یا وسط قرار دهید.
//در این صورت لازم است طول فیلد رمز در پایگاه داده افزایش یابد. رمز عبور رمزگذاری شده ممکن است بسیار بزرگتر باشد.

$result = mysql_query("SELECT * FROM users WHERE login="$login" AND password="$password"",$db); //بازیابی از پایگاه داده تمام داده های مربوط به کاربر با ورود و رمز عبور وارد شده
$myrow = mysql_fetch_array($result);
if (خالی ($myrow["id"]))
{
//در صورتی که کاربری با لاگین و رمز عبور وارد شده وجود نداشته باشد
//ما یک رکورد ایجاد می کنیم که این ip نمی تواند وارد شود.
$select = mysql_query("SELECT ip FROM oshibka WHERE ip="$ip"");
$tmp = mysql_fetch_row ($select);
if ($ip == $tmp) (//بررسی کنید که آیا کاربر در جدول "oshibka" قرار دارد یا خیر
$result52 = mysql_query("SELECT col FROM oshibka WHERE ip="$ip"",$db);
$myrow52 = mysql_fetch_array($result52);
$col = $myrow52 + 1;//یک تلاش ناموفق دیگر برای ورود به سیستم اضافه کنید
mysql_query("خطای به روز رسانی SET col=$col,date=NOW() WHERE ip="$ip"");
}
دیگر(
mysql_query("INSERT INTO oshibka (ip,date,col) VALUES ("$ip",NOW(),"1")");
//اگر در 15 دقیقه گذشته خطایی وجود نداشت، یک ورودی جدید در جدول "oshibka" وارد کنید.
}

exit ("با عرض پوزش، نام کاربری یا رمز عبوری که وارد کردید نادرست است.");
}
دیگر(
nbsp; //اگر پسوردها مطابقت داشته باشند، یک جلسه برای کاربر راه اندازی می کنیم! می توانید به او تبریک بگویید، او وارد شد!
$_SESSION["password"]=$myrow["password"];
$_SESSION["login"]=$myrow["login"];
$_SESSION["id"]=$myrow["id"];//این داده اغلب استفاده می شود، بنابراین کاربر وارد شده آن را با خود حمل می کند.

//بعد، داده ها را در کوکی ها برای ورود بعدی ذخیره می کنیم.
//توجه!!! این کار را بنا به صلاحدید خود انجام دهید زیرا داده ها در کوکی ها بدون رمزگذاری ذخیره می شوند
اگر ($_POST["ذخیره"] == 1) (
//اگر کاربر بخواهد داده هایش برای ورود بعدی ذخیره شود، آن را در کوکی های مرورگرش ذخیره می کنیم.
setcookie("login", $_POST["login"], time()+9999999);
setcookie("password", $_POST["password"], time()+9999999);
}}
echo ""؛ // کاربر را به صفحه اصلی هدایت می کنیم، جایی که او را از ورود موفقیت آمیز مطلع می کنیم
?>

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




صفحه نخست


صفحه نخست



6. لازم است امکان خروج کاربران لاگین شده فراهم شود. قبلاً پیوندی برای خروج در صفحه اصلی وجود داشت. اما این فایل هنوز وجود ندارد. پس بیایید یک فایل exit.php جدید با کد ایجاد کنیم:

باشه الان همه چی تموم شد! برای سلامتی خود از آن لذت ببرید! موفق باشید!

Reg.ru: دامنه و هاست

بزرگترین ثبت کننده و ارائه دهنده میزبانی در روسیه.

بیش از 2 میلیون نام دامنه در حال خدمت است.

تبلیغات، ایمیل دامنه، راه حل های تجاری.

بیش از 700 هزار مشتری در سراسر جهان قبلاً انتخاب خود را انجام داده اند.

* ماوس را روی پیمایش مکث کنید.

عقب به جلو

ایجاد یک سیستم ساده ثبت نام کاربر در PHP و MySQL

ایجاد یک سیستم ثبت نام کار بسیار زیادی است. شما باید کدی را بنویسید که آدرس های ایمیل را تأیید می کند، یک ایمیل تأیید کننده ثبت نام ارسال می کند، و همچنین سایر فیلدهای فرم را تأیید می کند و موارد دیگر.

و حتی پس از نوشتن همه اینها، کاربران تمایلی به ثبت نام ندارند، زیرا ... این مستلزم تلاشی از جانب آنها است.

در این آموزش، ما یک سیستم ثبت نام بسیار ساده ایجاد می کنیم که به هیچ وجه نیازی به رمز عبور یا ذخیره آن ندارد! نتیجه تغییر و افزودن به یک سایت PHP موجود آسان خواهد بود. می خواهید بدانید چگونه کار می کند؟ در زیر می خوانید.



در اینجا نحوه عملکرد سیستم فوق العاده ساده ما آمده است:

ما فرم مجوز و ثبت نام را ترکیب خواهیم کرد. این فرم دارای یک فیلد برای وارد کردن آدرس ایمیل شما و یک دکمه ثبت نام است.
- هنگام پر کردن فیلد با آدرس ایمیل، با کلیک بر روی دکمه ثبت نام، یک رکورد در مورد یک کاربر جدید ایجاد می شود، اما به شرطی که آدرس ایمیل وارد شده در پایگاه داده پیدا نشود.

پس از این، یک مجموعه تصادفی منحصر به فرد از کاراکترها (توکن) ایجاد می شود که به ایمیل مشخص شده توسط کاربر در قالب یک لینک که به مدت 10 دقیقه مرتبط خواهد بود ارسال می شود.
- لینک کاربر را به وب سایت ما می برد. سیستم وجود یک رمز را تعیین می کند و به کاربر اجازه می دهد.

مزایای این روش:

نیازی به ذخیره رمزهای عبور یا تأیید فیلدها نیست.
- نیازی به بازیابی رمز عبور، سوالات امنیتی و غیره نیست.
- از لحظه ای که کاربر ثبت نام / وارد می شود، همیشه می توانید مطمئن باشید که این کاربر در منطقه دسترسی شما خواهد بود (آدرس ایمیل درست است).
- فرآیند ثبت نام بسیار ساده

ایرادات:

امنیت حساب کاربری اگر شخصی به ایمیل کاربر دسترسی داشته باشد، می تواند وارد شود.
- ایمیل امن نیست و قابل رهگیری است. به خاطر داشته باشید که این سوال در مواردی که رمز عبور فراموش شده است و نیاز به بازیابی دارد یا در هر سیستم مجوزی که از HTTPS برای انتقال داده استفاده نمی‌کند (ورود به سیستم/رمز عبور) مرتبط است.
- در حالی که سرور ایمیل خود را به درستی پیکربندی می کنید، این احتمال وجود دارد که پیام های دارای پیوندهای مجوز به هرزنامه ختم شوند.

با مقایسه مزایا و معایب سیستم ما، می توان گفت که این سیستم قابلیت استفاده بالایی دارد (حداکثر راحتی برای کاربر نهایی) و در عین حال از شاخص امنیتی پایینی برخوردار است.

بنابراین پیشنهاد می شود از آن برای ثبت نام در انجمن ها و خدماتی که با اطلاعات مهم کار نمی کنند استفاده کنید.

نحوه استفاده از این سیستم

در صورتی که فقط نیاز به استفاده از یک سیستم برای مجوز دادن به کاربران در سایت خود دارید، و نمی خواهید این درس را تکه تکه کنید، این کاری است که باید انجام دهید:

شما باید منابع ضمیمه درس را دانلود کنید
- فایل tables.sql را در بایگانی پیدا کنید با استفاده از گزینه import در phpMyAdmin آن را به پایگاه داده خود وارد کنید. راه جایگزین: این فایل را از طریق یک ویرایشگر متن باز کنید، کوئری SQL را کپی کرده و اجرا کنید.
- include/main.php را باز کرده و تنظیمات ارتباط با دیتابیس خود را پر کنید ( یوزر و پسورد اتصال با دیتابیس و همچنین هاست و نام دیتابیس را مشخص کنید). در همین فایل باید ایمیل را نیز مشخص کنید که به عنوان آدرس اصلی پیام های ارسالی سیستم استفاده می شود. برخی از میزبان‌ها ایمیل‌های خروجی را مسدود می‌کنند مگر اینکه فرم حاوی یک آدرس ایمیل واقعی باشد که از کنترل پنل میزبان ایجاد شده است، بنابراین یک آدرس واقعی ارائه دهید.
- تمام فایل‌ها و دارایی‌های index.php، protected.php و شامل پوشه‌ها از طریق FTP در هاست خود آپلود کنید.
- کد زیر را به هر صفحه PHP که می خواهید فرم ورود به سیستم را نمایش دهید اضافه کنید.

Require_once "includes/main.php"; $user = کاربر جدید(); if(!$user->loggedIn())( redirect("index.php"); )
- آماده!

برای کسانی که علاقه مند به نحوه عملکرد آن هستند، در زیر بخوانید!

اولین قدم نوشتن کد HTM برای فرم مجوز است. این کد در فایل index.php قرار دارد. این فایل همچنین حاوی کد PHP است که داده‌های فرم و سایر عملکردهای مفید سیستم ورود را مدیریت می‌کند. می توانید در بخش زیر که به بررسی کد PHP اختصاص دارد، در مورد این موضوع بیشتر بیاموزید.

index.php

آموزش: سیستم ثبت نام فوق العاده ساده با PHP و MySQL ورود یا ثبت نام

آدرس ایمیل خود را در بالا وارد کنید و ما ارسال خواهیم کرد
شما یک لینک ورود

ورود/ثبت نام

در قسمت head (بین تگ‌ها و) استایل‌های اصلی را قرار دادم (در این آموزش به آن‌ها پرداخته نمی‌شود، بنابراین می‌توانید خودتان به آنها نگاه کنید. Folder assets/css/style.css). قبل از تگ بسته شدن، کتابخانه jQuery و فایل script.js را قرار دادم که در زیر می نویسیم و تجزیه و تحلیل می کنیم.


جاوا اسکریپت

jQuery وضعیت دکمه "ثبت/ورود" را با استفاده از عملکرد ردیابی می کند e.preventDefault()و درخواست های AJAX را ارسال می کند. بسته به پاسخ سرور، پیامی را نمایش می دهد و اقدامات بعدی را تعیین می کند.

assets/js/script.js

$(function())( var form = $("#login-register"); form.on("submit"، function(e)( if(form.is(".loading, .loggedIn"))( بازگشت false ; ) var email = form.find("input").val()، messageHolder = form.find("span")؛ e.preventDefault(); $.post(this.action, (ایمیل: ایمیل)، تابع (m)( if(m.error)( form.addClass("خطا")؛ messageHolder.text(m.message); ) else(form.removeClass("خطا").addClass("loggedIn")؛ messageHolder . text(m.message); ) )); )); $(document).ajaxStart(function())( form.addClass("بارگیری"); )); $(document).ajaxComplete(function()) ( form. removeClass("loading"); )); ));

برای نمایش وضعیت فعلی درخواست AJAX به فرم اضافه شد (این به لطف روش ها امکان پذیر شد ajaxStart()) و ajaxComplete()، که در انتهای فایل می توانید پیدا کنید).

این کلاس یک فایل GIF متحرک در حال چرخش را نمایش می دهد (مثل اینکه به ما اشاره می کند که درخواست در حال پردازش است)، و همچنین به عنوان یک پرچم برای جلوگیری از ارسال مجدد فرم عمل می کند (زمانی که دکمه ثبت نام قبلاً یک بار کلیک شده باشد). کلاس LoggedIn. پرچم دیگری است - زمانی که ایمیل ارسال شد تنظیم می شود. این پرچم بلافاصله هر گونه اقدام بعدی را با فرم مسدود می کند.

طرح واره پایگاه داده

سیستم ثبت فوق العاده ساده ما از 2 جدول MySQL استفاده می کند (کد SQL در فایل tables.sql است). اولی اطلاعات مربوط به حساب های کاربری را ذخیره می کند. دومی اطلاعات مربوط به تعداد تلاش برای ورود را ذخیره می کند.


طرح جدول کاربر.

همانطور که در نمودار مشاهده می شود، سیستم از رمز عبور استفاده نمی کند. روی آن می‌توانید ستون توکن را با نشانه‌هایی در مجاورت ستون token_validity ببینید. توکن به محض اتصال کاربر به سیستم و تنظیم ایمیل خود برای ارسال پیام نصب می‌شود (اطلاعات بیشتر در این مورد در بلوک بعدی). ستون token_validity زمان را 10 دقیقه بعد تنظیم می کند و پس از آن رمز دیگر معتبر نیست.


طرح جدولی که تعداد تلاش‌های مجوز را شمارش می‌کند.

در هر دو جدول، آدرس IP به شکل پردازش شده با استفاده از تابع ip2long در یک فیلد از نوع عدد صحیح ذخیره می شود.

حالا می توانیم مقداری کد PHP بنویسیم. عملکرد اصلی سیستم به کلاس User.class.php اختصاص داده شده است که در زیر مشاهده می کنید.

این کلاس به طور فعال از idorm (docs) استفاده می کند، این کتابخانه ها حداقل ابزار لازم برای کار با پایگاه های داده هستند. دسترسی به پایگاه داده، تولید توکن و اعتبار سنجی توکن را کنترل می کند. این یک رابط ساده ارائه می دهد که اتصال یک سیستم ثبت نام را به سایت شما در صورت استفاده از PHP آسان می کند.

User.class.php

Class User(// Private ORM case private $orm; /** * یافتن کاربر بر اساس نشانه. فقط نشانه های معتبر برای بررسی پذیرفته می شوند. نشانه فقط به مدت 10 دقیقه از لحظه ایجاد آن ایجاد می شود * @param string $token این همان رمزی است که ما به دنبال آن هستیم * @return User مقدار تابع کاربر */ تابع استاتیک عمومی findByToken($token)( // رمز را در پایگاه داده پیدا کنید و مطمئن شوید که مهر زمانی صحیح تنظیم شده است $result = ORM::for_table("reg_users") ->where ("token"، $token) ->where_raw("token_validity > NOW()") ->find_one(); if(!$result)( return false; ) بازگشت کاربر جدید($result); ) /** * مجوز یا ثبت یک کاربر * @param string $email آدرس ایمیل کاربر * @return کاربر */ عملکرد ثابت عمومی loginOrRegister($email)( // اگر چنین کاربری قبلاً وجود دارد، مقدار تابع User را از آدرس ایمیل مشخص شده ذخیره شده در پایگاه داده برگردانید if(User::exists($email))( return new User($email); ) // در غیر این صورت یک کاربر جدید در پایگاه داده ایجاد کنید و مقدار تابع User::create را از ایمیل مشخص شده بازگردانید User::create($email ); ) /** * یک کاربر جدید ایجاد کنید و در پایگاه داده ذخیره کنید * @param string $email. آدرس ایمیل کاربر * @return کاربر */ تابع ثابت خصوصی create($email)( // یک کاربر جدید بنویسید و نتیجه تابع کاربر را از این مقادیر برگردانید $result = ORM::for_table("reg_users")- >create(); $result->email = $email; $result->save(); return new User($result); ) /** * بررسی کنید که آیا چنین کاربری در پایگاه داده وجود دارد یا خیر و مقدار Boolean را برگردانید متغیر * @param string $email. آدرس ایمیل کاربر * @return boolean */ تابع ثابت عمومی وجود دارد($email)( // آیا کاربر در پایگاه داده وجود دارد؟ $result = ORM::for_table("reg_users") ->where("email", $email ) ->count(); return $result == 1; ) /** * یک شی کاربر جدید ایجاد کنید * @param instance $param ORM , id, email or 0 * @return User */ public function __construct($param = null) ( if($param instanceof ORM)( // بررسی ORM $this->orm = $param; ) other if(is_string($param))( // چک ایمیل پاس شد $this->orm = ORM:: for_table ("reg_users") ->where("email", $param) ->find_one(); ) else($id = 0; if(is_numeric($param))( // مقدار متغیر $param است به شناسه کاربر ارسال شد $id = $param; ) else if(isset($_SESSION["loginid"]))( // در غیر این صورت، به جلسه $id = $_SESSION["loginid"]; ) $this->orm مراجعه کنید = ORM::for_table( "reg_users") ->where("id", $id) ->find_one(); ) ) /** * یک نشانه مجوز جدید SHA1 ایجاد کنید، آن را در پایگاه داده می نویسید و مقدار آن را برمی گرداند * @return string */ public function generateToken( )( // یک توکن برای یک کاربر مجاز تولید کنید و آن را در پایگاه داده ذخیره کنید $token = sha1($this->email.time().rand(0, 1000000)); // توکن را در پایگاه داده ذخیره کنید // و آن را فقط برای 10 دقیقه آینده به عنوان معتبر علامت گذاری کنید $this->orm->set("token", $token); $this->orm->set_expr("token_validity", "ADDTIME(NOW(),"0:10")"); $this->orm->save(); بازگشت $token; ) /** * مجوز دادن به کاربر * @return void */ عملکرد عمومی login())( // علامت گذاری کاربر به عنوان وارد شده در $_SESSION["loginid"] = $this->orm->id؛ // به روز رسانی مقدار فیلد پایگاه داده last_login $this->orm->set_expr("last_login", "NOW()"); $this->orm->save(); ) /** * جلسه را نابود کنید و کاربر را از سیستم خارج کنید * @return void */ عملکرد عمومی خروج ()($_SESSION = آرایه(); unset($_SESSION); ) /** * بررسی کنید آیا کاربر وارد شده است * @return boolean */ عملکرد عمومی logedIn())( return isset($this->orm->id) && $_SESSION["loginid"] == $this->orm->id; ) /** * بررسی می کند که آیا کاربر مدیر است * @return boolean */ public تابع isAdmin())( return $this->rank() = = "administrator"; ) /** * نوع کاربر را پیدا کنید، می تواند مدیر یا معمولی باشد * @return string */ public function rank())( اگر ($this->orm->rank == 1)( return "administrator" "; ) return "regular"; ) /** * روشی که به شما امکان می دهد اطلاعات خصوصی کاربر را به عنوان * ویژگی های شی User * @ دریافت کنید. param string $key نام خاصیتی که دسترسی پیدا می کند * @return mixed */ public function __get($key)( if(isset($this->orm->$key))( return $this->orm-> کلید $; ) null را برگرداند. ))

توکن ها با استفاده از الگوریتم SHA1 تولید و در پایگاه داده ذخیره می شوند. من از توابع زمان بندی MySQL برای تعیین یک محدودیت زمانی 10 دقیقه ای برای اعتبار یک توکن استفاده می کنم.

هنگامی که یک توکن اعتبارسنجی می شود، مستقیماً به کنترل کننده می گوییم که فقط نشانه هایی را در نظر می گیریم که هنوز منقضی نشده اند و در ستون token_validity ذخیره شده اند.

لطفا توجه داشته باشید که من از روش جادویی استفاده می کنم __گرفتنکتابخانه docs در انتهای فایل برای جلوگیری از دسترسی به خصوصیات شی User.

به لطف این، دسترسی به اطلاعات ذخیره شده در پایگاه داده به لطف ویژگی های $user->email، $user->token و غیره امکان پذیر می شود. در قسمت کد بعدی، نحوه استفاده از این کلاس ها را به عنوان مثال بررسی خواهیم کرد. .


صفحه محافظت شده

فایل دیگری که قابلیت های مفید و ضروری را ذخیره می کند فایل functions.php است. چندین توابع به اصطلاح کمک کننده - دستیار وجود دارد که به شما امکان می دهد کدهای تمیزتر و خواناتر را در فایل های دیگر ایجاد کنید.

functions.php

تابع send_email($from، $to، $subject، $message)( // راهنمای ارسال ایمیل $headers = "MIME-Version: 1.0". "\r\n"; $headers .= "نوع محتوا: متن /plain; charset=utf-8." ); ) تابع get_page_url())( // URL فایل PHP را تعیین کنید $url = "http".(empty($_SERVER["HTTPS"])?"":"s")."://" .$_SERVER ["SERVER_NAME"]; if(isset($_SERVER["REQUEST_URI"]) && $_SERVER["REQUEST_URI"] != "")($url.= $_SERVER["REQUEST_URI"]; ) other( $url. = $_SERVER["PATH_INFO"]; ) بازگشت $url; ) تابع rate_limit($ip, $limit_hour = 20, $limit_10_min = 10)( // تعداد تلاش برای ورود به سیستم در یک ساعت گذشته به این آدرس IP $ count_hour = ORM: :for_table("reg_login_attempt") ->where("ip", sprintf("%u", ip2long($ip))) ->where_raw("ts > SUBTIME(NOW(),"1:00 ")") ->count(); // تعداد تلاش برای ورود به سیستم در 10 دقیقه گذشته در این آدرس IP $count_10_min = ORM::for_table("reg_login_attempt") ->where("ip", sprintf("%u "، ip2long($ ip))) ->where_raw("ts > SUBTIME(NOW(),"0:10")") ->count(); if($count_hour > $limit_hour || $count_10_min > $limit_10_min)( throw new Exception("تعداد زیادی برای ورود به سیستم!"); ) ) function rate_limit_tick($ip, $email)( // ایجاد یک رکورد جدید در جدول که تعداد تلاش‌های ورود به سیستم را محاسبه می‌کند $login_attempt = ORM::for_table("reg_login_attempt")->create(); $login_attempt->email = $email؛ $login_attempt->ip = sprintf("%u", ip2long($ip ))؛ $login_attempt->save(); ) تابع redirect($url)( header("مکان: $url")؛ exit; )

کارکرد حد نرخو rate_limit_tickنظارت بر تعداد تلاش های مجوز در طول مدت زمان سپری شده از اولین تلاش. تلاش برای ورود در پایگاه داده در ستون reg_login_attempt ثبت می شود. این توابع زمانی فراخوانی می شوند که داده های فرم پردازش و ارسال شوند همانطور که در قطعه کد زیر مشاهده می کنید.

کد زیر از فایل index.php گرفته شده است و ارسال فرم را مدیریت می کند. این یک پاسخ JSON را برمی گرداند، که به نوبه خود توسط jQuery در فایل assets/js/script.js که قبلا به آن نگاه کردیم، پردازش می شود.

index.php

Try( if(!empty($_POST) && isset($_SERVER["HTTP_X_REQUESTED_WITH"]))(// خروجی سرصفحه JSON ("Content-type: application/json"); // آیا این آدرس ایمیل معتبر است اگر (!isset($_POST["ایمیل"]) || !filter_var($_POST["ایمیل"]، FILTER_VALIDATE_EMAIL))( استثناء جدید ("لطفا یک ایمیل معتبر وارد کنید") را وارد کنید.) // بررسی کنید. کاربر مجاز به ورود به سیستم است، آیا از تعداد اتصالات مجاز فراتر رفته است؟ (فایل functions.php برای اطلاعات بیشتر) rate_limit($_SERVER["REMOTE_ADDR"])؛ // ورود این تلاش برای ورود به سیستم rate_limit_tick($_SERVER["REMOTE_ADDR"] , $ _POST["email"])؛ // ارسال یک ایمیل به کاربر $message = ""؛ $email = $_POST["email"]؛ $subject = "پیوند ورود شما"؛ if(!User:: وجود دارد($email) )( $subject = "از ثبت نام شما متشکرم!"; $message = "از اینکه در سایت ما ثبت نام کردید متشکریم!\n\n"؛ ) // تلاش برای مجوز دادن یا ثبت نام کاربر $user = کاربر ::loginOrRegister($_POST[ "email"]);$message.= "شما می توانید از این URL وارد شوید:\n"; $message.= get_page_url()."?tkn=".$user->generateToken()."\n\n"; $message.= "پیوند به طور خودکار پس از 10 دقیقه منقضی می شود."; $result = send_email($fromEmail، $_POST["email"]، $subject، $message); if(!$result)( throw new Exception("خطایی در ارسال ایمیل شما وجود داشت. لطفا دوباره امتحان کنید."); ) die(json_encode(array("message" => "متشکرم! ما یک پیوند ارسال کردیم. به صندوق ورودی خود. پوشه اسپم خود را نیز بررسی کنید."))); ) ) catch(Exception $e)( die(json_encode(array("error"=>1, "message" => $e->getMessage() )))))

پس از ورود/ثبت نام موفقیت آمیز، کد بالا یک لینک ورود برای کاربر ارسال می کند. رمز در دسترس می شود زیرا به عنوان یک متغیر در لینک تولید شده توسط متد ارسال می شود $_GETبا نشانگر tkn

index.php

If(isset($_GET["tkn"]))( // آیا این نشانه برای مجوز معتبر است؟ $user = کاربر::findByToken($_GET["tkn"]); if($user)( // بله، است. تغییر مسیر به یک صفحه محافظت شده $user->login(); redirect("protected.php"); ) // خیر، نشانه معتبر نیست. به صفحه ای با فرم مجوز/ثبت نام redirect("index. php ");)

$user->login()

متغیرهای لازم را برای جلسه ایجاد می کند، به طوری که کاربر با مشاهده صفحات بعدی سایت، همیشه مجاز خواهد بود.

پردازش تابع برای خروج از سیستم به روشی مشابه مرتب شده است.

index.php

If(isset($_GET["logout"]))($user = new user(); if($user->loggedIn())($user->logout(); ) redirect("index.php") ;)

در پایان کد، من دوباره یک تغییر مسیر به index.php تنظیم کردم، بنابراین پارامتر ?logout=1ارسال از طریق URL لازم نیست.

فایل index.php ما به موارد اضافی نیاز دارد. حفاظت - ما نمی خواهیم افرادی که وارد سیستم شده اند دوباره فرم ثبت نام را ببینند. برای این منظور از روش استفاده می کنیم $user->loggedIn().

index.php

$user = کاربر جدید(); if($user->loggedIn())( redirect("protected.php"); )

در نهایت، در اینجا یک قطعه کد وجود دارد که به شما امکان می دهد از صفحات سایت خود محافظت کنید و فقط پس از مجوز در دسترس قرار دهید.

محافظت شده.php

// برای محافظت از هر صفحه در سایت خود، یک فایل main.php // قرار دهید و یک شی User جدید ایجاد کنید. به همین راحتی! require_once "includes/main.php"; $user = کاربر جدید(); if(!$user->loggedIn())( redirect("index.php"); )

پس از این بررسی، می توانید مطمئن شوید که کاربر با موفقیت مجاز شده است. همچنین می توانید با استفاده از ویژگی های شیء به اطلاعات ذخیره شده در پایگاه داده دسترسی داشته باشید $user. برای نمایش ایمیل و وضعیت کاربر از این کد استفاده کنید:

Echo "ایمیل شما: ".$user->email; echo "رتبه شما: ".$user->rank();

روش رتبه ()در اینجا استفاده می شود زیرا پایگاه داده معمولاً اعداد را ذخیره می کند (0 برای یک کاربر معمولی، 1 برای یک مدیر) و ما باید این داده ها را به وضعیت هایی تبدیل کنیم که به آنها تعلق دارند، که این روش به ما کمک می کند.

برای اینکه یک کاربر معمولی را به عنوان مدیر تبدیل کنید، کافی است ورودی کاربر را از طریق phpMyAdmin (یا هر برنامه دیگری که به شما امکان مدیریت پایگاه داده ها را می دهد) ویرایش کنید. وضعیت مدیر هیچ امتیازی نمی دهد؛ در این مثال، صفحه نشان می دهد که شما یک مدیر هستید - و تمام.

اما اینکه با این کار چه باید کرد به اختیار شما سپرده می شود؛ می توانید خودتان کدی بنویسید و بنویسید که امتیازات و قابلیت های خاصی را برای مدیران تعیین می کند.

انجام شد!

کار ما با این شکل فوق العاده شبه ساده تمام شد! شما می توانید از آن در سایت های PHP خود استفاده کنید، بسیار ساده است. شما همچنین می توانید آن را برای خود تغییر دهید و آن را آنطور که می خواهید بسازید.

این مطالب توسط Denis Malyshok به طور خاص برای وب سایت تهیه شده است

P.S. آیا می خواهید در تسلط بر PHP و OOP بیشتر حرکت کنید؟ به درس های برتر در جنبه های مختلف ساخت وب سایت، از جمله برنامه نویسی در PHP، و همچنین یک دوره رایگان برای ایجاد سیستم CMS خود در PHP از ابتدا با استفاده از OOP توجه کنید:

آیا مطالب را دوست داشتید و می خواهید از من تشکر کنید؟
فقط با دوستان و همکاران خود به اشتراک بگذارید!


تصمیم گرفتم این یادداشت را بنویسم زیرا از 100500 بار پاسخ دادن به یک چیز در پرسش و پاسخ خسته شده ام.

بسیاری از برنامه نویسان وب مبتدی دیر یا زود با وظیفه معرفی پیوندهای قابل خواندن توسط انسان (HUR) در وب سایت خود مواجه می شوند. قبل از پیاده سازی CNC، همه لینک ها شبیه /myscript.php یا حتی /myfolder/myfolder2/myscript3.php بودند که به خاطر سپردن سخت است و حتی بدتر از آن برای SEO. پس از پیاده سازی CNC، لینک ها به شکل /statiya-o-php یا حتی به صورت سیریلیک /article-o-php هستند.

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

تکامل یک برنامه نویس PHP تازه کار را می توان در مراحل زیر بیان کرد:

  • قرار دادن کدهای PHP ساده در فایل های جداگانه و دسترسی به این فایل ها از طریق پیوندهایی مانند /myfolder/myscript.php
  • درک این موضوع که همه اسکریپت ها دارای بخش مشترک قابل توجهی هستند (به عنوان مثال، ایجاد یک اتصال به پایگاه داده، خواندن پیکربندی، شروع یک جلسه، و غیره) و در نتیجه، ایجاد یک نقطه شروع مشترک، یک اسکریپت که همه درخواست ها را می پذیرد و سپس انتخاب می کند که کدام یک اسکریپت داخلی متصل شود. معمولاً این اسکریپت index.php نام دارد و در ریشه قرار دارد، در نتیجه همه درخواست‌ها (معروف به URL) به این شکل هستند: /index.php?com=myaction&com2=mysubaction
  • نیاز به پیاده سازی روتر و انتقال به پیوندهای قابل خواندن توسط انسان.
  • متذکر می شوم که بین نقاط 2 و 3، اکثر برنامه نویسان یک اشتباه آشکار مرتکب می شوند. اگر این را ارزش حدود 95 درصد برنامه نویسان بدانم، اشتباه نمی کنم. حتی اکثر فریمورک های شناخته شده حاوی این خطا هستند. و شامل موارد زیر است.

    به جای اجرای یک روش اساسی جدید برای پردازش پیوندها، مفهوم "وصله ها و تغییر مسیرها" بر اساس .htaccess به اشتباه ساخته شده است که شامل ایجاد بسیاری از قوانین تغییر مسیر با استفاده از mod_rewrite است. این خطوط URL را با برخی از عبارت های معمولی مقایسه می کنند و در صورت وجود مطابقت، مقادیر استخراج شده از URL را به متغیرهای GET فشار می دهند و متعاقباً همان index.php را فراخوانی می کنند.

    #روش CNC نادرست RewriteEngine On RewriteRule ^\/users\/(.+)$ index.php?module=users&id=$1 #....قوانین مشابه خیلی بیشتر...

    این مفهوم دارای معایب بسیاری است. یکی از آنها دشواری ایجاد قوانین است، درصد زیادی از خطاهای انسانی هنگام اضافه کردن قوانینی که تشخیص آنها دشوار است، اما منجر به خطای 500 سرور می شود.

    اشکال دیگر این است که اغلب بر اساس پیکربندی سرور ویرایش می شود که به خودی خود مزخرف است. و اگر در Apache پیکربندی را بتوان با استفاده از htaccess "وصله کرد"، در nginx محبوب چنین گزینه ای وجود ندارد، همه چیز در یک فایل پیکربندی مشترک در منطقه سیستم قرار دارد.

    و یک اشکال دیگر، احتمالا مهمترین، این است که با این رویکرد، پیکربندی پویا روتر، یعنی "در حال پرواز"، تغییر الگوریتمی و گسترش قوانین انتخاب اسکریپت مورد نظر غیرممکن است.

    روش ارائه شده در زیر تمام این معایب را از بین می برد. در حال حاضر در تعداد زیادی از چارچوب های مدرن استفاده می شود.

    نکته اصلی این است که درخواست اولیه همیشه در متغیر $_SERVER['REQUEST_URI'] ذخیره می‌شود، یعنی می‌توان آن را در داخل index.php خواند و به‌عنوان یک رشته با استفاده از PHP با تمام مدیریت خطاها، تغییر مسیرهای پویا و غیره تجزیه و تحلیل کرد.

    در این مورد، شما می توانید تنها یک قانون ثابت در فایل پیکربندی ایجاد کنید، که تمام درخواست ها را به فایل ها یا پوشه های موجود به index.php هدایت می کند.

    RewriteEngine در RewriteCond %(REQUEST_FILENAME) !-f #اگر فایل وجود ندارد RewriteCond %(REQUEST_FILENAME) !-d #و اگر پوشه وجود نداشت RewriteRule ^.*$ index.php

    علاوه بر این، این قانون را می توان هم در htaccess. و هم در فایل پیکربندی اصلی آپاچی قرار داد.

    برای nginx، قانون مربوطه به این صورت خواهد بود:

    مکان / (اگر (!-e $request_filename) (بازنویسی ^/(.*)$ /index.php آخرین؛ ))

    ساده است.

    حالا بیایید به یک کد PHP در index.php نگاه کنیم، که پیوندها را تجزیه و تحلیل می کند و تصمیم می گیرد کدام اسکریپت اجرا شود.

    /part1/part2/part3

    اولین چیزی که به ذهن می رسد این است که آن را با استفاده از explode(‘/’، $uri) تجزیه کنید و یک روتر پیچیده بر اساس سوئیچ/موردی بسازید که هر قطعه از درخواست را تجزیه و تحلیل کند. آن را انجام نده! این پیچیده است و در نهایت باعث می شود که کد به طرز وحشتناکی نامفهوم و غیر قابل تنظیم به نظر برسد!

    من یک راه مختصرتر را پیشنهاد می کنم. بهتر است آن را با کلمات توصیف نکنید، بلکه بلافاصله کد را نشان دهید.



    دوست داشت؟ مثل ما در فیس بوک