اعتبارسنجی همزمان فرم با ای جکس (Ajax) و PHP

استفاده از ای جکس (Ajax) به جهت قابلیت منحصر به فرد آن یعنی عدم نیاز به بارگذاری مجدد صفحه وب و رفرش کامل می تواند در بسیاری از مواقع و بنا بر نیاز برنامه نویسان کاربردی و رهگشا باشد، یکی از این موارد اعتبارسنجی فرم های وب پیش از ارسال و حین تکمیل است، همان طور که می دانیم اعتبارسنجی به فرآیند بررسی معتبر بودن داده های ارائه شده توسط کاربر یا تطبیق آنها با الگوهای مورد انتظار گفته می شود که در مجموع در دو حالت سمت کاربر (در مرورگر و با زبان هایی مانند جاوا اسکریپت) یا سمت سرور (در سرور و با زبان های سمت سرور مانند PHP، ASP.NET، Python و...) انجام می شود، اما استفاده از Ajax قابلیت دیگری نیز در اختیارمان قرار می دهد و آن بررسی همزمان فرم های وب در سمت سرور بدون رفرش یا نیاز به بارگذاری مجدد صفحات در سمت کاربر است، به این صورت داده ها حین تکمیل فرم به سرور ارسال، اعتبارسنجی شده و در نهایت پاسخ در سمت کاربر دریافت و نمایش داده شده یا پردازش می شوند.
کد ای جکس (Ajax) برای ارسال اطلاعات فرم
برای ارسال اطلاعات فرم قبل از هر چیز باید موتور پایه مبتنی بر ای جکس (Ajax) را برنامه نویسی کنیم، همان طور که در آموزش های مقدماتی دیدیم درخواست های ای جکس مبتنی بر آبجکت XMLHttpRequest (برای تمام مرورگرها به جزء نسخه های قدیمی اینترنت اکسپلورر) یا ActiveXObject (برای اینترنت اکسپلورر نسخه 7 و ماقبل) هستند، بر همین مبنا در نمونه کد زیر ابتدا با دستورات جاوا اسکریپت اطلاعات فیلدهای فرم دریافت و به سرور ارسال می شوند، پس از ارسال درخواست و تا زمان بازگشت پاسخ از سرور پیام یا تصویری مبنی بر درحال پردازش بودن درخواست نمایش داده و در نهایت پاسخ سرور را تجزیه تحلیل یا در بلاک div خروجی می دهیم:
<script>
function ajaxRequest(input_name, input_value, div_id){
var form_value = input_name + "=" + input_value;
var loading_message = '<img src="loading.gif" alt="loading" height="16" width="16"> لطفا کمی صبر کنید...';
var xmlhttp;
if(window.XMLHttpRequest){
//IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
//IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState < 4){
document.getElementById(div_id).innerHTML = loading_message;
} else if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
document.getElementById(div_id).innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("POST","ajax-validate.php", true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(form_value);
}
</script>
توضیح:- تابع اصلی کد ajaxRequest (نام دلخواه) است و از سه آرگیومنت استفاده می کند که به ترتیب شامل نام فیلد مورد نظر، مقادیر و آی دی فیلد می شوند، این آرگیومنت ها در قسمت های مختلف تابع استفاده شده اند.
- در متغیر form_value پارامتر و مقادیر را برای ارسال از طریق متد xmlhttp.send آماده می کنیم، به طور مثال اگر input_name برابر usertext باشد و input_value برابر 1، مقادیر متغیر form_value به صورت usertext=1 خواهد بود، به این صورت در سمت سرور می توانیم اطلاعات را با متد POST دریافت کنیم، به طور مثال:
<?php
$usertext = $_POST['usertext'];
?>
- متغیر loading_message برای نمایش تصویر و پیام "در حال پردازش ..." یا "لطفا کمی صبر کنید..." در حالتی که xmlhttp.readyState < 4 است استفاده می شود.- با توجه به تنظیمات قسمت xmlhttp.open اطلاعات فیلدهای فرم با متد POST به فایل ajax-validate.php ارسال می شوند.
- در نهایت نیز پاسخ سرور با متد responseText دریافت و با innerHTML در بلاک div هدف (که آی دی آن را با آرگیومنت div_id دریافت کرده ایم) خروجی داده می شود.
نحوه استفاده و فراخوانی تابع ای جکس
برای اینکه موتور ای جکس ما به کار بیفتد لازم است که با استفاده از رویدادهای جاوا اسکریپتی نظیر onkeyup یا onchange تابع را فراخوانی کنیم، در نمونه کدهای زیر از رویداد onchange بدین منظور استفاده کرده ایم:
<form action="ajax-validate.php" method="post">
<label for="usertext">اعتبار سنجی عدد بودن مقادیر:</label><br>
<input type="text" name="usertext" id="usertext" dir="ltr" onchange="ajaxRequest('usertext', this.value, 'showresult-1');">
<div class="inline" id="showresult-1"></div>
<br><br>
<label for="usermail">اعتبار سنجی معتبر بودن ایمیل:</label><br>
<input type="text" name="usermail" id="usermail" dir="ltr" onchange="ajaxRequest('usermail', this.value, 'showresult-2');">
<div class="inline" id="showresult-2"></div>
<br><br>
<label for="usersite">اعتبار سنجی معتبر بودن آدرس سایت:</label><br>
<input type="text" name="usersite" id="usersite" dir="ltr" onchange="ajaxRequest('usersite', this.value, 'showresult-3');">
<div class="inline" id="showresult-3"></div>
</form>
توضیح:- همان طور که گفتیم برای هر فیلد تابع ajaxRequest را با سه آرگیومنت متفاوت فراخوانی می کنیم که آرگیومنت اول نام فیلد، آرگیومنت دوم مقادیر فیلد و آرگیومنت سوم آی دی بلاک div است که قصد داریم نتیجه را در آن نمایش دهیم، به این صورت مواد اولیه به تابع داده شده و تابع پس از آماده سازی پارامترها و مقادیر درخواست را به سرور ارسال می کند، در نهایت پاسخ سرور در بلاک div (که آی دی آن را با آرگیومنت div_id تنظیم کرده ایم) خروجی داده می شود.
- در این مثال از رویداد onchange استفاده کرده ایم که بنا به نیاز می توانیم از سایر رویدادها مانند onkeyup، onblur، onfocus و... نیز استفاده کنیم.
کد PHP برای پردازش اطلاعات ارسالی
با توجه به هدفمان از اعتبارسنجی شکل برنامه نویسی سمت سرور نیز متفاوت خواهد بود، برای نمونه در مثال زیر سه فیلد را از لحاظ اینکه مقادیر ارسال شده عدد، آدرس ایمیل معتبر و یا آدرس وبسایت یا وبلاگ باشد بررسی و نتیجه را چاپ کرده ایم:
<?php
@$usertext = $_POST['usertext'];
@$usermail = $_POST['usermail'];
@$usersite = $_POST['usersite'];
if(isset($usertext) && is_numeric($usertext)){
echo '<div class="result-true">عبارت وارد شده یک عدد است!</div>';
} elseif(isset($usertext) && !is_numeric($usertext)){
echo '<div class="result-false">عبارت وارد شده یک عدد نیست!</div>';
}
if(isset($usermail) && preg_match("/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i", $usermail) > 0){
echo '<div class="result-true">ایمیل وارد شده معتبر است!</div>';
} elseif(isset($usermail) && preg_match("/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i", $usermail) == 0){
echo '<div class="result-false">ایمیل وارد شده معتبر نیست!</div>';
}
if(isset($usersite) && preg_match("/^\S+\.\S+.+$/i", $usersite) > 0){
echo '<div class="result-true">آدرس سایت وارد شده معتبر است!</div>';
} elseif(isset($usersite) && preg_match("/^\S+\.\S+.+$/i", $usersite) == 0){
echo '<div class="result-false">آدرس سایت وارد شده معتبر نیست!</div>';
}
?>
توضیح:- متغیر usertext به لحاظ اینکه یک مقدار عددی باشد یا خیر بررسی می شود، در این بررسی از تابع is_numeric در PHP استفاده کرده ایم.
- متغیر usermail به لحاظ اینکه آدرس ایمیل معتبر باشد بررسی می شود، در اینجا از تابع preg_match و یک الگو بر اساس عبارات باقاعده (Regular Expression) استفاده کرده ایم.
- متغیر usersite نیز به لحاظ پیروی کردن از الگوی صحیح آدرس وبسایت بررسی می شود، در اینجا نیز از تابع preg_match و الگو بر اساس عبارات باقاعده (Regular Expression) استفاده کرده ایم.
نکته 1: تابع preg_match با توجه به الگوی در نظر گرفته شده رشته ارسالی را بررسی می کند، اگر مقادیر ارسال شده مطابق با الگو باشد، مقدار 1 (یا true) و در غیر این صورت مقدار 0 (یا false) را برمی گرداند.
نکته 2: علامت @ در ابتدای متغیرها برای جلوگیری از نمایش خطاها و نادیده گرفته شدن آنها در PHP است.
کد و پیش نمایش آنلاین
در ادامه کد نهایی و پیش نمایش آنلاین اعتبارسنجی همزمان فیلدهای فرم با ای جکس (Ajax) و PHP را جهت تست و بررسی بیشتر درج کرده ایم:
<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>وبگو | اعتبارسنجی فرم های وب با ای جکس</title>
<!-- Webgoo.ir -->
<style>
body {
font-family: Tahoma, Geneva, sans-serif;
font-size: 12px;
direction: rtl;
}
.inline {
display: inline-block;
}
.result-true {
color: #090;
}
.result-false {
color: #C00;
}
</style>
<script>
function ajaxRequest(input_name, input_value, div_id){
var form_value = input_name + "=" + input_value;
var loading_message = '<img src="loading.gif" alt="loading" height="16" width="16"> لطفا کمی صبر کنید...';
var xmlhttp;
if(window.XMLHttpRequest){
//IE7+, Firefox, Chrome, Opera, Safari
xmlhttp = new XMLHttpRequest();
} else {
//IE6, IE5
xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.onreadystatechange = function(){
if(xmlhttp.readyState < 4){
document.getElementById(div_id).innerHTML = loading_message;
} else if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
document.getElementById(div_id).innerHTML = xmlhttp.responseText;
}
}
xmlhttp.open("POST","ajax-validate.php", true);
xmlhttp.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xmlhttp.send(form_value);
}
</script>
</head>
<body>
<noscript>
جاوا اسکریپت در مرورگر شما غیرفعال است یا پشتیبانی نمی شود!<br>
</noscript>
<form action="ajax-validate.php" method="post">
<label for="usertext">اعتبار سنجی عدد بودن مقادیر:</label><br>
<input type="text" name="usertext" id="usertext" dir="ltr" onchange="ajaxRequest('usertext', this.value, 'showresult-1');">
<div class="inline" id="showresult-1"></div>
<br><br>
<label for="usermail">اعتبار سنجی معتبر بودن ایمیل:</label><br>
<input type="text" name="usermail" id="usermail" dir="ltr" onchange="ajaxRequest('usermail', this.value, 'showresult-2');">
<div class="inline" id="showresult-2"></div>
<br><br>
<label for="usersite">اعتبار سنجی معتبر بودن آدرس سایت:</label><br>
<input type="text" name="usersite" id="usersite" dir="ltr" onchange="ajaxRequest('usersite', this.value, 'showresult-3');">
<div class="inline" id="showresult-3"></div>
</form>
<br>
<hr>
پس از تایپ یک عبارت در هر فیلد، در فیلد بعدی یا فضای خالی صفحه کلیک کنید تا رویداد onchange اجرا شود.
</body>
</html>
پیش نمایش آنلاین
نمایش نتایج پایگاه داده MySQL با PHP و ای جکس (Ajax)
نمایش زنده آمار و اطلاعات با ای جکس (Ajax)
ارسال اطلاعات فرم با ای جکس (Ajax) و نمایش پیام در حال پردازش
نمایش داینامیک و صفحه به صفحه مطالب با ای جکس (Ajax)
آموزش نحوه آپلود فایل با PHP و ای جکس (Ajax)


اعتبار سنجی برای فیلدهای فارسی چطوره؟
یعنی من میخوام فقط کاراکترهای فارسی و اعداد قبول باشند.
البته برای طرف سرور میخوام.
طرف جاوا اسکریپت رو انجام دادم .
برای این کار باید modifier u را به صورت نمونه زیر استفاده کنید:
<?php
$str_1 = 'متن فارسی و 0 9';
$str_2 = 'متن فارسی و a z';
if(preg_match('/^[0-9آ-ی\s]+$/u', $str_1)){
echo '1: Valid' . '<br>';
}
else{
echo '1: Invalid' . '<br>';
}
if(preg_match('/^[0-9آ-ی\s]+$/u', $str_2)){
echo '2: Valid' . '<br>';
}
else{
echo '2: Invalid' . '<br>';
}
?>
نکته: یونیکد فایل های شما باید از حروف فارسی پشتیبانی کند، به عبارتی باید فایل های خود را به صورت utf-8 ذخیره کنید.قاعدتا مشکلی وجود دارد! ممکن است ایراد از بخشی از کدها یا روشتان باشد، به فرض عدم اجرای برنامه در لوکال هاست یا یک سرور آنلاین، در هر حال می توانید برای بررسی بیشتر فایل ها را به صورت فشرده به آدرس ایمیل ما (موجود در بخش تماس) ارسال کنید.
نکته: راه حل گفته شده ممکن است بین نسخه های مختلف کمی متفاوت باشد.
جاوا اسکریپت به صورت پیش فرض در مرورگرها فعال است، اما اگر به هر دلیل این امکان غیر فعال شده، می توانید از قسمت تنظیمات این قابلیت را فعال کنید (در مرورگرهای مختلف، شیوه متفاوتی وجود دارد)، به طور مثال در مرورگر فایرفاکس باید عبارت
about:config
را در نوار آدرس وارد کنید و سپس بر روی دکمه I'll be careful, I promise کلیک کرده و در قسمت جستجو، عبارت javascript.enabled را وارد کنید، در نهایت نیز مقادیر true را با دابل کلیک کردن به false تغییر دهید، برای کسب اطلاعات بیشتر لطفا در وب جستجو کنید.میخوام اگر همه اعتبار سنجی ها درست بود دکمه ارسال باشد اما اگر مقداری درست نبود این دکمه وجود نداشته باشد و کاربر مجبور باشد حتما قبل از ارسال فرم اون قسمت را درست وارد کند البته در سمت سرور هم قبل از ذخیره اطلاعات اعتبار سنجی رو انجام میدم اما می خوام اینجوری بیخودی کاربر رو به صفحه دیگه ای واسه نمایش خطا ارسال نکنم
لطفا آموزش مربوط به مبحث متد innerHTML و document.getElementById را مطالعه کنید، می توانید برای تگ یک کلاس CSS تعریف کنید و در حالت پیش فرض، خاصیت display را با none مقدار دهید، سپس با تغییر style تگ مورد نظر در توابع جاوا اسکریپت به هدفتان برسید (قاعدتا باید تا حدودی با جاوا اسکریپت آشنا باشید).
درخواست/پاسخ آژاکس هم می تواند از صفحه با فرمت php باشد و هم html، البته کدهای صفحه باید در یک سرور یا لوکال هاست اجرا شوند (در دایرکتوری سرور باشند) و به فرض با اجرای مستقیم فایل در مرورگر (به طور مثال از روی دسکتاپ) ممکن است دچار مشکل شوید.
منتظر بررسیتون هستم
ممنون
من طبق کد های شما یه اعتبار سنجی تو در تو با کلی if نوشتم البته نهایتا یک echo داره ولی چون فیلد های مختلف بررسی میشه تعداد زیاد هست echo ها زیاد هست الان مشکل اینکه وقتی اعتبار سنجی 1 کد رو میسنجه نتیجه رو برای تمام فیلد ها نمایش میده مثلا برای فیلد نام نتیجه اعتبار سنجی درست بود.
در فیلد بعدی که مثلا پسورد هست هم نتیجه همون اعتبار سنجی نام رو به صورت FALSE یا نادرست به همراه اعتبار سنجی فیلد پسورد نمایش میده و این همینجور ادامه داره تا آخرین فیلد. که یعنی آخرین فیلد کلی جواب نادرست داره به همراه جواب خودش
میشه بپرسم مشکل کارم کجاست ؟
هر چند این نوع سوالات باید با ارائه نمونه کد مطرح شوند، اما به نظر مشکل شما از استفاده از if های پشت سر هم به جای استفاده از if و elseif است، باید از if در کنار elseif استفاده کنید تا با نادرست شدن یک حالت، بقیه موارد بررسی نشوند.
- اعبتار سنجی با جاوا اسکریپت، رابط کاربری بهتری ایجاد می کند.
- اعتبار سنجی سمت سرور، اطمینان بیشتر.
من یه سیستم مدیریت محتوا دارم که یک پلاگین عضویت داره توی این پلاگین یه مشکل اساسی هستش اونم اینه که ایمیل چه صحیح باشه و چه اشتباه در بانک اطلاعاتی ذخیره می شود این قسمتی از کد هستش:
<?php
//If User Is Not Logged In
if(!isset($_SESSION['LoggedIn']))
{
if(isset($_POST['register-form']))
{
//If Register Form Was Submitted
if($_POST['username'] != '' && $_POST['password'] != '' && $_POST['email'] != '')
{
$addUser = $Feul->processAddUserAdmin($_POST['username'], $_POST['password'], $_POST['email'], $_POST['website'], $_POST['mobile']);
if($addUser == true)
{
echo '<div class="success">Your account was successfully created</div>';
$Feul->checkLogin(true, $_POST['username'], $_POST['password']);
//Send Email
$to = $_POST['email'];
$Username = $_POST['username'];
$chosen_password = $_POST['password'];
// subject
$subject = 'Your New Account ('.$Username.') Is Setup!';
// message
$message = '
<html>
<head>
<title>Your New Account Is Setup!</title>
</head>
<body>
<h2><strong>Below is your login information:</strong></h2><br/><br/>
<strong>Username: </strong>'.$Username.'<br/>
<strong>Password: </strong>'.$chosen_password.'<br/>
<br/>
<a href="'.$SITEURL.'">Click Here To Visit Website</a>
</body>
</html>
';
// To send HTML mail, the Content-type header must be set
$headers = 'MIME-Version: 1.0' . "";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "";
// Additional headers
//$headers .= 'To: Mary <mary@example.com>, Kelly <kelly@example.com>' . "";
$headers .= 'From: New Account <'.$Feul->getData('email').'>' . "";
//$headers .= 'Cc: birthdayarchive@example.com' . "";
//$headers .= 'Bcc: birthdaycheck@example.com' . "";
// Mail it
$success = mail($to, $subject, $message, $headers);
if(!$success)
{
$error = '<div class="error">Unable to send welcome email.</div>';
}
}
else
{
$error = '<div class="error">User Already Exists</div>';
}
}
else
{
$error = '<div class="error">Please fill in the required fields</div>';
}
}
echo $Feul->getData('registerbox');
}
?>
ممنون میشم راهنمایی کنید چطوری می تونم اعتبارسنجی کنم که آیا ایمیل وارد شده صحیح هست یا نه اگر صحیح نبود یک پیام خطا نمایش داده بشود و اگر صحیح بود ذخیره اطلاعات در بانک انجام بشهمی توانید مطابق الگوی استفاده شده در مطلب، پارامتر دیگری به دستورات شرطی خود اضافه کنید، به فرض:
$email_check = preg_match("|^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$|i", $_POST['email']);
//If Register Form Was Submitted
if($_POST['username'] != '' && $_POST['password'] != '' && $_POST['email'] != '' && $email_check > 0)
و برای نمایش پیغام خطا در صورت معتبر نبودن، قسمت else مربوط به Please fill in the required fields را به صورت زیر ویرایش کنید: else
{
if($email_check == 0){
$error = '<div class="error">email is not valid!</div>';
}
else{
$error = '<div class="error">Please fill in the required fields</div>';
}
}
در مرحله اول از سایت خوبتون کمال قدردانی رو دارم...
چطوری میشه از ثبت اطلاعات تکراری در mysql با php و ajax جلوگیری کرد...
یعنی یه فرم ثبت نام داریم ، بررسی کنه که اگه نام کاربری در بانک تکراری بود اون رو ثبت نکنه و با یه پیغام مناسب اخطار بده...
باز هم ممنون...
سوالتان کلی است و به ناچار جواب هم کلی:
باید قبل از ذخیره اطلاعات، یک پرس و جوی فرضی بنویسید که به طور مثال ردیف های مشابه با مقادیر ارسالی را فراخوانی کند، اگر نتایج حاصل از پرس وجو بزرگتر از صفر بود، پس چنین موردی از قبل در دیتابیس وجود داشته، می توانید یک پیام به صورت مستقیم ارسال کنید یا اینکه به فرض یک عدد در پاسخ درخواست آژاکسی ارسال کنید و در سمت کاربر آن عدد را تجزیه و تحلیل کرده، متناسب با آن پیامی نمایش دهید.
- به سوالات کلی، زمانبر، مبهم و مشکلاتی که تلاشی برای رفع آنها نکرده باشید پاسخ مختصر داده شده یا به بخش برنامه نویسی اختصاصی ارجاع داده می شوند.
- کدها و اسکریپت های طولانی را ترجیحا در یک صفحه وب آنلاین یا به صورت حساب موقت و آزمایشی قرار دهید تا امکان بررسی دقیق مشکل و خطایابی میسر باشد.
- تمام دیدگاه های ارسالی خوانده شده و برای هر کاربر مدت زمان لازم جهت پاسخگویی در نظر گرفته می شود، لطفا از طرح سوالات متعدد در بازه زمانی کوتاه خودداری کنید.