מעבר מ-PHP ל – C# , ומ-Laravel אל ASP.NET MVC – רשמים ראשונים

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

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

ועכשיו לתכלס – ההבדלים העיקרים בין PHP ל- C# .

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

ה-Framework של C# מבית מיקרוסופט, נקרא ASP.NET MVC, וקיימת גם גירסה שונה שלו שמיועדת עבור API ונקראת WebAPI ( ניתנים לשילוב, אך בעיקרון – 2 מוצרים שונים).

והמקבילה בעולם ה-PHP שאיתה עבדתי בעיקר, הייתה ה-Framework המוביל כיום ב-PHP, שנקרא Laravel , גם אצלו קיימת גירסה ל-API שנקראת Lumen.

הבדלים ברמת מחיר :

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

הבדלים ברמת השפה – בין PHP ל- C# .

אז ההבדל העיקרי ביותר – הוא ש-C# מחייבת להצהיר על סוגי המשתנים, בניגוד ל-PHP.

מבחינת Syntax, השפות מאוד מאוד דומות, וכמעט אין הבדלים משמעותיים . נציין כמה הבדלים קטנים :

  • בהכרזה של namespace, ב-C# ,  צריך להכניס  את כל ה- קלאס תחתיו גם כן בתוך סוגרים מסולסלות { } .
  • המילה use מתחלפת במילה using.
  • אין triats ב-C#
  • יש  ב-C# משתנה מסוג List שעובד די יעיל ולא קיים ב-PHP ( יותר נכון, קיים, אך רק דרך תוספות)
  • יש מתודות מובנות ב- C# למחרוזות, מערכים , ועוד ( בסגנון של JS – שכל משתנה הוא אוביקט … רק הרבה יותר מתודות מובנות ) .
  • מימוש של Interface נעשה ב-C# עם נקודותיים, לעומת implements ב-php
  • במקום final עבור מתודות \ קלאסים שלא יורשים מהם, משתמשים ב-seald ב-c# .
  • קיים מבנה של Enum ב-C# שלא קיים ב-PHP ( למרות שקל מאוד לממש – מפתחים רבים פותחים מחלקה שמכילה Consts בלבד , והיא משמשת בתור enum )
  • שתי השפות יכולות לרוץ על כל מערכת הפעלה
    כן כן, גם למיקרוסופט יש גירסה ל-dot net שנקרא dot net core ורצה היטב על Linux .
  • ב-c# לפני הרצה צריך לבצע תהליך Build (קומפלייר)
    מה שנחסך מאיתנו כשעובדים ב-PHP
    זה יכול לקחת זמן לפעמים….וזה קטע מעצבן.

