האתר של יוחאי

מוזמנים להכנס (:

הבנתי איך לקבל body של fetch request ב-PHP. סוף סוף

הרבה מאוד זמן אני מסתבך עם בקשות fetch ה-API העדכני של JS לבקשות HTTP. ואני לא מבין למה.

ההזדמנות

הזדמנות מצויינת נקריתה בדרכי כהתבקשתי לכתוב טופס פשוט ללקוח, הטופס פשוט אבל האינטגרציה היא העניין. בתמצית העניין, פרטי הטופס צריכים להישלח ל-DB של הלקוח ולהישמר שם בצורה מסויימת. לא משהו חריג בנוף התיכנותי מאז… ומתמיד בערך.

אני מתכנת בעיקר ב-PHP על WordPress ושם גם הלקוח היה צריך אותי (מאוד הגיוני). האתר של הלקוח היה מבוסס על וורדפרס, ושם הטופס היה קיים. השרת של האתר שעליו מותקן וורדפרס, צריך לשלוח ולקבל נתונים.

הרקע

הדרך לעשות את זה בוורדפרס היא באמצעות הוק מובנה wp_ajax בתשלובת עם פונקציית ajax שנורית היישר מהלוע המאסיבית של jQuery. אממה (נקרא: אמה-מה) אני רוצה להפחית את השימוש שלי בפריימוורקים (למעט וורדפרס כמובן) ולכן אני רוצה להשתמש בפונקציית ה-JS המובנית fetch() הנ״ל.

כמו רוב הבעיות בקוד שאני כותב, מקורן בחוסר הידע שלי בנושא המיועד. וגם עם fetch, לא הבנתי לעומק -והאמת שעדיין לא- את כל רזי הממשק התוכנתי היישומי שלו. למשל, מה ההבדל בין application/json לבין application/x-www-form-urlencoded ב-header של content-type. ועוד יותר לא הבנתי למה כשאני שולח ל-wp_ajax בקשת fetch עם סוג התוכן הראשון אני מקבל כלום בפיתה בשרת שמקבל את הבקשה. אז כאשר ההזדמנות נקריתה, אמרתי לעצמי ״איזו הזדמות טובה לרדת לעומקו של העניין הזה שמציק לי כבר נצח, יאללה.״ אז יאללה.

אז כדי להבין את הסיפור צריך לחזור על הרקע, מדובר בפריימוורק ה-PHP הנודע WordPress, ובפונקציה מקומית fetch משפת ה-JavaScript. המשמעות של זה היא שאני מפתח שמכיר PHP, אבל PHP של וורדפרס, ואני יודע JS, אבל לא בונה אפליקציות איתה, היא באמת שפת סקריפטים בשבילי. רוב הקוד שאני כותב מאוזן יפה בין HTML, CSS, JS וכל השאר PHP. ולכן לא הכרתי לעומק את fetch, ולא בקשות HTTP באופן כללי, במיוחד לא סוגי תוכן של בקשות אלו. עכשיו, חשוב לציין שהסיבה שכלכך רציתי לשלוח JSON במקקרה הזה היא שהטופס מורכב מכמה שדות שניקלטים במערך, וממש לא נוח לשלוח מערך כ-URLSearchParams כדי להעביר מידע בין הטופס לשרת.

הבעיה

אז מה הבעיה? שלחתי JSON כסוג תוכן, אבל כלום לא הגיע בצד השני, עם x-www-form-urlencoded זה קל, ב-PHP הכל מרוכז בכמה סופר-גלובלס ובניהם $_POST, אז אני שולף ממנו את הפרמטרים ששלחתי וזהו נגמר הסיפור. אבל כששולחים JSON, ב-$_POST אין כלום, הוא אפילו לא מוגדר. גם ב-$_REQUEST לא מצאתי משהו רללונטי, וב-$_SERVER פחדתי להסתכל.
אז מה עושים? מחפשים בגוגל, ברור. כותבים בצ׳אט ג׳יפיטי (או באלטרנטיבה מעולה) כמובן. מגששים.

הפתרון!

אז הרבה זריקות חכה שהעלו נעלה ישנה שלא רלוונטית לא לפתרון ולא למילוי כרס מטאפורי, עלה איזה קרפיון חלקלק בחכה בדמות:

<?php
add_action('wp_ajax_your_ajax_action', 'your_ajax_handler');
add_action('wp_ajax_nopriv_your_ajax_action', 'your_ajax_handler');
function your_ajax_handler() {
$body = json_decode(file_get_contents('php://input'), true);
// Access the data sent in the request body
$data = $body['data'];
// Perform further processing with the data
// …
// Send the response
wp_send_json_success('Request received successfully');
}

בוא נדגיש את החלק המעניין:

$body = json_decode(file_get_contents('php://input'), true);

אני שנתיים עובד עם PHP ובחיים שלי לא ראיתי את הקוד הזה, ממש מסקרן. אבל עכשיו כשיש לי משהו ביד, אפשר לחפור עליו. אז קראתי באתר של PHP וקראתי גם קצת באיזה שאלה ב-Stack Overflow כראוי ובעוד כל מיני…
אז ככה PHP מקבל body של בקשה מסוג json, הא-הא!

הסיכום

וזהו בגדול, רק רציתי לשתף, זה היה מסע מרתק ומעניין ואני ממש מבסוט שאני כותב תוכנה לפרנסתי, להנאתי ולשקט הנפשי שלי.


הנוסף בזאת

באותו עניין, אבל אחר, למדתי גם איך להשתמש בקטנה בתגית הנחמדת <template>, אולי אכתוב עליה בהמשך.