ארכיון תגיות: php

מעבר מ-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 שאתם לא שולטים במקור שלהם, ויש סיכוי לקבצים עם בעיות …תבחרו שפה אחרת כדי לקרוא אותם. זו ההמלצה שלי.

סיכום מתומצת בעברית CakePHP – חלק 1

מבנה תיקיות:
בתיקיה הראשית יש 3 תיקיות:
app – התיקיה בה אתה יוצר את האפליקציות
lib – תיקית המנוע, בה אסור לגעת
vendors – תיקיה לספריות חיצוניות שבהן משתמשים.
בנוסף התיקיה מכילה קובץ Index.php וגם קובץ htaccess.

מבנה תיקית app :

תיקית app מכילה מספר תיקיות :
config – קבצי הגדרות, קישור לדאטאבייס, bootstarp וכדומה.
console – פקודות ל-Console. וניתן להכיל בתוך התיקיה הזו גם Templates.
תיקיות Controller / Model / View – אין מה לפרט, לפי מודל ה-MVC.
Lib – עוד תיקית לסריות חיצוניות, למה יש גם כאן וגם בתיקית האם ? כדי להפריד ספריות של ספקים חיצונים שיאוחסנו בתוך vendors בתיקית האם, ולעומת זאת ספריות שאתה כותב, יאוחסנו כאן.
locale – קבצי תרגום לשפות שונות.
plugin … ברור.
test – מכילה את כל ה-test cases, פירוט בהמשך.
tmp – לוגים, לפעמים שמירה של Sessions ועוד. התיקיה חייבת להיות קיימת, ועם הרשאות כתיבה.
Vendor – ספריות של ספקים חיצוניים . ברגע ששמים אותם כאן, אפשר לקרוא לפונקציות שלהם בצורה הרגילה
כלומר App::import('vendor','name'); הסיבה לכפילות עם תיקיה דומה בתיקית האם תוסבר בהמשך.

webroot – בסביבת יצור, זו תיקית האם, ובתוכה יהיו גם קבצי CSS, JS, תמונות וכדומה.

מקור : http://book.cakephp.org/2.0/en/getting-started/cakephp-folder-structure.html

מוסכמות במתן שמות ב- CakePhp

מוסכמות של מתן שמות, הן עניין גדול ב-CakePhp שאם שומרים עליו מסייע רבות לכל אורך הדרך.

מוסכמות שמות עבור Controller

– נכתבים בלשון רבים
– מסתיימים במילה Controller
למשל : PeopleController and LatestArticlesController

המתודה הראשונה של קונטרלר היא תמיד index() .
ולכן כאשר מבצעים request לקונטרולר, זו המתודה שמוחזרת כברירת מחדל.
למשל הכתובת http://www.example.com/apples/ מחזירה את המתודה index() של אוביקט ApplesController.
כאשר ה-View של אותו אוביקט יהיה בכתובת http://www.example.com/apples/view/
ויקרא למתודה view() של אוביקט ApplesController.

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

class NewsController extends AppController {

    public function latest() {
        $this->_findNewArticles();
    }

    protected function _findNewArticles() {
        // Logic to find latest news articles
    }
}

אז הגישה למתודה תהיה דרך http://www.example.com/news/latest/ אבל מי שיקליד http://www.example.com/news/_findNewArticles/ יגיע לדף שגיאה.

מבנה URL לפי המוסכמות של קונטרולרים

כל עוד הקונטרולר כתוב לפי המוסכמות, אז מספיקה מילת השם שלו, בלשון רבים, באותיות קטנות בתור URL.
למשל, קונטרולר בשם ApplesController – ניגש אליו באמצעות הכתובת http://example.com/apples.

לגבי ביטויים שמורכבים ממספר מילים, אפשר להשתמש בכל הצורות של החיבור (עם /בלי מקף תחתון בין המילים, וכאשר כל מילה מתחילה באות גדולה או קטנה). אבל יחד עם זאת, ה-URL תמיד יהיה אותיות קטנות, עם מקף תחתון.
למשל אם יש לנו מתודה RedApplesController::go_pick , אז ה-URL שלה יהיה /red_apples/go_pick

מוסכמות לשמות קבצים ושמות Class

