طلب مني أحد الأحبة أن أكتب له هذا الحل، فأردت إشراككم في الفائدة.
إذا كان لديك برنامج تصويت، فإنه يمكن أن يعبث متصفح بواحد بنتائج التصويت؛ وذلك بتكرار
العملية.
هناك عدة حلول :
1 - الحل الأول : أن تجعل التصويت للأعضاء. فإذا (صوّت) عضو فإن رقمه يسجل في قاعدة البيانات،
ولا يمكن أن يصوت مرة أخرى.
وهذه الطريقة معمول بها في المنتديات.
2 - الحل الثاني : أن تعتمد على ملف البصمة(cookie)؛ لحفظ معلومات المتصفح.
وهذه الطريقة تقلل العبث، ولا تقضي عليه؛ لأنه يمكن حذف ملف البصمة؛ لكن الغالب أن متصفح
الشبكة لا يهتمون بمثل هذه الأمور.
3 - الحل الثالث : الاعتماد على ملفات نصية أو قاعدة البيانات في حفظ معلومات المتصفح. وهي
أفضل من الطريقة السابقة؛ لأنه لا يمكن للعابث أن يحذف المعلومات.
أما الحل الأول فهو واضح؛ وذلك بأن تضع في حقل التصويت حقلا باسم
ثم يدخل رقم العضو في هذا الحقل عند التصويت
وقبل إدخال قيمة التصويت يُتحقق من وجود الرقم أو لا؟
كود PHP:
$query ="SELECT member_id FROM vote WHERE vote_id='$vote_id'";
$result=mysql_query($query);
while (list ($member_id)=mysql_fetch_array ($result)) {
if ( $member_id== $m_id ) {
echo "لا يمكنك التصويت أكثر من مرة";
exit ();
}// End : if
}// End : While
الأمر الأول :
كود PHP:
$query ="SELECT member_id FROM vote WHERE vote_id='$vote_id'";
طلبنا الاستعلام من قاعدة البيانات؛ حيث طلبنا رقم العضو من الجدول vote حيث رقم التصويت
vote_id يساوي التصويت المختار.
لأننا نريد التأكد هل صوت في هذا التصويت أو لا؟
الأمر الثاني :
طلب هذا الاستعلام من قاعدة البيانات وجعله في متغير باسم $result
كود PHP:
$result=mysql_query($query);
الأمر الثالث :
عمل حقلة تكرار لأرقام الأعضاء بحيث نستعرض أرقام الأعضاء الذين صوّتوا في هذا التصويت.
while (list ($member_id)=mysql_fetch_array ($result)) {
الأمر الرابع :
في أثناء حقلة التكرار نستعرض كل رقم على حدة؛ لنرى هذا يوافق رقم العضو الرقم المخزن في قاعدة
البيانات؟
فـ $member_id هم رقم العضو المخزن في القاعدة.
و $m_id هو رقم العضو الذي جلبناه عنده تسجيله الدخول
كود PHP:
if ( $member_id== $m_id ) {
الأمر الخامس :
إذا كان رقم العضو يتفق مع الرقم في قاعدة البيانات فهذا يعني أنه سبق أن صوت؛ فنظهر له رسالة، ثم
نوقف العمل.
كود PHP:
echo "لا يمكنك التصويت أكثر من مرة";
exit ();
ثم نغلق الأقواس
كود PHP:
}// End : if
}// End : While
هذه طريقة الحل الأول؛ وهو التصويت الخاص بالأعضاء
الحل الثاني : الاعتماد على ملف البصمة :
قبل التصويت علينا أن نحصل على معلومات معينة عن الزائر
كود PHP:
$rate_agent = $_SERVER['HTTP_USER_AGENT'];
$rate_ip=$_SERVE['REMOTE_ADDR'];
$rate_host=$_SERVER['REMOTE_HOST'];
المتغير $_SERVER هو متغير خاص بمتغيرات المزود والزائر، وهو اختصار للمتغير في الإصدارات
القديمة : $HTTP_SERVER_VARS
يمكنك عن طريق هذا المتغير تحديد عدة معلومات حسب النوع؛ ويمكنك معرفة الأنواع التي يمكن جلبها
من هنا :
أو البحث في دليل php
في
VII. Appendixes
ثم
Appendix G. List of Reserved Words
ثم
Predefined Variables
في السطر الأول طلبنا معلومات معلومات النظام والمتصفح
($_SERVER['HTTP_USER_AGENT'];)؛ فإذا كان الزائر يستخدم نظام XP
ومتصفح إنترنت إكسبلورر فستظهر معلومات مشابهة لهذه :
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; Q312461)
في السطر الثاني : طلبنا معلومات الرقتفي ( مصطلح من بدلا من آيبي )
($_SERVE['REMOTE_ADDR'])
في السطر الثالث طلبنا معلومات مقدم الخدمة ($_SERVER['REMOTE_HOST'])
وحفظنا هذه المعلومات في المتغيرات الثلاث :
كود PHP:
$rate_agent
$rate_ip
$rate_host
ثم نضيف متغيرا آخر وهو رقم التصويت :
كود PHP:
$rate_id = $voteid;
بعد هذا نشئ ملف بصمة جديد
كود PHP:
$cookieinfo = "$rate_agent:$rate_ip:$rate_host";
setcookie("rateinfo($rate_id)","$cookieinfo",time()+3600*120);
أولا جمعنا المتغيرات الثلاث السابقة في متغير واحد، وفصلنا بينها بعلامة (:) نقطة فوقها نقطة.
ثم طلبنا إنشاء ملف البصمة ؛ حيث يحمل الاسم rateinfo ورقم التصويت الحالي
كود PHP:
rateinfo($rate_id)
تلحظ أنن وضعنا رقم التصويت مع اسم ملف البصمة؛ وذلك لئلا تحصل مشكلات عند تعدد التصويت؛
لأننا لو وضعنا اسم ملف البصمة هكذا
rateinfo
فإنه لن يسمح إلا بالمشاركة في تصويت واحد فقط؛ فلو كان لديك كل يوم تصويت فلن يتمكن الزائر
من المشاركة في كلها؛ لهذا من الأفضل أن نحدد اسم ملف البصمة برقم التصويت
ثم أعلمنا الدالة أن تحفظ المعلومات المخزنة في المتغير $cookieinfo في ملف البصمة
ثم أعلمنا الدالة أن تحفظ هذه المعلومات لمدة خمسة أيام.
لأن الساعة فيه 3600 ثانية ( نظام الحفظ يعتمد على الثواني)
واليوم فيه 24 ساعة، وخمسة أيام تعني 120 ساعة
فضربنا عدد الثواني في الساعة بعدد الساعات في خمسة أيام
بعد هذا نغلق قوس الشرط
}
الآن حفظت المعلومات.
هذه المعلومات تكون في صفحة عرض التصويت rate.php
وفي صفحة اعتماد التصويت dorate.php نضع الأوامر التالية :
كود PHP:
$rate_agent = $_SERVER['HTTP_USER_AGENT'];
$rate_ip=$_SERVE['REMOTE_ADDR'];
$rate_host=$_SERVER['REMOTE_HOST'];
$rate_id = $voteid;
وقد مضت هذه الأوامر من قبل
ونضيف إليها :
كود PHP:
$cookie = $_COOKIE['rateinfo($rate_id)'];
المتغير $_COOKIE يضمن أن المعلومات المجلوبة هي من ملف البصمة وليس من متغير آخر، فمثلا
لو وضعت
$rateinfo فإنه يمكن خداع البرنامج عن طريق المتصفح، وتمرير المتغير منه!
لكن $_COOKIE لا يسمح بمثل هذا، وهذا المتغير اختصار للمتغير في الإصدارات السابقة
$HTTP_COOKIE_VARS
الآن نطلب المعلومات المحفوظة :
كود PHP:
$cookieexplode = explode (":",$cookie);
كما سبق بيانه؛ فإن المعلومات المخزنة في ملف البصمة قد فصلت بعلام : ؛ لهذا طلبنا فصل المتغيرات في
هذا المتصفح، وجعلها في خانات باسم
ثم نعيد ترتيب المتغيرات
كود PHP:
$getcooki_agent = $cookieexplode[0];
$getcooki_ip = $cookieexplode[1];
$getcooki_host = $cookieexplode[2];
السطر الأول يجلب المعلومة في الخانة ذات الرقم صفر
والثاني يجلب المعلومة في الخانة ذات الرقم 1
والثالث يجلب المعلومات في الخانة ذات الرقم 2
لأننا وضعنا متغير ملف البصمة بهذا الترتيب
كود PHP:
$cookieinfo = "$rate_agent:$rate_ip:$rate_host";
الآن نتحقق هل المعلومات المسحلة عن الزائر توافق المعلومات المحفوظة في ملف البصمة؟
كود PHP:
if ( $rate_agent == $getcooki_agent && $rate_ip == $getcooki_ip
&& $rate_host == $getcooki_host ) {
فإذا كانت المعلومات الثلاث متطابقة فإننا نظهر رسالة
كود PHP:
echo "لقد صوّت من قبل";
exit ();
ثم نغلق قوس الشرط:
}
ثم ننفذ عملية إدراج التصويت.
انتهى الحل الثاني :
الحل الثالث :
مثل الطريقة السابقة إلا في طريقة حفظ المعلومات، فبدلا من حفظها في ملف البصمة تحفظ المعلومات
في ملف نصي أو في قاعدة البيانات.
ولعلي أتفرغ لشرح الحل الثالث بالتفصيل