ทำยังไง? อยากให้ JavaScriptเรียกฟังก์ชันในภาษา PHPเขียนโค้ดยังไงนะ

หนึ่งในคำถามที่เว็บโปรแกรมเมอร์มือใหม่ถามกันเยอะมากจนน่าจัดเก็บไว้เป็น FAQเลยก็คือ
"จะทำยังไงให้เราเรียกใช้ฟังก์ชันภาษา PHPจากสคริป JavaScriptได้"
เช่นแบบนี้...
<button onclick="<?php functionInPhp1(); ?>">
    คลิกฉันสิ!
</button>
หรือแบบนี้...
function functionInJs(){
    let x = <?php functionInPhp2(); ?>
}
คำตอบคือ ด้วยการทำงานของเว็บที่ทำงานบนโปรโตคอล httpนั้น...มันทำไม่ได้!! (แต่มีวิธีแก้ ถ้าอยากทำจริงๆ อ่านต่อไป!)

จริงๆ แล้วไม่จำกัดว่าต้องเป็นภาษา PHP เท่านั้นนะ เคสนี้เป็นกับทุกภาษาฝั่งเซิร์ฟเวอร์เลย


เพื่อจะตอบว่าทำไมมันทำไม่ได้ เราจะต้องอธิบายการทำงานของ httpกันซะก่อน

httpและ 무국적


httpเป็นโปรโตคอลมาตราฐานสำหรับการเขียนเว็บ ซึ่งการทำงานของมันสรุปง่ายๆ ได้ดังนี้