הבדלים מבחינת Enviroment  בין PHP ל- C# :

  • מנהל החבילות המוכר ב-PHP נקרא composer , בסביבת .Net קיים מנהל חבילות שנקרא NuGet
  • "על הנייר" נראה שיש פחות חבילות ל-C# , אבל זו השוואה ממש לא רלוונטית, כיוון שהרבה מאוד ספריות, מובנות כבר בתור השפה, ואין שום צורך בחבילה חיצונית.
    • דוגמא פשוטה לכך : ב-PHP נפוץ מאוד השימוש בספריה Carbon לצורך מניפולציות על תאריכים, לעומת זאת ב-C# , הספריה של DateTime כבר מובנה בשפה, ואין צורך לייבא אותה.
      נכון אומנם שגם ב-PHP יש ספרית DateTime, אך מהניסיון שלי, היא פחות נוחה לעבודה, וכיוון שכך – משתמשים ב-Carbon.
  • בסביבת מיקרוסופט, קיים IDE חזק, ללא תשלום, שנקרא Visual Studio , בא נגיד שאם מקבילים את זה לסביבת ה-PHP, אז זה כמו לקבל בחינם IDE ברמה של PHP Storm ( ואולי יותר מזה )
    • חיסרון מעצבן שלו  בכל זאת – זה שאין לו באופן מובנה ctrl+d לשכפול שורה, אך למרבה המזל, בגיגול פשוט, מוצאים תוספים שעושים זאת.
  • שרת Web – ב-PHP נהוג לעבוד עם Apache או Ngnix , לעומת סביבת dot net , שבה עובדים עם IIS.
  • אפליקציות Mobile – כאן יש יתרון עצום לסביבת מיקרוסופט, עם כלי שנקרא xamarin, ומאפשר לפתח אפליקציות שמתקפלות ל-Native , באותה שפה ( C# ) שבה אתה מפתח כרגיל.
    זה חוסך שימוש בפתרונות כמו PhoneGap \ Cordova וכדומה.
    והביצועים – בשמים.
  • כלי Debug :  ב-PHP נפוץ מאוד השימוש ב-xdebug , שההתקנה שלו עשויה להיות לפעמים סיזיפית ( חפשו ב-Youtube ותראו את כמות המדריכים בנושא ) .
    ה-Xdebug הוא תוספת ל-PHP שמאיטה מאוד את ההרצה.
    ב-C#, כלי ה-Debug מובנה בתוך Visual Studio, גם מאט מעט את ההרצה, אך פחות לעומת Xdbeug בתחושה האישית שלי.
  • הבדלים בתיעוד : 
    • מיקרוסופט מנצחת בגדול, הכל מתועד עד לפרטי פרטים,
      יחד עם זאת, קיים חיסרון של "יותר מדי מידע" ולפעמים קשה להבין איפה נמצא כל דבר בתור הררי התיעוד של מיקרוסופט.
    • לנקודה הזו יש יתרון מסויים נוסף מה קורה כאשר יש משהו לא ברור בתיעוד הרשמי ? – התיעוד של Laravel הוא מעולה בעיני, אך יש קטעים מסויימים בהם הוא כתוב גרו ( למשל ההסברים על IOC וקונספטים אחרים ) ובמקרה כזה – אין הרבה אפשרויות חוץ מלהתחיל לחפש בפורומים – שזה חיסרון .
      במיקרוסופט – בגלל עודף המקורות הרשמיים, אין הרבה צורך בפורומים. כי כמעט כל מה שתחפש כתוב בתיעוד הרשמי.

הבדלים ברמת ה- Framework  בין Laravel אל- ASP.NET MVC:

  • במבט ראשון, יש המון דברים מקבילים בין ASP.NET MVC ל- C#
  • זה מעלה מחשבות קלות של "מי העתיק ממי" אם כי, אני נוטה להניח שמיקרוסופט היו ראשונים, ו-Taylor היוצר של Laravel פשוט מימש את הדברים ב-Laravel כמו שהוא הכיר אותם לפני כן בסביבת מיקרוסופט.
  • לשתיהם יש ORM חזק, המקבילה של Eloquent ב-Laravel נקראת Entity ב-.Net
  • למרות שקיבלתי רושם שמפתחים רבים מסתייגים משימוש ב-Entity, לאחר מחקר קטן, זה כנראה חסר בסיס ( אולי בעבר היא הייתה נחותה מבחינת ביצועים, אך כיום ממש לא כך). מבחינת ביצועים – היא בסדר גמור לכל השאילתות הרגילות והפשוטות, כך שבשיקול עלות-תועלת של מהירות פיתוח מול ביצועים – זה בהחלט אופציה טובה.
  • גודל ההשקעה בפרוייקט – Laravel היא בסופו של דבר יציר כפיו של אדם אחד, עם מעט שותפים. קיימת כמובן קהילת Open Source גדולה וכו', אבל הוא ה-PO שלה חד משמעית (טיילור).
    ב-ASP.NET MVC זה מוצר של חברת ענק, ולפחות מבחינתי האישית זה היווה שיקול משמעותי בהחלטה לעבור, היות ואני לא נסמך על אדם אחד, עם קהילת קוד פתוח ( גדולה, ופעילה ככל שתהיה, כל עוד אין אינטרס כספי, לדעתי האישית, זה סיכון מסוים שצריך להילקח בחשבון).

הבדלים ברמת ביצועים בין C# ל- PHP :

  • אין כלל ספק ש-C# עולה בכמה רמות על PHP מבחינת ביצועים.
  • זה מורגש מעט בקטעי קוד שמבצעים עיבודים רציניים.
  • שפת C# היא שפה חצי-מתקמפלת , זה משליך על הביצועים משמעותית לטובה לעומת PHP.
  • עוד דברים שמשפיעים על ביצועים :
    • ב–C# התוכנה "נשארת" במצב ריצה כל הזמן, לעומת PHP שבה כל Request הוא מופע עצמאי שמתחיל מחדש.
    • החיבור ל-DB הוא קבוע ב-C#, לעומת PHP שבה החיבור נוצר בכל Request מחדש (לפי הצורך כמובן ) .
  • בקטעי קוד קטנים, אין הבדל מורגש בכלל בין השפות.
  • אומנם ב-PHP יש פתרונות לעבודה במקביל, אבל הם לא פשוטים ליישום כמו ב-C#  ( מספר תהליכים יחד).

 

סיכום – PHP לעומת C#

עניינים של בחירת שפה הפכו להיות נושאים "דתיים" לפעמים, אבל תכלס, כשבאים לבחון איזה כלי יותר טוב, בלי לערב שיקולים "כאילו-אידיאולוגים" של קוד פתוח וכו' – אז נראה שמיקרוסופט נותנת יותר ב-C# +ASP.NET MVC  לעומת PHP עם Laravel

יחד עם זאת, חייבים להודות שאם מישהו מחפש ללמוד במהירות שפת Web – אז PHP עדיפה משמעותית ..פשוט פותחים עמוד html, כותבים תגית php וזה רץ….

לדעתי, עקומת הלמידה לא כל כך משמעותית כדי להצדיק להתחיל עם PHP, בוא נגיד שאילו הייתי היום חוזר לאחור, אז הייתי מתחיל מראש עם c# , אבל כדי ללמד את הילדים בבית תיכנות הייתי בוחר ב-PHP .

המנצחת בעיני היא C# .

בהצלחה.

 

 

 

 

 

באגים ב-PHP בטיפול ב-XML באמצעות DomDocument \ SimpleXml

אני לא שותף למלחמות דת על "שפת התיכנות הטובה ביותר"

לרוב, מלחמות כאלו חסרות משמעות.

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

כבר כמה שנים שאני מתעסק עם קבצי XML ענקים שמגיעים מגופים גדולים.

והסתבר לי עם הזמן שלספריות ש-PHP מציעה כדי לפענח XML, יש חסרונות עצומים.

  • אם הקובץ לא מגיע בקידוד המצופה ( למשל, הקובץ מוצהר כ-UTF-8 אבל בפועל הוא UTF-16LE )
    אז צריך לאתר זאת מראש, כי הפקודות שטוענות את הקובץ ומפרשות את ה-XML, לא יודעות לפענח את הקידוד השונה בעצמן.
  • שאילתות XPATH, לעיתים לא עובדות – מאוד תלוי "במצב הרוח" של הספריה.
    לדוגמא – DomDocument מסוגלת לבצע שאילתות XPATH בצורה טובה, ואז בלי סיבה מיוחדת – לא לעבוד.
  • לעיתים, ספריה אחרת יודעת לפרש את ה-XML, והספריה השניה לא מצליחה להתמודד איתו, ומחזירה false.

הפתרון שמצאתי בסופו של דבר קורא את הקובץ בספריה אחת ושומר אותו מחדש כדי שהספריה השניה תואיל בטובה לקרוא אותו בכל מצב.

זה אומנם עובד, אך גובה מחיר יקר בזמן עיבוד שבמקרה שלי הוא אקוטי כיוון שהלקוח יושב וממתין…

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

במקרה הזה, יש לי רק מחמאות למיקרוסופט, הספריה העתיקה שלהם, עובדת מעולה.

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

מה המסקנה ?

אז אומנם php היא שפה מאוד כייפית לפיתוח, ומכילה כמות עצומה של פקודות וספריות, קהילה תומכת וכו' וכו'

אבל כנראה שיש צדדים מסויימים שבהם יש לה חסרונות ולגביהם כנראה צריך לבחור דרך להתגבר עליהם בשפות אחרות.

חבל …אבל זה מה יש.

אם יש לכם קבצי xml שאתם הייצרנים שלהם , ו- php היא שפת הפיתוח שלכם, אז תישארו איתה. אבל כשיש קבצי xml שאתם לא שולטים במקור שלהם, ויש סיכוי לקבצים עם בעיות …תבחרו שפה אחרת כדי לקרוא אותם. זו ההמלצה שלי.

איך להחזיר ב-Laravel רשימה עבור select במהירות ?

פעמים רבות, כאשר אנו יוצרים טופס HTML, צריך לשלוף רשימה מתוך טבלה ב-DB ולשים אותה בתוך select בטופס ה-HTML.
כאשר פעמים רבות, לכל ערך יש מפתח בטבלה, ואותו נרשום ב-select בתור ה-value.
ב-laravel יש צורה ממש פשוטה לעשות זאת, הן ישירות על הדאטאבייס והן עם מודל של Eloquent .

ישירות מהדאטאבייס :

DB::table('foo')->list('name','value');

ועל מודל של Eloquent זה עובד דומה, אבל משום מה המתודה מסתיימת ב-S

להלן דוגמא מפרויקט שלי על מודל של Eloquent :

AppJob::where('company','=',$company->company)->lists('job','id');

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

 

אז כדי ליישם את זה בתבנית של Blade זה נראה כך


                        @foreach($list as $key => $value)
                            
                        @endforeach
                  

להפוך DomNodeList למערך. PHP – DomDocument – Convert DomNodeList to Assosiative array

xml DomNodeList To php array
Photo by dpstyles™

האובייקטים של DomDocument ב-php הם מתעתעים, היות והם לא מתנהגים כרגיל, ולא מאפשרים לעשות עליהם var_dump וכדומה.

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

נא תשומת לב – כדי לקבל DomNodeList אפשר פשוט להשתמש על אוביקט ה-XML במתודה getElementsByTagName

ומה שמקבלים בחזרה – הוא אוביקט DomNodeList


/* Get DomNodeList Object
* and return an assosiative array
* This function is NOT recursive
*/
function DomNodeListToArray(DOMNodeList $domNodeList)
{
$items = $domNodeList;
$headlines = array();

foreach($items as $item) {
$headline = array();

if($item->childNodes->length) {
foreach($item->childNodes as $i) {
$headline[$i->nodeName] = $i->nodeValue;
}
}

$headlines[] = $headline;
}
return $headlines;
}

 

מקור – ההערות של הדוקומטציה http://php.net/manual/en/domdocument.getelementsbytagname.php

חיבור דינמי לדאטאבייסים רבים ב-Laravel

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

אז השלב הראשון לפתרון העניין, הוא הוספה דינמית של הגדרה.
כלומר – כידוע, בדרך כלל ההגדרות של הדאטאבייסים ב-Laravel יושבות במערך שמוגדר בקובץ database.php בתיקית config.

עכשיו, כיוון שזאת הגדרה לכל דבר ועניין, אז laravel מאפשרת להוסיף הגדרות דינמיות , באמצעות המתודה Config::set.

אז ככה אני מגדיר דאטאבייס חדש , מה שנקרא "on the fly", כלומר תוך כדי ריצה :

 Config::set('database.connections.'.'YOUR KEY COME HERE', array(
            'driver'    => 'mysql',
            'host'      => env('DB_HOST', 'localhost'),
            'database'  => $this->dbName,
            'username'  => env('DB_USERNAME', 'root'),
            'password'  => env('DB_PASSWORD', 'YOUR PASSWORD COME HERE'),
            'charset'   => 'utf8',
            'collation' => 'utf8_unicode_ci',
            'prefix'    => '',
            'strict'    => false,
                     ));

נא תשומת לב למספר נקודות :
1. השתמשתי ב-dot.notation, כלומר בתחביר של נקודה מפרידה, ו-Laravel יודעת להפריד אותו לבד.
2. המקום שבו סימנתי Your key come here – מיועד כמובן, כדי לתת שם יחודי ל-Connection הזה.

ועכשיו, אחרי שהגדרנו –
אז נשאר לבצע שאילתות.
אני אדגים על שאילתא בצורה גולמית, בלי להתייחס במאמר הזה ל-Eloquoent בינתיים.
אז נניח ואני רוצה לבצע שאילתת select על טבלת users באותו דאטאבייס שאליו התחברתי :
זה הולך ככה :

 $results = DB::connection($user->id)->select('select * from users where id > ?', [0]);

זהו, ראינו כאן איך להתחבר באופן דינמי לדאטאבייסים ב-laravel.
יום נעים
איל

שימוש בוורד / אקסל / PP על שרת ווינדוס עם php

לאחרונה בפרויקט מסוים היינו צריכים להשתמש בתוספות COM של PHP

כלומר להפעיל בצד השרת אקסל / וורד וכדומה.

התקנו שרת ווינדוס עם Wamp , ועליו מותקנות גם התוכנות הרלוונטיות (אקסל / וורד)

כדי שתוספת ה-COM תוכל לעבוד , צריך לאפשר אותה בתהליך הבא :

  • Run “dcomcnfg” to get to Component Services
  • Open Component Services > Computers > My Computer > DCOM Config
  • Search for Microsoft Excel Application or the appropriate application you working with on COM
  • Right-Click on it and open the properties
  • Choose “Identity” tab
  • Normally this is set to “the launching user” by default. You have to change this to “the interactive user”.
  • Apply these new settings and test your COM application. It should work fine now.

מקור : http://stackoverflow.com/questions/11704440/uncaught-exception-com-exception-with-message-bsource-b-microsoft-office

 

לאחר שמאפשרים את התוספת, אפשר בקלות להשתמש ב-word/Excel –

להלן דוגמא ב-php  מתוך התיעוד הרשמי

Version}n";

