article

ساخت قابلیت امتیازدهی با PHP و Ajax

ajax-php-voting

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

کد جاوا اسکریپت سیستم امتیازدهی


قبل از هر چیز ما به واسطه ای نیاز داریم که بتواند بدون رفرش شدن صفحه، درخواست کاربر را به سرور منتقل کرده و پاسخ سرور را دریافت، پردازش و در صورت نیاز خروجی دهد، این واسطه در اکثر موارد چیزی نیست به جزء آژاکس و جاوا اسکریپت (یا فریم ورک های مبتنی بر آن مانند جی کئوری) که در زیر یک نمونه از آن را ملاحظه می کنید.
<script type="text/javascript">
//<![CDATA[
function voting(action,id){
    var up_point_id = "up_point_" + id;
    var down_point_id = "down_point_" + id;    
    var loading_id = "loading_img_" + id;        
    var loading = '<img src="loading.gif" alt="loading" height="16" width="16" border="0" />';
    if (action == 'up'){
        var user_point = document.getElementById(up_point_id).innerHTML;
    }
    else if (action == 'down'){
        var user_point = document.getElementById(down_point_id).innerHTML;
    }
    var xmlhttp;
    if (window.XMLHttpRequest){
        xmlhttp=new XMLHttpRequest();
    }
    else{
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function(){
    if (xmlhttp.readyState > 0 && xmlhttp.readyState < 4){
        document.getElementById(loading_id).innerHTML=loading;
    }
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
        document.getElementById(loading_id).innerHTML='';
        var response = xmlhttp.responseText;
        var splited_response = response.split("||");
        var status = splited_response[0];        
        var new_point = splited_response[1];
        if (action == 'up' && status == 'ok'){
            document.getElementById(up_point_id).innerHTML=new_point;
        }
        else if (action == 'down' && status == 'ok'){
            document.getElementById(down_point_id).innerHTML=new_point;
        }
    }
  }
  var req = "vote.php?do=" + action + "&user=" + id + "&point=" + user_point;
  xmlhttp.open("GET",req,true);
  xmlhttp.send();
}
//]]>
</script>
توضیح:
- در کد بالا ما صرفا از برنامه نویسی ساده جاوا اسکریپت و آژاکس استفاده کرده ایم که این کار موجب کاهش چشمگیر حجم نهایی صفحات وب می شود.
- تابعی که از آن استفاده کرده ایم، voting نام دارد که البته یک نام دلخواه و فرضی است، این تابع از دو آرگومان استفاده می کند، آرگومان اول (action) مشخص می کند که آیا کاربر قصد دادن امتیاز منفی را دارد یا اینکه می خواهد امتیاز مثبت بدهد، مقادیر آرگومان در هنگام فراخوانی تابع با عبارات up یا down مشخص می شوند.
- آرگومان دوم برای این است که کاربران مختلف را در صفحه از هم متمایز کنیم، در اینجا می توان از تکنیک های زیادی بسته به سلیقه استفاده کرد، به طور مثال ما از نام کاربران برای آرگومان دوم استفاده کرده ایم و برای هر کاربر نیز، نام او را به انتهای عنوان آی دی بلاک ها اضافه نموده ایم، به این ترتیب سیستم ما قادر خواهد بود که هر کاربر را به طور مجزا شناسایی کند، البته در عمل برای ایجاد چنین مواردی می توان در هنگام خروجی گرفتن، لیست کاربران را از دیتابیس استخراج و در حلقه foreach یا for به صورت داینامیک چاپ کرد.
- در قسمت اول تابع  voting چند متغیر تعریف می کنیم که در ادامه به آنها نیاز خواهیم داشت، به فرض متغیر up_point_id از پیوستن پیش عبارت _up_point به آرگومان id برای هر کاربر به صورت داینامیک، آی دی اختصاصی بلاک او را برای امتیازات مثبت تعریف می کند، یا متغیر loading_id به همین ترتیب مشخص می کند که تصویر کوچک نمایش در حال بارگذاری باید برای کدام کاربر به نمایش درآید.
- در گام بعدی چون در اینجا ما از دیتابیس استفاده نمی کنیم، ناچاریم امتیازات فعلی را از صفحه حاضر دریافت کنیم، لذا یک متغیر با نام user_point تعریف می کنیم که وظیفه اش گرفتن محتوای درون بلاک up_point_id یا down_point_id است، این مقدار به سرور ارسال شده و (در این مثال) با عدد 1 جمع می شود، نهایتا نیز حاصل با xmlhttp.responseText بازگشت داده می شود.
- همان طور که در آموزش های مقدماتی آژاکس (Ajax) گفته ایم، پس از ارسال درخواست آژاکسی، xmlhttp.readyState در چند وضعیت قرار می گیرد که با اعداد 0 تا 4 دریافت می شوند، بدین شرح:
عدد 0 به معنی حالت عادی و عدم درخواست آژاکس است.
عدد 1 به معنی شروع درخواست آژاکس است.
عدد 2 به معنی دریافت درخواست آژاکس توسط سرور است.
عدد 3 به معنی در حال پردازش بودن درخواست آژاکس است.
عدد 4 به معنی تکمیل درخواست و آماده بودن پاسخ آن است.
لذا بین عدد 0 تا 4 می توان یک تصویر کوچک به عنوان در حال بارگذاری نمایش داد.
- برای اینکه بتوانیم پاسخ سرور را به درستی مدیریت کنیم، آن را با split به آرایه هایی تجزیه می کنیم، در اینجا از علامت || به عنوان جدا کننده، برای قسمت کردن پاسخ و تجزیه آن در چند متغیر مجزا استفاده کرده ایم، حال متغیر status بخش اول پاسخ سرور و متغیر new_point قسمت دوم آن را در خود دارد.
- ملاحظه می کنید که از متد GET برای ارسال و دریافت متغیرها و مقادیر آنها به سرور استفاده شده است.

