בדף הזה כל דרכי הקריאה מהמסד: ה-builder DB::query() שמחזיר אובייקט שאילתה, הקיצורים DB::get_val() ו-DB::get_all(), ו-SQL גולמי דרך DB::sql(). תראו מה כל אחד מקבל ומחזיר, איך כותבים תנאים, ואילו חלקים בשאילתה אינם עוברים escaping.
בעמוד הזה system/ הוא תיקיית הליבה הפרוסה (= api/core בריפו) ו-{admin} הוא CONFIG::$admin_url של האתר.
DB::query#
DB::query($table = "", $whereCond = [], $orderBy = "", $lang = "", $limit = null): DB_QUERY_OBJECT
| פרמטר | משמעות |
|---|---|
$table | שם הטבלה בלי CRM_ |
$whereCond | מערך עמודה => ערך, תנאי שוויון בלבד (ראו למטה) |
$orderBy | מחרוזת SQL גולמית, למשל "ord ASC, id DESC" |
$lang | מזהה שפה (CRM_platforms.id) לטבלאות _content. ריק = השפה הנוכחית (CONFIG::$lang) |
$limit | מחרוזת "offset,count", למשל "0,20" (ה-offset קודם) |
האובייקט שחוזר לא מריץ כלום עד שקוראים לאחת ממתודות הקריאה שלו:
| מתודה | מה היא עושה |
|---|---|
get_row() | מביאה את השורה הבאה ומחזירה אותה (וגם שומרת ב-$q->rows). false כשנגמרו |
get_all($key = false, $value = false) | מחזירה את כל השורות. עם $key המערך ממופתח לפי העמודה הזאת. עם $value נוסף, הערכים הם העמודה הזאת בלבד |
num_rows() | מספר השורות. מריצה את השאילתה מחדש |
affected_rows() | מספר השורות שהושפעו |
free_results() | משחררת את ה-statement |
// שורה אחת
$page = DB::query("pages", ["id" => 12])->get_row();
// לולאה
$q = DB::query("pages", ["noDelete" => 0], "ord ASC", "", "0,20");
while ($q->get_row()) {
echo $q->rows["id"];
}
// הכול, ממופתח לפי id
$byId = DB::query("pages", [], "ord")->get_all("id");
תנאי where#
מערך ה-where הוא שוויון בלבד, והכללים הם:
- המפתח
idמקבל אוטומטית את הקידומתtConf.(הטבלה הראשית). מפתחות אחרים נכנסים כמו שהם. - הערך
nullהופך ל-IS NULL. - ערך מספרי (
is_numeric) נכנס בלי גרשיים. - ערך שמתחיל בתו backtick נכנס גולמי, כהפניה לעמודה.
- כל ערך אחר הופך ל-
= '<escaped>'.
לכל תנאי אחר (>, LIKE, IN, OR) משתמשים במאפיין filter, מחרוזת SQL גולמית שהליבה עוטפת ב-AND (...):
$q = DB::query("pages");
$q->filter = "ord > 5 AND title LIKE '%" . DB::escape($search) . "%'";
$q->fields = "id, title";
$q->order_by = "id DESC";
$q->limit = "0,50";
while ($q->get_row()) { /* ... */ }
מאפיינים נוספים באובייקט: fields (ברירת מחדל "*"), group_by, lang, ו-BuildQuery() שמחזירה את מחרוזת ה-SQL שתורץ.
is_numeric("0501234567") הוא true, ולכן הערך נכנס כמספר בלי גרשיים ו-MySQL משווה אותו כמספר: האפס המוביל אובד. כדי להשוות מחרוזת ספרות כמחרוזת, השתמשו ב-filter עם גרשיים: $q->filter = "phone = '" . DB::escape($phone) . "'".fields, filter, order_by, group_by, limit, שמות המפתחות של מערך ה-where, וערכים שמתחילים ב-backtick נכנסים ל-SQL כפי שהם. קלט של משתמש שמגיע לאחד מהם (למשל ?sort= שהופך ל-order_by) הוא SQL injection. אמתו מול רשימה לבנה, או העבירו DB::escape() ושימו בגרשיים בעצמכם. ראו SQL injection.DB::get_val#
DB::get_val($tblName, $filter = "", $rowName = "")
קיצור לשורה אחת או לערך אחד. $filter יכול להיות:
| סוג | משמעות |
|---|---|
| מערך | תנאי שוויון מחוברים ב-AND |
| מספר | id |
| מחרוזת לא ריקה | SQL גולמי שמשמש כתנאי |
| ריק | מחזירה false |
אם נתתם $rowName, מוחזר ערך העמודה הזאת, אחרת כל השורה. אין שורה מתאימה: false. השאילתה משתמשת ב-limit "0,1".
$version = DB::get_val("params", ["sysName" => "attaches_version"], "value");
$row = DB::get_val("pages", 12);
DB::get_val("pages", $_GET["x"]) עם מחרוזת מהמשתמש מזריק אותה ישירות ל-SQL. העבירו מערך (["id" => ...]) או מספר מאומת.DB::sql, DB::get_all, DB::get_row#
DB::sql($sql) // PDOStatement
DB::get_all($res, $key = NULL, $val = NULL) // array
DB::get_row($res, $return_key = false) // array | false | ערך
כאן שמות הטבלאות עם CRM_. get_all ו-get_row מקבלות או מחרוזת SQL או statement ש-DB::sql החזירה.
$platforms = DB::get_all("SELECT * FROM CRM_platforms", "domain"); // ממופתח לפי domain
$names = DB::get_all("SELECT id, name FROM CRM_platforms", "id", "name"); // id => name
$one = DB::get_row("SELECT * FROM CRM_pages WHERE id = " . (int)$id);
$title = DB::get_row("SELECT title FROM CRM_pages_content WHERE parentId = 12 LIMIT 1", "title");
כש-$res הוא מחרוזת, get_row מריצה את ה-SQL בכל קריאה. לכן while ($r = DB::get_row("SELECT ...")) {} לא נגמר לעולם. לולאה כותבים כך:
$res = DB::sql("SELECT id FROM CRM_pages");
while ($r = DB::get_row($res)) { /* ... */ }DB::escape#
DB::escape($str)
משתמשת ב-PDO::quote ומקלפת את הגרשיים החיצוניים, כך שהיא לא מוסיפה גרשיים. את הגרשיים מוסיפים אתם:
$sql = "SELECT * FROM CRM_pages WHERE title = '" . DB::escape($title) . "'";
לערכים מספריים עדיף (int) או (float). מחרוזת ריקה ו-NULL מוחזרות ללא שינוי.
שאילתה שנכשלת זורקת Exception עם ההודעה "<שגיאת הדרייבר> | <ה-SQL>", ולכן אפשר להיעזר בה בדיבוג. ראו דיבוג SQL.