//bring it to front
$word->Visible = 1;

//open an empty document
$word->Documents->Add();

//do some weird stuff
$word->Selection->TypeText("This is a test...");
$word->Documents[1]->SaveAs("Useless test.doc");

//closing word
$word->Quit();

//free the object
$word = null;
?> 

התקנת Yii 2 על linux עם php composer

במדריך הזה, אני מראה איך להתקין את Yii 2 על לינוקס עם composer.

  • פתח תיקיה חדשה בתיקית ה-web שלך.
  • דאג שיהיו לך הרשאות מתאימות לתיקיה (chown/ chmod )
  • מתוך התיקיה – הקלד את הפקודות הבאות  ב-console כדי להוריד את ה-composer אל תוך התיקיה, וכדי להתקין אותה במצב "גלובלי"
sudo curl -sS https://getcomposer.org/installer | php
sudo mv composer.phar /usr/local/bin/composer
  • השלב הבא הוא להוריד פלאגאין ל-Composer ולהתקין אותו
    כיוון שהעברנו את ה-composer לתיקיה אחרת, ושינינו את שם הקובץ, הפקודה תהיה כך :
sudo php /usr/local/bin/composer global require "fxp/composer-asset-plugin:1.0.0-beta3"
  • עכשיו – אם יש לך חשבון GitHub, אז תיזכר בשם משתמש והסיסמא, ואם לא – אז פתח לעצמך חשבון.
  • ועכשיו הרץ את הפקודה הבאה ב-Console :
sudo php /usr/local/bin/composer create-project yiisoft/yii2-app-basic basic 2.0.0
  • ה-composer יתחיל בהתקנה ויתכן שידרוש להקליד את שם המשתמש והסיסמא ב-Git.

בסיום ההתקנה – אתם מוזמנים לגלוש אל הפרויקט שהותקן.

הערה : בדוגמא התקנו את פרויקט basic של Yii, יש גם אפשרות להתקין פרויקט advanced.

המדריך מפורסם לפי התנאים של Yii, והמקור נמצא כאן, במקרה זה בוצעו מספר שינויים בתרגום להתאמה ל-ubuntu

מדריך Yii 2 – עבודה עם Gii – כלי ליצירה אוטומטית של קוד

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

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

במדריך הזה נלמד :

  • איך לאפשר את הפעלת הכלי Gii בשרת הפיתוח שלך
  • ליצור מחלקת ActiveRecord באמצעות Gii
  • ליצור את כל פעולות ה-CRUD באמצעות Gii
  • שינוי של קוד שנוצר ב-Gii

איך להפעיל את המודול Gii

Gii הוא מודול של Yii. וכדי להפעיל אותו, צריך לפני כן לאפשר אותו. בעיקרון , ברירת המחדל של קובץ ההגדרות נמצאת ב : config/web.php , היכנס לשם, ותשנה את השורות הרלוונטיות :

