פונקציית תבניות של עשר שורות היא כל מה שאתר קטן צריך
כל פרויקט PHP מגיע בסופו של דבר לנקודה שבה צריך להפריד בין HTML ללוגיקה, ובנקודה הזו רוב האנשים שולחים יד לספריית תבניות. Smarty, Twig וקרוביהן הן תוכנות טובות. הן גם שפה שנייה ללמוד, שלב קומפילציה, ספריית מטמון שצריך להשאיר ניתנת לכתיבה, וכמה אלפי שורות קוד ביניכם לבין העמוד. לאתר קטן דבר מזה אינו נחוץ, מפני ש-PHP כבר היא שפת תבניות. כל מה שחסר הוא פונקציה שמשתמשת בה ככזו.
הפונקציה
<?php
function render($template, array $vars = array())
{
extract($vars, EXTR_SKIP);
ob_start();
include $template;
return ob_get_clean();
}
זה כל הדבר. הוא עושה שלוש עבודות.
extract() הופכת את מפתחות המערך למשתנים מקומיים, כך שתבנית יכולה לומר $title במקום
$vars['title']. הדגל EXTR_SKIP אומר שמפתח בשם template אינו יכול לדרוס את הפרמטר של
הפונקציה עצמה.
ob_start() מפעילה חציצת פלט, כך שכל מה שהתבנית מדפיסה נלכד במקום להישלח לדפדפן.
include מריצה את קובץ התבנית כ-PHP רגיל עם המשתנים האלה בתחום, ו-ob_get_clean() מחזירה את
הפלט שנלכד כמחרוזת ומכבה את החציצה.
תבנית
תבניות הן קובצי PHP פשוטים שמכילים בעיקר HTML:
<h1><?php echo htmlspecialchars($title); ?></h1>
<ul>
<?php foreach ($items as $item): ?>
<li><?php echo htmlspecialchars($item); ?></li>
<?php endforeach; ?>
</ul>
התחביר החלופי למבני בקרה (foreach ... endforeach, if ... endif) קיים בדיוק לשימוש הזה. הוא
נקרא כתבנית ולא כקוד, ומילות הסיום שומרות על הקינון גלוי כשתגים משולבים בתוך סימון.
שימוש
<?php
$page = render('templates/list.php', array(
'title' => 'Things I own',
'items' => array('a bicycle', 'a piano', 'too many books'),
));
echo render('templates/layout.php', array(
'title' => 'Things I own',
'body' => $page,
));
תבניות מקוננות על ידי רינדור הפנימית למחרוזת והעברתה לחיצונית כמשתנה. תבנית פריסה מדפיסה את $body
במקום שאליו הולך התוכן. זה נותן לכם את התכונה האחת שאנשים באמת רוצים ממנוע תבניות, מסגרת עמוד
משותפת, בלי מנוע.
בריחה מתווים
הדבר האחד שמנוע תבניות נותן לכם והפונקציה הזו אינה נותנת הוא בריחה אוטומטית מתווים, וזה הדבר האחד
שאסור לכם לשכוח. כל ערך שהגיע מחוץ לתוכנית עובר דרך htmlspecialchars() לפני שהוא מודפס.
להקליד את זה מייגע, אז הגדירו כינוי קצר:
<?php
function e($s)
{
return htmlspecialchars($s, ENT_QUOTES, 'UTF-8');
}
וכתבו <?php echo e($title); ?>. התבנית שלמעלה נעשית קצרה יותר והכלל נעשה קל לביקורת: כל echo
בלי e() סביבו הוא באג, אלא אם ידוע שהמשתנה הוא HTML שאתם ייצרתם בעצמכם, כמו $body בפריסה.
מדוע זה מספיק
מנוע תבניות מצדיק את משקלו כשמעצבים שאינם יודעים PHP עורכים את התבניות, כשהתבניות מגיעות ממקור לא מהימן וצריך לבודדן, או כשאותן תבניות מרונדרות על ידי משהו שאינו PHP. לאתרים קטנים אין אף אחת מהבעיות האלה. האדם שעורך את התבנית הוא האדם שכתב את הפונקציה.
מה שעשר השורות נותנות לכם הוא בדיוק מה שהמנוע נותן במקרה הרגיל: HTML בקבצים שלו, לוגיקה בקבצים שלה, משתנים שמועברים במפורש על פני הגבול, ופריסות באמצעות קינון. מה שהן עולות לכם הוא כלום. אין תחביר ללמוד מעבר לשפה שאתם כבר משתמשים בה, אין מטמון לפסול, וכשמשהו משתבש עקבות המחסנית מצביעות על שורה בקובץ שאתם יכולים לקרוא.
השתמשתי בפונקציה הזו, או באחת שאינה ניתנת להבחנה ממנה, בכל אתר PHP קטן שבניתי. מעולם לא נזקקתי להחליף אותה.