فراخوانی تابع voting


برای فراخوانی تابع کافی است آن را به صورت a و href به همراه رویداد onclick تعریف کنید، این کار را در نمونه زیر برای دو کاربر انجام داده ایم.
<div class="user">
<a href="#" onclick="voting('up','user1');"><img src="plus.png" height="16" width="16" alt="up" title="امتیاز مثبت" border="0" /></a>
<span id="up_point_user1">0</span>
<a href="#" onclick="voting('down','user1');"><img src="minus.png" height="16" width="16" alt="down" title="امتیاز منفی" border="0" /></a>
<span id="down_point_user1" dir="ltr">0</span>
<span id="loading_img_user1"></span>
</div>
<div class="user">
<a href="#" onclick="voting('up','user2');"><img src="plus.png" height="16" width="16" alt="up" title="امتیاز مثبت" border="0" /></a>
<span id="up_point_user2">0</span>
<a href="#" onclick="voting('down','user2');"><img src="minus.png" height="16" width="16" alt="down" title="امتیاز منفی" border="0" /></a>
<span id="down_point_user2" dir="ltr">0</span>
<span id="loading_img_user2"></span>
</div>
توضیح:
- در مثال بالا برای هر کاربر یک بلاک با کلاس فرضی user در نظر گرفته ایم.
- اگر به آی دی به کار رفته شده برای تگ های span دقت کنید، ملاحظه می کنید که نام هر کاربر برای تفکیک، به انتهای آنها اضافه شده است.

کد php برای سیستم امتیازدهی