$config = [ ... ];

if (YII_ENV_DEV) {
    $config['bootstrap'][] = 'gii';
    $config['modules']['gii'] = 'yiigiiModule';
}

כמו שבוודאי שמת לב, התנאי בקטע הקוד בודק האם המשתנה YII_ENV_DEV הוא true, ואם כן, מפעיל את המודול.

משתנה זה הוא משתנה שקובע האם אתה בסביבת פיתוח או יצור (production). ואם הסביבה היא סביבת פיתוח, אז האפלקציה עושה include למחלקה שהיא המודול הזה – מחלקת yiigiiModule.

אז כדי לוודא שהמשתנה הזה מכוון אצלך על סביבת פיתוח, עליך לבדוק ש בקובץ  web/index.php (מה שנקרא entry script - הכוונה לסקריפט שדרכו מנותבת כל התנועה ב Yii) 

מופיעה ההגדרה הבאה שקובעת את ערך המשתנה ל-true  :

defined('YII_ENV') or define('YII_ENV', 'dev');

השורה הזו קובעת בפועל שאתה ב-development mode  והכלי Gii מאופשר.

עכשיו אתה יכול לגלוש אל הכלי :

http://hostname/index.php?r=gii

שים לב : אם אתה עובד על שרת שאיננו localhost , אזי Gii יחסם אוטמטית, מטעמי אבטחה. אם תרצה לאפשר זאת על השרת, תצטרך לציין IP של השרת בהגדרה הבאה :

