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

כפי שניתן לראות בקובץ index.php בספריית השורש של האתר, שמובילה לקובץ בשם wp-blog-header, וורדפרס מחולקת ל-3 שלבים:
1. הליבה של וורדפרס, שמרוכזת בקובץ wp-load.php. במסגרת טעינת הליבה, מאותחל אינסטנס ריק של קלאס בשם WP ומאוחסן כמשתנה גלובלי.
2. פונקציה בשם wp() שמאתחלת את האינסטנס הזה (או יותר נכון מריצה פונקציה בשם main).
3. template loader – הפרונט-אנד של האפליקציה

רגע לפני ששלב 1 נגמר קורים כמה דברים:
א. וורדפרס מתוודע לספריית functions.php שבתבנית הפעילה. לצורך העניין, ה-Model נכנס לפעולה. כאן מרוכזים כל ההוקים שלנו, שיכנסו לאקשנים ופילטרים בהמשך האפליקציה.
ב. וורדפרס מצהיר: עשיתי את שלב א', ואני כעת בשלב שנקרא: after_setup_theme.
ג. וורדפרס מתוודע למשתמש שהריץ את הסקריפט הנוכחי. אם ישנו קוקי, הוא מזהה אותו. אם לא, הוא מצהיר שמדובר במשתמש אנונימי.
ד. וורדפרס מצהיר: סיימתי את על מה שאני צריך לעשות, בואו נצא לדרך. השלב: init. ולאחריו wp_loaded.

השלב הזה חשוב רק מפני שהוא מאפשר לנו בעצם להשתיל עבור שלב 2, הגדרות מראש. כמו לדוגמה:
א. אל תנסה להתעכב על השלב הידוע של WP_Rewrite.
ב. נהל בעצמך את ההדרים (headers) שתשלח בחזרה בתשובת ה-HTTP.
ג. אל תנסה לנצל את מערך ה- query vars לטובת בניית שאילתא.
ד. אם אתה מעוניין להפטר מהעזרה של ה- query flags, פשוט תעשה את זה.

במילים אחרות, הפונקציה WP::main() כוללת ארבעה שלבים, שבהתאמה מקבילים לסעיפים א'-ד' בפסקה הקודמת
א. $this->parse_request($query_args); הפונקציה משתמשת במנגנון WP_Rewrite כדי להרכיב את מערך משתני השאילתא (query vars)
ב. $this->send_headers(); בהתאם למשתני השאילתא הפונקציה מנבאת מה ההדרים שמתאימים לכל מצב.
ג. $this->query_posts(); מערך משתני השאילתא מעובד לשאילתא אקטואלית לדאטהבייס, הדאטהבייס מחזיר מערך של תוצאות.
ד. $this->handle_404(); בהתאם לתוצאות, ובעיקר אם התוצאות הן "אין שום דבר שמתאים לבקשה שלך", האפליקציה מנתחת את מה שהתקבל ומחליטה לאיפה לשלוח את המשתמש.

מחזור חיים של אפליקציית וורדפרס רגילה עובר בכל ארבעת השלבים האלה ובסופו של דבר עם סיום שלב 2, יודע:
א. מה המשתמש ביקש לקבל
ב. מה קיבל בפועל
ג. מה אמור להיות מוצג לו

כאן נכנס שלב 3 לתמונה. נניח, התקבלה מהכתובת המסקנה שהמשתמש ביקש לקבל עמוד בשם xxxx, ונמצא הפוסט המתאים. האפליקציה תנותב (כלומר, controlled) לקובץ בשם single.php, והטמפלייט שם (ה- View) יפרוש את המידע שנתקבל לטובת פלט html יאה. הוא ישלח ביחד עם ה- headers דלעיל למשתמש בחזרה, והעמוד המבוקש יתקבל ויוצג.

למחזור חיים שכזה יש כמה מגבלות: וורדפרס אוהב לעבוד עם מבנה הדאטהבייס שלו. WP_Query בונה שאילתות שדולות מידע מטבלת wp_posts ונספחיו (מטא, טקסונומיות וכו'). התוצאה תתקבל בצורה של פוסטים, כלומר אובייקטים של WP_Post. ה- flags גם הם ידברו בשפה שוורדפרס מכיר, posts, שפה של CMS. ברגע שרוצים לבנות ישויות מידע שאינן מעולם ניהול התוכן נאלצים אותן כמעין ישויות תוכן, ולהשתמש בטבלת wp_posts ונספחיה. הדבר גורם לבזבוז של מקום. שכן, רבות מהעמודות שיש גם כך בטבלת wp_posts לא נמצאות בשימוש, וטלעומת זאת רבים מפריטי המידע שיש בהם צורך מוגדרים כשדות מטא, ומאכלסים את הטבלה wp_postmeta.

המצב שמתקבל הוא: כל רכיב מידע משתמש לרוב ב-5 עמודות מתוך 15+ ב- wp_posts, וכל שאילתא שתצטרך לדלות מידע על פי מטא תבצע שאילתא לא אופטימלית לדאטהבייס. שתי השלכות מיידיות לדבר: הראשונה, טבלת wp_posts תופחת למרות שחצי ממנה חסר שימוש. השניה, והיותר חשובה, הטבלה wp_postmeta תופחת, ובשל כך ביצועי האתר נפגעים. כל ישויות המידע יאוחסנו בשתי הטבלאות האלה, ומהר מאוד מגיעים למצב שמידע טריוויאלי שרוצים לדלות משילוב של שתי הטבלאות האלה (ומבוצע כזכור בכל טעינה של כל עמוד בוורדפרס) עובר דרך חתחתים ארוכה ואיטית עד שמתקבל מידע.

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

איך ניתן להמנע מזה?

אם מעוניינים להפטר ב- WP_Rewrite.

add_filter( 'do_parse_request', 'give_up_wprewrite', 1, 3 );

function give_up_wprewrite( $continue, WP $wp, $extra_query_vars ) {
	$wp->query_vars=array();
	return false;
}

ניתן כמובן להיעזר בקלאס הזה בכל זאת, לטובת בניית מערך משתני שאילתא שישמשו לצרכים אחרים.

אם רוצים לשלוט ב- headers ניתן להשתמש בפילטרים wp_headers ו- send_headers.

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

add_filter('posts_pre_query',function($something,$wp_query){
	return array();
},10,2);

כדי להמנע מהשלב האחרון, שיתן לי תמיד 404 עבור שאילתה שלא צייתה לחוקים הדפולטיביים של וורדפרס, כלומר מתן יחס לדגלים של השאילתא, אפשר פשוט להחזיר בפילטר pre_handle_404 תמיד true. או אם רוצים להשתמש בכל זאת במשתני השאילתא, אפשר לעשות מה שרוצים. העיקר שבמקרה שרוצים להמשיך "כמו שצריך", יוחזר תמיד סטטוס 200.

add_filter('pre_handle_404',function($continue, $wp_query){
        set_status(200);
	return true;
},10,2);

הלאה: אחרי שהחלטנו באיזה מנגנון ראוטינג אנחנו רוצים להשתמש יש לנו שתי ברירות:
א. לתת לוורדפרס להמשיך להתנהג כרגיל, בעזרת שלב 3 דלעיל.
ב. בשלב 2.ד. דלעיל, להזריק קונטרולר עצמאי משלנו ואז לשים בסופו exit().

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

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *