מדריך MongoDB: שימוש ב-MongoDB עם PHP

התחברות באמצעות PHP אל MongoDB ועבודה איתו.

במאמר הקודם דיברנו על ייבוא ויצאו של MongoDB. עד עכשיו בכל המאמרים הקודמים דיברנו על MongoDB באופן אגנוסטי – כלומר איך להפעיל אותו באופן ישיר מהקונסולה. אך בעולם האמיתי אנחנו משתמשים בשפת תכנות כלשהי על מנת לתפעל את מסד הנתונים. וזה לא משנה אם מדובר ב-PHP או JAVA או node.js ושפות אחרות. בסופו של יום אנחנו משתמשים בשכבה כלשהי של אבסטרקציה.
מה הטעם ללמוד MongoDB? כי גם שכבת האבסטרקציה מחייבת אותנו לדעת את הסינטקס של הפקודות, כי שום שכבת אבסטרקציה לא תציל אותנו אם נצטרך לתכנן את מסד הנתונים שלנו, כי תמיד משהו משתבש ואז אנחנו צריכים לבדוק את הקונסולה. וגם עם MySQL ו-וורדפרס (לצורך העניין) ששם יש אבסטרקציה של וורדפרס על האבסטרקציה של PHP MySQLi – יצא לי לא מעט פעמים לבחון את השאילתה מול הקונסולה של MySQL כאשר דברים התחרבשו.

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

ולעניין שלנו. עבודה עם PHP ו-MongoDB היא קלה ביותר. לשם כך אנו זקוקים ל MongoDB Class.

נכון לכתיבת שורות אלו, ה-Mongo Extension שאנו זקוקים לו על מנת לעבוד עם Mongo לא מגיע באופן דיפולטיבי עם PHP ויש להתקינו. כך מתקינים אותו על לינוקס:

ראשית חשוב לציין שאתם צריכים את php5-dev package. אם אין לכם אותה, כדאי להתקין אותה באמצעות:


apt-get install php5-dev

החבילה הזו פשוט מאפשרת לקמפל מחדש את PHP עם מודולים חדשים. אחרי שהתקנו אותה אנחנו יכולים להתחיל בהתקנה. הוראות ההתקנה מפורטות בדוקומנטציה של PHP. אני רק מעתיק משם את הוראות ההתקנה שלהם לאובונטו (ושאר הדביאנים)


sudo pecl install mongo

אחרי כן יש צורך להכניס את השורה הבאה ל-php.ini שלכם, באיזור של Dynamic Extensions:


extension=mongo.so

לא לשכוח לעשות ריסטארט ל-apache על ידי:


sudo /etc/init.d/apache2 restart

איך יודעים אם זה מותקן? משתמשים בפקודת php_info על מנת לראות את כל המודולים שמותקנים. אם הכל תקין, תוכלו לראות שם את "mongo" – כולל כל הפרטים. אפשר להשתמש גם ב:


print extension_loaded("mongo") ? "Loaded\n" : "Not Loaded\n";

אפשר להתקין כמובן את Mongo Extension על PHP שרץ על חלונות. אבל שאלוהים יעזור ויציל – יש תועבות שעדיף לא לדבר עליהם פה. בכל מקרה יש בקישור של ההתקנות גם הסברים על איך להתקין על חלונות. אני הייתי מעדיף למות, אבל כל אחד והתחביבים שלו.

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

על מנת להתחבר (use) למסד נתונים מסוים, אנו צריכים לבצע instance ל-class באופן הבא:


$m = new Mongo(); 

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

אני יוצא מנקודת הנחה שיש לכם את ה-collection של מאה users שדיברנו עליו באחד המדריכים הקודמים. אם לא, אפשר ליצור אותו באופן הזה באמצעות העתק הדבק בקונסולה החביבה של MongoDB


function randomString() {
    var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
    var randomstring = '';
    var string_length = 100 + Math.floor(Math.random() * 200);
    for (var i = 0; i < string_length; i++) {
        var rnum = Math.floor(Math.random() * chars.length);
        randomstring += chars.substring(rnum, rnum + 1);
    }
    return randomstring;
}
for (var i = 0; i < 100; i++) {
    db.clients.insert({
        x: i,
        name: randomString(),
        value: _rand() * 100
    });
}

אחרי כל ההכנות וההתקנות – הגיע הזמן לכתוב מעט קוד PHP. כל הדוגמאות שאני מציין כאן מבוססות על המדריך הנהדר של PHP ל-Class המדובר. שווה להציץ בו.

על מנת ליצור שאילתה בסיסית, כל מה שאני צריך זה לעשות use test (שזה מסד הנתונים שלי) ולבצע שאילתת find פשוטה. הנה דוגמה:


<?php 
try 
{
    $m = new Mongo(); // connect
    $db = $m->selectDB("test");
    $collection = $db->users;
	$cursor = $collection->find();

	// iterate through the results
	foreach ($cursor as $document) {
	    echo $document["name"] . "\n";
	}

}
catch ( MongoConnectionException $e ) 
{
    echo '<p>Couldn\'t connect to mongodb, is the "mongo" process running?</p>';
    exit();
}

שימו לב שהקוד הזה עטוף ב-try-catch. אני בדרך כלל לא אוהב לסבך את הקוד במדריכים שלי, אבל הפעם כן שמתי כזה קוד. למי שלא יודע – פשוט לקרוא את מה שיש ב-try.

בהתחלה יצרתי חיבור ל-MongoDB. במקרה הזה לא העברתי ארגומנטים לחיבור כי הכל על הסביבה הלוקלית שלי. אם התקנתם את הסביבה כפי שהסברתי במאמר הראשון בסדרת המדריכים, גם אתם לא תצטרכו להעביר ארגומנטים. ובכל מקרה הארגומנטים האלו לא מאוד מסובכים. אחרי כן בחרתי מסד נתונים – מקבילה ל use db. אחרי כן ממסד הנתונים בודדתי את ה-collection וביצעתי עליו את שאילתת ה-find. נכון לעכשיו ללא פרמטרים.

קטע הקוד המעניין הוא זה:


	$cursor = $collection->find();

	// iterate through the results
	foreach ($cursor as $document) {
	    echo $document["name"] . "\n";
	}


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

אם אני רוצה להכניס פרמטרים ל-find (ותמיד צריך) אז זה עובד בשיטה הזו:


<?php 
try 
{
    $m = new Mongo(); // connect
    $db = $m->selectDB("test");
    $collection = $db->users;

    $query = array( 'x' => 18 );

	$cursor = $collection->find($query);

	// iterate through the results
	foreach ($cursor as $document) {
	    echo $document["name"] . "\n";
	}

}
catch ( MongoConnectionException $e ) 
{
    echo '<p>Couldn\'t connect to mongodb, is the "mongo" process running?</p>';
    exit();
}


אני מעביר query שהיא בעצם מערך. במקרה הזה ה-query מבקש את המשתמש שה-x שלו הוא 18. זה מקביל ל:


db.users.find({"x":18})

ואם אני רוצה לכתוב שאילתה שמשתמשת בפרמטרים נוספים? כמו gt$? למשל כל אלו שיותר גדולים מ-18? אם כך, ה-query שלי יראה ככה:


    $query = array( 'x' => array( '$gt' => 18 )  );

ואם אני רוצה לשלב כמה תנאים (כמו למשל למצוא משהו בטווח מסוים) אז אני אשתמש ב:


$query = array( 'x' => array( '$gt' => 20, "$lte" => 30 )  );

ובתנאים מורכבים יותר אני פשוט אוסיף עוד איבר למערך.

עד כאן בנוגע לקריאה, מה עם יצירה? גם זה קל:


<?php 
try 
{
    $m = new Mongo(); // connect
    $db = $m->selectDB("test");
    $collection = $db->users;

    $doc = array(
    "name" => "Ran",
    "x" => 9999
	);

	$collection->insert( $doc );

}
catch ( MongoConnectionException $e ) 
{
    echo '<p>Couldn\'t connect to mongodb, is the "mongo" process running?</p>';
    exit();
}


קודם יוצרים את ה-document ואז מכניסים אותו.

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

במאמר הבא אנו נדבר על MongoDB עם node.js.

פוסטים נוספים שכדאי לקרוא

עבודה בהיי טק

איך מראיינים סניורים?

השיטה שלי לבדיקת התאמה טכנית למתכנתות ולמתכנתים בכירים עם כמה שנות ניסיון.

פיתוח ב-JavaScript

Axios interceptors

תכנון נכון של קריאות AJAX באפליקציה ריאקטית וניהול השגיאות או ההצלחות עם פיצ׳ר נחמד של axios

פתרונות ומאמרים על פיתוח אינטרנט

המנעו מהעלאת source control לשרת פומבי

לא תאמינו כמה אתרים מעלים את ה-source control שלהם לשרת. ככה תמצאו אותם וגם הסבר למה זה רעיון רע.

צילום מסך של סוואגר
יסודות בתכנות

openAPI

שימוש בתשתית הפופולרית למיפוי ותיעוד של API וגם הסבר בסיסי על מה זה API

גלילה לראש העמוד