'gii' => [
    'class' => 'yiigiiModule',
    'allowedIPs' => ['127.0.0.1', '::1', '192.168.0.*', '192.168.178.20'] // adjust this to your needs
],

 

וכך נראה הכלי Gii – במסך הכניסה : 

 

2 הערות חשובות לפני שמתקדמים

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

איך לייצר מחלקה של Active Record באמצעות Gii ?

כדי להשתמש ב-Gii ליצור class של Active Record, בחר ב-Model Generator, ואז מלא את הפרטים הבאים בטופס :

  • Table Name: country
  • Model Class: Country

וכך זה צריך להיראות : 

 

עכשיו, לחץ על Preview, אתה תראה את הקובץ models/Country.php ברשימת התוצאות, אתה יכול ללחוץ על שם הקובץ אם אתה רוצה לראות את תוכנו – הקוד עצמו.

כאשר משתמשים ב-Gii, אם יש קובץ קודם בעל אותו שם – הוא ידרס, אם רוצים לראות את ההבדלים בקוד לעומת הגירסה הקודמת, לחץ diff .

השלב הבא הוא ללחוץ על Generate, ואז לאשר את ה-overwrite.

יצירת CRUD עם הכלי Gii

המונח CRUD מתאר את הפעולות הבסיסיות בדאטאבייס – יצירה, קריאה, עדכון ומחיקה, וניתן ליצור את כל רצף ה-actions וה-view עם המודל והקונטרולר במהירות באמצעות Gii.

כדי לעשות זאת לחץ על CRUD Generator, ואם נמשיך עם הדוגמא של טבלת Country, אז צריך למלא את הערכים הבאים :

  • Model Class: appmodelsCountry
  • Search Model Class: appmodelsCountrySearch
  • Controller Class: appcontrollersCountryController

זה צריך להיראות כך :

והמסך הבא (אחרי לחיצה על Preview) נראה כך : 

אם יצרת במדריכים הקודמים את הקונטרולר ואת ה-Index, אז תצטרך לאשר דריסה (overwrite) אחרי לחיצה על Generate.

 נסה את זה בעצמך

כדי לראות את כל מה שנוצר , גלוש אל

http://hostname/index.php?r=country/index

 

אתה תראה רשימה של המדינות, כאשר יש מעל כל עמודה אפשרות חיפוש, ולצד כל עמודה מופיעות האפשרויות לערוך, למחוק ולצפות.

 

אפשרות העדכון נראית כך : 

 