برنامه هنوز تکمیل نشده است، گذشته از سمت کاربر و اسکریپت نویسی آن، بخش عمده کار مربوط می شود به سمت سرور و پردازش های آن، به طور مثال پس از ارسال درخواست، ابتدا باید ببینیم کاربر به چه کسی قصد امتیاز دادن دارد  و امتیاز فعلی آن فرد چقدر است، اگر قصد کاربر امتیاز مثبت بود، امتیازات فعلی را به اضافه مقادیر جدید کنیم، یا برعکس اگر کاربر امتیاز منفی داد، امتیازات فرد را از مقادیر جدید کم و سپس نتایج جدید را هم در دیتابیس به روز کرده و هم به صفحه مرورگر ارسال کنیم، لذا بخش اصلی کار ما در کنار کدها و برنامه نویسی php کار با دیتابیس و پرس و جوهای mysql خواهد بود، اما به جهت اینکه آموزش حاضر صرفا برای این است که یک نمونه باشد، از مباحث مربوط به mysql آن می گذریم و برای درک مطلب با یک تکه کد php ساده کار را ادامه می دهیم.
<?php
$do = $_GET['do'];
$point = $_GET['point'];
if ($do == 'up'){
    $new_point = $point + 1;
}
elseif($do == 'down'){
    $new_point = $point - 1;    
}
echo 'ok'.'||'.$new_point;
?>
توضیح:
- این کد را با نام vote.php در یک فایل ذخیره کنید، فایل حاضر و صفحه html که کد آژاکس را در آن قرار داده ایم باید در یک فولدر قرار گیرند یا اینکه آدرس قسمت var req به درستی تنظیم شود.
- در کد بالا تنها با یک دستور شرطی ساده امتیاز فعلی کاربر را یک واحد افزایش یا کاهش می دهیم.
- خروجی ما با علامت || از هم تفکیک شده است، همان طور که پیش تر گفتیم، در سمت کاربر و در کد آژاکس، پاسخ سرور را با این علامت و دستور split تجزیه می کنیم.

کد نهایی و پیش نمایش آنلاین