שמות קבצים ושמות קלאסים תמיד CamelCased כלומר כל מילה מתחילה באות גדולה. שם הקובץ יהיה אותו דבר בדיוק עם נקודה והסיומת php.

לדוגמא :
הקלאס יקרא MyNiftyClass
אז הקובץ יקרא MyNiftyClass.php

עוד דוגמא לקלאס EspeciallyFunkableBehavior , אז שם הקובץ יהיה EspeciallyFunkableBehavior.php .

אם יש לי קונטרולר אז הוא יקרא KissesAndHugsController
ושם הקובץ יקרא MyHandyComponent.php

אם יש לי מודל שנקרא OptionValue
אז שם הקובץ יהיה OptionValue.php

כל קובץ כמובן בתיקיה שבה הוא צריך להיות.

מוסכמות לגבי שמות מודל ושמות של רכיבים בדאטאבייס

שמות של קלאסים במודל, הם תמיד CamelCased, בלשון יחיד. למשל Person, BigPerson, and ReallyBigPerson.

שמות של טבלאות שתואמות למודלים הן תמיד בלשון רבים, והמילים מופרדות בקו תחתון. למשל people, big_people, and really_big_people.

יש בקישור הזה הסבר על היכולות של יחיד/רבים ב-CakePHP.

שמות שדות שמורכבות מכמה מילים, מופרדות בקו תחתון. my_field

שמות של מפתחות זרים מורכבים משם הטבלה המקורית עם סיומת _id למשל., אם לאופה אחד יש הרבה עוגות, אז המפתח הזר שמתייחס לטבלה bakers יקרא בשם baker_id (מה שמסביר שוב פעם למה שמות הטבלאות הן בלשון רבים).

אם יש טבלאות שעושים להם join בקשר hasAndBelongsToMany , אז קוראים להם בשם טבלאות המודל שהם מצרפות יחד , בסדר אלפביתי, נניח אני עושה join לטבלאות apples וגם zebras אז המודל יקרא apples_zebras כי a הוא לפני z.

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

המפתח הראשי יכול להיות מספר רץ (auto-increment ) או char(36) ואז יש מתודה שנקראת String::uuid שנותנת לו מפתח.

מוסכמות לגבי View

שמות של הקבצים שמכילים את ה – view, הם תמיד מורכבים משמות הפונקציות של הקונטרולר שאותו הן מציגות , אבל עם קו תחתון.
למשל הפונקציה getReady() ששייכת לקונטרולר PeopleControler , תחפש את ה-View שלה כאן /app/View/People/get_ready.ctp

דוגמא אחרונה, שמסכמת הכל ומציגה שאפשר להשתמש גם בלשון רבים שמובנה בתוך המילה, ולאו דווקא עם S בסוף :
Database table: “people”
Model class: “Person”, found at /app/Model/Person.php
Controller class: “PeopleController”, found at /app/Controller/PeopleController.php
View template, found at /app/View/People/index.ctp

המבנה הוא תמיד /app/View/Controller/underscored_function_name.ctp

מקור : http://book.cakephp.org/2.0/en/getting-started/cakephp-conventions.html

תקלת XML – שנקראת Invalid at the top level of the document

אני משתמש ב-MSXML כדי לקבל XML באמצעות VBA, שנשלח מ-PHP .

מסיבה לא ברורה, לפעמים יש סימן שאלה *לפני* התו הראשון.
זה נראה כך :

?

מה שגורם לתקלה "קטנה" ב-XML.

הבעיה : תקלות ב-MSXML לא תמיד מדווחות כתקלות VBA
לכן קשה לדעת שהייתה תקלה כי (Err.number=0)

פתרונות משולבים :
1. כדי לדעת אם הייתה תקלה יש להשתמש ב
xmlOBJECT.parseError.errorCode - עבור הקוד של התקלה
ועבור התיאור ב - reason במקום errorcode.

2. כדי להתמודד עם זה, יש לזהות את הקוד ASCII של התו הראשון, ולנקות אותו.

מדריך 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, והמקור נמצא כאן

 

מדריך 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, והמקור נמצא כאן

שימוש בוורד / אקסל / 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;
?>