הקבצים שנוצרו על ידי Gii הם הקבצים הבאים, אתה מוזמן להיכנס אליהם ולשנות אותם לפי הצורך :

  • Controller: controllers/CountryController.php
  • Models: models/Country.php and models/CountrySearch.php
  • Views: views/country/*.php

מידע: Gii נועד להיות כלי יצירת קוד אוטומטי, כדי לאפשר לך התאמה אישית של הקוד והרחבה. אם תשתמש בו בתבונה, תוכל להאיץ את מהירות הפיתוח משמעותית.

סיכום – שימוש בכלי Gii של Yii

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

 

המדריך מפורסם לפי התנאים של Yii, והמקור נמצא כאן

מדריך Yii 2 – עבודה עם דאטאבייסים

במדריך הזה ניצור עמוד חדש שמציג תוכן של טבלה ב-DB בשם country. כדי לעשות זאת, אנחנו נגדיר את החיבור ל-DB ( כלומר connection), ניצור אוביקט של  Active Record , נגדיר action, וניצור view.

במדריך נעבור על הנושאים הבאים :

  • הגדרת connection אל הדאטאבייס
  • הגדרת אוביקט ActiveRecord
  • איך לבצע שאילתות על אוביקט ActiveRecord
  • איך להציג רשומות , עם חלוקה לעמודים (pagnition)

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

הכנת הדאטאבייס

כדי להתחיל, צור דאטאבייס בשם yii2basic שממנו נמשוך את הנתונים. אתה יכול ליצור אותו ב- SQLite, MySQL, PostgreSQL, MSSQL ,Oracle, לכולם יש תמיכה מובנית ב-Yii.

יחד עם זאת, בשביל הפשטות ההנחה לצורך המדריך הזה היא שאתה משתמש ב-MySql.

שלב שני, הרץ את הפקודות הבאות, שיוצרות טבלה בשם country, ומכניסות לה מספר רשומות.

CREATE TABLE `country` (
  `code` CHAR(2) NOT NULL PRIMARY KEY,
  `name` CHAR(52) NOT NULL,
  `population` INT(11) NOT NULL DEFAULT '0'
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

INSERT INTO `country` VALUES ('AU','Australia',18886000);
INSERT INTO `country` VALUES ('BR','Brazil',170115000);
INSERT INTO `country` VALUES ('CA','Canada',1147000);
INSERT INTO `country` VALUES ('CN','China',1277558000);
INSERT INTO `country` VALUES ('DE','Germany',82164700);
INSERT INTO `country` VALUES ('FR','France',59225700);
INSERT INTO `country` VALUES ('GB','United Kingdom',59623400);
INSERT INTO `country` VALUES ('IN','India',1013662000);
INSERT INTO `country` VALUES ('RU','Russia',146934000);
INSERT INTO `country` VALUES ('US','United States',278357000);

כעת, יש לך כבר דאטאבייס שנקרא yii2basic ובתוכו לפחות טבלה אחת בשם country עם כמה עמודות ו-10 רשומות.

הגדרת החיבור לדאטאבייס (database connection)

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

בהנחה ש-PDO מותקנת אצלך, פתח את הקובץ config/db.php ושנה את הפרמטרים הנחוצים כדי ליצור חיבור עם הדאטאבייס על השרת שלך.

<?php
// שנה את מה שצריך כאן
return [
    'class' => 'yiidbConnection',
    'dsn' => 'mysql:host=localhost;dbname=yii2basic',
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
];

הקובץ config/db.php הוא כלי הגדרה, שעוזר לאתחל ברקע מופע (instance) של אוביקט  yiidbConnection כדי שיהיה אפשר לתקשר עם הדאטאבייס.

אם אתה צריך לגשת לאוביקט הקונקשיין תוך כדי ריצה, תוכל לעשות זאת בפניה אל  Yii::$app->db.

הערה : הקובץ config/db.php נמשך (include) על ידי הקובץ  config/web.php שמאתחל את האוביקט  application. להרחבה בנושא הגדרות, בקר בקישור  Configurations.

 יצירה של ActiveRecord

כדי לגשת למידע מתוך הטבלה country, עלינו ליצור מחלקת בת של Active Record בשם של הטבלה – Country ולשמור את זה בקובץ models/Country.php.

<?php

namespace appmodels;

use yiidbActiveRecord;

class Country extends ActiveRecord
{
}

המחלקה Country מרחיבה (extends) את המחלקה  yiidbActiveRecord. בעיקרון , אתה לא צריך לרשום כלום בתוך המחלקה, כי Yii "תנחש" את הטבלה המשויכת למודל זה לבד.

הערה : אם אין סיכוי לנחש את השם מתוך שם ה-class, אתה יכול להגדיר את שם הטבלה בעצמך באמצעות המתודה yiidbActiveRecord::tableName().

עכשיו, אחרי שיש לנו מחלקה בשם Country, יהיה קל יותר לגשת למידע ולעשות מניפולציות עליו.

הנה כמה דוגמאות קוד לשליפת נתונים וגישה אליהם :

 

use appmodelsCountry;

// לשלוף את כל הרשומות מהטבלה ולמיין אותן לפי השדה name
$countries = Country::find()->orderBy('name')->all();

// שלוף את כל הרשומות עם מפתח ראשי שהוא US
$country = Country::findOne('US');

// להציג תוכן של שדה
echo $country->name;

// לשנות ערך בשדה ולשמור את השינוי בדאטאבייס
$country->name = 'U.S.A.';
$country->save();

הערה : גישה לנתונים באמצעות ActiveRecord היא דרך מאוד עוצמתית, מונחית עצמים. למידע נוסף בקר בקישור הבא :  Active Record

כדאי לדעת שיש אפשרות לבצע שאילתות בצורה "גולמית" יותר עם אוביקט אחר שנקרא Data Access Objects.

יצירת Action

כדי להציג לגולשים את תוכן הטבלה country, אנחנו צריכים ליצור action חדש. הפעם, במקום ליצור אותו בתוך ה-controller שנקרא site, אנחנו ניצור אותו בתוך controller חדש, שיהיה שייך ספציפית לטבלה הזו, ונקרא לו בשם CountryController, בתוך הקונטרולר החדש, ניצור מתודה/action בשם index כמו שמוצג בקוד הבא :

<?php

namespace appcontrollers;

use yiiwebController;
use yiidataPagination;
use appmodelsCountry;

class CountryController extends Controller
{
    public function actionIndex()
    {
        $query = Country::find();

        $pagination = new Pagination([
            'defaultPageSize' => 5,
            'totalCount' => $query->count(),
        ]);

        $countries = $query->orderBy('name')
            ->offset($pagination->offset)
            ->limit($pagination->limit)
            ->all();

        return $this->render('index', [
            'countries' => $countries,
            'pagination' => $pagination,
        ]);
    }
}

שמור את קטע הקוד הזה בקובץ  controllers/CountryController.php.

מה בעצם קורה בקוד ? המתודה/action שנקראת index קוראת ל Country::find() שזוהי מתודה מובנית לביצוע שאילתות DB , וכך מחזירה מידע מתוך הטבלה country .

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

האוביקט הזה –yiidataPagination  יכול לסייע לנו בכמה צורות :

  • הוא מוסיף פסויקיות LIMIT ו-OFFSET למשפט ה-SQL של השאילתא. (במקרה שלנו הגבלנו ל-5 רשומות בכל דף).
  • הוא מאפשר להוסיף ל-view סט  של כפתורים לדילוג בין עמודים (1,2 וכו…)

בסוף הפונקציה index, אנו קוראים ל-render כדי ליצר view שנקרא index ומעבירים אליו את חבילת המידע על country, ביחד עם אוביקט העימוד שיצרנו.

יצירת ה-view

עכשיו, צור תיקיה חדשה תחת תיקית views וקרא לה country. התיקיה הזו תכיל את כל ה-views שקשורים לקונטרולר country. בתוך תיקית views/country צור קובץ חדש וקרא לו index.php ובתוכו הדבק את הקוד הבא :

<?php
use yiihelpersHtml;
use yiiwidgetsLinkPager;
?>
<h1>Countries</h1>
<ul>
<?php foreach ($countries as $country): ?>
    <li>
        <?= Html::encode("{$country->name} ({$country->code})") ?>:
        <?= $country->population ?>
    </li>
<?php endforeach; ?>
</ul>

<?= LinkPager::widget(['pagination' => $pagination]) ?>

ל-view יש 2 חלקים : החלק הראשון מציג את הרשומות מתוך הטבלה country בתור "רשימה" של html.

והחלק השני  יש widget של Yii שנותן את כפתורי מעבר בין עמודים. הוא נקרא yiiwidgetsLinkPager  .

נסה את זה בעצמך

כדי לראות את כל הקוד בפעולה, גלוש אל

http://hostname/index.php?r=country/index

זה צריך להיראות כך :

בראש הדף אתה תראה 5 מדינות, ומתחת להן, יופיעו כפתורי העימוד. אם תקליק על אחד מכפתורי העימוד, תראה כיצד מופיעות רשומות אחרות בהתאמה, ואם תשים לב, תראה שגם הכתובת בדפדפן משתנה בהתאם.

לדוגמא , עבור העמוד השני , הכתובת שתופיע היא :

http://hostname/index.php?r=country/index&page=2

 

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

  • בתחילה, אוביקט Pagination מציג את העמוד הראשון, באמצעות פסוקית SQL  הבאה לסוף המשפט LIMIT 5 OFFSET 0. , כתוצאה מכך נקבל את 5 המדינות הראשונות.
  • רכיב ה-  LinkPager מרנדר את הכפתורים למטה, כשכל כפתור מכיל URL עם פרמטר page לעמוד אחר.
  • כאשר אנו מקליקים על "2" לדוגמא, אז אוביקט ה- Pagination מקבל את הפרמטר, ומוסיף לסוף משפט ה-SQL את הפסוקית LIMIT 5 OFFSET 5 ומחזיר את המדינות הבאות בהתאם.

סיכום – עבודה עם דאטאבייסים ב- Yii 2

במדריך הזה למדת כיצד לעבוד עם דאטאבייס, בנוסף למדת על השימוש באוביקט yiidataPagination , וברכיב ה yiiwidgetsLinkPager .

במדריך הבא נראה איך להשתמש בכלי ה-Gii, כלי עוצמתי של Yii המאפשר לחסוך המון זמן באמצעות כך שהוא בונה עבורך חלקים שלמים באפליקציה – מודלים, CRUD, ועוד.

המדריך מפורסם לפי התנאים של Yii, והמקור נמצא כאן