برای ملاحظه یک نمونه آزمایشی و اولیه از سیستم امتیازدهی می توانید از کد و پیش نمایش آنلاین زیر استفاده کنید.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>وبگو | ایجاد امکان امتیازدهی در سایت</title>
<!-- https://webgoo.ir -->
<style type="text/css">
body{
    font-family:Tahoma, Geneva, sans-serif;
    font-size:12px;
    direction:rtl;
}
.user{
    display:block;
    border:#666 1px dashed;
    height:30px;
    width:120px;
    padding:4px;
    margin:4px;
}
</style>
<script type="text/javascript">
//<![CDATA[
function voting(action,id){
    var up_point_id = "up_point_" + id;
    var down_point_id = "down_point_" + id;    
    var loading_id = "loading_img_" + id;        
    var loading = '<img src="loading.gif" alt="loading" height="16" width="16" border="0" />';
    if (action == 'up'){
        var user_point = document.getElementById(up_point_id).innerHTML;
    }
    else if (action == 'down'){
        var user_point = document.getElementById(down_point_id).innerHTML;
    }
    var xmlhttp;
    if (window.XMLHttpRequest){
        xmlhttp=new XMLHttpRequest();
    }
    else{
        xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange=function(){
    if (xmlhttp.readyState > 0 && xmlhttp.readyState < 4){
        document.getElementById(loading_id).innerHTML=loading;
    }
    if (xmlhttp.readyState==4 && xmlhttp.status==200){
        document.getElementById(loading_id).innerHTML='';
        var response = xmlhttp.responseText;
        var splited_response = response.split("||");
        var status = splited_response[0];        
        var new_point = splited_response[1];
        if (action == 'up' && status == 'ok'){
            document.getElementById(up_point_id).innerHTML=new_point;
        }
        else if (action == 'down' && status == 'ok'){
            document.getElementById(down_point_id).innerHTML=new_point;
        }
    }
  }
  var req = "vote.php?do=" + action + "&user=" + id + "&point=" + user_point;
  xmlhttp.open("GET",req,true);
  xmlhttp.send();
}
//]]>
</script>
</head>
<body>
<noscript>
جاوا اسکریپت در مرورگر شما غیر فعال است یا پشتیبانی نمی شود! <br />
</noscript>

<div class="user">
<a href="#" onclick="voting('up','user1');"><img src="plus.png" height="16" width="16" alt="up" title="امتیاز مثبت" border="0" /></a>
<span id="up_point_user1">0</span>
<a href="#" onclick="voting('down','user1');"><img src="minus.png" height="16" width="16" alt="down" title="امتیاز منفی" border="0" /></a>
<span id="down_point_user1" dir="ltr">0</span>
<span id="loading_img_user1"></span>
</div>
<div class="user">
<a href="#" onclick="voting('up','user2');"><img src="plus.png" height="16" width="16" alt="up" title="امتیاز مثبت" border="0" /></a>
<span id="up_point_user2">0</span>
<a href="#" onclick="voting('down','user2');"><img src="minus.png" height="16" width="16" alt="down" title="امتیاز منفی" border="0" /></a>
<span id="down_point_user2" dir="ltr">0</span>
<span id="loading_img_user2"></span>
</div>
<hr />
سیستم امتیازدهی بالا جهت تست و بدون استفاده از دیتابیس کار می کند؛ لذا امتیازات بعد از بستن یا رفرش صفحه به حالت پیش فرض بر می گردند، برای ساخت یک سیستم امتیازدهی کامل باید علاوه بر آژاکس و php از mysql نیز استفاده کنید.
</body>
</html>
پیش نمایش
sectionدسته بندی: آموزش کاربردی » Ajax
related مطالب بیشتر:
» نمایش داینامیک و صفحه به صفحه مطالب با ای جکس (Ajax)
» اعتبار سنجی همزمان فرم با آژاکس (Ajax) و PHP
» ارسال اطلاعات فرم با ای جکس (Ajax) و نمایش پیام در حال پردازش
» نمایش نتایج پایگاه داده MySQL با PHP و ای جکس (Ajax)
» آموزش نحوه آپلود فایل با PHP و آژاکس (Ajax)
commentنظرات (۱۸ یادداشت برای این مطلب ارسال شده است)
more یادداشت های جدید بر اساس تاریخ ارسال در انتهای یادداشت های موجود نمایش داده می شوند.
نویسنده: mehrdad
زمان: ۱۳:۵۱:۴۴ - تاریخ: ۱۳۹۴/۰۱/۳۱
سلام
ایا اموزش مربوطه (یعنی کسب امتیاز با فعالیت کاربران) را در سایت قرار می دهید؟
با سپاس
پاسخ: 
سلام
به دنبال این نوع آموزش ها در وب نباشید! چون اصولا چنین مواردی به دلیل گسترده و پیوسته بودن موضوع قابل طرح در یک مطلب نیست (به عبارتی شما باید برنامه نویس باشید و متناسب با برنامه و نیاز خودتان کدهای سفارشی تعریف کنید!).
نویسنده: بهرنگ
زمان: ۱۰:۱۹:۴۶ - تاریخ: ۱۳۹۵/۰۳/۱۵
سلام خیلی عالی بود
نویسنده: اسماعیل
زمان: ۱۶:۰۶:۱۵ - تاریخ: ۱۳۹۸/۱۰/۰۸
ممنون از سایت بسیار عالیتون من الان مسلط به html و php و css هستم و برنامه های java و ajax رو هم تا 50 درصد یاد گرفتم تمام اینها رو مدیون سایت خوب شما هستم.
خواستم بپرسم در جایی چت آنلاین کاربر با سایت رو هم آموزش دادید ؟؟؟
مرسی و سپاس
پاسخ: 
متاسفانه خیر، در حال حاضر به صورت مستقل آموزشی برای این موضوع در سایت منتشر نشده است.
more لطفا پیش از ارسال یادداشت نکات زیر را مد نظر داشته باشید:
- مواردی که به کلی خارج از موضوع این مطلب هستند را در فرم منوی "تماس با ما" مطرح و پاسخ را از طریق ایمیل دریافت کنید.
- به سوالات کلی، مبهم، غیرضروری و مشکلاتی که تلاشی برای رفع آن نکرده باشید پاسخ خاصی داده نخواهد شد.
- کدها و اسکریپت های طولانی را ترجیحا در یک صفحه وب آنلاین قرار دهید تا امکان تست و بررسی وجود داشته باشد.
- تمام یادداشت ها بررسی و برای هر کاربر زمان مشخصی جهت پاسخگویی در نظر گرفته می شود، لذا از طرح سوالات متعدد در بازه زمانی کوتاه خودداری کنید.




3 × 7
 refresh
نکته:
با توجه به تاریخ نگارش آموزش های سایت و پیشرفت تکنولوژی های مرتبط با وب در سالیان اخیر، محتوای برخی از مطالب قدیمی ممکن است نیاز به ویرایش و به روزرسانی داشته باشد که این کار هم زمان با تهیه نسخه جدید «وبگو» به مرور در حال انجام است، لطفا در استفاده از مطالب سایت به این نکته دقت داشته و حتی المقدور از چند منبع مختلف استفاده نمائید.
آخرین دیدگاه ها
form امین
در:
سلام خسته نباشید یه اسکریپت دارم که وقتی کاربر ثبت نام میکنه یه پوشه و محتواش ایجاد میشه. میخوام یه صفحه با هر ثبت نام...
۱۴:۱۸:۵۱ ۱۳۹۸/۱۰/۳۰

form Admin
در:
سلام دوست عزیز. میشه بگویید چگونه میتوان در وبلاگ کادری را باز کرد که بازدید کنندگان بتوانند در آن چیزی بنویسند. ممنون میشم...
۱۱:۲۸:۵۰ ۱۳۹۸/۱۰/۳۰

form مهدی
در:
سلام میشه به من کمک کنید من چجوری برای وب سایتم لینک بزارم؟ اگه میشه برای ایمیلم جواب را ارسال کنید.
۲۰:۲۹:۰۸ ۱۳۹۸/۱۰/۲۹

form مهدی
در:
سلام من مهدی هستم. چجوری باید برای سایتی که ساختم آدرس بسازم که وقتی در سرچ گوگل بنویسیم برایمان بیاورد.
۱۹:۴۶:۲۳ ۱۳۹۸/۱۰/۲۸

form sadegh
در:
سلام من میخوام قالب وبلاگم رو تغییر بدم و تاریخ یا تعداد کامنت های مطالب پربازدید رو بهش اضافه کنم ولی طبق جدولی که...
۱۲:۳۰:۰۳ ۱۳۹۸/۱۰/۲۸

form امیر علی
در:
سلام من یه وبلاگ برای امان زمان ساختم الان وقتی میخوام از مدیریت برم توش میاره که فیلتره ولی وقتی ادرسش رو سرچ میکنم میاره...
۲۰:۲۶:۲۷ ۱۳۹۸/۱۰/۲۷

form حمید شیخلر
در:
سلام خسته نباشید دوست عزیز من یه راهنمایی میخواستم یه شخصی برنامه بله رو دانلود کرده ولی مخفیانه شماره تلفن من رو داده پیامک کد...
۱۷:۴۷:۴۸ ۱۳۹۸/۱۰/۲۶

form سید محسن
در:
من داخل وبلاگم تو بلاگفا یک متن نوشتم ولی 4 بار تکرار شده علتش چیه؟
۱۵:۰۵:۳۱ ۱۳۹۸/۱۰/۲۴

form ainaz
در:
سلام من در صفحم عکس گذاشتم ولی عکسم تیکه تیکه افتاده باید چکار کنم
۲۰:۵۶:۵۷ ۱۳۹۸/۱۰/۲۳

form zb84
در:
هنگام آپدیت افزونه های وردپرس به این ارور برخورد میکنم لطفا راهنمایی کنید.
۲۱:۳۴:۲۷ ۱۳۹۸/۱۰/۲۲

form esmaeel
در:
سلام من فونتا رو اوکی می کنم تو وبسایت وقتی با کامپیوتر میرم فونتا درسته ولی وقتی با گوشی میرم فونت نمیاد مشکلش چی میتونه...
۱۹:۲۹:۰۹ ۱۳۹۸/۱۰/۱۹

form john
در:
سلام خدمت شما ببخشید آیا میشه از کد های پی اچ پی هم داخل وبلاگ استفاده کرد؟
۱۳:۴۴:۱۵ ۱۳۹۸/۱۰/۱۸

form ابوالفضل شیخیانی
در:
عالی بود، ممنون بابت این پستتون
۲۲:۳۰:۴۰ ۱۳۹۸/۱۰/۱۶

form بهنام
در:
سلام من میخوام برای یک متغیر دو تا مقدار تعیین کنم مثلا هم باشه واضح تر بگم میخوام بگم اگه...
۱۷:۱۶:۳۶ ۱۳۹۸/۱۰/۱۶

form مهدی
در:
می خوام در صفحه ای رنگ آبی گزینه نام و نام خانوادگی نوشته بشود و جای خالی برای آنها گذاشته شود و در آخر داخل...
۱۴:۲۱:۳۸ ۱۳۹۸/۱۰/۱۳
آگهی
موسسه خیریه سگال