โปรโตคอล (Protocol) = กฎที่ตั้งขึ้นมาเพื่อให้คอมพิวเตอร์ในเน็ตเวิร์คสามารถคุยกันด้วยภาษาเดียวกัน ไม่งั้นมันจะคุยกันไม่รู้เรื่อง


  • 고객ส่งคำขอหรือ request ไปหา 서버
  • เมื่อ 서버ได้รับ request แล้วก็จะรันสคริปที่เตรียมไว้ เพื่อหาว่าจะตอบอะไรกลับไปให้ 고객ในสเต็ปนี้ อาจจะมีการเชื่อมต่อเพื่อขอข้อมูลจาก 데이터베이스ด้วย
  • หลังจาก 서버คิดเสร็จ ก็จะส่งคำตอบ (อยู่ในรูปแบบของ 문자열)กลับไปให้ 고객มาถึงตรงนี้ถือว่า 서버ทำงานเสร็จแล้ว!]
  • 고객รับข้อมูลไป (ส่วนใหญ่จะอยู่ในรูปแบบ html)ก็เอาไปแสดงผล แต่ถ้ามีการแนบสคริปมาด้วย ก็จะจัดการรันสคริปตัวนั้นซะในสเต็ปนี้
  • จบจ้า!

  • สำหรับฝั่ง 고객นั้นไม่ค่อยมีปัญหาเพราะมีแค่ภาษาเดียวเท่านั้นที่ครอบครองอยู่ นั่นคือ JavaScriptแต่ฝั่ง 서버นี่มีหลายภาษามากๆ เช่น PHP, 노드js.가다순액
    แต่ไม่ว่าฝั่งเซิร์ฟเวอร์จะเขียนด้วยภาษาอะไร หน้าที่ของมันคือส่ง HTML、CSS、JSกลับมาให้ 고객เพื่อโปรเซสต่อ
    จะเห็นว่า httpเป็นโปรโตคอลง่ายๆ ถามมา-ตอบกลับ แล้วก็จบงาน
    ซึ่งเราเรียกการทำงานแบบนี้ว่า 상태 없음คือทำงานเป็นรอบ พอเรียกใช้งานและทำงานนั้นเสร็จแล้ว ก็จบการทำงาน (เว็บส่วนใหญ่ทำงานแบบนี้)
    ตรงข้ามกับ "상태 있어요".ที่ตัวโปรแกรมรันค้างอยู่ตลอดเวลา (ให้นึกถึงแอพพลิเคชันมือถือหรือโปรแกรมที่รันใน 데스크톱)

    서버ทำงานก่อน 고객เสมอ!


    เราอธิบายให้ฟังแล้วว่า httpนั้นเริ่มทำงานที่ 서버รันเพื่อโปรเซสข้อมูลที่จะส่งกลับมาให้ 고객ก่อน ... แล้วพอ 고객ได้รับข้อมูล (ซึ่งอาจจะมี JavaScriptแนบติดมาให้ด้วย) ก็จะเอาสคริปตัวนั้นมารันต่อ
    แสดงว่าในจังหวะที่ 고객เริ่มทำงานนั้น ... โค้ดฝั่ง 서버ทำงานเสร็จไปแล้ว !
    นี่เลยเป็นเหตุผลว่าทำไมเราไม่สามารถทำให้ JavaScriptเรียกให้ PHPทำงานได้
    เช่น
    <?php
        function registerMeeting(){
            //ต้องการบันทึกว่าเข้าร่วมประชุมแล้ว
        }
    
        function getOnlines(){
            //ต้องการดึงรายชื่อคนที่กำลังออนไลน์อยู่ในขณะนี้
        }
    ?>
    
    <button onclick="<?php registerMeeting(); ?>">
        ลงชื่อเข้าประชุม
    </button>
    
    <script>
        function getWhoOnlineNow(){
            let onlines = <?php getOnlines(); ?>
        }
    </script>
    
    ในโค้ดตัวอย่างนี้เรามีฟังก์ชันในภาษา PHPอยู่ 이.ตัว คือ registerMeeting() และ getOnlines()จากนั้นเราไปเขียนโค้ด JavaScriptเพื่อเรียกใช้งานฟังก์ชัน PHPทั้งสองตัวนี้ต่อ
    แต่ปัญหาก็คือ PHPเป็น 서버 측 스크립트มันทำงานก่อนเสมอ (ไม่ต้องรอให้ JavaScriptเรียกหรอก ฉันทำงานเองตอนนี้เลย!)
    แต่ด้วยโลจิคแล้ว เราต้องการให้ฟังก์ชันพวกนี้ทำงานเมื่อเรามี 이벤트เท่านั้น (เชื่อ ปุ่มโดน onclick 회사หรือฟังก์ชัน JavaScriptทำงาน)
    ดังนั้นโค้ดนี้เลยผิด!

    비동기คือทางแก้


    หากต้องการให้ JavaScriptเรียกให้ PHPทำงานได้ มีอยู่วิธีเดียวนั้นคือใช้เทคนิคการเขียนโปรแกรมแบบ 비동기
    หรือถ้าจะเรียกด้วยชื่อแบบดังเดิมคือเทคนิคที่เรียกว่า Ajax(비동기식 JavaScript 및 XML)...แต่ปัจจุบันไม่ค่อยเรียกชื่อนี้กันแล้วนะ และเราก็ไม่ได้ใช้แค่ XMLเป็นตัวกลางส่งข้อมูลกันอีกตัวไป มีการใช้ JSONเพิ่มเข้ามาด้วย

    ในบทความนี้จะไม่สอน Ajax แบบละเอียดนะ ถ้าอยากรู้ตามไปอ่านได้ที่ Ajax คืออะไร แล้วมันใช้ยังไง?


    สำหรับ PHP...
    ให้แยกโค้ดส่วนที่ต้องการให้ JavaScriptเรียกใช้งานได้ออกมาอยู่อีกไฟล์หนึ่ง เช่นกรณีนี้ตั้งชื่อไฟล์ว่า async-handler.php
    FILE: async-handler.php
    
    <?php
    function registerMeeting(){
        //ต้องการบันทึกว่าเข้าร่วมประชุมแล้ว
    }
    
    function getOnlines(){
        //ต้องการดึงรายชื่อคนที่กำลังออนไลน์อยู่ในขณะนี้
    }
    
    switch($_GET['action']){
        case 'register-meeting': 
            registerMeeting(); 
            break;
        case 'get-online-user': 
            getOnlines(); 
            break;
    }
    
    และเนื่องจากเรามี 행동ที่ต้องการให้ทำงานมากกว่า 일.ตัว ก็เลยใช้ 질의 문자열ชื่อว่า action เป็นตัวแยกว่า 요구 사항ครั้งนี้ต้องการให้ฟังก์ชันไหนทำงาน (ตรงนี้ตั้งชื่อว่าอะไรก็ได้นะ แล้วแต่เลย)
    <button onclick="registerMeeting()">
        ลงชื่อเข้าประชุม
    </button>
    
    <script>
        function registerMeeting(){
            fetch('/async-handler.php?action=register-meeting')
        }
    
        function getWhoOnlineNow(){
            fetch('/async-handler.php?action=get-online-user')
            .then(onlines => {
                ...
            })
        }
    </script>
    
    จากนั้น ในฝั่ง JavaScriptก็ใช้การ 요구 사항กลับไปยังไฟล์ 필리핀 페소async-handler.phpที่เตรียมไว้อีกรอบ จะใช้คำสั่ง fetch() หรือไลบรารี่ Axios 회사หรือถ้าเก่าหน่อยก็ใช้ $.ajax() ของ jQueryก็ตามสะดวกเลย

    สรุป


    การจะให้ JavaScriptเรียกคำสั่ง PHPตรงๆ นั้นทำไม่ได้ เพราะกว่า JavaScriptจะเริ่มทำงาน PHPก็ทำงานจนเสร็จไปก่อนแล้ว

    แต่มีวิธีการแก้ทางคือสร้าง 요구 사항ขึ้นมาอีกครั้งเพื่อเรียกไปหา 서버ให้ปลุก PHPขึ้นมาทำงานอีกรอบหนึ่ง
    คือต้อง 요청 2ครั้ง
  • ครั้งแรก - ให้ 서버ส่ง HTML、CSS、JSมาให้ก่อน
  • ครั้งที่สอง - JavaScriptสร้าง 요구 사항อีกครั้ง เรียกไปยังไฟล์ PHPที่เตรียมเป็น 비동기식 프로세서เอาไว้
  • 좋은 웹페이지 즐겨찾기