GORAGOD.com

[แจกฟรี] AJAX Shoutbox พร้อมโค้ด ตอนที่ 2

ในตอนนี้จะเป็นการอธิบายในส่วนของการโพสต์ด้วย Ajax กันก่อน

ก่อนอื่นในการใช้งาน Ajax ของ Browser จะต้องมีการเรียกใช้งาน Object XMLHTTP หรือ XMLHttpRequest โดยใช้ฟังก์ชั่น initAjax
/**
* ฟังก์ชั่นเรียกใช้งาน Ajax
*/

function initAjax() {
  // IE
  try {return new ActiveXObject("Msxml2.XMLHTTP");} catch (e) {}
  // IE
  try {return new ActiveXObject("Microsoft.XMLHTTP");} catch (e) {}
  // Native Javascript
  try {return new XMLHttpRequest();} catch (e) {}
  alert("XMLHttpRequest not supported");
  return null;
}

ขั้นตอนการโพสต์ข้อความก็เริ่มจากฟอร์ม ที่เมธอด onsubmit ของฟอร์มไปเรียกฟังก์ชั่น shoutSubmit ของ Javascript
<form id="shout_form" action="save.php" method="POST" onsubmit="return shoutSubmit()">
  <table>
    <tr>
      <td class="right">ข้อความ :</td>
      <td><input type=text id=shout_text maxlength=50></td>
    </tr>
    <tr>
      <td class="right">ชื่อ :</td>
      <td><input type=text id=shout_user maxlength=10></td>
    </tr>
    <tr>
      <td colspan="2"><button type="submit">ส่ง</button></td>
    </tr>
  </table>
  <footer class="center">design by <a href="https://www.goragod.com">Goragod.com</a></footer>
</form>

ฟังก์ชั่น shoutSubmit ของ Javascript มีโค้ดดังด้านล่าง เป็นการอ่านค่าจาก input shout_text และ shout_user ของฟอร์มส่งไปยัง Server เพื่อบันทึกข้อมูลเป็นไฟล์ด้วย Ajax
/**
* จำนวนข้อมูลสูงสุดที่จัดเก็บ
*/

var linecount = 20;

/**
* form submit
*/

function shoutSubmit() {
  var text = document.getElementById("shout_text"),
    user = document.getElementById("shout_user");
  if (text.value.length < 3) {
    alert("กรุณากรอกข้อความไม่น้อยกว่า 3 ตัวอักษร");
    text.focus();
  } else if (user.value.length < 3) {
    alert("กรุณากรอกชื่อผู้ส่งไม่น้อยกว่า 3 ตัวอักษร");
    user.focus();
  } else {
    // โหลด Ajax
    var req = initAjax(),
      q = "value=" + encodeURIComponent(text.value) + "&user=" + encodeURIComponent(user.value) + "&count=" + linecount;
    // Event
    req.onreadystatechange = function() {
      if (req.readyState == 4) {
        if (req.status == 200) {
           text.value = "";
           text.focus();
           // โหลดข้อความใหม่
           doSoutbox.call();
        }
      }
    };
    // สร้าง connection
    req.open("POST", "save.php");
    // Header ภาษาไทย
    req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
    // ส่งค่า
    req.send(q);
  }
  return false;
}

ไฟล์ที่รับค่าข้อมูลที่ส่งมาอยู่ที่ save.php
<?php
if (!empty($_POST['user']) && !empty($_POST['value']) && !empty($_POST['count'])) {
  // ปรับเวลาให้ตรงกับประเทศไทย
  @date_default_timezone_set('Asia/Bangkok');
  // BBCode
  $patt = array();
  $replace = array();
  $patt[] = '/\[(i|dfn|b|strong|u|em|ins|del|sub|sup|small|big)\](.*)\[\/\\1\]/is';
  $replace[] = '<\\1>\\2</\\1>';
  $patt[] = '/\[color=([#a-z0-9]+)\]/i';
  $replace[] = '<span style="color:\\1">';
  $patt[] = '/\[\/(color)\]/i';
  $replace[] = '</span>';
  $patt[] = '/([^["]]|\r|\n|\s|\t|^)((ftp|https?):\/\/([a-z0-9\.\-_]+)\/([^\s<>\"\']{1,})([^\s<>\"\']{20,20}))/i';
  $replace[] = '\\1<a href="\\2" target="_blank">\\3://\\4/...\\6</a>';
  $patt[] = '/([^["]]|\r|\n|\s|\t|^)((ftp|https?):\/\/([^\s<>\"\']+))/i';
  $replace[] = '\\1<a href="\\2" target="_blank">\\2</a>';
  $patt[] = '/(<a[^>]+>)(https?:\/\/[^\%<]+)([\%][^\.\&<]+)([^<]{5,})(<\/a>)/i';
  $replace[] = '\\1\\2...\\4\\5';
  $patt[] = '/[\r\n\t]+/';
  $replace[] = '';
  // ค่าที่ส่งมา
  $value = preg_replace($patt, $replace, htmlspecialchars(isset($_POST['value']) ? $_POST['value'] : ''));
  $user = htmlspecialchars(isset($_POST['user']) ? $_POST['user'] : '');
  $count = intval(isset($_POST['count']) ? $_POST['count'] : 20);
  // file
  $chat = './datas/chat.php';
  // ข้อมูลแชต
  $result = array();
  if (is_file($chat)) {
    // อ่านไฟล์
    $list = file($chat);
    // จำกัดจำนวนบรรทัดที่จัดเก็บ
    --$count;
    $l = sizeof($list);
    for ($i = $l - 1; $i > 0; --$i) {
      if ($count > 0) {
        --$count;
        array_unshift($result, trim($list[$i]));
      }
    }
  }
  // เพิ่มข้อมูลใหม่ลงรายการสุดท้าย
  $result[] = '<li><strong>'.$user.'</strong><time>'.date('d M H:i').'</time><p>'.$value.'</p></li>';
  // บันทึกข้อมูลลงไฟล์
  $f = @fopen($chat, 'wb');
  if ($f) {
    fwrite($f, "<?php exit; ?>\n".implode("\n", $result));
    fclose($f);
  }
}

คำอธิบายโค้ดอยู่ในโค้ดแล้วนะครับ หลักการก็คือรับข้อความที่โพสต์มาจาก Ajax แล้วทำการบันทึกลงในไฟล์ chat.php โดยมีการจำกัดจำนวนบรรทัดที่จัดเก็บเอาไว้ไม่เกิน 20 บรรทัด โดยข้อความที่ส่งมา รองรับการใช้งาน BBCode บางตัว และมีการป้องกันอักขระพิเศษไว้แล้ว

สำหรับผู้ที่มีปัญหา เวลาแสดงไม่ตรงให้แทรกคำสั่งนี้ลงในไฟล์ save.php ก่อนบรรทัด BBCode
<?php
// สำหรับปรับให้เวลาของ Server ตรงกับเวลาท้องถิ่น
@date_default_timezone_set('Asia/Bangkok');
// BBCode
.........